@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
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
integrationAddComponent,
|
|
18
18
|
integrationAddTemplate,
|
|
19
19
|
} from './add-contribution.mjs';
|
|
20
|
+
import {formatCliCommand} from '../../foundation/env/package-manager.mjs';
|
|
20
21
|
|
|
21
22
|
let tmpDir;
|
|
22
23
|
|
|
@@ -213,6 +214,7 @@ function writePackage({
|
|
|
213
214
|
themeExports = false,
|
|
214
215
|
npmignore,
|
|
215
216
|
components = false,
|
|
217
|
+
templates = false,
|
|
216
218
|
scripts,
|
|
217
219
|
} = {}) {
|
|
218
220
|
const pkg = {name, version};
|
|
@@ -272,6 +274,14 @@ export default {type: 'theme', name: 'ocean', displayName: 'Ocean', description:
|
|
|
272
274
|
'export default function Card() { return null; }\n',
|
|
273
275
|
);
|
|
274
276
|
}
|
|
277
|
+
if (templates) {
|
|
278
|
+
const root = path.join(tmpDir, 'templates');
|
|
279
|
+
fs.mkdirSync(root, {recursive: true});
|
|
280
|
+
fs.writeFileSync(
|
|
281
|
+
path.join(root, 'stray.tsx'),
|
|
282
|
+
'export default function Stray() { return null; }\n',
|
|
283
|
+
);
|
|
284
|
+
}
|
|
275
285
|
if (npmignore) {
|
|
276
286
|
fs.writeFileSync(path.join(tmpDir, '.npmignore'), npmignore);
|
|
277
287
|
}
|
|
@@ -303,6 +313,363 @@ function runCliVerify() {
|
|
|
303
313
|
};
|
|
304
314
|
}
|
|
305
315
|
|
|
316
|
+
/**
|
|
317
|
+
* Give the built ocean theme a font stylesheet and an entry module that loads
|
|
318
|
+
* the theme's own styles, and export them the way such a package does.
|
|
319
|
+
* @param {string} entry
|
|
320
|
+
* @param {string} [file] the entry's file name in `entries/`
|
|
321
|
+
*/
|
|
322
|
+
function writeOwnStylesEntry(entry, file = 'ocean.mjs') {
|
|
323
|
+
fs.writeFileSync(
|
|
324
|
+
path.join(tmpDir, 'themes', 'ocean', 'ocean.fonts.css'),
|
|
325
|
+
"@font-face { font-family: 'Ocean Sans'; src: local('Ocean Sans'); }\n",
|
|
326
|
+
);
|
|
327
|
+
fs.mkdirSync(path.join(tmpDir, 'entries'), {recursive: true});
|
|
328
|
+
fs.writeFileSync(path.join(tmpDir, 'entries', file), entry);
|
|
329
|
+
const packageFile = path.join(tmpDir, 'package.json');
|
|
330
|
+
const pkg = JSON.parse(fs.readFileSync(packageFile, 'utf-8'));
|
|
331
|
+
pkg.files = ['astryx.integration.mjs', 'themes', 'entries'];
|
|
332
|
+
pkg.exports = {
|
|
333
|
+
'./themes/ocean': `./entries/${file}`,
|
|
334
|
+
'./themes/ocean.css': './themes/ocean/ocean.css',
|
|
335
|
+
'./themes/ocean.fonts.css': './themes/ocean/ocean.fonts.css',
|
|
336
|
+
};
|
|
337
|
+
fs.writeFileSync(packageFile, `${JSON.stringify(pkg, null, 2)}\n`);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Rename the ocean theme to deep-sea, keeping its `ocean` slug, and build it,
|
|
342
|
+
* so its outputs are named after the theme: `deep-sea.css` and `deep-sea.js`,
|
|
343
|
+
* which exports `deepSeaTheme`.
|
|
344
|
+
*/
|
|
345
|
+
function writeRenamedOcean() {
|
|
346
|
+
writePackage({files: ['astryx.integration.mjs', 'themes', 'entries']});
|
|
347
|
+
fs.writeFileSync(
|
|
348
|
+
path.join(tmpDir, 'themes', 'ocean', 'oceanTheme.ts'),
|
|
349
|
+
"import {defineTheme} from '@astryxdesign/core/theme';\n\nexport const oceanTheme = defineTheme({name: 'deep-sea'});\n",
|
|
350
|
+
);
|
|
351
|
+
const built = spawnSync(
|
|
352
|
+
process.execPath,
|
|
353
|
+
[
|
|
354
|
+
path.join(process.cwd(), 'packages/cli/clients/cli/bin/astryx.mjs'),
|
|
355
|
+
'theme',
|
|
356
|
+
'build',
|
|
357
|
+
'themes/ocean/oceanTheme.ts',
|
|
358
|
+
],
|
|
359
|
+
{cwd: tmpDir, encoding: 'utf-8', timeout: 30_000},
|
|
360
|
+
);
|
|
361
|
+
if (built.status !== 0) {
|
|
362
|
+
throw new Error(`Could not build the theme fixture: ${built.stderr}`);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Give the ocean theme an icon registry and build it, so its built module
|
|
368
|
+
* also exports `oceanIcons`.
|
|
369
|
+
*/
|
|
370
|
+
function writeOceanWithIcons() {
|
|
371
|
+
writePackage({files: ['astryx.integration.mjs', 'themes', 'entries']});
|
|
372
|
+
const themeDir = path.join(tmpDir, 'themes', 'ocean');
|
|
373
|
+
fs.writeFileSync(
|
|
374
|
+
path.join(themeDir, 'icons.js'),
|
|
375
|
+
'export const oceanIcons = {};\n',
|
|
376
|
+
);
|
|
377
|
+
fs.writeFileSync(
|
|
378
|
+
path.join(themeDir, 'oceanTheme.ts'),
|
|
379
|
+
"import {defineTheme} from '@astryxdesign/core/theme';\nimport {oceanIcons} from './icons';\n\nexport const oceanTheme = defineTheme({name: 'ocean', icons: oceanIcons});\n",
|
|
380
|
+
);
|
|
381
|
+
const built = spawnSync(
|
|
382
|
+
process.execPath,
|
|
383
|
+
[
|
|
384
|
+
path.join(process.cwd(), 'packages/cli/clients/cli/bin/astryx.mjs'),
|
|
385
|
+
'theme',
|
|
386
|
+
'build',
|
|
387
|
+
'themes/ocean/oceanTheme.ts',
|
|
388
|
+
],
|
|
389
|
+
{cwd: tmpDir, encoding: 'utf-8', timeout: 30_000},
|
|
390
|
+
);
|
|
391
|
+
if (built.status !== 0) {
|
|
392
|
+
throw new Error(`Could not build the theme fixture: ${built.stderr}`);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// An entry like one whose import is the whole integration: it loads the
|
|
397
|
+
// theme's fonts and stylesheet, by relative path and through the package's
|
|
398
|
+
// own exports, and re-exports the built theme.
|
|
399
|
+
const OWN_STYLES_ENTRY = `// Copyright (c) Acme.
|
|
400
|
+
|
|
401
|
+
import '../themes/ocean/ocean.fonts.css';
|
|
402
|
+
import '@acme/widgets/themes/ocean.css';
|
|
403
|
+
|
|
404
|
+
export {oceanTheme} from '../themes/ocean/ocean.js';
|
|
405
|
+
`;
|
|
406
|
+
|
|
407
|
+
describe('a theme module that loads its own styles', () => {
|
|
408
|
+
it('passes an entry that imports the theme stylesheet and fonts and re-exports the built module', async () => {
|
|
409
|
+
writePackage({themeExports: true});
|
|
410
|
+
writeOwnStylesEntry(OWN_STYLES_ENTRY);
|
|
411
|
+
|
|
412
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
413
|
+
|
|
414
|
+
expect(result.data.issues).toEqual([]);
|
|
415
|
+
expect(result.data.packable).toBe(true);
|
|
416
|
+
const cli = runCliVerify();
|
|
417
|
+
expect(cli.status, cli.stderr).toBe(0);
|
|
418
|
+
expect(cli.receipt?.data.issues).toEqual([]);
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
it('passes an entry that imports its fonts through the package exports and re-exports everything', async () => {
|
|
422
|
+
writePackage({themeExports: true});
|
|
423
|
+
writeOwnStylesEntry(
|
|
424
|
+
"import '@acme/widgets/themes/ocean.fonts.css';\nimport '../themes/ocean/ocean.css';\nexport * from '../themes/ocean/ocean.js';\n",
|
|
425
|
+
);
|
|
426
|
+
|
|
427
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
428
|
+
|
|
429
|
+
expect(result.data.issues).toEqual([]);
|
|
430
|
+
expect(result.data.packable).toBe(true);
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
it.each([
|
|
434
|
+
[
|
|
435
|
+
'also imports another stylesheet',
|
|
436
|
+
`${OWN_STYLES_ENTRY}import './other.css';\n`,
|
|
437
|
+
"./other.css is not the theme's own stylesheet or font stylesheet",
|
|
438
|
+
],
|
|
439
|
+
[
|
|
440
|
+
'also imports a script',
|
|
441
|
+
`import './setup.mjs';\n${OWN_STYLES_ENTRY}`,
|
|
442
|
+
"./setup.mjs is not the theme's own stylesheet or font stylesheet",
|
|
443
|
+
],
|
|
444
|
+
[
|
|
445
|
+
'runs code',
|
|
446
|
+
`${OWN_STYLES_ENTRY}console.log('ocean');\n`,
|
|
447
|
+
'line 7 is neither a stylesheet import nor the re-export',
|
|
448
|
+
],
|
|
449
|
+
[
|
|
450
|
+
'exports another value',
|
|
451
|
+
`${OWN_STYLES_ENTRY}export const extra = 1;\n`,
|
|
452
|
+
'line 7 is neither a stylesheet import nor the re-export',
|
|
453
|
+
],
|
|
454
|
+
[
|
|
455
|
+
'renames the theme it re-exports',
|
|
456
|
+
"import '../themes/ocean/ocean.css';\nexport {oceanTheme, oceanTheme as theme} from '../themes/ocean/ocean.js';\n",
|
|
457
|
+
'it re-exports names other than oceanTheme',
|
|
458
|
+
],
|
|
459
|
+
[
|
|
460
|
+
'binds the stylesheet it imports',
|
|
461
|
+
"import styles from '../themes/ocean/ocean.css';\nexport {oceanTheme} from '../themes/ocean/ocean.js';\n",
|
|
462
|
+
'its import of ../themes/ocean/ocean.css is not a side-effect import',
|
|
463
|
+
],
|
|
464
|
+
[
|
|
465
|
+
'imports the stylesheet as a CSS module script',
|
|
466
|
+
"import '../themes/ocean/ocean.css' with {type: 'css'};\nexport {oceanTheme} from '../themes/ocean/ocean.js';\n",
|
|
467
|
+
'its import of ../themes/ocean/ocean.css is not a side-effect import',
|
|
468
|
+
],
|
|
469
|
+
[
|
|
470
|
+
're-exports another name',
|
|
471
|
+
"import '../themes/ocean/ocean.css';\nexport {oceanTheme, missing} from '../themes/ocean/ocean.js';\n",
|
|
472
|
+
'it re-exports names other than oceanTheme',
|
|
473
|
+
],
|
|
474
|
+
[
|
|
475
|
+
're-exports a copy that is not a .js module',
|
|
476
|
+
"import '../themes/ocean/ocean.css';\nexport {oceanTheme} from './copy.cjs';\n",
|
|
477
|
+
'its re-export from ./copy.cjs does not name a .js module',
|
|
478
|
+
],
|
|
479
|
+
[
|
|
480
|
+
'has a directive',
|
|
481
|
+
`'use client';\n${OWN_STYLES_ENTRY}`,
|
|
482
|
+
'it has a directive',
|
|
483
|
+
],
|
|
484
|
+
[
|
|
485
|
+
're-exports twice',
|
|
486
|
+
`${OWN_STYLES_ENTRY}export * from '../themes/ocean/ocean.js';\n`,
|
|
487
|
+
'it has more than one re-export',
|
|
488
|
+
],
|
|
489
|
+
])('fails an entry that %s', async (_label, entry, reason) => {
|
|
490
|
+
writePackage({themeExports: true});
|
|
491
|
+
writeOwnStylesEntry(entry);
|
|
492
|
+
fs.writeFileSync(path.join(tmpDir, 'entries', 'other.css'), '.x {}\n');
|
|
493
|
+
fs.writeFileSync(path.join(tmpDir, 'entries', 'setup.mjs'), 'export {};\n');
|
|
494
|
+
fs.copyFileSync(
|
|
495
|
+
path.join(tmpDir, 'themes', 'ocean', 'ocean.js'),
|
|
496
|
+
path.join(tmpDir, 'entries', 'copy.cjs'),
|
|
497
|
+
);
|
|
498
|
+
|
|
499
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
500
|
+
|
|
501
|
+
expect(result.data.packable).toBe(false);
|
|
502
|
+
expect(result.data.issues).toEqual([
|
|
503
|
+
{
|
|
504
|
+
code: 'theme_module_stale',
|
|
505
|
+
severity: 'error',
|
|
506
|
+
message: `Theme "ocean" module is not the module \`${formatCliCommand('theme build themes/ocean/oceanTheme.ts', tmpDir)}\` writes and does not only wrap it: ${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 oceanTheme.`,
|
|
507
|
+
},
|
|
508
|
+
]);
|
|
509
|
+
});
|
|
510
|
+
|
|
511
|
+
it('fails an entry whose re-exported module drifts from source', async () => {
|
|
512
|
+
writePackage({themeExports: true});
|
|
513
|
+
writeOwnStylesEntry(OWN_STYLES_ENTRY);
|
|
514
|
+
fs.appendFileSync(
|
|
515
|
+
path.join(tmpDir, 'themes', 'ocean', 'ocean.js'),
|
|
516
|
+
'// stale module\n',
|
|
517
|
+
);
|
|
518
|
+
|
|
519
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
520
|
+
|
|
521
|
+
expect(result.data.packable).toBe(false);
|
|
522
|
+
expect(result.data.issues).toEqual([
|
|
523
|
+
{
|
|
524
|
+
code: 'theme_module_stale',
|
|
525
|
+
severity: 'error',
|
|
526
|
+
message: `Theme "ocean" module re-exports ../themes/ocean/ocean.js, which does not match themes/ocean/oceanTheme.ts. Run \`${formatCliCommand('theme build themes/ocean/oceanTheme.ts', tmpDir)}\` before packing.`,
|
|
527
|
+
},
|
|
528
|
+
]);
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
it('does not accept a TypeScript entry', async () => {
|
|
532
|
+
writePackage({themeExports: true});
|
|
533
|
+
writeOwnStylesEntry(OWN_STYLES_ENTRY, 'ocean.ts');
|
|
534
|
+
|
|
535
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
536
|
+
|
|
537
|
+
expect(result.data.packable).toBe(false);
|
|
538
|
+
expect(result.data.issues).toEqual([
|
|
539
|
+
{
|
|
540
|
+
code: 'theme_module_stale',
|
|
541
|
+
severity: 'error',
|
|
542
|
+
message: `Theme "ocean" module does not match themes/ocean/oceanTheme.ts. Run \`${formatCliCommand('theme build themes/ocean/oceanTheme.ts', tmpDir)}\` before packing.`,
|
|
543
|
+
},
|
|
544
|
+
]);
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
it('does not accept an entry that re-exports itself', async () => {
|
|
548
|
+
writePackage({themeExports: true});
|
|
549
|
+
writeOwnStylesEntry(
|
|
550
|
+
"import '../themes/ocean/ocean.css';\nexport * from './ocean.js';\n",
|
|
551
|
+
'ocean.js',
|
|
552
|
+
);
|
|
553
|
+
|
|
554
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
555
|
+
|
|
556
|
+
expect(result.data.packable).toBe(false);
|
|
557
|
+
expect(result.data.issues).toContainEqual(
|
|
558
|
+
expect.objectContaining({
|
|
559
|
+
code: 'theme_import_unresolvable',
|
|
560
|
+
message: expect.stringContaining('does not export "oceanTheme"'),
|
|
561
|
+
}),
|
|
562
|
+
);
|
|
563
|
+
});
|
|
564
|
+
|
|
565
|
+
it('passes an entry for a theme whose own name differs from its slug', async () => {
|
|
566
|
+
writeRenamedOcean();
|
|
567
|
+
writeOwnStylesEntry(
|
|
568
|
+
"import '../themes/ocean/deep-sea.css';\nexport {deepSeaTheme as oceanTheme} from '../themes/ocean/deep-sea.js';\n",
|
|
569
|
+
);
|
|
570
|
+
setThemeExports({
|
|
571
|
+
'./themes/ocean': './entries/ocean.mjs',
|
|
572
|
+
'./themes/ocean.css': './themes/ocean/deep-sea.css',
|
|
573
|
+
});
|
|
574
|
+
|
|
575
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
576
|
+
|
|
577
|
+
expect(result.data.issues).toEqual([]);
|
|
578
|
+
expect(result.data.packable).toBe(true);
|
|
579
|
+
const cli = runCliVerify();
|
|
580
|
+
expect(cli.status, cli.stderr).toBe(0);
|
|
581
|
+
});
|
|
582
|
+
|
|
583
|
+
it('says a rebuild cannot fix exports that name the theme after its folder once its source renames it', async () => {
|
|
584
|
+
writePackage({
|
|
585
|
+
files: ['astryx.integration.mjs', 'themes'],
|
|
586
|
+
themeExports: true,
|
|
587
|
+
});
|
|
588
|
+
fs.writeFileSync(
|
|
589
|
+
path.join(tmpDir, 'themes', 'ocean', 'oceanTheme.ts'),
|
|
590
|
+
"import {defineTheme} from '@astryxdesign/core/theme';\n\nexport const oceanTheme = defineTheme({name: 'sea'});\n",
|
|
591
|
+
);
|
|
592
|
+
|
|
593
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
594
|
+
|
|
595
|
+
expect(result.data.issues.map(issue => issue.message)).toEqual([
|
|
596
|
+
`Theme "ocean" module is themes/ocean/ocean.js, but oceanTheme.ts calls defineTheme with name: 'sea', so \`${formatCliCommand('theme build themes/ocean/oceanTheme.ts', tmpDir)}\` writes themes/ocean/sea.js instead and rebuilding never updates ocean.js. Fix: point the package export that serves it at themes/ocean/sea.js after building, or set name: 'ocean' in oceanTheme.ts and rebuild.`,
|
|
597
|
+
`Theme "ocean" stylesheet is themes/ocean/ocean.css, but oceanTheme.ts calls defineTheme with name: 'sea', so \`${formatCliCommand('theme build themes/ocean/oceanTheme.ts', tmpDir)}\` writes themes/ocean/sea.css instead and rebuilding never updates ocean.css. Fix: point the package export that serves it at themes/ocean/sea.css after building, or set name: 'ocean' in oceanTheme.ts and rebuild.`,
|
|
598
|
+
]);
|
|
599
|
+
});
|
|
600
|
+
|
|
601
|
+
it('compares a partial export set with the module named after the theme', async () => {
|
|
602
|
+
writeRenamedOcean();
|
|
603
|
+
setThemeExports({'./themes/ocean': './themes/ocean/deep-sea.js'});
|
|
604
|
+
|
|
605
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
606
|
+
|
|
607
|
+
expect(result.data.packable).toBe(true);
|
|
608
|
+
expect(result.data.issues.map(issue => issue.code)).toEqual([
|
|
609
|
+
'theme_exports_incomplete',
|
|
610
|
+
]);
|
|
611
|
+
});
|
|
612
|
+
|
|
613
|
+
it('passes an entry that re-exports only the theme from a built module that also exports its icons', async () => {
|
|
614
|
+
writeOceanWithIcons();
|
|
615
|
+
writeOwnStylesEntry(OWN_STYLES_ENTRY);
|
|
616
|
+
|
|
617
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
618
|
+
|
|
619
|
+
expect(result.data.issues).toEqual([]);
|
|
620
|
+
expect(result.data.packable).toBe(true);
|
|
621
|
+
});
|
|
622
|
+
|
|
623
|
+
it('fails an entry that gives the built icons the theme export name', async () => {
|
|
624
|
+
writeOceanWithIcons();
|
|
625
|
+
writeOwnStylesEntry(
|
|
626
|
+
"import '../themes/ocean/ocean.css';\nexport {oceanIcons as oceanTheme} from '../themes/ocean/ocean.js';\n",
|
|
627
|
+
);
|
|
628
|
+
|
|
629
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
630
|
+
|
|
631
|
+
expect(result.data.packable).toBe(false);
|
|
632
|
+
expect(result.data.issues).toEqual([
|
|
633
|
+
expect.objectContaining({
|
|
634
|
+
code: 'theme_module_stale',
|
|
635
|
+
message: expect.stringContaining(
|
|
636
|
+
'it re-exports oceanIcons, which is not the built theme',
|
|
637
|
+
),
|
|
638
|
+
}),
|
|
639
|
+
]);
|
|
640
|
+
});
|
|
641
|
+
|
|
642
|
+
it('fails when packing changes the module an entry re-exports', async () => {
|
|
643
|
+
const prepack = [
|
|
644
|
+
"const fs=require('fs')",
|
|
645
|
+
"fs.copyFileSync('themes/ocean/ocean.js','.ocean.js.orig')",
|
|
646
|
+
"fs.appendFileSync('themes/ocean/ocean.js','// packed\\n')",
|
|
647
|
+
].join(';');
|
|
648
|
+
const postpack =
|
|
649
|
+
"require('fs').renameSync('.ocean.js.orig','themes/ocean/ocean.js')";
|
|
650
|
+
writePackage({
|
|
651
|
+
themeExports: true,
|
|
652
|
+
scripts: {
|
|
653
|
+
prepack: `node -e "${prepack}"`,
|
|
654
|
+
postpack: `node -e "${postpack}"`,
|
|
655
|
+
},
|
|
656
|
+
});
|
|
657
|
+
writeOwnStylesEntry(OWN_STYLES_ENTRY);
|
|
658
|
+
|
|
659
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
660
|
+
|
|
661
|
+
expect(result.data.packable).toBe(false);
|
|
662
|
+
expect(result.data.issues).toEqual([
|
|
663
|
+
{
|
|
664
|
+
code: 'packed_theme_module_changed',
|
|
665
|
+
severity: 'error',
|
|
666
|
+
message:
|
|
667
|
+
'Theme "ocean" module changed during packing. Keep the built output unchanged in the tarball.',
|
|
668
|
+
},
|
|
669
|
+
]);
|
|
670
|
+
});
|
|
671
|
+
});
|
|
672
|
+
|
|
306
673
|
describe('integrationPackCheck', () => {
|
|
307
674
|
it('returns packable:true for a valid integration with themes', async () => {
|
|
308
675
|
writePackage({files: ['astryx.integration.mjs', 'themes']});
|
|
@@ -337,8 +704,7 @@ describe('integrationPackCheck', () => {
|
|
|
337
704
|
{
|
|
338
705
|
code: 'theme_exports_missing',
|
|
339
706
|
severity: 'warning',
|
|
340
|
-
message:
|
|
341
|
-
'Theme "ocean" has no declared built exports. The package remains source-compatible. To make it importable, run `astryx theme build themes/ocean/oceanTheme.ts` and export "./themes/ocean" plus "./themes/ocean.css" from package.json; `astryx integration add theme ocean` creates those exports for a new theme.',
|
|
707
|
+
message: `Theme "ocean" has no declared built exports. The package remains source-compatible. To make it importable, run \`${formatCliCommand('theme build themes/ocean/oceanTheme.ts', tmpDir)}\` and export "./themes/ocean" plus "./themes/ocean.css" from package.json; \`${formatCliCommand('integration add theme ocean', tmpDir)}\` creates those exports for a new theme.`,
|
|
342
708
|
},
|
|
343
709
|
]);
|
|
344
710
|
const cli = runCliVerify();
|
|
@@ -509,8 +875,7 @@ describe('integrationPackCheck', () => {
|
|
|
509
875
|
{
|
|
510
876
|
code: 'theme_stylesheet_stale',
|
|
511
877
|
severity: 'warning',
|
|
512
|
-
message:
|
|
513
|
-
'Theme "ocean" stylesheet does not match themes/ocean/oceanTheme.ts. This incomplete export remains packable, but run `astryx theme build themes/ocean/oceanTheme.ts` before adding its matching export.',
|
|
878
|
+
message: `Theme "ocean" stylesheet does not match themes/ocean/oceanTheme.ts. This incomplete export remains packable, but run \`${formatCliCommand('theme build themes/ocean/oceanTheme.ts', tmpDir)}\` before adding its matching export.`,
|
|
514
879
|
},
|
|
515
880
|
]);
|
|
516
881
|
const cli = runCliVerify();
|
|
@@ -543,8 +908,7 @@ describe('integrationPackCheck', () => {
|
|
|
543
908
|
{
|
|
544
909
|
code: 'theme_stylesheet_stale',
|
|
545
910
|
severity: 'warning',
|
|
546
|
-
message:
|
|
547
|
-
'Theme "ocean" stylesheet does not match themes/ocean/oceanTheme.ts. This incomplete export remains packable, but run `astryx theme build themes/ocean/oceanTheme.ts` before adding its matching export.',
|
|
911
|
+
message: `Theme "ocean" stylesheet does not match themes/ocean/oceanTheme.ts. This incomplete export remains packable, but run \`${formatCliCommand('theme build themes/ocean/oceanTheme.ts', tmpDir)}\` before adding its matching export.`,
|
|
548
912
|
},
|
|
549
913
|
]);
|
|
550
914
|
const cli = runCliVerify();
|
|
@@ -617,14 +981,12 @@ describe('integrationPackCheck', () => {
|
|
|
617
981
|
{
|
|
618
982
|
code: 'theme_module_stale',
|
|
619
983
|
severity: 'error',
|
|
620
|
-
message:
|
|
621
|
-
'Theme "ocean" module does not match themes/ocean/oceanTheme.ts. Run `astryx theme build themes/ocean/oceanTheme.ts` before packing.',
|
|
984
|
+
message: `Theme "ocean" module does not match themes/ocean/oceanTheme.ts. Run \`${formatCliCommand('theme build themes/ocean/oceanTheme.ts', tmpDir)}\` before packing.`,
|
|
622
985
|
},
|
|
623
986
|
{
|
|
624
987
|
code: 'theme_stylesheet_stale',
|
|
625
988
|
severity: 'error',
|
|
626
|
-
message:
|
|
627
|
-
'Theme "ocean" stylesheet does not match themes/ocean/oceanTheme.ts. Run `astryx theme build themes/ocean/oceanTheme.ts` before packing.',
|
|
989
|
+
message: `Theme "ocean" stylesheet does not match themes/ocean/oceanTheme.ts. Run \`${formatCliCommand('theme build themes/ocean/oceanTheme.ts', tmpDir)}\` before packing.`,
|
|
628
990
|
},
|
|
629
991
|
]);
|
|
630
992
|
const cli = runCliVerify();
|
|
@@ -754,6 +1116,285 @@ describe('integrationPackCheck', () => {
|
|
|
754
1116
|
);
|
|
755
1117
|
});
|
|
756
1118
|
|
|
1119
|
+
it('checks the export a component doc names when its file is named otherwise', async () => {
|
|
1120
|
+
fs.writeFileSync(
|
|
1121
|
+
path.join(tmpDir, 'package.json'),
|
|
1122
|
+
`${JSON.stringify({
|
|
1123
|
+
name: '@acme/widgets',
|
|
1124
|
+
version: '1.0.0',
|
|
1125
|
+
files: ['astryx.integration.mjs', 'components'],
|
|
1126
|
+
exports: {'./components/Slides': './components/Slides.tsx'},
|
|
1127
|
+
})}\n`,
|
|
1128
|
+
);
|
|
1129
|
+
fs.writeFileSync(
|
|
1130
|
+
path.join(tmpDir, 'astryx.integration.mjs'),
|
|
1131
|
+
"export default {components: './components'};\n",
|
|
1132
|
+
);
|
|
1133
|
+
fs.mkdirSync(path.join(tmpDir, 'components'));
|
|
1134
|
+
// Slides.tsx exports AcmeCarousel and nothing named Slides.
|
|
1135
|
+
fs.writeFileSync(
|
|
1136
|
+
path.join(tmpDir, 'components', 'Slides.tsx'),
|
|
1137
|
+
'export function AcmeCarousel() { return null; }\n',
|
|
1138
|
+
);
|
|
1139
|
+
fs.writeFileSync(
|
|
1140
|
+
path.join(tmpDir, 'components', 'Slides.doc.mjs'),
|
|
1141
|
+
"export default {type: 'component', name: 'AcmeCarousel', import: '@acme/widgets/components/Slides', description: 'x', props: []};\n",
|
|
1142
|
+
);
|
|
1143
|
+
|
|
1144
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
1145
|
+
expect(result.data.packable).toBe(true);
|
|
1146
|
+
expect(result.data.contributions.packed.components).toEqual([
|
|
1147
|
+
'AcmeCarousel',
|
|
1148
|
+
]);
|
|
1149
|
+
});
|
|
1150
|
+
|
|
1151
|
+
it('checks each family member against the module its family doc imports', async () => {
|
|
1152
|
+
fs.writeFileSync(
|
|
1153
|
+
path.join(tmpDir, 'package.json'),
|
|
1154
|
+
`${JSON.stringify({
|
|
1155
|
+
name: '@acme/widgets',
|
|
1156
|
+
version: '1.0.0',
|
|
1157
|
+
files: ['astryx.integration.mjs', 'components'],
|
|
1158
|
+
exports: {'./tabs': './components/tabs/index.ts'},
|
|
1159
|
+
})}\n`,
|
|
1160
|
+
);
|
|
1161
|
+
fs.writeFileSync(
|
|
1162
|
+
path.join(tmpDir, 'astryx.integration.mjs'),
|
|
1163
|
+
"export default {components: './components'};\n",
|
|
1164
|
+
);
|
|
1165
|
+
const dir = path.join(tmpDir, 'components', 'tabs');
|
|
1166
|
+
fs.mkdirSync(dir, {recursive: true});
|
|
1167
|
+
fs.writeFileSync(
|
|
1168
|
+
path.join(dir, 'AcmeTabs.tsx'),
|
|
1169
|
+
'export function AcmeTabs() { return null; }\nexport function AcmeTabsLegacy() { return null; }\n',
|
|
1170
|
+
);
|
|
1171
|
+
fs.writeFileSync(
|
|
1172
|
+
path.join(dir, 'tab.tsx'),
|
|
1173
|
+
'export function AcmeTab() { return null; }\n',
|
|
1174
|
+
);
|
|
1175
|
+
// The module apps import exports AcmeTabs and AcmeTab, not AcmeTabsLegacy.
|
|
1176
|
+
fs.writeFileSync(
|
|
1177
|
+
path.join(dir, 'index.ts'),
|
|
1178
|
+
"export {AcmeTabs} from './AcmeTabs';\nexport {AcmeTab} from './tab';\n",
|
|
1179
|
+
);
|
|
1180
|
+
fs.writeFileSync(
|
|
1181
|
+
path.join(dir, 'AcmeTabs.doc.mjs'),
|
|
1182
|
+
"export default {type: 'component', name: 'AcmeTabs', import: '@acme/widgets/tabs', description: 'x', components: [{name: 'AcmeTabs', description: 'x', props: []}, {name: 'AcmeTab', description: 'x', props: []}, {name: 'AcmeTabsLegacy', description: 'x', props: []}]};\n",
|
|
1183
|
+
);
|
|
1184
|
+
|
|
1185
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
1186
|
+
|
|
1187
|
+
expect(result.data.issues).toEqual([]);
|
|
1188
|
+
expect(result.data.packable).toBe(true);
|
|
1189
|
+
expect(result.data.contributions.packed.components).toEqual([
|
|
1190
|
+
'AcmeTab',
|
|
1191
|
+
'AcmeTabs',
|
|
1192
|
+
]);
|
|
1193
|
+
});
|
|
1194
|
+
|
|
1195
|
+
it.each([
|
|
1196
|
+
'a clean checkout',
|
|
1197
|
+
'a stale build',
|
|
1198
|
+
'a stale build that exports more',
|
|
1199
|
+
])(
|
|
1200
|
+
'reads members a family imports from output its pack lifecycle builds, from %s',
|
|
1201
|
+
async start => {
|
|
1202
|
+
fs.writeFileSync(
|
|
1203
|
+
path.join(tmpDir, 'package.json'),
|
|
1204
|
+
`${JSON.stringify({
|
|
1205
|
+
name: '@acme/widgets',
|
|
1206
|
+
version: '1.0.0',
|
|
1207
|
+
files: ['astryx.integration.mjs', 'components', 'dist'],
|
|
1208
|
+
exports: {'./tabs': './dist/tabs/index.mjs'},
|
|
1209
|
+
scripts: {prepack: 'node build.mjs'},
|
|
1210
|
+
})}\n`,
|
|
1211
|
+
);
|
|
1212
|
+
fs.writeFileSync(
|
|
1213
|
+
path.join(tmpDir, 'astryx.integration.mjs'),
|
|
1214
|
+
"export default {components: './components'};\n",
|
|
1215
|
+
);
|
|
1216
|
+
// The build writes the module the family imports; a clean checkout has none.
|
|
1217
|
+
fs.writeFileSync(
|
|
1218
|
+
path.join(tmpDir, 'build.mjs'),
|
|
1219
|
+
"import fs from 'node:fs';\nfs.mkdirSync('dist/tabs', {recursive: true});\nfs.writeFileSync('dist/tabs/index.mjs', \"export {AcmeTabs, AcmeTab} from '../../components/tabs/AcmeTabs.tsx';\\n\");\n",
|
|
1220
|
+
);
|
|
1221
|
+
const dir = path.join(tmpDir, 'components', 'tabs');
|
|
1222
|
+
fs.mkdirSync(dir, {recursive: true});
|
|
1223
|
+
fs.writeFileSync(
|
|
1224
|
+
path.join(dir, 'AcmeTabs.tsx'),
|
|
1225
|
+
'export function AcmeTabs() { return null; }\nexport function AcmeTab() { return null; }\nexport function AcmeTabLegacy() { return null; }\n',
|
|
1226
|
+
);
|
|
1227
|
+
fs.writeFileSync(
|
|
1228
|
+
path.join(dir, 'AcmeTabs.doc.mjs'),
|
|
1229
|
+
"export default {type: 'component', name: 'AcmeTabs', import: '@acme/widgets/tabs', description: 'x', components: [{name: 'AcmeTabs', description: 'x', props: []}, {name: 'AcmeTab', description: 'x', props: []}, {name: 'AcmeTabLegacy', description: 'x', props: []}]};\n",
|
|
1230
|
+
);
|
|
1231
|
+
|
|
1232
|
+
if (start !== 'a clean checkout') {
|
|
1233
|
+
// An earlier build: before AcmeTab was exported, or while AcmeTabLegacy
|
|
1234
|
+
// still was.
|
|
1235
|
+
const names =
|
|
1236
|
+
start === 'a stale build'
|
|
1237
|
+
? 'AcmeTabs'
|
|
1238
|
+
: 'AcmeTabs, AcmeTab, AcmeTabLegacy';
|
|
1239
|
+
fs.mkdirSync(path.join(tmpDir, 'dist', 'tabs'), {recursive: true});
|
|
1240
|
+
fs.writeFileSync(
|
|
1241
|
+
path.join(tmpDir, 'dist', 'tabs', 'index.mjs'),
|
|
1242
|
+
`export {${names}} from '../../components/tabs/AcmeTabs.tsx';\n`,
|
|
1243
|
+
);
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
1247
|
+
|
|
1248
|
+
expect(result.data.issues).toEqual([]);
|
|
1249
|
+
expect(result.data.packable).toBe(true);
|
|
1250
|
+
expect(result.data.contributions.local.components).toEqual(
|
|
1251
|
+
result.data.contributions.packed.components,
|
|
1252
|
+
);
|
|
1253
|
+
},
|
|
1254
|
+
);
|
|
1255
|
+
|
|
1256
|
+
it.each(['a clean checkout', 'an incremental build'])(
|
|
1257
|
+
'reads members built output re-exports from compiled files, from %s',
|
|
1258
|
+
async start => {
|
|
1259
|
+
fs.writeFileSync(
|
|
1260
|
+
path.join(tmpDir, 'package.json'),
|
|
1261
|
+
`${JSON.stringify({
|
|
1262
|
+
name: '@acme/widgets',
|
|
1263
|
+
version: '1.0.0',
|
|
1264
|
+
files: ['astryx.integration.mjs', 'components', 'dist'],
|
|
1265
|
+
exports: {'./tabs': './dist/tabs/index.mjs'},
|
|
1266
|
+
scripts: {prepack: 'node build.mjs'},
|
|
1267
|
+
})}\n`,
|
|
1268
|
+
);
|
|
1269
|
+
fs.writeFileSync(
|
|
1270
|
+
path.join(tmpDir, 'astryx.integration.mjs'),
|
|
1271
|
+
"export default {components: './components'};\n",
|
|
1272
|
+
);
|
|
1273
|
+
// The build compiles each source to its own file and, like an
|
|
1274
|
+
// incremental build, rewrites only the files whose output changed.
|
|
1275
|
+
const output = {
|
|
1276
|
+
'index.mjs':
|
|
1277
|
+
"export {AcmeTabs} from './tabs.mjs';\nexport * from './tab.mjs';\n",
|
|
1278
|
+
'tabs.mjs': 'export function AcmeTabs() { return null; }\n',
|
|
1279
|
+
'tab.mjs': 'export function AcmeTab() { return null; }\n',
|
|
1280
|
+
};
|
|
1281
|
+
fs.writeFileSync(
|
|
1282
|
+
path.join(tmpDir, 'build.mjs'),
|
|
1283
|
+
`import fs from 'node:fs';\nconst output = ${JSON.stringify(output)};\nfs.mkdirSync('dist/tabs', {recursive: true});\nfor (const [file, text] of Object.entries(output)) {\n const target = 'dist/tabs/' + file;\n if (!fs.existsSync(target) || fs.readFileSync(target, 'utf-8') !== text) fs.writeFileSync(target, text);\n}\n`,
|
|
1284
|
+
);
|
|
1285
|
+
const dir = path.join(tmpDir, 'components', 'tabs');
|
|
1286
|
+
fs.mkdirSync(dir, {recursive: true});
|
|
1287
|
+
fs.writeFileSync(
|
|
1288
|
+
path.join(dir, 'AcmeTabs.tsx'),
|
|
1289
|
+
'export function AcmeTabs() { return null; }\n',
|
|
1290
|
+
);
|
|
1291
|
+
fs.writeFileSync(
|
|
1292
|
+
path.join(dir, 'AcmeTab.tsx'),
|
|
1293
|
+
'export function AcmeTab() { return null; }\n',
|
|
1294
|
+
);
|
|
1295
|
+
fs.writeFileSync(
|
|
1296
|
+
path.join(dir, 'AcmeTabs.doc.mjs'),
|
|
1297
|
+
"export default {type: 'component', name: 'AcmeTabs', import: '@acme/widgets/tabs', description: 'x', components: [{name: 'AcmeTabs', description: 'x', props: []}, {name: 'AcmeTab', description: 'x', props: []}]};\n",
|
|
1298
|
+
);
|
|
1299
|
+
if (start === 'an incremental build') {
|
|
1300
|
+
// An earlier build from before AcmeTab existed: the file the import
|
|
1301
|
+
// names is already current, so the build leaves it untouched.
|
|
1302
|
+
fs.mkdirSync(path.join(tmpDir, 'dist', 'tabs'), {recursive: true});
|
|
1303
|
+
for (const [file, text] of Object.entries({...output, 'tab.mjs': ''})) {
|
|
1304
|
+
fs.writeFileSync(path.join(tmpDir, 'dist', 'tabs', file), text);
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
1309
|
+
|
|
1310
|
+
expect(result.data.issues).toEqual([]);
|
|
1311
|
+
expect(result.data.packable).toBe(true);
|
|
1312
|
+
expect(result.data.contributions.packed.components).toEqual([
|
|
1313
|
+
'AcmeTab',
|
|
1314
|
+
'AcmeTabs',
|
|
1315
|
+
]);
|
|
1316
|
+
expect(result.data.contributions.local.components).toEqual(
|
|
1317
|
+
result.data.contributions.packed.components,
|
|
1318
|
+
);
|
|
1319
|
+
},
|
|
1320
|
+
);
|
|
1321
|
+
|
|
1322
|
+
it('passes a member another folder declares, which has no source', async () => {
|
|
1323
|
+
fs.writeFileSync(
|
|
1324
|
+
path.join(tmpDir, 'package.json'),
|
|
1325
|
+
`${JSON.stringify({
|
|
1326
|
+
name: '@acme/widgets',
|
|
1327
|
+
version: '1.0.0',
|
|
1328
|
+
files: ['astryx.integration.mjs', 'components'],
|
|
1329
|
+
exports: {'./menu': './components/menu/index.ts'},
|
|
1330
|
+
})}\n`,
|
|
1331
|
+
);
|
|
1332
|
+
fs.writeFileSync(
|
|
1333
|
+
path.join(tmpDir, 'astryx.integration.mjs'),
|
|
1334
|
+
"export default {components: './components'};\n",
|
|
1335
|
+
);
|
|
1336
|
+
const menu = path.join(tmpDir, 'components', 'menu');
|
|
1337
|
+
const shared = path.join(tmpDir, 'components', 'shared');
|
|
1338
|
+
fs.mkdirSync(menu, {recursive: true});
|
|
1339
|
+
fs.mkdirSync(shared, {recursive: true});
|
|
1340
|
+
fs.writeFileSync(
|
|
1341
|
+
path.join(menu, 'AcmeMenu.doc.mjs'),
|
|
1342
|
+
"export default {type: 'component', name: 'AcmeMenu', import: '@acme/widgets/menu', description: 'x', components: [{name: 'AcmeMenuItem', description: 'x', props: []}]};\n",
|
|
1343
|
+
);
|
|
1344
|
+
fs.writeFileSync(
|
|
1345
|
+
path.join(menu, 'AcmeMenu.tsx'),
|
|
1346
|
+
'export function AcmeMenu() { return null; }\n',
|
|
1347
|
+
);
|
|
1348
|
+
fs.writeFileSync(
|
|
1349
|
+
path.join(menu, 'index.ts'),
|
|
1350
|
+
"export {AcmeMenu} from './AcmeMenu';\nexport {AcmeMenuItem} from '../shared/AcmeMenuItem';\n",
|
|
1351
|
+
);
|
|
1352
|
+
fs.writeFileSync(
|
|
1353
|
+
path.join(shared, 'AcmeMenuItem.tsx'),
|
|
1354
|
+
'export function AcmeMenuItem() { return null; }\n',
|
|
1355
|
+
);
|
|
1356
|
+
|
|
1357
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
1358
|
+
|
|
1359
|
+
expect(result.data.issues).toEqual([]);
|
|
1360
|
+
expect(result.data.packable).toBe(true);
|
|
1361
|
+
expect(result.data.contributions.packed.components).toEqual([
|
|
1362
|
+
'AcmeMenu',
|
|
1363
|
+
'AcmeMenuItem',
|
|
1364
|
+
]);
|
|
1365
|
+
});
|
|
1366
|
+
|
|
1367
|
+
it('reports a family doc the loader rejects once, not once per member', async () => {
|
|
1368
|
+
fs.writeFileSync(
|
|
1369
|
+
path.join(tmpDir, 'package.json'),
|
|
1370
|
+
`${JSON.stringify({
|
|
1371
|
+
name: '@acme/widgets',
|
|
1372
|
+
version: '1.0.0',
|
|
1373
|
+
files: ['astryx.integration.mjs', 'components'],
|
|
1374
|
+
})}\n`,
|
|
1375
|
+
);
|
|
1376
|
+
fs.writeFileSync(
|
|
1377
|
+
path.join(tmpDir, 'astryx.integration.mjs'),
|
|
1378
|
+
"export default {components: './components'};\n",
|
|
1379
|
+
);
|
|
1380
|
+
fs.mkdirSync(path.join(tmpDir, 'components'));
|
|
1381
|
+
fs.writeFileSync(
|
|
1382
|
+
path.join(tmpDir, 'components', 'AcmeTabs.tsx'),
|
|
1383
|
+
'export function AcmeTabs() { return null; }\nexport function AcmeTab() { return null; }\nexport function AcmeTabPanel() { return null; }\n',
|
|
1384
|
+
);
|
|
1385
|
+
// A displayName that is not a string makes the loader reject the doc.
|
|
1386
|
+
fs.writeFileSync(
|
|
1387
|
+
path.join(tmpDir, 'components', 'AcmeTabs.doc.mjs'),
|
|
1388
|
+
"export default {type: 'component', name: 'AcmeTabs', displayName: 1, description: 'x', components: [{name: 'AcmeTab', description: 'x', props: []}, {name: 'AcmeTabPanel', description: 'x', props: []}]};\n",
|
|
1389
|
+
);
|
|
1390
|
+
|
|
1391
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
1392
|
+
const codes = result.data.issues.map(issue => issue.code);
|
|
1393
|
+
|
|
1394
|
+
expect(codes).toContain('component_doc_unloadable');
|
|
1395
|
+
expect(codes.length).toBe(new Set(codes).size);
|
|
1396
|
+
});
|
|
1397
|
+
|
|
757
1398
|
it('passes a generated component through its exact packed export', async () => {
|
|
758
1399
|
fs.writeFileSync(
|
|
759
1400
|
path.join(tmpDir, 'package.json'),
|
|
@@ -811,6 +1452,86 @@ describe('integrationPackCheck', () => {
|
|
|
811
1452
|
);
|
|
812
1453
|
});
|
|
813
1454
|
|
|
1455
|
+
it('does not count a type-only re-export as the component', async () => {
|
|
1456
|
+
fs.writeFileSync(
|
|
1457
|
+
path.join(tmpDir, 'package.json'),
|
|
1458
|
+
`${JSON.stringify({
|
|
1459
|
+
name: '@acme/widgets',
|
|
1460
|
+
version: '1.0.0',
|
|
1461
|
+
files: ['astryx.integration.mjs', 'src'],
|
|
1462
|
+
exports: {'.': './src/index.ts'},
|
|
1463
|
+
})}\n`,
|
|
1464
|
+
);
|
|
1465
|
+
fs.writeFileSync(
|
|
1466
|
+
path.join(tmpDir, 'astryx.integration.mjs'),
|
|
1467
|
+
"export default {components: './src'};\n",
|
|
1468
|
+
);
|
|
1469
|
+
fs.mkdirSync(path.join(tmpDir, 'src'));
|
|
1470
|
+
fs.writeFileSync(
|
|
1471
|
+
path.join(tmpDir, 'src', 'index.ts'),
|
|
1472
|
+
"export type {AcmeWidget} from './AcmeWidget';\n",
|
|
1473
|
+
);
|
|
1474
|
+
fs.writeFileSync(
|
|
1475
|
+
path.join(tmpDir, 'src', 'AcmeWidget.tsx'),
|
|
1476
|
+
'export function AcmeWidget() { return null; }\n',
|
|
1477
|
+
);
|
|
1478
|
+
fs.writeFileSync(
|
|
1479
|
+
path.join(tmpDir, 'src', 'AcmeWidget.doc.mjs'),
|
|
1480
|
+
"export default {type: 'component', name: 'AcmeWidget', import: '@acme/widgets', description: 'Widget.', props: []};\n",
|
|
1481
|
+
);
|
|
1482
|
+
|
|
1483
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
1484
|
+
|
|
1485
|
+
expect(result.data.issues).toContainEqual(
|
|
1486
|
+
expect.objectContaining({code: 'component_export_missing'}),
|
|
1487
|
+
);
|
|
1488
|
+
});
|
|
1489
|
+
|
|
1490
|
+
it('follows a re-export of a folder to its index file', async () => {
|
|
1491
|
+
// `./primitives` names a folder: TypeScript and bundlers load its index file.
|
|
1492
|
+
fs.writeFileSync(
|
|
1493
|
+
path.join(tmpDir, 'package.json'),
|
|
1494
|
+
`${JSON.stringify({
|
|
1495
|
+
name: '@acme/widgets',
|
|
1496
|
+
version: '1.0.0',
|
|
1497
|
+
files: ['astryx.integration.mjs', 'src'],
|
|
1498
|
+
exports: {'.': './src/index.ts'},
|
|
1499
|
+
})}\n`,
|
|
1500
|
+
);
|
|
1501
|
+
fs.writeFileSync(
|
|
1502
|
+
path.join(tmpDir, 'astryx.integration.mjs'),
|
|
1503
|
+
"export default {components: './src'};\n",
|
|
1504
|
+
);
|
|
1505
|
+
const primitives = path.join(tmpDir, 'src', 'primitives');
|
|
1506
|
+
fs.mkdirSync(primitives, {recursive: true});
|
|
1507
|
+
fs.writeFileSync(
|
|
1508
|
+
path.join(tmpDir, 'src', 'index.ts'),
|
|
1509
|
+
"export * from './primitives';\n",
|
|
1510
|
+
);
|
|
1511
|
+
fs.writeFileSync(
|
|
1512
|
+
path.join(primitives, 'index.ts'),
|
|
1513
|
+
"export * from './AcmeWidget';\n",
|
|
1514
|
+
);
|
|
1515
|
+
fs.writeFileSync(
|
|
1516
|
+
path.join(primitives, 'AcmeWidget.tsx'),
|
|
1517
|
+
'export function AcmeWidget() { return null; }\n',
|
|
1518
|
+
);
|
|
1519
|
+
fs.writeFileSync(
|
|
1520
|
+
path.join(primitives, 'AcmeWidget.doc.mjs'),
|
|
1521
|
+
"export default {type: 'component', name: 'AcmeWidget', import: '@acme/widgets', description: 'Widget.', props: []};\n",
|
|
1522
|
+
);
|
|
1523
|
+
|
|
1524
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
1525
|
+
|
|
1526
|
+
expect(result.data.issues).not.toContainEqual(
|
|
1527
|
+
expect.objectContaining({code: 'component_export_missing'}),
|
|
1528
|
+
);
|
|
1529
|
+
expect(
|
|
1530
|
+
result.data.packable,
|
|
1531
|
+
JSON.stringify(result.data.issues, null, 2),
|
|
1532
|
+
).toBe(true);
|
|
1533
|
+
});
|
|
1534
|
+
|
|
814
1535
|
it('fails when packed template source is hidden by package exports', async () => {
|
|
815
1536
|
writePackage({
|
|
816
1537
|
manifest: "export default {templates: './templates'};\n",
|
|
@@ -1199,6 +1920,92 @@ describe('integrationPackCheck', () => {
|
|
|
1199
1920
|
expect(sourceWarnings[0].message).toContain('Card.tsx');
|
|
1200
1921
|
});
|
|
1201
1922
|
|
|
1923
|
+
it('reports template sources without metadata as warnings', async () => {
|
|
1924
|
+
writePackage({
|
|
1925
|
+
manifest:
|
|
1926
|
+
"export default {themes: './themes', templates: './templates'};\n",
|
|
1927
|
+
files: ['astryx.integration.mjs', 'themes', 'templates'],
|
|
1928
|
+
templates: true,
|
|
1929
|
+
});
|
|
1930
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
1931
|
+
|
|
1932
|
+
const sourceWarnings = result.data.issues.filter(
|
|
1933
|
+
issue => issue.code === 'source_without_template_doc',
|
|
1934
|
+
);
|
|
1935
|
+
expect(sourceWarnings).toHaveLength(1);
|
|
1936
|
+
expect(sourceWarnings[0].severity).toBe('warning');
|
|
1937
|
+
expect(sourceWarnings[0].message).toContain('stray.tsx');
|
|
1938
|
+
});
|
|
1939
|
+
|
|
1940
|
+
it('says npm pack skips a symlinked root instead of asking for a "files" entry', async () => {
|
|
1941
|
+
writePackage({
|
|
1942
|
+
manifest:
|
|
1943
|
+
"export default {themes: './themes', components: './components'};\n",
|
|
1944
|
+
});
|
|
1945
|
+
const real = path.join(tmpDir, 'real-components');
|
|
1946
|
+
fs.mkdirSync(real, {recursive: true});
|
|
1947
|
+
fs.writeFileSync(
|
|
1948
|
+
path.join(real, 'Card.doc.mjs'),
|
|
1949
|
+
"export default {type: 'component', name: 'Card', displayName: 'Card', usage: {description: 'Card.'}, props: []};\n",
|
|
1950
|
+
);
|
|
1951
|
+
fs.writeFileSync(
|
|
1952
|
+
path.join(real, 'Card.tsx'),
|
|
1953
|
+
'export function Card() { return null; }\n',
|
|
1954
|
+
);
|
|
1955
|
+
fs.symlinkSync('real-components', path.join(tmpDir, 'components'));
|
|
1956
|
+
|
|
1957
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
1958
|
+
const codes = result.data.issues.map(issue => issue.code);
|
|
1959
|
+
expect(codes).toContain('symlinked_root');
|
|
1960
|
+
const notPacked = result.data.issues.find(
|
|
1961
|
+
issue => issue.code === 'root_not_packed',
|
|
1962
|
+
);
|
|
1963
|
+
expect(notPacked?.message).toBe(
|
|
1964
|
+
'Declared components root "components" has 0 of 2 expected files in the pack list. It is reached through the symlink "components", and npm pack does not follow a symlinked folder. Fix: replace the link with the folder itself, or point "components" at the folder it links to.',
|
|
1965
|
+
);
|
|
1966
|
+
});
|
|
1967
|
+
|
|
1968
|
+
it('names packed files by their path in the package, never the scratch copy', async () => {
|
|
1969
|
+
writePackage({
|
|
1970
|
+
manifest:
|
|
1971
|
+
"export default {themes: './themes', docs: './docs/a.doc.mjs'};\n",
|
|
1972
|
+
});
|
|
1973
|
+
fs.mkdirSync(path.join(tmpDir, 'docs'), {recursive: true});
|
|
1974
|
+
fs.writeFileSync(path.join(tmpDir, 'docs', 'a.doc.mjs'), '');
|
|
1975
|
+
|
|
1976
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
1977
|
+
const messages = result.data.issues.map(issue => issue.message);
|
|
1978
|
+
expect(messages.join('\n')).not.toContain(
|
|
1979
|
+
path.join(tmpDir, '.astryx-pack-check-'),
|
|
1980
|
+
);
|
|
1981
|
+
expect(messages).toContain(
|
|
1982
|
+
'Packed: Declared docs root is a file, not a folder: docs/a.doc.mjs. Fix: point "docs" in the manifest at the folder that holds them.',
|
|
1983
|
+
);
|
|
1984
|
+
// The root's own issue covers it: no empty-root error, no raw errno.
|
|
1985
|
+
const codes = result.data.issues.map(issue => issue.code);
|
|
1986
|
+
expect(codes).not.toContain('empty_contribution_root');
|
|
1987
|
+
expect(codes).not.toContain('local_discovery_failed');
|
|
1988
|
+
expect(codes).not.toContain('packed_discovery_failed');
|
|
1989
|
+
});
|
|
1990
|
+
|
|
1991
|
+
it('fails on a package.json npm cannot pack, which validate only warns about', async () => {
|
|
1992
|
+
writePackage({files: ['astryx.integration.mjs', 'themes']});
|
|
1993
|
+
const packageFile = path.join(tmpDir, 'package.json');
|
|
1994
|
+
const pkg = JSON.parse(fs.readFileSync(packageFile, 'utf-8'));
|
|
1995
|
+
delete pkg.name;
|
|
1996
|
+
fs.writeFileSync(packageFile, `${JSON.stringify(pkg, null, 2)}\n`);
|
|
1997
|
+
|
|
1998
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
1999
|
+
|
|
2000
|
+
expect(result.data.packable).toBe(false);
|
|
2001
|
+
expect(
|
|
2002
|
+
result.data.issues.map(issue => [issue.code, issue.severity]),
|
|
2003
|
+
).toEqual([
|
|
2004
|
+
['invalid_package_json', 'error'],
|
|
2005
|
+
['pack_failed', 'error'],
|
|
2006
|
+
]);
|
|
2007
|
+
});
|
|
2008
|
+
|
|
1202
2009
|
it('cleans up its scratch consumer when npm pack fails', async () => {
|
|
1203
2010
|
writePackage({
|
|
1204
2011
|
files: ['astryx.integration.mjs', 'themes'],
|