lint-suite 1.2.2 → 1.3.0
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 +74 -43
- package/index.cjs +174 -26
- package/index.cjs.map +4 -4
- package/index.d.ts +2 -1
- package/index.d.ts.map +1 -1
- package/index.js +173 -26
- package/index.js.map +4 -4
- package/lib/angular-template.d.ts.map +1 -1
- package/lib/angular.d.ts.map +1 -1
- package/lib/base.d.ts.map +1 -1
- package/lib/boundaries.d.ts.map +1 -1
- package/lib/jest.d.ts.map +1 -1
- package/lib/json.d.ts.map +1 -1
- package/lib/playwright.d.ts.map +1 -1
- package/lib/prettier.d.ts +2 -0
- package/lib/prettier.d.ts.map +1 -0
- package/lib/rules/explicit-accessibility.d.ts +3 -1
- package/lib/rules/explicit-accessibility.d.ts.map +1 -1
- package/lib/rxjs.d.ts.map +1 -1
- package/lib/storybook.d.ts.map +1 -1
- package/lib/typescript.d.ts.map +1 -1
- package/lib/vitest.d.ts.map +1 -1
- package/package.json +17 -16
package/index.js
CHANGED
|
@@ -26,11 +26,27 @@ var angularTemplate = defineConfig([
|
|
|
26
26
|
"@angular-eslint/template/prefer-self-closing-tags": "error",
|
|
27
27
|
"@angular-eslint/template/prefer-ngsrc": "error",
|
|
28
28
|
"@angular-eslint/template/prefer-built-in-pipes": "error",
|
|
29
|
-
"@angular-eslint/template/no-call-expression": "error",
|
|
30
29
|
"@angular-eslint/template/no-interpolation-in-attributes": "error",
|
|
31
30
|
"@angular-eslint/template/no-nested-tags": "error",
|
|
32
31
|
"@angular-eslint/template/use-track-by-function": "error",
|
|
33
32
|
"@angular-eslint/template/label-has-associated-control": "error",
|
|
33
|
+
"@angular-eslint/template/prefer-at-else": "error",
|
|
34
|
+
// v21: @if/@else syntax
|
|
35
|
+
"@angular-eslint/template/prefer-at-empty": "error",
|
|
36
|
+
// v21: @for/@empty syntax
|
|
37
|
+
"@angular-eslint/template/prefer-contextual-for-variables": "error",
|
|
38
|
+
// v21: Use $index, $first, etc.
|
|
39
|
+
"@angular-eslint/template/no-empty-control-flow": "error",
|
|
40
|
+
// v21: Catch incomplete refactoring
|
|
41
|
+
"@angular-eslint/template/prefer-class-binding": "error",
|
|
42
|
+
// v21.2.0: Prefer [class] over ngClass
|
|
43
|
+
"@angular-eslint/template/prefer-static-string-properties": "error",
|
|
44
|
+
// Reduce change detection
|
|
45
|
+
"@angular-eslint/template/conditional-complexity": [
|
|
46
|
+
"warn",
|
|
47
|
+
{ maxComplexity: 5 }
|
|
48
|
+
],
|
|
49
|
+
// Template readability
|
|
34
50
|
"@angular-eslint/template/attributes-order": [
|
|
35
51
|
"error",
|
|
36
52
|
{
|
|
@@ -77,7 +93,17 @@ var angular = defineConfig2([
|
|
|
77
93
|
"@angular-eslint/use-injectable-provided-in": "error",
|
|
78
94
|
"@angular-eslint/prefer-signal-model": "error",
|
|
79
95
|
"@angular-eslint/no-uncalled-signals": "error",
|
|
80
|
-
"@angular-eslint/prefer-host-metadata-property": "error"
|
|
96
|
+
"@angular-eslint/prefer-host-metadata-property": "error",
|
|
97
|
+
"@angular-eslint/no-implicit-take-until-destroyed": "error",
|
|
98
|
+
// v21.2.0: Enforce explicit DestroyRef
|
|
99
|
+
"@angular-eslint/no-async-lifecycle-method": "error",
|
|
100
|
+
// Prevent async lifecycle hooks
|
|
101
|
+
"@angular-eslint/prefer-output-readonly": "warn",
|
|
102
|
+
// Prevent accidental reassignment
|
|
103
|
+
"@angular-eslint/prefer-output-emitter-ref": "warn",
|
|
104
|
+
// Modern output() function over @Output()
|
|
105
|
+
"@angular-eslint/sort-lifecycle-methods": "warn"
|
|
106
|
+
// Consistent lifecycle method ordering
|
|
81
107
|
}
|
|
82
108
|
}
|
|
83
109
|
]);
|
|
@@ -140,7 +166,10 @@ var base = defineConfig3([
|
|
|
140
166
|
"no-useless-concat": "error",
|
|
141
167
|
"prefer-template": "error",
|
|
142
168
|
"no-nested-ternary": "error",
|
|
143
|
-
"no-
|
|
169
|
+
"no-useless-assignment": "error",
|
|
170
|
+
// NEW: Catch unused assignments (ESLint v9)
|
|
171
|
+
"no-object-constructor": "error",
|
|
172
|
+
// Disallow new Object() without arguments
|
|
144
173
|
"no-else-return": ["error", { allowElseIf: false }],
|
|
145
174
|
// Prefer early returns
|
|
146
175
|
"no-multi-assign": "error",
|
|
@@ -322,9 +351,29 @@ import { defineConfig as defineConfig5 } from "eslint/config";
|
|
|
322
351
|
var jest = defineConfig5([
|
|
323
352
|
{
|
|
324
353
|
files: ["**/*.spec.ts", "**/*.spec.js"],
|
|
325
|
-
extends: [jestEslint.configs["flat/
|
|
354
|
+
extends: [jestEslint.configs["flat/recommended"]],
|
|
326
355
|
rules: {
|
|
327
|
-
"jest/no-done-callback": "off"
|
|
356
|
+
"jest/no-done-callback": "off",
|
|
357
|
+
// Elevated from recommended defaults
|
|
358
|
+
"jest/no-focused-tests": "error",
|
|
359
|
+
"jest/no-identical-title": "error",
|
|
360
|
+
"jest/valid-expect": "error",
|
|
361
|
+
// Style rules (selective additions from flat/style)
|
|
362
|
+
"jest/prefer-to-be": "warn",
|
|
363
|
+
"jest/prefer-to-contain": "warn",
|
|
364
|
+
"jest/prefer-to-have-length": "warn",
|
|
365
|
+
// Best practice additions
|
|
366
|
+
"jest/consistent-test-it": ["error", { fn: "it" }],
|
|
367
|
+
"jest/prefer-comparison-matcher": "error",
|
|
368
|
+
"jest/prefer-equality-matcher": "error",
|
|
369
|
+
"jest/prefer-hooks-on-top": "error",
|
|
370
|
+
"jest/prefer-spy-on": "error",
|
|
371
|
+
"jest/prefer-strict-equal": "warn",
|
|
372
|
+
"jest/prefer-mock-promise-shorthand": "error",
|
|
373
|
+
"jest/no-conditional-in-test": "warn",
|
|
374
|
+
"jest/no-duplicate-hooks": "error",
|
|
375
|
+
"jest/no-test-return-statement": "error",
|
|
376
|
+
"jest/require-to-throw-message": "warn"
|
|
328
377
|
}
|
|
329
378
|
}
|
|
330
379
|
]);
|
|
@@ -336,13 +385,22 @@ var json = defineConfig6([
|
|
|
336
385
|
{
|
|
337
386
|
files: ["**/*.json"],
|
|
338
387
|
extends: [jsonEslint.configs.recommended]
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
files: ["**/tsconfig*.json", "**/.vscode/*.json"],
|
|
391
|
+
extends: [jsonEslint.configs["recommended-with-comments"]]
|
|
339
392
|
}
|
|
340
393
|
]);
|
|
341
394
|
|
|
395
|
+
// packages/lint-suite/src/lib/prettier.ts
|
|
396
|
+
import eslintConfigPrettier from "eslint-config-prettier";
|
|
397
|
+
import { defineConfig as defineConfig7 } from "eslint/config";
|
|
398
|
+
var prettier = defineConfig7([eslintConfigPrettier]);
|
|
399
|
+
|
|
342
400
|
// packages/lint-suite/src/lib/rxjs.ts
|
|
343
401
|
import rxjsEslint from "@smarttools/eslint-plugin-rxjs";
|
|
344
|
-
import { defineConfig as
|
|
345
|
-
var rxjs =
|
|
402
|
+
import { defineConfig as defineConfig8 } from "eslint/config";
|
|
403
|
+
var rxjs = defineConfig8([
|
|
346
404
|
{
|
|
347
405
|
files: [
|
|
348
406
|
"**/*.js",
|
|
@@ -398,7 +456,13 @@ var rxjs = defineConfig7([
|
|
|
398
456
|
"rxjs/no-unsafe-first": "error",
|
|
399
457
|
"rxjs/no-topromise": "error",
|
|
400
458
|
"rxjs/throw-error": "error",
|
|
401
|
-
"rxjs/no-async-subscribe": "off"
|
|
459
|
+
"rxjs/no-async-subscribe": "off",
|
|
460
|
+
"rxjs/no-exposed-subjects": "error",
|
|
461
|
+
// Enforce subject encapsulation
|
|
462
|
+
"rxjs/no-cyclic-action": "error",
|
|
463
|
+
// Prevent infinite loops in NgRx effects
|
|
464
|
+
"rxjs/no-subscribe-handlers": "warn"
|
|
465
|
+
// Prefer observer objects (complements prefer-observer)
|
|
402
466
|
}
|
|
403
467
|
},
|
|
404
468
|
{
|
|
@@ -411,12 +475,18 @@ var rxjs = defineConfig7([
|
|
|
411
475
|
|
|
412
476
|
// packages/lint-suite/src/lib/storybook.ts
|
|
413
477
|
import storybookEslint from "eslint-plugin-storybook";
|
|
414
|
-
import { defineConfig as
|
|
415
|
-
var storybook =
|
|
478
|
+
import { defineConfig as defineConfig9 } from "eslint/config";
|
|
479
|
+
var storybook = defineConfig9([
|
|
416
480
|
{
|
|
417
481
|
ignores: ["!.storybook"],
|
|
418
482
|
files: ["**/*.stories.ts"],
|
|
419
|
-
extends: [storybookEslint.configs["flat/recommended"]]
|
|
483
|
+
extends: [storybookEslint.configs["flat/recommended"]],
|
|
484
|
+
rules: {
|
|
485
|
+
"storybook/csf-component": "warn",
|
|
486
|
+
// Ensure component property is set
|
|
487
|
+
"storybook/no-stories-of": "error"
|
|
488
|
+
// Prevent deprecated storiesOf API
|
|
489
|
+
}
|
|
420
490
|
}
|
|
421
491
|
]);
|
|
422
492
|
|
|
@@ -424,7 +494,7 @@ var storybook = defineConfig8([
|
|
|
424
494
|
import { configs as configs5 } from "@nx/eslint-plugin";
|
|
425
495
|
import { createTypeScriptImportResolver } from "eslint-import-resolver-typescript";
|
|
426
496
|
import importPluginX2 from "eslint-plugin-import-x";
|
|
427
|
-
import { defineConfig as
|
|
497
|
+
import { defineConfig as defineConfig10 } from "eslint/config";
|
|
428
498
|
|
|
429
499
|
// packages/lint-suite/src/lib/rules/explicit-accessibility.ts
|
|
430
500
|
import { ESLintUtils, TSESTree } from "@typescript-eslint/utils";
|
|
@@ -565,7 +635,7 @@ var localTypescriptRules = {
|
|
|
565
635
|
"explicit-accessibility": explicit_accessibility_default
|
|
566
636
|
}
|
|
567
637
|
};
|
|
568
|
-
var typescript =
|
|
638
|
+
var typescript = defineConfig10([
|
|
569
639
|
// NOTE: Checks for 'prettier' and 'eslint-plugin-prettier'
|
|
570
640
|
{
|
|
571
641
|
files: ["**/*.ts", "**/*.tsx", "**/*.cts", "**/*.mts"],
|
|
@@ -591,6 +661,13 @@ var typescript = defineConfig9([
|
|
|
591
661
|
"@typescript-eslint/no-unsafe-member-access": "error",
|
|
592
662
|
"@typescript-eslint/no-unsafe-return": "error",
|
|
593
663
|
"@typescript-eslint/no-unsafe-argument": "error",
|
|
664
|
+
// New v8 type-safety rules (replacements for deprecated ban-types)
|
|
665
|
+
"@typescript-eslint/no-empty-object-type": "error",
|
|
666
|
+
// Bans confusing {} type
|
|
667
|
+
"@typescript-eslint/no-unsafe-function-type": "error",
|
|
668
|
+
// Bans Function type
|
|
669
|
+
"@typescript-eslint/no-wrapper-object-types": "error",
|
|
670
|
+
// Bans Number, String, Boolean wrappers
|
|
594
671
|
// B. Explicit Annotations (partially covered, explicit module boundaries is key)
|
|
595
672
|
"@typescript-eslint/explicit-module-boundary-types": "error",
|
|
596
673
|
// Consider enabling if maximum explicitness is desired, even if verbose:
|
|
@@ -611,8 +688,14 @@ var typescript = defineConfig9([
|
|
|
611
688
|
// E. Best Practices & Potential Errors (Some covered by presets, fine-tuning here)
|
|
612
689
|
"@typescript-eslint/no-inferrable-types": "warn",
|
|
613
690
|
// Keep as warn or disable if inference is preferred
|
|
614
|
-
"@typescript-eslint/no-
|
|
615
|
-
// Use ES modules
|
|
691
|
+
"@typescript-eslint/no-require-imports": "error",
|
|
692
|
+
// Use ES modules (replaces deprecated no-var-requires)
|
|
693
|
+
"@typescript-eslint/only-throw-error": "error",
|
|
694
|
+
// Replaces deprecated no-throw-literal
|
|
695
|
+
"@typescript-eslint/no-array-delete": "error",
|
|
696
|
+
// Prevents delete arr[0]
|
|
697
|
+
"@typescript-eslint/return-await": ["error", "in-try-catch"],
|
|
698
|
+
// Better stack traces in try/catch
|
|
616
699
|
"@typescript-eslint/require-await": "error",
|
|
617
700
|
"@typescript-eslint/restrict-template-expressions": [
|
|
618
701
|
"error",
|
|
@@ -632,6 +715,32 @@ var typescript = defineConfig9([
|
|
|
632
715
|
"@typescript-eslint/no-useless-constructor": "error",
|
|
633
716
|
"@typescript-eslint/dot-notation": ["error", { allowKeywords: true }],
|
|
634
717
|
// Prefer dot notation where possible
|
|
718
|
+
// Strict type-checked rules
|
|
719
|
+
"@typescript-eslint/no-unnecessary-condition": "error",
|
|
720
|
+
// Catches always-true/false conditions
|
|
721
|
+
"@typescript-eslint/no-confusing-void-expression": "error",
|
|
722
|
+
// Prevent confusing void usage
|
|
723
|
+
"@typescript-eslint/no-dynamic-delete": "error",
|
|
724
|
+
// Use Map instead of delete obj[key]
|
|
725
|
+
"@typescript-eslint/no-extraneous-class": ["error", { allowWithDecorator: true }],
|
|
726
|
+
// Allow Angular classes
|
|
727
|
+
"@typescript-eslint/no-invalid-void-type": "error",
|
|
728
|
+
// Restrict void to return types
|
|
729
|
+
"@typescript-eslint/unified-signatures": "error",
|
|
730
|
+
// Merge overloads where possible
|
|
731
|
+
"@typescript-eslint/no-non-null-asserted-nullish-coalescing": "error",
|
|
732
|
+
// Forbids foo! ?? bar
|
|
733
|
+
// Stylistic type-checked rules
|
|
734
|
+
"@typescript-eslint/prefer-find": "error",
|
|
735
|
+
// Use find() instead of filter()[0]
|
|
736
|
+
"@typescript-eslint/prefer-for-of": "error",
|
|
737
|
+
// Modern iteration
|
|
738
|
+
"@typescript-eslint/prefer-includes": "error",
|
|
739
|
+
// indexOf() → includes()
|
|
740
|
+
"@typescript-eslint/prefer-string-starts-ends-with": "error",
|
|
741
|
+
// Modern string methods
|
|
742
|
+
"@typescript-eslint/prefer-regexp-exec": "error",
|
|
743
|
+
// Better regex performance
|
|
635
744
|
// F. Consistency & Style (Some covered by stylistic-type-checked)
|
|
636
745
|
"@typescript-eslint/consistent-type-assertions": [
|
|
637
746
|
"error",
|
|
@@ -733,10 +842,18 @@ var typescript = defineConfig9([
|
|
|
733
842
|
"import-x/no-unresolved": "error",
|
|
734
843
|
"import-x/no-duplicates": "error",
|
|
735
844
|
"import-x/prefer-default-export": "off",
|
|
736
|
-
"import-x/no-useless-path-segments": "error",
|
|
845
|
+
"import-x/no-useless-path-segments": ["error", { noUselessIndex: true }],
|
|
737
846
|
"import-x/newline-after-import": "error",
|
|
738
847
|
"import-x/first": "error",
|
|
739
|
-
"import-x/no-mutable-exports": "error"
|
|
848
|
+
"import-x/no-mutable-exports": "error",
|
|
849
|
+
"import-x/no-self-import": "error",
|
|
850
|
+
// Prevents modules importing themselves
|
|
851
|
+
"import-x/no-cycle": ["error", { maxDepth: 2, ignoreExternal: true }],
|
|
852
|
+
// Prevents circular dependencies
|
|
853
|
+
"import-x/consistent-type-specifier-style": ["error", "prefer-top-level"],
|
|
854
|
+
// Consistent type imports
|
|
855
|
+
"import-x/no-anonymous-default-export": "error"
|
|
856
|
+
// Improve code searchability
|
|
740
857
|
},
|
|
741
858
|
settings: {
|
|
742
859
|
"import-x/resolver-next": [
|
|
@@ -790,38 +907,63 @@ var typescript = defineConfig9([
|
|
|
790
907
|
|
|
791
908
|
// packages/lint-suite/src/lib/vitest.ts
|
|
792
909
|
import vitestEslint from "@vitest/eslint-plugin";
|
|
793
|
-
import { defineConfig as
|
|
910
|
+
import { defineConfig as defineConfig11 } from "eslint/config";
|
|
794
911
|
var vitestPlugin = {
|
|
795
912
|
vitest: vitestEslint
|
|
796
913
|
};
|
|
797
|
-
var vitest =
|
|
914
|
+
var vitest = defineConfig11([
|
|
798
915
|
{
|
|
799
916
|
files: ["**/*.spec.ts", "**/*.spec.js", "**/*.test.ts", "**/*.test.js"],
|
|
800
917
|
plugins: vitestPlugin,
|
|
801
918
|
rules: {
|
|
802
919
|
...vitestEslint.configs.recommended.rules,
|
|
803
|
-
"vitest/max-nested-describe": ["error", { max: 3 }]
|
|
920
|
+
"vitest/max-nested-describe": ["error", { max: 3 }],
|
|
921
|
+
// Matcher improvements
|
|
922
|
+
"vitest/prefer-to-be": "error",
|
|
923
|
+
"vitest/prefer-to-contain": "error",
|
|
924
|
+
"vitest/prefer-to-have-length": "error",
|
|
925
|
+
"vitest/prefer-comparison-matcher": "error",
|
|
926
|
+
"vitest/prefer-strict-equal": "warn",
|
|
927
|
+
// Test quality
|
|
928
|
+
"vitest/prefer-spy-on": "error",
|
|
929
|
+
"vitest/prefer-hooks-on-top": "error",
|
|
930
|
+
"vitest/prefer-each": "warn",
|
|
931
|
+
"vitest/no-conditional-in-test": "error",
|
|
932
|
+
"vitest/no-test-return-statement": "error",
|
|
933
|
+
"vitest/prefer-mock-promise-shorthand": "error"
|
|
804
934
|
}
|
|
805
935
|
}
|
|
806
936
|
]);
|
|
807
937
|
|
|
808
938
|
// packages/lint-suite/src/lib/playwright.ts
|
|
809
939
|
import playwrightEslint from "eslint-plugin-playwright";
|
|
810
|
-
import { defineConfig as
|
|
811
|
-
var playwright =
|
|
940
|
+
import { defineConfig as defineConfig12 } from "eslint/config";
|
|
941
|
+
var playwright = defineConfig12([
|
|
812
942
|
{
|
|
813
943
|
...playwrightEslint.configs["flat/recommended"],
|
|
814
944
|
files: ["**/*.e2e.ts", "**/*.e2e.js"],
|
|
815
945
|
rules: {
|
|
816
|
-
...playwrightEslint.configs["flat/recommended"].rules
|
|
946
|
+
...playwrightEslint.configs["flat/recommended"].rules,
|
|
947
|
+
// Locator best practices
|
|
948
|
+
"playwright/prefer-locator": "error",
|
|
949
|
+
"playwright/prefer-native-locators": "error",
|
|
950
|
+
"playwright/no-nth-methods": "warn",
|
|
951
|
+
// Matcher improvements
|
|
952
|
+
"playwright/prefer-to-be": "error",
|
|
953
|
+
"playwright/prefer-to-have-count": "error",
|
|
954
|
+
"playwright/prefer-to-have-length": "error",
|
|
955
|
+
"playwright/prefer-comparison-matcher": "error",
|
|
956
|
+
// Test structure
|
|
957
|
+
"playwright/prefer-hooks-on-top": "error",
|
|
958
|
+
"playwright/require-top-level-describe": "warn"
|
|
817
959
|
}
|
|
818
960
|
}
|
|
819
961
|
]);
|
|
820
962
|
|
|
821
963
|
// packages/lint-suite/src/lib/boundaries.ts
|
|
822
964
|
import boundariesPlugin from "eslint-plugin-boundaries";
|
|
823
|
-
import { defineConfig as
|
|
824
|
-
var boundaries =
|
|
965
|
+
import { defineConfig as defineConfig13 } from "eslint/config";
|
|
966
|
+
var boundaries = defineConfig13([
|
|
825
967
|
{
|
|
826
968
|
files: [
|
|
827
969
|
"**/*.js",
|
|
@@ -869,6 +1011,8 @@ var boundaries = defineConfig12([
|
|
|
869
1011
|
},
|
|
870
1012
|
rules: {
|
|
871
1013
|
...boundariesPlugin.configs.recommended.rules,
|
|
1014
|
+
"boundaries/no-unknown": "warn",
|
|
1015
|
+
// Warn on imports from uncategorized files
|
|
872
1016
|
"boundaries/element-types": [
|
|
873
1017
|
"error",
|
|
874
1018
|
{
|
|
@@ -925,7 +1069,9 @@ var recommended = [
|
|
|
925
1069
|
...boundaries,
|
|
926
1070
|
...storybook,
|
|
927
1071
|
...vitest,
|
|
928
|
-
...playwright
|
|
1072
|
+
...playwright,
|
|
1073
|
+
...prettier
|
|
1074
|
+
// Must be last to disable formatting rules that conflict with Prettier
|
|
929
1075
|
];
|
|
930
1076
|
export {
|
|
931
1077
|
angular,
|
|
@@ -936,6 +1082,7 @@ export {
|
|
|
936
1082
|
jest,
|
|
937
1083
|
json,
|
|
938
1084
|
playwright,
|
|
1085
|
+
prettier,
|
|
939
1086
|
recommended,
|
|
940
1087
|
rxjs,
|
|
941
1088
|
storybook,
|