@astryxdesign/cli 0.7.2-canary.fe2c655 → 0.7.3-canary.02f5fe4
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 +216 -162
- package/api/build/_adapter.d.mts +66 -0
- package/api/build/_adapter.mjs +139 -4
- package/api/build/blocks/blocks.d.mts +92 -0
- package/api/build/blocks/blocks.mjs +528 -0
- package/api/build/blocks/blocks.test.mjs +238 -0
- package/api/build/blocks/blocks.weights.json +1 -0
- package/api/build/build.doc.mjs +4 -0
- package/api/build/build.mjs +25 -6
- package/api/build/build.type.mjs +1 -1
- package/api/build/help/help.mjs +1 -1
- package/api/build/kit/answer.d.mts +18 -0
- package/api/build/kit/answer.mjs +195 -0
- package/api/build/kit/answer.test.mjs +108 -0
- package/api/build/kit/kind.d.mts +25 -0
- package/api/build/kit/kind.mjs +170 -0
- package/api/build/kit/kit.d.mts +2 -4
- package/api/build/kit/kit.mjs +8 -406
- package/api/build/kit/rank.d.mts +3 -32
- package/api/build/kit/rank.mjs +25 -342
- package/api/build/kit/rank.test.mjs +2 -1
- package/api/build/kit/signals.d.mts +79 -0
- package/api/build/kit/signals.mjs +295 -0
- package/api/build/kit/start.d.mts +32 -0
- package/api/build/kit/start.mjs +163 -0
- package/api/build/kit/words.d.mts +72 -0
- package/api/build/kit/words.mjs +202 -0
- package/api/build/tree.d.mts +20 -0
- package/api/build/tree.mjs +53 -0
- package/api/build/tree.test.mjs +185 -0
- package/api/build/tree.weights.json +1 -0
- package/api/component/_adapter.d.mts +72 -1
- package/api/component/_adapter.mjs +251 -23
- package/api/component/component-replacement.test.mjs +1 -0
- package/api/component/component.doc.mjs +6 -1
- package/api/component/component.mjs +97 -16
- package/api/component/component.test.mjs +95 -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 +131 -12
- package/api/discover/_adapter.mjs +520 -34
- package/api/discover/_adapter.test.mjs +641 -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 +120 -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 +76 -2
- package/api/docs/_adapter.mjs +630 -34
- package/api/docs/docs-homes.test.mjs +127 -0
- package/api/docs/docs.doc.mjs +5 -4
- package/api/docs/docs.mjs +2 -1
- package/api/docs/docs.test.mjs +39 -20
- package/api/docs/integration-tree.test.mjs +42 -20
- package/api/docs/integrationDocs.test.mjs +125 -1
- package/api/docs/list/list.mjs +12 -2
- package/api/docs/namespace-section.test.mjs +6 -6
- package/api/docs/reference-blocks.test.mjs +3 -5
- package/api/doctor/_adapter.d.mts +128 -0
- package/api/doctor/_adapter.mjs +253 -4
- package/api/doctor/doctor.d.mts +217 -0
- package/api/doctor/doctor.doc.mjs +3 -2
- package/api/doctor/doctor.mjs +691 -52
- package/api/doctor/doctor.test.mjs +267 -18
- 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/hook.mjs +1 -1
- 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 +45 -10
- package/api/init/init.mjs +28 -4
- package/api/init/init.test.mjs +18 -2
- package/api/init/init.type.d.mts +50 -5
- package/api/init/init.type.mjs +39 -5
- package/api/init/remove/remove.mjs +17 -4
- package/api/init/remove/remove.test.mjs +114 -2
- package/api/init/run/run.d.mts +1 -1
- package/api/init/run/run.mjs +86 -12
- 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 +53 -0
- package/api/integration/_adapter.mjs +132 -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 +192 -14
- package/api/integration/authoring-checks.test.mjs +1028 -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 +486 -123
- package/api/integration/pack-check.test.mjs +817 -10
- package/api/integration/validate-integration-case-disk.test.mjs +111 -0
- package/api/integration/validate-integration-fixes.test.mjs +73 -5
- package/api/integration/validate-integration-gaps.test.mjs +1975 -0
- package/api/integration/validate-integration.d.mts +23 -2
- package/api/integration/validate-integration.mjs +358 -45
- package/api/integration/validate-integration.test.mjs +88 -8
- package/api/integration/validate-integration.type.d.mts +105 -0
- package/api/integration/validate-integration.type.mjs +79 -1
- package/api/integration/validate-unread-theme-folders.test.mjs +3 -2
- package/api/integration/validateIntegration.doc.mjs +19 -3
- package/api/search/ORDERING.md +28 -0
- package/api/search/_adapter.d.mts +91 -0
- package/api/search/_adapter.mjs +172 -0
- package/api/search/_adapter.test.mjs +173 -0
- package/api/search/_candidate-score.d.mts +40 -0
- package/api/search/_candidate-score.mjs +238 -0
- package/api/search/_cards.json +6098 -0
- package/api/search/_compound.d.mts +50 -0
- package/api/search/_compound.mjs +170 -0
- package/api/search/_doc-searcher.d.mts +4 -0
- package/api/search/_doc-searcher.mjs +23 -0
- package/api/search/_doc-searcher.test.mjs +36 -0
- package/api/search/_doc-searcher.weights.json +1 -0
- package/api/search/_doc-text.d.mts +30 -0
- package/api/search/_doc-text.mjs +87 -0
- package/api/search/_entries.d.mts +63 -0
- package/api/search/_entries.mjs +232 -0
- package/api/search/_entries.test.mjs +48 -0
- package/api/search/_features.d.mts +35 -0
- package/api/search/_features.mjs +155 -0
- package/api/search/_gather-components.d.mts +26 -0
- package/api/search/_gather-components.mjs +284 -0
- package/api/search/_gather-docs.d.mts +20 -0
- package/api/search/_gather-docs.mjs +254 -0
- package/api/search/_gather-hooks.d.mts +12 -0
- package/api/search/_gather-hooks.mjs +52 -0
- package/api/search/_gather-templates.d.mts +25 -0
- package/api/search/_gather-templates.mjs +107 -0
- package/api/search/_lexical.d.mts +135 -0
- package/api/search/_lexical.mjs +351 -0
- package/api/search/_main-searcher.d.mts +19 -0
- package/api/search/_main-searcher.mjs +115 -0
- package/api/search/_main-searcher.test.mjs +106 -0
- package/api/search/_main-searcher.weights.json +1 -0
- package/api/search/_module-doc.d.mts +32 -0
- package/api/search/_module-doc.mjs +78 -0
- package/api/search/_order.d.mts +32 -0
- package/api/search/_order.mjs +162 -0
- package/api/search/_order.test.mjs +72 -0
- package/api/search/_priority.d.mts +50 -0
- package/api/search/_priority.mjs +139 -0
- package/api/search/_query-words.d.mts +25 -0
- package/api/search/_query-words.mjs +92 -0
- package/api/search/_query.d.mts +65 -0
- package/api/search/_query.mjs +176 -0
- package/api/search/_result.d.mts +97 -0
- package/api/search/_result.mjs +150 -0
- package/api/search/_score.d.mts +60 -0
- package/api/search/_score.mjs +283 -0
- package/api/search/_synonyms.d.mts +21 -0
- package/api/search/_synonyms.mjs +67 -0
- package/api/search/_template-searcher.d.mts +4 -0
- package/api/search/_template-searcher.mjs +23 -0
- package/api/search/_template-searcher.test.mjs +40 -0
- package/api/search/_template-searcher.weights.json +1 -0
- package/api/search/_titles.d.mts +33 -0
- package/api/search/_titles.mjs +65 -0
- package/api/search/_words.d.mts +64 -0
- package/api/search/_words.mjs +157 -0
- package/api/search/search.d.mts +22 -236
- package/api/search/search.doc.mjs +14 -7
- 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 +59 -1904
- package/api/search/search.test.mjs +193 -15
- package/api/search/search.type.d.mts +20 -2
- package/api/search/search.type.mjs +12 -2
- package/api/search/tree.d.mts +15 -0
- package/api/search/tree.mjs +40 -0
- package/api/search/tree.test.mjs +66 -0
- package/api/search/tree.weights.json +1 -0
- 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.mjs +5 -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 +21 -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 +97 -11
- package/api/upgrade/_adapter.mjs +315 -32
- package/api/upgrade/registry/registry.d.mts +10 -4
- package/api/upgrade/registry/registry.mjs +33 -16
- package/api/upgrade/registry/registry.test.mjs +85 -0
- package/api/upgrade/run/cli-behind-core.test.mjs +438 -0
- package/api/upgrade/run/run.d.mts +4 -2
- package/api/upgrade/run/run.mjs +48 -4
- package/api/upgrade/run/run.test.mjs +417 -3
- package/api/upgrade/status/status.d.mts +21 -5
- package/api/upgrade/status/status.mjs +45 -8
- package/api/upgrade/upgrade.doc.mjs +16 -8
- package/api/upgrade/upgrade.mjs +18 -3
- package/api/upgrade/upgrade.test.mjs +194 -0
- package/api/upgrade/upgrade.type.d.mts +28 -3
- package/api/upgrade/upgrade.type.mjs +24 -7
- 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.0/__tests__/validate-data-token-ownership.test.mjs +11 -0
- package/assets/codemods/transforms/v0.7.0/validate-data-token-ownership.mjs +3 -3
- 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 +5 -5
- package/assets/docs/browser-support.doc.mjs +1 -1
- package/assets/docs/getting-started.doc.mjs +26 -6
- package/assets/docs/is-my-code-good.doc.mjs +287 -0
- 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 +14 -4
- 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/api.doc.mjs +6 -0
- package/assets/docs/tree/authoring.doc.mjs +61 -0
- 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 +6 -2
- 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 +101 -0
- package/assets/docs/tree/cli-command.doc.mjs +142 -0
- package/assets/docs/tree/cli.doc.mjs +7 -1
- 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 +8 -4
- package/assets/docs/tree/debug-and-gap-reports.doc.mjs +41 -22
- package/assets/docs/tree/define-the-theme.doc.mjs +7 -6
- 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 +4 -4
- 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/{authoring.doc.mjs → tree/field-reference.doc.mjs} +4 -3
- package/assets/docs/tree/fonts-and-assets.doc.mjs +3 -3
- package/assets/docs/tree/generate-a-palette.doc.mjs +8 -6
- 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/help.doc.mjs +2 -2
- package/assets/docs/tree/host-entry.doc.mjs +128 -0
- package/assets/docs/tree/install-once.doc.mjs +105 -0
- 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 +54 -28
- 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/ship.doc.mjs +2 -2
- 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-grading-rubric.doc.mjs +17 -38
- 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 +5 -1
- package/assets/docs/tree/tokens-and-setup.doc.mjs +19 -15
- package/assets/docs/tree/tokens-data.doc.mjs +2 -2
- 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 +15 -3
- package/assets/docs/tree/verify-packed-template.doc.mjs +3 -3
- package/assets/docs/tree/versioning.doc.mjs +14 -9
- package/assets/docs/tree/who-answers.doc.mjs +119 -0
- package/assets/docs/tree/write-good-templates.doc.mjs +1 -1
- 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/use-integrations.doc.mjs +120 -0
- package/assets/docs/working-with-ai.doc.mjs +70 -13
- package/assets/templates/themes/butter/butterTheme.ts +4 -2
- package/assets/templates/themes/stone/stoneTheme.ts +4 -2
- package/assets/templates/themes/y2k/y2kTheme.ts +4 -2
- 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 +10 -10
- 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 +13 -1
- package/clients/cli/bin/astryx.mjs +11 -65
- package/clients/cli/cli-command.test.mjs +166 -0
- package/clients/cli/command-result-coverage.test.mjs +6 -5
- 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.color-scheme.test.mjs +1 -1
- package/clients/cli/commands/build-theme.font-warning.test.mjs +3 -3
- 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/{component/index.mjs → component.mjs} +37 -37
- package/clients/cli/commands/component.test.mjs +6 -6
- 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 +3 -2
- package/clients/cli/commands/docs.mjs +50 -20
- package/clients/cli/commands/docs.test.mjs +16 -16
- 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 +936 -3
- package/clients/cli/commands/doctor.doc.mjs +12 -2
- package/clients/cli/commands/doctor.mjs +332 -7
- package/clients/cli/commands/doctor.test.mjs +75 -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/{hook/index.mjs → hook.mjs} +22 -22
- package/clients/cli/commands/import-hint-correctness.test.mjs +1 -1
- package/clients/cli/commands/init.behavior.test.mjs +235 -1
- package/clients/cli/commands/init.doc.mjs +55 -10
- package/clients/cli/commands/init.flag-help.test.mjs +1 -0
- package/clients/cli/commands/init.mjs +2 -2
- 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 +489 -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 +2 -1
- package/clients/cli/commands/manifest.mjs +67 -0
- package/clients/cli/commands/outside-project.test.mjs +874 -0
- package/clients/cli/commands/postinstall.doc.mjs +23 -0
- package/clients/cli/commands/postinstall.mjs +31 -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 +180 -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/{build-theme.mjs → theme.mjs} +27 -14
- package/clients/cli/commands/upgrade.config-ordering.test.mjs +2 -1
- package/clients/cli/commands/upgrade.doc.mjs +26 -3
- 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.mjs +9 -2
- package/clients/cli/commands/upgrade.older-cli.test.mjs +160 -0
- package/clients/cli/commands/upgrade.subfolder-path.test.mjs +97 -0
- package/clients/cli/index.mjs +156 -100
- package/clients/cli/lib/cli-error.mjs +4 -1
- package/clients/cli/lib/component-format.mjs +1 -1
- package/clients/cli/lib/component-format.test.mjs +1 -1
- package/clients/cli/lib/define-command.mjs +14 -9
- package/clients/cli/lib/exit-codes.test.mjs +5 -0
- 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 +37 -0
- package/clients/cli/lib/welcome-box.mjs +50 -0
- package/clients/cli/run.mjs +108 -0
- package/foundation/agent-docs/agent-doc-state.d.mts +67 -13
- package/foundation/agent-docs/agent-doc-state.mjs +123 -14
- package/foundation/agent-docs/agent-docs.d.mts +104 -15
- package/foundation/agent-docs/agent-docs.mjs +1028 -114
- package/foundation/agent-docs/agent-docs.path-safety.test.mjs +1239 -17
- package/foundation/agent-docs/agent-docs.test.mjs +683 -39
- package/foundation/agent-docs/computer-agent-text.d.mts +170 -0
- package/foundation/agent-docs/computer-agent-text.mjs +750 -0
- package/foundation/agent-docs/computer-agent-text.test.mjs +699 -0
- package/foundation/config/project.d.mts +35 -3
- package/foundation/config/project.mjs +243 -26
- package/foundation/config/project.test.mjs +122 -0
- package/foundation/config/theme-state.mjs +5 -4
- package/foundation/discovery/authoring-self-docs.d.mts +7 -0
- package/foundation/discovery/authoring-self-docs.mjs +17 -4
- package/foundation/discovery/authoring-self-docs.test.mjs +15 -3
- package/foundation/discovery/authoring-surface.d.mts +1 -1
- package/foundation/discovery/authoring-surface.mjs +2 -2
- package/foundation/discovery/authoring-surface.test.mjs +1 -1
- package/foundation/discovery/cli-self-docs.d.mts +2 -1
- package/foundation/discovery/cli-self-docs.mjs +22 -4
- package/foundation/discovery/cli-self-docs.test.mjs +3 -2
- package/foundation/discovery/component-discovery.d.mts +227 -10
- package/foundation/discovery/component-discovery.export-names.test.mjs +760 -0
- package/foundation/discovery/component-discovery.mjs +940 -57
- package/foundation/discovery/component-discovery.test.mjs +96 -0
- package/foundation/discovery/component-loader.d.mts +1 -1
- 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 +97 -3
- 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 +68 -0
- package/foundation/discovery/module-exports.mjs +609 -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 +38 -0
- package/foundation/discovery/runner-allowlist.mjs +51 -0
- package/foundation/discovery/runner-commands.d.mts +77 -0
- package/foundation/discovery/runner-commands.mjs +294 -0
- package/foundation/discovery/runner-commands.test.mjs +128 -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 +92 -6
- package/foundation/discovery/template-needs.mjs +6 -46
- package/foundation/discovery/theme-discovery.mjs +147 -3
- 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 +84 -10
- 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/read.mjs +59 -1
- package/foundation/doc-compiler/read.test.mjs +11 -2
- package/foundation/doc-compiler/split-topic-keywords.test.mjs +3 -2
- package/foundation/doc-compiler/tree.d.mts +32 -6
- package/foundation/doc-compiler/tree.mjs +107 -44
- package/foundation/doc-compiler/tree.test.mjs +14 -7
- 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 +122 -4
- package/foundation/fs/paths.mjs +675 -29
- package/foundation/fs/paths.test.mjs +439 -54
- package/foundation/fs/read-record.d.mts +18 -0
- package/foundation/fs/read-record.mjs +131 -0
- package/foundation/fs/read-record.test.mjs +77 -0
- package/foundation/integrations/autolink.d.mts +2 -1
- package/foundation/integrations/autolink.mjs +4 -13
- package/foundation/integrations/cli-peer-version.d.mts +36 -0
- package/foundation/integrations/cli-peer-version.mjs +132 -0
- package/foundation/integrations/cli-peer-version.test.mjs +354 -0
- package/foundation/integrations/computer-integrations.d.mts +81 -0
- package/foundation/integrations/computer-integrations.mjs +345 -0
- package/foundation/integrations/computer-integrations.test.mjs +292 -0
- package/foundation/integrations/contribution-inventory.d.mts +26 -20
- package/foundation/integrations/contribution-inventory.mjs +97 -8
- package/foundation/integrations/exports-subpaths.d.mts +57 -0
- package/foundation/integrations/exports-subpaths.mjs +113 -0
- package/foundation/integrations/integration-warnings.mjs +3 -2
- package/foundation/integrations/integration-warnings.test.mjs +8 -9
- package/foundation/integrations/integrations.d.mts +51 -1
- package/foundation/integrations/integrations.mjs +106 -4
- package/foundation/integrations/issue.ts +6 -0
- package/foundation/integrations/public-imports.d.mts +118 -0
- package/foundation/integrations/public-imports.mjs +1769 -0
- package/foundation/integrations/public-imports.test.mjs +1793 -0
- package/foundation/integrations/validate-contributions.d.mts +117 -0
- package/foundation/integrations/validate-contributions.mjs +1209 -14
- 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 +923 -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 +263 -0
- package/foundation/release/global-state.mjs +474 -0
- package/foundation/release/global-state.test.mjs +381 -0
- package/foundation/release/handoff.d.mts +79 -0
- package/foundation/release/handoff.e2e.test.mjs +278 -0
- package/foundation/release/handoff.mjs +524 -0
- package/foundation/release/lock-lease.d.mts +23 -0
- package/foundation/release/lock-lease.mjs +80 -0
- package/foundation/release/notices.d.mts +307 -0
- package/foundation/release/notices.mjs +707 -0
- package/foundation/release/notices.test.mjs +586 -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 +163 -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/route/route.d.mts +285 -0
- package/foundation/route/route.mjs +324 -0
- package/foundation/route/route.test.mjs +153 -0
- package/foundation/runtime/hosted-runtime.test.mjs +403 -0
- package/foundation/runtime/locked-versions.d.mts +32 -0
- package/foundation/runtime/locked-versions.mjs +65 -0
- package/foundation/runtime/package-root.d.mts +91 -0
- package/foundation/runtime/package-root.mjs +174 -0
- package/foundation/runtime/package-set.d.mts +62 -0
- package/foundation/runtime/package-set.mjs +130 -0
- package/foundation/runtime/package-set.test.mjs +432 -0
- package/foundation/text/string-utils.d.mts +2 -1
- package/foundation/text/string-utils.mjs +16 -5
- package/foundation/text/suggest-order.d.mts +72 -0
- package/foundation/text/suggest-order.mjs +363 -0
- package/foundation/text/suggest-order.test.mjs +259 -0
- 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/host/door-conformance.test.mjs +274 -0
- package/host/index.d.ts +116 -0
- package/host/index.mjs +295 -0
- package/host/index.test.mjs +302 -0
- package/package.json +16 -11
- package/scripts/postinstall.mjs +24 -5
- package/assets/docs/tree/integrations.doc.mjs +0 -40
|
@@ -24,9 +24,13 @@ 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';
|
|
29
|
+
import {
|
|
30
|
+
literalThemeName,
|
|
31
|
+
rootProblem,
|
|
32
|
+
symlinkedFolder,
|
|
33
|
+
} from '../../foundation/integrations/validate-contributions.mjs';
|
|
30
34
|
import {
|
|
31
35
|
componentReplacesCliProblem,
|
|
32
36
|
docsTreeCliProblem,
|
|
@@ -41,6 +45,8 @@ import {
|
|
|
41
45
|
} from '../../foundation/discovery/docs-discovery.mjs';
|
|
42
46
|
import {discoverIntegrationThemes} from '../../foundation/discovery/theme-discovery.mjs';
|
|
43
47
|
import {inspectPackageExport} from '../../foundation/discovery/package-exports.mjs';
|
|
48
|
+
import {parse as parseModule} from '@babel/parser';
|
|
49
|
+
import {moduleExportsName} from '../../foundation/discovery/module-exports.mjs';
|
|
44
50
|
import {
|
|
45
51
|
ThemeImportError,
|
|
46
52
|
resolveThemeImports,
|
|
@@ -51,6 +57,9 @@ import {
|
|
|
51
57
|
} from '../theme/build/build.mjs';
|
|
52
58
|
import {
|
|
53
59
|
discoverIntegrationComponents,
|
|
60
|
+
docStem,
|
|
61
|
+
familyImports,
|
|
62
|
+
isIntegrationMember,
|
|
54
63
|
resolveIntegrationImportPath,
|
|
55
64
|
} from '../../foundation/discovery/component-discovery.mjs';
|
|
56
65
|
import {loadComponentReplacements} from '../component/_adapter.mjs';
|
|
@@ -65,6 +74,7 @@ import {
|
|
|
65
74
|
collectIdentities,
|
|
66
75
|
compareIdentities,
|
|
67
76
|
} from '../../foundation/integrations/contribution-inventory.mjs';
|
|
77
|
+
import {formatCliCommand} from '../../foundation/env/package-manager.mjs';
|
|
68
78
|
|
|
69
79
|
/**
|
|
70
80
|
* @typedef {import('../../foundation/integrations/issue').AstryxIntegrationIssue} Issue
|
|
@@ -307,98 +317,6 @@ function extractTarball(tgzPath, extractDir) {
|
|
|
307
317
|
}
|
|
308
318
|
}
|
|
309
319
|
|
|
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
320
|
/**
|
|
403
321
|
* Whether any of these doc files has a section that sets `id`.
|
|
404
322
|
* @param {string[]} files
|
|
@@ -472,15 +390,20 @@ async function validatePackedComponentExports(integration, scratchBase) {
|
|
|
472
390
|
const issues = [];
|
|
473
391
|
/** @type {Array<{name: string, specifier: string}>} */
|
|
474
392
|
const components = [];
|
|
393
|
+
// A family doc backs several records: load it, and report it, once.
|
|
394
|
+
const loads = new Map();
|
|
475
395
|
for (const record of records) {
|
|
396
|
+
const first = !loads.has(record.docPath);
|
|
397
|
+
if (first) loads.set(record.docPath, loadComponentDoc(record.docPath));
|
|
476
398
|
let docs;
|
|
477
399
|
try {
|
|
478
|
-
docs = await
|
|
400
|
+
docs = await loads.get(record.docPath);
|
|
479
401
|
} catch (err) {
|
|
402
|
+
if (!first) continue;
|
|
480
403
|
issues.push(
|
|
481
404
|
error(
|
|
482
405
|
'component_doc_unloadable',
|
|
483
|
-
`Component "${record.
|
|
406
|
+
`Component "${docStem(record.docPath)}" doc at "${record.docPath}" could not be loaded: ${err instanceof Error ? err.message : String(err)}`,
|
|
484
407
|
),
|
|
485
408
|
);
|
|
486
409
|
continue;
|
|
@@ -658,16 +581,22 @@ async function validateIncompleteThemeExports(
|
|
|
658
581
|
path.join(os.tmpdir(), `astryx-theme-${localTheme.slug}-`),
|
|
659
582
|
);
|
|
660
583
|
const expectedCss = path.join(expectedDir, `${localTheme.slug}.css`);
|
|
584
|
+
let expectedModule = path.join(expectedDir, `${localTheme.slug}.js`);
|
|
661
585
|
try {
|
|
662
586
|
if (outputs.some(output => output.kind !== 'font stylesheet')) {
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
);
|
|
587
|
+
// The scratch directory is the write root; the package stays the cwd,
|
|
588
|
+
// so the build selects the package's Core and its paths as before.
|
|
589
|
+
const scratchBuild = {out: expectedCss, __writeRoot: expectedDir};
|
|
590
|
+
const receipt = await themeBuild(source, scratchBuild, {cwd: packageDir});
|
|
668
591
|
if (receipt == null || receipt.type !== 'theme.build') {
|
|
669
592
|
throw new Error('the theme build produced no complete receipt');
|
|
670
593
|
}
|
|
594
|
+
expectedModule = builtModuleFile(
|
|
595
|
+
receipt,
|
|
596
|
+
packageDir,
|
|
597
|
+
expectedDir,
|
|
598
|
+
localTheme.slug,
|
|
599
|
+
);
|
|
671
600
|
}
|
|
672
601
|
for (const output of outputs) {
|
|
673
602
|
const localFile = /** @type {string} */ (output.inspected.target);
|
|
@@ -684,9 +613,7 @@ async function validateIncompleteThemeExports(
|
|
|
684
613
|
continue;
|
|
685
614
|
}
|
|
686
615
|
const expectedFile =
|
|
687
|
-
output.kind === 'module'
|
|
688
|
-
? path.join(expectedDir, `${localTheme.slug}.js`)
|
|
689
|
-
: expectedCss;
|
|
616
|
+
output.kind === 'module' ? expectedModule : expectedCss;
|
|
690
617
|
const expected = normalizeThemeVerifyForCompare(
|
|
691
618
|
fs.readFileSync(expectedFile, 'utf-8'),
|
|
692
619
|
);
|
|
@@ -702,7 +629,7 @@ async function validateIncompleteThemeExports(
|
|
|
702
629
|
output.kind === 'module'
|
|
703
630
|
? 'theme_module_stale'
|
|
704
631
|
: 'theme_stylesheet_stale',
|
|
705
|
-
`Theme "${localTheme.slug}" ${output.kind} does not match ${sourceRelative}. This incomplete export remains packable, but run
|
|
632
|
+
`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
633
|
),
|
|
707
634
|
);
|
|
708
635
|
}
|
|
@@ -721,7 +648,7 @@ async function validateIncompleteThemeExports(
|
|
|
721
648
|
issues.push(
|
|
722
649
|
error(
|
|
723
650
|
'theme_build_failed',
|
|
724
|
-
`Theme "${localTheme.slug}" could not be rebuilt from ${sourceRelative}: ${err instanceof Error ? err.message : String(err)} Run
|
|
651
|
+
`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
652
|
),
|
|
726
653
|
);
|
|
727
654
|
} finally {
|
|
@@ -730,6 +657,250 @@ async function validateIncompleteThemeExports(
|
|
|
730
657
|
return issues;
|
|
731
658
|
}
|
|
732
659
|
|
|
660
|
+
/**
|
|
661
|
+
* The module a scratch `theme build` wrote. Its file is named by the theme's
|
|
662
|
+
* own name, which can differ from the slug the package exports it under. A
|
|
663
|
+
* receipt that names no file inside the scratch directory falls back to the
|
|
664
|
+
* slug.
|
|
665
|
+
* @param {any} receipt
|
|
666
|
+
* @param {string} cwd the directory the build ran in
|
|
667
|
+
* @param {string} expectedDir
|
|
668
|
+
* @param {string} slug
|
|
669
|
+
* @returns {string}
|
|
670
|
+
*/
|
|
671
|
+
function builtModuleFile(receipt, cwd, expectedDir, slug) {
|
|
672
|
+
const written = receipt?.data?.outputs?.js;
|
|
673
|
+
if (typeof written === 'string') {
|
|
674
|
+
const file = path.resolve(cwd, written);
|
|
675
|
+
const relative = path.relative(expectedDir, file);
|
|
676
|
+
if (relative && !relative.startsWith('..') && !path.isAbsolute(relative)) {
|
|
677
|
+
return file;
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
return path.join(expectedDir, `${slug}.js`);
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
/**
|
|
684
|
+
* The `.js` file a relative module specifier names from `fromFile`, the
|
|
685
|
+
* extension `theme build` gives the built module: the exact path, the path
|
|
686
|
+
* with `.js`, or its `index.js`.
|
|
687
|
+
* @param {string} specifier
|
|
688
|
+
* @param {string} fromFile
|
|
689
|
+
* @returns {string | null}
|
|
690
|
+
*/
|
|
691
|
+
function resolveRelativeJsModule(specifier, fromFile) {
|
|
692
|
+
if (!specifier.startsWith('./') && !specifier.startsWith('../')) return null;
|
|
693
|
+
const base = path.resolve(path.dirname(fromFile), specifier);
|
|
694
|
+
const candidates = [base, `${base}.js`, path.join(base, 'index.js')];
|
|
695
|
+
return (
|
|
696
|
+
candidates.find(candidate => {
|
|
697
|
+
try {
|
|
698
|
+
return candidate.endsWith('.js') && fs.statSync(candidate).isFile();
|
|
699
|
+
} catch {
|
|
700
|
+
return false;
|
|
701
|
+
}
|
|
702
|
+
}) ?? null
|
|
703
|
+
);
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
/** @param {string} file */
|
|
707
|
+
function realFile(file) {
|
|
708
|
+
try {
|
|
709
|
+
return fs.realpathSync(file);
|
|
710
|
+
} catch {
|
|
711
|
+
return null;
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
* The file a stylesheet import names: a relative path from the module, or a
|
|
717
|
+
* subpath of the package itself, resolved through its own exports.
|
|
718
|
+
* @param {string} specifier
|
|
719
|
+
* @param {string} moduleFile
|
|
720
|
+
* @param {{name?: string}} pkg
|
|
721
|
+
* @param {string} packageDir
|
|
722
|
+
* @returns {string | null}
|
|
723
|
+
*/
|
|
724
|
+
function resolveStylesheetImport(specifier, moduleFile, pkg, packageDir) {
|
|
725
|
+
if (specifier.startsWith('./') || specifier.startsWith('../')) {
|
|
726
|
+
const file = path.resolve(path.dirname(moduleFile), specifier);
|
|
727
|
+
try {
|
|
728
|
+
return fs.statSync(file).isFile() ? realFile(file) : null;
|
|
729
|
+
} catch {
|
|
730
|
+
return null;
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
if (typeof pkg.name !== 'string' || !specifier.startsWith(`${pkg.name}/`)) {
|
|
734
|
+
return null;
|
|
735
|
+
}
|
|
736
|
+
const exported = inspectPackageExport(
|
|
737
|
+
pkg,
|
|
738
|
+
packageDir,
|
|
739
|
+
`.${specifier.slice(pkg.name.length)}`,
|
|
740
|
+
);
|
|
741
|
+
return exported.exported && exported.target
|
|
742
|
+
? realFile(exported.target)
|
|
743
|
+
: null;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
/**
|
|
747
|
+
* The theme binding of a built module: the name of its `export const`.
|
|
748
|
+
* @param {string} file
|
|
749
|
+
* @returns {string | null}
|
|
750
|
+
*/
|
|
751
|
+
function builtThemeBinding(file) {
|
|
752
|
+
try {
|
|
753
|
+
const ast = parseModule(fs.readFileSync(file, 'utf-8'), {
|
|
754
|
+
sourceType: 'module',
|
|
755
|
+
plugins: ['importAttributes'],
|
|
756
|
+
});
|
|
757
|
+
for (const node of ast.program.body) {
|
|
758
|
+
if (
|
|
759
|
+
node.type === 'ExportNamedDeclaration' &&
|
|
760
|
+
node.declaration?.type === 'VariableDeclaration'
|
|
761
|
+
) {
|
|
762
|
+
const id = node.declaration.declarations[0]?.id;
|
|
763
|
+
return id?.type === 'Identifier' ? id.name : null;
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
} catch {
|
|
767
|
+
// An unreadable module has no binding to match.
|
|
768
|
+
}
|
|
769
|
+
return null;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
/** @param {any} node */
|
|
773
|
+
function exportedName(node) {
|
|
774
|
+
return node?.name ?? node?.value;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
/**
|
|
778
|
+
* Check a `.js` or `.mjs` theme module that is not the built module itself.
|
|
779
|
+
* It is accepted when it only loads the theme's own styles and re-exports the
|
|
780
|
+
* built module: each statement imports the theme's exported stylesheet or font
|
|
781
|
+
* stylesheet for its side effects, except one, which re-exports from a `.js`
|
|
782
|
+
* file that matches the built module either everything or only its theme,
|
|
783
|
+
* under the theme's export name. Returns null for any other file and for a module that
|
|
784
|
+
* re-exports nothing, and otherwise whether it is accepted. A
|
|
785
|
+
* rejection gives the reason, or, when only the re-exported module is stale,
|
|
786
|
+
* that module's specifier with `rebuild` set.
|
|
787
|
+
*
|
|
788
|
+
* @param {string} moduleFile
|
|
789
|
+
* @param {string} expected the built module, normalized for comparison
|
|
790
|
+
* @param {{exportName: string, stylesheetFile: string, fontStylesheetFile?: string, pkg: {name?: string}, packageDir: string}} theme
|
|
791
|
+
* @returns {{ok: true} | {ok: false, reason: string, rebuild: boolean} | null}
|
|
792
|
+
*/
|
|
793
|
+
function ownStylesEntry(moduleFile, expected, theme) {
|
|
794
|
+
if (!/\.m?js$/u.test(moduleFile)) return null;
|
|
795
|
+
let ast;
|
|
796
|
+
try {
|
|
797
|
+
ast = parseModule(fs.readFileSync(moduleFile, 'utf-8'), {
|
|
798
|
+
sourceType: 'module',
|
|
799
|
+
plugins: ['importAttributes'],
|
|
800
|
+
});
|
|
801
|
+
} catch {
|
|
802
|
+
return null;
|
|
803
|
+
}
|
|
804
|
+
const body = ast.program.body;
|
|
805
|
+
const reexports = body.filter(
|
|
806
|
+
(/** @type {any} */ node) =>
|
|
807
|
+
node.type === 'ExportAllDeclaration' ||
|
|
808
|
+
(node.type === 'ExportNamedDeclaration' && node.source != null),
|
|
809
|
+
);
|
|
810
|
+
if (reexports.length === 0) return null;
|
|
811
|
+
/** @param {string} reason @param {boolean} [rebuild] */
|
|
812
|
+
const reject = (reason, rebuild = false) => ({
|
|
813
|
+
ok: /** @type {const} */ (false),
|
|
814
|
+
reason,
|
|
815
|
+
rebuild,
|
|
816
|
+
});
|
|
817
|
+
if (reexports.length > 1) return reject('it has more than one re-export');
|
|
818
|
+
if ((ast.program.directives ?? []).length > 0) {
|
|
819
|
+
return reject('it has a directive');
|
|
820
|
+
}
|
|
821
|
+
const ownStylesheets = new Set(
|
|
822
|
+
[theme.stylesheetFile, theme.fontStylesheetFile]
|
|
823
|
+
.filter(file => file != null)
|
|
824
|
+
.map(file => realFile(/** @type {string} */ (file))),
|
|
825
|
+
);
|
|
826
|
+
const imported = new Set();
|
|
827
|
+
for (const node of body) {
|
|
828
|
+
if (node === reexports[0]) continue;
|
|
829
|
+
const line = node.loc?.start.line;
|
|
830
|
+
if (node.type !== 'ImportDeclaration') {
|
|
831
|
+
return reject(
|
|
832
|
+
`line ${line} is neither a stylesheet import nor the re-export`,
|
|
833
|
+
);
|
|
834
|
+
}
|
|
835
|
+
const specifier = node.source.value;
|
|
836
|
+
if (
|
|
837
|
+
node.importKind === 'type' ||
|
|
838
|
+
node.specifiers.length > 0 ||
|
|
839
|
+
(node.attributes ?? []).length > 0 ||
|
|
840
|
+
node.phase != null
|
|
841
|
+
) {
|
|
842
|
+
return reject(`its import of ${specifier} is not a side-effect import`);
|
|
843
|
+
}
|
|
844
|
+
const file = resolveStylesheetImport(
|
|
845
|
+
specifier,
|
|
846
|
+
moduleFile,
|
|
847
|
+
theme.pkg,
|
|
848
|
+
theme.packageDir,
|
|
849
|
+
);
|
|
850
|
+
if (!file || !ownStylesheets.has(file)) {
|
|
851
|
+
return reject(
|
|
852
|
+
`${specifier} is not the theme's own stylesheet or font stylesheet`,
|
|
853
|
+
);
|
|
854
|
+
}
|
|
855
|
+
if (imported.has(file)) return reject(`it imports ${specifier} twice`);
|
|
856
|
+
imported.add(file);
|
|
857
|
+
}
|
|
858
|
+
const reexport = /** @type {any} */ (reexports[0]);
|
|
859
|
+
const from = reexport.source.value;
|
|
860
|
+
/** @type {string | null} */
|
|
861
|
+
let reexported = null;
|
|
862
|
+
if (
|
|
863
|
+
reexport.exportKind === 'type' ||
|
|
864
|
+
(reexport.attributes ?? []).length > 0
|
|
865
|
+
) {
|
|
866
|
+
return reject(`its re-export from ${from} is not a plain re-export`);
|
|
867
|
+
}
|
|
868
|
+
if (reexport.type === 'ExportAllDeclaration') {
|
|
869
|
+
if (reexport.exported != null) {
|
|
870
|
+
return reject(`it re-exports ${from} as a namespace`);
|
|
871
|
+
}
|
|
872
|
+
} else {
|
|
873
|
+
const specifiers = reexport.specifiers ?? [];
|
|
874
|
+
if (
|
|
875
|
+
specifiers.length !== 1 ||
|
|
876
|
+
specifiers[0].type !== 'ExportSpecifier' ||
|
|
877
|
+
specifiers[0].exportKind === 'type' ||
|
|
878
|
+
exportedName(specifiers[0].exported) !== theme.exportName
|
|
879
|
+
) {
|
|
880
|
+
return reject(`it re-exports names other than ${theme.exportName}`);
|
|
881
|
+
}
|
|
882
|
+
reexported = exportedName(specifiers[0].local);
|
|
883
|
+
}
|
|
884
|
+
const target = resolveRelativeJsModule(from, moduleFile);
|
|
885
|
+
if (!target) {
|
|
886
|
+
return reject(`its re-export from ${from} does not name a .js module`);
|
|
887
|
+
}
|
|
888
|
+
if (
|
|
889
|
+
normalizeThemeVerifyForCompare(fs.readFileSync(target, 'utf-8')) !==
|
|
890
|
+
expected
|
|
891
|
+
) {
|
|
892
|
+
return reject(from, true);
|
|
893
|
+
}
|
|
894
|
+
// `theme build` names the theme's export after the theme's own name, which
|
|
895
|
+
// can differ from its slug, so a named re-export may give that export the
|
|
896
|
+
// slug's export name. It must be the theme, not another export of the built
|
|
897
|
+
// module, such as its icon registry.
|
|
898
|
+
if (reexported != null && reexported !== builtThemeBinding(target)) {
|
|
899
|
+
return reject(`it re-exports ${reexported}, which is not the built theme`);
|
|
900
|
+
}
|
|
901
|
+
return {ok: /** @type {const} */ (true)};
|
|
902
|
+
}
|
|
903
|
+
|
|
733
904
|
/**
|
|
734
905
|
* Prove local theme exports are fresh, prove the same exports resolve from the
|
|
735
906
|
* tarball, and reject lifecycle changes to source or built output bytes.
|
|
@@ -787,6 +958,10 @@ async function validatePackedThemeExports(
|
|
|
787
958
|
);
|
|
788
959
|
}
|
|
789
960
|
|
|
961
|
+
// The name the source gives defineTheme, when the file says it: the
|
|
962
|
+
// build names its files after it.
|
|
963
|
+
const builtName = literalThemeName(source, localTheme.exportName);
|
|
964
|
+
|
|
790
965
|
const declaredOutputs = declaredThemeBuildOutputs(
|
|
791
966
|
localIntegration,
|
|
792
967
|
localTheme,
|
|
@@ -796,7 +971,7 @@ async function validatePackedThemeExports(
|
|
|
796
971
|
issues.push(
|
|
797
972
|
warning(
|
|
798
973
|
'theme_exports_missing',
|
|
799
|
-
`Theme "${localTheme.slug}" has no declared built exports. The package remains source-compatible. To make it importable, run
|
|
974
|
+
`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
975
|
),
|
|
801
976
|
);
|
|
802
977
|
continue;
|
|
@@ -836,7 +1011,7 @@ async function validatePackedThemeExports(
|
|
|
836
1011
|
err instanceof ThemeImportError
|
|
837
1012
|
? 'theme_import_unresolvable'
|
|
838
1013
|
: 'theme_import_invalid',
|
|
839
|
-
`${message} Run
|
|
1014
|
+
`${message} Run \`${formatCliCommand(`theme build ${sourceRelative}`, localIntegration.__packageDir)}\` before packing.`,
|
|
840
1015
|
),
|
|
841
1016
|
);
|
|
842
1017
|
continue;
|
|
@@ -847,21 +1022,27 @@ async function validatePackedThemeExports(
|
|
|
847
1022
|
);
|
|
848
1023
|
const expectedCss = path.join(expectedDir, `${localTheme.slug}.css`);
|
|
849
1024
|
try {
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
1025
|
+
// The scratch directory is the write root; the package stays the cwd,
|
|
1026
|
+
// so the build selects the package's Core and its paths as before.
|
|
1027
|
+
const scratchBuild = {out: expectedCss, __writeRoot: expectedDir};
|
|
1028
|
+
const receipt = await themeBuild(source, scratchBuild, {
|
|
1029
|
+
cwd: localIntegration.__packageDir,
|
|
1030
|
+
});
|
|
855
1031
|
if (receipt == null || receipt.type !== 'theme.build') {
|
|
856
1032
|
issues.push(
|
|
857
1033
|
error(
|
|
858
1034
|
'theme_build_failed',
|
|
859
|
-
`Theme "${localTheme.slug}" did not produce a complete build. Run
|
|
1035
|
+
`Theme "${localTheme.slug}" did not produce a complete build. Run \`${formatCliCommand(`theme build ${sourceRelative}`, localIntegration.__packageDir)}\` before packing.`,
|
|
860
1036
|
),
|
|
861
1037
|
);
|
|
862
1038
|
continue;
|
|
863
1039
|
}
|
|
864
|
-
const expectedModule =
|
|
1040
|
+
const expectedModule = builtModuleFile(
|
|
1041
|
+
receipt,
|
|
1042
|
+
localIntegration.__packageDir,
|
|
1043
|
+
expectedDir,
|
|
1044
|
+
localTheme.slug,
|
|
1045
|
+
);
|
|
865
1046
|
/** @type {Array<{kind: string, expected: string, local: string, packed: string, staleCode: string, packedCode: string}>} */
|
|
866
1047
|
const buildOutputs = [
|
|
867
1048
|
{
|
|
@@ -881,6 +1062,20 @@ async function validatePackedThemeExports(
|
|
|
881
1062
|
packedCode: 'packed_theme_stylesheet_changed',
|
|
882
1063
|
},
|
|
883
1064
|
];
|
|
1065
|
+
const localEntry = {
|
|
1066
|
+
exportName: localTheme.exportName,
|
|
1067
|
+
stylesheetFile: localImports.stylesheetFile,
|
|
1068
|
+
fontStylesheetFile: localImports.fontStylesheetFile,
|
|
1069
|
+
pkg: integrationPackageMetadata(localIntegration),
|
|
1070
|
+
packageDir: localIntegration.__packageDir,
|
|
1071
|
+
};
|
|
1072
|
+
const packedEntry = {
|
|
1073
|
+
exportName: packedTheme.exportName,
|
|
1074
|
+
stylesheetFile: packedImports.stylesheetFile,
|
|
1075
|
+
fontStylesheetFile: packedImports.fontStylesheetFile,
|
|
1076
|
+
pkg: integrationPackageMetadata(packedIntegration),
|
|
1077
|
+
packageDir: packedIntegration.__packageDir,
|
|
1078
|
+
};
|
|
884
1079
|
for (const output of buildOutputs) {
|
|
885
1080
|
const expected = normalizeThemeVerifyForCompare(
|
|
886
1081
|
fs.readFileSync(output.expected, 'utf-8'),
|
|
@@ -891,15 +1086,39 @@ async function validatePackedThemeExports(
|
|
|
891
1086
|
const packed = normalizeThemeVerifyForCompare(
|
|
892
1087
|
fs.readFileSync(output.packed, 'utf-8'),
|
|
893
1088
|
);
|
|
894
|
-
|
|
1089
|
+
// A module that is not the built module may still be an entry that
|
|
1090
|
+
// loads the theme's own styles and re-exports the built module.
|
|
1091
|
+
const localWrapper =
|
|
1092
|
+
output.kind === 'module' && expected !== local
|
|
1093
|
+
? ownStylesEntry(output.local, expected, localEntry)
|
|
1094
|
+
: null;
|
|
1095
|
+
const packedWrapper =
|
|
1096
|
+
output.kind === 'module' && expected !== packed
|
|
1097
|
+
? ownStylesEntry(output.packed, expected, packedEntry)
|
|
1098
|
+
: null;
|
|
1099
|
+
const localMatches = expected === local || localWrapper?.ok === true;
|
|
1100
|
+
const packedMatches = expected === packed || packedWrapper?.ok === true;
|
|
1101
|
+
if (!localMatches) {
|
|
895
1102
|
issues.push(
|
|
896
1103
|
error(
|
|
897
1104
|
output.staleCode,
|
|
898
|
-
|
|
1105
|
+
localWrapper && !localWrapper.ok && !localWrapper.rebuild
|
|
1106
|
+
? `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}.`
|
|
1107
|
+
: localWrapper && !localWrapper.ok
|
|
1108
|
+
? `Theme "${localTheme.slug}" module re-exports ${localWrapper.reason}, which does not match ${sourceRelative}. Run \`${formatCliCommand(`theme build ${sourceRelative}`, localIntegration.__packageDir)}\` before packing.`
|
|
1109
|
+
: (renamedOutputMessage(
|
|
1110
|
+
localTheme,
|
|
1111
|
+
output.kind,
|
|
1112
|
+
output.local,
|
|
1113
|
+
source,
|
|
1114
|
+
builtName,
|
|
1115
|
+
localIntegration.__packageDir,
|
|
1116
|
+
) ??
|
|
1117
|
+
`Theme "${localTheme.slug}" ${output.kind} does not match ${sourceRelative}. Run \`${formatCliCommand(`theme build ${sourceRelative}`, localIntegration.__packageDir)}\` before packing.`),
|
|
899
1118
|
),
|
|
900
1119
|
);
|
|
901
1120
|
}
|
|
902
|
-
if (local !== packed) {
|
|
1121
|
+
if (local !== packed || (localMatches && !packedMatches)) {
|
|
903
1122
|
issues.push(
|
|
904
1123
|
error(
|
|
905
1124
|
output.packedCode,
|
|
@@ -927,7 +1146,7 @@ async function validatePackedThemeExports(
|
|
|
927
1146
|
issues.push(
|
|
928
1147
|
error(
|
|
929
1148
|
'theme_build_failed',
|
|
930
|
-
`Theme "${localTheme.slug}" could not be rebuilt from ${sourceRelative}: ${err instanceof Error ? err.message : String(err)} Run
|
|
1149
|
+
`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
1150
|
),
|
|
932
1151
|
);
|
|
933
1152
|
} finally {
|
|
@@ -1063,7 +1282,17 @@ export async function integrationPackCheck(options = {}) {
|
|
|
1063
1282
|
// ── Phase 1: structure validation ──
|
|
1064
1283
|
const localResult = await validateLocalIntegration(cwd);
|
|
1065
1284
|
/** @type {Issue[]} */
|
|
1066
|
-
const issues = [
|
|
1285
|
+
const issues = [
|
|
1286
|
+
...localResult.issues,
|
|
1287
|
+
// Validate lists these layout findings without counting them. A
|
|
1288
|
+
// package.json npm cannot pack is what fails the pack here, as it did
|
|
1289
|
+
// before they were named; the rest stay warnings, which fail nothing.
|
|
1290
|
+
...(localResult.found ? (localResult.listed ?? []) : []).map(issue =>
|
|
1291
|
+
issue.code === 'invalid_package_json'
|
|
1292
|
+
? {...issue, severity: /** @type {const} */ ('error')}
|
|
1293
|
+
: issue,
|
|
1294
|
+
),
|
|
1295
|
+
];
|
|
1067
1296
|
|
|
1068
1297
|
if (!localResult.found || !localResult.integration) {
|
|
1069
1298
|
return emptyReceipt(pkgName, [
|
|
@@ -1085,6 +1314,24 @@ export async function integrationPackCheck(options = {}) {
|
|
|
1085
1314
|
const fileInv = computeRequiredFiles(loaded);
|
|
1086
1315
|
const {identities: localIdentities, errors: localDiscoveryErrors} =
|
|
1087
1316
|
await collectIdentities(loaded);
|
|
1317
|
+
// A family lists its members from the module its import names, which the
|
|
1318
|
+
// pack lifecycle may build or rebuild, so they are compared as local
|
|
1319
|
+
// discovery lists them after the pack.
|
|
1320
|
+
const familiesBefore = familyImports(loaded).map(family => family.docPath);
|
|
1321
|
+
/**
|
|
1322
|
+
* @param {Array<{name: string, docPath: string|null}>} records
|
|
1323
|
+
* @param {Set<string>} families
|
|
1324
|
+
*/
|
|
1325
|
+
const membersOf = (records, families) =>
|
|
1326
|
+
records
|
|
1327
|
+
.filter(
|
|
1328
|
+
r =>
|
|
1329
|
+
r.docPath != null &&
|
|
1330
|
+
families.has(r.docPath) &&
|
|
1331
|
+
isIntegrationMember(r),
|
|
1332
|
+
)
|
|
1333
|
+
.map(r => r.name);
|
|
1334
|
+
const recordsBefore = discoverIntegrationComponents(loaded);
|
|
1088
1335
|
for (const discoveryError of localDiscoveryErrors) {
|
|
1089
1336
|
issues.push(
|
|
1090
1337
|
error(
|
|
@@ -1094,6 +1341,8 @@ export async function integrationPackCheck(options = {}) {
|
|
|
1094
1341
|
);
|
|
1095
1342
|
}
|
|
1096
1343
|
for (const root of fileInv.roots) {
|
|
1344
|
+
// A root that is not a readable folder has its own issue.
|
|
1345
|
+
if (rootProblem(/** @type {string} */ (loaded[root.kind]))) continue;
|
|
1097
1346
|
if (root.files.length === 0) {
|
|
1098
1347
|
issues.push(
|
|
1099
1348
|
error(
|
|
@@ -1183,6 +1432,9 @@ export async function integrationPackCheck(options = {}) {
|
|
|
1183
1432
|
);
|
|
1184
1433
|
/** @type {string|null} */
|
|
1185
1434
|
let scratchBase = null;
|
|
1435
|
+
/** @type {string|undefined} the packed copy of the package */
|
|
1436
|
+
let extractDir;
|
|
1437
|
+
const issuesBeforePack = issues.length;
|
|
1186
1438
|
|
|
1187
1439
|
try {
|
|
1188
1440
|
// npm pack
|
|
@@ -1231,11 +1483,16 @@ export async function integrationPackCheck(options = {}) {
|
|
|
1231
1483
|
for (const root of fileInv.roots) {
|
|
1232
1484
|
const missing = root.files.filter(f => !packResult.packedPaths.has(f));
|
|
1233
1485
|
if (missing.length === root.files.length && root.files.length > 0) {
|
|
1486
|
+
const absolute = /** @type {string} */ (loaded[root.kind]);
|
|
1487
|
+
const link = symlinkedFolder(absolute, packageDir);
|
|
1234
1488
|
issues.push(
|
|
1235
1489
|
error(
|
|
1236
1490
|
'root_not_packed',
|
|
1237
1491
|
`Declared ${root.kind} root "${root.path}" has 0 of ${root.files.length} expected ` +
|
|
1238
|
-
`files in the pack list.
|
|
1492
|
+
`files in the pack list. ` +
|
|
1493
|
+
(link
|
|
1494
|
+
? `It is reached through the symlink "${path.relative(packageDir, link.path).split(path.sep).join('/')}", and npm pack does not follow a symlinked folder. Fix: replace the link with the folder itself, or point "${root.kind}" at the folder it links to.`
|
|
1495
|
+
: `Add "${root.path.replace(/^\.\//, '')}" to "files" in package.json.`),
|
|
1239
1496
|
),
|
|
1240
1497
|
);
|
|
1241
1498
|
} else {
|
|
@@ -1274,7 +1531,6 @@ export async function integrationPackCheck(options = {}) {
|
|
|
1274
1531
|
}
|
|
1275
1532
|
|
|
1276
1533
|
// ── Phase 3: extract + identity comparison ──
|
|
1277
|
-
let extractDir;
|
|
1278
1534
|
try {
|
|
1279
1535
|
extractDir = resolvePackageDir(pkgName, scratchBase);
|
|
1280
1536
|
} catch (err) {
|
|
@@ -1320,6 +1576,10 @@ export async function integrationPackCheck(options = {}) {
|
|
|
1320
1576
|
code: `packed_${issue.code}`,
|
|
1321
1577
|
severity: issue.severity,
|
|
1322
1578
|
message: `Packed: ${issue.message}`,
|
|
1579
|
+
// The packed tree keeps the package's own paths.
|
|
1580
|
+
...(issue.fix != null ? {fix: issue.fix} : {}),
|
|
1581
|
+
...(issue.file != null ? {file: issue.file} : {}),
|
|
1582
|
+
...(issue.line != null ? {line: issue.line} : {}),
|
|
1323
1583
|
});
|
|
1324
1584
|
}
|
|
1325
1585
|
|
|
@@ -1345,7 +1605,27 @@ export async function integrationPackCheck(options = {}) {
|
|
|
1345
1605
|
);
|
|
1346
1606
|
}
|
|
1347
1607
|
|
|
1348
|
-
|
|
1608
|
+
const families = new Set([
|
|
1609
|
+
...familiesBefore,
|
|
1610
|
+
...familyImports(loaded).map(family => family.docPath),
|
|
1611
|
+
]);
|
|
1612
|
+
let localComponents = localIdentities.components;
|
|
1613
|
+
if (families.size > 0) {
|
|
1614
|
+
const stale = new Set(membersOf(recordsBefore, families));
|
|
1615
|
+
const built = new Set(
|
|
1616
|
+
membersOf(discoverIntegrationComponents(loaded), families),
|
|
1617
|
+
);
|
|
1618
|
+
const {identities: afterPack} = await collectIdentities(loaded);
|
|
1619
|
+
localComponents = [
|
|
1620
|
+
...new Set([
|
|
1621
|
+
...localComponents.filter(name => !stale.has(name)),
|
|
1622
|
+
...afterPack.components.filter(name => built.has(name)),
|
|
1623
|
+
]),
|
|
1624
|
+
].sort();
|
|
1625
|
+
}
|
|
1626
|
+
// The receipt reports the local inventory that was compared.
|
|
1627
|
+
const comparedLocal = {...localIdentities, components: localComponents};
|
|
1628
|
+
issues.push(...compareIdentities(comparedLocal, packedIdentities));
|
|
1349
1629
|
issues.push(
|
|
1350
1630
|
...(await validatePackedThemeExports(
|
|
1351
1631
|
loaded,
|
|
@@ -1367,16 +1647,99 @@ export async function integrationPackCheck(options = {}) {
|
|
|
1367
1647
|
pkgVersion,
|
|
1368
1648
|
fileInv,
|
|
1369
1649
|
packResult,
|
|
1370
|
-
|
|
1650
|
+
comparedLocal,
|
|
1371
1651
|
packedIdentities,
|
|
1372
1652
|
issues,
|
|
1373
1653
|
);
|
|
1374
1654
|
} finally {
|
|
1655
|
+
// The packed copy lives in a scratch folder that is gone once this
|
|
1656
|
+
// returns: name its files the way the package does.
|
|
1657
|
+
if (extractDir && scratchBase) {
|
|
1658
|
+
packageRelative(issues.slice(issuesBeforePack), extractDir, scratchBase);
|
|
1659
|
+
}
|
|
1375
1660
|
removeTreeBestEffort(tgzTmpDir, 'temporary tarball directory', issues);
|
|
1376
1661
|
removeTreeBestEffort(scratchBase, 'scratch consumer', issues);
|
|
1377
1662
|
}
|
|
1378
1663
|
}
|
|
1379
1664
|
|
|
1665
|
+
/**
|
|
1666
|
+
* When a theme's source names it something other than the file the package
|
|
1667
|
+
* exports for it, a rebuild writes new files under that name and leaves the
|
|
1668
|
+
* exported one stale forever: say so, with both ways out. Null otherwise.
|
|
1669
|
+
* @param {{slug: string}} theme
|
|
1670
|
+
* @param {string} kind 'module' or 'stylesheet'
|
|
1671
|
+
* @param {string} exported the file the package exports for it
|
|
1672
|
+
* @param {string} source the theme's source
|
|
1673
|
+
* @param {string | null} builtName the literal defineTheme name, if any
|
|
1674
|
+
* @param {string} packageDir
|
|
1675
|
+
* @returns {string | null}
|
|
1676
|
+
*/
|
|
1677
|
+
function renamedOutputMessage(
|
|
1678
|
+
theme,
|
|
1679
|
+
kind,
|
|
1680
|
+
exported,
|
|
1681
|
+
source,
|
|
1682
|
+
builtName,
|
|
1683
|
+
packageDir,
|
|
1684
|
+
) {
|
|
1685
|
+
if (builtName == null || builtName === theme.slug) return null;
|
|
1686
|
+
const extension = kind === 'module' ? '.js' : '.css';
|
|
1687
|
+
if (path.basename(exported) === `${builtName}${extension}`) return null;
|
|
1688
|
+
const rel = (/** @type {string} */ file) =>
|
|
1689
|
+
path.relative(packageDir, file).split(path.sep).join('/');
|
|
1690
|
+
const built = rel(
|
|
1691
|
+
path.join(path.dirname(source), `${builtName}${extension}`),
|
|
1692
|
+
);
|
|
1693
|
+
return `Theme "${theme.slug}" ${kind} is ${rel(exported)}, but ${path.basename(source)} calls defineTheme with name: '${builtName}', so \`${formatCliCommand(`theme build ${rel(source)}`, packageDir)}\` writes ${built} instead and rebuilding never updates ${path.basename(exported)}. Fix: point the package export that serves it at ${built} after building, or set name: '${theme.slug}' in ${path.basename(source)} and rebuild.`;
|
|
1694
|
+
}
|
|
1695
|
+
|
|
1696
|
+
/**
|
|
1697
|
+
* Rewrite the scratch copy's absolute paths in each issue's message: a file
|
|
1698
|
+
* of the packed package as its path in the package, and any other path in the
|
|
1699
|
+
* scratch consumer (such as the module that resolved an import) as that
|
|
1700
|
+
* consumer. Both folders are gone once verify returns.
|
|
1701
|
+
* @param {Issue[]} issues
|
|
1702
|
+
* @param {string} packedDir the packed package inside the scratch consumer
|
|
1703
|
+
* @param {string} consumerDir the scratch consumer
|
|
1704
|
+
*/
|
|
1705
|
+
function packageRelative(issues, packedDir, consumerDir) {
|
|
1706
|
+
/** @param {string} dir */
|
|
1707
|
+
const spellings = dir => {
|
|
1708
|
+
const out = [dir];
|
|
1709
|
+
try {
|
|
1710
|
+
const real = fs.realpathSync(dir);
|
|
1711
|
+
if (real !== dir) out.push(real);
|
|
1712
|
+
} catch {
|
|
1713
|
+
// Already removed: the plain path is all there is.
|
|
1714
|
+
}
|
|
1715
|
+
return out;
|
|
1716
|
+
};
|
|
1717
|
+
/** @param {string} text */
|
|
1718
|
+
const escape = text => text.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
|
|
1719
|
+
const packed = spellings(packedDir);
|
|
1720
|
+
const consumer = spellings(consumerDir);
|
|
1721
|
+
for (const issue of issues) {
|
|
1722
|
+
if (typeof issue.message !== 'string') continue;
|
|
1723
|
+
let message = issue.message;
|
|
1724
|
+
for (const prefix of packed) {
|
|
1725
|
+
message = message
|
|
1726
|
+
.split(`${prefix}${path.sep}`)
|
|
1727
|
+
.join('')
|
|
1728
|
+
.replace(
|
|
1729
|
+
new RegExp(`${escape(prefix)}(?![\\w-]|\\.\\w)`, 'gu'),
|
|
1730
|
+
'the package root',
|
|
1731
|
+
);
|
|
1732
|
+
}
|
|
1733
|
+
for (const prefix of consumer) {
|
|
1734
|
+
message = message.replace(
|
|
1735
|
+
new RegExp(`${escape(prefix)}[^\\s"'\`]*`, 'gu'),
|
|
1736
|
+
'a consumer project',
|
|
1737
|
+
);
|
|
1738
|
+
}
|
|
1739
|
+
issue.message = message;
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1380
1743
|
/**
|
|
1381
1744
|
* Assemble the receipt.
|
|
1382
1745
|
* @param {string} name
|