@astryxdesign/cli 0.7.2-canary.fe2c655 → 0.7.2
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 +119 -0
- package/README.md +175 -154
- package/api/build/_adapter.d.mts +8 -0
- package/api/build/_adapter.mjs +12 -1
- package/api/build/build.doc.mjs +4 -0
- package/api/build/help/help.mjs +1 -1
- package/api/build/kit/kit.mjs +3 -11
- package/api/component/_adapter.d.mts +72 -1
- package/api/component/_adapter.mjs +212 -18
- package/api/component/component.doc.mjs +6 -1
- package/api/component/component.mjs +82 -15
- package/api/component/component.test.mjs +80 -0
- package/api/component/doc-links.test.mjs +386 -0
- package/api/component/integration-export-name.test.mjs +644 -0
- package/api/component/list/list.mjs +42 -4
- package/api/discover/_adapter.d.mts +132 -12
- package/api/discover/_adapter.mjs +488 -27
- package/api/discover/_adapter.test.mjs +599 -17
- package/api/discover/_catalog-view.d.mts +16 -5
- package/api/discover/_catalog-view.mjs +32 -8
- package/api/discover/detail/doc/doc.mjs +9 -1
- package/api/discover/discover.d.mts +11 -0
- package/api/discover/discover.doc.mjs +9 -7
- package/api/discover/discover.mjs +121 -19
- package/api/discover/discover.type.d.mts +20 -7
- package/api/discover/discover.type.mjs +17 -7
- package/api/discover/list/list.d.mts +4 -3
- package/api/discover/list/list.mjs +17 -10
- package/api/docs/_adapter.d.mts +74 -0
- package/api/docs/_adapter.mjs +553 -16
- package/api/docs/docs.doc.mjs +2 -1
- package/api/docs/docs.mjs +2 -1
- package/api/docs/docs.test.mjs +5 -2
- package/api/docs/integration-tree.test.mjs +22 -0
- package/api/docs/integrationDocs.test.mjs +124 -0
- package/api/docs/list/list.mjs +12 -2
- package/api/docs/reference-blocks.test.mjs +1 -3
- package/api/doctor/_adapter.d.mts +108 -0
- package/api/doctor/_adapter.mjs +223 -4
- package/api/doctor/doctor.d.mts +199 -0
- package/api/doctor/doctor.doc.mjs +3 -2
- package/api/doctor/doctor.mjs +530 -34
- package/api/doctor/doctor.test.mjs +180 -14
- package/api/doctor/release-checks.test.mjs +156 -0
- package/api/doctor/theme-checks.mjs +17 -4
- package/api/doctor/theme-checks.test.mjs +223 -7
- package/api/error.d.mts +10 -0
- package/api/error.mjs +25 -0
- package/api/gap-report/gap-report.d.mts +3 -0
- package/api/gap-report/gap-report.doc.mjs +11 -3
- package/api/gap-report/gap-report.mjs +219 -52
- package/api/gap-report/gap-report.test.mjs +233 -0
- package/api/gap-report/gap-report.type.d.mts +41 -0
- package/api/gap-report/gap-report.type.mjs +18 -0
- package/api/hook/_adapter.mjs +3 -11
- package/api/hook/hook.doc.mjs +4 -0
- package/api/hook/list/list.d.mts +1 -1
- package/api/index.d.mts +2 -0
- package/api/index.mjs +2 -0
- package/api/init/_adapter.d.mts +22 -0
- package/api/init/_adapter.mjs +59 -0
- package/api/init/init.d.mts +7 -5
- package/api/init/init.doc.mjs +28 -7
- package/api/init/init.mjs +28 -4
- package/api/init/init.type.d.mts +48 -3
- package/api/init/init.type.mjs +37 -3
- package/api/init/run/run.d.mts +1 -1
- package/api/init/run/run.mjs +17 -6
- package/api/init/user/user.d.mts +14 -0
- package/api/init/user/user.mjs +87 -0
- package/api/init/user/user.test.mjs +232 -0
- package/api/integration/_adapter.d.mts +45 -0
- package/api/integration/_adapter.mjs +112 -0
- package/api/integration/add-contribution.component-names.test.mjs +66 -0
- package/api/integration/add-contribution.mjs +8 -4
- package/api/integration/add-contribution.test.mjs +4 -2
- package/api/integration/authoring-checks.mjs +110 -6
- package/api/integration/authoring-checks.test.mjs +808 -0
- package/api/integration/authoring-checks.type.d.mts +143 -0
- package/api/integration/authoring-checks.type.mjs +74 -2
- package/api/integration/check/check.d.mts +96 -0
- package/api/integration/check/check.mjs +357 -0
- package/api/integration/check/check.test.mjs +489 -0
- package/api/integration/integration-check.type.d.mts +118 -0
- package/api/integration/integration-check.type.mjs +84 -0
- package/api/integration/integrationCheck.doc.d.mts +10 -0
- package/api/integration/integrationCheck.doc.mjs +73 -0
- package/api/integration/integrationComponentConflicts.doc.mjs +45 -6
- package/api/integration/integrationDocConflicts.doc.mjs +22 -5
- package/api/integration/pack-check.mjs +364 -120
- package/api/integration/pack-check.test.mjs +730 -10
- package/api/integration/validate-integration-fixes.test.mjs +67 -0
- package/api/integration/validate-integration.d.mts +8 -0
- package/api/integration/validate-integration.mjs +63 -9
- package/api/integration/validate-integration.test.mjs +88 -8
- package/api/integration/validate-integration.type.d.mts +16 -0
- package/api/integration/validate-integration.type.mjs +14 -1
- package/api/integration/validate-unread-theme-folders.test.mjs +3 -2
- package/api/integration/validateIntegration.doc.mjs +19 -3
- package/api/search/_adapter.d.mts +11 -0
- package/api/search/_adapter.mjs +25 -0
- package/api/search/search.d.mts +82 -13
- package/api/search/search.doc.mjs +8 -3
- package/api/search/search.domain-priority.test.mjs +108 -18
- package/api/search/search.integration-check.test.mjs +24 -0
- package/api/search/search.mjs +645 -64
- package/api/search/search.test.mjs +179 -1
- package/api/search/search.type.d.mts +14 -1
- package/api/search/search.type.mjs +6 -1
- package/api/swizzle/_adapter.mjs +2 -2
- package/api/swizzle/copy/copy.mjs +29 -15
- package/api/template/template-integration.test.mjs +1 -1
- package/api/template/template.test.mjs +120 -3
- package/api/theme/_adapter.d.mts +16 -0
- package/api/theme/_adapter.mjs +32 -5
- package/api/theme/build/build.d.mts +2 -1
- package/api/theme/build/build.family.test.mjs +64 -0
- package/api/theme/build/build.mjs +250 -38
- package/api/theme/build/build.packed-old-core.test.mjs +20 -3
- package/api/theme/build/font-warning.mjs +5 -3
- package/api/theme/build/font-warning.test.mjs +2 -1
- package/api/theme/remove/remove.test.mjs +2 -2
- package/api/theme/targets/targets.mjs +3 -10
- package/api/theme/themeBuild.doc.mjs +4 -4
- package/api/theme/themeTargets.doc.mjs +4 -0
- package/api/theme/use/use.test.mjs +1 -1
- package/api/upgrade/_adapter.d.mts +40 -2
- package/api/upgrade/_adapter.mjs +118 -5
- package/api/upgrade/run/cli-behind-core.test.mjs +438 -0
- package/api/upgrade/run/run.mjs +35 -2
- package/api/upgrade/status/status.d.mts +21 -5
- package/api/upgrade/status/status.mjs +45 -8
- package/api/upgrade/upgrade.doc.mjs +6 -3
- package/api/upgrade/upgrade.mjs +5 -1
- package/api/upgrade/upgrade.type.d.mts +23 -0
- package/api/upgrade/upgrade.type.mjs +16 -1
- package/assets/codemods/__tests__/registry.test.mjs +1 -0
- package/assets/codemods/registry.mjs +1 -0
- package/assets/codemods/runner.mjs +7 -1
- package/assets/codemods/transforms/v0.7.2/__tests__/migrate-list-edge-compensation-to-edge.test.mjs +120 -0
- package/assets/codemods/transforms/v0.7.2/index.mjs +20 -0
- package/assets/codemods/transforms/v0.7.2/migrate-list-edge-compensation-to-edge.mjs +198 -0
- package/assets/discover/official-packages.json +367 -0
- package/assets/docs/README.md +10 -0
- package/assets/docs/author-a-theme.doc.mjs +3 -3
- package/assets/docs/browser-support.doc.mjs +1 -1
- package/assets/docs/getting-started.doc.mjs +26 -6
- package/assets/docs/styling-overview.doc.mjs +1 -1
- package/assets/docs/theme.doc.dense.mjs +1 -1
- package/assets/docs/theme.doc.mjs +2 -2
- package/assets/docs/theme.doc.zh.mjs +1 -1
- package/assets/docs/tree/add-a-component.doc.mjs +22 -2
- package/assets/docs/tree/add-a-theme.doc.mjs +13 -3
- package/assets/docs/tree/add-a-topic.doc.mjs +54 -9
- package/assets/docs/tree/agent-guidance.doc.mjs +19 -5
- package/assets/docs/tree/block-template.doc.mjs +8 -20
- package/assets/docs/tree/build-the-template.doc.mjs +1 -1
- package/assets/docs/tree/building-blocks.doc.mjs +4 -0
- package/assets/docs/tree/check-the-props.doc.mjs +201 -0
- package/assets/docs/tree/check-your-docs.doc.mjs +69 -11
- package/assets/docs/tree/checks.doc.mjs +32 -24
- package/assets/docs/tree/ci-and-containers.doc.mjs +88 -0
- package/assets/docs/tree/cli-command.doc.mjs +142 -0
- package/assets/docs/tree/cli.doc.mjs +6 -0
- package/assets/docs/tree/codemods.doc.mjs +17 -7
- package/assets/docs/tree/commands.doc.mjs +7 -1
- package/assets/docs/tree/component-family.doc.mjs +8 -6
- package/assets/docs/tree/component-imports.doc.mjs +21 -3
- package/assets/docs/tree/components.doc.mjs +7 -1
- package/assets/docs/tree/computer-agent-guide.doc.mjs +160 -0
- package/assets/docs/tree/computer-integrations.doc.mjs +93 -0
- package/assets/docs/tree/configuration.doc.mjs +7 -3
- package/assets/docs/tree/debug-and-gap-reports.doc.mjs +41 -22
- package/assets/docs/tree/define-the-theme.doc.mjs +6 -5
- package/assets/docs/tree/describe-the-component.doc.mjs +3 -3
- package/assets/docs/tree/docs.doc.mjs +9 -3
- package/assets/docs/tree/document-the-template.doc.mjs +1 -1
- package/assets/docs/tree/document-the-theme.doc.mjs +3 -3
- package/assets/docs/tree/export-template-assets.doc.mjs +1 -1
- package/assets/docs/tree/extend-or-replace.doc.mjs +19 -9
- package/assets/docs/tree/fonts-and-assets.doc.mjs +2 -2
- package/assets/docs/tree/generate-a-palette.doc.mjs +7 -5
- package/assets/docs/tree/global-integrations.doc.mjs +124 -0
- package/assets/docs/tree/global.doc.mjs +131 -0
- package/assets/docs/tree/grade-template-with-agent.doc.mjs +5 -5
- package/assets/docs/tree/install-once.doc.mjs +105 -0
- package/assets/docs/tree/integrations.doc.mjs +13 -1
- package/assets/docs/tree/layout-spacing.doc.mjs +2 -3
- package/assets/docs/tree/layout.doc.mjs +6 -6
- package/assets/docs/tree/links.doc.mjs +7 -6
- package/assets/docs/tree/migration-setup.doc.mjs +3 -2
- package/assets/docs/tree/migration-verification.doc.mjs +0 -1
- package/assets/docs/tree/migration.doc.mjs +0 -1
- package/assets/docs/tree/monorepos.doc.mjs +84 -0
- package/assets/docs/tree/package-and-test.doc.mjs +1 -1
- package/assets/docs/tree/page-template.doc.mjs +4 -8
- package/assets/docs/tree/problems.doc.mjs +205 -0
- package/assets/docs/tree/project-global-or-both.doc.mjs +131 -0
- package/assets/docs/tree/publishing.doc.mjs +6 -6
- package/assets/docs/tree/quick-start.doc.mjs +53 -27
- package/assets/docs/tree/reference.doc.mjs +192 -0
- package/assets/docs/tree/replace-a-core-component.doc.mjs +15 -7
- package/assets/docs/tree/replace-a-core-template.doc.mjs +10 -12
- package/assets/docs/tree/scaffold.doc.mjs +1 -1
- package/assets/docs/tree/sections-and-placement.doc.mjs +9 -11
- package/assets/docs/tree/see-it-in-an-app.doc.mjs +17 -5
- package/assets/docs/tree/short-and-findable.doc.mjs +9 -8
- package/assets/docs/tree/single-component.doc.mjs +15 -6
- package/assets/docs/tree/start-a-template.doc.mjs +18 -8
- package/assets/docs/tree/subcomponent.doc.mjs +6 -6
- package/assets/docs/tree/template-assets.doc.mjs +2 -2
- package/assets/docs/tree/template-doc-overview.doc.mjs +6 -17
- package/assets/docs/tree/template-fonts.doc.mjs +1 -1
- package/assets/docs/tree/template-icons.doc.mjs +1 -1
- package/assets/docs/tree/template-images-media.doc.mjs +1 -1
- package/assets/docs/tree/template-styles.doc.mjs +2 -2
- package/assets/docs/tree/templates.doc.mjs +7 -1
- package/assets/docs/tree/test-in-an-app.doc.mjs +7 -7
- package/assets/docs/tree/test-template-in-app.doc.mjs +5 -5
- package/assets/docs/tree/themes.doc.mjs +4 -0
- package/assets/docs/tree/tokens-and-setup.doc.mjs +19 -15
- package/assets/docs/tree/troubleshooting.doc.mjs +29 -13
- package/assets/docs/tree/type-scale.doc.mjs +3 -3
- package/assets/docs/tree/uninstall.doc.mjs +109 -0
- package/assets/docs/tree/updates.doc.mjs +92 -0
- package/assets/docs/tree/upgrading.doc.mjs +6 -6
- package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +14 -2
- package/assets/docs/tree/verify-packed-template.doc.mjs +3 -3
- package/assets/docs/tree/versioning.doc.mjs +10 -9
- package/assets/docs/tree/who-answers.doc.mjs +119 -0
- package/assets/docs/tree/write-the-template-file.doc.mjs +7 -6
- package/assets/docs/use-a-theme.doc.mjs +2 -2
- package/assets/docs/working-with-ai.doc.mjs +66 -13
- package/assets/theme.template.ts +1 -1
- package/authoring/codemod/codemod.doc.mjs +7 -3
- package/authoring/config/config.doc.mjs +9 -6
- package/authoring/config/type.ts +4 -2
- package/authoring/debug/parse.d.mts +5 -5
- package/authoring/discover/discover.doc.mjs +7 -1
- package/authoring/doctypes/_schema.d.mts +8 -3
- package/authoring/doctypes/_schema.mjs +1 -0
- package/authoring/doctypes/base/graph-fields.doc.mjs +6 -4
- package/authoring/doctypes/command/command.doc.mjs +20 -12
- package/authoring/doctypes/command/type.ts +14 -0
- package/authoring/doctypes/component/component.doc.mjs +30 -27
- package/authoring/doctypes/component/type.ts +21 -8
- package/authoring/doctypes/enum/enum.doc.mjs +7 -4
- package/authoring/doctypes/function/function.doc.mjs +9 -8
- package/authoring/doctypes/hook/hook.doc.mjs +5 -4
- package/authoring/doctypes/hook/type.ts +4 -0
- package/authoring/doctypes/namespace/namespace.doc.mjs +7 -6
- package/authoring/doctypes/reference/reference.doc.mjs +12 -11
- package/authoring/doctypes/schema/schema.doc.mjs +9 -9
- package/authoring/doctypes/template/integration-template.doc.d.mts +11 -0
- package/authoring/doctypes/template/integration-template.doc.mjs +49 -0
- package/authoring/doctypes/template/parse.d.mts +6 -2
- package/authoring/doctypes/template/parse.mjs +3 -1
- package/authoring/doctypes/template/template.doc.mjs +3 -3
- package/authoring/doctypes/template/type.ts +22 -0
- package/authoring/doctypes/theme/theme.doc.mjs +2 -2
- package/authoring/gap-report/gap-report.doc.mjs +2 -2
- package/authoring/identity/identity.doc.mjs +3 -3
- package/authoring/index.d.ts +2 -0
- package/authoring/integration/integration.doc.mjs +30 -6
- package/authoring/integration/parse.test.mjs +21 -0
- package/authoring/integration/schema.d.mts +16 -3
- package/authoring/integration/schema.mjs +34 -2
- package/authoring/integration/type.ts +12 -0
- package/clients/cli/bin/astryx.mjs +20 -3
- package/clients/cli/cli-command.test.mjs +166 -0
- package/clients/cli/commands/blog.doc.mjs +1 -0
- package/clients/cli/commands/build-theme.batch-report.test.mjs +17 -3
- package/clients/cli/commands/build-theme.font-warning.test.mjs +3 -3
- package/clients/cli/commands/build-theme.mjs +26 -13
- package/clients/cli/commands/build-theme.path-safety.test.mjs +224 -6
- package/clients/cli/commands/build-theme.registry.test.mjs +5 -2
- package/clients/cli/commands/build.doc.mjs +1 -0
- package/clients/cli/commands/build.exit-codes-doc.test.mjs +4 -0
- package/clients/cli/commands/cli-postinstall.test.mjs +49 -1
- package/clients/cli/commands/component.doc.mjs +1 -0
- package/clients/cli/commands/discover.broken-integration.test.mjs +11 -7
- package/clients/cli/commands/discover.doc.mjs +9 -1
- package/clients/cli/commands/discover.mjs +144 -93
- package/clients/cli/commands/discover.no-source.test.mjs +448 -33
- package/clients/cli/commands/discover.sources.test.mjs +20 -1
- package/clients/cli/commands/docs.doc.mjs +1 -0
- package/clients/cli/commands/docs.mjs +49 -19
- package/clients/cli/commands/docs.test.mjs +2 -2
- package/clients/cli/commands/doctor-integration-components.doc.mjs +19 -4
- package/clients/cli/commands/doctor-integration-docs.doc.mjs +20 -5
- package/clients/cli/commands/doctor-integration-templates.doc.mjs +1 -0
- package/clients/cli/commands/doctor-integration-validate.doc.mjs +22 -2
- package/clients/cli/commands/doctor-integration.test.mjs +888 -3
- package/clients/cli/commands/doctor.doc.mjs +12 -2
- package/clients/cli/commands/doctor.mjs +292 -7
- package/clients/cli/commands/doctor.test.mjs +10 -4
- package/clients/cli/commands/gap-report.doc.mjs +15 -2
- package/clients/cli/commands/gap-report.mjs +24 -2
- package/clients/cli/commands/gap-report.test.mjs +79 -0
- package/clients/cli/commands/hook.doc.mjs +1 -0
- package/clients/cli/commands/init.behavior.test.mjs +5 -0
- package/clients/cli/commands/init.doc.mjs +29 -3
- package/clients/cli/commands/integration-add.doc.mjs +7 -0
- package/clients/cli/commands/integration-authoring.test.mjs +49 -3
- package/clients/cli/commands/integration-check.doc.mjs +93 -0
- package/clients/cli/commands/integration-check.test.mjs +441 -0
- package/clients/cli/commands/integration-pack.doc.mjs +8 -1
- package/clients/cli/commands/integration-verify.doc.mjs +8 -1
- package/clients/cli/commands/integration.doc.mjs +6 -2
- package/clients/cli/commands/integration.mjs +119 -7
- package/clients/cli/commands/json-contract.test.mjs +11 -2
- package/clients/cli/commands/manifest.doc.mjs +1 -0
- package/clients/cli/commands/outside-project.test.mjs +774 -0
- package/clients/cli/commands/search.doc.mjs +1 -0
- package/clients/cli/commands/search.mjs +16 -11
- package/clients/cli/commands/search.test.mjs +429 -296
- package/clients/cli/commands/setup-nudge.test.mjs +102 -2
- package/clients/cli/commands/swizzle.doc.mjs +7 -0
- package/clients/cli/commands/swizzle.mjs +5 -3
- package/clients/cli/commands/swizzle.routing.test.mjs +19 -2
- package/clients/cli/commands/template.doc.mjs +1 -0
- package/clients/cli/commands/text-json-parity.test.mjs +5 -0
- package/clients/cli/commands/theme-add-lifecycle.test.mjs +3 -3
- package/clients/cli/commands/theme-add.doc.mjs +8 -1
- package/clients/cli/commands/theme-build.doc.mjs +3 -2
- package/clients/cli/commands/theme-eject.doc.mjs +1 -0
- package/clients/cli/commands/theme-list.behavior.test.mjs +6 -0
- package/clients/cli/commands/theme-list.doc.mjs +1 -0
- package/clients/cli/commands/theme-palette-generate.doc.mjs +1 -0
- package/clients/cli/commands/theme-remove.doc.mjs +7 -0
- package/clients/cli/commands/theme-targets.doc.mjs +1 -0
- package/clients/cli/commands/theme-template.doc.mjs +1 -0
- package/clients/cli/commands/theme-use.doc.mjs +7 -0
- package/clients/cli/commands/upgrade.config-ordering.test.mjs +2 -1
- package/clients/cli/commands/upgrade.doc.mjs +22 -1
- package/clients/cli/commands/upgrade.file-protection.test.mjs +3 -2
- package/clients/cli/commands/upgrade.hook-output.test.mjs +2 -1
- package/clients/cli/commands/upgrade.older-cli.test.mjs +160 -0
- package/clients/cli/index.mjs +112 -16
- package/clients/cli/lib/cli-error.mjs +4 -1
- package/clients/cli/lib/component-format.test.mjs +1 -1
- package/clients/cli/lib/define-command.mjs +2 -2
- package/clients/cli/lib/json-shim.mjs +3 -1
- package/clients/cli/lib/manifest.d.ts +9 -0
- package/clients/cli/lib/manifest.mjs +17 -1
- package/clients/cli/lib/manifest.test.mjs +25 -0
- package/foundation/agent-docs/agent-doc-state.d.mts +35 -6
- package/foundation/agent-docs/agent-doc-state.mjs +66 -6
- package/foundation/agent-docs/agent-docs.d.mts +4 -3
- package/foundation/agent-docs/agent-docs.mjs +11 -9
- package/foundation/agent-docs/computer-agent-text.d.mts +133 -0
- package/foundation/agent-docs/computer-agent-text.mjs +623 -0
- package/foundation/agent-docs/computer-agent-text.test.mjs +602 -0
- package/foundation/config/project.d.mts +35 -3
- package/foundation/config/project.mjs +226 -7
- package/foundation/config/project.test.mjs +66 -0
- package/foundation/config/theme-state.mjs +5 -4
- package/foundation/discovery/authoring-self-docs.mjs +2 -1
- package/foundation/discovery/cli-self-docs.mjs +20 -3
- package/foundation/discovery/cli-self-docs.test.mjs +3 -2
- package/foundation/discovery/component-discovery.d.mts +190 -10
- package/foundation/discovery/component-discovery.export-names.test.mjs +760 -0
- package/foundation/discovery/component-discovery.mjs +864 -56
- package/foundation/discovery/component-discovery.test.mjs +96 -0
- package/foundation/discovery/component-replacement.mjs +20 -1
- package/foundation/discovery/component-replacement.test.mjs +40 -0
- package/foundation/discovery/copied-passages.d.mts +216 -0
- package/foundation/discovery/copied-passages.mjs +720 -0
- package/foundation/discovery/copied-passages.test.mjs +124 -0
- package/foundation/discovery/doc-consistency.d.mts +34 -0
- package/foundation/discovery/doc-consistency.mjs +513 -0
- package/foundation/discovery/doc-consistency.test.mjs +347 -0
- package/foundation/discovery/doc-fluff.d.mts +112 -0
- package/foundation/discovery/doc-fluff.mjs +328 -0
- package/foundation/discovery/doc-fluff.test.mjs +142 -0
- package/foundation/discovery/doc-types.d.mts +157 -0
- package/foundation/discovery/doc-types.mjs +1231 -0
- package/foundation/discovery/doc-types.test.mjs +744 -0
- package/foundation/discovery/docs-discovery.d.mts +88 -0
- package/foundation/discovery/docs-discovery.mjs +83 -2
- package/foundation/discovery/integration-doc-files.d.mts +22 -0
- package/foundation/discovery/integration-doc-files.mjs +231 -0
- package/foundation/discovery/integration-doc-files.test.mjs +246 -0
- package/foundation/discovery/module-exports.d.mts +27 -0
- package/foundation/discovery/module-exports.mjs +356 -31
- package/foundation/discovery/module-exports.test.mjs +172 -0
- package/foundation/discovery/package-tsconfig.d.mts +14 -0
- package/foundation/discovery/package-tsconfig.mjs +228 -0
- package/foundation/discovery/package-tsconfig.test.mjs +210 -0
- package/foundation/discovery/project-typescript.d.mts +32 -0
- package/foundation/discovery/project-typescript.mjs +89 -0
- package/foundation/discovery/prop-drift.d.mts +297 -0
- package/foundation/discovery/prop-drift.mjs +2428 -0
- package/foundation/discovery/prop-drift.test.mjs +2337 -0
- package/foundation/discovery/runner-allowlist.d.mts +40 -0
- package/foundation/discovery/runner-allowlist.mjs +53 -0
- package/foundation/discovery/stray-pointers.d.mts +52 -0
- package/foundation/discovery/stray-pointers.mjs +293 -0
- package/foundation/discovery/stray-pointers.test.mjs +86 -0
- package/foundation/discovery/template-adapter.mjs +74 -5
- package/foundation/discovery/template-needs.mjs +5 -2
- package/foundation/discovery/theme-imports.mjs +8 -4
- package/foundation/discovery/theme-imports.test.mjs +1 -1
- package/foundation/discovery/type-match.d.mts +53 -0
- package/foundation/discovery/type-match.mjs +660 -0
- package/foundation/discovery/type-match.test.mjs +169 -0
- package/foundation/discovery/type-text.d.mts +68 -0
- package/foundation/discovery/type-text.mjs +658 -0
- package/foundation/discovery/type-text.test.mjs +196 -0
- package/foundation/discovery/unresolved-references.d.mts +62 -0
- package/foundation/discovery/unresolved-references.mjs +790 -0
- package/foundation/discovery/unresolved-references.test.mjs +567 -0
- package/foundation/doc-compiler/doc-loads.test.mjs +51 -1
- package/foundation/doc-compiler/inputs.mjs +27 -1
- package/foundation/doc-compiler/inputs.test.mjs +0 -1
- package/foundation/doc-compiler/links.d.mts +41 -5
- package/foundation/doc-compiler/links.mjs +167 -28
- package/foundation/doc-compiler/links.test.mjs +97 -4
- package/foundation/doc-compiler/read.d.mts +1 -1
- package/foundation/doc-compiler/tree.mjs +30 -1
- package/foundation/doc-compiler/tree.test.mjs +8 -1
- package/foundation/env/cli-command.d.mts +83 -0
- package/foundation/env/cli-command.mjs +152 -0
- package/foundation/env/cli-command.test.mjs +129 -0
- package/foundation/env/node-version.test.mjs +15 -3
- package/foundation/env/package-manager.d.mts +93 -9
- package/foundation/env/package-manager.global.test.mjs +66 -0
- package/foundation/env/package-manager.mjs +184 -13
- package/foundation/env/package-manager.test.mjs +341 -15
- package/foundation/env/project-scope.d.mts +9 -0
- package/foundation/env/project-scope.mjs +33 -0
- package/foundation/env/search-path.d.mts +42 -0
- package/foundation/env/search-path.mjs +205 -0
- package/foundation/env/search-path.test.mjs +122 -0
- package/foundation/env/user-dirs.d.mts +39 -0
- package/foundation/env/user-dirs.mjs +93 -0
- package/foundation/env/user-dirs.test.mjs +72 -0
- package/foundation/env/user-settings.d.mts +46 -0
- package/foundation/env/user-settings.mjs +106 -0
- package/foundation/env/user-settings.test.mjs +64 -0
- package/foundation/fs/file-protection.mjs +15 -1
- package/foundation/fs/module-loader.d.mts +2 -1
- package/foundation/fs/module-loader.mjs +60 -4
- package/foundation/fs/module-loader.stdout.test.mjs +3 -2
- package/foundation/fs/module-loader.test.mjs +194 -0
- package/foundation/fs/path-compare.d.mts +33 -0
- package/foundation/fs/path-compare.mjs +73 -0
- package/foundation/fs/paths.d.mts +57 -1
- package/foundation/fs/paths.mjs +131 -3
- package/foundation/fs/paths.test.mjs +10 -1
- package/foundation/integrations/computer-integrations.d.mts +78 -0
- package/foundation/integrations/computer-integrations.mjs +316 -0
- package/foundation/integrations/computer-integrations.test.mjs +292 -0
- package/foundation/integrations/contribution-inventory.d.mts +11 -0
- package/foundation/integrations/contribution-inventory.mjs +56 -3
- package/foundation/integrations/integration-warnings.mjs +3 -2
- package/foundation/integrations/integration-warnings.test.mjs +8 -9
- package/foundation/integrations/integrations.d.mts +25 -1
- package/foundation/integrations/integrations.mjs +46 -3
- package/foundation/integrations/issue.ts +6 -0
- package/foundation/integrations/validate-contributions.d.mts +2 -0
- package/foundation/integrations/validate-contributions.mjs +41 -1
- package/foundation/release/agent-text-worker.d.mts +4 -0
- package/foundation/release/agent-text-worker.mjs +52 -0
- package/foundation/release/cache.d.mts +310 -0
- package/foundation/release/cache.mjs +1216 -0
- package/foundation/release/cache.test.mjs +920 -0
- package/foundation/release/choose.d.mts +207 -0
- package/foundation/release/choose.mjs +677 -0
- package/foundation/release/choose.test.mjs +427 -0
- package/foundation/release/core-worker.d.mts +4 -0
- package/foundation/release/core-worker.mjs +38 -0
- package/foundation/release/global-state.d.mts +259 -0
- package/foundation/release/global-state.mjs +472 -0
- package/foundation/release/global-state.test.mjs +381 -0
- package/foundation/release/handoff.d.mts +60 -0
- package/foundation/release/handoff.e2e.test.mjs +278 -0
- package/foundation/release/handoff.mjs +357 -0
- package/foundation/release/lock-lease.d.mts +23 -0
- package/foundation/release/lock-lease.mjs +80 -0
- package/foundation/release/notices.d.mts +253 -0
- package/foundation/release/notices.mjs +596 -0
- package/foundation/release/notices.test.mjs +565 -0
- package/foundation/release/npm-guard.d.mts +4 -0
- package/foundation/release/npm-guard.mjs +126 -0
- package/foundation/release/project.d.mts +141 -0
- package/foundation/release/project.mjs +466 -0
- package/foundation/release/project.test.mjs +288 -0
- package/foundation/release/refresh-worker.d.mts +4 -0
- package/foundation/release/refresh-worker.mjs +27 -0
- package/foundation/release/run-context.d.mts +47 -0
- package/foundation/release/run-context.mjs +149 -0
- package/foundation/release/update-notice-env.d.mts +28 -0
- package/foundation/release/update-notice-env.mjs +39 -0
- package/foundation/response/base.d.ts +26 -3
- package/foundation/response/error-codes.d.mts +3 -1
- package/foundation/response/error-codes.doc.mjs +12 -0
- package/foundation/response/error-codes.mjs +17 -0
- package/foundation/response/error-codes.test.mjs +2 -0
- package/foundation/response/json-contract.test.mjs +7 -2
- package/foundation/response/json.mjs +4 -1
- package/foundation/response/response-types.doc.mjs +22 -11
- package/foundation/response/response-types.doc.test.mjs +46 -0
- package/foundation/response/response.doc.mjs +3 -3
- package/foundation/xle/browser-imports.test.mjs +74 -0
- package/foundation/xle/registry.mjs +4 -0
- package/foundation/xle/registry.test.mjs +28 -0
- package/package.json +11 -11
- package/scripts/postinstall.mjs +24 -5
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file Core codemods ship inside the CLI, so a CLI older than the installed
|
|
5
|
+
* Core has none for the releases after its own version. Every result past the
|
|
6
|
+
* up-to-date exit says so in `cliBehindCore`, with the same upgrade pinned to
|
|
7
|
+
* the CLI release that matches the Core; a CLI that covers the range returns
|
|
8
|
+
* what it always did. The pinned command changes to the folder the run used
|
|
9
|
+
* and names the directory it scanned as an absolute path, both with symbolic
|
|
10
|
+
* links resolved, so a POSIX shell runs it there, with every argument
|
|
11
|
+
* unchanged, wherever it is pasted, even when upgrade() reached the project
|
|
12
|
+
* through a link.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import {describe, it, expect, beforeEach, afterEach, vi} from 'vitest';
|
|
16
|
+
import {execFileSync, spawnSync} from 'node:child_process';
|
|
17
|
+
import * as fs from 'node:fs';
|
|
18
|
+
import * as os from 'node:os';
|
|
19
|
+
import * as path from 'node:path';
|
|
20
|
+
import {upgrade} from '../upgrade.mjs';
|
|
21
|
+
import {logCliBehindCore} from '../status/status.mjs';
|
|
22
|
+
import {logger} from '../../logger.mjs';
|
|
23
|
+
import {CLI_ROOT} from '../../../foundation/fs/paths.mjs';
|
|
24
|
+
import {
|
|
25
|
+
commandInFolder,
|
|
26
|
+
getDlxPrefix,
|
|
27
|
+
quoteCommandArgument,
|
|
28
|
+
} from '../../../foundation/env/package-manager.mjs';
|
|
29
|
+
|
|
30
|
+
const SLOW = 30_000;
|
|
31
|
+
|
|
32
|
+
const CLI_VERSION = JSON.parse(
|
|
33
|
+
fs.readFileSync(path.join(CLI_ROOT, 'package.json'), 'utf8'),
|
|
34
|
+
).version;
|
|
35
|
+
const [MAJOR, MINOR] = CLI_VERSION.split('.').map(Number);
|
|
36
|
+
/** A Core release after this CLI: it has no codemods for it. */
|
|
37
|
+
const NEWER_CORE = `${MAJOR}.${MINOR + 1}.0`;
|
|
38
|
+
|
|
39
|
+
/** A source file a 0.7.0 codemod rewrites (`emptySearchResultsText`). */
|
|
40
|
+
const TYPEAHEAD_SOURCE =
|
|
41
|
+
"import {Typeahead} from '@astryxdesign/core';\n" +
|
|
42
|
+
'export const x = <Typeahead emptySearchResultsText="None" />;\n';
|
|
43
|
+
|
|
44
|
+
let dir;
|
|
45
|
+
|
|
46
|
+
/** @param {string} version @param {string} [packageName] */
|
|
47
|
+
function installCore(version, packageName = '@astryxdesign/core') {
|
|
48
|
+
const core = path.join(dir, 'node_modules', ...packageName.split('/'));
|
|
49
|
+
fs.mkdirSync(core, {recursive: true});
|
|
50
|
+
fs.writeFileSync(
|
|
51
|
+
path.join(core, 'package.json'),
|
|
52
|
+
JSON.stringify({name: packageName, version}),
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** @param {string} rel @param {string} body */
|
|
57
|
+
function write(rel, body) {
|
|
58
|
+
const file = path.join(dir, rel);
|
|
59
|
+
fs.mkdirSync(path.dirname(file), {recursive: true});
|
|
60
|
+
fs.writeFileSync(file, body);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* A path in the project as a process running there sees it: every symbolic
|
|
65
|
+
* link resolved.
|
|
66
|
+
* @param {string} rel
|
|
67
|
+
*/
|
|
68
|
+
function inProject(rel) {
|
|
69
|
+
return path.join(fs.realpathSync(dir), rel);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* The pinned command for this project, as the CLI prints it.
|
|
74
|
+
* @param {...string} args the arguments after `upgrade`
|
|
75
|
+
*/
|
|
76
|
+
function pinned(...args) {
|
|
77
|
+
return commandInFolder(
|
|
78
|
+
fs.realpathSync(dir),
|
|
79
|
+
[
|
|
80
|
+
getDlxPrefix(dir),
|
|
81
|
+
`@astryxdesign/cli@${NEWER_CORE}`,
|
|
82
|
+
'upgrade',
|
|
83
|
+
...args.map(arg => quoteCommandArgument(arg)),
|
|
84
|
+
].join(' '),
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Stand-ins for the package runners: each prints the folder it runs in and the
|
|
90
|
+
* arguments the shell passed.
|
|
91
|
+
*/
|
|
92
|
+
const RUNNERS = ['npx', 'pnpm', 'yarn', 'bunx']
|
|
93
|
+
.map(
|
|
94
|
+
name =>
|
|
95
|
+
`${name}() { "$0" -e 'process.stdout.write(JSON.stringify({cwd: process.cwd(), argv: process.argv.slice(1)}))' -- "$@"; }`,
|
|
96
|
+
)
|
|
97
|
+
.join('; ');
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* What a POSIX shell runs for `command` pasted in `cwd`: the folder the
|
|
101
|
+
* package runner ran in, and its arguments from the pinned CLI package on.
|
|
102
|
+
* @param {string} command
|
|
103
|
+
* @param {string} cwd the folder the command is pasted in
|
|
104
|
+
* @returns {{cwd: string, args: string[]}}
|
|
105
|
+
*/
|
|
106
|
+
function runInShell(command, cwd) {
|
|
107
|
+
const ran = JSON.parse(
|
|
108
|
+
execFileSync(
|
|
109
|
+
'/bin/sh',
|
|
110
|
+
['-c', `${RUNNERS}; ${command}`, process.execPath],
|
|
111
|
+
{
|
|
112
|
+
cwd,
|
|
113
|
+
encoding: 'utf8',
|
|
114
|
+
},
|
|
115
|
+
),
|
|
116
|
+
);
|
|
117
|
+
return {
|
|
118
|
+
cwd: ran.cwd,
|
|
119
|
+
args: ran.argv.slice(ran.argv.indexOf(`@astryxdesign/cli@${NEWER_CORE}`)),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
beforeEach(() => {
|
|
124
|
+
dir = fs.mkdtempSync(path.join(os.tmpdir(), 'upg-cli-behind-'));
|
|
125
|
+
write('package.json', JSON.stringify({name: 'consumer', version: '1.0.0'}));
|
|
126
|
+
write('src/index.tsx', TYPEAHEAD_SOURCE);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
afterEach(() => fs.rmSync(dir, {recursive: true, force: true}));
|
|
130
|
+
|
|
131
|
+
describe('a CLI older than the installed Core', {timeout: SLOW}, () => {
|
|
132
|
+
// The defect: the range past this CLI has no codemods here, so the run
|
|
133
|
+
// reported `no_codemods` (and "already up to date") and exited 0, while the
|
|
134
|
+
// project still needed the newer releases' migrations.
|
|
135
|
+
it('marks a range this CLI has no codemods for, and names the CLI that does', async () => {
|
|
136
|
+
installCore(NEWER_CORE);
|
|
137
|
+
|
|
138
|
+
const res = await upgrade({from: CLI_VERSION, apply: true}, {cwd: dir});
|
|
139
|
+
|
|
140
|
+
expect(res.type).toBe('upgrade.status');
|
|
141
|
+
expect(res.data.status).toBe('no_codemods');
|
|
142
|
+
expect(res.data.cliBehindCore).toEqual({
|
|
143
|
+
cliVersion: CLI_VERSION,
|
|
144
|
+
command: pinned(
|
|
145
|
+
'--from',
|
|
146
|
+
CLI_VERSION,
|
|
147
|
+
'--path',
|
|
148
|
+
inProject('src'),
|
|
149
|
+
'--apply',
|
|
150
|
+
),
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('runs the codemods it has for a range it covers only in part, and marks the rest', async () => {
|
|
155
|
+
installCore(NEWER_CORE);
|
|
156
|
+
|
|
157
|
+
const res = await upgrade({from: '0.6.8', apply: true}, {cwd: dir});
|
|
158
|
+
|
|
159
|
+
expect(res.type).toBe('upgrade.run');
|
|
160
|
+
expect(res.data.codemods).toBeGreaterThan(0);
|
|
161
|
+
expect(fs.readFileSync(path.join(dir, 'src/index.tsx'), 'utf8')).toContain(
|
|
162
|
+
'emptySearchText="None"',
|
|
163
|
+
);
|
|
164
|
+
expect(res.data.cliBehindCore).toEqual({
|
|
165
|
+
cliVersion: CLI_VERSION,
|
|
166
|
+
command: pinned('--from', '0.6.8', '--path', inProject('src'), '--apply'),
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it('repeats the invocation in the pinned command', async () => {
|
|
171
|
+
installCore(NEWER_CORE);
|
|
172
|
+
write('my src/index.tsx', TYPEAHEAD_SOURCE);
|
|
173
|
+
// An installed integration the run names, so --integration is repeated.
|
|
174
|
+
write(
|
|
175
|
+
'node_modules/@acme/widgets/package.json',
|
|
176
|
+
JSON.stringify({name: '@acme/widgets', version: '1.0.0'}),
|
|
177
|
+
);
|
|
178
|
+
write(
|
|
179
|
+
'node_modules/@acme/widgets/astryx.integration.mjs',
|
|
180
|
+
'export default {};\n',
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
const res = await upgrade(
|
|
184
|
+
{
|
|
185
|
+
from: CLI_VERSION,
|
|
186
|
+
path: 'my src',
|
|
187
|
+
codemod: 'only-this',
|
|
188
|
+
skipCodemod: ['first', 'second'],
|
|
189
|
+
integration: ['@acme/widgets'],
|
|
190
|
+
force: true,
|
|
191
|
+
installDeps: true,
|
|
192
|
+
},
|
|
193
|
+
{cwd: dir},
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
expect(res.data.cliBehindCore?.command).toBe(
|
|
197
|
+
pinned(
|
|
198
|
+
'--from',
|
|
199
|
+
CLI_VERSION,
|
|
200
|
+
'--path',
|
|
201
|
+
inProject('my src'),
|
|
202
|
+
'--codemod',
|
|
203
|
+
'only-this',
|
|
204
|
+
'--skip-codemod',
|
|
205
|
+
'first',
|
|
206
|
+
'--skip-codemod',
|
|
207
|
+
'second',
|
|
208
|
+
'--integration',
|
|
209
|
+
'@acme/widgets',
|
|
210
|
+
'--force',
|
|
211
|
+
'--install-deps',
|
|
212
|
+
),
|
|
213
|
+
);
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
// Where an upgrade runs decides what it finds: the installed Core is read
|
|
217
|
+
// from that folder, and --path must stay inside it. The command printed
|
|
218
|
+
// without a folder failed when pasted anywhere else: ERR_PATH_TRAVERSAL from
|
|
219
|
+
// a subfolder, ERR_VERSION_DETECT from a parent. A package runner can also
|
|
220
|
+
// move the run: Yarn 1 runs `yarn astryx` at the project root.
|
|
221
|
+
it('changes to the folder the run used and names the directory it scanned as an absolute path', async () => {
|
|
222
|
+
installCore(NEWER_CORE);
|
|
223
|
+
write('app/index.tsx', TYPEAHEAD_SOURCE);
|
|
224
|
+
const project = fs.realpathSync(dir);
|
|
225
|
+
|
|
226
|
+
for (const [given, scanned] of [
|
|
227
|
+
[undefined, inProject('src')],
|
|
228
|
+
['.', project],
|
|
229
|
+
['app', inProject('app')],
|
|
230
|
+
['./app/', inProject('app')],
|
|
231
|
+
]) {
|
|
232
|
+
const res = await upgrade(
|
|
233
|
+
{from: CLI_VERSION, ...(given ? {path: given} : {})},
|
|
234
|
+
{cwd: dir},
|
|
235
|
+
);
|
|
236
|
+
const command = /** @type {string} */ (res.data.cliBehindCore?.command);
|
|
237
|
+
|
|
238
|
+
expect(command).toBe(pinned('--from', CLI_VERSION, '--path', scanned));
|
|
239
|
+
if (process.platform !== 'win32') {
|
|
240
|
+
for (const pastedIn of [
|
|
241
|
+
path.join(dir, 'app'),
|
|
242
|
+
path.dirname(dir),
|
|
243
|
+
path.parse(dir).root,
|
|
244
|
+
]) {
|
|
245
|
+
const ran = runInShell(command, pastedIn);
|
|
246
|
+
expect(ran.cwd).toBe(project);
|
|
247
|
+
expect(ran.args[ran.args.indexOf('--path') + 1]).toBe(scanned);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
it.skipIf(process.platform === 'win32')(
|
|
254
|
+
'quotes the command so a POSIX shell enters the folder and passes every argument unchanged',
|
|
255
|
+
async () => {
|
|
256
|
+
fs.rmSync(dir, {recursive: true, force: true});
|
|
257
|
+
dir = fs.mkdtempSync(
|
|
258
|
+
path.join(os.tmpdir(), 'upg cost $5 `date` \'one\' "two" !x -'),
|
|
259
|
+
);
|
|
260
|
+
write(
|
|
261
|
+
'package.json',
|
|
262
|
+
JSON.stringify({name: 'consumer', version: '1.0.0'}),
|
|
263
|
+
);
|
|
264
|
+
write('src/index.tsx', TYPEAHEAD_SOURCE);
|
|
265
|
+
installCore(NEWER_CORE);
|
|
266
|
+
|
|
267
|
+
const res = await upgrade(
|
|
268
|
+
{
|
|
269
|
+
from: CLI_VERSION,
|
|
270
|
+
skipCodemod: ["it's", 'a$b c'],
|
|
271
|
+
apply: true,
|
|
272
|
+
},
|
|
273
|
+
{cwd: dir},
|
|
274
|
+
);
|
|
275
|
+
|
|
276
|
+
const ran = runInShell(
|
|
277
|
+
/** @type {string} */ (res.data.cliBehindCore?.command),
|
|
278
|
+
path.dirname(dir),
|
|
279
|
+
);
|
|
280
|
+
|
|
281
|
+
expect(ran.cwd).toBe(fs.realpathSync(dir));
|
|
282
|
+
expect(ran.args).toEqual([
|
|
283
|
+
`@astryxdesign/cli@${NEWER_CORE}`,
|
|
284
|
+
'upgrade',
|
|
285
|
+
'--from',
|
|
286
|
+
CLI_VERSION,
|
|
287
|
+
'--path',
|
|
288
|
+
inProject('src'),
|
|
289
|
+
'--skip-codemod',
|
|
290
|
+
"it's",
|
|
291
|
+
'--skip-codemod',
|
|
292
|
+
'a$b c',
|
|
293
|
+
'--apply',
|
|
294
|
+
]);
|
|
295
|
+
},
|
|
296
|
+
);
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
/** The CLI's own bin, which the stand-in runners below run. */
|
|
300
|
+
const BIN = path.join(CLI_ROOT, 'clients', 'cli', 'bin', 'astryx.mjs');
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Stand-ins for the package runners: each drops its own words and the pinned
|
|
304
|
+
* package, then runs this CLI with the rest of the command.
|
|
305
|
+
*/
|
|
306
|
+
const RUNS_THIS_CLI = /** @type {Array<[string, number]>} */ ([
|
|
307
|
+
['npx', 1],
|
|
308
|
+
['bunx', 1],
|
|
309
|
+
['pnpm', 2],
|
|
310
|
+
['yarn', 2],
|
|
311
|
+
])
|
|
312
|
+
.map(
|
|
313
|
+
([name, words]) =>
|
|
314
|
+
`${name}() { shift ${words}; "$0" ${quoteCommandArgument(BIN)} "$@"; }`,
|
|
315
|
+
)
|
|
316
|
+
.join('; ');
|
|
317
|
+
|
|
318
|
+
// A shell's `cd` follows a symbolic link, but the CLI it starts reads its
|
|
319
|
+
// folder with every link resolved and checks --path against that. A command
|
|
320
|
+
// that kept the link upgrade() was given exited 1 with ERR_PATH_TRAVERSAL.
|
|
321
|
+
describe.skipIf(process.platform === 'win32')(
|
|
322
|
+
'a project upgrade() reaches through a symbolic link',
|
|
323
|
+
{timeout: SLOW},
|
|
324
|
+
() => {
|
|
325
|
+
/** @type {string} */
|
|
326
|
+
let base;
|
|
327
|
+
|
|
328
|
+
beforeEach(() => {
|
|
329
|
+
fs.rmSync(dir, {recursive: true, force: true});
|
|
330
|
+
base = fs.mkdtempSync(path.join(os.tmpdir(), 'upg-link-'));
|
|
331
|
+
dir = path.join(base, 'real', 'my app');
|
|
332
|
+
write(
|
|
333
|
+
'package.json',
|
|
334
|
+
JSON.stringify({name: 'consumer', version: '1.0.0'}),
|
|
335
|
+
);
|
|
336
|
+
write('src/index.tsx', TYPEAHEAD_SOURCE);
|
|
337
|
+
installCore(NEWER_CORE);
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
afterEach(() => fs.rmSync(base, {recursive: true, force: true}));
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Run upgrade() from `cwd`, then the command it prints, in /bin/sh, from
|
|
344
|
+
* `cwd` and from the folder above the project.
|
|
345
|
+
* @param {string} cwd
|
|
346
|
+
*/
|
|
347
|
+
async function expectPrintedCommandToRun(cwd) {
|
|
348
|
+
const res = await upgrade({from: CLI_VERSION}, {cwd});
|
|
349
|
+
const command = /** @type {string} */ (res.data.cliBehindCore?.command);
|
|
350
|
+
|
|
351
|
+
for (const pastedIn of [cwd, base]) {
|
|
352
|
+
const ran = spawnSync(
|
|
353
|
+
'/bin/sh',
|
|
354
|
+
['-c', `${RUNS_THIS_CLI}; ${command}`, process.execPath],
|
|
355
|
+
{cwd: pastedIn, encoding: 'utf8'},
|
|
356
|
+
);
|
|
357
|
+
|
|
358
|
+
expect(ran.status, ran.stderr).toBe(0);
|
|
359
|
+
expect(ran.stdout).toContain(`Installed target: ${NEWER_CORE}`);
|
|
360
|
+
expect(ran.stdout).toContain(`Scanning ${inProject('src')} `);
|
|
361
|
+
}
|
|
362
|
+
expect(command).toBe(
|
|
363
|
+
pinned('--from', CLI_VERSION, '--path', inProject('src')),
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
it('prints a command that runs, from a folder reached through a link above the project', async () => {
|
|
368
|
+
fs.symlinkSync(path.join(base, 'real'), path.join(base, 'link'), 'dir');
|
|
369
|
+
|
|
370
|
+
await expectPrintedCommandToRun(path.join(base, 'link', 'my app'));
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
it('prints a command that runs, through a project root that is a link', async () => {
|
|
374
|
+
fs.symlinkSync(dir, path.join(base, 'app'), 'dir');
|
|
375
|
+
|
|
376
|
+
await expectPrintedCommandToRun(path.join(base, 'app'));
|
|
377
|
+
});
|
|
378
|
+
},
|
|
379
|
+
);
|
|
380
|
+
|
|
381
|
+
describe('a CLI that covers the range', {timeout: SLOW}, () => {
|
|
382
|
+
it('adds nothing when the installed Core is this CLI release', async () => {
|
|
383
|
+
installCore(CLI_VERSION);
|
|
384
|
+
|
|
385
|
+
const res = await upgrade({from: '0.6.8'}, {cwd: dir});
|
|
386
|
+
|
|
387
|
+
expect(res.type).toBe('upgrade.run');
|
|
388
|
+
expect('cliBehindCore' in res.data).toBe(false);
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
it('adds nothing when --from is already the installed Core', async () => {
|
|
392
|
+
installCore(NEWER_CORE);
|
|
393
|
+
|
|
394
|
+
const res = await upgrade({from: NEWER_CORE}, {cwd: dir});
|
|
395
|
+
|
|
396
|
+
expect(res.data.status).toBe('up_to_date');
|
|
397
|
+
expect('cliBehindCore' in res.data).toBe(false);
|
|
398
|
+
|
|
399
|
+
const forced = await upgrade({from: NEWER_CORE, force: true}, {cwd: dir});
|
|
400
|
+
|
|
401
|
+
expect(forced.data.status).toBe('no_codemods');
|
|
402
|
+
expect('cliBehindCore' in forced.data).toBe(false);
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
it('adds nothing for legacy @xds/core, which shares no version with a CLI release', async () => {
|
|
406
|
+
installCore(NEWER_CORE, '@xds/core');
|
|
407
|
+
|
|
408
|
+
const res = await upgrade({from: CLI_VERSION}, {cwd: dir});
|
|
409
|
+
|
|
410
|
+
expect(res.data.status).toBe('no_codemods');
|
|
411
|
+
expect('cliBehindCore' in res.data).toBe(false);
|
|
412
|
+
});
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
describe('logCliBehindCore: the warning names the shell its command is written for', () => {
|
|
416
|
+
it.each([
|
|
417
|
+
['win32', 'Run it in PowerShell with the CLI that matches your Core:'],
|
|
418
|
+
['linux', 'Run it with the CLI that matches your Core:'],
|
|
419
|
+
['darwin', 'Run it with the CLI that matches your Core:'],
|
|
420
|
+
])('on %s', (platform, ending) => {
|
|
421
|
+
const warn = vi.spyOn(logger, 'warn').mockImplementation(() => {});
|
|
422
|
+
try {
|
|
423
|
+
logCliBehindCore(
|
|
424
|
+
{cliVersion: '0.7.0', command: 'cd x; npx y'},
|
|
425
|
+
'0.8.0',
|
|
426
|
+
platform,
|
|
427
|
+
);
|
|
428
|
+
expect(warn.mock.calls.map(([line]) => String(line))).toEqual([
|
|
429
|
+
expect.stringMatching(
|
|
430
|
+
new RegExp(`${ending.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&')}$`, 'u'),
|
|
431
|
+
),
|
|
432
|
+
' cd x; npx y',
|
|
433
|
+
]);
|
|
434
|
+
} finally {
|
|
435
|
+
warn.mockRestore();
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
});
|
package/api/upgrade/run/run.mjs
CHANGED
|
@@ -15,12 +15,18 @@
|
|
|
15
15
|
* ShadCN-copied compositions → post-codemod hooks → render + refresh agent docs
|
|
16
16
|
* from final post-upgrade state. Integration DISCOVERY errors skip that
|
|
17
17
|
* integration; execution errors abort before the agent-doc write.
|
|
18
|
+
*
|
|
19
|
+
* Core codemods ship inside the CLI, so a CLI older than the installed Core
|
|
20
|
+
* has none for the releases after its own version. Every result past the
|
|
21
|
+
* up-to-date exit then carries `cliBehindCore`, and no human line says the
|
|
22
|
+
* upgrade finished; the warning names the same upgrade on the matching CLI.
|
|
18
23
|
*/
|
|
19
24
|
|
|
20
25
|
import * as fs from 'node:fs';
|
|
21
26
|
import * as path from 'node:path';
|
|
22
27
|
import {
|
|
23
28
|
detectInstalledTargetVersion,
|
|
29
|
+
detectCliBehindCore,
|
|
24
30
|
prepareAgentDocsRefresh,
|
|
25
31
|
applyAgentDocsRefresh,
|
|
26
32
|
inspectAgentDocs,
|
|
@@ -42,9 +48,11 @@ import {
|
|
|
42
48
|
statusUpToDate,
|
|
43
49
|
statusNoCodemods,
|
|
44
50
|
statusConfigFixable,
|
|
51
|
+
logCliBehindCore,
|
|
45
52
|
} from '../status/status.mjs';
|
|
46
53
|
import {semverGte} from '../../../foundation/env/semver.mjs';
|
|
47
54
|
import {getCliInvocation} from '../../../foundation/env/package-manager.mjs';
|
|
55
|
+
import {isOutsideProject} from '../../../foundation/env/project-scope.mjs';
|
|
48
56
|
import {ERROR_CODES} from '../../../foundation/response/error-codes.mjs';
|
|
49
57
|
import {AstryxError} from '../../error.mjs';
|
|
50
58
|
import {logger} from '../../logger.mjs';
|
|
@@ -146,7 +154,10 @@ export async function run(options = {}, {cwd = process.cwd()} = {}) {
|
|
|
146
154
|
const currentVersion = /** @type {string} */ (options.from);
|
|
147
155
|
const installed = detectInstalledTargetVersion(cwd);
|
|
148
156
|
if (!installed) {
|
|
149
|
-
|
|
157
|
+
// Outside a project there is no version to install (spec AST-081 FR3).
|
|
158
|
+
const msg = isOutsideProject(cwd)
|
|
159
|
+
? 'Could not find installed @astryxdesign/core (or legacy @xds/core). This folder is outside a project; upgrade migrates the code of an app project that installs @astryxdesign/core.'
|
|
160
|
+
: `Could not find installed @astryxdesign/core (or legacy @xds/core). Install the target version first, then rerun \`${getCliInvocation()} upgrade --from <old-version>\`.`;
|
|
150
161
|
logger.error(msg);
|
|
151
162
|
logger.log('Aborted\n');
|
|
152
163
|
throw new AstryxError(msg, undefined, ERROR_CODES.ERR_VERSION_DETECT);
|
|
@@ -195,6 +206,17 @@ export async function run(options = {}, {cwd = process.cwd()} = {}) {
|
|
|
195
206
|
});
|
|
196
207
|
}
|
|
197
208
|
|
|
209
|
+
// Past the up-to-date exit, codemods are needed through targetVersion. A
|
|
210
|
+
// CLI older than that has none for the releases after its own version.
|
|
211
|
+
const cliBehindCore = detectCliBehindCore({
|
|
212
|
+
from: currentVersion,
|
|
213
|
+
to: targetVersion,
|
|
214
|
+
packageName: installed.packageName,
|
|
215
|
+
options,
|
|
216
|
+
cwd,
|
|
217
|
+
sourcePath: path_,
|
|
218
|
+
});
|
|
219
|
+
|
|
198
220
|
const versionManifests = await getCoreVersionManifests(
|
|
199
221
|
currentVersion,
|
|
200
222
|
targetVersion,
|
|
@@ -243,6 +265,7 @@ export async function run(options = {}, {cwd = process.cwd()} = {}) {
|
|
|
243
265
|
skipCodemods,
|
|
244
266
|
root: cwd,
|
|
245
267
|
protection,
|
|
268
|
+
coversTarget: !cliBehindCore,
|
|
246
269
|
});
|
|
247
270
|
const coreResult =
|
|
248
271
|
codemodResult && 'totalFilesChanged' in codemodResult
|
|
@@ -271,6 +294,7 @@ export async function run(options = {}, {cwd = process.cwd()} = {}) {
|
|
|
271
294
|
for (const item of protectedFiles) {
|
|
272
295
|
logger.error(` ${item.file} — ${item.declarations.join('; ')}`);
|
|
273
296
|
}
|
|
297
|
+
if (cliBehindCore) logCliBehindCore(cliBehindCore, targetVersion);
|
|
274
298
|
logger.log('Upgrade incomplete: protected changes remain\n');
|
|
275
299
|
return {
|
|
276
300
|
type: 'upgrade.run',
|
|
@@ -299,6 +323,7 @@ export async function run(options = {}, {cwd = process.cwd()} = {}) {
|
|
|
299
323
|
complete: false,
|
|
300
324
|
errorCode: 'ERR_CODEMOD_PROTECTED',
|
|
301
325
|
errors: coreResult?.errors ?? [],
|
|
326
|
+
...(cliBehindCore ? {cliBehindCore} : {}),
|
|
302
327
|
},
|
|
303
328
|
};
|
|
304
329
|
}
|
|
@@ -316,6 +341,7 @@ export async function run(options = {}, {cwd = process.cwd()} = {}) {
|
|
|
316
341
|
to: targetVersion,
|
|
317
342
|
configError: configErr.message,
|
|
318
343
|
configCodemods: coreConfigCodemodNames,
|
|
344
|
+
cliBehindCore,
|
|
319
345
|
agentDocs:
|
|
320
346
|
/** @type {import('../upgrade.type.mjs').AgentDocsSummary} */ ({
|
|
321
347
|
status: inspection.status,
|
|
@@ -381,6 +407,7 @@ export async function run(options = {}, {cwd = process.cwd()} = {}) {
|
|
|
381
407
|
to: targetVersion,
|
|
382
408
|
agentDocs,
|
|
383
409
|
...(registryResult ? {registryCompositions: registryResult.summary} : {}),
|
|
410
|
+
cliBehindCore,
|
|
384
411
|
});
|
|
385
412
|
}
|
|
386
413
|
|
|
@@ -620,6 +647,7 @@ export async function run(options = {}, {cwd = process.cwd()} = {}) {
|
|
|
620
647
|
}
|
|
621
648
|
receipt.errors = finalErrors;
|
|
622
649
|
if (registryResult) receipt.registryCompositions = registryResult.summary;
|
|
650
|
+
if (cliBehindCore) receipt.cliBehindCore = cliBehindCore;
|
|
623
651
|
|
|
624
652
|
if (protectedFiles.length > 0) {
|
|
625
653
|
logger.error(
|
|
@@ -655,7 +683,12 @@ export async function run(options = {}, {cwd = process.cwd()} = {}) {
|
|
|
655
683
|
}
|
|
656
684
|
|
|
657
685
|
const registryOk = receipt.registryCompositions?.ok ?? true;
|
|
658
|
-
|
|
686
|
+
if (cliBehindCore) logCliBehindCore(cliBehindCore, targetVersion);
|
|
687
|
+
const done = cliBehindCore
|
|
688
|
+
? 'Upgrade incomplete'
|
|
689
|
+
: apply
|
|
690
|
+
? 'Upgrade complete'
|
|
691
|
+
: 'Dry run complete';
|
|
659
692
|
logger.log(
|
|
660
693
|
protectedFiles.length > 0
|
|
661
694
|
? 'Upgrade incomplete: protected changes remain\n'
|
|
@@ -13,27 +13,43 @@ export function statusUpToDate({ from, to, agentDocs, registryCompositions }: {
|
|
|
13
13
|
registryCompositions?: import("../upgrade.type.mjs").RegistryCompositionSummary;
|
|
14
14
|
}): import("../upgrade.type.mjs").UpgradeStatusResponse;
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
16
|
+
* The one warning for a CLI older than the installed Core: it has no codemods
|
|
17
|
+
* for the releases after its own version, and the pinned command does. The
|
|
18
|
+
* command gets a line of its own, so it copies exactly, whatever quotes or
|
|
19
|
+
* backticks its arguments carry. On Windows it is written for PowerShell, and
|
|
20
|
+
* the warning says so.
|
|
21
|
+
* @param {import('../upgrade.type.mjs').CliBehindCore} cliBehindCore
|
|
22
|
+
* @param {string} to the installed Core version
|
|
23
|
+
* @param {string} [platform] the `process.platform` the command was printed
|
|
24
|
+
* for, as `quoteCommandArgument` and `commandInFolder` take it
|
|
25
|
+
*/
|
|
26
|
+
export function logCliBehindCore({ cliVersion, command }: import("../upgrade.type.mjs").CliBehindCore, to: string, platform?: string): void;
|
|
27
|
+
/**
|
|
28
|
+
* No core or integration codemods apply to the requested version range. When
|
|
29
|
+
* the CLI is older than the installed Core, that only means this CLI has none:
|
|
30
|
+
* the result carries `cliBehindCore` and the human lines say so.
|
|
31
|
+
* @param {{from: string, to: string, agentDocs: import('../upgrade.type.mjs').AgentDocsSummary, registryCompositions?: import('../upgrade.type.mjs').RegistryCompositionSummary, cliBehindCore?: import('../upgrade.type.mjs').CliBehindCore | null}} data
|
|
18
32
|
* @returns {import('../upgrade.type.mjs').UpgradeStatusResponse}
|
|
19
33
|
*/
|
|
20
|
-
export function statusNoCodemods({ from, to, agentDocs, registryCompositions }: {
|
|
34
|
+
export function statusNoCodemods({ from, to, agentDocs, registryCompositions, cliBehindCore }: {
|
|
21
35
|
from: string;
|
|
22
36
|
to: string;
|
|
23
37
|
agentDocs: import("../upgrade.type.mjs").AgentDocsSummary;
|
|
24
38
|
registryCompositions?: import("../upgrade.type.mjs").RegistryCompositionSummary;
|
|
39
|
+
cliBehindCore?: import("../upgrade.type.mjs").CliBehindCore | null;
|
|
25
40
|
}): import("../upgrade.type.mjs").UpgradeStatusResponse;
|
|
26
41
|
/**
|
|
27
42
|
* DRY-RUN only: the consumer's astryx.config fails strict validation, but a
|
|
28
43
|
* pending core CONFIG codemod previewed a change that would repair it. Preview
|
|
29
44
|
* the fix + report the exact `--apply` command; integrations are skipped here.
|
|
30
|
-
* @param {{from: string, to: string, configError: string, configCodemods: string[], agentDocs: import('../upgrade.type.mjs').AgentDocsSummary}} data
|
|
45
|
+
* @param {{from: string, to: string, configError: string, configCodemods: string[], agentDocs: import('../upgrade.type.mjs').AgentDocsSummary, cliBehindCore?: import('../upgrade.type.mjs').CliBehindCore | null}} data
|
|
31
46
|
* @returns {import('../upgrade.type.mjs').UpgradeStatusResponse}
|
|
32
47
|
*/
|
|
33
|
-
export function statusConfigFixable({ from, to, configError, configCodemods, agentDocs }: {
|
|
48
|
+
export function statusConfigFixable({ from, to, configError, configCodemods, agentDocs, cliBehindCore }: {
|
|
34
49
|
from: string;
|
|
35
50
|
to: string;
|
|
36
51
|
configError: string;
|
|
37
52
|
configCodemods: string[];
|
|
38
53
|
agentDocs: import("../upgrade.type.mjs").AgentDocsSummary;
|
|
54
|
+
cliBehindCore?: import("../upgrade.type.mjs").CliBehindCore | null;
|
|
39
55
|
}): import("../upgrade.type.mjs").UpgradeStatusResponse;
|