@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,106 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file The CLI's per-user settings file (spec AST-081 FR8):
|
|
5
|
+
* `astryx/settings.json` in the platform's per-user configuration folder.
|
|
6
|
+
*
|
|
7
|
+
* It holds the person's choices about the computer-level agent text:
|
|
8
|
+
*
|
|
9
|
+
* ```json
|
|
10
|
+
* {"computerAgentText": {"install": true, "links": ["/home/me/.claude/skills/astryx"]}}
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* - `computerAgentText.install`: `false` after `astryx init --user
|
|
14
|
+
* --remove-agents`, `true` after `astryx init --user`. A missing file or
|
|
15
|
+
* value means install.
|
|
16
|
+
* - `computerAgentText.links`: the links to the skill folder Astryx made, so
|
|
17
|
+
* removal removes exactly those.
|
|
18
|
+
*
|
|
19
|
+
* Only `astryx init --user` and the global copy's refresh change it. No environment variable or option
|
|
20
|
+
* does. A file that cannot be read or parsed counts as missing, and one that
|
|
21
|
+
* cannot be written never fails a run.
|
|
22
|
+
*
|
|
23
|
+
* @input the per-user configuration folder
|
|
24
|
+
* @output the settings, and writes to them
|
|
25
|
+
* @position packages/cli/foundation/env
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
import * as fs from 'node:fs';
|
|
29
|
+
import * as path from 'node:path';
|
|
30
|
+
import {userConfigDir} from './user-dirs.mjs';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @typedef {object} ComputerAgentTextSettings
|
|
34
|
+
* @property {boolean} install Whether the computer-level text is wanted.
|
|
35
|
+
* @property {string[]} links The links to its skill folder Astryx made, so
|
|
36
|
+
* removal removes exactly those.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The settings file's path.
|
|
41
|
+
* @param {string} [configDir]
|
|
42
|
+
* @returns {string}
|
|
43
|
+
*/
|
|
44
|
+
export function settingsFile(configDir = userConfigDir()) {
|
|
45
|
+
return path.join(configDir, 'settings.json');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* The whole settings object; `{}` when the file is missing or unreadable.
|
|
50
|
+
* @param {string} [configDir]
|
|
51
|
+
* @returns {Record<string, unknown>}
|
|
52
|
+
*/
|
|
53
|
+
export function readSettings(configDir = userConfigDir()) {
|
|
54
|
+
try {
|
|
55
|
+
const value = JSON.parse(fs.readFileSync(settingsFile(configDir), 'utf8'));
|
|
56
|
+
return value && typeof value === 'object' && !Array.isArray(value)
|
|
57
|
+
? value
|
|
58
|
+
: {};
|
|
59
|
+
} catch {
|
|
60
|
+
return {};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The person's choices about the computer-level agent text.
|
|
66
|
+
* @param {string} [configDir]
|
|
67
|
+
* @returns {ComputerAgentTextSettings}
|
|
68
|
+
*/
|
|
69
|
+
export function computerAgentTextSettings(configDir = userConfigDir()) {
|
|
70
|
+
const raw = readSettings(configDir).computerAgentText;
|
|
71
|
+
const value =
|
|
72
|
+
raw && typeof raw === 'object' && !Array.isArray(raw)
|
|
73
|
+
? /** @type {Record<string, unknown>} */ (raw)
|
|
74
|
+
: {};
|
|
75
|
+
const links = Array.isArray(value.links)
|
|
76
|
+
? value.links.filter(link => typeof link === 'string')
|
|
77
|
+
: [];
|
|
78
|
+
return {install: value.install !== false, links};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Record the person's choices about the computer-level agent text, keeping
|
|
83
|
+
* every other setting. Returns whether the file was written.
|
|
84
|
+
* @param {ComputerAgentTextSettings} choice
|
|
85
|
+
* @param {string} [configDir]
|
|
86
|
+
* @returns {boolean}
|
|
87
|
+
*/
|
|
88
|
+
export function recordComputerAgentTextSettings(
|
|
89
|
+
choice,
|
|
90
|
+
configDir = userConfigDir(),
|
|
91
|
+
) {
|
|
92
|
+
const next = {
|
|
93
|
+
...readSettings(configDir),
|
|
94
|
+
computerAgentText: {install: choice.install, links: choice.links},
|
|
95
|
+
};
|
|
96
|
+
const file = settingsFile(configDir);
|
|
97
|
+
try {
|
|
98
|
+
fs.mkdirSync(path.dirname(file), {recursive: true});
|
|
99
|
+
const tmp = `${file}.${process.pid}.tmp`;
|
|
100
|
+
fs.writeFileSync(tmp, `${JSON.stringify(next, null, 2)}\n`);
|
|
101
|
+
fs.renameSync(tmp, file);
|
|
102
|
+
return true;
|
|
103
|
+
} catch {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
import * as fs from 'node:fs';
|
|
4
|
+
import * as os from 'node:os';
|
|
5
|
+
import * as path from 'node:path';
|
|
6
|
+
import {afterEach, describe, expect, it} from 'vitest';
|
|
7
|
+
import {
|
|
8
|
+
computerAgentTextSettings,
|
|
9
|
+
readSettings,
|
|
10
|
+
recordComputerAgentTextSettings,
|
|
11
|
+
settingsFile,
|
|
12
|
+
} from './user-settings.mjs';
|
|
13
|
+
|
|
14
|
+
/** @type {string[]} */
|
|
15
|
+
const dirs = [];
|
|
16
|
+
const tmp = () => {
|
|
17
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-settings-'));
|
|
18
|
+
dirs.push(dir);
|
|
19
|
+
return dir;
|
|
20
|
+
};
|
|
21
|
+
afterEach(() => {
|
|
22
|
+
for (const dir of dirs.splice(0)) {
|
|
23
|
+
fs.rmSync(dir, {recursive: true, force: true});
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe('the settings file (spec AST-081 FR8)', () => {
|
|
28
|
+
it('means install, with no links, when missing or unreadable', () => {
|
|
29
|
+
const dir = tmp();
|
|
30
|
+
expect(computerAgentTextSettings(dir)).toEqual({install: true, links: []});
|
|
31
|
+
fs.writeFileSync(settingsFile(dir), 'not json');
|
|
32
|
+
expect(readSettings(dir)).toEqual({});
|
|
33
|
+
expect(computerAgentTextSettings(dir)).toEqual({install: true, links: []});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('records and reads the choice and the links Astryx made, keeping other settings', () => {
|
|
37
|
+
const dir = tmp();
|
|
38
|
+
fs.writeFileSync(settingsFile(dir), '{"other":true}');
|
|
39
|
+
expect(
|
|
40
|
+
recordComputerAgentTextSettings(
|
|
41
|
+
{install: true, links: ['/h/.claude/skills/astryx']},
|
|
42
|
+
dir,
|
|
43
|
+
),
|
|
44
|
+
).toBe(true);
|
|
45
|
+
expect(JSON.parse(fs.readFileSync(settingsFile(dir), 'utf8'))).toEqual({
|
|
46
|
+
other: true,
|
|
47
|
+
computerAgentText: {install: true, links: ['/h/.claude/skills/astryx']},
|
|
48
|
+
});
|
|
49
|
+
expect(computerAgentTextSettings(dir)).toEqual({
|
|
50
|
+
install: true,
|
|
51
|
+
links: ['/h/.claude/skills/astryx'],
|
|
52
|
+
});
|
|
53
|
+
recordComputerAgentTextSettings({install: false, links: []}, dir);
|
|
54
|
+
expect(computerAgentTextSettings(dir)).toEqual({install: false, links: []});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('never fails when the folder cannot be written', () => {
|
|
58
|
+
const file = path.join(tmp(), 'file');
|
|
59
|
+
fs.writeFileSync(file, '');
|
|
60
|
+
expect(
|
|
61
|
+
recordComputerAgentTextSettings({install: false, links: []}, file),
|
|
62
|
+
).toBe(false);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
@@ -9,8 +9,22 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import * as fs from 'node:fs';
|
|
12
|
+
import {createRequire} from 'node:module';
|
|
12
13
|
import * as path from 'node:path';
|
|
13
|
-
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The `ignore` matcher factory, loaded on first use: this module is reached
|
|
17
|
+
* from every CLI run through the agent-docs helpers, and only a run that
|
|
18
|
+
* classifies a file needs the matcher.
|
|
19
|
+
* @type {typeof import('ignore') | undefined}
|
|
20
|
+
*/
|
|
21
|
+
let ignoreFactory;
|
|
22
|
+
|
|
23
|
+
/** @param {import('ignore').Options} [options] */
|
|
24
|
+
function ignore(options) {
|
|
25
|
+
ignoreFactory ??= createRequire(import.meta.url)('ignore');
|
|
26
|
+
return /** @type {typeof import('ignore')} */ (ignoreFactory)(options);
|
|
27
|
+
}
|
|
14
28
|
|
|
15
29
|
const DEPENDENCY_DIRS = new Set([
|
|
16
30
|
'node_modules',
|
|
@@ -21,7 +21,8 @@ export function importUserModule(file: string, { fresh }?: {
|
|
|
21
21
|
/**
|
|
22
22
|
* Load a generated theme artifact and its extensionless JS/JSX/TS/TSX graph.
|
|
23
23
|
* Package specifiers resolve from the consumer project, while relative paths
|
|
24
|
-
* resolve from that same project root.
|
|
24
|
+
* resolve from that same project root. An import of an existing `.css` file
|
|
25
|
+
* loads as an empty module.
|
|
25
26
|
* @param {string} specifier
|
|
26
27
|
* @param {string} cwd
|
|
27
28
|
* @returns {Promise<Record<string, unknown>>}
|
|
@@ -7,9 +7,11 @@
|
|
|
7
7
|
* user-authored module (`.ts` via jiti, `.mjs`/`.js` via native dynamic
|
|
8
8
|
* import) and (b) find conventional files by basename in a fixed
|
|
9
9
|
* load-precedence order. Generated theme artifacts also use a dedicated jiti
|
|
10
|
-
* path that resolves extensionless JSX/TSX registry imports
|
|
11
|
-
*
|
|
12
|
-
*
|
|
10
|
+
* path that resolves extensionless JSX/TSX registry imports and loads the
|
|
11
|
+
* stylesheets they import as empty modules. These helpers centralize that
|
|
12
|
+
* behavior so callers stay in lockstep. A module's stdout writes go to stderr
|
|
13
|
+
* while it loads, so project code that prints cannot corrupt a `--json`
|
|
14
|
+
* envelope.
|
|
13
15
|
*
|
|
14
16
|
* `loadModuleWithParser` builds on these primitives to provide the single
|
|
15
17
|
* load/validation boundary shared by config, integration, codemod, and
|
|
@@ -125,6 +127,56 @@ const THEME_ARTIFACT_EXTENSIONS = [
|
|
|
125
127
|
'.cts',
|
|
126
128
|
];
|
|
127
129
|
|
|
130
|
+
/**
|
|
131
|
+
* @param {string | symbol} specifier
|
|
132
|
+
* @returns {specifier is string}
|
|
133
|
+
*/
|
|
134
|
+
function isStylesheetSpecifier(specifier) {
|
|
135
|
+
return typeof specifier === 'string' && specifier.endsWith('.css');
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Whether `specifier`, resolved from the module at `from`, names an existing
|
|
140
|
+
* `.css` file.
|
|
141
|
+
* @param {string} specifier
|
|
142
|
+
* @param {string} from
|
|
143
|
+
*/
|
|
144
|
+
function resolvesToStylesheet(specifier, from) {
|
|
145
|
+
try {
|
|
146
|
+
return createRequire(from).resolve(specifier).endsWith('.css');
|
|
147
|
+
} catch {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* A built theme module may import a stylesheet so that the app's bundler emits
|
|
154
|
+
* it. Node cannot load a stylesheet, so an import that ends in `.css` and
|
|
155
|
+
* resolves from the theme module to an existing `.css` file loads as an empty
|
|
156
|
+
* module. Any other import loads as before: a missing stylesheet fails like
|
|
157
|
+
* any missing import, and `./tokens.css` loads `tokens.css.js` when that is
|
|
158
|
+
* the file it names. jiti shows only the import text, so the check resolves it
|
|
159
|
+
* from the theme module's folder, not from the importing module's. A module in
|
|
160
|
+
* another folder fails on a stylesheet it reaches by a different relative
|
|
161
|
+
* path, and passes on a missing stylesheet whose path exists from the theme
|
|
162
|
+
* module's folder.
|
|
163
|
+
* @param {() => string} themeModule returns the theme module's path
|
|
164
|
+
* @returns {Record<string, unknown>}
|
|
165
|
+
*/
|
|
166
|
+
function themeArtifactStylesheets(themeModule) {
|
|
167
|
+
return new Proxy(
|
|
168
|
+
{},
|
|
169
|
+
{
|
|
170
|
+
has: (_target, specifier) =>
|
|
171
|
+
specifier !== themeModule() &&
|
|
172
|
+
isStylesheetSpecifier(specifier) &&
|
|
173
|
+
resolvesToStylesheet(specifier, themeModule()),
|
|
174
|
+
get: (_target, specifier) =>
|
|
175
|
+
isStylesheetSpecifier(specifier) ? {} : undefined,
|
|
176
|
+
},
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
128
180
|
class ThemeArtifactNotFoundError extends Error {
|
|
129
181
|
code = 'ERR_THEME_ARTIFACT_NOT_FOUND';
|
|
130
182
|
|
|
@@ -153,17 +205,20 @@ function isMissingPackageExport(error) {
|
|
|
153
205
|
/**
|
|
154
206
|
* Load a generated theme artifact and its extensionless JS/JSX/TS/TSX graph.
|
|
155
207
|
* Package specifiers resolve from the consumer project, while relative paths
|
|
156
|
-
* resolve from that same project root.
|
|
208
|
+
* resolve from that same project root. An import of an existing `.css` file
|
|
209
|
+
* loads as an empty module.
|
|
157
210
|
* @param {string} specifier
|
|
158
211
|
* @param {string} cwd
|
|
159
212
|
* @returns {Promise<Record<string, unknown>>}
|
|
160
213
|
*/
|
|
161
214
|
export async function importThemeArtifact(specifier, cwd) {
|
|
215
|
+
let themeModule = path.join(cwd, 'package.json');
|
|
162
216
|
const loader = createJiti(path.join(cwd, 'package.json'), {
|
|
163
217
|
moduleCache: false,
|
|
164
218
|
jsx: true,
|
|
165
219
|
interopDefault: true,
|
|
166
220
|
extensions: THEME_ARTIFACT_EXTENSIONS,
|
|
221
|
+
virtualModules: themeArtifactStylesheets(() => themeModule),
|
|
167
222
|
});
|
|
168
223
|
let target;
|
|
169
224
|
if (specifier.startsWith('.') || path.isAbsolute(specifier)) {
|
|
@@ -179,6 +234,7 @@ export async function importThemeArtifact(specifier, cwd) {
|
|
|
179
234
|
if (!fs.existsSync(target)) {
|
|
180
235
|
throw new ThemeArtifactNotFoundError(specifier);
|
|
181
236
|
}
|
|
237
|
+
themeModule = target;
|
|
182
238
|
return await withStdoutOnStderr(() => loader.import(target));
|
|
183
239
|
}
|
|
184
240
|
|
|
@@ -14,6 +14,7 @@ import * as fs from 'node:fs';
|
|
|
14
14
|
import * as os from 'node:os';
|
|
15
15
|
import * as path from 'node:path';
|
|
16
16
|
import {fileURLToPath, pathToFileURL} from 'node:url';
|
|
17
|
+
import {CLI_VERSION} from '../../test-utils/release-fixtures.mjs';
|
|
17
18
|
|
|
18
19
|
const HERE = path.dirname(fileURLToPath(import.meta.url));
|
|
19
20
|
const LOADER_URL = pathToFileURL(path.join(HERE, 'module-loader.mjs')).href;
|
|
@@ -268,7 +269,7 @@ describe('--json stdout stays one envelope when project modules print', () => {
|
|
|
268
269
|
write('package.json', JSON.stringify({name: 'consumer', private: true}));
|
|
269
270
|
write(
|
|
270
271
|
'node_modules/@astryxdesign/core/package.json',
|
|
271
|
-
JSON.stringify({name: '@astryxdesign/core', version:
|
|
272
|
+
JSON.stringify({name: '@astryxdesign/core', version: CLI_VERSION}),
|
|
272
273
|
);
|
|
273
274
|
write(
|
|
274
275
|
'astryx.config.js',
|
|
@@ -289,7 +290,7 @@ describe('--json stdout stays one envelope when project modules print', () => {
|
|
|
289
290
|
);
|
|
290
291
|
write(
|
|
291
292
|
'node_modules/@astryxdesign/core/package.json',
|
|
292
|
-
JSON.stringify({name: '@astryxdesign/core', version:
|
|
293
|
+
JSON.stringify({name: '@astryxdesign/core', version: CLI_VERSION}),
|
|
293
294
|
);
|
|
294
295
|
write(
|
|
295
296
|
'astryx.config.mjs',
|
|
@@ -9,6 +9,7 @@ import {pathToFileURL} from 'node:url';
|
|
|
9
9
|
import {z} from 'zod';
|
|
10
10
|
import {
|
|
11
11
|
findPresentFiles,
|
|
12
|
+
importThemeArtifact,
|
|
12
13
|
importUserModule,
|
|
13
14
|
loadModuleWithParser,
|
|
14
15
|
} from './module-loader.mjs';
|
|
@@ -155,6 +156,199 @@ process.stdout.write(JSON.stringify({first: first.default?.answer, fresh: fresh.
|
|
|
155
156
|
});
|
|
156
157
|
});
|
|
157
158
|
|
|
159
|
+
describe('importThemeArtifact', () => {
|
|
160
|
+
const STYLESHEET_RAN = '__astryxThemeArtifactStylesheetRan';
|
|
161
|
+
|
|
162
|
+
/** @param {string} file @param {string} content */
|
|
163
|
+
function write(file, content) {
|
|
164
|
+
const target = path.join(tmpDir, file);
|
|
165
|
+
fs.mkdirSync(path.dirname(target), {recursive: true});
|
|
166
|
+
fs.writeFileSync(target, content);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
beforeEach(() => {
|
|
170
|
+
write('package.json', JSON.stringify({type: 'module'}));
|
|
171
|
+
write(
|
|
172
|
+
'ocean.css',
|
|
173
|
+
'[data-astryx-theme="ocean"] { --color-text: black; }\n',
|
|
174
|
+
);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
afterEach(() => {
|
|
178
|
+
Reflect.deleteProperty(globalThis, STYLESHEET_RAN);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it('loads a built module that imports its stylesheet, without running the stylesheet', async () => {
|
|
182
|
+
// Valid JavaScript, so running this stylesheet would leave a trace.
|
|
183
|
+
write('ran.css', `globalThis.${STYLESHEET_RAN} = true;\n`);
|
|
184
|
+
write(
|
|
185
|
+
'ocean.js',
|
|
186
|
+
"import './ocean.css';\nimport './ran.css';\nexport const oceanTheme = {name: 'ocean'};\n",
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
const mod = await importThemeArtifact('./ocean.js', tmpDir);
|
|
190
|
+
|
|
191
|
+
expect(mod.oceanTheme).toEqual({name: 'ocean'});
|
|
192
|
+
expect(Reflect.get(globalThis, STYLESHEET_RAN)).toBeUndefined();
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it('loads a CommonJS built module that requires its stylesheet', async () => {
|
|
196
|
+
write('commonjs/package.json', JSON.stringify({type: 'commonjs'}));
|
|
197
|
+
write(
|
|
198
|
+
'commonjs/ocean.css',
|
|
199
|
+
'[data-astryx-theme="ocean"] { --color-text: black; }\n',
|
|
200
|
+
);
|
|
201
|
+
write(
|
|
202
|
+
'commonjs/ocean.js',
|
|
203
|
+
"require('./ocean.css');\nexports.oceanTheme = {name: 'ocean'};\n",
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
const mod = await importThemeArtifact('./commonjs/ocean.js', tmpDir);
|
|
207
|
+
|
|
208
|
+
expect(mod.oceanTheme).toEqual({name: 'ocean'});
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it('loads stylesheets imported by a nested module, through a package export, and dynamically', async () => {
|
|
212
|
+
const packageDir = 'node_modules/@acme/themes';
|
|
213
|
+
write(
|
|
214
|
+
`${packageDir}/package.json`,
|
|
215
|
+
JSON.stringify({
|
|
216
|
+
name: '@acme/themes',
|
|
217
|
+
type: 'module',
|
|
218
|
+
exports: {
|
|
219
|
+
'./themes/ocean': './dist/ocean.js',
|
|
220
|
+
'./themes/ocean.css': './dist/ocean.css',
|
|
221
|
+
},
|
|
222
|
+
}),
|
|
223
|
+
);
|
|
224
|
+
write(
|
|
225
|
+
`${packageDir}/dist/ocean.css`,
|
|
226
|
+
'[data-astryx-theme="ocean"] { --color-text: black; }\n',
|
|
227
|
+
);
|
|
228
|
+
write(
|
|
229
|
+
`${packageDir}/dist/tokens.js`,
|
|
230
|
+
"import '@acme/themes/themes/ocean.css';\nexport const tokens = {};\n",
|
|
231
|
+
);
|
|
232
|
+
write(
|
|
233
|
+
`${packageDir}/dist/ocean.js`,
|
|
234
|
+
"import {tokens} from './tokens.js';\nawait import('./ocean.css');\nexport const oceanTheme = {name: 'ocean', tokens};\n",
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
const mod = await importThemeArtifact('@acme/themes/themes/ocean', tmpDir);
|
|
238
|
+
|
|
239
|
+
expect(mod.oceanTheme).toEqual({name: 'ocean', tokens: {}});
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
it('still resolves an extensionless import to its directory index beside a same-named stylesheet', async () => {
|
|
243
|
+
write('ocean/index.js', "export const oceanTheme = {name: 'ocean'};\n");
|
|
244
|
+
write(
|
|
245
|
+
'entry.js',
|
|
246
|
+
"import './ocean.css';\nexport {oceanTheme} from './ocean';\n",
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
const mod = await importThemeArtifact('./entry.js', tmpDir);
|
|
250
|
+
|
|
251
|
+
expect(mod.oceanTheme).toEqual({name: 'ocean'});
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
it('loads a module whose import ends in .css but names a JavaScript file', async () => {
|
|
255
|
+
write('tokens.css.js', "export const vars = {accent: 'blue'};\n");
|
|
256
|
+
write(
|
|
257
|
+
'ocean.js',
|
|
258
|
+
"import './ocean.css';\nimport {vars} from './tokens.css';\nexport const oceanTheme = {name: 'ocean', vars};\n",
|
|
259
|
+
);
|
|
260
|
+
|
|
261
|
+
const mod = await importThemeArtifact('./ocean.js', tmpDir);
|
|
262
|
+
|
|
263
|
+
expect(mod.oceanTheme).toEqual({name: 'ocean', vars: {accent: 'blue'}});
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
it.each([
|
|
267
|
+
['a missing file', "import './fonts.css';\n", /fonts\.css/],
|
|
268
|
+
[
|
|
269
|
+
'a package that is not installed',
|
|
270
|
+
"import '@acme/missing-fonts/inter.css';\n",
|
|
271
|
+
/@acme\/missing-fonts\/inter\.css/,
|
|
272
|
+
],
|
|
273
|
+
])(
|
|
274
|
+
'still rejects a stylesheet import of %s',
|
|
275
|
+
async (_label, stylesheetImport, expected) => {
|
|
276
|
+
write(
|
|
277
|
+
'ocean.js',
|
|
278
|
+
`import './ocean.css';\n${stylesheetImport}export const oceanTheme = {name: 'ocean'};\n`,
|
|
279
|
+
);
|
|
280
|
+
|
|
281
|
+
await expect(importThemeArtifact('./ocean.js', tmpDir)).rejects.toThrow(
|
|
282
|
+
expected,
|
|
283
|
+
);
|
|
284
|
+
},
|
|
285
|
+
);
|
|
286
|
+
|
|
287
|
+
it('still rejects a theme module path that names a stylesheet', async () => {
|
|
288
|
+
await expect(importThemeArtifact('./ocean.css', tmpDir)).rejects.toThrow(
|
|
289
|
+
/Unknown file extension "\.css"/,
|
|
290
|
+
);
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
it('still rejects a stylesheet import that its package does not export', async () => {
|
|
294
|
+
const packageDir = 'node_modules/@acme/themes';
|
|
295
|
+
write(
|
|
296
|
+
`${packageDir}/package.json`,
|
|
297
|
+
JSON.stringify({
|
|
298
|
+
name: '@acme/themes',
|
|
299
|
+
type: 'module',
|
|
300
|
+
exports: {'./themes/ocean': './dist/ocean.js'},
|
|
301
|
+
}),
|
|
302
|
+
);
|
|
303
|
+
write(
|
|
304
|
+
`${packageDir}/dist/ocean.css`,
|
|
305
|
+
'[data-astryx-theme="ocean"] { --color-text: black; }\n',
|
|
306
|
+
);
|
|
307
|
+
write(
|
|
308
|
+
`${packageDir}/dist/ocean.js`,
|
|
309
|
+
"import '@acme/themes/themes/ocean.css';\nexport const oceanTheme = {name: 'ocean'};\n",
|
|
310
|
+
);
|
|
311
|
+
|
|
312
|
+
await expect(
|
|
313
|
+
importThemeArtifact('@acme/themes/themes/ocean', tmpDir),
|
|
314
|
+
).rejects.toThrow(/not defined by "exports"/);
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
it.each([
|
|
318
|
+
[
|
|
319
|
+
'a missing dependency',
|
|
320
|
+
"import './missing.js';\nexport const oceanTheme = {name: 'ocean'};\n",
|
|
321
|
+
/missing\.js/,
|
|
322
|
+
],
|
|
323
|
+
[
|
|
324
|
+
'a syntax error in a module it imports',
|
|
325
|
+
"import './broken.js';\nexport const oceanTheme = {name: 'ocean'};\n",
|
|
326
|
+
/ParseError/,
|
|
327
|
+
],
|
|
328
|
+
[
|
|
329
|
+
'a throwing module',
|
|
330
|
+
"throw new Error('broken theme module');\n",
|
|
331
|
+
/broken theme module/,
|
|
332
|
+
],
|
|
333
|
+
[
|
|
334
|
+
'an asset that is not a stylesheet',
|
|
335
|
+
"import './logo.svg';\nexport const oceanTheme = {name: 'ocean'};\n",
|
|
336
|
+
/Unknown file extension "\.svg"/,
|
|
337
|
+
],
|
|
338
|
+
])(
|
|
339
|
+
'still rejects a built module that imports its stylesheet and has %s',
|
|
340
|
+
async (_label, rest, expected) => {
|
|
341
|
+
write('logo.svg', '<svg xmlns="http://www.w3.org/2000/svg"/>\n');
|
|
342
|
+
write('broken.js', 'export const broken = ;\n');
|
|
343
|
+
write('ocean.js', `import './ocean.css';\n${rest}`);
|
|
344
|
+
|
|
345
|
+
await expect(importThemeArtifact('./ocean.js', tmpDir)).rejects.toThrow(
|
|
346
|
+
expected,
|
|
347
|
+
);
|
|
348
|
+
},
|
|
349
|
+
);
|
|
350
|
+
});
|
|
351
|
+
|
|
158
352
|
describe('loadModuleWithParser', () => {
|
|
159
353
|
// Temp module files live under a repo-local dir (not /tmp): Vite's dynamic
|
|
160
354
|
// import blocks /tmp, so we mirror the existing repo-local temp pattern.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// @generated by scripts/sync-api-types.mjs from the JSDoc in foundation/**/*.mjs.
|
|
2
|
+
// DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Whether the platform's file systems ignore letter case by default.
|
|
6
|
+
* @param {NodeJS.Platform} [platform]
|
|
7
|
+
* @returns {boolean}
|
|
8
|
+
*/
|
|
9
|
+
export function ignoresCase(platform?: NodeJS.Platform): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* A path in the form two spellings of one folder share.
|
|
12
|
+
* @param {string} p
|
|
13
|
+
* @param {NodeJS.Platform} [platform]
|
|
14
|
+
* @returns {string}
|
|
15
|
+
*/
|
|
16
|
+
export function pathKey(p: string, platform?: NodeJS.Platform): string;
|
|
17
|
+
/**
|
|
18
|
+
* Whether two paths name the same folder or file.
|
|
19
|
+
* @param {string} a
|
|
20
|
+
* @param {string} b
|
|
21
|
+
* @param {NodeJS.Platform} [platform]
|
|
22
|
+
* @returns {boolean}
|
|
23
|
+
*/
|
|
24
|
+
export function samePath(a: string, b: string, platform?: NodeJS.Platform): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* `child` relative to `parent`, compared the way the file system compares
|
|
27
|
+
* names; `null` when `child` is not inside `parent` (or is `parent`).
|
|
28
|
+
* @param {string} parent
|
|
29
|
+
* @param {string} child
|
|
30
|
+
* @param {NodeJS.Platform} [platform]
|
|
31
|
+
* @returns {string | null}
|
|
32
|
+
*/
|
|
33
|
+
export function relativeWithin(parent: string, child: string, platform?: NodeJS.Platform): string | null;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file Path comparison that matches the file system (spec AST-081 FR11):
|
|
5
|
+
* Windows and macOS file systems ignore letter case by default, so two
|
|
6
|
+
* spellings that differ only in case name the same folder there, and the
|
|
7
|
+
* release choice must treat them as one.
|
|
8
|
+
*
|
|
9
|
+
* @input paths and the platform
|
|
10
|
+
* @output whether two paths are the same, and a path relative to a folder
|
|
11
|
+
* @position packages/cli/foundation/fs — used by the release choice and the
|
|
12
|
+
* release cache.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import * as path from 'node:path';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Whether the platform's file systems ignore letter case by default.
|
|
19
|
+
* @param {NodeJS.Platform} [platform]
|
|
20
|
+
* @returns {boolean}
|
|
21
|
+
*/
|
|
22
|
+
export function ignoresCase(platform = process.platform) {
|
|
23
|
+
return platform === 'win32' || platform === 'darwin';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The path module of a platform.
|
|
28
|
+
* @param {NodeJS.Platform} platform
|
|
29
|
+
* @returns {typeof path.posix}
|
|
30
|
+
*/
|
|
31
|
+
function pathsOf(platform) {
|
|
32
|
+
return platform === 'win32' ? path.win32 : path.posix;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* A path in the form two spellings of one folder share.
|
|
37
|
+
* @param {string} p
|
|
38
|
+
* @param {NodeJS.Platform} [platform]
|
|
39
|
+
* @returns {string}
|
|
40
|
+
*/
|
|
41
|
+
export function pathKey(p, platform = process.platform) {
|
|
42
|
+
const normal = pathsOf(platform).normalize(p);
|
|
43
|
+
return ignoresCase(platform) ? normal.toLowerCase() : normal;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Whether two paths name the same folder or file.
|
|
48
|
+
* @param {string} a
|
|
49
|
+
* @param {string} b
|
|
50
|
+
* @param {NodeJS.Platform} [platform]
|
|
51
|
+
* @returns {boolean}
|
|
52
|
+
*/
|
|
53
|
+
export function samePath(a, b, platform = process.platform) {
|
|
54
|
+
return pathKey(a, platform) === pathKey(b, platform);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* `child` relative to `parent`, compared the way the file system compares
|
|
59
|
+
* names; `null` when `child` is not inside `parent` (or is `parent`).
|
|
60
|
+
* @param {string} parent
|
|
61
|
+
* @param {string} child
|
|
62
|
+
* @param {NodeJS.Platform} [platform]
|
|
63
|
+
* @returns {string | null}
|
|
64
|
+
*/
|
|
65
|
+
export function relativeWithin(parent, child, platform = process.platform) {
|
|
66
|
+
const paths = pathsOf(platform);
|
|
67
|
+
const rel = paths.relative(
|
|
68
|
+
pathKey(parent, platform),
|
|
69
|
+
pathKey(child, platform),
|
|
70
|
+
);
|
|
71
|
+
if (rel === '' || rel.startsWith('..') || paths.isAbsolute(rel)) return null;
|
|
72
|
+
return rel;
|
|
73
|
+
}
|