@cplieger/deadset-ts 8.0.0-dev.1 → 8.0.0-dev.11

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 (276) hide show
  1. package/README.md +1 -1
  2. package/dist/bin/mapper-connection.js +2 -1
  3. package/dist/bin/node-host.js +24 -5
  4. package/dist/src/analysis.js +181 -341
  5. package/dist/src/augmentations.js +106 -13
  6. package/dist/src/automatic-types.js +10 -29
  7. package/dist/src/build-scripts.js +425 -0
  8. package/dist/src/component-layer.js +4 -2
  9. package/dist/src/components.js +2 -3
  10. package/dist/src/config.js +6 -82
  11. package/dist/src/configuration-files.js +28 -176
  12. package/dist/src/configured-declarations.js +15 -20
  13. package/dist/src/conformance-record.js +1 -1
  14. package/dist/src/consumers.js +3 -30
  15. package/dist/src/contextual-uses.js +56 -9
  16. package/dist/src/contract/config.generated.js +558 -0
  17. package/dist/src/contract/contract.generated.js +1244 -0
  18. package/dist/src/contract/report.generated.js +862 -0
  19. package/dist/src/convention-rows.js +73 -3
  20. package/dist/src/conventions.js +36 -66
  21. package/dist/src/dependencies.js +103 -40
  22. package/dist/src/edges.js +38 -122
  23. package/dist/src/element-access.js +4 -6
  24. package/dist/src/entry-point-gaps.js +2 -8
  25. package/dist/src/entry-points.js +11 -27
  26. package/dist/src/enum-group.js +3 -10
  27. package/dist/src/erased-stores.js +4 -6
  28. package/dist/src/exempt-classes.js +1 -63
  29. package/dist/src/exempt.js +21 -40
  30. package/dist/src/failure.js +36 -0
  31. package/dist/src/file-facts.js +2 -25
  32. package/dist/src/findings/completion.js +139 -72
  33. package/dist/src/findings/dependencies-and-module-machinery.js +4 -5
  34. package/dist/src/findings/emitters.js +5 -5
  35. package/dist/src/findings/interfaces.js +4 -5
  36. package/dist/src/findings/intra-function.js +13 -10
  37. package/dist/src/findings/non-code-artifacts.js +7 -8
  38. package/dist/src/findings/reads-and-writes.js +16 -13
  39. package/dist/src/findings/self-check.js +10 -12
  40. package/dist/src/findings/unused-declarations.js +41 -32
  41. package/dist/src/findings/visibility-narrowing.js +19 -16
  42. package/dist/src/findings-pass.js +8 -15
  43. package/dist/src/framework-lifecycle.js +7 -7
  44. package/dist/src/fs/document.js +52 -0
  45. package/dist/src/fs/manifest.js +72 -0
  46. package/dist/src/fs/tree.js +88 -0
  47. package/dist/src/generated-file.js +7 -4
  48. package/dist/src/git-ignore.js +39 -26
  49. package/dist/src/graph.js +5 -3
  50. package/dist/src/html-entries.js +6 -33
  51. package/dist/src/in-operands.js +2 -1
  52. package/dist/src/index.js +1 -1
  53. package/dist/src/injection-container.js +1 -1
  54. package/dist/src/intra-function-parts.js +63 -43
  55. package/dist/src/inventory.js +2 -21
  56. package/dist/src/javascript-file.js +33 -0
  57. package/dist/src/json-document.js +198 -67
  58. package/dist/src/keyof-comparisons.js +4 -6
  59. package/dist/src/kinds.js +3 -366
  60. package/dist/src/load/classify.js +270 -0
  61. package/dist/src/load/diagnostics.js +80 -0
  62. package/dist/src/load/discover.js +277 -0
  63. package/dist/src/{emit-map.js → load/emit-map.js} +1 -1
  64. package/dist/src/load/expected-module.js +136 -0
  65. package/dist/src/load/load.js +27 -0
  66. package/dist/src/load/module-lookup.js +37 -0
  67. package/dist/src/load/plan.js +313 -0
  68. package/dist/src/load/specifiers.js +115 -0
  69. package/dist/src/load/synthesize.js +140 -0
  70. package/dist/src/load/test-globals.js +207 -0
  71. package/dist/src/load/test-joins.js +82 -0
  72. package/dist/src/{workspace-manifests.js → load/workspace-manifests.js} +4 -4
  73. package/dist/src/{workspace-programs.js → load/workspace-programs.js} +89 -66
  74. package/dist/src/{workspace-resolution.js → load/workspace-resolution.js} +23 -65
  75. package/dist/src/{workspace-run.js → load/workspace-run.js} +7 -7
  76. package/dist/src/{workspace.js → load/workspace.js} +62 -124
  77. package/dist/src/manifest.js +49 -54
  78. package/dist/src/matrix.js +76 -4
  79. package/dist/src/mdx-entries.js +3 -26
  80. package/dist/src/outside-tests.js +1 -1
  81. package/dist/src/partial.js +2 -1
  82. package/dist/src/paths.js +26 -15
  83. package/dist/src/position.js +2 -1
  84. package/dist/src/print.js +11 -79
  85. package/dist/src/product.js +13 -0
  86. package/dist/src/query.js +1 -0
  87. package/dist/src/ref.js +1 -0
  88. package/dist/src/references.js +48 -30
  89. package/dist/src/report-schema.js +51 -0
  90. package/dist/src/report.js +57 -41
  91. package/dist/src/reporters/annotations.js +15 -8
  92. package/dist/src/reporters/sarif.js +16 -10
  93. package/dist/src/reporters/template.js +4 -19
  94. package/dist/src/resolve.js +245 -729
  95. package/dist/src/roots.js +273 -87
  96. package/dist/src/run.js +66 -77
  97. package/dist/src/schema.js +320 -343
  98. package/dist/src/scope.js +38 -115
  99. package/dist/src/serialization-contract.js +595 -21
  100. package/dist/src/session.js +34 -29
  101. package/dist/src/source-files.js +1 -1
  102. package/dist/src/suppress-file.js +25 -28
  103. package/dist/src/suppress-inline.js +3 -2
  104. package/dist/src/suppress.js +33 -51
  105. package/dist/src/sweep.js +7 -9
  106. package/dist/src/symbol-keys.js +3 -5
  107. package/dist/src/template-field.js +9 -19
  108. package/dist/src/test-support.js +8 -11
  109. package/dist/src/text/compare.js +26 -0
  110. package/dist/src/text/glob.js +194 -0
  111. package/dist/src/text/named-files.js +54 -0
  112. package/dist/src/text/shell.js +159 -0
  113. package/dist/src/text/yaml.js +393 -0
  114. package/dist/src/type-errors.js +11 -232
  115. package/dist/src/unseen-loads.js +100 -0
  116. package/dist/src/unwrap.js +23 -0
  117. package/dist/src/usage.js +10 -0
  118. package/dist/src/verbs/analyze.js +166 -126
  119. package/dist/src/verbs/describe.js +9 -16
  120. package/dist/src/verbs/explain.js +10 -7
  121. package/dist/src/verbs/print-config.js +2 -1
  122. package/dist/src/verbs/print-projects.js +6 -4
  123. package/dist/src/verbs/print-retained.js +4 -2
  124. package/dist/src/verbs/print-roots.js +4 -2
  125. package/dist/src/verbs/verb.js +1 -5
  126. package/dist/src/verbs/version.js +14 -3
  127. package/dist/src/workflow-steps.js +62 -64
  128. package/jsr.json +1 -1
  129. package/package.json +5 -4
  130. package/src/analysis.ts +245 -502
  131. package/src/augmentations.ts +135 -17
  132. package/src/automatic-types.ts +11 -29
  133. package/src/build-scripts.ts +543 -0
  134. package/src/component-layer.ts +4 -2
  135. package/src/components.ts +2 -4
  136. package/src/config.ts +31 -302
  137. package/src/configuration-files.ts +34 -179
  138. package/src/configured-declarations.ts +18 -23
  139. package/src/conformance-record.ts +1 -1
  140. package/src/consumers.ts +6 -57
  141. package/src/contextual-uses.ts +64 -12
  142. package/src/contract/config.generated.ts +818 -0
  143. package/src/contract/contract.generated.ts +1308 -0
  144. package/src/contract/report.generated.ts +1237 -0
  145. package/src/convention-rows.ts +85 -3
  146. package/src/conventions.ts +46 -84
  147. package/src/dependencies.ts +118 -46
  148. package/src/edges.ts +41 -140
  149. package/src/element-access.ts +4 -7
  150. package/src/entry-point-gaps.ts +3 -9
  151. package/src/entry-points.ts +12 -38
  152. package/src/enum-group.ts +2 -11
  153. package/src/erased-stores.ts +3 -7
  154. package/src/exempt-classes.ts +1 -75
  155. package/src/exempt.ts +36 -50
  156. package/src/failure.ts +63 -0
  157. package/src/file-facts.ts +9 -24
  158. package/src/finding.ts +14 -9
  159. package/src/findings/boundary.ts +2 -0
  160. package/src/findings/completion.ts +181 -84
  161. package/src/findings/dependencies-and-module-machinery.ts +4 -7
  162. package/src/findings/emitter.ts +8 -9
  163. package/src/findings/emitters.ts +7 -7
  164. package/src/findings/interfaces.ts +4 -6
  165. package/src/findings/intra-function.ts +13 -11
  166. package/src/findings/non-code-artifacts.ts +9 -11
  167. package/src/findings/reads-and-writes.ts +20 -16
  168. package/src/findings/self-check.ts +11 -17
  169. package/src/findings/unused-declarations.ts +45 -32
  170. package/src/findings/visibility-narrowing.ts +20 -17
  171. package/src/findings-pass.ts +10 -19
  172. package/src/framework-lifecycle.ts +7 -7
  173. package/src/fs/document.ts +70 -0
  174. package/src/fs/manifest.ts +92 -0
  175. package/src/fs/tree.ts +110 -0
  176. package/src/generated-file.ts +7 -4
  177. package/src/git-ignore.ts +50 -26
  178. package/src/graph.ts +5 -3
  179. package/src/host.ts +12 -5
  180. package/src/html-entries.ts +6 -33
  181. package/src/in-operands.ts +2 -1
  182. package/src/index.ts +1 -1
  183. package/src/injection-container.ts +1 -1
  184. package/src/intra-function-parts.ts +73 -44
  185. package/src/inventory.ts +2 -20
  186. package/src/javascript-file.ts +37 -0
  187. package/src/json-document.ts +241 -76
  188. package/src/keyof-comparisons.ts +3 -7
  189. package/src/kinds.ts +5 -413
  190. package/src/load/classify.ts +397 -0
  191. package/src/load/diagnostics.ts +144 -0
  192. package/src/load/discover.ts +455 -0
  193. package/src/{emit-map.ts → load/emit-map.ts} +1 -1
  194. package/src/load/expected-module.ts +188 -0
  195. package/src/load/load.ts +73 -0
  196. package/src/load/module-lookup.ts +50 -0
  197. package/src/load/plan.ts +504 -0
  198. package/src/load/specifiers.ts +168 -0
  199. package/src/load/synthesize.ts +211 -0
  200. package/src/load/test-globals.ts +251 -0
  201. package/src/load/test-joins.ts +98 -0
  202. package/src/{workspace-manifests.ts → load/workspace-manifests.ts} +5 -5
  203. package/src/{workspace-programs.ts → load/workspace-programs.ts} +128 -85
  204. package/src/{workspace-resolution.ts → load/workspace-resolution.ts} +33 -76
  205. package/src/{workspace-run.ts → load/workspace-run.ts} +18 -16
  206. package/src/{workspace.ts → load/workspace.ts} +90 -134
  207. package/src/manifest.ts +81 -75
  208. package/src/matrix.ts +122 -4
  209. package/src/mdx-entries.ts +3 -26
  210. package/src/outside-tests.ts +1 -1
  211. package/src/partial.ts +3 -2
  212. package/src/paths.ts +27 -15
  213. package/src/position.ts +2 -1
  214. package/src/print.ts +12 -92
  215. package/src/product.ts +18 -0
  216. package/src/query.ts +11 -0
  217. package/src/ref.ts +1 -0
  218. package/src/references.ts +52 -31
  219. package/src/report-schema.ts +68 -0
  220. package/src/report.ts +101 -224
  221. package/src/reporters/annotations.ts +22 -11
  222. package/src/reporters/json.ts +1 -1
  223. package/src/reporters/reporter.ts +2 -4
  224. package/src/reporters/reporters.ts +1 -1
  225. package/src/reporters/sarif.ts +29 -16
  226. package/src/reporters/template.ts +4 -20
  227. package/src/reporters/text.ts +3 -3
  228. package/src/resolve.ts +283 -1114
  229. package/src/roots.ts +339 -104
  230. package/src/run.ts +75 -91
  231. package/src/schema.ts +391 -388
  232. package/src/scope.ts +46 -138
  233. package/src/serialization-contract.ts +763 -22
  234. package/src/session.ts +70 -54
  235. package/src/source-files.ts +1 -1
  236. package/src/suppress-file.ts +24 -33
  237. package/src/suppress-inline.ts +2 -2
  238. package/src/suppress.ts +43 -58
  239. package/src/sweep.ts +23 -9
  240. package/src/symbol-keys.ts +2 -5
  241. package/src/template-field.ts +15 -25
  242. package/src/test-support.ts +17 -13
  243. package/src/text/compare.ts +27 -0
  244. package/src/text/glob.ts +210 -0
  245. package/src/text/named-files.inputs.json +1522 -0
  246. package/src/text/named-files.ts +68 -0
  247. package/src/text/shell.ts +161 -0
  248. package/src/text/yaml.ts +423 -0
  249. package/src/type-errors.ts +18 -288
  250. package/src/unseen-loads.ts +134 -0
  251. package/src/unwrap.ts +34 -0
  252. package/src/usage.ts +10 -0
  253. package/src/verbs/analyze.ts +224 -162
  254. package/src/verbs/describe.ts +14 -15
  255. package/src/verbs/explain.ts +10 -11
  256. package/src/verbs/print-config.ts +2 -1
  257. package/src/verbs/print-projects.ts +6 -4
  258. package/src/verbs/print-retained.ts +4 -2
  259. package/src/verbs/print-roots.ts +4 -2
  260. package/src/verbs/verb.ts +2 -8
  261. package/src/verbs/version.ts +15 -3
  262. package/src/workflow-steps.ts +74 -64
  263. package/dist/src/base-url.js +0 -18
  264. package/dist/src/discover.js +0 -468
  265. package/dist/src/glob.js +0 -65
  266. package/dist/src/pnpm-workspace.js +0 -120
  267. package/dist/src/setup-failure.js +0 -23
  268. package/dist/src/test-joins.js +0 -101
  269. package/dist/src/version.js +0 -7
  270. package/src/base-url.ts +0 -24
  271. package/src/discover.ts +0 -653
  272. package/src/glob.ts +0 -67
  273. package/src/pnpm-workspace.ts +0 -135
  274. package/src/setup-failure.ts +0 -39
  275. package/src/test-joins.ts +0 -120
  276. package/src/version.ts +0 -7
package/dist/src/run.js CHANGED
@@ -1,8 +1,12 @@
1
- import { ConfigError, REPOSITORY_DOCUMENT } from "./config.js";
2
- import { DiscoveryError, renderDiagnostic } from "./discover.js";
1
+ import { CONFIG_MAX_BYTES, SETTINGS } from "./contract/config.generated.js";
2
+ import { EXIT_FAILURE, EXIT_USAGE } from "./contract/contract.generated.js";
3
+ import { REPOSITORY_DOCUMENT } from "./config.js";
4
+ import { readTargetDocument } from "./fs/document.js";
3
5
  import { joinPath, resolvePath } from "./paths.js";
4
- import { readScope, ScopeError, scopeForDir } from "./scope.js";
5
- import { SetupError, setupLine } from "./setup-failure.js";
6
+ import { renderDiagnostic } from "./load/diagnostics.js";
7
+ import { FailureExit, failureLines, productFault } from "./failure.js";
8
+ import { readScope, scopeForDir } from "./scope.js";
9
+ import { UsageError } from "./usage.js";
6
10
  import { openEngine } from "./session.js";
7
11
  import { printConfigVerb } from "./verbs/print-config.js";
8
12
  import { printProjectsVerb } from "./verbs/print-projects.js";
@@ -11,8 +15,9 @@ import { printRootsVerb } from "./verbs/print-roots.js";
11
15
  import { ANALYZE_OPTIONS, analyzeVerb } from "./verbs/analyze.js";
12
16
  import { describeVerb } from "./verbs/describe.js";
13
17
  import { EXPLAIN_OPTIONS, explainVerb } from "./verbs/explain.js";
14
- import { EXIT_FAILURE, EXIT_USAGE } from "./verbs/verb.js";
18
+ import {} from "./verbs/verb.js";
15
19
  import { versionVerb } from "./verbs/version.js";
20
+ import { diagnose, message, PRODUCT } from "./product.js";
16
21
  /** Every verb this command answers, in the order the usage text lists them. */
17
22
  const VERBS = [
18
23
  { name: "analyze", run: analyzeVerb, options: ANALYZE_OPTIONS },
@@ -24,7 +29,7 @@ const VERBS = [
24
29
  { name: "describe", run: describeVerb },
25
30
  { name: "version", run: versionVerb },
26
31
  ];
27
- const USAGE = `usage: deadset-ts <verb> [options]\nverbs: ${VERBS.map((verb) => verb.name).join(", ")}\n`;
32
+ const USAGE = `usage: ${PRODUCT} <verb> [options]\nverbs: ${VERBS.map((verb) => verb.name).join(", ")}\n`;
28
33
  /**
29
34
  * The tokens whose presence in an option's name makes that option a request to
30
35
  * edit a source file. The set is closed, and a token is matched in any position of
@@ -32,29 +37,12 @@ const USAGE = `usage: deadset-ts <verb> [options]\nverbs: ${VERBS.map((verb) =>
32
37
  */
33
38
  const SOURCE_EDIT_TOKENS = ["fix", "edit", "delete", "rewrite"];
34
39
  /**
35
- * Maps an option name to the setting of the Contract's configuration schema it supplies,
36
- * so one entry registers the option, supplies the document resolution reads, and gives
37
- * the spelling the setting's provenance names. The name is this command's vocabulary and
38
- * is never derived from the path: a setting reaches the command line only by an entry,
39
- * and a path names a key the schema declares.
40
+ * Maps an option name to the setting of the Contract's configuration schema it supplies:
41
+ * the options contract/settings.json names for a setting this analyzer reads.
40
42
  */
41
- export const SETTING_OPTIONS = new Map([
42
- ["min-confidence", "analysis.min_confidence"],
43
- ["sort", "reporters.sort"],
44
- ["cascade", "reporters.cascade"],
45
- ["max-findings", "reporters.max_findings"],
46
- ["fail-on", "reporters.fail_on"],
47
- ]);
43
+ export const SETTING_OPTIONS = new Map(SETTINGS.flatMap((row) => (row.option === undefined ? [] : [[row.option, row.key]])));
48
44
  /** The options that take a value and are not settings. */
49
45
  const PLAIN_OPTIONS = new Set(["target", "config", "central", "scope"]);
50
- /**
51
- * The setting options whose value is an integer rather than a string. A value
52
- * written other than as digits is passed on as the string it is, so resolution
53
- * refuses it by its type rather than reading `1e2` as 100.
54
- */
55
- const INTEGER_OPTIONS = new Set(["max-findings"]);
56
- /** An integer as an option writes it: an optional minus sign and digits alone. */
57
- const INTEGER_TEXT = /^-?[0-9]+$/u;
58
46
  /** No option beyond the ones every verb takes. */
59
47
  const NO_OPTIONS = { plain: [], repeatable: [] };
60
48
  /**
@@ -81,7 +69,7 @@ function readOptions(args, own) {
81
69
  const repeated = new Map();
82
70
  for (const arg of args) {
83
71
  if (!arg.startsWith("-")) {
84
- throw new ConfigError("malformed", "", `unexpected argument ${JSON.stringify(arg)}`);
72
+ throw new UsageError(`unexpected argument ${JSON.stringify(arg)}`);
85
73
  }
86
74
  const [spelled, ...rest] = arg.split("=");
87
75
  const name = (spelled ?? "").replace(/^-+/u, "");
@@ -89,10 +77,10 @@ function readOptions(args, own) {
89
77
  !SETTING_OPTIONS.has(name) &&
90
78
  !own.plain.includes(name) &&
91
79
  !own.repeatable.includes(name)) {
92
- throw new ConfigError("malformed", "", `unknown option ${JSON.stringify(spelled ?? arg)}`);
80
+ throw new UsageError(`unknown option ${JSON.stringify(spelled ?? arg)}`);
93
81
  }
94
82
  if (rest.length === 0) {
95
- throw new ConfigError("malformed", "", `option ${JSON.stringify(spelled ?? arg)} takes a value`);
83
+ throw new UsageError(`option ${JSON.stringify(spelled ?? arg)} takes a value`);
96
84
  }
97
85
  const value = rest.join("=");
98
86
  named.set(name, value);
@@ -100,45 +88,49 @@ function readOptions(args, own) {
100
88
  }
101
89
  return { named, repeated };
102
90
  }
103
- function readFileOr(host, path, orUndefined) {
91
+ /** The document an option names. */
92
+ function documentAt(host, label) {
104
93
  try {
105
- return host.readFile(resolvePath(host.workingDirectory(), path));
94
+ const path = resolvePath(host.workingDirectory(), label);
95
+ // A file past the bound reads as one byte more than it, which resolution refuses.
96
+ return { text: host.readFile(path, CONFIG_MAX_BYTES + 1), label };
106
97
  }
107
98
  catch (error) {
108
- if (orUndefined) {
109
- return undefined;
110
- }
111
- throw new ConfigError("malformed", "", `${path}: ${error instanceof Error ? error.message : String(error)}`);
99
+ throw new UsageError(`${label}: ${message(error)}`);
112
100
  }
113
101
  }
114
102
  /**
115
- * The configuration documents one invocation reads: the repository configuration
116
- * at the target root or the path an option named, the central configuration, and
117
- * the settings the options supply as one flag document.
103
+ * The repository configuration at the target root, none where it is absent. One that
104
+ * cannot be read is a configuration document that cannot be, refused with the usage code.
105
+ */
106
+ function repositoryAt(host, target) {
107
+ const label = joinPath(target, REPOSITORY_DOCUMENT);
108
+ const root = resolvePath(host.workingDirectory(), target);
109
+ const text = readTargetDocument(host, root, REPOSITORY_DOCUMENT, label, (named, reason) => new UsageError(`${named}: ${reason}`));
110
+ return text === undefined ? undefined : { text, label };
111
+ }
112
+ /**
113
+ * The configuration sources one invocation carries: the repository configuration at
114
+ * the target root or the path an option named, the central configuration, and the
115
+ * text each setting option was given.
118
116
  */
119
117
  function inputsOf(host, options) {
120
- const target = options.named.get("target") ?? ".";
121
118
  const named = options.named.get("config");
122
- const repositoryLabel = named ?? joinPath(target, REPOSITORY_DOCUMENT);
123
- const repository = readFileOr(host, repositoryLabel, named === undefined);
119
+ const target = options.named.get("target") ?? ".";
120
+ const repository = named === undefined ? repositoryAt(host, target) : documentAt(host, named);
124
121
  const centralLabel = options.named.get("central");
125
- const central = centralLabel === undefined ? undefined : readFileOr(host, centralLabel, false);
126
- const flat = {};
127
- const flagLabels = new Map();
128
- for (const [name, path] of SETTING_OPTIONS) {
122
+ const central = centralLabel === undefined ? undefined : documentAt(host, centralLabel);
123
+ const flags = new Map();
124
+ for (const [name, key] of SETTING_OPTIONS) {
129
125
  const value = options.named.get(name);
130
- if (value === undefined) {
131
- continue;
126
+ if (value !== undefined) {
127
+ flags.set(key, value);
132
128
  }
133
- flat[path] = INTEGER_OPTIONS.has(name) && INTEGER_TEXT.test(value) ? Number(value) : value;
134
- flagLabels.set(path, `--${name}`);
135
129
  }
136
- const flags = Object.keys(flat).length === 0 ? undefined : JSON.stringify(flat);
137
130
  return {
138
- ...(flags === undefined ? {} : { flags }),
139
- ...(repository === undefined ? {} : { repository, repositoryLabel }),
140
- ...(central === undefined || centralLabel === undefined ? {} : { central, centralLabel }),
141
- flagLabels,
131
+ flags,
132
+ ...(repository === undefined ? {} : { repository }),
133
+ ...(central === undefined ? {} : { central }),
142
134
  };
143
135
  }
144
136
  /** The scope one invocation analyzes: the document an option named, or the target. */
@@ -154,14 +146,12 @@ function scopeOf(host, options) {
154
146
  * the exit code: 0 for a completed verb, 1 for a finding that fails the run, 2 for a
155
147
  * usage error, a requested source edit or a refused configuration, 3 for a failure that
156
148
  * produced no answer. It writes nothing outside `out` and `err` and never exits the
157
- * process. `host` is the platform the run reads, the version it reports included, and
158
- * `openClient` opens the compiler client; a caller that watches what a run reads
159
- * supplies its own of either.
149
+ * process. A caller that watches what a run reads supplies its own `host` or `openClient`.
160
150
  */
161
151
  export function run(args, out, err, host, openClient = openEngine) {
162
152
  const editing = sourceEditOption(args);
163
153
  if (editing !== undefined) {
164
- err.write(`deadset-ts: ${editing} is not supported: deadset-ts reports and never edits a source file\n`);
154
+ diagnose(err, `${editing} is not supported: ${PRODUCT} reports and never edits a source file`);
165
155
  err.write(USAGE);
166
156
  return EXIT_USAGE;
167
157
  }
@@ -171,7 +161,7 @@ export function run(args, out, err, host, openClient = openEngine) {
171
161
  return invoke(verb.run, verb.options ?? NO_OPTIONS, args.slice(1), { out, err, host }, openClient);
172
162
  }
173
163
  if (name !== undefined) {
174
- err.write(`deadset-ts: unknown verb ${JSON.stringify(name)}\n`);
164
+ diagnose(err, `unknown verb ${JSON.stringify(name)}`);
175
165
  }
176
166
  err.write(USAGE);
177
167
  return EXIT_USAGE;
@@ -196,7 +186,7 @@ function invoke(verb, own, args, streams, openClient) {
196
186
  openClient: (config) => {
197
187
  opened = openClient({
198
188
  collectTiming: false,
199
- components: { extensions: config.ts.componentExtensions, host: streams.host },
189
+ components: { extensions: config.ts.component_extensions, host: streams.host },
200
190
  });
201
191
  return opened;
202
192
  },
@@ -207,29 +197,28 @@ function invoke(verb, own, args, streams, openClient) {
207
197
  return refuse(error, streams.err);
208
198
  }
209
199
  }
210
- /** Turns one refusal into the exit code the Contract's table gives it. */
200
+ /**
201
+ * Turns one refusal into the exit code the Contract's table gives it. An error no class names
202
+ * is a fault of this analyzer, printed with its stack for the maintainers it asks the user to
203
+ * report it to.
204
+ */
211
205
  function refuse(error, err) {
212
- if (error instanceof ConfigError) {
213
- err.write(`deadset-ts: ${error.message}\n`);
206
+ if (error instanceof UsageError) {
207
+ diagnose(err, error.message);
214
208
  err.write(USAGE);
215
209
  return EXIT_USAGE;
216
210
  }
217
- if (error instanceof DiscoveryError) {
218
- for (const diagnostic of error.diagnostics) {
219
- err.write(`${renderDiagnostic(diagnostic)}\n`);
211
+ if (!(error instanceof FailureExit)) {
212
+ if (error instanceof Error && error.stack !== undefined) {
213
+ err.write(`${error.stack}\n`);
220
214
  }
221
- err.write(`deadset-ts: ${error.message}\n`);
222
- return EXIT_FAILURE;
215
+ return refuse(productFault(`meets an error none of its classes names: ${message(error)}`), err);
223
216
  }
224
- if (error instanceof SetupError) {
225
- for (const failure of error.failures) {
226
- err.write(`${setupLine(failure)}\n`);
227
- }
228
- return EXIT_FAILURE;
217
+ for (const diagnostic of error.diagnostics) {
218
+ err.write(`${renderDiagnostic(diagnostic)}\n`);
229
219
  }
230
- if (error instanceof ScopeError) {
231
- err.write(`deadset-ts: ${error.message}\n`);
232
- return EXIT_FAILURE;
220
+ for (const line of failureLines(error.failures)) {
221
+ err.write(`${line}\n`);
233
222
  }
234
- throw error;
223
+ return EXIT_FAILURE;
235
224
  }