@astryxdesign/cli 0.6.3 → 0.6.4-canary.06c8fa3

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 (670) hide show
  1. package/CHANGELOG.md +194 -0
  2. package/README.md +121 -85
  3. package/api/blog/blog.doc.mjs +1 -0
  4. package/api/build/_adapter.d.mts +50 -0
  5. package/api/build/_adapter.mjs +60 -0
  6. package/api/build/build.doc.mjs +16 -9
  7. package/api/build/build.test.mjs +197 -8
  8. package/api/build/build.type.d.mts +91 -2
  9. package/api/build/build.type.mjs +52 -8
  10. package/api/build/help/help.d.mts +12 -5
  11. package/api/build/help/help.mjs +69 -6
  12. package/api/build/kit/kit.d.mts +4 -1
  13. package/api/build/kit/kit.mjs +165 -49
  14. package/api/build/kit/rank.d.mts +44 -0
  15. package/api/build/kit/rank.mjs +432 -0
  16. package/api/build/kit/rank.test.mjs +196 -0
  17. package/api/component/_adapter.d.mts +31 -12
  18. package/api/component/_adapter.mjs +79 -15
  19. package/api/component/component.d.mts +6 -3
  20. package/api/component/component.doc.mjs +36 -13
  21. package/api/component/component.mjs +339 -22
  22. package/api/component/component.test.mjs +38 -0
  23. package/api/component/component.type.d.mts +47 -11
  24. package/api/component/component.type.mjs +76 -24
  25. package/api/component/detail/blocks/blocks.d.mts +2 -1
  26. package/api/component/detail/blocks/blocks.mjs +4 -3
  27. package/api/component/list/list.d.mts +0 -5
  28. package/api/component/list/list.mjs +40 -11
  29. package/api/discover/_adapter.d.mts +114 -6
  30. package/api/discover/_adapter.mjs +372 -17
  31. package/api/discover/_adapter.test.mjs +215 -0
  32. package/api/discover/_catalog-view.d.mts +115 -0
  33. package/api/discover/_catalog-view.mjs +203 -0
  34. package/api/discover/_catalog-view.test.mjs +128 -0
  35. package/api/discover/detail/detail.d.mts +18 -6
  36. package/api/discover/detail/detail.mjs +67 -13
  37. package/api/discover/detail/detail.test.mjs +85 -0
  38. package/api/discover/detail/item/item.d.mts +26 -0
  39. package/api/discover/detail/item/item.mjs +78 -0
  40. package/api/discover/detail/item/item.test.mjs +73 -0
  41. package/api/discover/discover.d.mts +3 -9
  42. package/api/discover/discover.doc.mjs +62 -18
  43. package/api/discover/discover.mjs +220 -36
  44. package/api/discover/discover.test.mjs +11 -2
  45. package/api/discover/discover.type.d.mts +150 -11
  46. package/api/discover/discover.type.mjs +107 -17
  47. package/api/discover/list/list.d.mts +20 -6
  48. package/api/discover/list/list.mjs +45 -12
  49. package/api/discover/list/list.test.mjs +46 -0
  50. package/api/discover/search/search.d.mts +18 -16
  51. package/api/discover/search/search.mjs +102 -56
  52. package/api/discover/search/search.test.mjs +144 -10
  53. package/api/docs/_adapter.d.mts +272 -41
  54. package/api/docs/_adapter.mjs +985 -108
  55. package/api/docs/compiled-topics.test.mjs +78 -0
  56. package/api/docs/detail/detail.mjs +22 -63
  57. package/api/docs/detail/section/section.d.mts +1 -1
  58. package/api/docs/detail/section/section.mjs +54 -19
  59. package/api/docs/detail/section/section.test.mjs +50 -0
  60. package/api/docs/docs.d.mts +10 -3
  61. package/api/docs/docs.doc.mjs +55 -16
  62. package/api/docs/docs.mjs +53 -10
  63. package/api/docs/docs.test.mjs +166 -4
  64. package/api/docs/docs.type.d.mts +221 -5
  65. package/api/docs/docs.type.mjs +153 -11
  66. package/api/docs/index/index.d.mts +18 -0
  67. package/api/docs/index/index.mjs +40 -0
  68. package/api/docs/index/index.test.mjs +62 -0
  69. package/api/docs/integration-tree.test.mjs +555 -0
  70. package/api/docs/integrationDocs.test.mjs +114 -8
  71. package/api/docs/list/list.mjs +28 -12
  72. package/api/docs/node/node.d.mts +43 -0
  73. package/api/docs/node/node.mjs +192 -0
  74. package/api/docs/reference-blocks.test.mjs +406 -0
  75. package/api/doctor/doctor.d.mts +104 -1
  76. package/api/doctor/doctor.doc.mjs +1 -0
  77. package/api/doctor/doctor.mjs +635 -7
  78. package/api/doctor/doctor.test.mjs +732 -11
  79. package/api/gap-report/gap-report.doc.mjs +8 -4
  80. package/api/hook/_adapter.mjs +19 -5
  81. package/api/hook/hook.doc.mjs +1 -0
  82. package/api/hook/hook.type.d.mts +3 -3
  83. package/api/hook/hook.type.mjs +11 -11
  84. package/api/hook/list/list.d.mts +2 -2
  85. package/api/hook/list/list.mjs +69 -17
  86. package/api/index.d.mts +2 -3
  87. package/api/index.mjs +5 -4
  88. package/api/init/init.doc.mjs +6 -1
  89. package/api/init/init.test.mjs +41 -1
  90. package/api/init/remove/remove.mjs +1 -1
  91. package/api/init/run/run.mjs +20 -10
  92. package/api/integration/add-contribution.component-names.test.mjs +120 -0
  93. package/api/integration/add-contribution.d.mts +2 -1
  94. package/api/integration/add-contribution.mjs +130 -15
  95. package/api/integration/add-contribution.test.mjs +258 -7
  96. package/api/integration/add-helpers.d.mts +5 -2
  97. package/api/integration/add-helpers.mjs +36 -9
  98. package/api/integration/add-theme.mjs +34 -64
  99. package/api/integration/add-theme.test.mjs +105 -21
  100. package/api/integration/authoring-checks.mjs +138 -28
  101. package/api/integration/authoring-checks.test.mjs +179 -7
  102. package/api/integration/authoring-checks.type.mjs +6 -1
  103. package/api/integration/integration-authoring.type.d.mts +3 -1
  104. package/api/integration/integration-authoring.type.mjs +2 -0
  105. package/api/integration/integration-block-exports.test.mjs +10 -6
  106. package/api/integration/integrationAdd.doc.mjs +14 -4
  107. package/api/integration/integrationAddAgentDoc.doc.mjs +1 -0
  108. package/api/integration/integrationAddCodemod.doc.mjs +1 -0
  109. package/api/integration/integrationAddComponent.doc.mjs +2 -1
  110. package/api/integration/integrationAddDoc.doc.mjs +8 -1
  111. package/api/integration/integrationAddTemplate.doc.mjs +1 -0
  112. package/api/integration/integrationAddTheme.doc.mjs +6 -5
  113. package/api/integration/integrationComponentConflicts.doc.mjs +1 -0
  114. package/api/integration/integrationDocConflicts.doc.mjs +2 -1
  115. package/api/integration/integrationPackCheck.doc.mjs +2 -1
  116. package/api/integration/integrationTemplateConflicts.doc.d.mts +3 -0
  117. package/api/integration/integrationTemplateConflicts.doc.mjs +4 -0
  118. package/api/integration/pack-check.lifecycle-output.test.mjs +105 -0
  119. package/api/integration/pack-check.mjs +111 -10
  120. package/api/integration/pack-check.test.mjs +387 -47
  121. package/api/integration/pack-check.type.d.mts +26 -2
  122. package/api/integration/pack-check.type.mjs +14 -1
  123. package/api/integration/summarizeIssues.doc.mjs +1 -0
  124. package/api/integration/template-conflict-compatibility.test.mjs +73 -0
  125. package/api/integration/validate-integration-fixes.test.mjs +1389 -0
  126. package/api/integration/validate-integration.mjs +52 -102
  127. package/api/integration/validate-integration.test.mjs +179 -26
  128. package/api/integration/validate-unread-theme-folders.test.mjs +110 -0
  129. package/api/integration/validateIntegration.doc.mjs +3 -2
  130. package/api/json/assertResponse.doc.mjs +1 -0
  131. package/api/json/envelope-types.test.mjs +76 -0
  132. package/api/json/index.ts +2 -1
  133. package/api/json/isError.doc.mjs +1 -0
  134. package/api/json/parseResponse.doc.mjs +3 -2
  135. package/api/search/search-return-type.test.mjs +54 -0
  136. package/api/search/search.d.mts +62 -11
  137. package/api/search/search.doc.mjs +8 -2
  138. package/api/search/search.mjs +471 -83
  139. package/api/search/search.test.mjs +142 -1
  140. package/api/search/search.type.d.mts +15 -3
  141. package/api/search/search.type.mjs +5 -2
  142. package/api/swizzle/copy/copy.mjs +28 -11
  143. package/api/swizzle/swizzle.doc.mjs +2 -1
  144. package/api/swizzle/swizzle.type.d.mts +2 -2
  145. package/api/swizzle/swizzle.type.mjs +2 -2
  146. package/api/template/copy/copy.mjs +17 -23
  147. package/api/template/copy/copy.test.mjs +17 -0
  148. package/api/template/list/list.mjs +1 -0
  149. package/api/template/table-floating-bulk-actions.test.mjs +66 -0
  150. package/api/template/template-integration.test.mjs +1008 -3
  151. package/api/template/template-suffix.test.mjs +41 -21
  152. package/api/template/template.d.mts +1 -1
  153. package/api/template/template.doc.mjs +30 -8
  154. package/api/template/template.mjs +46 -9
  155. package/api/template/template.type.d.mts +12 -14
  156. package/api/template/template.type.mjs +15 -14
  157. package/api/theme/_adapter.d.mts +2 -3
  158. package/api/theme/_adapter.mjs +4 -5
  159. package/api/theme/add/add.binary.test.mjs +84 -0
  160. package/api/theme/add/add.mjs +31 -22
  161. package/api/theme/add/add.rollback.test.mjs +158 -0
  162. package/api/theme/add/add.staging.test.mjs +83 -0
  163. package/api/theme/add/add.test.mjs +14 -1
  164. package/api/theme/build/build.family.test.mjs +7 -12
  165. package/api/theme/build/build.mjs +140 -59
  166. package/api/theme/build/build.public-component-vars.test.mjs +1 -1
  167. package/api/theme/build/build.receipt-doc.test.mjs +111 -0
  168. package/api/theme/build/build.rollback.test.mjs +148 -0
  169. package/api/theme/build/build.test.mjs +127 -0
  170. package/api/theme/build/font-warning.mjs +3 -3
  171. package/api/theme/build/font-warning.test.mjs +5 -2
  172. package/api/theme/generateTonalPalette.doc.mjs +1 -0
  173. package/api/theme/integration-themes.test.mjs +39 -28
  174. package/api/theme/list/list.test.mjs +19 -20
  175. package/api/theme/listThemes.doc.mjs +6 -5
  176. package/api/theme/palette/generate/generate.mjs +8 -3
  177. package/api/theme/palette/generate/generate.test.mjs +96 -0
  178. package/api/theme/palette/generate/generator.d.mts +10 -13
  179. package/api/theme/palette/generate/generator.mjs +15 -4
  180. package/api/theme/palette/generate/generator.test.mjs +10 -0
  181. package/api/theme/template/template.mjs +11 -2
  182. package/api/theme/template/template.test.mjs +20 -0
  183. package/api/theme/theme.type.d.mts +170 -11
  184. package/api/theme/theme.type.mjs +94 -27
  185. package/api/theme/themeAdd.doc.mjs +4 -3
  186. package/api/theme/themeBuild.doc.mjs +8 -4
  187. package/api/theme/themeList.doc.mjs +6 -3
  188. package/api/theme/themeListAvailable.doc.mjs +5 -3
  189. package/api/theme/themePaletteGenerate.doc.mjs +1 -0
  190. package/api/theme/themeTargets.doc.mjs +1 -0
  191. package/api/theme/themeTemplate.doc.mjs +6 -2
  192. package/api/upgrade/_adapter.d.mts +32 -5
  193. package/api/upgrade/_adapter.mjs +139 -22
  194. package/api/upgrade/list/list.mjs +2 -1
  195. package/api/upgrade/list/list.test.mjs +73 -0
  196. package/api/upgrade/project-context.test.mjs +272 -0
  197. package/api/upgrade/provider-agreement.test.mjs +152 -0
  198. package/api/upgrade/run/files-changed.test.mjs +111 -0
  199. package/api/upgrade/run/run.mjs +359 -60
  200. package/api/upgrade/status/status.mjs +2 -2
  201. package/api/upgrade/upgrade.doc.mjs +12 -5
  202. package/api/upgrade/upgrade.type.d.mts +43 -5
  203. package/api/upgrade/upgrade.type.mjs +29 -13
  204. package/assets/codemods/__tests__/registry.test.mjs +1 -0
  205. package/assets/codemods/__tests__/runner.test.mjs +332 -8
  206. package/assets/codemods/file-count.test.mjs +163 -0
  207. package/assets/codemods/integration-discovery.mjs +48 -4
  208. package/assets/codemods/integration-discovery.test.mjs +73 -0
  209. package/assets/codemods/integration-runner.mjs +59 -7
  210. package/assets/codemods/integration-runner.protection.test.mjs +153 -0
  211. package/assets/codemods/registry.mjs +1 -0
  212. package/assets/codemods/run-codemod.mjs +177 -34
  213. package/assets/codemods/runner.mjs +353 -104
  214. package/assets/codemods/term-log.mjs +32 -8
  215. package/assets/codemods/term-log.test.mjs +19 -1
  216. package/assets/codemods/transform-prop.mjs +109 -0
  217. package/assets/codemods/transform-prop.test.mjs +95 -0
  218. package/assets/codemods/transforms/v0.0.14/__tests__/rename-status-variants.test.mjs +86 -165
  219. package/assets/codemods/transforms/v0.0.14/rename-status-variants.mjs +72 -210
  220. package/assets/codemods/transforms/v0.1.8/__tests__/rename-avatar-size-scale.test.mjs +83 -115
  221. package/assets/codemods/transforms/v0.1.8/rename-avatar-size-scale.mjs +57 -186
  222. package/assets/codemods/transforms/v0.3.0/__tests__/unwrap-authoring-factories.test.mjs +27 -5
  223. package/assets/codemods/transforms/v0.3.0/unwrap-authoring-factories.mjs +20 -5
  224. package/assets/codemods/transforms/v0.6.0/__tests__/next-codemods.test.mjs +47 -0
  225. package/assets/codemods/transforms/v0.6.0/rename-resizable-pixel-bounds.mjs +57 -10
  226. package/assets/codemods/transforms/v0.6.4/__tests__/migrate-native-picker-to-presentation.test.mjs +63 -0
  227. package/assets/codemods/transforms/v0.6.4/__tests__/migrate-theme-catalog-to-descriptors.test.mjs +220 -0
  228. package/assets/codemods/transforms/v0.6.4/index.mjs +31 -0
  229. package/assets/codemods/transforms/v0.6.4/migrate-native-picker-to-presentation.mjs +148 -0
  230. package/assets/codemods/transforms/v0.6.4/migrate-theme-catalog-to-descriptors.mjs +141 -0
  231. package/assets/docs/README.md +9 -0
  232. package/assets/docs/authoring.doc.mjs +14 -0
  233. package/assets/docs/getting-started.doc.mjs +2 -2
  234. package/assets/docs/internationalization.doc.mjs +7 -5
  235. package/assets/docs/layout.doc.dense.mjs +2 -2
  236. package/assets/docs/layout.doc.mjs +1 -1
  237. package/assets/docs/principles.doc.mjs +6 -6
  238. package/assets/docs/styling-libraries.doc.mjs +4 -4
  239. package/assets/docs/styling.doc.mjs +4 -4
  240. package/assets/docs/theme.doc.mjs +5 -5
  241. package/assets/docs/tokens.doc.mjs +1 -1
  242. package/assets/docs/tree/api.doc.mjs +30 -0
  243. package/assets/docs/tree/cli.doc.mjs +23 -0
  244. package/assets/docs/tree/commands.doc.mjs +25 -0
  245. package/assets/docs/tree/component-lookups.doc.mjs +149 -0
  246. package/assets/docs/{cli-integrations.doc.mjs → tree/integrations.doc.mjs} +144 -26
  247. package/assets/docs/tree/integrations.test.mjs +62 -0
  248. package/assets/docs/tree/writing-docs.doc.mjs +286 -0
  249. package/assets/docs/working-with-ai.doc.mjs +4 -4
  250. package/assets/templates/blocks/components/CheckboxList/CheckboxListSelectAllPattern.doc.mjs +1 -1
  251. package/assets/templates/blocks/components/CheckboxList/CheckboxListSelectAllPattern.tsx +1 -3
  252. package/assets/templates/blocks/components/DateInput/DateInputDateRange.tsx +1 -1
  253. package/assets/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.tsx +1 -1
  254. package/assets/templates/blocks/components/Item/ItemDocumentTabs.doc.mjs +14 -0
  255. package/assets/templates/blocks/components/Item/ItemDocumentTabs.tsx +100 -0
  256. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.doc.mjs +14 -0
  257. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.tsx +61 -0
  258. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.doc.mjs +14 -0
  259. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.tsx +126 -0
  260. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.doc.mjs +15 -0
  261. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.tsx +86 -0
  262. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.doc.mjs +14 -0
  263. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.tsx +99 -0
  264. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.doc.mjs +14 -0
  265. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.tsx +122 -0
  266. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.doc.mjs +14 -0
  267. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.tsx +95 -0
  268. package/assets/templates/blocks/components/Table/TableBulkActionsTable.doc.mjs +14 -0
  269. package/assets/templates/blocks/components/Table/TableBulkActionsTable.tsx +71 -0
  270. package/assets/templates/blocks/components/Table/TableFloatingBulkActionsTable.doc.mjs +19 -0
  271. package/assets/templates/blocks/components/Table/TableFloatingBulkActionsTable.tsx +139 -0
  272. package/assets/templates/blocks/components/TimeInput/TimeInputConstrained.tsx +1 -0
  273. package/assets/templates/blocks/components/Timer/TimerFormats.doc.mjs +14 -0
  274. package/assets/templates/blocks/components/Timer/TimerFormats.tsx +34 -0
  275. package/assets/templates/blocks/components/Timer/TimerInline.doc.mjs +14 -0
  276. package/assets/templates/blocks/components/Timer/TimerInline.tsx +14 -0
  277. package/assets/templates/blocks/components/Timer/TimerShowcase.doc.mjs +13 -0
  278. package/assets/templates/blocks/components/Timer/TimerShowcase.tsx +47 -0
  279. package/assets/templates/blocks/components/Timer/TimerTypography.doc.mjs +14 -0
  280. package/assets/templates/blocks/components/Timer/TimerTypography.tsx +31 -0
  281. package/assets/templates/blocks/components/Toolbar/ToolbarTableFilter.doc.mjs +19 -3
  282. package/assets/templates/blocks/components/Toolbar/ToolbarTableFilter.tsx +383 -65
  283. package/assets/templates/pages/table-tree/page.tsx +1704 -0
  284. package/assets/templates/pages/table-tree/template.doc.mjs +12 -0
  285. package/assets/templates/themes/butter/butterTheme.doc.mjs +11 -0
  286. package/assets/templates/themes/chocolate/chocolateTheme.doc.mjs +11 -0
  287. package/assets/templates/themes/gothic/gothicTheme.doc.mjs +11 -0
  288. package/assets/templates/themes/matcha/matchaTheme.doc.mjs +11 -0
  289. package/assets/templates/themes/neutral/neutralTheme.doc.mjs +11 -0
  290. package/assets/templates/themes/stone/stoneTheme.doc.mjs +11 -0
  291. package/assets/templates/themes/y2k/y2kTheme.doc.mjs +11 -0
  292. package/authoring/_shared/contract.ts +22 -0
  293. package/authoring/codemod/codemod.doc.mjs +7 -2
  294. package/authoring/codemod/parse.d.mts +8 -8
  295. package/authoring/codemod/parse.mjs +8 -6
  296. package/authoring/codemod/type.ts +12 -0
  297. package/authoring/config/config.doc.mjs +11 -3
  298. package/authoring/config/debug-composition.test.mjs +92 -0
  299. package/authoring/config/parse.d.mts +15 -13
  300. package/authoring/config/parse.mjs +27 -8
  301. package/authoring/config/parse.test.mjs +8 -0
  302. package/authoring/config/type.ts +31 -8
  303. package/authoring/debug/debug.doc.d.mts +11 -0
  304. package/authoring/debug/debug.doc.mjs +182 -0
  305. package/authoring/debug/parse.d.mts +8 -8
  306. package/authoring/debug/parse.mjs +3 -3
  307. package/authoring/discover/discover.doc.d.mts +13 -0
  308. package/authoring/discover/discover.doc.mjs +138 -0
  309. package/authoring/discover/parse.d.mts +24 -0
  310. package/authoring/discover/parse.mjs +128 -0
  311. package/authoring/discover/parse.test.mjs +124 -0
  312. package/authoring/discover/type.ts +87 -0
  313. package/authoring/doctypes/_schema.d.mts +790 -23
  314. package/authoring/doctypes/_schema.mjs +543 -39
  315. package/authoring/doctypes/base/graph-fields.doc.d.mts +9 -0
  316. package/authoring/doctypes/base/graph-fields.doc.mjs +64 -0
  317. package/authoring/doctypes/base/type.ts +41 -0
  318. package/authoring/doctypes/command/command.doc.mjs +5 -4
  319. package/authoring/doctypes/command/parse.d.mts +2 -2
  320. package/authoring/doctypes/command/parse.mjs +1 -1
  321. package/authoring/doctypes/command/type.ts +6 -5
  322. package/authoring/doctypes/component/component.doc.mjs +6 -3
  323. package/authoring/doctypes/component/parse.d.mts +2 -2
  324. package/authoring/doctypes/component/parse.mjs +1 -1
  325. package/authoring/doctypes/component/type.ts +6 -5
  326. package/authoring/doctypes/doctypes-new.test.mjs +48 -6
  327. package/authoring/doctypes/enum/enum.doc.mjs +1 -1
  328. package/authoring/doctypes/enum/parse.d.mts +2 -2
  329. package/authoring/doctypes/enum/parse.mjs +1 -1
  330. package/authoring/doctypes/enum/type.ts +4 -2
  331. package/authoring/doctypes/function/function.doc.mjs +7 -2
  332. package/authoring/doctypes/function/parse.d.mts +2 -2
  333. package/authoring/doctypes/function/parse.mjs +1 -1
  334. package/authoring/doctypes/function/type.ts +9 -4
  335. package/authoring/doctypes/hook/hook.doc.mjs +4 -0
  336. package/authoring/doctypes/hook/parse.d.mts +2 -2
  337. package/authoring/doctypes/hook/parse.mjs +1 -1
  338. package/authoring/doctypes/hook/type.ts +5 -4
  339. package/authoring/doctypes/legacy.d.mts +8 -6
  340. package/authoring/doctypes/legacy.mjs +5 -4
  341. package/authoring/doctypes/load-contract.test.mjs +233 -0
  342. package/authoring/doctypes/namespace/namespace.doc.d.mts +9 -0
  343. package/authoring/doctypes/namespace/namespace.doc.mjs +128 -0
  344. package/authoring/doctypes/namespace/parse.d.mts +12 -0
  345. package/authoring/doctypes/namespace/parse.mjs +25 -0
  346. package/authoring/doctypes/namespace/parse.test.mjs +163 -0
  347. package/authoring/doctypes/namespace/type.ts +74 -0
  348. package/authoring/doctypes/parse.d.mts +22 -18
  349. package/authoring/doctypes/parse.mjs +22 -11
  350. package/authoring/doctypes/parse.test.mjs +77 -3
  351. package/authoring/doctypes/reference/parse.d.mts +2 -2
  352. package/authoring/doctypes/reference/parse.mjs +8 -5
  353. package/authoring/doctypes/reference/reference.doc.mjs +48 -6
  354. package/authoring/doctypes/reference/type.ts +70 -7
  355. package/authoring/doctypes/schema/parse.d.mts +2 -2
  356. package/authoring/doctypes/schema/parse.mjs +1 -1
  357. package/authoring/doctypes/schema/schema.doc.mjs +1 -1
  358. package/authoring/doctypes/schema/type.ts +4 -4
  359. package/authoring/doctypes/template/parse.d.mts +94 -1
  360. package/authoring/doctypes/template/parse.mjs +40 -2
  361. package/authoring/doctypes/template/parse.test.mjs +26 -2
  362. package/authoring/doctypes/template/template.doc.mjs +13 -3
  363. package/authoring/doctypes/template/type.ts +13 -2
  364. package/authoring/doctypes/theme/parse.d.mts +35 -0
  365. package/authoring/doctypes/theme/parse.mjs +76 -0
  366. package/authoring/doctypes/theme/theme.doc.d.mts +9 -0
  367. package/authoring/doctypes/theme/theme.doc.mjs +79 -0
  368. package/authoring/doctypes/theme/type.ts +42 -0
  369. package/authoring/doctypes/types.ts +12 -10
  370. package/authoring/gap-report/gap-report.doc.d.mts +12 -0
  371. package/authoring/gap-report/gap-report.doc.mjs +183 -0
  372. package/authoring/gap-report/parse.d.mts +10 -10
  373. package/authoring/gap-report/parse.mjs +6 -6
  374. package/authoring/gap-report/type.ts +1 -1
  375. package/authoring/identity/identity.doc.d.mts +9 -0
  376. package/authoring/identity/identity.doc.mjs +61 -0
  377. package/authoring/identity/type.ts +132 -0
  378. package/authoring/index.d.mts +3 -0
  379. package/authoring/index.d.ts +62 -17
  380. package/authoring/index.mjs +4 -1
  381. package/authoring/integration/integration.doc.mjs +15 -8
  382. package/authoring/integration/parse.d.mts +2 -2
  383. package/authoring/integration/parse.mjs +1 -1
  384. package/authoring/integration/parse.test.mjs +10 -1
  385. package/authoring/integration/schema.d.mts +6 -4
  386. package/authoring/integration/schema.mjs +9 -3
  387. package/authoring/integration/type.ts +19 -8
  388. package/authoring/shadcn/receipt.d.mts +6 -6
  389. package/clients/cli/__tests__/cliManifest.test.ts +27 -29
  390. package/clients/cli/command-load-failure.test.mjs +83 -0
  391. package/clients/cli/command-result-coverage.test.mjs +7 -7
  392. package/clients/cli/commands/blog.doc.mjs +1 -1
  393. package/clients/cli/commands/blog.mjs +23 -8
  394. package/clients/cli/commands/blog.test.mjs +42 -1
  395. package/clients/cli/commands/build-theme.adaptations.test.mjs +100 -1
  396. package/clients/cli/commands/build-theme.ascii-output.test.mjs +161 -0
  397. package/clients/cli/commands/build-theme.flag-docs.test.mjs +110 -0
  398. package/clients/cli/commands/build-theme.mjs +16 -50
  399. package/clients/cli/commands/build-theme.path-safety.test.mjs +86 -1
  400. package/clients/cli/commands/build-theme.variants.test.mjs +76 -0
  401. package/clients/cli/commands/build.doc.mjs +16 -8
  402. package/clients/cli/commands/build.exit-codes-doc.test.mjs +50 -0
  403. package/clients/cli/commands/build.mjs +137 -114
  404. package/clients/cli/commands/build.playbook.test.mjs +75 -0
  405. package/clients/cli/commands/build.text-fields.test.mjs +81 -0
  406. package/clients/cli/commands/component/index.mjs +153 -61
  407. package/clients/cli/commands/component-batch.test.mjs +341 -0
  408. package/clients/cli/commands/component-ownership.test.mjs +92 -3
  409. package/clients/cli/commands/component-package.test.mjs +46 -0
  410. package/clients/cli/commands/component-resolution.test.mjs +21 -0
  411. package/clients/cli/commands/component.doc.mjs +24 -7
  412. package/clients/cli/commands/component.test.mjs +19 -0
  413. package/clients/cli/commands/debug-result-summary.test.mjs +2 -2
  414. package/clients/cli/commands/detail-levels.test.mjs +2 -2
  415. package/clients/cli/commands/discover.broken-integration.test.mjs +52 -5
  416. package/clients/cli/commands/discover.components-flag.test.mjs +97 -0
  417. package/clients/cli/commands/discover.doc.mjs +55 -9
  418. package/clients/cli/commands/discover.mjs +393 -118
  419. package/clients/cli/commands/discover.sources.test.mjs +267 -0
  420. package/clients/cli/commands/discover.text-projection.test.mjs +103 -0
  421. package/clients/cli/commands/docs.doc.mjs +28 -6
  422. package/clients/cli/commands/docs.mjs +240 -26
  423. package/clients/cli/commands/docs.test.mjs +222 -1
  424. package/clients/cli/commands/doctor-integration-components.doc.mjs +1 -1
  425. package/clients/cli/commands/doctor-integration-docs.doc.mjs +3 -3
  426. package/clients/cli/commands/doctor-integration-templates.doc.mjs +15 -8
  427. package/clients/cli/commands/doctor-integration-validate.doc.mjs +1 -1
  428. package/clients/cli/commands/doctor-integration.doc.mjs +1 -1
  429. package/clients/cli/commands/doctor-integration.package-json.test.mjs +53 -0
  430. package/clients/cli/commands/doctor-integration.test.mjs +90 -8
  431. package/clients/cli/commands/doctor.doc.mjs +1 -1
  432. package/clients/cli/commands/doctor.mjs +59 -32
  433. package/clients/cli/commands/doctor.test.mjs +42 -0
  434. package/clients/cli/commands/gap-report.doc.mjs +17 -6
  435. package/clients/cli/commands/gap-report.test.mjs +72 -0
  436. package/clients/cli/commands/hook/index.mjs +7 -17
  437. package/clients/cli/commands/hook.doc.mjs +1 -1
  438. package/clients/cli/commands/hook.text-projection.test.mjs +45 -0
  439. package/clients/cli/commands/init.doc.mjs +20 -9
  440. package/clients/cli/commands/init.flag-help.test.mjs +153 -0
  441. package/clients/cli/commands/integration-add.controls.test.mjs +132 -0
  442. package/clients/cli/commands/integration-add.doc.mjs +32 -6
  443. package/clients/cli/commands/integration-authoring.test.mjs +13 -9
  444. package/clients/cli/commands/integration-pack.doc.mjs +1 -1
  445. package/clients/cli/commands/integration-real-world.test.mjs +3 -9
  446. package/clients/cli/commands/integration.doc.mjs +1 -1
  447. package/clients/cli/commands/integration.mjs +1 -0
  448. package/clients/cli/commands/interactive-guard.test.mjs +101 -24
  449. package/clients/cli/commands/json-contract.test.mjs +33 -0
  450. package/clients/cli/commands/manifest.doc.mjs +1 -1
  451. package/clients/cli/commands/no-prompt-wording.test.mjs +94 -0
  452. package/clients/cli/commands/search.doc.mjs +7 -4
  453. package/clients/cli/commands/search.mjs +28 -9
  454. package/clients/cli/commands/search.test.mjs +75 -0
  455. package/clients/cli/commands/setup-nudge.test.mjs +6 -0
  456. package/clients/cli/commands/swizzle.doc.mjs +3 -2
  457. package/clients/cli/commands/swizzle.path-safety.test.mjs +42 -0
  458. package/clients/cli/commands/template.doc.mjs +52 -13
  459. package/clients/cli/commands/template.flag-help.test.mjs +117 -0
  460. package/clients/cli/commands/template.mjs +4 -91
  461. package/clients/cli/commands/template.path-help.test.mjs +40 -0
  462. package/clients/cli/commands/text-json-parity.test.mjs +702 -0
  463. package/clients/cli/commands/theme-add.doc.mjs +4 -3
  464. package/clients/cli/commands/theme-build.doc.mjs +8 -7
  465. package/clients/cli/commands/theme-list.doc.mjs +2 -2
  466. package/clients/cli/commands/theme-palette-generate.doc.mjs +9 -5
  467. package/clients/cli/commands/theme-palette-generate.test.mjs +19 -0
  468. package/clients/cli/commands/theme-palette.doc.mjs +1 -1
  469. package/clients/cli/commands/theme-targets.behavior.test.mjs +4 -3
  470. package/clients/cli/commands/theme-targets.doc.mjs +1 -1
  471. package/clients/cli/commands/theme-template.behavior.test.mjs +12 -0
  472. package/clients/cli/commands/theme-template.doc.mjs +2 -2
  473. package/clients/cli/commands/theme.doc.mjs +1 -1
  474. package/clients/cli/commands/upgrade.ascii-output.test.mjs +87 -0
  475. package/clients/cli/commands/upgrade.doc.mjs +22 -10
  476. package/clients/cli/commands/upgrade.file-protection.test.mjs +228 -0
  477. package/clients/cli/commands/upgrade.flag-help.test.mjs +188 -0
  478. package/clients/cli/commands/upgrade.hook-output.test.mjs +88 -0
  479. package/clients/cli/commands/upgrade.mjs +29 -7
  480. package/clients/cli/formatters/index.mjs +164 -1
  481. package/clients/cli/formatters/index.test.mjs +97 -0
  482. package/clients/cli/index.mjs +21 -34
  483. package/clients/cli/latest-version-env.test.mjs +50 -0
  484. package/clients/cli/lib/cli-error.test.mjs +7 -0
  485. package/clients/cli/lib/component-format.mjs +9 -9
  486. package/clients/cli/lib/component-format.test.mjs +1 -1
  487. package/clients/cli/lib/define-command.mjs +32 -6
  488. package/clients/cli/lib/doc-text-ascii.test.mjs +82 -0
  489. package/clients/cli/lib/exit-codes.test.mjs +90 -0
  490. package/clients/cli/lib/hook-format.mjs +19 -10
  491. package/clients/cli/lib/json-shim.mjs +62 -16
  492. package/clients/cli/lib/json-shim.test.mjs +69 -0
  493. package/clients/cli/lib/manifest.d.ts +2 -0
  494. package/clients/cli/lib/manifest.mjs +39 -10
  495. package/clients/cli/lib/manifest.test.mjs +22 -2
  496. package/clients/cli/lib/parse-error-format.test.mjs +81 -0
  497. package/foundation/agent-docs/agent-docs.d.mts +7 -2
  498. package/foundation/agent-docs/agent-docs.mjs +82 -12
  499. package/foundation/agent-docs/agent-docs.path-safety.test.mjs +266 -4
  500. package/foundation/agent-docs/agent-docs.test.mjs +19 -1
  501. package/foundation/config/integration-debug.test.mjs +28 -3
  502. package/foundation/config/project-themes.test.mjs +11 -19
  503. package/foundation/config/project.d.mts +20 -11
  504. package/foundation/config/project.mjs +263 -91
  505. package/foundation/config/project.test.mjs +270 -21
  506. package/foundation/discovery/authoring-self-docs.d.mts +87 -0
  507. package/foundation/discovery/authoring-self-docs.mjs +237 -0
  508. package/foundation/discovery/authoring-self-docs.test.mjs +170 -0
  509. package/foundation/discovery/authoring-surface.d.mts +74 -0
  510. package/foundation/discovery/authoring-surface.mjs +525 -0
  511. package/foundation/discovery/authoring-surface.test.mjs +392 -0
  512. package/foundation/discovery/cli-self-docs.d.mts +119 -0
  513. package/foundation/discovery/cli-self-docs.mjs +490 -0
  514. package/foundation/discovery/cli-self-docs.test.mjs +375 -0
  515. package/foundation/discovery/component-discovery.d.mts +39 -1
  516. package/foundation/discovery/component-discovery.mjs +50 -1
  517. package/foundation/discovery/component-loader.d.mts +35 -38
  518. package/foundation/discovery/component-loader.mjs +53 -222
  519. package/foundation/discovery/docs-discovery.d.mts +119 -11
  520. package/foundation/discovery/docs-discovery.mjs +423 -108
  521. package/foundation/discovery/docs-discovery.test.mjs +365 -20
  522. package/foundation/discovery/docs-output-budget.d.mts +28 -0
  523. package/foundation/discovery/docs-output-budget.mjs +50 -0
  524. package/foundation/discovery/docs-section-key.d.mts +116 -0
  525. package/foundation/discovery/docs-section-key.mjs +322 -0
  526. package/foundation/discovery/docs-section-key.test.mjs +246 -0
  527. package/foundation/discovery/template-adapter.d.mts +113 -11
  528. package/foundation/discovery/template-adapter.fixture-refs.test.mjs +248 -0
  529. package/foundation/discovery/template-adapter.integration-isolation.test.mjs +94 -0
  530. package/foundation/discovery/template-adapter.mjs +775 -84
  531. package/foundation/discovery/template-adapter.test.mjs +57 -0
  532. package/foundation/discovery/template-conflict-release.d.mts +13 -0
  533. package/foundation/discovery/template-conflict-release.mjs +40 -0
  534. package/foundation/discovery/template-conflict-release.test.mjs +40 -0
  535. package/foundation/discovery/theme-discovery.d.mts +67 -7
  536. package/foundation/discovery/theme-discovery.mjs +916 -186
  537. package/foundation/discovery/theme-discovery.test.mjs +613 -219
  538. package/foundation/discovery/theming-targets.test.mjs +4 -0
  539. package/foundation/doc-compiler/bundle.d.mts +47 -0
  540. package/foundation/doc-compiler/bundle.mjs +278 -0
  541. package/foundation/doc-compiler/bundle.test.mjs +266 -0
  542. package/foundation/doc-compiler/compile.d.mts +343 -0
  543. package/foundation/doc-compiler/compile.mjs +558 -0
  544. package/foundation/doc-compiler/diagnostics.d.mts +126 -0
  545. package/foundation/doc-compiler/diagnostics.mjs +305 -0
  546. package/foundation/doc-compiler/doc-compiler.test.mjs +714 -0
  547. package/foundation/doc-compiler/doc-loads.test.mjs +1630 -0
  548. package/foundation/doc-compiler/import.d.mts +24 -0
  549. package/foundation/doc-compiler/import.mjs +59 -0
  550. package/foundation/doc-compiler/inputs.d.mts +102 -0
  551. package/foundation/doc-compiler/inputs.mjs +291 -0
  552. package/foundation/doc-compiler/inputs.test.mjs +299 -0
  553. package/foundation/doc-compiler/ir.d.mts +22 -0
  554. package/foundation/doc-compiler/ir.mjs +471 -0
  555. package/foundation/doc-compiler/lenses.d.mts +36 -0
  556. package/foundation/doc-compiler/lenses.mjs +173 -0
  557. package/foundation/doc-compiler/links.d.mts +162 -0
  558. package/foundation/doc-compiler/links.mjs +294 -0
  559. package/foundation/doc-compiler/links.test.mjs +192 -0
  560. package/foundation/doc-compiler/lower-doc.test.mjs +495 -0
  561. package/foundation/doc-compiler/overlays.d.mts +37 -0
  562. package/foundation/doc-compiler/overlays.mjs +206 -0
  563. package/foundation/doc-compiler/parse-readable.d.mts +9 -0
  564. package/foundation/doc-compiler/parse-readable.mjs +29 -0
  565. package/foundation/doc-compiler/read.d.mts +127 -0
  566. package/foundation/doc-compiler/read.mjs +325 -0
  567. package/foundation/doc-compiler/read.test.mjs +313 -0
  568. package/foundation/doc-compiler/source.d.mts +33 -0
  569. package/foundation/doc-compiler/source.mjs +128 -0
  570. package/foundation/doc-compiler/tree.d.mts +288 -0
  571. package/foundation/doc-compiler/tree.mjs +876 -0
  572. package/foundation/doc-compiler/tree.test.mjs +606 -0
  573. package/foundation/fs/file-protection.d.mts +33 -0
  574. package/foundation/fs/file-protection.mjs +825 -0
  575. package/foundation/fs/file-protection.test.mjs +250 -0
  576. package/foundation/fs/module-loader.d.mts +1 -0
  577. package/foundation/fs/module-loader.mjs +50 -1
  578. package/foundation/fs/module-loader.stdout.test.mjs +332 -0
  579. package/foundation/fs/path-safety.d.mts +3 -2
  580. package/foundation/fs/path-safety.mjs +49 -19
  581. package/foundation/fs/path-safety.test.mjs +50 -0
  582. package/foundation/fs/publish-file-hardlink-unavailable.test.mjs +129 -94
  583. package/foundation/identity/provider-identity.d.mts +90 -0
  584. package/foundation/identity/provider-identity.mjs +320 -0
  585. package/foundation/identity/provider-identity.test.mjs +254 -0
  586. package/foundation/identity/providers.d.mts +7 -0
  587. package/foundation/identity/providers.mjs +16 -0
  588. package/foundation/integrations/autolink.d.mts +58 -1
  589. package/foundation/integrations/autolink.mjs +143 -45
  590. package/foundation/integrations/autolink.test.mjs +1 -1
  591. package/foundation/integrations/cli-requirement.d.mts +45 -0
  592. package/foundation/integrations/cli-requirement.mjs +154 -0
  593. package/foundation/integrations/cli-requirement.test.mjs +84 -0
  594. package/foundation/integrations/contribution-fixes.d.mts +145 -0
  595. package/foundation/integrations/contribution-fixes.mjs +1284 -0
  596. package/foundation/integrations/contribution-inventory.d.mts +3 -2
  597. package/foundation/integrations/contribution-inventory.mjs +27 -24
  598. package/foundation/integrations/contribution-inventory.test.mjs +86 -27
  599. package/foundation/integrations/integration-warnings.d.mts +9 -2
  600. package/foundation/integrations/integration-warnings.mjs +52 -21
  601. package/foundation/integrations/integration-warnings.test.mjs +74 -1
  602. package/foundation/integrations/integrations.d.mts +63 -3
  603. package/foundation/integrations/integrations.mjs +122 -9
  604. package/foundation/integrations/integrations.test.mjs +415 -1
  605. package/foundation/integrations/provider-conflicts.test.mjs +125 -0
  606. package/foundation/integrations/provider-ledger.test.mjs +275 -0
  607. package/foundation/integrations/provider-resolution.d.mts +152 -0
  608. package/foundation/integrations/provider-resolution.mjs +576 -0
  609. package/foundation/integrations/provider-resolution.test.mjs +369 -0
  610. package/foundation/integrations/theme-descriptor.d.mts +8 -0
  611. package/foundation/integrations/theme-descriptor.mjs +44 -0
  612. package/foundation/integrations/validate-contributions.d.mts +2 -0
  613. package/foundation/integrations/validate-contributions.mjs +131 -29
  614. package/foundation/response/base.d.ts +8 -4
  615. package/foundation/response/batch.type.d.mts +33 -0
  616. package/foundation/response/batch.type.mjs +34 -0
  617. package/foundation/response/error-codes.d.mts +3 -1
  618. package/foundation/response/error-codes.d.ts +2 -0
  619. package/foundation/response/error-codes.doc.mjs +13 -4
  620. package/foundation/response/error-codes.mjs +8 -2
  621. package/foundation/response/error-codes.test.mjs +137 -10
  622. package/foundation/response/json-contract.test.mjs +57 -17
  623. package/foundation/response/json.d.mts +4 -2
  624. package/foundation/response/json.mjs +8 -10
  625. package/foundation/response/response-types.doc.d.mts +5 -1
  626. package/foundation/response/response-types.doc.mjs +46 -38
  627. package/foundation/response/response-types.doc.test.mjs +181 -0
  628. package/foundation/response/response.doc.mjs +1 -1
  629. package/foundation/text/string-utils.d.mts +8 -0
  630. package/foundation/text/string-utils.mjs +40 -10
  631. package/foundation/xle/browser.d.mts +3 -3
  632. package/foundation/xle/browser.mjs +3 -3
  633. package/foundation/xle/expand.d.mts +2 -0
  634. package/foundation/xle/expand.mjs +6 -5
  635. package/foundation/xle/expand.test.mjs +54 -0
  636. package/foundation/xle/parse.mjs +1 -1
  637. package/foundation/xle/print.mjs +2 -2
  638. package/foundation/xle/splice.mjs +1 -1
  639. package/foundation/xle/xle.test.mjs +13 -0
  640. package/package.json +10 -11
  641. package/api/layout/_adapter.d.mts +0 -34
  642. package/api/layout/_adapter.mjs +0 -133
  643. package/api/layout/check/check.d.mts +0 -16
  644. package/api/layout/check/check.mjs +0 -40
  645. package/api/layout/expand/expand.d.mts +0 -22
  646. package/api/layout/expand/expand.mjs +0 -153
  647. package/api/layout/grammar/grammar.d.mts +0 -13
  648. package/api/layout/grammar/grammar.mjs +0 -86
  649. package/api/layout/layout.d.mts +0 -6
  650. package/api/layout/layout.mjs +0 -17
  651. package/api/layout/layout.test.mjs +0 -297
  652. package/api/layout/layout.type.d.mts +0 -89
  653. package/api/layout/layout.type.mjs +0 -103
  654. package/api/layout/layoutCheck.doc.d.mts +0 -11
  655. package/api/layout/layoutCheck.doc.mjs +0 -84
  656. package/api/layout/layoutExpand.doc.d.mts +0 -11
  657. package/api/layout/layoutExpand.doc.mjs +0 -106
  658. package/api/layout/layoutGrammar.doc.d.mts +0 -11
  659. package/api/layout/layoutGrammar.doc.mjs +0 -56
  660. package/assets/templates/themes/manifest.json +0 -95
  661. package/clients/cli/commands/layout-check.doc.mjs +0 -54
  662. package/clients/cli/commands/layout-expand.doc.mjs +0 -66
  663. package/clients/cli/commands/layout-grammar.doc.mjs +0 -30
  664. package/clients/cli/commands/layout.doc.mjs +0 -34
  665. package/clients/cli/commands/layout.error-codes.test.mjs +0 -66
  666. package/clients/cli/commands/layout.exit-parity.test.mjs +0 -41
  667. package/clients/cli/commands/layout.mjs +0 -263
  668. package/clients/cli/lib/update-check.mjs +0 -83
  669. package/clients/cli/lib/update-check.test.mjs +0 -137
  670. package/clients/cli/update-hint-commands.test.mjs +0 -54
@@ -0,0 +1,115 @@
1
+ // @generated by scripts/sync-api-types.mjs from the JSDoc in api/**/*.mjs.
2
+ // DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
3
+
4
+ /**
5
+ * @typedef {import('./_adapter.mjs').InstalledPackage} InstalledPackage
6
+ * @typedef {import('./_adapter.mjs').CatalogResult} CatalogResult
7
+ * @typedef {CatalogResult['packages'][number]} CatalogPackage
8
+ * @typedef {import('../../authoring/discover/type').DiscoverKind} DiscoverKind
9
+ */
10
+ /**
11
+ * An item search looks through. `kind: 'package'` is a package itself.
12
+ * @typedef {object} SearchItem
13
+ * @property {string} package
14
+ * @property {DiscoverKind | 'package'} kind
15
+ * @property {string} name
16
+ * @property {boolean} installed
17
+ * @property {string} [title]
18
+ * @property {string} [summary]
19
+ * @property {string[]} [keywords]
20
+ * @property {string} [description]
21
+ */
22
+ /**
23
+ * Group a version's contributions into the entry fields, one list per kind.
24
+ * `components` is always present, like on an installed entry.
25
+ * @param {CatalogPackage['contributions']} contributions
26
+ * @returns {Record<string, string[]>}
27
+ */
28
+ export function kindLists(contributions: CatalogPackage["contributions"]): Record<string, string[]>;
29
+ /**
30
+ * Whether an entry adds at least one item of `kind`.
31
+ * @param {Record<string, unknown>} entry
32
+ * @param {DiscoverKind} kind
33
+ * @returns {boolean}
34
+ */
35
+ export function hasKind(entry: Record<string, unknown>, kind: DiscoverKind): boolean;
36
+ /**
37
+ * Where a catalog package stands against the project.
38
+ * @param {CatalogPackage} pkg
39
+ * @param {Set<string>} installedNames
40
+ * @param {Set<string>} declared
41
+ * @returns {{state: 'installed' | 'declared' | 'alias' | 'available', installedAs?: string}}
42
+ */
43
+ export function catalogState(pkg: CatalogPackage, installedNames: Set<string>, declared: Set<string>): {
44
+ state: "installed" | "declared" | "alias" | "available";
45
+ installedAs?: string;
46
+ };
47
+ /**
48
+ * The version a catalog package shows by default.
49
+ * @param {CatalogPackage} pkg
50
+ * @returns {string | undefined}
51
+ */
52
+ export function defaultVersion(pkg: CatalogPackage): string | undefined;
53
+ /**
54
+ * Project a catalog package into the entry shape installed packages use.
55
+ * @param {CatalogPackage} pkg
56
+ * @param {string | undefined} version
57
+ */
58
+ export function catalogEntry(pkg: CatalogPackage, version: string | undefined): {
59
+ description?: string | undefined;
60
+ version?: string | undefined;
61
+ name: string;
62
+ category: string;
63
+ components: string[];
64
+ };
65
+ /**
66
+ * What the project could add: every catalog package it does not have, once per
67
+ * integration (the first name a source lists), never an alias of one it has.
68
+ * @param {CatalogResult} catalog
69
+ * @param {InstalledPackage[]} installed
70
+ * @param {Set<string>} declared
71
+ */
72
+ export function availableEntries(catalog: CatalogResult, installed: InstalledPackage[], declared: Set<string>): {
73
+ source: string;
74
+ aliases?: string[] | undefined;
75
+ description?: string | undefined;
76
+ version?: string | undefined;
77
+ name: string;
78
+ components: string[];
79
+ }[];
80
+ /**
81
+ * Installed packages with the latest release a source knows for each.
82
+ * @param {InstalledPackage[]} installed
83
+ * @param {CatalogResult} catalog
84
+ * @returns {Array<InstalledPackage & {latest?: string}>}
85
+ */
86
+ export function withLatest(installed: InstalledPackage[], catalog: CatalogResult): Array<InstalledPackage & {
87
+ latest?: string;
88
+ }>;
89
+ /**
90
+ * Everything search looks through besides installed components (which the
91
+ * search leaf keeps resolving the way it always has): installed packages and
92
+ * their other items, and every package the project could add with its items.
93
+ * @param {InstalledPackage[]} installed
94
+ * @param {CatalogResult} catalog
95
+ * @param {Set<string>} declared
96
+ * @returns {SearchItem[]}
97
+ */
98
+ export function searchItems(installed: InstalledPackage[], catalog: CatalogResult, declared: Set<string>): SearchItem[];
99
+ export type InstalledPackage = import("./_adapter.mjs").InstalledPackage;
100
+ export type CatalogResult = import("./_adapter.mjs").CatalogResult;
101
+ export type CatalogPackage = CatalogResult["packages"][number];
102
+ export type DiscoverKind = import("../../authoring/discover/type").DiscoverKind;
103
+ /**
104
+ * An item search looks through. `kind: 'package'` is a package itself.
105
+ */
106
+ export type SearchItem = {
107
+ package: string;
108
+ kind: DiscoverKind | "package";
109
+ name: string;
110
+ installed: boolean;
111
+ title?: string | undefined;
112
+ summary?: string | undefined;
113
+ keywords?: string[] | undefined;
114
+ description?: string | undefined;
115
+ };
@@ -0,0 +1,203 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file Pure views over discover sources' catalogs: which catalog packages the
5
+ * project already has, what it could add, and the items search looks through.
6
+ * No I/O; the adapter supplies every input.
7
+ *
8
+ * @position api/discover — shared by the list, detail, item, and search leaves.
9
+ */
10
+
11
+ import {KIND_FIELDS} from './_adapter.mjs';
12
+
13
+ /**
14
+ * @typedef {import('./_adapter.mjs').InstalledPackage} InstalledPackage
15
+ * @typedef {import('./_adapter.mjs').CatalogResult} CatalogResult
16
+ * @typedef {CatalogResult['packages'][number]} CatalogPackage
17
+ * @typedef {import('../../authoring/discover/type').DiscoverKind} DiscoverKind
18
+ */
19
+
20
+ /**
21
+ * An item search looks through. `kind: 'package'` is a package itself.
22
+ * @typedef {object} SearchItem
23
+ * @property {string} package
24
+ * @property {DiscoverKind | 'package'} kind
25
+ * @property {string} name
26
+ * @property {boolean} installed
27
+ * @property {string} [title]
28
+ * @property {string} [summary]
29
+ * @property {string[]} [keywords]
30
+ * @property {string} [description]
31
+ */
32
+
33
+ /**
34
+ * Group a version's contributions into the entry fields, one list per kind.
35
+ * `components` is always present, like on an installed entry.
36
+ * @param {CatalogPackage['contributions']} contributions
37
+ * @returns {Record<string, string[]>}
38
+ */
39
+ export function kindLists(contributions) {
40
+ /** @type {Record<string, string[]>} */
41
+ const lists = {components: []};
42
+ for (const [kind, field] of KIND_FIELDS) {
43
+ const names = contributions.filter(c => c.kind === kind).map(c => c.name);
44
+ if (names.length > 0 || field === 'components') lists[field] = names;
45
+ }
46
+ return lists;
47
+ }
48
+
49
+ /**
50
+ * Whether an entry adds at least one item of `kind`.
51
+ * @param {Record<string, unknown>} entry
52
+ * @param {DiscoverKind} kind
53
+ * @returns {boolean}
54
+ */
55
+ export function hasKind(entry, kind) {
56
+ const field = KIND_FIELDS.find(([k]) => k === kind)?.[1];
57
+ const values = field == null ? undefined : entry[field];
58
+ return Array.isArray(values) && values.length > 0;
59
+ }
60
+
61
+ /**
62
+ * Where a catalog package stands against the project.
63
+ * @param {CatalogPackage} pkg
64
+ * @param {Set<string>} installedNames
65
+ * @param {Set<string>} declared
66
+ * @returns {{state: 'installed' | 'declared' | 'alias' | 'available', installedAs?: string}}
67
+ */
68
+ export function catalogState(pkg, installedNames, declared) {
69
+ if (installedNames.has(pkg.package)) return {state: 'installed'};
70
+ if (declared.has(pkg.package)) return {state: 'declared'};
71
+ const installedAs = pkg.aliases.find(
72
+ name => installedNames.has(name) || declared.has(name),
73
+ );
74
+ if (installedAs != null) return {state: 'alias', installedAs};
75
+ return {state: 'available'};
76
+ }
77
+
78
+ /**
79
+ * The version a catalog package shows by default.
80
+ * @param {CatalogPackage} pkg
81
+ * @returns {string | undefined}
82
+ */
83
+ export function defaultVersion(pkg) {
84
+ return pkg.latest ?? pkg.versions[0]?.version;
85
+ }
86
+
87
+ /**
88
+ * Project a catalog package into the entry shape installed packages use.
89
+ * @param {CatalogPackage} pkg
90
+ * @param {string | undefined} version
91
+ */
92
+ export function catalogEntry(pkg, version) {
93
+ const {components, ...others} = kindLists(pkg.contributions);
94
+ return {
95
+ name: pkg.package,
96
+ category: pkg.package,
97
+ components,
98
+ ...(version ? {version} : {}),
99
+ ...(pkg.description ? {description: pkg.description} : {}),
100
+ ...others,
101
+ };
102
+ }
103
+
104
+ /**
105
+ * What the project could add: every catalog package it does not have, once per
106
+ * integration (the first name a source lists), never an alias of one it has.
107
+ * @param {CatalogResult} catalog
108
+ * @param {InstalledPackage[]} installed
109
+ * @param {Set<string>} declared
110
+ */
111
+ export function availableEntries(catalog, installed, declared) {
112
+ const installedNames = new Set(installed.map(p => p.name));
113
+ /** @type {Set<string>} */
114
+ const integrations = new Set();
115
+ const entries = [];
116
+ for (const pkg of catalog.packages) {
117
+ if (catalogState(pkg, installedNames, declared).state !== 'available')
118
+ continue;
119
+ if (integrations.has(pkg.integration)) continue;
120
+ integrations.add(pkg.integration);
121
+ const version = defaultVersion(pkg);
122
+ const {category: _category, ...entry} = catalogEntry(pkg, version);
123
+ entries.push({
124
+ ...entry,
125
+ ...(pkg.aliases.length > 0 ? {aliases: pkg.aliases} : {}),
126
+ source: pkg.source,
127
+ });
128
+ }
129
+ return entries;
130
+ }
131
+
132
+ /**
133
+ * Installed packages with the latest release a source knows for each.
134
+ * @param {InstalledPackage[]} installed
135
+ * @param {CatalogResult} catalog
136
+ * @returns {Array<InstalledPackage & {latest?: string}>}
137
+ */
138
+ export function withLatest(installed, catalog) {
139
+ const byName = new Map(catalog.packages.map(p => [p.package, p]));
140
+ return installed.map(pkg => {
141
+ const latest = byName.get(pkg.name)?.latest;
142
+ return latest ? {...pkg, latest} : pkg;
143
+ });
144
+ }
145
+
146
+ /**
147
+ * Everything search looks through besides installed components (which the
148
+ * search leaf keeps resolving the way it always has): installed packages and
149
+ * their other items, and every package the project could add with its items.
150
+ * @param {InstalledPackage[]} installed
151
+ * @param {CatalogResult} catalog
152
+ * @param {Set<string>} declared
153
+ * @returns {SearchItem[]}
154
+ */
155
+ export function searchItems(installed, catalog, declared) {
156
+ /** @type {SearchItem[]} */
157
+ const items = [];
158
+ for (const pkg of installed) {
159
+ items.push({
160
+ package: pkg.name,
161
+ kind: 'package',
162
+ name: pkg.name,
163
+ installed: true,
164
+ ...(pkg.description ? {description: pkg.description} : {}),
165
+ });
166
+ for (const [kind, field] of KIND_FIELDS) {
167
+ if (kind === 'component') continue;
168
+ const names = /** @type {Record<string, unknown>} */ (pkg)[field];
169
+ if (!Array.isArray(names)) continue;
170
+ for (const name of names) {
171
+ items.push({package: pkg.name, kind, name, installed: true});
172
+ }
173
+ }
174
+ }
175
+ const installedNames = new Set(installed.map(p => p.name));
176
+ /** @type {Set<string>} */
177
+ const integrations = new Set();
178
+ for (const pkg of catalog.packages) {
179
+ if (catalogState(pkg, installedNames, declared).state !== 'available')
180
+ continue;
181
+ if (integrations.has(pkg.integration)) continue;
182
+ integrations.add(pkg.integration);
183
+ items.push({
184
+ package: pkg.package,
185
+ kind: 'package',
186
+ name: pkg.package,
187
+ installed: false,
188
+ ...(pkg.description ? {description: pkg.description} : {}),
189
+ });
190
+ for (const c of pkg.contributions) {
191
+ items.push({
192
+ package: pkg.package,
193
+ kind: c.kind,
194
+ name: c.name,
195
+ installed: false,
196
+ ...(c.title ? {title: c.title} : {}),
197
+ ...(c.summary ? {summary: c.summary} : {}),
198
+ ...(c.keywords ? {keywords: c.keywords} : {}),
199
+ });
200
+ }
201
+ }
202
+ return items;
203
+ }
@@ -0,0 +1,128 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file Tests for the pure views over discover sources' catalogs.
5
+ */
6
+
7
+ import {describe, expect, it} from 'vitest';
8
+ import {
9
+ availableEntries,
10
+ catalogState,
11
+ kindLists,
12
+ searchItems,
13
+ withLatest,
14
+ } from './_catalog-view.mjs';
15
+
16
+ /**
17
+ * @param {string} name
18
+ * @param {string} integration
19
+ * @param {object} [extra]
20
+ * @returns {any}
21
+ */
22
+ function entry(name, integration, extra = {}) {
23
+ return {
24
+ package: name,
25
+ integration,
26
+ aliases: [],
27
+ latest: '1.0.0',
28
+ versions: [],
29
+ contributions: [{kind: 'component', name: 'A'}],
30
+ source: 'S',
31
+ ...extra,
32
+ };
33
+ }
34
+
35
+ const CATALOG = {
36
+ sources: [],
37
+ packages: [
38
+ entry('@acme/ui', 'acme-ui', {aliases: ['@acme/ui-classic']}),
39
+ entry('@acme/ui-classic', 'acme-ui', {aliases: ['@acme/ui']}),
40
+ entry('@acme/charts', 'charts', {
41
+ latest: '2.0.0',
42
+ contributions: [{kind: 'theme', name: 'ocean'}],
43
+ }),
44
+ ],
45
+ };
46
+
47
+ /** @param {string} name @returns {any} */
48
+ const installed = name => ({name, category: name, components: []});
49
+
50
+ describe('availableEntries', () => {
51
+ it('offers each integration once, under the first name a source lists', () => {
52
+ expect(
53
+ availableEntries(CATALOG, [], new Set()).map(e => [e.name, e.aliases]),
54
+ ).toEqual([
55
+ ['@acme/ui', ['@acme/ui-classic']],
56
+ ['@acme/charts', undefined],
57
+ ]);
58
+ });
59
+
60
+ it('never offers an integration the project has under another name', () => {
61
+ expect(
62
+ availableEntries(CATALOG, [installed('@acme/ui-classic')], new Set()).map(
63
+ e => e.name,
64
+ ),
65
+ ).toEqual(['@acme/charts']);
66
+ });
67
+
68
+ it('does not offer a package the project declares, even when it did not load', () => {
69
+ expect(
70
+ availableEntries(CATALOG, [], new Set(['@acme/charts'])).map(e => e.name),
71
+ ).toEqual(['@acme/ui']);
72
+ });
73
+
74
+ it('describes an entry the way an installed one is described', () => {
75
+ expect(availableEntries(CATALOG, [], new Set())[1]).toEqual({
76
+ name: '@acme/charts',
77
+ components: [],
78
+ version: '2.0.0',
79
+ themes: ['ocean'],
80
+ source: 'S',
81
+ });
82
+ });
83
+ });
84
+
85
+ describe('catalogState', () => {
86
+ it('names the package the project has instead', () => {
87
+ expect(
88
+ catalogState(CATALOG.packages[0], new Set(['@acme/ui-classic']), new Set()),
89
+ ).toEqual({state: 'alias', installedAs: '@acme/ui-classic'});
90
+ });
91
+ });
92
+
93
+ describe('withLatest', () => {
94
+ it('adds the latest release a source knows to an installed package', () => {
95
+ expect(withLatest([installed('@acme/charts')], CATALOG)[0]).toMatchObject({
96
+ latest: '2.0.0',
97
+ });
98
+ });
99
+ });
100
+
101
+ describe('kindLists', () => {
102
+ it('groups items by kind, always with components', () => {
103
+ expect(
104
+ kindLists([
105
+ {kind: 'theme', name: 'ocean'},
106
+ {kind: 'component', name: 'A'},
107
+ ]),
108
+ ).toEqual({components: ['A'], themes: ['ocean']});
109
+ });
110
+ });
111
+
112
+ describe('searchItems', () => {
113
+ it('covers installed packages and their other items, then what could be added', () => {
114
+ const items = searchItems(
115
+ [{...installed('@acme/widgets'), templates: ['pages/Home']}],
116
+ CATALOG,
117
+ new Set(),
118
+ );
119
+ expect(items.map(i => [i.package, i.kind, i.name, i.installed])).toEqual([
120
+ ['@acme/widgets', 'package', '@acme/widgets', true],
121
+ ['@acme/widgets', 'template', 'pages/Home', true],
122
+ ['@acme/ui', 'package', '@acme/ui', false],
123
+ ['@acme/ui', 'component', 'A', false],
124
+ ['@acme/charts', 'package', '@acme/charts', false],
125
+ ['@acme/charts', 'theme', 'ocean', false],
126
+ ]);
127
+ });
128
+ });
@@ -2,12 +2,24 @@
2
2
  // DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
3
3
 
4
4
  /**
5
- * Build the discover.detail response for a scoped package name. Throws
6
- * AstryxError (ERR_UNKNOWN_PACKAGE) — with the available packages as
7
- * suggestions — when no package matches.
5
+ * Build the discover.detail response for one package. The project's installed
6
+ * copy describes itself; any other version is described by its source. For a
7
+ * package the project does not have, `install` is the package-manager command
8
+ * that adds it — printed, never run.
8
9
  *
9
- * @param {import('../_package-scanner.mjs').ScannedPackage[]} packages
10
- * @param {string} query scoped package name, e.g. `@scope/name`
10
+ * @param {import('../_adapter.mjs').InstalledPackage[]} packages
11
+ * @param {string} name package name, e.g. `@scope/name`
12
+ * @param {{
13
+ * catalog?: import('../_catalog-view.mjs').CatalogPackage,
14
+ * version?: string,
15
+ * add?: (name: string, version?: string) => string,
16
+ * installedAs?: string,
17
+ * }} [options]
11
18
  * @returns {import('../discover.type.mjs').DiscoverDetailResponse}
12
19
  */
13
- export function detail(packages: import("../_package-scanner.mjs").ScannedPackage[], query: string): import("../discover.type.mjs").DiscoverDetailResponse;
20
+ export function detail(packages: import("../_adapter.mjs").InstalledPackage[], name: string, options?: {
21
+ catalog?: import("../_catalog-view.mjs").CatalogPackage;
22
+ version?: string;
23
+ add?: (name: string, version?: string) => string;
24
+ installedAs?: string;
25
+ }): import("../discover.type.mjs").DiscoverDetailResponse;
@@ -1,33 +1,87 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
3
  /**
4
- * @file discover.detail leaf — browse one external package (@scope/name).
4
+ * @file discover.detail leaf — one package: what it adds, and, when a discover
5
+ * source knows it, every version and the latest one.
5
6
  *
6
- * @position api/discover/detail — pure projection over the packages resolved by
7
- * ../_adapter; throws AstryxError (ERR_UNKNOWN_PACKAGE) for an unknown scope.
7
+ * @position api/discover/detail — pure projection over the packages and catalog
8
+ * entry resolved by ../_adapter; throws AstryxError (ERR_UNKNOWN_PACKAGE) for
9
+ * a package neither the project nor any source knows.
8
10
  */
9
11
 
10
12
  import {toEntry} from '../_adapter.mjs';
13
+ import {catalogEntry, defaultVersion} from '../_catalog-view.mjs';
11
14
  import {AstryxError} from '../../error.mjs';
12
15
  import {ERROR_CODES} from '../../../foundation/response/error-codes.mjs';
13
16
 
14
17
  /**
15
- * Build the discover.detail response for a scoped package name. Throws
16
- * AstryxError (ERR_UNKNOWN_PACKAGE) — with the available packages as
17
- * suggestions — when no package matches.
18
+ * Build the discover.detail response for one package. The project's installed
19
+ * copy describes itself; any other version is described by its source. For a
20
+ * package the project does not have, `install` is the package-manager command
21
+ * that adds it — printed, never run.
18
22
  *
19
- * @param {import('../_package-scanner.mjs').ScannedPackage[]} packages
20
- * @param {string} query scoped package name, e.g. `@scope/name`
23
+ * @param {import('../_adapter.mjs').InstalledPackage[]} packages
24
+ * @param {string} name package name, e.g. `@scope/name`
25
+ * @param {{
26
+ * catalog?: import('../_catalog-view.mjs').CatalogPackage,
27
+ * version?: string,
28
+ * add?: (name: string, version?: string) => string,
29
+ * installedAs?: string,
30
+ * }} [options]
21
31
  * @returns {import('../discover.type.mjs').DiscoverDetailResponse}
22
32
  */
23
- export function detail(packages, query) {
24
- const pkg = packages.find(p => p.name === query);
25
- if (!pkg) {
33
+ export function detail(packages, name, options = {}) {
34
+ const {catalog, version, add, installedAs} = options;
35
+ const pkg = packages.find(p => p.name === name);
36
+ if (!pkg && !catalog) {
26
37
  throw new AstryxError(
27
- `Package "${query}" not found`,
38
+ `Package "${name}" not found`,
28
39
  packages.map(p => ({name: p.name, reason: 'available package'})),
29
40
  ERROR_CODES.ERR_UNKNOWN_PACKAGE,
30
41
  );
31
42
  }
32
- return {type: 'discover.detail', data: toEntry(pkg)};
43
+
44
+ const known = new Set([
45
+ ...(catalog?.versions.map(v => v.version) ?? []),
46
+ ...(pkg?.version ? [pkg.version] : []),
47
+ ]);
48
+ if (version && !known.has(version)) {
49
+ const releases = catalog?.versions.filter(v => !v.prerelease) ?? [];
50
+ throw new AstryxError(
51
+ `Version "${version}" of ${name} not found`,
52
+ (releases.length > 0 ? releases.map(v => v.version) : [...known])
53
+ .slice(0, 5)
54
+ .map(v => ({name: `${name}@${v}`, reason: 'published version'})),
55
+ ERROR_CODES.ERR_NOT_FOUND,
56
+ );
57
+ }
58
+
59
+ const local = pkg != null && (!version || version === pkg.version);
60
+ /** @type {Record<string, unknown>} */
61
+ const data = local
62
+ ? {...toEntry(pkg), installed: true}
63
+ : {
64
+ ...catalogEntry(
65
+ /** @type {NonNullable<typeof catalog>} */ (catalog),
66
+ version ?? defaultVersion(/** @type {NonNullable<typeof catalog>} */ (catalog)),
67
+ ),
68
+ installed: pkg != null,
69
+ ...(pkg?.version ? {installedVersion: pkg.version} : {}),
70
+ };
71
+ if (catalog) {
72
+ if (catalog.latest) data.latest = catalog.latest;
73
+ if (catalog.aliases.length > 0) data.aliases = catalog.aliases;
74
+ data.source = catalog.source;
75
+ }
76
+ if (!pkg) {
77
+ if (installedAs) data.installedAs = installedAs;
78
+ else if (add) data.install = add(name, version);
79
+ }
80
+ if (catalog) data.versions = catalog.versions;
81
+ return {
82
+ type: 'discover.detail',
83
+ data: /** @type {import('../discover.type.mjs').DiscoverDetailResponse['data']} */ (
84
+ data
85
+ ),
86
+ };
33
87
  }
@@ -36,6 +36,7 @@ describe('discover.detail leaf', () => {
36
36
  category: '@acme/widgets',
37
37
  components: ['Alpha', 'Beta'],
38
38
  version: '1.2.3',
39
+ installed: true,
39
40
  });
40
41
  });
41
42
 
@@ -55,3 +56,87 @@ describe('discover.detail leaf', () => {
55
56
  ]);
56
57
  });
57
58
  });
59
+
60
+ describe('discover.detail leaf with a discover source', () => {
61
+ /** @type {any} */
62
+ const catalog = {
63
+ package: '@acme/charts',
64
+ integration: 'acme-charts',
65
+ aliases: ['@acme/charts-legacy'],
66
+ latest: '2.0.0',
67
+ source: 'Acme',
68
+ versions: [
69
+ {version: '2.1.0-beta.1', publishedAt: '2026-09-30T00:00:00.000Z', prerelease: true, status: 'ok'},
70
+ {version: '2.0.0', publishedAt: '2026-09-20T00:00:00.000Z', prerelease: false, status: 'ok'},
71
+ {version: '1.0.0', publishedAt: null, prerelease: false, status: 'manifest_load_error'},
72
+ ],
73
+ contributions: [
74
+ {kind: 'component', name: 'Chart'},
75
+ {kind: 'template', name: 'pages/Report'},
76
+ ],
77
+ };
78
+ /** @param {string} name @param {string} [version] */
79
+ const add = (name, version) => `pnpm add ${version ? `${name}@${version}` : name}`;
80
+
81
+ it('describes a package the project does not have, with the command that adds it', () => {
82
+ expect(detail(PACKAGES, '@acme/charts', {catalog, add}).data).toEqual({
83
+ name: '@acme/charts',
84
+ category: '@acme/charts',
85
+ components: ['Chart'],
86
+ version: '2.0.0',
87
+ templates: ['pages/Report'],
88
+ installed: false,
89
+ latest: '2.0.0',
90
+ aliases: ['@acme/charts-legacy'],
91
+ source: 'Acme',
92
+ install: 'pnpm add @acme/charts',
93
+ versions: catalog.versions,
94
+ });
95
+ });
96
+
97
+ it('describes any version, prereleases included', () => {
98
+ const {data} = detail(PACKAGES, '@acme/charts', {catalog, add, version: '2.1.0-beta.1'});
99
+ expect(data.version).toBe('2.1.0-beta.1');
100
+ expect(data.install).toBe('pnpm add @acme/charts@2.1.0-beta.1');
101
+ });
102
+
103
+ it('refuses a version that was never published, and suggests releases', () => {
104
+ let err;
105
+ try {
106
+ detail(PACKAGES, '@acme/charts', {catalog, add, version: '3.0.0'});
107
+ } catch (e) {
108
+ err = e;
109
+ }
110
+ expect(err).toBeInstanceOf(AstryxError);
111
+ expect(err.code).toBe('ERR_NOT_FOUND');
112
+ expect(err.suggestions.map(s => s.name)).toEqual([
113
+ '@acme/charts@2.0.0',
114
+ '@acme/charts@1.0.0',
115
+ ]);
116
+ });
117
+
118
+ it('names the package the project has instead of offering an alias', () => {
119
+ const {data} = detail(PACKAGES, '@acme/charts', {
120
+ catalog,
121
+ add,
122
+ installedAs: '@acme/charts-legacy',
123
+ });
124
+ expect(data.installedAs).toBe('@acme/charts-legacy');
125
+ expect(data).not.toHaveProperty('install');
126
+ });
127
+
128
+ it("keeps describing the installed copy from the project, with the source's versions", () => {
129
+ const {data} = detail(PACKAGES, '@acme/widgets', {
130
+ catalog: {...catalog, package: '@acme/widgets', latest: '1.3.0'},
131
+ add,
132
+ });
133
+ expect(data).toMatchObject({
134
+ name: '@acme/widgets',
135
+ components: ['Alpha', 'Beta'],
136
+ version: '1.2.3',
137
+ installed: true,
138
+ latest: '1.3.0',
139
+ });
140
+ expect(data).not.toHaveProperty('install');
141
+ });
142
+ });