Socket
Socket
Sign inDemoInstall

eslint-plugin-functional

Package Overview
Dependencies
162
Maintainers
1
Versions
108
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.4.0 to 0.5.0

24

CHANGELOG.md

@@ -8,4 +8,26 @@ # Changelog

## [Unreleased](https://github.com/jonaskello/eslint-plugin-functional/compare/v0.3.0...HEAD)
## [Unreleased](https://github.com/jonaskello/eslint-plugin-functional/compare/v0.5.0...HEAD)
## [v0.5.0](https://github.com/jonaskello/eslint-plugin-functional/compare/v0.4.0...v0.5.0)
### Merged
- Refactor out the checkNode function for createRule. [`#48`](https://github.com/jonaskello/eslint-plugin-functional/pull/48)
- Text matching of MemberExpression nodes now includes the property name [`#47`](https://github.com/jonaskello/eslint-plugin-functional/pull/47)
- Test configs [`#43`](https://github.com/jonaskello/eslint-plugin-functional/pull/43)
- feat(no-mixed-type): no-mixed-interface -> no-mixed-type [`#42`](https://github.com/jonaskello/eslint-plugin-functional/pull/42)
- feat(configs): Create additional configs for each category of rules. [`#40`](https://github.com/jonaskello/eslint-plugin-functional/pull/40)
- feat(functional-parameters): Add option to allow iifes [`#39`](https://github.com/jonaskello/eslint-plugin-functional/pull/39)
- new rule: prefer-type [`#38`](https://github.com/jonaskello/eslint-plugin-functional/pull/38)
### Fixed
- feat(functional-parameters): Add option to allow iifes [`#37`](https://github.com/jonaskello/eslint-plugin-functional/issues/37)
## [v0.4.0](https://github.com/jonaskello/eslint-plugin-functional/compare/v0.3.0...v0.4.0)
### Changed
- Renamed to pacakge from `eslint-plugin-ts-immutable` to `eslint-plugin-functional`.
## [v0.3.0](https://github.com/jonaskello/eslint-plugin-functional/compare/v0.2.1...v0.3.0)

@@ -12,0 +34,0 @@

927

lib/index.js

@@ -5,12 +5,14 @@ 'use strict';

var deepmerge = require('deepmerge');
var deepMerge = require('deepmerge');
var deepMerge__default = _interopDefault(deepMerge);
require('array.prototype.flatmap/auto.js');
var escapeRegExp = _interopDefault(require('escape-string-regexp'));
var typescriptEstree = require('@typescript-eslint/typescript-estree');
var tslib_1 = require('tslib');
var experimentalUtils = require('@typescript-eslint/experimental-utils');
var astNodeTypes = require('@typescript-eslint/typescript-estree/dist/ts-estree/ast-node-types');
var tslib_1 = require('tslib');
var config = {
rules: {
"functional/functional-parameters": "error",
"functional/immutable-data": "error",

@@ -33,3 +35,5 @@ "functional/no-class": "error",

"functional/no-mixed-interface": "error",
"functional/prefer-readonly-types": "error"
"functional/prefer-readonly-type": "error",
"functional/prefer-type-literal": "error",
"functional/no-return-void": "error"
}

@@ -63,58 +67,79 @@ }

var config$2 = deepmerge.all([
config$1,
{
rules: {
"functional/no-let": "error",
"functional/immutable-data": "error"
},
overrides: [
{
files: ["*.ts", "*.tsx"],
rules: {
"functional/no-method-signature": "warn",
"functional/prefer-readonly-types": "error"
}
}
]
var config$2 = deepMerge__default(config$1, {
rules: {
"functional/functional-parameters": "error"
}
]);
});
var config$3 = deepmerge.all([
config$2,
{
rules: {
"functional/no-this": "error",
"functional/no-class": "error",
"functional/no-loop-statement": "error",
"functional/no-conditional-statement": [
"error",
{ allowReturningBranches: true }
],
"functional/no-throw": "error",
"functional/no-return-void": "error",
"functional/functional-parameters": "error"
},
overrides: [
{
files: ["*.ts", "*.tsx"],
rules: {
"functional/no-mixed-interface": "error"
}
var config$3 = deepMerge__default(config$1, {
rules: {
"functional/no-let": "error",
"functional/immutable-data": "error"
},
overrides: [
{
files: ["*.ts", "*.tsx"],
rules: {
"functional/no-method-signature": "warn",
"functional/prefer-readonly-type": "error"
}
]
}
]
});
var config$4 = deepMerge__default(config$1, {
rules: {
"functional/no-throw": "error",
"functional/no-try": "error"
}
]);
});
var config$4 = deepmerge.all([
var config$5 = deepMerge__default(config$1, {
rules: {
"functional/no-this": "error",
"functional/no-class": "error"
},
overrides: [
{
files: ["*.ts", "*.tsx"],
rules: {
"functional/no-mixed-type": "error",
"functional/prefer-type-literal": "error"
}
}
]
});
var config$6 = deepMerge__default(config$1, {
rules: {
"functional/no-expression-statement": "error",
"functional/no-conditional-statement": "error",
"functional/no-loop-statement": "error"
},
overrides: [
{
files: ["*.ts", "*.tsx"],
rules: {
"functional/no-return-void": "error"
}
}
]
});
var config$7 = deepMerge.all([
config$2,
config$3,
{
rules: {
"functional/no-conditional-statement": "error",
"functional/no-expression-statement": "error",
"functional/no-try": "error"
}
}
config$4,
config$5,
config$6
]);
var config$8 = deepMerge__default(config$7, {
rules: {
"functional/no-conditional-statement": "off",
"functional/no-expression-statement": "off",
"functional/no-try": "off"
}
});
// Conditionally loaded TypeScript but only if it is avaliable.

@@ -160,3 +185,15 @@ var ts = (function () {

}
function isFunctionDeclaration(node) {
return node.type === typescriptEstree.AST_NODE_TYPES.FunctionDeclaration;
}
/**
* Is the given node a function expression node?
*
* It doesn't matter what type of function expression.
*/
function isFunctionExpressionLike(node) {
return (node.type === typescriptEstree.AST_NODE_TYPES.FunctionExpression ||
node.type === typescriptEstree.AST_NODE_TYPES.ArrowFunctionExpression);
}
/**
* Is the given node a function node?

@@ -167,5 +204,3 @@ *

function isFunctionLike(node) {
return (node.type === typescriptEstree.AST_NODE_TYPES.FunctionDeclaration ||
node.type === typescriptEstree.AST_NODE_TYPES.FunctionExpression ||
node.type === typescriptEstree.AST_NODE_TYPES.ArrowFunctionExpression);
return isFunctionDeclaration(node) || isFunctionExpressionLike(node);
}

@@ -220,2 +255,5 @@ function isIdentifier(node) {

}
function isTSTypeLiteral(node) {
return node.type === typescriptEstree.AST_NODE_TYPES.TSTypeLiteral;
}
function isTSTypeOperator(node) {

@@ -336,2 +374,11 @@ return node.type === typescriptEstree.AST_NODE_TYPES.TSTypeOperator;

}
/**
* Is the given function an IIFE?
*/
function isIIFE(node) {
return (isFunctionExpressionLike(node) &&
node.parent !== undefined &&
isCallExpression(node.parent) &&
node.parent.callee === node);
}

@@ -400,36 +447,28 @@ // Polyfill.

/**
* Recursive callback of `getNodeText`.
*
* This function not be called from anywhere else.
* Get the text of the given node.
*/
function _getNodeText(node, context) {
function getNodeText(node, context) {
return isIdentifier(node)
? node.name
: isMemberExpression(node)
? _getNodeText(node.object, context) + "." + _getNodeText(node.property, context)
: context.getSourceCode().getText(node);
: isAssignmentExpression(node)
? getNodeText(node.left, context)
: isCallExpression(node)
? getNodeText(node.callee, context)
: isMemberExpression(node)
? getNodeText(node.object, context) + "." + getNodeText(node.property, context)
: isVariableDeclarator(node)
? getNodeText(node.id, context)
: isTSTypeAliasDeclaration(node)
? getNodeText(node.id, context)
: isTSPropertySignature(node)
? getNodeText(node.key, context)
: context.getSourceCode().getText(node);
}
/**
* Get the text of the given node.
*/
function getNodeText(node, context) {
return isAssignmentExpression(node)
? getNodeText(node.left, context)
: isCallExpression(node)
? getNodeText(node.callee, context)
: isMemberExpression(node)
? _getNodeText(node.object, context)
: isVariableDeclarator(node) || isTSTypeAliasDeclaration(node)
? _getNodeText(node.id, context)
: isTSPropertySignature(node)
? _getNodeText(node.key, context)
: _getNodeText(node, context);
}
/**
* Get all the important bits of texts from the given node.
*/
function getNodeTexts(node, context) {
return (isVariableDeclaration(node)
return isVariableDeclaration(node)
? node.declarations.flatMap(function (declarator) { return getNodeText(declarator, context); })
: [getNodeText(node, context)]).filter(function (name) { return name !== undefined; });
: [getNodeText(node, context)];
}

@@ -497,7 +536,7 @@ /**

// Ignore if in a function and ignoreLocal is set.
(Boolean(options.ignoreLocal) && inFunction(node)) ||
(options.ignoreLocal === true && inFunction(node)) ||
// Ignore if in a class and ignoreClass is set.
(Boolean(options.ignoreClass) && inClass(node)) ||
(options.ignoreClass === true && inClass(node)) ||
// Ignore if in an interface and ignoreInterface is set.
(Boolean(options.ignoreInterface) && inInterface(node)) ||
(options.ignoreInterface === true && inInterface(node)) ||
(function (texts) {

@@ -519,21 +558,4 @@ return texts.length > 0

const version = "0.3.0";
const version = "0.4.0";
/**
* Create a rule.
*/
function createRule(name, meta, defaultOptions, create) {
return experimentalUtils.ESLintUtils.RuleCreator(function (name) {
return "https://github.com/jonaskello/eslint-plugin-functional/blob/v" + version + "/docs/rules/" + name + ".md";
})({
name: name,
meta: meta,
defaultOptions: [defaultOptions],
create: function (c, _a) {
var o = _a[0];
return create(c, o);
}
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
});
}
// This function can't be functional as it needs to interact with 3rd-party

@@ -558,2 +580,27 @@ // libraries that aren't functional.

/**
* Create a rule.
*/
function createRule(name, meta, defaultOptions, ruleFunctionsMap) {
return experimentalUtils.ESLintUtils.RuleCreator(function (name) {
return "https://github.com/jonaskello/eslint-plugin-functional/blob/v" + version + "/docs/rules/" + name + ".md";
})({
name: name,
meta: meta,
defaultOptions: [defaultOptions],
create: function (context, _a) {
var options = _a[0];
return Object.entries(ruleFunctionsMap)
.map(function (_a) {
var _b;
var nodeSelector = _a[0], ruleFunction = _a[1];
return (_b = {},
_b[nodeSelector] = checkNode(ruleFunction, context, options),
_b);
})
.reduce(function (carry, object) { return (tslib_1.__assign({}, carry, object)); }, {});
}
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
});
}
/**
* Get the type of the the given node.

@@ -576,3 +623,3 @@ */

var schema = [
deepmerge.all([
deepMerge.all([
ignorePatternOptionSchema,

@@ -597,2 +644,15 @@ {

enum: ["atLeastOne", "exactlyOne"]
},
{
type: "object",
properties: {
count: {
type: "string",
enum: ["atLeastOne", "exactlyOne"]
},
allowIIFE: {
type: "boolean"
}
},
additionalProperties: false
}

@@ -610,3 +670,6 @@ ]

allowArgumentsKeyword: false,
enforceParameterCount: "atLeastOne"
enforceParameterCount: {
count: "atLeastOne",
allowIIFE: false
}
};

@@ -650,4 +713,14 @@ // The possible error messages.

function getParamCountViolations(enforceParameterCount, node) {
return enforceParameterCount === "atLeastOne" && node.params.length < 1
? [
if (enforceParameterCount === false ||
(node.params.length === 0 &&
typeof enforceParameterCount === "object" &&
enforceParameterCount.allowIIFE &&
isIIFE(node))) {
return [];
}
else if (node.params.length === 0 &&
(enforceParameterCount === "atLeastOne" ||
(typeof enforceParameterCount === "object" &&
enforceParameterCount.count === "atLeastOne"))) {
return [
{

@@ -657,11 +730,18 @@ node: node,

}
]
: enforceParameterCount === "exactlyOne" && node.params.length !== 1
? [
{
node: node,
messageId: "paramCountExactlyOne"
}
]
: [];
];
}
else if (node.params.length !== 1 &&
(enforceParameterCount === "exactlyOne" ||
(typeof enforceParameterCount === "object" &&
enforceParameterCount.count === "exactlyOne"))) {
return [
{
node: node,
messageId: "paramCountExactlyOne"
}
];
}
else {
return [];
}
}

@@ -697,11 +777,7 @@ /**

// Create the rule.
var rule = createRule(name, meta, defaultOptions, function (context, options) {
var _checkFunction = checkNode(checkFunction, context, options);
var _checkIdentifier = checkNode(checkIdentifier, context, options);
return {
FunctionDeclaration: _checkFunction,
FunctionExpression: _checkFunction,
ArrowFunctionExpression: _checkFunction,
Identifier: _checkIdentifier
};
var rule = createRule(name, meta, defaultOptions, {
FunctionDeclaration: checkFunction,
FunctionExpression: checkFunction,
ArrowFunctionExpression: checkFunction,
Identifier: checkIdentifier
});

@@ -721,3 +797,3 @@

var schema$1 = [
deepmerge.all([
deepMerge.all([
ignorePatternOptionSchema,

@@ -883,5 +959,5 @@ ignoreAccessorPatternOptionSchema,

var assumeTypesForArrays = options.assumeTypes === true ||
(options.assumeTypes !== false && Boolean(options.assumeTypes.forArrays));
(options.assumeTypes !== false && options.assumeTypes.forArrays === true);
var assumeTypesForObjects = options.assumeTypes === true ||
(options.assumeTypes !== false && Boolean(options.assumeTypes.forObjects));
(options.assumeTypes !== false && options.assumeTypes.forObjects === true);
return {

@@ -917,15 +993,7 @@ context: context,

// Create the rule.
var rule$1 = createRule(name$1, meta$1, defaultOptions$1, function (context, options) {
var _checkAssignmentExpression = checkNode(checkAssignmentExpression, context, options);
var _checkUnaryExpression = checkNode(checkUnaryExpression, context, options);
var _checkUpdateExpression = checkNode(checkUpdateExpression, context, options);
// This functionality is only avaliable if the parser services are
// avaliable.
var _checkCallExpression = checkNode(checkCallExpression, context, options);
return {
AssignmentExpression: _checkAssignmentExpression,
UnaryExpression: _checkUnaryExpression,
UpdateExpression: _checkUpdateExpression,
CallExpression: _checkCallExpression
};
var rule$1 = createRule(name$1, meta$1, defaultOptions$1, {
AssignmentExpression: checkAssignmentExpression,
UnaryExpression: checkUnaryExpression,
UpdateExpression: checkUpdateExpression,
CallExpression: checkCallExpression
});

@@ -962,12 +1030,6 @@

// Create the rule.
var rule$2 = createRule(name$2, meta$2, defaultOptions$2, function (context, options) {
var _checkClass = checkNode(checkClass, context, options);
return {
ClassDeclaration: _checkClass,
ClassExpression: _checkClass
};
});
var rule$2 = createRule(name$2, meta$2, defaultOptions$2, { ClassDeclaration: checkClass, ClassExpression: checkClass });
// The name of this rule.
var name$3 = "no-return-void";
var name$3 = "no-conditional-statement";
// The schema for the rule options.

@@ -978,66 +1040,2 @@ var schema$3 = [

properties: {
allowNull: {
type: "boolean"
},
allowUndefined: {
type: "boolean"
}
},
additionalProperties: false
}
];
// The default options for the rule.
var defaultOptions$3 = {
allowNull: true,
allowUndefined: true
};
// The possible error messages.
var errorMessages$3 = {
generic: "Function must return a value."
};
// The meta data for this rule.
var meta$3 = {
type: "suggestion",
docs: {
description: "Disallow functions that don't return anything.",
category: "Best Practices",
recommended: false
},
messages: errorMessages$3,
schema: schema$3
};
/**
* Check if the given function node violates this rule.
*/
function checkFunction$1(node, context, options) {
return {
context: context,
descriptors: node.returnType !== undefined &&
(isTSVoidKeyword(node.returnType.typeAnnotation) ||
(!options.allowNull &&
isTSNullKeyword(node.returnType.typeAnnotation)) ||
(!options.allowUndefined &&
isTSUndefinedKeyword(node.returnType.typeAnnotation)))
? [{ node: node.returnType, messageId: "generic" }]
: []
};
}
// Create the rule.
var rule$3 = createRule(name$3, meta$3, defaultOptions$3, function (context, options) {
var _checkFunction = checkNode(checkFunction$1, context, options);
return {
FunctionDeclaration: _checkFunction,
FunctionExpression: _checkFunction,
ArrowFunctionExpression: _checkFunction,
TSFunctionType: _checkFunction
};
});
// The name of this rule.
var name$4 = "no-conditional-statement";
// The schema for the rule options.
var schema$4 = [
{
type: "object",
properties: {
allowReturningBranches: {

@@ -1059,5 +1057,5 @@ oneOf: [

// The default options for the rule.
var defaultOptions$4 = { allowReturningBranches: false };
var defaultOptions$3 = { allowReturningBranches: false };
// The possible error messages.
var errorMessages$4 = {
var errorMessages$3 = {
incompleteBranch: "Incomplete branch, every branch in a conditional statement must contain a return statement.",

@@ -1070,3 +1068,3 @@ incompleteIf: "Incomplete if, it must have an else statement and every branch must contain a return statement.",

// The meta data for this rule.
var meta$4 = {
var meta$3 = {
type: "suggestion",

@@ -1078,4 +1076,4 @@ docs: {

},
messages: errorMessages$4,
schema: schema$4
messages: errorMessages$3,
schema: schema$3
};

@@ -1164,23 +1162,19 @@ /**

// Create the rule.
var rule$4 = createRule(name$4, meta$4, defaultOptions$4, function (context, options) {
var _checkIfStatement = checkNode(checkIfStatement, context, options);
var _checkSwitchStatement = checkNode(checkSwitchStatement, context, options);
return {
IfStatement: _checkIfStatement,
SwitchStatement: _checkSwitchStatement
};
var rule$3 = createRule(name$3, meta$3, defaultOptions$3, {
IfStatement: checkIfStatement,
SwitchStatement: checkSwitchStatement
});
// The name of this rule.
var name$5 = "no-expression-statement";
var name$4 = "no-expression-statement";
// The schema for the rule options.
var schema$5 = [ignorePatternOptionSchema];
var schema$4 = [ignorePatternOptionSchema];
// The default options for the rule.
var defaultOptions$5 = {};
var defaultOptions$4 = {};
// The possible error messages.
var errorMessages$5 = {
var errorMessages$4 = {
generic: "Using expressions to cause side-effects not allowed."
};
// The meta data for this rule.
var meta$5 = {
var meta$4 = {
type: "suggestion",

@@ -1192,4 +1186,4 @@ docs: {

},
messages: errorMessages$5,
schema: schema$5
messages: errorMessages$4,
schema: schema$4
};

@@ -1204,25 +1198,22 @@ /**

// Create the rule.
var rule$5 = createRule(name$5, meta$5, defaultOptions$5, function (context, options) {
var _checkExpressionStatement = checkNode(checkExpressionStatement, context, options);
return {
ExpressionStatement: _checkExpressionStatement
};
var rule$4 = createRule(name$4, meta$4, defaultOptions$4, {
ExpressionStatement: checkExpressionStatement
});
// The name of this rule.
var name$6 = "no-let";
var name$5 = "no-let";
// The schema for the rule options.
var schema$6 = [
deepmerge.all([ignoreLocalOptionSchema, ignorePatternOptionSchema])
var schema$5 = [
deepMerge.all([ignoreLocalOptionSchema, ignorePatternOptionSchema])
];
// The default options for the rule.
var defaultOptions$6 = {
var defaultOptions$5 = {
ignoreLocal: false
};
// The possible error messages.
var errorMessages$6 = {
var errorMessages$5 = {
generic: "Unexpected let, use const instead."
};
// The meta data for this rule.
var meta$6 = {
var meta$5 = {
type: "suggestion",

@@ -1234,5 +1225,5 @@ docs: {

},
messages: errorMessages$6,
messages: errorMessages$5,
fixable: "code",
schema: schema$6
schema: schema$5
};

@@ -1249,21 +1240,18 @@ /**

// Create the rule.
var rule$6 = createRule(name$6, meta$6, defaultOptions$6, function (context, options) {
var _checkVariableDeclaration = checkNode(checkVariableDeclaration, context, options);
return {
VariableDeclaration: _checkVariableDeclaration
};
var rule$5 = createRule(name$5, meta$5, defaultOptions$5, {
VariableDeclaration: checkVariableDeclaration
});
// The name of this rule.
var name$7 = "no-loop-statement";
var name$6 = "no-loop-statement";
// The schema for the rule options.
var schema$7 = [];
var schema$6 = [];
// The default options for the rule.
var defaultOptions$7 = {};
var defaultOptions$6 = {};
// The possible error messages.
var errorMessages$7 = {
var errorMessages$6 = {
generic: "Unexpected loop, use map or reduce instead."
};
// The meta data for this rule.
var meta$7 = {
var meta$6 = {
type: "suggestion",

@@ -1275,4 +1263,4 @@ docs: {

},
messages: errorMessages$7,
schema: schema$7
messages: errorMessages$6,
schema: schema$6
};

@@ -1287,25 +1275,22 @@ /**

// Create the rule.
var rule$7 = createRule(name$7, meta$7, defaultOptions$7, function (context, options) {
var _checkLoop = checkNode(checkLoop, context, options);
return {
ForStatement: _checkLoop,
ForInStatement: _checkLoop,
ForOfStatement: _checkLoop,
WhileStatement: _checkLoop,
DoWhileStatement: _checkLoop
};
var rule$6 = createRule(name$6, meta$6, defaultOptions$6, {
ForStatement: checkLoop,
ForInStatement: checkLoop,
ForOfStatement: checkLoop,
WhileStatement: checkLoop,
DoWhileStatement: checkLoop
});
// The name of this rule.
var name$8 = "no-method-signature";
var name$7 = "no-method-signature";
// The schema for the rule options.
var schema$8 = [];
var schema$7 = [];
// The default options for the rule.
var defaultOptions$8 = {};
var defaultOptions$7 = {};
// The possible error messages.
var errorMessages$8 = {
var errorMessages$7 = {
generic: "Method signature is mutable, use property signature with readonly modifier instead."
};
// The meta data for this rule.
var meta$8 = {
var meta$7 = {
type: "suggestion",

@@ -1317,4 +1302,4 @@ docs: {

},
messages: errorMessages$8,
schema: schema$8
messages: errorMessages$7,
schema: schema$7
};

@@ -1329,84 +1314,114 @@ /**

// Create the rule.
var rule$8 = createRule(name$8, meta$8, defaultOptions$8, function (context, options) {
var _checkTSMethodSignature = checkNode(checkTSMethodSignature, context, options);
return {
TSMethodSignature: _checkTSMethodSignature
};
var rule$7 = createRule(name$7, meta$7, defaultOptions$7, {
TSMethodSignature: checkTSMethodSignature
});
// The name of this rule.
var name$9 = "no-mixed-interface";
var name$8 = "no-mixed-type";
// The schema for the rule options.
var schema$9 = [];
var schema$8 = [
{
type: "object",
properties: {
checkInterfaces: {
type: "boolean"
},
checkTypeLiterals: {
type: "boolean"
}
},
additionalProperties: false
}
];
// The default options for the rule.
var defaultOptions$9 = {};
var defaultOptions$8 = {
checkInterfaces: true,
checkTypeLiterals: true
};
// The possible error messages.
var errorMessages$9 = {
generic: "Only the same kind of members allowed in interfaces."
var errorMessages$8 = {
generic: "Only the same kind of members allowed in types."
};
// The meta data for this rule.
var meta$9 = {
var meta$8 = {
type: "suggestion",
docs: {
description: "Restrict interfaces so that only members of the same kind of are allowed in them.",
description: "Restrict types so that only members of the same kind of are allowed in them.",
category: "Best Practices",
recommended: false
},
messages: errorMessages$9,
schema: schema$9
messages: errorMessages$8,
schema: schema$8
};
/**
* Get the violations for the given type elements.
*/
function getTypeElementViolations(typeElements) {
return typeElements.reduce(function (carry, member) {
var memberType = member.type;
var memberTypeAnnotation = isTSPropertySignature(member) && member.typeAnnotation !== undefined
? member.typeAnnotation.typeAnnotation.type
: undefined;
return {
prevMemberType: memberType,
prevMemberTypeAnnotation: memberTypeAnnotation,
violations:
// Not the first property in the interface.
carry.prevMemberType !== undefined &&
// And different property type to previous property.
(carry.prevMemberType !== memberType ||
// Or annotationed with a different type annotation.
(carry.prevMemberTypeAnnotation !== memberTypeAnnotation &&
// Where one of the properties is a annotationed as a function.
(carry.prevMemberTypeAnnotation ===
astNodeTypes.AST_NODE_TYPES.TSFunctionType ||
memberTypeAnnotation === astNodeTypes.AST_NODE_TYPES.TSFunctionType)))
? carry.violations.concat([{ node: member, messageId: "generic" }]) : carry.violations
};
}, {
prevMemberType: undefined,
prevMemberTypeAnnotation: undefined,
violations: []
}).violations;
}
/**
* Check if the given TSInterfaceDeclaration violates this rule.
*/
function checkTSInterfaceDeclaration(node, context) {
function checkTSInterfaceDeclaration(node, context, options) {
return {
context: context,
descriptors: node.body.body.reduce(function (carry, member) {
var memberType = member.type;
var memberTypeAnnotation = isTSPropertySignature(member) && member.typeAnnotation !== undefined
? member.typeAnnotation.typeAnnotation.type
: undefined;
return {
prevMemberType: memberType,
prevMemberTypeAnnotation: memberTypeAnnotation,
violations:
// Not the first property in the interface.
carry.prevMemberType !== undefined &&
// And different property type to previous property.
(carry.prevMemberType !== memberType ||
// Or annotationed with a different type annotation.
(carry.prevMemberTypeAnnotation !== memberTypeAnnotation &&
// Where one of the properties is a annotationed as a function.
(carry.prevMemberTypeAnnotation ===
astNodeTypes.AST_NODE_TYPES.TSFunctionType ||
memberTypeAnnotation === astNodeTypes.AST_NODE_TYPES.TSFunctionType)))
? carry.violations.concat([{ node: member, messageId: "generic" }]) : carry.violations
};
}, {
prevMemberType: undefined,
prevMemberTypeAnnotation: undefined,
violations: []
}).violations
descriptors: options.checkInterfaces
? getTypeElementViolations(node.body.body)
: []
};
}
// Create the rule.
var rule$9 = createRule(name$9, meta$9, defaultOptions$9, function (context, options) {
var _checkTSInterfaceDeclaration = checkNode(checkTSInterfaceDeclaration, context, options);
/**
* Check if the given TSTypeAliasDeclaration violates this rule.
*/
function checkTSTypeAliasDeclaration(node, context, options) {
return {
TSInterfaceDeclaration: _checkTSInterfaceDeclaration
context: context,
descriptors: options.checkTypeLiterals && isTSTypeLiteral(node.typeAnnotation)
? getTypeElementViolations(node.typeAnnotation.members)
: []
};
}
// Create the rule.
var rule$8 = createRule(name$8, meta$8, defaultOptions$8, {
TSInterfaceDeclaration: checkTSInterfaceDeclaration,
TSTypeAliasDeclaration: checkTSTypeAliasDeclaration
});
// The name of this rule.
var name$a = "no-reject";
var name$9 = "no-reject";
// The schema for the rule options.
var schema$a = [];
var schema$9 = [];
// The default options for the rule.
var defaultOptions$a = {};
var defaultOptions$9 = {};
// The possible error messages.
var errorMessages$a = {
var errorMessages$9 = {
generic: "Unexpected reject, return an error instead."
};
// The meta data for this rule.
var meta$a = {
var meta$9 = {
type: "suggestion",

@@ -1418,4 +1433,4 @@ docs: {

},
messages: errorMessages$a,
schema: schema$a
messages: errorMessages$9,
schema: schema$9
};

@@ -1438,7 +1453,65 @@ /**

// Create the rule.
var rule$a = createRule(name$a, meta$a, defaultOptions$a, function (context, options) {
var _checkCallExpression = checkNode(checkCallExpression$1, context, options);
var rule$9 = createRule(name$9, meta$9, defaultOptions$9, {
CallExpression: checkCallExpression$1
});
// The name of this rule.
var name$a = "no-return-void";
// The schema for the rule options.
var schema$a = [
{
type: "object",
properties: {
allowNull: {
type: "boolean"
},
allowUndefined: {
type: "boolean"
}
},
additionalProperties: false
}
];
// The default options for the rule.
var defaultOptions$a = {
allowNull: true,
allowUndefined: true
};
// The possible error messages.
var errorMessages$a = {
generic: "Function must return a value."
};
// The meta data for this rule.
var meta$a = {
type: "suggestion",
docs: {
description: "Disallow functions that don't return anything.",
category: "Best Practices",
recommended: false
},
messages: errorMessages$a,
schema: schema$a
};
/**
* Check if the given function node violates this rule.
*/
function checkFunction$1(node, context, options) {
return {
CallExpression: _checkCallExpression
context: context,
descriptors: node.returnType !== undefined &&
(isTSVoidKeyword(node.returnType.typeAnnotation) ||
(!options.allowNull &&
isTSNullKeyword(node.returnType.typeAnnotation)) ||
(!options.allowUndefined &&
isTSUndefinedKeyword(node.returnType.typeAnnotation)))
? [{ node: node.returnType, messageId: "generic" }]
: []
};
}
// Create the rule.
var rule$a = createRule(name$a, meta$a, defaultOptions$a, {
FunctionDeclaration: checkFunction$1,
FunctionExpression: checkFunction$1,
ArrowFunctionExpression: checkFunction$1,
TSFunctionType: checkFunction$1
});

@@ -1475,7 +1548,4 @@

// Create the rule.
var rule$b = createRule(name$b, meta$b, defaultOptions$b, function (context, options) {
var _checkThisExpression = checkNode(checkThisExpression, context, options);
return {
ThisExpression: _checkThisExpression
};
var rule$b = createRule(name$b, meta$b, defaultOptions$b, {
ThisExpression: checkThisExpression
});

@@ -1512,7 +1582,4 @@

// Create the rule.
var rule$c = createRule(name$c, meta$c, defaultOptions$c, function (context, options) {
var _checkThrowStatement = checkNode(checkThrowStatement, context, options);
return {
ThrowStatement: _checkThrowStatement
};
var rule$c = createRule(name$c, meta$c, defaultOptions$c, {
ThrowStatement: checkThrowStatement
});

@@ -1549,14 +1616,12 @@

// Create the rule.
var rule$d = createRule(name$d, meta$d, defaultOptions$d, function (context, options) {
var _checkTryStatement = checkNode(checkTryStatement, context, options);
return {
TryStatement: _checkTryStatement
};
var rule$d = createRule(name$d, meta$d, defaultOptions$d, {
TryStatement: checkTryStatement
});
// Polyfill.
// The name of this rule.
var name$e = "prefer-readonly-types";
var name$e = "prefer-readonly-type";
// The schema for the rule options.
var schema$e = [
deepmerge.all([
deepMerge.all([
ignoreLocalOptionSchema,

@@ -1682,54 +1747,123 @@ ignorePatternOptionSchema,

*/
function checkImplicitType(node, context) {
var declarators = isFunctionLike(node)
? node.params
.map(function (param) {
return isAssignmentPattern(param)
? /* eslint-disable-next-line @typescript-eslint/no-object-literal-type-assertion */
{ id: param.left, init: param.right, node: param }
: undefined;
})
.filter(function (param) { return param !== undefined; })
: node.declarations.map(function (declaration) {
/* eslint-disable-next-line @typescript-eslint/no-object-literal-type-assertion */
return ({
id: declaration.id,
init: declaration.init,
node: declaration
function checkImplicitType(node, context, options) {
if (options.checkImplicit) {
var declarators = isFunctionLike(node)
? node.params
.map(function (param) {
return isAssignmentPattern(param)
? /* eslint-disable-next-line @typescript-eslint/no-object-literal-type-assertion */
{
id: param.left,
init: param.right,
node: param
}
: undefined;
})
.filter(function (param) { return param !== undefined; })
: node.declarations.map(function (declaration) {
/* eslint-disable-next-line @typescript-eslint/no-object-literal-type-assertion */
return ({
id: declaration.id,
init: declaration.init,
node: declaration
});
});
});
return {
context: context,
descriptors: declarators.flatMap(function (declarator) {
return isIdentifier(declarator.id) &&
declarator.id.typeAnnotation === undefined &&
declarator.init !== null &&
isArrayType(getTypeOfNode(declarator.init, context))
? [
{
node: declarator.node,
messageId: "implicit",
fix: function (fixer) {
return fixer.insertTextAfter(declarator.id, ": readonly unknown[]");
}
}
]
: [];
})
};
}
else {
return {
context: context,
descriptors: []
};
}
}
// Create the rule.
var rule$e = createRule(name$e, meta$e, defaultOptions$e, {
TSArrayType: checkArrayOrTupleType,
TSTupleType: checkArrayOrTupleType,
TSTypeReference: checkTypeReference,
ClassProperty: checkProperty,
TSIndexSignature: checkProperty,
TSParameterProperty: checkProperty,
TSPropertySignature: checkProperty,
VariableDeclaration: checkImplicitType,
FunctionDeclaration: checkImplicitType,
FunctionExpression: checkImplicitType,
ArrowFunctionExpression: checkImplicitType
});
// The name of this rule.
var name$f = "prefer-type-literal";
// The schema for the rule options.
var schema$f = [
deepMerge.all([ignoreLocalOptionSchema, ignorePatternOptionSchema])
];
// The default options for the rule.
var defaultOptions$f = {};
// The possible error messages.
var errorMessages$f = {
generic: "Unexpected interface, use a type literal instead."
};
// The meta data for this rule.
var meta$f = {
type: "suggestion",
docs: {
description: "Prefer Type Literals over Interfaces.",
category: "Best Practices",
recommended: false
},
messages: errorMessages$f,
fixable: "code",
schema: schema$f
};
/**
* Check if the given interface node violates this rule.
*/
function checkInterface(node, context) {
return {
context: context,
descriptors: declarators.flatMap(function (declarator) {
return isIdentifier(declarator.id) &&
declarator.id.typeAnnotation === undefined &&
declarator.init !== null &&
isArrayType(getTypeOfNode(declarator.init, context))
? [
{
node: declarator.node,
messageId: "implicit",
fix: function (fixer) {
return fixer.insertTextAfter(declarator.id, ": readonly unknown[]");
}
}
]
: [];
})
descriptors: [
{
node: node,
messageId: "generic",
fix: node.extends === undefined ||
node.extends.every(function (type) { return isIdentifier(type.expression); })
? function (fixer) { return [
fixer.replaceTextRange([node.range[0], node.range[0] + "interface".length], "type"),
fixer.insertTextBefore(node.body, "= ")
].concat((node.extends === undefined
? []
: [
fixer.replaceTextRange([node.id.range[1], node.body.range[0]], " ")
].concat(node.extends.map(function (type) {
return fixer.insertTextBefore(node.body, type.expression.name + " & ");
}))), [
fixer.insertTextAfter(node, ";")
]); }
: undefined
}
]
};
}
// Create the rule.
var rule$e = createRule(name$e, meta$e, defaultOptions$e, function (context, options) {
var _checkArrayOrTupleType = checkNode(checkArrayOrTupleType, context, options);
var _checkTypeReference = checkNode(checkTypeReference, context, options);
var _checkProperty = checkNode(checkProperty, context, options);
var _checkImplicitType = checkNode(checkImplicitType, context, options);
return tslib_1.__assign({ TSArrayType: _checkArrayOrTupleType, TSTupleType: _checkArrayOrTupleType, TSTypeReference: _checkTypeReference, ClassProperty: _checkProperty, TSIndexSignature: _checkProperty, TSParameterProperty: _checkProperty, TSPropertySignature: _checkProperty }, (options.checkImplicit
? {
VariableDeclaration: _checkImplicitType,
FunctionDeclaration: _checkImplicitType,
FunctionExpression: _checkImplicitType,
ArrowFunctionExpression: _checkImplicitType
}
: {}));
var rule$f = createRule(name$f, meta$f, defaultOptions$f, {
TSInterfaceDeclaration: checkInterface
});

@@ -1745,2 +1879,3 @@

_a[name$2] = rule$2,
_a[name$3] = rule$3,
_a[name$4] = rule$4,

@@ -1753,3 +1888,2 @@ _a[name$5] = rule$5,

_a[name$a] = rule$a,
_a[name$3] = rule$3,
_a[name$b] = rule$b,

@@ -1759,14 +1893,19 @@ _a[name$c] = rule$c,

_a[name$e] = rule$e,
_a[name$f] = rule$f,
_a);
var config$5 = {
var config$9 = {
rules: rules,
configs: {
all: config,
recommended: config$2,
functional: config$4,
"functional-lite": config$3
currying: config$2,
immutable: config$3,
lite: config$8,
"no-exceptions": config$4,
"no-object-orientation": config$5,
"no-statements": config$6,
recommended: config$7
}
};
module.exports = config$5;
module.exports = config$9;
{
"name": "eslint-plugin-functional",
"version": "0.4.0",
"version": "0.5.0",
"description": "ESLint rules to disable mutation and promote fp in TypeScript.",

@@ -5,0 +5,0 @@ "main": "lib/index.js",

@@ -78,9 +78,5 @@ # eslint-plugin-functional

The following rulesets are provided by this plugin.
[See bellow](#supported-rules) for what rules are including in each.
There are several rulesets provided by this plugin.
[See bellow](#supported-rules) for what they are and what rules are including in each.
- `recommended`
- `functional-lite`
- `functional`
You can enable one of these rulesets like so:

@@ -122,5 +118,4 @@

| :---------------: | -------------------------------------------------------------------------------------------------------------------------------------- |
| :see_no_evil: | Ruleset: Recommended<br><sub><sup>This ruleset is designed to enforce immutability in the code.</sup></sub> |
| :hear_no_evil: | Ruleset: Functional Lite<br><sub><sup>This ruleset is designed to enforce a somewhat functional programming code style.</sup></sub> |
| :speak_no_evil: | Ruleset: Functional<br><sub><sup>This ruleset is designed to enforce a functional programming code style.</sup></sub> |
| :hear_no_evil: | Ruleset: Lite<br><sub><sup>This ruleset is designed to enforce a somewhat functional programming code style.</sup></sub> |
| :speak_no_evil: | Ruleset: Recommended<br><sub><sup>This ruleset is designed to enforce a functional programming code style.</sup></sub> |
| :wrench: | Fixable<br><sub><sup>Problems found by this rule are potentially fixable with the `--fix` option.</sup></sub> |

@@ -130,42 +125,53 @@ | :thought_balloon: | Only Avaliable for TypeScript<br><sub><sup>The rule either requires Type Information or only works with TypeScript syntax.</sup></sub> |

### No mutability
### Immutability Rules
| Name | Description | <span title="Recommended">:see_no_evil:</span> | <span title="Functional Lite">:hear_no_evil:</span> | <span title="Functional">:speak_no_evil:</span> | :wrench: | :blue_heart: |
| ---------------------------------------------------------------- | -------------------------------------------------------------------------- | :--------------------------------------------: | :-------------------------------------------------: | :---------------------------------------------: | :------: | :---------------: |
| [`prefer-readonly-types`](./docs/rules/prefer-readonly-types.md) | Use readonly types and readonly modifiers where possible | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :wrench: | :thought_balloon: |
| [`no-let`](./docs/rules/no-let.md) | Disallow mutable variables | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | |
| [`immutable-data`](./docs/rules/immutable-data.md) | Disallow mutating objects and arrays | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :blue_heart: |
| [`no-method-signature`](./docs/rules/no-method-signature.md) | Enforce property signatures with readonly modifiers over method signatures | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :thought_balloon: |
:see_no_evil: = `immutable` Ruleset.
### No object-orientation
| Name | Description | <span title="Immutable">:see_no_evil:</span> | <span title="Lite">:hear_no_evil:</span> | <span title="Recommended">:speak_no_evil:</span> | :wrench: | :blue_heart: |
| -------------------------------------------------------------- | -------------------------------------------------------------------------- | :------------------------------------------: | :--------------------------------------: | :----------------------------------------------: | :------: | :---------------: |
| [`prefer-readonly-type`](./docs/rules/prefer-readonly-type.md) | Use readonly types and readonly modifiers where possible | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :wrench: | :thought_balloon: |
| [`no-let`](./docs/rules/no-let.md) | Disallow mutable variables | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | |
| [`immutable-data`](./docs/rules/immutable-data.md) | Disallow mutating objects and arrays | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :blue_heart: |
| [`no-method-signature`](./docs/rules/no-method-signature.md) | Enforce property signatures with readonly modifiers over method signatures | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :thought_balloon: |
| Name | Description | <span title="Recommended">:see_no_evil:</span> | <span title="Functional Lite">:hear_no_evil:</span> | <span title="Functional">:speak_no_evil:</span> | :wrench: | :blue_heart: |
| ---------------------------------------------------------- | ----------------------------------------------------------------------------- | :--------------------------------------------: | :-------------------------------------------------: | :---------------------------------------------: | :------: | :---------------: |
| [`no-this`](./docs/rules/no-this.md) | Disallow this access | | :heavy_check_mark: | :heavy_check_mark: | | |
| [`no-class`](./docs/rules/no-class.md) | Disallow classes | | :heavy_check_mark: | :heavy_check_mark: | | |
| [`no-mixed-interface`](./docs/rules/no-mixed-interface.md) | Restrict interfaces so that only members of the same kind are allowed in them | | :heavy_check_mark: | :heavy_check_mark: | | :thought_balloon: |
### No Object-Orientation Rules
### No statements
:see_no_evil: = `no-object-orientation` Ruleset.
| Name | Description | <span title="Recommended">:see_no_evil:</span> | <span title="Functional Lite">:hear_no_evil:</span> | <span title="Functional">:speak_no_evil:</span> | :wrench: | :blue_heart: |
| ---------------------------------------------------------------------- | ---------------------------------------------------------- | :--------------------------------------------: | :-------------------------------------------------: | :---------------------------------------------: | :------: | :---------------: |
| [`no-expression-statement`](./docs/rules/no-expression-statement.md) | Disallow expressions to cause side-effects | | | :heavy_check_mark: | | |
| [`no-conditional-statement`](./docs/rules/no-conditional-statement.md) | Disallow conditional statements (if and switch statements) | | | :heavy_check_mark: | | |
| [`no-loop-statement`](./docs/rules/no-loop-statement.md) | Disallow imperative loops | | :heavy_check_mark: | :heavy_check_mark: | | |
| [`no-return-void`](./docs/rules/no-return-void.md) | Disallow function that return nothing | | :heavy_check_mark: | :heavy_check_mark: | | :thought_balloon: |
| Name | Description | <span title="No Object-Orientation">:see_no_evil:</span> | <span title="Lite">:hear_no_evil:</span> | <span title="Recommended">:speak_no_evil:</span> | :wrench: | :blue_heart: |
| ------------------------------------------------------------ | ------------------------------------------------------------------------ | :------------------------------------------------------: | :--------------------------------------: | :----------------------------------------------: | :------: | :---------------: |
| [`no-this`](./docs/rules/no-this.md) | Disallow `this` access | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | |
| [`no-class`](./docs/rules/no-class.md) | Disallow classes | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | |
| [`no-mixed-type`](./docs/rules/no-mixed-type.md) | Restrict types so that only members of the same kind are allowed in them | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :thought_balloon: |
| [`prefer-type-literal`](./docs/rules/prefer-type-literal.md) | Use type literals over interfaces | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :thought_balloon: |
### No exceptions
### No Statements Rules
| Name | Description | <span title="Recommended">:see_no_evil:</span> | <span title="Functional Lite">:hear_no_evil:</span> | <span title="Functional">:speak_no_evil:</span> | :wrench: | :blue_heart: |
| ---------------------------------------- | ----------------------------------------------------- | :--------------------------------------------: | :-------------------------------------------------: | :---------------------------------------------: | :------: | :----------: |
| [`no-throw`](./docs/rules/no-throw.md) | Disallow throwing exceptions | | :heavy_check_mark: | :heavy_check_mark: | | |
| [`no-try`](./docs/rules/no-try.md) | Disallow try-catch[-finally] and try-finally patterns | | | :heavy_check_mark: | | |
| [`no-reject`](./docs/rules/no-reject.md) | Disallow rejecting Promises | | | | | |
:see_no_evil: = `no-statements` Ruleset.
### Currying
| Name | Description | <span title="No Statements">:see_no_evil:</span> | <span title="Lite">:hear_no_evil:</span> | <span title="Recommended">:speak_no_evil:</span> | :wrench: | :blue_heart: |
| ---------------------------------------------------------------------- | ---------------------------------------------------------- | :----------------------------------------------: | :--------------------------------------: | :----------------------------------------------: | :------: | :---------------: |
| [`no-expression-statement`](./docs/rules/no-expression-statement.md) | Disallow expressions to cause side-effects | :heavy_check_mark: | | :heavy_check_mark: | | |
| [`no-conditional-statement`](./docs/rules/no-conditional-statement.md) | Disallow conditional statements (if and switch statements) | :heavy_check_mark: | | :heavy_check_mark: | | |
| [`no-loop-statement`](./docs/rules/no-loop-statement.md) | Disallow imperative loops | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | |
| [`no-return-void`](./docs/rules/no-return-void.md) | Disallow function that return nothing | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :thought_balloon: |
| Name | Description | <span title="Recommended">:see_no_evil:</span> | <span title="Functional Lite">:hear_no_evil:</span> | <span title="Functional">:speak_no_evil:</span> | :wrench: | :blue_heart: |
| ---------------------------------------------------------------- | ---------------------------------------- | :--------------------------------------------: | :-------------------------------------------------: | :---------------------------------------------: | :------: | :----------: |
| [`functional-parameters`](./docs/rules/functional-parameters.md) | Functions must have functional parameter | | :heavy_check_mark: | :heavy_check_mark: | | |
### No Exceptions Rules
:see_no_evil: = `no-exceptions` Ruleset.
| Name | Description | <span title="No Exceptions">:see_no_evil:</span> | <span title="Lite">:hear_no_evil:</span> | <span title="Recommended">:speak_no_evil:</span> | :wrench: | :blue_heart: |
| ---------------------------------------- | ----------------------------------------------------- | :----------------------------------------------: | :--------------------------------------: | :----------------------------------------------: | :------: | :----------: |
| [`no-throw`](./docs/rules/no-throw.md) | Disallow throwing exceptions | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | |
| [`no-try`](./docs/rules/no-try.md) | Disallow try-catch[-finally] and try-finally patterns | :heavy_check_mark: | | :heavy_check_mark: | | |
| [`no-reject`](./docs/rules/no-reject.md) | Disallow rejecting Promises | | | | | |
### Currying Rules
:see_no_evil: = `currying` Ruleset.
| Name | Description | <span title="Currying">:see_no_evil:</span> | <span title="Lite">:hear_no_evil:</span> | <span title="Recommended">:speak_no_evil:</span> | :wrench: | :blue_heart: |
| ---------------------------------------------------------------- | ----------------------------------------- | :-----------------------------------------: | :--------------------------------------: | :----------------------------------------------: | :------: | :----------: |
| [`functional-parameters`](./docs/rules/functional-parameters.md) | Functions must have functional parameters | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | |
## Recommended standard rules

@@ -172,0 +178,0 @@

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc