You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 7-8.RSVP
Socket
Socket
Sign inDemoInstall

eslint-plugin-ava

Package Overview
Dependencies
Maintainers
2
Versions
59
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 13.2.0 to 14.0.0

12

create-ava-rule.js

@@ -191,3 +191,3 @@ 'use strict';

const predefinedRules = {
ImportDeclaration: node => {
ImportDeclaration(node) {
if (!isTestFile && avaImportDeclarationAsts.some(ast => isDeepStrictEqual(espurify(node), ast))) {

@@ -197,3 +197,3 @@ isTestFile = true;

},
VariableDeclarator: node => {
VariableDeclarator(node) {
if (!isTestFile && avaVariableDeclaratorAsts.some(ast => isDeepStrictEqual(espurify(node), ast))) {

@@ -203,3 +203,3 @@ isTestFile = true;

},
CallExpression: node => {
CallExpression(node) {
if (isTestFunctionCall(node.callee)) {

@@ -210,3 +210,3 @@ // Entering test function

},
'CallExpression:exit': node => {
'CallExpression:exit'(node) {
if (currentTestNode === node) {

@@ -217,3 +217,3 @@ // Leaving test function

},
'Program:exit': () => {
'Program:exit'() {
isTestFile = false;

@@ -225,3 +225,3 @@ },

hasTestModifier: mod => getTestModifierNames(currentTestNode).includes(mod),
hasNoUtilityModifier: () => {
hasNoUtilityModifier() {
const modifiers = getTestModifierNames(currentTestNode);

@@ -228,0 +228,0 @@ return !modifiers.includes('before')

{
"name": "eslint-plugin-ava",
"version": "13.2.0",
"version": "14.0.0",
"description": "ESLint rules for AVA",

@@ -8,7 +8,12 @@ "license": "MIT",

"engines": {
"node": ">=12.22 <13 || >=14.17 <15 || >=16.4"
"node": ">=14.17 <15 || >=16.4"
},
"scripts": {
"test": "xo && c8 ava",
"integration": "node ./test/integration/test.js"
"integration": "node ./test/integration/test.js",
"lint": "npm-run-all \"lint:*\"",
"lint:eslint-docs": "npm-run-all \"update:eslint-docs -- --check\"",
"lint:js": "xo",
"test": "npm-run-all lint test:unit",
"test:unit": "c8 ava",
"update:eslint-docs": "eslint-doc-generator --rule-doc-section-include Pass --rule-doc-section-include Fail --url-configs \"https://github.com/avajs/eslint-plugin-ava#recommended-config\""
},

@@ -49,14 +54,16 @@ "files": [

"del": "^6.0.0",
"eslint": "^8.0.1",
"eslint": "^8.26.0",
"eslint-ava-rule-tester": "^4.0.0",
"eslint-plugin-eslint-plugin": "^4.0.1",
"eslint-doc-generator": "^1.0.0",
"eslint-plugin-eslint-plugin": "^5.0.6",
"execa": "^5.1.1",
"listr": "^0.14.3",
"npm-run-all": "^4.1.5",
"outdent": "^0.8.0",
"pify": "^5.0.0",
"tempy": "^1.0.1",
"xo": "^0.46.4"
"xo": "^0.52.4"
},
"peerDependencies": {
"eslint": ">=7.22.0"
"eslint": ">=8.26.0"
},

@@ -91,3 +98,8 @@ "ava": {

"eslint-plugin/prefer-message-ids": "off",
"eslint-plugin/require-meta-docs-description": "off",
"eslint-plugin/require-meta-docs-description": [
"error",
{
"pattern": "^(Enforce|Ensure|Require|Disallow|Prevent|Prefer)"
}
],
"eslint-plugin/require-meta-has-suggestions": "off",

@@ -94,0 +106,0 @@ "eslint-plugin/prefer-placeholders": "off",

@@ -13,5 +13,5 @@ # eslint-plugin-ava [![Coverage Status](https://coveralls.io/repos/github/avajs/eslint-plugin-ava/badge.svg?branch=main)](https://coveralls.io/github/avajs/eslint-plugin-ava?branch=main)

```sh
npm install --save-dev eslint eslint-plugin-ava
```
$ npm install --save-dev eslint eslint-plugin-ava
```

@@ -38,33 +38,5 @@ ## Usage

"ava/assertion-arguments": "error",
"ava/hooks-order": "error",
"ava/max-asserts": [
"off",
5
],
"ava/no-async-fn-without-await": "error",
"ava/no-duplicate-modifiers": "error",
"ava/no-identical-title": "error",
"ava/no-ignored-test-files": "error",
"ava/no-import-test-files": "error",
"ava/no-incorrect-deep-equal": "error",
"ava/no-inline-assertions": "error",
"ava/no-nested-tests": "error",
"ava/no-only-test": "error",
"ava/no-skip-assert": "error",
"ava/no-skip-test": "error",
"ava/no-todo-implementation": "error",
"ava/no-todo-test": "warn",
"ava/no-unknown-modifiers": "error",
"ava/prefer-async-await": "error",
"ava/prefer-power-assert": "off",
"ava/prefer-t-regex": "error",
"ava/test-title": "error",
"ava/test-title-format": "off",
"ava/use-t": "error",
"ava/use-t-throws-async-well": "error",
"ava/use-t-well": "error",
"ava/use-test": "error",
"ava/use-true-false": "error"
}
}
"ava/...": "error"
}
}
}

@@ -77,30 +49,43 @@ ```

- [assertion-arguments](docs/rules/assertion-arguments.md) - Enforce passing correct arguments to assertions.
- [hooks-order](docs/rules/hooks-order.md) - Enforce test hook ordering. *(fixable)*
- [max-asserts](docs/rules/max-asserts.md) - Limit the number of assertions in a test.
- [no-async-fn-without-await](docs/rules/no-async-fn-without-await.md) - Ensure that async tests use `await`.
- [no-duplicate-modifiers](docs/rules/no-duplicate-modifiers.md) - Ensure tests do not have duplicate modifiers.
- [no-identical-title](docs/rules/no-identical-title.md) - Ensure no tests have the same title.
- [no-ignored-test-files](docs/rules/no-ignored-test-files.md) - Ensure no tests are written in ignored files.
- [no-import-test-files](docs/rules/no-import-test-files.md) - Ensure no test files are imported anywhere.
- [no-incorrect-deep-equal](docs/rules/no-incorrect-deep-equal.md) - Avoid using `deepEqual` with primitives. *(fixable)*
- [no-inline-assertions](docs/rules/no-inline-assertions.md) - Ensure assertions are not called from inline arrow functions. *(fixable)*
- [no-nested-tests](docs/rules/no-nested-tests.md) - Ensure no tests are nested.
- [no-only-test](docs/rules/no-only-test.md) - Ensure no `test.only()` are present.
- [no-skip-assert](docs/rules/no-skip-assert.md) - Ensure no assertions are skipped.
- [no-skip-test](docs/rules/no-skip-test.md) - Ensure no tests are skipped.
- [no-todo-implementation](docs/rules/no-todo-implementation.md) - Ensure `test.todo()` is not given an implementation function.
- [no-todo-test](docs/rules/no-todo-test.md) - Ensure no `test.todo()` is used.
- [no-unknown-modifiers](docs/rules/no-unknown-modifiers.md) - Prevent the use of unknown test modifiers.
- [prefer-async-await](docs/rules/prefer-async-await.md) - Prefer using async/await instead of returning a Promise.
- [prefer-power-assert](docs/rules/prefer-power-assert.md) - Allow only use of the asserts that have no [power-assert](https://github.com/power-assert-js/power-assert) alternative.
- [prefer-t-regex](docs/rules/prefer-t-regex.md) - Prefer using `t.regex()` to test regular expressions. *(fixable)*
- [test-title](docs/rules/test-title.md) - Ensure tests have a title.
- [test-title-format](docs/rules/test-title-format.md) - Ensure test titles have a certain format.
- [use-t](docs/rules/use-t.md) - Ensure test functions use `t` as their parameter.
- [use-t-throws-async-well](docs/rules/use-t-throws-async-well.md) - Ensure that `t.throwsAsync()` and `t.notThrowsAsync()` are awaited. *(partly fixable)*
- [use-t-well](docs/rules/use-t-well.md) - Prevent the incorrect use of `t`. *(partly fixable)*
- [use-test](docs/rules/use-test.md) - Ensure that AVA is imported with `test` as the variable name.
- [use-true-false](docs/rules/use-true-false.md) - Ensure that `t.true()`/`t.false()` are used instead of `t.truthy()`/`t.falsy()`.
<!-- begin auto-generated rules list -->
💼 [Configurations](https://github.com/avajs/eslint-plugin-ava#recommended-config) enabled in.\
⚠️ [Configurations](https://github.com/avajs/eslint-plugin-ava#recommended-config) set to warn in.\
🚫 [Configurations](https://github.com/avajs/eslint-plugin-ava#recommended-config) disabled in.\
✅ Set in the `recommended` [configuration](https://github.com/avajs/eslint-plugin-ava#recommended-config).\
🔧 Automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix).\
💡 Manually fixable by [editor suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions).
| Name                      | Description | 💼 | ⚠️ | 🚫 | 🔧 | 💡 |
| :------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------- | :- | :- | :- | :- | :- |
| [assertion-arguments](docs/rules/assertion-arguments.md) | Enforce passing correct arguments to assertions. | ✅ | | | 🔧 | |
| [hooks-order](docs/rules/hooks-order.md) | Enforce test hook ordering. | ✅ | | | 🔧 | |
| [max-asserts](docs/rules/max-asserts.md) | Enforce a limit on the number of assertions in a test. | | | ✅ | | |
| [no-async-fn-without-await](docs/rules/no-async-fn-without-await.md) | Ensure that async tests use `await`. | ✅ | | | | |
| [no-duplicate-modifiers](docs/rules/no-duplicate-modifiers.md) | Ensure tests do not have duplicate modifiers. | ✅ | | | | |
| [no-identical-title](docs/rules/no-identical-title.md) | Ensure no tests have the same title. | ✅ | | | | |
| [no-ignored-test-files](docs/rules/no-ignored-test-files.md) | Ensure no tests are written in ignored files. | ✅ | | | | |
| [no-import-test-files](docs/rules/no-import-test-files.md) | Ensure no test files are imported anywhere. | ✅ | | | | |
| [no-incorrect-deep-equal](docs/rules/no-incorrect-deep-equal.md) | Disallow using `deepEqual` with primitives. | ✅ | | | 🔧 | |
| [no-inline-assertions](docs/rules/no-inline-assertions.md) | Ensure assertions are not called from inline arrow functions. | ✅ | | | 🔧 | |
| [no-nested-tests](docs/rules/no-nested-tests.md) | Ensure no tests are nested. | ✅ | | | | |
| [no-only-test](docs/rules/no-only-test.md) | Ensure no `test.only()` are present. | ✅ | | | 🔧 | 💡 |
| [no-skip-assert](docs/rules/no-skip-assert.md) | Ensure no assertions are skipped. | ✅ | | | | |
| [no-skip-test](docs/rules/no-skip-test.md) | Ensure no tests are skipped. | ✅ | | | 🔧 | 💡 |
| [no-todo-implementation](docs/rules/no-todo-implementation.md) | Ensure `test.todo()` is not given an implementation function. | ✅ | | | | |
| [no-todo-test](docs/rules/no-todo-test.md) | Ensure no `test.todo()` is used. | | ✅ | | | |
| [no-unknown-modifiers](docs/rules/no-unknown-modifiers.md) | Disallow the use of unknown test modifiers. | ✅ | | | | |
| [prefer-async-await](docs/rules/prefer-async-await.md) | Prefer using async/await instead of returning a Promise. | ✅ | | | | |
| [prefer-power-assert](docs/rules/prefer-power-assert.md) | Enforce the use of the asserts that have no [power-assert](https://github.com/power-assert-js/power-assert) alternative. | | | ✅ | | |
| [prefer-t-regex](docs/rules/prefer-t-regex.md) | Prefer using `t.regex()` to test regular expressions. | ✅ | | | 🔧 | |
| [test-title](docs/rules/test-title.md) | Ensure tests have a title. | ✅ | | | | |
| [test-title-format](docs/rules/test-title-format.md) | Ensure test titles have a certain format. | | | ✅ | | |
| [use-t](docs/rules/use-t.md) | Ensure test functions use `t` as their parameter. | ✅ | | | | |
| [use-t-throws-async-well](docs/rules/use-t-throws-async-well.md) | Ensure that `t.throwsAsync()` and `t.notThrowsAsync()` are awaited. | ✅ | | | 🔧 | |
| [use-t-well](docs/rules/use-t-well.md) | Disallow the incorrect use of `t`. | ✅ | | | 🔧 | |
| [use-test](docs/rules/use-test.md) | Ensure that AVA is imported with `test` as the variable name. | ✅ | | | | |
| [use-true-false](docs/rules/use-true-false.md) | Ensure that `t.true()`/`t.false()` are used instead of `t.truthy()`/`t.falsy()`. | ✅ | | | | |
<!-- end auto-generated rules list -->
## Recommended config

@@ -107,0 +92,0 @@

@@ -214,3 +214,3 @@ 'use strict';

const ava = createAvaRule();
const options = context.options[0] || {};
const options = context.options[0] ?? {};
const enforcesMessage = Boolean(options.message);

@@ -289,3 +289,3 @@ const shouldHaveMessage = options.message !== 'never';

for (const ref of variable.references) {
value = ref.writeExpr || value;
value = ref.writeExpr ?? value;
}

@@ -401,2 +401,3 @@

docs: {
description: 'Enforce passing correct arguments to assertions.',
url: util.getDocsUrl(__filename),

@@ -403,0 +404,0 @@ },

@@ -25,3 +25,3 @@ 'use strict';

const buildMessage = (name, orders, visited) => {
const checks = orders[name] || [];
const checks = orders[name] ?? [];

@@ -94,3 +94,3 @@ for (const check of checks) {

// TODO: Remove `.reduce()` usage.
// eslint-disable-next-line unicorn/no-array-reduce, unicorn/prefer-object-from-entries
// eslint-disable-next-line unicorn/no-array-reduce
const selectors = checks.reduce((result, check) => {

@@ -111,6 +111,6 @@ result[check.selector] = visitIf([

data: message.data,
fix: fixer => {
fix(fixer) {
const tokensBetween = sourceCode.getTokensBetween(nodeEarlier.parent, node.parent);
if (tokensBetween && tokensBetween.length > 0) {
if (tokensBetween?.length > 0) {
return;

@@ -157,2 +157,3 @@ }

docs: {
description: 'Enforce test hook ordering.',
url: util.getDocsUrl(__filename),

@@ -159,0 +160,0 @@ },

@@ -15,3 +15,3 @@ 'use strict';

// https://github.com/avajs/eslint-plugin-ava/issues/260
const maxAssertions = context.options[0] || MAX_ASSERTIONS_DEFAULT;
const maxAssertions = context.options[0] ?? MAX_ASSERTIONS_DEFAULT;
let assertionCount = 0;

@@ -76,2 +76,3 @@ let nodeToReport;

docs: {
description: 'Enforce a limit on the number of assertions in a test.',
url: util.getDocsUrl(__filename),

@@ -78,0 +79,0 @@ },

@@ -18,3 +18,3 @@ 'use strict';

const isAsync = node => Boolean(node && node.async);
const isAsync = node => Boolean(node?.async);

@@ -58,2 +58,3 @@ return ava.merge({

docs: {
description: 'Ensure that async tests use `await`.',
url: util.getDocsUrl(__filename),

@@ -60,0 +61,0 @@ },

@@ -54,2 +54,3 @@ 'use strict';

docs: {
description: 'Ensure tests do not have duplicate modifiers.',
url: util.getDocsUrl(__filename),

@@ -56,0 +57,0 @@ },

@@ -55,3 +55,3 @@ 'use strict';

}),
'Program:exit': () => {
'Program:exit'() {
usedTitleNodes = [];

@@ -67,2 +67,3 @@ },

docs: {
description: 'Ensure no tests have the same title.',
url: util.getDocsUrl(__filename),

@@ -69,0 +70,0 @@ },

@@ -25,3 +25,3 @@ 'use strict';

}),
'Program:exit': node => {
'Program:exit'(node) {
if (!hasTestCall) {

@@ -71,2 +71,3 @@ return;

docs: {
description: 'Ensure no tests are written in ignored files.',
url: util.getDocsUrl(__filename),

@@ -73,0 +74,0 @@ },

@@ -50,6 +50,6 @@ 'use strict';

return {
ImportDeclaration: node => {
ImportDeclaration(node) {
validateImportPath(node, node.source.value);
},
CallExpression: node => {
CallExpression(node) {
if (!(node.callee.type === 'Identifier' && node.callee.name === 'require')) {

@@ -83,2 +83,3 @@ return;

docs: {
description: 'Ensure no test files are imported anywhere.',
url: util.getDocsUrl(__filename),

@@ -85,0 +86,0 @@ },

@@ -87,2 +87,3 @@ 'use strict';

docs: {
description: 'Disallow using `deepEqual` with primitives.',
url: util.getDocsUrl(__filename),

@@ -89,0 +90,0 @@ },

@@ -43,2 +43,3 @@ 'use strict';

docs: {
description: 'Ensure assertions are not called from inline arrow functions.',
url: util.getDocsUrl(__filename),

@@ -45,0 +46,0 @@ },

@@ -39,2 +39,3 @@ 'use strict';

docs: {
description: 'Ensure no tests are nested.',
url: util.getDocsUrl(__filename),

@@ -41,0 +42,0 @@ },

@@ -39,2 +39,3 @@ 'use strict';

docs: {
description: 'Ensure no `test.only()` are present.',
url: util.getDocsUrl(__filename),

@@ -41,0 +42,0 @@ },

@@ -33,2 +33,3 @@ 'use strict';

docs: {
description: 'Ensure no assertions are skipped.',
url: util.getDocsUrl(__filename),

@@ -35,0 +36,0 @@ },

@@ -39,2 +39,3 @@ 'use strict';

docs: {
description: 'Ensure no tests are skipped.',
url: util.getDocsUrl(__filename),

@@ -41,0 +42,0 @@ },

@@ -30,2 +30,3 @@ 'use strict';

docs: {
description: 'Ensure `test.todo()` is not given an implementation function.',
url: util.getDocsUrl(__filename),

@@ -32,0 +33,0 @@ },

@@ -30,2 +30,3 @@ 'use strict';

docs: {
description: 'Ensure no `test.todo()` is used.',
url: util.getDocsUrl(__filename),

@@ -32,0 +33,0 @@ },

@@ -50,2 +50,3 @@ 'use strict';

docs: {
description: 'Disallow the use of unknown test modifiers.',
url: util.getDocsUrl(__filename),

@@ -52,0 +53,0 @@ },

@@ -57,2 +57,3 @@ 'use strict';

docs: {
description: 'Prefer using async/await instead of returning a Promise.',
url: util.getDocsUrl(__filename),

@@ -59,0 +60,0 @@ },

@@ -88,2 +88,3 @@ 'use strict';

docs: {
description: 'Enforce the use of the asserts that have no [power-assert](https://github.com/power-assert-js/power-assert) alternative.',
url: util.getDocsUrl(__filename),

@@ -90,0 +91,0 @@ },

@@ -26,3 +26,3 @@ 'use strict';

if (reference && reference.resolved) {
if (reference?.resolved) {
const definitions = reference.resolved.defs;

@@ -55,6 +55,10 @@

const findRootReference = node => {
if (!node) {
return;
}
if (node.type === 'Identifier') {
const reference = findReference(node.name);
if (reference && reference.init) {
if (reference?.init) {
return findRootReference(reference.init);

@@ -85,2 +89,6 @@ }

const isRegExp = lookup => {
if (!lookup) {
return false;
}
if (lookup.regex) {

@@ -92,3 +100,8 @@ return true;

const reference = findRootReference(lookup);
return reference.regex || reference.name === 'RegExp';
if (!reference) {
return false;
}
return reference.regex ?? reference.name === 'RegExp';
};

@@ -99,2 +112,6 @@

if (!firstArg) {
return;
}
const isFunctionCall = firstArg.type === 'CallExpression';

@@ -152,2 +169,7 @@ if (!isFunctionCall || !firstArg.callee.property) {

const matchee = secondArgumentIsRegex ? firstArg : secondArg;
if (!matchee) {
return;
}
const regex = secondArgumentIsRegex ? secondArg : firstArg;

@@ -188,3 +210,8 @@

ava.isInTestNode,
])(node => {
],
)(node => {
if (!node?.callee?.property) {
return;
}
const isAssertion = node.callee.type === 'MemberExpression'

@@ -213,2 +240,3 @@ && util.getNameOfRootNodeObject(node.callee) === 't';

docs: {
description: 'Prefer using `t.regex()` to test regular expressions.',
url: util.getDocsUrl(__filename),

@@ -215,0 +243,0 @@ },

@@ -11,3 +11,3 @@ 'use strict';

let titleRegExp;
if (context.options[0] && context.options[0].format) {
if (context.options[0]?.format) {
titleRegExp = new RegExp(context.options[0].format);

@@ -57,2 +57,3 @@ } else {

docs: {
description: 'Ensure test titles have a certain format.',
url: util.getDocsUrl(__filename),

@@ -59,0 +60,0 @@ },

@@ -33,2 +33,3 @@ 'use strict';

docs: {
description: 'Ensure tests have a title.',
url: util.getDocsUrl(__filename),

@@ -35,0 +36,0 @@ },

@@ -44,2 +44,3 @@ 'use strict';

docs: {
description: 'Ensure that `t.throwsAsync()` and `t.notThrowsAsync()` are awaited.',
url: util.getDocsUrl(__filename),

@@ -46,0 +47,0 @@ },

@@ -128,3 +128,3 @@ 'use strict';

message: 'Too many chained uses of `.skip`.',
fix: fixer => {
fix(fixer) {
const chain = ['t', ...members.map(member => member.name).filter(name => name !== 'skip'), 'skip'];

@@ -140,3 +140,3 @@ return fixer.replaceText(node, chain.join('.'));

message: '`.skip` modifier should be the last in chain.',
fix: fixer => {
fix(fixer) {
const chain = ['t', ...members.map(member => member.name).filter(name => name !== 'skip'), 'skip'];

@@ -156,2 +156,3 @@ return fixer.replaceText(node, chain.join('.'));

docs: {
description: 'Disallow the incorrect use of `t`.',
url: util.getDocsUrl(__filename),

@@ -158,0 +159,0 @@ },

@@ -23,3 +23,3 @@ 'use strict';

const execProperty = implementationArg.properties.find(p => p.key.name === 'exec');
implementationArg = execProperty && execProperty.value;
implementationArg = execProperty?.value;
}

@@ -46,2 +46,3 @@

docs: {
description: 'Ensure test functions use `t` as their parameter.',
url: util.getDocsUrl(__filename),

@@ -48,0 +49,0 @@ },

@@ -34,3 +34,3 @@ 'use strict';

return {
'ImportDeclaration[importKind!="type"]': node => {
'ImportDeclaration[importKind!="type"]'(node) {
if (node.source.value === 'ava') {

@@ -43,3 +43,3 @@ const {name} = node.specifiers[0].local;

},
VariableDeclarator: node => {
VariableDeclarator(node) {
if (node.init && isDeepStrictEqual(espurify(node.init), avaVariableDeclaratorInitAst)) {

@@ -60,2 +60,3 @@ const {name} = node.id;

docs: {
description: 'Ensure that AVA is imported with `test` as the variable name.',
url: util.getDocsUrl(__filename),

@@ -62,0 +63,0 @@ },

@@ -93,2 +93,3 @@ 'use strict';

docs: {
description: 'Ensure that `t.true()`/`t.false()` are used instead of `t.truthy()`/`t.falsy()`.',
url: util.getDocsUrl(__filename),

@@ -95,0 +96,0 @@ },

@@ -87,5 +87,4 @@ 'use strict';

const getDocsUrl = (filename, commitHash) => {
const getDocsUrl = (filename, commitHash = `v${pkg.version}`) => {
const ruleName = path.basename(filename, '.js');
commitHash = commitHash || `v${pkg.version}`;
return `${repoUrl}/blob/${commitHash}/docs/rules/${ruleName}.md`;

@@ -92,0 +91,0 @@ };

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc