Repository navigation
Expand file tree
/
Copy patheslint.config.mjs
More file actions
183 lines (179 loc) · 6.9 KB
/
Copy patheslint.config.mjs
File metadata and controls
183 lines (179 loc) · 6.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// @ts-check
import eslint from "@eslint/js";
import tseslint from "typescript-eslint";
import angular from "angular-eslint";
import stratos from "./tools/eslint-rules/index.mjs";
import { E2E_LEGACY_FILES } from "./tools/eslint-rules/e2e-legacy-files.mjs";
export default tseslint.config(
{
linterOptions: {
reportUnusedDisableDirectives: "warn",
},
plugins: { stratos },
},
{
files: ["**/*.ts"],
ignores: ["e2e/**"],
extends: [
eslint.configs.recommended,
...tseslint.configs.recommended,
...angular.configs.tsRecommended,
],
processor: angular.processInlineTemplates,
rules: {
// Off — not applicable to this codebase
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-empty-function": "off",
"@angular-eslint/no-empty-lifecycle-method": "off",
"@angular-eslint/directive-selector": "off",
"@angular-eslint/component-selector": "off",
// Warn — migration-period rules to fix over time
// Ignore underscore-prefixed params (intentionally unused) and common
// single-letter callback/catch params that are positional placeholders.
"@typescript-eslint/no-unused-vars": [
"warn",
{
argsIgnorePattern: "^_",
varsIgnorePattern: "^_",
caughtErrorsIgnorePattern: "^_",
ignoreRestSiblings: true,
},
],
"@typescript-eslint/no-unsafe-declaration-merging": "warn",
"@typescript-eslint/no-wrapper-object-types": "warn",
"@typescript-eslint/no-empty-object-type": "warn",
"@angular-eslint/prefer-inject": "warn",
"@angular-eslint/prefer-standalone": "warn",
"@angular-eslint/no-input-rename": "warn",
"@angular-eslint/no-output-native": "warn",
"@angular-eslint/no-output-on-prefix": "warn",
"no-case-declarations": "warn",
"no-extra-boolean-cast": "warn",
"no-prototype-builtins": "warn",
"no-useless-escape": "warn",
"no-empty": "warn",
"no-unexpected-multiline": "warn",
"no-var": "warn",
"no-constant-condition": "warn",
"@typescript-eslint/no-non-null-asserted-optional-chain": "warn",
"@typescript-eslint/no-unused-expressions": "warn",
"@typescript-eslint/no-this-alias": "warn",
"@typescript-eslint/no-duplicate-enum-values": "warn",
"prefer-const": "warn",
"no-irregular-whitespace": "warn",
"no-duplicate-case": "warn",
"@typescript-eslint/no-unsafe-function-type": "warn",
// A snackbar service injected but never called is dead weight that
// misleads readers about what the component can do (#5603).
"stratos/no-unused-snackbar-service": "error",
// APIs deprecated in RxJS 7 (removed in RxJS 8) and Angular APIs the
// zoneless app has no use for. All call sites were replaced in #6022;
// these keep them from coming back.
"no-restricted-imports": ["error", { paths: [
...["rxjs", "rxjs/operators"].map(name => ({
name,
importNames: ["publishReplay", "refCount", "publish", "publishLast", "publishBehavior", "multicast"],
message: "Deprecated in RxJS 7: use shareReplay({ bufferSize: 1, refCount: true }), share() or connectable().",
})),
...["rxjs", "rxjs/operators"].map(name => ({
name,
importNames: ["retryWhen"],
message: "Deprecated in RxJS 7: use retry({ count, delay }).",
})),
{
name: "rxjs/operators",
importNames: ["combineLatest"],
message: "Deprecated in RxJS 7: use the combineLatestWith operator.",
},
{
name: "@angular/common/http",
importNames: ["HttpClientModule"],
message: "Deprecated: the app configures HttpClient with provideHttpClient() in AppModule.",
},
{
name: "@angular/core",
importNames: ["NgZone"],
message: "The app is zoneless: NgZone.run() and runOutsideAngular() only call their callback.",
},
] }],
"no-restricted-syntax": ["error",
{
selector: "CallExpression[callee.property.name='toPromise']",
message: "Deprecated in RxJS 7: use firstValueFrom() or lastValueFrom().",
},
{
selector: "CallExpression[callee.property.name='subscribe'][arguments.length>1]",
message: "Deprecated in RxJS 7: pass one observer, subscribe({ next, error, complete }).",
},
{
selector: "CallExpression[callee.name=/^(combineLatest|observableCombineLatest)$/][arguments.length>1]",
message: "Deprecated in RxJS 7: pass the sources as one array, combineLatest([a, b]).",
},
{
selector: "CallExpression[callee.name='throwError'][arguments.0.type!=/^(ArrowFunctionExpression|FunctionExpression)$/]",
message: "Deprecated in RxJS 7: pass an inline error factory, throwError(() => error).",
},
],
},
},
{
files: ["**/*.spec.ts", "**/test-setup.ts"],
ignores: ["e2e/**"],
rules: {
"@typescript-eslint/no-unused-vars": [
"warn",
{
varsIgnorePattern: "^(describe|it|test|expect|beforeAll|afterAll|beforeEach|afterEach|vi|fixture|component|provideZonelessChangeDetection|_\\w*)$",
argsIgnorePattern: "^_",
caughtErrorsIgnorePattern: "^_",
ignoreRestSiblings: true,
},
],
},
},
{
files: ["**/*.html"],
extends: [
...angular.configs.templateRecommended,
...angular.configs.templateAccessibility,
],
rules: {
// Warn — migration-period rules to fix over time
"@angular-eslint/template/no-negated-async": "warn",
"@angular-eslint/template/eqeqeq": "warn",
"@angular-eslint/template/prefer-control-flow": "warn",
"@angular-eslint/template/interactive-supports-focus": "warn",
"@angular-eslint/template/click-events-have-key-events": "warn",
"@angular-eslint/template/alt-text": "warn",
"@angular-eslint/template/label-has-associated-control": "warn",
"@angular-eslint/template/elements-content": "warn",
},
},
// e2e specs get only the drift guards (#5619), not the app ruleset: the
// goal is that DOM drift and can't-fail assertions turn red on the PR
// that introduces them.
{
files: ["e2e/**/*.ts"],
languageOptions: {
parser: tseslint.parser,
},
rules: {
"stratos/no-dead-material-selectors": "error",
"stratos/no-hollow-assertions": "error",
},
},
// Ratchet: files that predate the guards keep their existing violations
// until they are modernised; new files and cleaned files gate red.
// Remove entries as files are fixed — never add to this list.
...(E2E_LEGACY_FILES.length
? [
{
files: E2E_LEGACY_FILES,
rules: {
"stratos/no-dead-material-selectors": "off",
"stratos/no-hollow-assertions": "off",
},
},
]
: [])
);