@astryxdesign/cli 0.1.8-canary.0c4d8d7 → 0.1.8-canary.0db5dfd

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 (303) hide show
  1. package/{src/api → api/blog}/blog.mjs +42 -6
  2. package/{src/api → api/blog}/blog.test.mjs +2 -2
  3. package/api/build/build.mjs +92 -0
  4. package/api/build/build.test.mjs +92 -0
  5. package/{src/api → api/component}/component.mjs +49 -26
  6. package/{src/api → api/discover}/discover.mjs +55 -18
  7. package/{src/api → api/docs}/docs.mjs +47 -21
  8. package/{src/api → api/doctor}/doctor.mjs +11 -8
  9. package/{src/api → api/hook}/hook.mjs +11 -11
  10. package/{src/api → api}/index.mjs +16 -9
  11. package/{src/api → api/integration}/validate-integration.mjs +48 -15
  12. package/{src/api → api/integration}/validate-integration.test.mjs +1 -1
  13. package/{src/api → api/layout}/layout.mjs +66 -17
  14. package/{src/api → api/layout}/layout.test.mjs +1 -1
  15. package/{src/api → api/search}/search.mjs +71 -12
  16. package/api/swizzle/swizzle.mjs +283 -0
  17. package/{src/commands → api/swizzle}/swizzle.test.mjs +26 -1
  18. package/{src/api → api/template}/template-integration.test.mjs +2 -2
  19. package/{src/api → api/template}/template-suffix.test.mjs +3 -3
  20. package/{src/api → api/template}/template.mjs +96 -19
  21. package/{src/api → api/theme}/theme-add.mjs +35 -7
  22. package/{src → authoring}/codemod.mjs +6 -6
  23. package/{src → authoring}/config.test.mjs +1 -1
  24. package/{src → authoring}/doc.mjs +1 -1
  25. package/{src → authoring}/doc.test.mjs +1 -1
  26. package/{src → authoring}/template.mjs +1 -1
  27. package/bin/astryx.mjs +12 -10
  28. package/{src → cli}/commands/blog.mjs +48 -7
  29. package/{src → cli}/commands/build-theme.mjs +125 -46
  30. package/{src → cli}/commands/build.mjs +33 -57
  31. package/{src → cli}/commands/component/index.mjs +49 -22
  32. package/{src → cli}/commands/component-ownership.test.mjs +3 -3
  33. package/{src → cli}/commands/component-package.test.mjs +1 -1
  34. package/{src → cli}/commands/component-resolution.test.mjs +2 -2
  35. package/{src → cli}/commands/discover.mjs +17 -8
  36. package/{src → cli}/commands/docs.mjs +39 -7
  37. package/{src → cli}/commands/docs.test.mjs +1 -1
  38. package/{src → cli}/commands/doctor.mjs +3 -3
  39. package/{src → cli}/commands/doctor.test.mjs +2 -2
  40. package/{src → cli}/commands/ensure-core-built.mjs +3 -2
  41. package/{src → cli}/commands/external-showcase.test.mjs +1 -1
  42. package/{src → cli}/commands/hook/index.mjs +37 -14
  43. package/{src → cli}/commands/import-hint-correctness.test.mjs +1 -1
  44. package/{src → cli}/commands/init.mjs +20 -9
  45. package/{src → cli}/commands/layout.mjs +58 -18
  46. package/{src → cli}/commands/search.mjs +19 -12
  47. package/{src → cli}/commands/search.test.mjs +1 -1
  48. package/{src → cli}/commands/setup-nudge.test.mjs +1 -1
  49. package/cli/commands/swizzle.mjs +103 -0
  50. package/{src → cli}/commands/template.mjs +73 -22
  51. package/{src → cli}/commands/template.path-safety.test.mjs +2 -2
  52. package/{src → cli}/commands/upgrade.integration-policy.test.mjs +1 -1
  53. package/{src → cli}/commands/upgrade.mjs +160 -52
  54. package/{src → cli}/commands/upgrade.test.mjs +1 -1
  55. package/{src → cli}/commands/validate-integration.mjs +17 -37
  56. package/{src → cli}/index.mjs +17 -15
  57. package/{src/codemods → codemods}/ensure-jscodeshift.mjs +1 -1
  58. package/{src/codemods → codemods}/integration-discovery.mjs +6 -3
  59. package/{src/codemods → codemods}/integration-discovery.test.mjs +1 -1
  60. package/{src/codemods → codemods}/integration-runner.mjs +8 -3
  61. package/{src/codemods → codemods}/registry.mjs +3 -1
  62. package/{src/codemods → codemods}/run-codemod.mjs +17 -10
  63. package/{src/codemods → codemods}/runner.mjs +22 -12
  64. package/{src/codemods → codemods}/transforms/v0.0.10/remove-size-props.mjs +9 -4
  65. package/{src/codemods → codemods}/transforms/v0.0.12/add-is-icon-only.mjs +27 -22
  66. package/{src/codemods → codemods}/transforms/v0.0.13/icon-name-deprecations.mjs +12 -5
  67. package/{src/codemods → codemods}/transforms/v0.0.13/rename-attachments-to-drawer.mjs +15 -8
  68. package/{src/codemods → codemods}/transforms/v0.0.13/toolbar-density-to-size.mjs +10 -4
  69. package/{src/codemods → codemods}/transforms/v0.0.14/rename-action-props.mjs +11 -5
  70. package/{src/codemods → codemods}/transforms/v0.0.14/rename-section-wash-to-muted.mjs +11 -6
  71. package/{src/codemods → codemods}/transforms/v0.0.14/rename-status-variants.mjs +15 -10
  72. package/{src/codemods → codemods}/transforms/v0.0.15/migrate-item-children-to-endcontent.mjs +13 -8
  73. package/{src/codemods → codemods}/transforms/v0.0.15/migrate-selector-children-to-render-option.mjs +18 -13
  74. package/{src/codemods → codemods}/transforms/v0.0.15/migrate-theme-selectors-to-data-attrs.mjs +8 -4
  75. package/{src/codemods → codemods}/transforms/v0.0.15/rename-date-picker-to-input.mjs +11 -6
  76. package/{src/codemods → codemods}/transforms/v0.0.15/rename-imperative-ref-to-handleRef.mjs +6 -1
  77. package/{src/codemods → codemods}/transforms/v0.0.15/rename-isStreaming-to-isStopShown.mjs +6 -1
  78. package/{src/codemods → codemods}/transforms/v0.0.15/rename-stack-element-to-as.mjs +8 -3
  79. package/{src/codemods → codemods}/transforms/v0.0.2/migrate-badge-dot-to-statusdot.mjs +17 -10
  80. package/{src/codemods → codemods}/transforms/v0.0.2/migrate-gap-to-numeric.mjs +7 -1
  81. package/{src/codemods → codemods}/transforms/v0.0.2/migrate-isFullBleed-to-padding.mjs +9 -4
  82. package/{src/codemods → codemods}/transforms/v0.0.2/migrate-useXDSIcon-to-getIcon.mjs +12 -7
  83. package/{src/codemods → codemods}/transforms/v0.0.2/rename-banner-endButton-to-endContent.mjs +7 -2
  84. package/{src/codemods → codemods}/transforms/v0.0.2/rename-form-tooltip-startIcon.mjs +8 -2
  85. package/{src/codemods → codemods}/transforms/v0.0.2/rename-isShown-to-isOpen.mjs +7 -2
  86. package/{src/codemods → codemods}/transforms/v0.0.2/rename-selector-items-to-options.mjs +7 -2
  87. package/{src/codemods → codemods}/transforms/v0.0.2/rename-sidenav-header-to-heading.mjs +11 -4
  88. package/{src/codemods → codemods}/transforms/v0.0.2/rename-topnav-title-to-heading.mjs +10 -4
  89. package/{src/codemods → codemods}/transforms/v0.0.2/unify-uncontrolled-to-defaultX.mjs +7 -2
  90. package/{src/codemods → codemods}/transforms/v0.0.2/unify-visibility-to-onOpenChange.mjs +10 -5
  91. package/{src/codemods → codemods}/transforms/v0.0.6/migrate-badge-children-to-label.mjs +7 -2
  92. package/{src/codemods → codemods}/transforms/v0.0.6/migrate-collapse-to-collapsible.mjs +9 -3
  93. package/{src/codemods → codemods}/transforms/v0.0.6/migrate-radius-tokens.mjs +11 -5
  94. package/{src/codemods → codemods}/transforms/v0.0.6/migrate-shadow-tokens.mjs +13 -6
  95. package/{src/codemods → codemods}/transforms/v0.0.6/migrate-skeleton-radius.mjs +7 -1
  96. package/{src/codemods → codemods}/transforms/v0.0.6/migrate-token-names.mjs +11 -5
  97. package/{src/codemods → codemods}/transforms/v0.0.7/rename-banner-variant-to-container.mjs +8 -3
  98. package/{src/codemods → codemods}/transforms/v0.0.8/migrate-token-renames.mjs +15 -8
  99. package/{src/codemods → codemods}/transforms/v0.0.8/rename-endslot-to-endcontent.mjs +7 -2
  100. package/{src/codemods → codemods}/transforms/v0.1.0/drop-xds-prefix-imports.mjs +19 -14
  101. package/{src/codemods → codemods}/transforms/v0.1.0/migrate-xds-css-surfaces.mjs +21 -17
  102. package/{src/codemods → codemods}/transforms/v0.1.0/migrate-xds-declare-module.mjs +7 -2
  103. package/{src/codemods → codemods}/transforms/v0.1.0/migrate-xds-module-specifiers.mjs +16 -11
  104. package/{src/codemods → codemods}/transforms/v0.1.2/rename-text-color-active-to-accent.mjs +15 -9
  105. package/{src/codemods → codemods}/transforms/v0.1.3/migrate-layout-components-to-experimental.mjs +17 -12
  106. package/{src/codemods → codemods}/transforms/v0.1.5/rename-switch-label-spacing-default-to-hug.mjs +15 -9
  107. package/{src/codemods → codemods}/transforms/v0.1.7/migrate-table-tableprops-to-direct-props.mjs +17 -10
  108. package/{src/codemods → codemods}/transforms/v0.1.7/rename-table-renderprops-styles-to-xstyle.mjs +18 -13
  109. package/{src/codemods → codemods}/transforms/v0.1.8/rename-avatar-size-scale.mjs +15 -10
  110. package/docs/internationalization.doc.mjs +92 -46
  111. package/{src/commands → lib/agent-docs}/agent-docs.mjs +30 -11
  112. package/{src/commands → lib/agent-docs}/agent-docs.path-safety.test.mjs +1 -1
  113. package/{src/lib → lib}/component-discovery.mjs +44 -2
  114. package/{src/lib → lib}/component-format.mjs +65 -24
  115. package/{src/lib → lib}/component-loader.mjs +27 -13
  116. package/{src/lib → lib}/componentDocOverlay.test.mjs +0 -1
  117. package/{src/lib → lib}/error-codes.test.mjs +1 -1
  118. package/{src/lib → lib}/hook-discovery.mjs +14 -1
  119. package/{src/lib → lib}/hook-format.mjs +29 -5
  120. package/{src/lib → lib}/integration-warnings.mjs +2 -2
  121. package/{src/lib → lib}/integrations.mjs +20 -0
  122. package/{src/lib → lib}/integrations.test.mjs +1 -1
  123. package/{src/lib → lib}/json-contract.test.mjs +1 -1
  124. package/{src/lib → lib}/json-shim.mjs +10 -5
  125. package/{src/lib → lib}/json-shim.test.mjs +1 -1
  126. package/{src/lib → lib}/levenshtein.mjs +6 -0
  127. package/{src/lib → lib}/manifest.mjs +7 -5
  128. package/{src/lib → lib}/manifest.test.mjs +2 -2
  129. package/{src/lib → lib}/module-loader.mjs +1 -0
  130. package/{src/lib → lib}/package-scanner.mjs +47 -0
  131. package/{src/lib → lib}/project.mjs +48 -18
  132. package/{src/lib → lib}/project.test.mjs +1 -1
  133. package/{src/lib → lib}/resolve-theme.mjs +5 -0
  134. package/{src/lib → lib}/string-utils.mjs +15 -0
  135. package/{src/lib → lib}/term-log.mjs +12 -3
  136. package/{src/lib → lib}/xle/browser.mjs +18 -8
  137. package/{src/lib → lib}/xle/expand.mjs +155 -22
  138. package/{src/lib → lib}/xle/parse.mjs +119 -13
  139. package/{src/lib → lib}/xle/print.mjs +54 -14
  140. package/{src/lib → lib}/xle/registry-core.mjs +28 -3
  141. package/{src/lib → lib}/xle/registry.mjs +9 -4
  142. package/{src/lib → lib}/xle/splice.mjs +13 -2
  143. package/{src/lib → lib}/xle/validate.mjs +95 -14
  144. package/lib/xle/xle-ast.d.ts +214 -0
  145. package/package.json +33 -26
  146. package/scripts/postinstall.mjs +4 -4
  147. package/templates/blocks/components/Avatar/AvatarShowcase.tsx +1 -1
  148. package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.doc.mjs +19 -0
  149. package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.tsx +46 -0
  150. package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider02Overrides.doc.mjs +14 -0
  151. package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider02Overrides.tsx +33 -0
  152. package/{src/types → types}/api.contract.assert.ts +17 -8
  153. package/{src/types → types}/api.d.ts +106 -0
  154. package/{src/types → types}/base.d.ts +17 -2
  155. package/types/build.d.ts +53 -0
  156. package/types/codemod.d.ts +166 -0
  157. package/{src/types → types}/component.d.ts +1 -1
  158. package/{src/types → types}/discover.d.ts +1 -1
  159. package/{src/types → types}/docs.d.ts +1 -4
  160. package/{src/types → types}/hook.d.ts +1 -1
  161. package/types/jscodeshift.d.ts +19 -0
  162. package/types/layout.d.ts +74 -0
  163. package/types/theme.d.ts +53 -0
  164. package/{src/types → types}/upgrade.d.ts +8 -1
  165. package/{src/utils → utils}/paths.mjs +4 -1
  166. package/src/commands/swizzle.mjs +0 -417
  167. package/src/types/build.d.ts +0 -23
  168. package/src/types/codemod.d.ts +0 -81
  169. package/src/types/theme.d.ts +0 -23
  170. /package/{src/api → api/docs}/docOverlays.test.mjs +0 -0
  171. /package/{src/api → api}/error.mjs +0 -0
  172. /package/{src/api → api/integration}/integration-block-exports.test.mjs +0 -0
  173. /package/{src/api → api/template}/template.test.mjs +0 -0
  174. /package/{src → authoring}/codemod.test.mjs +0 -0
  175. /package/{src → authoring}/config.mjs +0 -0
  176. /package/{src → authoring}/integration.mjs +0 -0
  177. /package/{src → authoring}/template.test.mjs +0 -0
  178. /package/{src → cli}/cli-exit-codes.test.mjs +0 -0
  179. /package/{src → cli}/commands/build-theme.color-scheme.test.mjs +0 -0
  180. /package/{src → cli}/commands/build-theme.import-path.test.mjs +0 -0
  181. /package/{src → cli}/commands/build-theme.path-safety.test.mjs +0 -0
  182. /package/{src → cli}/commands/build-theme.prose.test.mjs +0 -0
  183. /package/{src → cli}/commands/build-theme.variants.test.mjs +0 -0
  184. /package/{src → cli}/commands/build-theme.watch.test.mjs +0 -0
  185. /package/{src → cli}/commands/cli-postinstall.test.mjs +0 -0
  186. /package/{src → cli}/commands/component.test.mjs +0 -0
  187. /package/{src → cli}/commands/detail-levels.test.mjs +0 -0
  188. /package/{src → cli}/commands/init.next-steps.test.mjs +0 -0
  189. /package/{src → cli}/commands/interactive-guard.test.mjs +0 -0
  190. /package/{src → cli}/commands/json-contract.test.mjs +0 -0
  191. /package/{src → cli}/commands/swizzle.path-safety.test.mjs +0 -0
  192. /package/{src → cli}/commands/swizzle.routing.test.mjs +0 -0
  193. /package/{src → cli}/commands/template.test.mjs +0 -0
  194. /package/{src → cli}/commands/upgrade.config-ordering.test.mjs +0 -0
  195. /package/{src → cli}/commands/validate-integration.test.mjs +0 -0
  196. /package/{src → cli}/update-hint-commands.test.mjs +0 -0
  197. /package/{src/codemods → codemods}/__tests__/registry.test.mjs +0 -0
  198. /package/{src/codemods → codemods}/__tests__/rename-imperative-ref-to-handleRef.test.mjs +0 -0
  199. /package/{src/codemods → codemods}/__tests__/rename-isStreaming-to-isStopShown.test.mjs +0 -0
  200. /package/{src/codemods → codemods}/__tests__/rename-section-wash-to-muted.test.mjs +0 -0
  201. /package/{src/codemods → codemods}/__tests__/runner.test.mjs +0 -0
  202. /package/{src/codemods → codemods}/__tests__/toolbar-density-to-size.test.mjs +0 -0
  203. /package/{src/codemods → codemods}/__tests__/validation.test.mjs +0 -0
  204. /package/{src/codemods → codemods}/transforms/v0.0.10/__tests__/remove-size-props.test.mjs +0 -0
  205. /package/{src/codemods → codemods}/transforms/v0.0.10/index.mjs +0 -0
  206. /package/{src/codemods → codemods}/transforms/v0.0.12/__tests__/add-is-icon-only.test.mjs +0 -0
  207. /package/{src/codemods → codemods}/transforms/v0.0.12/index.mjs +0 -0
  208. /package/{src/codemods → codemods}/transforms/v0.0.13/__tests__/icon-name-deprecations.test.mjs +0 -0
  209. /package/{src/codemods → codemods}/transforms/v0.0.13/__tests__/rename-attachments-to-drawer.test.mjs +0 -0
  210. /package/{src/codemods → codemods}/transforms/v0.0.13/index.mjs +0 -0
  211. /package/{src/codemods → codemods}/transforms/v0.0.14/__tests__/rename-action-props.test.mjs +0 -0
  212. /package/{src/codemods → codemods}/transforms/v0.0.14/__tests__/rename-status-variants.test.mjs +0 -0
  213. /package/{src/codemods → codemods}/transforms/v0.0.14/index.mjs +0 -0
  214. /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/migrate-item-children-to-endcontent.test.mjs +0 -0
  215. /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/migrate-selector-children-to-render-option.test.mjs +0 -0
  216. /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/migrate-theme-selectors-to-data-attrs.test.mjs +0 -0
  217. /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/rename-date-picker-to-input.test.mjs +0 -0
  218. /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/rename-stack-element-to-as.test.mjs +0 -0
  219. /package/{src/codemods → codemods}/transforms/v0.0.15/index.mjs +0 -0
  220. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/migrate-badge-dot-to-statusdot.test.mjs +0 -0
  221. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/migrate-gap-to-numeric.test.mjs +0 -0
  222. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/migrate-isFullBleed-to-padding.test.mjs +0 -0
  223. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/migrate-useXDSIcon-to-getIcon.test.mjs +0 -0
  224. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-banner-endButton-to-endContent.test.mjs +0 -0
  225. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-form-tooltip-startIcon.test.mjs +0 -0
  226. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-isShown-to-isOpen.test.mjs +0 -0
  227. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-selector-items-to-options.test.mjs +0 -0
  228. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-sidenav-header-to-heading.test.mjs +0 -0
  229. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-topnav-title-to-heading.test.mjs +0 -0
  230. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/unify-uncontrolled-to-defaultX.test.mjs +0 -0
  231. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/unify-visibility-to-onOpenChange.test.mjs +0 -0
  232. /package/{src/codemods → codemods}/transforms/v0.0.2/index.mjs +0 -0
  233. /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-collapse-to-collapsible.test.mjs +0 -0
  234. /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-radius-tokens.test.mjs +0 -0
  235. /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-shadow-tokens.test.mjs +0 -0
  236. /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-skeleton-radius.test.mjs +0 -0
  237. /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-token-names.test.mjs +0 -0
  238. /package/{src/codemods → codemods}/transforms/v0.0.6/index.mjs +0 -0
  239. /package/{src/codemods → codemods}/transforms/v0.0.7/__tests__/rename-banner-variant-to-container.test.mjs +0 -0
  240. /package/{src/codemods → codemods}/transforms/v0.0.7/index.mjs +0 -0
  241. /package/{src/codemods → codemods}/transforms/v0.0.8/__tests__/migrate-token-renames.test.mjs +0 -0
  242. /package/{src/codemods → codemods}/transforms/v0.0.8/__tests__/rename-endslot-to-endcontent.test.mjs +0 -0
  243. /package/{src/codemods → codemods}/transforms/v0.0.8/index.mjs +0 -0
  244. /package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/drop-xds-prefix-imports.test.mjs +0 -0
  245. /package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/migrate-xds-css-surfaces.test.mjs +0 -0
  246. /package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/migrate-xds-declare-module.test.mjs +0 -0
  247. /package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/migrate-xds-module-specifiers.test.mjs +0 -0
  248. /package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/v0.1.0-ordering.test.mjs +0 -0
  249. /package/{src/codemods → codemods}/transforms/v0.1.0/index.mjs +0 -0
  250. /package/{src/codemods → codemods}/transforms/v0.1.2/__tests__/rename-text-color-active-to-accent.test.mjs +0 -0
  251. /package/{src/codemods → codemods}/transforms/v0.1.2/index.mjs +0 -0
  252. /package/{src/codemods → codemods}/transforms/v0.1.3/__tests__/migrate-layout-components-to-experimental.test.mjs +0 -0
  253. /package/{src/codemods → codemods}/transforms/v0.1.3/index.mjs +0 -0
  254. /package/{src/codemods → codemods}/transforms/v0.1.5/__tests__/rename-switch-label-spacing-default-to-hug.test.mjs +0 -0
  255. /package/{src/codemods → codemods}/transforms/v0.1.5/index.mjs +0 -0
  256. /package/{src/codemods → codemods}/transforms/v0.1.7/__tests__/migrate-table-tableprops-to-direct-props.test.mjs +0 -0
  257. /package/{src/codemods → codemods}/transforms/v0.1.7/__tests__/rename-table-renderprops-styles-to-xstyle.test.mjs +0 -0
  258. /package/{src/codemods → codemods}/transforms/v0.1.7/index.mjs +0 -0
  259. /package/{src/codemods → codemods}/transforms/v0.1.8/__tests__/rename-avatar-size-scale.test.mjs +0 -0
  260. /package/{src/codemods → codemods}/transforms/v0.1.8/index.mjs +0 -0
  261. /package/{src/commands → lib/agent-docs}/agent-docs.test.mjs +0 -0
  262. /package/{src/lib → lib}/cli-error.mjs +0 -0
  263. /package/{src/lib → lib}/cli-error.test.mjs +0 -0
  264. /package/{src/lib → lib}/component-discovery.importpath.test.mjs +0 -0
  265. /package/{src/lib → lib}/component-format.test.mjs +0 -0
  266. /package/{src/lib → lib}/component-loader.test.mjs +0 -0
  267. /package/{src/lib → lib}/config-cache.mjs +0 -0
  268. /package/{src/lib → lib}/config-cache.test.mjs +0 -0
  269. /package/{src/lib → lib}/config-schema.mjs +0 -0
  270. /package/{src/lib → lib}/error-codes.mjs +0 -0
  271. /package/{src/lib → lib}/integration-warnings.test.mjs +0 -0
  272. /package/{src/lib → lib}/json.mjs +0 -0
  273. /package/{src/lib → lib}/module-loader.test.mjs +0 -0
  274. /package/{src/lib → lib}/node-version.mjs +0 -0
  275. /package/{src/lib → lib}/node-version.test.mjs +0 -0
  276. /package/{src/lib → lib}/parse.mjs +0 -0
  277. /package/{src/lib → lib}/site.mjs +0 -0
  278. /package/{src/lib → lib}/xle/browser.d.ts +0 -0
  279. /package/{src/lib → lib}/xle/xle.test.mjs +0 -0
  280. /package/{src/schemas → schemas}/doc-schema.mjs +0 -0
  281. /package/{src/schemas → schemas}/template-schema.mjs +0 -0
  282. /package/{src/types → types}/config.d.ts +0 -0
  283. /package/{src/types → types}/doc.d.ts +0 -0
  284. /package/{src/types → types}/doctor.d.ts +0 -0
  285. /package/{src/types → types}/error-codes.d.ts +0 -0
  286. /package/{src/types → types}/index.d.ts +0 -0
  287. /package/{src/types → types}/integration.d.ts +0 -0
  288. /package/{src/types → types}/manifest.d.ts +0 -0
  289. /package/{src/types → types}/search.d.ts +0 -0
  290. /package/{src/types → types}/swizzle.d.ts +0 -0
  291. /package/{src/types → types}/template-api.d.ts +0 -0
  292. /package/{src/types → types}/template.d.ts +0 -0
  293. /package/{src/types → types}/validate-integration.d.ts +0 -0
  294. /package/{src/utils → utils}/github.mjs +0 -0
  295. /package/{src/utils → utils}/package-manager.mjs +0 -0
  296. /package/{src/utils → utils}/package-manager.test.mjs +0 -0
  297. /package/{src/utils → utils}/path-safety.mjs +0 -0
  298. /package/{src/utils → utils}/path-safety.test.mjs +0 -0
  299. /package/{src/utils → utils}/paths.test.mjs +0 -0
  300. /package/{src/utils → utils}/semver.mjs +0 -0
  301. /package/{src/utils → utils}/semver.test.mjs +0 -0
  302. /package/{src/utils → utils}/update-check.mjs +0 -0
  303. /package/{src/utils → utils}/update-check.test.mjs +0 -0
@@ -33,19 +33,34 @@
33
33
  import * as fs from 'node:fs';
34
34
  import * as path from 'node:path';
35
35
  import {pathToFileURL} from 'node:url';
36
- import {findCoreDir, CLI_ROOT} from '../utils/paths.mjs';
36
+ import {findCoreDir, CLI_ROOT} from '../../utils/paths.mjs';
37
37
  import {
38
38
  discoverComponents,
39
39
  findComponentReadme,
40
40
  resolveImportPath,
41
- } from '../lib/component-discovery.mjs';
42
- import {discoverHooks, findHookDoc} from '../lib/hook-discovery.mjs';
43
- import {levenshteinDistance} from '../lib/string-utils.mjs';
44
- import {discoverTemplates, extractComponents} from './template.mjs';
45
- import {AstryxError} from './error.mjs';
41
+ } from '../../lib/component-discovery.mjs';
42
+ import {discoverHooks, findHookDoc} from '../../lib/hook-discovery.mjs';
43
+ import {levenshteinDistance} from '../../lib/string-utils.mjs';
44
+ import {discoverTemplates, extractComponents} from '../template/template.mjs';
45
+ import {AstryxError} from '../error.mjs';
46
46
 
47
47
  const DOCS_DIR = path.join(CLI_ROOT, 'docs');
48
48
 
49
+ /**
50
+ * A search candidate gathered from one content domain. Extra underscore-
51
+ * prefixed fields carry domain-specific payload used only by {@link toResult}.
52
+ * @typedef {object} Candidate
53
+ * @property {'component'|'hook'|'doc'|'template'} domain
54
+ * @property {string} name
55
+ * @property {string[]} [keywords]
56
+ * @property {string} [description]
57
+ * @property {string[]} [prose]
58
+ * @property {string} [_import]
59
+ * @property {string} [_title]
60
+ * @property {string} [_displayName]
61
+ * @property {'page'|'block'} [_kind]
62
+ */
63
+
49
64
  /**
50
65
  * Synonym / intent map: product-language terms an agent is likely to type,
51
66
  * expanded to the catalog's vocabulary so oblique queries still rank. Keys and
@@ -72,10 +87,19 @@ const SYNONYMS = {
72
87
 
73
88
  // Flatten into a token -> Set(expansions) lookup (bidirectional).
74
89
  const SYNONYM_INDEX = (() => {
90
+ /** @type {Map<string, Set<string>>} */
75
91
  const idx = new Map();
92
+ /**
93
+ * @param {string} a
94
+ * @param {string} b
95
+ */
76
96
  const add = (a, b) => {
77
- if (!idx.has(a)) idx.set(a, new Set());
78
- idx.get(a).add(b);
97
+ let set = idx.get(a);
98
+ if (!set) {
99
+ set = new Set();
100
+ idx.set(a, set);
101
+ }
102
+ set.add(b);
79
103
  };
80
104
  for (const [key, vals] of Object.entries(SYNONYMS)) {
81
105
  for (const v of vals) {
@@ -159,6 +183,8 @@ const MIN_TOKEN_SCORE = 50;
159
183
  /**
160
184
  * Best score for a token against a candidate, fanning out through synonyms
161
185
  * (synonym hits are discounted so a direct hit always wins).
186
+ * @param {string} tok
187
+ * @param {Candidate} candidate
162
188
  * @returns {{score: number, reason: string} | null}
163
189
  */
164
190
  function bestForToken(tok, candidate) {
@@ -176,6 +202,12 @@ function bestForToken(tok, candidate) {
176
202
  return best;
177
203
  }
178
204
 
205
+ /**
206
+ * @param {string} term - Lowercased full query.
207
+ * @param {string[]} tokens - Content tokens from tokenizeQuery(term).
208
+ * @param {Candidate} candidate
209
+ * @returns {{score: number, reason: string} | null}
210
+ */
179
211
  export function scoreQuery(term, tokens, candidate) {
180
212
  const full = scoreCandidate(term, candidate);
181
213
 
@@ -192,6 +224,7 @@ export function scoreQuery(term, tokens, candidate) {
192
224
  // strong hits, then reward coverage so candidates matching more terms win.
193
225
  let sum = 0;
194
226
  let matched = 0;
227
+ /** @type {string[]} */
195
228
  const hitTerms = [];
196
229
  for (const tok of tokens) {
197
230
  const h = bestForToken(tok, candidate);
@@ -235,6 +268,10 @@ export function scoreQuery(term, tokens, candidate) {
235
268
  export function scoreCandidate(term, {name, keywords = [], description = '', prose = []}) {
236
269
  let best = 0;
237
270
  let reason = '';
271
+ /**
272
+ * @param {number} score
273
+ * @param {string} why
274
+ */
238
275
  const consider = (score, why) => {
239
276
  if (score > best) {
240
277
  best = score;
@@ -299,7 +336,12 @@ export function scoreCandidate(term, {name, keywords = [], description = '', pro
299
336
  return best > 0 ? {score: best, reason} : null;
300
337
  }
301
338
 
302
- /** Load a doc module's `docs`/`doc` export, swallowing errors. */
339
+ /**
340
+ * Load a doc module's `docs`/`doc` export, swallowing errors.
341
+ * @param {string} docPath
342
+ * @param {string} [exportName]
343
+ * @returns {Promise<any>}
344
+ */
303
345
  async function loadModuleDoc(docPath, exportName = 'docs') {
304
346
  try {
305
347
  const mod = await import(pathToFileURL(docPath).href);
@@ -313,13 +355,16 @@ async function loadModuleDoc(docPath, exportName = 'docs') {
313
355
  * Build component candidates: name + keywords + usage/description from the
314
356
  * component's .doc.mjs.
315
357
  * @param {string} coreDir
358
+ * @returns {Promise<Candidate[]>}
316
359
  */
317
360
  async function gatherComponents(coreDir) {
318
361
  const grouped = discoverComponents(coreDir);
319
362
  const names = Object.values(grouped).flat();
363
+ /** @type {Candidate[]} */
320
364
  const candidates = [];
321
365
  for (const comp of names) {
322
366
  const readme = findComponentReadme(coreDir, comp);
367
+ /** @type {string[]} */
323
368
  let keywords = [];
324
369
  let description = '';
325
370
  if (readme && readme.endsWith('.doc.mjs')) {
@@ -344,13 +389,16 @@ async function gatherComponents(coreDir) {
344
389
  * Build hook candidates: name + keywords + usage/description from the hook's
345
390
  * .doc.mjs.
346
391
  * @param {string} coreDir
392
+ * @returns {Promise<Candidate[]>}
347
393
  */
348
394
  async function gatherHooks(coreDir) {
349
395
  const grouped = discoverHooks(coreDir);
350
396
  const names = Object.values(grouped).flat();
397
+ /** @type {Candidate[]} */
351
398
  const candidates = [];
352
399
  for (const hookName of names) {
353
400
  const docPath = findHookDoc(coreDir, hookName);
401
+ /** @type {string[]} */
354
402
  let keywords = [];
355
403
  let description = '';
356
404
  let importPath = '@astryxdesign/core/hooks';
@@ -373,9 +421,13 @@ async function gatherHooks(coreDir) {
373
421
  return candidates;
374
422
  }
375
423
 
376
- /** Build doc-topic candidates: topic name + description + section prose. */
424
+ /**
425
+ * Build doc-topic candidates: topic name + description + section prose.
426
+ * @returns {Promise<Candidate[]>}
427
+ */
377
428
  async function gatherDocs() {
378
429
  if (!fs.existsSync(DOCS_DIR)) return [];
430
+ /** @type {Candidate[]} */
379
431
  const candidates = [];
380
432
  for (const file of fs.readdirSync(DOCS_DIR)) {
381
433
  const match = file.match(/^([\w-]+)\.doc\.mjs$/);
@@ -383,6 +435,7 @@ async function gatherDocs() {
383
435
  const topic = match[1];
384
436
  const doc = await loadModuleDoc(path.join(DOCS_DIR, file));
385
437
  let description = '';
438
+ /** @type {string[]} */
386
439
  const prose = [];
387
440
  if (doc) {
388
441
  description = doc.description || '';
@@ -405,7 +458,11 @@ async function gatherDocs() {
405
458
  return candidates;
406
459
  }
407
460
 
408
- /** Build template candidates (page + block) from the template discovery API. */
461
+ /**
462
+ * Build template candidates (page + block) from the template discovery API.
463
+ * @param {string} cwd
464
+ * @returns {Promise<Candidate[]>}
465
+ */
409
466
  async function gatherTemplates(cwd) {
410
467
  let templates;
411
468
  try {
@@ -444,7 +501,7 @@ async function gatherTemplates(cwd) {
444
501
  * carries enough to act on it: the domain, name, a one-line description, and
445
502
  * the follow-up command (and import path where relevant).
446
503
  *
447
- * @param {object} c - candidate
504
+ * @param {Candidate} c - candidate
448
505
  * @param {number} score
449
506
  * @param {string} reason
450
507
  */
@@ -522,6 +579,7 @@ export async function search(query, options = {}) {
522
579
  }
523
580
 
524
581
  // Gather candidates from each requested domain in parallel.
582
+ /** @param {string} d */
525
583
  const wants = d => !type || type === d;
526
584
  const [components, hooks, docTopics, templates] = await Promise.all([
527
585
  wants('component') ? gatherComponents(coreDir) : [],
@@ -543,6 +601,7 @@ export async function search(query, options = {}) {
543
601
  }
544
602
 
545
603
  // Sort by score desc, then domain (stable order), then name.
604
+ /** @type {Record<string, number>} */
546
605
  const domainOrder = {component: 0, hook: 1, doc: 2, template: 3};
547
606
  scored.sort(
548
607
  (a, b) =>
@@ -0,0 +1,283 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file swizzle API — copy a component's source into the consumer project for
5
+ * customization, rewriting escaping relative imports to the OWNER package's
6
+ * subpaths.
7
+ *
8
+ * Side-effecting: `swizzle(name, ...)` writes files and returns a
9
+ * `swizzle.copy` receipt describing what it did; with no name (or `list`) it
10
+ * returns `swizzle.list`. Errors throw AstryxError (stable code + suggestions).
11
+ * All human prose / package-manager prefixing lives in the CLI renderer.
12
+ */
13
+
14
+ import * as fs from 'node:fs';
15
+ import * as path from 'node:path';
16
+ import {findCoreDir, listComponents} from '../../utils/paths.mjs';
17
+ import {assertWithin, PathSafetyError} from '../../utils/path-safety.mjs';
18
+ import {checkGhCli} from '../../utils/github.mjs';
19
+ import {Project} from '../../lib/project.mjs';
20
+ import {
21
+ CORE_PACKAGE,
22
+ findIntegrationComponentDoc,
23
+ findIntegrationComponentSource,
24
+ } from '../../lib/component-discovery.mjs';
25
+ import {ERROR_CODES} from '../../lib/error-codes.mjs';
26
+ import {AstryxError} from '../error.mjs';
27
+
28
+ /** Default issue tracker for maintainer feedback after swizzling. */
29
+ const DEFAULT_ISSUES_URL = 'https://github.com/facebook/astryx/issues/new';
30
+
31
+ /**
32
+ * Rewrite relative imports that point outside the component directory to use
33
+ * the OWNER package's subpaths. Imports within the copied directory (./x) are
34
+ * left untouched.
35
+ *
36
+ * e.g. with ownerPackage '@astryxdesign/core':
37
+ * '../theme/tokens.stylex' -> '@astryxdesign/core/theme'
38
+ * '../utils/mergeProps' -> '@astryxdesign/core/utils'
39
+ *
40
+ * @param {string} content
41
+ * @param {string} [ownerPackage]
42
+ */
43
+ export function rewriteImports(content, ownerPackage = CORE_PACKAGE) {
44
+ return content.replace(
45
+ /(from\s+['"])(\.\.\/.+?)(['"])/g,
46
+ (match, prefix, importPath, suffix) => {
47
+ const parts = importPath.replace(/^\.\.\//, '').split('/');
48
+ const topDir = parts[0];
49
+ return `${prefix}${ownerPackage}/${topDir}${suffix}`;
50
+ },
51
+ );
52
+ }
53
+
54
+ /**
55
+ * Build the maintainer feedback note for a swizzled component.
56
+ * @param {string} component
57
+ * @param {string|undefined} issuesUrl
58
+ * @returns {{issuesUrl: string, ghCommand?: string} | null}
59
+ */
60
+ function buildFeedback(component, issuesUrl) {
61
+ if (!issuesUrl) return null;
62
+ /** @type {{issuesUrl: string, ghCommand?: string}} */
63
+ const feedback = {issuesUrl};
64
+ const match = issuesUrl.match(
65
+ /^https:\/\/github\.com\/([^/]+)\/([^/]+)\/issues(?:\/new)?\/?$/,
66
+ );
67
+ if (match && checkGhCli()) {
68
+ const [, owner, repo] = match;
69
+ feedback.ghCommand = `gh issue create --repo ${owner}/${repo} --title "[${component}] Swizzle feedback"`;
70
+ }
71
+ return feedback;
72
+ }
73
+
74
+ /**
75
+ * Load the configured integrations + core issues URL for `cwd`, swallowing any
76
+ * config errors so swizzle never hard-fails on a malformed/absent config.
77
+ * @param {string} cwd
78
+ * @returns {Promise<{loadedIntegrations: import('../../lib/integrations.mjs').LoadedIntegration[], issuesUrl: string|undefined, project: Project|null}>}
79
+ */
80
+ async function loadConfigSafely(cwd) {
81
+ try {
82
+ const project = await Project.load(cwd);
83
+ return {
84
+ loadedIntegrations: project.loadedIntegrations,
85
+ issuesUrl: project.config.issuesUrl,
86
+ project,
87
+ };
88
+ } catch {
89
+ return {loadedIntegrations: [], issuesUrl: undefined, project: null};
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Build the set of OWNER packages that provide a component named `name` across
95
+ * core + every loaded integration.
96
+ * @param {string} coreDir
97
+ * @param {Array<{name: string, components?: string, issuesUrl?: string}>} loadedIntegrations
98
+ * @param {string} name
99
+ * @param {string|undefined} coreIssuesUrl
100
+ * @returns {Array<{package: string, sourceDir: string|null, ownerPackage: string, issuesUrl: string|undefined}>}
101
+ */
102
+ function resolveOwners(coreDir, loadedIntegrations, name, coreIssuesUrl) {
103
+ const owners = [];
104
+ const coreComponentDir = path.join(coreDir, 'src', name);
105
+ if (fs.existsSync(coreComponentDir)) {
106
+ owners.push({
107
+ package: CORE_PACKAGE,
108
+ sourceDir: coreComponentDir,
109
+ ownerPackage: CORE_PACKAGE,
110
+ issuesUrl: coreIssuesUrl || DEFAULT_ISSUES_URL,
111
+ });
112
+ }
113
+ for (const integration of loadedIntegrations) {
114
+ const docPath = findIntegrationComponentDoc(integration, name);
115
+ if (!docPath) continue;
116
+ const sourcePath = findIntegrationComponentSource(integration, name);
117
+ owners.push({
118
+ package: integration.name,
119
+ sourceDir: sourcePath ? path.dirname(sourcePath) : null,
120
+ ownerPackage: integration.name,
121
+ issuesUrl: integration.issuesUrl,
122
+ });
123
+ }
124
+ return owners;
125
+ }
126
+
127
+ /** @param {string} file */
128
+ function isExcludedFromCopy(file) {
129
+ return (
130
+ file.includes('.test.') || file.includes('.doc.') || file === 'README.md'
131
+ );
132
+ }
133
+
134
+ /**
135
+ * List swizzlable components, or copy one component's source for customization.
136
+ *
137
+ * @param {string} [component] bare or XDS-prefixed component name; omit to list
138
+ * @param {{cwd?: string, output?: string, package?: string, list?: boolean, overwrite?: boolean}} [options]
139
+ * @returns {Promise<import('../../types/swizzle').SwizzleListResponse | import('../../types/swizzle').SwizzleCopyResponse>}
140
+ */
141
+ export async function swizzle(component, options = {}) {
142
+ const {
143
+ cwd = process.cwd(),
144
+ output = './components/astryx',
145
+ package: pkg,
146
+ list = false,
147
+ overwrite = false,
148
+ } = options;
149
+
150
+ const coreDir = findCoreDir(cwd);
151
+ if (!coreDir) {
152
+ throw new AstryxError(
153
+ 'Could not find @astryxdesign/core package. Make sure you are inside the design system monorepo or have @astryxdesign/core installed.',
154
+ [],
155
+ ERROR_CODES.ERR_CORE_NOT_FOUND,
156
+ );
157
+ }
158
+
159
+ const components = listComponents(coreDir);
160
+
161
+ if (list || !component) {
162
+ return {type: 'swizzle.list', data: components};
163
+ }
164
+
165
+ const dirName = component.replace(/^XDS/, '');
166
+
167
+ const {loadedIntegrations, project} = await loadConfigSafely(cwd);
168
+ const coreIssuesUrl = project
169
+ ? project.issuesUrl({package: CORE_PACKAGE})
170
+ : undefined;
171
+ const allOwners = resolveOwners(coreDir, loadedIntegrations, dirName, coreIssuesUrl);
172
+
173
+ if (allOwners.length === 0) {
174
+ throw new AstryxError(
175
+ `Component "${component}" not found.`,
176
+ components.slice(0, 10).map(n => ({name: n})),
177
+ ERROR_CODES.ERR_UNKNOWN_COMPONENT,
178
+ );
179
+ }
180
+
181
+ let owner;
182
+ if (pkg) {
183
+ owner = allOwners.find(o => o.package === pkg);
184
+ if (!owner) {
185
+ throw new AstryxError(
186
+ `Component "${dirName}" is not provided by package "${pkg}".`,
187
+ allOwners.map(o => ({name: o.package, reason: 'provides this component'})),
188
+ ERROR_CODES.ERR_UNKNOWN_COMPONENT,
189
+ );
190
+ }
191
+ } else if (allOwners.length > 1) {
192
+ throw new AstryxError(
193
+ `Component "${dirName}" is provided by multiple packages. Re-run with --package <pkg> to choose one.`,
194
+ allOwners.map(o => ({name: o.package, reason: 'provides this component'})),
195
+ ERROR_CODES.ERR_AMBIGUOUS_COMPONENT,
196
+ );
197
+ } else {
198
+ owner = allOwners[0];
199
+ }
200
+
201
+ if (!owner.sourceDir || !fs.existsSync(owner.sourceDir)) {
202
+ throw new AstryxError(
203
+ `No source found for "${dirName}" in package "${owner.package}".`,
204
+ [],
205
+ ERROR_CODES.ERR_NO_SOURCE,
206
+ );
207
+ }
208
+
209
+ const componentDir = owner.sourceDir;
210
+
211
+ // Path-safety: --output must resolve inside cwd.
212
+ let outputBase;
213
+ try {
214
+ outputBase = assertWithin(output, cwd, {label: 'output directory'});
215
+ } catch (err) {
216
+ if (err instanceof PathSafetyError) {
217
+ throw new AstryxError(err.message, [], ERROR_CODES.ERR_PATH_TRAVERSAL);
218
+ }
219
+ throw err;
220
+ }
221
+ const outputDir = path.join(outputBase, dirName);
222
+
223
+ // Pre-flight overwrite check before any mkdir/writeFile.
224
+ const sourceFiles = fs.readdirSync(componentDir).filter(file => {
225
+ if (isExcludedFromCopy(file)) return false;
226
+ return fs.statSync(path.join(componentDir, file)).isFile();
227
+ });
228
+ const existingFiles = sourceFiles.filter(f =>
229
+ fs.existsSync(path.join(outputDir, f)),
230
+ );
231
+ if (existingFiles.length > 0 && !overwrite) {
232
+ const relOutputForMsg = path.relative(cwd, outputDir) || '.';
233
+ throw new AstryxError(
234
+ `Refusing to overwrite ${existingFiles.length} existing file(s) in ${relOutputForMsg}/. ` +
235
+ `Re-run with --overwrite (or -f) to replace them.`,
236
+ [],
237
+ ERROR_CODES.ERR_FILE_EXISTS,
238
+ );
239
+ }
240
+
241
+ fs.mkdirSync(outputDir, {recursive: true});
242
+
243
+ const files = fs.readdirSync(componentDir);
244
+ let copied = 0;
245
+ let usesStyleX = false;
246
+ for (const file of files) {
247
+ if (isExcludedFromCopy(file)) continue;
248
+ const srcPath = path.join(componentDir, file);
249
+ if (!fs.statSync(srcPath).isFile()) continue;
250
+ let content = fs.readFileSync(srcPath, 'utf-8');
251
+ if (file.endsWith('.ts') || file.endsWith('.tsx')) {
252
+ content = rewriteImports(content, owner.ownerPackage);
253
+ }
254
+ if (
255
+ (file.endsWith('.ts') || file.endsWith('.tsx')) &&
256
+ content.includes('@stylexjs/stylex')
257
+ ) {
258
+ usesStyleX = true;
259
+ }
260
+ fs.writeFileSync(path.join(outputDir, file), content);
261
+ copied++;
262
+ }
263
+
264
+ const relOutput = path.relative(cwd, outputDir);
265
+ const copiedFiles = files.filter(
266
+ f =>
267
+ !isExcludedFromCopy(f) &&
268
+ fs.statSync(path.join(componentDir, f)).isFile(),
269
+ );
270
+ const feedback = buildFeedback(dirName, owner.issuesUrl);
271
+
272
+ /** @type {import('../../types/swizzle').SwizzleCopyResponse['data']} */
273
+ const data = {
274
+ component: dirName,
275
+ package: owner.package,
276
+ outputDir: relOutput,
277
+ filesCopied: copied,
278
+ files: copiedFiles.map(f => f),
279
+ usesStyleX,
280
+ };
281
+ if (feedback) data.feedback = feedback;
282
+ return {type: 'swizzle.copy', data};
283
+ }
@@ -1,7 +1,12 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
3
  import {describe, it, expect} from 'vitest';
4
- import {rewriteImports} from './swizzle.mjs';
4
+ import * as path from 'node:path';
5
+ import {fileURLToPath} from 'node:url';
6
+ import {rewriteImports, swizzle} from './swizzle.mjs';
7
+
8
+ // api/swizzle/ -> up 3 = packages/cli, up 4 = repo root (has packages/core).
9
+ const REPO = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../../..');
5
10
 
6
11
  describe('rewriteImports', () => {
7
12
  it('rewrites ../theme/tokens to @astryxdesign/core/theme', () => {
@@ -51,3 +56,23 @@ describe('rewriteImports', () => {
51
56
  );
52
57
  });
53
58
  });
59
+
60
+ describe('swizzle() API', () => {
61
+ it('no component → swizzle.list of core components', async () => {
62
+ const r = await swizzle(undefined, {cwd: REPO});
63
+ expect(r.type).toBe('swizzle.list');
64
+ expect(Array.isArray(r.data)).toBe(true);
65
+ expect(r.data).toContain('Button');
66
+ });
67
+
68
+ it('--list → swizzle.list even with a component arg', async () => {
69
+ const r = await swizzle('Button', {cwd: REPO, list: true});
70
+ expect(r.type).toBe('swizzle.list');
71
+ });
72
+
73
+ it('unknown component → AstryxError ERR_UNKNOWN_COMPONENT with suggestions', async () => {
74
+ await expect(swizzle('NotARealComponent99', {cwd: REPO})).rejects.toMatchObject({
75
+ code: 'ERR_UNKNOWN_COMPONENT',
76
+ });
77
+ });
78
+ });
@@ -62,7 +62,7 @@ function writeTemplate(pkgDir, id, {kind, body, withSource = true}) {
62
62
  fs.writeFileSync(
63
63
  docPath,
64
64
  body ??
65
- `import {${create}} from '${CLI_PKG}/src/template.mjs';\n` +
65
+ `import {${create}} from '${CLI_PKG}/authoring/template.mjs';\n` +
66
66
  `export default ${create}({name: '${id} name', description: '${id} desc'});\n`,
67
67
  );
68
68
  if (withSource) {
@@ -166,7 +166,7 @@ describe('integration template discovery', () => {
166
166
  );
167
167
  fs.writeFileSync(
168
168
  path.join(pkg2, 'templates', 'hero.doc.mjs'),
169
- `import {createBlockTemplate} from '${CLI_PKG}/src/template.mjs';\n` +
169
+ `import {createBlockTemplate} from '${CLI_PKG}/authoring/template.mjs';\n` +
170
170
  `export default createBlockTemplate({name: 'Hero block', description: 'b'});\n`,
171
171
  );
172
172
  fs.writeFileSync(
@@ -21,7 +21,7 @@ import {
21
21
  findRelatedBlocks,
22
22
  } from './template.mjs';
23
23
 
24
- /** Absolute path to the CLI package so fixtures can import /src/template.mjs. */
24
+ /** Absolute path to the CLI package so fixtures can import /authoring/template.mjs. */
25
25
  const CLI_PKG = path.resolve(import.meta.dirname, '..', '..');
26
26
 
27
27
  let tmpDir;
@@ -68,7 +68,7 @@ function writeTemplate(pkgDir, id, {kind, suffix}) {
68
68
  kind === 'page' ? 'createPageTemplate' : 'createBlockTemplate';
69
69
  fs.writeFileSync(
70
70
  docPath,
71
- `import {${create}} from '${CLI_PKG}/src/template.mjs';\n` +
71
+ `import {${create}} from '${CLI_PKG}/authoring/template.mjs';\n` +
72
72
  `export default ${create}({name: '${id} name', description: '${id} desc'});\n`,
73
73
  );
74
74
  fs.writeFileSync(
@@ -177,7 +177,7 @@ describe('external showcase blocks: .template.* discovered like legacy .doc.*',
177
177
  fs.mkdirSync(fooDir, {recursive: true});
178
178
  fs.writeFileSync(
179
179
  path.join(fooDir, 'FooShowcase.template.ts'),
180
- `import {createBlockTemplate} from '${CLI_PKG}/src/template.mjs';\n` +
180
+ `import {createBlockTemplate} from '${CLI_PKG}/authoring/template.mjs';\n` +
181
181
  `export default createBlockTemplate({\n` +
182
182
  ` name: 'Foo — Showcase',\n` +
183
183
  ` description: 'Foo showcase.',\n` +