@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,152 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file The command that runs the CLI for this project, when something other
|
|
5
|
+
* than the package-manager guess says what it is.
|
|
6
|
+
*
|
|
7
|
+
* `getCliInvocation` (package-manager.mjs) is the one picker every printed
|
|
8
|
+
* command goes through. It asks, in order:
|
|
9
|
+
*
|
|
10
|
+
* 1. **The integrations** — the `cliCommand` field of each loaded
|
|
11
|
+
* integration's manifest. `Project.load` records them per project with
|
|
12
|
+
* {@link recordDeclaredCliCommands}. One command, declared by one or more
|
|
13
|
+
* integrations, is used. Two different commands cancel each other out: the
|
|
14
|
+
* picker falls back to its guess, even when a host set a door, and
|
|
15
|
+
* `astryx doctor` warns.
|
|
16
|
+
* 2. **The door** — the command a host ran this call through. A host sets it
|
|
17
|
+
* for the duration of one call with {@link runWithCliDoor}; nothing in the
|
|
18
|
+
* public API sets it yet, so it is empty in every plain run.
|
|
19
|
+
* 3. **The guess** — the package-manager prefix, as before.
|
|
20
|
+
*
|
|
21
|
+
* @input A host's door name; the loaded integrations of a project.
|
|
22
|
+
* @output The declared command for a directory, or the conflict.
|
|
23
|
+
* @position foundation/env — read by the picker and by `astryx doctor`.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import {AsyncLocalStorage} from 'node:async_hooks';
|
|
27
|
+
import * as fs from 'node:fs';
|
|
28
|
+
import * as path from 'node:path';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* One integration's declared command.
|
|
32
|
+
* @typedef {object} DeclaredCliCommand
|
|
33
|
+
* @property {string} package the integration package that declared it
|
|
34
|
+
* @property {string} command its `cliCommand` value
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
/** @type {AsyncLocalStorage<{command: string}>} */
|
|
38
|
+
const doorScope = new AsyncLocalStorage();
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Run `fn` with `command` as the door printed commands start with. The slot a
|
|
42
|
+
* host fills for one call. An integration's `cliCommand` still comes first,
|
|
43
|
+
* and conflicting ones still fall back to the guess.
|
|
44
|
+
* @template T
|
|
45
|
+
* @param {string} command e.g. `astryx` for a global launcher
|
|
46
|
+
* @param {() => T} fn
|
|
47
|
+
* @returns {T}
|
|
48
|
+
*/
|
|
49
|
+
export function runWithCliDoor(command, fn) {
|
|
50
|
+
return doorScope.run({command}, fn);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* The door of the current call, if a host set one.
|
|
55
|
+
* @returns {string | undefined}
|
|
56
|
+
*/
|
|
57
|
+
export function cliDoor() {
|
|
58
|
+
return doorScope.getStore()?.command;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** @type {Map<string, DeclaredCliCommand[]>} */
|
|
62
|
+
const declaredByProject = new Map();
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The directory a project is keyed by: the nearest one with a package.json,
|
|
66
|
+
* the same root `Project.load` resolves; otherwise the directory itself.
|
|
67
|
+
* @param {string} dir
|
|
68
|
+
* @returns {string}
|
|
69
|
+
*/
|
|
70
|
+
function projectKey(dir) {
|
|
71
|
+
const start = path.resolve(dir);
|
|
72
|
+
let current = start;
|
|
73
|
+
for (;;) {
|
|
74
|
+
if (fs.existsSync(path.join(current, 'package.json'))) return current;
|
|
75
|
+
const parent = path.dirname(current);
|
|
76
|
+
if (parent === current) return start;
|
|
77
|
+
current = parent;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The commands a set of loaded integrations declares, in load order. An
|
|
83
|
+
* integration that failed to load, or was set aside for a provider conflict,
|
|
84
|
+
* contributes nothing, so it declares nothing either.
|
|
85
|
+
* @param {ReadonlyArray<{name?: string, __spec?: string, cliCommand?: string, __loadError?: string, __providerConflict?: unknown}>} integrations
|
|
86
|
+
* @returns {DeclaredCliCommand[]}
|
|
87
|
+
*/
|
|
88
|
+
export function declaredCliCommandsOf(integrations) {
|
|
89
|
+
/** @type {DeclaredCliCommand[]} */
|
|
90
|
+
const declared = [];
|
|
91
|
+
for (const integration of integrations) {
|
|
92
|
+
if (integration.__loadError != null) continue;
|
|
93
|
+
if (integration.__providerConflict != null) continue;
|
|
94
|
+
if (typeof integration.cliCommand !== 'string') continue;
|
|
95
|
+
declared.push({
|
|
96
|
+
package: integration.name ?? integration.__spec ?? '(unnamed)',
|
|
97
|
+
command: integration.cliCommand,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
return declared;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Choose among declarations: one command, declared by one or more
|
|
105
|
+
* integrations, is used; different commands are a conflict.
|
|
106
|
+
* @param {DeclaredCliCommand[]} declared
|
|
107
|
+
* @returns {{command?: string, conflict: boolean, declared: DeclaredCliCommand[]}}
|
|
108
|
+
*/
|
|
109
|
+
export function chooseDeclaredCliCommand(declared) {
|
|
110
|
+
const commands = new Set(declared.map(entry => entry.command));
|
|
111
|
+
if (commands.size === 1) {
|
|
112
|
+
return {command: declared[0].command, conflict: false, declared};
|
|
113
|
+
}
|
|
114
|
+
return {conflict: commands.size > 1, declared};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Record the commands a project's loaded integrations declare. Called by
|
|
119
|
+
* `Project.load` each time it resolves the integration set; the latest load
|
|
120
|
+
* wins.
|
|
121
|
+
* @param {string} projectDir
|
|
122
|
+
* @param {Parameters<typeof declaredCliCommandsOf>[0]} integrations
|
|
123
|
+
* @returns {void}
|
|
124
|
+
*/
|
|
125
|
+
export function recordDeclaredCliCommands(projectDir, integrations) {
|
|
126
|
+
declaredByProject.set(
|
|
127
|
+
projectKey(projectDir),
|
|
128
|
+
declaredCliCommandsOf(integrations),
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Whether this process has loaded the project at `targetDir`.
|
|
134
|
+
* @param {string} [targetDir=process.cwd()]
|
|
135
|
+
* @returns {boolean}
|
|
136
|
+
*/
|
|
137
|
+
export function hasRecordedProject(targetDir = process.cwd()) {
|
|
138
|
+
return declaredByProject.has(projectKey(targetDir));
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* What the integrations of the project at `targetDir` declare, as recorded by
|
|
143
|
+
* its last `Project.load` in this process; see
|
|
144
|
+
* {@link chooseDeclaredCliCommand}.
|
|
145
|
+
* @param {string} [targetDir=process.cwd()]
|
|
146
|
+
* @returns {{command?: string, conflict: boolean, declared: DeclaredCliCommand[]}}
|
|
147
|
+
*/
|
|
148
|
+
export function declaredCliCommand(targetDir = process.cwd()) {
|
|
149
|
+
return chooseDeclaredCliCommand(
|
|
150
|
+
declaredByProject.get(projectKey(targetDir)) ?? [],
|
|
151
|
+
);
|
|
152
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
import {describe, it, expect, afterEach} from 'vitest';
|
|
4
|
+
import * as fs from 'node:fs';
|
|
5
|
+
import * as path from 'node:path';
|
|
6
|
+
import * as os from 'node:os';
|
|
7
|
+
import {
|
|
8
|
+
chooseDeclaredCliCommand,
|
|
9
|
+
cliDoor,
|
|
10
|
+
declaredCliCommand,
|
|
11
|
+
declaredCliCommandsOf,
|
|
12
|
+
hasRecordedProject,
|
|
13
|
+
recordDeclaredCliCommands,
|
|
14
|
+
runWithCliDoor,
|
|
15
|
+
} from './cli-command.mjs';
|
|
16
|
+
|
|
17
|
+
/** @type {string[]} */
|
|
18
|
+
const dirs = [];
|
|
19
|
+
|
|
20
|
+
afterEach(() => {
|
|
21
|
+
for (const dir of dirs.splice(0)) {
|
|
22
|
+
fs.rmSync(dir, {recursive: true, force: true});
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
/** A project directory with a package.json, and a folder inside it. */
|
|
27
|
+
function makeProject() {
|
|
28
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-cli-command-'));
|
|
29
|
+
dirs.push(dir);
|
|
30
|
+
fs.writeFileSync(path.join(dir, 'package.json'), '{"name":"app"}');
|
|
31
|
+
fs.mkdirSync(path.join(dir, 'src'));
|
|
32
|
+
return dir;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
describe('runWithCliDoor', () => {
|
|
36
|
+
it('sets the door for the call, and only for it', async () => {
|
|
37
|
+
expect(cliDoor()).toBeUndefined();
|
|
38
|
+
const inside = await runWithCliDoor('astryx', async () => {
|
|
39
|
+
await Promise.resolve();
|
|
40
|
+
return cliDoor();
|
|
41
|
+
});
|
|
42
|
+
expect(inside).toBe('astryx');
|
|
43
|
+
expect(cliDoor()).toBeUndefined();
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
describe('declaredCliCommandsOf', () => {
|
|
48
|
+
it('skips integrations that failed to load or were set aside', () => {
|
|
49
|
+
expect(
|
|
50
|
+
declaredCliCommandsOf([
|
|
51
|
+
{name: '@acme/a', cliCommand: 'acme astryx'},
|
|
52
|
+
{name: '@acme/b'},
|
|
53
|
+
{name: '@acme/c', cliCommand: 'c astryx', __loadError: 'boom'},
|
|
54
|
+
{name: '@acme/d', cliCommand: 'd astryx', __providerConflict: {}},
|
|
55
|
+
{__spec: '@acme/e', cliCommand: 'acme astryx'},
|
|
56
|
+
]),
|
|
57
|
+
).toEqual([
|
|
58
|
+
{package: '@acme/a', command: 'acme astryx'},
|
|
59
|
+
{package: '@acme/e', command: 'acme astryx'},
|
|
60
|
+
]);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
describe('chooseDeclaredCliCommand', () => {
|
|
65
|
+
it('uses one command, however many packages declare it', () => {
|
|
66
|
+
const declared = [
|
|
67
|
+
{package: '@acme/a', command: 'acme astryx'},
|
|
68
|
+
{package: '@acme/b', command: 'acme astryx'},
|
|
69
|
+
];
|
|
70
|
+
expect(chooseDeclaredCliCommand(declared)).toEqual({
|
|
71
|
+
command: 'acme astryx',
|
|
72
|
+
conflict: false,
|
|
73
|
+
declared,
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('uses neither of two different commands, and calls it a conflict', () => {
|
|
78
|
+
const result = chooseDeclaredCliCommand([
|
|
79
|
+
{package: '@acme/a', command: 'acme astryx'},
|
|
80
|
+
{package: '@acme/b', command: 'other astryx'},
|
|
81
|
+
]);
|
|
82
|
+
expect(result.command).toBeUndefined();
|
|
83
|
+
expect(result.conflict).toBe(true);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('has nothing to choose with no declarations', () => {
|
|
87
|
+
expect(chooseDeclaredCliCommand([])).toEqual({
|
|
88
|
+
conflict: false,
|
|
89
|
+
declared: [],
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
describe('recordDeclaredCliCommands', () => {
|
|
95
|
+
it('answers for the project and any folder inside it', () => {
|
|
96
|
+
const dir = makeProject();
|
|
97
|
+
expect(hasRecordedProject(dir)).toBe(false);
|
|
98
|
+
recordDeclaredCliCommands(dir, [
|
|
99
|
+
{name: '@acme/a', cliCommand: 'acme astryx'},
|
|
100
|
+
]);
|
|
101
|
+
expect(hasRecordedProject(dir)).toBe(true);
|
|
102
|
+
expect(declaredCliCommand(dir).command).toBe('acme astryx');
|
|
103
|
+
expect(declaredCliCommand(path.join(dir, 'src')).command).toBe(
|
|
104
|
+
'acme astryx',
|
|
105
|
+
);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('lets the latest load win', () => {
|
|
109
|
+
const dir = makeProject();
|
|
110
|
+
recordDeclaredCliCommands(dir, [
|
|
111
|
+
{name: '@acme/a', cliCommand: 'acme astryx'},
|
|
112
|
+
]);
|
|
113
|
+
recordDeclaredCliCommands(dir, []);
|
|
114
|
+
expect(hasRecordedProject(dir)).toBe(true);
|
|
115
|
+
expect(declaredCliCommand(dir).command).toBeUndefined();
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('does not answer for a nested project of its own', () => {
|
|
119
|
+
const dir = makeProject();
|
|
120
|
+
const nested = path.join(dir, 'packages', 'web');
|
|
121
|
+
fs.mkdirSync(nested, {recursive: true});
|
|
122
|
+
fs.writeFileSync(path.join(nested, 'package.json'), '{"name":"web"}');
|
|
123
|
+
recordDeclaredCliCommands(dir, [
|
|
124
|
+
{name: '@acme/a', cliCommand: 'acme astryx'},
|
|
125
|
+
]);
|
|
126
|
+
expect(hasRecordedProject(nested)).toBe(false);
|
|
127
|
+
expect(declaredCliCommand(nested).command).toBeUndefined();
|
|
128
|
+
});
|
|
129
|
+
});
|
|
@@ -20,15 +20,27 @@ import {
|
|
|
20
20
|
|
|
21
21
|
describe('parseNodeVersion', () => {
|
|
22
22
|
it('parses a plain semver string', () => {
|
|
23
|
-
expect(parseNodeVersion('22.14.1')).toEqual({
|
|
23
|
+
expect(parseNodeVersion('22.14.1')).toEqual({
|
|
24
|
+
major: 22,
|
|
25
|
+
minor: 14,
|
|
26
|
+
patch: 1,
|
|
27
|
+
});
|
|
24
28
|
});
|
|
25
29
|
|
|
26
30
|
it('strips a leading v', () => {
|
|
27
|
-
expect(parseNodeVersion('v20.10.0')).toEqual({
|
|
31
|
+
expect(parseNodeVersion('v20.10.0')).toEqual({
|
|
32
|
+
major: 20,
|
|
33
|
+
minor: 10,
|
|
34
|
+
patch: 0,
|
|
35
|
+
});
|
|
28
36
|
});
|
|
29
37
|
|
|
30
38
|
it('ignores a prerelease/build suffix on the patch segment', () => {
|
|
31
|
-
expect(parseNodeVersion('16.20.2-nightly')).toEqual({
|
|
39
|
+
expect(parseNodeVersion('16.20.2-nightly')).toEqual({
|
|
40
|
+
major: 16,
|
|
41
|
+
minor: 20,
|
|
42
|
+
patch: 2,
|
|
43
|
+
});
|
|
32
44
|
});
|
|
33
45
|
|
|
34
46
|
it('defaults missing segments to 0', () => {
|
|
@@ -130,21 +130,55 @@ export function isCliOneOff(): boolean;
|
|
|
130
130
|
*/
|
|
131
131
|
export function cliBinResolves(targetDir?: string): boolean;
|
|
132
132
|
/**
|
|
133
|
-
* The
|
|
133
|
+
* The CLI invocation stem every printed command starts with. The one picker:
|
|
134
|
+
* every hint, error, Doctor fix and doc line that names a command goes through
|
|
135
|
+
* it (directly, or through {@link formatCliCommand} and
|
|
136
|
+
* {@link formatCliCommandsIn}). JSON fields that carry a command stay bare.
|
|
134
137
|
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
* -
|
|
138
|
-
* `
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
138
|
+
* In order:
|
|
139
|
+
*
|
|
140
|
+
* - The `cliCommand` an integration loaded in this project declares, e.g.
|
|
141
|
+
* `acme astryx`. When two integrations declare different commands,
|
|
142
|
+
* neither is used, the guess below is (even when a host set a door), and
|
|
143
|
+
* `astryx doctor` warns.
|
|
144
|
+
* - The door a host ran this call through (see cli-command.mjs). Empty in a
|
|
145
|
+
* plain run.
|
|
146
|
+
* - Otherwise the guess below.
|
|
147
|
+
*
|
|
148
|
+
* The guess names a command that, run from `targetDir`, reaches the release
|
|
149
|
+
* that answered (spec AST-081 FR5):
|
|
150
|
+
*
|
|
151
|
+
* - The project's own CLI answered and its `astryx` bin resolves from
|
|
152
|
+
* `targetDir`: `<run-prefix> astryx` (e.g. `pnpm exec astryx`).
|
|
153
|
+
* - Outside a project, the CLI installed for the computer (or the release it
|
|
154
|
+
* keeps) answered: `astryx`.
|
|
155
|
+
* - Otherwise: `<dlx-prefix> @astryxdesign/cli@<answering version>`, pinned so
|
|
156
|
+
* the package runner starts the same release. The bare `astryx` name would
|
|
157
|
+
* make npm fetch an unrelated registry package, and the unpinned scoped
|
|
158
|
+
* package the newest release.
|
|
159
|
+
*
|
|
160
|
+
* With `installed`, the line follows a step that installs the project's own
|
|
161
|
+
* CLI (an update notice, the hint that matches a project's CLI to its Core),
|
|
162
|
+
* so the guess is that CLI: `<run-prefix> astryx`. A declared `cliCommand`
|
|
163
|
+
* and a host's door still come first.
|
|
142
164
|
*
|
|
143
165
|
* @param {string} [targetDir] the project the printed command runs in;
|
|
144
166
|
* defaults to the working directory
|
|
167
|
+
* @param {{installed?: boolean}} [options]
|
|
145
168
|
* @returns {string}
|
|
146
169
|
*/
|
|
147
|
-
export function getCliInvocation(targetDir?: string
|
|
170
|
+
export function getCliInvocation(targetDir?: string, { installed }?: {
|
|
171
|
+
installed?: boolean;
|
|
172
|
+
}): string;
|
|
173
|
+
/**
|
|
174
|
+
* The package-manager guess alone, without any integration's `cliCommand` or
|
|
175
|
+
* a host's door. The picker falls back to it when declared commands conflict,
|
|
176
|
+
* and Doctor names it then.
|
|
177
|
+
*
|
|
178
|
+
* @param {string} [targetDir]
|
|
179
|
+
* @returns {string}
|
|
180
|
+
*/
|
|
181
|
+
export function guessCliInvocation(targetDir?: string): string;
|
|
148
182
|
/**
|
|
149
183
|
* Format a full, runnable CLI command from a subcommand string.
|
|
150
184
|
*
|
|
@@ -157,6 +191,56 @@ export function getCliInvocation(targetDir?: string): string;
|
|
|
157
191
|
* @returns {string}
|
|
158
192
|
*/
|
|
159
193
|
export function formatCliCommand(command: string, targetDir?: string): string;
|
|
194
|
+
/**
|
|
195
|
+
* Prefix every CLI command in doc text with `stem`, the invocation from
|
|
196
|
+
* {@link getCliInvocation}.
|
|
197
|
+
*
|
|
198
|
+
* Docs, including an integration's, are written with bare `astryx ...`
|
|
199
|
+
* commands; this rewrites them when they are shown. In prose, an inline code
|
|
200
|
+
* span that starts with `astryx`. In a shell code fence (no language, `bash`,
|
|
201
|
+
* `sh`, `shell`, `zsh`, `console`), each `astryx` that starts a command. In a
|
|
202
|
+
* `text` or `markdown` fence, both. Other fences, and plain words, are left
|
|
203
|
+
* alone. JSON output keeps the authored text.
|
|
204
|
+
*
|
|
205
|
+
* @param {string} text Markdown-style doc text, or the body of one code block.
|
|
206
|
+
* @param {string} stem e.g. `pnpm exec astryx`
|
|
207
|
+
* @param {string | null} [lang] the code block's language when `text` is one
|
|
208
|
+
* block's body; omit for Markdown, whose fences are followed
|
|
209
|
+
* @returns {string}
|
|
210
|
+
*/
|
|
211
|
+
export function prefixCliCommands(text: string, stem: string, lang?: string | null): string;
|
|
212
|
+
/**
|
|
213
|
+
* Quote one argument of a printed command so the shell it is pasted into
|
|
214
|
+
* passes it on unchanged. Printed commands target a POSIX shell (sh, bash,
|
|
215
|
+
* zsh), and PowerShell on Windows; cmd.exe is not a target. A value made only
|
|
216
|
+
* of letters, digits and `@ / . _ -` (and, on Windows, a drive path's `:` and
|
|
217
|
+
* `\`) stays bare. Any other value gets single quotes, inside which both
|
|
218
|
+
* shells read `$`, backticks, `%`, `!`, spaces and double quotes literally. An
|
|
219
|
+
* embedded single quote is written `'\''` for a POSIX shell and doubled for
|
|
220
|
+
* PowerShell, which also ends a single-quoted string at the typographic
|
|
221
|
+
* quotes `‘ ’ ‚ ‛`, so those are doubled too (`Macy’s` → `'Macy’’s'`).
|
|
222
|
+
*
|
|
223
|
+
* @param {string} value
|
|
224
|
+
* @param {string} [platform] the `process.platform` the command is printed for
|
|
225
|
+
* @returns {string}
|
|
226
|
+
*/
|
|
227
|
+
export function quoteCommandArgument(value: string, platform?: string): string;
|
|
228
|
+
/**
|
|
229
|
+
* A printed command that changes to `dir`, then runs `command` there, so it
|
|
230
|
+
* does the same work pasted from any folder. It runs `command` only when the
|
|
231
|
+
* change worked. For a POSIX shell: `cd <dir> && <command>`. For PowerShell
|
|
232
|
+
* on Windows: `cd -LiteralPath <dir> -ErrorAction Stop; <command>`, because
|
|
233
|
+
* `-LiteralPath` reads `[` and `]` in a folder name literally, and a failed
|
|
234
|
+
* change stops the line in Windows PowerShell 5.1, which has no `&&`, as in
|
|
235
|
+
* PowerShell 7.
|
|
236
|
+
*
|
|
237
|
+
* @param {string} dir an absolute folder
|
|
238
|
+
* @param {string} command the command to run there, its arguments already
|
|
239
|
+
* quoted with {@link quoteCommandArgument}
|
|
240
|
+
* @param {string} [platform] the `process.platform` the command is printed for
|
|
241
|
+
* @returns {string}
|
|
242
|
+
*/
|
|
243
|
+
export function commandInFolder(dir: string, command: string, platform?: string): string;
|
|
160
244
|
/** The published CLI package name — used for one-off (uninstalled) invocations. */
|
|
161
245
|
export const CLI_PACKAGE: "@astryxdesign/cli";
|
|
162
246
|
/** The CLI binary name — only resolves once the CLI is installed (or run via CLI_PACKAGE). */
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file The picker's guess when the CLI installed for the computer answers:
|
|
5
|
+
* `astryx` outside a project, and the pinned package inside one, where the
|
|
6
|
+
* global copy never answers for itself (spec AST-081 FR5).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import {describe, it, expect, vi, afterEach} from 'vitest';
|
|
10
|
+
import * as fs from 'node:fs';
|
|
11
|
+
import * as path from 'node:path';
|
|
12
|
+
import {guessCliInvocation} from './package-manager.mjs';
|
|
13
|
+
import {
|
|
14
|
+
CLI_VERSION,
|
|
15
|
+
cleanupFixtures,
|
|
16
|
+
installCore,
|
|
17
|
+
project,
|
|
18
|
+
tempDir,
|
|
19
|
+
} from '../../test-utils/release-fixtures.mjs';
|
|
20
|
+
|
|
21
|
+
vi.mock('../release/choose.mjs', async importOriginal => ({
|
|
22
|
+
.../** @type {object} */ (await importOriginal()),
|
|
23
|
+
isGlobalCopy: () => true,
|
|
24
|
+
}));
|
|
25
|
+
|
|
26
|
+
afterEach(cleanupFixtures);
|
|
27
|
+
|
|
28
|
+
describe('guessCliInvocation for the copy installed for the computer', () => {
|
|
29
|
+
it('prints the bare `astryx` command outside a project', () => {
|
|
30
|
+
const empty = tempDir('empty');
|
|
31
|
+
fs.writeFileSync(path.join(empty, 'package-lock.json'), '{}');
|
|
32
|
+
const before = process.cwd();
|
|
33
|
+
process.chdir(empty);
|
|
34
|
+
try {
|
|
35
|
+
expect(guessCliInvocation(empty)).toBe('astryx');
|
|
36
|
+
} finally {
|
|
37
|
+
process.chdir(before);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('prints the pinned package inside a project it answers as the matched release', () => {
|
|
42
|
+
const root = project(tempDir(), {'@astryxdesign/core': CLI_VERSION});
|
|
43
|
+
installCore(root, CLI_VERSION);
|
|
44
|
+
fs.writeFileSync(path.join(root, 'package-lock.json'), '{}');
|
|
45
|
+
expect(guessCliInvocation(root)).toBe(
|
|
46
|
+
`npx @astryxdesign/cli@${CLI_VERSION}`,
|
|
47
|
+
);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe('one stem per run', () => {
|
|
52
|
+
it('names the release that answered the run, whichever folder a line names', () => {
|
|
53
|
+
// The run answers outside a project; a line about a project folder whose
|
|
54
|
+
// own CLI sits beyond the read reach still gets the same stem.
|
|
55
|
+
const empty = tempDir('empty');
|
|
56
|
+
const other = project(tempDir(), {'@astryxdesign/core': CLI_VERSION});
|
|
57
|
+
installCore(other, CLI_VERSION);
|
|
58
|
+
const before = process.cwd();
|
|
59
|
+
process.chdir(empty);
|
|
60
|
+
try {
|
|
61
|
+
expect(guessCliInvocation(other)).toBe(guessCliInvocation(empty));
|
|
62
|
+
} finally {
|
|
63
|
+
process.chdir(before);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
});
|