@cplieger/deadset-ts 4.0.1 → 5.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.
Files changed (138) hide show
  1. package/README.md +4 -4
  2. package/dist/bin/component-mapper.js +5 -0
  3. package/dist/bin/mapper-connection.js +101 -0
  4. package/dist/bin/node-host.js +24 -2
  5. package/dist/src/analysis.js +301 -41
  6. package/dist/src/component-files.js +612 -0
  7. package/dist/src/component-layer.js +132 -0
  8. package/dist/src/config.js +9 -2
  9. package/dist/src/configuration-files.js +290 -0
  10. package/dist/src/conformance-record.js +3 -9
  11. package/dist/src/contextual-uses.js +240 -0
  12. package/dist/src/convention-rows.js +389 -0
  13. package/dist/src/conventions.js +565 -0
  14. package/dist/src/dependencies.js +36 -3
  15. package/dist/src/destructuring.js +6 -6
  16. package/dist/src/discover.js +10 -3
  17. package/dist/src/emit-map.js +72 -0
  18. package/dist/src/entry-point-gaps.js +81 -35
  19. package/dist/src/entry-points.js +50 -32
  20. package/dist/src/exempt-classes.js +6 -1
  21. package/dist/src/exempt.js +32 -20
  22. package/dist/src/findings/completion.js +46 -32
  23. package/dist/src/findings/emitters.js +22 -1
  24. package/dist/src/findings/interfaces.js +6 -2
  25. package/dist/src/findings/reads-and-writes.js +53 -9
  26. package/dist/src/findings/unused-declarations.js +47 -3
  27. package/dist/src/generated-file.js +24 -0
  28. package/dist/src/graph.js +13 -5
  29. package/dist/src/interface-satisfaction.js +2 -68
  30. package/dist/src/inventory.js +8 -3
  31. package/dist/src/kinds.js +6 -5
  32. package/dist/src/manifest.js +37 -11
  33. package/dist/src/matrix.js +21 -13
  34. package/dist/src/partial.js +3 -1
  35. package/dist/src/pnpm-workspace.js +120 -0
  36. package/dist/src/position.js +17 -2
  37. package/dist/src/print.js +2 -0
  38. package/dist/src/query.js +15 -0
  39. package/dist/src/references.js +404 -36
  40. package/dist/src/report.js +26 -6
  41. package/dist/src/reporters/annotations.js +10 -3
  42. package/dist/src/reporters/template.js +3 -0
  43. package/dist/src/resolve.js +37 -11
  44. package/dist/src/roots.js +37 -8
  45. package/dist/src/run.js +13 -3
  46. package/dist/src/schema.js +2 -0
  47. package/dist/src/session.js +141 -34
  48. package/dist/src/setup-failure.js +23 -0
  49. package/dist/src/source-files.js +4 -61
  50. package/dist/src/stores.js +3 -0
  51. package/dist/src/sweep.js +4 -2
  52. package/dist/src/template-field.js +38 -6
  53. package/dist/src/test-support.js +59 -0
  54. package/dist/src/type-errors.js +252 -0
  55. package/dist/src/type-query-alias.js +92 -0
  56. package/dist/src/value-flow.js +74 -0
  57. package/dist/src/verbs/analyze.js +24 -4
  58. package/dist/src/verbs/explain.js +4 -1
  59. package/dist/src/verbs/print-projects.js +17 -56
  60. package/dist/src/verbs/print-retained.js +7 -2
  61. package/dist/src/verbs/print-roots.js +7 -2
  62. package/dist/src/version-range.js +255 -0
  63. package/dist/src/version.js +1 -1
  64. package/dist/src/workspace-manifests.js +68 -0
  65. package/dist/src/workspace-programs.js +342 -0
  66. package/dist/src/workspace-resolution.js +307 -0
  67. package/dist/src/workspace-run.js +75 -0
  68. package/dist/src/workspace.js +358 -0
  69. package/jsr.json +1 -1
  70. package/package.json +3 -2
  71. package/src/analysis.ts +475 -72
  72. package/src/component-files.ts +718 -0
  73. package/src/component-layer.ts +160 -0
  74. package/src/config.ts +11 -2
  75. package/src/configuration-files.ts +370 -0
  76. package/src/conformance-record.ts +3 -10
  77. package/src/contextual-uses.ts +354 -0
  78. package/src/convention-rows.ts +448 -0
  79. package/src/conventions.ts +788 -0
  80. package/src/dependencies.ts +49 -2
  81. package/src/destructuring.ts +16 -6
  82. package/src/discover.ts +10 -6
  83. package/src/emit-map.ts +93 -0
  84. package/src/entry-point-gaps.ts +92 -38
  85. package/src/entry-points.ts +79 -36
  86. package/src/exempt-classes.ts +6 -1
  87. package/src/exempt.ts +69 -20
  88. package/src/file-facts.ts +2 -0
  89. package/src/findings/completion.ts +55 -36
  90. package/src/findings/emitters.ts +32 -1
  91. package/src/findings/interfaces.ts +9 -2
  92. package/src/findings/reads-and-writes.ts +70 -9
  93. package/src/findings/unused-declarations.ts +60 -3
  94. package/src/generated-file.ts +27 -0
  95. package/src/graph.ts +15 -4
  96. package/src/host.ts +23 -0
  97. package/src/index.ts +1 -1
  98. package/src/interface-satisfaction.ts +1 -92
  99. package/src/inventory.ts +17 -3
  100. package/src/kinds.ts +7 -5
  101. package/src/manifest.ts +47 -14
  102. package/src/matrix.ts +43 -15
  103. package/src/partial.ts +6 -1
  104. package/src/pnpm-workspace.ts +135 -0
  105. package/src/position.ts +23 -2
  106. package/src/print.ts +2 -0
  107. package/src/query.ts +26 -0
  108. package/src/references.ts +472 -40
  109. package/src/report.ts +56 -6
  110. package/src/reporters/annotations.ts +12 -3
  111. package/src/reporters/template.ts +3 -0
  112. package/src/resolve.ts +65 -11
  113. package/src/roots.ts +70 -9
  114. package/src/run.ts +15 -5
  115. package/src/schema.ts +2 -0
  116. package/src/session.ts +218 -37
  117. package/src/setup-failure.ts +39 -0
  118. package/src/source-files.ts +4 -66
  119. package/src/stores.ts +9 -0
  120. package/src/sweep.ts +9 -2
  121. package/src/template-field.ts +42 -7
  122. package/src/test-support.ts +77 -0
  123. package/src/type-errors.ts +340 -0
  124. package/src/type-query-alias.ts +133 -0
  125. package/src/value-flow.ts +104 -0
  126. package/src/verbs/analyze.ts +38 -4
  127. package/src/verbs/explain.ts +4 -1
  128. package/src/verbs/print-projects.ts +17 -69
  129. package/src/verbs/print-retained.ts +7 -2
  130. package/src/verbs/print-roots.ts +7 -2
  131. package/src/verbs/verb.ts +6 -3
  132. package/src/version-range.ts +309 -0
  133. package/src/version.ts +1 -1
  134. package/src/workspace-manifests.ts +100 -0
  135. package/src/workspace-programs.ts +486 -0
  136. package/src/workspace-resolution.ts +393 -0
  137. package/src/workspace-run.ts +148 -0
  138. package/src/workspace.ts +463 -0
@@ -2,7 +2,8 @@
2
2
  * The dependencies the target's manifest declares, and what the projects' own files
3
3
  * need from outside the target. A file needs a package it imports, re-exports from,
4
4
  * augments or references the types of, by name or through the file the specifier
5
- * resolves to; a configuration needs one it names. A package one dependency pulls in
5
+ * resolves to; a compiler configuration needs one it names, and a configuration file a
6
+ * tool loads needs each dependency its strings spell. A package one dependency pulls in
6
7
  * for itself is that dependency's need, not the target's.
7
8
  */
8
9
 
@@ -21,6 +22,13 @@ import {
21
22
  type Node,
22
23
  type SourceFile,
23
24
  } from "@typescript/native/unstable/ast";
25
+ import {
26
+ configurationFiles,
27
+ declaredIn as declaredBeside,
28
+ dependenciesNamed,
29
+ moduleStrings,
30
+ type ParseFile,
31
+ } from "./configuration-files.ts";
24
32
  import type { FindingPosition } from "./finding.ts";
25
33
  import type { Host } from "./host.ts";
26
34
  import { nodeKey, packageScope, type Inventory } from "./inventory.ts";
@@ -28,6 +36,7 @@ import { dirnamePath, isAbsolutePath, joinPath, resolvePath } from "./paths.ts";
28
36
  import type { DependencySection, Module } from "./ref.ts";
29
37
  import { UNANSWERED } from "./query.ts";
30
38
  import type { Handle, ProjectView } from "./session.ts";
39
+ import { sourceFilesOf } from "./source-files.ts";
31
40
 
32
41
  const MANIFEST = "package.json";
33
42
  const MODULES_DIR = "node_modules";
@@ -268,12 +277,15 @@ function bindingsOf(node: Node | undefined): readonly Texted[] {
268
277
  * Every package one project needs, and which declaration each use is written in.
269
278
  * One local walk and one batched resolution per file: a use of an import binding is
270
279
  * an identifier resolving to the binding's own symbol, so a local declaration that
271
- * shadows the name is not one.
280
+ * shadows the name is not one. A string of a configuration file uses each dependency
281
+ * the manifest beside the file declares that it spells.
272
282
  */
273
283
  export function projectNeeds<Brand>(
274
284
  project: ProjectView<Brand>,
275
285
  held: Inventory,
276
286
  host: Host,
287
+ targetRoot: string,
288
+ parse?: ParseFile,
277
289
  ): ProjectNeeds {
278
290
  const programPackages = new Set<string>();
279
291
  for (const name of project.program.getSourceFileNames()) {
@@ -308,6 +320,41 @@ export function projectNeeds<Brand>(
308
320
  for (const file of project.ownSourceFiles()) {
309
321
  unanswered = fileNeeds(project, held, file, programPackages, use) || unanswered;
310
322
  }
323
+
324
+ const beside = new Map<string, readonly string[]>();
325
+ const declaredAt = (path: string): readonly string[] => {
326
+ const dir = dirnamePath(path);
327
+ let names = beside.get(dir);
328
+ if (names === undefined) {
329
+ names = declaredBeside(host, dir);
330
+ beside.set(dir, names);
331
+ }
332
+ return names;
333
+ };
334
+ const configuration = configurationFiles(
335
+ host,
336
+ targetRoot,
337
+ sourceFilesOf(project, targetRoot),
338
+ parse,
339
+ );
340
+ for (const { file } of configuration.modules) {
341
+ const names = declaredAt(file.fileName);
342
+ for (const { node, text } of moduleStrings(file)) {
343
+ use(ownersOf(file, held, node), dependenciesNamed(text, names));
344
+ }
345
+ }
346
+ for (const document of configuration.documents) {
347
+ const names = declaredAt(document.path);
348
+ for (const text of document.strings) {
349
+ use([PROJECT_OWNER], dependenciesNamed(text, names));
350
+ }
351
+ }
352
+ for (const { file, manifestDir } of configuration.outside) {
353
+ const names = declaredAt(joinPath(manifestDir, "package.json"));
354
+ for (const { text } of moduleStrings(file)) {
355
+ use([PROJECT_OWNER], dependenciesNamed(text, names));
356
+ }
357
+ }
311
358
  return { packages, uses, unanswered };
312
359
  }
313
360
 
@@ -25,7 +25,13 @@ import {
25
25
  type Node,
26
26
  } from "@typescript/native/unstable/ast";
27
27
  import { TypeFlags, type Symbol as TSSymbol, type Type } from "@typescript/native/unstable/sync";
28
- import { isAnswered, UNANSWERED, type Answer } from "./query.ts";
28
+ import {
29
+ isAnswered,
30
+ propertyTables,
31
+ UNANSWERED,
32
+ type Answer,
33
+ type PropertyTables,
34
+ } from "./query.ts";
29
35
  import type { ProjectView } from "./session.ts";
30
36
 
31
37
  /** One property one object pattern reads. */
@@ -228,7 +234,11 @@ type Found = Answer<Type | undefined>;
228
234
  * read once per type for the whole project, since one type is destructured in many
229
235
  * places and a table answers every name of it.
230
236
  */
231
- export function destructuring<Brand>(project: ProjectView<Brand>, cap: number): Destructuring {
237
+ export function destructuring<Brand>(
238
+ project: ProjectView<Brand>,
239
+ cap: number,
240
+ properties: PropertyTables = propertyTables(project.queries),
241
+ ): Destructuring {
232
242
  const queries = project.queries;
233
243
  const tables = new Map<number, Answer<ReadonlyMap<string, TSSymbol>>>();
234
244
  let patternBatches = 0;
@@ -241,10 +251,10 @@ export function destructuring<Brand>(project: ProjectView<Brand>, cap: number):
241
251
  }
242
252
  let table: Answer<ReadonlyMap<string, TSSymbol>> = new Map<string, TSSymbol>();
243
253
  if ((type.flags & TypeFlags.AnyOrUnknown) === 0) {
244
- patternLookups += 1;
245
- const properties = queries.propertiesOf(type);
246
- table = isAnswered(properties)
247
- ? new Map(properties.map((property) => [property.name, property]))
254
+ const read = properties.of(type);
255
+ patternLookups += read.asked ? 1 : 0;
256
+ table = isAnswered(read.properties)
257
+ ? new Map(read.properties.map((property) => [property.name, property]))
248
258
  : UNANSWERED;
249
259
  }
250
260
  tables.set(type.id, table);
package/src/discover.ts CHANGED
@@ -4,6 +4,7 @@ import type { BuildConfiguration, ProjectConfiguration } from "./config.ts";
4
4
  import type { Host } from "./host.ts";
5
5
  import { dirnamePath, isAbsolutePath, joinPath, relativePath, resolvePath } from "./paths.ts";
6
6
  import type { Scope } from "./scope.ts";
7
+ import { SetupError } from "./setup-failure.ts";
7
8
  import type { Engine, ProjectDiagnostics } from "./session.ts";
8
9
 
9
10
  /** Directory names discovery does not descend into. */
@@ -323,13 +324,16 @@ function derivedFrom(
323
324
  */
324
325
  export function consumerProjects(engine: Engine, host: Host, root: string): readonly string[] {
325
326
  const kind = host.kindOf(root);
327
+ if (kind === "absent") {
328
+ throw new SetupError([
329
+ {
330
+ setupClass: "missing-consumer",
331
+ detail: `the scope declares the consumer ${root}, and nothing is at that path: check the consumer out at ${root} and install its dependencies`,
332
+ },
333
+ ]);
334
+ }
326
335
  if (kind !== "directory") {
327
- throw new DiscoveryError(
328
- kind === "absent"
329
- ? `the consumer ${root} does not exist`
330
- : `the consumer ${root} is not a directory`,
331
- [],
332
- );
336
+ throw new DiscoveryError(`the consumer ${root} is not a directory`, []);
333
337
  }
334
338
  const found = derivedFrom(engine, host, configFilesUnder(host, root));
335
339
  if (found.length === 0) {
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Where the compiler writes what it compiles: the output extension each source
3
+ * extension becomes, and the output path one source path is written to. A path a
4
+ * manifest or a document names is read back to its source through this one rule,
5
+ * whether the path is the target's own or a workspace package's.
6
+ */
7
+
8
+ import { dirnamePath, joinPath, relativePath } from "./paths.ts";
9
+
10
+ /** The source extensions the compiler emits each output extension from. */
11
+ const EMITTED: readonly { readonly emitted: string; readonly sources: readonly string[] }[] = [
12
+ { emitted: ".d.ts", sources: [".ts", ".tsx"] },
13
+ { emitted: ".d.mts", sources: [".mts"] },
14
+ { emitted: ".d.cts", sources: [".cts"] },
15
+ { emitted: ".js", sources: [".ts", ".tsx"] },
16
+ { emitted: ".jsx", sources: [".tsx"] },
17
+ { emitted: ".mjs", sources: [".mts"] },
18
+ { emitted: ".cjs", sources: [".cts"] },
19
+ ];
20
+
21
+ /** Where one compiler configuration writes its output, and the directories it writes it from. */
22
+ export interface EmitLayout {
23
+ /** The directory every output is written below, absolute. */
24
+ readonly outDir?: string | undefined;
25
+ /** The directory declaration outputs are written below where it differs, absolute. */
26
+ readonly declarationDir?: string | undefined;
27
+ /**
28
+ * The directories an output path below the output directory is read below, in the
29
+ * order they are tried: the one the configuration declares, or the ones the
30
+ * compiler's default may be.
31
+ */
32
+ readonly sourceDirs: readonly string[];
33
+ }
34
+
35
+ /** One path with its extension replaced, where it carries the one named. */
36
+ function reExtended(path: string, emitted: string, source: string): string | undefined {
37
+ return path.endsWith(emitted) ? path.slice(0, path.length - emitted.length) + source : undefined;
38
+ }
39
+
40
+ /**
41
+ * The longest directory every path shares, which is where the compiler roots its
42
+ * output when the configuration declares no root directory and its directory is not
43
+ * the root.
44
+ */
45
+ export function commonDirectory(paths: readonly string[]): string {
46
+ const first = paths[0];
47
+ if (first === undefined) {
48
+ return "";
49
+ }
50
+ let common = dirnamePath(first).split("/");
51
+ for (const path of paths.slice(1)) {
52
+ const segments = dirnamePath(path).split("/");
53
+ let shared = 0;
54
+ while (
55
+ shared < common.length &&
56
+ shared < segments.length &&
57
+ common[shared] === segments[shared]
58
+ ) {
59
+ shared += 1;
60
+ }
61
+ common = common.slice(0, shared);
62
+ }
63
+ return common.join("/");
64
+ }
65
+
66
+ /**
67
+ * The source paths one written path may be compiled from, in the order they are
68
+ * tried: for each output extension the path carries, the path re-extended where it
69
+ * stands, then read below each source directory where it is below the directory that
70
+ * output is written to.
71
+ */
72
+ export function emittedFrom(path: string, layout: EmitLayout): readonly string[] {
73
+ const found: string[] = [];
74
+ for (const { emitted, sources } of EMITTED) {
75
+ if (!path.endsWith(emitted)) {
76
+ continue;
77
+ }
78
+ const emitDir = emitted.startsWith(".d.")
79
+ ? (layout.declarationDir ?? layout.outDir)
80
+ : layout.outDir;
81
+ const below = emitDir === undefined ? undefined : relativePath(emitDir, path);
82
+ const mapped = below === undefined ? [] : layout.sourceDirs.map((dir) => joinPath(dir, below));
83
+ for (const source of sources) {
84
+ for (const from of [path, ...mapped]) {
85
+ const candidate = reExtended(from, emitted, source);
86
+ if (candidate !== undefined) {
87
+ found.push(candidate);
88
+ }
89
+ }
90
+ }
91
+ }
92
+ return found;
93
+ }
@@ -17,18 +17,23 @@ export interface DeclinedConvention {
17
17
  readonly reason: string;
18
18
  }
19
19
 
20
- /** What is declined for a tool none of whose conventions is entered. */
21
- const EVERY_CONVENTION = "its configuration and every file it loads by its own convention";
20
+ /** What is declined for a tool whose own conventions are entered only through its configuration files. */
21
+ const EVERY_CONVENTION = "every file it loads by its own convention beyond its configuration files";
22
22
 
23
- /** Why a tool none of whose conventions is entered declines them. */
23
+ /** Why a tool whose own conventions are not read declines them. */
24
24
  const UNREAD =
25
- "No rule reads it, so a file only it loads is reported as never imported unless " +
26
- "ts.entry_files or roots.patterns names it.";
25
+ "No rule reads it beyond a configuration file the file-name form or a string enters, so a " +
26
+ "file only it loads is reported as never imported unless ts.entry_files or roots.patterns " +
27
+ "names it.";
27
28
 
28
- /** The tools none of whose conventions is entered. */
29
+ /** Why a configuration's file names that are not relative literals are declined. */
30
+ const NOT_RELATIVE =
31
+ "A string of a configuration file names a file only where it is a literal starting with ./ " +
32
+ "or ../, so a file named otherwise is reported as never imported.";
33
+
34
+ /** The tools whose own conventions are not read. */
29
35
  const UNREAD_TOOLS: readonly string[] = [
30
36
  "angular",
31
- "astro",
32
37
  "astro-db",
33
38
  "astro-markdoc",
34
39
  "astro-og-canvas",
@@ -61,7 +66,6 @@ const UNREAD_TOOLS: readonly string[] = [
61
66
  "esbuild",
62
67
  "eve",
63
68
  "execa",
64
- "expo",
65
69
  "expressive-code",
66
70
  "fast",
67
71
  "fumadocs",
@@ -98,7 +102,6 @@ const UNREAD_TOOLS: readonly string[] = [
98
102
  "nano-staged",
99
103
  "nest",
100
104
  "netlify",
101
- "next",
102
105
  "next-intl",
103
106
  "next-mdx",
104
107
  "nitro",
@@ -106,7 +109,6 @@ const UNREAD_TOOLS: readonly string[] = [
106
109
  "node-modules-inspector",
107
110
  "nodemon",
108
111
  "npm-package-json-lint",
109
- "nuxt",
110
112
  "nuxtjs-i18n",
111
113
  "nx",
112
114
  "nyc",
@@ -131,17 +133,14 @@ const UNREAD_TOOLS: readonly string[] = [
131
133
  "prettier",
132
134
  "prisma",
133
135
  "quasar",
134
- "qwik",
135
136
  "railway",
136
137
  "raycast",
137
138
  "react-cosmos",
138
139
  "react-email",
139
140
  "react-native",
140
- "react-router",
141
141
  "relay",
142
142
  "release-it",
143
143
  "remark",
144
- "remix",
145
144
  "rolldown",
146
145
  "rollup",
147
146
  "rsbuild",
@@ -157,11 +156,9 @@ const UNREAD_TOOLS: readonly string[] = [
157
156
  "sst",
158
157
  "starlight",
159
158
  "stencil",
160
- "storybook",
161
159
  "stylelint",
162
160
  "svelte",
163
161
  "sveltejs-package",
164
- "sveltekit",
165
162
  "svgo",
166
163
  "svgr",
167
164
  "swc",
@@ -184,7 +181,6 @@ const UNREAD_TOOLS: readonly string[] = [
184
181
  "typescript-content-mapper",
185
182
  "unbuild",
186
183
  "unocss",
187
- "unplugin-auto-import",
188
184
  "unplugin-icons",
189
185
  "unplugin-vue-components",
190
186
  "unplugin-vue-i18n",
@@ -215,10 +211,17 @@ const UNREAD_TOOLS: readonly string[] = [
215
211
  const PARTLY_ENTERED: readonly DeclinedConvention[] = [
216
212
  {
217
213
  tool: "eslint",
218
- convention: "the legacy .eslintrc configuration files",
214
+ convention: "a legacy configuration written in YAML or in JSON with comments",
215
+ reason:
216
+ "Only a configuration module and a strict JSON configuration file are read, so a " +
217
+ "dependency only such a file names is reported as unused.",
218
+ },
219
+ {
220
+ tool: "eslint",
221
+ convention: "a plugin or shareable configuration named without its package's prefix",
219
222
  reason:
220
- "Only the flat configuration's file names are entered, so a legacy configuration " +
221
- "file the program holds is reported as never imported.",
223
+ "A string uses a dependency only where it spells the dependency's name, so a " +
224
+ "dependency only a shortened name loads is reported as unused.",
222
225
  },
223
226
  {
224
227
  tool: "playwright",
@@ -229,9 +232,8 @@ const PARTLY_ENTERED: readonly DeclinedConvention[] = [
229
232
  },
230
233
  {
231
234
  tool: "playwright",
232
- convention: "the globalSetup and globalTeardown files",
233
- reason:
234
- "No rule enters them, so a setup file only the runner loads is reported as never imported.",
235
+ convention: "a globalSetup or globalTeardown file named without a leading ./ or ../",
236
+ reason: NOT_RELATIVE,
235
237
  },
236
238
  {
237
239
  tool: "playwright",
@@ -240,17 +242,73 @@ const PARTLY_ENTERED: readonly DeclinedConvention[] = [
240
242
  "Only the configuration object's own testDir and testMatch are read, so a test " +
241
243
  "directory a project entry moves is not entered.",
242
244
  },
245
+ {
246
+ tool: "expo",
247
+ convention: "an app directory the expo-router entry of an app configuration moves",
248
+ reason:
249
+ "The convention row reads the app directory at its default places only, so a route " +
250
+ "below a moved directory is reported as never imported unless ts.entry_files names it.",
251
+ },
252
+ {
253
+ tool: "next",
254
+ convention: "a page extension next.config adds through pageExtensions",
255
+ reason:
256
+ "The convention row roots the default extensions only, so a route file of another " +
257
+ "extension is reported as never imported unless ts.entry_files names it.",
258
+ },
259
+ {
260
+ tool: "nuxt",
261
+ convention: "the files of a layer below layers/ beyond its nuxt.config",
262
+ reason:
263
+ "The convention row reads the project's own directories, so a layer's pages, plugins " +
264
+ "and server routes are reported as never imported unless ts.entry_files names them.",
265
+ },
266
+ {
267
+ tool: "qwik",
268
+ convention: "the routes of @qwik.dev/router",
269
+ reason:
270
+ "No convention row holds for that package, so its route files are reported as " +
271
+ "never imported unless ts.entry_files names them.",
272
+ },
273
+ {
274
+ tool: "react-router",
275
+ convention: "a route module app/routes.ts names outside the routes directory",
276
+ reason:
277
+ "The convention row roots the routes directory, and a string of routes.ts names no " +
278
+ "file, so a route module elsewhere is reported as never imported unless " +
279
+ "ts.entry_files names it.",
280
+ },
281
+ {
282
+ tool: "storybook",
283
+ convention: "a story the stories member of .storybook/main names outside *.stories.* files",
284
+ reason:
285
+ "The convention row roots *.stories.* files, so a story file named otherwise is " +
286
+ "reported as never imported unless ts.entry_files names it.",
287
+ },
243
288
  {
244
289
  tool: "stryker",
245
- convention: "a configuration file named on the command line",
246
- reason: "Only the file names the tool looks for by default are entered.",
290
+ convention: "a configuration file named on a command line no package.json script writes",
291
+ reason:
292
+ "Only the file names the tool looks for by default and the files a script names are entered.",
293
+ },
294
+ {
295
+ tool: "unplugin-auto-import",
296
+ convention: "an import its generated declarations add for a component's template alone",
297
+ reason:
298
+ "Only a global declared as an alias of an export is read, so an export the generated " +
299
+ "declarations name only for templates is reported as unused.",
300
+ },
301
+ {
302
+ tool: "vite",
303
+ convention: "an entry point its configuration names without a leading ./ or ../, or computes",
304
+ reason: NOT_RELATIVE,
247
305
  },
248
306
  {
249
307
  tool: "vite",
250
- convention: "its configuration and every entry point it names",
308
+ convention: "the module scripts an index.html loads",
251
309
  reason:
252
- "Only a worker a call addresses by a literal is entered. No rule reads the " +
253
- "configuration, so a file only it names is reported as never imported.",
310
+ "No rule reads an HTML file, so a script only index.html loads is reported as never " +
311
+ "imported unless ts.entry_files names it.",
254
312
  },
255
313
  {
256
314
  tool: "vitest",
@@ -261,17 +319,15 @@ const PARTLY_ENTERED: readonly DeclinedConvention[] = [
261
319
  },
262
320
  {
263
321
  tool: "vitest",
264
- convention: "the mock files below a __mocks__ directory",
322
+ convention: "the setup files of a configuration that moves its root",
265
323
  reason:
266
- "No rule enters a file by its directory, so a mock only the runner's module mocking " +
267
- "loads is reported as never imported.",
324
+ "A string is read against the configuration file's directory, so a setup file named " +
325
+ "against a root the configuration moves is not entered.",
268
326
  },
269
327
  {
270
328
  tool: "vitest",
271
- convention: "the setup files of a configuration that moves its root",
272
- reason:
273
- "A configuration writing root reads its setup files against a directory its text " +
274
- "may not state, so none of them is entered.",
329
+ convention: "a setup file named without a leading ./ or ../",
330
+ reason: NOT_RELATIVE,
275
331
  },
276
332
  {
277
333
  tool: "vitest",
@@ -282,10 +338,8 @@ const PARTLY_ENTERED: readonly DeclinedConvention[] = [
282
338
  },
283
339
  {
284
340
  tool: "webpack",
285
- convention: "its configuration and every entry point it names",
286
- reason:
287
- "Only a worker a call addresses by a literal is entered. No rule reads the " +
288
- "configuration, so a file only it names is reported as never imported.",
341
+ convention: "an entry point its configuration names without a leading ./ or ../, or computes",
342
+ reason: NOT_RELATIVE,
289
343
  },
290
344
  ];
291
345