@astryxdesign/cli 0.7.2-canary.fe2c655 → 0.7.3-canary.02f5fe4

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 (694) hide show
  1. package/CHANGELOG.md +119 -0
  2. package/README.md +216 -162
  3. package/api/build/_adapter.d.mts +66 -0
  4. package/api/build/_adapter.mjs +139 -4
  5. package/api/build/blocks/blocks.d.mts +92 -0
  6. package/api/build/blocks/blocks.mjs +528 -0
  7. package/api/build/blocks/blocks.test.mjs +238 -0
  8. package/api/build/blocks/blocks.weights.json +1 -0
  9. package/api/build/build.doc.mjs +4 -0
  10. package/api/build/build.mjs +25 -6
  11. package/api/build/build.type.mjs +1 -1
  12. package/api/build/help/help.mjs +1 -1
  13. package/api/build/kit/answer.d.mts +18 -0
  14. package/api/build/kit/answer.mjs +195 -0
  15. package/api/build/kit/answer.test.mjs +108 -0
  16. package/api/build/kit/kind.d.mts +25 -0
  17. package/api/build/kit/kind.mjs +170 -0
  18. package/api/build/kit/kit.d.mts +2 -4
  19. package/api/build/kit/kit.mjs +8 -406
  20. package/api/build/kit/rank.d.mts +3 -32
  21. package/api/build/kit/rank.mjs +25 -342
  22. package/api/build/kit/rank.test.mjs +2 -1
  23. package/api/build/kit/signals.d.mts +79 -0
  24. package/api/build/kit/signals.mjs +295 -0
  25. package/api/build/kit/start.d.mts +32 -0
  26. package/api/build/kit/start.mjs +163 -0
  27. package/api/build/kit/words.d.mts +72 -0
  28. package/api/build/kit/words.mjs +202 -0
  29. package/api/build/tree.d.mts +20 -0
  30. package/api/build/tree.mjs +53 -0
  31. package/api/build/tree.test.mjs +185 -0
  32. package/api/build/tree.weights.json +1 -0
  33. package/api/component/_adapter.d.mts +72 -1
  34. package/api/component/_adapter.mjs +251 -23
  35. package/api/component/component-replacement.test.mjs +1 -0
  36. package/api/component/component.doc.mjs +6 -1
  37. package/api/component/component.mjs +97 -16
  38. package/api/component/component.test.mjs +95 -0
  39. package/api/component/doc-links.test.mjs +386 -0
  40. package/api/component/integration-export-name.test.mjs +644 -0
  41. package/api/component/list/list.mjs +42 -4
  42. package/api/discover/_adapter.d.mts +131 -12
  43. package/api/discover/_adapter.mjs +520 -34
  44. package/api/discover/_adapter.test.mjs +641 -17
  45. package/api/discover/_catalog-view.d.mts +16 -5
  46. package/api/discover/_catalog-view.mjs +32 -8
  47. package/api/discover/detail/doc/doc.mjs +9 -1
  48. package/api/discover/discover.d.mts +11 -0
  49. package/api/discover/discover.doc.mjs +9 -7
  50. package/api/discover/discover.mjs +120 -19
  51. package/api/discover/discover.type.d.mts +20 -7
  52. package/api/discover/discover.type.mjs +17 -7
  53. package/api/discover/list/list.d.mts +4 -3
  54. package/api/discover/list/list.mjs +17 -10
  55. package/api/docs/_adapter.d.mts +76 -2
  56. package/api/docs/_adapter.mjs +630 -34
  57. package/api/docs/docs-homes.test.mjs +127 -0
  58. package/api/docs/docs.doc.mjs +5 -4
  59. package/api/docs/docs.mjs +2 -1
  60. package/api/docs/docs.test.mjs +39 -20
  61. package/api/docs/integration-tree.test.mjs +42 -20
  62. package/api/docs/integrationDocs.test.mjs +125 -1
  63. package/api/docs/list/list.mjs +12 -2
  64. package/api/docs/namespace-section.test.mjs +6 -6
  65. package/api/docs/reference-blocks.test.mjs +3 -5
  66. package/api/doctor/_adapter.d.mts +128 -0
  67. package/api/doctor/_adapter.mjs +253 -4
  68. package/api/doctor/doctor.d.mts +217 -0
  69. package/api/doctor/doctor.doc.mjs +3 -2
  70. package/api/doctor/doctor.mjs +691 -52
  71. package/api/doctor/doctor.test.mjs +267 -18
  72. package/api/doctor/release-checks.test.mjs +156 -0
  73. package/api/doctor/theme-checks.mjs +17 -4
  74. package/api/doctor/theme-checks.test.mjs +223 -7
  75. package/api/error.d.mts +10 -0
  76. package/api/error.mjs +25 -0
  77. package/api/gap-report/gap-report.d.mts +3 -0
  78. package/api/gap-report/gap-report.doc.mjs +11 -3
  79. package/api/gap-report/gap-report.mjs +219 -52
  80. package/api/gap-report/gap-report.test.mjs +233 -0
  81. package/api/gap-report/gap-report.type.d.mts +41 -0
  82. package/api/gap-report/gap-report.type.mjs +18 -0
  83. package/api/hook/_adapter.mjs +3 -11
  84. package/api/hook/hook.doc.mjs +4 -0
  85. package/api/hook/hook.mjs +1 -1
  86. package/api/hook/list/list.d.mts +1 -1
  87. package/api/index.d.mts +2 -0
  88. package/api/index.mjs +2 -0
  89. package/api/init/_adapter.d.mts +22 -0
  90. package/api/init/_adapter.mjs +59 -0
  91. package/api/init/init.d.mts +7 -5
  92. package/api/init/init.doc.mjs +45 -10
  93. package/api/init/init.mjs +28 -4
  94. package/api/init/init.test.mjs +18 -2
  95. package/api/init/init.type.d.mts +50 -5
  96. package/api/init/init.type.mjs +39 -5
  97. package/api/init/remove/remove.mjs +17 -4
  98. package/api/init/remove/remove.test.mjs +114 -2
  99. package/api/init/run/run.d.mts +1 -1
  100. package/api/init/run/run.mjs +86 -12
  101. package/api/init/user/user.d.mts +14 -0
  102. package/api/init/user/user.mjs +87 -0
  103. package/api/init/user/user.test.mjs +232 -0
  104. package/api/integration/_adapter.d.mts +53 -0
  105. package/api/integration/_adapter.mjs +132 -0
  106. package/api/integration/add-contribution.component-names.test.mjs +66 -0
  107. package/api/integration/add-contribution.mjs +8 -4
  108. package/api/integration/add-contribution.test.mjs +4 -2
  109. package/api/integration/authoring-checks.mjs +192 -14
  110. package/api/integration/authoring-checks.test.mjs +1028 -0
  111. package/api/integration/authoring-checks.type.d.mts +143 -0
  112. package/api/integration/authoring-checks.type.mjs +74 -2
  113. package/api/integration/check/check.d.mts +96 -0
  114. package/api/integration/check/check.mjs +357 -0
  115. package/api/integration/check/check.test.mjs +489 -0
  116. package/api/integration/integration-check.type.d.mts +118 -0
  117. package/api/integration/integration-check.type.mjs +84 -0
  118. package/api/integration/integrationCheck.doc.d.mts +10 -0
  119. package/api/integration/integrationCheck.doc.mjs +73 -0
  120. package/api/integration/integrationComponentConflicts.doc.mjs +45 -6
  121. package/api/integration/integrationDocConflicts.doc.mjs +22 -5
  122. package/api/integration/pack-check.mjs +486 -123
  123. package/api/integration/pack-check.test.mjs +817 -10
  124. package/api/integration/validate-integration-case-disk.test.mjs +111 -0
  125. package/api/integration/validate-integration-fixes.test.mjs +73 -5
  126. package/api/integration/validate-integration-gaps.test.mjs +1975 -0
  127. package/api/integration/validate-integration.d.mts +23 -2
  128. package/api/integration/validate-integration.mjs +358 -45
  129. package/api/integration/validate-integration.test.mjs +88 -8
  130. package/api/integration/validate-integration.type.d.mts +105 -0
  131. package/api/integration/validate-integration.type.mjs +79 -1
  132. package/api/integration/validate-unread-theme-folders.test.mjs +3 -2
  133. package/api/integration/validateIntegration.doc.mjs +19 -3
  134. package/api/search/ORDERING.md +28 -0
  135. package/api/search/_adapter.d.mts +91 -0
  136. package/api/search/_adapter.mjs +172 -0
  137. package/api/search/_adapter.test.mjs +173 -0
  138. package/api/search/_candidate-score.d.mts +40 -0
  139. package/api/search/_candidate-score.mjs +238 -0
  140. package/api/search/_cards.json +6098 -0
  141. package/api/search/_compound.d.mts +50 -0
  142. package/api/search/_compound.mjs +170 -0
  143. package/api/search/_doc-searcher.d.mts +4 -0
  144. package/api/search/_doc-searcher.mjs +23 -0
  145. package/api/search/_doc-searcher.test.mjs +36 -0
  146. package/api/search/_doc-searcher.weights.json +1 -0
  147. package/api/search/_doc-text.d.mts +30 -0
  148. package/api/search/_doc-text.mjs +87 -0
  149. package/api/search/_entries.d.mts +63 -0
  150. package/api/search/_entries.mjs +232 -0
  151. package/api/search/_entries.test.mjs +48 -0
  152. package/api/search/_features.d.mts +35 -0
  153. package/api/search/_features.mjs +155 -0
  154. package/api/search/_gather-components.d.mts +26 -0
  155. package/api/search/_gather-components.mjs +284 -0
  156. package/api/search/_gather-docs.d.mts +20 -0
  157. package/api/search/_gather-docs.mjs +254 -0
  158. package/api/search/_gather-hooks.d.mts +12 -0
  159. package/api/search/_gather-hooks.mjs +52 -0
  160. package/api/search/_gather-templates.d.mts +25 -0
  161. package/api/search/_gather-templates.mjs +107 -0
  162. package/api/search/_lexical.d.mts +135 -0
  163. package/api/search/_lexical.mjs +351 -0
  164. package/api/search/_main-searcher.d.mts +19 -0
  165. package/api/search/_main-searcher.mjs +115 -0
  166. package/api/search/_main-searcher.test.mjs +106 -0
  167. package/api/search/_main-searcher.weights.json +1 -0
  168. package/api/search/_module-doc.d.mts +32 -0
  169. package/api/search/_module-doc.mjs +78 -0
  170. package/api/search/_order.d.mts +32 -0
  171. package/api/search/_order.mjs +162 -0
  172. package/api/search/_order.test.mjs +72 -0
  173. package/api/search/_priority.d.mts +50 -0
  174. package/api/search/_priority.mjs +139 -0
  175. package/api/search/_query-words.d.mts +25 -0
  176. package/api/search/_query-words.mjs +92 -0
  177. package/api/search/_query.d.mts +65 -0
  178. package/api/search/_query.mjs +176 -0
  179. package/api/search/_result.d.mts +97 -0
  180. package/api/search/_result.mjs +150 -0
  181. package/api/search/_score.d.mts +60 -0
  182. package/api/search/_score.mjs +283 -0
  183. package/api/search/_synonyms.d.mts +21 -0
  184. package/api/search/_synonyms.mjs +67 -0
  185. package/api/search/_template-searcher.d.mts +4 -0
  186. package/api/search/_template-searcher.mjs +23 -0
  187. package/api/search/_template-searcher.test.mjs +40 -0
  188. package/api/search/_template-searcher.weights.json +1 -0
  189. package/api/search/_titles.d.mts +33 -0
  190. package/api/search/_titles.mjs +65 -0
  191. package/api/search/_words.d.mts +64 -0
  192. package/api/search/_words.mjs +157 -0
  193. package/api/search/search.d.mts +22 -236
  194. package/api/search/search.doc.mjs +14 -7
  195. package/api/search/search.domain-priority.test.mjs +108 -18
  196. package/api/search/search.integration-check.test.mjs +24 -0
  197. package/api/search/search.mjs +59 -1904
  198. package/api/search/search.test.mjs +193 -15
  199. package/api/search/search.type.d.mts +20 -2
  200. package/api/search/search.type.mjs +12 -2
  201. package/api/search/tree.d.mts +15 -0
  202. package/api/search/tree.mjs +40 -0
  203. package/api/search/tree.test.mjs +66 -0
  204. package/api/search/tree.weights.json +1 -0
  205. package/api/swizzle/_adapter.mjs +2 -2
  206. package/api/swizzle/copy/copy.mjs +29 -15
  207. package/api/template/template-integration.test.mjs +1 -1
  208. package/api/template/template.mjs +5 -1
  209. package/api/template/template.test.mjs +120 -3
  210. package/api/theme/_adapter.d.mts +16 -0
  211. package/api/theme/_adapter.mjs +32 -5
  212. package/api/theme/build/build.d.mts +2 -1
  213. package/api/theme/build/build.family.test.mjs +64 -0
  214. package/api/theme/build/build.mjs +250 -38
  215. package/api/theme/build/build.packed-old-core.test.mjs +21 -3
  216. package/api/theme/build/font-warning.mjs +5 -3
  217. package/api/theme/build/font-warning.test.mjs +2 -1
  218. package/api/theme/remove/remove.test.mjs +2 -2
  219. package/api/theme/targets/targets.mjs +3 -10
  220. package/api/theme/themeBuild.doc.mjs +4 -4
  221. package/api/theme/themeTargets.doc.mjs +4 -0
  222. package/api/theme/use/use.test.mjs +1 -1
  223. package/api/upgrade/_adapter.d.mts +97 -11
  224. package/api/upgrade/_adapter.mjs +315 -32
  225. package/api/upgrade/registry/registry.d.mts +10 -4
  226. package/api/upgrade/registry/registry.mjs +33 -16
  227. package/api/upgrade/registry/registry.test.mjs +85 -0
  228. package/api/upgrade/run/cli-behind-core.test.mjs +438 -0
  229. package/api/upgrade/run/run.d.mts +4 -2
  230. package/api/upgrade/run/run.mjs +48 -4
  231. package/api/upgrade/run/run.test.mjs +417 -3
  232. package/api/upgrade/status/status.d.mts +21 -5
  233. package/api/upgrade/status/status.mjs +45 -8
  234. package/api/upgrade/upgrade.doc.mjs +16 -8
  235. package/api/upgrade/upgrade.mjs +18 -3
  236. package/api/upgrade/upgrade.test.mjs +194 -0
  237. package/api/upgrade/upgrade.type.d.mts +28 -3
  238. package/api/upgrade/upgrade.type.mjs +24 -7
  239. package/assets/codemods/__tests__/registry.test.mjs +1 -0
  240. package/assets/codemods/registry.mjs +1 -0
  241. package/assets/codemods/runner.mjs +7 -1
  242. package/assets/codemods/transforms/v0.7.0/__tests__/validate-data-token-ownership.test.mjs +11 -0
  243. package/assets/codemods/transforms/v0.7.0/validate-data-token-ownership.mjs +3 -3
  244. package/assets/codemods/transforms/v0.7.2/__tests__/migrate-list-edge-compensation-to-edge.test.mjs +120 -0
  245. package/assets/codemods/transforms/v0.7.2/index.mjs +20 -0
  246. package/assets/codemods/transforms/v0.7.2/migrate-list-edge-compensation-to-edge.mjs +198 -0
  247. package/assets/discover/official-packages.json +367 -0
  248. package/assets/docs/README.md +10 -0
  249. package/assets/docs/author-a-theme.doc.mjs +5 -5
  250. package/assets/docs/browser-support.doc.mjs +1 -1
  251. package/assets/docs/getting-started.doc.mjs +26 -6
  252. package/assets/docs/is-my-code-good.doc.mjs +287 -0
  253. package/assets/docs/styling-overview.doc.mjs +1 -1
  254. package/assets/docs/theme.doc.dense.mjs +1 -1
  255. package/assets/docs/theme.doc.mjs +2 -2
  256. package/assets/docs/theme.doc.zh.mjs +1 -1
  257. package/assets/docs/tree/add-a-component.doc.mjs +22 -2
  258. package/assets/docs/tree/add-a-theme.doc.mjs +14 -4
  259. package/assets/docs/tree/add-a-topic.doc.mjs +54 -9
  260. package/assets/docs/tree/agent-guidance.doc.mjs +19 -5
  261. package/assets/docs/tree/api.doc.mjs +6 -0
  262. package/assets/docs/tree/authoring.doc.mjs +61 -0
  263. package/assets/docs/tree/block-template.doc.mjs +8 -20
  264. package/assets/docs/tree/build-the-template.doc.mjs +1 -1
  265. package/assets/docs/tree/building-blocks.doc.mjs +6 -2
  266. package/assets/docs/tree/check-the-props.doc.mjs +201 -0
  267. package/assets/docs/tree/check-your-docs.doc.mjs +69 -11
  268. package/assets/docs/tree/checks.doc.mjs +32 -24
  269. package/assets/docs/tree/ci-and-containers.doc.mjs +101 -0
  270. package/assets/docs/tree/cli-command.doc.mjs +142 -0
  271. package/assets/docs/tree/cli.doc.mjs +7 -1
  272. package/assets/docs/tree/codemods.doc.mjs +17 -7
  273. package/assets/docs/tree/commands.doc.mjs +7 -1
  274. package/assets/docs/tree/component-family.doc.mjs +8 -6
  275. package/assets/docs/tree/component-imports.doc.mjs +21 -3
  276. package/assets/docs/tree/components.doc.mjs +7 -1
  277. package/assets/docs/tree/computer-agent-guide.doc.mjs +160 -0
  278. package/assets/docs/tree/computer-integrations.doc.mjs +93 -0
  279. package/assets/docs/tree/configuration.doc.mjs +8 -4
  280. package/assets/docs/tree/debug-and-gap-reports.doc.mjs +41 -22
  281. package/assets/docs/tree/define-the-theme.doc.mjs +7 -6
  282. package/assets/docs/tree/describe-the-component.doc.mjs +3 -3
  283. package/assets/docs/tree/docs.doc.mjs +9 -3
  284. package/assets/docs/tree/document-the-template.doc.mjs +1 -1
  285. package/assets/docs/tree/document-the-theme.doc.mjs +4 -4
  286. package/assets/docs/tree/export-template-assets.doc.mjs +1 -1
  287. package/assets/docs/tree/extend-or-replace.doc.mjs +19 -9
  288. package/assets/docs/{authoring.doc.mjs → tree/field-reference.doc.mjs} +4 -3
  289. package/assets/docs/tree/fonts-and-assets.doc.mjs +3 -3
  290. package/assets/docs/tree/generate-a-palette.doc.mjs +8 -6
  291. package/assets/docs/tree/global-integrations.doc.mjs +124 -0
  292. package/assets/docs/tree/global.doc.mjs +131 -0
  293. package/assets/docs/tree/grade-template-with-agent.doc.mjs +5 -5
  294. package/assets/docs/tree/help.doc.mjs +2 -2
  295. package/assets/docs/tree/host-entry.doc.mjs +128 -0
  296. package/assets/docs/tree/install-once.doc.mjs +105 -0
  297. package/assets/docs/tree/layout-spacing.doc.mjs +2 -3
  298. package/assets/docs/tree/layout.doc.mjs +6 -6
  299. package/assets/docs/tree/links.doc.mjs +7 -6
  300. package/assets/docs/tree/migration-setup.doc.mjs +3 -2
  301. package/assets/docs/tree/migration-verification.doc.mjs +0 -1
  302. package/assets/docs/tree/migration.doc.mjs +0 -1
  303. package/assets/docs/tree/monorepos.doc.mjs +84 -0
  304. package/assets/docs/tree/package-and-test.doc.mjs +1 -1
  305. package/assets/docs/tree/page-template.doc.mjs +4 -8
  306. package/assets/docs/tree/problems.doc.mjs +205 -0
  307. package/assets/docs/tree/project-global-or-both.doc.mjs +131 -0
  308. package/assets/docs/tree/publishing.doc.mjs +6 -6
  309. package/assets/docs/tree/quick-start.doc.mjs +54 -28
  310. package/assets/docs/tree/reference.doc.mjs +192 -0
  311. package/assets/docs/tree/replace-a-core-component.doc.mjs +15 -7
  312. package/assets/docs/tree/replace-a-core-template.doc.mjs +10 -12
  313. package/assets/docs/tree/scaffold.doc.mjs +1 -1
  314. package/assets/docs/tree/sections-and-placement.doc.mjs +9 -11
  315. package/assets/docs/tree/see-it-in-an-app.doc.mjs +17 -5
  316. package/assets/docs/tree/ship.doc.mjs +2 -2
  317. package/assets/docs/tree/short-and-findable.doc.mjs +9 -8
  318. package/assets/docs/tree/single-component.doc.mjs +15 -6
  319. package/assets/docs/tree/start-a-template.doc.mjs +18 -8
  320. package/assets/docs/tree/subcomponent.doc.mjs +6 -6
  321. package/assets/docs/tree/template-assets.doc.mjs +2 -2
  322. package/assets/docs/tree/template-doc-overview.doc.mjs +6 -17
  323. package/assets/docs/tree/template-fonts.doc.mjs +1 -1
  324. package/assets/docs/tree/template-grading-rubric.doc.mjs +17 -38
  325. package/assets/docs/tree/template-icons.doc.mjs +1 -1
  326. package/assets/docs/tree/template-images-media.doc.mjs +1 -1
  327. package/assets/docs/tree/template-styles.doc.mjs +2 -2
  328. package/assets/docs/tree/templates.doc.mjs +7 -1
  329. package/assets/docs/tree/test-in-an-app.doc.mjs +7 -7
  330. package/assets/docs/tree/test-template-in-app.doc.mjs +5 -5
  331. package/assets/docs/tree/themes.doc.mjs +5 -1
  332. package/assets/docs/tree/tokens-and-setup.doc.mjs +19 -15
  333. package/assets/docs/tree/tokens-data.doc.mjs +2 -2
  334. package/assets/docs/tree/troubleshooting.doc.mjs +29 -13
  335. package/assets/docs/tree/type-scale.doc.mjs +3 -3
  336. package/assets/docs/tree/uninstall.doc.mjs +109 -0
  337. package/assets/docs/tree/updates.doc.mjs +92 -0
  338. package/assets/docs/tree/upgrading.doc.mjs +6 -6
  339. package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +15 -3
  340. package/assets/docs/tree/verify-packed-template.doc.mjs +3 -3
  341. package/assets/docs/tree/versioning.doc.mjs +14 -9
  342. package/assets/docs/tree/who-answers.doc.mjs +119 -0
  343. package/assets/docs/tree/write-good-templates.doc.mjs +1 -1
  344. package/assets/docs/tree/write-the-template-file.doc.mjs +7 -6
  345. package/assets/docs/use-a-theme.doc.mjs +2 -2
  346. package/assets/docs/use-integrations.doc.mjs +120 -0
  347. package/assets/docs/working-with-ai.doc.mjs +70 -13
  348. package/assets/templates/themes/butter/butterTheme.ts +4 -2
  349. package/assets/templates/themes/stone/stoneTheme.ts +4 -2
  350. package/assets/templates/themes/y2k/y2kTheme.ts +4 -2
  351. package/assets/theme.template.ts +1 -1
  352. package/authoring/codemod/codemod.doc.mjs +7 -3
  353. package/authoring/config/config.doc.mjs +9 -6
  354. package/authoring/config/type.ts +4 -2
  355. package/authoring/debug/parse.d.mts +5 -5
  356. package/authoring/discover/discover.doc.mjs +7 -1
  357. package/authoring/doctypes/_schema.d.mts +8 -3
  358. package/authoring/doctypes/_schema.mjs +1 -0
  359. package/authoring/doctypes/base/graph-fields.doc.mjs +6 -4
  360. package/authoring/doctypes/command/command.doc.mjs +20 -12
  361. package/authoring/doctypes/command/type.ts +14 -0
  362. package/authoring/doctypes/component/component.doc.mjs +30 -27
  363. package/authoring/doctypes/component/type.ts +21 -8
  364. package/authoring/doctypes/enum/enum.doc.mjs +7 -4
  365. package/authoring/doctypes/function/function.doc.mjs +9 -8
  366. package/authoring/doctypes/hook/hook.doc.mjs +5 -4
  367. package/authoring/doctypes/hook/type.ts +4 -0
  368. package/authoring/doctypes/namespace/namespace.doc.mjs +7 -6
  369. package/authoring/doctypes/reference/reference.doc.mjs +12 -11
  370. package/authoring/doctypes/schema/schema.doc.mjs +10 -10
  371. package/authoring/doctypes/template/integration-template.doc.d.mts +11 -0
  372. package/authoring/doctypes/template/integration-template.doc.mjs +49 -0
  373. package/authoring/doctypes/template/parse.d.mts +6 -2
  374. package/authoring/doctypes/template/parse.mjs +3 -1
  375. package/authoring/doctypes/template/template.doc.mjs +3 -3
  376. package/authoring/doctypes/template/type.ts +22 -0
  377. package/authoring/doctypes/theme/theme.doc.mjs +2 -2
  378. package/authoring/gap-report/gap-report.doc.mjs +2 -2
  379. package/authoring/identity/identity.doc.mjs +3 -3
  380. package/authoring/index.d.ts +2 -0
  381. package/authoring/integration/integration.doc.mjs +30 -6
  382. package/authoring/integration/parse.test.mjs +21 -0
  383. package/authoring/integration/schema.d.mts +16 -3
  384. package/authoring/integration/schema.mjs +34 -2
  385. package/authoring/integration/type.ts +13 -1
  386. package/clients/cli/bin/astryx.mjs +11 -65
  387. package/clients/cli/cli-command.test.mjs +166 -0
  388. package/clients/cli/command-result-coverage.test.mjs +6 -5
  389. package/clients/cli/commands/blog.doc.mjs +1 -0
  390. package/clients/cli/commands/build-theme.batch-report.test.mjs +17 -3
  391. package/clients/cli/commands/build-theme.color-scheme.test.mjs +1 -1
  392. package/clients/cli/commands/build-theme.font-warning.test.mjs +3 -3
  393. package/clients/cli/commands/build-theme.path-safety.test.mjs +224 -6
  394. package/clients/cli/commands/build-theme.registry.test.mjs +5 -2
  395. package/clients/cli/commands/build.doc.mjs +1 -0
  396. package/clients/cli/commands/build.exit-codes-doc.test.mjs +4 -0
  397. package/clients/cli/commands/cli-postinstall.test.mjs +49 -1
  398. package/clients/cli/commands/component.doc.mjs +1 -0
  399. package/clients/cli/commands/{component/index.mjs → component.mjs} +37 -37
  400. package/clients/cli/commands/component.test.mjs +6 -6
  401. package/clients/cli/commands/discover.broken-integration.test.mjs +11 -7
  402. package/clients/cli/commands/discover.doc.mjs +9 -1
  403. package/clients/cli/commands/discover.mjs +144 -93
  404. package/clients/cli/commands/discover.no-source.test.mjs +448 -33
  405. package/clients/cli/commands/discover.sources.test.mjs +20 -1
  406. package/clients/cli/commands/docs.doc.mjs +3 -2
  407. package/clients/cli/commands/docs.mjs +50 -20
  408. package/clients/cli/commands/docs.test.mjs +16 -16
  409. package/clients/cli/commands/doctor-integration-components.doc.mjs +19 -4
  410. package/clients/cli/commands/doctor-integration-docs.doc.mjs +20 -5
  411. package/clients/cli/commands/doctor-integration-templates.doc.mjs +1 -0
  412. package/clients/cli/commands/doctor-integration-validate.doc.mjs +22 -2
  413. package/clients/cli/commands/doctor-integration.test.mjs +936 -3
  414. package/clients/cli/commands/doctor.doc.mjs +12 -2
  415. package/clients/cli/commands/doctor.mjs +332 -7
  416. package/clients/cli/commands/doctor.test.mjs +75 -4
  417. package/clients/cli/commands/gap-report.doc.mjs +15 -2
  418. package/clients/cli/commands/gap-report.mjs +24 -2
  419. package/clients/cli/commands/gap-report.test.mjs +79 -0
  420. package/clients/cli/commands/hook.doc.mjs +1 -0
  421. package/clients/cli/commands/{hook/index.mjs → hook.mjs} +22 -22
  422. package/clients/cli/commands/import-hint-correctness.test.mjs +1 -1
  423. package/clients/cli/commands/init.behavior.test.mjs +235 -1
  424. package/clients/cli/commands/init.doc.mjs +55 -10
  425. package/clients/cli/commands/init.flag-help.test.mjs +1 -0
  426. package/clients/cli/commands/init.mjs +2 -2
  427. package/clients/cli/commands/integration-add.doc.mjs +7 -0
  428. package/clients/cli/commands/integration-authoring.test.mjs +49 -3
  429. package/clients/cli/commands/integration-check.doc.mjs +93 -0
  430. package/clients/cli/commands/integration-check.test.mjs +489 -0
  431. package/clients/cli/commands/integration-pack.doc.mjs +8 -1
  432. package/clients/cli/commands/integration-verify.doc.mjs +8 -1
  433. package/clients/cli/commands/integration.doc.mjs +6 -2
  434. package/clients/cli/commands/integration.mjs +119 -7
  435. package/clients/cli/commands/json-contract.test.mjs +11 -2
  436. package/clients/cli/commands/manifest.doc.mjs +2 -1
  437. package/clients/cli/commands/manifest.mjs +67 -0
  438. package/clients/cli/commands/outside-project.test.mjs +874 -0
  439. package/clients/cli/commands/postinstall.doc.mjs +23 -0
  440. package/clients/cli/commands/postinstall.mjs +31 -0
  441. package/clients/cli/commands/search.doc.mjs +1 -0
  442. package/clients/cli/commands/search.mjs +16 -11
  443. package/clients/cli/commands/search.test.mjs +429 -296
  444. package/clients/cli/commands/setup-nudge.test.mjs +180 -2
  445. package/clients/cli/commands/swizzle.doc.mjs +7 -0
  446. package/clients/cli/commands/swizzle.mjs +5 -3
  447. package/clients/cli/commands/swizzle.routing.test.mjs +19 -2
  448. package/clients/cli/commands/template.doc.mjs +1 -0
  449. package/clients/cli/commands/text-json-parity.test.mjs +5 -0
  450. package/clients/cli/commands/theme-add-lifecycle.test.mjs +3 -3
  451. package/clients/cli/commands/theme-add.doc.mjs +8 -1
  452. package/clients/cli/commands/theme-build.doc.mjs +3 -2
  453. package/clients/cli/commands/theme-eject.doc.mjs +1 -0
  454. package/clients/cli/commands/theme-list.behavior.test.mjs +6 -0
  455. package/clients/cli/commands/theme-list.doc.mjs +1 -0
  456. package/clients/cli/commands/theme-palette-generate.doc.mjs +1 -0
  457. package/clients/cli/commands/theme-remove.doc.mjs +7 -0
  458. package/clients/cli/commands/theme-targets.doc.mjs +1 -0
  459. package/clients/cli/commands/theme-template.doc.mjs +1 -0
  460. package/clients/cli/commands/theme-use.doc.mjs +7 -0
  461. package/clients/cli/commands/{build-theme.mjs → theme.mjs} +27 -14
  462. package/clients/cli/commands/upgrade.config-ordering.test.mjs +2 -1
  463. package/clients/cli/commands/upgrade.doc.mjs +26 -3
  464. package/clients/cli/commands/upgrade.file-protection.test.mjs +3 -2
  465. package/clients/cli/commands/upgrade.hook-output.test.mjs +2 -1
  466. package/clients/cli/commands/upgrade.mjs +9 -2
  467. package/clients/cli/commands/upgrade.older-cli.test.mjs +160 -0
  468. package/clients/cli/commands/upgrade.subfolder-path.test.mjs +97 -0
  469. package/clients/cli/index.mjs +156 -100
  470. package/clients/cli/lib/cli-error.mjs +4 -1
  471. package/clients/cli/lib/component-format.mjs +1 -1
  472. package/clients/cli/lib/component-format.test.mjs +1 -1
  473. package/clients/cli/lib/define-command.mjs +14 -9
  474. package/clients/cli/lib/exit-codes.test.mjs +5 -0
  475. package/clients/cli/lib/json-shim.mjs +3 -1
  476. package/clients/cli/lib/manifest.d.ts +9 -0
  477. package/clients/cli/lib/manifest.mjs +17 -1
  478. package/clients/cli/lib/manifest.test.mjs +37 -0
  479. package/clients/cli/lib/welcome-box.mjs +50 -0
  480. package/clients/cli/run.mjs +108 -0
  481. package/foundation/agent-docs/agent-doc-state.d.mts +67 -13
  482. package/foundation/agent-docs/agent-doc-state.mjs +123 -14
  483. package/foundation/agent-docs/agent-docs.d.mts +104 -15
  484. package/foundation/agent-docs/agent-docs.mjs +1028 -114
  485. package/foundation/agent-docs/agent-docs.path-safety.test.mjs +1239 -17
  486. package/foundation/agent-docs/agent-docs.test.mjs +683 -39
  487. package/foundation/agent-docs/computer-agent-text.d.mts +170 -0
  488. package/foundation/agent-docs/computer-agent-text.mjs +750 -0
  489. package/foundation/agent-docs/computer-agent-text.test.mjs +699 -0
  490. package/foundation/config/project.d.mts +35 -3
  491. package/foundation/config/project.mjs +243 -26
  492. package/foundation/config/project.test.mjs +122 -0
  493. package/foundation/config/theme-state.mjs +5 -4
  494. package/foundation/discovery/authoring-self-docs.d.mts +7 -0
  495. package/foundation/discovery/authoring-self-docs.mjs +17 -4
  496. package/foundation/discovery/authoring-self-docs.test.mjs +15 -3
  497. package/foundation/discovery/authoring-surface.d.mts +1 -1
  498. package/foundation/discovery/authoring-surface.mjs +2 -2
  499. package/foundation/discovery/authoring-surface.test.mjs +1 -1
  500. package/foundation/discovery/cli-self-docs.d.mts +2 -1
  501. package/foundation/discovery/cli-self-docs.mjs +22 -4
  502. package/foundation/discovery/cli-self-docs.test.mjs +3 -2
  503. package/foundation/discovery/component-discovery.d.mts +227 -10
  504. package/foundation/discovery/component-discovery.export-names.test.mjs +760 -0
  505. package/foundation/discovery/component-discovery.mjs +940 -57
  506. package/foundation/discovery/component-discovery.test.mjs +96 -0
  507. package/foundation/discovery/component-loader.d.mts +1 -1
  508. package/foundation/discovery/component-replacement.mjs +20 -1
  509. package/foundation/discovery/component-replacement.test.mjs +40 -0
  510. package/foundation/discovery/copied-passages.d.mts +216 -0
  511. package/foundation/discovery/copied-passages.mjs +720 -0
  512. package/foundation/discovery/copied-passages.test.mjs +124 -0
  513. package/foundation/discovery/doc-consistency.d.mts +34 -0
  514. package/foundation/discovery/doc-consistency.mjs +513 -0
  515. package/foundation/discovery/doc-consistency.test.mjs +347 -0
  516. package/foundation/discovery/doc-fluff.d.mts +112 -0
  517. package/foundation/discovery/doc-fluff.mjs +328 -0
  518. package/foundation/discovery/doc-fluff.test.mjs +142 -0
  519. package/foundation/discovery/doc-types.d.mts +157 -0
  520. package/foundation/discovery/doc-types.mjs +1231 -0
  521. package/foundation/discovery/doc-types.test.mjs +744 -0
  522. package/foundation/discovery/docs-discovery.d.mts +88 -0
  523. package/foundation/discovery/docs-discovery.mjs +97 -3
  524. package/foundation/discovery/integration-doc-files.d.mts +22 -0
  525. package/foundation/discovery/integration-doc-files.mjs +231 -0
  526. package/foundation/discovery/integration-doc-files.test.mjs +246 -0
  527. package/foundation/discovery/module-exports.d.mts +68 -0
  528. package/foundation/discovery/module-exports.mjs +609 -31
  529. package/foundation/discovery/module-exports.test.mjs +172 -0
  530. package/foundation/discovery/package-tsconfig.d.mts +14 -0
  531. package/foundation/discovery/package-tsconfig.mjs +228 -0
  532. package/foundation/discovery/package-tsconfig.test.mjs +210 -0
  533. package/foundation/discovery/project-typescript.d.mts +32 -0
  534. package/foundation/discovery/project-typescript.mjs +89 -0
  535. package/foundation/discovery/prop-drift.d.mts +297 -0
  536. package/foundation/discovery/prop-drift.mjs +2428 -0
  537. package/foundation/discovery/prop-drift.test.mjs +2337 -0
  538. package/foundation/discovery/runner-allowlist.d.mts +38 -0
  539. package/foundation/discovery/runner-allowlist.mjs +51 -0
  540. package/foundation/discovery/runner-commands.d.mts +77 -0
  541. package/foundation/discovery/runner-commands.mjs +294 -0
  542. package/foundation/discovery/runner-commands.test.mjs +128 -0
  543. package/foundation/discovery/stray-pointers.d.mts +52 -0
  544. package/foundation/discovery/stray-pointers.mjs +293 -0
  545. package/foundation/discovery/stray-pointers.test.mjs +86 -0
  546. package/foundation/discovery/template-adapter.mjs +92 -6
  547. package/foundation/discovery/template-needs.mjs +6 -46
  548. package/foundation/discovery/theme-discovery.mjs +147 -3
  549. package/foundation/discovery/theme-imports.mjs +8 -4
  550. package/foundation/discovery/theme-imports.test.mjs +1 -1
  551. package/foundation/discovery/type-match.d.mts +53 -0
  552. package/foundation/discovery/type-match.mjs +660 -0
  553. package/foundation/discovery/type-match.test.mjs +169 -0
  554. package/foundation/discovery/type-text.d.mts +68 -0
  555. package/foundation/discovery/type-text.mjs +658 -0
  556. package/foundation/discovery/type-text.test.mjs +196 -0
  557. package/foundation/discovery/unresolved-references.d.mts +62 -0
  558. package/foundation/discovery/unresolved-references.mjs +790 -0
  559. package/foundation/discovery/unresolved-references.test.mjs +567 -0
  560. package/foundation/doc-compiler/doc-loads.test.mjs +84 -10
  561. package/foundation/doc-compiler/inputs.mjs +27 -1
  562. package/foundation/doc-compiler/inputs.test.mjs +0 -1
  563. package/foundation/doc-compiler/links.d.mts +41 -5
  564. package/foundation/doc-compiler/links.mjs +167 -28
  565. package/foundation/doc-compiler/links.test.mjs +97 -4
  566. package/foundation/doc-compiler/read.d.mts +1 -1
  567. package/foundation/doc-compiler/read.mjs +59 -1
  568. package/foundation/doc-compiler/read.test.mjs +11 -2
  569. package/foundation/doc-compiler/split-topic-keywords.test.mjs +3 -2
  570. package/foundation/doc-compiler/tree.d.mts +32 -6
  571. package/foundation/doc-compiler/tree.mjs +107 -44
  572. package/foundation/doc-compiler/tree.test.mjs +14 -7
  573. package/foundation/env/cli-command.d.mts +83 -0
  574. package/foundation/env/cli-command.mjs +152 -0
  575. package/foundation/env/cli-command.test.mjs +129 -0
  576. package/foundation/env/node-version.test.mjs +15 -3
  577. package/foundation/env/package-manager.d.mts +93 -9
  578. package/foundation/env/package-manager.global.test.mjs +66 -0
  579. package/foundation/env/package-manager.mjs +184 -13
  580. package/foundation/env/package-manager.test.mjs +341 -15
  581. package/foundation/env/project-scope.d.mts +9 -0
  582. package/foundation/env/project-scope.mjs +33 -0
  583. package/foundation/env/search-path.d.mts +42 -0
  584. package/foundation/env/search-path.mjs +205 -0
  585. package/foundation/env/search-path.test.mjs +122 -0
  586. package/foundation/env/user-dirs.d.mts +39 -0
  587. package/foundation/env/user-dirs.mjs +93 -0
  588. package/foundation/env/user-dirs.test.mjs +72 -0
  589. package/foundation/env/user-settings.d.mts +46 -0
  590. package/foundation/env/user-settings.mjs +106 -0
  591. package/foundation/env/user-settings.test.mjs +64 -0
  592. package/foundation/fs/file-protection.mjs +15 -1
  593. package/foundation/fs/module-loader.d.mts +2 -1
  594. package/foundation/fs/module-loader.mjs +60 -4
  595. package/foundation/fs/module-loader.stdout.test.mjs +3 -2
  596. package/foundation/fs/module-loader.test.mjs +194 -0
  597. package/foundation/fs/path-compare.d.mts +33 -0
  598. package/foundation/fs/path-compare.mjs +73 -0
  599. package/foundation/fs/paths.d.mts +122 -4
  600. package/foundation/fs/paths.mjs +675 -29
  601. package/foundation/fs/paths.test.mjs +439 -54
  602. package/foundation/fs/read-record.d.mts +18 -0
  603. package/foundation/fs/read-record.mjs +131 -0
  604. package/foundation/fs/read-record.test.mjs +77 -0
  605. package/foundation/integrations/autolink.d.mts +2 -1
  606. package/foundation/integrations/autolink.mjs +4 -13
  607. package/foundation/integrations/cli-peer-version.d.mts +36 -0
  608. package/foundation/integrations/cli-peer-version.mjs +132 -0
  609. package/foundation/integrations/cli-peer-version.test.mjs +354 -0
  610. package/foundation/integrations/computer-integrations.d.mts +81 -0
  611. package/foundation/integrations/computer-integrations.mjs +345 -0
  612. package/foundation/integrations/computer-integrations.test.mjs +292 -0
  613. package/foundation/integrations/contribution-inventory.d.mts +26 -20
  614. package/foundation/integrations/contribution-inventory.mjs +97 -8
  615. package/foundation/integrations/exports-subpaths.d.mts +57 -0
  616. package/foundation/integrations/exports-subpaths.mjs +113 -0
  617. package/foundation/integrations/integration-warnings.mjs +3 -2
  618. package/foundation/integrations/integration-warnings.test.mjs +8 -9
  619. package/foundation/integrations/integrations.d.mts +51 -1
  620. package/foundation/integrations/integrations.mjs +106 -4
  621. package/foundation/integrations/issue.ts +6 -0
  622. package/foundation/integrations/public-imports.d.mts +118 -0
  623. package/foundation/integrations/public-imports.mjs +1769 -0
  624. package/foundation/integrations/public-imports.test.mjs +1793 -0
  625. package/foundation/integrations/validate-contributions.d.mts +117 -0
  626. package/foundation/integrations/validate-contributions.mjs +1209 -14
  627. package/foundation/release/agent-text-worker.d.mts +4 -0
  628. package/foundation/release/agent-text-worker.mjs +52 -0
  629. package/foundation/release/cache.d.mts +310 -0
  630. package/foundation/release/cache.mjs +1216 -0
  631. package/foundation/release/cache.test.mjs +923 -0
  632. package/foundation/release/choose.d.mts +207 -0
  633. package/foundation/release/choose.mjs +677 -0
  634. package/foundation/release/choose.test.mjs +427 -0
  635. package/foundation/release/core-worker.d.mts +4 -0
  636. package/foundation/release/core-worker.mjs +38 -0
  637. package/foundation/release/global-state.d.mts +263 -0
  638. package/foundation/release/global-state.mjs +474 -0
  639. package/foundation/release/global-state.test.mjs +381 -0
  640. package/foundation/release/handoff.d.mts +79 -0
  641. package/foundation/release/handoff.e2e.test.mjs +278 -0
  642. package/foundation/release/handoff.mjs +524 -0
  643. package/foundation/release/lock-lease.d.mts +23 -0
  644. package/foundation/release/lock-lease.mjs +80 -0
  645. package/foundation/release/notices.d.mts +307 -0
  646. package/foundation/release/notices.mjs +707 -0
  647. package/foundation/release/notices.test.mjs +586 -0
  648. package/foundation/release/npm-guard.d.mts +4 -0
  649. package/foundation/release/npm-guard.mjs +126 -0
  650. package/foundation/release/project.d.mts +141 -0
  651. package/foundation/release/project.mjs +466 -0
  652. package/foundation/release/project.test.mjs +288 -0
  653. package/foundation/release/refresh-worker.d.mts +4 -0
  654. package/foundation/release/refresh-worker.mjs +27 -0
  655. package/foundation/release/run-context.d.mts +47 -0
  656. package/foundation/release/run-context.mjs +163 -0
  657. package/foundation/release/update-notice-env.d.mts +28 -0
  658. package/foundation/release/update-notice-env.mjs +39 -0
  659. package/foundation/response/base.d.ts +26 -3
  660. package/foundation/response/error-codes.d.mts +3 -1
  661. package/foundation/response/error-codes.doc.mjs +12 -0
  662. package/foundation/response/error-codes.mjs +17 -0
  663. package/foundation/response/error-codes.test.mjs +2 -0
  664. package/foundation/response/json-contract.test.mjs +7 -2
  665. package/foundation/response/json.mjs +4 -1
  666. package/foundation/response/response-types.doc.mjs +22 -11
  667. package/foundation/response/response-types.doc.test.mjs +46 -0
  668. package/foundation/response/response.doc.mjs +3 -3
  669. package/foundation/route/route.d.mts +285 -0
  670. package/foundation/route/route.mjs +324 -0
  671. package/foundation/route/route.test.mjs +153 -0
  672. package/foundation/runtime/hosted-runtime.test.mjs +403 -0
  673. package/foundation/runtime/locked-versions.d.mts +32 -0
  674. package/foundation/runtime/locked-versions.mjs +65 -0
  675. package/foundation/runtime/package-root.d.mts +91 -0
  676. package/foundation/runtime/package-root.mjs +174 -0
  677. package/foundation/runtime/package-set.d.mts +62 -0
  678. package/foundation/runtime/package-set.mjs +130 -0
  679. package/foundation/runtime/package-set.test.mjs +432 -0
  680. package/foundation/text/string-utils.d.mts +2 -1
  681. package/foundation/text/string-utils.mjs +16 -5
  682. package/foundation/text/suggest-order.d.mts +72 -0
  683. package/foundation/text/suggest-order.mjs +363 -0
  684. package/foundation/text/suggest-order.test.mjs +259 -0
  685. package/foundation/xle/browser-imports.test.mjs +74 -0
  686. package/foundation/xle/registry.mjs +4 -0
  687. package/foundation/xle/registry.test.mjs +28 -0
  688. package/host/door-conformance.test.mjs +274 -0
  689. package/host/index.d.ts +116 -0
  690. package/host/index.mjs +295 -0
  691. package/host/index.test.mjs +302 -0
  692. package/package.json +16 -11
  693. package/scripts/postinstall.mjs +24 -5
  694. package/assets/docs/tree/integrations.doc.mjs +0 -40
@@ -6,14 +6,16 @@
6
6
  * Proves a runtime export without executing package code. Local ESM re-exports
7
7
  * are followed recursively; unresolved or unparsable modules fail closed.
8
8
  *
9
- * @input A module path and runtime export name
10
- * @output Whether that export can be proved statically
9
+ * @input A module path and runtime export name, or a module path and the
10
+ * exports to try
11
+ * @output Whether that export can be proved statically and the file that
12
+ * declares it, or the exported object literal as plain data
11
13
  * @position packages/cli/foundation/discovery — shared package inspection
12
14
  */
13
15
 
14
16
  import * as fs from 'node:fs';
15
17
  import * as path from 'node:path';
16
- import jscodeshift from 'jscodeshift';
18
+ import {parse} from '@babel/parser';
17
19
 
18
20
  const MODULE_EXTENSIONS = [
19
21
  '.mjs',
@@ -25,7 +27,141 @@ const MODULE_EXTENSIONS = [
25
27
  '.tsx',
26
28
  '.jsx',
27
29
  ];
28
- const parser = jscodeshift.withParser('tsx');
30
+ // The options jscodeshift's tsx parser passes to Babel, so the same sources
31
+ // parse, without tokens or the recast layer: these reads only look at the tree.
32
+ /** @type {import('@babel/parser').ParserOptions} */
33
+ const PARSE_OPTIONS = /** @type {any} */ ({
34
+ sourceType: 'module',
35
+ allowImportExportEverywhere: true,
36
+ allowReturnOutsideFunction: true,
37
+ plugins: [
38
+ 'jsx',
39
+ 'asyncGenerators',
40
+ 'decoratorAutoAccessors',
41
+ 'bigInt',
42
+ 'classPrivateMethods',
43
+ 'classPrivateProperties',
44
+ 'classProperties',
45
+ 'decorators-legacy',
46
+ 'doExpressions',
47
+ 'dynamicImport',
48
+ 'exportDefaultFrom',
49
+ 'exportExtensions',
50
+ 'exportNamespaceFrom',
51
+ 'functionBind',
52
+ 'functionSent',
53
+ 'importAttributes',
54
+ 'importMeta',
55
+ 'nullishCoalescingOperator',
56
+ 'numericSeparator',
57
+ 'objectRestSpread',
58
+ 'optionalCatchBinding',
59
+ 'optionalChaining',
60
+ ['pipelineOperator', {proposal: 'minimal'}],
61
+ 'throwExpressions',
62
+ 'typescript',
63
+ ],
64
+ });
65
+
66
+ /**
67
+ * Modules parsed in this process, by path, reused while the file is unchanged:
68
+ * one command can ask about the same module more than once.
69
+ * @type {Map<string, {stamp: string, ast: any}>}
70
+ */
71
+ const parsedModules = new Map();
72
+
73
+ /**
74
+ * Module texts read in this process, by path, reused while the file is
75
+ * unchanged.
76
+ * @type {Map<string, {stamp: string, text: string}>}
77
+ */
78
+ const moduleTexts = new Map();
79
+
80
+ /**
81
+ * A file's identity for these caches: size and mtime, plus ctime and inode,
82
+ * which change when a file is rewritten even if npm stamps the same mtime on it.
83
+ * @param {string} file
84
+ */
85
+ function fileStamp(file) {
86
+ const {size, mtimeMs, ctimeMs, ino} = fs.statSync(file);
87
+ return `${size}:${mtimeMs}:${ctimeMs}:${ino}`;
88
+ }
89
+
90
+ /** @param {string} file */
91
+ function moduleText(file) {
92
+ const stamp = fileStamp(file);
93
+ const cached = moduleTexts.get(file);
94
+ if (cached?.stamp === stamp) return cached.text;
95
+ const text = fs.readFileSync(file, 'utf-8');
96
+ moduleTexts.set(file, {stamp, text});
97
+ return text;
98
+ }
99
+
100
+ /** @param {string} file */
101
+ function parseModule(file) {
102
+ const stamp = fileStamp(file);
103
+ const cached = parsedModules.get(file);
104
+ if (cached?.stamp === stamp) return cached.ast;
105
+ const ast = parse(moduleText(file), PARSE_OPTIONS);
106
+ parsedModules.set(file, {stamp, ast});
107
+ return ast;
108
+ }
109
+
110
+ // `export *`: the one way a module exports a name it never writes.
111
+ const EXPORT_ALL_RE = /\bexport\s*\*/;
112
+
113
+ /**
114
+ * Whether `text` has `word` with no identifier character on either side.
115
+ * @param {string} text
116
+ * @param {string} word
117
+ */
118
+ function writesWord(text, word) {
119
+ for (
120
+ let at = text.indexOf(word);
121
+ at !== -1;
122
+ at = text.indexOf(word, at + 1)
123
+ ) {
124
+ const before = text[at - 1] ?? '';
125
+ const after = text[at + word.length] ?? '';
126
+ if (!/[\w$]/.test(before) && !/[\w$]/.test(after)) return true;
127
+ }
128
+ return false;
129
+ }
130
+
131
+ const NOT_CHILDREN = new Set([
132
+ 'loc',
133
+ 'start',
134
+ 'end',
135
+ 'extra',
136
+ 'comments',
137
+ 'leadingComments',
138
+ 'trailingComments',
139
+ 'innerComments',
140
+ ]);
141
+
142
+ /**
143
+ * Every node of `type` in the tree, at any depth, in source order.
144
+ * @param {any} node
145
+ * @param {string} type
146
+ * @param {any[]} [found]
147
+ * @returns {any[]}
148
+ */
149
+ function nodesOfType(node, type, found = []) {
150
+ if (Array.isArray(node)) {
151
+ for (const child of node) nodesOfType(child, type, found);
152
+ return found;
153
+ }
154
+ if (node == null || typeof node !== 'object') return found;
155
+ if (node.type === type) found.push(node);
156
+ for (const key in node) {
157
+ if (NOT_CHILDREN.has(key)) continue;
158
+ const child = node[key];
159
+ if (child != null && typeof child === 'object') {
160
+ nodesOfType(child, type, found);
161
+ }
162
+ }
163
+ return found;
164
+ }
29
165
 
30
166
  /** @param {unknown} specifier @param {string} fromFile */
31
167
  function resolveLocalModule(specifier, fromFile) {
@@ -76,32 +212,56 @@ function runtimeDefault(declaration) {
76
212
  * @param {string} file
77
213
  * @param {string} exportName
78
214
  * @param {Set<string>} [seen]
215
+ * @returns {boolean}
79
216
  */
80
217
  export function moduleExportsName(file, exportName, seen = new Set()) {
218
+ return moduleExportSource(file, exportName, seen) != null;
219
+ }
220
+
221
+ /**
222
+ * The file that declares a module's runtime export, without executing it (the
223
+ * module, or where a local re-export leads); null when it cannot be proved.
224
+ * @param {string} file
225
+ * @param {string} exportName
226
+ * @param {Set<string>} [seen]
227
+ * @returns {string | null}
228
+ */
229
+ export function moduleExportSource(file, exportName, seen = new Set()) {
81
230
  const identity = `${file}\0${exportName}`;
82
- if (seen.has(identity)) return false;
231
+ if (seen.has(identity)) return null;
83
232
  seen.add(identity);
233
+ let text;
84
234
  try {
85
- if (!fs.statSync(file).isFile()) return false;
235
+ if (!fs.statSync(file).isFile()) return null;
236
+ text = moduleText(file);
86
237
  } catch {
87
- return false;
238
+ return null;
239
+ }
240
+ // A module whose text writes neither the export's name as a word nor
241
+ // `export *` cannot export it, so it is not parsed. Any `export *` text, even
242
+ // in a comment, leaves the answer to the parsed tree below.
243
+ if (
244
+ exportName !== 'default' &&
245
+ !writesWord(text, exportName) &&
246
+ !EXPORT_ALL_RE.test(text)
247
+ ) {
248
+ return null;
88
249
  }
89
250
 
90
- let root;
251
+ let ast;
91
252
  try {
92
- root = parser(fs.readFileSync(file, 'utf-8'));
253
+ ast = parseModule(file);
93
254
  } catch {
94
- return false;
255
+ return null;
95
256
  }
96
257
 
97
- let found = false;
98
- root
99
- .find(parser.ExportNamedDeclaration)
100
- .forEach((/** @type {any} */ exportPath) => {
101
- if (found || exportPath.node.exportKind === 'type') return;
102
- const node = exportPath.node;
258
+ /** @type {string | null} */
259
+ let found = null;
260
+ nodesOfType(ast.program, 'ExportNamedDeclaration').forEach(
261
+ (/** @type {any} */ node) => {
262
+ if (found || node.exportKind === 'type') return;
103
263
  if (declarationExports(node.declaration, exportName)) {
104
- found = true;
264
+ found = file;
105
265
  return;
106
266
  }
107
267
  for (const specifier of node.specifiers ?? []) {
@@ -114,33 +274,451 @@ export function moduleExportsName(file, exportName, seen = new Set()) {
114
274
  const exported = specifier.exported?.name ?? specifier.exported?.value;
115
275
  if (exported !== exportName) continue;
116
276
  if (!node.source) {
117
- found = true;
277
+ found = file;
118
278
  return;
119
279
  }
120
280
  const target = resolveLocalModule(node.source.value, file);
121
281
  const imported =
122
282
  specifier.local?.name ?? specifier.local?.value ?? exportName;
123
- if (target && moduleExportsName(target, imported, seen)) {
124
- found = true;
283
+ const declared = target
284
+ ? moduleExportSource(target, imported, seen)
285
+ : null;
286
+ if (declared) {
287
+ found = declared;
125
288
  return;
126
289
  }
127
290
  }
128
- });
129
- if (found) return true;
291
+ },
292
+ );
293
+ if (found) return found;
130
294
 
131
295
  if (exportName === 'default') {
132
- const defaults = root.find(parser.ExportDefaultDeclaration).nodes();
296
+ const defaults = nodesOfType(ast.program, 'ExportDefaultDeclaration');
133
297
  if (defaults.some((/** @type {any} */ node) => runtimeDefault(node.declaration))) {
134
- return true;
298
+ return file;
135
299
  }
136
300
  }
137
301
 
138
- root
139
- .find(parser.ExportAllDeclaration)
140
- .forEach((/** @type {any} */ exportPath) => {
141
- if (found || exportPath.node.exportKind === 'type') return;
142
- const target = resolveLocalModule(exportPath.node.source?.value, file);
143
- if (target && moduleExportsName(target, exportName, seen)) found = true;
144
- });
302
+ nodesOfType(ast.program, 'ExportAllDeclaration').forEach(
303
+ (/** @type {any} */ node) => {
304
+ if (found || node.exportKind === 'type') return;
305
+ const target = resolveLocalModule(node.source?.value, file);
306
+ if (target) found = moduleExportSource(target, exportName, seen);
307
+ },
308
+ );
145
309
  return found;
146
310
  }
311
+
312
+ /**
313
+ * The module's own top-level statements of one type: an `export` inside a
314
+ * TypeScript namespace names a member of that namespace, not of the module.
315
+ * @param {any} program
316
+ * @param {string} type
317
+ * @returns {any[]}
318
+ */
319
+ function topLevel(program, type) {
320
+ return program.body.filter((/** @type {any} */ node) => node.type === type);
321
+ }
322
+
323
+ /**
324
+ * Every runtime name a module exports that this read can see (`default` for
325
+ * a default export), or null when it cannot see them all: an `export *`, `export =`, CommonJS exports, or a
326
+ * file that does not parse.
327
+ * @param {string} file
328
+ * @returns {string[] | null}
329
+ */
330
+ export function moduleExportNames(file) {
331
+ let text;
332
+ let ast;
333
+ try {
334
+ if (!fs.statSync(file).isFile()) return null;
335
+ text = moduleText(file);
336
+ ast = parseModule(file);
337
+ } catch {
338
+ return null;
339
+ }
340
+ if (/\bmodule\.exports\b|\bexports\.[$\w]/u.test(text)) return null;
341
+ if (
342
+ topLevel(ast.program, 'TSExportAssignment').length > 0 ||
343
+ topLevel(ast.program, 'ExportAllDeclaration').length > 0
344
+ ) {
345
+ return null;
346
+ }
347
+ /** @type {Set<string>} */
348
+ const names = new Set();
349
+ for (const node of topLevel(ast.program, 'TSImportEqualsDeclaration')) {
350
+ if (!node.isExport) continue;
351
+ // A type-only alias has no runtime value; any other might.
352
+ if (node.importKind === 'type') continue;
353
+ if (typeof node.id?.name !== 'string') return null;
354
+ names.add(node.id.name);
355
+ }
356
+ for (const node of topLevel(ast.program, 'ExportNamedDeclaration')) {
357
+ if (node.exportKind === 'type') continue;
358
+ const declaration = node.declaration;
359
+ if (declaration?.type === 'VariableDeclaration') {
360
+ for (const item of declaration.declarations) {
361
+ if (item.id?.type !== 'Identifier') return null;
362
+ names.add(item.id.name);
363
+ }
364
+ } else if (declaration != null) {
365
+ if (!runtimeDefault(declaration)) continue;
366
+ if (typeof declaration.id?.name !== 'string') return null;
367
+ names.add(declaration.id.name);
368
+ }
369
+ for (const specifier of node.specifiers ?? []) {
370
+ if (specifier.exportKind === 'type') continue;
371
+ const exported = specifier.exported?.name ?? specifier.exported?.value;
372
+ if (typeof exported === 'string') names.add(exported);
373
+ }
374
+ }
375
+ if (
376
+ topLevel(ast.program, 'ExportDefaultDeclaration').some(
377
+ (/** @type {any} */ node) => runtimeDefault(node.declaration),
378
+ )
379
+ ) {
380
+ names.add('default');
381
+ }
382
+ return [...names].sort();
383
+ }
384
+
385
+ /**
386
+ * @typedef {{verdict: 'exports'} | {verdict: 'lacks'} | {verdict: 'unknown', reason: string}} ExportVerdict
387
+ */
388
+
389
+ /**
390
+ * Whether a module exports `exportName` at runtime, read without executing
391
+ * it: `exports` when a declaration or a followed re-export binds it, `lacks`
392
+ * only when every export the module writes was read and none binds it, and
393
+ * `unknown`, with the first reason, when some export could not be read: a
394
+ * re-export from another package or from a specifier that resolves to no
395
+ * file, a destructured binding, a namespace, an ambient or const enum
396
+ * declaration, `export =`, CommonJS exports, or a file that does not parse.
397
+ * @param {string} file
398
+ * @param {string} exportName
399
+ * @param {Set<string>} [seen]
400
+ * @returns {ExportVerdict}
401
+ */
402
+ export function moduleExportVerdict(file, exportName, seen = new Set()) {
403
+ const identity = `${file}\0${exportName}`;
404
+ // A cycle adds nothing a module's own exports have not already said.
405
+ if (seen.has(identity)) return {verdict: 'lacks'};
406
+ seen.add(identity);
407
+ const shown = path.basename(file);
408
+ let text;
409
+ let ast;
410
+ try {
411
+ if (!fs.statSync(file).isFile()) {
412
+ return {verdict: 'unknown', reason: `${shown} is not a file.`};
413
+ }
414
+ text = moduleText(file);
415
+ ast = parseModule(file);
416
+ } catch {
417
+ return {
418
+ verdict: 'unknown',
419
+ reason: `${shown} could not be read or parsed.`,
420
+ };
421
+ }
422
+ /** @type {string[]} */
423
+ const unknown = [];
424
+ if (/\bmodule\.exports\b|\bexports\.[$\w]/u.test(text)) {
425
+ unknown.push(
426
+ `${shown} uses CommonJS exports, whose names this check does not read.`,
427
+ );
428
+ }
429
+ if (topLevel(ast.program, 'TSExportAssignment').length > 0) {
430
+ unknown.push(`${shown} uses \`export =\`, whose names this check does not read.`);
431
+ }
432
+ /**
433
+ * Follow a re-export of `imported` from `specifier`.
434
+ * @param {string} specifier
435
+ * @param {string} imported
436
+ * @param {string} what how the reason names what is re-exported
437
+ * @returns {boolean} true when it proves the export
438
+ */
439
+ const follow = (specifier, imported, what) => {
440
+ if (!specifier.startsWith('.')) {
441
+ unknown.push(
442
+ `${shown} re-exports ${what} from "${specifier}", another package this check does not read.`,
443
+ );
444
+ return false;
445
+ }
446
+ const target = resolveLocalModule(specifier, file);
447
+ if (!target) {
448
+ unknown.push(
449
+ `${shown} re-exports ${what} from "${specifier}", which resolves to no file this check can read.`,
450
+ );
451
+ return false;
452
+ }
453
+ const inner = moduleExportVerdict(target, imported, seen);
454
+ if (inner.verdict === 'exports') return true;
455
+ if (inner.verdict === 'unknown') unknown.push(inner.reason);
456
+ return false;
457
+ };
458
+ // `export import Name = Some.Path;` binds a runtime value unless it is
459
+ // type-only.
460
+ for (const node of topLevel(ast.program, 'TSImportEqualsDeclaration')) {
461
+ if (!node.isExport || node.id?.name !== exportName) continue;
462
+ if (node.importKind === 'type') {
463
+ unknown.push(
464
+ `${shown} exports ${exportName} with \`export import type\`, which has no runtime value this check can see.`,
465
+ );
466
+ } else {
467
+ return {verdict: 'exports'};
468
+ }
469
+ }
470
+ for (const node of topLevel(ast.program, 'ExportNamedDeclaration')) {
471
+ if (node.exportKind === 'type') continue;
472
+ const declaration = node.declaration;
473
+ if (declaration?.type === 'VariableDeclaration') {
474
+ for (const item of declaration.declarations) {
475
+ if (item.id?.type !== 'Identifier') {
476
+ unknown.push(
477
+ `${shown} exports a destructured binding, whose names this check does not read.`,
478
+ );
479
+ } else if (item.id.name === exportName) {
480
+ if (declaration.declare === true) {
481
+ unknown.push(
482
+ `${shown} declares ${exportName} with \`declare\`, which has no runtime value this check can see.`,
483
+ );
484
+ } else {
485
+ return {verdict: 'exports'};
486
+ }
487
+ }
488
+ }
489
+ } else if (declaration != null && declaration.id?.name === exportName) {
490
+ if (
491
+ ['TSInterfaceDeclaration', 'TSTypeAliasDeclaration'].includes(
492
+ declaration.type,
493
+ )
494
+ ) {
495
+ // A type only: no runtime export.
496
+ } else if (declaration.type === 'TSModuleDeclaration') {
497
+ unknown.push(
498
+ `${shown} exports ${exportName} as a TypeScript namespace, which has a runtime value only when it holds one.`,
499
+ );
500
+ } else if (declaration.declare === true || declaration.const === true) {
501
+ unknown.push(
502
+ `${shown} declares ${exportName} as an ambient or const declaration, which has no runtime value this check can see.`,
503
+ );
504
+ } else if (runtimeDefault(declaration)) {
505
+ return {verdict: 'exports'};
506
+ }
507
+ }
508
+ for (const specifier of node.specifiers ?? []) {
509
+ if (specifier.exportKind === 'type') continue;
510
+ const exported = specifier.exported?.name ?? specifier.exported?.value;
511
+ if (exported !== exportName) continue;
512
+ if (!node.source || specifier.type === 'ExportNamespaceSpecifier') {
513
+ return {verdict: 'exports'};
514
+ }
515
+ if (specifier.type !== 'ExportSpecifier') {
516
+ unknown.push(`${shown} re-exports ${exportName} in a form this check does not read.`);
517
+ continue;
518
+ }
519
+ const imported =
520
+ specifier.local?.name ?? specifier.local?.value ?? exportName;
521
+ if (follow(String(node.source.value), imported, exportName)) {
522
+ return {verdict: 'exports'};
523
+ }
524
+ }
525
+ }
526
+ if (exportName === 'default') {
527
+ const defaults = topLevel(ast.program, 'ExportDefaultDeclaration');
528
+ if (
529
+ defaults.some((/** @type {any} */ node) =>
530
+ runtimeDefault(node.declaration),
531
+ )
532
+ ) {
533
+ return {verdict: 'exports'};
534
+ }
535
+ }
536
+ for (const node of topLevel(ast.program, 'ExportAllDeclaration')) {
537
+ if (node.exportKind === 'type') continue;
538
+ const exported = node.exported?.name ?? node.exported?.value;
539
+ if (exported != null) {
540
+ if (exported === exportName) return {verdict: 'exports'};
541
+ continue;
542
+ }
543
+ // `export *` never re-exports a default.
544
+ if (exportName === 'default') continue;
545
+ if (follow(String(node.source?.value ?? ''), exportName, 'everything')) {
546
+ return {verdict: 'exports'};
547
+ }
548
+ }
549
+ return unknown.length > 0
550
+ ? {verdict: 'unknown', reason: unknown[0]}
551
+ : {verdict: 'lacks'};
552
+ }
553
+
554
+ /**
555
+ * Whether a module provably does not export `exportName` at runtime: see
556
+ * {@link moduleExportVerdict}.
557
+ * @param {string} file
558
+ * @param {string} exportName
559
+ * @returns {boolean}
560
+ */
561
+ export function moduleLacksExport(file, exportName) {
562
+ return moduleExportVerdict(file, exportName).verdict === 'lacks';
563
+ }
564
+
565
+ /**
566
+ * Marks an object {@link staticExportObject} returns (or one inside it) whose
567
+ * source also has properties or spreads it could not read as literals. Not
568
+ * enumerable, so the object compares and serializes as its literal properties.
569
+ */
570
+ export const HAS_COMPUTED = Symbol('hasComputed');
571
+
572
+ const TS_WRAPPERS = new Set([
573
+ 'TSSatisfiesExpression',
574
+ 'TSAsExpression',
575
+ 'TSNonNullExpression',
576
+ 'ParenthesizedExpression',
577
+ ]);
578
+
579
+ /** @param {any} node */
580
+ function withoutTypeWrappers(node) {
581
+ let current = node;
582
+ while (current && TS_WRAPPERS.has(current.type)) current = current.expression;
583
+ return current;
584
+ }
585
+
586
+ /**
587
+ * The object a module exports, as plain data, read without running it: the
588
+ * first of `exportNames` it exports, an object literal in place or a top-level
589
+ * binding (under `satisfies` or `as` too). Only literal values are kept;
590
+ * anything computed, or overridable by a later spread, is left out.
591
+ *
592
+ * @param {string} file
593
+ * @param {readonly string[]} exportNames `default` or named exports, in order
594
+ * @returns {Record<string, unknown> | null}
595
+ */
596
+ export function staticExportObject(file, exportNames) {
597
+ /** @type {any[]} */
598
+ let body;
599
+ try {
600
+ body = parseModule(file).program.body;
601
+ } catch {
602
+ return null;
603
+ }
604
+
605
+ /** @type {Map<string, any>} top-level bindings to their initializers */
606
+ const bindings = new Map();
607
+ for (const statement of body) {
608
+ const declaration =
609
+ statement.type === 'ExportNamedDeclaration'
610
+ ? statement.declaration
611
+ : statement;
612
+ if (declaration?.type !== 'VariableDeclaration') continue;
613
+ for (const declarator of declaration.declarations) {
614
+ if (declarator.id?.type === 'Identifier' && declarator.init) {
615
+ bindings.set(declarator.id.name, declarator.init);
616
+ }
617
+ }
618
+ }
619
+
620
+ /** @param {string} name @returns {any} undefined when not exported */
621
+ const exported = name => {
622
+ for (const statement of body) {
623
+ if (name === 'default' && statement.type === 'ExportDefaultDeclaration') {
624
+ return statement.declaration;
625
+ }
626
+ if (
627
+ statement.type !== 'ExportNamedDeclaration' ||
628
+ statement.exportKind === 'type'
629
+ ) {
630
+ continue;
631
+ }
632
+ if (statement.declaration?.type === 'VariableDeclaration') {
633
+ const declarator = statement.declaration.declarations.find(
634
+ (/** @type {any} */ item) =>
635
+ item.id?.type === 'Identifier' && item.id.name === name,
636
+ );
637
+ if (declarator) return declarator.init ?? null;
638
+ }
639
+ if (statement.source) continue;
640
+ for (const specifier of statement.specifiers ?? []) {
641
+ const as = specifier.exported?.name ?? specifier.exported?.value;
642
+ if (specifier.type === 'ExportSpecifier' && as === name) {
643
+ return {type: 'Identifier', name: specifier.local?.name};
644
+ }
645
+ }
646
+ }
647
+ return undefined;
648
+ };
649
+
650
+ /**
651
+ * @param {any} node
652
+ * @param {Set<string>} following bindings being followed, against cycles
653
+ * @returns {unknown} undefined when the value is not a literal
654
+ */
655
+ const literal = (node, following) => {
656
+ const value = withoutTypeWrappers(node);
657
+ switch (value?.type) {
658
+ case 'StringLiteral':
659
+ case 'NumericLiteral':
660
+ case 'BooleanLiteral':
661
+ return value.value;
662
+ case 'NullLiteral':
663
+ return null;
664
+ case 'TemplateLiteral':
665
+ return value.expressions.length === 0
666
+ ? value.quasis[0]?.value.cooked
667
+ : undefined;
668
+ case 'Identifier': {
669
+ if (!bindings.has(value.name) || following.has(value.name)) {
670
+ return undefined;
671
+ }
672
+ const next = new Set(following).add(value.name);
673
+ return literal(bindings.get(value.name), next);
674
+ }
675
+ case 'ArrayExpression':
676
+ return value.elements
677
+ .map((/** @type {any} */ element) =>
678
+ element == null || element.type === 'SpreadElement'
679
+ ? undefined
680
+ : literal(element, following),
681
+ )
682
+ .filter((/** @type {unknown} */ item) => item !== undefined);
683
+ case 'ObjectExpression': {
684
+ /** @type {Record<string, unknown>} */
685
+ let object = {};
686
+ let computed = false;
687
+ for (const property of value.properties) {
688
+ if (property.type === 'SpreadElement') {
689
+ object = {};
690
+ computed = true;
691
+ continue;
692
+ }
693
+ const key = property.computed
694
+ ? undefined
695
+ : (property.key?.name ?? property.key?.value);
696
+ const item =
697
+ typeof key === 'string' && property.type === 'ObjectProperty'
698
+ ? literal(property.value, following)
699
+ : undefined;
700
+ if (item === undefined) computed = true;
701
+ if (typeof key !== 'string') continue;
702
+ if (item === undefined) delete object[key];
703
+ else object[key] = item;
704
+ }
705
+ if (computed) {
706
+ Object.defineProperty(object, HAS_COMPUTED, {value: true});
707
+ }
708
+ return object;
709
+ }
710
+ default:
711
+ return undefined;
712
+ }
713
+ };
714
+
715
+ for (const exportName of exportNames) {
716
+ const node = exported(exportName);
717
+ if (node === undefined) continue;
718
+ const value = literal(node, new Set());
719
+ return value != null && typeof value === 'object' && !Array.isArray(value)
720
+ ? /** @type {Record<string, unknown>} */ (value)
721
+ : null;
722
+ }
723
+ return null;
724
+ }