@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
|
@@ -24,7 +24,6 @@ import * as path from 'node:path';
|
|
|
24
24
|
import * as os from 'node:os';
|
|
25
25
|
import {fileURLToPath} from 'node:url';
|
|
26
26
|
import {spawnSync} from 'node:child_process';
|
|
27
|
-
import jscodeshift from 'jscodeshift';
|
|
28
27
|
import {assertWithin} from '../../foundation/fs/path-safety.mjs';
|
|
29
28
|
import {resolvePackageDir} from '../../foundation/integrations/integrations.mjs';
|
|
30
29
|
import {
|
|
@@ -41,6 +40,8 @@ import {
|
|
|
41
40
|
} from '../../foundation/discovery/docs-discovery.mjs';
|
|
42
41
|
import {discoverIntegrationThemes} from '../../foundation/discovery/theme-discovery.mjs';
|
|
43
42
|
import {inspectPackageExport} from '../../foundation/discovery/package-exports.mjs';
|
|
43
|
+
import {parse as parseModule} from '@babel/parser';
|
|
44
|
+
import {moduleExportsName} from '../../foundation/discovery/module-exports.mjs';
|
|
44
45
|
import {
|
|
45
46
|
ThemeImportError,
|
|
46
47
|
resolveThemeImports,
|
|
@@ -51,6 +52,9 @@ import {
|
|
|
51
52
|
} from '../theme/build/build.mjs';
|
|
52
53
|
import {
|
|
53
54
|
discoverIntegrationComponents,
|
|
55
|
+
docStem,
|
|
56
|
+
familyImports,
|
|
57
|
+
isIntegrationMember,
|
|
54
58
|
resolveIntegrationImportPath,
|
|
55
59
|
} from '../../foundation/discovery/component-discovery.mjs';
|
|
56
60
|
import {loadComponentReplacements} from '../component/_adapter.mjs';
|
|
@@ -65,6 +69,7 @@ import {
|
|
|
65
69
|
collectIdentities,
|
|
66
70
|
compareIdentities,
|
|
67
71
|
} from '../../foundation/integrations/contribution-inventory.mjs';
|
|
72
|
+
import {formatCliCommand} from '../../foundation/env/package-manager.mjs';
|
|
68
73
|
|
|
69
74
|
/**
|
|
70
75
|
* @typedef {import('../../foundation/integrations/issue').AstryxIntegrationIssue} Issue
|
|
@@ -307,98 +312,6 @@ function extractTarball(tgzPath, extractDir) {
|
|
|
307
312
|
}
|
|
308
313
|
}
|
|
309
314
|
|
|
310
|
-
const MODULE_EXTENSIONS = ['.mjs', '.js', '.mts', '.ts', '.tsx', '.jsx'];
|
|
311
|
-
const moduleParser = jscodeshift.withParser('tsx');
|
|
312
|
-
|
|
313
|
-
/** @param {unknown} specifier @param {string} fromFile */
|
|
314
|
-
function resolveLocalModule(specifier, fromFile) {
|
|
315
|
-
if (typeof specifier !== 'string' || !specifier.startsWith('.')) return null;
|
|
316
|
-
const base = path.resolve(path.dirname(fromFile), specifier);
|
|
317
|
-
const candidates = [
|
|
318
|
-
base,
|
|
319
|
-
...MODULE_EXTENSIONS.map(extension => `${base}${extension}`),
|
|
320
|
-
...MODULE_EXTENSIONS.map(extension => path.join(base, `index${extension}`)),
|
|
321
|
-
];
|
|
322
|
-
return candidates.find(candidate => fs.existsSync(candidate)) ?? null;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
/** @param {any} declaration @param {string} exportName */
|
|
326
|
-
function declarationExports(declaration, exportName) {
|
|
327
|
-
if (!declaration) return false;
|
|
328
|
-
if (['FunctionDeclaration', 'ClassDeclaration'].includes(declaration.type)) {
|
|
329
|
-
return declaration.id?.name === exportName;
|
|
330
|
-
}
|
|
331
|
-
if (declaration.type !== 'VariableDeclaration') return false;
|
|
332
|
-
return declaration.declarations.some(
|
|
333
|
-
(/** @type {any} */ item) =>
|
|
334
|
-
item.id?.type === 'Identifier' && item.id.name === exportName,
|
|
335
|
-
);
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
/**
|
|
339
|
-
* Check one resolved module's static export surface without executing package
|
|
340
|
-
* code. Local ESM re-exports are followed recursively.
|
|
341
|
-
*
|
|
342
|
-
* @param {string} file
|
|
343
|
-
* @param {string} exportName
|
|
344
|
-
* @param {Set<string>} [seen]
|
|
345
|
-
*/
|
|
346
|
-
function moduleExportsName(file, exportName, seen = new Set()) {
|
|
347
|
-
const identity = `${file}\0${exportName}`;
|
|
348
|
-
if (seen.has(identity) || !fs.existsSync(file)) return false;
|
|
349
|
-
seen.add(identity);
|
|
350
|
-
|
|
351
|
-
let root;
|
|
352
|
-
try {
|
|
353
|
-
root = moduleParser(fs.readFileSync(file, 'utf-8'));
|
|
354
|
-
} catch {
|
|
355
|
-
return false;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
let found = false;
|
|
359
|
-
root
|
|
360
|
-
.find(moduleParser.ExportNamedDeclaration)
|
|
361
|
-
.forEach((/** @type {any} */ exportPath) => {
|
|
362
|
-
if (found) return;
|
|
363
|
-
const node = exportPath.node;
|
|
364
|
-
if (declarationExports(node.declaration, exportName)) {
|
|
365
|
-
found = true;
|
|
366
|
-
return;
|
|
367
|
-
}
|
|
368
|
-
for (const specifier of node.specifiers ?? []) {
|
|
369
|
-
const exported = specifier.exported?.name ?? specifier.exported?.value;
|
|
370
|
-
if (exported !== exportName) continue;
|
|
371
|
-
if (!node.source) {
|
|
372
|
-
found = true;
|
|
373
|
-
return;
|
|
374
|
-
}
|
|
375
|
-
const target = resolveLocalModule(node.source.value, file);
|
|
376
|
-
const imported =
|
|
377
|
-
specifier.local?.name ?? specifier.local?.value ?? exportName;
|
|
378
|
-
if (target && moduleExportsName(target, imported, seen)) {
|
|
379
|
-
found = true;
|
|
380
|
-
return;
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
});
|
|
384
|
-
if (found) return true;
|
|
385
|
-
if (
|
|
386
|
-
exportName === 'default' &&
|
|
387
|
-
root.find(moduleParser.ExportDefaultDeclaration).size() > 0
|
|
388
|
-
) {
|
|
389
|
-
return true;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
root
|
|
393
|
-
.find(moduleParser.ExportAllDeclaration)
|
|
394
|
-
.forEach((/** @type {any} */ exportPath) => {
|
|
395
|
-
if (found) return;
|
|
396
|
-
const target = resolveLocalModule(exportPath.node.source?.value, file);
|
|
397
|
-
if (target && moduleExportsName(target, exportName, seen)) found = true;
|
|
398
|
-
});
|
|
399
|
-
return found;
|
|
400
|
-
}
|
|
401
|
-
|
|
402
315
|
/**
|
|
403
316
|
* Whether any of these doc files has a section that sets `id`.
|
|
404
317
|
* @param {string[]} files
|
|
@@ -472,15 +385,20 @@ async function validatePackedComponentExports(integration, scratchBase) {
|
|
|
472
385
|
const issues = [];
|
|
473
386
|
/** @type {Array<{name: string, specifier: string}>} */
|
|
474
387
|
const components = [];
|
|
388
|
+
// A family doc backs several records: load it, and report it, once.
|
|
389
|
+
const loads = new Map();
|
|
475
390
|
for (const record of records) {
|
|
391
|
+
const first = !loads.has(record.docPath);
|
|
392
|
+
if (first) loads.set(record.docPath, loadComponentDoc(record.docPath));
|
|
476
393
|
let docs;
|
|
477
394
|
try {
|
|
478
|
-
docs = await
|
|
395
|
+
docs = await loads.get(record.docPath);
|
|
479
396
|
} catch (err) {
|
|
397
|
+
if (!first) continue;
|
|
480
398
|
issues.push(
|
|
481
399
|
error(
|
|
482
400
|
'component_doc_unloadable',
|
|
483
|
-
`Component "${record.
|
|
401
|
+
`Component "${docStem(record.docPath)}" doc at "${record.docPath}" could not be loaded: ${err instanceof Error ? err.message : String(err)}`,
|
|
484
402
|
),
|
|
485
403
|
);
|
|
486
404
|
continue;
|
|
@@ -658,16 +576,22 @@ async function validateIncompleteThemeExports(
|
|
|
658
576
|
path.join(os.tmpdir(), `astryx-theme-${localTheme.slug}-`),
|
|
659
577
|
);
|
|
660
578
|
const expectedCss = path.join(expectedDir, `${localTheme.slug}.css`);
|
|
579
|
+
let expectedModule = path.join(expectedDir, `${localTheme.slug}.js`);
|
|
661
580
|
try {
|
|
662
581
|
if (outputs.some(output => output.kind !== 'font stylesheet')) {
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
);
|
|
582
|
+
// The scratch directory is the write root; the package stays the cwd,
|
|
583
|
+
// so the build selects the package's Core and its paths as before.
|
|
584
|
+
const scratchBuild = {out: expectedCss, __writeRoot: expectedDir};
|
|
585
|
+
const receipt = await themeBuild(source, scratchBuild, {cwd: packageDir});
|
|
668
586
|
if (receipt == null || receipt.type !== 'theme.build') {
|
|
669
587
|
throw new Error('the theme build produced no complete receipt');
|
|
670
588
|
}
|
|
589
|
+
expectedModule = builtModuleFile(
|
|
590
|
+
receipt,
|
|
591
|
+
packageDir,
|
|
592
|
+
expectedDir,
|
|
593
|
+
localTheme.slug,
|
|
594
|
+
);
|
|
671
595
|
}
|
|
672
596
|
for (const output of outputs) {
|
|
673
597
|
const localFile = /** @type {string} */ (output.inspected.target);
|
|
@@ -684,9 +608,7 @@ async function validateIncompleteThemeExports(
|
|
|
684
608
|
continue;
|
|
685
609
|
}
|
|
686
610
|
const expectedFile =
|
|
687
|
-
output.kind === 'module'
|
|
688
|
-
? path.join(expectedDir, `${localTheme.slug}.js`)
|
|
689
|
-
: expectedCss;
|
|
611
|
+
output.kind === 'module' ? expectedModule : expectedCss;
|
|
690
612
|
const expected = normalizeThemeVerifyForCompare(
|
|
691
613
|
fs.readFileSync(expectedFile, 'utf-8'),
|
|
692
614
|
);
|
|
@@ -702,7 +624,7 @@ async function validateIncompleteThemeExports(
|
|
|
702
624
|
output.kind === 'module'
|
|
703
625
|
? 'theme_module_stale'
|
|
704
626
|
: 'theme_stylesheet_stale',
|
|
705
|
-
`Theme "${localTheme.slug}" ${output.kind} does not match ${sourceRelative}. This incomplete export remains packable, but run
|
|
627
|
+
`Theme "${localTheme.slug}" ${output.kind} does not match ${sourceRelative}. This incomplete export remains packable, but run \`${formatCliCommand(`theme build ${sourceRelative}`, packageDir)}\` before adding its matching export.`,
|
|
706
628
|
),
|
|
707
629
|
);
|
|
708
630
|
}
|
|
@@ -721,7 +643,7 @@ async function validateIncompleteThemeExports(
|
|
|
721
643
|
issues.push(
|
|
722
644
|
error(
|
|
723
645
|
'theme_build_failed',
|
|
724
|
-
`Theme "${localTheme.slug}" could not be rebuilt from ${sourceRelative}: ${err instanceof Error ? err.message : String(err)} Run
|
|
646
|
+
`Theme "${localTheme.slug}" could not be rebuilt from ${sourceRelative}: ${err instanceof Error ? err.message : String(err)} Run \`${formatCliCommand(`theme build ${sourceRelative}`, packageDir)}\` before packing.`,
|
|
725
647
|
),
|
|
726
648
|
);
|
|
727
649
|
} finally {
|
|
@@ -730,6 +652,250 @@ async function validateIncompleteThemeExports(
|
|
|
730
652
|
return issues;
|
|
731
653
|
}
|
|
732
654
|
|
|
655
|
+
/**
|
|
656
|
+
* The module a scratch `theme build` wrote. Its file is named by the theme's
|
|
657
|
+
* own name, which can differ from the slug the package exports it under. A
|
|
658
|
+
* receipt that names no file inside the scratch directory falls back to the
|
|
659
|
+
* slug.
|
|
660
|
+
* @param {any} receipt
|
|
661
|
+
* @param {string} cwd the directory the build ran in
|
|
662
|
+
* @param {string} expectedDir
|
|
663
|
+
* @param {string} slug
|
|
664
|
+
* @returns {string}
|
|
665
|
+
*/
|
|
666
|
+
function builtModuleFile(receipt, cwd, expectedDir, slug) {
|
|
667
|
+
const written = receipt?.data?.outputs?.js;
|
|
668
|
+
if (typeof written === 'string') {
|
|
669
|
+
const file = path.resolve(cwd, written);
|
|
670
|
+
const relative = path.relative(expectedDir, file);
|
|
671
|
+
if (relative && !relative.startsWith('..') && !path.isAbsolute(relative)) {
|
|
672
|
+
return file;
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
return path.join(expectedDir, `${slug}.js`);
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
/**
|
|
679
|
+
* The `.js` file a relative module specifier names from `fromFile`, the
|
|
680
|
+
* extension `theme build` gives the built module: the exact path, the path
|
|
681
|
+
* with `.js`, or its `index.js`.
|
|
682
|
+
* @param {string} specifier
|
|
683
|
+
* @param {string} fromFile
|
|
684
|
+
* @returns {string | null}
|
|
685
|
+
*/
|
|
686
|
+
function resolveRelativeJsModule(specifier, fromFile) {
|
|
687
|
+
if (!specifier.startsWith('./') && !specifier.startsWith('../')) return null;
|
|
688
|
+
const base = path.resolve(path.dirname(fromFile), specifier);
|
|
689
|
+
const candidates = [base, `${base}.js`, path.join(base, 'index.js')];
|
|
690
|
+
return (
|
|
691
|
+
candidates.find(candidate => {
|
|
692
|
+
try {
|
|
693
|
+
return candidate.endsWith('.js') && fs.statSync(candidate).isFile();
|
|
694
|
+
} catch {
|
|
695
|
+
return false;
|
|
696
|
+
}
|
|
697
|
+
}) ?? null
|
|
698
|
+
);
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
/** @param {string} file */
|
|
702
|
+
function realFile(file) {
|
|
703
|
+
try {
|
|
704
|
+
return fs.realpathSync(file);
|
|
705
|
+
} catch {
|
|
706
|
+
return null;
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
/**
|
|
711
|
+
* The file a stylesheet import names: a relative path from the module, or a
|
|
712
|
+
* subpath of the package itself, resolved through its own exports.
|
|
713
|
+
* @param {string} specifier
|
|
714
|
+
* @param {string} moduleFile
|
|
715
|
+
* @param {{name?: string}} pkg
|
|
716
|
+
* @param {string} packageDir
|
|
717
|
+
* @returns {string | null}
|
|
718
|
+
*/
|
|
719
|
+
function resolveStylesheetImport(specifier, moduleFile, pkg, packageDir) {
|
|
720
|
+
if (specifier.startsWith('./') || specifier.startsWith('../')) {
|
|
721
|
+
const file = path.resolve(path.dirname(moduleFile), specifier);
|
|
722
|
+
try {
|
|
723
|
+
return fs.statSync(file).isFile() ? realFile(file) : null;
|
|
724
|
+
} catch {
|
|
725
|
+
return null;
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
if (typeof pkg.name !== 'string' || !specifier.startsWith(`${pkg.name}/`)) {
|
|
729
|
+
return null;
|
|
730
|
+
}
|
|
731
|
+
const exported = inspectPackageExport(
|
|
732
|
+
pkg,
|
|
733
|
+
packageDir,
|
|
734
|
+
`.${specifier.slice(pkg.name.length)}`,
|
|
735
|
+
);
|
|
736
|
+
return exported.exported && exported.target
|
|
737
|
+
? realFile(exported.target)
|
|
738
|
+
: null;
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
/**
|
|
742
|
+
* The theme binding of a built module: the name of its `export const`.
|
|
743
|
+
* @param {string} file
|
|
744
|
+
* @returns {string | null}
|
|
745
|
+
*/
|
|
746
|
+
function builtThemeBinding(file) {
|
|
747
|
+
try {
|
|
748
|
+
const ast = parseModule(fs.readFileSync(file, 'utf-8'), {
|
|
749
|
+
sourceType: 'module',
|
|
750
|
+
plugins: ['importAttributes'],
|
|
751
|
+
});
|
|
752
|
+
for (const node of ast.program.body) {
|
|
753
|
+
if (
|
|
754
|
+
node.type === 'ExportNamedDeclaration' &&
|
|
755
|
+
node.declaration?.type === 'VariableDeclaration'
|
|
756
|
+
) {
|
|
757
|
+
const id = node.declaration.declarations[0]?.id;
|
|
758
|
+
return id?.type === 'Identifier' ? id.name : null;
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
} catch {
|
|
762
|
+
// An unreadable module has no binding to match.
|
|
763
|
+
}
|
|
764
|
+
return null;
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
/** @param {any} node */
|
|
768
|
+
function exportedName(node) {
|
|
769
|
+
return node?.name ?? node?.value;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
/**
|
|
773
|
+
* Check a `.js` or `.mjs` theme module that is not the built module itself.
|
|
774
|
+
* It is accepted when it only loads the theme's own styles and re-exports the
|
|
775
|
+
* built module: each statement imports the theme's exported stylesheet or font
|
|
776
|
+
* stylesheet for its side effects, except one, which re-exports from a `.js`
|
|
777
|
+
* file that matches the built module either everything or only its theme,
|
|
778
|
+
* under the theme's export name. Returns null for any other file and for a module that
|
|
779
|
+
* re-exports nothing, and otherwise whether it is accepted. A
|
|
780
|
+
* rejection gives the reason, or, when only the re-exported module is stale,
|
|
781
|
+
* that module's specifier with `rebuild` set.
|
|
782
|
+
*
|
|
783
|
+
* @param {string} moduleFile
|
|
784
|
+
* @param {string} expected the built module, normalized for comparison
|
|
785
|
+
* @param {{exportName: string, stylesheetFile: string, fontStylesheetFile?: string, pkg: {name?: string}, packageDir: string}} theme
|
|
786
|
+
* @returns {{ok: true} | {ok: false, reason: string, rebuild: boolean} | null}
|
|
787
|
+
*/
|
|
788
|
+
function ownStylesEntry(moduleFile, expected, theme) {
|
|
789
|
+
if (!/\.m?js$/u.test(moduleFile)) return null;
|
|
790
|
+
let ast;
|
|
791
|
+
try {
|
|
792
|
+
ast = parseModule(fs.readFileSync(moduleFile, 'utf-8'), {
|
|
793
|
+
sourceType: 'module',
|
|
794
|
+
plugins: ['importAttributes'],
|
|
795
|
+
});
|
|
796
|
+
} catch {
|
|
797
|
+
return null;
|
|
798
|
+
}
|
|
799
|
+
const body = ast.program.body;
|
|
800
|
+
const reexports = body.filter(
|
|
801
|
+
(/** @type {any} */ node) =>
|
|
802
|
+
node.type === 'ExportAllDeclaration' ||
|
|
803
|
+
(node.type === 'ExportNamedDeclaration' && node.source != null),
|
|
804
|
+
);
|
|
805
|
+
if (reexports.length === 0) return null;
|
|
806
|
+
/** @param {string} reason @param {boolean} [rebuild] */
|
|
807
|
+
const reject = (reason, rebuild = false) => ({
|
|
808
|
+
ok: /** @type {const} */ (false),
|
|
809
|
+
reason,
|
|
810
|
+
rebuild,
|
|
811
|
+
});
|
|
812
|
+
if (reexports.length > 1) return reject('it has more than one re-export');
|
|
813
|
+
if ((ast.program.directives ?? []).length > 0) {
|
|
814
|
+
return reject('it has a directive');
|
|
815
|
+
}
|
|
816
|
+
const ownStylesheets = new Set(
|
|
817
|
+
[theme.stylesheetFile, theme.fontStylesheetFile]
|
|
818
|
+
.filter(file => file != null)
|
|
819
|
+
.map(file => realFile(/** @type {string} */ (file))),
|
|
820
|
+
);
|
|
821
|
+
const imported = new Set();
|
|
822
|
+
for (const node of body) {
|
|
823
|
+
if (node === reexports[0]) continue;
|
|
824
|
+
const line = node.loc?.start.line;
|
|
825
|
+
if (node.type !== 'ImportDeclaration') {
|
|
826
|
+
return reject(
|
|
827
|
+
`line ${line} is neither a stylesheet import nor the re-export`,
|
|
828
|
+
);
|
|
829
|
+
}
|
|
830
|
+
const specifier = node.source.value;
|
|
831
|
+
if (
|
|
832
|
+
node.importKind === 'type' ||
|
|
833
|
+
node.specifiers.length > 0 ||
|
|
834
|
+
(node.attributes ?? []).length > 0 ||
|
|
835
|
+
node.phase != null
|
|
836
|
+
) {
|
|
837
|
+
return reject(`its import of ${specifier} is not a side-effect import`);
|
|
838
|
+
}
|
|
839
|
+
const file = resolveStylesheetImport(
|
|
840
|
+
specifier,
|
|
841
|
+
moduleFile,
|
|
842
|
+
theme.pkg,
|
|
843
|
+
theme.packageDir,
|
|
844
|
+
);
|
|
845
|
+
if (!file || !ownStylesheets.has(file)) {
|
|
846
|
+
return reject(
|
|
847
|
+
`${specifier} is not the theme's own stylesheet or font stylesheet`,
|
|
848
|
+
);
|
|
849
|
+
}
|
|
850
|
+
if (imported.has(file)) return reject(`it imports ${specifier} twice`);
|
|
851
|
+
imported.add(file);
|
|
852
|
+
}
|
|
853
|
+
const reexport = /** @type {any} */ (reexports[0]);
|
|
854
|
+
const from = reexport.source.value;
|
|
855
|
+
/** @type {string | null} */
|
|
856
|
+
let reexported = null;
|
|
857
|
+
if (
|
|
858
|
+
reexport.exportKind === 'type' ||
|
|
859
|
+
(reexport.attributes ?? []).length > 0
|
|
860
|
+
) {
|
|
861
|
+
return reject(`its re-export from ${from} is not a plain re-export`);
|
|
862
|
+
}
|
|
863
|
+
if (reexport.type === 'ExportAllDeclaration') {
|
|
864
|
+
if (reexport.exported != null) {
|
|
865
|
+
return reject(`it re-exports ${from} as a namespace`);
|
|
866
|
+
}
|
|
867
|
+
} else {
|
|
868
|
+
const specifiers = reexport.specifiers ?? [];
|
|
869
|
+
if (
|
|
870
|
+
specifiers.length !== 1 ||
|
|
871
|
+
specifiers[0].type !== 'ExportSpecifier' ||
|
|
872
|
+
specifiers[0].exportKind === 'type' ||
|
|
873
|
+
exportedName(specifiers[0].exported) !== theme.exportName
|
|
874
|
+
) {
|
|
875
|
+
return reject(`it re-exports names other than ${theme.exportName}`);
|
|
876
|
+
}
|
|
877
|
+
reexported = exportedName(specifiers[0].local);
|
|
878
|
+
}
|
|
879
|
+
const target = resolveRelativeJsModule(from, moduleFile);
|
|
880
|
+
if (!target) {
|
|
881
|
+
return reject(`its re-export from ${from} does not name a .js module`);
|
|
882
|
+
}
|
|
883
|
+
if (
|
|
884
|
+
normalizeThemeVerifyForCompare(fs.readFileSync(target, 'utf-8')) !==
|
|
885
|
+
expected
|
|
886
|
+
) {
|
|
887
|
+
return reject(from, true);
|
|
888
|
+
}
|
|
889
|
+
// `theme build` names the theme's export after the theme's own name, which
|
|
890
|
+
// can differ from its slug, so a named re-export may give that export the
|
|
891
|
+
// slug's export name. It must be the theme, not another export of the built
|
|
892
|
+
// module, such as its icon registry.
|
|
893
|
+
if (reexported != null && reexported !== builtThemeBinding(target)) {
|
|
894
|
+
return reject(`it re-exports ${reexported}, which is not the built theme`);
|
|
895
|
+
}
|
|
896
|
+
return {ok: /** @type {const} */ (true)};
|
|
897
|
+
}
|
|
898
|
+
|
|
733
899
|
/**
|
|
734
900
|
* Prove local theme exports are fresh, prove the same exports resolve from the
|
|
735
901
|
* tarball, and reject lifecycle changes to source or built output bytes.
|
|
@@ -796,7 +962,7 @@ async function validatePackedThemeExports(
|
|
|
796
962
|
issues.push(
|
|
797
963
|
warning(
|
|
798
964
|
'theme_exports_missing',
|
|
799
|
-
`Theme "${localTheme.slug}" has no declared built exports. The package remains source-compatible. To make it importable, run
|
|
965
|
+
`Theme "${localTheme.slug}" has no declared built exports. The package remains source-compatible. To make it importable, run \`${formatCliCommand(`theme build ${sourceRelative}`, localIntegration.__packageDir)}\` and export "./themes/${localTheme.slug}" plus "./themes/${localTheme.slug}.css" from package.json; \`${formatCliCommand(`integration add theme ${localTheme.slug}`, localIntegration.__packageDir)}\` creates those exports for a new theme.`,
|
|
800
966
|
),
|
|
801
967
|
);
|
|
802
968
|
continue;
|
|
@@ -836,7 +1002,7 @@ async function validatePackedThemeExports(
|
|
|
836
1002
|
err instanceof ThemeImportError
|
|
837
1003
|
? 'theme_import_unresolvable'
|
|
838
1004
|
: 'theme_import_invalid',
|
|
839
|
-
`${message} Run
|
|
1005
|
+
`${message} Run \`${formatCliCommand(`theme build ${sourceRelative}`, localIntegration.__packageDir)}\` before packing.`,
|
|
840
1006
|
),
|
|
841
1007
|
);
|
|
842
1008
|
continue;
|
|
@@ -847,21 +1013,27 @@ async function validatePackedThemeExports(
|
|
|
847
1013
|
);
|
|
848
1014
|
const expectedCss = path.join(expectedDir, `${localTheme.slug}.css`);
|
|
849
1015
|
try {
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
1016
|
+
// The scratch directory is the write root; the package stays the cwd,
|
|
1017
|
+
// so the build selects the package's Core and its paths as before.
|
|
1018
|
+
const scratchBuild = {out: expectedCss, __writeRoot: expectedDir};
|
|
1019
|
+
const receipt = await themeBuild(source, scratchBuild, {
|
|
1020
|
+
cwd: localIntegration.__packageDir,
|
|
1021
|
+
});
|
|
855
1022
|
if (receipt == null || receipt.type !== 'theme.build') {
|
|
856
1023
|
issues.push(
|
|
857
1024
|
error(
|
|
858
1025
|
'theme_build_failed',
|
|
859
|
-
`Theme "${localTheme.slug}" did not produce a complete build. Run
|
|
1026
|
+
`Theme "${localTheme.slug}" did not produce a complete build. Run \`${formatCliCommand(`theme build ${sourceRelative}`, localIntegration.__packageDir)}\` before packing.`,
|
|
860
1027
|
),
|
|
861
1028
|
);
|
|
862
1029
|
continue;
|
|
863
1030
|
}
|
|
864
|
-
const expectedModule =
|
|
1031
|
+
const expectedModule = builtModuleFile(
|
|
1032
|
+
receipt,
|
|
1033
|
+
localIntegration.__packageDir,
|
|
1034
|
+
expectedDir,
|
|
1035
|
+
localTheme.slug,
|
|
1036
|
+
);
|
|
865
1037
|
/** @type {Array<{kind: string, expected: string, local: string, packed: string, staleCode: string, packedCode: string}>} */
|
|
866
1038
|
const buildOutputs = [
|
|
867
1039
|
{
|
|
@@ -881,6 +1053,20 @@ async function validatePackedThemeExports(
|
|
|
881
1053
|
packedCode: 'packed_theme_stylesheet_changed',
|
|
882
1054
|
},
|
|
883
1055
|
];
|
|
1056
|
+
const localEntry = {
|
|
1057
|
+
exportName: localTheme.exportName,
|
|
1058
|
+
stylesheetFile: localImports.stylesheetFile,
|
|
1059
|
+
fontStylesheetFile: localImports.fontStylesheetFile,
|
|
1060
|
+
pkg: integrationPackageMetadata(localIntegration),
|
|
1061
|
+
packageDir: localIntegration.__packageDir,
|
|
1062
|
+
};
|
|
1063
|
+
const packedEntry = {
|
|
1064
|
+
exportName: packedTheme.exportName,
|
|
1065
|
+
stylesheetFile: packedImports.stylesheetFile,
|
|
1066
|
+
fontStylesheetFile: packedImports.fontStylesheetFile,
|
|
1067
|
+
pkg: integrationPackageMetadata(packedIntegration),
|
|
1068
|
+
packageDir: packedIntegration.__packageDir,
|
|
1069
|
+
};
|
|
884
1070
|
for (const output of buildOutputs) {
|
|
885
1071
|
const expected = normalizeThemeVerifyForCompare(
|
|
886
1072
|
fs.readFileSync(output.expected, 'utf-8'),
|
|
@@ -891,15 +1077,31 @@ async function validatePackedThemeExports(
|
|
|
891
1077
|
const packed = normalizeThemeVerifyForCompare(
|
|
892
1078
|
fs.readFileSync(output.packed, 'utf-8'),
|
|
893
1079
|
);
|
|
894
|
-
|
|
1080
|
+
// A module that is not the built module may still be an entry that
|
|
1081
|
+
// loads the theme's own styles and re-exports the built module.
|
|
1082
|
+
const localWrapper =
|
|
1083
|
+
output.kind === 'module' && expected !== local
|
|
1084
|
+
? ownStylesEntry(output.local, expected, localEntry)
|
|
1085
|
+
: null;
|
|
1086
|
+
const packedWrapper =
|
|
1087
|
+
output.kind === 'module' && expected !== packed
|
|
1088
|
+
? ownStylesEntry(output.packed, expected, packedEntry)
|
|
1089
|
+
: null;
|
|
1090
|
+
const localMatches = expected === local || localWrapper?.ok === true;
|
|
1091
|
+
const packedMatches = expected === packed || packedWrapper?.ok === true;
|
|
1092
|
+
if (!localMatches) {
|
|
895
1093
|
issues.push(
|
|
896
1094
|
error(
|
|
897
1095
|
output.staleCode,
|
|
898
|
-
|
|
1096
|
+
localWrapper && !localWrapper.ok && !localWrapper.rebuild
|
|
1097
|
+
? `Theme "${localTheme.slug}" module is not the module \`${formatCliCommand(`theme build ${sourceRelative}`, localIntegration.__packageDir)}\` writes and does not only wrap it: ${localWrapper.reason}. A module that wraps the built module may only import the theme's own stylesheet and font stylesheet for their side effects and re-export from the built module either everything or only its theme, as ${localTheme.exportName}.`
|
|
1098
|
+
: localWrapper && !localWrapper.ok
|
|
1099
|
+
? `Theme "${localTheme.slug}" module re-exports ${localWrapper.reason}, which does not match ${sourceRelative}. Run \`${formatCliCommand(`theme build ${sourceRelative}`, localIntegration.__packageDir)}\` before packing.`
|
|
1100
|
+
: `Theme "${localTheme.slug}" ${output.kind} does not match ${sourceRelative}. Run \`${formatCliCommand(`theme build ${sourceRelative}`, localIntegration.__packageDir)}\` before packing.`,
|
|
899
1101
|
),
|
|
900
1102
|
);
|
|
901
1103
|
}
|
|
902
|
-
if (local !== packed) {
|
|
1104
|
+
if (local !== packed || (localMatches && !packedMatches)) {
|
|
903
1105
|
issues.push(
|
|
904
1106
|
error(
|
|
905
1107
|
output.packedCode,
|
|
@@ -927,7 +1129,7 @@ async function validatePackedThemeExports(
|
|
|
927
1129
|
issues.push(
|
|
928
1130
|
error(
|
|
929
1131
|
'theme_build_failed',
|
|
930
|
-
`Theme "${localTheme.slug}" could not be rebuilt from ${sourceRelative}: ${err instanceof Error ? err.message : String(err)} Run
|
|
1132
|
+
`Theme "${localTheme.slug}" could not be rebuilt from ${sourceRelative}: ${err instanceof Error ? err.message : String(err)} Run \`${formatCliCommand(`theme build ${sourceRelative}`, localIntegration.__packageDir)}\` before packing.`,
|
|
931
1133
|
),
|
|
932
1134
|
);
|
|
933
1135
|
} finally {
|
|
@@ -1085,6 +1287,24 @@ export async function integrationPackCheck(options = {}) {
|
|
|
1085
1287
|
const fileInv = computeRequiredFiles(loaded);
|
|
1086
1288
|
const {identities: localIdentities, errors: localDiscoveryErrors} =
|
|
1087
1289
|
await collectIdentities(loaded);
|
|
1290
|
+
// A family lists its members from the module its import names, which the
|
|
1291
|
+
// pack lifecycle may build or rebuild, so they are compared as local
|
|
1292
|
+
// discovery lists them after the pack.
|
|
1293
|
+
const familiesBefore = familyImports(loaded).map(family => family.docPath);
|
|
1294
|
+
/**
|
|
1295
|
+
* @param {Array<{name: string, docPath: string|null}>} records
|
|
1296
|
+
* @param {Set<string>} families
|
|
1297
|
+
*/
|
|
1298
|
+
const membersOf = (records, families) =>
|
|
1299
|
+
records
|
|
1300
|
+
.filter(
|
|
1301
|
+
r =>
|
|
1302
|
+
r.docPath != null &&
|
|
1303
|
+
families.has(r.docPath) &&
|
|
1304
|
+
isIntegrationMember(r),
|
|
1305
|
+
)
|
|
1306
|
+
.map(r => r.name);
|
|
1307
|
+
const recordsBefore = discoverIntegrationComponents(loaded);
|
|
1088
1308
|
for (const discoveryError of localDiscoveryErrors) {
|
|
1089
1309
|
issues.push(
|
|
1090
1310
|
error(
|
|
@@ -1320,6 +1540,10 @@ export async function integrationPackCheck(options = {}) {
|
|
|
1320
1540
|
code: `packed_${issue.code}`,
|
|
1321
1541
|
severity: issue.severity,
|
|
1322
1542
|
message: `Packed: ${issue.message}`,
|
|
1543
|
+
// The packed tree keeps the package's own paths.
|
|
1544
|
+
...(issue.fix != null ? {fix: issue.fix} : {}),
|
|
1545
|
+
...(issue.file != null ? {file: issue.file} : {}),
|
|
1546
|
+
...(issue.line != null ? {line: issue.line} : {}),
|
|
1323
1547
|
});
|
|
1324
1548
|
}
|
|
1325
1549
|
|
|
@@ -1345,7 +1569,27 @@ export async function integrationPackCheck(options = {}) {
|
|
|
1345
1569
|
);
|
|
1346
1570
|
}
|
|
1347
1571
|
|
|
1348
|
-
|
|
1572
|
+
const families = new Set([
|
|
1573
|
+
...familiesBefore,
|
|
1574
|
+
...familyImports(loaded).map(family => family.docPath),
|
|
1575
|
+
]);
|
|
1576
|
+
let localComponents = localIdentities.components;
|
|
1577
|
+
if (families.size > 0) {
|
|
1578
|
+
const stale = new Set(membersOf(recordsBefore, families));
|
|
1579
|
+
const built = new Set(
|
|
1580
|
+
membersOf(discoverIntegrationComponents(loaded), families),
|
|
1581
|
+
);
|
|
1582
|
+
const {identities: afterPack} = await collectIdentities(loaded);
|
|
1583
|
+
localComponents = [
|
|
1584
|
+
...new Set([
|
|
1585
|
+
...localComponents.filter(name => !stale.has(name)),
|
|
1586
|
+
...afterPack.components.filter(name => built.has(name)),
|
|
1587
|
+
]),
|
|
1588
|
+
].sort();
|
|
1589
|
+
}
|
|
1590
|
+
// The receipt reports the local inventory that was compared.
|
|
1591
|
+
const comparedLocal = {...localIdentities, components: localComponents};
|
|
1592
|
+
issues.push(...compareIdentities(comparedLocal, packedIdentities));
|
|
1349
1593
|
issues.push(
|
|
1350
1594
|
...(await validatePackedThemeExports(
|
|
1351
1595
|
loaded,
|
|
@@ -1367,7 +1611,7 @@ export async function integrationPackCheck(options = {}) {
|
|
|
1367
1611
|
pkgVersion,
|
|
1368
1612
|
fileInv,
|
|
1369
1613
|
packResult,
|
|
1370
|
-
|
|
1614
|
+
comparedLocal,
|
|
1371
1615
|
packedIdentities,
|
|
1372
1616
|
issues,
|
|
1373
1617
|
);
|