@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
@@ -1,123 +0,0 @@
1
- /**
2
- * The exemption classes of the Contract's vocabulary, in its order: each class's name, its
3
- * languages and, for a TypeScript class, which private members it may retain. The rows are
4
- * written out, as the fixed severity codes are, and a test holds them equal to the Contract.
5
- * A class name is a type, so a table or a record naming a class outside the vocabulary, or
6
- * one of another language only, does not compile.
7
- */
8
-
9
- import type { Language } from "./config.ts";
10
-
11
- /**
12
- * Whether a class may retain a member declared with the `private` modifier, and one
13
- * declared with a `#private` name. The modifier is a compile-time constraint only, so
14
- * such a member stays reachable by its name at run time; a private name cannot be
15
- * named from outside its class body at all.
16
- */
17
- export interface TypeScriptVisibility {
18
- readonly private: boolean;
19
- readonly privateName: boolean;
20
- }
21
-
22
- /** One class of the vocabulary. */
23
- interface ExemptionClassRow {
24
- readonly class: string;
25
- readonly languages: readonly Language[];
26
- /** Present exactly on a class that runs on TypeScript. */
27
- readonly typescriptVisibility?: TypeScriptVisibility;
28
- }
29
-
30
- /** Every class of the vocabulary, in the order the Contract lists them. */
31
- export const EXEMPTION_CLASSES = [
32
- {
33
- class: "interface-satisfaction",
34
- languages: ["go", "ts"],
35
- typescriptVisibility: { private: false, privateName: false },
36
- },
37
- { class: "encoding-reflection", languages: ["go"] },
38
- { class: "format-verb-contract", languages: ["go"] },
39
- { class: "errors-duck-typing", languages: ["go"] },
40
- {
41
- class: "enum-group",
42
- languages: ["go", "ts"],
43
- typescriptVisibility: { private: false, privateName: false },
44
- },
45
- {
46
- class: "generated-file",
47
- languages: ["go", "ts"],
48
- typescriptVisibility: { private: true, privateName: false },
49
- },
50
- { class: "linkname-cgo-asm-plugin", languages: ["go"] },
51
- {
52
- class: "template-field",
53
- languages: ["go", "ts"],
54
- typescriptVisibility: { private: true, privateName: false },
55
- },
56
- {
57
- class: "reflective-lookup",
58
- languages: ["go", "ts"],
59
- typescriptVisibility: { private: true, privateName: false },
60
- },
61
- {
62
- class: "decorator",
63
- languages: ["ts"],
64
- typescriptVisibility: { private: true, privateName: false },
65
- },
66
- {
67
- class: "injection-container",
68
- languages: ["ts"],
69
- typescriptVisibility: { private: true, privateName: false },
70
- },
71
- {
72
- class: "framework-lifecycle",
73
- languages: ["ts"],
74
- typescriptVisibility: { private: true, privateName: false },
75
- },
76
- {
77
- class: "serialization-contract",
78
- languages: ["ts"],
79
- typescriptVisibility: { private: true, privateName: false },
80
- },
81
- ] as const satisfies readonly ExemptionClassRow[];
82
-
83
- type Row = (typeof EXEMPTION_CLASSES)[number];
84
-
85
- /** The name of a class of the vocabulary. */
86
- export type ExemptionClass = Row["class"];
87
-
88
- /** The classes of the rows that list one language. */
89
- type ClassesOf<R, L extends Language> = R extends {
90
- readonly class: infer C;
91
- readonly languages: readonly (infer Listed)[];
92
- }
93
- ? L extends Listed
94
- ? C
95
- : never
96
- : never;
97
-
98
- /** The name of a class that runs on TypeScript, the only classes this analyzer records. */
99
- export type TSExemptionClass = ClassesOf<Row, "ts">;
100
-
101
- function runsOnTS(row: Row): row is Extract<Row, { readonly class: TSExemptionClass }> {
102
- const languages: readonly Language[] = row.languages;
103
- return languages.includes("ts");
104
- }
105
-
106
- const TS_ROWS = EXEMPTION_CLASSES.filter(runsOnTS);
107
-
108
- /** The classes that run on TypeScript, in the vocabulary's order. */
109
- export const TS_EXEMPTION_CLASSES: readonly TSExemptionClass[] = TS_ROWS.map((row) => row.class);
110
-
111
- const VISIBILITY: ReadonlyMap<TSExemptionClass, TypeScriptVisibility> = new Map(
112
- TS_ROWS.map((row) => [row.class, row.typescriptVisibility]),
113
- );
114
-
115
- /** Which private members one class that runs on TypeScript may retain. */
116
- export function typescriptVisibilityOf(exemptionClass: TSExemptionClass): TypeScriptVisibility {
117
- return VISIBILITY.get(exemptionClass) ?? { private: false, privateName: false };
118
- }
119
-
120
- /** Whether one name is a class of the vocabulary, whichever language it runs on. */
121
- export function isExemptionClass(name: string): name is ExemptionClass {
122
- return EXEMPTION_CLASSES.some((row) => row.class === name);
123
- }
package/src/exempt.ts DELETED
@@ -1,323 +0,0 @@
1
- /**
2
- * The exemption framework: the classes of reason for which a declaration the reference
3
- * graph alone would report is live all the same. A class is policy over what one
4
- * project's checker answers, and its detector names the declarations it holds back;
5
- * this module runs the detectors, decides which of their records stand, and answers
6
- * which records held something back. It names no class's detector: the composition
7
- * hands it the table of the classes it has.
8
- */
9
-
10
- import type { Config, TSSection } from "./config.ts";
11
- import { ConfigError } from "./config.ts";
12
- import {
13
- EXEMPTION_CLASSES,
14
- isExemptionClass,
15
- TS_EXEMPTION_CLASSES,
16
- typescriptVisibilityOf,
17
- type ExemptionClass,
18
- type TSExemptionClass,
19
- type TypeScriptVisibility,
20
- } from "./exempt-classes.ts";
21
- import type { Inventory, InventorySymbol, SymbolKind, Visibility } from "./inventory.ts";
22
- import type { Matrix } from "./matrix.ts";
23
- import { byPosition, positionKey, type Position } from "./position.ts";
24
- import { Unanswerable } from "./query.ts";
25
- import type { ProjectView } from "./session.ts";
26
- import type { Templates } from "./template-field.ts";
27
- import { sweep, type Exemption, type Implementing, type Mode, type SweepInput } from "./sweep.ts";
28
-
29
- /** One declaration a detector holds back, and where and why. */
30
- export interface Evidence {
31
- /** The identifier of the declaration held back. */
32
- readonly id: string;
33
- /** One clause naming the relation, then the thing it relates to. */
34
- readonly detail: string;
35
- readonly site: Position;
36
- /** The component file, below the target root, whose markup holds the evidence. */
37
- readonly whileLive?: string;
38
- /** Where the evidence is an implementation of interface methods, which and how. */
39
- readonly implementing?: Implementing;
40
- }
41
-
42
- /** What a detector reads of one project, while the project's view is open. */
43
- export interface DetectorInput<Brand> {
44
- readonly project: ProjectView<Brand>;
45
- readonly held: Inventory;
46
- readonly targetRoot: string;
47
- /** The configured templates, read once for the run. */
48
- readonly templates: Templates;
49
- /** The `ts` section, whose declarations the configured classes read. */
50
- readonly ts: TSSection;
51
- /** The absolute path of each declared consumer, whose modules are part of the analysis. */
52
- readonly consumers: readonly string[];
53
- /** The project's generated files, by path below the target root, each with the detail its retentions name. */
54
- readonly generated?: ReadonlyMap<string, string>;
55
- }
56
-
57
- /**
58
- * One class's detection over one project. The framework records each piece of evidence
59
- * under the class the table names the detector by, so a detector names no class.
60
- */
61
- export type Detector = <Brand>(input: DetectorInput<Brand>) => readonly Evidence[];
62
-
63
- /** The detector of each class one composition implements. */
64
- export type Detectors = ReadonlyMap<TSExemptionClass, Detector>;
65
-
66
- /** What decides which records of one project stand. */
67
- interface Holding {
68
- readonly mode: Mode;
69
- /** The paths the reference pass classified as test files. */
70
- readonly testFiles: ReadonlySet<string>;
71
- }
72
-
73
- /**
74
- * The classes `exemptions.disabled` switches off. A name is refused unless the
75
- * vocabulary holds it; a class that runs on another language only is admitted and
76
- * switches nothing off here, so one configuration serves every analyzer.
77
- */
78
- export function disabledClasses(config: Config): ReadonlySet<ExemptionClass> {
79
- const disabled = new Set<ExemptionClass>();
80
- for (const name of config.exemptionsDisabled) {
81
- if (!isExemptionClass(name)) {
82
- const known = EXEMPTION_CLASSES.map((row) => row.class).join(", ");
83
- throw new ConfigError(
84
- "malformed",
85
- "exemptions.disabled",
86
- `exemptions.disabled: ${JSON.stringify(name)} is not an exemption class: the classes are ${known}`,
87
- );
88
- }
89
- disabled.add(name);
90
- }
91
- return disabled;
92
- }
93
-
94
- /**
95
- * Whether a class whose row states `allowed` may retain a member of one visibility. A
96
- * declaration the inventory does not hold has no visibility to refuse it by.
97
- */
98
- function retainable(allowed: TypeScriptVisibility, visibility: Visibility | undefined): boolean {
99
- if (visibility === "private") {
100
- return allowed.private;
101
- }
102
- if (visibility === "private-name") {
103
- return allowed.privateName;
104
- }
105
- return true;
106
- }
107
-
108
- /**
109
- * The kinds of declaration each class can hold back, which a detector that stops holds
110
- * back whole. A class with no row here holds back every declaration but a file.
111
- */
112
- const RETAINABLE: ReadonlyMap<TSExemptionClass, ReadonlySet<SymbolKind>> = new Map([
113
- ["interface-satisfaction", new Set<SymbolKind>(["method", "class-member"])],
114
- ["enum-group", new Set<SymbolKind>(["enum-member"])],
115
- ["injection-container", new Set<SymbolKind>(["method", "class-member"])],
116
- ["framework-lifecycle", new Set<SymbolKind>(["method", "class-member"])],
117
- [
118
- "serialization-contract",
119
- new Set<SymbolKind>(["method", "class-member", "interface-method", "type-member"]),
120
- ],
121
- ]);
122
-
123
- /** The detail of a record a detector that could not finish holds. */
124
- const UNANSWERED_DETAIL = "kept live by a question the checker did not answer";
125
-
126
- /** Whether one record is held by a detector that could not finish. */
127
- export function isUnansweredRecord(record: Exemption): boolean {
128
- return record.detail === UNANSWERED_DETAIL;
129
- }
130
-
131
- /**
132
- * What one detector holds back over one project. A detector that stops because the
133
- * checker left a question it needs unanswered holds back every declaration of the
134
- * project its class could hold back, each recorded at its own position, so the gap
135
- * never yields a finding.
136
- */
137
- function detected<Brand>(
138
- exemptionClass: TSExemptionClass,
139
- detect: Detector,
140
- input: DetectorInput<Brand>,
141
- ): readonly Evidence[] {
142
- try {
143
- return detect(input);
144
- } catch (error: unknown) {
145
- if (!(error instanceof Unanswerable)) {
146
- throw error;
147
- }
148
- const kinds = RETAINABLE.get(exemptionClass);
149
- return input.held.symbols
150
- .filter((symbol) => (kinds === undefined ? symbol.kind !== "file" : kinds.has(symbol.kind)))
151
- .map((symbol) => ({ id: symbol.id, detail: UNANSWERED_DETAIL, site: symbol.position }));
152
- }
153
- }
154
-
155
- /** One project's records, and the evidence a production mode found in a test file. */
156
- interface Detected {
157
- readonly records: readonly Exemption[];
158
- /**
159
- * Under a production mode, each record whose evidence is written in a test file. It
160
- * holds nothing, and it is a test reference to its declaration, as a reference the
161
- * test file wrote would be.
162
- */
163
- readonly inTestFiles: readonly Exemption[];
164
- }
165
-
166
- /**
167
- * Every record one project's detectors found, one per piece of evidence, before the
168
- * mode decides which of them hold: what {@link heldRecords} reads. Classes run in the
169
- * vocabulary's order and a switched-off class runs not at all; evidence on a private
170
- * member the class's row says it cannot retain is dropped, whatever the detector found.
171
- */
172
- export function evidenceRecords<Brand>(
173
- input: DetectorInput<Brand>,
174
- detectors: Detectors,
175
- disabled: ReadonlySet<ExemptionClass>,
176
- ): readonly Exemption[] {
177
- const visibility = new Map(input.held.symbols.map((symbol) => [symbol.id, symbol.visibility]));
178
- const found: Exemption[] = [];
179
- for (const exemptionClass of TS_EXEMPTION_CLASSES) {
180
- const detect = detectors.get(exemptionClass);
181
- if (detect === undefined || disabled.has(exemptionClass)) {
182
- continue;
183
- }
184
- const allowed = typescriptVisibilityOf(exemptionClass);
185
- for (const evidence of detected(exemptionClass, detect, input)) {
186
- if (!retainable(allowed, visibility.get(evidence.id))) {
187
- continue;
188
- }
189
- found.push({
190
- id: evidence.id,
191
- class: exemptionClass,
192
- detail: evidence.detail,
193
- site: evidence.site,
194
- ...(evidence.whileLive === undefined ? {} : { whileLive: evidence.whileLive }),
195
- ...(evidence.implementing === undefined ? {} : { implementing: evidence.implementing }),
196
- });
197
- }
198
- }
199
- return found;
200
- }
201
-
202
- /** The records that hold under one mode, beside the evidence a production mode found in a test file. */
203
- export function heldRecords(records: readonly Exemption[], holding: Holding): Detected {
204
- const found: Exemption[] = [];
205
- const inTestFiles: Exemption[] = [];
206
- for (const record of records) {
207
- if (holding.mode.production && holding.testFiles.has(record.site.path)) {
208
- inTestFiles.push(record);
209
- } else {
210
- found.push(record);
211
- }
212
- }
213
- return { records: exemptionsOf(found), inTestFiles };
214
- }
215
-
216
- /** Two strings ordered bytewise. */
217
- function compare(a: string, b: string): number {
218
- if (a === b) {
219
- return 0;
220
- }
221
- return a < b ? -1 : 1;
222
- }
223
-
224
- /**
225
- * Records as a run holds them: ordered by site, then class, then declaration, and one
226
- * per declaration, class, detail and file it holds while live, the one at the first
227
- * site. A fact found at many sites, or by several projects, is one record.
228
- */
229
- export function exemptionsOf(found: readonly Exemption[]): readonly Exemption[] {
230
- const ordered = [...found].sort(
231
- (a, b) => byPosition(a.site, b.site) || compare(a.class, b.class) || compare(a.id, b.id),
232
- );
233
- const seen = new Set<string>();
234
- return ordered.filter((record) => {
235
- const fact = [record.id, record.class, record.detail, record.whileLive ?? ""].join("\u0000");
236
- if (seen.has(fact)) {
237
- return false;
238
- }
239
- seen.add(fact);
240
- return true;
241
- });
242
- }
243
-
244
- /**
245
- * The records that hold while the component files at `live` are live: every record that
246
- * holds whatever is live, and each one a live file's markup holds, as a record of the run.
247
- */
248
- export function holdingWhile(
249
- records: readonly Exemption[],
250
- live: ReadonlySet<string>,
251
- ): readonly Exemption[] {
252
- return exemptionsOf(
253
- records.flatMap(({ whileLive, ...record }) =>
254
- whileLive === undefined || live.has(whileLive) ? [record] : [],
255
- ),
256
- );
257
- }
258
-
259
- /** The records per declaration, each declaration's in the order given. */
260
- function byDeclaration(records: readonly Exemption[]): ReadonlyMap<string, readonly Exemption[]> {
261
- const grouped = new Map<string, Exemption[]>();
262
- for (const record of records) {
263
- const held = grouped.get(record.id);
264
- if (held === undefined) {
265
- grouped.set(record.id, [record]);
266
- } else {
267
- held.push(record);
268
- }
269
- }
270
- return grouped;
271
- }
272
-
273
- /**
274
- * The records that held back a declaration: one some configuration's graph, swept
275
- * again with no exemption and its marks, judges a candidate, whatever another
276
- * configuration answers, or one in `writeOnly`, which the run would report as written
277
- * and never read without the record's read. A declaration a relation or a mark holds
278
- * live in every configuration is held back by no record. The order is the
279
- * declarations' site order, and for one declaration the input's.
280
- */
281
- export function retainedIn(
282
- matrix: Matrix,
283
- input: SweepInput,
284
- writeOnly: ReadonlySet<string> = new Set(),
285
- ): readonly Exemption[] {
286
- const exempt = input.exempt ?? [];
287
- if (exempt.length === 0) {
288
- return [];
289
- }
290
- const bare: SweepInput = { marked: input.marked, mode: input.mode };
291
- const dead = new Set(
292
- matrix.graphs.flatMap((graph) =>
293
- sweep(graph, bare).candidates.map((candidate) => candidate.id),
294
- ),
295
- );
296
- const held = byDeclaration(
297
- exempt.filter((record) => dead.has(record.id) || writeOnly.has(record.id)),
298
- );
299
- return matrix.union.symbols.flatMap((symbol) => held.get(symbol.id) ?? []);
300
- }
301
-
302
- /**
303
- * One line per held-back declaration, in site order: its reference, then each record's
304
- * class, site and detail, all separated by tabs.
305
- */
306
- export function retainedLines(
307
- symbols: readonly InventorySymbol[],
308
- retained: readonly Exemption[],
309
- ): readonly string[] {
310
- const held = byDeclaration(retained);
311
- return symbols.flatMap((symbol) => {
312
- const records = held.get(symbol.id);
313
- if (records === undefined) {
314
- return [];
315
- }
316
- const fields = records.flatMap((record) => [
317
- record.class,
318
- positionKey(record.site),
319
- record.detail,
320
- ]);
321
- return [[symbol.ref, ...fields].join("\t")];
322
- });
323
- }
@@ -1,111 +0,0 @@
1
- /**
2
- * The generated-file class on TypeScript: every declaration in a file that marks itself
3
- * generated, or below a directory an applied convention row names as generated, is
4
- * retained, because a generator owns the file and a deletion there is undone at the next
5
- * generation.
6
- */
7
-
8
- import type { DetectorInput, Evidence } from "./exempt.ts";
9
- import type { SourceFiles } from "./source-files.ts";
10
-
11
- /** The generated-code header, matched against each line of a leading comment. */
12
- const HEADER_LINE = /^\/\/ Code generated .* DO NOT EDIT\.$/u;
13
-
14
- /** The documentation tag `@generated` as a word of a comment. */
15
- const GENERATED_TAG = /(?<![\w@$])@generated(?![\w$-])/u;
16
-
17
- /** A first comment naming the tool that wrote the file. */
18
- const GENERATED_BY = /^\/\/ Generated by \S/u;
19
-
20
- /** The word a generator's notice holds, beside one of {@link KEEP_OUT}. */
21
- const GENERATED_WORD = /\bgenerated\b/iu;
22
-
23
- /** The phrases a generator's notice asks a reader not to edit the file by. */
24
- const KEEP_OUT = /\b(?:do not edit|will be overwritten|should not make any changes)\b/iu;
25
-
26
- /** The comments before a text's first token, a leading hashbang line skipped. */
27
- function leadingComments(text: string): readonly string[] {
28
- const comments: string[] = [];
29
- let at = text.startsWith("\uFEFF") ? 1 : 0;
30
- if (text.startsWith("#!", at)) {
31
- const end = text.indexOf("\n", at);
32
- at = end === -1 ? text.length : end + 1;
33
- }
34
- for (;;) {
35
- while (at < text.length && /\s/u.test(text.charAt(at))) {
36
- at++;
37
- }
38
- if (text.startsWith("//", at)) {
39
- const end = text.slice(at).search(/[\r\n\u2028\u2029]/u);
40
- const stop = end === -1 ? text.length : at + end;
41
- comments.push(text.slice(at, stop));
42
- at = stop;
43
- } else if (text.startsWith("/*", at)) {
44
- const end = text.indexOf("*/", at + 2);
45
- if (end === -1) {
46
- return comments;
47
- }
48
- comments.push(text.slice(at, end + 2));
49
- at = end + 2;
50
- } else {
51
- return comments;
52
- }
53
- }
54
- }
55
-
56
- /** The detail a file's leading comments mark it generated by, or undefined where they mark nothing. */
57
- export function generatedByComment(text: string): string | undefined {
58
- const comments = leadingComments(text);
59
- if (comments.some((one) => one.split(/\r?\n/u).some((line) => HEADER_LINE.test(line)))) {
60
- return "generated by the header line its leading comments hold";
61
- }
62
- if (comments.some((one) => GENERATED_TAG.test(one))) {
63
- return "generated by the @generated tag its leading comments hold";
64
- }
65
- const notice = comments.join("\n");
66
- if (
67
- GENERATED_BY.test(comments[0] ?? "") ||
68
- (GENERATED_WORD.test(notice) && KEEP_OUT.test(notice))
69
- ) {
70
- return "generated by the notice its leading comments hold";
71
- }
72
- return undefined;
73
- }
74
-
75
- /**
76
- * Every own file of one project that is generated, by its path below the target root,
77
- * with the detail a retention in it names: its leading comments' mark, else the row
78
- * naming its directory as generated.
79
- */
80
- export function generatedFilesOf(
81
- files: SourceFiles,
82
- byRow: ReadonlyMap<string, string>,
83
- ): ReadonlyMap<string, string> {
84
- const found = new Map<string, string>();
85
- for (const [path, file] of files.byPath) {
86
- const row = byRow.get(path);
87
- const detail =
88
- generatedByComment(file.text) ??
89
- (row === undefined
90
- ? undefined
91
- : `generated below a directory the convention row ${row} names`);
92
- if (detail !== undefined) {
93
- found.set(path, detail);
94
- }
95
- }
96
- return found;
97
- }
98
-
99
- /** The generated-file detector, recording each file's first line. */
100
- export function generatedFile<Brand>(input: DetectorInput<Brand>): readonly Evidence[] {
101
- const generated = input.generated;
102
- if (generated === undefined || generated.size === 0) {
103
- return [];
104
- }
105
- return input.held.symbols.flatMap((symbol): Evidence[] => {
106
- const detail = generated.get(symbol.position.path);
107
- return symbol.kind === "file" || detail === undefined
108
- ? []
109
- : [{ id: symbol.id, detail, site: { path: symbol.position.path, line: 1, column: 1 } }];
110
- });
111
- }
package/src/glob.ts DELETED
@@ -1,67 +0,0 @@
1
- /**
2
- * Glob patterns over the paths of the target's own files, as the configuration
3
- * writes them. Both `ts.test_files` and `ts.entry_files` name files this way, and
4
- * one grammar answers for both.
5
- *
6
- * A configured root is not written in this grammar. It names a symbol reference
7
- * rather than a path, `*` there spans the solidus and a brace list means nothing,
8
- * so that rule is written where it is read.
9
- */
10
-
11
- /**
12
- * One literal run of a pattern, with every character the expression syntax claims
13
- * escaped.
14
- *
15
- * The set is the syntax characters and the solidus, and it is closed: an escape of any
16
- * other character is refused outright by the expression syntax under the unicode flag,
17
- * so escaping a hyphen, which needs none outside a character class, would refuse every
18
- * pattern that names a hyphenated path.
19
- */
20
- function quoted(text: string): string {
21
- return text.replaceAll(/[.*+?^${}()|[\]\\/]/gu, (character) => `\\${character}`);
22
- }
23
-
24
- /**
25
- * The expression one glob pattern denotes. `**` spans path separators while `*` and `?`
26
- * do not, a brace list is an alternation of its members, and every other character
27
- * stands for itself.
28
- */
29
- export function globExpression(pattern: string): RegExp {
30
- let source = "^";
31
- let at = 0;
32
- while (at < pattern.length) {
33
- const rest = pattern.slice(at);
34
- if (rest.startsWith("**/")) {
35
- source += "(?:[^/]*/)*";
36
- at += 3;
37
- continue;
38
- }
39
- if (rest.startsWith("**")) {
40
- source += ".*";
41
- at += 2;
42
- continue;
43
- }
44
- const character = pattern[at] ?? "";
45
- at += 1;
46
- if (character === "*") {
47
- source += "[^/]*";
48
- continue;
49
- }
50
- if (character === "?") {
51
- source += "[^/]";
52
- continue;
53
- }
54
- if (character === "{") {
55
- const close = pattern.indexOf("}", at);
56
- if (close < 0) {
57
- source += "\\{";
58
- continue;
59
- }
60
- source += `(?:${pattern.slice(at, close).split(",").map(quoted).join("|")})`;
61
- at = close + 1;
62
- continue;
63
- }
64
- source += quoted(character);
65
- }
66
- return new RegExp(`${source}$`, "u");
67
- }