eslint-plugin-th-rules 3.2.0 → 3.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,IAAI,EAAE,MAAM,QAAQ,CAAC;AAQhD,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,eAAO,MAAM,OAAO;;;;;CAKnB,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAE1E,QAAA,MAAM,KAAK,EAAoC;IAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAA;CAAE,CAAC;AACpI,eAAe,KAAK,CAAC"}
|
package/dist/plugin.d.ts
CHANGED
|
@@ -1,85 +1,85 @@
|
|
|
1
1
|
export declare const rules: {
|
|
2
|
-
|
|
2
|
+
'no-boolean-coercion': import("@typescript-eslint/utils/ts-eslint").RuleModule<"useIsEmpty" | "useIsNil", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
3
3
|
name: string;
|
|
4
4
|
};
|
|
5
|
-
|
|
5
|
+
'no-comments': import("@typescript-eslint/utils/ts-eslint").RuleModule<"commentNotAllowed", [({
|
|
6
6
|
allow?: string[];
|
|
7
7
|
disallow?: string[];
|
|
8
8
|
} | undefined)?], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
9
9
|
name: string;
|
|
10
10
|
};
|
|
11
|
-
|
|
11
|
+
'no-default-export': import("@typescript-eslint/utils/ts-eslint").RuleModule<"unnamed", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
12
12
|
name: string;
|
|
13
13
|
};
|
|
14
|
-
|
|
14
|
+
'no-destructuring': import("@typescript-eslint/utils/ts-eslint").RuleModule<"tooDeep" | "tooMany" | "tooLong", [{
|
|
15
15
|
maximumDestructuredVariables: number;
|
|
16
16
|
maximumLineLength: number;
|
|
17
17
|
}], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
18
18
|
name: string;
|
|
19
19
|
};
|
|
20
|
-
|
|
20
|
+
'prefer-is-empty': import("@typescript-eslint/utils/ts-eslint").RuleModule<"useIsEmpty", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
21
21
|
name: string;
|
|
22
22
|
};
|
|
23
|
-
|
|
23
|
+
'schemas-in-schemas-file': import("@typescript-eslint/utils/ts-eslint").RuleModule<"moveSchema", [{
|
|
24
24
|
allowedSuffixes: string[];
|
|
25
25
|
onlyWhenAssigned: boolean;
|
|
26
26
|
allowInTests: boolean;
|
|
27
27
|
}], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
28
28
|
name: string;
|
|
29
29
|
};
|
|
30
|
-
|
|
30
|
+
'top-level-functions': import("@typescript-eslint/utils/ts-eslint").RuleModule<"arrow" | "funcExpr" | "anonDecl", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
31
31
|
name: string;
|
|
32
32
|
};
|
|
33
|
-
|
|
33
|
+
'types-in-dts': import("@typescript-eslint/utils/ts-eslint").RuleModule<"moveToDts", [{
|
|
34
34
|
allowEnums: boolean;
|
|
35
35
|
allowDeclare: boolean;
|
|
36
36
|
}], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
37
37
|
name: string;
|
|
38
38
|
};
|
|
39
|
-
|
|
39
|
+
'no-explicit-nil-compare': import("@typescript-eslint/utils/ts-eslint").RuleModule<"useIsNull" | "useIsUndefined", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
40
40
|
name: string;
|
|
41
41
|
};
|
|
42
42
|
};
|
|
43
43
|
declare const plugin: {
|
|
44
44
|
rules: {
|
|
45
|
-
|
|
45
|
+
'no-boolean-coercion': import("@typescript-eslint/utils/ts-eslint").RuleModule<"useIsEmpty" | "useIsNil", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
46
46
|
name: string;
|
|
47
47
|
};
|
|
48
|
-
|
|
48
|
+
'no-comments': import("@typescript-eslint/utils/ts-eslint").RuleModule<"commentNotAllowed", [({
|
|
49
49
|
allow?: string[];
|
|
50
50
|
disallow?: string[];
|
|
51
51
|
} | undefined)?], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
52
52
|
name: string;
|
|
53
53
|
};
|
|
54
|
-
|
|
54
|
+
'no-default-export': import("@typescript-eslint/utils/ts-eslint").RuleModule<"unnamed", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
55
55
|
name: string;
|
|
56
56
|
};
|
|
57
|
-
|
|
57
|
+
'no-destructuring': import("@typescript-eslint/utils/ts-eslint").RuleModule<"tooDeep" | "tooMany" | "tooLong", [{
|
|
58
58
|
maximumDestructuredVariables: number;
|
|
59
59
|
maximumLineLength: number;
|
|
60
60
|
}], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
61
61
|
name: string;
|
|
62
62
|
};
|
|
63
|
-
|
|
63
|
+
'prefer-is-empty': import("@typescript-eslint/utils/ts-eslint").RuleModule<"useIsEmpty", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
64
64
|
name: string;
|
|
65
65
|
};
|
|
66
|
-
|
|
66
|
+
'schemas-in-schemas-file': import("@typescript-eslint/utils/ts-eslint").RuleModule<"moveSchema", [{
|
|
67
67
|
allowedSuffixes: string[];
|
|
68
68
|
onlyWhenAssigned: boolean;
|
|
69
69
|
allowInTests: boolean;
|
|
70
70
|
}], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
71
71
|
name: string;
|
|
72
72
|
};
|
|
73
|
-
|
|
73
|
+
'top-level-functions': import("@typescript-eslint/utils/ts-eslint").RuleModule<"arrow" | "funcExpr" | "anonDecl", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
74
74
|
name: string;
|
|
75
75
|
};
|
|
76
|
-
|
|
76
|
+
'types-in-dts': import("@typescript-eslint/utils/ts-eslint").RuleModule<"moveToDts", [{
|
|
77
77
|
allowEnums: boolean;
|
|
78
78
|
allowDeclare: boolean;
|
|
79
79
|
}], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
80
80
|
name: string;
|
|
81
81
|
};
|
|
82
|
-
|
|
82
|
+
'no-explicit-nil-compare': import("@typescript-eslint/utils/ts-eslint").RuleModule<"useIsNull" | "useIsUndefined", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
83
83
|
name: string;
|
|
84
84
|
};
|
|
85
85
|
};
|
package/dist/plugin.js
CHANGED
|
@@ -8,15 +8,15 @@ import schemasInSchemasFile from './rules/schemas-in-schemas-file.js';
|
|
|
8
8
|
import topLevelFunctions from './rules/top-level-functions.js';
|
|
9
9
|
import typesInDts from './rules/types-in-dts.js';
|
|
10
10
|
export const rules = {
|
|
11
|
-
noBooleanCoercion,
|
|
12
|
-
noComments,
|
|
13
|
-
noDefaultExport,
|
|
14
|
-
noDestructuring,
|
|
15
|
-
preferIsEmpty,
|
|
16
|
-
schemasInSchemasFile,
|
|
17
|
-
topLevelFunctions,
|
|
18
|
-
typesInDts,
|
|
19
|
-
noExplicitNilCompare,
|
|
11
|
+
'no-boolean-coercion': noBooleanCoercion,
|
|
12
|
+
'no-comments': noComments,
|
|
13
|
+
'no-default-export': noDefaultExport,
|
|
14
|
+
'no-destructuring': noDestructuring,
|
|
15
|
+
'prefer-is-empty': preferIsEmpty,
|
|
16
|
+
'schemas-in-schemas-file': schemasInSchemasFile,
|
|
17
|
+
'top-level-functions': topLevelFunctions,
|
|
18
|
+
'types-in-dts': typesInDts,
|
|
19
|
+
'no-explicit-nil-compare': noExplicitNilCompare,
|
|
20
20
|
};
|
|
21
21
|
const plugin = { rules };
|
|
22
22
|
export default plugin;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-boolean-coercion.d.ts","sourceRoot":"","sources":["../../src/rules/no-boolean-coercion.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"no-boolean-coercion.d.ts","sourceRoot":"","sources":["../../src/rules/no-boolean-coercion.ts"],"names":[],"mappings":"AAGA,OAAO,EAAkB,WAAW,EAAiB,MAAM,0BAA0B,CAAC;AAQtF,QAAA,MAAM,iBAAiB;;CAmGrB,CAAC;AAEH,eAAe,iBAAiB,CAAC"}
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
2
|
+
/* eslint-disable new-cap */
|
|
3
|
+
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
4
|
+
import { AST_NODE_TYPES, ESLintUtils } from '@typescript-eslint/utils';
|
|
2
5
|
const createRule = ESLintUtils.RuleCreator(() => 'https://github.com/tomerh2001/eslint-plugin-th-rules/blob/main/docs/rules/no-boolean-coercion.md');
|
|
6
|
+
const LODASH_MODULE = 'lodash';
|
|
7
|
+
const LODASH_IDENT = '_';
|
|
3
8
|
const noBooleanCoercion = createRule({
|
|
4
9
|
name: 'no-boolean-coercion',
|
|
5
10
|
meta: {
|
|
6
11
|
type: 'problem',
|
|
12
|
+
fixable: 'code',
|
|
7
13
|
docs: {
|
|
8
14
|
description: 'Disallow Boolean(value) or !!value. Enforce explicit checks: !_.isNil(value) for scalars and !_.isEmpty(value) for strings, arrays, and objects.',
|
|
9
15
|
},
|
|
10
|
-
hasSuggestions: true,
|
|
11
16
|
schema: [],
|
|
12
17
|
messages: {
|
|
13
18
|
useIsEmpty: 'Boolean coercion is not allowed. Use !_.isEmpty(value) for strings, arrays, and objects.',
|
|
@@ -16,62 +21,67 @@ const noBooleanCoercion = createRule({
|
|
|
16
21
|
},
|
|
17
22
|
defaultOptions: [],
|
|
18
23
|
create(context) {
|
|
19
|
-
const { sourceCode } = context;
|
|
20
24
|
const services = ESLintUtils.getParserServices(context);
|
|
21
|
-
const checker = services
|
|
25
|
+
const checker = services.program.getTypeChecker();
|
|
26
|
+
function hasLodashImport() {
|
|
27
|
+
return context.sourceCode.ast.body.some((node) => node.type === AST_NODE_TYPES.ImportDeclaration && node.source.value === LODASH_MODULE);
|
|
28
|
+
}
|
|
29
|
+
function getLodashImportFixer(fixer) {
|
|
30
|
+
if (hasLodashImport()) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
const firstNode = context.sourceCode.ast.body[0];
|
|
34
|
+
const importText = `import ${LODASH_IDENT} from '${LODASH_MODULE}';\n`;
|
|
35
|
+
if (!firstNode) {
|
|
36
|
+
return fixer.insertTextAfterRange([0, 0], importText);
|
|
37
|
+
}
|
|
38
|
+
return fixer.insertTextBefore(firstNode, importText);
|
|
39
|
+
}
|
|
22
40
|
function isBooleanCall(node) {
|
|
23
|
-
return node.type ===
|
|
41
|
+
return node.type === AST_NODE_TYPES.CallExpression && node.callee.type === AST_NODE_TYPES.Identifier && node.callee.name === 'Boolean' && node.arguments.length === 1;
|
|
24
42
|
}
|
|
25
43
|
function isDoubleNegation(node) {
|
|
26
|
-
return node.type ===
|
|
44
|
+
return node.type === AST_NODE_TYPES.UnaryExpression && node.operator === '!' && node.argument.type === AST_NODE_TYPES.UnaryExpression && node.argument.operator === '!';
|
|
27
45
|
}
|
|
28
46
|
function isCollectionLikeByTS(node) {
|
|
29
|
-
if (!checker || !services.esTreeNodeToTSNodeMap) {
|
|
30
|
-
return false;
|
|
31
|
-
}
|
|
32
47
|
const tsNode = services.esTreeNodeToTSNodeMap.get(node);
|
|
33
48
|
if (!tsNode) {
|
|
34
49
|
return false;
|
|
35
50
|
}
|
|
36
51
|
const type = checker.getTypeAtLocation(tsNode);
|
|
37
52
|
const typeString = checker.typeToString(type);
|
|
38
|
-
return typeString
|
|
53
|
+
return typeString === 'string' || typeString === 'object' || typeString.includes('[]') || typeString.startsWith('Array<') || typeString.startsWith('ReadonlyArray<');
|
|
39
54
|
}
|
|
40
55
|
function isCollectionLikeBySyntax(node) {
|
|
41
|
-
return node.type ===
|
|
56
|
+
return node.type === AST_NODE_TYPES.ArrayExpression || node.type === AST_NODE_TYPES.ObjectExpression || (node.type === AST_NODE_TYPES.Literal && typeof node.value === 'string');
|
|
42
57
|
}
|
|
43
58
|
function report(node, valueNode) {
|
|
44
59
|
const isCollection = isCollectionLikeBySyntax(valueNode) || isCollectionLikeByTS(valueNode);
|
|
45
|
-
const
|
|
46
|
-
const replacement = `!${
|
|
60
|
+
const fnName = isCollection ? 'isEmpty' : 'isNil';
|
|
61
|
+
const replacement = `!${LODASH_IDENT}.${fnName}(${context.sourceCode.getText(valueNode)})`;
|
|
47
62
|
context.report({
|
|
48
63
|
node,
|
|
49
64
|
messageId: isCollection ? 'useIsEmpty' : 'useIsNil',
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
65
|
+
fix(fixer) {
|
|
66
|
+
const fixes = [fixer.replaceText(node, replacement)];
|
|
67
|
+
const importFix = getLodashImportFixer(fixer);
|
|
68
|
+
if (importFix) {
|
|
69
|
+
fixes.push(importFix);
|
|
70
|
+
}
|
|
71
|
+
return fixes;
|
|
72
|
+
},
|
|
58
73
|
});
|
|
59
74
|
}
|
|
60
75
|
return {
|
|
61
76
|
CallExpression(node) {
|
|
62
77
|
if (isBooleanCall(node)) {
|
|
63
|
-
|
|
64
|
-
if (arg) {
|
|
65
|
-
report(node, arg);
|
|
66
|
-
}
|
|
78
|
+
report(node, node.arguments[0]);
|
|
67
79
|
}
|
|
68
80
|
},
|
|
69
81
|
UnaryExpression(node) {
|
|
70
82
|
if (isDoubleNegation(node)) {
|
|
71
83
|
const valueNode = node.argument.argument;
|
|
72
|
-
|
|
73
|
-
report(node, valueNode);
|
|
74
|
-
}
|
|
84
|
+
report(node, valueNode);
|
|
75
85
|
}
|
|
76
86
|
},
|
|
77
87
|
};
|