eslint-plugin-th-rules 3.0.0 → 3.1.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/configs/bundles/recommended-react.d.ts +2 -199
- package/dist/configs/bundles/recommended-react.js +4 -3
- package/dist/configs/bundles/recommended-typescript-react.d.ts +2 -0
- package/dist/configs/bundles/recommended-typescript-react.js +9 -0
- package/dist/configs/bundles/recommended-typescript.d.ts +2 -190
- package/dist/configs/bundles/recommended-typescript.js +3 -2
- package/dist/configs/bundles/recommended.d.ts +2 -190
- package/dist/configs/bundles/recommended.js +3 -2
- package/dist/configs/core/base.d.ts +2 -170
- package/dist/configs/core/react.d.ts +2 -6
- package/dist/configs/externals/base.d.ts +2 -15
- package/dist/configs/externals/opinionated.d.ts +2 -10
- package/dist/index.d.ts +9 -1157
- package/dist/index.js +6 -7
- package/dist/rules/no-comments.d.ts +2 -2
- package/dist/rules/no-comments.js +2 -2
- package/dist/rules/no-default-export.d.ts +2 -2
- package/dist/rules/no-default-export.js +2 -6
- package/dist/rules/no-destructuring.d.ts +2 -2
- package/dist/rules/no-destructuring.js +2 -2
- package/dist/rules/prefer-is-empty.d.ts +3 -3
- package/dist/rules/prefer-is-empty.js +38 -47
- package/dist/rules/schemas-in-schemas-file.d.ts +2 -2
- package/dist/rules/schemas-in-schemas-file.js +2 -1
- package/dist/rules/top-level-functions.d.ts +2 -2
- package/dist/rules/top-level-functions.js +3 -18
- package/dist/rules/types-in-dts.d.ts +3 -3
- package/dist/rules/types-in-dts.js +23 -23
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -3,7 +3,9 @@ import { rules } from './plugin.js';
|
|
|
3
3
|
import { recommended } from './configs/bundles/recommended.js';
|
|
4
4
|
import { recommendedReact } from './configs/bundles/recommended-react.js';
|
|
5
5
|
import { recommendedTypescript } from './configs/bundles/recommended-typescript.js';
|
|
6
|
+
import { recommendedTypescriptReact } from './configs/bundles/recommended-typescript-react.js';
|
|
6
7
|
// Internal layers (named exports only)
|
|
8
|
+
export { rules } from './plugin.js';
|
|
7
9
|
export { coreBase } from './configs/core/base.js';
|
|
8
10
|
export { coreTypescript } from './configs/core/typescript.js';
|
|
9
11
|
export { coreReact } from './configs/core/react.js';
|
|
@@ -11,11 +13,8 @@ export { externalsBase } from './configs/externals/base.js';
|
|
|
11
13
|
export { externalsOpinionated } from './configs/externals/opinionated.js';
|
|
12
14
|
export const configs = {
|
|
13
15
|
recommended,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
export default {
|
|
18
|
-
rules,
|
|
19
|
-
configs,
|
|
16
|
+
recommendedReact,
|
|
17
|
+
recommendedTypescript,
|
|
18
|
+
recommendedTypescriptReact,
|
|
20
19
|
};
|
|
21
|
-
export { rules }
|
|
20
|
+
export default { rules, configs };
|
|
@@ -5,7 +5,7 @@ type Options = [
|
|
|
5
5
|
disallow?: string[];
|
|
6
6
|
}?
|
|
7
7
|
];
|
|
8
|
-
declare const
|
|
8
|
+
declare const noComments: ESLintUtils.RuleModule<"commentNotAllowed", Options, unknown, ESLintUtils.RuleListener> & {
|
|
9
9
|
name: string;
|
|
10
10
|
};
|
|
11
|
-
export default
|
|
11
|
+
export default noComments;
|
|
@@ -6,7 +6,7 @@ const DEFAULT_ALLOWED_PATTERNS = [
|
|
|
6
6
|
/info/i, // Allow INFO (case-insensitive)
|
|
7
7
|
/^\s*eslint-(disable|enable|env|globals|ignore|directive)/,
|
|
8
8
|
];
|
|
9
|
-
|
|
9
|
+
const noComments = ESLintUtils.RuleCreator(() => 'https://github.com/tomerh2001/eslint-plugin-th-rules/blob/main/docs/rules/no-comments.md')({
|
|
10
10
|
name: 'no-comments',
|
|
11
11
|
meta: {
|
|
12
12
|
type: 'problem',
|
|
@@ -43,7 +43,6 @@ export default ESLintUtils.RuleCreator(() => 'https://github.com/tomerh2001/esli
|
|
|
43
43
|
const userDisallowedPatterns = (option.disallow ?? []).map(pattern => new RegExp(pattern));
|
|
44
44
|
function isCommentAllowed(comment) {
|
|
45
45
|
const text = comment.value.trim();
|
|
46
|
-
// Allow JSDoc
|
|
47
46
|
if (comment.type === 'Block' && comment.value.startsWith('*')) {
|
|
48
47
|
return true;
|
|
49
48
|
}
|
|
@@ -81,3 +80,4 @@ export default ESLintUtils.RuleCreator(() => 'https://github.com/tomerh2001/esli
|
|
|
81
80
|
};
|
|
82
81
|
},
|
|
83
82
|
});
|
|
83
|
+
export default noComments;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ESLintUtils } from '@typescript-eslint/utils';
|
|
2
|
-
declare const
|
|
2
|
+
declare const noDefaultExport: ESLintUtils.RuleModule<"unnamed", [], unknown, ESLintUtils.RuleListener> & {
|
|
3
3
|
name: string;
|
|
4
4
|
};
|
|
5
|
-
export default
|
|
5
|
+
export default noDefaultExport;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as path from 'node:path';
|
|
2
2
|
import { ESLintUtils } from '@typescript-eslint/utils';
|
|
3
|
-
|
|
3
|
+
const noDefaultExport = ESLintUtils.RuleCreator(() => 'https://github.com/tomerh2001/eslint-plugin-th-rules/blob/main/docs/rules/no-default-export.md')({
|
|
4
4
|
name: 'no-default-export',
|
|
5
5
|
meta: {
|
|
6
6
|
type: 'problem',
|
|
@@ -16,9 +16,7 @@ export default ESLintUtils.RuleCreator(() => 'https://github.com/tomerh2001/esli
|
|
|
16
16
|
defaultOptions: [],
|
|
17
17
|
create(context) {
|
|
18
18
|
function generateExportNameFromFileName(fileName) {
|
|
19
|
-
// Remove all invalid characters, replace with spaces
|
|
20
19
|
const cleaned = fileName.replaceAll(/[^a-zA-Z\d]+/g, ' ');
|
|
21
|
-
// Split into tokens
|
|
22
20
|
const parts = cleaned
|
|
23
21
|
.trim()
|
|
24
22
|
.split(/\s+/g)
|
|
@@ -26,7 +24,6 @@ export default ESLintUtils.RuleCreator(() => 'https://github.com/tomerh2001/esli
|
|
|
26
24
|
if (parts.length === 0) {
|
|
27
25
|
return 'defaultExport';
|
|
28
26
|
}
|
|
29
|
-
// Build camelCase
|
|
30
27
|
const [first, ...rest] = parts;
|
|
31
28
|
return (first.charAt(0).toLowerCase() + first.slice(1)) + rest
|
|
32
29
|
.map(p => p.charAt(0).toUpperCase() + p.slice(1))
|
|
@@ -34,11 +31,9 @@ export default ESLintUtils.RuleCreator(() => 'https://github.com/tomerh2001/esli
|
|
|
34
31
|
}
|
|
35
32
|
return {
|
|
36
33
|
ExportDefaultDeclaration(node) {
|
|
37
|
-
// 1. skip `export default Foo`
|
|
38
34
|
if (node.declaration.type === 'Identifier') {
|
|
39
35
|
return;
|
|
40
36
|
}
|
|
41
|
-
// 2. skip named function/class: `export default function Foo() {}`
|
|
42
37
|
if ('id' in node.declaration && node.declaration.id != null) {
|
|
43
38
|
return;
|
|
44
39
|
}
|
|
@@ -59,3 +54,4 @@ export default ESLintUtils.RuleCreator(() => 'https://github.com/tomerh2001/esli
|
|
|
59
54
|
};
|
|
60
55
|
},
|
|
61
56
|
});
|
|
57
|
+
export default noDefaultExport;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ESLintUtils } from '@typescript-eslint/utils';
|
|
2
|
-
declare const
|
|
2
|
+
declare const noDestructuring: ESLintUtils.RuleModule<"tooDeep" | "tooMany" | "tooLong", [{
|
|
3
3
|
maximumDestructuredVariables: number;
|
|
4
4
|
maximumLineLength: number;
|
|
5
5
|
}], unknown, ESLintUtils.RuleListener> & {
|
|
6
6
|
name: string;
|
|
7
7
|
};
|
|
8
|
-
export default
|
|
8
|
+
export default noDestructuring;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ESLintUtils } from '@typescript-eslint/utils';
|
|
2
2
|
const MAX_TAB_COUNT = 3;
|
|
3
|
-
|
|
3
|
+
const noDestructuring = ESLintUtils.RuleCreator(() => 'https://github.com/tomerh2001/eslint-plugin-th-rules/blob/main/docs/rules/no-destructuring.md')({
|
|
4
4
|
name: 'no-destructuring',
|
|
5
5
|
meta: {
|
|
6
6
|
type: 'problem',
|
|
@@ -85,7 +85,6 @@ export default ESLintUtils.RuleCreator(() => 'https://github.com/tomerh2001/esli
|
|
|
85
85
|
if (!p) {
|
|
86
86
|
continue;
|
|
87
87
|
}
|
|
88
|
-
// (...args = {}) pattern
|
|
89
88
|
if (p.type === 'AssignmentPattern') {
|
|
90
89
|
reportIfNeeded(p.left, p);
|
|
91
90
|
continue;
|
|
@@ -119,3 +118,4 @@ export default ESLintUtils.RuleCreator(() => 'https://github.com/tomerh2001/esli
|
|
|
119
118
|
};
|
|
120
119
|
},
|
|
121
120
|
});
|
|
121
|
+
export default noDestructuring;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ESLintUtils } from
|
|
2
|
-
declare const
|
|
1
|
+
import { ESLintUtils } from '@typescript-eslint/utils';
|
|
2
|
+
declare const preferIsEmpty: ESLintUtils.RuleModule<"useIsEmpty", [], unknown, ESLintUtils.RuleListener> & {
|
|
3
3
|
name: string;
|
|
4
4
|
};
|
|
5
|
-
export default
|
|
5
|
+
export default preferIsEmpty;
|
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
import { ESLintUtils } from
|
|
2
|
-
|
|
3
|
-
name:
|
|
1
|
+
import { ESLintUtils } from '@typescript-eslint/utils';
|
|
2
|
+
const preferIsEmpty = ESLintUtils.RuleCreator(() => 'https://github.com/tomerh2001/eslint-plugin-th-rules/blob/main/docs/rules/prefer-is-empty.md')({
|
|
3
|
+
name: 'prefer-is-empty',
|
|
4
4
|
meta: {
|
|
5
|
-
type:
|
|
5
|
+
type: 'problem',
|
|
6
6
|
docs: {
|
|
7
|
-
description:
|
|
7
|
+
description: 'Require _.isEmpty instead of length comparisons.',
|
|
8
8
|
},
|
|
9
9
|
hasSuggestions: true,
|
|
10
10
|
schema: [],
|
|
11
11
|
messages: {
|
|
12
|
-
useIsEmpty:
|
|
13
|
-
}
|
|
12
|
+
useIsEmpty: 'Use _.isEmpty({{collection}}) instead of checking {{collection}}.length {{operator}} {{value}}.',
|
|
13
|
+
},
|
|
14
14
|
},
|
|
15
15
|
defaultOptions: [],
|
|
16
16
|
create(context) {
|
|
17
17
|
const sourceCode = context.getSourceCode();
|
|
18
18
|
function isLengthAccess(node) {
|
|
19
|
-
return (
|
|
20
|
-
node.type ===
|
|
21
|
-
node.property.type ===
|
|
22
|
-
node.property.name ===
|
|
23
|
-
node.computed
|
|
19
|
+
return (Boolean(node)
|
|
20
|
+
&& node.type === 'MemberExpression'
|
|
21
|
+
&& node.property.type === 'Identifier'
|
|
22
|
+
&& node.property.name === 'length'
|
|
23
|
+
&& !node.computed);
|
|
24
24
|
}
|
|
25
25
|
function isNumericLiteral(node) {
|
|
26
|
-
return (
|
|
27
|
-
node.type ===
|
|
28
|
-
typeof node.value ===
|
|
26
|
+
return (Boolean(node)
|
|
27
|
+
&& node.type === 'Literal'
|
|
28
|
+
&& typeof node.value === 'number');
|
|
29
29
|
}
|
|
30
30
|
function report(node, collectionNode, operator, value, isEmptyCheck) {
|
|
31
31
|
const collectionText = sourceCode.getText(collectionNode.object);
|
|
@@ -34,68 +34,59 @@ export default ESLintUtils.RuleCreator(() => "https://github.com/tomerh2001/esli
|
|
|
34
34
|
: `!_.isEmpty(${collectionText})`;
|
|
35
35
|
context.report({
|
|
36
36
|
node,
|
|
37
|
-
messageId:
|
|
37
|
+
messageId: 'useIsEmpty',
|
|
38
38
|
data: {
|
|
39
39
|
collection: collectionText,
|
|
40
40
|
operator,
|
|
41
|
-
value
|
|
41
|
+
value,
|
|
42
42
|
},
|
|
43
43
|
suggest: [
|
|
44
44
|
{
|
|
45
|
-
messageId:
|
|
45
|
+
messageId: 'useIsEmpty',
|
|
46
46
|
data: {
|
|
47
47
|
collection: collectionText,
|
|
48
48
|
operator,
|
|
49
|
-
value
|
|
49
|
+
value,
|
|
50
50
|
},
|
|
51
51
|
fix(fixer) {
|
|
52
52
|
return fixer.replaceText(node, replacement);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
]
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
58
|
return {
|
|
59
59
|
BinaryExpression(node) {
|
|
60
60
|
const { left, right, operator } = node;
|
|
61
|
-
//
|
|
62
|
-
// Case 1: values.length <op> N
|
|
63
|
-
//
|
|
64
61
|
if (isLengthAccess(left) && isNumericLiteral(right)) {
|
|
65
|
-
const value = right
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
(operator ===
|
|
69
|
-
(operator === "<" && value === 1)) {
|
|
62
|
+
const { value } = right;
|
|
63
|
+
if ((operator === '===' && value === 0)
|
|
64
|
+
|| (operator === '<=' && value === 0)
|
|
65
|
+
|| (operator === '<' && value === 1)) {
|
|
70
66
|
report(node, left, operator, value, true);
|
|
71
67
|
return;
|
|
72
68
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
(operator ===
|
|
76
|
-
((operator === "!=" || operator === "!==") && value === 0)) {
|
|
69
|
+
if ((operator === '>' && value === 0)
|
|
70
|
+
|| (operator === '>=' && value === 1)
|
|
71
|
+
|| ((operator === '!=' || operator === '!==') && value === 0)) {
|
|
77
72
|
report(node, left, operator, value, false);
|
|
78
73
|
}
|
|
79
74
|
}
|
|
80
|
-
//
|
|
81
|
-
// Case 2: N <op> values.length (reverse order)
|
|
82
|
-
//
|
|
83
75
|
if (isNumericLiteral(left) && isLengthAccess(right)) {
|
|
84
|
-
const value = left
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
(operator ===
|
|
88
|
-
(operator === ">" && value === 0)) {
|
|
76
|
+
const { value } = left;
|
|
77
|
+
if ((operator === '===' && value === 0)
|
|
78
|
+
|| (operator === '>=' && value === 0)
|
|
79
|
+
|| (operator === '>' && value === 0)) {
|
|
89
80
|
report(node, right, operator, value, true);
|
|
90
81
|
return;
|
|
91
82
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
(operator === "<=" && value === 0)) {
|
|
83
|
+
if ((operator === '<' && value === 1)
|
|
84
|
+
|| (operator === '<=' && value === 0)) {
|
|
95
85
|
report(node, right, operator, value, false);
|
|
96
86
|
}
|
|
97
87
|
}
|
|
98
|
-
}
|
|
88
|
+
},
|
|
99
89
|
};
|
|
100
|
-
}
|
|
90
|
+
},
|
|
101
91
|
});
|
|
92
|
+
export default preferIsEmpty;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ESLintUtils } from '@typescript-eslint/utils';
|
|
2
|
-
declare const
|
|
2
|
+
declare const schemasInSchemasFile: ESLintUtils.RuleModule<"moveSchema", [{
|
|
3
3
|
allowedSuffixes: string[];
|
|
4
4
|
onlyWhenAssigned: boolean;
|
|
5
5
|
allowInTests: boolean;
|
|
6
6
|
}], unknown, ESLintUtils.RuleListener> & {
|
|
7
7
|
name: string;
|
|
8
8
|
};
|
|
9
|
-
export default
|
|
9
|
+
export default schemasInSchemasFile;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ESLintUtils } from '@typescript-eslint/utils';
|
|
2
|
-
|
|
2
|
+
const schemasInSchemasFile = ESLintUtils.RuleCreator(() => 'https://github.com/tomerh2001/eslint-plugin-th-rules/blob/main/docs/rules/schemas-in-schemas-file.md')({
|
|
3
3
|
name: 'schemas-in-schemas-file',
|
|
4
4
|
meta: {
|
|
5
5
|
type: 'problem',
|
|
@@ -139,3 +139,4 @@ export default ESLintUtils.RuleCreator(() => 'https://github.com/tomerh2001/esli
|
|
|
139
139
|
};
|
|
140
140
|
},
|
|
141
141
|
});
|
|
142
|
+
export default schemasInSchemasFile;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ESLintUtils } from '@typescript-eslint/utils';
|
|
2
|
-
declare const
|
|
2
|
+
declare const topLevelFunctions: ESLintUtils.RuleModule<"arrow" | "funcExpr" | "anonDecl", [], unknown, ESLintUtils.RuleListener> & {
|
|
3
3
|
name: string;
|
|
4
4
|
};
|
|
5
|
-
export default
|
|
5
|
+
export default topLevelFunctions;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ESLintUtils } from '@typescript-eslint/utils';
|
|
2
|
-
|
|
2
|
+
const topLevelFunctions = ESLintUtils.RuleCreator(() => 'https://github.com/tomerh2001/eslint-plugin-th-rules/blob/main/docs/rules/top-level-functions.md')({
|
|
3
3
|
name: 'top-level-functions',
|
|
4
4
|
meta: {
|
|
5
5
|
type: 'suggestion',
|
|
@@ -17,9 +17,6 @@ export default ESLintUtils.RuleCreator(() => 'https://github.com/tomerh2001/esli
|
|
|
17
17
|
defaultOptions: [],
|
|
18
18
|
create(context) {
|
|
19
19
|
const sourceCode = context.getSourceCode();
|
|
20
|
-
//
|
|
21
|
-
// Helpers
|
|
22
|
-
//
|
|
23
20
|
function buildArrowFunctionReplacement(functionName, arrow, isExport) {
|
|
24
21
|
const asyncKeyword = arrow.async ? 'async ' : '';
|
|
25
22
|
const exportKeyword = isExport ? 'export ' : '';
|
|
@@ -31,7 +28,6 @@ export default ESLintUtils.RuleCreator(() => 'https://github.com/tomerh2001/esli
|
|
|
31
28
|
bodyText = sourceCode.getText(arrow.body);
|
|
32
29
|
}
|
|
33
30
|
else {
|
|
34
|
-
// Expression → convert to return
|
|
35
31
|
const expressionText = sourceCode.getText(arrow.body);
|
|
36
32
|
bodyText = `{ return ${expressionText}; }`;
|
|
37
33
|
}
|
|
@@ -63,9 +59,6 @@ export default ESLintUtils.RuleCreator(() => 'https://github.com/tomerh2001/esli
|
|
|
63
59
|
}
|
|
64
60
|
return replaced;
|
|
65
61
|
}
|
|
66
|
-
//
|
|
67
|
-
// Utility
|
|
68
|
-
//
|
|
69
62
|
function isTopLevel(node) {
|
|
70
63
|
const { parent } = node;
|
|
71
64
|
return (parent?.type === 'Program'
|
|
@@ -77,9 +70,6 @@ export default ESLintUtils.RuleCreator(() => 'https://github.com/tomerh2001/esli
|
|
|
77
70
|
return (p?.type === 'ExportNamedDeclaration'
|
|
78
71
|
|| p?.type === 'ExportDefaultDeclaration');
|
|
79
72
|
}
|
|
80
|
-
//
|
|
81
|
-
// Rule
|
|
82
|
-
//
|
|
83
73
|
return {
|
|
84
74
|
VariableDeclarator(node) {
|
|
85
75
|
const declParent = node.parent;
|
|
@@ -102,9 +92,6 @@ export default ESLintUtils.RuleCreator(() => 'https://github.com/tomerh2001/esli
|
|
|
102
92
|
if (!functionName) {
|
|
103
93
|
return;
|
|
104
94
|
}
|
|
105
|
-
//
|
|
106
|
-
// Arrow functions
|
|
107
|
-
//
|
|
108
95
|
if (node.init.type === 'ArrowFunctionExpression') {
|
|
109
96
|
const arrowFunc = node.init;
|
|
110
97
|
context.report({
|
|
@@ -116,9 +103,6 @@ export default ESLintUtils.RuleCreator(() => 'https://github.com/tomerh2001/esli
|
|
|
116
103
|
},
|
|
117
104
|
});
|
|
118
105
|
}
|
|
119
|
-
//
|
|
120
|
-
// Function expressions
|
|
121
|
-
//
|
|
122
106
|
if (node.init.type === 'FunctionExpression') {
|
|
123
107
|
const funcExpr = node.init;
|
|
124
108
|
context.report({
|
|
@@ -134,7 +118,7 @@ export default ESLintUtils.RuleCreator(() => 'https://github.com/tomerh2001/esli
|
|
|
134
118
|
FunctionDeclaration(node) {
|
|
135
119
|
if (node.id) {
|
|
136
120
|
return;
|
|
137
|
-
}
|
|
121
|
+
}
|
|
138
122
|
if (!isTopLevel(node)) {
|
|
139
123
|
return;
|
|
140
124
|
}
|
|
@@ -151,3 +135,4 @@ export default ESLintUtils.RuleCreator(() => 'https://github.com/tomerh2001/esli
|
|
|
151
135
|
};
|
|
152
136
|
},
|
|
153
137
|
});
|
|
138
|
+
export default topLevelFunctions;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { ESLintUtils } from
|
|
2
|
-
declare const
|
|
1
|
+
import { ESLintUtils } from '@typescript-eslint/utils';
|
|
2
|
+
declare const typesInDts: ESLintUtils.RuleModule<"moveToDts", [{
|
|
3
3
|
allowEnums: boolean;
|
|
4
4
|
allowDeclare: boolean;
|
|
5
5
|
}], unknown, ESLintUtils.RuleListener> & {
|
|
6
6
|
name: string;
|
|
7
7
|
};
|
|
8
|
-
export default
|
|
8
|
+
export default typesInDts;
|
|
@@ -1,49 +1,48 @@
|
|
|
1
|
-
import { ESLintUtils } from
|
|
2
|
-
|
|
3
|
-
name:
|
|
1
|
+
import { ESLintUtils } from '@typescript-eslint/utils';
|
|
2
|
+
const typesInDts = ESLintUtils.RuleCreator(() => 'https://github.com/tomerh2001/eslint-plugin-th-rules/blob/main/docs/rules/types-in-dts.md')({
|
|
3
|
+
name: 'types-in-dts',
|
|
4
4
|
meta: {
|
|
5
|
-
type:
|
|
5
|
+
type: 'problem',
|
|
6
6
|
docs: {
|
|
7
|
-
description:
|
|
7
|
+
description: 'Require TypeScript type declarations (type/interface/enum) to be placed in .d.ts files.',
|
|
8
8
|
},
|
|
9
9
|
schema: [
|
|
10
10
|
{
|
|
11
|
-
type:
|
|
11
|
+
type: 'object',
|
|
12
12
|
properties: {
|
|
13
|
-
allowEnums: { type:
|
|
14
|
-
allowDeclare: { type:
|
|
13
|
+
allowEnums: { type: 'boolean' },
|
|
14
|
+
allowDeclare: { type: 'boolean' },
|
|
15
15
|
},
|
|
16
|
-
additionalProperties: false
|
|
17
|
-
}
|
|
16
|
+
additionalProperties: false,
|
|
17
|
+
},
|
|
18
18
|
],
|
|
19
19
|
messages: {
|
|
20
|
-
moveToDts:
|
|
21
|
-
}
|
|
20
|
+
moveToDts: 'Type declarations must be defined in a .d.ts file.',
|
|
21
|
+
},
|
|
22
22
|
},
|
|
23
23
|
defaultOptions: [
|
|
24
24
|
{
|
|
25
25
|
allowEnums: false,
|
|
26
|
-
allowDeclare: false
|
|
27
|
-
}
|
|
26
|
+
allowDeclare: false,
|
|
27
|
+
},
|
|
28
28
|
],
|
|
29
29
|
create(context, [options]) {
|
|
30
30
|
const allowEnums = Boolean(options.allowEnums);
|
|
31
31
|
const allowDeclare = Boolean(options.allowDeclare);
|
|
32
32
|
function isDtsFile(filename) {
|
|
33
|
-
if (!filename || filename ===
|
|
33
|
+
if (!filename || filename === '<input>') {
|
|
34
34
|
return false;
|
|
35
35
|
}
|
|
36
|
-
return filename.endsWith(
|
|
36
|
+
return filename.endsWith('.d.ts');
|
|
37
37
|
}
|
|
38
38
|
function hasDeclareModifier(node) {
|
|
39
|
-
|
|
40
|
-
if ("declare" in node && node.declare === true) {
|
|
39
|
+
if ('declare' in node && node.declare) {
|
|
41
40
|
return true;
|
|
42
41
|
}
|
|
43
|
-
const modifiers =
|
|
42
|
+
const modifiers = 'modifiers' in node && Array.isArray(node.modifiers)
|
|
44
43
|
? node.modifiers
|
|
45
44
|
: [];
|
|
46
|
-
return modifiers.some(m => m?.type ===
|
|
45
|
+
return modifiers.some(m => m?.type === 'TSDeclareKeyword');
|
|
47
46
|
}
|
|
48
47
|
function reportIfNotDts(node) {
|
|
49
48
|
const filename = context.getFilename();
|
|
@@ -55,7 +54,7 @@ export default ESLintUtils.RuleCreator(() => "https://github.com/tomerh2001/esli
|
|
|
55
54
|
}
|
|
56
55
|
context.report({
|
|
57
56
|
node,
|
|
58
|
-
messageId:
|
|
57
|
+
messageId: 'moveToDts',
|
|
59
58
|
});
|
|
60
59
|
}
|
|
61
60
|
return {
|
|
@@ -70,7 +69,8 @@ export default ESLintUtils.RuleCreator(() => "https://github.com/tomerh2001/esli
|
|
|
70
69
|
return;
|
|
71
70
|
}
|
|
72
71
|
reportIfNotDts(node);
|
|
73
|
-
}
|
|
72
|
+
},
|
|
74
73
|
};
|
|
75
|
-
}
|
|
74
|
+
},
|
|
76
75
|
});
|
|
76
|
+
export default typesInDts;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-th-rules",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.1",
|
|
4
4
|
"description": "A List of custom ESLint rules created by Tomer Horowitz",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"eslint",
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@codedependant/semantic-release-docker": "^5.1.1",
|
|
46
46
|
"@eslint/js": "^9.39.2",
|
|
47
|
+
"@leancodepl/resolve-eslint-flat-config": "^9.7.0",
|
|
47
48
|
"@semantic-release/changelog": "^6.0.3",
|
|
48
49
|
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
49
50
|
"@semantic-release/git": "^10.0.1",
|