@cplieger/deadset-ts 8.0.0-dev.2 → 8.0.0-dev.21

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 (431) hide show
  1. package/README.md +3 -1
  2. package/THIRD_PARTY_NOTICES.md +27 -0
  3. package/dist/bin/mapper-connection.js +2 -1
  4. package/dist/bin/node-host.js +24 -5
  5. package/dist/src/alias-chain.js +35 -9
  6. package/dist/src/amd.js +81 -0
  7. package/dist/src/analysis.js +274 -496
  8. package/dist/src/augmentations.js +64 -3
  9. package/dist/src/automatic-types.js +10 -29
  10. package/dist/src/bindings.js +382 -0
  11. package/dist/src/commands/held.js +499 -0
  12. package/dist/src/commands/read.js +161 -0
  13. package/dist/src/commands/shell.js +169 -0
  14. package/dist/src/commands/tools.js +1847 -0
  15. package/dist/src/component-files.js +3 -2
  16. package/dist/src/component-layer.js +4 -2
  17. package/dist/src/config.js +6 -82
  18. package/dist/src/conformance-record.js +2 -2
  19. package/dist/src/consumers.js +10 -38
  20. package/dist/src/contextual-uses.js +57 -26
  21. package/dist/src/contract/config.generated.js +561 -0
  22. package/dist/src/contract/contract.generated.js +1370 -0
  23. package/dist/src/contract/report.generated.js +866 -0
  24. package/dist/src/dependencies.js +165 -122
  25. package/dist/src/destructuring.js +1 -19
  26. package/dist/src/edges.js +38 -122
  27. package/dist/src/element-access.js +181 -168
  28. package/dist/src/entries/build-scripts.js +222 -0
  29. package/dist/src/{configuration-files.js → entries/configuration-files.js} +52 -256
  30. package/dist/src/{convention-rows.js → entries/convention-rows.js} +170 -30
  31. package/dist/src/entries/conventions.js +740 -0
  32. package/dist/src/{html-entries.js → entries/html-entries.js} +12 -42
  33. package/dist/src/{mdx-entries.js → entries/mdx-entries.js} +5 -28
  34. package/dist/src/entries/run-directories.js +77 -0
  35. package/dist/src/entries/sources.js +144 -0
  36. package/dist/src/entries/static-module.js +670 -0
  37. package/dist/src/entries/test-runners.js +650 -0
  38. package/dist/src/entries/workflow-steps.js +345 -0
  39. package/dist/src/exemptions/argument-places.js +131 -0
  40. package/dist/src/exemptions/calls.js +338 -0
  41. package/dist/src/exemptions/classes.js +13 -0
  42. package/dist/src/{decorator.js → exemptions/decorator.js} +19 -30
  43. package/dist/src/exemptions/detectors.js +48 -0
  44. package/dist/src/{enum-group.js → exemptions/enum-group.js} +9 -16
  45. package/dist/src/{erased-stores.js → exemptions/erased-stores.js} +7 -11
  46. package/dist/src/{framework-lifecycle.js → exemptions/framework-lifecycle.js} +76 -54
  47. package/dist/src/exemptions/generated-file.js +241 -0
  48. package/dist/src/{injection-container.js → exemptions/injection-container.js} +20 -26
  49. package/dist/src/exemptions/installed-globals.js +173 -0
  50. package/dist/src/{interface-satisfaction.js → exemptions/interface-satisfaction.js} +52 -121
  51. package/dist/src/exemptions/lifecycle.js +150 -0
  52. package/dist/src/{reflective-lookup.js → exemptions/reflective-lookup.js} +3 -3
  53. package/dist/src/exemptions/serialization-contract.js +1276 -0
  54. package/dist/src/exemptions/sites.js +182 -0
  55. package/dist/src/{template-field.js → exemptions/template-field.js} +13 -23
  56. package/dist/src/{value-reach.js → exemptions/value-reach.js} +14 -7
  57. package/dist/src/exposure.js +400 -0
  58. package/dist/src/extensions.js +37 -0
  59. package/dist/src/facts.js +38 -0
  60. package/dist/src/failure.js +36 -0
  61. package/dist/src/file-facts.js +3 -26
  62. package/dist/src/findings/completion.js +109 -56
  63. package/dist/src/findings/dependencies-and-module-machinery.js +4 -5
  64. package/dist/src/findings/emitters.js +27 -41
  65. package/dist/src/{implementations.js → findings/implementations.js} +3 -3
  66. package/dist/src/{in-operands.js → findings/in-operands.js} +3 -2
  67. package/dist/src/findings/interfaces.js +4 -5
  68. package/dist/src/findings/intra-function.js +16 -13
  69. package/dist/src/findings/non-code-artifacts.js +17 -12
  70. package/dist/src/findings/reads-and-writes.js +86 -27
  71. package/dist/src/findings/self-check.js +44 -30
  72. package/dist/src/findings/unused-declarations.js +29 -45
  73. package/dist/src/findings/visibility-narrowing.js +23 -31
  74. package/dist/src/findings-pass.js +13 -21
  75. package/dist/src/fs/document.js +52 -0
  76. package/dist/src/fs/manifest.js +67 -0
  77. package/dist/src/fs/tree.js +88 -0
  78. package/dist/src/git-ignore.js +39 -26
  79. package/dist/src/import-bindings.js +73 -28
  80. package/dist/src/index/sites.js +557 -0
  81. package/dist/src/index/values.js +124 -0
  82. package/dist/src/index.js +2 -2
  83. package/dist/src/indexed-access.js +523 -478
  84. package/dist/src/intra-function-parts.js +63 -43
  85. package/dist/src/inventory/commonjs.js +507 -0
  86. package/dist/src/inventory/enumerate.js +167 -0
  87. package/dist/src/inventory/syntax.js +236 -0
  88. package/dist/src/inventory.js +323 -724
  89. package/dist/src/javascript-file.js +48 -0
  90. package/dist/src/json-document.js +198 -67
  91. package/dist/src/keyof-comparisons.js +126 -107
  92. package/dist/src/kinds.js +3 -366
  93. package/dist/src/{components.js → liveness/components.js} +2 -3
  94. package/dist/src/{graph.js → liveness/graph.js} +52 -28
  95. package/dist/src/liveness/matrix.js +99 -0
  96. package/dist/src/liveness/sweep.js +558 -0
  97. package/dist/src/load/classify.js +289 -0
  98. package/dist/src/load/diagnostics.js +87 -0
  99. package/dist/src/load/discover.js +285 -0
  100. package/dist/src/{emit-map.js → load/emit-map.js} +1 -1
  101. package/dist/src/load/expected-module.js +136 -0
  102. package/dist/src/load/load.js +27 -0
  103. package/dist/src/load/module-lookup.js +37 -0
  104. package/dist/src/load/package-scope.js +56 -0
  105. package/dist/src/load/plan.js +313 -0
  106. package/dist/src/load/specifiers.js +113 -0
  107. package/dist/src/load/synthesize.js +152 -0
  108. package/dist/src/load/test-globals.js +207 -0
  109. package/dist/src/load/test-joins.js +82 -0
  110. package/dist/src/{workspace-manifests.js → load/workspace-manifests.js} +4 -4
  111. package/dist/src/{workspace-programs.js → load/workspace-programs.js} +89 -66
  112. package/dist/src/{workspace-resolution.js → load/workspace-resolution.js} +24 -66
  113. package/dist/src/{workspace-run.js → load/workspace-run.js} +7 -7
  114. package/dist/src/{workspace.js → load/workspace.js} +62 -124
  115. package/dist/src/module-declarations.js +70 -85
  116. package/dist/src/overrides.js +134 -112
  117. package/dist/src/partial.js +2 -1
  118. package/dist/src/paths.js +82 -16
  119. package/dist/src/platform-calls.js +78 -0
  120. package/dist/src/platform-symbols.js +134 -0
  121. package/dist/src/position.js +43 -1
  122. package/dist/src/print.js +11 -79
  123. package/dist/src/product.js +13 -0
  124. package/dist/src/query.js +95 -0
  125. package/dist/src/ref.js +12 -20
  126. package/dist/src/references/read-rule.js +1 -0
  127. package/dist/src/references/read-rules.js +48 -0
  128. package/dist/src/references/sink.js +237 -0
  129. package/dist/src/references/sources.js +450 -0
  130. package/dist/src/references.js +117 -1074
  131. package/dist/src/report-schema.js +51 -0
  132. package/dist/src/report.js +57 -41
  133. package/dist/src/reporters/annotations.js +15 -8
  134. package/dist/src/reporters/sarif.js +16 -10
  135. package/dist/src/reporters/template.js +4 -19
  136. package/dist/src/resolve.js +246 -730
  137. package/dist/src/{configured-declarations.js → roots/configured-declarations.js} +22 -24
  138. package/dist/src/{entry-point-gaps.js → roots/entry-point-gaps.js} +6 -15
  139. package/dist/src/roots/manifest.js +216 -0
  140. package/dist/src/roots/published-reach.js +412 -0
  141. package/dist/src/roots/root-set.js +487 -0
  142. package/dist/src/roots/unseen-loads.js +236 -0
  143. package/dist/src/run.js +66 -77
  144. package/dist/src/schema.js +320 -343
  145. package/dist/src/scope.js +38 -115
  146. package/dist/src/session.js +37 -29
  147. package/dist/src/source-files.js +6 -10
  148. package/dist/src/stores.js +4 -2
  149. package/dist/src/suppress-file.js +25 -28
  150. package/dist/src/suppress-inline.js +36 -83
  151. package/dist/src/suppress.js +50 -71
  152. package/dist/src/symbol-keys.js +92 -88
  153. package/dist/src/tests/file-class.js +76 -0
  154. package/dist/src/{outside-tests.js → tests/outside.js} +7 -7
  155. package/dist/src/{test-support.js → tests/support.js} +5 -12
  156. package/dist/src/text/compare.js +26 -0
  157. package/dist/src/text/glob.js +194 -0
  158. package/dist/src/text/named-files.js +298 -0
  159. package/dist/src/text/yaml.js +684 -0
  160. package/dist/src/type-errors.js +11 -232
  161. package/dist/src/type-parameter-reads.js +178 -139
  162. package/dist/src/unimplemented-callees.js +262 -242
  163. package/dist/src/unwrap.js +23 -0
  164. package/dist/src/usage.js +10 -0
  165. package/dist/src/vendor/unbash/ansi-c.js +132 -0
  166. package/dist/src/vendor/unbash/arithmetic-parts.js +37 -0
  167. package/dist/src/vendor/unbash/arithmetic.js +591 -0
  168. package/dist/src/vendor/unbash/assignment.js +131 -0
  169. package/dist/src/vendor/unbash/chars.js +48 -0
  170. package/dist/src/vendor/unbash/command.js +41 -0
  171. package/dist/src/vendor/unbash/expansion.js +80 -0
  172. package/dist/src/vendor/unbash/glob.js +268 -0
  173. package/dist/src/vendor/unbash/heredoc.js +27 -0
  174. package/dist/src/vendor/unbash/internal-types.js +1 -0
  175. package/dist/src/vendor/unbash/lexer.js +4274 -0
  176. package/dist/src/vendor/unbash/limits.js +3 -0
  177. package/dist/src/vendor/unbash/parser.js +1366 -0
  178. package/dist/src/vendor/unbash/parts.js +57 -0
  179. package/dist/src/vendor/unbash/substitution-context.js +8 -0
  180. package/dist/src/vendor/unbash/traversal.js +212 -0
  181. package/dist/src/vendor/unbash/types.js +1 -0
  182. package/dist/src/vendor/unbash/word-value.js +61 -0
  183. package/dist/src/vendor/unbash/word.js +40 -0
  184. package/dist/src/verbs/analyze.js +194 -127
  185. package/dist/src/verbs/describe.js +13 -18
  186. package/dist/src/verbs/explain.js +85 -139
  187. package/dist/src/verbs/print-config.js +2 -1
  188. package/dist/src/verbs/print-projects.js +6 -4
  189. package/dist/src/verbs/print-retained.js +30 -6
  190. package/dist/src/verbs/print-roots.js +4 -2
  191. package/dist/src/verbs/verb.js +1 -5
  192. package/dist/src/verbs/version.js +14 -3
  193. package/jsr.json +2 -1
  194. package/package.json +14 -8
  195. package/src/alias-chain.ts +40 -11
  196. package/src/amd.ts +130 -0
  197. package/src/analysis.ts +426 -733
  198. package/src/augmentations.ts +93 -4
  199. package/src/automatic-types.ts +12 -30
  200. package/src/bindings.ts +460 -0
  201. package/src/commands/held.ts +632 -0
  202. package/src/commands/read.ts +242 -0
  203. package/src/commands/shell.ts +228 -0
  204. package/src/commands/tools.ts +2382 -0
  205. package/src/component-files.ts +4 -2
  206. package/src/component-layer.ts +4 -2
  207. package/src/config.ts +31 -302
  208. package/src/conformance-record.ts +2 -2
  209. package/src/consumers.ts +16 -66
  210. package/src/contextual-uses.ts +66 -34
  211. package/src/contract/config.generated.ts +821 -0
  212. package/src/contract/contract.generated.ts +1453 -0
  213. package/src/contract/report.generated.ts +1241 -0
  214. package/src/dependencies.ts +223 -128
  215. package/src/destructuring.ts +1 -31
  216. package/src/edges.ts +41 -140
  217. package/src/element-access.ts +190 -187
  218. package/src/entries/build-scripts.ts +292 -0
  219. package/src/{configuration-files.ts → entries/configuration-files.ts} +68 -278
  220. package/src/{convention-rows.ts → entries/convention-rows.ts} +227 -31
  221. package/src/{conventions.ts → entries/conventions.ts} +367 -583
  222. package/src/{html-entries.ts → entries/html-entries.ts} +22 -48
  223. package/src/{mdx-entries.ts → entries/mdx-entries.ts} +7 -30
  224. package/src/entries/run-directories.ts +108 -0
  225. package/src/entries/sources.ts +266 -0
  226. package/src/entries/static-module.ts +858 -0
  227. package/src/entries/test-runners.ts +835 -0
  228. package/src/entries/workflow-steps.ts +432 -0
  229. package/src/exemptions/argument-places.ts +198 -0
  230. package/src/exemptions/calls.ts +483 -0
  231. package/src/exemptions/classes.ts +49 -0
  232. package/src/exemptions/decorator.ts +56 -0
  233. package/src/exemptions/detectors.ts +75 -0
  234. package/src/{enum-group.ts → exemptions/enum-group.ts} +10 -19
  235. package/src/{erased-stores.ts → exemptions/erased-stores.ts} +7 -14
  236. package/src/{framework-lifecycle.ts → exemptions/framework-lifecycle.ts} +85 -66
  237. package/src/exemptions/generated-file.ts +318 -0
  238. package/src/{injection-container.ts → exemptions/injection-container.ts} +29 -34
  239. package/src/exemptions/installed-globals.ts +255 -0
  240. package/src/{interface-satisfaction.ts → exemptions/interface-satisfaction.ts} +69 -160
  241. package/src/exemptions/lifecycle.ts +286 -0
  242. package/src/{reflective-lookup.ts → exemptions/reflective-lookup.ts} +5 -5
  243. package/src/exemptions/serialization-contract.ts +1729 -0
  244. package/src/exemptions/sites.ts +293 -0
  245. package/src/{template-field.ts → exemptions/template-field.ts} +22 -32
  246. package/src/{value-reach.ts → exemptions/value-reach.ts} +16 -8
  247. package/src/exposure.ts +492 -0
  248. package/src/extensions.ts +45 -0
  249. package/src/facts.ts +46 -0
  250. package/src/failure.ts +63 -0
  251. package/src/file-facts.ts +15 -25
  252. package/src/finding.ts +10 -10
  253. package/src/findings/boundary.ts +11 -0
  254. package/src/findings/completion.ts +133 -64
  255. package/src/findings/dependencies-and-module-machinery.ts +4 -7
  256. package/src/findings/emitter.ts +9 -10
  257. package/src/findings/emitters.ts +38 -52
  258. package/src/{implementations.ts → findings/implementations.ts} +4 -4
  259. package/src/{in-operands.ts → findings/in-operands.ts} +4 -3
  260. package/src/findings/interfaces.ts +7 -9
  261. package/src/findings/intra-function.ts +16 -14
  262. package/src/findings/non-code-artifacts.ts +24 -15
  263. package/src/findings/reads-and-writes.ts +118 -41
  264. package/src/findings/self-check.ts +51 -38
  265. package/src/findings/unused-declarations.ts +31 -49
  266. package/src/findings/visibility-narrowing.ts +36 -40
  267. package/src/findings-pass.ts +15 -31
  268. package/src/fs/document.ts +70 -0
  269. package/src/fs/manifest.ts +96 -0
  270. package/src/fs/tree.ts +110 -0
  271. package/src/git-ignore.ts +50 -26
  272. package/src/host.ts +12 -5
  273. package/src/import-bindings.ts +98 -29
  274. package/src/index/sites.ts +781 -0
  275. package/src/index/values.ts +170 -0
  276. package/src/index.ts +2 -2
  277. package/src/indexed-access.ts +570 -527
  278. package/src/intra-function-parts.ts +73 -44
  279. package/src/inventory/commonjs.ts +696 -0
  280. package/src/inventory/enumerate.ts +203 -0
  281. package/src/inventory/syntax.ts +311 -0
  282. package/src/inventory.ts +442 -895
  283. package/src/javascript-file.ts +54 -0
  284. package/src/json-document.ts +241 -76
  285. package/src/keyof-comparisons.ts +133 -122
  286. package/src/kinds.ts +5 -413
  287. package/src/{components.ts → liveness/components.ts} +4 -6
  288. package/src/{graph.ts → liveness/graph.ts} +100 -35
  289. package/src/liveness/matrix.ts +162 -0
  290. package/src/liveness/sweep.ts +855 -0
  291. package/src/load/classify.ts +433 -0
  292. package/src/load/diagnostics.ts +154 -0
  293. package/src/load/discover.ts +471 -0
  294. package/src/{emit-map.ts → load/emit-map.ts} +1 -1
  295. package/src/load/expected-module.ts +194 -0
  296. package/src/load/load.ts +73 -0
  297. package/src/load/module-lookup.ts +50 -0
  298. package/src/load/package-scope.ts +74 -0
  299. package/src/load/plan.ts +513 -0
  300. package/src/load/specifiers.ts +171 -0
  301. package/src/load/synthesize.ts +230 -0
  302. package/src/load/test-globals.ts +251 -0
  303. package/src/load/test-joins.ts +98 -0
  304. package/src/{workspace-manifests.ts → load/workspace-manifests.ts} +5 -5
  305. package/src/{workspace-programs.ts → load/workspace-programs.ts} +128 -85
  306. package/src/{workspace-resolution.ts → load/workspace-resolution.ts} +41 -77
  307. package/src/{workspace-run.ts → load/workspace-run.ts} +18 -16
  308. package/src/{workspace.ts → load/workspace.ts} +90 -134
  309. package/src/module-declarations.ts +74 -98
  310. package/src/overrides.ts +162 -134
  311. package/src/partial.ts +3 -2
  312. package/src/paths.ts +92 -16
  313. package/src/platform-calls.ts +119 -0
  314. package/src/platform-symbols.ts +189 -0
  315. package/src/position.ts +44 -1
  316. package/src/print.ts +12 -92
  317. package/src/product.ts +18 -0
  318. package/src/query.ts +201 -10
  319. package/src/ref.ts +12 -20
  320. package/src/references/read-rule.ts +60 -0
  321. package/src/references/read-rules.ts +55 -0
  322. package/src/references/sink.ts +314 -0
  323. package/src/references/sources.ts +632 -0
  324. package/src/references.ts +187 -1450
  325. package/src/report-schema.ts +68 -0
  326. package/src/report.ts +103 -226
  327. package/src/reporters/annotations.ts +22 -11
  328. package/src/reporters/json.ts +1 -1
  329. package/src/reporters/reporter.ts +2 -4
  330. package/src/reporters/reporters.ts +1 -1
  331. package/src/reporters/sarif.ts +29 -16
  332. package/src/reporters/template.ts +4 -20
  333. package/src/reporters/text.ts +3 -3
  334. package/src/resolve.ts +284 -1115
  335. package/src/{configured-declarations.ts → roots/configured-declarations.ts} +26 -29
  336. package/src/{entry-point-gaps.ts → roots/entry-point-gaps.ts} +7 -16
  337. package/src/roots/manifest.ts +303 -0
  338. package/src/roots/published-reach.ts +486 -0
  339. package/src/{roots.ts → roots/root-set.ts} +286 -469
  340. package/src/roots/unseen-loads.ts +345 -0
  341. package/src/run.ts +75 -91
  342. package/src/schema.ts +391 -388
  343. package/src/scope.ts +46 -138
  344. package/src/session.ts +87 -55
  345. package/src/source-files.ts +6 -11
  346. package/src/stores.ts +15 -3
  347. package/src/suppress-file.ts +24 -33
  348. package/src/suppress-inline.ts +55 -91
  349. package/src/suppress.ts +78 -79
  350. package/src/symbol-keys.ts +104 -107
  351. package/src/tests/file-class.ts +135 -0
  352. package/src/{outside-tests.ts → tests/outside.ts} +16 -10
  353. package/src/{test-support.ts → tests/support.ts} +15 -21
  354. package/src/text/compare.ts +27 -0
  355. package/src/text/glob.ts +210 -0
  356. package/src/text/named-files.ts +388 -0
  357. package/src/text/yaml.ts +747 -0
  358. package/src/type-errors.ts +18 -288
  359. package/src/type-parameter-reads.ts +187 -158
  360. package/src/unimplemented-callees.ts +297 -280
  361. package/src/unwrap.ts +34 -0
  362. package/src/usage.ts +10 -0
  363. package/src/vendor/unbash/LICENSE +15 -0
  364. package/src/vendor/unbash/VENDORED.md +16 -0
  365. package/src/vendor/unbash/ansi-c.ts +132 -0
  366. package/src/vendor/unbash/arithmetic-parts.ts +53 -0
  367. package/src/vendor/unbash/arithmetic.ts +641 -0
  368. package/src/vendor/unbash/assignment.ts +163 -0
  369. package/src/vendor/unbash/chars.ts +48 -0
  370. package/src/vendor/unbash/command.ts +47 -0
  371. package/src/vendor/unbash/expansion.ts +144 -0
  372. package/src/vendor/unbash/glob.ts +284 -0
  373. package/src/vendor/unbash/heredoc.ts +34 -0
  374. package/src/vendor/unbash/internal-types.ts +94 -0
  375. package/src/vendor/unbash/lexer.ts +4352 -0
  376. package/src/vendor/unbash/limits.ts +3 -0
  377. package/src/vendor/unbash/parser.ts +1612 -0
  378. package/src/vendor/unbash/parts.ts +96 -0
  379. package/src/vendor/unbash/substitution-context.ts +20 -0
  380. package/src/vendor/unbash/traversal.ts +182 -0
  381. package/src/vendor/unbash/types.ts +660 -0
  382. package/src/vendor/unbash/word-value.ts +64 -0
  383. package/src/vendor/unbash/word.ts +50 -0
  384. package/src/verbs/analyze.ts +255 -164
  385. package/src/verbs/describe.ts +19 -17
  386. package/src/verbs/explain.ts +93 -169
  387. package/src/verbs/print-config.ts +2 -1
  388. package/src/verbs/print-projects.ts +6 -4
  389. package/src/verbs/print-retained.ts +36 -6
  390. package/src/verbs/print-roots.ts +4 -2
  391. package/src/verbs/verb.ts +2 -8
  392. package/src/verbs/version.ts +15 -3
  393. package/dist/src/base-url.js +0 -18
  394. package/dist/src/calls.js +0 -155
  395. package/dist/src/conventions.js +0 -937
  396. package/dist/src/discover.js +0 -468
  397. package/dist/src/entry-points.js +0 -529
  398. package/dist/src/exempt-classes.js +0 -75
  399. package/dist/src/exempt.js +0 -209
  400. package/dist/src/generated-file.js +0 -95
  401. package/dist/src/glob.js +0 -65
  402. package/dist/src/manifest.js +0 -165
  403. package/dist/src/matrix.js +0 -246
  404. package/dist/src/pnpm-workspace.js +0 -120
  405. package/dist/src/roots.js +0 -672
  406. package/dist/src/serialization-contract.js +0 -611
  407. package/dist/src/setup-failure.js +0 -23
  408. package/dist/src/sweep.js +0 -224
  409. package/dist/src/test-joins.js +0 -101
  410. package/dist/src/value-flow.js +0 -74
  411. package/dist/src/version.js +0 -7
  412. package/dist/src/workflow-steps.js +0 -185
  413. package/src/base-url.ts +0 -24
  414. package/src/calls.ts +0 -225
  415. package/src/decorator.ts +0 -78
  416. package/src/discover.ts +0 -653
  417. package/src/entry-points.ts +0 -687
  418. package/src/exempt-classes.ts +0 -123
  419. package/src/exempt.ts +0 -323
  420. package/src/generated-file.ts +0 -111
  421. package/src/glob.ts +0 -67
  422. package/src/manifest.ts +0 -234
  423. package/src/matrix.ts +0 -423
  424. package/src/pnpm-workspace.ts +0 -135
  425. package/src/serialization-contract.ts +0 -849
  426. package/src/setup-failure.ts +0 -39
  427. package/src/sweep.ts +0 -347
  428. package/src/test-joins.ts +0 -120
  429. package/src/value-flow.ts +0 -104
  430. package/src/version.ts +0 -7
  431. package/src/workflow-steps.ts +0 -216
@@ -0,0 +1,345 @@
1
+ /**
2
+ * The loads by a computed path: those whose files the analysis resolves, and those it
3
+ * cannot, whose files are roots the analysis does not see, so the configuration's roots
4
+ * are never complete.
5
+ */
6
+
7
+ import {
8
+ isBinaryExpression,
9
+ isCallExpression,
10
+ isIdentifier,
11
+ isMetaProperty,
12
+ isNoSubstitutionTemplateLiteral,
13
+ isPropertyAccessExpression,
14
+ isStringLiteral,
15
+ isTemplateExpression,
16
+ SyntaxKind,
17
+ type CallExpression,
18
+ type Identifier,
19
+ type Node,
20
+ type SourceFile,
21
+ } from "@typescript/native/ast";
22
+ import { amdLoadOf, amdUnresolved } from "../amd.ts";
23
+ import { membersNamed, textsOf, writtenValue, type Value } from "../entries/static-module.ts";
24
+ import { writtenName } from "../platform-calls.ts";
25
+ import {
26
+ cannotStartPackageName,
27
+ dirnamePath,
28
+ hasURLScheme,
29
+ isAbsolutePath,
30
+ relativePath,
31
+ resolvePath,
32
+ startsRelativePath,
33
+ } from "../paths.ts";
34
+ import type { Position } from "../position.ts";
35
+ import { unwrapped } from "../unwrap.ts";
36
+ import { globExpression } from "../text/glob.ts";
37
+
38
+ /** One load the analysis cannot resolve, in the configuration whose production file writes it. */
39
+ export interface UnseenLoad {
40
+ readonly configuration: string;
41
+ /** The position of the call. */
42
+ readonly position: Position;
43
+ }
44
+
45
+ /** The literal text a computed path starts with: a template's head, or a concatenation's first literal. */
46
+ function leadingLiteral(node: Node): string | undefined {
47
+ const at = unwrapped(node);
48
+ if (isTemplateExpression(at)) {
49
+ return at.head.text;
50
+ }
51
+ if (isBinaryExpression(at) && at.operatorToken.kind === SyntaxKind.PlusToken) {
52
+ const left = unwrapped(at.left);
53
+ return isStringLiteral(left) || isNoSubstitutionTemplateLiteral(left)
54
+ ? left.text
55
+ : leadingLiteral(at.left);
56
+ }
57
+ return undefined;
58
+ }
59
+
60
+ /**
61
+ * The directory below `dir` a computed load's leading literal names, every file of which
62
+ * the load reaches, or none where it names a package, `dir` itself or a directory holding
63
+ * it, each of which would name every sibling.
64
+ */
65
+ function computedLoadDirectory(dir: string, prefix: string): string | undefined {
66
+ if (!startsRelativePath(prefix) || !prefix.endsWith("/")) {
67
+ return undefined;
68
+ }
69
+ const target = resolvePath(dir, prefix);
70
+ return target === dir || relativePath(target, dir) !== undefined ? undefined : target;
71
+ }
72
+
73
+ /** One `import()`, `require()` or `import.meta.glob()` call, and the declaration whose code writes it. */
74
+ export interface LoadCall {
75
+ readonly call: CallExpression;
76
+ readonly from: string;
77
+ }
78
+
79
+ /** One file a computed load may load, by its id. */
80
+ interface Loadable {
81
+ readonly file: SourceFile;
82
+ readonly fileId: string;
83
+ }
84
+
85
+ /** One load by a computed path whose files the analysis resolves. */
86
+ export interface ComputedLoad {
87
+ readonly call: CallExpression;
88
+ readonly from: string;
89
+ /** The name a `require()` call is written with; {@link callsPlatform} owns which one loads. */
90
+ readonly require: Identifier | undefined;
91
+ /** Whether the call is an AMD `define` or `require` (references-ts.37). */
92
+ readonly amd: boolean;
93
+ readonly files: readonly Loadable[];
94
+ /** Whether the load reads each file as text or as a URL, which references no declaration of it. */
95
+ readonly asset: boolean;
96
+ /**
97
+ * Whether the analysis names every file the load may load. An unresolved load names none,
98
+ * and leaves the configuration's roots incomplete (confidence.26).
99
+ */
100
+ readonly resolved: boolean;
101
+ /**
102
+ * Whether the load is an eager glob, which Vite turns into static imports at the top of
103
+ * the calling module (https://vite.dev/guide/features.html#glob-import), so the file
104
+ * evaluates what it loads wherever the call is written.
105
+ */
106
+ readonly eager: boolean;
107
+ }
108
+
109
+ /** Whether one node is a call that may load a module by a computed path. */
110
+ export function isLoadCall(node: Node): node is CallExpression {
111
+ if (!isCallExpression(node)) {
112
+ return false;
113
+ }
114
+ return (
115
+ node.expression.kind === SyntaxKind.ImportKeyword ||
116
+ writtenName(node.expression) !== undefined ||
117
+ isMetaGlob(node)
118
+ );
119
+ }
120
+
121
+ /**
122
+ * The files one `import.meta.glob` call loads, as Vite's `toAbsoluteGlob` reads its globs
123
+ * (https://vite.dev/guide/features.html#glob-import): `/` against the project root, `./`
124
+ * and `../` against a literal `base` (read against the root where it starts with `/`) or the
125
+ * calling file's directory, `**` as written, and `!` removing what it matches. Undefined
126
+ * where Vite reads a glob through an alias, the root is unknown, or a glob or base is computed.
127
+ */
128
+ function globbed(
129
+ file: SourceFile,
130
+ first: Node,
131
+ options: Node | undefined,
132
+ others: readonly Loadable[],
133
+ rootOf: (fileName: string) => string | undefined,
134
+ ): readonly Loadable[] | undefined {
135
+ const patterns = textsOf(writtenValue(first), true);
136
+ const bases = globOption(options, "base");
137
+ const [written, ...more] = bases ?? [];
138
+ const base = written === undefined ? undefined : textsOf(written, false);
139
+ if (
140
+ patterns === undefined ||
141
+ bases === undefined ||
142
+ more.length > 0 ||
143
+ (written !== undefined && base === undefined)
144
+ ) {
145
+ return undefined;
146
+ }
147
+ const dir = dirnamePath(file.fileName);
148
+ const root = (): string | undefined => rootOf(file.fileName);
149
+ const against = (at: string): string | undefined => {
150
+ if (!isAbsolutePath(at)) {
151
+ return resolvePath(dir, at);
152
+ }
153
+ const top = root();
154
+ return top === undefined ? undefined : resolvePath(top, `.${at}`);
155
+ };
156
+ const from = base?.[0] === undefined ? dir : against(base[0]);
157
+ const keep: RegExp[] = [];
158
+ const drop: RegExp[] = [];
159
+ for (const written of patterns) {
160
+ const negated = written.startsWith("!");
161
+ const pattern = negated ? written.slice(1) : written;
162
+ let path: string | undefined;
163
+ if (isAbsolutePath(pattern)) {
164
+ path = against(pattern);
165
+ } else if (startsRelativePath(pattern)) {
166
+ path = from === undefined ? undefined : resolvePath(from, pattern);
167
+ } else if (pattern.startsWith("**")) {
168
+ path = pattern;
169
+ }
170
+ if (path === undefined) {
171
+ return undefined;
172
+ }
173
+ (negated ? drop : keep).push(globExpression(path));
174
+ }
175
+ return others.filter(
176
+ (candidate) =>
177
+ keep.some((glob) => glob.test(candidate.file.fileName)) &&
178
+ !drop.some((glob) => glob.test(candidate.file.fileName)),
179
+ );
180
+ }
181
+
182
+ /**
183
+ * The computed loads among one file's load calls, each loading the `candidates` but the
184
+ * file itself: an `import()` or `require()` whose path starts with a relative literal naming
185
+ * a directory below the file's loads every candidate below it, as a bundler's context module
186
+ * reads it, and an `import.meta.glob` every candidate its globs match ({@link globbed}). A
187
+ * call of a computed path that names no such directory and no package is an unresolved load,
188
+ * and so is an AMD call one of whose dependencies names no path ({@link amdUnresolved}).
189
+ */
190
+ export function computedLoadsOf(
191
+ file: SourceFile,
192
+ calls: readonly LoadCall[],
193
+ candidates: readonly Loadable[],
194
+ rootOf: (fileName: string) => string | undefined,
195
+ ): readonly ComputedLoad[] {
196
+ const dir = dirnamePath(file.fileName);
197
+ const others = candidates.filter((candidate) => candidate.file !== file);
198
+ return calls.flatMap(({ call, from }): ComputedLoad[] => {
199
+ const [first, options] = call.arguments;
200
+ if (first === undefined) {
201
+ return [];
202
+ }
203
+ if (isMetaGlob(call)) {
204
+ const files = globbed(file, first, options, others, rootOf);
205
+ const asset = readsAsAsset(options);
206
+ return [
207
+ {
208
+ call,
209
+ from,
210
+ require: undefined,
211
+ amd: false,
212
+ files: files ?? [],
213
+ resolved: files !== undefined,
214
+ asset,
215
+ eager: isEager(options),
216
+ },
217
+ ];
218
+ }
219
+ const amd = amdLoadOf(call);
220
+ if (amd !== undefined) {
221
+ return amdUnresolved(amd)
222
+ ? [
223
+ {
224
+ call,
225
+ from,
226
+ require: amd.callee,
227
+ amd: true,
228
+ files: [],
229
+ resolved: false,
230
+ asset: false,
231
+ eager: false,
232
+ },
233
+ ]
234
+ : [];
235
+ }
236
+ const argument = unwrapped(first);
237
+ const require =
238
+ call.expression.kind === SyntaxKind.ImportKeyword ? undefined : writtenName(call.expression);
239
+ if (!mayNamePath(argument)) {
240
+ return [];
241
+ }
242
+ const prefix = leadingLiteral(argument);
243
+ if (namesPackage(prefix)) {
244
+ return [];
245
+ }
246
+ const target = prefix === undefined ? undefined : computedLoadDirectory(dir, prefix);
247
+ const files =
248
+ target === undefined
249
+ ? []
250
+ : others.filter((candidate) => relativePath(target, candidate.file.fileName) !== undefined);
251
+ return [
252
+ {
253
+ call,
254
+ from,
255
+ require,
256
+ amd: false,
257
+ files,
258
+ resolved: target !== undefined,
259
+ asset: false,
260
+ eager: false,
261
+ },
262
+ ];
263
+ });
264
+ }
265
+
266
+ /**
267
+ * Whether a computed argument may be a module path: anything but a string, which names its
268
+ * module, and a value no path is, a number, a boolean, `null`, an object, an array, a
269
+ * function or a class.
270
+ */
271
+ function mayNamePath(argument: Node): boolean {
272
+ return !NO_PATH.has(argument.kind);
273
+ }
274
+
275
+ const NO_PATH: ReadonlySet<SyntaxKind> = new Set([
276
+ SyntaxKind.StringLiteral,
277
+ SyntaxKind.NoSubstitutionTemplateLiteral,
278
+ SyntaxKind.NumericLiteral,
279
+ SyntaxKind.BigIntLiteral,
280
+ SyntaxKind.TrueKeyword,
281
+ SyntaxKind.FalseKeyword,
282
+ SyntaxKind.NullKeyword,
283
+ SyntaxKind.ObjectLiteralExpression,
284
+ SyntaxKind.ArrayLiteralExpression,
285
+ SyntaxKind.ArrowFunction,
286
+ SyntaxKind.FunctionExpression,
287
+ SyntaxKind.ClassExpression,
288
+ SyntaxKind.RegularExpressionLiteral,
289
+ ]);
290
+
291
+ /** Whether one call is `import.meta.glob(...)`. */
292
+ function isMetaGlob(node: CallExpression): boolean {
293
+ if (!isPropertyAccessExpression(node.expression)) {
294
+ return false;
295
+ }
296
+ const { expression, name } = node.expression;
297
+ return (
298
+ isIdentifier(name) &&
299
+ name.text === "glob" &&
300
+ isMetaProperty(expression) &&
301
+ expression.keywordToken === SyntaxKind.ImportKeyword
302
+ );
303
+ }
304
+
305
+ /** The values the options of an `import.meta.glob` write for one key, undefined where a spread may hide one. */
306
+ function globOption(options: Node | undefined, key: string): readonly Value[] | undefined {
307
+ return options === undefined ? [] : membersNamed(writtenValue(options), key);
308
+ }
309
+
310
+ /** Whether the options of an `import.meta.glob` set `eager` to `true`. */
311
+ function isEager(options: Node | undefined): boolean {
312
+ return (
313
+ globOption(options, "eager")?.some((value) => value.kind === "boolean" && value.value) === true
314
+ );
315
+ }
316
+
317
+ /** The query parameters that make Vite load a file as its text or its URL, each written bare. */
318
+ const ASSET_QUERY = /(?:^\?|&)(?:raw|url|inline)(?:&|$)/u;
319
+
320
+ /**
321
+ * Whether the options of an `import.meta.glob` read each file as text or as a URL: a
322
+ * `query` string holding a bare `raw`, `url` or `inline`, or an `as` of `raw` or `url`,
323
+ * which Vite reads as that query (https://vite.dev/guide/features.html#glob-import). Any
324
+ * other query is read as loading the module, which keeps more than it may.
325
+ */
326
+ function readsAsAsset(options: Node | undefined): boolean {
327
+ const texts = (key: string): readonly string[] =>
328
+ (globOption(options, key) ?? []).flatMap((value) =>
329
+ value.kind === "text" ? [value.text] : [],
330
+ );
331
+ return (
332
+ texts("as").some((text) => text === "raw" || text === "url") ||
333
+ texts("query").some((text) => ASSET_QUERY.test(text.startsWith("?") ? text : `?${text}`))
334
+ );
335
+ }
336
+
337
+ /** Whether a computed path's leading literal names a package, whose files are none of the target's. */
338
+ function namesPackage(prefix: string | undefined): boolean {
339
+ return (
340
+ prefix !== undefined &&
341
+ prefix !== "" &&
342
+ !cannotStartPackageName(prefix) &&
343
+ !hasURLScheme(prefix)
344
+ );
345
+ }
package/src/run.ts CHANGED
@@ -1,9 +1,13 @@
1
- import { ConfigError, REPOSITORY_DOCUMENT, type Inputs } from "./config.ts";
2
- import { DiscoveryError, renderDiagnostic } from "./discover.ts";
1
+ import { CONFIG_MAX_BYTES, SETTINGS } from "./contract/config.generated.ts";
2
+ import { EXIT_FAILURE, EXIT_USAGE } from "./contract/contract.generated.ts";
3
+ import { REPOSITORY_DOCUMENT, type Document, type Inputs } from "./config.ts";
4
+ import { readTargetDocument } from "./fs/document.ts";
3
5
  import type { Host } from "./host.ts";
4
6
  import { joinPath, resolvePath } from "./paths.ts";
5
- import { readScope, ScopeError, scopeForDir, type Scope } from "./scope.ts";
6
- import { SetupError, setupLine } from "./setup-failure.ts";
7
+ import { renderDiagnostic } from "./load/diagnostics.ts";
8
+ import { FailureExit, failureLines, productFault } from "./failure.ts";
9
+ import { readScope, scopeForDir, type Scope } from "./scope.ts";
10
+ import { UsageError } from "./usage.ts";
7
11
  import { openEngine, type Engine, type EngineOptions } from "./session.ts";
8
12
  import { printConfigVerb } from "./verbs/print-config.ts";
9
13
  import { printProjectsVerb } from "./verbs/print-projects.ts";
@@ -12,8 +16,9 @@ import { printRootsVerb } from "./verbs/print-roots.ts";
12
16
  import { ANALYZE_OPTIONS, analyzeVerb } from "./verbs/analyze.ts";
13
17
  import { describeVerb } from "./verbs/describe.ts";
14
18
  import { EXPLAIN_OPTIONS, explainVerb } from "./verbs/explain.ts";
15
- import { EXIT_FAILURE, EXIT_USAGE, type Verb, type VerbOptions } from "./verbs/verb.ts";
19
+ import { type Verb, type VerbOptions } from "./verbs/verb.ts";
16
20
  import { versionVerb } from "./verbs/version.ts";
21
+ import { diagnose, message, PRODUCT } from "./product.ts";
17
22
 
18
23
  /** One output stream of the command line. `process.stdout` and `process.stderr` satisfy it. */
19
24
  export interface Writer {
@@ -36,7 +41,7 @@ const VERBS: readonly {
36
41
  { name: "version", run: versionVerb },
37
42
  ];
38
43
 
39
- const USAGE = `usage: deadset-ts <verb> [options]\nverbs: ${VERBS.map((verb) => verb.name).join(", ")}\n`;
44
+ const USAGE = `usage: ${PRODUCT} <verb> [options]\nverbs: ${VERBS.map((verb) => verb.name).join(", ")}\n`;
40
45
 
41
46
  /**
42
47
  * The tokens whose presence in an option's name makes that option a request to
@@ -46,33 +51,16 @@ const USAGE = `usage: deadset-ts <verb> [options]\nverbs: ${VERBS.map((verb) =>
46
51
  const SOURCE_EDIT_TOKENS = ["fix", "edit", "delete", "rewrite"] as const;
47
52
 
48
53
  /**
49
- * Maps an option name to the setting of the Contract's configuration schema it supplies,
50
- * so one entry registers the option, supplies the document resolution reads, and gives
51
- * the spelling the setting's provenance names. The name is this command's vocabulary and
52
- * is never derived from the path: a setting reaches the command line only by an entry,
53
- * and a path names a key the schema declares.
54
+ * Maps an option name to the setting of the Contract's configuration schema it supplies:
55
+ * the options contract/settings.json names for a setting this analyzer reads.
54
56
  */
55
- export const SETTING_OPTIONS: ReadonlyMap<string, string> = new Map([
56
- ["min-confidence", "analysis.min_confidence"],
57
- ["sort", "reporters.sort"],
58
- ["cascade", "reporters.cascade"],
59
- ["max-findings", "reporters.max_findings"],
60
- ["fail-on", "reporters.fail_on"],
61
- ]);
57
+ export const SETTING_OPTIONS: ReadonlyMap<string, string> = new Map(
58
+ SETTINGS.flatMap((row) => (row.option === undefined ? [] : [[row.option, row.key] as const])),
59
+ );
62
60
 
63
61
  /** The options that take a value and are not settings. */
64
62
  const PLAIN_OPTIONS: ReadonlySet<string> = new Set(["target", "config", "central", "scope"]);
65
63
 
66
- /**
67
- * The setting options whose value is an integer rather than a string. A value
68
- * written other than as digits is passed on as the string it is, so resolution
69
- * refuses it by its type rather than reading `1e2` as 100.
70
- */
71
- const INTEGER_OPTIONS: ReadonlySet<string> = new Set(["max-findings"]);
72
-
73
- /** An integer as an option writes it: an optional minus sign and digits alone. */
74
- const INTEGER_TEXT = /^-?[0-9]+$/u;
75
-
76
64
  /** One invocation's options, by name: the last value of each, and every value of a repeatable one. */
77
65
  interface Options {
78
66
  readonly named: ReadonlyMap<string, string>;
@@ -107,7 +95,7 @@ function readOptions(args: readonly string[], own: VerbOptions): Options {
107
95
  const repeated = new Map<string, string[]>();
108
96
  for (const arg of args) {
109
97
  if (!arg.startsWith("-")) {
110
- throw new ConfigError("malformed", "", `unexpected argument ${JSON.stringify(arg)}`);
98
+ throw new UsageError(`unexpected argument ${JSON.stringify(arg)}`);
111
99
  }
112
100
  const [spelled, ...rest] = arg.split("=");
113
101
  const name = (spelled ?? "").replace(/^-+/u, "");
@@ -117,14 +105,10 @@ function readOptions(args: readonly string[], own: VerbOptions): Options {
117
105
  !own.plain.includes(name) &&
118
106
  !own.repeatable.includes(name)
119
107
  ) {
120
- throw new ConfigError("malformed", "", `unknown option ${JSON.stringify(spelled ?? arg)}`);
108
+ throw new UsageError(`unknown option ${JSON.stringify(spelled ?? arg)}`);
121
109
  }
122
110
  if (rest.length === 0) {
123
- throw new ConfigError(
124
- "malformed",
125
- "",
126
- `option ${JSON.stringify(spelled ?? arg)} takes a value`,
127
- );
111
+ throw new UsageError(`option ${JSON.stringify(spelled ?? arg)} takes a value`);
128
112
  }
129
113
  const value = rest.join("=");
130
114
  named.set(name, value);
@@ -133,51 +117,56 @@ function readOptions(args: readonly string[], own: VerbOptions): Options {
133
117
  return { named, repeated };
134
118
  }
135
119
 
136
- function readFileOr(host: Host, path: string, orUndefined: boolean): string | undefined {
120
+ /** The document an option names. */
121
+ function documentAt(host: Host, label: string): Document {
137
122
  try {
138
- return host.readFile(resolvePath(host.workingDirectory(), path));
123
+ const path = resolvePath(host.workingDirectory(), label);
124
+ // A file past the bound reads as one byte more than it, which resolution refuses.
125
+ return { text: host.readFile(path, CONFIG_MAX_BYTES + 1), label };
139
126
  } catch (error: unknown) {
140
- if (orUndefined) {
141
- return undefined;
142
- }
143
- throw new ConfigError(
144
- "malformed",
145
- "",
146
- `${path}: ${error instanceof Error ? error.message : String(error)}`,
147
- );
127
+ throw new UsageError(`${label}: ${message(error)}`);
148
128
  }
149
129
  }
150
130
 
151
131
  /**
152
- * The configuration documents one invocation reads: the repository configuration
153
- * at the target root or the path an option named, the central configuration, and
154
- * the settings the options supply as one flag document.
132
+ * The repository configuration at the target root, none where it is absent. One that
133
+ * cannot be read is a configuration document that cannot be, refused with the usage code.
134
+ */
135
+ function repositoryAt(host: Host, target: string): Document | undefined {
136
+ const label = joinPath(target, REPOSITORY_DOCUMENT);
137
+ const root = resolvePath(host.workingDirectory(), target);
138
+ const text = readTargetDocument(
139
+ host,
140
+ root,
141
+ REPOSITORY_DOCUMENT,
142
+ label,
143
+ (named, reason) => new UsageError(`${named}: ${reason}`),
144
+ );
145
+ return text === undefined ? undefined : { text, label };
146
+ }
147
+
148
+ /**
149
+ * The configuration sources one invocation carries: the repository configuration at
150
+ * the target root or the path an option named, the central configuration, and the
151
+ * text each setting option was given.
155
152
  */
156
153
  function inputsOf(host: Host, options: Options): Inputs {
157
- const target = options.named.get("target") ?? ".";
158
154
  const named = options.named.get("config");
159
- const repositoryLabel = named ?? joinPath(target, REPOSITORY_DOCUMENT);
160
- const repository = readFileOr(host, repositoryLabel, named === undefined);
155
+ const target = options.named.get("target") ?? ".";
156
+ const repository = named === undefined ? repositoryAt(host, target) : documentAt(host, named);
161
157
  const centralLabel = options.named.get("central");
162
- const central = centralLabel === undefined ? undefined : readFileOr(host, centralLabel, false);
163
-
164
- const flat: Record<string, unknown> = {};
165
- const flagLabels = new Map<string, string>();
166
- for (const [name, path] of SETTING_OPTIONS) {
158
+ const central = centralLabel === undefined ? undefined : documentAt(host, centralLabel);
159
+ const flags = new Map<string, string>();
160
+ for (const [name, key] of SETTING_OPTIONS) {
167
161
  const value = options.named.get(name);
168
- if (value === undefined) {
169
- continue;
162
+ if (value !== undefined) {
163
+ flags.set(key, value);
170
164
  }
171
- flat[path] = INTEGER_OPTIONS.has(name) && INTEGER_TEXT.test(value) ? Number(value) : value;
172
- flagLabels.set(path, `--${name}`);
173
165
  }
174
- const flags = Object.keys(flat).length === 0 ? undefined : JSON.stringify(flat);
175
-
176
166
  return {
177
- ...(flags === undefined ? {} : { flags }),
178
- ...(repository === undefined ? {} : { repository, repositoryLabel }),
179
- ...(central === undefined || centralLabel === undefined ? {} : { central, centralLabel }),
180
- flagLabels,
167
+ flags,
168
+ ...(repository === undefined ? {} : { repository }),
169
+ ...(central === undefined ? {} : { central }),
181
170
  };
182
171
  }
183
172
 
@@ -195,9 +184,7 @@ function scopeOf(host: Host, options: Options): Scope {
195
184
  * the exit code: 0 for a completed verb, 1 for a finding that fails the run, 2 for a
196
185
  * usage error, a requested source edit or a refused configuration, 3 for a failure that
197
186
  * produced no answer. It writes nothing outside `out` and `err` and never exits the
198
- * process. `host` is the platform the run reads, the version it reports included, and
199
- * `openClient` opens the compiler client; a caller that watches what a run reads
200
- * supplies its own of either.
187
+ * process. A caller that watches what a run reads supplies its own `host` or `openClient`.
201
188
  */
202
189
  export function run(
203
190
  args: readonly string[],
@@ -208,9 +195,7 @@ export function run(
208
195
  ): number {
209
196
  const editing = sourceEditOption(args);
210
197
  if (editing !== undefined) {
211
- err.write(
212
- `deadset-ts: ${editing} is not supported: deadset-ts reports and never edits a source file\n`,
213
- );
198
+ diagnose(err, `${editing} is not supported: ${PRODUCT} reports and never edits a source file`);
214
199
  err.write(USAGE);
215
200
  return EXIT_USAGE;
216
201
  }
@@ -227,7 +212,7 @@ export function run(
227
212
  );
228
213
  }
229
214
  if (name !== undefined) {
230
- err.write(`deadset-ts: unknown verb ${JSON.stringify(name)}\n`);
215
+ diagnose(err, `unknown verb ${JSON.stringify(name)}`);
231
216
  }
232
217
  err.write(USAGE);
233
218
  return EXIT_USAGE;
@@ -259,7 +244,7 @@ function invoke(
259
244
  openClient: (config) => {
260
245
  opened = openClient({
261
246
  collectTiming: false,
262
- components: { extensions: config.ts.componentExtensions, host: streams.host },
247
+ components: { extensions: config.ts.component_extensions, host: streams.host },
263
248
  });
264
249
  return opened;
265
250
  },
@@ -270,29 +255,28 @@ function invoke(
270
255
  }
271
256
  }
272
257
 
273
- /** Turns one refusal into the exit code the Contract's table gives it. */
258
+ /**
259
+ * Turns one refusal into the exit code the Contract's table gives it. An error no class names
260
+ * is a fault of this analyzer, printed with its stack for the maintainers it asks the user to
261
+ * report it to.
262
+ */
274
263
  function refuse(error: unknown, err: Writer): number {
275
- if (error instanceof ConfigError) {
276
- err.write(`deadset-ts: ${error.message}\n`);
264
+ if (error instanceof UsageError) {
265
+ diagnose(err, error.message);
277
266
  err.write(USAGE);
278
267
  return EXIT_USAGE;
279
268
  }
280
- if (error instanceof DiscoveryError) {
281
- for (const diagnostic of error.diagnostics) {
282
- err.write(`${renderDiagnostic(diagnostic)}\n`);
269
+ if (!(error instanceof FailureExit)) {
270
+ if (error instanceof Error && error.stack !== undefined) {
271
+ err.write(`${error.stack}\n`);
283
272
  }
284
- err.write(`deadset-ts: ${error.message}\n`);
285
- return EXIT_FAILURE;
273
+ return refuse(productFault(`meets an error none of its classes names: ${message(error)}`), err);
286
274
  }
287
- if (error instanceof SetupError) {
288
- for (const failure of error.failures) {
289
- err.write(`${setupLine(failure)}\n`);
290
- }
291
- return EXIT_FAILURE;
275
+ for (const diagnostic of error.diagnostics) {
276
+ err.write(`${renderDiagnostic(diagnostic)}\n`);
292
277
  }
293
- if (error instanceof ScopeError) {
294
- err.write(`deadset-ts: ${error.message}\n`);
295
- return EXIT_FAILURE;
278
+ for (const line of failureLines(error.failures)) {
279
+ err.write(`${line}\n`);
296
280
  }
297
- throw error;
281
+ return EXIT_FAILURE;
298
282
  }