@astryxdesign/cli 0.1.2 → 0.1.3

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 (238) hide show
  1. package/CHANGELOG.md +64 -1
  2. package/README.md +49 -55
  3. package/docs/layout.doc.dense.mjs +90 -0
  4. package/docs/layout.doc.mjs +160 -0
  5. package/docs/principles.doc.dense.mjs +2 -2
  6. package/docs/principles.doc.mjs +4 -0
  7. package/docs/principles.doc.zh.mjs +2 -2
  8. package/docs/theme.doc.mjs +2 -2
  9. package/package.json +13 -1
  10. package/src/api/blog.mjs +192 -0
  11. package/src/api/blog.test.mjs +144 -0
  12. package/src/api/component.mjs +253 -12
  13. package/src/api/discover.mjs +14 -7
  14. package/src/api/doctor.mjs +10 -25
  15. package/src/api/index.mjs +1 -0
  16. package/src/api/layout.mjs +11 -10
  17. package/src/api/layout.test.mjs +4 -1
  18. package/src/api/template-integration.test.mjs +225 -0
  19. package/src/api/template.mjs +242 -84
  20. package/src/api/validate-integration.mjs +370 -0
  21. package/src/api/validate-integration.test.mjs +222 -0
  22. package/src/codemod.mjs +93 -0
  23. package/src/codemod.test.mjs +134 -0
  24. package/src/codemods/__tests__/registry.test.mjs +1 -0
  25. package/src/codemods/__tests__/runner.test.mjs +103 -0
  26. package/src/codemods/integration-discovery.mjs +168 -0
  27. package/src/codemods/integration-discovery.test.mjs +234 -0
  28. package/src/codemods/integration-runner.mjs +109 -0
  29. package/src/codemods/registry.mjs +1 -0
  30. package/src/codemods/run-codemod.mjs +207 -0
  31. package/src/codemods/runner.mjs +73 -96
  32. package/src/codemods/transforms/v0.0.15/index.mjs +0 -13
  33. package/src/codemods/transforms/v0.1.0/__tests__/migrate-xds-css-surfaces.test.mjs +67 -0
  34. package/src/codemods/transforms/v0.1.0/__tests__/migrate-xds-declare-module.test.mjs +61 -0
  35. package/src/codemods/transforms/v0.1.0/__tests__/v0.1.0-ordering.test.mjs +104 -0
  36. package/src/codemods/transforms/{v0.0.15 → v0.1.0}/drop-xds-prefix-imports.mjs +15 -4
  37. package/src/codemods/transforms/v0.1.0/index.mjs +43 -6
  38. package/src/codemods/transforms/v0.1.0/migrate-xds-css-surfaces.mjs +77 -0
  39. package/src/codemods/transforms/v0.1.0/migrate-xds-declare-module.mjs +78 -0
  40. package/src/codemods/transforms/v0.1.3/__tests__/migrate-layout-components-to-experimental.test.mjs +360 -0
  41. package/src/codemods/transforms/v0.1.3/index.mjs +19 -0
  42. package/src/codemods/transforms/v0.1.3/migrate-layout-components-to-experimental.mjs +260 -0
  43. package/src/commands/agent-docs.mjs +4 -1
  44. package/src/commands/blog.mjs +60 -0
  45. package/src/commands/build-theme.import-path.test.mjs +2 -12
  46. package/src/commands/build-theme.mjs +117 -0
  47. package/src/commands/build-theme.prose.test.mjs +5 -15
  48. package/src/commands/build-theme.watch.test.mjs +149 -0
  49. package/src/commands/component/index.mjs +44 -10
  50. package/src/commands/component-ownership.test.mjs +227 -0
  51. package/src/commands/discover.mjs +5 -16
  52. package/src/commands/doctor.test.mjs +3 -3
  53. package/src/commands/ensure-core-built.mjs +120 -0
  54. package/src/commands/json-contract.test.mjs +0 -32
  55. package/src/commands/swizzle.mjs +224 -235
  56. package/src/commands/swizzle.path-safety.test.mjs +3 -3
  57. package/src/commands/swizzle.routing.test.mjs +279 -0
  58. package/src/commands/template.mjs +33 -37
  59. package/src/commands/upgrade.config-ordering.test.mjs +273 -0
  60. package/src/commands/upgrade.integration-policy.test.mjs +204 -0
  61. package/src/commands/upgrade.mjs +349 -170
  62. package/src/commands/validate-integration.mjs +110 -0
  63. package/src/commands/validate-integration.test.mjs +124 -0
  64. package/src/config.mjs +7 -20
  65. package/src/config.test.mjs +89 -13
  66. package/src/index.mjs +8 -3
  67. package/src/integration.mjs +19 -0
  68. package/src/lib/component-discovery.mjs +177 -0
  69. package/src/lib/config-cache.mjs +91 -0
  70. package/src/lib/config-cache.test.mjs +83 -0
  71. package/src/lib/config-schema.mjs +41 -55
  72. package/src/lib/error-codes.mjs +15 -12
  73. package/src/lib/integration-warnings.mjs +62 -0
  74. package/src/lib/integration-warnings.test.mjs +102 -0
  75. package/src/lib/integrations.mjs +92 -115
  76. package/src/lib/integrations.test.mjs +88 -107
  77. package/src/lib/manifest.mjs +5 -2
  78. package/src/lib/module-loader.mjs +80 -0
  79. package/src/lib/module-loader.test.mjs +106 -0
  80. package/src/lib/project.mjs +502 -0
  81. package/src/lib/project.test.mjs +308 -0
  82. package/src/lib/site.mjs +20 -0
  83. package/src/template.mjs +73 -0
  84. package/src/template.test.mjs +127 -0
  85. package/src/types/api.d.ts +2 -6
  86. package/src/types/base.d.ts +3 -9
  87. package/src/types/codemod.d.ts +81 -0
  88. package/src/types/component.d.ts +27 -2
  89. package/src/types/config.d.ts +56 -85
  90. package/src/types/error-codes.d.ts +5 -3
  91. package/src/types/index.d.ts +0 -1
  92. package/src/types/integration.d.ts +29 -0
  93. package/src/types/swizzle.d.ts +9 -2
  94. package/src/types/template-api.d.ts +54 -0
  95. package/src/types/template.d.ts +10 -7
  96. package/src/types/upgrade.d.ts +29 -0
  97. package/src/types/validate-integration.d.ts +24 -0
  98. package/src/utils/github.mjs +0 -237
  99. package/src/utils/interactive.mjs +2 -2
  100. package/templates/blocks/components/AvatarStatusDot/AvatarStatusDotVariants.doc.mjs +14 -0
  101. package/templates/blocks/components/AvatarStatusDot/AvatarStatusDotVariants.tsx +28 -0
  102. package/templates/blocks/components/Blockquote/BlockquoteTestimonials.doc.mjs +14 -0
  103. package/templates/blocks/components/Blockquote/BlockquoteTestimonials.tsx +34 -0
  104. package/templates/blocks/components/Blockquote/BlockquoteWithCite.doc.mjs +14 -0
  105. package/templates/blocks/components/Blockquote/BlockquoteWithCite.tsx +21 -0
  106. package/templates/blocks/components/BreadcrumbItem/BreadcrumbItemBasic.doc.mjs +14 -0
  107. package/templates/blocks/components/BreadcrumbItem/BreadcrumbItemBasic.tsx +15 -0
  108. package/templates/blocks/components/ButtonGroup/ButtonGroupBasic.doc.mjs +14 -0
  109. package/templates/blocks/components/ButtonGroup/ButtonGroupBasic.tsx +16 -0
  110. package/templates/blocks/components/ChatDictationButton/ChatDictationButtonBasic.doc.mjs +19 -0
  111. package/templates/blocks/components/ChatDictationButton/ChatDictationButtonBasic.tsx +34 -0
  112. package/templates/blocks/components/CheckboxListItem/CheckboxListItemBasic.doc.mjs +14 -0
  113. package/templates/blocks/components/CheckboxListItem/CheckboxListItemBasic.tsx +30 -0
  114. package/templates/blocks/components/CollapsibleGroup/CollapsibleGroupAccordion.doc.mjs +14 -0
  115. package/templates/blocks/components/CollapsibleGroup/CollapsibleGroupAccordion.tsx +31 -0
  116. package/templates/blocks/components/CommandPaletteEmpty/CommandPaletteEmptyBasic.doc.mjs +14 -0
  117. package/templates/blocks/components/CommandPaletteEmpty/CommandPaletteEmptyBasic.tsx +26 -0
  118. package/templates/blocks/components/CommandPaletteFooter/CommandPaletteFooterBasic.doc.mjs +14 -0
  119. package/templates/blocks/components/CommandPaletteFooter/CommandPaletteFooterBasic.tsx +32 -0
  120. package/templates/blocks/components/CommandPaletteGroup/CommandPaletteGroupBasic.doc.mjs +18 -0
  121. package/templates/blocks/components/CommandPaletteGroup/CommandPaletteGroupBasic.tsx +32 -0
  122. package/templates/blocks/components/CommandPaletteItem/CommandPaletteItemBasic.doc.mjs +14 -0
  123. package/templates/blocks/components/CommandPaletteItem/CommandPaletteItemBasic.tsx +27 -0
  124. package/templates/blocks/components/ContextMenu/ContextMenuBasic.doc.mjs +14 -0
  125. package/templates/blocks/components/ContextMenu/ContextMenuBasic.tsx +32 -0
  126. package/templates/blocks/components/DateRangeInput/DateRangeInputWithPresets.doc.mjs +14 -0
  127. package/templates/blocks/components/DateRangeInput/DateRangeInputWithPresets.tsx +46 -0
  128. package/templates/blocks/components/DateRangeInput/DateRangeInputWithValidation.doc.mjs +14 -0
  129. package/templates/blocks/components/DateRangeInput/DateRangeInputWithValidation.tsx +52 -0
  130. package/templates/blocks/components/DateTimeInput/DateTimeInputWithValidation.doc.mjs +14 -0
  131. package/templates/blocks/components/DateTimeInput/DateTimeInputWithValidation.tsx +43 -0
  132. package/templates/blocks/components/DialogHeader/DialogHeaderBasic.doc.mjs +14 -0
  133. package/templates/blocks/components/DialogHeader/DialogHeaderBasic.tsx +30 -0
  134. package/templates/blocks/components/DropdownMenu/DropdownMenuShowcase.tsx +0 -6
  135. package/templates/blocks/components/DropdownMenuItem/DropdownMenuItemBasic.doc.mjs +14 -0
  136. package/templates/blocks/components/DropdownMenuItem/DropdownMenuItemBasic.tsx +27 -0
  137. package/templates/blocks/components/DropdownMenuItem/DropdownMenuItemShowcase.tsx +1 -5
  138. package/templates/blocks/components/FieldLabel/FieldLabelBasic.doc.mjs +14 -0
  139. package/templates/blocks/components/FieldLabel/FieldLabelBasic.tsx +20 -0
  140. package/templates/blocks/components/FieldStatus/FieldStatusBasic.doc.mjs +14 -0
  141. package/templates/blocks/components/FieldStatus/FieldStatusBasic.tsx +23 -0
  142. package/templates/blocks/components/FileInput/FileInputBasic.doc.mjs +14 -0
  143. package/templates/blocks/components/FileInput/FileInputBasic.tsx +22 -0
  144. package/templates/blocks/components/GridSpan/GridSpanColumns.doc.mjs +14 -0
  145. package/templates/blocks/components/GridSpan/GridSpanColumns.tsx +38 -0
  146. package/templates/blocks/components/HStack/HStackBasic.doc.mjs +14 -0
  147. package/templates/blocks/components/HStack/HStackBasic.tsx +16 -0
  148. package/templates/blocks/components/Hooks/useKeyboardHintHookUsage.doc.mjs +14 -0
  149. package/templates/blocks/components/Hooks/useKeyboardHintHookUsage.tsx +57 -0
  150. package/templates/blocks/components/HoverCard/HoverCardInteractiveContent.doc.mjs +1 -1
  151. package/templates/blocks/components/HoverCard/HoverCardInteractiveContent.tsx +9 -4
  152. package/templates/blocks/components/InputGroup/InputGroupBasic.doc.mjs +14 -0
  153. package/templates/blocks/components/InputGroup/InputGroupBasic.tsx +27 -0
  154. package/templates/blocks/components/LayoutContent/LayoutContentBasic.doc.mjs +23 -0
  155. package/templates/blocks/components/LayoutContent/LayoutContentBasic.tsx +40 -0
  156. package/templates/blocks/components/LayoutFooter/LayoutFooterActions.doc.mjs +22 -0
  157. package/templates/blocks/components/LayoutFooter/LayoutFooterActions.tsx +41 -0
  158. package/templates/blocks/components/LayoutHeader/LayoutHeaderWithActions.doc.mjs +23 -0
  159. package/templates/blocks/components/LayoutHeader/LayoutHeaderWithActions.tsx +40 -0
  160. package/templates/blocks/components/LayoutPanel/LayoutPanelNavigation.doc.mjs +22 -0
  161. package/templates/blocks/components/LayoutPanel/LayoutPanelNavigation.tsx +37 -0
  162. package/templates/blocks/components/Lightbox/LightboxGallery.doc.mjs +14 -0
  163. package/templates/blocks/components/Lightbox/LightboxGallery.tsx +53 -0
  164. package/templates/blocks/components/Lightbox/LightboxShowcase.tsx +4 -3
  165. package/templates/blocks/components/Lightbox/LightboxVideo.doc.mjs +14 -0
  166. package/templates/blocks/components/Lightbox/LightboxVideo.tsx +27 -0
  167. package/templates/blocks/components/Lightbox/LightboxZoom.doc.mjs +14 -0
  168. package/templates/blocks/components/Lightbox/LightboxZoom.tsx +33 -0
  169. package/templates/blocks/components/LinkProvider/LinkProviderCustomLink.doc.mjs +1 -1
  170. package/templates/blocks/components/MetadataListItem/MetadataListItemBasic.doc.mjs +14 -0
  171. package/templates/blocks/components/MetadataListItem/MetadataListItemBasic.tsx +19 -0
  172. package/templates/blocks/components/MobileNavToggle/MobileNavToggleBasic.doc.mjs +23 -0
  173. package/templates/blocks/components/MobileNavToggle/MobileNavToggleBasic.tsx +42 -0
  174. package/templates/blocks/components/MoreMenu/MoreMenuShowcase.tsx +0 -6
  175. package/templates/blocks/components/NavIcon/NavIconBasic.doc.mjs +14 -0
  176. package/templates/blocks/components/NavIcon/NavIconBasic.tsx +16 -0
  177. package/templates/blocks/components/RadioListItem/RadioListItemBasic.doc.mjs +14 -0
  178. package/templates/blocks/components/RadioListItem/RadioListItemBasic.tsx +30 -0
  179. package/templates/blocks/components/Resizable/ResizableSidebar.doc.mjs +25 -0
  180. package/templates/blocks/components/Resizable/ResizableSidebar.tsx +67 -0
  181. package/templates/blocks/components/SegmentedControlItem/SegmentedControlItemBasic.doc.mjs +14 -0
  182. package/templates/blocks/components/SegmentedControlItem/SegmentedControlItemBasic.tsx +21 -0
  183. package/templates/blocks/components/SelectorOption/SelectorOptionBasic.doc.mjs +14 -0
  184. package/templates/blocks/components/SelectorOption/SelectorOptionBasic.tsx +39 -0
  185. package/templates/blocks/components/SideNavCollapseButton/SideNavCollapseButtonBasic.doc.mjs +14 -0
  186. package/templates/blocks/components/SideNavCollapseButton/SideNavCollapseButtonBasic.tsx +55 -0
  187. package/templates/blocks/components/SideNavHeading/SideNavHeadingBasic.doc.mjs +14 -0
  188. package/templates/blocks/components/SideNavHeading/SideNavHeadingBasic.tsx +38 -0
  189. package/templates/blocks/components/SideNavItem/SideNavItemBasic.doc.mjs +14 -0
  190. package/templates/blocks/components/SideNavItem/SideNavItemBasic.tsx +49 -0
  191. package/templates/blocks/components/SideNavSection/SideNavSectionBasic.doc.mjs +14 -0
  192. package/templates/blocks/components/SideNavSection/SideNavSectionBasic.tsx +71 -0
  193. package/templates/blocks/components/StackItem/StackItemFill.doc.mjs +14 -0
  194. package/templates/blocks/components/StackItem/StackItemFill.tsx +28 -0
  195. package/templates/blocks/components/Tab/TabWithSelectedIcon.doc.mjs +13 -0
  196. package/templates/blocks/components/Tab/TabWithSelectedIcon.tsx +39 -0
  197. package/templates/blocks/components/TabMenu/TabMenuBasic.doc.mjs +14 -0
  198. package/templates/blocks/components/TabMenu/TabMenuBasic.tsx +23 -0
  199. package/templates/blocks/components/Table/StickyColumnsHookUsage.doc.mjs +1 -1
  200. package/templates/blocks/components/ToggleButtonGroup/ToggleButtonGroupVertical.doc.mjs +14 -0
  201. package/templates/blocks/components/ToggleButtonGroup/ToggleButtonGroupVertical.tsx +47 -0
  202. package/templates/blocks/components/TopNavHeading/TopNavHeadingBasic.doc.mjs +14 -0
  203. package/templates/blocks/components/TopNavHeading/TopNavHeadingBasic.tsx +22 -0
  204. package/templates/blocks/components/TopNavItem/TopNavItemBasic.doc.mjs +14 -0
  205. package/templates/blocks/components/TopNavItem/TopNavItemBasic.tsx +21 -0
  206. package/templates/blocks/components/TopNavMegaMenu/TopNavMegaMenuBasic.doc.mjs +20 -0
  207. package/templates/blocks/components/TopNavMegaMenu/TopNavMegaMenuBasic.tsx +46 -0
  208. package/templates/blocks/components/TopNavMegaMenuFeaturedCard/TopNavMegaMenuFeaturedCardBasic.doc.mjs +14 -0
  209. package/templates/blocks/components/TopNavMegaMenuFeaturedCard/TopNavMegaMenuFeaturedCardBasic.tsx +16 -0
  210. package/templates/blocks/components/TopNavMegaMenuItem/TopNavMegaMenuItemBasic.doc.mjs +14 -0
  211. package/templates/blocks/components/TopNavMegaMenuItem/TopNavMegaMenuItemBasic.tsx +26 -0
  212. package/templates/blocks/components/TopNavMenu/TopNavMenuBasic.doc.mjs +14 -0
  213. package/templates/blocks/components/TopNavMenu/TopNavMenuBasic.tsx +43 -0
  214. package/templates/blocks/components/TypeaheadItem/TypeaheadItemBasic.doc.mjs +14 -0
  215. package/templates/blocks/components/TypeaheadItem/TypeaheadItemBasic.tsx +43 -0
  216. package/templates/blocks/components/VStack/VStackBasic.doc.mjs +14 -0
  217. package/templates/blocks/components/VStack/VStackBasic.tsx +20 -0
  218. package/templates/pages/kanban-board/page.tsx +729 -0
  219. package/templates/pages/kanban-board/template.doc.mjs +12 -0
  220. package/templates/pages/shell-nav/page.tsx +321 -0
  221. package/templates/pages/shell-nav/template.doc.mjs +12 -0
  222. package/templates/pages/shell-side-nav/page.tsx +241 -0
  223. package/templates/pages/shell-side-nav/template.doc.mjs +12 -0
  224. package/templates/pages/shell-top-nav/page.tsx +224 -0
  225. package/templates/pages/shell-top-nav/template.doc.mjs +12 -0
  226. package/src/codemods/transforms/v0.1.0/__tests__/migrate-xds-config-surfaces.test.mjs +0 -116
  227. package/src/codemods/transforms/v0.1.0/migrate-xds-config-surfaces.mjs +0 -230
  228. package/src/commands/gap-report.mjs +0 -464
  229. package/src/commands/gap-report.test.mjs +0 -168
  230. package/src/commands/swizzle-gap-safety.test.mjs +0 -273
  231. package/src/lib/config.mjs +0 -113
  232. package/src/lib/config.test.mjs +0 -91
  233. package/src/types/gap-report.d.ts +0 -29
  234. package/templates/blocks/components/TreeListBranches/TreeListBranchesShowcase.doc.mjs +0 -14
  235. package/templates/blocks/components/TreeListBranches/TreeListBranchesShowcase.tsx +0 -64
  236. package/templates/blocks/components/TreeListItem/TreeListItemShowcase.doc.mjs +0 -14
  237. package/templates/blocks/components/TreeListItem/TreeListItemShowcase.tsx +0 -60
  238. /package/src/codemods/transforms/{v0.0.15 → v0.1.0}/__tests__/drop-xds-prefix-imports.test.mjs +0 -0
@@ -0,0 +1,61 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ import {describe, it, expect} from 'vitest';
4
+
5
+ async function applyTransform(source, filePath = 'test.d.ts') {
6
+ const {default: transform} = await import('../migrate-xds-declare-module.mjs');
7
+ const jscodeshift = (await import('jscodeshift')).default;
8
+ const j = jscodeshift.withParser('tsx');
9
+ const api = {jscodeshift: j, stats: () => {}, report: () => {}};
10
+ const file = {source, path: filePath};
11
+ const result = transform(file, api);
12
+ return result ?? source;
13
+ }
14
+
15
+ describe('migrate-xds-declare-module', () => {
16
+ it('renames a subpath declare module', async () => {
17
+ const input = [
18
+ "declare module '@xds/core/Heading' {",
19
+ ' export const HeadingLevelMap: Record<string, number>;',
20
+ '}',
21
+ ].join('\n');
22
+
23
+ const output = await applyTransform(input);
24
+ expect(output).toMatch(/declare module ['"]@astryxdesign\/core\/Heading['"]/);
25
+ expect(output).not.toContain('@xds/core');
26
+ // The augmentation body identifier is untouched.
27
+ expect(output).toContain('HeadingLevelMap');
28
+ });
29
+
30
+ it('renames a bare @xds/core declare module', async () => {
31
+ const input = "declare module '@xds/core' {\n const x: number;\n}";
32
+ const output = await applyTransform(input);
33
+ expect(output).toMatch(/declare module ['"]@astryxdesign\/core['"]/);
34
+ expect(output).not.toContain('@xds/core');
35
+ });
36
+
37
+ it('renames @xds/lab declare module using the shared map', async () => {
38
+ const input = "declare module '@xds/lab/Thing' {\n const y: number;\n}";
39
+ const output = await applyTransform(input);
40
+ expect(output).toMatch(/declare module ['"]@astryxdesign\/lab\/Thing['"]/);
41
+ expect(output).not.toContain('@xds/lab');
42
+ });
43
+
44
+ it('leaves non-xds declare modules alone', async () => {
45
+ const input = "declare module 'react' {\n const z: number;\n}";
46
+ const output = await applyTransform(input);
47
+ expect(output).toBe(input);
48
+ });
49
+
50
+ it('leaves an already-migrated declare module unchanged', async () => {
51
+ const input = "declare module '@astryxdesign/core/Heading' {\n const a: number;\n}";
52
+ const output = await applyTransform(input);
53
+ expect(output).toBe(input);
54
+ });
55
+
56
+ it('does not touch namespace declarations (Identifier id)', async () => {
57
+ const input = 'declare namespace XDSCore {\n const b: number;\n}';
58
+ const output = await applyTransform(input, 'test.ts');
59
+ expect(output).toBe(input);
60
+ });
61
+ });
@@ -0,0 +1,104 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ import {describe, it, expect} from 'vitest';
4
+
5
+ /**
6
+ * End-to-end test proving the v0.1.0 manifest ordering: the prefix-drop
7
+ * codemod runs BEFORE migrate-xds-module-specifiers, so a prefixed identifier
8
+ * imported from `@xds/core` is un-prefixed AND the module path is rewritten to
9
+ * `@astryxdesign/core` in a single upgrade pass.
10
+ */
11
+ async function applyManifestInOrder(source, filePath = 'test.tsx') {
12
+ const {default: manifest} = await import('../index.mjs');
13
+ const jscodeshift = (await import('jscodeshift')).default;
14
+ const j = jscodeshift.withParser('tsx');
15
+ const api = {jscodeshift: j, stats: () => {}, report: () => {}};
16
+
17
+ let current = source;
18
+ for (const {transform} of manifest) {
19
+ const file = {source: current, path: filePath};
20
+ const result = transform(file, api);
21
+ current = result ?? current;
22
+ }
23
+ return current;
24
+ }
25
+
26
+ describe('v0.1.0 codemod manifest ordering', () => {
27
+ it('runs drop-xds-prefix-imports before migrate-xds-module-specifiers', async () => {
28
+ const {default: manifest} = await import('../index.mjs');
29
+ const names = manifest.map(entry => entry.name);
30
+ const prefixDropIdx = names.indexOf('drop-xds-prefix-imports');
31
+ const specifierIdx = names.indexOf('migrate-xds-module-specifiers');
32
+ expect(prefixDropIdx).toBeGreaterThanOrEqual(0);
33
+ expect(specifierIdx).toBeGreaterThanOrEqual(0);
34
+ expect(prefixDropIdx).toBeLessThan(specifierIdx);
35
+ });
36
+
37
+ it('drop-xds-prefix-imports is mandatory (not optional) in v0.1.0', async () => {
38
+ const {default: manifest} = await import('../index.mjs');
39
+ const entry = manifest.find(e => e.name === 'drop-xds-prefix-imports');
40
+ expect(entry).toBeDefined();
41
+ expect(entry.optional).toBeFalsy();
42
+ });
43
+
44
+ it('orders declare-module and CSS codemods after migrate-xds-module-specifiers', async () => {
45
+ const {default: manifest} = await import('../index.mjs');
46
+ const names = manifest.map(entry => entry.name);
47
+ expect(names).toEqual([
48
+ 'drop-xds-prefix-imports',
49
+ 'migrate-xds-module-specifiers',
50
+ 'migrate-xds-declare-module',
51
+ 'migrate-xds-css-surfaces',
52
+ ]);
53
+ });
54
+
55
+ it('marks migrate-xds-declare-module and migrate-xds-css-surfaces mandatory', async () => {
56
+ const {default: manifest} = await import('../index.mjs');
57
+ for (const name of [
58
+ 'migrate-xds-declare-module',
59
+ 'migrate-xds-css-surfaces',
60
+ ]) {
61
+ const entry = manifest.find(e => e.name === name);
62
+ expect(entry, name).toBeDefined();
63
+ expect(entry.optional).toBeFalsy();
64
+ }
65
+ });
66
+
67
+ it('un-prefixes useXDSTheme from @xds/core/theme AND renames the scope to @astryxdesign', async () => {
68
+ const input = [
69
+ "import {useXDSTheme} from '@xds/core/theme';",
70
+ '',
71
+ 'function App() {',
72
+ ' const theme = useXDSTheme();',
73
+ ' return theme;',
74
+ '}',
75
+ ].join('\n');
76
+
77
+ const output = await applyManifestInOrder(input);
78
+
79
+ expect(output).toMatch(/import\s*\{useTheme\}\s*from\s*['"]@astryxdesign\/core\/theme['"]/);
80
+ expect(output).toContain('const theme = useTheme();');
81
+ // The prefixed name and old scope must be fully gone.
82
+ expect(output).not.toContain('useXDSTheme');
83
+ expect(output).not.toContain('@xds/core');
84
+ });
85
+
86
+ it('un-prefixes XDSButton and XDSIconRegistry alongside the scope rename', async () => {
87
+ const input = [
88
+ "import {XDSButton, XDSIconRegistry} from '@xds/core';",
89
+ '',
90
+ 'const registry = new XDSIconRegistry();',
91
+ 'const el = <XDSButton />;',
92
+ ].join('\n');
93
+
94
+ const output = await applyManifestInOrder(input);
95
+
96
+ expect(output).toMatch(/from\s*['"]@astryxdesign\/core['"]/);
97
+ expect(output).toContain('Button');
98
+ expect(output).toContain('IconRegistry');
99
+ expect(output).toContain('new IconRegistry()');
100
+ expect(output).not.toContain('XDSButton');
101
+ expect(output).not.toContain('XDSIconRegistry');
102
+ expect(output).not.toContain('@xds/core');
103
+ });
104
+ });
@@ -4,12 +4,23 @@
4
4
  * @file Codemod: Drop the `XDS` prefix from @xds/core imports and their usages
5
5
  *
6
6
  * Part of the XDS-prefix migration (P2380608025). Rewrites consumer code from
7
- * the prefixed names to the bare compatibility aliases shipped in P1:
7
+ * the prefixed names to their bare equivalents:
8
8
  *
9
9
  * XDSButton -> Button
10
10
  * XDSButtonProps -> ButtonProps
11
11
  * useXDSTheme -> useTheme
12
12
  * useXDSToast -> useToast
13
+ * XDSIconRegistry-> IconRegistry
14
+ *
15
+ * Mandatory in v0.1.0: the prefixed compatibility aliases (which made both
16
+ * prefixed and bare names valid during the 0.0.x compat window) were dropped
17
+ * in v0.1.0, so the un-prefixing is now required for code to keep type-
18
+ * checking against @astryxdesign/core.
19
+ *
20
+ * Ordering: within the v0.1.0 manifest this runs BEFORE
21
+ * migrate-xds-module-specifiers so it still matches `@xds/core` imports (its
22
+ * source matcher) and un-prefixes the identifiers first; the specifier codemod
23
+ * then rewrites the module paths `@xds/*` -> `@astryxdesign/*`.
13
24
  *
14
25
  * Safety: this codemod ONLY renames identifiers that are imported from
15
26
  * `@xds/core` (bare or subpath, e.g. `@xds/core/Button`). It tracks the local
@@ -36,9 +47,9 @@ export const meta = {
36
47
  title: 'Drop XDS prefix from @xds/core imports (XDSButton -> Button)',
37
48
  description:
38
49
  'Rewrites @xds/core imports and their usages from the prefixed names ' +
39
- '(XDSButton, useXDSTheme, XDSButtonProps) to the bare compatibility ' +
40
- 'aliases (Button, useTheme, ButtonProps). Only renames bindings imported ' +
41
- 'from @xds/core, leaving unrelated identifiers untouched.',
50
+ '(XDSButton, useXDSTheme, XDSIconRegistry, XDSButtonProps) to their bare ' +
51
+ 'names (Button, useTheme, IconRegistry, ButtonProps). Only renames ' +
52
+ 'bindings imported from @xds/core, leaving unrelated identifiers untouched.',
42
53
  pr: '#2880',
43
54
  };
44
55
 
@@ -6,23 +6,60 @@
6
6
  * Lists all codemods for the v0.1.0 release in the order they should run.
7
7
  */
8
8
 
9
- import migrateXdsConfigSurfaces, {
10
- meta as migrateXdsConfigSurfacesMeta,
11
- } from './migrate-xds-config-surfaces.mjs';
9
+ import dropXdsPrefixImports, {
10
+ meta as dropXdsPrefixImportsMeta,
11
+ } from './drop-xds-prefix-imports.mjs';
12
12
 
13
13
  import migrateXdsModuleSpecifiers, {
14
14
  meta as migrateXdsModuleSpecifiersMeta,
15
15
  } from './migrate-xds-module-specifiers.mjs';
16
16
 
17
+ import migrateXdsDeclareModule, {
18
+ meta as migrateXdsDeclareModuleMeta,
19
+ } from './migrate-xds-declare-module.mjs';
20
+
21
+ import migrateXdsCssSurfaces, {
22
+ meta as migrateXdsCssSurfacesMeta,
23
+ } from './migrate-xds-css-surfaces.mjs';
24
+
17
25
  export default [
18
26
  {
19
- name: 'migrate-xds-config-surfaces',
20
- transform: migrateXdsConfigSurfaces,
21
- meta: migrateXdsConfigSurfacesMeta,
27
+ // XDS-prefix migration (P2380608025). Mandatory in v0.1.0: the release
28
+ // dropped the prefixed compatibility aliases (useXDSTheme, XDSButton,
29
+ // XDSIconRegistry, ...), so consumers upgrading from 0.0.x MUST rewrite
30
+ // prefixed imports to their bare names.
31
+ //
32
+ // Ordered BEFORE migrate-xds-module-specifiers so it sees `@xds/core`
33
+ // imports (its source matcher) and un-prefixes the identifiers first;
34
+ // the specifier codemod then rewrites the paths to `@astryxdesign/core`.
35
+ // The runner preserves this array order (see runner.mjs).
36
+ name: 'drop-xds-prefix-imports',
37
+ transform: dropXdsPrefixImports,
38
+ meta: dropXdsPrefixImportsMeta,
22
39
  },
23
40
  {
24
41
  name: 'migrate-xds-module-specifiers',
25
42
  transform: migrateXdsModuleSpecifiers,
26
43
  meta: migrateXdsModuleSpecifiersMeta,
27
44
  },
45
+ {
46
+ // Cleans up TypeScript `declare module "@xds/core/..."` augmentations,
47
+ // which reference the package by string specifier and so are dead after
48
+ // the scope rename. Mandatory in v0.1.0. Ordered AFTER the specifier
49
+ // codemod: it uses the same @xds -> @astryxdesign mapping and repairs an
50
+ // adjacent surface the specifier codemod does not visit (module-decl ids
51
+ // are not import/export/require sources).
52
+ name: 'migrate-xds-declare-module',
53
+ transform: migrateXdsDeclareModule,
54
+ meta: migrateXdsDeclareModuleMeta,
55
+ },
56
+ {
57
+ // Rewrites consumer CSS surfaces broken by the v0.1.0 DOM-namespace rename
58
+ // (core no longer dual-emits `xds-*`): the `.xds-*` class-selector prefix,
59
+ // `[data-xds-*]` attribute selectors, and `@layer xds-*` layer names all
60
+ // become their `astryx-*` forms. Mandatory in v0.1.0.
61
+ name: 'migrate-xds-css-surfaces',
62
+ transform: migrateXdsCssSurfaces,
63
+ meta: migrateXdsCssSurfacesMeta,
64
+ },
28
65
  ];
@@ -0,0 +1,77 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file Codemod: migrate XDS CSS surfaces to their Astryx equivalents
5
+ *
6
+ * The v0.1.0 release renamed the DOM namespace emitted by @astryxdesign/core
7
+ * from `xds-*` to `astryx-*` and dropped the dual-emit compatibility (core no
8
+ * longer emits the legacy `xds-*` classes or `data-xds-*` attributes). Any
9
+ * consumer CSS that targeted those surfaces is now broken.
10
+ *
11
+ * This transform performs precise, targeted string replacements on CSS/SCSS
12
+ * files for the documented surfaces only:
13
+ *
14
+ * .xds-* (class-name prefix in selectors — matched only
15
+ * after a `.` so it is a class selector)
16
+ * [data-xds-theme (theme attribute selector)
17
+ * [data-xds-theme-prose (prose-theme attribute selector)
18
+ * [data-xds-media (media attribute selector)
19
+ * @layer xds-theme (cascade layer name — incl. comma-separated
20
+ * @layer xds-base `@layer a, b;` statement lists and nested blocks)
21
+ *
22
+ * It deliberately does NOT blindly replace every `xds` substring: a bare
23
+ * `xds` in a comment, a custom-property value, or an unrelated identifier is
24
+ * left untouched. CSS has no meaningful AST for this class of edit, so this is
25
+ * a plain string transform — `api.jscodeshift` is available but unused.
26
+ */
27
+
28
+ export const meta = {
29
+ title: 'Migrate .xds-* / [data-xds-*] / @layer xds-* CSS surfaces to astryx',
30
+ description:
31
+ 'Rewrites the documented XDS CSS surfaces to their Astryx equivalents: ' +
32
+ 'the `.xds-*` class-selector prefix, `[data-xds-theme]` / ' +
33
+ '`[data-xds-theme-prose]` / `[data-xds-media]` attribute selectors, and ' +
34
+ '`@layer xds-theme` / `@layer xds-base` cascade-layer names all become ' +
35
+ 'their `astryx-*` / `data-astryx-*` forms.',
36
+ pr: '#3092',
37
+ fileExtensions: ['.css', '.scss'],
38
+ };
39
+
40
+ // The XDS cascade-layer names we own. A `@layer` prelude can name several
41
+ // layers in a comma-separated list (`@layer a, b;`), so we can't anchor every
42
+ // occurrence to the `@layer` keyword. We instead rewrite these exact layer
43
+ // tokens within a `@layer ...` prelude (up to the next `{` or `;`).
44
+ const XDS_LAYER_NAMES = new Map([
45
+ ['xds-theme', 'astryx-theme'],
46
+ ['xds-base', 'astryx-base'],
47
+ ]);
48
+
49
+ function rewriteLayerPrelude(prelude) {
50
+ return prelude.replace(/\bxds-(?:theme|base)\b/g, name =>
51
+ XDS_LAYER_NAMES.get(name) ?? name,
52
+ );
53
+ }
54
+
55
+ // Ordered, non-overlapping replacements. Each pattern is intentionally narrow
56
+ // so we never touch a bare `xds` substring outside these surfaces.
57
+ const REPLACEMENTS = [
58
+ // Class-name prefix: only when preceded by a `.` (a class selector).
59
+ {re: /\.xds-/g, to: '.astryx-'},
60
+ // Attribute selectors: any `[data-xds-` opener (theme, theme-prose, media).
61
+ {re: /\[data-xds-/g, to: '[data-astryx-'},
62
+ // Cascade-layer preludes: `@layer <names>` up to the block `{` or `;`.
63
+ // Rewrite only the recognized xds-* layer tokens inside the prelude.
64
+ {re: /@layer\b[^{;]*/g, to: match => rewriteLayerPrelude(match)},
65
+ ];
66
+
67
+ export default function transformer(file /*, api */) {
68
+ const source = file.source;
69
+ if (typeof source !== 'string') return undefined;
70
+
71
+ let next = source;
72
+ for (const {re, to} of REPLACEMENTS) {
73
+ next = next.replace(re, to);
74
+ }
75
+
76
+ return next === source ? undefined : next;
77
+ }
@@ -0,0 +1,78 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file Codemod: migrate `declare module "@xds/..."` augmentations to
5
+ * `@astryxdesign/...`
6
+ *
7
+ * The v0.1.0 release moved the public package scope from @xds to
8
+ * @astryxdesign. TypeScript module augmentations (`declare module "@xds/core"
9
+ * { ... }`) reference the package by its string specifier, so they are dead
10
+ * after the scope rename: TypeScript resolves the augmentation against a
11
+ * module that no longer exists.
12
+ *
13
+ * This transform rewrites the augmented module string on `TSModuleDeclaration`
14
+ * nodes whose `id` is a StringLiteral matching a renamed @xds package (or one
15
+ * of its subpaths). It only touches the module path — identifiers *inside* the
16
+ * augmentation (e.g. an augmented interface name) are a separate concern
17
+ * handled by drop-xds-prefix-imports.
18
+ *
19
+ * Ordered AFTER migrate-xds-module-specifiers in the v0.1.0 manifest: it uses
20
+ * the same PACKAGE_RENAMES mapping and cleans up the module-augmentation
21
+ * surface alongside the import/export/require specifier rename.
22
+ */
23
+
24
+ export const meta = {
25
+ title: 'Migrate declare-module augmentations from @xds/* to @astryxdesign/*',
26
+ description:
27
+ 'Rewrites the module specifier on TypeScript `declare module "@xds/..."` ' +
28
+ 'augmentations to the @astryxdesign/* packages used by Astryx v0.1.0. ' +
29
+ 'Only the augmented module path is changed; identifiers inside the ' +
30
+ 'augmentation are left untouched.',
31
+ pr: '#3092',
32
+ fileExtensions: ['.ts', '.d.ts', '.tsx'],
33
+ };
34
+
35
+ const PACKAGE_RENAMES = new Map([
36
+ ['@xds/build', '@astryxdesign/build'],
37
+ ['@xds/cli', '@astryxdesign/cli'],
38
+ ['@xds/core', '@astryxdesign/core'],
39
+ ['@xds/lab', '@astryxdesign/lab'],
40
+ ['@xds/theme-butter', '@astryxdesign/theme-butter'],
41
+ ['@xds/theme-chocolate', '@astryxdesign/theme-chocolate'],
42
+ ['@xds/theme-daily', '@astryxdesign/theme-neutral'],
43
+ ['@xds/theme-default', '@astryxdesign/theme-neutral'],
44
+ ['@xds/theme-gothic', '@astryxdesign/theme-gothic'],
45
+ ['@xds/theme-matcha', '@astryxdesign/theme-matcha'],
46
+ ['@xds/theme-neutral', '@astryxdesign/theme-neutral'],
47
+ ['@xds/theme-stone', '@astryxdesign/theme-stone'],
48
+ ['@xds/theme-y2k', '@astryxdesign/theme-y2k'],
49
+ ]);
50
+
51
+ function renamePackageSpecifier(value) {
52
+ if (typeof value !== 'string') return value;
53
+ for (const [from, to] of PACKAGE_RENAMES) {
54
+ if (value === from) return to;
55
+ if (value.startsWith(from + '/')) return to + value.slice(from.length);
56
+ }
57
+ return value;
58
+ }
59
+
60
+ export default function transformer(file, api) {
61
+ const j = api.jscodeshift;
62
+ const root = j(file.source);
63
+ let hasChanges = false;
64
+
65
+ root.find(j.TSModuleDeclaration).forEach(path => {
66
+ const id = path.node.id;
67
+ // Module augmentations name the module with a string literal id; a
68
+ // `namespace Foo {}` uses an Identifier id, which we ignore.
69
+ if (!id || (id.type !== 'StringLiteral' && id.type !== 'Literal')) return;
70
+ if (typeof id.value !== 'string') return;
71
+ const next = renamePackageSpecifier(id.value);
72
+ if (next === id.value) return;
73
+ id.value = next;
74
+ hasChanges = true;
75
+ });
76
+
77
+ return hasChanges ? root.toSource() : undefined;
78
+ }