@cplieger/deadset-ts 8.0.0-dev.6 → 8.0.0-dev.8

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 (193) hide show
  1. package/dist/bin/mapper-connection.js +2 -1
  2. package/dist/bin/node-host.js +24 -5
  3. package/dist/src/analysis.js +37 -56
  4. package/dist/src/automatic-types.js +10 -29
  5. package/dist/src/build-scripts.js +17 -29
  6. package/dist/src/component-layer.js +4 -2
  7. package/dist/src/components.js +2 -3
  8. package/dist/src/config.js +6 -82
  9. package/dist/src/configuration-files.js +27 -168
  10. package/dist/src/configured-declarations.js +15 -20
  11. package/dist/src/consumers.js +2 -2
  12. package/dist/src/contract/config.generated.js +544 -0
  13. package/dist/src/contract/contract.generated.js +13 -0
  14. package/dist/src/contract/report.generated.js +3 -2
  15. package/dist/src/conventions.js +20 -60
  16. package/dist/src/dependencies.js +25 -43
  17. package/dist/src/discover.js +14 -40
  18. package/dist/src/edges.js +38 -122
  19. package/dist/src/element-access.js +4 -6
  20. package/dist/src/entry-point-gaps.js +2 -8
  21. package/dist/src/entry-points.js +3 -10
  22. package/dist/src/enum-group.js +3 -10
  23. package/dist/src/erased-stores.js +4 -6
  24. package/dist/src/exempt-classes.js +0 -4
  25. package/dist/src/exempt.js +6 -22
  26. package/dist/src/file-facts.js +2 -25
  27. package/dist/src/findings/completion.js +5 -4
  28. package/dist/src/findings/emitters.js +1 -1
  29. package/dist/src/findings/intra-function.js +1 -1
  30. package/dist/src/findings/non-code-artifacts.js +2 -2
  31. package/dist/src/findings/reads-and-writes.js +2 -1
  32. package/dist/src/findings/self-check.js +3 -2
  33. package/dist/src/findings/unused-declarations.js +1 -1
  34. package/dist/src/findings/visibility-narrowing.js +2 -2
  35. package/dist/src/findings-pass.js +7 -12
  36. package/dist/src/framework-lifecycle.js +7 -7
  37. package/dist/src/fs/document.js +59 -0
  38. package/dist/src/fs/manifest.js +43 -0
  39. package/dist/src/fs/tree.js +88 -0
  40. package/dist/src/git-ignore.js +34 -25
  41. package/dist/src/html-entries.js +6 -33
  42. package/dist/src/in-operands.js +2 -1
  43. package/dist/src/injection-container.js +1 -1
  44. package/dist/src/intra-function-parts.js +10 -13
  45. package/dist/src/inventory.js +2 -21
  46. package/dist/src/json-document.js +198 -67
  47. package/dist/src/keyof-comparisons.js +4 -6
  48. package/dist/src/kinds.js +0 -7
  49. package/dist/src/manifest.js +5 -43
  50. package/dist/src/mdx-entries.js +3 -26
  51. package/dist/src/partial.js +2 -1
  52. package/dist/src/paths.js +26 -15
  53. package/dist/src/position.js +2 -1
  54. package/dist/src/print.js +11 -79
  55. package/dist/src/product.js +13 -0
  56. package/dist/src/references.js +14 -27
  57. package/dist/src/report-schema.js +3 -225
  58. package/dist/src/report.js +22 -31
  59. package/dist/src/reporters/sarif.js +4 -2
  60. package/dist/src/reporters/template.js +4 -19
  61. package/dist/src/resolve.js +245 -724
  62. package/dist/src/roots.js +7 -17
  63. package/dist/src/run.js +55 -61
  64. package/dist/src/schema.js +320 -343
  65. package/dist/src/scope.js +34 -103
  66. package/dist/src/serialization-contract.js +5 -9
  67. package/dist/src/session.js +2 -1
  68. package/dist/src/suppress-file.js +21 -25
  69. package/dist/src/suppress.js +3 -3
  70. package/dist/src/symbol-keys.js +3 -5
  71. package/dist/src/template-field.js +9 -19
  72. package/dist/src/test-globals.js +6 -28
  73. package/dist/src/test-joins.js +6 -6
  74. package/dist/src/text/compare.js +26 -0
  75. package/dist/src/text/glob.js +194 -0
  76. package/dist/src/text/shell.js +159 -0
  77. package/dist/src/{yaml-document.js → text/yaml.js} +38 -0
  78. package/dist/src/type-errors.js +14 -38
  79. package/dist/src/unseen-loads.js +2 -9
  80. package/dist/src/unwrap.js +23 -0
  81. package/dist/src/usage.js +10 -0
  82. package/dist/src/verbs/analyze.js +25 -26
  83. package/dist/src/verbs/describe.js +4 -4
  84. package/dist/src/verbs/explain.js +8 -6
  85. package/dist/src/verbs/print-projects.js +4 -3
  86. package/dist/src/verbs/print-retained.js +2 -1
  87. package/dist/src/verbs/print-roots.js +2 -1
  88. package/dist/src/verbs/version.js +2 -1
  89. package/dist/src/workflow-steps.js +9 -46
  90. package/dist/src/workspace-manifests.js +2 -2
  91. package/dist/src/workspace-programs.js +5 -3
  92. package/dist/src/workspace-resolution.js +13 -17
  93. package/dist/src/workspace.js +28 -116
  94. package/jsr.json +1 -1
  95. package/package.json +1 -1
  96. package/src/analysis.ts +55 -76
  97. package/src/automatic-types.ts +11 -29
  98. package/src/build-scripts.ts +17 -38
  99. package/src/component-layer.ts +4 -2
  100. package/src/components.ts +2 -4
  101. package/src/config.ts +31 -296
  102. package/src/configuration-files.ts +27 -170
  103. package/src/configured-declarations.ts +18 -23
  104. package/src/consumers.ts +4 -4
  105. package/src/contract/config.generated.ts +798 -0
  106. package/src/contract/contract.generated.ts +25 -0
  107. package/src/contract/report.generated.ts +3 -2
  108. package/src/conventions.ts +26 -74
  109. package/src/dependencies.ts +32 -50
  110. package/src/discover.ts +15 -40
  111. package/src/edges.ts +41 -140
  112. package/src/element-access.ts +4 -7
  113. package/src/entry-point-gaps.ts +3 -9
  114. package/src/entry-points.ts +2 -13
  115. package/src/enum-group.ts +2 -11
  116. package/src/erased-stores.ts +3 -7
  117. package/src/exempt-classes.ts +0 -5
  118. package/src/exempt.ts +8 -30
  119. package/src/file-facts.ts +6 -24
  120. package/src/findings/completion.ts +5 -6
  121. package/src/findings/emitter.ts +2 -2
  122. package/src/findings/emitters.ts +1 -1
  123. package/src/findings/intra-function.ts +1 -1
  124. package/src/findings/non-code-artifacts.ts +4 -4
  125. package/src/findings/reads-and-writes.ts +2 -1
  126. package/src/findings/self-check.ts +3 -2
  127. package/src/findings/unused-declarations.ts +1 -1
  128. package/src/findings/visibility-narrowing.ts +2 -2
  129. package/src/findings-pass.ts +9 -15
  130. package/src/framework-lifecycle.ts +7 -7
  131. package/src/fs/document.ts +74 -0
  132. package/src/fs/manifest.ts +52 -0
  133. package/src/fs/tree.ts +110 -0
  134. package/src/git-ignore.ts +38 -25
  135. package/src/host.ts +12 -5
  136. package/src/html-entries.ts +6 -33
  137. package/src/in-operands.ts +2 -1
  138. package/src/injection-container.ts +1 -1
  139. package/src/intra-function-parts.ts +10 -14
  140. package/src/inventory.ts +2 -20
  141. package/src/json-document.ts +241 -76
  142. package/src/keyof-comparisons.ts +3 -7
  143. package/src/kinds.ts +0 -8
  144. package/src/manifest.ts +5 -46
  145. package/src/mdx-entries.ts +3 -26
  146. package/src/partial.ts +2 -1
  147. package/src/paths.ts +27 -15
  148. package/src/position.ts +2 -1
  149. package/src/print.ts +12 -92
  150. package/src/product.ts +18 -0
  151. package/src/references.ts +14 -29
  152. package/src/report-schema.ts +3 -301
  153. package/src/report.ts +24 -34
  154. package/src/reporters/sarif.ts +4 -4
  155. package/src/reporters/template.ts +4 -20
  156. package/src/resolve.ts +283 -1114
  157. package/src/roots.ts +7 -20
  158. package/src/run.ts +57 -75
  159. package/src/schema.ts +391 -388
  160. package/src/scope.ts +40 -126
  161. package/src/serialization-contract.ts +5 -10
  162. package/src/session.ts +2 -1
  163. package/src/suppress-file.ts +21 -29
  164. package/src/suppress.ts +3 -3
  165. package/src/symbol-keys.ts +2 -5
  166. package/src/template-field.ts +15 -25
  167. package/src/test-globals.ts +9 -27
  168. package/src/test-joins.ts +6 -8
  169. package/src/text/compare.ts +27 -0
  170. package/src/text/glob.ts +210 -0
  171. package/src/text/shell.ts +161 -0
  172. package/src/{yaml-document.ts → text/yaml.ts} +46 -0
  173. package/src/type-errors.ts +25 -36
  174. package/src/unseen-loads.ts +1 -12
  175. package/src/unwrap.ts +34 -0
  176. package/src/usage.ts +10 -0
  177. package/src/verbs/analyze.ts +32 -42
  178. package/src/verbs/describe.ts +4 -4
  179. package/src/verbs/explain.ts +8 -10
  180. package/src/verbs/print-projects.ts +4 -3
  181. package/src/verbs/print-retained.ts +2 -1
  182. package/src/verbs/print-roots.ts +2 -1
  183. package/src/verbs/verb.ts +2 -2
  184. package/src/verbs/version.ts +2 -1
  185. package/src/workflow-steps.ts +9 -44
  186. package/src/workspace-manifests.ts +2 -2
  187. package/src/workspace-programs.ts +5 -3
  188. package/src/workspace-resolution.ts +21 -17
  189. package/src/workspace.ts +35 -121
  190. package/dist/src/glob.js +0 -65
  191. package/dist/src/pnpm-workspace.js +0 -120
  192. package/src/glob.ts +0 -67
  193. package/src/pnpm-workspace.ts +0 -135
@@ -7,8 +7,12 @@
7
7
  * uses it and each relative one that names a source file of the program roots the file.
8
8
  */
9
9
  import { isCallExpression, isExportDeclaration, isIdentifier, isImportDeclaration, isNoSubstitutionTemplateLiteral, isStringLiteral, SyntaxKind, } from "@typescript/native/ast";
10
- import { dirnamePath, joinPath, relativePath, resolvePath } from "./paths.js";
11
- const MANIFEST = "package.json";
10
+ import { ancestors, dirnamePath, joinPath, relativePath, resolvePath } from "./paths.js";
11
+ import { bytewise } from "./text/compare.js";
12
+ import { isRecord } from "./json-document.js";
13
+ import { filesIn } from "./fs/tree.js";
14
+ import { holdsManifest, inInstalledPackages, manifestAt, readJSON } from "./fs/manifest.js";
15
+ import { shellWords } from "./text/shell.js";
12
16
  /** A configuration module's name, each form with the spelling a root reports it by. */
13
17
  const MODULE_FORMS = [
14
18
  { name: /^[\w-]+\.config\.(?:js|mjs|cjs|ts|mts|cts)$/u, form: "<stem>.config.<ext>" },
@@ -50,18 +54,14 @@ export const RESOLVED_EXTENSIONS = [
50
54
  ".mjs",
51
55
  ".cjs",
52
56
  ];
53
- /** The directory a package manager installs packages into, whose files are no project's own. */
54
- const MODULES_DIR = "node_modules";
55
57
  /** The file's name, the last segment of its path. */
56
58
  function basename(path) {
57
59
  return path.slice(path.lastIndexOf("/") + 1);
58
60
  }
59
61
  /** Whether one path is the project's own: below the target root and in no `node_modules`. */
60
62
  function isProjectPath(root, path) {
61
- return relativePath(root, path)?.split("/").includes(MODULES_DIR) === false;
62
- }
63
- function isRecord(value) {
64
- return typeof value === "object" && value !== null && !Array.isArray(value);
63
+ const below = relativePath(root, path);
64
+ return below !== undefined && !inInstalledPackages(below);
65
65
  }
66
66
  /** The form one file name is as a configuration module, or undefined where it is none. */
67
67
  export function configurationModuleForm(name) {
@@ -75,122 +75,13 @@ export function isConfigurationDocumentName(name) {
75
75
  const CONFIG_FLAGS = new Set(["--config", "-c"]);
76
76
  /** The extensions of a module a configuration flag may name. */
77
77
  const MODULE_EXTENSIONS = [".js", ".mjs", ".cjs", ".ts", ".mts", ".cts"];
78
- /** The characters that end a word outside quotes and separate nothing: blanks. */
79
- // Stryker disable next-line Regex: its \v to \V mutant is no valid escape under the u flag, so the whole module fails to parse
80
- const BLANK = /[ \t\r\f\v]/u;
81
- /** The characters that end a word outside quotes and begin an operator: newline included. */
82
- const OPERATOR = /[\n;&|()<>]/u;
83
- /** The characters a backslash escapes inside double quotes; before any other it stands for itself. */
84
- const DOUBLE_QUOTE_ESCAPES = new Set(["$", "`", '"', "\\"]);
85
- /**
86
- * The words of one command line, as POSIX token recognition reads quotes, backslashes,
87
- * line continuations, comments and operators. A word an expansion may change (an unquoted
88
- * `$`, backquote, glob character or leading `~`, or a `$` or backquote in double quotes)
89
- * is computed, and so is the rest of a line whose quote is never closed. A computed word
90
- * and each operator are undefined, so a flag's file is never read across them.
91
- */
92
- function shellWords(command) {
93
- const words = [];
94
- let word;
95
- let computed = false;
96
- const end = () => {
97
- if (word !== undefined) {
98
- words.push(computed ? undefined : word);
99
- }
100
- word = undefined;
101
- computed = false;
102
- };
103
- for (let at = 0; at < command.length; at += 1) {
104
- const char = command.charAt(at);
105
- if (char === "\\" && command.charAt(at + 1) === "\n") {
106
- at += 1;
107
- }
108
- else if (BLANK.test(char)) {
109
- end();
110
- }
111
- else if (OPERATOR.test(char)) {
112
- end();
113
- words.push(undefined);
114
- }
115
- else if (char === "#" && word === undefined) {
116
- const newline = command.indexOf("\n", at);
117
- at = newline < 0 ? command.length : newline - 1;
118
- }
119
- else if (char === "\\") {
120
- at += 1;
121
- word = (word ?? "") + command.charAt(at);
122
- }
123
- else if (char === "'" || char === '"') {
124
- const close = closingQuote(command, at);
125
- if (close < 0) {
126
- word ??= "";
127
- computed = true;
128
- break;
129
- }
130
- const quoted = char === "'"
131
- ? { text: command.slice(at + 1, close), computed: false }
132
- : doubleQuoted(command.slice(at + 1, close));
133
- word = (word ?? "") + quoted.text;
134
- computed ||= quoted.computed;
135
- at = close;
136
- }
137
- else {
138
- computed ||= /[$`*?[]/u.test(char) || (char === "~" && word === undefined);
139
- word = (word ?? "") + char;
140
- }
141
- }
142
- end();
143
- return words;
144
- }
145
- /** The text between one pair of double quotes, unescaped, and whether an expansion may change it. */
146
- function doubleQuoted(inner) {
147
- let text = "";
148
- let computed = false;
149
- for (let at = 0; at < inner.length; at += 1) {
150
- const char = inner.charAt(at);
151
- const next = inner.charAt(at + 1);
152
- if (char === "\\" && next === "\n") {
153
- at += 1;
154
- }
155
- else if (char === "\\" && DOUBLE_QUOTE_ESCAPES.has(next)) {
156
- text += next;
157
- at += 1;
158
- }
159
- else {
160
- computed ||= char === "$" || char === "`";
161
- text += char;
162
- }
163
- }
164
- return { text, computed };
165
- }
166
- /** The index of the quote that closes the one at `open`, or -1 where none does. */
167
- function closingQuote(command, open) {
168
- const quote = command.charAt(open);
169
- for (let at = open + 1; at < command.length; at += 1) {
170
- const char = command.charAt(at);
171
- if (char === quote) {
172
- return at;
173
- }
174
- if (quote === '"' && char === "\\") {
175
- at += 1;
176
- }
177
- }
178
- return -1;
179
- }
180
78
  /**
181
79
  * The files the scripts of the manifest in one directory name after a configuration flag,
182
80
  * `--config <file>`, `-c <file>` or `--config=<file>`, each a JSON file or a module below
183
81
  * the target root and in no `node_modules`.
184
82
  */
185
83
  function scriptConfigurations(host, root, dir) {
186
- let scripts;
187
- try {
188
- const manifest = JSON.parse(host.readFile(joinPath(dir, MANIFEST)));
189
- scripts = isRecord(manifest) ? manifest["scripts"] : undefined;
190
- }
191
- catch {
192
- return [];
193
- }
84
+ const scripts = manifestAt(host, dir)?.["scripts"];
194
85
  if (!isRecord(scripts)) {
195
86
  return [];
196
87
  }
@@ -217,15 +108,6 @@ function scriptConfigurations(host, root, dir) {
217
108
  }
218
109
  return found;
219
110
  }
220
- /** The decoded value of one JSON file, or undefined where it cannot be read or parsed. */
221
- function readDocument(host, path) {
222
- try {
223
- return JSON.parse(host.readFile(path));
224
- }
225
- catch {
226
- return undefined;
227
- }
228
- }
229
111
  /** Every string value one decoded JSON value holds at any depth. */
230
112
  export function documentStrings(value) {
231
113
  if (typeof value === "string") {
@@ -258,10 +140,10 @@ export function moduleStrings(file) {
258
140
  export function configurationFiles(host, targetRoot, files, parse) {
259
141
  const root = resolvePath(host.workingDirectory(), targetRoot);
260
142
  const manifests = new Map();
261
- const holdsManifest = (dir) => {
143
+ const manifestHeld = (dir) => {
262
144
  let held = manifests.get(dir);
263
145
  if (held === undefined) {
264
- held = host.kindOf(joinPath(dir, MANIFEST)) === "file";
146
+ held = holdsManifest(host, dir);
265
147
  manifests.set(dir, held);
266
148
  }
267
149
  return held;
@@ -271,30 +153,23 @@ export function configurationFiles(host, targetRoot, files, parse) {
271
153
  for (const file of files.byPath.values()) {
272
154
  const form = configurationModuleForm(basename(file.fileName));
273
155
  const fileDir = dirnamePath(file.fileName);
274
- if (form !== undefined && holdsManifest(fileDir)) {
156
+ if (form !== undefined && manifestHeld(fileDir)) {
275
157
  modules.push({ file, form, manifestDir: fileDir });
276
158
  }
277
- for (let dir = dirnamePath(file.fileName); relativePath(root, dir) !== undefined && !dirs.has(dir); dir = dirnamePath(dir)) {
159
+ for (const dir of ancestors(dirnamePath(file.fileName), root)) {
160
+ if (dirs.has(dir)) {
161
+ break;
162
+ }
278
163
  dirs.add(dir);
279
164
  }
280
165
  }
281
166
  const pending = [];
282
167
  const named = [];
283
- for (const dir of [...dirs].sort()) {
284
- if (!holdsManifest(dir)) {
168
+ for (const dir of [...dirs].sort(bytewise)) {
169
+ if (!manifestHeld(dir)) {
285
170
  continue;
286
171
  }
287
- let names;
288
- try {
289
- names = host
290
- .readDirectory(dir)
291
- .filter((entry) => !entry.directory && isConfigurationDocumentName(entry.name))
292
- .map((entry) => entry.name)
293
- .sort();
294
- }
295
- catch {
296
- names = [];
297
- }
172
+ const names = filesIn(host, dir, isConfigurationDocumentName);
298
173
  pending.push(...names.map((name) => ({ path: joinPath(dir, name), manifestDir: dir })));
299
174
  for (const path of scriptConfigurations(host, root, dir)) {
300
175
  const held = files.byName.get(path);
@@ -318,7 +193,7 @@ export function configurationFiles(host, targetRoot, files, parse) {
318
193
  continue;
319
194
  }
320
195
  if (document === undefined) {
321
- const value = readDocument(host, next.path);
196
+ const value = readJSON(host, next.path);
322
197
  if (value === undefined) {
323
198
  unreadable.add(next.path);
324
199
  continue;
@@ -343,7 +218,7 @@ export function configurationFiles(host, targetRoot, files, parse) {
343
218
  documents: [...documents.values()],
344
219
  outside: parse === undefined
345
220
  ? []
346
- : outsideModules(host, root, [...dirs], files, holdsManifest, parse, named),
221
+ : outsideModules(host, root, [...dirs], files, manifestHeld, parse, named),
347
222
  };
348
223
  }
349
224
  /** The literal module specifier one `require(...)` or `import(...)` call names, if any. */
@@ -429,23 +304,13 @@ export function resolveRelativeSpecifier(host, dir, specifier) {
429
304
  * does not hold, and the project files below `root` they import by a relative specifier,
430
305
  * until no further file joins. A file that cannot be read is skipped.
431
306
  */
432
- function outsideModules(host, root, dirs, files, holdsManifest, parse, named) {
307
+ function outsideModules(host, root, dirs, files, manifestHeld, parse, named) {
433
308
  const pending = [...named];
434
- for (const dir of [...dirs].sort()) {
435
- if (!holdsManifest(dir)) {
436
- continue;
437
- }
438
- let names;
439
- try {
440
- names = host
441
- .readDirectory(dir)
442
- .filter((entry) => !entry.directory && configurationModuleForm(entry.name) !== undefined)
443
- .map((entry) => entry.name)
444
- .sort();
445
- }
446
- catch {
309
+ for (const dir of [...dirs].sort(bytewise)) {
310
+ if (!manifestHeld(dir)) {
447
311
  continue;
448
312
  }
313
+ const names = filesIn(host, dir, (name) => configurationModuleForm(name) !== undefined);
449
314
  pending.push(...names.map((name) => ({ path: joinPath(dir, name), manifestDir: dir })));
450
315
  }
451
316
  const found = new Map();
@@ -481,14 +346,8 @@ function outsideModules(host, root, dirs, files, holdsManifest, parse, named) {
481
346
  }
482
347
  /** Every dependency the manifest in one directory declares, or none where it holds none to read. */
483
348
  export function declaredIn(host, dir) {
484
- let value;
485
- try {
486
- value = JSON.parse(host.readFile(joinPath(dir, MANIFEST)));
487
- }
488
- catch {
489
- return [];
490
- }
491
- if (!isRecord(value)) {
349
+ const value = manifestAt(host, dir);
350
+ if (value === undefined) {
492
351
  return [];
493
352
  }
494
353
  const names = new Set();
@@ -179,19 +179,19 @@ export function resolveEntries(project, held, entries) {
179
179
  for (const symbol of held.symbols) {
180
180
  byRef.set(symbol.ref, [...(byRef.get(symbol.ref) ?? []), symbol.id]);
181
181
  }
182
- const modules = modulesNamed(project, new Set(entries.flatMap((entry) => (entry.shape === "module" ? [entry.module] : []))));
182
+ const modules = modulesNamed(project, new Set(entries.flatMap((entry) => ("module" in entry ? [entry.module] : []))));
183
183
  return entries.map((entry) => {
184
- if (entry.shape === "symbol") {
184
+ if ("symbol" in entry) {
185
185
  return { entry, handles: new Set(), ids: new Set(byRef.get(entry.symbol) ?? []) };
186
186
  }
187
- const { components, static: isStatic } = componentsOf(entry.shape === "module" ? entry.name : entry.global);
187
+ const { components, static: isStatic } = componentsOf("module" in entry ? entry.name : entry.global);
188
188
  const [first = "", ...rest] = components;
189
189
  let start;
190
190
  if (isStatic && rest.length === 0) {
191
191
  // Only a member is static, and a path of one component names no member.
192
192
  start = undefined;
193
193
  }
194
- else if (entry.shape === "module") {
194
+ else if ("module" in entry) {
195
195
  const module = modules.get(entry.module);
196
196
  start = module === undefined ? undefined : memberOf(project, module, first, false);
197
197
  }
@@ -246,14 +246,10 @@ export function entriesAt(project, chains, nodes, resolved) {
246
246
  * program the display name the inventory gives it.
247
247
  */
248
248
  export function spelledEntry(entry, held) {
249
- switch (entry.shape) {
250
- case "symbol":
251
- return held.symbols.find((symbol) => symbol.ref === entry.symbol)?.name ?? entry.symbol;
252
- case "module":
253
- return entry.name;
254
- case "global":
255
- return entry.global;
249
+ if ("symbol" in entry) {
250
+ return held.symbols.find((symbol) => symbol.ref === entry.symbol)?.name ?? entry.symbol;
256
251
  }
252
+ return "module" in entry ? entry.name : entry.global;
257
253
  }
258
254
  /** The key under which a lifecycle contract's declarations are configured. */
259
255
  const LIFECYCLE_KEY = "ts.lifecycle_contracts";
@@ -264,11 +260,14 @@ const LIFECYCLE_KEY = "ts.lifecycle_contracts";
264
260
  */
265
261
  export function configuredDeclarations(config) {
266
262
  return [
267
- ...config.ts.injectionRegistrations.map((entry) => ({
263
+ ...config.ts.injection_registrations.map((entry) => ({
268
264
  key: "ts.injection_registrations",
269
265
  entry,
270
266
  })),
271
- ...config.ts.lifecycleContracts.flatMap((contract) => [...contract.components, ...contract.bases].map((entry) => ({ key: LIFECYCLE_KEY, entry }))),
267
+ ...config.ts.lifecycle_contracts.flatMap((contract) => [...(contract.components ?? []), ...(contract.bases ?? [])].map((entry) => ({
268
+ key: LIFECYCLE_KEY,
269
+ entry,
270
+ }))),
272
271
  ...config.ts.serializers.map((entry) => ({ key: "ts.serializers", entry })),
273
272
  ];
274
273
  }
@@ -294,12 +293,8 @@ export function declarationsNamed(project, held, configured) {
294
293
  * sign and its name, and a global entry's path after a number sign.
295
294
  */
296
295
  export function configuredRef(entry) {
297
- switch (entry.shape) {
298
- case "symbol":
299
- return entry.symbol;
300
- case "module":
301
- return `${entry.module}#${entry.name}`;
302
- case "global":
303
- return `#${entry.global}`;
296
+ if ("symbol" in entry) {
297
+ return entry.symbol;
304
298
  }
299
+ return "module" in entry ? `${entry.module}#${entry.name}` : `#${entry.global}`;
305
300
  }
@@ -39,10 +39,10 @@ export function consumerLoads(engine, host, scope, targetConfigFiles) {
39
39
  export function consumerReferences(project, host, targetRoot, consumer, config) {
40
40
  const held = inventory(narrowedTo(project, (file) => relativePath(targetRoot, file.fileName) !== undefined), host, targetRoot);
41
41
  const found = references(project, held, targetRoot, {
42
- testFiles: config.ts.testFiles,
42
+ testFiles: config.ts.test_files,
43
43
  consumer,
44
44
  }).references;
45
- if (config.analysis.consumerTests !== "production") {
45
+ if (config.analysis.consumer_tests !== "production") {
46
46
  return found;
47
47
  }
48
48
  return found.map((reference) => (reference.test ? { ...reference, test: false } : reference));