@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.
- package/CHANGELOG.md +64 -1
- package/README.md +49 -55
- package/docs/layout.doc.dense.mjs +90 -0
- package/docs/layout.doc.mjs +160 -0
- package/docs/principles.doc.dense.mjs +2 -2
- package/docs/principles.doc.mjs +4 -0
- package/docs/principles.doc.zh.mjs +2 -2
- package/docs/theme.doc.mjs +2 -2
- package/package.json +13 -1
- package/src/api/blog.mjs +192 -0
- package/src/api/blog.test.mjs +144 -0
- package/src/api/component.mjs +253 -12
- package/src/api/discover.mjs +14 -7
- package/src/api/doctor.mjs +10 -25
- package/src/api/index.mjs +1 -0
- package/src/api/layout.mjs +11 -10
- package/src/api/layout.test.mjs +4 -1
- package/src/api/template-integration.test.mjs +225 -0
- package/src/api/template.mjs +242 -84
- package/src/api/validate-integration.mjs +370 -0
- package/src/api/validate-integration.test.mjs +222 -0
- package/src/codemod.mjs +93 -0
- package/src/codemod.test.mjs +134 -0
- package/src/codemods/__tests__/registry.test.mjs +1 -0
- package/src/codemods/__tests__/runner.test.mjs +103 -0
- package/src/codemods/integration-discovery.mjs +168 -0
- package/src/codemods/integration-discovery.test.mjs +234 -0
- package/src/codemods/integration-runner.mjs +109 -0
- package/src/codemods/registry.mjs +1 -0
- package/src/codemods/run-codemod.mjs +207 -0
- package/src/codemods/runner.mjs +73 -96
- package/src/codemods/transforms/v0.0.15/index.mjs +0 -13
- package/src/codemods/transforms/v0.1.0/__tests__/migrate-xds-css-surfaces.test.mjs +67 -0
- package/src/codemods/transforms/v0.1.0/__tests__/migrate-xds-declare-module.test.mjs +61 -0
- package/src/codemods/transforms/v0.1.0/__tests__/v0.1.0-ordering.test.mjs +104 -0
- package/src/codemods/transforms/{v0.0.15 → v0.1.0}/drop-xds-prefix-imports.mjs +15 -4
- package/src/codemods/transforms/v0.1.0/index.mjs +43 -6
- package/src/codemods/transforms/v0.1.0/migrate-xds-css-surfaces.mjs +77 -0
- package/src/codemods/transforms/v0.1.0/migrate-xds-declare-module.mjs +78 -0
- package/src/codemods/transforms/v0.1.3/__tests__/migrate-layout-components-to-experimental.test.mjs +360 -0
- package/src/codemods/transforms/v0.1.3/index.mjs +19 -0
- package/src/codemods/transforms/v0.1.3/migrate-layout-components-to-experimental.mjs +260 -0
- package/src/commands/agent-docs.mjs +4 -1
- package/src/commands/blog.mjs +60 -0
- package/src/commands/build-theme.import-path.test.mjs +2 -12
- package/src/commands/build-theme.mjs +117 -0
- package/src/commands/build-theme.prose.test.mjs +5 -15
- package/src/commands/build-theme.watch.test.mjs +149 -0
- package/src/commands/component/index.mjs +44 -10
- package/src/commands/component-ownership.test.mjs +227 -0
- package/src/commands/discover.mjs +5 -16
- package/src/commands/doctor.test.mjs +3 -3
- package/src/commands/ensure-core-built.mjs +120 -0
- package/src/commands/json-contract.test.mjs +0 -32
- package/src/commands/swizzle.mjs +224 -235
- package/src/commands/swizzle.path-safety.test.mjs +3 -3
- package/src/commands/swizzle.routing.test.mjs +279 -0
- package/src/commands/template.mjs +33 -37
- package/src/commands/upgrade.config-ordering.test.mjs +273 -0
- package/src/commands/upgrade.integration-policy.test.mjs +204 -0
- package/src/commands/upgrade.mjs +349 -170
- package/src/commands/validate-integration.mjs +110 -0
- package/src/commands/validate-integration.test.mjs +124 -0
- package/src/config.mjs +7 -20
- package/src/config.test.mjs +89 -13
- package/src/index.mjs +8 -3
- package/src/integration.mjs +19 -0
- package/src/lib/component-discovery.mjs +177 -0
- package/src/lib/config-cache.mjs +91 -0
- package/src/lib/config-cache.test.mjs +83 -0
- package/src/lib/config-schema.mjs +41 -55
- package/src/lib/error-codes.mjs +15 -12
- package/src/lib/integration-warnings.mjs +62 -0
- package/src/lib/integration-warnings.test.mjs +102 -0
- package/src/lib/integrations.mjs +92 -115
- package/src/lib/integrations.test.mjs +88 -107
- package/src/lib/manifest.mjs +5 -2
- package/src/lib/module-loader.mjs +80 -0
- package/src/lib/module-loader.test.mjs +106 -0
- package/src/lib/project.mjs +502 -0
- package/src/lib/project.test.mjs +308 -0
- package/src/lib/site.mjs +20 -0
- package/src/template.mjs +73 -0
- package/src/template.test.mjs +127 -0
- package/src/types/api.d.ts +2 -6
- package/src/types/base.d.ts +3 -9
- package/src/types/codemod.d.ts +81 -0
- package/src/types/component.d.ts +27 -2
- package/src/types/config.d.ts +56 -85
- package/src/types/error-codes.d.ts +5 -3
- package/src/types/index.d.ts +0 -1
- package/src/types/integration.d.ts +29 -0
- package/src/types/swizzle.d.ts +9 -2
- package/src/types/template-api.d.ts +54 -0
- package/src/types/template.d.ts +10 -7
- package/src/types/upgrade.d.ts +29 -0
- package/src/types/validate-integration.d.ts +24 -0
- package/src/utils/github.mjs +0 -237
- package/src/utils/interactive.mjs +2 -2
- package/templates/blocks/components/AvatarStatusDot/AvatarStatusDotVariants.doc.mjs +14 -0
- package/templates/blocks/components/AvatarStatusDot/AvatarStatusDotVariants.tsx +28 -0
- package/templates/blocks/components/Blockquote/BlockquoteTestimonials.doc.mjs +14 -0
- package/templates/blocks/components/Blockquote/BlockquoteTestimonials.tsx +34 -0
- package/templates/blocks/components/Blockquote/BlockquoteWithCite.doc.mjs +14 -0
- package/templates/blocks/components/Blockquote/BlockquoteWithCite.tsx +21 -0
- package/templates/blocks/components/BreadcrumbItem/BreadcrumbItemBasic.doc.mjs +14 -0
- package/templates/blocks/components/BreadcrumbItem/BreadcrumbItemBasic.tsx +15 -0
- package/templates/blocks/components/ButtonGroup/ButtonGroupBasic.doc.mjs +14 -0
- package/templates/blocks/components/ButtonGroup/ButtonGroupBasic.tsx +16 -0
- package/templates/blocks/components/ChatDictationButton/ChatDictationButtonBasic.doc.mjs +19 -0
- package/templates/blocks/components/ChatDictationButton/ChatDictationButtonBasic.tsx +34 -0
- package/templates/blocks/components/CheckboxListItem/CheckboxListItemBasic.doc.mjs +14 -0
- package/templates/blocks/components/CheckboxListItem/CheckboxListItemBasic.tsx +30 -0
- package/templates/blocks/components/CollapsibleGroup/CollapsibleGroupAccordion.doc.mjs +14 -0
- package/templates/blocks/components/CollapsibleGroup/CollapsibleGroupAccordion.tsx +31 -0
- package/templates/blocks/components/CommandPaletteEmpty/CommandPaletteEmptyBasic.doc.mjs +14 -0
- package/templates/blocks/components/CommandPaletteEmpty/CommandPaletteEmptyBasic.tsx +26 -0
- package/templates/blocks/components/CommandPaletteFooter/CommandPaletteFooterBasic.doc.mjs +14 -0
- package/templates/blocks/components/CommandPaletteFooter/CommandPaletteFooterBasic.tsx +32 -0
- package/templates/blocks/components/CommandPaletteGroup/CommandPaletteGroupBasic.doc.mjs +18 -0
- package/templates/blocks/components/CommandPaletteGroup/CommandPaletteGroupBasic.tsx +32 -0
- package/templates/blocks/components/CommandPaletteItem/CommandPaletteItemBasic.doc.mjs +14 -0
- package/templates/blocks/components/CommandPaletteItem/CommandPaletteItemBasic.tsx +27 -0
- package/templates/blocks/components/ContextMenu/ContextMenuBasic.doc.mjs +14 -0
- package/templates/blocks/components/ContextMenu/ContextMenuBasic.tsx +32 -0
- package/templates/blocks/components/DateRangeInput/DateRangeInputWithPresets.doc.mjs +14 -0
- package/templates/blocks/components/DateRangeInput/DateRangeInputWithPresets.tsx +46 -0
- package/templates/blocks/components/DateRangeInput/DateRangeInputWithValidation.doc.mjs +14 -0
- package/templates/blocks/components/DateRangeInput/DateRangeInputWithValidation.tsx +52 -0
- package/templates/blocks/components/DateTimeInput/DateTimeInputWithValidation.doc.mjs +14 -0
- package/templates/blocks/components/DateTimeInput/DateTimeInputWithValidation.tsx +43 -0
- package/templates/blocks/components/DialogHeader/DialogHeaderBasic.doc.mjs +14 -0
- package/templates/blocks/components/DialogHeader/DialogHeaderBasic.tsx +30 -0
- package/templates/blocks/components/DropdownMenu/DropdownMenuShowcase.tsx +0 -6
- package/templates/blocks/components/DropdownMenuItem/DropdownMenuItemBasic.doc.mjs +14 -0
- package/templates/blocks/components/DropdownMenuItem/DropdownMenuItemBasic.tsx +27 -0
- package/templates/blocks/components/DropdownMenuItem/DropdownMenuItemShowcase.tsx +1 -5
- package/templates/blocks/components/FieldLabel/FieldLabelBasic.doc.mjs +14 -0
- package/templates/blocks/components/FieldLabel/FieldLabelBasic.tsx +20 -0
- package/templates/blocks/components/FieldStatus/FieldStatusBasic.doc.mjs +14 -0
- package/templates/blocks/components/FieldStatus/FieldStatusBasic.tsx +23 -0
- package/templates/blocks/components/FileInput/FileInputBasic.doc.mjs +14 -0
- package/templates/blocks/components/FileInput/FileInputBasic.tsx +22 -0
- package/templates/blocks/components/GridSpan/GridSpanColumns.doc.mjs +14 -0
- package/templates/blocks/components/GridSpan/GridSpanColumns.tsx +38 -0
- package/templates/blocks/components/HStack/HStackBasic.doc.mjs +14 -0
- package/templates/blocks/components/HStack/HStackBasic.tsx +16 -0
- package/templates/blocks/components/Hooks/useKeyboardHintHookUsage.doc.mjs +14 -0
- package/templates/blocks/components/Hooks/useKeyboardHintHookUsage.tsx +57 -0
- package/templates/blocks/components/HoverCard/HoverCardInteractiveContent.doc.mjs +1 -1
- package/templates/blocks/components/HoverCard/HoverCardInteractiveContent.tsx +9 -4
- package/templates/blocks/components/InputGroup/InputGroupBasic.doc.mjs +14 -0
- package/templates/blocks/components/InputGroup/InputGroupBasic.tsx +27 -0
- package/templates/blocks/components/LayoutContent/LayoutContentBasic.doc.mjs +23 -0
- package/templates/blocks/components/LayoutContent/LayoutContentBasic.tsx +40 -0
- package/templates/blocks/components/LayoutFooter/LayoutFooterActions.doc.mjs +22 -0
- package/templates/blocks/components/LayoutFooter/LayoutFooterActions.tsx +41 -0
- package/templates/blocks/components/LayoutHeader/LayoutHeaderWithActions.doc.mjs +23 -0
- package/templates/blocks/components/LayoutHeader/LayoutHeaderWithActions.tsx +40 -0
- package/templates/blocks/components/LayoutPanel/LayoutPanelNavigation.doc.mjs +22 -0
- package/templates/blocks/components/LayoutPanel/LayoutPanelNavigation.tsx +37 -0
- package/templates/blocks/components/Lightbox/LightboxGallery.doc.mjs +14 -0
- package/templates/blocks/components/Lightbox/LightboxGallery.tsx +53 -0
- package/templates/blocks/components/Lightbox/LightboxShowcase.tsx +4 -3
- package/templates/blocks/components/Lightbox/LightboxVideo.doc.mjs +14 -0
- package/templates/blocks/components/Lightbox/LightboxVideo.tsx +27 -0
- package/templates/blocks/components/Lightbox/LightboxZoom.doc.mjs +14 -0
- package/templates/blocks/components/Lightbox/LightboxZoom.tsx +33 -0
- package/templates/blocks/components/LinkProvider/LinkProviderCustomLink.doc.mjs +1 -1
- package/templates/blocks/components/MetadataListItem/MetadataListItemBasic.doc.mjs +14 -0
- package/templates/blocks/components/MetadataListItem/MetadataListItemBasic.tsx +19 -0
- package/templates/blocks/components/MobileNavToggle/MobileNavToggleBasic.doc.mjs +23 -0
- package/templates/blocks/components/MobileNavToggle/MobileNavToggleBasic.tsx +42 -0
- package/templates/blocks/components/MoreMenu/MoreMenuShowcase.tsx +0 -6
- package/templates/blocks/components/NavIcon/NavIconBasic.doc.mjs +14 -0
- package/templates/blocks/components/NavIcon/NavIconBasic.tsx +16 -0
- package/templates/blocks/components/RadioListItem/RadioListItemBasic.doc.mjs +14 -0
- package/templates/blocks/components/RadioListItem/RadioListItemBasic.tsx +30 -0
- package/templates/blocks/components/Resizable/ResizableSidebar.doc.mjs +25 -0
- package/templates/blocks/components/Resizable/ResizableSidebar.tsx +67 -0
- package/templates/blocks/components/SegmentedControlItem/SegmentedControlItemBasic.doc.mjs +14 -0
- package/templates/blocks/components/SegmentedControlItem/SegmentedControlItemBasic.tsx +21 -0
- package/templates/blocks/components/SelectorOption/SelectorOptionBasic.doc.mjs +14 -0
- package/templates/blocks/components/SelectorOption/SelectorOptionBasic.tsx +39 -0
- package/templates/blocks/components/SideNavCollapseButton/SideNavCollapseButtonBasic.doc.mjs +14 -0
- package/templates/blocks/components/SideNavCollapseButton/SideNavCollapseButtonBasic.tsx +55 -0
- package/templates/blocks/components/SideNavHeading/SideNavHeadingBasic.doc.mjs +14 -0
- package/templates/blocks/components/SideNavHeading/SideNavHeadingBasic.tsx +38 -0
- package/templates/blocks/components/SideNavItem/SideNavItemBasic.doc.mjs +14 -0
- package/templates/blocks/components/SideNavItem/SideNavItemBasic.tsx +49 -0
- package/templates/blocks/components/SideNavSection/SideNavSectionBasic.doc.mjs +14 -0
- package/templates/blocks/components/SideNavSection/SideNavSectionBasic.tsx +71 -0
- package/templates/blocks/components/StackItem/StackItemFill.doc.mjs +14 -0
- package/templates/blocks/components/StackItem/StackItemFill.tsx +28 -0
- package/templates/blocks/components/Tab/TabWithSelectedIcon.doc.mjs +13 -0
- package/templates/blocks/components/Tab/TabWithSelectedIcon.tsx +39 -0
- package/templates/blocks/components/TabMenu/TabMenuBasic.doc.mjs +14 -0
- package/templates/blocks/components/TabMenu/TabMenuBasic.tsx +23 -0
- package/templates/blocks/components/Table/StickyColumnsHookUsage.doc.mjs +1 -1
- package/templates/blocks/components/ToggleButtonGroup/ToggleButtonGroupVertical.doc.mjs +14 -0
- package/templates/blocks/components/ToggleButtonGroup/ToggleButtonGroupVertical.tsx +47 -0
- package/templates/blocks/components/TopNavHeading/TopNavHeadingBasic.doc.mjs +14 -0
- package/templates/blocks/components/TopNavHeading/TopNavHeadingBasic.tsx +22 -0
- package/templates/blocks/components/TopNavItem/TopNavItemBasic.doc.mjs +14 -0
- package/templates/blocks/components/TopNavItem/TopNavItemBasic.tsx +21 -0
- package/templates/blocks/components/TopNavMegaMenu/TopNavMegaMenuBasic.doc.mjs +20 -0
- package/templates/blocks/components/TopNavMegaMenu/TopNavMegaMenuBasic.tsx +46 -0
- package/templates/blocks/components/TopNavMegaMenuFeaturedCard/TopNavMegaMenuFeaturedCardBasic.doc.mjs +14 -0
- package/templates/blocks/components/TopNavMegaMenuFeaturedCard/TopNavMegaMenuFeaturedCardBasic.tsx +16 -0
- package/templates/blocks/components/TopNavMegaMenuItem/TopNavMegaMenuItemBasic.doc.mjs +14 -0
- package/templates/blocks/components/TopNavMegaMenuItem/TopNavMegaMenuItemBasic.tsx +26 -0
- package/templates/blocks/components/TopNavMenu/TopNavMenuBasic.doc.mjs +14 -0
- package/templates/blocks/components/TopNavMenu/TopNavMenuBasic.tsx +43 -0
- package/templates/blocks/components/TypeaheadItem/TypeaheadItemBasic.doc.mjs +14 -0
- package/templates/blocks/components/TypeaheadItem/TypeaheadItemBasic.tsx +43 -0
- package/templates/blocks/components/VStack/VStackBasic.doc.mjs +14 -0
- package/templates/blocks/components/VStack/VStackBasic.tsx +20 -0
- package/templates/pages/kanban-board/page.tsx +729 -0
- package/templates/pages/kanban-board/template.doc.mjs +12 -0
- package/templates/pages/shell-nav/page.tsx +321 -0
- package/templates/pages/shell-nav/template.doc.mjs +12 -0
- package/templates/pages/shell-side-nav/page.tsx +241 -0
- package/templates/pages/shell-side-nav/template.doc.mjs +12 -0
- package/templates/pages/shell-top-nav/page.tsx +224 -0
- package/templates/pages/shell-top-nav/template.doc.mjs +12 -0
- package/src/codemods/transforms/v0.1.0/__tests__/migrate-xds-config-surfaces.test.mjs +0 -116
- package/src/codemods/transforms/v0.1.0/migrate-xds-config-surfaces.mjs +0 -230
- package/src/commands/gap-report.mjs +0 -464
- package/src/commands/gap-report.test.mjs +0 -168
- package/src/commands/swizzle-gap-safety.test.mjs +0 -273
- package/src/lib/config.mjs +0 -113
- package/src/lib/config.test.mjs +0 -91
- package/src/types/gap-report.d.ts +0 -29
- package/templates/blocks/components/TreeListBranches/TreeListBranchesShowcase.doc.mjs +0 -14
- package/templates/blocks/components/TreeListBranches/TreeListBranchesShowcase.tsx +0 -64
- package/templates/blocks/components/TreeListItem/TreeListItemShowcase.doc.mjs +0 -14
- package/templates/blocks/components/TreeListItem/TreeListItemShowcase.tsx +0 -60
- /package/src/codemods/transforms/{v0.0.15 → v0.1.0}/__tests__/drop-xds-prefix-imports.test.mjs +0 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file Upgrade integration error-policy + --skip-codemod tests.
|
|
5
|
+
*
|
|
6
|
+
* These scaffold a real consumer project (astryx.config.mjs + an installed
|
|
7
|
+
* integration package with codemods) under a REPO-LOCAL temp dir so Vite
|
|
8
|
+
* permits dynamic import of the config/integration modules (it blocks /tmp).
|
|
9
|
+
* They assert:
|
|
10
|
+
* - a broken integration codemod definition is SKIPPED (warned), not a hard
|
|
11
|
+
* fail of the upgrade (reverses the previous policy);
|
|
12
|
+
* - --skip-codemod excludes a named integration codemod.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import {describe, it, expect, beforeEach, afterEach, vi} from 'vitest';
|
|
16
|
+
import * as fs from 'node:fs';
|
|
17
|
+
import * as path from 'node:path';
|
|
18
|
+
import {pathToFileURL} from 'node:url';
|
|
19
|
+
import {Command} from 'commander';
|
|
20
|
+
import {registerUpgrade} from './upgrade.mjs';
|
|
21
|
+
|
|
22
|
+
let tmpDir;
|
|
23
|
+
let originalCwd;
|
|
24
|
+
let logCalls;
|
|
25
|
+
let errCalls;
|
|
26
|
+
let exitCode;
|
|
27
|
+
|
|
28
|
+
const codemodModuleUrl = pathToFileURL(
|
|
29
|
+
path.resolve(process.cwd(), 'packages/cli/src/codemod.mjs'),
|
|
30
|
+
).href;
|
|
31
|
+
|
|
32
|
+
beforeEach(() => {
|
|
33
|
+
originalCwd = process.cwd();
|
|
34
|
+
// Repo-local temp dir: under cwd so Vite allows config/integration imports.
|
|
35
|
+
tmpDir = fs.mkdtempSync(path.join(process.cwd(), '.astryx-upgrade-policy-'));
|
|
36
|
+
process.chdir(tmpDir);
|
|
37
|
+
logCalls = [];
|
|
38
|
+
errCalls = [];
|
|
39
|
+
exitCode = undefined;
|
|
40
|
+
vi.spyOn(console, 'log').mockImplementation((...a) => logCalls.push(a.join(' ')));
|
|
41
|
+
vi.spyOn(console, 'error').mockImplementation((...a) => errCalls.push(a.join(' ')));
|
|
42
|
+
vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
43
|
+
vi.spyOn(process, 'exit').mockImplementation(code => {
|
|
44
|
+
exitCode = code;
|
|
45
|
+
throw new Error(`__exit ${code}`);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
afterEach(() => {
|
|
50
|
+
process.chdir(originalCwd);
|
|
51
|
+
fs.rmSync(tmpDir, {recursive: true, force: true});
|
|
52
|
+
vi.restoreAllMocks();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
function writeInstalledCore(version) {
|
|
56
|
+
const dir = path.join(tmpDir, 'node_modules', '@astryxdesign', 'core');
|
|
57
|
+
fs.mkdirSync(dir, {recursive: true});
|
|
58
|
+
fs.writeFileSync(
|
|
59
|
+
path.join(dir, 'package.json'),
|
|
60
|
+
JSON.stringify({name: '@astryxdesign/core', version}),
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function writeSource() {
|
|
65
|
+
fs.mkdirSync(path.join(tmpDir, 'src'), {recursive: true});
|
|
66
|
+
fs.writeFileSync(path.join(tmpDir, 'src', 'index.ts'), 'const foo = 1;\n');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Scaffold a consumer + an installed integration package with codemods.
|
|
71
|
+
* @param {Object<string,string>} codemodFiles "<version>/<id>.mjs" -> body
|
|
72
|
+
*/
|
|
73
|
+
function scaffoldIntegration(codemodFiles) {
|
|
74
|
+
fs.writeFileSync(
|
|
75
|
+
path.join(tmpDir, 'package.json'),
|
|
76
|
+
JSON.stringify({name: 'consumer'}),
|
|
77
|
+
);
|
|
78
|
+
fs.writeFileSync(
|
|
79
|
+
path.join(tmpDir, 'astryx.config.mjs'),
|
|
80
|
+
`export default { integrations: ['@acme/widgets'] };\n`,
|
|
81
|
+
);
|
|
82
|
+
const pkgDir = path.join(tmpDir, 'node_modules', '@acme', 'widgets');
|
|
83
|
+
fs.mkdirSync(pkgDir, {recursive: true});
|
|
84
|
+
fs.writeFileSync(
|
|
85
|
+
path.join(pkgDir, 'package.json'),
|
|
86
|
+
JSON.stringify({name: '@acme/widgets', version: '1.0.0'}),
|
|
87
|
+
);
|
|
88
|
+
fs.writeFileSync(
|
|
89
|
+
path.join(pkgDir, 'astryx.integration.mjs'),
|
|
90
|
+
`export default { codemods: './codemods' };\n`,
|
|
91
|
+
);
|
|
92
|
+
for (const [rel, body] of Object.entries(codemodFiles)) {
|
|
93
|
+
const full = path.join(pkgDir, 'codemods', rel);
|
|
94
|
+
fs.mkdirSync(path.dirname(full), {recursive: true});
|
|
95
|
+
fs.writeFileSync(full, body);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function createProgram() {
|
|
100
|
+
const program = new Command();
|
|
101
|
+
program.exitOverride();
|
|
102
|
+
program.option('--json', 'Output as typed JSON');
|
|
103
|
+
registerUpgrade(program);
|
|
104
|
+
return program;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async function runJson(args) {
|
|
108
|
+
const program = createProgram();
|
|
109
|
+
try {
|
|
110
|
+
await program.parseAsync(['node', 'astryx', ...args]);
|
|
111
|
+
} catch (err) {
|
|
112
|
+
if (!String(err?.message || '').startsWith('__exit')) throw err;
|
|
113
|
+
}
|
|
114
|
+
for (let i = logCalls.length - 1; i >= 0; i--) {
|
|
115
|
+
const line = logCalls[i];
|
|
116
|
+
if (line.startsWith('{')) {
|
|
117
|
+
try {
|
|
118
|
+
return JSON.parse(line);
|
|
119
|
+
} catch {
|
|
120
|
+
// keep looking
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
describe('upgrade integration error policy (skip + warn)', () => {
|
|
128
|
+
it('SKIPS a broken integration codemod instead of hard-failing the upgrade', async () => {
|
|
129
|
+
// A codemod module whose default export is not a valid codemod result —
|
|
130
|
+
// a DEFINITION error. The upgrade must NOT abort; it skips the broken
|
|
131
|
+
// integration's codemods and completes.
|
|
132
|
+
scaffoldIntegration({
|
|
133
|
+
'0.2.0/bad.mjs': `export default { not: 'a codemod' };\n`,
|
|
134
|
+
});
|
|
135
|
+
writeInstalledCore('0.2.0');
|
|
136
|
+
writeSource();
|
|
137
|
+
|
|
138
|
+
const result = await runJson([
|
|
139
|
+
'--json',
|
|
140
|
+
'upgrade',
|
|
141
|
+
'--from',
|
|
142
|
+
'0.1.0',
|
|
143
|
+
'--path',
|
|
144
|
+
'src',
|
|
145
|
+
]);
|
|
146
|
+
|
|
147
|
+
// Did NOT hard-fail: no error envelope, and it ran to a status/run result.
|
|
148
|
+
expect(result).not.toBeNull();
|
|
149
|
+
expect(result.error).toBeUndefined();
|
|
150
|
+
expect(exitCode).not.toBe(1);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it('runs a healthy integration codemod for an applicable range', async () => {
|
|
154
|
+
scaffoldIntegration({
|
|
155
|
+
'0.2.0/drop-foo.mjs':
|
|
156
|
+
`import {createCodemod} from ${JSON.stringify(codemodModuleUrl)};\n` +
|
|
157
|
+
`export default createCodemod({ title: 'Drop foo', transform: (file) => file.source.replace(/foo/g, 'bar') });\n`,
|
|
158
|
+
});
|
|
159
|
+
writeInstalledCore('0.2.0');
|
|
160
|
+
writeSource();
|
|
161
|
+
|
|
162
|
+
const result = await runJson([
|
|
163
|
+
'--json',
|
|
164
|
+
'upgrade',
|
|
165
|
+
'--from',
|
|
166
|
+
'0.1.0',
|
|
167
|
+
'--path',
|
|
168
|
+
'src',
|
|
169
|
+
'--apply',
|
|
170
|
+
]);
|
|
171
|
+
expect(result).not.toBeNull();
|
|
172
|
+
expect(result.error).toBeUndefined();
|
|
173
|
+
// The codemod rewrote foo -> bar.
|
|
174
|
+
const out = fs.readFileSync(path.join(tmpDir, 'src', 'index.ts'), 'utf-8');
|
|
175
|
+
expect(out).toContain('bar');
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it('--skip-codemod excludes a named integration codemod', async () => {
|
|
179
|
+
scaffoldIntegration({
|
|
180
|
+
'0.2.0/drop-foo.mjs':
|
|
181
|
+
`import {createCodemod} from ${JSON.stringify(codemodModuleUrl)};\n` +
|
|
182
|
+
`export default createCodemod({ title: 'Drop foo', transform: (file) => file.source.replace(/foo/g, 'bar') });\n`,
|
|
183
|
+
});
|
|
184
|
+
writeInstalledCore('0.2.0');
|
|
185
|
+
writeSource();
|
|
186
|
+
|
|
187
|
+
const result = await runJson([
|
|
188
|
+
'--json',
|
|
189
|
+
'upgrade',
|
|
190
|
+
'--from',
|
|
191
|
+
'0.1.0',
|
|
192
|
+
'--path',
|
|
193
|
+
'src',
|
|
194
|
+
'--apply',
|
|
195
|
+
'--skip-codemod',
|
|
196
|
+
'drop-foo',
|
|
197
|
+
]);
|
|
198
|
+
expect(result).not.toBeNull();
|
|
199
|
+
// Skipped: the source is unchanged (foo not rewritten to bar).
|
|
200
|
+
const out = fs.readFileSync(path.join(tmpDir, 'src', 'index.ts'), 'utf-8');
|
|
201
|
+
expect(out).toContain('foo');
|
|
202
|
+
expect(out).not.toContain('bar');
|
|
203
|
+
});
|
|
204
|
+
});
|