eslint-plugin-functional
Advanced tools
Comparing version 3.1.0 to 3.2.0
@@ -10,4 +10,19 @@ # Changelog | ||
## [v3.1.0](https://github.com/jonaskello/eslint-plugin-functional/compare/v3.0.2...v3.1.0) - 2020-10-07 | ||
## [v3.2.0](https://github.com/jonaskello/eslint-plugin-functional/compare/v3.2.0...v3.2.0) | ||
## [v3.2.0](https://github.com/jonaskello/eslint-plugin-functional/compare/v3.1.0...v3.2.0) - 2020-12-31 | ||
### Merged | ||
- build(deps-dev): bump @rollup/plugin-typescript from 8.0.0 to 8.1.0 [`#164`](https://github.com/jonaskello/eslint-plugin-functional/pull/164) | ||
- build(deps): bump @typescript-eslint/experimental-utils from 4.9.1 to 4.11.0 [`#162`](https://github.com/jonaskello/eslint-plugin-functional/pull/162) | ||
- build(deps-dev): bump eslint from 7.15.0 to 7.16.0 [`#163`](https://github.com/jonaskello/eslint-plugin-functional/pull/163) | ||
- build(deps-dev): bump @typescript-eslint/parser from 4.9.1 to 4.11.0 [`#165`](https://github.com/jonaskello/eslint-plugin-functional/pull/165) | ||
- build(deps-dev): bump rollup from 2.34.2 to 2.35.1 [`#166`](https://github.com/jonaskello/eslint-plugin-functional/pull/166) | ||
- Automerge dependabot updates [`#167`](https://github.com/jonaskello/eslint-plugin-functional/pull/167) | ||
- chore: configure github settings [`#161`](https://github.com/jonaskello/eslint-plugin-functional/pull/161) | ||
- refactor: general tidy up of code and configs [`#149`](https://github.com/jonaskello/eslint-plugin-functional/pull/149) | ||
## [v3.1.0](https://github.com/jonaskello/eslint-plugin-functional/compare/v3.0.2...v3.1.0) - 2020-10-08 | ||
### Commits | ||
@@ -14,0 +29,0 @@ |
589
lib/index.js
'use strict'; | ||
var deepMerge = require('deepmerge'); | ||
require('array.prototype.flatmap/auto.js'); | ||
var escapeRegExp = require('escape-string-regexp'); | ||
var experimentalUtils = require('@typescript-eslint/experimental-utils'); | ||
require('object.fromentries/auto.js'); | ||
@@ -27,2 +25,3 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } | ||
"functional/no-try-statement": "error", | ||
"functional/prefer-tacit": ["warn", { assumeTypes: { allowFixer: false } }], | ||
}, | ||
@@ -36,2 +35,3 @@ overrides: [ | ||
"functional/prefer-readonly-type": "error", | ||
"functional/prefer-tacit": ["error", { assumeTypes: false }], | ||
"functional/prefer-type-literal": "error", | ||
@@ -150,3 +150,16 @@ "functional/no-return-void": "error", | ||
// Conditionally loaded TypeScript but only if it is avaliable. | ||
const config$9 = { | ||
rules: { | ||
"functional/prefer-tacit": ["warn", { assumeTypes: { allowFixer: false } }], | ||
}, | ||
overrides: [ | ||
{ | ||
files: ["*.ts", "*.tsx"], | ||
rules: { | ||
"functional/prefer-tacit": ["error", { assumeTypes: false }], | ||
}, | ||
}, | ||
], | ||
}; | ||
var ts = (() => { | ||
@@ -161,8 +174,2 @@ try { | ||
/** | ||
* @file Functions that typeguard the given node/type. | ||
*/ | ||
/* | ||
* Node type guards. | ||
*/ | ||
function isArrayExpression(node) { | ||
@@ -183,7 +190,2 @@ return node.type === experimentalUtils.AST_NODE_TYPES.ArrayExpression; | ||
} | ||
/** | ||
* Is the given node a class node? | ||
* | ||
* It doesn't matter what type of class. | ||
*/ | ||
function isClassLike(node) { | ||
@@ -199,7 +201,2 @@ return (node.type === experimentalUtils.AST_NODE_TYPES.ClassDeclaration || | ||
} | ||
/** | ||
* Is the given node a function expression node? | ||
* | ||
* It doesn't matter what type of function expression. | ||
*/ | ||
function isFunctionExpressionLike(node) { | ||
@@ -209,7 +206,2 @@ return (node.type === experimentalUtils.AST_NODE_TYPES.FunctionExpression || | ||
} | ||
/** | ||
* Is the given node a function node? | ||
* | ||
* It doesn't matter what type of function. | ||
*/ | ||
function isFunctionLike(node) { | ||
@@ -248,2 +240,5 @@ return isFunctionDeclaration(node) || isFunctionExpressionLike(node); | ||
} | ||
function isTSFunctionType(node) { | ||
return node.type === experimentalUtils.AST_NODE_TYPES.TSFunctionType; | ||
} | ||
function isTSIndexSignature(node) { | ||
@@ -297,5 +292,2 @@ return node.type === experimentalUtils.AST_NODE_TYPES.TSIndexSignature; | ||
} | ||
/* | ||
* TS types type guards. | ||
*/ | ||
function isUnionType(type) { | ||
@@ -329,5 +321,2 @@ return ts !== undefined && type.flags === ts.TypeFlags.Union; | ||
/** | ||
* Return the first ancestor that meets the given check criteria. | ||
*/ | ||
function getAncestorOfType(checker, node, child = null) { | ||
@@ -340,23 +329,11 @@ return checker(node, child) | ||
} | ||
/** | ||
* Test if the given node is in a function's body. | ||
*/ | ||
function inFunctionBody(node) { | ||
return (getAncestorOfType((n, c) => isFunctionLike(n) && n.body === c, node) !== null); | ||
} | ||
/** | ||
* Test if the given node is in a class. | ||
*/ | ||
function inClass(node) { | ||
return getAncestorOfType(isClassLike, node) !== null; | ||
} | ||
/** | ||
* Test if the given node is in a TS Property Signature. | ||
*/ | ||
function inInterface(node) { | ||
return getAncestorOfType(isTSInterfaceBody, node) !== null; | ||
} | ||
/** | ||
* Test if the given node is in a Constructor. | ||
*/ | ||
function inConstructor(node) { | ||
@@ -368,5 +345,2 @@ const methodDefinition = getAncestorOfType(isMethodDefinition, node); | ||
} | ||
/** | ||
* Is the given node in the return type. | ||
*/ | ||
function isInReturnType(node) { | ||
@@ -377,5 +351,2 @@ return (getAncestorOfType((n) => n.parent != undefined && | ||
} | ||
/** | ||
* Is the given identifier a property of an object? | ||
*/ | ||
function isPropertyAccess(node) { | ||
@@ -386,5 +357,2 @@ return (node.parent !== undefined && | ||
} | ||
/** | ||
* Is the given identifier a property name? | ||
*/ | ||
function isPropertyName(node) { | ||
@@ -395,5 +363,2 @@ return (node.parent !== undefined && | ||
} | ||
/** | ||
* Is the given function an IIFE? | ||
*/ | ||
function isIIFE(node) { | ||
@@ -406,3 +371,2 @@ return (isFunctionExpressionLike(node) && | ||
// Polyfill. | ||
const allowLocalMutationOptionSchema = { | ||
@@ -459,5 +423,2 @@ type: "object", | ||
}; | ||
/** | ||
* Get the identifier text of the given node. | ||
*/ | ||
function getNodeIdentifierText(node, context) { | ||
@@ -491,5 +452,2 @@ return node === undefined || node === null | ||
} | ||
/** | ||
* Get all the identifier texts of the given node. | ||
*/ | ||
function getNodeIdentifierTexts(node, context) { | ||
@@ -500,7 +458,2 @@ return (isVariableDeclaration(node) | ||
} | ||
/** | ||
* Should the given text be allowed? | ||
* | ||
* Test using the given pattern(s). | ||
*/ | ||
function shouldIgnoreViaPattern(text, ignorePattern) { | ||
@@ -510,16 +463,8 @@ const patterns = Array.isArray(ignorePattern) | ||
: [ignorePattern]; | ||
// One or more patterns match? | ||
return patterns.some((pattern) => new RegExp(pattern).test(text)); | ||
} | ||
/** | ||
* Recursive callback of `shouldIgnoreViaAccessorPattern`. | ||
* | ||
* This function not be called from anywhere else. | ||
* | ||
* Does the given text match the given pattern. | ||
*/ | ||
function accessorPatternMatch([pattern, ...remainingPatternParts], textParts, allowExtra = false) { | ||
return pattern === undefined | ||
? allowExtra || textParts.length === 0 | ||
: // Match any depth (including 0)? | ||
: | ||
pattern === "**" | ||
@@ -531,15 +476,10 @@ ? textParts.length === 0 | ||
.some((offset) => accessorPatternMatch(remainingPatternParts, textParts.slice(offset), true)) | ||
: // Match anything? | ||
: | ||
pattern === "*" | ||
? textParts.length > 0 && | ||
accessorPatternMatch(remainingPatternParts, textParts.slice(1), allowExtra) | ||
: // Text matches pattern? | ||
: | ||
new RegExp(`^${escapeRegExp__default['default'](pattern).replace(/\\\*/g, ".*")}$`).test(textParts[0]) && | ||
accessorPatternMatch(remainingPatternParts, textParts.slice(1), allowExtra); | ||
} | ||
/** | ||
* Should the given text be allowed? | ||
* | ||
* Test using the given accessor pattern(s). | ||
*/ | ||
function shouldIgnoreViaAccessorPattern(text, ignorePattern) { | ||
@@ -549,27 +489,12 @@ const patterns = Array.isArray(ignorePattern) | ||
: [ignorePattern]; | ||
// One or more patterns match? | ||
return patterns.some((pattern) => accessorPatternMatch(pattern.split("."), text.split("."))); | ||
} | ||
/** | ||
* Should the given node be allowed base off the following rule options? | ||
* | ||
* - IgnoreAccessorPatternOption. | ||
* - IgnoreClassOption. | ||
* - IgnoreInterfaceOption. | ||
* - IgnorePatternOption. | ||
* - AllowLocalMutationOption. | ||
*/ | ||
function shouldIgnore(node, context, options) { | ||
return ( | ||
// Allow if in a function and allowLocalMutation is set. | ||
(options.allowLocalMutation === true && inFunctionBody(node)) || | ||
// Ignore if in a class and ignoreClass is set. | ||
return ((options.allowLocalMutation === true && inFunctionBody(node)) || | ||
(options.ignoreClass === true && inClass(node)) || | ||
// Ignore if in an interface and ignoreInterface is set. | ||
(options.ignoreInterface === true && inInterface(node)) || | ||
((texts) => texts.length > 0 | ||
? // Ignore if ignorePattern is set and a pattern matches. | ||
? | ||
(options.ignorePattern !== undefined && | ||
texts.every((text) => shouldIgnoreViaPattern(text, options.ignorePattern))) || | ||
// Ignore if ignoreAccessorPattern is set and an accessor pattern matches. | ||
(options.ignoreAccessorPattern !== undefined && | ||
@@ -580,12 +505,4 @@ texts.every((text) => shouldIgnoreViaAccessorPattern(text, options.ignoreAccessorPattern))) | ||
const version = "3.0.2"; | ||
const version = "3.1.0"; | ||
// Polyfill. | ||
// This function can't be functional as it needs to interact with 3rd-party | ||
// libraries that aren't functional. | ||
/* eslint-disable functional/no-return-void, functional/no-conditional-statement, functional/no-expression-statement */ | ||
/** | ||
* Create a function that processes common options and then runs the given | ||
* check. | ||
*/ | ||
function checkNode(check, context, options) { | ||
@@ -599,6 +516,2 @@ return (node) => { | ||
} | ||
/* eslint-enable functional/no-return-void, functional/no-conditional-statement, functional/no-expression-statement */ | ||
/** | ||
* Create a rule. | ||
*/ | ||
function createRule(name, meta, defaultOptions, ruleFunctionsMap) { | ||
@@ -615,5 +528,2 @@ return experimentalUtils.ESLintUtils.RuleCreator((name) => `https://github.com/jonaskello/eslint-plugin-functional/blob/v${version}/docs/rules/${name}.md`)({ | ||
} | ||
/** | ||
* Get the type of the the given node. | ||
*/ | ||
function getTypeOfNode(node, context) { | ||
@@ -629,6 +539,12 @@ const { parserServices } = context; | ||
} | ||
function getESTreeNode(node, context) { | ||
const { parserServices } = context; | ||
return parserServices === undefined || | ||
parserServices.program === undefined || | ||
parserServices.tsNodeToESTreeNodeMap === undefined | ||
? null | ||
: parserServices.tsNodeToESTreeNodeMap.get(node); | ||
} | ||
// The name of this rule. | ||
const name = "functional-parameters"; | ||
// The schema for the rule options. | ||
const schema = [ | ||
@@ -676,3 +592,2 @@ deepMerge.all([ | ||
]; | ||
// The default options for the rule. | ||
const defaultOptions = { | ||
@@ -686,3 +601,2 @@ allowRestParameter: false, | ||
}; | ||
// The possible error messages. | ||
const errorMessages = { | ||
@@ -694,3 +608,2 @@ restParam: "Unexpected rest parameter. Use a regular parameter of type array instead.", | ||
}; | ||
// The meta data for this rule. | ||
const meta = { | ||
@@ -706,5 +619,2 @@ type: "suggestion", | ||
}; | ||
/** | ||
* Get the rest parameter violations. | ||
*/ | ||
function getRestParamViolations(allowRestParameter, node) { | ||
@@ -722,5 +632,2 @@ return !allowRestParameter && | ||
} | ||
/** | ||
* Get the parameter count violations. | ||
*/ | ||
function getParamCountViolations(enforceParameterCount, node) { | ||
@@ -760,5 +667,2 @@ if (enforceParameterCount === false || | ||
} | ||
/** | ||
* Check if the given function node has a reset parameter this rule. | ||
*/ | ||
function checkFunction(node, context, options) { | ||
@@ -773,5 +677,2 @@ return { | ||
} | ||
/** | ||
* Check if the given identifier is for the "arguments" keyword. | ||
*/ | ||
function checkIdentifier(node, context, options) { | ||
@@ -793,3 +694,2 @@ return { | ||
} | ||
// Create the rule. | ||
const rule = createRule(name, meta, defaultOptions, { | ||
@@ -802,12 +702,5 @@ FunctionDeclaration: checkFunction, | ||
/** | ||
* Returns a function that checks if the given value is the same as the expected | ||
* value. | ||
*/ | ||
function isExpected(expected) { | ||
return (actual) => actual === expected; | ||
} | ||
/** | ||
* Does the given ExpressionStatement specify directive prologues. | ||
*/ | ||
function isDirectivePrologue(node) { | ||
@@ -819,5 +712,3 @@ return (node.expression.type === experimentalUtils.AST_NODE_TYPES.Literal && | ||
// The name of this rule. | ||
const name$1 = "immutable-data"; | ||
// The schema for the rule options. | ||
const schema$1 = [ | ||
@@ -857,3 +748,2 @@ deepMerge.all([ | ||
]; | ||
// The default options for the rule. | ||
const defaultOptions$1 = { | ||
@@ -866,3 +756,2 @@ ignoreImmediateMutation: true, | ||
}; | ||
// The possible error messages. | ||
const errorMessages$1 = { | ||
@@ -873,3 +762,2 @@ generic: "Modifying an existing object/array is not allowed.", | ||
}; | ||
// The meta data for this rule. | ||
const meta$1 = { | ||
@@ -885,7 +773,2 @@ type: "suggestion", | ||
}; | ||
/** | ||
* Array methods that mutate an array. | ||
* | ||
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype#Methods#Mutator_methods | ||
*/ | ||
const arrayMutatorMethods = [ | ||
@@ -902,8 +785,2 @@ "copyWithin", | ||
]; | ||
/** | ||
* Array methods that return a new object (or array) without mutating the original. | ||
* | ||
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype#Methods#Accessor_methods | ||
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype#Iteration_methods | ||
*/ | ||
const arrayNewObjectReturningMethods = [ | ||
@@ -917,13 +794,3 @@ "concat", | ||
]; | ||
/** | ||
* Array constructor functions that create a new array. | ||
* | ||
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#Methods | ||
*/ | ||
const arrayConstructorFunctions = ["from", "of"]; | ||
/** | ||
* Object constructor functions that mutate an object. | ||
* | ||
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object#Methods_of_the_Object_constructor | ||
*/ | ||
const objectConstructorMutatorFunctions = [ | ||
@@ -935,5 +802,2 @@ "assign", | ||
]; | ||
/** | ||
* Check if the given assignment expression violates this rule. | ||
*/ | ||
function checkAssignmentExpression(node, context) { | ||
@@ -943,3 +807,2 @@ return { | ||
descriptors: isMemberExpression(node.left) && | ||
// Allow if in a constructor - allow for field initialization. | ||
!inConstructor(node) | ||
@@ -950,5 +813,2 @@ ? [{ node, messageId: "generic" }] | ||
} | ||
/** | ||
* Check if the given node violates this rule. | ||
*/ | ||
function checkUnaryExpression(node, context) { | ||
@@ -962,5 +822,2 @@ return { | ||
} | ||
/** | ||
* Check if the given node violates this rule. | ||
*/ | ||
function checkUpdateExpression(node, context, options) { | ||
@@ -975,30 +832,13 @@ return { | ||
} | ||
/** | ||
* Check if the given the given MemberExpression is part of a chain and | ||
* immediately follows a method/function call that returns a new array. | ||
* | ||
* If this is the case, then the given MemberExpression is allowed to be | ||
* a mutator method call. | ||
*/ | ||
function isInChainCallAndFollowsNew(node, context, assumeArrayTypes) { | ||
return ( | ||
// Check for: [0, 1, 2] | ||
isArrayExpression(node.object) || | ||
// Check for: new Array() | ||
return (isArrayExpression(node.object) || | ||
(isNewExpression(node.object) && | ||
isArrayConstructorType( | ||
// `isNewExpression` type guard doesn't seem to be working? so use `as`. | ||
getTypeOfNode(node.object.callee, context), assumeArrayTypes, node.object.callee)) || | ||
isArrayConstructorType(getTypeOfNode(node.object.callee, context), assumeArrayTypes, node.object.callee)) || | ||
(isCallExpression(node.object) && | ||
isMemberExpression(node.object.callee) && | ||
isIdentifier(node.object.callee.property) && | ||
// Check for: Array.from(iterable) | ||
((arrayConstructorFunctions.some(isExpected(node.object.callee.property.name)) && | ||
isArrayConstructorType(getTypeOfNode(node.object.callee.object, context), assumeArrayTypes, node.object.callee.object)) || | ||
// Check for: array.slice(0) | ||
arrayNewObjectReturningMethods.some(isExpected(node.object.callee.property.name))))); | ||
} | ||
/** | ||
* Check if the given node violates this rule. | ||
*/ | ||
function checkCallExpression(node, context, options) { | ||
@@ -1011,7 +851,4 @@ const assumeTypesForArrays = options.assumeTypes === true || | ||
context, | ||
descriptors: | ||
// Potential object mutation? | ||
isMemberExpression(node.callee) && isIdentifier(node.callee.property) | ||
? // Potential array mutation? | ||
// Check if allowed here - this cannot be automatically checked beforehand. | ||
descriptors: isMemberExpression(node.callee) && isIdentifier(node.callee.property) | ||
? | ||
!shouldIgnore(node.callee.object, context, options) && | ||
@@ -1025,3 +862,3 @@ arrayMutatorMethods.some((m) => m === | ||
? [{ node, messageId: "array" }] | ||
: // Potential non-array object mutation (ex. Object.assign on identifier)? | ||
: | ||
objectConstructorMutatorFunctions.some((m) => m === | ||
@@ -1033,3 +870,2 @@ node.callee | ||
isMemberExpression(node.arguments[0])) && | ||
// Check if allowed here - this cannot be automatically checked beforehand. | ||
!shouldIgnore(node.arguments[0], context, options) && | ||
@@ -1042,3 +878,2 @@ isObjectConstructorType(getTypeOfNode(node.callee.object, context), assumeTypesForObjects, node.callee.object) | ||
} | ||
// Create the rule. | ||
const rule$1 = createRule(name$1, meta$1, defaultOptions$1, { | ||
@@ -1051,13 +886,8 @@ AssignmentExpression: checkAssignmentExpression, | ||
// The name of this rule. | ||
const name$2 = "no-class"; | ||
// The schema for the rule options. | ||
const schema$2 = []; | ||
// The default options for the rule. | ||
const defaultOptions$2 = {}; | ||
// The possible error messages. | ||
const errorMessages$2 = { | ||
generic: "Unexpected class, use functions not classes.", | ||
}; | ||
// The meta data for this rule. | ||
const meta$2 = { | ||
@@ -1073,15 +903,8 @@ type: "suggestion", | ||
}; | ||
/** | ||
* Check if the given class node violates this rule. | ||
*/ | ||
function checkClass(node, context) { | ||
// All class nodes violate this rule. | ||
return { context, descriptors: [{ node, messageId: "generic" }] }; | ||
} | ||
// Create the rule. | ||
const rule$2 = createRule(name$2, meta$2, defaultOptions$2, { ClassDeclaration: checkClass, ClassExpression: checkClass }); | ||
// The name of this rule. | ||
const name$3 = "no-conditional-statement"; | ||
// The schema for the rule options. | ||
const schema$3 = [ | ||
@@ -1106,5 +929,3 @@ { | ||
]; | ||
// The default options for the rule. | ||
const defaultOptions$3 = { allowReturningBranches: false }; | ||
// The possible error messages. | ||
const errorMessages$3 = { | ||
@@ -1117,3 +938,2 @@ incompleteBranch: "Incomplete branch, every branch in a conditional statement must contain a return statement.", | ||
}; | ||
// The meta data for this rule. | ||
const meta$3 = { | ||
@@ -1129,6 +949,2 @@ type: "suggestion", | ||
}; | ||
/** | ||
* Get all of the violations in the given if statement assuming if statements | ||
* are allowed. | ||
*/ | ||
function getIfBranchViolations(node) { | ||
@@ -1140,3 +956,2 @@ const branches = [node.consequent, node.alternate]; | ||
branch.body.some((statement) => isReturnStatement(statement) || | ||
// Another instance of this rule will check nested if statements. | ||
isIfStatement(statement))) && | ||
@@ -1148,6 +963,2 @@ !isIfStatement(branch)); | ||
} | ||
/** | ||
* Get all of the violations in the given switch statement assuming switch | ||
* statements are allowed. | ||
*/ | ||
function getSwitchViolations(node) { | ||
@@ -1162,21 +973,9 @@ const violations = node.cases.filter((branch) => branch.consequent.length !== 0 && | ||
} | ||
/** | ||
* Does the given if statement violate this rule if it must be exhaustive. | ||
*/ | ||
function isExhaustiveIfViolation(node) { | ||
return node.alternate === null; | ||
} | ||
/** | ||
* Does the given switch statement violate this rule if it must be exhaustive. | ||
*/ | ||
function isExhaustiveSwitchViolation(node) { | ||
return ( | ||
// No cases defined. | ||
node.cases.length === 0 || | ||
// No default case defined. | ||
return (node.cases.length === 0 || | ||
node.cases.every((c) => c.test !== null)); | ||
} | ||
/** | ||
* Check if the given IfStatement violates this rule. | ||
*/ | ||
function checkIfStatement(node, context, options) { | ||
@@ -1194,5 +993,2 @@ return { | ||
} | ||
/** | ||
* Check if the given SwitchStatement violates this rule. | ||
*/ | ||
function checkSwitchStatement(node, context, options) { | ||
@@ -1210,3 +1006,2 @@ return { | ||
} | ||
// Create the rule. | ||
const rule$3 = createRule(name$3, meta$3, defaultOptions$3, { | ||
@@ -1217,13 +1012,8 @@ IfStatement: checkIfStatement, | ||
// The name of this rule. | ||
const name$4 = "no-expression-statement"; | ||
// The schema for the rule options. | ||
const schema$4 = [ignorePatternOptionSchema]; | ||
// The default options for the rule. | ||
const defaultOptions$4 = {}; | ||
// The possible error messages. | ||
const errorMessages$4 = { | ||
generic: "Using expressions to cause side-effects not allowed.", | ||
}; | ||
// The meta data for this rule. | ||
const meta$4 = { | ||
@@ -1239,14 +1029,8 @@ type: "suggestion", | ||
}; | ||
/** | ||
* Check if the given ExpressionStatement violates this rule. | ||
*/ | ||
function checkExpressionStatement(node, context) { | ||
return { | ||
context, | ||
descriptors: | ||
// Allow specifying directive prologues. | ||
isDirectivePrologue(node) ? [] : [{ node, messageId: "generic" }], | ||
descriptors: isDirectivePrologue(node) ? [] : [{ node, messageId: "generic" }], | ||
}; | ||
} | ||
// Create the rule. | ||
const rule$4 = createRule(name$4, meta$4, defaultOptions$4, { | ||
@@ -1256,17 +1040,12 @@ ExpressionStatement: checkExpressionStatement, | ||
// The name of this rule. | ||
const name$5 = "no-let"; | ||
// The schema for the rule options. | ||
const schema$5 = [ | ||
deepMerge.all([allowLocalMutationOptionSchema, ignorePatternOptionSchema]), | ||
]; | ||
// The default options for the rule. | ||
const defaultOptions$5 = { | ||
allowLocalMutation: false, | ||
}; | ||
// The possible error messages. | ||
const errorMessages$5 = { | ||
generic: "Unexpected let, use const instead.", | ||
}; | ||
// The meta data for this rule. | ||
const meta$5 = { | ||
@@ -1283,5 +1062,2 @@ type: "suggestion", | ||
}; | ||
/** | ||
* Check if the given VariableDeclaration violates this rule. | ||
*/ | ||
function checkVariableDeclaration(node, context) { | ||
@@ -1293,3 +1069,2 @@ return { | ||
} | ||
// Create the rule. | ||
const rule$5 = createRule(name$5, meta$5, defaultOptions$5, { | ||
@@ -1299,13 +1074,8 @@ VariableDeclaration: checkVariableDeclaration, | ||
// The name of this rule. | ||
const name$6 = "no-loop-statement"; | ||
// The schema for the rule options. | ||
const schema$6 = []; | ||
// The default options for the rule. | ||
const defaultOptions$6 = {}; | ||
// The possible error messages. | ||
const errorMessages$6 = { | ||
generic: "Unexpected loop, use map or reduce instead.", | ||
}; | ||
// The meta data for this rule. | ||
const meta$6 = { | ||
@@ -1321,10 +1091,5 @@ type: "suggestion", | ||
}; | ||
/** | ||
* Check if the given loop violates this rule. | ||
*/ | ||
function checkLoop(node, context) { | ||
// All loops violate this rule. | ||
return { context, descriptors: [{ node, messageId: "generic" }] }; | ||
} | ||
// Create the rule. | ||
const rule$6 = createRule(name$6, meta$6, defaultOptions$6, { | ||
@@ -1338,13 +1103,8 @@ ForStatement: checkLoop, | ||
// The name of this rule. | ||
const name$7 = "no-method-signature"; | ||
// The schema for the rule options. | ||
const schema$7 = []; | ||
// The default options for the rule. | ||
const defaultOptions$7 = {}; | ||
// The possible error messages. | ||
const errorMessages$7 = { | ||
generic: "Method signature is mutable, use property signature with readonly modifier instead.", | ||
}; | ||
// The meta data for this rule. | ||
const meta$7 = { | ||
@@ -1360,10 +1120,5 @@ type: "suggestion", | ||
}; | ||
/** | ||
* Check if the given TSMethodSignature violates this rule. | ||
*/ | ||
function checkTSMethodSignature(node, context) { | ||
// All TS method signatures violate this rule. | ||
return { context, descriptors: [{ node, messageId: "generic" }] }; | ||
} | ||
// Create the rule. | ||
const rule$7 = createRule(name$7, meta$7, defaultOptions$7, { | ||
@@ -1373,5 +1128,3 @@ TSMethodSignature: checkTSMethodSignature, | ||
// The name of this rule. | ||
const name$8 = "no-mixed-type"; | ||
// The schema for the rule options. | ||
const schema$8 = [ | ||
@@ -1391,3 +1144,2 @@ { | ||
]; | ||
// The default options for the rule. | ||
const defaultOptions$8 = { | ||
@@ -1397,7 +1149,5 @@ checkInterfaces: true, | ||
}; | ||
// The possible error messages. | ||
const errorMessages$8 = { | ||
generic: "Only the same kind of members allowed in types.", | ||
}; | ||
// The meta data for this rule. | ||
const meta$8 = { | ||
@@ -1413,5 +1163,2 @@ type: "suggestion", | ||
}; | ||
/** | ||
* Does the given type elements violate the rule. | ||
*/ | ||
function hasTypeElementViolations(typeElements) { | ||
@@ -1427,10 +1174,5 @@ const typeElementsTypeInfo = typeElements.map((member) => ({ | ||
prevMemberTypeAnnotation: member.typeAnnotation, | ||
violations: | ||
// Not the first property in the interface. | ||
carry.prevMemberType !== undefined && | ||
// And different property type to previous property. | ||
violations: carry.prevMemberType !== undefined && | ||
(carry.prevMemberType !== member.type || | ||
// Or annotationed with a different type annotation. | ||
(carry.prevMemberTypeAnnotation !== member.typeAnnotation && | ||
// Where one of the properties is a annotationed as a function. | ||
(carry.prevMemberTypeAnnotation === experimentalUtils.AST_NODE_TYPES.TSFunctionType || | ||
@@ -1444,5 +1186,2 @@ member.typeAnnotation === experimentalUtils.AST_NODE_TYPES.TSFunctionType))), | ||
} | ||
/** | ||
* Check if the given TSInterfaceDeclaration violates this rule. | ||
*/ | ||
function checkTSInterfaceDeclaration(node, context, options) { | ||
@@ -1456,5 +1195,2 @@ return { | ||
} | ||
/** | ||
* Check if the given TSTypeAliasDeclaration violates this rule. | ||
*/ | ||
function checkTSTypeAliasDeclaration(node, context, options) { | ||
@@ -1470,3 +1206,2 @@ return { | ||
} | ||
// Create the rule. | ||
const rule$8 = createRule(name$8, meta$8, defaultOptions$8, { | ||
@@ -1477,13 +1212,8 @@ TSInterfaceDeclaration: checkTSInterfaceDeclaration, | ||
// The name of this rule. | ||
const name$9 = "no-promise-reject"; | ||
// The schema for the rule options. | ||
const schema$9 = []; | ||
// The default options for the rule. | ||
const defaultOptions$9 = {}; | ||
// The possible error messages. | ||
const errorMessages$9 = { | ||
generic: "Unexpected reject, return an error instead.", | ||
}; | ||
// The meta data for this rule. | ||
const meta$9 = { | ||
@@ -1499,5 +1229,2 @@ type: "suggestion", | ||
}; | ||
/** | ||
* Check if the given CallExpression violates this rule. | ||
*/ | ||
function checkCallExpression$1(node, context) { | ||
@@ -1515,3 +1242,2 @@ return { | ||
} | ||
// Create the rule. | ||
const rule$9 = createRule(name$9, meta$9, defaultOptions$9, { | ||
@@ -1521,5 +1247,3 @@ CallExpression: checkCallExpression$1, | ||
// The name of this rule. | ||
const name$a = "no-return-void"; | ||
// The schema for the rule options. | ||
const schema$a = [ | ||
@@ -1539,3 +1263,2 @@ { | ||
]; | ||
// The default options for the rule. | ||
const defaultOptions$a = { | ||
@@ -1545,7 +1268,5 @@ allowNull: true, | ||
}; | ||
// The possible error messages. | ||
const errorMessages$a = { | ||
generic: "Function must return a value.", | ||
}; | ||
// The meta data for this rule. | ||
const meta$a = { | ||
@@ -1561,5 +1282,2 @@ type: "suggestion", | ||
}; | ||
/** | ||
* Check if the given function node violates this rule. | ||
*/ | ||
function checkFunction$1(node, context, options) { | ||
@@ -1578,3 +1296,2 @@ return { | ||
} | ||
// Create the rule. | ||
const rule$a = createRule(name$a, meta$a, defaultOptions$a, { | ||
@@ -1587,13 +1304,8 @@ FunctionDeclaration: checkFunction$1, | ||
// The name of this rule. | ||
const name$b = "no-this-expression"; | ||
// The schema for the rule options. | ||
const schema$b = []; | ||
// The default options for the rule. | ||
const defaultOptions$b = {}; | ||
// The possible error messages. | ||
const errorMessages$b = { | ||
generic: "Unexpected this, use functions not classes.", | ||
}; | ||
// The meta data for this rule. | ||
const meta$b = { | ||
@@ -1609,10 +1321,5 @@ type: "suggestion", | ||
}; | ||
/** | ||
* Check if the given ThisExpression violates this rule. | ||
*/ | ||
function checkThisExpression(node, context) { | ||
// All throw statements violate this rule. | ||
return { context, descriptors: [{ node, messageId: "generic" }] }; | ||
} | ||
// Create the rule. | ||
const rule$b = createRule(name$b, meta$b, defaultOptions$b, { | ||
@@ -1622,13 +1329,8 @@ ThisExpression: checkThisExpression, | ||
// The name of this rule. | ||
const name$c = "no-throw-statement"; | ||
// The schema for the rule options. | ||
const schema$c = []; | ||
// The default options for the rule. | ||
const defaultOptions$c = {}; | ||
// The possible error messages. | ||
const errorMessages$c = { | ||
generic: "Unexpected throw, throwing exceptions is not functional.", | ||
}; | ||
// The meta data for this rule. | ||
const meta$c = { | ||
@@ -1644,10 +1346,5 @@ type: "suggestion", | ||
}; | ||
/** | ||
* Check if the given ThrowStatement violates this rule. | ||
*/ | ||
function checkThrowStatement(node, context) { | ||
// All throw statements violate this rule. | ||
return { context, descriptors: [{ node, messageId: "generic" }] }; | ||
} | ||
// Create the rule. | ||
const rule$c = createRule(name$c, meta$c, defaultOptions$c, { | ||
@@ -1657,5 +1354,3 @@ ThrowStatement: checkThrowStatement, | ||
// The name of this rule. | ||
const name$d = "no-try-statement"; | ||
// The schema for the rule options. | ||
const schema$d = [ | ||
@@ -1675,3 +1370,2 @@ { | ||
]; | ||
// The default options for the rule. | ||
const defaultOptions$d = { | ||
@@ -1681,3 +1375,2 @@ allowCatch: false, | ||
}; | ||
// The possible error messages. | ||
const errorMessages$d = { | ||
@@ -1687,3 +1380,2 @@ catch: "Unexpected try-catch, this pattern is not functional.", | ||
}; | ||
// The meta data for this rule. | ||
const meta$d = { | ||
@@ -1699,5 +1391,2 @@ type: "suggestion", | ||
}; | ||
/** | ||
* Check if the given TryStatement violates this rule. | ||
*/ | ||
function checkTryStatement(node, context, options) { | ||
@@ -1713,3 +1402,2 @@ return { | ||
} | ||
// Create the rule. | ||
const rule$d = createRule(name$d, meta$d, defaultOptions$d, { | ||
@@ -1719,6 +1407,3 @@ TryStatement: checkTryStatement, | ||
// Polyfill. | ||
// The name of this rule. | ||
const name$e = "prefer-readonly-type"; | ||
// The schema for the rule options. | ||
const schema$e = [ | ||
@@ -1747,3 +1432,2 @@ deepMerge.all([ | ||
]; | ||
// The default options for the rule. | ||
const defaultOptions$e = { | ||
@@ -1757,3 +1441,2 @@ checkImplicit: false, | ||
}; | ||
// The possible error messages. | ||
const errorMessages$e = { | ||
@@ -1766,3 +1449,2 @@ array: "Only readonly arrays allowed.", | ||
}; | ||
// The meta data for this rule. | ||
const meta$e = { | ||
@@ -1785,5 +1467,2 @@ type: "suggestion", | ||
const mutableTypeRegex = new RegExp(`^${Array.from(mutableToImmutableTypes.keys()).join("|")}$`); | ||
/** | ||
* Check if the given ArrayType or TupleType violates this rule. | ||
*/ | ||
function checkArrayOrTupleType(node, context, options) { | ||
@@ -1819,5 +1498,2 @@ if (options.ignoreCollections) { | ||
} | ||
/** | ||
* Check if the given TSMappedType violates this rule. | ||
*/ | ||
function checkMappedType(node, context) { | ||
@@ -1837,5 +1513,2 @@ return { | ||
} | ||
/** | ||
* Check if the given TypeReference violates this rule. | ||
*/ | ||
function checkTypeReference(node, context, options) { | ||
@@ -1874,5 +1547,2 @@ if (isIdentifier(node.typeName)) { | ||
} | ||
/** | ||
* Check if the given property/signature node violates this rule. | ||
*/ | ||
function checkProperty(node, context) { | ||
@@ -1896,5 +1566,2 @@ return { | ||
} | ||
/** | ||
* Check if the given TypeReference violates this rule. | ||
*/ | ||
function checkImplicitType(node, context, options) { | ||
@@ -1941,3 +1608,2 @@ if (options.checkImplicit) { | ||
} | ||
// Create the rule. | ||
const rule$e = createRule(name$e, meta$e, defaultOptions$e, { | ||
@@ -1958,19 +1624,46 @@ ArrowFunctionExpression: checkImplicitType, | ||
// The name of this rule. | ||
const name$f = "prefer-type-literal"; | ||
// The schema for the rule options. | ||
const schema$f = [ignorePatternOptionSchema]; | ||
// The default options for the rule. | ||
const defaultOptions$f = {}; | ||
// The possible error messages. | ||
const name$f = "prefer-tacit"; | ||
const schema$f = [ | ||
deepMerge.all([ | ||
ignorePatternOptionSchema, | ||
{ | ||
type: "object", | ||
properties: { | ||
ignoreImmediateMutation: { | ||
type: "boolean", | ||
}, | ||
assumeTypes: { | ||
oneOf: [ | ||
{ | ||
type: "boolean", | ||
enum: [false], | ||
}, | ||
{ | ||
type: "object", | ||
properties: { | ||
allowFixer: { | ||
type: "boolean", | ||
}, | ||
}, | ||
additionalProperties: false, | ||
}, | ||
], | ||
}, | ||
}, | ||
additionalProperties: false, | ||
}, | ||
]), | ||
]; | ||
const defaultOptions$f = { | ||
assumeTypes: false, | ||
}; | ||
const errorMessages$f = { | ||
generic: "Unexpected interface, use a type literal instead.", | ||
generic: "Potentially unnecessary function wrapper.", | ||
}; | ||
// The meta data for this rule. | ||
const meta$f = { | ||
type: "suggestion", | ||
docs: { | ||
description: "Prefer Type Literals over Interfaces.", | ||
description: "Replaces `x => f(x)` with just `f`.", | ||
category: "Best Practices", | ||
recommended: false, | ||
recommended: "warn", | ||
}, | ||
@@ -1981,5 +1674,111 @@ messages: errorMessages$f, | ||
}; | ||
/** | ||
* Check if the given interface node violates this rule. | ||
*/ | ||
function isCallerViolation(caller, calleeType, context) { | ||
var _a, _b; | ||
if (calleeType.symbol === undefined) { | ||
return false; | ||
} | ||
else { | ||
const tsDeclaration = (_a = calleeType.symbol.valueDeclaration) !== null && _a !== void 0 ? _a : (_b = calleeType.symbol.declarations) === null || _b === void 0 ? void 0 : _b[0]; | ||
if (tsDeclaration === undefined) { | ||
return false; | ||
} | ||
else { | ||
const declaration = getESTreeNode(tsDeclaration, context); | ||
return ((declaration !== null && | ||
(isFunctionLike(declaration) || isTSFunctionType(declaration)) && | ||
declaration.params.length === caller.arguments.length) || | ||
tsDeclaration.parameters | ||
.slice(caller.arguments.length) | ||
.every((param) => param.initializer !== undefined || | ||
param.questionToken !== undefined)); | ||
} | ||
} | ||
} | ||
function getCallDescriptors(node, context, options, caller) { | ||
if (isIdentifier(caller.callee) && | ||
node.params.length === caller.arguments.length && | ||
node.params.every((param, index) => { | ||
const callArg = caller.arguments[index]; | ||
return (isIdentifier(callArg) && | ||
isIdentifier(param) && | ||
callArg.name === param.name); | ||
})) { | ||
const calleeType = getTypeOfNode(caller.callee, context); | ||
const assumingTypes = (calleeType === null || calleeType.symbol === undefined) && | ||
options.assumeTypes !== false; | ||
if (assumingTypes || | ||
(calleeType !== null && isCallerViolation(caller, calleeType, context))) { | ||
const calleeName = caller.callee.name; | ||
return [ | ||
{ | ||
node: node, | ||
messageId: "generic", | ||
fix: (typeof options.assumeTypes !== "object" && assumingTypes) || | ||
(typeof options.assumeTypes === "object" && | ||
!options.assumeTypes.allowFixer) | ||
? undefined | ||
: (fixer) => fixer.replaceText(node, calleeName), | ||
}, | ||
]; | ||
} | ||
else { | ||
return []; | ||
} | ||
} | ||
else { | ||
return []; | ||
} | ||
} | ||
function getDirectCallDescriptors(node, context, options) { | ||
if (isCallExpression(node.body)) { | ||
return getCallDescriptors(node, context, options, node.body); | ||
} | ||
else { | ||
return []; | ||
} | ||
} | ||
function getNestedCallDescriptors(node, context, options) { | ||
if (isBlockStatement(node.body) && | ||
node.body.body.length === 1 && | ||
isReturnStatement(node.body.body[0]) && | ||
node.body.body[0].argument !== null && | ||
isCallExpression(node.body.body[0].argument)) { | ||
return getCallDescriptors(node, context, options, node.body.body[0].argument); | ||
} | ||
else { | ||
return []; | ||
} | ||
} | ||
function checkFunction$2(node, context, options) { | ||
return { | ||
context, | ||
descriptors: [ | ||
...getDirectCallDescriptors(node, context, options), | ||
...getNestedCallDescriptors(node, context, options), | ||
], | ||
}; | ||
} | ||
const rule$f = createRule(name$f, meta$f, defaultOptions$f, { | ||
FunctionDeclaration: checkFunction$2, | ||
FunctionExpression: checkFunction$2, | ||
ArrowFunctionExpression: checkFunction$2, | ||
}); | ||
const name$g = "prefer-type-literal"; | ||
const schema$g = [ignorePatternOptionSchema]; | ||
const defaultOptions$g = {}; | ||
const errorMessages$g = { | ||
generic: "Unexpected interface, use a type literal instead.", | ||
}; | ||
const meta$g = { | ||
type: "suggestion", | ||
docs: { | ||
description: "Prefer Type Literals over Interfaces.", | ||
category: "Best Practices", | ||
recommended: false, | ||
}, | ||
messages: errorMessages$g, | ||
fixable: "code", | ||
schema: schema$g, | ||
}; | ||
function checkInterface(node, context) { | ||
@@ -2010,10 +1809,6 @@ return { | ||
} | ||
// Create the rule. | ||
const rule$f = createRule(name$f, meta$f, defaultOptions$f, { | ||
const rule$g = createRule(name$g, meta$g, defaultOptions$g, { | ||
TSInterfaceDeclaration: checkInterface, | ||
}); | ||
/** | ||
* All of the custom rules. | ||
*/ | ||
const rules = { | ||
@@ -2036,5 +1831,6 @@ [name]: rule, | ||
[name$f]: rule$f, | ||
[name$g]: rule$g, | ||
}; | ||
const config$9 = { | ||
const config$a = { | ||
rules, | ||
@@ -2051,5 +1847,6 @@ configs: { | ||
currying: config$1, | ||
stylitic: config$9, | ||
}, | ||
}; | ||
module.exports = config$9; | ||
module.exports = config$a; |
105
package.json
@@ -30,4 +30,10 @@ { | ||
], | ||
"exports": { | ||
"default": "./lib/index.js", | ||
"import": "./lib/index.mjs", | ||
"require": "./lib/index.js" | ||
}, | ||
"main": "lib/index.js", | ||
"files": [ | ||
"/lib", | ||
"lib/", | ||
"package.json", | ||
@@ -38,79 +44,66 @@ "CHANGELOG.md", | ||
], | ||
"exports": { | ||
"import": "./lib/index.mjs", | ||
"require": "./lib/index.js", | ||
"default": "./lib/index.js" | ||
}, | ||
"main": "lib/index.js", | ||
"scripts": { | ||
"build": "yarn rimraf lib && yarn compile", | ||
"build-tests": "yarn rimraf build && yarn compile-tests", | ||
"compile": "yarn rollup -c", | ||
"compile-tests": "yarn tsc -p tests/tsconfig.json && cp ./tests/helpers/tsconfig.json ./build/tests/helpers/", | ||
"prebuild": "rimraf lib", | ||
"build": "yarn compile", | ||
"prebuild-tests": "rimraf build", | ||
"build-tests": "yarn compile-tests", | ||
"compile": "rollup -c", | ||
"compile-tests": "tsc -p tests/tsconfig.json && cpx ./tests/helpers/tsconfig.json ./build/tests/helpers/", | ||
"prelint": "yarn build && yarn link && yarn link 'eslint-plugin-functional'", | ||
"lint": "yarn eslint './{src,tests}/**/*.ts' --ext .ts -f visualstudio", | ||
"report-coverage": "yarn codecov -f coverage/lcov.info", | ||
"test": "yarn jest --testPathIgnorePatterns _work.test", | ||
"test-compiled": "USE_COMPLIED=1 yarn test", | ||
"test-work": "yarn jest tests/rules/_work.test.ts --no-coverage", | ||
"lint": "eslint . -f visualstudio", | ||
"lint-fix": "yarn lint --fix", | ||
"test": "jest --testPathIgnorePatterns _work.test", | ||
"test-compiled": "cross-env USE_COMPLIED=1 yarn test", | ||
"test-work": "jest tests/rules/_work.test.ts --no-coverage", | ||
"verify": "yarn build && yarn lint && yarn build-tests && yarn test-compiled && rimraf build", | ||
"preversion": "yarn verify", | ||
"version": "yarn auto-changelog -p && git add CHANGELOG.md", | ||
"version": "auto-changelog -p && git add CHANGELOG.md", | ||
"postversion": "git push --tags && yarn publish --new-version $npm_package_version && git push && echo \"Successfully released version $npm_package_version!\"" | ||
}, | ||
"husky": { | ||
"hooks": { | ||
"pre-commit": "yarn lint-staged" | ||
} | ||
}, | ||
"lint-staged": { | ||
"./{src,tests}/**/*.{ts,json}": [ | ||
"yarn prettier --write", | ||
"git add" | ||
], | ||
"./{src,tests}/**/*.{ts}": "eslint" | ||
}, | ||
"dependencies": { | ||
"@typescript-eslint/experimental-utils": "^3.9.1", | ||
"array.prototype.flatmap": "^1.2.3", | ||
"@typescript-eslint/experimental-utils": "^4.9.1", | ||
"array.prototype.flatmap": "^1.2.4", | ||
"deepmerge": "^4.2.2", | ||
"escape-string-regexp": "^4.0.0", | ||
"object.fromentries": "^2.0.2" | ||
"object.fromentries": "^2.0.3" | ||
}, | ||
"devDependencies": { | ||
"@rollup/plugin-commonjs": "^15.0.0", | ||
"@rollup/plugin-commonjs": "^17.0.0", | ||
"@rollup/plugin-json": "^4.1.0", | ||
"@rollup/plugin-node-resolve": "^9.0.0", | ||
"@rollup/plugin-typescript": "^5.0.2", | ||
"@rollup/plugin-node-resolve": "^11.0.0", | ||
"@rollup/plugin-typescript": "^8.0.0", | ||
"@types/dedent": "^0.7.0", | ||
"@types/eslint": "^7.2.1", | ||
"@types/eslint": "^7.2.6", | ||
"@types/estree": "^0.0.45", | ||
"@types/glob": "^7.1.1", | ||
"@types/jest": "^26.0.10", | ||
"@types/node": "10.17.28", | ||
"@typescript-eslint/eslint-plugin": "^3.9.1", | ||
"@typescript-eslint/parser": "^3.9.1", | ||
"auto-changelog": "^2.2.0", | ||
"@types/jest": "^26.0.19", | ||
"@types/node": "14.14.12", | ||
"@typescript-eslint/eslint-plugin": "^4.9.1", | ||
"@typescript-eslint/parser": "^4.9.1", | ||
"auto-changelog": "^2.2.1", | ||
"babel-eslint": "^10.0.2", | ||
"codecov": "^3.5.0", | ||
"codecov": "^3.8.1", | ||
"cpx": "^1.5.0", | ||
"cross-env": "^7.0.3", | ||
"dedent": "^0.7.0", | ||
"eslint": "^7.7.0", | ||
"eslint-config-prettier": "^6.9.0", | ||
"eslint": "^7.15.0", | ||
"eslint-config-prettier": "^7.0.0", | ||
"eslint-plugin-eslint-plugin": "^2.2.0", | ||
"eslint-plugin-import": "^2.20.0", | ||
"eslint-plugin-jest": "^23.4.0", | ||
"eslint-plugin-jsdoc": "^30.2.4", | ||
"eslint-plugin-prettier": "^3.1.2", | ||
"eslint-plugin-import": "^2.22.1", | ||
"eslint-plugin-jest": "^24.1.3", | ||
"eslint-plugin-jsdoc": "^30.7.8", | ||
"eslint-plugin-prettier": "^3.2.0", | ||
"glob": "^7.1.6", | ||
"husky": "^4.0.6", | ||
"jest": "^26.4.2", | ||
"husky": "^4.3.5", | ||
"jest": "^26.6.3", | ||
"json-schema": "^0.2.5", | ||
"lint-staged": "^10.2.11", | ||
"prettier": "^2.0.5", | ||
"lint-staged": "^10.5.3", | ||
"prettier": "^2.2.1", | ||
"rimraf": "^3.0.0", | ||
"rollup": "^2.26.5", | ||
"rollup": "^2.34.2", | ||
"rollup-plugin-auto-external": "^2.0.0", | ||
"shelljs": "^0.8.3", | ||
"ts-jest": "^26.2.0", | ||
"tslib": "^2.0.1", | ||
"typescript": "^4.0.2" | ||
"ts-jest": "^26.4.4", | ||
"tslib": "^2.0.3", | ||
"typescript": "^4.1.3" | ||
}, | ||
@@ -117,0 +110,0 @@ "peerDependencies": { |
@@ -27,2 +27,3 @@ <div align="center"> | ||
- [Currying](#currying) | ||
- [Stylitic](#stylitic) | ||
@@ -49,2 +50,6 @@ ### No mutations | ||
### Stylitic | ||
Make things look nicer (in our opinion). | ||
## Installation | ||
@@ -99,3 +104,4 @@ | ||
"plugin:functional/external-recommended", | ||
"plugin:functional/recommended" | ||
"plugin:functional/recommended", | ||
"plugin:functional/stylitic" | ||
] | ||
@@ -142,3 +148,4 @@ } | ||
"plugin:functional/external-recommended", | ||
"plugin:functional/recommended" | ||
"plugin:functional/recommended", | ||
"plugin:functional/stylitic" | ||
] | ||
@@ -164,2 +171,3 @@ } | ||
- **Currying** (plugin:functional/currying) | ||
- **Stylitic** (plugin:functional/stylitic) | ||
@@ -236,2 +244,10 @@ Other: | ||
### Stylitic Rules | ||
:see_no_evil: = `stylitic` Ruleset. | ||
| Name | Description | <span title="Stylitic">:see_no_evil:</span> | <span title="Lite">:hear_no_evil:</span> | <span title="Recommended">:speak_no_evil:</span> | :wrench: | :blue_heart: | | ||
| ---------------------------------------------- | ----------------------- | :-----------------------------------------: | :--------------------------------------: | :----------------------------------------------: | :------: | :----------: | | ||
| [`prefer-tacit`](./docs/rules/prefer-tacit.md) | Tacit/Point-Free style. | :heavy_check_mark: | | | :wrench: | :blue_heart: | | ||
## Recommended standard rules | ||
@@ -238,0 +254,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
300
154569
38
3398
1
1
+ Added@nodelib/fs.scandir@2.1.5(transitive)
+ Added@nodelib/fs.stat@2.0.5(transitive)
+ Added@nodelib/fs.walk@1.2.8(transitive)
+ Added@typescript-eslint/experimental-utils@4.33.0(transitive)
+ Added@typescript-eslint/scope-manager@4.33.0(transitive)
+ Added@typescript-eslint/types@4.33.0(transitive)
+ Added@typescript-eslint/typescript-estree@4.33.0(transitive)
+ Added@typescript-eslint/visitor-keys@4.33.0(transitive)
+ Addedarray-union@2.1.0(transitive)
+ Addedbraces@3.0.3(transitive)
+ Addeddir-glob@3.0.1(transitive)
+ Addedeslint-utils@3.0.0(transitive)
+ Addedfast-glob@3.3.2(transitive)
+ Addedfastq@1.17.1(transitive)
+ Addedfill-range@7.1.1(transitive)
+ Addedglobby@11.1.0(transitive)
+ Addedignore@5.3.2(transitive)
+ Addedis-number@7.0.0(transitive)
+ Addedmerge2@1.4.1(transitive)
+ Addedmicromatch@4.0.8(transitive)
+ Addedpath-type@4.0.0(transitive)
+ Addedpicomatch@2.3.1(transitive)
+ Addedqueue-microtask@1.2.3(transitive)
+ Addedreusify@1.0.4(transitive)
+ Addedrun-parallel@1.2.0(transitive)
+ Addedslash@3.0.0(transitive)
+ Addedto-regex-range@5.0.1(transitive)
- Removed@typescript-eslint/experimental-utils@3.10.1(transitive)
- Removed@typescript-eslint/types@3.10.1(transitive)
- Removed@typescript-eslint/typescript-estree@3.10.1(transitive)
- Removed@typescript-eslint/visitor-keys@3.10.1(transitive)
- Removedlodash@4.17.21(transitive)
Updatedobject.fromentries@^2.0.3