lint-suite 2.1.1 → 2.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/CHANGELOG.md CHANGED
@@ -1,3 +1,87 @@
1
+ ## 2.3.0 (2026-10-11)
2
+
3
+ ### 🚀 Features
4
+
5
+ - ⚠️ **lint-suite:** ✨ add workspace project boundaries enforcement ([3c1ca35](https://github.com/F0rty-Tw0/lint-suite/commit/3c1ca35))
6
+ - ⚠️ **lint-suite:** ✨ add new ESLint rules and stylelint configuration ([c004e95](https://github.com/F0rty-Tw0/lint-suite/commit/c004e95))
7
+ - ⚠️ **tests:** ✨ add `reportedRuleIds` utility function for ESLint ([15f4794](https://github.com/F0rty-Tw0/lint-suite/commit/15f4794))
8
+ - ⚠️ **tests:** ✨ add tests for angular, boundaries, and playwright ([5e43275](https://github.com/F0rty-Tw0/lint-suite/commit/5e43275))
9
+ - ⚠️ **lint-suite:** ✨ drop nx's legacy settings from the JS and TS presets ([a63e5e5](https://github.com/F0rty-Tw0/lint-suite/commit/a63e5e5))
10
+ - ⚠️ **lint-suite:** ✨ drop the @nx/eslint-plugin dependency ([79d6b62](https://github.com/F0rty-Tw0/lint-suite/commit/79d6b62))
11
+
12
+ ### ⚠️ Breaking Changes
13
+
14
+ - **lint-suite:** ✨ add workspace project boundaries enforcement ([3c1ca35](https://github.com/F0rty-Tw0/lint-suite/commit/3c1ca35))
15
+ projects tagged `type:lib` or `type:app` cannot
16
+ import each other; untagged projects are unconstrained. See
17
+ migration details in the documentation.
18
+ - **lint-suite:** ✨ add new ESLint rules and stylelint configuration ([c004e95](https://github.com/F0rty-Tw0/lint-suite/commit/c004e95))
19
+ - **tests:** ✨ add `reportedRuleIds` utility function for ESLint ([15f4794](https://github.com/F0rty-Tw0/lint-suite/commit/15f4794))
20
+ - **tests:** ✨ add tests for angular, boundaries, and playwright ([5e43275](https://github.com/F0rty-Tw0/lint-suite/commit/5e43275))
21
+ - **lint-suite:** ✨ drop nx's legacy settings from the JS and TS presets ([a63e5e5](https://github.com/F0rty-Tw0/lint-suite/commit/a63e5e5))
22
+ JS files report the 18 core bug rules and no longer
23
+ get @typescript-eslint/* rules; ecmaVersion is latest; .cjs files get
24
+ CommonJS scoping; @typescript-eslint/no-empty-interface is no longer
25
+ set. Migrations are in RELEASE_NOTES.md.
26
+ - **lint-suite:** ✨ drop the @nx/eslint-plugin dependency ([79d6b62](https://github.com/F0rty-Tw0/lint-suite/commit/79d6b62))
27
+ the @nx plugin is no longer registered; composing
28
+ base/javascript/typescript without prettier now reports formatting
29
+ rules nx's prettier append used to turn off; the default TS
30
+ tsconfigRootDir is process.cwd() instead of the Nx workspace root.
31
+ Migrations are in RELEASE_NOTES.md.
32
+
33
+ ### 🧱 Updated Dependencies
34
+
35
+ - Updated eslint-plugin-arrow-body-fits-line to 1.1.0
36
+ - Updated eslint-plugin-chain-fits-line to 1.1.0
37
+ - Updated eslint-plugin-chain-receiver-is-name to 1.1.0
38
+ - Updated eslint-plugin-explicit-accessibility to 1.1.0
39
+ - Updated eslint-plugin-max-condition-operands to 1.1.0
40
+ - Updated eslint-plugin-modular-boundaries to 1.0.0
41
+ - Updated eslint-plugin-no-call-in-condition to 1.1.0
42
+ - Updated eslint-plugin-no-grouped-condition to 1.1.0
43
+ - Updated eslint-plugin-no-inline-object-types to 1.1.0
44
+ - Updated eslint-plugin-no-inline-return-object to 1.1.0
45
+ - Updated eslint-plugin-no-nested-object-value to 1.1.0
46
+ - Updated eslint-plugin-no-spread-expression to 1.1.0
47
+ - Updated eslint-plugin-no-unused-exports to 1.1.0
48
+ - Updated eslint-plugin-one-line-guard to 1.1.0
49
+ - Updated eslint-plugin-readonly-type-properties to 1.1.0
50
+ - Updated eslint-plugin-ternary-branch-shape to 1.1.0
51
+ - Updated eslint-plugin-test-file-shape to 1.1.0
52
+ - Updated eslint-plugin-type-placement to 1.1.0
53
+ - Updated eslint-plugin-util-purity to 1.1.0
54
+ - Updated eslint-plugin-no-unused-angular-instance-fields to 1.2.0
55
+ - Updated eslint-plugin-no-unstyled-classes to 1.1.0
56
+ - Updated stylelint-no-unused-classes to 1.1.0
57
+
58
+ ### ❤️ Thank You
59
+
60
+ - Artiom Tofan
61
+ - F0rty-Tw0
62
+
63
+ ## 2.2.0 (2026-09-23)
64
+
65
+ ### 🚀 Features
66
+
67
+ - ⚠️ **eslint-plugin:** ✨ report unread inputs, outputs, and queries ([57ab38a](https://github.com/F0rty-Tw0/lint-suite/commit/57ab38a))
68
+ - **eslint-plugin:** ✨ add `allowRxjsInteropFields` option ([faa7d90](https://github.com/F0rty-Tw0/lint-suite/commit/faa7d90))
69
+
70
+ ### ⚠️ Breaking Changes
71
+
72
+ - **eslint-plugin:** ✨ report unread inputs, outputs, and queries ([57ab38a](https://github.com/F0rty-Tw0/lint-suite/commit/57ab38a))
73
+ unread inputs, outputs, and queries are now reported
74
+ by default.
75
+ Claude-Session: https://claude.ai/code/session_01GNCvxVFjNTyt6y9q281siN
76
+
77
+ ### 🧱 Updated Dependencies
78
+
79
+ - Updated eslint-plugin-no-unused-angular-instance-fields to 1.1.0
80
+
81
+ ### ❤️ Thank You
82
+
83
+ - Artiom Tofan
84
+
1
85
  ## 2.1.1 (2026-09-11)
2
86
 
3
87
  ### 🚀 Features
@@ -40,6 +124,37 @@
40
124
 
41
125
  ## [Unreleased]
42
126
 
127
+ ### Breaking Changes
128
+
129
+ - **Workspace project boundaries**: `boundaries`, and so `recommended`, now
130
+ enables `modular-boundaries/modular-boundaries` from
131
+ `@lint-suite/eslint-plugin-modular-boundaries`. Projects tagged `type:lib`
132
+ or `type:app` cannot import a project tagged `type:app`; untagged projects
133
+ are unconstrained. The rule's default cycle and undeclared-dependency checks
134
+ are on. See `RELEASE_NOTES.md` for migration.
135
+ - **`@nx/eslint-plugin` dropped**: the `@nx` plugin is no longer registered,
136
+ and the `javascript` and `typescript` presets are rebuilt on `@eslint/js`
137
+ and `typescript-eslint` recommended. See `RELEASE_NOTES.md` for the full
138
+ list and migrations.
139
+
140
+ ### Dependencies
141
+
142
+ - `angular-eslint` 22.5.0, `typescript-eslint` 8.71.1, `globals` 17.13.0,
143
+ `@eslint/json` 2.1.1, `eslint-plugin-playwright` 2.12.1,
144
+ `eslint-plugin-storybook` 10.6.1, `stylelint` 17.16.0, `stylelint-scss`
145
+ 7.3.0. The ESLint peer range stays `^10.9.1`.
146
+ - New upstream rules enabled at `error`: typescript-eslint
147
+ `no-generated-empty-object-type` and `no-unsafe-enum-assignment`; Angular
148
+ `reactive-context-must-read-signal` and template `prefer-style-binding`;
149
+ Playwright `no-export`, `no-test-return-statement`,
150
+ `no-template-literal-title`, `prefer-ending-with-an-expect`,
151
+ `require-annotation-reason`, `no-action-timeout` and `no-magic-timeouts`;
152
+ Stylelint `selector-no-unmatchable`.
153
+ - `playwright` now warns on `playwright/no-identical-title`, added to
154
+ `eslint-plugin-playwright`'s `flat/recommended` in 2.12.
155
+
156
+ ## [2.1.1] - 2026-09-11
157
+
43
158
  ### Features
44
159
 
45
160
  - All 21 custom rules are independently installable as scoped ESLint and
package/README.md CHANGED
@@ -24,7 +24,7 @@ The suite includes custom rules for TypeScript code structure, unused exports, u
24
24
  - **Prettier**: Automatic disabling of formatting rules that conflict with Prettier (`eslint-config-prettier`)
25
25
  - **Prettier config**: Standalone formatting preset (subpath `lint-suite/prettier`) with the suite's house defaults and Angular/HTML overrides
26
26
  - **Stylelint**: Standalone SCSS/CSS preset (subpath `lint-suite/stylelint`) with standard + recess-order + BEM selector enforcement and `lint-suite/no-unused-classes`
27
- - **Architecture**: Module boundary enforcement with `eslint-plugin-boundaries`
27
+ - **Architecture**: Folder layer boundaries with `eslint-plugin-boundaries`, and workspace project boundaries by tag with `@lint-suite/eslint-plugin-modular-boundaries`
28
28
  - **Additional Support**: JSON (with comment support for tsconfig), Storybook CSF enforcement
29
29
 
30
30
  ## Installation
@@ -35,7 +35,7 @@ pnpm add -D lint-suite
35
35
 
36
36
  ## Standalone custom rules
37
37
 
38
- All 21 custom rules also have independently versioned scoped packages.
38
+ All 22 custom rules also have independently versioned scoped packages.
39
39
  Installing one does not install this umbrella or its unrelated presets.
40
40
  For example:
41
41
 
@@ -64,9 +64,7 @@ remains `no-unused-instance-fields`. The Stylelint package is
64
64
  `@lint-suite/stylelint-no-unused-classes`, with rule ID
65
65
  `lint-suite/no-unused-classes`.
66
66
 
67
- No migration is needed for existing umbrella users: its three entrypoints,
68
- presets, rule IDs, severities, and options are unchanged. Avoid enabling a
69
- standalone rule alongside the corresponding umbrella rule.
67
+ Avoid enabling a standalone rule alongside the corresponding umbrella rule.
70
68
 
71
69
  ## Dependencies
72
70
 
@@ -135,7 +133,7 @@ export default [
135
133
  | Configuration | Description |
136
134
  | ----------------- | ---------------------------------------------------------------------------------------------------------------------- |
137
135
  | `base` | Core JavaScript rules, formatting, and complexity limits |
138
- | `javascript` | JavaScript-specific rules via `@nx/eslint-plugin` |
136
+ | `javascript` | JavaScript-specific rules (`@eslint/js` recommended) |
139
137
  | `typescript` | TypeScript strict typing, imports, and naming conventions |
140
138
  | `angular` | Angular component best practices with Signal support |
141
139
  | `angularTemplate` | HTML template rules with accessibility, performance, and `lint-suite-angular-template/no-unstyled-classes` |
@@ -144,7 +142,7 @@ export default [
144
142
  | `playwright` | Playwright e2e locator and matcher best practices |
145
143
  | `json` | JSON linting with comment support for tsconfig/vscode |
146
144
  | `storybook` | Storybook CSF enforcement |
147
- | `boundaries` | Module boundary rules (feature, data-access, ui, etc.) |
145
+ | `boundaries` | Folder layer rules (feature, data-access, ui, etc.) and workspace project rules by tag (`type:app` is a leaf) |
148
146
  | `prettier` | Disables rules that conflict with Prettier (use last) |
149
147
  | **`recommended`** | **Baseline only: `base` + `javascript` + `typescript` + `json` + `boundaries` + `prettier` — compose the rest on top** |
150
148
 
@@ -194,6 +192,58 @@ export default [
194
192
  ];
195
193
  ```
196
194
 
195
+ ### Workspace project boundaries
196
+
197
+ The `boundaries` config enables `modular-boundaries/modular-boundaries` from
198
+ [`@lint-suite/eslint-plugin-modular-boundaries`](https://github.com/F0rty-Tw0/lint-suite/tree/master/packages/eslint-plugin/modular-boundaries#readme).
199
+ It reads pnpm, npm, Nx, Turborepo and moon workspace files and checks imports
200
+ between workspace projects. Outside a workspace it does nothing.
201
+
202
+ The preset's constraints make `type:app` projects leaves: a project tagged
203
+ `type:lib` or `type:app` cannot import a project tagged `type:app`. Untagged
204
+ projects are unconstrained. Tag a project in `project.json` `tags`,
205
+ `package.json` `nx.tags`, or a top-level `package.json` `tags` array:
206
+
207
+ ```json
208
+ { "name": "@acme/web", "tags": ["type:app"] }
209
+ ```
210
+
211
+ The rule's default checks also run: cycles between projects, relative imports
212
+ into another project, self-imports by package name, and packages a project's
213
+ own `package.json` does not declare. That last check includes tooling
214
+ installed only at the workspace root, such as `vitest` imported from a
215
+ package's specs; declare it in the package's `devDependencies`, or set
216
+ `checkUndeclaredDependencies: false`.
217
+
218
+ To change the options, set the rule again in a later entry. ESLint replaces
219
+ options rather than merging them, so repeat the `depConstraints` you keep:
220
+
221
+ ```js
222
+ import { recommended } from 'lint-suite/eslint';
223
+
224
+ export default [
225
+ ...recommended,
226
+ {
227
+ rules: {
228
+ 'modular-boundaries/modular-boundaries': [
229
+ 'error',
230
+ {
231
+ depConstraints: [
232
+ { sourceTag: 'type:lib', notDependOnLibsWithTags: ['type:app'] },
233
+ { sourceTag: 'type:app', notDependOnLibsWithTags: ['type:app'] },
234
+ { sourceTag: '*', onlyDependOnLibsWithTags: ['*'] }
235
+ ],
236
+ checkUndeclaredDependencies: false
237
+ }
238
+ ]
239
+ }
240
+ }
241
+ ];
242
+ ```
243
+
244
+ With `eslint --cache`, a cycle created by editing one file is not reported in
245
+ other, unchanged files until they are linted again.
246
+
197
247
  ### Unused Angular instance fields
198
248
 
199
249
  The `angular` config enables `lint-suite-angular/no-unused-instance-fields`.
@@ -246,8 +296,17 @@ files and Angular templates. It requires parser services with type information:
246
296
  - `allowEffectFields` defaults to `false`. When enabled, fields holding
247
297
  auto-cleaned Angular `effect()` calls are allowed; effects configured with
248
298
  `manualCleanup: true` must still be read.
249
- - Angular signal inputs, models, outputs, and query fields are always treated
250
- as framework-managed.
299
+ - `allowRxjsInteropFields` defaults to `false`. When enabled, unread fields
300
+ holding `@angular/core/rxjs-interop` calls (`toSignal`, `toObservable`,
301
+ `outputToObservable`, `rxResource`) are allowed.
302
+ - Inputs, outputs, and queries (`input()`, `model()`, `output()`,
303
+ `viewChild()`, `viewChildren()`, `contentChild()`, `contentChildren()`, and
304
+ the matching `@Input()`, `@Output()`, `@ViewChild()`, `@ViewChildren()`,
305
+ `@ContentChild()`, and `@ContentChildren()` fields) are reported when the
306
+ class, its template, and its host metadata never read them. Parent bindings
307
+ do not count as reads. `outputFromObservable()` fields, `@Output()` fields
308
+ not initialized with `new EventEmitter()`, and inputs of classes that declare
309
+ `ngOnChanges` are always treated as framework-managed.
251
310
  - Fields typed with `ComponentRef` imported from `@angular/core` are excluded
252
311
  from unused-field reports.
253
312
  - In local mode, non-private members of `abstract` components and directives
@@ -698,12 +757,6 @@ The Prettier preset is published with `prettier` as a peer dependency. The Style
698
757
 
699
758
  ## Available Rules (you can add more as you prefer)
700
759
 
701
- ### nx/eslint-plugin
702
-
703
- - `@nx/enforce-module-boundaries`: Enforces module boundary restrictions
704
- - `@nx/dependency-checks`: Validates dependencies in workspace projects
705
- - ...
706
-
707
760
  ### @vitest/eslint-plugin
708
761
 
709
762
  - `vitest/max-nested-describe`: Limits describe nesting depth
@@ -766,6 +819,7 @@ The Prettier preset is published with `prettier` as a peer dependency. The Style
766
819
  - `plugin/selector-bem-pattern`: enforces BEM selectors, treats `*.component.scss`/`*.component.css` as implicit components, ignores `--mdc`/`--sys` custom properties
767
820
  - `lint-suite/no-unused-classes`: reports a class selector no template of the component uses (see [No unused classes](#no-unused-classes))
768
821
  - `no-descending-specificity`: disabled
822
+ - `selector-no-unmatchable`: reports selectors that can never match, such as a pseudo-element inside `:is()`
769
823
 
770
824
  ### prettier (format config)
771
825
 
package/eslint.js CHANGED
@@ -50,6 +50,8 @@ var angularTemplate = defineConfig([
50
50
  // v21: Catch incomplete refactoring
51
51
  "@angular-eslint/template/prefer-class-binding": "error",
52
52
  // v21.2.0: Prefer [class] over ngClass
53
+ "@angular-eslint/template/prefer-style-binding": "error",
54
+ // v22.4: Prefer [style] over ngStyle
53
55
  "@angular-eslint/template/prefer-static-string-properties": "error",
54
56
  // Reduce change detection
55
57
  "@angular-eslint/template/no-non-null-assertion": "error",
@@ -139,6 +141,8 @@ var angular = defineConfig2([
139
141
  // Consistent lifecycle method ordering
140
142
  "@angular-eslint/computed-must-return": "error",
141
143
  // Catch silent computed() bugs missing a return
144
+ "@angular-eslint/reactive-context-must-read-signal": "error",
145
+ // v22.3: computed/linkedSignal/effect that reads no signal never re-runs
142
146
  "@angular-eslint/no-duplicates-in-metadata-arrays": "error",
143
147
  // Catch duplicate imports/providers in @Component/@NgModule
144
148
  "@angular-eslint/no-lifecycle-call": "error",
@@ -359,12 +363,10 @@ var basePractices = defineConfig4([
359
363
  ]);
360
364
 
361
365
  // packages/lint-suite/src/lib/base-recommended.ts
362
- import { configs as configs3 } from "@nx/eslint-plugin";
363
366
  import stylistic from "@stylistic/eslint-plugin";
364
367
  import { defineConfig as defineConfig5 } from "eslint/config";
365
368
  import importPluginX from "eslint-plugin-import-x";
366
369
  var baseRecommended = defineConfig5([
367
- { extends: [...configs3["flat/base"]] },
368
370
  {
369
371
  files: [
370
372
  "**/*.js",
@@ -401,6 +403,7 @@ var base = defineConfig6([
401
403
  ]);
402
404
 
403
405
  // packages/lint-suite/src/lib/boundaries.ts
406
+ import modularBoundariesPlugin from "@lint-suite/eslint-plugin-modular-boundaries";
404
407
  import { defineConfig as defineConfig7 } from "eslint/config";
405
408
  import boundariesPlugin from "eslint-plugin-boundaries";
406
409
  var boundaries = defineConfig7([
@@ -414,7 +417,8 @@ var boundaries = defineConfig7([
414
417
  "**/*.mts"
415
418
  ],
416
419
  plugins: {
417
- boundaries: boundariesPlugin
420
+ boundaries: boundariesPlugin,
421
+ "modular-boundaries": modularBoundariesPlugin
418
422
  },
419
423
  settings: {
420
424
  "boundaries/elements": [
@@ -450,6 +454,20 @@ var boundaries = defineConfig7([
450
454
  }
451
455
  },
452
456
  rules: {
457
+ // Workspace projects tagged type:app are leaves: no lib or app imports
458
+ // them. The '*' entry keeps untagged projects free to import.
459
+ // Bad: libs/ui (type:lib) imports apps/web (type:app)
460
+ // Good: move the shared code from apps/web into a type:lib project
461
+ "modular-boundaries/modular-boundaries": [
462
+ "error",
463
+ {
464
+ depConstraints: [
465
+ { sourceTag: "type:lib", notDependOnLibsWithTags: ["type:app"] },
466
+ { sourceTag: "type:app", notDependOnLibsWithTags: ["type:app"] },
467
+ { sourceTag: "*", onlyDependOnLibsWithTags: ["*"] }
468
+ ]
469
+ }
470
+ ],
453
471
  ...boundariesPlugin.configs.recommended.rules,
454
472
  "boundaries/dependencies": [
455
473
  "error",
@@ -517,13 +535,37 @@ var boundaries = defineConfig7([
517
535
  ]);
518
536
 
519
537
  // packages/lint-suite/src/lib/javascript.ts
520
- import { configs as configs4 } from "@nx/eslint-plugin";
538
+ import js from "@eslint/js";
521
539
  import { defineConfig as defineConfig8 } from "eslint/config";
522
- var nxJavascript = configs4["flat/javascript"];
523
- var javascript = defineConfig8({
524
- files: ["**/*.js", "**/*.jsx", "**/*.cjs", "**/*.mjs"],
525
- extends: nxJavascript
526
- });
540
+ import globals2 from "globals";
541
+ import tseslint from "typescript-eslint";
542
+ var javascript = defineConfig8(
543
+ {
544
+ files: ["**/*.js", "**/*.jsx", "**/*.cjs", "**/*.mjs"],
545
+ extends: [js.configs.recommended],
546
+ // Parser and plugin stay so consumer @typescript-eslint/* rules set without `files` still run on JS.
547
+ plugins: { "@typescript-eslint": tseslint.plugin },
548
+ languageOptions: {
549
+ parser: tseslint.parser,
550
+ globals: { ...globals2.browser, ...globals2.node }
551
+ },
552
+ rules: {
553
+ "no-unused-expressions": "error",
554
+ "no-array-constructor": "error",
555
+ "no-empty-function": "error",
556
+ "prefer-rest-params": "error",
557
+ "prefer-spread": "error",
558
+ "no-var": "error",
559
+ "prefer-const": ["error", { destructuring: "all" }]
560
+ }
561
+ },
562
+ {
563
+ files: ["**/*.cjs"],
564
+ languageOptions: {
565
+ parserOptions: { ecmaFeatures: { globalReturn: true } }
566
+ }
567
+ }
568
+ );
527
569
 
528
570
  // packages/lint-suite/src/lib/json.ts
529
571
  import jsonPlugin from "@eslint/json";
@@ -559,7 +601,15 @@ var playwright = defineConfig10([
559
601
  "playwright/prefer-comparison-matcher": "error",
560
602
  // Test structure
561
603
  "playwright/prefer-hooks-on-top": "error",
562
- "playwright/require-top-level-describe": "warn"
604
+ "playwright/require-top-level-describe": "warn",
605
+ "playwright/no-export": "error",
606
+ "playwright/no-test-return-statement": "error",
607
+ "playwright/no-template-literal-title": "error",
608
+ "playwright/prefer-ending-with-an-expect": "error",
609
+ "playwright/require-annotation-reason": "error",
610
+ // Timeouts
611
+ "playwright/no-action-timeout": "error",
612
+ "playwright/no-magic-timeouts": "error"
563
613
  }
564
614
  }
565
615
  ]);
@@ -811,6 +861,7 @@ var typescriptOverrides = defineConfig16([
811
861
  "**/*.e2e.js"
812
862
  ],
813
863
  rules: {
864
+ "no-empty-function": "off",
814
865
  "@typescript-eslint/no-empty-function": "off",
815
866
  "@typescript-eslint/unbound-method": "off",
816
867
  "@typescript-eslint/consistent-type-assertions": "off"
@@ -826,14 +877,22 @@ var typescriptOverrides = defineConfig16([
826
877
  ]);
827
878
 
828
879
  // packages/lint-suite/src/lib/typescript-recommended.ts
829
- import { configs as configs5 } from "@nx/eslint-plugin";
880
+ import js2 from "@eslint/js";
830
881
  import { defineConfig as defineConfig17 } from "eslint/config";
831
882
  import importPluginX2 from "eslint-plugin-import-x";
832
- var nxTypescript = configs5["flat/typescript"];
883
+ import tseslint2 from "typescript-eslint";
833
884
  var typescriptRecommended = defineConfig17([
834
885
  {
835
886
  files: ["**/*.ts", "**/*.tsx", "**/*.cts", "**/*.mts"],
836
- extends: [importPluginX2.flatConfigs.typescript, ...nxTypescript]
887
+ extends: [
888
+ importPluginX2.flatConfigs.typescript,
889
+ js2.configs.recommended,
890
+ ...tseslint2.configs.recommended,
891
+ {
892
+ languageOptions: { parserOptions: { tsconfigRootDir: process.cwd() } }
893
+ },
894
+ { rules: { "@typescript-eslint/adjacent-overload-signatures": "error" } }
895
+ ]
837
896
  }
838
897
  ]);
839
898
 
@@ -975,6 +1034,10 @@ var typescriptSafety = defineConfig18([
975
1034
  "@typescript-eslint/no-unsafe-return": "error",
976
1035
  "@typescript-eslint/no-unsafe-argument": "error",
977
1036
  "@typescript-eslint/no-empty-object-type": "error",
1037
+ "@typescript-eslint/no-generated-empty-object-type": "error",
1038
+ // v8.70: type operations resolving to {}
1039
+ "@typescript-eslint/no-unsafe-enum-assignment": "error",
1040
+ // v8.71: non-enum value where an enum is expected
978
1041
  "@typescript-eslint/no-unsafe-function-type": "error",
979
1042
  "@typescript-eslint/no-wrapper-object-types": "error",
980
1043
  "@typescript-eslint/explicit-module-boundary-types": "error",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lint-suite",
3
- "version": "2.1.1",
3
+ "version": "2.3.0",
4
4
  "description": "Reusable ESLint, Stylelint, and Prettier configurations",
5
5
  "repository": {
6
6
  "type": "git",
@@ -25,49 +25,49 @@
25
25
  "author": "Artiom Tofan artiomtofancv@gmail.com",
26
26
  "type": "module",
27
27
  "dependencies": {
28
- "@lint-suite/eslint-plugin-arrow-body-fits-line": "1.0.0",
29
- "@lint-suite/eslint-plugin-chain-fits-line": "1.0.0",
30
- "@lint-suite/eslint-plugin-chain-receiver-is-name": "1.0.0",
31
- "@lint-suite/eslint-plugin-explicit-accessibility": "1.0.0",
32
- "@lint-suite/eslint-plugin-max-condition-operands": "1.0.0",
33
- "@lint-suite/eslint-plugin-no-call-in-condition": "1.0.0",
34
- "@lint-suite/eslint-plugin-no-grouped-condition": "1.0.0",
35
- "@lint-suite/eslint-plugin-no-inline-object-types": "1.0.0",
36
- "@lint-suite/eslint-plugin-no-inline-return-object": "1.0.0",
37
- "@lint-suite/eslint-plugin-no-nested-object-value": "1.0.0",
38
- "@lint-suite/eslint-plugin-no-spread-expression": "1.0.0",
39
- "@lint-suite/eslint-plugin-no-unused-exports": "1.0.0",
40
- "@lint-suite/eslint-plugin-one-line-guard": "1.0.0",
41
- "@lint-suite/eslint-plugin-readonly-type-properties": "1.0.0",
42
- "@lint-suite/eslint-plugin-ternary-branch-shape": "1.0.0",
43
- "@lint-suite/eslint-plugin-test-file-shape": "1.0.0",
44
- "@lint-suite/eslint-plugin-type-placement": "1.0.0",
45
- "@lint-suite/eslint-plugin-util-purity": "1.0.0",
46
- "@lint-suite/eslint-plugin-no-unused-angular-instance-fields": "1.0.0",
47
- "@lint-suite/eslint-plugin-no-unstyled-classes": "1.0.0",
48
- "@lint-suite/stylelint-no-unused-classes": "1.0.0",
28
+ "@lint-suite/eslint-plugin-arrow-body-fits-line": "1.1.0",
29
+ "@lint-suite/eslint-plugin-chain-fits-line": "1.1.0",
30
+ "@lint-suite/eslint-plugin-chain-receiver-is-name": "1.1.0",
31
+ "@lint-suite/eslint-plugin-explicit-accessibility": "1.1.0",
32
+ "@lint-suite/eslint-plugin-max-condition-operands": "1.1.0",
33
+ "@lint-suite/eslint-plugin-modular-boundaries": "1.0.0",
34
+ "@lint-suite/eslint-plugin-no-call-in-condition": "1.1.0",
35
+ "@lint-suite/eslint-plugin-no-grouped-condition": "1.1.0",
36
+ "@lint-suite/eslint-plugin-no-inline-object-types": "1.1.0",
37
+ "@lint-suite/eslint-plugin-no-inline-return-object": "1.1.0",
38
+ "@lint-suite/eslint-plugin-no-nested-object-value": "1.1.0",
39
+ "@lint-suite/eslint-plugin-no-spread-expression": "1.1.0",
40
+ "@lint-suite/eslint-plugin-no-unused-exports": "1.1.0",
41
+ "@lint-suite/eslint-plugin-one-line-guard": "1.1.0",
42
+ "@lint-suite/eslint-plugin-readonly-type-properties": "1.1.0",
43
+ "@lint-suite/eslint-plugin-ternary-branch-shape": "1.1.0",
44
+ "@lint-suite/eslint-plugin-test-file-shape": "1.1.0",
45
+ "@lint-suite/eslint-plugin-type-placement": "1.1.0",
46
+ "@lint-suite/eslint-plugin-util-purity": "1.1.0",
47
+ "@lint-suite/eslint-plugin-no-unused-angular-instance-fields": "1.2.0",
48
+ "@lint-suite/eslint-plugin-no-unstyled-classes": "1.1.0",
49
+ "@lint-suite/stylelint-no-unused-classes": "1.1.0",
49
50
  "@eslint/js": "^10.0.1",
50
- "@eslint/json": "^2.1.0",
51
- "@nx/eslint-plugin": "23.2.0",
51
+ "@eslint/json": "^2.1.1",
52
52
  "@smarttools/eslint-plugin-rxjs": "1.0.22",
53
53
  "@stylistic/eslint-plugin": "5.10.0",
54
54
  "@vitest/eslint-plugin": "1.6.27",
55
- "angular-eslint": "^22.2.0",
55
+ "angular-eslint": "^22.5.0",
56
56
  "eslint": "^10.9.1",
57
57
  "eslint-config-prettier": "^10.1.8",
58
58
  "eslint-import-resolver-typescript": "4.4.5",
59
59
  "eslint-plugin-boundaries": "7.2.0",
60
60
  "eslint-plugin-import-x": "4.17.1",
61
- "eslint-plugin-playwright": "2.11.0",
62
- "eslint-plugin-storybook": "10.6.0",
63
- "globals": "17.12.0",
64
- "stylelint": "17.14.1",
61
+ "eslint-plugin-playwright": "2.12.1",
62
+ "eslint-plugin-storybook": "10.6.1",
63
+ "globals": "17.13.0",
64
+ "stylelint": "17.16.0",
65
65
  "stylelint-config-recess-order": "7.8.0",
66
66
  "stylelint-config-standard": "40.0.0",
67
67
  "stylelint-config-standard-scss": "17.0.0",
68
- "stylelint-scss": "7.2.0",
68
+ "stylelint-scss": "7.3.0",
69
69
  "stylelint-selector-bem-pattern": "5.0.0",
70
- "typescript-eslint": "8.69.0"
70
+ "typescript-eslint": "8.71.1"
71
71
  },
72
72
  "peerDependencies": {
73
73
  "prettier": "^3.9.6",
package/stylelint.js CHANGED
@@ -28,6 +28,7 @@ var stylelint = {
28
28
  ignoreCustomProperties: ["^--mdc", "^--sys"]
29
29
  },
30
30
  "no-descending-specificity": null,
31
+ "selector-no-unmatchable": true,
31
32
  // A stylesheet class no linked template uses is reported.
32
33
  // Bad: .ghost {} used by no template
33
34
  // Good: delete it, or use it in a template