@astryxdesign/cli 0.6.4-canary.f0355e3 → 0.6.4

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 (331) hide show
  1. package/README.md +96 -99
  2. package/api/build/build.doc.mjs +1 -6
  3. package/api/build/build.test.mjs +0 -22
  4. package/api/build/kit/kit.mjs +5 -44
  5. package/api/component/_adapter.d.mts +0 -25
  6. package/api/component/_adapter.mjs +5 -59
  7. package/api/component/component.d.mts +3 -6
  8. package/api/component/component.doc.mjs +17 -37
  9. package/api/component/component.mjs +9 -249
  10. package/api/component/component.type.d.mts +0 -25
  11. package/api/component/component.type.mjs +0 -44
  12. package/api/discover/_adapter.d.mts +6 -114
  13. package/api/discover/_adapter.mjs +17 -372
  14. package/api/discover/detail/detail.d.mts +6 -18
  15. package/api/discover/detail/detail.mjs +13 -67
  16. package/api/discover/detail/detail.test.mjs +0 -85
  17. package/api/discover/discover.d.mts +9 -3
  18. package/api/discover/discover.doc.mjs +18 -61
  19. package/api/discover/discover.mjs +36 -220
  20. package/api/discover/discover.test.mjs +2 -11
  21. package/api/discover/discover.type.d.mts +8 -147
  22. package/api/discover/discover.type.mjs +12 -102
  23. package/api/discover/list/list.d.mts +6 -20
  24. package/api/discover/list/list.mjs +12 -45
  25. package/api/discover/list/list.test.mjs +0 -46
  26. package/api/discover/search/search.d.mts +16 -18
  27. package/api/discover/search/search.mjs +56 -102
  28. package/api/discover/search/search.test.mjs +10 -144
  29. package/api/docs/_adapter.d.mts +3 -8
  30. package/api/docs/_adapter.mjs +6 -14
  31. package/api/docs/docOverlays.test.mjs +1 -27
  32. package/api/docs/docs.doc.mjs +2 -2
  33. package/api/docs/docs.test.mjs +243 -0
  34. package/api/docs/integration-tree.test.mjs +555 -0
  35. package/api/docs/integrationDocs.test.mjs +314 -0
  36. package/api/doctor/doctor.d.mts +3 -8
  37. package/api/doctor/doctor.doc.mjs +8 -17
  38. package/api/doctor/doctor.mjs +9 -90
  39. package/api/doctor/doctor.test.mjs +10 -122
  40. package/api/doctor/doctor.type.d.mts +1 -1
  41. package/api/doctor/doctor.type.mjs +1 -1
  42. package/api/gap-report/gap-report.doc.mjs +10 -19
  43. package/api/hook/hook.doc.mjs +3 -6
  44. package/api/index.d.mts +2 -1
  45. package/api/index.mjs +5 -5
  46. package/api/init/init.doc.mjs +12 -17
  47. package/api/integration/add-helpers.d.mts +2 -5
  48. package/api/integration/add-helpers.mjs +9 -36
  49. package/api/integration/add-theme.mjs +1 -22
  50. package/api/integration/add-theme.test.mjs +0 -34
  51. package/api/integration/authoring-checks.mjs +2 -2
  52. package/api/integration/integrationPackCheck.doc.mjs +3 -3
  53. package/api/integration/pack-check.mjs +9 -82
  54. package/api/integration/pack-check.test.mjs +0 -90
  55. package/api/integration/pack-check.type.mjs +1 -1
  56. package/api/json/assertResponse.doc.mjs +1 -1
  57. package/api/json/index.ts +1 -0
  58. package/api/json/isError.doc.mjs +1 -1
  59. package/api/layout/_adapter.d.mts +34 -0
  60. package/api/layout/_adapter.mjs +148 -0
  61. package/api/layout/check/check.d.mts +16 -0
  62. package/api/layout/check/check.mjs +40 -0
  63. package/api/layout/expand/expand.d.mts +22 -0
  64. package/api/layout/expand/expand.mjs +155 -0
  65. package/api/layout/expand/expand.path-safety.test.mjs +53 -0
  66. package/api/layout/grammar/grammar.d.mts +13 -0
  67. package/api/layout/grammar/grammar.mjs +87 -0
  68. package/api/layout/layout.d.mts +6 -0
  69. package/api/layout/layout.mjs +17 -0
  70. package/api/layout/layout.test.mjs +297 -0
  71. package/api/layout/layout.type.d.mts +89 -0
  72. package/api/layout/layout.type.mjs +103 -0
  73. package/api/layout/layoutCheck.doc.d.mts +11 -0
  74. package/api/layout/layoutCheck.doc.mjs +85 -0
  75. package/api/layout/layoutExpand.doc.d.mts +11 -0
  76. package/api/layout/layoutExpand.doc.mjs +107 -0
  77. package/api/layout/layoutGrammar.doc.d.mts +11 -0
  78. package/api/layout/layoutGrammar.doc.mjs +57 -0
  79. package/api/search/search.d.mts +1 -27
  80. package/api/search/search.doc.mjs +2 -2
  81. package/api/search/search.mjs +16 -228
  82. package/api/search/search.test.mjs +512 -0
  83. package/api/swizzle/swizzle.doc.mjs +5 -7
  84. package/api/template/copy/copy.mjs +1 -1
  85. package/api/template/copy/copy.test.mjs +0 -9
  86. package/api/template/template-integration.test.mjs +65 -1
  87. package/api/template/template.doc.mjs +1 -2
  88. package/api/template/template.mjs +1 -1
  89. package/api/theme/add/add.mjs +25 -17
  90. package/api/theme/add/add.staging.test.mjs +23 -40
  91. package/api/theme/build/build.family.test.mjs +12 -7
  92. package/api/theme/build/build.mjs +18 -8
  93. package/api/theme/generateTonalPalette.doc.mjs +2 -1
  94. package/api/theme/listThemes.doc.mjs +1 -1
  95. package/api/theme/themeAdd.doc.mjs +10 -9
  96. package/api/theme/themeBuild.doc.mjs +13 -13
  97. package/api/theme/themeList.doc.mjs +1 -1
  98. package/api/theme/themeListAvailable.doc.mjs +1 -2
  99. package/api/theme/themePaletteGenerate.doc.mjs +8 -15
  100. package/api/theme/themeTargets.doc.mjs +2 -3
  101. package/api/theme/themeTemplate.doc.mjs +1 -2
  102. package/api/upgrade/run/run.mjs +4 -6
  103. package/api/upgrade/upgrade.doc.mjs +22 -24
  104. package/api/upgrade/upgrade.type.mjs +2 -2
  105. package/assets/codemods/__tests__/runner.test.mjs +1 -3
  106. package/assets/codemods/integration-runner.mjs +3 -3
  107. package/assets/codemods/runner.mjs +4 -5
  108. package/assets/docs/README.md +2 -4
  109. package/assets/docs/browser-support.doc.mjs +11 -11
  110. package/assets/docs/color.doc.mjs +2 -8
  111. package/assets/docs/elevation.doc.mjs +4 -6
  112. package/assets/docs/getting-started.doc.mjs +16 -5
  113. package/assets/docs/icons.doc.mjs +21 -2
  114. package/assets/docs/illustrations.doc.mjs +15 -7
  115. package/assets/docs/internationalization.doc.mjs +5 -7
  116. package/assets/docs/layout.doc.dense.mjs +82 -130
  117. package/assets/docs/layout.doc.mjs +77 -133
  118. package/assets/docs/migration.doc.mjs +21 -19
  119. package/assets/docs/motion.doc.mjs +3 -16
  120. package/assets/docs/principles.doc.dense.mjs +5 -5
  121. package/assets/docs/principles.doc.mjs +0 -8
  122. package/assets/docs/principles.doc.zh.mjs +6 -6
  123. package/assets/docs/shape.doc.mjs +3 -8
  124. package/assets/docs/spacing.doc.mjs +2 -7
  125. package/assets/docs/styling-libraries.doc.mjs +2 -6
  126. package/assets/docs/styling.doc.mjs +23 -19
  127. package/assets/docs/theme.doc.dense.mjs +18 -58
  128. package/assets/docs/theme.doc.mjs +46 -56
  129. package/assets/docs/theme.doc.zh.mjs +8 -9
  130. package/assets/docs/tokens.doc.dense.mjs +2 -2
  131. package/assets/docs/tokens.doc.mjs +8 -389
  132. package/assets/docs/tokens.doc.zh.mjs +2 -2
  133. package/assets/docs/tree/integrations.doc.mjs +451 -25
  134. package/assets/docs/tree/integrations.test.mjs +62 -0
  135. package/assets/docs/tree/writing-docs.doc.mjs +286 -0
  136. package/assets/docs/typography.doc.mjs +4 -24
  137. package/assets/docs/working-with-ai.doc.mjs +22 -30
  138. package/assets/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.tsx +1 -1
  139. package/authoring/config/config.doc.mjs +2 -10
  140. package/authoring/config/parse.d.mts +0 -2
  141. package/authoring/config/parse.mjs +0 -19
  142. package/authoring/config/parse.test.mjs +0 -8
  143. package/authoring/config/type.ts +2 -13
  144. package/authoring/doctypes/_schema.d.mts +2 -3
  145. package/authoring/doctypes/_schema.mjs +0 -6
  146. package/authoring/doctypes/base/graph-fields.doc.mjs +3 -3
  147. package/authoring/doctypes/base/type.ts +2 -4
  148. package/authoring/doctypes/command/command.doc.mjs +1 -1
  149. package/authoring/doctypes/command/type.ts +1 -1
  150. package/authoring/doctypes/component/component.doc.mjs +0 -6
  151. package/authoring/doctypes/component/type.ts +0 -8
  152. package/authoring/doctypes/reference/reference.doc.mjs +0 -7
  153. package/authoring/doctypes/reference/type.ts +0 -5
  154. package/authoring/doctypes/schema/schema.doc.mjs +2 -2
  155. package/authoring/doctypes/template/template.doc.mjs +1 -1
  156. package/authoring/doctypes/template/type.ts +2 -2
  157. package/authoring/index.d.mts +0 -1
  158. package/authoring/index.d.ts +0 -10
  159. package/authoring/index.mjs +0 -1
  160. package/authoring/integration/integration.doc.mjs +10 -12
  161. package/clients/cli/command-result-coverage.test.mjs +7 -7
  162. package/clients/cli/commands/component/index.mjs +55 -152
  163. package/clients/cli/commands/component-ownership.test.mjs +0 -89
  164. package/clients/cli/commands/component.doc.mjs +9 -27
  165. package/clients/cli/commands/debug-result-summary.test.mjs +2 -2
  166. package/clients/cli/commands/discover.doc.mjs +9 -53
  167. package/clients/cli/commands/discover.mjs +118 -393
  168. package/clients/cli/commands/docs.doc.mjs +1 -1
  169. package/clients/cli/commands/docs.mjs +17 -60
  170. package/clients/cli/commands/docs.test.mjs +294 -0
  171. package/clients/cli/commands/doctor-integration-docs.doc.mjs +2 -3
  172. package/clients/cli/commands/doctor-integration.test.mjs +0 -53
  173. package/clients/cli/commands/doctor.doc.mjs +1 -3
  174. package/clients/cli/commands/doctor.mjs +5 -49
  175. package/clients/cli/commands/gap-report.doc.mjs +9 -10
  176. package/clients/cli/commands/init.doc.mjs +6 -9
  177. package/clients/cli/commands/integration-add.doc.mjs +9 -9
  178. package/clients/cli/commands/integration-authoring.test.mjs +10 -61
  179. package/clients/cli/commands/integration-pack.doc.mjs +9 -5
  180. package/clients/cli/commands/integration-real-world.test.mjs +1 -1
  181. package/clients/cli/commands/integration.doc.mjs +4 -4
  182. package/clients/cli/commands/integration.mjs +43 -74
  183. package/clients/cli/commands/layout-check.doc.mjs +65 -0
  184. package/clients/cli/commands/layout-expand.doc.mjs +83 -0
  185. package/clients/cli/commands/layout-grammar.doc.mjs +30 -0
  186. package/clients/cli/commands/layout.doc.mjs +34 -0
  187. package/clients/cli/commands/layout.error-codes.test.mjs +66 -0
  188. package/clients/cli/commands/layout.exit-parity.test.mjs +41 -0
  189. package/clients/cli/commands/layout.mjs +275 -0
  190. package/clients/cli/commands/layout.path-help.test.mjs +33 -0
  191. package/clients/cli/commands/layout.stdin-cap.test.mjs +47 -0
  192. package/clients/cli/commands/layout.text-fields.test.mjs +39 -0
  193. package/clients/cli/commands/manifest.doc.mjs +1 -1
  194. package/clients/cli/commands/search.doc.mjs +3 -10
  195. package/clients/cli/commands/search.mjs +2 -21
  196. package/clients/cli/commands/search.test.mjs +4 -21
  197. package/clients/cli/commands/swizzle.doc.mjs +1 -1
  198. package/clients/cli/commands/template.doc.mjs +1 -1
  199. package/clients/cli/commands/text-json-parity.test.mjs +16 -5
  200. package/clients/cli/commands/theme-add.doc.mjs +1 -1
  201. package/clients/cli/commands/theme-palette-generate.doc.mjs +2 -3
  202. package/clients/cli/commands/theme-palette.doc.mjs +2 -1
  203. package/clients/cli/commands/theme-targets.doc.mjs +2 -2
  204. package/clients/cli/commands/theme.doc.mjs +1 -2
  205. package/clients/cli/commands/upgrade.doc.mjs +3 -62
  206. package/clients/cli/index.mjs +10 -28
  207. package/clients/cli/lib/define-command.mjs +4 -28
  208. package/clients/cli/lib/define-command.test.mjs +0 -54
  209. package/clients/cli/lib/exit-codes.test.mjs +9 -18
  210. package/clients/cli/lib/json-shim.mjs +14 -24
  211. package/clients/cli/lib/json-shim.test.mjs +20 -6
  212. package/clients/cli/lib/manifest.mjs +13 -18
  213. package/clients/cli/lib/manifest.test.mjs +2 -5
  214. package/foundation/agent-docs/agent-docs.mjs +1 -1
  215. package/foundation/agent-docs/agent-docs.test.mjs +1159 -0
  216. package/foundation/discovery/authoring-self-docs.mjs +0 -1
  217. package/foundation/discovery/authoring-self-docs.test.mjs +2 -6
  218. package/foundation/discovery/cli-self-docs.mjs +2 -16
  219. package/foundation/discovery/cli-self-docs.test.mjs +0 -20
  220. package/foundation/discovery/docs-discovery.mjs +1 -5
  221. package/foundation/discovery/docs-discovery.test.mjs +0 -21
  222. package/foundation/discovery/docs-section-key.d.mts +1 -1
  223. package/foundation/discovery/docs-section-key.mjs +1 -1
  224. package/foundation/discovery/template-adapter.mjs +1 -1
  225. package/foundation/doc-compiler/doc-loads.test.mjs +14 -3
  226. package/foundation/doc-compiler/tree.d.mts +0 -4
  227. package/foundation/doc-compiler/tree.mjs +1 -6
  228. package/foundation/doc-compiler/tree.test.mjs +598 -0
  229. package/foundation/integrations/cli-requirement.d.mts +6 -26
  230. package/foundation/integrations/cli-requirement.mjs +11 -46
  231. package/foundation/integrations/cli-requirement.test.mjs +2 -7
  232. package/foundation/integrations/contribution-inventory.mjs +1 -1
  233. package/foundation/integrations/integrations.d.mts +1 -14
  234. package/foundation/integrations/integrations.mjs +1 -41
  235. package/foundation/integrations/integrations.test.mjs +0 -31
  236. package/foundation/response/error-codes.doc.mjs +8 -6
  237. package/foundation/response/error-codes.test.mjs +5 -30
  238. package/foundation/response/response-types.doc.d.mts +3 -4
  239. package/foundation/response/response-types.doc.mjs +27 -40
  240. package/foundation/response/response-types.doc.test.mjs +0 -23
  241. package/foundation/response/response.doc.mjs +10 -11
  242. package/foundation/xle/browser.d.mts +3 -3
  243. package/foundation/xle/browser.mjs +3 -3
  244. package/foundation/xle/expand.mjs +2 -2
  245. package/foundation/xle/parse.mjs +1 -1
  246. package/foundation/xle/print.mjs +2 -2
  247. package/foundation/xle/splice.mjs +1 -1
  248. package/package.json +9 -9
  249. package/api/discover/_adapter.test.mjs +0 -215
  250. package/api/discover/_catalog-view.d.mts +0 -115
  251. package/api/discover/_catalog-view.mjs +0 -203
  252. package/api/discover/_catalog-view.test.mjs +0 -128
  253. package/api/discover/detail/item/item.d.mts +0 -26
  254. package/api/discover/detail/item/item.mjs +0 -78
  255. package/api/discover/detail/item/item.test.mjs +0 -73
  256. package/api/integration/pack-check.lifecycle-output.test.mjs +0 -107
  257. package/api/theme/add/add.rollback.test.mjs +0 -158
  258. package/api/theme/build/build.rollback.test.mjs +0 -148
  259. package/api/upgrade/run/files-changed.test.mjs +0 -111
  260. package/assets/codemods/file-count.test.mjs +0 -163
  261. package/assets/docs/tree/add-a-component.doc.mjs +0 -75
  262. package/assets/docs/tree/add-a-theme.doc.mjs +0 -85
  263. package/assets/docs/tree/add-a-topic.doc.mjs +0 -144
  264. package/assets/docs/tree/agent-guidance.doc.mjs +0 -138
  265. package/assets/docs/tree/block-template.doc.mjs +0 -130
  266. package/assets/docs/tree/build-the-template.doc.mjs +0 -28
  267. package/assets/docs/tree/building-blocks.doc.mjs +0 -46
  268. package/assets/docs/tree/check-your-docs.doc.mjs +0 -137
  269. package/assets/docs/tree/checks.doc.mjs +0 -119
  270. package/assets/docs/tree/codemods.doc.mjs +0 -147
  271. package/assets/docs/tree/component-family.doc.mjs +0 -113
  272. package/assets/docs/tree/component-imports.doc.mjs +0 -69
  273. package/assets/docs/tree/component-lookups.doc.mjs +0 -149
  274. package/assets/docs/tree/components.doc.mjs +0 -23
  275. package/assets/docs/tree/configuration.doc.mjs +0 -23
  276. package/assets/docs/tree/debug-and-gap-reports.doc.mjs +0 -182
  277. package/assets/docs/tree/define-the-theme.doc.mjs +0 -118
  278. package/assets/docs/tree/describe-the-component.doc.mjs +0 -57
  279. package/assets/docs/tree/docs.doc.mjs +0 -21
  280. package/assets/docs/tree/document-the-template.doc.mjs +0 -28
  281. package/assets/docs/tree/document-the-theme.doc.mjs +0 -68
  282. package/assets/docs/tree/export-template-assets.doc.mjs +0 -147
  283. package/assets/docs/tree/extend-or-replace.doc.mjs +0 -103
  284. package/assets/docs/tree/fonts-and-assets.doc.mjs +0 -106
  285. package/assets/docs/tree/generate-a-palette.doc.mjs +0 -66
  286. package/assets/docs/tree/grade-template-with-agent.doc.mjs +0 -105
  287. package/assets/docs/tree/help.doc.mjs +0 -16
  288. package/assets/docs/tree/links.doc.mjs +0 -98
  289. package/assets/docs/tree/package-and-test.doc.mjs +0 -32
  290. package/assets/docs/tree/page-template.doc.mjs +0 -71
  291. package/assets/docs/tree/publishing.doc.mjs +0 -111
  292. package/assets/docs/tree/quick-start.doc.mjs +0 -272
  293. package/assets/docs/tree/replace-a-core-component.doc.mjs +0 -104
  294. package/assets/docs/tree/replace-a-core-template.doc.mjs +0 -172
  295. package/assets/docs/tree/sections-and-placement.doc.mjs +0 -108
  296. package/assets/docs/tree/see-it-in-an-app.doc.mjs +0 -59
  297. package/assets/docs/tree/ship.doc.mjs +0 -16
  298. package/assets/docs/tree/short-and-findable.doc.mjs +0 -108
  299. package/assets/docs/tree/single-component.doc.mjs +0 -165
  300. package/assets/docs/tree/start-a-template.doc.mjs +0 -143
  301. package/assets/docs/tree/subcomponent.doc.mjs +0 -115
  302. package/assets/docs/tree/template-assets.doc.mjs +0 -64
  303. package/assets/docs/tree/template-doc-overview.doc.mjs +0 -109
  304. package/assets/docs/tree/template-fonts.doc.mjs +0 -102
  305. package/assets/docs/tree/template-grading-rubric.doc.mjs +0 -452
  306. package/assets/docs/tree/template-icons.doc.mjs +0 -97
  307. package/assets/docs/tree/template-images-media.doc.mjs +0 -127
  308. package/assets/docs/tree/template-styles.doc.mjs +0 -93
  309. package/assets/docs/tree/templates.doc.mjs +0 -34
  310. package/assets/docs/tree/test-in-an-app.doc.mjs +0 -115
  311. package/assets/docs/tree/test-template-in-app.doc.mjs +0 -128
  312. package/assets/docs/tree/themes.doc.mjs +0 -39
  313. package/assets/docs/tree/troubleshooting.doc.mjs +0 -149
  314. package/assets/docs/tree/upgrading.doc.mjs +0 -103
  315. package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +0 -51
  316. package/assets/docs/tree/verify-packed-template.doc.mjs +0 -77
  317. package/assets/docs/tree/versioning.doc.mjs +0 -161
  318. package/assets/docs/tree/write-good-templates.doc.mjs +0 -64
  319. package/assets/docs/tree/write-the-template-file.doc.mjs +0 -154
  320. package/authoring/discover/discover.doc.d.mts +0 -13
  321. package/authoring/discover/discover.doc.mjs +0 -138
  322. package/authoring/discover/parse.d.mts +0 -24
  323. package/authoring/discover/parse.mjs +0 -128
  324. package/authoring/discover/parse.test.mjs +0 -124
  325. package/authoring/discover/type.ts +0 -87
  326. package/clients/cli/commands/component-batch.test.mjs +0 -341
  327. package/clients/cli/commands/discover.sources.test.mjs +0 -267
  328. package/clients/cli/commands/integration-verify.doc.mjs +0 -22
  329. package/clients/cli/lib/parse-error-format.test.mjs +0 -81
  330. package/foundation/response/batch.type.d.mts +0 -33
  331. package/foundation/response/batch.type.mjs +0 -34
@@ -7,13 +7,13 @@ export const doc = {
7
7
  name: 'integrationPackCheck',
8
8
  namespace: 'cli/api',
9
9
  displayName: 'integrationPackCheck()',
10
- summary: 'Check an integration package the way npm will publish it.',
10
+ summary: 'Prove an integration package survives npm packing.',
11
11
  description:
12
12
  "Validates the local integration, runs the package lifecycle, packs with npm, checks required files against npm's authoritative tarball list, extracts the real tarball into a scratch consumer, compares local and packed contribution inventories, and resolves every packed component through its documented public import to verify that module exports the component. A package that ships a namespace doc or a placed guide, or has a template that sets `replaces`, fails unless its `@astryxdesign/cli` peer range admits only CLIs that read them.",
13
13
  importPath: '@astryxdesign/cli/api',
14
14
  signature:
15
15
  'integrationPackCheck(options?: IntegrationPackCheckOptions): Promise<IntegrationPackCheckResponse>',
16
- keywords: ['verify', 'pack', 'publish', 'tarball', 'consumer'],
16
+ keywords: ['integration', 'pack', 'check', 'publish', 'tarball', 'consumer'],
17
17
  params: [
18
18
  {
19
19
  name: 'options.cwd',
@@ -31,6 +31,6 @@ export const doc = {
31
31
  examples: [
32
32
  {label: 'Check the local package', code: 'await integrationPackCheck();'},
33
33
  ],
34
- command: 'integration verify',
34
+ command: 'integration pack',
35
35
  related: ['integrationAdd', 'validateIntegration'],
36
36
  };
@@ -1,7 +1,7 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
3
  /**
4
- * @file `astryx integration verify` — verify an integration package is
4
+ * @file `astryx integration pack --check` — verify an integration package is
5
5
  * ready to publish by cross-referencing its declared contributions against the
6
6
  * real npm tarball.
7
7
  *
@@ -30,13 +30,8 @@ import {resolvePackageDir} from '../../foundation/integrations/integrations.mjs'
30
30
  import {
31
31
  docsTreeCliProblem,
32
32
  replacesCliProblem,
33
- sectionIdsCliProblem,
34
- themesCliProblem,
35
33
  } from '../../foundation/integrations/cli-requirement.mjs';
36
- import {
37
- discoverIntegrationDocs,
38
- loadTopicModule,
39
- } from '../../foundation/discovery/docs-discovery.mjs';
34
+ import {discoverIntegrationDocs} from '../../foundation/discovery/docs-discovery.mjs';
40
35
  import {
41
36
  discoverIntegrationComponents,
42
37
  resolveIntegrationImportPath,
@@ -167,22 +162,6 @@ export function parseNpmPackOutput(output) {
167
162
  };
168
163
  }
169
164
 
170
- /**
171
- * Summarize the JSON error npm prints on stdout when `--json` pack fails.
172
- * @param {string} output
173
- * @returns {string}
174
- */
175
- function npmPackErrorDetail(output) {
176
- try {
177
- const error = JSON.parse(output)?.error;
178
- return [error?.summary, error?.detail]
179
- .filter(part => typeof part === 'string' && part.trim() !== '')
180
- .join(': ');
181
- } catch {
182
- return (output || '').trim();
183
- }
184
- }
185
-
186
165
  /**
187
166
  * Run `npm pack --json` with output directed to `destDir` so no preexisting
188
167
  * tgz is overwritten. This intentionally runs the package lifecycle, matching
@@ -196,25 +175,16 @@ function npmPackErrorDetail(output) {
196
175
  function runNpmPack(packageDir, destDir) {
197
176
  const result = spawnSync(
198
177
  'npm',
199
- [
200
- 'pack',
201
- '--json',
202
- '--silent',
203
- // Lifecycle scripts still run; background mode keeps their output off
204
- // the stdout that carries the JSON result.
205
- '--foreground-scripts=false',
206
- `--pack-destination=${destDir}`,
207
- ],
178
+ ['pack', '--json', '--silent', `--pack-destination=${destDir}`],
208
179
  {cwd: packageDir, encoding: 'utf-8', timeout: 60_000},
209
180
  );
210
181
  if (result.error) {
211
182
  throw new Error(`Could not start npm pack: ${result.error.message}`);
212
183
  }
213
184
  if (result.status !== 0) {
214
- const detail =
215
- (result.stderr || '').trim() || npmPackErrorDetail(result.stdout);
185
+ const stderr = (result.stderr || '').trim();
216
186
  throw new Error(
217
- `npm pack failed (exit ${result.status})${detail ? `: ${detail}` : ''}.`,
187
+ `npm pack failed (exit ${result.status})${stderr ? `: ${stderr}` : ''}.`,
218
188
  );
219
189
  }
220
190
  return parseNpmPackOutput(result.stdout);
@@ -338,23 +308,6 @@ function moduleExportsName(file, exportName, seen = new Set()) {
338
308
  return found;
339
309
  }
340
310
 
341
- /**
342
- * Whether any of these doc files has a section that sets `id`.
343
- * @param {string[]} files
344
- * @returns {Promise<boolean>}
345
- */
346
- async function setsSectionIds(files) {
347
- for (const file of files) {
348
- if (typeof file !== 'string') continue;
349
- const doc = /** @type {any} */ (await loadTopicModule(file).catch(() => null));
350
- const sections = Array.isArray(doc?.sections) ? doc.sections : [];
351
- if (sections.some((/** @type {any} */ section) => section?.id != null)) {
352
- return true;
353
- }
354
- }
355
- return false;
356
- }
357
-
358
311
  /**
359
312
  * Resolve package specifiers through Node's real ESM resolver from the scratch
360
313
  * consumer. Resolution does not execute the target module, so source `.tsx`
@@ -647,31 +600,19 @@ export async function integrationPackCheck(options = {}) {
647
600
  // (spec:AST-046 FR11): an older CLI can hide every doc topic the package
648
601
  // ships, so the declared CLI range must admit only CLIs that read it.
649
602
  if (loaded.docs) {
650
- const {records, namespaces, guides} = await discoverIntegrationDocs(
651
- loaded,
652
- ).catch(() => ({records: [], namespaces: [], guides: []}));
603
+ const {namespaces, guides} = await discoverIntegrationDocs(loaded).catch(
604
+ () => ({namespaces: [], guides: []}),
605
+ );
653
606
  const problem =
654
607
  namespaces.length > 0 || guides.length > 0
655
608
  ? docsTreeCliProblem(pkg)
656
609
  : null;
657
610
  if (problem != null) {
658
611
  issues.push(error('docs_tree_needs_cli', problem));
659
- } else if (
660
- await setsSectionIds([
661
- ...records.map(record => record.path),
662
- ...guides.map(guide => /** @type {any} */ (guide.ref).topicFile),
663
- ])
664
- ) {
665
- // A section `id` is also a field an older CLI rejects, hiding the
666
- // package's doc topics; the same peer range fixes both.
667
- const idProblem = sectionIdsCliProblem(pkg);
668
- if (idProblem != null) {
669
- issues.push(error('section_ids_need_cli', idProblem));
670
- }
671
612
  }
672
613
  }
673
614
  // A template that sets `replaces` needs a CLI that reads the field
674
- // (spec:AST-035): an older CLI drops that template and hides the package's docs.
615
+ // (spec:AST-035): an older CLI withholds the package's templates and docs.
675
616
  if (loaded.templates) {
676
617
  const found = await discoverIntegrationTemplatesForOne(loaded).catch(
677
618
  () => ({templates: [], errors: []}),
@@ -684,12 +625,6 @@ export async function integrationPackCheck(options = {}) {
684
625
  const problem = setsReplaces ? replacesCliProblem(pkg) : null;
685
626
  if (problem != null) issues.push(error('replaces_needs_cli', problem));
686
627
  }
687
- // A theme needs a CLI that reads typed theme descriptors: an older CLI
688
- // rejects the themes root and withholds the package's themes and docs.
689
- if (localIdentities.themes.length > 0) {
690
- const problem = themesCliProblem(pkg);
691
- if (problem != null) issues.push(error('themes_need_cli', problem));
692
- }
693
628
 
694
629
  // Temp resources — always cleaned up
695
630
  const tgzTmpDir = fs.mkdtempSync(
@@ -722,14 +657,6 @@ export async function integrationPackCheck(options = {}) {
722
657
  // package's already-installed dependencies. The unique suffix makes
723
658
  // concurrent checks independent.
724
659
  scratchBase = fs.mkdtempSync(path.join(packageDir, '.astryx-pack-check-'));
725
- // The consumer's own package.json makes it the package scope for its
726
- // imports. Without one, Node resolves the package's name through the
727
- // SOURCE package.json (self-reference), so an export target left out of
728
- // the tarball would still resolve.
729
- fs.writeFileSync(
730
- path.join(scratchBase, 'package.json'),
731
- `${JSON.stringify({name: 'astryx-verify-consumer', private: true})}\n`,
732
- );
733
660
 
734
661
  // Cross-reference file inventory vs pack list
735
662
  if (!packResult.packedPaths.has(fileInv.manifest)) {
@@ -36,8 +36,6 @@ function writePackage({
36
36
  scripts,
37
37
  } = {}) {
38
38
  const pkg = {name, version};
39
- // A theme needs a CLI that reads typed theme descriptors.
40
- if (themes) pkg.peerDependencies = {'@astryxdesign/cli': '>=0.7.0'};
41
39
  if (files !== undefined) pkg.files = files;
42
40
  if (scripts !== undefined) pkg.scripts = scripts;
43
41
  fs.writeFileSync(
@@ -96,30 +94,6 @@ describe('integrationPackCheck', () => {
96
94
  );
97
95
  });
98
96
 
99
- it('fails a package that ships a theme on a CLI range that cannot read it', async () => {
100
- writePackage({files: ['astryx.integration.mjs', 'themes']});
101
- const pkgFile = path.join(tmpDir, 'package.json');
102
- const pkg = JSON.parse(fs.readFileSync(pkgFile, 'utf-8'));
103
- delete pkg.peerDependencies;
104
- fs.writeFileSync(pkgFile, `${JSON.stringify(pkg, null, 2)}\n`);
105
-
106
- const missing = await integrationPackCheck({cwd: tmpDir});
107
- expect(missing.data.packable).toBe(false);
108
- expect(missing.data.issues).toContainEqual(
109
- expect.objectContaining({
110
- code: 'themes_need_cli',
111
- message: expect.stringContaining('ships a theme'),
112
- }),
113
- );
114
-
115
- pkg.peerDependencies = {'@astryxdesign/cli': '^0.6.3'};
116
- fs.writeFileSync(pkgFile, `${JSON.stringify(pkg, null, 2)}\n`);
117
- const old = await integrationPackCheck({cwd: tmpDir});
118
- expect(old.data.issues).toContainEqual(
119
- expect.objectContaining({code: 'themes_need_cli'}),
120
- );
121
- });
122
-
123
97
  it('fails when a theme entry omits its inferred runtime export', async () => {
124
98
  writePackage({files: ['astryx.integration.mjs', 'themes']});
125
99
  fs.writeFileSync(
@@ -219,39 +193,6 @@ describe('integrationPackCheck', () => {
219
193
  );
220
194
  });
221
195
 
222
- it('resolves public imports in the packed package, not the source', async () => {
223
- // The root export's target is left out of `files`: the source package
224
- // resolves it, but an app that installs the tarball cannot.
225
- fs.writeFileSync(
226
- path.join(tmpDir, 'package.json'),
227
- `${JSON.stringify({
228
- name: '@acme/widgets',
229
- version: '1.0.0',
230
- files: ['astryx.integration.mjs'],
231
- exports: {'.': './index.mjs'},
232
- })}\n`,
233
- );
234
- fs.writeFileSync(
235
- path.join(tmpDir, 'index.mjs'),
236
- "export {AcmeWidget} from './components/AcmeWidget.tsx';\n",
237
- );
238
- await integrationAddComponent('AcmeWidget', {cwd: tmpDir});
239
- const docFile = path.join(tmpDir, 'components', 'AcmeWidget.doc.mjs');
240
- const doc = fs.readFileSync(docFile, 'utf-8');
241
- expect(doc).toContain('@acme/widgets/components/AcmeWidget');
242
- fs.writeFileSync(
243
- docFile,
244
- doc.replace('@acme/widgets/components/AcmeWidget', '@acme/widgets'),
245
- );
246
-
247
- const result = await integrationPackCheck({cwd: tmpDir});
248
-
249
- expect(result.data.packable).toBe(false);
250
- expect(result.data.issues).toContainEqual(
251
- expect.objectContaining({code: 'component_export_missing'}),
252
- );
253
- });
254
-
255
196
  it('fails when packed template source is hidden by package exports', async () => {
256
197
  writePackage({
257
198
  manifest: "export default {templates: './templates'};\n",
@@ -395,37 +336,6 @@ describe('integrationPackCheck', () => {
395
336
  expect(await codes()).not.toContain('docs_tree_needs_cli');
396
337
  }, 120_000);
397
338
 
398
- it('fails a package whose doc section sets id on a CLI range that rejects the field', async () => {
399
- writePackage({manifest: "export default {docs: './docs'};\n", themes: false});
400
- fs.mkdirSync(path.join(tmpDir, 'docs'), {recursive: true});
401
- const topic = (/** @type {string} */ section) =>
402
- `export default {type: 'generic', name: 'notes', title: 'Notes', description: 'Notes.', sections: [${section}]};\n`;
403
- const file = path.join(tmpDir, 'docs', 'notes.doc.mjs');
404
- const codes = async () =>
405
- (await integrationPackCheck({cwd: tmpDir})).data.issues.map(
406
- (/** @type {{code: string}} */ issue) => issue.code,
407
- );
408
- fs.writeFileSync(
409
- file,
410
- topic("{title: 'Take notes', content: [{type: 'prose', text: 'Notes.'}]}"),
411
- );
412
- expect(await codes()).not.toContain('section_ids_need_cli');
413
- // A fresh file name: the module loader caches a path once it is imported.
414
- fs.rmSync(file);
415
- fs.writeFileSync(
416
- path.join(tmpDir, 'docs', 'notes-with-ids.doc.mjs'),
417
- topic(
418
- "{id: 'take-notes', title: 'Take notes', content: [{type: 'prose', text: 'Notes.'}]}",
419
- ),
420
- );
421
- expect(await codes()).toContain('section_ids_need_cli');
422
- const pkgFile = path.join(tmpDir, 'package.json');
423
- const pkg = JSON.parse(fs.readFileSync(pkgFile, 'utf-8'));
424
- pkg.peerDependencies = {'@astryxdesign/cli': '>=0.7.0'};
425
- fs.writeFileSync(pkgFile, `${JSON.stringify(pkg, null, 2)}\n`);
426
- expect(await codes()).not.toContain('section_ids_need_cli');
427
- }, 120_000);
428
-
429
339
  it('fails a package with a template that sets replaces on a CLI range that rejects the field', async () => {
430
340
  writePackage({manifest: "export default {templates: './templates'};\n", themes: false});
431
341
  fs.mkdirSync(path.join(tmpDir, 'templates'), {recursive: true});
@@ -1,7 +1,7 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
3
  /**
4
- * @file Colocated types for `astryx integration verify`.
4
+ * @file Colocated types for `astryx integration pack --check`.
5
5
  */
6
6
 
7
7
  /**
@@ -49,7 +49,7 @@ export const doc = {
49
49
  throws: [
50
50
  {
51
51
  code: 'Error',
52
- when: 'a plain Error with no code: the CLI returned an error envelope (its message is rethrown; code and suggestions are dropped), or the response `type` is not expectedType',
52
+ when: 'the CLI returned an error envelope (the CLI message is rethrown), or the response `type` is not expectedType',
53
53
  },
54
54
  ],
55
55
  examples: [
package/api/json/index.ts CHANGED
@@ -26,6 +26,7 @@ export type * from '../gap-report/gap-report.type.mjs';
26
26
  export type * from '../upgrade/upgrade.type.mjs';
27
27
  export type * from '../init/init.type.mjs';
28
28
  export type * from '../doctor/doctor.type.mjs';
29
+ export type * from '../layout/layout.type.mjs';
29
30
  export type * from '../integration/validate-integration.type.mjs';
30
31
  export type * from '../integration/authoring-checks.type.mjs';
31
32
  export type * from '../integration/pack-check.type.mjs';
@@ -15,7 +15,7 @@ export const doc = {
15
15
  displayName: 'isError()',
16
16
  summary: 'Did the CLI return an error envelope?',
17
17
  description:
18
- 'Tests a parsed response for an `error` key. Branch on this before touching `data`, ' +
18
+ 'Tests a parsed response for an `error` key. Branch on this before touching `data`: ' +
19
19
  'and prefer the stable `code` field over matching the human-readable message, which is ' +
20
20
  'not a contract. Note this returns a plain boolean, not a TypeScript type predicate, so ' +
21
21
  'it does not narrow on its own: cast to the matching *Response type to get typed access.',
@@ -0,0 +1,34 @@
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
+ /** @param {import('../../foundation/xle/xle-ast').RawIssue} issue */
5
+ export function formatIssue(issue: import("../../foundation/xle/xle-ast").RawIssue): string;
6
+ /**
7
+ * Parse + validate, throwing structured XDSErrors on failure.
8
+ * Returns {doc, registry, blocks, warnings}.
9
+ *
10
+ * @param {string} expression
11
+ * @param {{form?: 'compact'|'outline'|'auto', loose?: boolean, cwd?: string}} [options]
12
+ */
13
+ export function analyze(expression: string, { form, loose, cwd }?: {
14
+ form?: "compact" | "outline" | "auto";
15
+ loose?: boolean;
16
+ cwd?: string;
17
+ }): Promise<{
18
+ doc: import("../../foundation/xle/xle-ast").XLEDoc;
19
+ registry: import("../../foundation/xle/xle-ast").Registry;
20
+ blocks: LayoutBlock[];
21
+ errors: import("../../foundation/xle/xle-ast").RawIssue[];
22
+ warnings: import("../../foundation/xle/xle-ast").RawIssue[];
23
+ }>;
24
+ export type LayoutBlock = {
25
+ dirName: string;
26
+ name: string;
27
+ kind: "template" | "component";
28
+ type?: string | undefined;
29
+ description?: string | undefined;
30
+ category?: string | undefined;
31
+ importPath?: string | undefined;
32
+ filePath?: string | undefined;
33
+ isDefault?: boolean | undefined;
34
+ };
@@ -0,0 +1,148 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file Shared analysis layer for the `layout` command's expand/check leaves.
5
+ *
6
+ * Loads the block catalog (template blocks + app-registered components), builds
7
+ * the branch registry, and parses+validates a layout expression into a doc +
8
+ * issues. Both the expand and check leaves sit on `analyze`; neither parses or
9
+ * validates directly. (The grammar leaf needs none of this — it only reads the
10
+ * registry alias table.)
11
+ *
12
+ * @input expression string (+ options)
13
+ * @output analyze() -> {doc, registry, blocks, errors, warnings}; formatIssue()
14
+ * @position api — shared core over lib/xle; leaves in expand/ + check/ project it
15
+ */
16
+
17
+ import {AstryxError} from '../error.mjs';
18
+ import {ERROR_CODES} from '../../foundation/response/error-codes.mjs';
19
+ import {parse, XLEParseError} from '../../foundation/xle/parse.mjs';
20
+ import {validate} from '../../foundation/xle/validate.mjs';
21
+ import {buildRegistry} from '../../foundation/xle/registry.mjs';
22
+ import {discoverTemplates} from '../template/template.mjs';
23
+ import {Project} from '../../foundation/config/project.mjs';
24
+
25
+ /**
26
+ * @typedef {object} LayoutBlock
27
+ * @property {string} dirName
28
+ * @property {string} name
29
+ * @property {'template'|'component'} kind
30
+ * @property {string} [type]
31
+ * @property {string} [description]
32
+ * @property {string} [category]
33
+ * @property {string} [importPath]
34
+ * @property {string} [filePath]
35
+ * @property {boolean} [isDefault]
36
+ */
37
+
38
+ /**
39
+ * The catalog a `{hint}` can resolve to: template blocks (spliced inline) plus
40
+ * any app-registered local components from astryx.config.mjs
41
+ * `experimental.xle.components` (imported by name). App components are how XLE
42
+ * reaches domain pieces — the KpiCard/chart/drawer set that the
43
+ * @astryxdesign/core registry can't see.
44
+ *
45
+ * @param {string} cwd
46
+ * @returns {Promise<LayoutBlock[]>}
47
+ */
48
+ async function loadBlocks(cwd) {
49
+ /** @type {LayoutBlock[]} */
50
+ const blocks = [];
51
+ try {
52
+ const all = await discoverTemplates(cwd);
53
+ const templates = all.filter(template => template.type === 'block');
54
+ /** @type {Map<string, import('../../foundation/discovery/template-adapter.mjs').DiscoveredTemplate>} */
55
+ const byId = new Map();
56
+ // Exact ids are the fallback. Active replacement aliases override them in a
57
+ // second pass, matching template() regardless of discovery/display order.
58
+ for (const template of templates) byId.set(template.dirName, template);
59
+ for (const template of templates) {
60
+ if (template.replaces != null) byId.set(template.replaces, template);
61
+ }
62
+ for (const [id, template] of byId) {
63
+ blocks.push({...template, dirName: id, kind: 'template'});
64
+ }
65
+ } catch {
66
+ // discovery is best-effort
67
+ }
68
+ try {
69
+ const project = await Project.load(cwd);
70
+ /** @type {Record<string, {from?: string, description?: string, default?: boolean}>} */
71
+ const components = project.config.experimental?.xle?.components ?? {};
72
+ for (const [name, spec] of Object.entries(components)) {
73
+ const importPath = spec.from;
74
+ if (!importPath) continue;
75
+ blocks.push({
76
+ type: 'block',
77
+ kind: 'component',
78
+ dirName: name,
79
+ name,
80
+ description: spec.description ?? '',
81
+ category: 'app',
82
+ importPath,
83
+ isDefault: Boolean(spec.default),
84
+ });
85
+ }
86
+ } catch {
87
+ // config is optional
88
+ }
89
+ return blocks;
90
+ }
91
+
92
+ /** @param {import('../../foundation/xle/xle-ast').RawIssue} issue */
93
+ export function formatIssue(issue) {
94
+ const where = issue.line != null ? `line ${issue.line}: ` : '';
95
+ return `${where}${issue.message}`;
96
+ }
97
+
98
+ /**
99
+ * Parse + validate, throwing structured XDSErrors on failure.
100
+ * Returns {doc, registry, blocks, warnings}.
101
+ *
102
+ * @param {string} expression
103
+ * @param {{form?: 'compact'|'outline'|'auto', loose?: boolean, cwd?: string}} [options]
104
+ */
105
+ export async function analyze(
106
+ expression,
107
+ {form = 'auto', loose = false, cwd = process.cwd()} = {},
108
+ ) {
109
+ // Validate inputs in the API (not just the CLI): an empty expression or an
110
+ // unknown --form must error, not silently parse as an empty/compact layout.
111
+ if (typeof expression !== 'string' || expression.trim() === '') {
112
+ throw new AstryxError(
113
+ 'Layout expression is empty.',
114
+ undefined,
115
+ ERROR_CODES.ERR_INVALID_ARGUMENT,
116
+ );
117
+ }
118
+ if (form !== 'compact' && form !== 'outline' && form !== 'auto') {
119
+ throw new AstryxError(
120
+ `Invalid form "${form}". Must be one of: compact, outline, auto.`,
121
+ undefined,
122
+ ERROR_CODES.ERR_INVALID_OPTION,
123
+ );
124
+ }
125
+ const registry =
126
+ /** @type {import('../../foundation/xle/xle-ast').Registry} */ (
127
+ /** @type {unknown} */ (await buildRegistry({cwd}))
128
+ );
129
+ const blocks = await loadBlocks(cwd);
130
+
131
+ /** @type {import('../../foundation/xle/xle-ast').XLEDoc} */
132
+ let doc;
133
+ try {
134
+ doc = parse(expression, {form});
135
+ } catch (e) {
136
+ if (e instanceof XLEParseError) {
137
+ throw new AstryxError(
138
+ `Layout expression syntax error at line ${e.line}, col ${e.col}: ${e.message}`,
139
+ undefined,
140
+ ERROR_CODES.ERR_LAYOUT_PARSE,
141
+ );
142
+ }
143
+ throw e;
144
+ }
145
+
146
+ const {errors, warnings} = validate(doc, registry, blocks, {loose});
147
+ return {doc, registry, blocks, errors, warnings};
148
+ }
@@ -0,0 +1,16 @@
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
+ * `astryx layout check "<expr>" [--form compact|outline]`
6
+ * Validates without expanding; echoes both canonical surfaces.
7
+ *
8
+ * @param {string} expression
9
+ * @param {{form?: 'compact'|'outline'|'auto', loose?: boolean, cwd?: string}} [options]
10
+ * @returns {Promise<import('../layout.type.mjs').LayoutCheckResponse>}
11
+ */
12
+ export function layoutCheck(expression: string, options?: {
13
+ form?: "compact" | "outline" | "auto";
14
+ loose?: boolean;
15
+ cwd?: string;
16
+ }): Promise<import("../layout.type.mjs").LayoutCheckResponse>;
@@ -0,0 +1,40 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file `astryx layout check` leaf — validate a layout expression without
5
+ * expanding, echoing both canonical surfaces (compact + outline). Resolution +
6
+ * validation come from ../_adapter.mjs (analyze); this leaf projects the
7
+ * `layout.check` envelope.
8
+ *
9
+ * @input expression string (+ options)
10
+ * @output {type:'layout.check', data}
11
+ * @position api — leaf over ../_adapter.mjs + lib/xle/print
12
+ */
13
+
14
+ import {toCompact, toOutline} from '../../../foundation/xle/print.mjs';
15
+ import {analyze, formatIssue} from '../_adapter.mjs';
16
+
17
+ /**
18
+ * `astryx layout check "<expr>" [--form compact|outline]`
19
+ * Validates without expanding; echoes both canonical surfaces.
20
+ *
21
+ * @param {string} expression
22
+ * @param {{form?: 'compact'|'outline'|'auto', loose?: boolean, cwd?: string}} [options]
23
+ * @returns {Promise<import('../layout.type.mjs').LayoutCheckResponse>}
24
+ */
25
+ export async function layoutCheck(expression, options = {}) {
26
+ const {form = 'auto', loose = false, cwd = process.cwd()} = options;
27
+ const {doc, errors, warnings} = await analyze(expression, {form, loose, cwd});
28
+
29
+ return {
30
+ type: 'layout.check',
31
+ data: {
32
+ valid: errors.length === 0,
33
+ form: doc.form,
34
+ errors: errors.map(e => ({...e, formatted: formatIssue(e)})),
35
+ warnings: warnings.map(formatIssue),
36
+ compact: toCompact(doc),
37
+ outline: toOutline(doc),
38
+ },
39
+ };
40
+ }
@@ -0,0 +1,22 @@
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
+ * `astryx layout expand "<expr>" [path]`
6
+ *
7
+ * @param {string} expression
8
+ * @param {object} [options]
9
+ * @param {string} [options.targetPath] - write TSX here (validated against cwd)
10
+ * @param {'compact'|'outline'|'auto'} [options.form]
11
+ * @param {boolean} [options.loose] - downgrade unknown {hints} to TODO warnings
12
+ * @param {string} [options.name] - generated component name
13
+ * @param {string} [options.cwd]
14
+ * @returns {Promise<import('../layout.type.mjs').LayoutExpandResponse>}
15
+ */
16
+ export function layoutExpand(expression: string, options?: {
17
+ targetPath?: string | undefined;
18
+ form?: "compact" | "auto" | "outline" | undefined;
19
+ loose?: boolean | undefined;
20
+ name?: string | undefined;
21
+ cwd?: string | undefined;
22
+ }): Promise<import("../layout.type.mjs").LayoutExpandResponse>;