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/README.md
CHANGED
|
@@ -4,61 +4,76 @@ A comprehensive collection of ESLint Flat configurations for modern web applicat
|
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **TypeScript Linting**: Strict typing rules, consistent imports, and code organization
|
|
8
|
-
- **Angular Support**: Component best practices (including Signals), template
|
|
9
|
-
- **RxJS Guidelines**: Observable patterns, Finnish notation, and operator safety
|
|
7
|
+
- **TypeScript Linting**: Strict typing rules, v8 type-safety replacements, consistent imports, and code organization
|
|
8
|
+
- **Angular Support**: Component best practices (including Signals), Angular 21+ template rules, and modern control flow
|
|
9
|
+
- **RxJS Guidelines**: Observable patterns, Finnish notation, subject encapsulation, and operator safety
|
|
10
10
|
- **Code Style**: Formatting rules, line limits, and structural consistency
|
|
11
11
|
- **Accessibility**: ARIA validation, keyboard events, and semantic HTML
|
|
12
|
-
- **Testing**: Jest
|
|
13
|
-
- **
|
|
12
|
+
- **Testing**: Jest, Vitest, and Playwright configurations with best-practice rules
|
|
13
|
+
- **Prettier**: Automatic disabling of formatting rules that conflict with Prettier
|
|
14
|
+
- **Architecture**: Module boundary enforcement with `eslint-plugin-boundaries`
|
|
15
|
+
- **Additional Support**: JSON (with comment support for tsconfig), Storybook CSF enforcement
|
|
14
16
|
|
|
15
17
|
## Installation
|
|
16
18
|
|
|
17
19
|
```bash
|
|
18
|
-
|
|
20
|
+
pnpm add -D lint-suite
|
|
19
21
|
```
|
|
20
22
|
|
|
21
23
|
## Dependencies
|
|
22
24
|
|
|
23
25
|
```bash
|
|
24
|
-
|
|
26
|
+
pnpm add -D eslint typescript-eslint eslint-config-prettier
|
|
25
27
|
```
|
|
26
28
|
|
|
27
29
|
## Usage
|
|
28
30
|
|
|
29
|
-
Create
|
|
31
|
+
Create an `eslint.config.mjs` file in your project root:
|
|
30
32
|
|
|
31
33
|
```js
|
|
32
|
-
import {
|
|
34
|
+
import { recommended } from 'lint-suite';
|
|
35
|
+
|
|
36
|
+
export default [...recommended];
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Or selectively include configurations:
|
|
40
|
+
|
|
41
|
+
```js
|
|
42
|
+
import { base, javascript, typescript, prettier } from 'lint-suite';
|
|
33
43
|
|
|
34
44
|
export default [
|
|
35
45
|
...base,
|
|
36
46
|
...javascript,
|
|
37
|
-
...typescript
|
|
38
|
-
//
|
|
47
|
+
...typescript,
|
|
48
|
+
...prettier // Must be last to disable conflicting formatting rules
|
|
39
49
|
];
|
|
40
50
|
```
|
|
41
51
|
|
|
42
|
-
You can selectively include configurations you need.
|
|
43
|
-
|
|
44
52
|
## Available Configurations
|
|
45
53
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
54
|
+
| Configuration | Description |
|
|
55
|
+
| ------------------- | -------------------------------------------------------- |
|
|
56
|
+
| `base` | Core JavaScript rules, formatting, and complexity limits |
|
|
57
|
+
| `javascript` | JavaScript-specific rules via `@nx/eslint-plugin` |
|
|
58
|
+
| `typescript` | TypeScript strict typing, imports, and naming conventions |
|
|
59
|
+
| `angular` | Angular component best practices with Signal support |
|
|
60
|
+
| `angularTemplate` | HTML template rules with accessibility and performance |
|
|
61
|
+
| `rxjs` | Observable patterns, operator safety, and subscriptions |
|
|
62
|
+
| `jest` | Jest testing best practices and matchers |
|
|
63
|
+
| `vitest` | Vitest testing rules and matcher improvements |
|
|
64
|
+
| `playwright` | Playwright e2e locator and matcher best practices |
|
|
65
|
+
| `json` | JSON linting with comment support for tsconfig/vscode |
|
|
66
|
+
| `storybook` | Storybook CSF enforcement |
|
|
67
|
+
| `boundaries` | Module boundary rules (feature, data-access, ui, etc.) |
|
|
68
|
+
| `prettier` | Disables rules that conflict with Prettier (use last) |
|
|
69
|
+
| **`recommended`** | **All of the above combined in the correct order** |
|
|
55
70
|
|
|
56
71
|
## Customization
|
|
57
72
|
|
|
58
73
|
You can override any rules by adding a `rules` section to your ESLint config:
|
|
59
74
|
|
|
60
75
|
```js
|
|
61
|
-
import { typescript } from 'lint-suite';
|
|
76
|
+
import { typescript, prettier } from 'lint-suite';
|
|
62
77
|
|
|
63
78
|
export default [
|
|
64
79
|
...typescript,
|
|
@@ -66,7 +81,8 @@ export default [
|
|
|
66
81
|
rules: {
|
|
67
82
|
'@typescript-eslint/explicit-function-return-type': 'off'
|
|
68
83
|
}
|
|
69
|
-
}
|
|
84
|
+
},
|
|
85
|
+
...prettier
|
|
70
86
|
];
|
|
71
87
|
```
|
|
72
88
|
|
|
@@ -80,9 +96,24 @@ export default [
|
|
|
80
96
|
|
|
81
97
|
### eslint-plugin-jest
|
|
82
98
|
|
|
83
|
-
- `jest/
|
|
84
|
-
- `jest/
|
|
85
|
-
- `jest/
|
|
99
|
+
- `jest/consistent-test-it`: Enforces consistent test function usage (`it`)
|
|
100
|
+
- `jest/prefer-comparison-matcher`: Enforces comparison matchers
|
|
101
|
+
- `jest/prefer-hooks-on-top`: Ensures hooks are at the top of describe blocks
|
|
102
|
+
- `jest/no-conditional-in-test`: Warns against conditionals in tests
|
|
103
|
+
- ...
|
|
104
|
+
|
|
105
|
+
### @vitest/eslint-plugin
|
|
106
|
+
|
|
107
|
+
- `vitest/max-nested-describe`: Limits describe nesting depth
|
|
108
|
+
- `vitest/prefer-to-be`: Enforces `toBe` matcher usage
|
|
109
|
+
- `vitest/no-conditional-in-test`: Disallows conditionals in tests
|
|
110
|
+
- ...
|
|
111
|
+
|
|
112
|
+
### eslint-plugin-playwright
|
|
113
|
+
|
|
114
|
+
- `playwright/prefer-locator`: Enforces modern locator API
|
|
115
|
+
- `playwright/prefer-native-locators`: Prefers native locator methods
|
|
116
|
+
- `playwright/prefer-to-be`: Enforces `toBe` matcher usage
|
|
86
117
|
- ...
|
|
87
118
|
|
|
88
119
|
### eslint-plugin-json
|
|
@@ -94,22 +125,23 @@ export default [
|
|
|
94
125
|
### @smarttools/eslint-plugin-rxjs
|
|
95
126
|
|
|
96
127
|
- `@rxjs/finnish`: Enforces Finnish notation for observables
|
|
97
|
-
- `@rxjs/no-
|
|
128
|
+
- `@rxjs/no-exposed-subjects`: Enforces subject encapsulation
|
|
129
|
+
- `@rxjs/no-cyclic-action`: Prevents infinite loops in NgRx effects
|
|
98
130
|
- `@rxjs/no-unsafe-takeuntil`: Ensures proper usage of takeUntil operator
|
|
99
131
|
- ...
|
|
100
132
|
|
|
101
133
|
### eslint-plugin-storybook
|
|
102
134
|
|
|
103
|
-
- `storybook/
|
|
104
|
-
- `storybook/
|
|
105
|
-
- `storybook/hierarchy-separator`: Enforces story hierarchy separators
|
|
135
|
+
- `storybook/csf-component`: Enforces component property in stories
|
|
136
|
+
- `storybook/no-stories-of`: Prevents deprecated `storiesOf` API
|
|
106
137
|
- ...
|
|
107
138
|
|
|
108
|
-
### eslint-plugin-import
|
|
139
|
+
### eslint-plugin-import-x
|
|
109
140
|
|
|
110
|
-
- `import/no-
|
|
111
|
-
- `import/
|
|
112
|
-
- `import/
|
|
141
|
+
- `import-x/no-cycle`: Detects circular dependencies
|
|
142
|
+
- `import-x/no-self-import`: Prevents modules importing themselves
|
|
143
|
+
- `import-x/order`: Enforces a consistent order of import statements
|
|
144
|
+
- `import-x/consistent-type-specifier-style`: Consistent type import style
|
|
113
145
|
- ...
|
|
114
146
|
|
|
115
147
|
### @stylistic/eslint-plugin
|
|
@@ -119,18 +151,17 @@ export default [
|
|
|
119
151
|
- `@stylistic/quotes`: Enforces consistent quote style
|
|
120
152
|
- ...
|
|
121
153
|
|
|
154
|
+
### eslint-config-prettier
|
|
155
|
+
|
|
156
|
+
- Automatically disables all ESLint rules that conflict with Prettier
|
|
157
|
+
- Must be the last configuration in the array
|
|
158
|
+
|
|
122
159
|
## Contributing
|
|
123
160
|
|
|
124
161
|
See [CONTRIBUTING.md](./CONTRIBUTING.md) for contribution guidelines.
|
|
162
|
+
See [CHANGELOG.md](./CHANGELOG.md) for version history.
|
|
163
|
+
See [RELEASE_NOTES.md](./RELEASE_NOTES.md) for detailed release notes.
|
|
125
164
|
|
|
126
165
|
## License
|
|
127
166
|
|
|
128
167
|
MIT
|
|
129
|
-
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
```
|
package/index.cjs
CHANGED
|
@@ -38,6 +38,7 @@ __export(index_exports, {
|
|
|
38
38
|
jest: () => jest,
|
|
39
39
|
json: () => json,
|
|
40
40
|
playwright: () => playwright,
|
|
41
|
+
prettier: () => prettier,
|
|
41
42
|
recommended: () => recommended,
|
|
42
43
|
rxjs: () => rxjs,
|
|
43
44
|
storybook: () => storybook,
|
|
@@ -74,11 +75,27 @@ var angularTemplate = (0, import_config.defineConfig)([
|
|
|
74
75
|
"@angular-eslint/template/prefer-self-closing-tags": "error",
|
|
75
76
|
"@angular-eslint/template/prefer-ngsrc": "error",
|
|
76
77
|
"@angular-eslint/template/prefer-built-in-pipes": "error",
|
|
77
|
-
"@angular-eslint/template/no-call-expression": "error",
|
|
78
78
|
"@angular-eslint/template/no-interpolation-in-attributes": "error",
|
|
79
79
|
"@angular-eslint/template/no-nested-tags": "error",
|
|
80
80
|
"@angular-eslint/template/use-track-by-function": "error",
|
|
81
81
|
"@angular-eslint/template/label-has-associated-control": "error",
|
|
82
|
+
"@angular-eslint/template/prefer-at-else": "error",
|
|
83
|
+
// v21: @if/@else syntax
|
|
84
|
+
"@angular-eslint/template/prefer-at-empty": "error",
|
|
85
|
+
// v21: @for/@empty syntax
|
|
86
|
+
"@angular-eslint/template/prefer-contextual-for-variables": "error",
|
|
87
|
+
// v21: Use $index, $first, etc.
|
|
88
|
+
"@angular-eslint/template/no-empty-control-flow": "error",
|
|
89
|
+
// v21: Catch incomplete refactoring
|
|
90
|
+
"@angular-eslint/template/prefer-class-binding": "error",
|
|
91
|
+
// v21.2.0: Prefer [class] over ngClass
|
|
92
|
+
"@angular-eslint/template/prefer-static-string-properties": "error",
|
|
93
|
+
// Reduce change detection
|
|
94
|
+
"@angular-eslint/template/conditional-complexity": [
|
|
95
|
+
"warn",
|
|
96
|
+
{ maxComplexity: 5 }
|
|
97
|
+
],
|
|
98
|
+
// Template readability
|
|
82
99
|
"@angular-eslint/template/attributes-order": [
|
|
83
100
|
"error",
|
|
84
101
|
{
|
|
@@ -125,7 +142,17 @@ var angular = (0, import_config2.defineConfig)([
|
|
|
125
142
|
"@angular-eslint/use-injectable-provided-in": "error",
|
|
126
143
|
"@angular-eslint/prefer-signal-model": "error",
|
|
127
144
|
"@angular-eslint/no-uncalled-signals": "error",
|
|
128
|
-
"@angular-eslint/prefer-host-metadata-property": "error"
|
|
145
|
+
"@angular-eslint/prefer-host-metadata-property": "error",
|
|
146
|
+
"@angular-eslint/no-implicit-take-until-destroyed": "error",
|
|
147
|
+
// v21.2.0: Enforce explicit DestroyRef
|
|
148
|
+
"@angular-eslint/no-async-lifecycle-method": "error",
|
|
149
|
+
// Prevent async lifecycle hooks
|
|
150
|
+
"@angular-eslint/prefer-output-readonly": "warn",
|
|
151
|
+
// Prevent accidental reassignment
|
|
152
|
+
"@angular-eslint/prefer-output-emitter-ref": "warn",
|
|
153
|
+
// Modern output() function over @Output()
|
|
154
|
+
"@angular-eslint/sort-lifecycle-methods": "warn"
|
|
155
|
+
// Consistent lifecycle method ordering
|
|
129
156
|
}
|
|
130
157
|
}
|
|
131
158
|
]);
|
|
@@ -188,7 +215,10 @@ var base = (0, import_config3.defineConfig)([
|
|
|
188
215
|
"no-useless-concat": "error",
|
|
189
216
|
"prefer-template": "error",
|
|
190
217
|
"no-nested-ternary": "error",
|
|
191
|
-
"no-
|
|
218
|
+
"no-useless-assignment": "error",
|
|
219
|
+
// NEW: Catch unused assignments (ESLint v9)
|
|
220
|
+
"no-object-constructor": "error",
|
|
221
|
+
// Disallow new Object() without arguments
|
|
192
222
|
"no-else-return": ["error", { allowElseIf: false }],
|
|
193
223
|
// Prefer early returns
|
|
194
224
|
"no-multi-assign": "error",
|
|
@@ -370,9 +400,29 @@ var import_config5 = require("eslint/config");
|
|
|
370
400
|
var jest = (0, import_config5.defineConfig)([
|
|
371
401
|
{
|
|
372
402
|
files: ["**/*.spec.ts", "**/*.spec.js"],
|
|
373
|
-
extends: [import_eslint_plugin_jest.default.configs["flat/
|
|
403
|
+
extends: [import_eslint_plugin_jest.default.configs["flat/recommended"]],
|
|
374
404
|
rules: {
|
|
375
|
-
"jest/no-done-callback": "off"
|
|
405
|
+
"jest/no-done-callback": "off",
|
|
406
|
+
// Elevated from recommended defaults
|
|
407
|
+
"jest/no-focused-tests": "error",
|
|
408
|
+
"jest/no-identical-title": "error",
|
|
409
|
+
"jest/valid-expect": "error",
|
|
410
|
+
// Style rules (selective additions from flat/style)
|
|
411
|
+
"jest/prefer-to-be": "warn",
|
|
412
|
+
"jest/prefer-to-contain": "warn",
|
|
413
|
+
"jest/prefer-to-have-length": "warn",
|
|
414
|
+
// Best practice additions
|
|
415
|
+
"jest/consistent-test-it": ["error", { fn: "it" }],
|
|
416
|
+
"jest/prefer-comparison-matcher": "error",
|
|
417
|
+
"jest/prefer-equality-matcher": "error",
|
|
418
|
+
"jest/prefer-hooks-on-top": "error",
|
|
419
|
+
"jest/prefer-spy-on": "error",
|
|
420
|
+
"jest/prefer-strict-equal": "warn",
|
|
421
|
+
"jest/prefer-mock-promise-shorthand": "error",
|
|
422
|
+
"jest/no-conditional-in-test": "warn",
|
|
423
|
+
"jest/no-duplicate-hooks": "error",
|
|
424
|
+
"jest/no-test-return-statement": "error",
|
|
425
|
+
"jest/require-to-throw-message": "warn"
|
|
376
426
|
}
|
|
377
427
|
}
|
|
378
428
|
]);
|
|
@@ -384,13 +434,22 @@ var json = (0, import_config6.defineConfig)([
|
|
|
384
434
|
{
|
|
385
435
|
files: ["**/*.json"],
|
|
386
436
|
extends: [import_eslint_plugin_json.default.configs.recommended]
|
|
437
|
+
},
|
|
438
|
+
{
|
|
439
|
+
files: ["**/tsconfig*.json", "**/.vscode/*.json"],
|
|
440
|
+
extends: [import_eslint_plugin_json.default.configs["recommended-with-comments"]]
|
|
387
441
|
}
|
|
388
442
|
]);
|
|
389
443
|
|
|
444
|
+
// packages/lint-suite/src/lib/prettier.ts
|
|
445
|
+
var import_eslint_config_prettier = __toESM(require("eslint-config-prettier"), 1);
|
|
446
|
+
var import_config7 = require("eslint/config");
|
|
447
|
+
var prettier = (0, import_config7.defineConfig)([import_eslint_config_prettier.default]);
|
|
448
|
+
|
|
390
449
|
// packages/lint-suite/src/lib/rxjs.ts
|
|
391
450
|
var import_eslint_plugin_rxjs = __toESM(require("@smarttools/eslint-plugin-rxjs"), 1);
|
|
392
|
-
var
|
|
393
|
-
var rxjs = (0,
|
|
451
|
+
var import_config8 = require("eslint/config");
|
|
452
|
+
var rxjs = (0, import_config8.defineConfig)([
|
|
394
453
|
{
|
|
395
454
|
files: [
|
|
396
455
|
"**/*.js",
|
|
@@ -446,7 +505,13 @@ var rxjs = (0, import_config7.defineConfig)([
|
|
|
446
505
|
"rxjs/no-unsafe-first": "error",
|
|
447
506
|
"rxjs/no-topromise": "error",
|
|
448
507
|
"rxjs/throw-error": "error",
|
|
449
|
-
"rxjs/no-async-subscribe": "off"
|
|
508
|
+
"rxjs/no-async-subscribe": "off",
|
|
509
|
+
"rxjs/no-exposed-subjects": "error",
|
|
510
|
+
// Enforce subject encapsulation
|
|
511
|
+
"rxjs/no-cyclic-action": "error",
|
|
512
|
+
// Prevent infinite loops in NgRx effects
|
|
513
|
+
"rxjs/no-subscribe-handlers": "warn"
|
|
514
|
+
// Prefer observer objects (complements prefer-observer)
|
|
450
515
|
}
|
|
451
516
|
},
|
|
452
517
|
{
|
|
@@ -459,12 +524,18 @@ var rxjs = (0, import_config7.defineConfig)([
|
|
|
459
524
|
|
|
460
525
|
// packages/lint-suite/src/lib/storybook.ts
|
|
461
526
|
var import_eslint_plugin_storybook = __toESM(require("eslint-plugin-storybook"), 1);
|
|
462
|
-
var
|
|
463
|
-
var storybook = (0,
|
|
527
|
+
var import_config9 = require("eslint/config");
|
|
528
|
+
var storybook = (0, import_config9.defineConfig)([
|
|
464
529
|
{
|
|
465
530
|
ignores: ["!.storybook"],
|
|
466
531
|
files: ["**/*.stories.ts"],
|
|
467
|
-
extends: [import_eslint_plugin_storybook.default.configs["flat/recommended"]]
|
|
532
|
+
extends: [import_eslint_plugin_storybook.default.configs["flat/recommended"]],
|
|
533
|
+
rules: {
|
|
534
|
+
"storybook/csf-component": "warn",
|
|
535
|
+
// Ensure component property is set
|
|
536
|
+
"storybook/no-stories-of": "error"
|
|
537
|
+
// Prevent deprecated storiesOf API
|
|
538
|
+
}
|
|
468
539
|
}
|
|
469
540
|
]);
|
|
470
541
|
|
|
@@ -472,7 +543,7 @@ var storybook = (0, import_config8.defineConfig)([
|
|
|
472
543
|
var import_eslint_plugin4 = require("@nx/eslint-plugin");
|
|
473
544
|
var import_eslint_import_resolver_typescript = require("eslint-import-resolver-typescript");
|
|
474
545
|
var import_eslint_plugin_import_x2 = __toESM(require("eslint-plugin-import-x"), 1);
|
|
475
|
-
var
|
|
546
|
+
var import_config10 = require("eslint/config");
|
|
476
547
|
|
|
477
548
|
// packages/lint-suite/src/lib/rules/explicit-accessibility.ts
|
|
478
549
|
var import_utils = require("@typescript-eslint/utils");
|
|
@@ -613,7 +684,7 @@ var localTypescriptRules = {
|
|
|
613
684
|
"explicit-accessibility": explicit_accessibility_default
|
|
614
685
|
}
|
|
615
686
|
};
|
|
616
|
-
var typescript = (0,
|
|
687
|
+
var typescript = (0, import_config10.defineConfig)([
|
|
617
688
|
// NOTE: Checks for 'prettier' and 'eslint-plugin-prettier'
|
|
618
689
|
{
|
|
619
690
|
files: ["**/*.ts", "**/*.tsx", "**/*.cts", "**/*.mts"],
|
|
@@ -639,6 +710,13 @@ var typescript = (0, import_config9.defineConfig)([
|
|
|
639
710
|
"@typescript-eslint/no-unsafe-member-access": "error",
|
|
640
711
|
"@typescript-eslint/no-unsafe-return": "error",
|
|
641
712
|
"@typescript-eslint/no-unsafe-argument": "error",
|
|
713
|
+
// New v8 type-safety rules (replacements for deprecated ban-types)
|
|
714
|
+
"@typescript-eslint/no-empty-object-type": "error",
|
|
715
|
+
// Bans confusing {} type
|
|
716
|
+
"@typescript-eslint/no-unsafe-function-type": "error",
|
|
717
|
+
// Bans Function type
|
|
718
|
+
"@typescript-eslint/no-wrapper-object-types": "error",
|
|
719
|
+
// Bans Number, String, Boolean wrappers
|
|
642
720
|
// B. Explicit Annotations (partially covered, explicit module boundaries is key)
|
|
643
721
|
"@typescript-eslint/explicit-module-boundary-types": "error",
|
|
644
722
|
// Consider enabling if maximum explicitness is desired, even if verbose:
|
|
@@ -659,8 +737,14 @@ var typescript = (0, import_config9.defineConfig)([
|
|
|
659
737
|
// E. Best Practices & Potential Errors (Some covered by presets, fine-tuning here)
|
|
660
738
|
"@typescript-eslint/no-inferrable-types": "warn",
|
|
661
739
|
// Keep as warn or disable if inference is preferred
|
|
662
|
-
"@typescript-eslint/no-
|
|
663
|
-
// Use ES modules
|
|
740
|
+
"@typescript-eslint/no-require-imports": "error",
|
|
741
|
+
// Use ES modules (replaces deprecated no-var-requires)
|
|
742
|
+
"@typescript-eslint/only-throw-error": "error",
|
|
743
|
+
// Replaces deprecated no-throw-literal
|
|
744
|
+
"@typescript-eslint/no-array-delete": "error",
|
|
745
|
+
// Prevents delete arr[0]
|
|
746
|
+
"@typescript-eslint/return-await": ["error", "in-try-catch"],
|
|
747
|
+
// Better stack traces in try/catch
|
|
664
748
|
"@typescript-eslint/require-await": "error",
|
|
665
749
|
"@typescript-eslint/restrict-template-expressions": [
|
|
666
750
|
"error",
|
|
@@ -680,6 +764,32 @@ var typescript = (0, import_config9.defineConfig)([
|
|
|
680
764
|
"@typescript-eslint/no-useless-constructor": "error",
|
|
681
765
|
"@typescript-eslint/dot-notation": ["error", { allowKeywords: true }],
|
|
682
766
|
// Prefer dot notation where possible
|
|
767
|
+
// Strict type-checked rules
|
|
768
|
+
"@typescript-eslint/no-unnecessary-condition": "error",
|
|
769
|
+
// Catches always-true/false conditions
|
|
770
|
+
"@typescript-eslint/no-confusing-void-expression": "error",
|
|
771
|
+
// Prevent confusing void usage
|
|
772
|
+
"@typescript-eslint/no-dynamic-delete": "error",
|
|
773
|
+
// Use Map instead of delete obj[key]
|
|
774
|
+
"@typescript-eslint/no-extraneous-class": ["error", { allowWithDecorator: true }],
|
|
775
|
+
// Allow Angular classes
|
|
776
|
+
"@typescript-eslint/no-invalid-void-type": "error",
|
|
777
|
+
// Restrict void to return types
|
|
778
|
+
"@typescript-eslint/unified-signatures": "error",
|
|
779
|
+
// Merge overloads where possible
|
|
780
|
+
"@typescript-eslint/no-non-null-asserted-nullish-coalescing": "error",
|
|
781
|
+
// Forbids foo! ?? bar
|
|
782
|
+
// Stylistic type-checked rules
|
|
783
|
+
"@typescript-eslint/prefer-find": "error",
|
|
784
|
+
// Use find() instead of filter()[0]
|
|
785
|
+
"@typescript-eslint/prefer-for-of": "error",
|
|
786
|
+
// Modern iteration
|
|
787
|
+
"@typescript-eslint/prefer-includes": "error",
|
|
788
|
+
// indexOf() → includes()
|
|
789
|
+
"@typescript-eslint/prefer-string-starts-ends-with": "error",
|
|
790
|
+
// Modern string methods
|
|
791
|
+
"@typescript-eslint/prefer-regexp-exec": "error",
|
|
792
|
+
// Better regex performance
|
|
683
793
|
// F. Consistency & Style (Some covered by stylistic-type-checked)
|
|
684
794
|
"@typescript-eslint/consistent-type-assertions": [
|
|
685
795
|
"error",
|
|
@@ -781,10 +891,18 @@ var typescript = (0, import_config9.defineConfig)([
|
|
|
781
891
|
"import-x/no-unresolved": "error",
|
|
782
892
|
"import-x/no-duplicates": "error",
|
|
783
893
|
"import-x/prefer-default-export": "off",
|
|
784
|
-
"import-x/no-useless-path-segments": "error",
|
|
894
|
+
"import-x/no-useless-path-segments": ["error", { noUselessIndex: true }],
|
|
785
895
|
"import-x/newline-after-import": "error",
|
|
786
896
|
"import-x/first": "error",
|
|
787
|
-
"import-x/no-mutable-exports": "error"
|
|
897
|
+
"import-x/no-mutable-exports": "error",
|
|
898
|
+
"import-x/no-self-import": "error",
|
|
899
|
+
// Prevents modules importing themselves
|
|
900
|
+
"import-x/no-cycle": ["error", { maxDepth: 2, ignoreExternal: true }],
|
|
901
|
+
// Prevents circular dependencies
|
|
902
|
+
"import-x/consistent-type-specifier-style": ["error", "prefer-top-level"],
|
|
903
|
+
// Consistent type imports
|
|
904
|
+
"import-x/no-anonymous-default-export": "error"
|
|
905
|
+
// Improve code searchability
|
|
788
906
|
},
|
|
789
907
|
settings: {
|
|
790
908
|
"import-x/resolver-next": [
|
|
@@ -838,38 +956,63 @@ var typescript = (0, import_config9.defineConfig)([
|
|
|
838
956
|
|
|
839
957
|
// packages/lint-suite/src/lib/vitest.ts
|
|
840
958
|
var import_eslint_plugin5 = __toESM(require("@vitest/eslint-plugin"), 1);
|
|
841
|
-
var
|
|
959
|
+
var import_config11 = require("eslint/config");
|
|
842
960
|
var vitestPlugin = {
|
|
843
961
|
vitest: import_eslint_plugin5.default
|
|
844
962
|
};
|
|
845
|
-
var vitest = (0,
|
|
963
|
+
var vitest = (0, import_config11.defineConfig)([
|
|
846
964
|
{
|
|
847
965
|
files: ["**/*.spec.ts", "**/*.spec.js", "**/*.test.ts", "**/*.test.js"],
|
|
848
966
|
plugins: vitestPlugin,
|
|
849
967
|
rules: {
|
|
850
968
|
...import_eslint_plugin5.default.configs.recommended.rules,
|
|
851
|
-
"vitest/max-nested-describe": ["error", { max: 3 }]
|
|
969
|
+
"vitest/max-nested-describe": ["error", { max: 3 }],
|
|
970
|
+
// Matcher improvements
|
|
971
|
+
"vitest/prefer-to-be": "error",
|
|
972
|
+
"vitest/prefer-to-contain": "error",
|
|
973
|
+
"vitest/prefer-to-have-length": "error",
|
|
974
|
+
"vitest/prefer-comparison-matcher": "error",
|
|
975
|
+
"vitest/prefer-strict-equal": "warn",
|
|
976
|
+
// Test quality
|
|
977
|
+
"vitest/prefer-spy-on": "error",
|
|
978
|
+
"vitest/prefer-hooks-on-top": "error",
|
|
979
|
+
"vitest/prefer-each": "warn",
|
|
980
|
+
"vitest/no-conditional-in-test": "error",
|
|
981
|
+
"vitest/no-test-return-statement": "error",
|
|
982
|
+
"vitest/prefer-mock-promise-shorthand": "error"
|
|
852
983
|
}
|
|
853
984
|
}
|
|
854
985
|
]);
|
|
855
986
|
|
|
856
987
|
// packages/lint-suite/src/lib/playwright.ts
|
|
857
988
|
var import_eslint_plugin_playwright = __toESM(require("eslint-plugin-playwright"), 1);
|
|
858
|
-
var
|
|
859
|
-
var playwright = (0,
|
|
989
|
+
var import_config12 = require("eslint/config");
|
|
990
|
+
var playwright = (0, import_config12.defineConfig)([
|
|
860
991
|
{
|
|
861
992
|
...import_eslint_plugin_playwright.default.configs["flat/recommended"],
|
|
862
993
|
files: ["**/*.e2e.ts", "**/*.e2e.js"],
|
|
863
994
|
rules: {
|
|
864
|
-
...import_eslint_plugin_playwright.default.configs["flat/recommended"].rules
|
|
995
|
+
...import_eslint_plugin_playwright.default.configs["flat/recommended"].rules,
|
|
996
|
+
// Locator best practices
|
|
997
|
+
"playwright/prefer-locator": "error",
|
|
998
|
+
"playwright/prefer-native-locators": "error",
|
|
999
|
+
"playwright/no-nth-methods": "warn",
|
|
1000
|
+
// Matcher improvements
|
|
1001
|
+
"playwright/prefer-to-be": "error",
|
|
1002
|
+
"playwright/prefer-to-have-count": "error",
|
|
1003
|
+
"playwright/prefer-to-have-length": "error",
|
|
1004
|
+
"playwright/prefer-comparison-matcher": "error",
|
|
1005
|
+
// Test structure
|
|
1006
|
+
"playwright/prefer-hooks-on-top": "error",
|
|
1007
|
+
"playwright/require-top-level-describe": "warn"
|
|
865
1008
|
}
|
|
866
1009
|
}
|
|
867
1010
|
]);
|
|
868
1011
|
|
|
869
1012
|
// packages/lint-suite/src/lib/boundaries.ts
|
|
870
1013
|
var import_eslint_plugin_boundaries = __toESM(require("eslint-plugin-boundaries"), 1);
|
|
871
|
-
var
|
|
872
|
-
var boundaries = (0,
|
|
1014
|
+
var import_config13 = require("eslint/config");
|
|
1015
|
+
var boundaries = (0, import_config13.defineConfig)([
|
|
873
1016
|
{
|
|
874
1017
|
files: [
|
|
875
1018
|
"**/*.js",
|
|
@@ -917,6 +1060,8 @@ var boundaries = (0, import_config12.defineConfig)([
|
|
|
917
1060
|
},
|
|
918
1061
|
rules: {
|
|
919
1062
|
...import_eslint_plugin_boundaries.default.configs.recommended.rules,
|
|
1063
|
+
"boundaries/no-unknown": "warn",
|
|
1064
|
+
// Warn on imports from uncategorized files
|
|
920
1065
|
"boundaries/element-types": [
|
|
921
1066
|
"error",
|
|
922
1067
|
{
|
|
@@ -973,7 +1118,9 @@ var recommended = [
|
|
|
973
1118
|
...boundaries,
|
|
974
1119
|
...storybook,
|
|
975
1120
|
...vitest,
|
|
976
|
-
...playwright
|
|
1121
|
+
...playwright,
|
|
1122
|
+
...prettier
|
|
1123
|
+
// Must be last to disable formatting rules that conflict with Prettier
|
|
977
1124
|
];
|
|
978
1125
|
// Annotate the CommonJS export names for ESM import in node:
|
|
979
1126
|
0 && (module.exports = {
|
|
@@ -985,6 +1132,7 @@ var recommended = [
|
|
|
985
1132
|
jest,
|
|
986
1133
|
json,
|
|
987
1134
|
playwright,
|
|
1135
|
+
prettier,
|
|
988
1136
|
recommended,
|
|
989
1137
|
rxjs,
|
|
990
1138
|
storybook,
|