@futdevpro/dynamo-eslint 1.15.28 → 1.20.2
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/README.md +13 -16
- package/__documentations/2026-08-22-angular-20-phase2-release.md +79 -0
- package/build/configs/base.d.ts +8 -9
- package/build/configs/base.d.ts.map +1 -1
- package/build/configs/base.js +149 -150
- package/build/configs/base.js.map +1 -1
- package/build/configs/fsm.d.ts +1 -1
- package/build/configs/fsm.js +7 -7
- package/build/configs/ngx-package.d.ts +1 -1
- package/build/configs/ngx-package.js +7 -7
- package/build/configs/ngx.d.ts +2 -4
- package/build/configs/ngx.d.ts.map +1 -1
- package/build/configs/ngx.js +88 -91
- package/build/configs/ngx.js.map +1 -1
- package/build/configs/nts-package.d.ts +1 -1
- package/build/configs/nts-package.js +17 -17
- package/build/configs/nts.d.ts +1 -1
- package/build/configs/nts.js +31 -31
- package/build/index.d.ts +1 -1
- package/build/index.js +2 -2
- package/build/plugin/index.d.ts +52 -52
- package/build/plugin/index.js +80 -80
- package/build/plugin/rules/angular/angular-for-track-logic.d.ts +7 -7
- package/build/plugin/rules/angular/angular-for-track-logic.js +81 -81
- package/build/plugin/rules/angular/effect-signal-loop.d.ts +9 -9
- package/build/plugin/rules/angular/effect-signal-loop.js +112 -112
- package/build/plugin/rules/angular/no-async-ngoninit.d.ts +8 -8
- package/build/plugin/rules/angular/no-async-ngoninit.js +42 -42
- package/build/plugin/rules/angular/no-component-direct-api.d.ts +9 -9
- package/build/plugin/rules/angular/no-component-direct-api.js +75 -75
- package/build/plugin/rules/angular/no-method-call-in-template.d.ts +8 -8
- package/build/plugin/rules/angular/no-method-call-in-template.js +79 -79
- package/build/plugin/rules/angular/no-ngfor-directive.d.ts +7 -7
- package/build/plugin/rules/angular/no-ngfor-directive.js +59 -59
- package/build/plugin/rules/angular/no-ngif-directive.d.ts +7 -7
- package/build/plugin/rules/angular/no-ngif-directive.js +59 -59
- package/build/plugin/rules/explicit-types.d.ts +3 -3
- package/build/plugin/rules/explicit-types.js +178 -178
- package/build/plugin/rules/import/import-order.d.ts +3 -3
- package/build/plugin/rules/import/import-order.js +154 -154
- package/build/plugin/rules/import/no-import-type.d.ts +3 -3
- package/build/plugin/rules/import/no-import-type.js +45 -45
- package/build/plugin/rules/import/no-js-import.d.ts +3 -3
- package/build/plugin/rules/import/no-js-import.js +40 -40
- package/build/plugin/rules/naming-patterns.d.ts +7 -7
- package/build/plugin/rules/naming-patterns.js +366 -366
- package/build/plugin/rules/no-getter-logic.d.ts +3 -3
- package/build/plugin/rules/no-getter-logic.js +194 -194
- package/build/plugin/rules/no-getter-logic.js.map +1 -1
- package/build/plugin/rules/prefer-enum-over-string-union.d.ts +3 -3
- package/build/plugin/rules/prefer-enum-over-string-union.js +289 -289
- package/build/plugin/rules/prefer-enum-over-string-union.js.map +1 -1
- package/build/plugin/rules/prefer-interface-over-duplicate-types.d.ts +3 -3
- package/build/plugin/rules/prefer-interface-over-duplicate-types.js +264 -264
- package/build/plugin/rules/prefer-interface-over-duplicate-types.js.map +1 -1
- package/build/plugin/rules/require-jsdoc-description.d.ts +3 -3
- package/build/plugin/rules/require-jsdoc-description.js +496 -496
- package/build/plugin/rules/require-jsdoc-description.js.map +1 -1
- package/build/plugin/rules/require-test-description-prefix.d.ts +3 -3
- package/build/plugin/rules/require-test-description-prefix.js +135 -135
- package/build/plugin/rules/ts/data-model-extends.d.ts +8 -8
- package/build/plugin/rules/ts/data-model-extends.js +94 -94
- package/build/plugin/rules/ts/no-any-type.d.ts +8 -8
- package/build/plugin/rules/ts/no-any-type.js +36 -36
- package/build/plugin/rules/ts/no-as-cast.d.ts +8 -8
- package/build/plugin/rules/ts/no-as-cast.js +49 -49
- package/build/plugin/rules/ts/no-dynamic-imports.d.ts +8 -8
- package/build/plugin/rules/ts/no-dynamic-imports.js +50 -50
- package/build/plugin/rules/ts/no-native-browser-dialogs.d.ts +8 -8
- package/build/plugin/rules/ts/no-native-browser-dialogs.js +78 -78
- package/build/plugin/rules/ts/no-plain-function-export.d.ts +9 -9
- package/build/plugin/rules/ts/no-plain-function-export.js +69 -69
- package/build/plugin/rules/ts/one-export-per-file.d.ts +8 -8
- package/build/plugin/rules/ts/one-export-per-file.js +73 -73
- package/build/scripts/dynamo-fix.d.ts +26 -26
- package/build/scripts/dynamo-fix.js +146 -146
- package/build/scripts/dynamo-fix.js.map +1 -1
- package/build/scripts/eslintrc-audit.d.ts +26 -26
- package/build/scripts/eslintrc-audit.js +100 -100
- package/build/scripts/fix-return-types.d.ts +74 -74
- package/build/scripts/fix-return-types.d.ts.map +1 -1
- package/build/scripts/fix-return-types.js +226 -226
- package/build/scripts/fix-return-types.js.map +1 -1
- package/build/scripts/validate-imports.d.ts +26 -26
- package/build/scripts/validate-imports.js +170 -157
- package/build/scripts/validate-imports.js.map +1 -1
- package/build/scripts/validate-naming.d.ts +26 -26
- package/build/scripts/validate-naming.js +170 -157
- package/build/scripts/validate-naming.js.map +1 -1
- package/eslint.config.js +1 -1
- package/package.json +104 -105
- package/pnpm-workspace.yaml +2 -0
- package/samples/package.json.example +5 -9
- package/src/configs/angular20-compatibility.spec.ts +62 -0
- package/src/configs/base.ts +3 -4
- package/src/configs/ngx.ts +5 -8
- package/src/plugin/rules/no-getter-logic.ts +1 -1
- package/src/plugin/rules/prefer-enum-over-string-union.spec.ts +9 -9
- package/src/plugin/rules/prefer-enum-over-string-union.ts +7 -8
- package/src/plugin/rules/prefer-interface-over-duplicate-types.spec.ts +22 -22
- package/src/plugin/rules/prefer-interface-over-duplicate-types.ts +2 -2
- package/src/plugin/rules/require-jsdoc-description.spec.ts +2 -2
- package/src/plugin/rules/require-jsdoc-description.ts +7 -7
- package/src/scripts/dynamo-fix.ts +1 -1
- package/src/scripts/fix-return-types.ts +4 -3
- package/src/scripts/validate-imports.ts +29 -15
- package/src/scripts/validate-naming.ts +29 -20
- package/src/scripts/validator-cli.integration.spec.ts +11 -8
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The published config is intentionally CommonJS and ESLint's config surface is dynamically typed.
|
|
3
|
+
* These narrow test-only exceptions keep the compatibility assertions faithful to the consumer API.
|
|
4
|
+
*/
|
|
5
|
+
/* eslint-disable @futdevpro/dynamo/no-dynamic-imports, @typescript-eslint/no-require-imports */
|
|
6
|
+
/* eslint-disable @futdevpro/dynamo/no-any-type */
|
|
7
|
+
const angularEslint = require('angular-eslint');
|
|
8
|
+
const ngxConfig = require('./ngx');
|
|
9
|
+
|
|
10
|
+
export {};
|
|
11
|
+
|
|
12
|
+
describe('| Angular 20 flat-config compatibility', (): void => {
|
|
13
|
+
it('| resolves every configured Angular TypeScript rule from the unified plugin', (): void => {
|
|
14
|
+
const typeScriptConfig: any = ngxConfig.find(
|
|
15
|
+
(config: any): boolean => !!config.plugins?.['@angular-eslint'],
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
expect(typeScriptConfig).toBeDefined();
|
|
19
|
+
expect(typeScriptConfig.rules['@angular-eslint/no-host-metadata-property']).toBeUndefined();
|
|
20
|
+
|
|
21
|
+
Object.keys(typeScriptConfig.rules)
|
|
22
|
+
.filter((ruleName: string): boolean => ruleName.startsWith('@angular-eslint/'))
|
|
23
|
+
.forEach((ruleName: string): void => {
|
|
24
|
+
const pluginRuleName: string = ruleName.replace('@angular-eslint/', '');
|
|
25
|
+
|
|
26
|
+
expect(angularEslint.tsPlugin.rules[pluginRuleName])
|
|
27
|
+
.withContext(`Missing Angular 20 TypeScript rule: ${ruleName}`)
|
|
28
|
+
.toBeDefined();
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('| resolves every configured Angular template rule from the unified plugin', (): void => {
|
|
33
|
+
const templateConfig: any = ngxConfig.find(
|
|
34
|
+
(config: any): boolean => !!config.plugins?.['@angular-eslint/template'],
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
expect(templateConfig).toBeDefined();
|
|
38
|
+
|
|
39
|
+
Object.keys(templateConfig.rules)
|
|
40
|
+
.filter((ruleName: string): boolean => ruleName.startsWith('@angular-eslint/template/'))
|
|
41
|
+
.forEach((ruleName: string): void => {
|
|
42
|
+
const pluginRuleName: string = ruleName.replace('@angular-eslint/template/', '');
|
|
43
|
+
|
|
44
|
+
expect(angularEslint.templatePlugin.rules[pluginRuleName])
|
|
45
|
+
.withContext(`Missing Angular 20 template rule: ${ruleName}`)
|
|
46
|
+
.toBeDefined();
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('| exposes the unified Angular parser and plugin objects in the preset', (): void => {
|
|
51
|
+
const typeScriptConfig: any = ngxConfig.find(
|
|
52
|
+
(config: any): boolean => !!config.plugins?.['@angular-eslint'],
|
|
53
|
+
);
|
|
54
|
+
const templateConfig: any = ngxConfig.find(
|
|
55
|
+
(config: any): boolean => !!config.plugins?.['@angular-eslint/template'],
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
expect(typeScriptConfig.plugins['@angular-eslint']).toBe(angularEslint.tsPlugin);
|
|
59
|
+
expect(templateConfig.plugins['@angular-eslint/template']).toBe(angularEslint.templatePlugin);
|
|
60
|
+
expect(templateConfig.languageOptions.parser).toBe(angularEslint.templateParser);
|
|
61
|
+
});
|
|
62
|
+
});
|
package/src/configs/base.ts
CHANGED
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
* Base Rulesets For Dynamo Based Systems
|
|
4
4
|
* ESLint v9 Flat Config Format
|
|
5
5
|
*/
|
|
6
|
-
const
|
|
7
|
-
const tsPlugin = require('@typescript-eslint/eslint-plugin');
|
|
6
|
+
const tsEslint = require('typescript-eslint');
|
|
8
7
|
const unusedImportsPlugin = require('eslint-plugin-unused-imports');
|
|
9
8
|
const maxParamsNoConstructorPlugin = require('eslint-plugin-max-params-no-constructor');
|
|
10
9
|
const dynamoPlugin = require('../plugin');
|
|
@@ -21,7 +20,7 @@ module.exports = [
|
|
|
21
20
|
{
|
|
22
21
|
files: [ '**/*.ts', '**/*.tsx' ],
|
|
23
22
|
languageOptions: {
|
|
24
|
-
parser:
|
|
23
|
+
parser: tsEslint.parser,
|
|
25
24
|
parserOptions: {
|
|
26
25
|
ecmaVersion: 'latest',
|
|
27
26
|
sourceType: 'module',
|
|
@@ -44,7 +43,7 @@ module.exports = [
|
|
|
44
43
|
},
|
|
45
44
|
},
|
|
46
45
|
plugins: {
|
|
47
|
-
'@typescript-eslint':
|
|
46
|
+
'@typescript-eslint': tsEslint.plugin,
|
|
48
47
|
'unused-imports': unusedImportsPlugin,
|
|
49
48
|
'max-params-no-constructor': maxParamsNoConstructorPlugin,
|
|
50
49
|
'@futdevpro/dynamo': dynamoPlugin,
|
package/src/configs/ngx.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
const ngxBaseConfig = require('./base');
|
|
2
|
-
const
|
|
3
|
-
const angularTemplatePlugin = require('@angular-eslint/eslint-plugin-template');
|
|
4
|
-
const angularTemplateParser = require('@angular-eslint/template-parser');
|
|
1
|
+
const ngxBaseConfig = require('./base');
|
|
2
|
+
const angularEslint = require('angular-eslint');
|
|
5
3
|
|
|
6
4
|
/**
|
|
7
5
|
* Rulesets For Dynamo Based Systems
|
|
@@ -31,7 +29,7 @@ module.exports = [
|
|
|
31
29
|
},
|
|
32
30
|
plugins: {
|
|
33
31
|
...ngxBaseConfig[1].plugins,
|
|
34
|
-
'@angular-eslint':
|
|
32
|
+
'@angular-eslint': angularEslint.tsPlugin,
|
|
35
33
|
},
|
|
36
34
|
rules: {
|
|
37
35
|
...ngxBaseConfig[1].rules,
|
|
@@ -39,7 +37,6 @@ module.exports = [
|
|
|
39
37
|
'@angular-eslint/directive-selector': 'error',
|
|
40
38
|
'@angular-eslint/component-selector': 'error',
|
|
41
39
|
'@angular-eslint/no-conflicting-lifecycle': 'error',
|
|
42
|
-
'@angular-eslint/no-host-metadata-property': 'error',
|
|
43
40
|
'@angular-eslint/no-input-rename': 'error',
|
|
44
41
|
'@angular-eslint/no-output-rename': 'error',
|
|
45
42
|
'@angular-eslint/no-outputs-metadata-property': 'error',
|
|
@@ -55,7 +52,7 @@ module.exports = [
|
|
|
55
52
|
{
|
|
56
53
|
files: ['**/*.html'],
|
|
57
54
|
languageOptions: {
|
|
58
|
-
parser:
|
|
55
|
+
parser: angularEslint.templateParser,
|
|
59
56
|
parserOptions: {
|
|
60
57
|
ecmaVersion: 'latest',
|
|
61
58
|
sourceType: 'module',
|
|
@@ -63,7 +60,7 @@ module.exports = [
|
|
|
63
60
|
},
|
|
64
61
|
plugins: {
|
|
65
62
|
...ngxBaseConfig[1].plugins,
|
|
66
|
-
'@angular-eslint/template':
|
|
63
|
+
'@angular-eslint/template': angularEslint.templatePlugin,
|
|
67
64
|
},
|
|
68
65
|
rules: {
|
|
69
66
|
'@angular-eslint/template/banana-in-box': 'error',
|
|
@@ -185,7 +185,7 @@ const rule: Rule.RuleModule = {
|
|
|
185
185
|
},
|
|
186
186
|
create(context) {
|
|
187
187
|
return {
|
|
188
|
-
MethodDefinition(node: any
|
|
188
|
+
MethodDefinition(node: any): void {
|
|
189
189
|
try {
|
|
190
190
|
// Only check getters
|
|
191
191
|
if (node.kind !== 'get') {
|
|
@@ -33,7 +33,7 @@ describe('| prefer-enum-over-string-union', () => {
|
|
|
33
33
|
},
|
|
34
34
|
} as any;
|
|
35
35
|
|
|
36
|
-
rule.TSTypeAliasDeclaration(mockNode);
|
|
36
|
+
rule.TSTypeAliasDeclaration(mockNode, undefined, undefined);
|
|
37
37
|
|
|
38
38
|
expect(reportCalled).toBe(false);
|
|
39
39
|
});
|
|
@@ -68,7 +68,7 @@ describe('| prefer-enum-over-string-union', () => {
|
|
|
68
68
|
},
|
|
69
69
|
} as any;
|
|
70
70
|
|
|
71
|
-
rule.TSTypeAliasDeclaration(mockNode);
|
|
71
|
+
rule.TSTypeAliasDeclaration(mockNode, undefined, undefined);
|
|
72
72
|
|
|
73
73
|
expect(reportCalled).toBe(true);
|
|
74
74
|
});
|
|
@@ -100,7 +100,7 @@ describe('| prefer-enum-over-string-union', () => {
|
|
|
100
100
|
},
|
|
101
101
|
} as any;
|
|
102
102
|
|
|
103
|
-
rule.TSTypeAliasDeclaration(mockNode);
|
|
103
|
+
rule.TSTypeAliasDeclaration(mockNode, undefined, undefined);
|
|
104
104
|
|
|
105
105
|
expect(reportCalled).toBe(false);
|
|
106
106
|
});
|
|
@@ -132,7 +132,7 @@ describe('| prefer-enum-over-string-union', () => {
|
|
|
132
132
|
},
|
|
133
133
|
} as any;
|
|
134
134
|
|
|
135
|
-
rule.TSTypeAliasDeclaration(mockNode);
|
|
135
|
+
rule.TSTypeAliasDeclaration(mockNode, undefined, undefined);
|
|
136
136
|
|
|
137
137
|
expect(reportCalled).toBe(false);
|
|
138
138
|
});
|
|
@@ -168,7 +168,7 @@ describe('| prefer-enum-over-string-union', () => {
|
|
|
168
168
|
parent: { type: 'TSInterfaceDeclaration' },
|
|
169
169
|
} as any;
|
|
170
170
|
|
|
171
|
-
rule.TSPropertySignature(mockNode);
|
|
171
|
+
rule.TSPropertySignature(mockNode, undefined, undefined);
|
|
172
172
|
|
|
173
173
|
expect(reportCalled).toBe(true);
|
|
174
174
|
});
|
|
@@ -478,7 +478,7 @@ describe('| prefer-enum-over-string-union', () => {
|
|
|
478
478
|
},
|
|
479
479
|
} as any;
|
|
480
480
|
|
|
481
|
-
rule.TSTypeAliasDeclaration(mockNode);
|
|
481
|
+
rule.TSTypeAliasDeclaration(mockNode, undefined, undefined);
|
|
482
482
|
|
|
483
483
|
expect(reportCalled).toBe(true);
|
|
484
484
|
});
|
|
@@ -511,7 +511,7 @@ describe('| prefer-enum-over-string-union', () => {
|
|
|
511
511
|
},
|
|
512
512
|
} as any;
|
|
513
513
|
|
|
514
|
-
rule.TSTypeAliasDeclaration(mockNode);
|
|
514
|
+
rule.TSTypeAliasDeclaration(mockNode, undefined, undefined);
|
|
515
515
|
|
|
516
516
|
expect(reportCalled).toBe(true);
|
|
517
517
|
});
|
|
@@ -554,7 +554,7 @@ describe('| prefer-enum-over-string-union', () => {
|
|
|
554
554
|
},
|
|
555
555
|
} as any;
|
|
556
556
|
|
|
557
|
-
rule.TSTypeAliasDeclaration(mockNode);
|
|
557
|
+
rule.TSTypeAliasDeclaration(mockNode, undefined, undefined);
|
|
558
558
|
});
|
|
559
559
|
|
|
560
560
|
it('| should handle errors gracefully', () => {
|
|
@@ -577,7 +577,7 @@ describe('| prefer-enum-over-string-union', () => {
|
|
|
577
577
|
} as any;
|
|
578
578
|
|
|
579
579
|
expect(() => {
|
|
580
|
-
rule.TSTypeAliasDeclaration(malformedNode);
|
|
580
|
+
rule.TSTypeAliasDeclaration(malformedNode, undefined, undefined);
|
|
581
581
|
}).not.toThrow();
|
|
582
582
|
});
|
|
583
583
|
});
|
|
@@ -215,7 +215,7 @@ const rule: Rule.RuleModule = {
|
|
|
215
215
|
|
|
216
216
|
return {
|
|
217
217
|
// Type aliases
|
|
218
|
-
TSTypeAliasDeclaration(node: any
|
|
218
|
+
TSTypeAliasDeclaration(node: any): void {
|
|
219
219
|
try {
|
|
220
220
|
if (allowTypeAliases) {
|
|
221
221
|
return;
|
|
@@ -230,7 +230,7 @@ const rule: Rule.RuleModule = {
|
|
|
230
230
|
},
|
|
231
231
|
|
|
232
232
|
// Interface/type properties
|
|
233
|
-
TSPropertySignature(node: any
|
|
233
|
+
TSPropertySignature(node: any): void {
|
|
234
234
|
try {
|
|
235
235
|
if (isAngularInput(node)) {
|
|
236
236
|
return;
|
|
@@ -247,7 +247,7 @@ const rule: Rule.RuleModule = {
|
|
|
247
247
|
},
|
|
248
248
|
|
|
249
249
|
// Class properties
|
|
250
|
-
PropertyDefinition(node: any
|
|
250
|
+
PropertyDefinition(node: any): void {
|
|
251
251
|
try {
|
|
252
252
|
if (isAngularInput(node)) {
|
|
253
253
|
return;
|
|
@@ -264,7 +264,7 @@ const rule: Rule.RuleModule = {
|
|
|
264
264
|
},
|
|
265
265
|
|
|
266
266
|
// Function parameters
|
|
267
|
-
FunctionDeclaration(node: any
|
|
267
|
+
FunctionDeclaration(node: any): void {
|
|
268
268
|
try {
|
|
269
269
|
if (node.params && Array.isArray(node.params)) {
|
|
270
270
|
node.params.forEach((param: any) => {
|
|
@@ -281,7 +281,7 @@ const rule: Rule.RuleModule = {
|
|
|
281
281
|
},
|
|
282
282
|
|
|
283
283
|
// Arrow function parameters
|
|
284
|
-
ArrowFunctionExpression(node: any
|
|
284
|
+
ArrowFunctionExpression(node: any): void {
|
|
285
285
|
try {
|
|
286
286
|
if (node.params && Array.isArray(node.params)) {
|
|
287
287
|
node.params.forEach((param: any) => {
|
|
@@ -298,7 +298,7 @@ const rule: Rule.RuleModule = {
|
|
|
298
298
|
},
|
|
299
299
|
|
|
300
300
|
// Variable declarations
|
|
301
|
-
VariableDeclarator(node: any
|
|
301
|
+
VariableDeclarator(node: any): void {
|
|
302
302
|
try {
|
|
303
303
|
if (node.typeAnnotation &&
|
|
304
304
|
isStringLiteralUnion(node.typeAnnotation.typeAnnotation) &&
|
|
@@ -311,7 +311,7 @@ const rule: Rule.RuleModule = {
|
|
|
311
311
|
},
|
|
312
312
|
|
|
313
313
|
// Method signatures
|
|
314
|
-
TSMethodSignature(node: any
|
|
314
|
+
TSMethodSignature(node: any): void {
|
|
315
315
|
try {
|
|
316
316
|
if (node.params && Array.isArray(node.params)) {
|
|
317
317
|
node.params.forEach((param: any) => {
|
|
@@ -331,4 +331,3 @@ const rule: Rule.RuleModule = {
|
|
|
331
331
|
};
|
|
332
332
|
|
|
333
333
|
export default rule;
|
|
334
|
-
|
|
@@ -59,8 +59,8 @@ describe('| prefer-interface-over-duplicate-types', () => {
|
|
|
59
59
|
],
|
|
60
60
|
} as any;
|
|
61
61
|
|
|
62
|
-
rule.TSTypeLiteral(mockNode1);
|
|
63
|
-
rule.TSTypeLiteral(mockNode2);
|
|
62
|
+
rule.TSTypeLiteral(mockNode1, undefined, undefined);
|
|
63
|
+
rule.TSTypeLiteral(mockNode2, undefined, undefined);
|
|
64
64
|
rule['Program:exit']({} as any);
|
|
65
65
|
|
|
66
66
|
expect(reportCalled).toBe(false);
|
|
@@ -94,9 +94,9 @@ describe('| prefer-interface-over-duplicate-types', () => {
|
|
|
94
94
|
],
|
|
95
95
|
} as any;
|
|
96
96
|
|
|
97
|
-
rule.TSTypeLiteral(mockNode);
|
|
98
|
-
rule.TSTypeLiteral(mockNode);
|
|
99
|
-
rule.TSTypeLiteral(mockNode);
|
|
97
|
+
rule.TSTypeLiteral(mockNode, undefined, undefined);
|
|
98
|
+
rule.TSTypeLiteral(mockNode, undefined, undefined);
|
|
99
|
+
rule.TSTypeLiteral(mockNode, undefined, undefined);
|
|
100
100
|
rule['Program:exit']({} as any);
|
|
101
101
|
|
|
102
102
|
expect(reportCalled).toBe(true);
|
|
@@ -126,8 +126,8 @@ describe('| prefer-interface-over-duplicate-types', () => {
|
|
|
126
126
|
],
|
|
127
127
|
} as any;
|
|
128
128
|
|
|
129
|
-
rule.TSTypeLiteral(mockNode);
|
|
130
|
-
rule.TSTypeLiteral(mockNode);
|
|
129
|
+
rule.TSTypeLiteral(mockNode, undefined, undefined);
|
|
130
|
+
rule.TSTypeLiteral(mockNode, undefined, undefined);
|
|
131
131
|
rule['Program:exit']({} as any);
|
|
132
132
|
|
|
133
133
|
expect(reportCalled).toBe(true);
|
|
@@ -168,8 +168,8 @@ describe('| prefer-interface-over-duplicate-types', () => {
|
|
|
168
168
|
],
|
|
169
169
|
} as any;
|
|
170
170
|
|
|
171
|
-
rule.TSTypeLiteral(mockNode1);
|
|
172
|
-
rule.TSTypeLiteral(mockNode2);
|
|
171
|
+
rule.TSTypeLiteral(mockNode1, undefined, undefined);
|
|
172
|
+
rule.TSTypeLiteral(mockNode2, undefined, undefined);
|
|
173
173
|
rule['Program:exit']({} as any);
|
|
174
174
|
|
|
175
175
|
expect(reportCalled).toBe(true);
|
|
@@ -200,8 +200,8 @@ describe('| prefer-interface-over-duplicate-types', () => {
|
|
|
200
200
|
],
|
|
201
201
|
} as any;
|
|
202
202
|
|
|
203
|
-
rule.TSTypeLiteral(mockNode);
|
|
204
|
-
rule.TSTypeLiteral(mockNode);
|
|
203
|
+
rule.TSTypeLiteral(mockNode, undefined, undefined);
|
|
204
|
+
rule.TSTypeLiteral(mockNode, undefined, undefined);
|
|
205
205
|
rule['Program:exit']({} as any);
|
|
206
206
|
|
|
207
207
|
expect(reportCalled).toBe(true);
|
|
@@ -232,8 +232,8 @@ describe('| prefer-interface-over-duplicate-types', () => {
|
|
|
232
232
|
],
|
|
233
233
|
} as any;
|
|
234
234
|
|
|
235
|
-
rule.TSTypeLiteral(mockNode);
|
|
236
|
-
rule.TSTypeLiteral(mockNode);
|
|
235
|
+
rule.TSTypeLiteral(mockNode, undefined, undefined);
|
|
236
|
+
rule.TSTypeLiteral(mockNode, undefined, undefined);
|
|
237
237
|
rule['Program:exit']({} as any);
|
|
238
238
|
|
|
239
239
|
expect(reportCalled).toBe(true);
|
|
@@ -286,8 +286,8 @@ describe('| prefer-interface-over-duplicate-types', () => {
|
|
|
286
286
|
// kulcsait használjuk a mockNode.members-ként:
|
|
287
287
|
mockNode.members = [ complexMember, numberMember ];
|
|
288
288
|
|
|
289
|
-
rule.TSTypeLiteral(mockNode);
|
|
290
|
-
rule.TSTypeLiteral(mockNode);
|
|
289
|
+
rule.TSTypeLiteral(mockNode, undefined, undefined);
|
|
290
|
+
rule.TSTypeLiteral(mockNode, undefined, undefined);
|
|
291
291
|
rule['Program:exit']({} as any);
|
|
292
292
|
|
|
293
293
|
// a generált interface a MEGŐRZÖTT function-type-ot tartalmazza, NEM `reference`/`complex`-et
|
|
@@ -321,9 +321,9 @@ describe('| prefer-interface-over-duplicate-types', () => {
|
|
|
321
321
|
],
|
|
322
322
|
} as any;
|
|
323
323
|
|
|
324
|
-
rule.TSTypeLiteral(mockNode);
|
|
325
|
-
rule.TSTypeLiteral(mockNode);
|
|
326
|
-
rule.TSTypeLiteral(mockNode);
|
|
324
|
+
rule.TSTypeLiteral(mockNode, undefined, undefined);
|
|
325
|
+
rule.TSTypeLiteral(mockNode, undefined, undefined);
|
|
326
|
+
rule.TSTypeLiteral(mockNode, undefined, undefined);
|
|
327
327
|
rule['Program:exit']({} as any);
|
|
328
328
|
|
|
329
329
|
expect(reportCalled).toBe(true);
|
|
@@ -365,8 +365,8 @@ describe('| prefer-interface-over-duplicate-types', () => {
|
|
|
365
365
|
],
|
|
366
366
|
} as any;
|
|
367
367
|
|
|
368
|
-
rule.TSTypeLiteral(mockNode);
|
|
369
|
-
rule.TSTypeLiteral(mockNode);
|
|
368
|
+
rule.TSTypeLiteral(mockNode, undefined, undefined);
|
|
369
|
+
rule.TSTypeLiteral(mockNode, undefined, undefined);
|
|
370
370
|
rule['Program:exit']({} as any);
|
|
371
371
|
|
|
372
372
|
expect(reportCalled).toBe(true);
|
|
@@ -396,8 +396,8 @@ describe('| prefer-interface-over-duplicate-types', () => {
|
|
|
396
396
|
|
|
397
397
|
// Should not throw error
|
|
398
398
|
expect(() => {
|
|
399
|
-
rule.TSTypeLiteral(mockNode);
|
|
400
|
-
rule.TSTypeLiteral(mockNode);
|
|
399
|
+
rule.TSTypeLiteral(mockNode, undefined, undefined);
|
|
400
|
+
rule.TSTypeLiteral(mockNode, undefined, undefined);
|
|
401
401
|
rule['Program:exit']({} as any);
|
|
402
402
|
}).not.toThrow();
|
|
403
403
|
});
|
|
@@ -213,7 +213,7 @@ const rule: Rule.RuleModule = {
|
|
|
213
213
|
}
|
|
214
214
|
|
|
215
215
|
return {
|
|
216
|
-
TSTypeLiteral(node: any
|
|
216
|
+
TSTypeLiteral(node: any): void {
|
|
217
217
|
try {
|
|
218
218
|
const signature = normalizeObjectType(node);
|
|
219
219
|
|
|
@@ -236,7 +236,7 @@ const rule: Rule.RuleModule = {
|
|
|
236
236
|
}
|
|
237
237
|
},
|
|
238
238
|
|
|
239
|
-
'Program:exit'(node: any
|
|
239
|
+
'Program:exit'(node: any): void {
|
|
240
240
|
try {
|
|
241
241
|
// Process all collected type usages
|
|
242
242
|
for (const [ signature, usages ] of typeUsages) {
|
|
@@ -246,7 +246,7 @@ describe('| require-jsdoc-description', () => {
|
|
|
246
246
|
loc: { start: { line: 1 } },
|
|
247
247
|
} as any;
|
|
248
248
|
|
|
249
|
-
rule.TSInterfaceDeclaration(mockNode);
|
|
249
|
+
rule.TSInterfaceDeclaration(mockNode, undefined, undefined);
|
|
250
250
|
|
|
251
251
|
expect(reportCalled).toBe(true);
|
|
252
252
|
});
|
|
@@ -273,7 +273,7 @@ describe('| require-jsdoc-description', () => {
|
|
|
273
273
|
loc: { start: { line: 1 } },
|
|
274
274
|
} as any;
|
|
275
275
|
|
|
276
|
-
rule.TSEnumDeclaration(mockNode);
|
|
276
|
+
rule.TSEnumDeclaration(mockNode, undefined, undefined);
|
|
277
277
|
|
|
278
278
|
expect(reportCalled).toBe(true);
|
|
279
279
|
});
|
|
@@ -445,7 +445,7 @@ const rule: Rule.RuleModule = {
|
|
|
445
445
|
|
|
446
446
|
return {
|
|
447
447
|
// Function declarations
|
|
448
|
-
FunctionDeclaration(node: any
|
|
448
|
+
FunctionDeclaration(node: any): void {
|
|
449
449
|
try {
|
|
450
450
|
if (!shouldBeDocumented(node)) {
|
|
451
451
|
return;
|
|
@@ -462,7 +462,7 @@ const rule: Rule.RuleModule = {
|
|
|
462
462
|
},
|
|
463
463
|
|
|
464
464
|
// Function expressions (when assigned to variables)
|
|
465
|
-
VariableDeclarator(node: any
|
|
465
|
+
VariableDeclarator(node: any): void {
|
|
466
466
|
try {
|
|
467
467
|
if (node.init &&
|
|
468
468
|
(node.init.type === 'FunctionExpression' || node.init.type === 'ArrowFunctionExpression')) {
|
|
@@ -482,7 +482,7 @@ const rule: Rule.RuleModule = {
|
|
|
482
482
|
},
|
|
483
483
|
|
|
484
484
|
// Class declarations
|
|
485
|
-
ClassDeclaration(node: any
|
|
485
|
+
ClassDeclaration(node: any): void {
|
|
486
486
|
try {
|
|
487
487
|
if (!shouldBeDocumented(node)) {
|
|
488
488
|
return;
|
|
@@ -499,7 +499,7 @@ const rule: Rule.RuleModule = {
|
|
|
499
499
|
},
|
|
500
500
|
|
|
501
501
|
// Interface declarations
|
|
502
|
-
TSInterfaceDeclaration(node: any
|
|
502
|
+
TSInterfaceDeclaration(node: any): void {
|
|
503
503
|
try {
|
|
504
504
|
if (!shouldBeDocumented(node)) {
|
|
505
505
|
return;
|
|
@@ -516,7 +516,7 @@ const rule: Rule.RuleModule = {
|
|
|
516
516
|
},
|
|
517
517
|
|
|
518
518
|
// Enum declarations
|
|
519
|
-
TSEnumDeclaration(node: any
|
|
519
|
+
TSEnumDeclaration(node: any): void {
|
|
520
520
|
try {
|
|
521
521
|
if (!shouldBeDocumented(node)) {
|
|
522
522
|
return;
|
|
@@ -533,7 +533,7 @@ const rule: Rule.RuleModule = {
|
|
|
533
533
|
},
|
|
534
534
|
|
|
535
535
|
// Type alias declarations (CCAP-megerősítés: exportált `type X = …` kötelező JSDoc).
|
|
536
|
-
TSTypeAliasDeclaration(node: any
|
|
536
|
+
TSTypeAliasDeclaration(node: any): void {
|
|
537
537
|
try {
|
|
538
538
|
if (!shouldBeDocumented(node)) {
|
|
539
539
|
return;
|
|
@@ -550,7 +550,7 @@ const rule: Rule.RuleModule = {
|
|
|
550
550
|
},
|
|
551
551
|
|
|
552
552
|
// Class methods
|
|
553
|
-
MethodDefinition(node: any
|
|
553
|
+
MethodDefinition(node: any): void {
|
|
554
554
|
try {
|
|
555
555
|
if (!shouldBeDocumented(node)) {
|
|
556
556
|
return;
|
|
@@ -64,7 +64,7 @@ async function fixFile(filePath: string): Promise<FixResult> {
|
|
|
64
64
|
{
|
|
65
65
|
files: [ '**/*.{ts,tsx}' ],
|
|
66
66
|
languageOptions: {
|
|
67
|
-
parser: require('
|
|
67
|
+
parser: require('typescript-eslint').parser,
|
|
68
68
|
parserOptions: { ecmaVersion: 2020, sourceType: 'module' },
|
|
69
69
|
},
|
|
70
70
|
plugins: {
|
|
@@ -27,9 +27,10 @@
|
|
|
27
27
|
|
|
28
28
|
import * as ts from 'typescript';
|
|
29
29
|
import * as fs from 'fs';
|
|
30
|
-
import * as path from 'path';
|
|
31
|
-
import fg from 'fast-glob';
|
|
32
|
-
|
|
30
|
+
import * as path from 'path';
|
|
31
|
+
import fg from 'fast-glob';
|
|
32
|
+
|
|
33
|
+
import { DyFM_Log } from '@futdevpro/fsm-dynamo';
|
|
33
34
|
|
|
34
35
|
/**
|
|
35
36
|
* Result of fixing type annotations in a single file
|
|
@@ -111,15 +111,14 @@ import { DyFM_Log } from '@futdevpro/fsm-dynamo';
|
|
|
111
111
|
|
|
112
112
|
import importOrderRule from '../plugin/rules/import/import-order';
|
|
113
113
|
|
|
114
|
-
// The parser is
|
|
115
|
-
//
|
|
116
|
-
|
|
117
|
-
const tsParser = require('@typescript-eslint/parser');
|
|
114
|
+
// The parser is provided by the unified typescript-eslint consumer peer.
|
|
115
|
+
// eslint-disable-next-line @futdevpro/dynamo/no-dynamic-imports, @typescript-eslint/no-require-imports
|
|
116
|
+
const tsParser = require('typescript-eslint').parser;
|
|
118
117
|
|
|
119
118
|
/**
|
|
120
119
|
* Result of validating imports in a single file
|
|
121
120
|
*/
|
|
122
|
-
interface ImportValidationResult {
|
|
121
|
+
interface ImportValidationResult {
|
|
123
122
|
/** Path to the file that was validated */
|
|
124
123
|
file: string;
|
|
125
124
|
/** Array of import validation errors found in the file */
|
|
@@ -133,7 +132,12 @@ interface ImportValidationResult {
|
|
|
133
132
|
/** ID of the ESLint rule that was violated */
|
|
134
133
|
ruleId: string;
|
|
135
134
|
}[];
|
|
136
|
-
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** Identifies the informational diagnostic emitted when isolated validators intentionally ignore inline config. */
|
|
138
|
+
function isIgnoredInlineConfigDiagnostic(message: Linter.LintMessage): boolean {
|
|
139
|
+
return !message.ruleId && message.message.includes("has no effect because you have 'noInlineConfig'");
|
|
140
|
+
}
|
|
137
141
|
|
|
138
142
|
/**
|
|
139
143
|
* Validates import ordering in a single TypeScript file
|
|
@@ -157,8 +161,9 @@ async function validateImportsInFile(filePath: string): Promise<ImportValidation
|
|
|
157
161
|
overrideConfigFile: true,
|
|
158
162
|
overrideConfig: [{
|
|
159
163
|
files: [ '**/*.{ts,tsx}' ],
|
|
160
|
-
linterOptions: {
|
|
161
|
-
|
|
164
|
+
linterOptions: {
|
|
165
|
+
noInlineConfig: true,
|
|
166
|
+
reportUnusedDisableDirectives: 'off',
|
|
162
167
|
},
|
|
163
168
|
languageOptions: {
|
|
164
169
|
parser: tsParser,
|
|
@@ -187,12 +192,14 @@ async function validateImportsInFile(filePath: string): Promise<ImportValidation
|
|
|
187
192
|
// Transform ESLint messages into our result format
|
|
188
193
|
return {
|
|
189
194
|
file: filePath,
|
|
190
|
-
errors: result.messages
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
195
|
+
errors: result.messages
|
|
196
|
+
.filter((message: Linter.LintMessage): boolean => !isIgnoredInlineConfigDiagnostic(message))
|
|
197
|
+
.map((message: Linter.LintMessage): ImportValidationResult['errors'][number] => ({
|
|
198
|
+
line: message.line,
|
|
199
|
+
column: message.column,
|
|
200
|
+
message: message.message,
|
|
201
|
+
ruleId: message.ruleId || 'unknown',
|
|
202
|
+
})),
|
|
196
203
|
};
|
|
197
204
|
}
|
|
198
205
|
|
|
@@ -210,7 +217,14 @@ async function validateImportsInFile(filePath: string): Promise<ImportValidation
|
|
|
210
217
|
async function main(): Promise<void> {
|
|
211
218
|
// Find all TypeScript files, excluding common directories and test files
|
|
212
219
|
const files: string[] = await fg([ '**/*.{ts,tsx}' ], {
|
|
213
|
-
ignore: [
|
|
220
|
+
ignore: [
|
|
221
|
+
'**/node_modules/**',
|
|
222
|
+
'**/build/**',
|
|
223
|
+
'**/dist/**',
|
|
224
|
+
'**/samples/**',
|
|
225
|
+
'**/*.spec.ts',
|
|
226
|
+
'**/*.test.ts',
|
|
227
|
+
],
|
|
214
228
|
});
|
|
215
229
|
|
|
216
230
|
DyFM_Log.log(`[dynamo-validate-imports] Scanning ${files.length} files...`);
|