lint-suite 1.2.3 → 1.3.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/README.md +72 -43
- package/index.cjs +175 -27
- package/index.cjs.map +4 -4
- package/index.d.ts +2 -1
- package/index.d.ts.map +1 -1
- package/index.js +174 -27
- 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/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
|
@@ -30,6 +30,23 @@ var angularTemplate = defineConfig([
|
|
|
30
30
|
"@angular-eslint/template/no-nested-tags": "error",
|
|
31
31
|
"@angular-eslint/template/use-track-by-function": "error",
|
|
32
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
|
|
33
50
|
"@angular-eslint/template/attributes-order": [
|
|
34
51
|
"error",
|
|
35
52
|
{
|
|
@@ -76,7 +93,17 @@ var angular = defineConfig2([
|
|
|
76
93
|
"@angular-eslint/use-injectable-provided-in": "error",
|
|
77
94
|
"@angular-eslint/prefer-signal-model": "error",
|
|
78
95
|
"@angular-eslint/no-uncalled-signals": "error",
|
|
79
|
-
"@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
|
|
80
107
|
}
|
|
81
108
|
}
|
|
82
109
|
]);
|
|
@@ -139,7 +166,10 @@ var base = defineConfig3([
|
|
|
139
166
|
"no-useless-concat": "error",
|
|
140
167
|
"prefer-template": "error",
|
|
141
168
|
"no-nested-ternary": "error",
|
|
142
|
-
"no-
|
|
169
|
+
"no-useless-assignment": "error",
|
|
170
|
+
// NEW: Catch unused assignments (ESLint v9)
|
|
171
|
+
"no-object-constructor": "error",
|
|
172
|
+
// Disallow new Object() without arguments
|
|
143
173
|
"no-else-return": ["error", { allowElseIf: false }],
|
|
144
174
|
// Prefer early returns
|
|
145
175
|
"no-multi-assign": "error",
|
|
@@ -321,9 +351,29 @@ import { defineConfig as defineConfig5 } from "eslint/config";
|
|
|
321
351
|
var jest = defineConfig5([
|
|
322
352
|
{
|
|
323
353
|
files: ["**/*.spec.ts", "**/*.spec.js"],
|
|
324
|
-
extends: [jestEslint.configs["flat/
|
|
354
|
+
extends: [jestEslint.configs["flat/recommended"]],
|
|
325
355
|
rules: {
|
|
326
|
-
"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"
|
|
327
377
|
}
|
|
328
378
|
}
|
|
329
379
|
]);
|
|
@@ -335,13 +385,22 @@ var json = defineConfig6([
|
|
|
335
385
|
{
|
|
336
386
|
files: ["**/*.json"],
|
|
337
387
|
extends: [jsonEslint.configs.recommended]
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
files: ["**/tsconfig*.json", "**/.vscode/*.json"],
|
|
391
|
+
extends: [jsonEslint.configs["recommended-with-comments"]]
|
|
338
392
|
}
|
|
339
393
|
]);
|
|
340
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
|
+
|
|
341
400
|
// packages/lint-suite/src/lib/rxjs.ts
|
|
342
401
|
import rxjsEslint from "@smarttools/eslint-plugin-rxjs";
|
|
343
|
-
import { defineConfig as
|
|
344
|
-
var rxjs =
|
|
402
|
+
import { defineConfig as defineConfig8 } from "eslint/config";
|
|
403
|
+
var rxjs = defineConfig8([
|
|
345
404
|
{
|
|
346
405
|
files: [
|
|
347
406
|
"**/*.js",
|
|
@@ -397,25 +456,38 @@ var rxjs = defineConfig7([
|
|
|
397
456
|
"rxjs/no-unsafe-first": "error",
|
|
398
457
|
"rxjs/no-topromise": "error",
|
|
399
458
|
"rxjs/throw-error": "error",
|
|
400
|
-
"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)
|
|
401
466
|
}
|
|
402
467
|
},
|
|
403
468
|
{
|
|
404
469
|
files: ["**/*.spec.ts", "**/*.test.ts", "**/*.spec.js", "**/*.test.js"],
|
|
405
470
|
rules: {
|
|
406
|
-
"rxjs/no-ignored-subscription": "off"
|
|
471
|
+
"rxjs/no-ignored-subscription": "off",
|
|
472
|
+
"rxjs/no-subscribe-handlers": "off"
|
|
407
473
|
}
|
|
408
474
|
}
|
|
409
475
|
]);
|
|
410
476
|
|
|
411
477
|
// packages/lint-suite/src/lib/storybook.ts
|
|
412
478
|
import storybookEslint from "eslint-plugin-storybook";
|
|
413
|
-
import { defineConfig as
|
|
414
|
-
var storybook =
|
|
479
|
+
import { defineConfig as defineConfig9 } from "eslint/config";
|
|
480
|
+
var storybook = defineConfig9([
|
|
415
481
|
{
|
|
416
482
|
ignores: ["!.storybook"],
|
|
417
483
|
files: ["**/*.stories.ts"],
|
|
418
|
-
extends: [storybookEslint.configs["flat/recommended"]]
|
|
484
|
+
extends: [storybookEslint.configs["flat/recommended"]],
|
|
485
|
+
rules: {
|
|
486
|
+
"storybook/csf-component": "warn",
|
|
487
|
+
// Ensure component property is set
|
|
488
|
+
"storybook/no-stories-of": "error"
|
|
489
|
+
// Prevent deprecated storiesOf API
|
|
490
|
+
}
|
|
419
491
|
}
|
|
420
492
|
]);
|
|
421
493
|
|
|
@@ -423,7 +495,7 @@ var storybook = defineConfig8([
|
|
|
423
495
|
import { configs as configs5 } from "@nx/eslint-plugin";
|
|
424
496
|
import { createTypeScriptImportResolver } from "eslint-import-resolver-typescript";
|
|
425
497
|
import importPluginX2 from "eslint-plugin-import-x";
|
|
426
|
-
import { defineConfig as
|
|
498
|
+
import { defineConfig as defineConfig10 } from "eslint/config";
|
|
427
499
|
|
|
428
500
|
// packages/lint-suite/src/lib/rules/explicit-accessibility.ts
|
|
429
501
|
import { ESLintUtils, TSESTree } from "@typescript-eslint/utils";
|
|
@@ -564,7 +636,7 @@ var localTypescriptRules = {
|
|
|
564
636
|
"explicit-accessibility": explicit_accessibility_default
|
|
565
637
|
}
|
|
566
638
|
};
|
|
567
|
-
var typescript =
|
|
639
|
+
var typescript = defineConfig10([
|
|
568
640
|
// NOTE: Checks for 'prettier' and 'eslint-plugin-prettier'
|
|
569
641
|
{
|
|
570
642
|
files: ["**/*.ts", "**/*.tsx", "**/*.cts", "**/*.mts"],
|
|
@@ -590,6 +662,13 @@ var typescript = defineConfig9([
|
|
|
590
662
|
"@typescript-eslint/no-unsafe-member-access": "error",
|
|
591
663
|
"@typescript-eslint/no-unsafe-return": "error",
|
|
592
664
|
"@typescript-eslint/no-unsafe-argument": "error",
|
|
665
|
+
// New v8 type-safety rules (replacements for deprecated ban-types)
|
|
666
|
+
"@typescript-eslint/no-empty-object-type": "error",
|
|
667
|
+
// Bans confusing {} type
|
|
668
|
+
"@typescript-eslint/no-unsafe-function-type": "error",
|
|
669
|
+
// Bans Function type
|
|
670
|
+
"@typescript-eslint/no-wrapper-object-types": "error",
|
|
671
|
+
// Bans Number, String, Boolean wrappers
|
|
593
672
|
// B. Explicit Annotations (partially covered, explicit module boundaries is key)
|
|
594
673
|
"@typescript-eslint/explicit-module-boundary-types": "error",
|
|
595
674
|
// Consider enabling if maximum explicitness is desired, even if verbose:
|
|
@@ -610,8 +689,14 @@ var typescript = defineConfig9([
|
|
|
610
689
|
// E. Best Practices & Potential Errors (Some covered by presets, fine-tuning here)
|
|
611
690
|
"@typescript-eslint/no-inferrable-types": "warn",
|
|
612
691
|
// Keep as warn or disable if inference is preferred
|
|
613
|
-
"@typescript-eslint/no-
|
|
614
|
-
// Use ES modules
|
|
692
|
+
"@typescript-eslint/no-require-imports": "error",
|
|
693
|
+
// Use ES modules (replaces deprecated no-var-requires)
|
|
694
|
+
"@typescript-eslint/only-throw-error": "error",
|
|
695
|
+
// Replaces deprecated no-throw-literal
|
|
696
|
+
"@typescript-eslint/no-array-delete": "error",
|
|
697
|
+
// Prevents delete arr[0]
|
|
698
|
+
"@typescript-eslint/return-await": ["error", "in-try-catch"],
|
|
699
|
+
// Better stack traces in try/catch
|
|
615
700
|
"@typescript-eslint/require-await": "error",
|
|
616
701
|
"@typescript-eslint/restrict-template-expressions": [
|
|
617
702
|
"error",
|
|
@@ -631,6 +716,32 @@ var typescript = defineConfig9([
|
|
|
631
716
|
"@typescript-eslint/no-useless-constructor": "error",
|
|
632
717
|
"@typescript-eslint/dot-notation": ["error", { allowKeywords: true }],
|
|
633
718
|
// Prefer dot notation where possible
|
|
719
|
+
// Strict type-checked rules
|
|
720
|
+
"@typescript-eslint/no-unnecessary-condition": "error",
|
|
721
|
+
// Catches always-true/false conditions
|
|
722
|
+
"@typescript-eslint/no-confusing-void-expression": "error",
|
|
723
|
+
// Prevent confusing void usage
|
|
724
|
+
"@typescript-eslint/no-dynamic-delete": "error",
|
|
725
|
+
// Use Map instead of delete obj[key]
|
|
726
|
+
"@typescript-eslint/no-extraneous-class": ["error", { allowWithDecorator: true }],
|
|
727
|
+
// Allow Angular classes
|
|
728
|
+
"@typescript-eslint/no-invalid-void-type": "error",
|
|
729
|
+
// Restrict void to return types
|
|
730
|
+
"@typescript-eslint/unified-signatures": "error",
|
|
731
|
+
// Merge overloads where possible
|
|
732
|
+
"@typescript-eslint/no-non-null-asserted-nullish-coalescing": "error",
|
|
733
|
+
// Forbids foo! ?? bar
|
|
734
|
+
// Stylistic type-checked rules
|
|
735
|
+
"@typescript-eslint/prefer-find": "error",
|
|
736
|
+
// Use find() instead of filter()[0]
|
|
737
|
+
"@typescript-eslint/prefer-for-of": "error",
|
|
738
|
+
// Modern iteration
|
|
739
|
+
"@typescript-eslint/prefer-includes": "error",
|
|
740
|
+
// indexOf() → includes()
|
|
741
|
+
"@typescript-eslint/prefer-string-starts-ends-with": "error",
|
|
742
|
+
// Modern string methods
|
|
743
|
+
"@typescript-eslint/prefer-regexp-exec": "error",
|
|
744
|
+
// Better regex performance
|
|
634
745
|
// F. Consistency & Style (Some covered by stylistic-type-checked)
|
|
635
746
|
"@typescript-eslint/consistent-type-assertions": [
|
|
636
747
|
"error",
|
|
@@ -732,10 +843,18 @@ var typescript = defineConfig9([
|
|
|
732
843
|
"import-x/no-unresolved": "error",
|
|
733
844
|
"import-x/no-duplicates": "error",
|
|
734
845
|
"import-x/prefer-default-export": "off",
|
|
735
|
-
"import-x/no-useless-path-segments": "error",
|
|
846
|
+
"import-x/no-useless-path-segments": ["error", { noUselessIndex: true }],
|
|
736
847
|
"import-x/newline-after-import": "error",
|
|
737
848
|
"import-x/first": "error",
|
|
738
|
-
"import-x/no-mutable-exports": "error"
|
|
849
|
+
"import-x/no-mutable-exports": "error",
|
|
850
|
+
"import-x/no-self-import": "error",
|
|
851
|
+
// Prevents modules importing themselves
|
|
852
|
+
"import-x/no-cycle": ["error", { maxDepth: 2, ignoreExternal: true }],
|
|
853
|
+
// Prevents circular dependencies
|
|
854
|
+
"import-x/consistent-type-specifier-style": ["error", "prefer-top-level"],
|
|
855
|
+
// Consistent type imports
|
|
856
|
+
"import-x/no-anonymous-default-export": "error"
|
|
857
|
+
// Improve code searchability
|
|
739
858
|
},
|
|
740
859
|
settings: {
|
|
741
860
|
"import-x/resolver-next": [
|
|
@@ -760,7 +879,8 @@ var typescript = defineConfig9([
|
|
|
760
879
|
{
|
|
761
880
|
files: ["**/*.action.ts"],
|
|
762
881
|
rules: {
|
|
763
|
-
"@typescript-eslint/no-namespace": "off"
|
|
882
|
+
"@typescript-eslint/no-namespace": "off",
|
|
883
|
+
"@typescript-eslint/no-extraneous-class": "off"
|
|
764
884
|
}
|
|
765
885
|
},
|
|
766
886
|
{
|
|
@@ -789,38 +909,62 @@ var typescript = defineConfig9([
|
|
|
789
909
|
|
|
790
910
|
// packages/lint-suite/src/lib/vitest.ts
|
|
791
911
|
import vitestEslint from "@vitest/eslint-plugin";
|
|
792
|
-
import { defineConfig as
|
|
912
|
+
import { defineConfig as defineConfig11 } from "eslint/config";
|
|
793
913
|
var vitestPlugin = {
|
|
794
914
|
vitest: vitestEslint
|
|
795
915
|
};
|
|
796
|
-
var vitest =
|
|
916
|
+
var vitest = defineConfig11([
|
|
797
917
|
{
|
|
798
918
|
files: ["**/*.spec.ts", "**/*.spec.js", "**/*.test.ts", "**/*.test.js"],
|
|
799
919
|
plugins: vitestPlugin,
|
|
800
920
|
rules: {
|
|
801
921
|
...vitestEslint.configs.recommended.rules,
|
|
802
|
-
"vitest/max-nested-describe": ["error", { max: 3 }]
|
|
922
|
+
"vitest/max-nested-describe": ["error", { max: 3 }],
|
|
923
|
+
// Matcher improvements
|
|
924
|
+
"vitest/prefer-to-be": "error",
|
|
925
|
+
"vitest/prefer-to-contain": "error",
|
|
926
|
+
"vitest/prefer-to-have-length": "error",
|
|
927
|
+
"vitest/prefer-comparison-matcher": "error",
|
|
928
|
+
"vitest/prefer-strict-equal": "warn",
|
|
929
|
+
// Test quality
|
|
930
|
+
"vitest/prefer-spy-on": "error",
|
|
931
|
+
"vitest/prefer-hooks-on-top": "error",
|
|
932
|
+
"vitest/prefer-each": "warn",
|
|
933
|
+
"vitest/no-test-return-statement": "error",
|
|
934
|
+
"vitest/prefer-mock-promise-shorthand": "error"
|
|
803
935
|
}
|
|
804
936
|
}
|
|
805
937
|
]);
|
|
806
938
|
|
|
807
939
|
// packages/lint-suite/src/lib/playwright.ts
|
|
808
940
|
import playwrightEslint from "eslint-plugin-playwright";
|
|
809
|
-
import { defineConfig as
|
|
810
|
-
var playwright =
|
|
941
|
+
import { defineConfig as defineConfig12 } from "eslint/config";
|
|
942
|
+
var playwright = defineConfig12([
|
|
811
943
|
{
|
|
812
944
|
...playwrightEslint.configs["flat/recommended"],
|
|
813
945
|
files: ["**/*.e2e.ts", "**/*.e2e.js"],
|
|
814
946
|
rules: {
|
|
815
|
-
...playwrightEslint.configs["flat/recommended"].rules
|
|
947
|
+
...playwrightEslint.configs["flat/recommended"].rules,
|
|
948
|
+
// Locator best practices
|
|
949
|
+
"playwright/prefer-locator": "error",
|
|
950
|
+
"playwright/prefer-native-locators": "error",
|
|
951
|
+
"playwright/no-nth-methods": "warn",
|
|
952
|
+
// Matcher improvements
|
|
953
|
+
"playwright/prefer-to-be": "error",
|
|
954
|
+
"playwright/prefer-to-have-count": "error",
|
|
955
|
+
"playwright/prefer-to-have-length": "error",
|
|
956
|
+
"playwright/prefer-comparison-matcher": "error",
|
|
957
|
+
// Test structure
|
|
958
|
+
"playwright/prefer-hooks-on-top": "error",
|
|
959
|
+
"playwright/require-top-level-describe": "warn"
|
|
816
960
|
}
|
|
817
961
|
}
|
|
818
962
|
]);
|
|
819
963
|
|
|
820
964
|
// packages/lint-suite/src/lib/boundaries.ts
|
|
821
965
|
import boundariesPlugin from "eslint-plugin-boundaries";
|
|
822
|
-
import { defineConfig as
|
|
823
|
-
var boundaries =
|
|
966
|
+
import { defineConfig as defineConfig13 } from "eslint/config";
|
|
967
|
+
var boundaries = defineConfig13([
|
|
824
968
|
{
|
|
825
969
|
files: [
|
|
826
970
|
"**/*.js",
|
|
@@ -924,7 +1068,9 @@ var recommended = [
|
|
|
924
1068
|
...boundaries,
|
|
925
1069
|
...storybook,
|
|
926
1070
|
...vitest,
|
|
927
|
-
...playwright
|
|
1071
|
+
...playwright,
|
|
1072
|
+
...prettier
|
|
1073
|
+
// Must be last to disable formatting rules that conflict with Prettier
|
|
928
1074
|
];
|
|
929
1075
|
export {
|
|
930
1076
|
angular,
|
|
@@ -935,6 +1081,7 @@ export {
|
|
|
935
1081
|
jest,
|
|
936
1082
|
json,
|
|
937
1083
|
playwright,
|
|
1084
|
+
prettier,
|
|
938
1085
|
recommended,
|
|
939
1086
|
rxjs,
|
|
940
1087
|
storybook,
|