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 +115 -0
- package/README.md +69 -15
- package/eslint.js +76 -13
- package/package.json +31 -31
- package/stylelint.js +1 -0
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**:
|
|
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
|
|
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
|
-
|
|
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
|
|
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` |
|
|
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
|
-
-
|
|
250
|
-
|
|
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
|
|
538
|
+
import js from "@eslint/js";
|
|
521
539
|
import { defineConfig as defineConfig8 } from "eslint/config";
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
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
|
|
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
|
-
|
|
883
|
+
import tseslint2 from "typescript-eslint";
|
|
833
884
|
var typescriptRecommended = defineConfig17([
|
|
834
885
|
{
|
|
835
886
|
files: ["**/*.ts", "**/*.tsx", "**/*.cts", "**/*.mts"],
|
|
836
|
-
extends: [
|
|
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.
|
|
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.
|
|
29
|
-
"@lint-suite/eslint-plugin-chain-fits-line": "1.
|
|
30
|
-
"@lint-suite/eslint-plugin-chain-receiver-is-name": "1.
|
|
31
|
-
"@lint-suite/eslint-plugin-explicit-accessibility": "1.
|
|
32
|
-
"@lint-suite/eslint-plugin-max-condition-operands": "1.
|
|
33
|
-
"@lint-suite/eslint-plugin-
|
|
34
|
-
"@lint-suite/eslint-plugin-no-
|
|
35
|
-
"@lint-suite/eslint-plugin-no-
|
|
36
|
-
"@lint-suite/eslint-plugin-no-inline-
|
|
37
|
-
"@lint-suite/eslint-plugin-no-
|
|
38
|
-
"@lint-suite/eslint-plugin-no-
|
|
39
|
-
"@lint-suite/eslint-plugin-no-
|
|
40
|
-
"@lint-suite/eslint-plugin-
|
|
41
|
-
"@lint-suite/eslint-plugin-
|
|
42
|
-
"@lint-suite/eslint-plugin-
|
|
43
|
-
"@lint-suite/eslint-plugin-
|
|
44
|
-
"@lint-suite/eslint-plugin-
|
|
45
|
-
"@lint-suite/eslint-plugin-
|
|
46
|
-
"@lint-suite/eslint-plugin-
|
|
47
|
-
"@lint-suite/eslint-plugin-no-
|
|
48
|
-
"@lint-suite/
|
|
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.
|
|
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.
|
|
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.
|
|
62
|
-
"eslint-plugin-storybook": "10.6.
|
|
63
|
-
"globals": "17.
|
|
64
|
-
"stylelint": "17.
|
|
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.
|
|
68
|
+
"stylelint-scss": "7.3.0",
|
|
69
69
|
"stylelint-selector-bem-pattern": "5.0.0",
|
|
70
|
-
"typescript-eslint": "8.
|
|
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
|