lint-suite 2.0.1 → 2.1.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 +27 -7
- package/eslint.js +221 -85
- package/eslint.js.map +4 -4
- package/lib/rules/file-cache.d.ts +1 -1
- package/lib/rules/file-cache.d.ts.map +1 -1
- package/lib/rules/no-unstyled-classes/styles/stylesheet-classes.d.ts.map +1 -1
- package/lib/rules/no-unstyled-classes/styles/stylesheet-collection.d.ts +1 -1
- package/lib/rules/no-unstyled-classes/styles/stylesheet-collection.d.ts.map +1 -1
- package/lib/rules/no-unstyled-classes/styles/stylesheet-imports.d.ts +8 -1
- package/lib/rules/no-unstyled-classes/styles/stylesheet-imports.d.ts.map +1 -1
- package/lib/rules/no-unused-angular-instance-fields/project-usage/angular/angular-template-reads.d.ts.map +1 -1
- package/lib/rules/no-unused-angular-instance-fields/project-usage/common/project-index.type.d.ts +1 -0
- package/lib/rules/no-unused-angular-instance-fields/project-usage/common/project-index.type.d.ts.map +1 -1
- package/lib/rules/no-unused-angular-instance-fields/project-usage/project-file-entry.d.ts.map +1 -1
- package/lib/rules/no-unused-angular-instance-fields/project-usage/project-index-reconciliation.d.ts.map +1 -1
- package/lib/rules/no-unused-angular-instance-fields/project-usage/typescript/typescript-dangling-imports.d.ts +8 -0
- package/lib/rules/no-unused-angular-instance-fields/project-usage/typescript/typescript-dangling-imports.d.ts.map +1 -0
- package/lib/rules/no-unused-classes/no-unused-classes.d.ts.map +1 -1
- package/lib/rules/no-unused-classes/template/template-usage.d.ts.map +1 -1
- package/lib/rules/no-unused-exports/common/no-unused-exports.type.d.ts +9 -1
- package/lib/rules/no-unused-exports/common/no-unused-exports.type.d.ts.map +1 -1
- package/lib/rules/no-unused-exports/disk-resolver.d.ts +9 -0
- package/lib/rules/no-unused-exports/disk-resolver.d.ts.map +1 -0
- package/lib/rules/no-unused-exports/export-index.d.ts.map +1 -1
- package/lib/rules/no-unused-exports/utils/module-edges.util.d.ts +3 -3
- package/lib/rules/no-unused-exports/utils/module-edges.util.d.ts.map +1 -1
- package/lib/rules/no-unused-exports/utils/module-resolver.util.d.ts +8 -0
- package/lib/rules/no-unused-exports/utils/module-resolver.util.d.ts.map +1 -0
- package/lib/rules/package-version.d.ts +2 -0
- package/lib/rules/package-version.d.ts.map +1 -0
- package/lib/rules/utils/template-classes.util.d.ts +2 -0
- package/lib/rules/utils/template-classes.util.d.ts.map +1 -1
- package/lib/typescript-safety.d.ts.map +1 -1
- package/package.json +4 -7
- package/stylelint.js +96 -28
- package/stylelint.js.map +4 -4
- package/eslint.cjs +0 -7363
- package/eslint.cjs.map +0 -7
- package/lib/rules/no-unused-exports/utils/module-target.util.d.ts +0 -4
- package/lib/rules/no-unused-exports/utils/module-target.util.d.ts.map +0 -1
- package/prettier.cjs +0 -50
- package/prettier.cjs.map +0 -7
- package/stylelint.cjs +0 -947
- package/stylelint.cjs.map +0 -7
package/eslint.js
CHANGED
|
@@ -13,8 +13,8 @@ var definePlugin = (name, rules) => {
|
|
|
13
13
|
import { ESLintUtils } from "@typescript-eslint/utils";
|
|
14
14
|
|
|
15
15
|
// packages/lint-suite/src/lib/rules/no-unstyled-classes/styles/component-stylesheets.ts
|
|
16
|
-
import { existsSync } from "node:fs";
|
|
17
|
-
import { dirname as
|
|
16
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
17
|
+
import { dirname as dirname3, resolve } from "node:path";
|
|
18
18
|
|
|
19
19
|
// packages/lint-suite/src/lib/rules/component-metadata.ts
|
|
20
20
|
import {
|
|
@@ -34,12 +34,59 @@ import {
|
|
|
34
34
|
// packages/lint-suite/src/lib/rules/file-cache.ts
|
|
35
35
|
import {
|
|
36
36
|
mkdirSync,
|
|
37
|
-
readFileSync,
|
|
37
|
+
readFileSync as readFileSync2,
|
|
38
38
|
renameSync,
|
|
39
39
|
statSync,
|
|
40
40
|
writeFileSync
|
|
41
41
|
} from "node:fs";
|
|
42
|
+
import { dirname as dirname2, join as join2 } from "node:path";
|
|
43
|
+
|
|
44
|
+
// packages/lint-suite/src/lib/rules/package-version.ts
|
|
45
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
42
46
|
import { dirname, join } from "node:path";
|
|
47
|
+
import { fileURLToPath } from "node:url";
|
|
48
|
+
var PACKAGE_NAME = "lint-suite";
|
|
49
|
+
var DEV_VERSION = "dev";
|
|
50
|
+
var MAX_MANIFEST_DEPTH = 6;
|
|
51
|
+
var moduleDirectory = () => {
|
|
52
|
+
const url = import.meta.url;
|
|
53
|
+
if (typeof url !== "string") return null;
|
|
54
|
+
return dirname(fileURLToPath(url));
|
|
55
|
+
};
|
|
56
|
+
var manifestVersion = (file) => {
|
|
57
|
+
const isPresent = existsSync(file);
|
|
58
|
+
if (!isPresent) return null;
|
|
59
|
+
try {
|
|
60
|
+
const manifest = JSON.parse(readFileSync(file, "utf8"));
|
|
61
|
+
const isRecord = typeof manifest === "object" && manifest !== null;
|
|
62
|
+
if (!isRecord) return null;
|
|
63
|
+
if (!("name" in manifest)) return null;
|
|
64
|
+
if (manifest.name !== PACKAGE_NAME) return null;
|
|
65
|
+
if (!("version" in manifest)) return null;
|
|
66
|
+
if (typeof manifest.version !== "string") return null;
|
|
67
|
+
return manifest.version;
|
|
68
|
+
} catch {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
var parentOf = (directory) => {
|
|
73
|
+
const parent = dirname(directory);
|
|
74
|
+
if (parent === directory) return null;
|
|
75
|
+
return parent;
|
|
76
|
+
};
|
|
77
|
+
var packageVersion = () => {
|
|
78
|
+
let directory = moduleDirectory();
|
|
79
|
+
for (let depth = 0; depth < MAX_MANIFEST_DEPTH; depth += 1) {
|
|
80
|
+
if (directory === null) break;
|
|
81
|
+
const version = manifestVersion(join(directory, "package.json"));
|
|
82
|
+
if (version !== null) return version;
|
|
83
|
+
directory = parentOf(directory);
|
|
84
|
+
}
|
|
85
|
+
return DEV_VERSION;
|
|
86
|
+
};
|
|
87
|
+
var PACKAGE_VERSION = packageVersion();
|
|
88
|
+
|
|
89
|
+
// packages/lint-suite/src/lib/rules/file-cache.ts
|
|
43
90
|
var CACHE_FORMAT_VERSION = 1;
|
|
44
91
|
var caches = /* @__PURE__ */ new Set();
|
|
45
92
|
var isFlushRegistered = false;
|
|
@@ -48,12 +95,12 @@ var cacheDirectory = () => {
|
|
|
48
95
|
const isDisabled = LINT_SUITE_CACHE === "0";
|
|
49
96
|
if (isDisabled) return null;
|
|
50
97
|
if (LINT_SUITE_CACHE_DIR) return LINT_SUITE_CACHE_DIR;
|
|
51
|
-
return
|
|
98
|
+
return join2(process.cwd(), "node_modules", ".cache", "lint-suite");
|
|
52
99
|
};
|
|
53
100
|
var cacheFile = (name) => {
|
|
54
101
|
const directory = cacheDirectory();
|
|
55
102
|
if (directory === null) return null;
|
|
56
|
-
return
|
|
103
|
+
return join2(directory, `${name}.v${CACHE_FORMAT_VERSION}.json`);
|
|
57
104
|
};
|
|
58
105
|
var isCachedFile = (value) => {
|
|
59
106
|
const isObject = typeof value === "object" && value !== null;
|
|
@@ -76,7 +123,7 @@ var load = (cache2) => {
|
|
|
76
123
|
const file = cacheFile(cache2.name);
|
|
77
124
|
if (file === null) return;
|
|
78
125
|
try {
|
|
79
|
-
const stored = storedEntries(
|
|
126
|
+
const stored = storedEntries(readFileSync2(file, "utf8"));
|
|
80
127
|
for (const [path, entry] of stored) cache2.entries.set(path, entry);
|
|
81
128
|
} catch {
|
|
82
129
|
return;
|
|
@@ -86,7 +133,7 @@ var write = (cache2) => {
|
|
|
86
133
|
const file = cacheFile(cache2.name);
|
|
87
134
|
if (file === null) return;
|
|
88
135
|
try {
|
|
89
|
-
mkdirSync(
|
|
136
|
+
mkdirSync(dirname2(file), { recursive: true });
|
|
90
137
|
const temporary = `${file}.${process.pid}.tmp`;
|
|
91
138
|
const stored = Object.fromEntries(cache2.entries);
|
|
92
139
|
writeFileSync(temporary, JSON.stringify(stored));
|
|
@@ -122,10 +169,10 @@ var readCached = (cache2, path, parse2) => {
|
|
|
122
169
|
if (!cache2.loaded) load(cache2);
|
|
123
170
|
try {
|
|
124
171
|
const stats = statSync(path, { bigint: true });
|
|
125
|
-
const version = `${stats.mtimeNs}:${stats.size}`;
|
|
172
|
+
const version = `${PACKAGE_VERSION}:${stats.mtimeNs}:${stats.size}`;
|
|
126
173
|
const cached = cache2.entries.get(path);
|
|
127
174
|
if (cached?.version === version) return cached.value;
|
|
128
|
-
const value = parse2(
|
|
175
|
+
const value = parse2(readFileSync2(path, "utf8"), path);
|
|
129
176
|
const fresh = { value, version };
|
|
130
177
|
cache2.entries.set(path, fresh);
|
|
131
178
|
cache2.dirty = true;
|
|
@@ -231,7 +278,7 @@ var matchesTemplate = (metadata, directory, templateFilename) => {
|
|
|
231
278
|
};
|
|
232
279
|
var templateMetadata = (componentPath, templateFilename) => {
|
|
233
280
|
const components = componentMetadata(componentPath);
|
|
234
|
-
const directory =
|
|
281
|
+
const directory = dirname3(componentPath);
|
|
235
282
|
const matches = (metadata) => {
|
|
236
283
|
return matchesTemplate(metadata, directory, templateFilename);
|
|
237
284
|
};
|
|
@@ -246,7 +293,7 @@ var stylesheetFiles = (paths, directory) => {
|
|
|
246
293
|
const sources = [];
|
|
247
294
|
for (const path of paths) {
|
|
248
295
|
const resolved = resolve(directory, path);
|
|
249
|
-
const isPresent =
|
|
296
|
+
const isPresent = existsSync2(resolved);
|
|
250
297
|
if (!isPresent) continue;
|
|
251
298
|
const source = { kind: "file", path: resolved };
|
|
252
299
|
sources.push(source);
|
|
@@ -267,7 +314,7 @@ var inlineSources = (styles, componentPath) => {
|
|
|
267
314
|
var metadataSources = (componentPath, templateFilename) => {
|
|
268
315
|
const metadata = templateMetadata(componentPath, templateFilename);
|
|
269
316
|
if (metadata === null) return [];
|
|
270
|
-
const directory =
|
|
317
|
+
const directory = dirname3(componentPath);
|
|
271
318
|
const files = stylesheetFiles(metadata.styleUrls, directory);
|
|
272
319
|
const inline = inlineSources(metadata.styles, componentPath);
|
|
273
320
|
return [...files, ...inline];
|
|
@@ -276,7 +323,7 @@ var siblingSources = (templateFilename) => {
|
|
|
276
323
|
const base2 = templateFilename.replace(HTML_EXTENSION, "");
|
|
277
324
|
const candidateOf = (extension) => `${base2}${extension}`;
|
|
278
325
|
const candidates = SIBLING_EXTENSIONS.map(candidateOf);
|
|
279
|
-
return stylesheetFiles(candidates,
|
|
326
|
+
return stylesheetFiles(candidates, dirname3(templateFilename));
|
|
280
327
|
};
|
|
281
328
|
var componentStylesheets = (templateFilename) => {
|
|
282
329
|
const componentPath = templateFilename.replace(HTML_EXTENSION, ".ts");
|
|
@@ -286,7 +333,7 @@ var componentStylesheets = (templateFilename) => {
|
|
|
286
333
|
};
|
|
287
334
|
|
|
288
335
|
// packages/lint-suite/src/lib/rules/no-unstyled-classes/styles/linked-stylesheets.ts
|
|
289
|
-
import { dirname as
|
|
336
|
+
import { dirname as dirname4 } from "node:path";
|
|
290
337
|
|
|
291
338
|
// packages/lint-suite/src/lib/rules/utils/template-links.util.ts
|
|
292
339
|
var LINK_TAG = /<link\b[^>]*>/giu;
|
|
@@ -309,16 +356,16 @@ var linkedStylesheetHrefs = (template) => {
|
|
|
309
356
|
// packages/lint-suite/src/lib/rules/no-unstyled-classes/styles/linked-stylesheets.ts
|
|
310
357
|
var linkedStylesheets = (template, templateFilename) => {
|
|
311
358
|
const hrefs = linkedStylesheetHrefs(template);
|
|
312
|
-
return stylesheetFiles(hrefs,
|
|
359
|
+
return stylesheetFiles(hrefs, dirname4(templateFilename));
|
|
313
360
|
};
|
|
314
361
|
|
|
315
362
|
// packages/lint-suite/src/lib/rules/no-unstyled-classes/styles/stylesheet-classes.ts
|
|
316
|
-
import { dirname as
|
|
363
|
+
import { dirname as dirname6 } from "node:path";
|
|
317
364
|
import { parse } from "postcss-scss";
|
|
318
365
|
|
|
319
366
|
// packages/lint-suite/src/lib/rules/no-unstyled-classes/styles/stylesheet-imports.ts
|
|
320
|
-
import { existsSync as
|
|
321
|
-
import { basename, dirname as
|
|
367
|
+
import { existsSync as existsSync3 } from "node:fs";
|
|
368
|
+
import { basename, dirname as dirname5, join as join3, resolve as resolve2 } from "node:path";
|
|
322
369
|
var QUOTED = /'([^']*)'|"([^"]*)"/u;
|
|
323
370
|
var SKIPPED_PREFIXES = ["sass:", "http", "url("];
|
|
324
371
|
var specifierOf = (params) => {
|
|
@@ -335,25 +382,28 @@ var isResolvable = (specifier) => {
|
|
|
335
382
|
if (isSkipped) return false;
|
|
336
383
|
return !specifier.endsWith(".css");
|
|
337
384
|
};
|
|
385
|
+
var importSpecifier = (params) => {
|
|
386
|
+
const specifier = specifierOf(params);
|
|
387
|
+
if (specifier === null) return null;
|
|
388
|
+
const isCandidate = isResolvable(specifier);
|
|
389
|
+
if (!isCandidate) return null;
|
|
390
|
+
return specifier;
|
|
391
|
+
};
|
|
338
392
|
var candidatesOf = (path) => {
|
|
339
393
|
const isStylesheet = path.endsWith(".scss");
|
|
340
|
-
if (isStylesheet) return [path,
|
|
341
|
-
const partial =
|
|
394
|
+
if (isStylesheet) return [path, join3(dirname5(path), `_${basename(path)}`)];
|
|
395
|
+
const partial = join3(dirname5(path), `_${basename(path)}.scss`);
|
|
342
396
|
return [
|
|
343
397
|
`${path}.scss`,
|
|
344
398
|
partial,
|
|
345
|
-
|
|
346
|
-
|
|
399
|
+
join3(path, "index.scss"),
|
|
400
|
+
join3(path, "_index.scss")
|
|
347
401
|
];
|
|
348
402
|
};
|
|
349
|
-
var resolveStylesheetImport = (
|
|
350
|
-
const specifier = specifierOf(params);
|
|
351
|
-
if (specifier === null) return null;
|
|
352
|
-
const isCandidate = isResolvable(specifier);
|
|
353
|
-
if (!isCandidate) return null;
|
|
403
|
+
var resolveStylesheetImport = (specifier, directory) => {
|
|
354
404
|
const path = resolve2(directory, specifier);
|
|
355
405
|
const candidates = candidatesOf(path);
|
|
356
|
-
const existing = candidates.find((candidate) =>
|
|
406
|
+
const existing = candidates.find((candidate) => existsSync3(candidate));
|
|
357
407
|
return existing ?? null;
|
|
358
408
|
};
|
|
359
409
|
|
|
@@ -456,19 +506,19 @@ var addSelectors = (selectors, entry) => {
|
|
|
456
506
|
entry.patterns.push(...patterns);
|
|
457
507
|
}
|
|
458
508
|
};
|
|
459
|
-
var addImport = (node, entry
|
|
509
|
+
var addImport = (node, entry) => {
|
|
460
510
|
const isImport = IMPORT_AT_RULES.has(node.name);
|
|
461
511
|
if (!isImport) return;
|
|
462
|
-
const
|
|
463
|
-
if (
|
|
512
|
+
const specifier = importSpecifier(node.params);
|
|
513
|
+
if (specifier !== null) entry.imports.push(specifier);
|
|
464
514
|
};
|
|
465
|
-
var collectStylesheet = (root
|
|
515
|
+
var collectStylesheet = (root) => {
|
|
466
516
|
const entry = { classes: [], patterns: [], imports: [] };
|
|
467
517
|
const onRule = (_rule, resolved) => {
|
|
468
518
|
addSelectors(resolved, entry);
|
|
469
519
|
};
|
|
470
520
|
const onAtRule = (node) => {
|
|
471
|
-
addImport(node, entry
|
|
521
|
+
addImport(node, entry);
|
|
472
522
|
};
|
|
473
523
|
walkResolvedRules(root, onRule);
|
|
474
524
|
root.walkAtRules(onAtRule);
|
|
@@ -485,8 +535,7 @@ var inlineStylesheets = /* @__PURE__ */ new Map();
|
|
|
485
535
|
var merged = /* @__PURE__ */ new Map();
|
|
486
536
|
var parseStylesheet = (source, path) => {
|
|
487
537
|
try {
|
|
488
|
-
|
|
489
|
-
return collectStylesheet(root, dirname5(path));
|
|
538
|
+
return collectStylesheet(parse(source, { from: path }));
|
|
490
539
|
} catch {
|
|
491
540
|
return EMPTY_ENTRY;
|
|
492
541
|
}
|
|
@@ -502,14 +551,16 @@ var inlineEntry = (source, path) => {
|
|
|
502
551
|
inlineStylesheets.set(key2, entry);
|
|
503
552
|
return entry;
|
|
504
553
|
};
|
|
505
|
-
var collectImports = (entry, chain, visited) => {
|
|
506
|
-
for (const
|
|
554
|
+
var collectImports = (entry, directory, chain, visited) => {
|
|
555
|
+
for (const specifier of entry.imports) {
|
|
556
|
+
const imported = resolveStylesheetImport(specifier, directory);
|
|
557
|
+
if (imported === null) continue;
|
|
507
558
|
const isVisited = visited.has(imported);
|
|
508
559
|
if (isVisited) continue;
|
|
509
560
|
visited.add(imported);
|
|
510
561
|
const importedEntry = fileEntry(imported);
|
|
511
562
|
chain.push(importedEntry);
|
|
512
|
-
collectImports(importedEntry, chain, visited);
|
|
563
|
+
collectImports(importedEntry, dirname6(imported), chain, visited);
|
|
513
564
|
}
|
|
514
565
|
};
|
|
515
566
|
var entryOf = (source) => {
|
|
@@ -524,7 +575,7 @@ var collectChain = (source, chain, visited) => {
|
|
|
524
575
|
}
|
|
525
576
|
const entry = entryOf(source);
|
|
526
577
|
chain.push(entry);
|
|
527
|
-
collectImports(entry, chain, visited);
|
|
578
|
+
collectImports(entry, dirname6(source.path), chain, visited);
|
|
528
579
|
};
|
|
529
580
|
var mergeChain = (chain) => {
|
|
530
581
|
const exact = /* @__PURE__ */ new Set();
|
|
@@ -668,7 +719,12 @@ var classExpressionLiterals = (source) => {
|
|
|
668
719
|
};
|
|
669
720
|
|
|
670
721
|
// packages/lint-suite/src/lib/rules/utils/template-classes.util.ts
|
|
671
|
-
var
|
|
722
|
+
var CLASS_ATTRIBUTES = [
|
|
723
|
+
"class",
|
|
724
|
+
"routerLinkActive",
|
|
725
|
+
"animate.enter",
|
|
726
|
+
"animate.leave"
|
|
727
|
+
];
|
|
672
728
|
var CLASS_BINDING_PREFIX = "class.";
|
|
673
729
|
var TOKEN = /\S+/gu;
|
|
674
730
|
var expressionSource = (value) => {
|
|
@@ -697,11 +753,11 @@ var boundClassName = (input) => {
|
|
|
697
753
|
return input.name;
|
|
698
754
|
};
|
|
699
755
|
var isClassExpression = (input) => {
|
|
700
|
-
const isClassName = input.name
|
|
756
|
+
const isClassName = CLASS_ATTRIBUTES.includes(input.name);
|
|
701
757
|
if (!isClassName) return false;
|
|
702
758
|
const { details } = input.keySpan;
|
|
703
759
|
if (details === null) return true;
|
|
704
|
-
return details ===
|
|
760
|
+
return details === input.name;
|
|
705
761
|
};
|
|
706
762
|
var expressionClasses = (input) => {
|
|
707
763
|
const source = expressionSource(input.value);
|
|
@@ -726,7 +782,7 @@ var inputClasses = (input) => {
|
|
|
726
782
|
var templateClasses = (node) => {
|
|
727
783
|
const classes = [];
|
|
728
784
|
for (const attribute of node.attributes) {
|
|
729
|
-
const isClassName = attribute.name
|
|
785
|
+
const isClassName = CLASS_ATTRIBUTES.includes(attribute.name);
|
|
730
786
|
if (isClassName) {
|
|
731
787
|
const found = staticClasses(attribute);
|
|
732
788
|
classes.push(...found);
|
|
@@ -1177,7 +1233,7 @@ var methodCandidate = (node, localPrivateOnly, implementedMethods) => {
|
|
|
1177
1233
|
};
|
|
1178
1234
|
|
|
1179
1235
|
// packages/lint-suite/src/lib/rules/no-unused-angular-instance-fields/rule/angular/angular-metadata-reads.ts
|
|
1180
|
-
import { dirname as
|
|
1236
|
+
import { dirname as dirname7, resolve as resolve3 } from "node:path";
|
|
1181
1237
|
import { TSESTree as TSESTree5 } from "@typescript-eslint/utils";
|
|
1182
1238
|
|
|
1183
1239
|
// packages/lint-suite/src/lib/rules/no-unused-angular-instance-fields/rule/angular/angular-metadata-literals.ts
|
|
@@ -1221,7 +1277,7 @@ import {
|
|
|
1221
1277
|
R3TargetBinder,
|
|
1222
1278
|
parseTemplate
|
|
1223
1279
|
} from "@angular/compiler";
|
|
1224
|
-
import { readFileSync as
|
|
1280
|
+
import { readFileSync as readFileSync3, statSync as statSync2 } from "node:fs";
|
|
1225
1281
|
|
|
1226
1282
|
// packages/lint-suite/src/lib/rules/no-unused-angular-instance-fields/rule/angular/angular-expression-reads.ts
|
|
1227
1283
|
import {
|
|
@@ -1320,7 +1376,7 @@ var externalTemplateReads = (filename) => {
|
|
|
1320
1376
|
const version = `${stats.mtimeNs}:${stats.size}`;
|
|
1321
1377
|
const cached = externalTemplates.get(filename);
|
|
1322
1378
|
if (cached?.version === version) return cached.reads;
|
|
1323
|
-
const reads = templateReads(
|
|
1379
|
+
const reads = templateReads(readFileSync3(filename, "utf8"), filename);
|
|
1324
1380
|
externalTemplates.set(filename, { reads, version });
|
|
1325
1381
|
return reads;
|
|
1326
1382
|
} catch {
|
|
@@ -1388,7 +1444,7 @@ var inlineTemplateReads = (template, reads, filename) => {
|
|
|
1388
1444
|
var externalTemplatePropertyReads = (templateUrl, reads, filename) => {
|
|
1389
1445
|
if (!templateUrl) return true;
|
|
1390
1446
|
const url = text(templateUrl);
|
|
1391
|
-
return url !== null && addReads(reads, externalTemplateReads(resolve3(
|
|
1447
|
+
return url !== null && addReads(reads, externalTemplateReads(resolve3(dirname7(filename), url)));
|
|
1392
1448
|
};
|
|
1393
1449
|
var componentTemplateReads = (metadata, reads, filename) => {
|
|
1394
1450
|
const template = metadataValue2(metadata, "template");
|
|
@@ -1617,7 +1673,7 @@ var lexicalThisVisitor = (thisStack) => {
|
|
|
1617
1673
|
|
|
1618
1674
|
// packages/lint-suite/src/lib/rules/no-unused-angular-instance-fields/rule/typescript/typescript-write-targets.ts
|
|
1619
1675
|
import { TSESTree as TSESTree8 } from "@typescript-eslint/utils";
|
|
1620
|
-
var
|
|
1676
|
+
var parentOf2 = (node) => {
|
|
1621
1677
|
if (node.type === TSESTree8.AST_NODE_TYPES.Program) return void 0;
|
|
1622
1678
|
return node.parent;
|
|
1623
1679
|
};
|
|
@@ -1661,10 +1717,10 @@ var isWrapping = (parent, child) => {
|
|
|
1661
1717
|
};
|
|
1662
1718
|
var isDirectWrite = (node) => {
|
|
1663
1719
|
let current = node;
|
|
1664
|
-
let parent =
|
|
1720
|
+
let parent = parentOf2(node);
|
|
1665
1721
|
while (parent && isTypeScriptExpressionWrapper(parent) && parent.expression === current) {
|
|
1666
1722
|
current = parent;
|
|
1667
|
-
parent =
|
|
1723
|
+
parent = parentOf2(parent);
|
|
1668
1724
|
}
|
|
1669
1725
|
const isDeleteExpression2 = parent?.type === TSESTree8.AST_NODE_TYPES.UnaryExpression && parent.operator === "delete";
|
|
1670
1726
|
const isAssignment = isSimpleAssignmentTarget(parent, current);
|
|
@@ -1672,7 +1728,7 @@ var isDirectWrite = (node) => {
|
|
|
1672
1728
|
};
|
|
1673
1729
|
var isDestructuringOrLoopTarget = (node) => {
|
|
1674
1730
|
let current = node;
|
|
1675
|
-
let parent =
|
|
1731
|
+
let parent = parentOf2(node);
|
|
1676
1732
|
let patternTarget = false;
|
|
1677
1733
|
while (parent) {
|
|
1678
1734
|
const wrapper = isWrapping(parent, current);
|
|
@@ -1682,7 +1738,7 @@ var isDestructuringOrLoopTarget = (node) => {
|
|
|
1682
1738
|
patternTarget = true;
|
|
1683
1739
|
}
|
|
1684
1740
|
current = parent;
|
|
1685
|
-
parent =
|
|
1741
|
+
parent = parentOf2(parent);
|
|
1686
1742
|
}
|
|
1687
1743
|
const isSimpleTarget = isSimpleAssignmentTarget(parent, current);
|
|
1688
1744
|
const isAssignedPattern = patternTarget && isSimpleTarget;
|
|
@@ -1865,11 +1921,11 @@ var replaceDeclarations = (index, previous, next) => {
|
|
|
1865
1921
|
};
|
|
1866
1922
|
|
|
1867
1923
|
// packages/lint-suite/src/lib/rules/no-unused-angular-instance-fields/project-usage/project-index-reconciliation.ts
|
|
1868
|
-
import { dirname as
|
|
1924
|
+
import { dirname as dirname10, normalize as normalize2 } from "node:path";
|
|
1869
1925
|
|
|
1870
1926
|
// packages/lint-suite/src/lib/rules/no-unused-angular-instance-fields/project-usage/angular/angular-template-reads.ts
|
|
1871
|
-
import { readFileSync as
|
|
1872
|
-
import { dirname as
|
|
1927
|
+
import { readFileSync as readFileSync4, statSync as statSync3 } from "node:fs";
|
|
1928
|
+
import { dirname as dirname8, normalize } from "node:path";
|
|
1873
1929
|
import { isIdentifier as isIdentifier3, isStringLiteralLike as isStringLiteralLike3 } from "typescript";
|
|
1874
1930
|
|
|
1875
1931
|
// packages/lint-suite/src/lib/rules/no-unused-angular-instance-fields/project-usage/angular/angular-template-read-resolution.ts
|
|
@@ -2308,6 +2364,7 @@ var addTemplateReads = ({
|
|
|
2308
2364
|
};
|
|
2309
2365
|
|
|
2310
2366
|
// packages/lint-suite/src/lib/rules/no-unused-angular-instance-fields/project-usage/angular/angular-template-reads.ts
|
|
2367
|
+
var MISSING = -1n;
|
|
2311
2368
|
var memberNameOf2 = (member) => {
|
|
2312
2369
|
const name = member.name;
|
|
2313
2370
|
if (!name) return [];
|
|
@@ -2333,17 +2390,27 @@ var addTemplateMentions = (source, sink) => {
|
|
|
2333
2390
|
for (const [name] of source.matchAll(IDENTIFIER)) sink.addMention(name);
|
|
2334
2391
|
};
|
|
2335
2392
|
var templateFileVersion = (fileName) => {
|
|
2336
|
-
const
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2393
|
+
const directory = dirname8(normalize(fileName));
|
|
2394
|
+
try {
|
|
2395
|
+
const { mtimeNs, size } = statSync3(fileName, { bigint: true });
|
|
2396
|
+
const version = { directory, fileName, mtimeNs, size };
|
|
2397
|
+
return version;
|
|
2398
|
+
} catch {
|
|
2399
|
+
const missing = {
|
|
2400
|
+
directory,
|
|
2401
|
+
fileName,
|
|
2402
|
+
mtimeNs: MISSING,
|
|
2403
|
+
size: MISSING
|
|
2404
|
+
};
|
|
2405
|
+
return missing;
|
|
2406
|
+
}
|
|
2340
2407
|
};
|
|
2341
2408
|
var templateFileIsCurrent = (version) => {
|
|
2342
2409
|
try {
|
|
2343
2410
|
const current = statSync3(version.fileName, { bigint: true });
|
|
2344
2411
|
return current.mtimeNs === version.mtimeNs && current.size === version.size;
|
|
2345
2412
|
} catch {
|
|
2346
|
-
return
|
|
2413
|
+
return version.mtimeNs === MISSING;
|
|
2347
2414
|
}
|
|
2348
2415
|
};
|
|
2349
2416
|
var templateSourceOf = (angularClass2, allNames, sink, versions) => {
|
|
@@ -2362,9 +2429,9 @@ var templateSourceOf = (angularClass2, allNames, sink, versions) => {
|
|
|
2362
2429
|
return inlineSource;
|
|
2363
2430
|
}
|
|
2364
2431
|
const templateFileName = template.fileName;
|
|
2432
|
+
versions.push(templateFileVersion(templateFileName));
|
|
2365
2433
|
try {
|
|
2366
|
-
|
|
2367
|
-
const source = readFileSync3(templateFileName, "utf8");
|
|
2434
|
+
const source = readFileSync4(templateFileName, "utf8");
|
|
2368
2435
|
const externalSource = {
|
|
2369
2436
|
fileName: templateFileName,
|
|
2370
2437
|
source
|
|
@@ -2412,6 +2479,18 @@ var collectAngularTemplateReads = ({
|
|
|
2412
2479
|
return templateReads2;
|
|
2413
2480
|
};
|
|
2414
2481
|
|
|
2482
|
+
// packages/lint-suite/src/lib/rules/no-unused-angular-instance-fields/project-usage/typescript/typescript-dangling-imports.ts
|
|
2483
|
+
import { isImportDeclaration } from "typescript";
|
|
2484
|
+
var hasDanglingImport = (sourceFile, checker) => {
|
|
2485
|
+
for (const statement of sourceFile.statements) {
|
|
2486
|
+
if (!isImportDeclaration(statement)) continue;
|
|
2487
|
+
if (!statement.importClause) continue;
|
|
2488
|
+
const symbol = checker.getSymbolAtLocation(statement.moduleSpecifier);
|
|
2489
|
+
if (!symbol) return true;
|
|
2490
|
+
}
|
|
2491
|
+
return false;
|
|
2492
|
+
};
|
|
2493
|
+
|
|
2415
2494
|
// packages/lint-suite/src/lib/rules/no-unused-angular-instance-fields/project-usage/typescript/typescript-reads.ts
|
|
2416
2495
|
import {
|
|
2417
2496
|
forEachChild as forEachChild2,
|
|
@@ -2969,6 +3048,13 @@ var collectFileReads = (index, sourceFile, checker, sink) => {
|
|
|
2969
3048
|
return noTemplateReads;
|
|
2970
3049
|
}
|
|
2971
3050
|
};
|
|
3051
|
+
var addDanglingFallback = (index, sourceFile, mentionedNames, sink) => {
|
|
3052
|
+
const isCandidate = (name) => index.candidateNames.has(name);
|
|
3053
|
+
const mentioned = [...mentionedNames];
|
|
3054
|
+
const names = mentioned.filter(isCandidate);
|
|
3055
|
+
const reason = `${sourceFile.fileName}: an import resolves to no module`;
|
|
3056
|
+
sink.addFallbackNames(names, reason);
|
|
3057
|
+
};
|
|
2972
3058
|
var computeEntry = (index, sourceFile, checker) => {
|
|
2973
3059
|
const declarations = /* @__PURE__ */ new Set();
|
|
2974
3060
|
const dependencies = /* @__PURE__ */ new Set();
|
|
@@ -2993,9 +3079,12 @@ var computeEntry = (index, sourceFile, checker) => {
|
|
|
2993
3079
|
}
|
|
2994
3080
|
};
|
|
2995
3081
|
const reads = collectFileReads(index, sourceFile, checker, sink);
|
|
3082
|
+
const dangling = hasDanglingImport(sourceFile, checker);
|
|
3083
|
+
if (dangling) addDanglingFallback(index, sourceFile, mentionedNames, sink);
|
|
2996
3084
|
dependencies.delete(sourceFile);
|
|
2997
3085
|
const fileEntry2 = {
|
|
2998
3086
|
...reads,
|
|
3087
|
+
dangling,
|
|
2999
3088
|
declarations,
|
|
3000
3089
|
dependencies,
|
|
3001
3090
|
fallbackNames,
|
|
@@ -3030,7 +3119,7 @@ import {
|
|
|
3030
3119
|
canHaveDecorators as canHaveDecorators2,
|
|
3031
3120
|
getDecorators as getDecorators2,
|
|
3032
3121
|
isCallExpression as isCallExpression2,
|
|
3033
|
-
isImportDeclaration,
|
|
3122
|
+
isImportDeclaration as isImportDeclaration2,
|
|
3034
3123
|
isStringLiteralLike as isStringLiteralLike5
|
|
3035
3124
|
} from "typescript";
|
|
3036
3125
|
var decoratorKinds = [
|
|
@@ -3046,16 +3135,16 @@ var isAngularCoreFile = (declaration) => {
|
|
|
3046
3135
|
const fileName = declaration.getSourceFile().fileName.replaceAll("\\", "/");
|
|
3047
3136
|
return fileName.includes("/node_modules/@angular/core/");
|
|
3048
3137
|
};
|
|
3049
|
-
var
|
|
3138
|
+
var parentOf3 = (node) => {
|
|
3050
3139
|
return node.parent;
|
|
3051
3140
|
};
|
|
3052
3141
|
var importedFromAngularCore = (declaration) => {
|
|
3053
|
-
let current =
|
|
3142
|
+
let current = parentOf3(declaration);
|
|
3054
3143
|
while (current) {
|
|
3055
|
-
if (
|
|
3144
|
+
if (isImportDeclaration2(current)) {
|
|
3056
3145
|
return isStringLiteralLike5(current.moduleSpecifier) && current.moduleSpecifier.text === "@angular/core";
|
|
3057
3146
|
}
|
|
3058
|
-
current =
|
|
3147
|
+
current = parentOf3(current);
|
|
3059
3148
|
}
|
|
3060
3149
|
return false;
|
|
3061
3150
|
};
|
|
@@ -3103,7 +3192,7 @@ var classDecoratorKind = (declaration, discovery) => {
|
|
|
3103
3192
|
};
|
|
3104
3193
|
|
|
3105
3194
|
// packages/lint-suite/src/lib/rules/no-unused-angular-instance-fields/project-usage/angular/angular-metadata-values.ts
|
|
3106
|
-
import { dirname as
|
|
3195
|
+
import { dirname as dirname9, resolve as resolve4 } from "node:path";
|
|
3107
3196
|
import {
|
|
3108
3197
|
isIdentifier as isIdentifier6,
|
|
3109
3198
|
isNumericLiteral as isNumericLiteral2,
|
|
@@ -3153,7 +3242,7 @@ var templateOf = (metadata, fileName, discovery) => {
|
|
|
3153
3242
|
if (url) {
|
|
3154
3243
|
const text2 = stringValue(url, discovery);
|
|
3155
3244
|
if (text2 === null) return void 0;
|
|
3156
|
-
const externalFileName = resolve4(
|
|
3245
|
+
const externalFileName = resolve4(dirname9(fileName), text2);
|
|
3157
3246
|
const externalTemplate = {
|
|
3158
3247
|
fileName: externalFileName,
|
|
3159
3248
|
kind: "external"
|
|
@@ -3536,6 +3625,7 @@ var lazyChecker = (program) => {
|
|
|
3536
3625
|
let typeChecker;
|
|
3537
3626
|
return () => typeChecker ??= program.getTypeChecker();
|
|
3538
3627
|
};
|
|
3628
|
+
var isDangling = (entry) => entry.dangling;
|
|
3539
3629
|
var indexMissingEntries = (index, sourceFiles, checker) => {
|
|
3540
3630
|
for (const sourceFile of sourceFiles) {
|
|
3541
3631
|
const isEntryIndexed = index.entries.has(sourceFile.fileName);
|
|
@@ -3547,6 +3637,7 @@ var reindexProgram = (index, program, checker) => {
|
|
|
3547
3637
|
const indexable = indexableSourceFiles(program);
|
|
3548
3638
|
const current = currentSourceFiles(program);
|
|
3549
3639
|
dropReplacedEntries(index, current);
|
|
3640
|
+
dropEntries(index, isDangling);
|
|
3550
3641
|
const newNames = reconcileClasses(index, indexable, current, checker);
|
|
3551
3642
|
dropEntriesMentioning(index, newNames);
|
|
3552
3643
|
index.program = program;
|
|
@@ -3571,7 +3662,7 @@ var isLocalEntry = (entry, sourceFile, directory) => {
|
|
|
3571
3662
|
var refreshLocalEntries = (index, program, fileName, checker) => {
|
|
3572
3663
|
const sourceFile = program.getSourceFile(fileName);
|
|
3573
3664
|
if (!sourceFile) return;
|
|
3574
|
-
const directory =
|
|
3665
|
+
const directory = dirname10(normalize2(sourceFile.fileName));
|
|
3575
3666
|
const stale = [];
|
|
3576
3667
|
for (const entry of index.entries.values()) {
|
|
3577
3668
|
if (entry.templateVersions.length === 0) continue;
|
|
@@ -5760,7 +5851,24 @@ var ruleDefaults4 = { entryPoints: [...entryPointDefaults] };
|
|
|
5760
5851
|
var defaultOptions7 = [ruleDefaults4];
|
|
5761
5852
|
|
|
5762
5853
|
// packages/lint-suite/src/lib/rules/no-unused-exports/export-index.ts
|
|
5763
|
-
import { dirname as
|
|
5854
|
+
import { dirname as dirname11 } from "node:path";
|
|
5855
|
+
|
|
5856
|
+
// packages/lint-suite/src/lib/rules/no-unused-exports/disk-resolver.ts
|
|
5857
|
+
import { resolveModuleName, sys } from "typescript";
|
|
5858
|
+
var diskResolver = (program) => {
|
|
5859
|
+
const options = program.getCompilerOptions();
|
|
5860
|
+
return (specifier) => {
|
|
5861
|
+
const containingFile = specifier.getSourceFile().fileName;
|
|
5862
|
+
const { resolvedModule } = resolveModuleName(
|
|
5863
|
+
specifier.text,
|
|
5864
|
+
containingFile,
|
|
5865
|
+
options,
|
|
5866
|
+
sys
|
|
5867
|
+
);
|
|
5868
|
+
if (!resolvedModule) return void 0;
|
|
5869
|
+
return program.getSourceFile(resolvedModule.resolvedFileName);
|
|
5870
|
+
};
|
|
5871
|
+
};
|
|
5764
5872
|
|
|
5765
5873
|
// packages/lint-suite/src/lib/rules/no-unused-exports/utils/export-usage.util.ts
|
|
5766
5874
|
var MAX_DEPTH = 50;
|
|
@@ -5991,7 +6099,7 @@ import {
|
|
|
5991
6099
|
isCallExpression as isCallExpression4,
|
|
5992
6100
|
isExportAssignment,
|
|
5993
6101
|
isExportDeclaration,
|
|
5994
|
-
isImportDeclaration as
|
|
6102
|
+
isImportDeclaration as isImportDeclaration3,
|
|
5995
6103
|
isModuleDeclaration,
|
|
5996
6104
|
isNamespaceImport
|
|
5997
6105
|
} from "typescript";
|
|
@@ -6083,22 +6191,37 @@ var exportedNames = (statement) => {
|
|
|
6083
6191
|
return [name];
|
|
6084
6192
|
};
|
|
6085
6193
|
|
|
6086
|
-
// packages/lint-suite/src/lib/rules/no-unused-exports/utils/module-
|
|
6194
|
+
// packages/lint-suite/src/lib/rules/no-unused-exports/utils/module-resolver.util.ts
|
|
6195
|
+
import { isStringLiteralLike as isStringLiteralLike9 } from "typescript";
|
|
6087
6196
|
var declarationOf = (specifier, checker) => {
|
|
6088
6197
|
const symbol = checker.getSymbolAtLocation(specifier);
|
|
6089
6198
|
if (!symbol) return void 0;
|
|
6090
6199
|
return symbol.valueDeclaration ?? symbol.declarations?.[0];
|
|
6091
6200
|
};
|
|
6092
|
-
var
|
|
6093
|
-
if (!specifier) return void 0;
|
|
6201
|
+
var declaredSourceFile = (specifier, checker) => {
|
|
6094
6202
|
const declaration = declarationOf(specifier, checker);
|
|
6095
6203
|
if (!declaration) return void 0;
|
|
6096
|
-
|
|
6204
|
+
return declaration.getSourceFile();
|
|
6205
|
+
};
|
|
6206
|
+
var moduleTarget = (sourceFile, isExternal) => {
|
|
6097
6207
|
if (sourceFile.isDeclarationFile) return void 0;
|
|
6098
6208
|
const isSourceExternal = isExternal(sourceFile);
|
|
6099
6209
|
if (isSourceExternal) return void 0;
|
|
6100
6210
|
return sourceFile.fileName;
|
|
6101
6211
|
};
|
|
6212
|
+
var moduleResolver = (resolution, dangling) => {
|
|
6213
|
+
const { checker, isExternal, onDisk } = resolution;
|
|
6214
|
+
return (specifier) => {
|
|
6215
|
+
if (!specifier) return void 0;
|
|
6216
|
+
const declared = declaredSourceFile(specifier, checker);
|
|
6217
|
+
if (declared) return moduleTarget(declared, isExternal);
|
|
6218
|
+
if (!isStringLiteralLike9(specifier)) return void 0;
|
|
6219
|
+
const found = onDisk(specifier);
|
|
6220
|
+
if (found) return moduleTarget(found, isExternal);
|
|
6221
|
+
dangling.push(specifier.text);
|
|
6222
|
+
return void 0;
|
|
6223
|
+
};
|
|
6224
|
+
};
|
|
6102
6225
|
|
|
6103
6226
|
// packages/lint-suite/src/lib/rules/no-unused-exports/utils/module-edges.util.ts
|
|
6104
6227
|
var importNames = (clause) => {
|
|
@@ -6164,16 +6287,17 @@ var emptyEdges = () => {
|
|
|
6164
6287
|
declared: /* @__PURE__ */ new Set(),
|
|
6165
6288
|
imports: [],
|
|
6166
6289
|
reExports: [],
|
|
6167
|
-
starTargets: []
|
|
6290
|
+
starTargets: [],
|
|
6291
|
+
dangling: []
|
|
6168
6292
|
};
|
|
6169
6293
|
return edges;
|
|
6170
6294
|
};
|
|
6171
|
-
var moduleEdges = (sourceFile,
|
|
6172
|
-
const resolve5 = (specifier) => moduleTarget(specifier, checker, isExternal);
|
|
6295
|
+
var moduleEdges = (sourceFile, resolution) => {
|
|
6173
6296
|
const edges = emptyEdges();
|
|
6297
|
+
const resolve5 = moduleResolver(resolution, edges.dangling);
|
|
6174
6298
|
let skipped = false;
|
|
6175
6299
|
for (const statement of sourceFile.statements) {
|
|
6176
|
-
if (
|
|
6300
|
+
if (isImportDeclaration3(statement)) {
|
|
6177
6301
|
addImport2(statement, edges, resolve5);
|
|
6178
6302
|
} else if (isExportDeclaration(statement)) {
|
|
6179
6303
|
if (statement.moduleSpecifier) addExportFrom(statement, edges, resolve5);
|
|
@@ -6218,28 +6342,32 @@ var LAST_AGGREGATE = /* @__PURE__ */ new Map();
|
|
|
6218
6342
|
var projectKey = (program) => {
|
|
6219
6343
|
const configFilePath = program.getCompilerOptions()["configFilePath"];
|
|
6220
6344
|
if (typeof configFilePath === "string") return configFilePath;
|
|
6221
|
-
const directories = program.getRootFileNames().map(
|
|
6345
|
+
const directories = program.getRootFileNames().map(dirname11);
|
|
6222
6346
|
const uniqueDirectorySet = new Set(directories);
|
|
6223
6347
|
const uniqueDirectories = [...uniqueDirectorySet];
|
|
6224
6348
|
const sortedDirectories = uniqueDirectories.sort();
|
|
6225
6349
|
return sortedDirectories.join("|");
|
|
6226
6350
|
};
|
|
6227
|
-
var fileEdges = (sourceFile,
|
|
6351
|
+
var fileEdges = (sourceFile, resolution) => {
|
|
6228
6352
|
const cached = FILE_EDGES.get(sourceFile);
|
|
6229
|
-
|
|
6230
|
-
const
|
|
6353
|
+
const isCached = cached !== void 0;
|
|
6354
|
+
const isSettled = isCached && cached.dangling.length === 0;
|
|
6355
|
+
if (isSettled) return cached;
|
|
6356
|
+
const edges = moduleEdges(sourceFile, resolution);
|
|
6231
6357
|
FILE_EDGES.set(sourceFile, edges);
|
|
6232
6358
|
return edges;
|
|
6233
6359
|
};
|
|
6234
6360
|
var programEdges = (program) => {
|
|
6235
6361
|
const checker = program.getTypeChecker();
|
|
6236
6362
|
const isExternal = (sourceFile) => program.isSourceFileFromExternalLibrary(sourceFile);
|
|
6363
|
+
const onDisk = diskResolver(program);
|
|
6364
|
+
const resolution = { checker, isExternal, onDisk };
|
|
6237
6365
|
const byFile = /* @__PURE__ */ new Map();
|
|
6238
6366
|
for (const sourceFile of program.getSourceFiles()) {
|
|
6239
6367
|
if (sourceFile.isDeclarationFile) continue;
|
|
6240
6368
|
const isSourceExternal = isExternal(sourceFile);
|
|
6241
6369
|
if (isSourceExternal) continue;
|
|
6242
|
-
byFile.set(sourceFile.fileName, fileEdges(sourceFile,
|
|
6370
|
+
byFile.set(sourceFile.fileName, fileEdges(sourceFile, resolution));
|
|
6243
6371
|
}
|
|
6244
6372
|
return byFile;
|
|
6245
6373
|
};
|
|
@@ -7418,6 +7546,14 @@ var typescriptSafety = defineConfig18([
|
|
|
7418
7546
|
// Class actions carry their payload as constructor parameter properties.
|
|
7419
7547
|
"@typescript-eslint/parameter-properties": "off"
|
|
7420
7548
|
}
|
|
7549
|
+
},
|
|
7550
|
+
{
|
|
7551
|
+
files: ["**/*.stub.ts"],
|
|
7552
|
+
rules: {
|
|
7553
|
+
// local/test-file-shape requires STUB: Type; a literal stub would trip
|
|
7554
|
+
// no-inferrable-types.
|
|
7555
|
+
"@typescript-eslint/no-inferrable-types": "off"
|
|
7556
|
+
}
|
|
7421
7557
|
}
|
|
7422
7558
|
]);
|
|
7423
7559
|
|