@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,650 @@
1
+ /**
2
+ * The test runners a convention row names by its `testRunner`, and `node --test`, which no
3
+ * package enables: each reads the files its runner runs as tests from the runner's
4
+ * configuration and from the commands a manifest's scripts run it with, as the runner's own
5
+ * source reads them. A value a reader needs that the text does not write out names no file.
6
+ */
7
+ import { readJSON, readJSONFile } from "../fs/manifest.js";
8
+ import { ancestors, dirnamePath, joinPath, relativePath, resolvePath } from "../paths.js";
9
+ import { globExpression } from "../text/glob.js";
10
+ import { documentValue, membersNamed, textsOf, } from "./static-module.js";
11
+ /** A member's last value: `null` where the object writes none, `undefined` where it may hide one or is no object. */
12
+ function lastOf(object, key) {
13
+ if (object.kind !== "object") {
14
+ return undefined;
15
+ }
16
+ const values = membersNamed(object, key);
17
+ return values === undefined ? undefined : (values.at(-1) ?? null);
18
+ }
19
+ /** The one object a configuration's default export writes, `undefined` where it writes anything else. */
20
+ function configurationObject(module) {
21
+ const [only, ...more] = module.defaultExport;
22
+ return only?.kind === "object" && more.length === 0 ? only : undefined;
23
+ }
24
+ /** The strings a member holds, one or an array of them: `null` where absent, `undefined` where not written out. */
25
+ function stringsOf(object, key) {
26
+ const value = lastOf(object, key);
27
+ return value === null || value === undefined ? value : textsOf(value, true);
28
+ }
29
+ /** A boolean member: `null` where absent, `undefined` where it is written as anything else. */
30
+ function booleanOf(object, key) {
31
+ const value = lastOf(object, key);
32
+ return value === null ? null : value?.kind === "boolean" ? value.value : undefined;
33
+ }
34
+ /** A manifest's member, `undefined` where it has none. */
35
+ function manifestMember(manifest, key) {
36
+ return typeof manifest === "object" && manifest !== null && !Array.isArray(manifest)
37
+ ? manifest[key]
38
+ : undefined;
39
+ }
40
+ /** The configuration a path names, read where the host holds it. */
41
+ function configurationAt(input, path) {
42
+ const dir = dirnamePath(path);
43
+ return input.configuration(dir, [path.slice(dir.length + 1)]);
44
+ }
45
+ /** Whether a pattern holds a character a glob reads specially. */
46
+ const MAGIC = /[*?[\]{}()!+@]/u;
47
+ /** A glob over the path below `dir`, case compared unless `caseless`. */
48
+ function belowGlob(dir, pattern, caseless = false) {
49
+ const expression = globExpression(pattern.replace(/^(?:\.\/)+/u, ""));
50
+ const tested = caseless ? new RegExp(expression.source, "iu") : expression;
51
+ return {
52
+ dir,
53
+ pattern,
54
+ matches: (fileName) => {
55
+ const below = relativePath(dir, fileName);
56
+ return below !== undefined && below !== "" && tested.test(below);
57
+ },
58
+ };
59
+ }
60
+ /** The glob less every file one of `excludes` names. */
61
+ function less(glob, excludes) {
62
+ return excludes.length === 0
63
+ ? glob
64
+ : { ...glob, matches: (name) => glob.matches(name) && !excludes.some((one) => one(name)) };
65
+ }
66
+ /** The one file a path names. */
67
+ function exactly(cwd, path) {
68
+ const file = resolvePath(cwd, path);
69
+ return { dir: dirnamePath(file), pattern: path, matches: (name) => name === file };
70
+ }
71
+ /** The words after the first one naming one of `programs`, by its name or a path ending in it. */
72
+ function afterProgram(command, programs) {
73
+ const at = command.words.findIndex((word) => word !== undefined && programs.includes(word.slice(word.lastIndexOf("/") + 1)));
74
+ return at < 0 ? undefined : command.words.slice(at + 1);
75
+ }
76
+ /** One command's options and operands, `undefined` where it holds a dynamic word or an option the table does not name. */
77
+ function parsed(words, table) {
78
+ const values = new Map();
79
+ const operands = [];
80
+ const keep = (name, value) => {
81
+ values.set(name, [...(values.get(name) ?? []), value]);
82
+ };
83
+ for (let at = 0; at < words.length; at += 1) {
84
+ const word = words[at];
85
+ if (word === undefined) {
86
+ return undefined;
87
+ }
88
+ if (word === "--") {
89
+ const rest = words.slice(at + 1);
90
+ return rest.every((one) => one !== undefined)
91
+ ? { values, operands: [...operands, ...rest] }
92
+ : undefined;
93
+ }
94
+ if (!word.startsWith("-") || word === "-") {
95
+ operands.push(word);
96
+ continue;
97
+ }
98
+ const equals = word.startsWith("--") ? word.indexOf("=") : -1;
99
+ const name = equals < 0 ? word : word.slice(0, equals);
100
+ if (table.valued.has(name)) {
101
+ const value = equals < 0 ? words[(at += 1)] : word.slice(equals + 1);
102
+ if (value === undefined) {
103
+ return undefined;
104
+ }
105
+ keep(name, value);
106
+ }
107
+ else if (table.flags.has(name)) {
108
+ keep(name, equals < 0 ? "true" : word.slice(equals + 1));
109
+ }
110
+ else {
111
+ return undefined;
112
+ }
113
+ }
114
+ return { values, operands };
115
+ }
116
+ /** Every value one command gives the options `names`, in order. */
117
+ function optionValues(command, ...names) {
118
+ return names.flatMap((name) => command.values.get(name) ?? []);
119
+ }
120
+ /** A table of options by their long names and one-letter aliases, each flag with its `--no-` form. */
121
+ function optionTable(valued, flags, aliases) {
122
+ const named = (name) => [name, ...(aliases[name] ?? [])].map((one) => (one.length === 1 ? `-${one}` : `--${one}`));
123
+ return {
124
+ valued: new Set(valued.flatMap(named)),
125
+ flags: new Set(flags.flatMap((flag) => [...named(flag), `--no-${flag}`])),
126
+ };
127
+ }
128
+ /**
129
+ * Mocha's options, `lib/cli/run-option-metadata` of 10.8 to 12.0: its array, string and number
130
+ * options take a value and its boolean ones none; `--config` and `--package` also take a `--no-`
131
+ * form. A Node option mocha hands on is not named, so a command writing one is not read.
132
+ */
133
+ const MOCHA_OPTIONS = optionTable([
134
+ ...["extension", "file", "global", "ignore", "node-option", "reporter-option", "require"],
135
+ ...["spec", "watch-files", "watch-ignore", "retries", "jobs", "config", "fgrep", "grep"],
136
+ ...["package", "reporter", "ui", "slow", "timeout"],
137
+ ], [
138
+ ...["allow-uncaught", "async-only", "bail", "check-leaks", "clear-screen", "color", "delay"],
139
+ ...["diff", "dry-run", "exit", "fail-hook-affected-tests", "pass-on-failing-test-suite"],
140
+ ...["fail-zero", "forbid-only", "forbid-pending", "full-trace", "inline-diffs", "invert"],
141
+ ...["list-interfaces", "list-reporters", "no-colors", "parallel", "posix-exit-codes"],
142
+ ...["recursive", "sort", "watch", "config", "package"],
143
+ ], {
144
+ "async-only": ["A"],
145
+ bail: ["b"],
146
+ color: ["c", "colors"],
147
+ fgrep: ["f"],
148
+ global: ["globals"],
149
+ grep: ["g"],
150
+ ignore: ["exclude"],
151
+ invert: ["i"],
152
+ jobs: ["j"],
153
+ "no-colors": ["C"],
154
+ "node-option": ["n"],
155
+ parallel: ["p"],
156
+ reporter: ["R"],
157
+ "reporter-option": ["reporter-options", "O"],
158
+ require: ["r"],
159
+ slow: ["s"],
160
+ sort: ["S"],
161
+ timeout: ["t", "timeouts"],
162
+ ui: ["u"],
163
+ watch: ["w"],
164
+ });
165
+ /** The test-file options a mocha configuration object sets, `undefined` where one is not written out. */
166
+ function mochaObject(object) {
167
+ const spec = stringsOf(object, "spec");
168
+ const file = stringsOf(object, "file");
169
+ const ignore = stringsOf(object, "ignore");
170
+ const exclude = stringsOf(object, "exclude");
171
+ const extension = stringsOf(object, "extension");
172
+ const recursive = booleanOf(object, "recursive");
173
+ if ([spec, file, ignore, exclude, extension, recursive].includes(undefined)) {
174
+ return undefined;
175
+ }
176
+ return {
177
+ spec: spec ?? [],
178
+ file: file ?? [],
179
+ ignore: [...(ignore ?? []), ...(exclude ?? [])],
180
+ ...(extension === null || extension === undefined ? {} : { extension }),
181
+ ...(recursive === null || recursive === undefined ? {} : { recursive }),
182
+ };
183
+ }
184
+ /** The test-file options one mocha command line sets. */
185
+ function mochaCommand(command) {
186
+ const recursive = optionValues(command, "--recursive", "--no-recursive");
187
+ const extension = optionValues(command, "--extension");
188
+ return {
189
+ spec: [...command.operands, ...optionValues(command, "--spec")],
190
+ file: optionValues(command, "--file"),
191
+ ignore: optionValues(command, "--ignore", "--exclude"),
192
+ ...(extension.length > 0 ? { extension } : {}),
193
+ ...(command.values.has("--no-recursive")
194
+ ? { recursive: false }
195
+ : recursive.length > 0
196
+ ? { recursive: recursive.at(-1) !== "false" }
197
+ : {}),
198
+ };
199
+ }
200
+ /**
201
+ * The files one mocha spec names, `lib/cli/lookup-files`: an existing file itself, the files of
202
+ * an existing directory with one of `extensions` and a name not starting with `.`, at any depth
203
+ * where `recursive`, a glob as written, and any other path with an extension appended.
204
+ */
205
+ function mochaSpec(host, cwd, spec, extensions, recursive) {
206
+ const path = resolvePath(cwd, spec);
207
+ const braced = `{${extensions.map((one) => one.replace(/^\./u, "")).join(",")}}`;
208
+ const kind = host.kindOf(path);
209
+ if (kind === "file") {
210
+ return exactly(cwd, spec);
211
+ }
212
+ if (kind === "directory") {
213
+ const inner = belowGlob(path, `${recursive ? "**/" : ""}*.${braced}`);
214
+ return {
215
+ ...inner,
216
+ pattern: spec,
217
+ matches: (name) => inner.matches(name) && !name.slice(name.lastIndexOf("/") + 1).startsWith("."),
218
+ };
219
+ }
220
+ return belowGlob(cwd, MAGIC.test(spec) ? spec : `${spec}.${braced}`);
221
+ }
222
+ /**
223
+ * Mocha over the configuration files it looks for, in its order of preference, the nearest at
224
+ * or above the working directory (`lib/cli/config`): one run with no operand, and one per
225
+ * script command naming `mocha` or `_mocha`, its sources merged as `lib/cli/options` merges
226
+ * them. A list each source sets is joined, `extension` replacing the default where any sets
227
+ * it, and the command line, then the file, then the manifest's `mocha` member decides
228
+ * `recursive`; a run with no spec runs `./test`.
229
+ */
230
+ function mochaRunner(configNames) {
231
+ return (input) => {
232
+ const { host, dir, manifest, scripts } = input;
233
+ const nearest = (from) => {
234
+ for (const at of ancestors(from)) {
235
+ const found = input.configuration(at, configNames);
236
+ if (found !== undefined) {
237
+ return found;
238
+ }
239
+ }
240
+ return undefined;
241
+ };
242
+ /**
243
+ * The document `lib/cli/options` `loadPkgRc` reads the `mocha` member of, `undefined` where
244
+ * the run fails: the file the last non-empty `--package` names, failing it where it cannot be
245
+ * read, else the nearest `package.json` at or above `cwd`, none where that cannot be read;
246
+ * either failing it where it does not parse to a document `pkg.mocha` can be read on. `null`
247
+ * for none, or where the last of `--package` and `--no-package` is the latter.
248
+ */
249
+ const packageOf = (cwd, words, command) => {
250
+ const last = words.findLast((word) => word === "--no-package" || word === "--package" || word?.startsWith("--package="));
251
+ if (last === "--no-package") {
252
+ return null;
253
+ }
254
+ const named = optionValues(command, "--package").at(-1);
255
+ const explicit = named !== undefined && named !== "";
256
+ const path = explicit
257
+ ? resolvePath(cwd, named)
258
+ : ancestors(cwd)
259
+ .map((at) => joinPath(at, "package.json"))
260
+ .find((one) => host.kindOf(one) === "file");
261
+ if (path === undefined) {
262
+ return null;
263
+ }
264
+ if (path === joinPath(dir, "package.json")) {
265
+ return manifest;
266
+ }
267
+ const read = readJSONFile(host, path);
268
+ if (read.kind === "unread") {
269
+ return explicit ? undefined : null;
270
+ }
271
+ return read.kind === "malformed" || read.value === null ? undefined : read.value;
272
+ };
273
+ const run = (cwd, words) => {
274
+ const command = parsed(words, MOCHA_OPTIONS);
275
+ if (command === undefined) {
276
+ return [];
277
+ }
278
+ const named = optionValues(command, "--config").at(-1);
279
+ const file = command.values.has("--no-config")
280
+ ? undefined
281
+ : named === undefined
282
+ ? nearest(cwd)
283
+ : configurationAt(input, resolvePath(cwd, named));
284
+ const object = file === undefined ? null : configurationObject(file.module);
285
+ const fromFile = object === null ? null : object === undefined ? undefined : mochaObject(object);
286
+ const pkg = packageOf(cwd, words, command);
287
+ const held = pkg === null || pkg === undefined ? undefined : manifestMember(pkg, "mocha");
288
+ const fromManifest = held === undefined ? null : mochaObject(documentValue(held));
289
+ if (pkg === undefined ||
290
+ (named !== undefined && file === undefined) ||
291
+ fromFile === undefined ||
292
+ fromManifest === undefined) {
293
+ return [];
294
+ }
295
+ const sources = [mochaCommand(command), fromFile ?? [], fromManifest ?? []].flat();
296
+ const spec = sources.flatMap((one) => one.spec);
297
+ const set = sources.flatMap((one) => one.extension ?? []);
298
+ const extensions = set.length > 0 ? [...new Set(set)] : ["js", "cjs", "mjs"];
299
+ const recursive = sources.find((one) => one.recursive !== undefined)?.recursive ?? false;
300
+ const ignored = sources
301
+ .flatMap((one) => one.ignore)
302
+ .map((one) => belowGlob(cwd, one).matches);
303
+ return [
304
+ ...(spec.length > 0 ? spec : ["./test"]).map((one) => less(mochaSpec(host, cwd, one, extensions, recursive), ignored)),
305
+ ...sources.flatMap((one) => one.file).map((one) => exactly(cwd, one)),
306
+ ];
307
+ };
308
+ return [
309
+ ...run(dir, []),
310
+ ...scripts.flatMap((command) => {
311
+ const words = afterProgram(command, ["mocha", "_mocha"]);
312
+ return words === undefined ? [] : run(command.dir, words);
313
+ }),
314
+ ];
315
+ };
316
+ }
317
+ const MOCHARC = [".mocharc.yaml", ".mocharc.yml", ".mocharc.jsonc", ".mocharc.json"];
318
+ /** Mocha 10 and 11, which read no `.mocharc.mjs`. */
319
+ export const MOCHA_10 = mochaRunner([".mocharc.cjs", ".mocharc.js", ...MOCHARC]);
320
+ /** Mocha 12. */
321
+ export const MOCHA_12 = mochaRunner([".mocharc.cjs", ".mocharc.js", ".mocharc.mjs", ...MOCHARC]);
322
+ /** A regular expression a runner writes as text, `undefined` where it is none. */
323
+ function expressionOf(source) {
324
+ try {
325
+ return new RegExp(source, "u");
326
+ }
327
+ catch {
328
+ try {
329
+ return new RegExp(source);
330
+ }
331
+ catch {
332
+ return undefined;
333
+ }
334
+ }
335
+ }
336
+ /** The text `<rootDir>` stands for in one of Jest's paths, `rootDir` itself. */
337
+ function inRoot(text, rootDir) {
338
+ return text.replaceAll("<rootDir>", rootDir);
339
+ }
340
+ /**
341
+ * Jest over the configuration files it looks for in a directory, in its order
342
+ * (jest-config `resolveConfigPath`): one run with no option, and one per script command naming
343
+ * `jest` with its `--config` or `-c` file. A configuration's own file, else its `package.json`
344
+ * member `jest`, else the defaults, configure a directory; two of them configure none.
345
+ */
346
+ function jestRunner(configNames, defaults) {
347
+ return (input) => {
348
+ const { host, dir, scripts } = input;
349
+ const directory = (at, depth) => {
350
+ const file = input.configuration(at, configNames);
351
+ const manifestPath = joinPath(at, "package.json");
352
+ const manifest = host.kindOf(manifestPath) === "file" ? readJSON(host, manifestPath) : undefined;
353
+ const held = manifestMember(manifest, "jest");
354
+ if (file !== undefined && held !== undefined) {
355
+ return [];
356
+ }
357
+ if (file !== undefined) {
358
+ return configured(file, depth);
359
+ }
360
+ if (typeof held === "string") {
361
+ const named = configurationAt(input, resolvePath(at, held));
362
+ return named === undefined ? [] : configured(named, depth);
363
+ }
364
+ return manifest === undefined && held === undefined
365
+ ? []
366
+ : project(held === undefined
367
+ ? { kind: "object", members: [], at: undefined }
368
+ : documentValue(held), at, depth);
369
+ };
370
+ const configured = (file, depth) => {
371
+ const object = configurationObject(file.module);
372
+ return object === undefined ? [] : project(object, file.dir, depth);
373
+ };
374
+ const project = (object, base, depth) => {
375
+ const rootValue = lastOf(object, "rootDir");
376
+ const rootDir = rootValue === null
377
+ ? base
378
+ : rootValue?.kind === "text"
379
+ ? resolvePath(base, inRoot(rootValue.text, base))
380
+ : undefined;
381
+ if (rootDir === undefined) {
382
+ return [];
383
+ }
384
+ const projects = lastOf(object, "projects");
385
+ if (projects === undefined || (projects !== null && projects.kind !== "array")) {
386
+ return [];
387
+ }
388
+ if (projects !== null && projects.elements.length > 0) {
389
+ return depth > 4
390
+ ? []
391
+ : projects.elements.flatMap((one) => one.kind === "object"
392
+ ? project(one, rootDir, depth + 1)
393
+ : one.kind === "text"
394
+ ? projectDirectories(host, inRoot(one.text, rootDir), rootDir).flatMap((at) => host.kindOf(at) === "file"
395
+ ? [configurationAt(input, at) ?? []]
396
+ .flat()
397
+ .flatMap((named) => configured(named, depth + 1))
398
+ : directory(at, depth + 1))
399
+ : []);
400
+ }
401
+ return testsOf(object, rootDir, defaults);
402
+ };
403
+ const named = scripts.flatMap((command) => {
404
+ const words = afterProgram(command, ["jest"]);
405
+ const at = words?.findIndex((word) => word === "--config" || word === "-c") ?? -1;
406
+ const written = words?.find((word) => word?.startsWith("--config=") === true)?.slice("--config=".length) ??
407
+ (at < 0 ? undefined : words?.[at + 1]);
408
+ return written === undefined ? [] : [resolvePath(command.dir, written)];
409
+ });
410
+ return [
411
+ ...directory(dir, 0),
412
+ ...named.flatMap((path) => host.kindOf(path) === "directory"
413
+ ? directory(path, 0)
414
+ : [configurationAt(input, path) ?? []].flat().flatMap((file) => configured(file, 0))),
415
+ ];
416
+ };
417
+ }
418
+ /**
419
+ * The paths one Jest `projects` string names: itself, or, where it is a glob, every
420
+ * directory and file its segments match below the directories the earlier ones name.
421
+ */
422
+ function projectDirectories(host, written, rootDir) {
423
+ const path = resolvePath(rootDir, written);
424
+ if (!MAGIC.test(path)) {
425
+ return [path];
426
+ }
427
+ let found = ["/"];
428
+ for (const segment of path.split("/").filter((one) => one !== "")) {
429
+ if (!MAGIC.test(segment)) {
430
+ found = found
431
+ .map((one) => joinPath(one, segment))
432
+ .filter((one) => host.kindOf(one) !== "absent");
433
+ continue;
434
+ }
435
+ const expression = globExpression(segment);
436
+ found = found.flatMap((one) => host.kindOf(one) === "directory"
437
+ ? host
438
+ .readDirectory(one)
439
+ .filter((entry) => expression.test(entry.name))
440
+ .map((entry) => joinPath(one, entry.name))
441
+ : []);
442
+ }
443
+ return found;
444
+ }
445
+ /**
446
+ * The tests one Jest project runs: files below each of its `roots` with one of its
447
+ * `moduleFileExtensions`, the only files jest-haste-map lists, that a `testMatch` glob, or a
448
+ * `testRegex` expression, matches over the whole path, and no `testPathIgnorePatterns`
449
+ * expression does. A project writing both `testMatch` and `testRegex` runs none.
450
+ */
451
+ function testsOf(object, rootDir, defaults) {
452
+ const roots = stringsOf(object, "roots");
453
+ const match = stringsOf(object, "testMatch");
454
+ const regex = stringsOf(object, "testRegex");
455
+ const ignore = stringsOf(object, "testPathIgnorePatterns");
456
+ const extensions = stringsOf(object, "moduleFileExtensions");
457
+ if (roots === undefined ||
458
+ match === undefined ||
459
+ regex === undefined ||
460
+ ignore === undefined ||
461
+ extensions === undefined) {
462
+ return [];
463
+ }
464
+ const listed = (extensions ?? defaults.moduleFileExtensions).map((one) => `.${one}`);
465
+ const ignored = (ignore ?? ["/node_modules/"]).map((one) => expressionOf(inRoot(one, rootDir)));
466
+ if (ignored.includes(undefined) || ((match ?? []).length > 0 && (regex ?? []).length > 0)) {
467
+ return [];
468
+ }
469
+ const tests = (regex ?? []).length > 0
470
+ ? (regex ?? []).flatMap((one) => {
471
+ const expression = expressionOf(one);
472
+ return expression === undefined
473
+ ? []
474
+ : [{ pattern: one, test: (path) => expression.test(path) }];
475
+ })
476
+ : match !== null
477
+ ? jestGlobs(match, rootDir)
478
+ : defaults.testMatch.map((expression) => ({
479
+ pattern: expression.source,
480
+ test: (path) => expression.test(path),
481
+ }));
482
+ return (roots ?? ["<rootDir>"]).flatMap((root) => {
483
+ const at = resolvePath(rootDir, inRoot(root, rootDir));
484
+ return tests.map(({ pattern, test }) => ({
485
+ dir: at,
486
+ pattern,
487
+ matches: (name) => relativePath(at, name) !== undefined &&
488
+ listed.some((extension) => name.endsWith(extension)) &&
489
+ test(name) &&
490
+ !ignored.some((expression) => expression?.test(name) === true),
491
+ }));
492
+ });
493
+ }
494
+ /** Jest's `testMatch` globs over the whole path, a `!` glob leaving out what it matches. */
495
+ function jestGlobs(globs, rootDir) {
496
+ const expression = (glob) => globExpression(inRoot(glob, rootDir).replace(/^\/+/u, ""));
497
+ const excluded = globs
498
+ .filter((one) => one.startsWith("!"))
499
+ .map((one) => expression(one.slice(1)));
500
+ return globs
501
+ .filter((one) => !one.startsWith("!"))
502
+ .map((glob) => {
503
+ const included = expression(glob);
504
+ return {
505
+ pattern: glob,
506
+ test: (path) => {
507
+ const bare = path.replace(/^\/+/u, "");
508
+ return included.test(bare) && !excluded.some((one) => one.test(bare));
509
+ },
510
+ };
511
+ });
512
+ }
513
+ /** Jest 29, which reads no `.mts` or `.cts` configuration and by default runs no `.mjs`, `.cjs`, `.mts` or `.cts` test. */
514
+ export const JEST_29 = jestRunner(["jest.config.js", "jest.config.ts", "jest.config.mjs", "jest.config.cjs", "jest.config.json"], {
515
+ testMatch: [
516
+ /\/__tests__\/(?:[^/]+\/)*[^/]*\.[jt]sx?$/u,
517
+ /\/(?:[^/]*\.)?(?:spec|test)+\.[jt]sx?$/u,
518
+ ],
519
+ moduleFileExtensions: ["js", "mjs", "cjs", "jsx", "ts", "tsx", "json", "node"],
520
+ });
521
+ /** Jest 30. */
522
+ export const JEST_30 = jestRunner([
523
+ "jest.config.js",
524
+ "jest.config.ts",
525
+ "jest.config.mjs",
526
+ "jest.config.mts",
527
+ "jest.config.cjs",
528
+ "jest.config.cts",
529
+ "jest.config.json",
530
+ ], {
531
+ testMatch: [
532
+ /\/__tests__\/(?:[^/]+\/)*[^/]*\.[mc]?[jt]sx?$/u,
533
+ /\/(?:[^/]*\.)?(?:spec|test)+\.[mc]?[jt]sx?$/u,
534
+ ],
535
+ moduleFileExtensions: ["js", "mjs", "cjs", "jsx", "ts", "mts", "cts", "tsx", "json", "node"],
536
+ });
537
+ /** The directories AVA leaves out, `ignore-by-default` 2.1 with `node_modules`. */
538
+ const AVA_IGNORED = /(?:^|\/)(?:\.git|\.log|\.nyc_output|\.sass-cache|\.yarn|bower_components|coverage|node_modules)\//u;
539
+ /** AVA's default exclusions (`lib/globs`), over the path below the project directory. */
540
+ const AVA_HELPERS = [
541
+ /(?:^|\/)__tests__\/(?:.*\/)?__(?:helper|fixture)s?__\//iu,
542
+ /(?:^|\/)tests?\/(?:.*\/)?(?:helper|fixture)s?\//iu,
543
+ ];
544
+ /** The extensions an AVA configuration's `extensions` names, an array or an object's keys. */
545
+ function avaExtensions(object) {
546
+ const value = lastOf(object, "extensions");
547
+ if (value === null || value === undefined) {
548
+ return value;
549
+ }
550
+ if (value.kind === "object") {
551
+ return value.members.every((member) => member.key !== undefined)
552
+ ? value.members.flatMap((member) => member.key ?? [])
553
+ : undefined;
554
+ }
555
+ return textsOf(value, true);
556
+ }
557
+ /**
558
+ * AVA over the first configuration file of the nearest directory holding one, up to the
559
+ * repository's, or the manifest's `ava` member; both, or a function, configure nothing
560
+ * (`lib/load-config`). Its tests match its `files` globs below the manifest's directory without
561
+ * regard to case, a list of exclusions only joining the defaults (`lib/globs`), with one of its
562
+ * extensions, in no directory AVA ignores and named without a leading `_`. Its command line
563
+ * only filters these, so none is read.
564
+ */
565
+ function avaRunner(configNames, defaults) {
566
+ return (input) => {
567
+ const { host, dir, manifest } = input;
568
+ let file;
569
+ for (const at of ancestors(dir)) {
570
+ file = input.configuration(at, configNames);
571
+ if (file !== undefined || host.kindOf(joinPath(at, ".git")) !== "absent") {
572
+ break;
573
+ }
574
+ }
575
+ const held = manifestMember(manifest, "ava");
576
+ if (file !== undefined && held !== undefined) {
577
+ return [];
578
+ }
579
+ const object = file === undefined
580
+ ? held === undefined
581
+ ? { kind: "object", members: [], at: undefined }
582
+ : documentValue(held)
583
+ : configurationObject(file.module);
584
+ const files = object === undefined ? undefined : stringsOf(object, "files");
585
+ const extensions = object === undefined ? undefined : avaExtensions(object);
586
+ if (files === undefined || extensions === undefined || files?.length === 0) {
587
+ return [];
588
+ }
589
+ const pattern = `{${(extensions ?? defaults).join(",")}}`;
590
+ const written = files === null || files.every((one) => one.startsWith("!"))
591
+ ? [
592
+ `test.${pattern}`,
593
+ `{src,source}/test.${pattern}`,
594
+ `**/__tests__/**/*.${pattern}`,
595
+ `**/*.spec.${pattern}`,
596
+ `**/*.test.${pattern}`,
597
+ `**/test-*.${pattern}`,
598
+ `**/test/**/*.${pattern}`,
599
+ `**/tests/**/*.${pattern}`,
600
+ ...(files ?? []),
601
+ ]
602
+ : files;
603
+ const excluded = [
604
+ ...written
605
+ .filter((one) => one.startsWith("!"))
606
+ .map((one) => belowGlob(dir, one.slice(1), true).matches),
607
+ ...(files === null || files.every((one) => one.startsWith("!"))
608
+ ? AVA_HELPERS.map((expression) => (name) => expression.test(relativePath(dir, name) ?? ""))
609
+ : []),
610
+ ];
611
+ const kept = new RegExp(`\\.(?:${(extensions ?? defaults).map((one) => one.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&")).join("|")})$`, "u");
612
+ return written
613
+ .filter((one) => !one.startsWith("!"))
614
+ .map((one) => {
615
+ const glob = less(belowGlob(dir, one, true), excluded);
616
+ return {
617
+ ...glob,
618
+ matches: (name) => {
619
+ const below = relativePath(dir, name) ?? "";
620
+ return (glob.matches(name) &&
621
+ kept.test(name) &&
622
+ !AVA_IGNORED.test(below) &&
623
+ !below.split("/").some((segment) => segment.startsWith(".")) &&
624
+ !name.slice(name.lastIndexOf("/") + 1).startsWith("_"));
625
+ },
626
+ };
627
+ });
628
+ };
629
+ }
630
+ const AVA_CONFIG = ["ava.config.js", "ava.config.cjs", "ava.config.mjs"];
631
+ /** AVA 6 and 7. */
632
+ export const AVA_6 = avaRunner(AVA_CONFIG, ["cjs", "mjs", "js"]);
633
+ /** AVA 8, which reads no `ava.config.cjs` and defaults to no `.cjs` test. */
634
+ export const AVA_8 = avaRunner(["ava.config.js", "ava.config.mjs"], ["mjs", "js"]);
635
+ /** The patterns `node --test` runs with no operand (`doc/api/test.md`), the TypeScript ones where types are stripped. */
636
+ function nodeTestDefaults(stripped) {
637
+ const forms = ["**/*.test", "**/*-test", "**/*_test", "**/test-*", "**/test", "**/test/**/*"];
638
+ return [
639
+ ...forms.map((one) => `${one}.{cjs,mjs,js}`),
640
+ ...(stripped ? forms.map((one) => `${one}.{cts,mts,ts}`) : []),
641
+ ];
642
+ }
643
+ /**
644
+ * The files each `node --test` run of a manifest's scripts runs, as the command reader reads
645
+ * it: its operands, each a glob read in the command's directory, or the default patterns where
646
+ * it writes none.
647
+ */
648
+ export function nodeTestGlobs(runs) {
649
+ return runs.flatMap((run) => (run.patterns.length > 0 ? run.patterns : nodeTestDefaults(run.stripped)).map((one) => belowGlob(run.dir, one)));
650
+ }