@astryxdesign/cli 0.6.3-canary.98a2e4e → 0.6.3-canary.9dbb6c1
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/README.md +106 -73
- package/api/blog/blog.doc.mjs +1 -0
- package/api/build/build.doc.mjs +4 -3
- package/api/build/build.test.mjs +14 -3
- package/api/build/build.type.d.mts +36 -2
- package/api/build/build.type.mjs +25 -4
- package/api/build/help/help.d.mts +8 -5
- package/api/build/help/help.mjs +56 -6
- package/api/component/component.doc.mjs +13 -3
- package/api/component/component.mjs +31 -2
- package/api/component/component.test.mjs +38 -0
- package/api/component/component.type.d.mts +22 -11
- package/api/component/component.type.mjs +32 -24
- package/api/component/detail/blocks/blocks.d.mts +2 -1
- package/api/component/detail/blocks/blocks.mjs +4 -3
- package/api/component/list/list.d.mts +0 -5
- package/api/component/list/list.mjs +37 -9
- package/api/discover/discover.doc.mjs +2 -1
- package/api/discover/discover.type.d.mts +4 -4
- package/api/discover/discover.type.mjs +10 -10
- package/api/docs/_adapter.d.mts +28 -30
- package/api/docs/_adapter.mjs +73 -135
- package/api/docs/compiled-topics.test.mjs +78 -0
- package/api/docs/detail/detail.d.mts +0 -15
- package/api/docs/detail/detail.mjs +14 -78
- package/api/docs/detail/section/section.mjs +22 -18
- package/api/docs/detail/section/section.test.mjs +4 -3
- package/api/docs/docs.doc.mjs +1 -0
- package/api/docs/docs.type.d.mts +4 -4
- package/api/docs/docs.type.mjs +10 -10
- package/api/docs/index/index.mjs +6 -5
- package/api/docs/list/list.mjs +3 -7
- package/api/doctor/doctor.d.mts +25 -3
- package/api/doctor/doctor.doc.mjs +1 -0
- package/api/doctor/doctor.mjs +186 -18
- package/api/doctor/doctor.test.mjs +326 -1
- package/api/gap-report/gap-report.doc.mjs +8 -4
- package/api/hook/_adapter.mjs +19 -5
- package/api/hook/hook.doc.mjs +1 -0
- package/api/hook/hook.type.d.mts +3 -3
- package/api/hook/hook.type.mjs +11 -11
- package/api/hook/list/list.d.mts +1 -1
- package/api/hook/list/list.mjs +69 -17
- package/api/init/init.doc.mjs +5 -0
- package/api/init/init.test.mjs +41 -1
- package/api/init/remove/remove.mjs +1 -1
- package/api/init/run/run.mjs +20 -10
- package/api/integration/add-contribution.component-names.test.mjs +120 -0
- package/api/integration/add-contribution.mjs +23 -10
- package/api/integration/add-contribution.test.mjs +121 -7
- package/api/integration/add-theme.mjs +34 -64
- package/api/integration/add-theme.test.mjs +105 -21
- package/api/integration/authoring-checks.test.mjs +8 -4
- package/api/integration/integration-block-exports.test.mjs +10 -6
- package/api/integration/integrationAdd.doc.mjs +8 -4
- package/api/integration/integrationAddAgentDoc.doc.mjs +1 -0
- package/api/integration/integrationAddCodemod.doc.mjs +1 -0
- package/api/integration/integrationAddComponent.doc.mjs +2 -1
- package/api/integration/integrationAddDoc.doc.mjs +1 -0
- package/api/integration/integrationAddTemplate.doc.mjs +1 -0
- package/api/integration/integrationAddTheme.doc.mjs +6 -5
- package/api/integration/integrationComponentConflicts.doc.mjs +1 -0
- package/api/integration/integrationDocConflicts.doc.mjs +1 -0
- package/api/integration/integrationPackCheck.doc.mjs +1 -0
- package/api/integration/integrationTemplateConflicts.doc.mjs +1 -0
- package/api/integration/pack-check.mjs +49 -7
- package/api/integration/pack-check.test.mjs +266 -47
- package/api/integration/summarizeIssues.doc.mjs +1 -0
- package/api/integration/validate-integration-fixes.test.mjs +1389 -0
- package/api/integration/validate-integration.mjs +52 -102
- package/api/integration/validate-integration.test.mjs +176 -23
- package/api/integration/validate-unread-theme-folders.test.mjs +110 -0
- package/api/integration/validateIntegration.doc.mjs +2 -1
- package/api/json/assertResponse.doc.mjs +1 -0
- package/api/json/envelope-types.test.mjs +76 -0
- package/api/json/isError.doc.mjs +1 -0
- package/api/json/parseResponse.doc.mjs +3 -2
- package/api/layout/expand/expand.mjs +7 -5
- package/api/layout/expand/expand.path-safety.test.mjs +53 -0
- package/api/layout/grammar/grammar.mjs +2 -1
- package/api/layout/layoutCheck.doc.mjs +1 -0
- package/api/layout/layoutExpand.doc.mjs +2 -1
- package/api/layout/layoutGrammar.doc.mjs +1 -0
- package/api/search/search-return-type.test.mjs +54 -0
- package/api/search/search.d.mts +2 -9
- package/api/search/search.doc.mjs +6 -1
- package/api/search/search.mjs +31 -14
- package/api/search/search.test.mjs +34 -0
- package/api/search/search.type.d.mts +1 -1
- package/api/search/search.type.mjs +1 -1
- package/api/swizzle/copy/copy.mjs +28 -11
- package/api/swizzle/swizzle.doc.mjs +2 -1
- package/api/swizzle/swizzle.type.d.mts +2 -2
- package/api/swizzle/swizzle.type.mjs +2 -2
- package/api/template/copy/copy.mjs +17 -23
- package/api/template/copy/copy.test.mjs +17 -0
- package/api/template/template-suffix.test.mjs +41 -21
- package/api/template/template.doc.mjs +3 -1
- package/api/template/template.type.d.mts +5 -5
- package/api/template/template.type.mjs +12 -12
- package/api/theme/_adapter.d.mts +2 -3
- package/api/theme/_adapter.mjs +4 -5
- package/api/theme/add/add.binary.test.mjs +84 -0
- package/api/theme/add/add.mjs +20 -3
- package/api/theme/add/add.staging.test.mjs +66 -0
- package/api/theme/add/add.test.mjs +14 -1
- package/api/theme/build/build.mjs +133 -42
- package/api/theme/build/build.public-component-vars.test.mjs +1 -1
- package/api/theme/build/build.receipt-doc.test.mjs +111 -0
- package/api/theme/build/build.test.mjs +127 -0
- package/api/theme/build/font-warning.mjs +3 -3
- package/api/theme/build/font-warning.test.mjs +5 -2
- package/api/theme/generateTonalPalette.doc.mjs +1 -0
- package/api/theme/integration-themes.test.mjs +39 -28
- package/api/theme/list/list.test.mjs +19 -20
- package/api/theme/listThemes.doc.mjs +6 -5
- package/api/theme/palette/generate/generate.mjs +8 -3
- package/api/theme/palette/generate/generate.test.mjs +96 -0
- package/api/theme/palette/generate/generator.d.mts +10 -13
- package/api/theme/palette/generate/generator.mjs +15 -4
- package/api/theme/palette/generate/generator.test.mjs +10 -0
- package/api/theme/template/template.mjs +11 -2
- package/api/theme/template/template.test.mjs +15 -0
- package/api/theme/theme.type.d.mts +170 -11
- package/api/theme/theme.type.mjs +94 -27
- package/api/theme/themeAdd.doc.mjs +4 -3
- package/api/theme/themeBuild.doc.mjs +8 -4
- package/api/theme/themeList.doc.mjs +6 -3
- package/api/theme/themeListAvailable.doc.mjs +5 -3
- package/api/theme/themePaletteGenerate.doc.mjs +1 -0
- package/api/theme/themeTargets.doc.mjs +1 -0
- package/api/theme/themeTemplate.doc.mjs +5 -1
- package/api/upgrade/_adapter.d.mts +12 -3
- package/api/upgrade/_adapter.mjs +108 -70
- package/api/upgrade/list/list.mjs +2 -1
- package/api/upgrade/list/list.test.mjs +73 -0
- package/api/upgrade/provider-agreement.test.mjs +152 -0
- package/api/upgrade/run/run.mjs +1 -0
- package/api/upgrade/status/status.mjs +2 -2
- package/api/upgrade/upgrade.doc.mjs +3 -1
- package/api/upgrade/upgrade.type.d.mts +8 -4
- package/api/upgrade/upgrade.type.mjs +11 -10
- package/assets/codemods/integration-discovery.mjs +48 -4
- package/assets/codemods/integration-discovery.test.mjs +73 -0
- package/assets/codemods/runner.mjs +115 -5
- package/assets/codemods/term-log.mjs +32 -8
- package/assets/codemods/term-log.test.mjs +19 -1
- package/assets/codemods/transform-prop.mjs +109 -0
- package/assets/codemods/transform-prop.test.mjs +95 -0
- package/assets/codemods/transforms/next/__tests__/migrate-theme-catalog-to-descriptors.test.mjs +216 -0
- package/assets/codemods/transforms/next/index.mjs +11 -1
- package/assets/codemods/transforms/next/migrate-theme-catalog-to-descriptors.mjs +141 -0
- package/assets/codemods/transforms/v0.0.14/__tests__/rename-status-variants.test.mjs +86 -165
- package/assets/codemods/transforms/v0.0.14/rename-status-variants.mjs +72 -210
- package/assets/codemods/transforms/v0.1.8/__tests__/rename-avatar-size-scale.test.mjs +83 -115
- package/assets/codemods/transforms/v0.1.8/rename-avatar-size-scale.mjs +57 -186
- package/assets/codemods/transforms/v0.3.0/__tests__/unwrap-authoring-factories.test.mjs +27 -5
- package/assets/codemods/transforms/v0.3.0/unwrap-authoring-factories.mjs +20 -5
- package/assets/codemods/transforms/v0.6.0/__tests__/next-codemods.test.mjs +47 -0
- package/assets/codemods/transforms/v0.6.0/rename-resizable-pixel-bounds.mjs +57 -10
- package/assets/docs/cli-integrations.doc.mjs +26 -30
- package/assets/docs/cli.doc.mjs +15 -0
- package/assets/docs/styling-libraries.doc.mjs +1 -1
- package/assets/docs/theme.doc.mjs +1 -1
- package/assets/docs/working-with-ai.doc.mjs +1 -1
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.doc.mjs +14 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.tsx +61 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.doc.mjs +14 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.tsx +126 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.doc.mjs +15 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.tsx +86 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.doc.mjs +14 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.tsx +99 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.doc.mjs +14 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.tsx +122 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.doc.mjs +14 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.tsx +95 -0
- package/assets/templates/pages/table-tree/page.tsx +1704 -0
- package/assets/templates/pages/table-tree/template.doc.mjs +12 -0
- package/assets/templates/themes/butter/butterTheme.doc.mjs +11 -0
- package/assets/templates/themes/chocolate/chocolateTheme.doc.mjs +11 -0
- package/assets/templates/themes/gothic/gothicTheme.doc.mjs +11 -0
- package/assets/templates/themes/matcha/matchaTheme.doc.mjs +11 -0
- package/assets/templates/themes/neutral/neutralTheme.doc.mjs +11 -0
- package/assets/templates/themes/stone/stoneTheme.doc.mjs +11 -0
- package/assets/templates/themes/y2k/y2kTheme.doc.mjs +11 -0
- package/authoring/_shared/contract.ts +22 -0
- package/authoring/codemod/codemod.doc.mjs +7 -2
- package/authoring/codemod/parse.d.mts +8 -8
- package/authoring/codemod/parse.mjs +8 -6
- package/authoring/config/config.doc.mjs +2 -2
- package/authoring/config/debug-composition.test.mjs +92 -0
- package/authoring/config/parse.d.mts +13 -13
- package/authoring/config/parse.mjs +8 -8
- package/authoring/config/type.ts +18 -6
- package/authoring/debug/debug.doc.d.mts +11 -0
- package/authoring/debug/debug.doc.mjs +182 -0
- package/authoring/debug/parse.d.mts +4 -4
- package/authoring/debug/parse.mjs +3 -3
- package/authoring/doctypes/_schema.d.mts +121 -11
- package/authoring/doctypes/_schema.mjs +144 -13
- package/authoring/doctypes/base/graph-fields.doc.mjs +11 -4
- package/authoring/doctypes/base/type.ts +8 -4
- package/authoring/doctypes/command/command.doc.mjs +4 -3
- package/authoring/doctypes/command/parse.d.mts +2 -2
- package/authoring/doctypes/command/parse.mjs +1 -1
- package/authoring/doctypes/command/type.ts +3 -3
- package/authoring/doctypes/component/component.doc.mjs +5 -2
- package/authoring/doctypes/component/parse.d.mts +2 -2
- package/authoring/doctypes/component/parse.mjs +1 -1
- package/authoring/doctypes/component/type.ts +3 -3
- package/authoring/doctypes/doctypes-new.test.mjs +48 -6
- package/authoring/doctypes/enum/enum.doc.mjs +1 -1
- package/authoring/doctypes/enum/parse.d.mts +2 -2
- package/authoring/doctypes/enum/parse.mjs +1 -1
- package/authoring/doctypes/enum/type.ts +2 -2
- package/authoring/doctypes/function/function.doc.mjs +5 -1
- package/authoring/doctypes/function/parse.d.mts +2 -2
- package/authoring/doctypes/function/parse.mjs +1 -1
- package/authoring/doctypes/function/type.ts +2 -2
- package/authoring/doctypes/hook/hook.doc.mjs +4 -0
- package/authoring/doctypes/hook/parse.d.mts +2 -2
- package/authoring/doctypes/hook/parse.mjs +1 -1
- package/authoring/doctypes/hook/type.ts +3 -3
- package/authoring/doctypes/legacy.d.mts +6 -6
- package/authoring/doctypes/legacy.mjs +3 -3
- package/authoring/doctypes/load-contract.test.mjs +208 -0
- package/authoring/doctypes/namespace/namespace.doc.mjs +7 -3
- package/authoring/doctypes/namespace/parse.d.mts +2 -2
- package/authoring/doctypes/namespace/parse.mjs +1 -1
- package/authoring/doctypes/namespace/type.ts +2 -2
- package/authoring/doctypes/parse.d.mts +22 -20
- package/authoring/doctypes/parse.mjs +16 -12
- package/authoring/doctypes/reference/parse.d.mts +2 -2
- package/authoring/doctypes/reference/parse.mjs +1 -1
- package/authoring/doctypes/reference/reference.doc.mjs +7 -3
- package/authoring/doctypes/reference/type.ts +3 -3
- package/authoring/doctypes/schema/parse.d.mts +2 -2
- package/authoring/doctypes/schema/parse.mjs +1 -1
- package/authoring/doctypes/schema/schema.doc.mjs +1 -1
- package/authoring/doctypes/schema/type.ts +3 -4
- package/authoring/doctypes/template/parse.d.mts +92 -1
- package/authoring/doctypes/template/parse.mjs +33 -1
- package/authoring/doctypes/template/template.doc.mjs +7 -3
- package/authoring/doctypes/template/type.ts +4 -1
- package/authoring/doctypes/theme/parse.d.mts +35 -0
- package/authoring/doctypes/theme/parse.mjs +76 -0
- package/authoring/doctypes/theme/theme.doc.d.mts +9 -0
- package/authoring/doctypes/theme/theme.doc.mjs +79 -0
- package/authoring/doctypes/theme/type.ts +42 -0
- package/authoring/doctypes/types.ts +12 -11
- package/authoring/gap-report/gap-report.doc.d.mts +12 -0
- package/authoring/gap-report/gap-report.doc.mjs +183 -0
- package/authoring/gap-report/parse.d.mts +9 -9
- package/authoring/gap-report/parse.mjs +6 -6
- package/authoring/gap-report/type.ts +1 -1
- package/authoring/identity/identity.doc.mjs +3 -2
- package/authoring/identity/type.ts +10 -10
- package/authoring/index.d.mts +1 -0
- package/authoring/index.d.ts +21 -19
- package/authoring/index.mjs +2 -1
- package/authoring/integration/integration.doc.mjs +2 -2
- package/authoring/integration/parse.d.mts +2 -2
- package/authoring/integration/parse.mjs +1 -1
- package/authoring/integration/schema.d.mts +4 -4
- package/authoring/integration/schema.mjs +3 -3
- package/authoring/integration/type.ts +4 -10
- package/clients/cli/__tests__/cliManifest.test.ts +27 -29
- package/clients/cli/command-load-failure.test.mjs +83 -0
- package/clients/cli/commands/blog.doc.mjs +1 -1
- package/clients/cli/commands/blog.mjs +23 -8
- package/clients/cli/commands/blog.test.mjs +42 -1
- package/clients/cli/commands/build-theme.ascii-output.test.mjs +161 -0
- package/clients/cli/commands/build-theme.flag-docs.test.mjs +110 -0
- package/clients/cli/commands/build-theme.mjs +5 -5
- package/clients/cli/commands/build-theme.path-safety.test.mjs +86 -1
- package/clients/cli/commands/build-theme.variants.test.mjs +76 -0
- package/clients/cli/commands/build.doc.mjs +5 -2
- package/clients/cli/commands/build.exit-codes-doc.test.mjs +50 -0
- package/clients/cli/commands/build.mjs +32 -47
- package/clients/cli/commands/build.playbook.test.mjs +75 -0
- package/clients/cli/commands/build.text-fields.test.mjs +40 -0
- package/clients/cli/commands/component/index.mjs +2 -7
- package/clients/cli/commands/component-package.test.mjs +46 -0
- package/clients/cli/commands/component-resolution.test.mjs +21 -0
- package/clients/cli/commands/component.doc.mjs +1 -1
- package/clients/cli/commands/component.test.mjs +19 -0
- package/clients/cli/commands/detail-levels.test.mjs +2 -2
- package/clients/cli/commands/discover.broken-integration.test.mjs +48 -0
- package/clients/cli/commands/discover.components-flag.test.mjs +97 -0
- package/clients/cli/commands/discover.doc.mjs +5 -3
- package/clients/cli/commands/discover.mjs +3 -3
- package/clients/cli/commands/discover.text-projection.test.mjs +103 -0
- package/clients/cli/commands/docs.doc.mjs +1 -1
- package/clients/cli/commands/doctor-integration-components.doc.mjs +1 -1
- package/clients/cli/commands/doctor-integration-docs.doc.mjs +1 -1
- package/clients/cli/commands/doctor-integration-templates.doc.mjs +1 -1
- package/clients/cli/commands/doctor-integration-validate.doc.mjs +1 -1
- package/clients/cli/commands/doctor-integration.doc.mjs +1 -1
- package/clients/cli/commands/doctor-integration.package-json.test.mjs +53 -0
- package/clients/cli/commands/doctor-integration.test.mjs +15 -7
- package/clients/cli/commands/doctor.doc.mjs +1 -1
- package/clients/cli/commands/doctor.mjs +6 -16
- package/clients/cli/commands/doctor.test.mjs +42 -0
- package/clients/cli/commands/gap-report.doc.mjs +17 -6
- package/clients/cli/commands/gap-report.test.mjs +72 -0
- package/clients/cli/commands/hook/index.mjs +7 -17
- package/clients/cli/commands/hook.doc.mjs +1 -1
- package/clients/cli/commands/hook.text-projection.test.mjs +45 -0
- package/clients/cli/commands/init.doc.mjs +20 -9
- package/clients/cli/commands/init.flag-help.test.mjs +153 -0
- package/clients/cli/commands/integration-add.controls.test.mjs +132 -0
- package/clients/cli/commands/integration-add.doc.mjs +22 -6
- package/clients/cli/commands/integration-authoring.test.mjs +13 -9
- package/clients/cli/commands/integration-pack.doc.mjs +1 -1
- package/clients/cli/commands/integration-real-world.test.mjs +3 -9
- package/clients/cli/commands/integration.doc.mjs +1 -1
- package/clients/cli/commands/interactive-guard.test.mjs +101 -24
- package/clients/cli/commands/json-contract.test.mjs +33 -0
- package/clients/cli/commands/layout-check.doc.mjs +15 -4
- package/clients/cli/commands/layout-expand.doc.mjs +22 -5
- package/clients/cli/commands/layout-grammar.doc.mjs +1 -1
- package/clients/cli/commands/layout.doc.mjs +3 -3
- package/clients/cli/commands/layout.mjs +21 -9
- package/clients/cli/commands/layout.path-help.test.mjs +33 -0
- package/clients/cli/commands/layout.stdin-cap.test.mjs +47 -0
- package/clients/cli/commands/layout.text-fields.test.mjs +39 -0
- package/clients/cli/commands/manifest.doc.mjs +1 -1
- package/clients/cli/commands/no-prompt-wording.test.mjs +94 -0
- package/clients/cli/commands/search.doc.mjs +7 -4
- package/clients/cli/commands/search.mjs +17 -7
- package/clients/cli/commands/search.test.mjs +75 -0
- package/clients/cli/commands/swizzle.doc.mjs +3 -2
- package/clients/cli/commands/swizzle.path-safety.test.mjs +42 -0
- package/clients/cli/commands/template.doc.mjs +29 -7
- package/clients/cli/commands/template.flag-help.test.mjs +117 -0
- package/clients/cli/commands/template.path-help.test.mjs +40 -0
- package/clients/cli/commands/theme-add.doc.mjs +4 -3
- package/clients/cli/commands/theme-build.doc.mjs +8 -7
- package/clients/cli/commands/theme-list.doc.mjs +2 -2
- package/clients/cli/commands/theme-palette-generate.doc.mjs +3 -3
- package/clients/cli/commands/theme-palette-generate.test.mjs +19 -0
- package/clients/cli/commands/theme-palette.doc.mjs +1 -1
- package/clients/cli/commands/theme-targets.doc.mjs +1 -1
- package/clients/cli/commands/theme-template.behavior.test.mjs +12 -0
- package/clients/cli/commands/theme-template.doc.mjs +2 -2
- package/clients/cli/commands/theme.doc.mjs +1 -1
- package/clients/cli/commands/upgrade.ascii-output.test.mjs +87 -0
- package/clients/cli/commands/upgrade.doc.mjs +18 -7
- package/clients/cli/commands/upgrade.flag-help.test.mjs +188 -0
- package/clients/cli/commands/upgrade.hook-output.test.mjs +88 -0
- package/clients/cli/index.mjs +13 -30
- package/clients/cli/latest-version-env.test.mjs +50 -0
- package/clients/cli/lib/cli-error.test.mjs +7 -0
- package/clients/cli/lib/component-format.mjs +9 -9
- package/clients/cli/lib/component-format.test.mjs +1 -1
- package/clients/cli/lib/define-command.mjs +32 -6
- package/clients/cli/lib/doc-text-ascii.test.mjs +82 -0
- package/clients/cli/lib/exit-codes.test.mjs +97 -0
- package/clients/cli/lib/hook-format.mjs +19 -10
- package/clients/cli/lib/json-shim.mjs +38 -2
- package/clients/cli/lib/json-shim.test.mjs +83 -0
- package/clients/cli/lib/manifest.d.ts +2 -0
- package/clients/cli/lib/manifest.mjs +22 -0
- package/clients/cli/lib/manifest.test.mjs +17 -0
- package/foundation/agent-docs/agent-docs.d.mts +4 -0
- package/foundation/agent-docs/agent-docs.mjs +69 -3
- package/foundation/agent-docs/agent-docs.path-safety.test.mjs +266 -4
- package/foundation/config/integration-debug.test.mjs +28 -3
- package/foundation/config/project-themes.test.mjs +11 -19
- package/foundation/config/project.d.mts +8 -0
- package/foundation/config/project.mjs +173 -30
- package/foundation/config/project.test.mjs +129 -16
- package/foundation/discovery/authoring-self-docs.d.mts +6 -0
- package/foundation/discovery/authoring-self-docs.mjs +17 -7
- package/foundation/discovery/authoring-self-docs.test.mjs +71 -12
- package/foundation/discovery/authoring-surface.d.mts +74 -0
- package/foundation/discovery/authoring-surface.mjs +525 -0
- package/foundation/discovery/authoring-surface.test.mjs +392 -0
- package/foundation/discovery/cli-self-docs.d.mts +113 -0
- package/foundation/discovery/cli-self-docs.mjs +514 -0
- package/foundation/discovery/cli-self-docs.test.mjs +437 -0
- package/foundation/discovery/component-loader.d.mts +35 -38
- package/foundation/discovery/component-loader.mjs +53 -222
- package/foundation/discovery/docs-discovery.d.mts +7 -2
- package/foundation/discovery/docs-discovery.mjs +24 -14
- package/foundation/discovery/docs-discovery.test.mjs +55 -16
- package/foundation/discovery/template-adapter.d.mts +21 -5
- package/foundation/discovery/template-adapter.fixture-refs.test.mjs +248 -0
- package/foundation/discovery/template-adapter.integration-isolation.test.mjs +94 -0
- package/foundation/discovery/template-adapter.mjs +319 -65
- package/foundation/discovery/template-adapter.test.mjs +15 -0
- package/foundation/discovery/theme-discovery.d.mts +67 -7
- package/foundation/discovery/theme-discovery.mjs +916 -186
- package/foundation/discovery/theme-discovery.test.mjs +613 -219
- package/foundation/discovery/theming-targets.test.mjs +4 -0
- package/foundation/doc-compiler/bundle.d.mts +47 -0
- package/foundation/doc-compiler/bundle.mjs +218 -0
- package/foundation/doc-compiler/bundle.test.mjs +255 -0
- package/foundation/doc-compiler/compile.d.mts +362 -0
- package/foundation/doc-compiler/compile.mjs +511 -0
- package/foundation/doc-compiler/diagnostics.d.mts +126 -0
- package/foundation/doc-compiler/diagnostics.mjs +277 -0
- package/foundation/doc-compiler/doc-compiler.test.mjs +714 -0
- package/foundation/doc-compiler/doc-loads.test.mjs +1642 -0
- package/foundation/doc-compiler/import.d.mts +24 -0
- package/foundation/doc-compiler/import.mjs +59 -0
- package/foundation/doc-compiler/inputs.d.mts +102 -0
- package/foundation/doc-compiler/inputs.mjs +286 -0
- package/foundation/doc-compiler/inputs.test.mjs +299 -0
- package/foundation/doc-compiler/ir.d.mts +22 -0
- package/foundation/doc-compiler/ir.mjs +464 -0
- package/foundation/doc-compiler/lenses.d.mts +33 -0
- package/foundation/doc-compiler/lenses.mjs +127 -0
- package/foundation/doc-compiler/lower-doc.test.mjs +492 -0
- package/foundation/doc-compiler/overlays.d.mts +37 -0
- package/foundation/doc-compiler/overlays.mjs +206 -0
- package/foundation/doc-compiler/parse-readable.d.mts +9 -0
- package/foundation/doc-compiler/parse-readable.mjs +29 -0
- package/foundation/doc-compiler/read.d.mts +126 -0
- package/foundation/doc-compiler/read.mjs +320 -0
- package/foundation/doc-compiler/read.test.mjs +313 -0
- package/foundation/doc-compiler/source.d.mts +33 -0
- package/foundation/doc-compiler/source.mjs +128 -0
- package/foundation/fs/module-loader.d.mts +1 -0
- package/foundation/fs/module-loader.mjs +50 -1
- package/foundation/fs/module-loader.stdout.test.mjs +332 -0
- package/foundation/fs/path-safety.d.mts +3 -2
- package/foundation/fs/path-safety.mjs +49 -19
- package/foundation/fs/path-safety.test.mjs +50 -0
- package/foundation/fs/publish-file-hardlink-unavailable.test.mjs +129 -94
- package/foundation/integrations/autolink.d.mts +58 -1
- package/foundation/integrations/autolink.mjs +143 -52
- package/foundation/integrations/contribution-fixes.d.mts +145 -0
- package/foundation/integrations/contribution-fixes.mjs +1284 -0
- package/foundation/integrations/contribution-inventory.d.mts +1 -1
- package/foundation/integrations/contribution-inventory.mjs +17 -20
- package/foundation/integrations/contribution-inventory.test.mjs +67 -27
- package/foundation/integrations/integrations.d.mts +3 -0
- package/foundation/integrations/integrations.mjs +11 -97
- package/foundation/integrations/provider-ledger.test.mjs +275 -0
- package/foundation/integrations/provider-resolution.d.mts +152 -0
- package/foundation/integrations/provider-resolution.mjs +576 -0
- package/foundation/integrations/provider-resolution.test.mjs +369 -0
- package/foundation/integrations/theme-descriptor.d.mts +8 -0
- package/foundation/integrations/theme-descriptor.mjs +44 -0
- package/foundation/integrations/validate-contributions.mjs +104 -10
- package/foundation/response/base.d.ts +8 -4
- package/foundation/response/error-codes.doc.mjs +3 -4
- package/foundation/response/error-codes.mjs +2 -2
- package/foundation/response/error-codes.test.mjs +83 -0
- package/foundation/response/json-contract.test.mjs +11 -0
- package/foundation/response/json.d.mts +4 -2
- package/foundation/response/json.mjs +8 -10
- package/foundation/response/response-types.doc.mjs +11 -11
- package/foundation/response/response-types.doc.test.mjs +158 -0
- package/foundation/response/response.doc.mjs +1 -1
- package/foundation/text/string-utils.mjs +22 -10
- package/foundation/xle/expand.d.mts +2 -0
- package/foundation/xle/expand.mjs +3 -2
- package/foundation/xle/expand.test.mjs +54 -0
- package/package.json +9 -11
- package/assets/templates/themes/manifest.json +0 -95
- package/clients/cli/lib/update-check.mjs +0 -83
- package/clients/cli/lib/update-check.test.mjs +0 -137
- package/clients/cli/update-hint-commands.test.mjs +0 -54
|
@@ -5,10 +5,11 @@ export const doc = {
|
|
|
5
5
|
type: 'function',
|
|
6
6
|
kind: 'api',
|
|
7
7
|
name: 'integrationAddComponent',
|
|
8
|
+
namespace: 'cli/api',
|
|
8
9
|
displayName: 'integrationAddComponent()',
|
|
9
10
|
summary: 'Add a complete component contribution.',
|
|
10
11
|
description:
|
|
11
|
-
'Creates the same-stem component source and metadata pair, declares the components root on first use, preserves existing package allowlists, and publishes an exact source subpath when the package already has an exports map.',
|
|
12
|
+
'Creates the same-stem component source and metadata pair, declares the components root on first use, preserves existing package allowlists, and publishes an exact source subpath when the package already has an exports map. Refuses with ERR_FILE_EXISTS when a component doc anywhere under the components root already uses the name.',
|
|
12
13
|
importPath: '@astryxdesign/cli/api',
|
|
13
14
|
signature:
|
|
14
15
|
'integrationAddComponent(name: string, options?: IntegrationAddComponentOptions): Promise<IntegrationAddResponse>',
|
|
@@ -5,10 +5,11 @@ export const doc = {
|
|
|
5
5
|
type: 'function',
|
|
6
6
|
kind: 'api',
|
|
7
7
|
name: 'integrationAddTheme',
|
|
8
|
+
namespace: 'cli/api',
|
|
8
9
|
displayName: 'integrationAddTheme()',
|
|
9
10
|
summary: 'Add a source theme to an integration package.',
|
|
10
11
|
description:
|
|
11
|
-
'Creates an integration manifest when the package has none, writes a minimal named-export defineTheme source file
|
|
12
|
+
'Creates an integration manifest when the package has none, writes a minimal named-export defineTheme source file plus its strongly typed same-stem ThemeDoc, declares the optional themes root on first use, and includes the manifest and root in package.json files when the package already uses an allowlist. Every path is confined to the package and existing theme directories are never overwritten.',
|
|
12
13
|
importPath: '@astryxdesign/cli/api',
|
|
13
14
|
signature:
|
|
14
15
|
'integrationAddTheme(name: string, options?: IntegrationAddThemeOptions): Promise<IntegrationAddResponse>',
|
|
@@ -17,7 +18,7 @@ export const doc = {
|
|
|
17
18
|
{
|
|
18
19
|
name: 'name',
|
|
19
20
|
type: 'string',
|
|
20
|
-
description: 'Lowercase kebab-case theme name and
|
|
21
|
+
description: 'Lowercase kebab-case theme name and directory slug.',
|
|
21
22
|
required: true,
|
|
22
23
|
},
|
|
23
24
|
{
|
|
@@ -51,7 +52,7 @@ export const doc = {
|
|
|
51
52
|
},
|
|
52
53
|
{
|
|
53
54
|
code: 'ERR_FILE_EXISTS',
|
|
54
|
-
when: 'the theme slug
|
|
55
|
+
when: 'the theme slug directory already exists',
|
|
55
56
|
},
|
|
56
57
|
{
|
|
57
58
|
code: 'ERR_PATH_TRAVERSAL',
|
|
@@ -63,7 +64,7 @@ export const doc = {
|
|
|
63
64
|
},
|
|
64
65
|
{
|
|
65
66
|
code: 'ERR_THEME_INVALID',
|
|
66
|
-
when: 'the package, integration manifest, or theme
|
|
67
|
+
when: 'the package, integration manifest, or theme descriptor is invalid',
|
|
67
68
|
},
|
|
68
69
|
{
|
|
69
70
|
code: 'ERR_WRITE_FAILED',
|
|
@@ -80,6 +81,6 @@ export const doc = {
|
|
|
80
81
|
code: "await integrationAddTheme('ocean', {dryRun: true});",
|
|
81
82
|
},
|
|
82
83
|
],
|
|
83
|
-
command: 'integration add',
|
|
84
|
+
command: 'integration add theme',
|
|
84
85
|
related: ['themeList', 'themeAdd', 'validateIntegration'],
|
|
85
86
|
};
|
|
@@ -388,6 +388,14 @@ async function validatePackedComponentExports(integration, scratchBase) {
|
|
|
388
388
|
components.map(component => component.specifier),
|
|
389
389
|
scratchBase,
|
|
390
390
|
);
|
|
391
|
+
issues.push(
|
|
392
|
+
...validateSpecifierExtensions(
|
|
393
|
+
components.map(({name, specifier}) => ({
|
|
394
|
+
label: `Component "${name}"`,
|
|
395
|
+
specifier,
|
|
396
|
+
})),
|
|
397
|
+
),
|
|
398
|
+
);
|
|
391
399
|
for (const {name, specifier} of components) {
|
|
392
400
|
const result = resolved.get(specifier);
|
|
393
401
|
if (!result?.url || result.error) {
|
|
@@ -427,19 +435,27 @@ async function validatePackedComponentExports(integration, scratchBase) {
|
|
|
427
435
|
*/
|
|
428
436
|
async function validatePackedTemplateExports(integration, scratchBase) {
|
|
429
437
|
const {templates} = await discoverIntegrationTemplatesForOne(integration);
|
|
430
|
-
const entries = templates.map(template =>
|
|
431
|
-
|
|
432
|
-
specifier: `${integration.name}/${path
|
|
438
|
+
const entries = templates.map(template => {
|
|
439
|
+
const relPath = path
|
|
433
440
|
.relative(integration.__packageDir, template.filePath)
|
|
434
441
|
.split(path.sep)
|
|
435
|
-
.join('/')
|
|
436
|
-
|
|
442
|
+
.join('/');
|
|
443
|
+
const extensionless = relPath.replace(/\.tsx?$/u, '');
|
|
444
|
+
return {
|
|
445
|
+
id: template.dirName,
|
|
446
|
+
specifier: `${integration.name}/${extensionless}`,
|
|
447
|
+
};
|
|
448
|
+
});
|
|
437
449
|
const resolved = resolveConsumerSpecifiers(
|
|
438
450
|
entries.map(entry => entry.specifier),
|
|
439
451
|
scratchBase,
|
|
440
452
|
);
|
|
441
|
-
|
|
442
|
-
|
|
453
|
+
const issues = validateSpecifierExtensions(
|
|
454
|
+
entries.map(({id, specifier}) => ({
|
|
455
|
+
label: `Template "${id}"`,
|
|
456
|
+
specifier,
|
|
457
|
+
})),
|
|
458
|
+
);
|
|
443
459
|
for (const {id, specifier} of entries) {
|
|
444
460
|
const result = resolved.get(specifier);
|
|
445
461
|
if (!result?.url || result.error) {
|
|
@@ -469,6 +485,32 @@ async function validatePackedTemplateExports(integration, scratchBase) {
|
|
|
469
485
|
return issues;
|
|
470
486
|
}
|
|
471
487
|
|
|
488
|
+
const TS_EXTENSION_RE = /\.tsx?$/u;
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* Reject specifiers that end in a TypeScript extension — they fail under
|
|
492
|
+
* default `moduleResolution` with TS5097/TS2307 unless the consumer enables
|
|
493
|
+
* `allowImportingTsExtensions`.
|
|
494
|
+
*
|
|
495
|
+
* @param {Array<{label: string, specifier: string}>} entries
|
|
496
|
+
* @returns {Issue[]}
|
|
497
|
+
*/
|
|
498
|
+
function validateSpecifierExtensions(entries) {
|
|
499
|
+
/** @type {Issue[]} */
|
|
500
|
+
const issues = [];
|
|
501
|
+
for (const {label, specifier} of entries) {
|
|
502
|
+
if (TS_EXTENSION_RE.test(specifier)) {
|
|
503
|
+
issues.push(
|
|
504
|
+
error(
|
|
505
|
+
'typescript_extension_in_specifier',
|
|
506
|
+
`${label} advertises import "${specifier}", which ends in a TypeScript extension. A consumer with default moduleResolution will reject it (TS5097). Use an extensionless specifier mapped through the package exports.`,
|
|
507
|
+
),
|
|
508
|
+
);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
return issues;
|
|
512
|
+
}
|
|
513
|
+
|
|
472
514
|
/**
|
|
473
515
|
* Verify an integration package is ready to publish.
|
|
474
516
|
*
|
|
@@ -53,25 +53,10 @@ function writePackage({
|
|
|
53
53
|
"import {defineTheme} from '@astryxdesign/core/theme';\n\nexport const oceanTheme = defineTheme({name: 'ocean'});\n",
|
|
54
54
|
);
|
|
55
55
|
fs.writeFileSync(
|
|
56
|
-
path.join(root, '
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
themes: [
|
|
61
|
-
{
|
|
62
|
-
slug: 'ocean',
|
|
63
|
-
displayName: 'Ocean',
|
|
64
|
-
description: 'Ocean theme.',
|
|
65
|
-
maintained: true,
|
|
66
|
-
entry: 'oceanTheme.ts',
|
|
67
|
-
exportName: 'oceanTheme',
|
|
68
|
-
files: ['oceanTheme.ts'],
|
|
69
|
-
},
|
|
70
|
-
],
|
|
71
|
-
},
|
|
72
|
-
null,
|
|
73
|
-
2,
|
|
74
|
-
) + '\n',
|
|
56
|
+
path.join(root, 'ocean', 'oceanTheme.doc.mjs'),
|
|
57
|
+
`/** @type {import('@astryxdesign/cli/authoring').ThemeDoc} */
|
|
58
|
+
export default {type: 'theme', name: 'ocean', displayName: 'Ocean', description: 'Ocean theme.', maintained: true};
|
|
59
|
+
`,
|
|
75
60
|
);
|
|
76
61
|
}
|
|
77
62
|
if (components) {
|
|
@@ -109,7 +94,7 @@ describe('integrationPackCheck', () => {
|
|
|
109
94
|
);
|
|
110
95
|
});
|
|
111
96
|
|
|
112
|
-
it('fails when a theme entry omits its
|
|
97
|
+
it('fails when a theme entry omits its inferred runtime export', async () => {
|
|
113
98
|
writePackage({files: ['astryx.integration.mjs', 'themes']});
|
|
114
99
|
fs.writeFileSync(
|
|
115
100
|
path.join(tmpDir, 'themes', 'ocean', 'oceanTheme.ts'),
|
|
@@ -129,19 +114,12 @@ describe('integrationPackCheck', () => {
|
|
|
129
114
|
);
|
|
130
115
|
});
|
|
131
116
|
|
|
132
|
-
it('fails when a theme imports a
|
|
117
|
+
it('fails when a theme imports a missing local file', async () => {
|
|
133
118
|
writePackage({files: ['astryx.integration.mjs', 'themes']});
|
|
134
|
-
fs.mkdirSync(path.join(tmpDir, 'themes', 'ocean', 'tokens'), {
|
|
135
|
-
recursive: true,
|
|
136
|
-
});
|
|
137
119
|
fs.writeFileSync(
|
|
138
120
|
path.join(tmpDir, 'themes', 'ocean', 'oceanTheme.ts'),
|
|
139
121
|
"import {oceanPalette} from './tokens/ocean.palette';\nexport const oceanTheme = {oceanPalette};\n",
|
|
140
122
|
);
|
|
141
|
-
fs.writeFileSync(
|
|
142
|
-
path.join(tmpDir, 'themes', 'ocean', 'tokens', 'ocean.palette.ts'),
|
|
143
|
-
'export const oceanPalette = {};\n',
|
|
144
|
-
);
|
|
145
123
|
|
|
146
124
|
const result = await integrationPackCheck({cwd: tmpDir});
|
|
147
125
|
|
|
@@ -150,7 +128,7 @@ describe('integrationPackCheck', () => {
|
|
|
150
128
|
expect.objectContaining({
|
|
151
129
|
code: 'invalid_theme',
|
|
152
130
|
message: expect.stringContaining(
|
|
153
|
-
'must resolve to a
|
|
131
|
+
'must resolve to a file inside the theme directory',
|
|
154
132
|
),
|
|
155
133
|
}),
|
|
156
134
|
);
|
|
@@ -231,7 +209,7 @@ describe('integrationPackCheck', () => {
|
|
|
231
209
|
);
|
|
232
210
|
fs.mkdirSync(path.join(tmpDir, 'templates'));
|
|
233
211
|
fs.writeFileSync(
|
|
234
|
-
path.join(tmpDir, 'templates', 'account-page.
|
|
212
|
+
path.join(tmpDir, 'templates', 'account-page.doc.mjs'),
|
|
235
213
|
"export default {type: 'page', name: 'Account page', description: 'Account page.'};\n",
|
|
236
214
|
);
|
|
237
215
|
fs.writeFileSync(
|
|
@@ -314,10 +292,10 @@ describe('integrationPackCheck', () => {
|
|
|
314
292
|
const script = [
|
|
315
293
|
"const fs=require('fs')",
|
|
316
294
|
"fs.renameSync('themes/ocean','themes/storm')",
|
|
317
|
-
"const p='themes/
|
|
318
|
-
|
|
319
|
-
"x.
|
|
320
|
-
'fs.writeFileSync(p,
|
|
295
|
+
"const p='themes/storm/oceanTheme.doc.mjs'",
|
|
296
|
+
"let x=fs.readFileSync(p,'utf8')",
|
|
297
|
+
"x=x.replace(/name: 'ocean'/, 'name: '+String.fromCharCode(39)+'storm'+String.fromCharCode(39))",
|
|
298
|
+
'fs.writeFileSync(p,x)',
|
|
321
299
|
].join(';');
|
|
322
300
|
writePackage({
|
|
323
301
|
files: ['astryx.integration.mjs', 'themes'],
|
|
@@ -513,23 +491,15 @@ describe('integrationPackCheck', () => {
|
|
|
513
491
|
});
|
|
514
492
|
|
|
515
493
|
describe('pack-check mutation tests', () => {
|
|
516
|
-
it('detects when a theme
|
|
494
|
+
it('detects when a theme source is deleted after initial authoring', async () => {
|
|
517
495
|
writePackage({files: ['astryx.integration.mjs', 'themes']});
|
|
518
|
-
|
|
519
|
-
// Write a second theme file then delete it — catalog still references it
|
|
520
|
-
const catalog = JSON.parse(
|
|
521
|
-
fs.readFileSync(path.join(tmpDir, 'themes', 'manifest.json'), 'utf-8'),
|
|
522
|
-
);
|
|
523
|
-
catalog.themes[0].files.push('tokens.ts');
|
|
524
|
-
fs.writeFileSync(
|
|
525
|
-
path.join(tmpDir, 'themes', 'manifest.json'),
|
|
526
|
-
JSON.stringify(catalog, null, 2) + '\n',
|
|
527
|
-
);
|
|
528
|
-
// tokens.ts doesn't exist on disk → will be in inventory but not on disk
|
|
529
|
-
// (Phase 1 catches this; the file won't be in the pack list either)
|
|
496
|
+
fs.rmSync(path.join(tmpDir, 'themes', 'ocean', 'oceanTheme.ts'));
|
|
530
497
|
|
|
531
498
|
const result = await integrationPackCheck({cwd: tmpDir});
|
|
532
499
|
expect(result.data.packable).toBe(false);
|
|
500
|
+
expect(result.data.issues).toContainEqual(
|
|
501
|
+
expect.objectContaining({code: 'invalid_theme'}),
|
|
502
|
+
);
|
|
533
503
|
});
|
|
534
504
|
|
|
535
505
|
it('detects when files[] is narrowed after add removes themes', async () => {
|
|
@@ -567,3 +537,252 @@ describe('pack-check mutation tests', () => {
|
|
|
567
537
|
}
|
|
568
538
|
});
|
|
569
539
|
});
|
|
540
|
+
|
|
541
|
+
describe('extensionless subpath resolution', () => {
|
|
542
|
+
it('rejects .tsx public specifiers before publishing', async () => {
|
|
543
|
+
// Manually construct a package with OLD-style .tsx exports keys
|
|
544
|
+
writePackage({
|
|
545
|
+
manifest: "export default {components: './components'};\n",
|
|
546
|
+
files: ['astryx.integration.mjs', 'components', 'index.mjs'],
|
|
547
|
+
themes: false,
|
|
548
|
+
});
|
|
549
|
+
const pkgFile = path.join(tmpDir, 'package.json');
|
|
550
|
+
const pkg = JSON.parse(fs.readFileSync(pkgFile, 'utf-8'));
|
|
551
|
+
pkg.exports = {
|
|
552
|
+
'.': './index.mjs',
|
|
553
|
+
'./components/AcmeWidget.tsx': './components/AcmeWidget.tsx',
|
|
554
|
+
};
|
|
555
|
+
fs.writeFileSync(pkgFile, `${JSON.stringify(pkg, null, 2)}\n`);
|
|
556
|
+
fs.writeFileSync(
|
|
557
|
+
path.join(tmpDir, 'index.mjs'),
|
|
558
|
+
'export const existing = 1;\n',
|
|
559
|
+
);
|
|
560
|
+
fs.mkdirSync(path.join(tmpDir, 'components'));
|
|
561
|
+
fs.writeFileSync(
|
|
562
|
+
path.join(tmpDir, 'components', 'AcmeWidget.doc.mjs'),
|
|
563
|
+
`export default {type: 'component', name: 'AcmeWidget', import: '@acme/widgets/components/AcmeWidget.tsx', description: 'Widget.', props: []};\n`,
|
|
564
|
+
);
|
|
565
|
+
fs.writeFileSync(
|
|
566
|
+
path.join(tmpDir, 'components', 'AcmeWidget.tsx'),
|
|
567
|
+
'export function AcmeWidget() { return null; }\n',
|
|
568
|
+
);
|
|
569
|
+
|
|
570
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
571
|
+
|
|
572
|
+
// The .tsx extension in the specifier must be caught
|
|
573
|
+
expect(result.data.packable).toBe(false);
|
|
574
|
+
expect(result.data.issues).toContainEqual(
|
|
575
|
+
expect.objectContaining({
|
|
576
|
+
code: 'typescript_extension_in_specifier',
|
|
577
|
+
message: expect.stringContaining('.tsx'),
|
|
578
|
+
}),
|
|
579
|
+
);
|
|
580
|
+
});
|
|
581
|
+
|
|
582
|
+
it('generated extensionless component specifier resolves through exports map', async () => {
|
|
583
|
+
fs.writeFileSync(
|
|
584
|
+
path.join(tmpDir, 'package.json'),
|
|
585
|
+
`${JSON.stringify({
|
|
586
|
+
name: '@acme/widgets',
|
|
587
|
+
version: '1.0.0',
|
|
588
|
+
files: ['index.mjs'],
|
|
589
|
+
exports: {'.': './index.mjs'},
|
|
590
|
+
})}\n`,
|
|
591
|
+
);
|
|
592
|
+
fs.writeFileSync(
|
|
593
|
+
path.join(tmpDir, 'index.mjs'),
|
|
594
|
+
'export const existing = 1;\n',
|
|
595
|
+
);
|
|
596
|
+
await integrationAddComponent('AcmeWidget', {cwd: tmpDir});
|
|
597
|
+
|
|
598
|
+
// Verify the exports map has extensionless key → .tsx target
|
|
599
|
+
const pkg = JSON.parse(
|
|
600
|
+
fs.readFileSync(path.join(tmpDir, 'package.json'), 'utf-8'),
|
|
601
|
+
);
|
|
602
|
+
expect(pkg.exports['./components/AcmeWidget']).toBe(
|
|
603
|
+
'./components/AcmeWidget.tsx',
|
|
604
|
+
);
|
|
605
|
+
expect(pkg.exports['./components/AcmeWidget.tsx']).toBeUndefined();
|
|
606
|
+
|
|
607
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
608
|
+
|
|
609
|
+
expect(result.data.packable).toBe(true);
|
|
610
|
+
expect(result.data.issues).not.toContainEqual(
|
|
611
|
+
expect.objectContaining({code: 'typescript_extension_in_specifier'}),
|
|
612
|
+
);
|
|
613
|
+
expect(result.data.issues).not.toContainEqual(
|
|
614
|
+
expect.objectContaining({code: 'component_import_unresolvable'}),
|
|
615
|
+
);
|
|
616
|
+
});
|
|
617
|
+
|
|
618
|
+
it('validates generated imports without project-local TypeScript', async () => {
|
|
619
|
+
fs.rmSync(tmpDir, {recursive: true, force: true});
|
|
620
|
+
tmpDir = fs.mkdtempSync(
|
|
621
|
+
path.join(os.tmpdir(), 'astryx-pack-check-no-typescript-'),
|
|
622
|
+
);
|
|
623
|
+
fs.writeFileSync(
|
|
624
|
+
path.join(tmpDir, 'package.json'),
|
|
625
|
+
`${JSON.stringify({
|
|
626
|
+
name: '@acme/widgets',
|
|
627
|
+
version: '1.0.0',
|
|
628
|
+
files: ['index.mjs'],
|
|
629
|
+
exports: {'.': './index.mjs'},
|
|
630
|
+
})}\n`,
|
|
631
|
+
);
|
|
632
|
+
fs.writeFileSync(
|
|
633
|
+
path.join(tmpDir, 'index.mjs'),
|
|
634
|
+
'export const existing = 1;\n',
|
|
635
|
+
);
|
|
636
|
+
await integrationAddComponent('AcmeWidget', {cwd: tmpDir});
|
|
637
|
+
|
|
638
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
639
|
+
|
|
640
|
+
expect(result.data.packable).toBe(true);
|
|
641
|
+
expect(result.data.issues).not.toContainEqual(
|
|
642
|
+
expect.objectContaining({code: 'component_import_unresolvable'}),
|
|
643
|
+
);
|
|
644
|
+
});
|
|
645
|
+
|
|
646
|
+
it('generated extensionless template specifiers resolve for page and block types', async () => {
|
|
647
|
+
fs.writeFileSync(
|
|
648
|
+
path.join(tmpDir, 'package.json'),
|
|
649
|
+
`${JSON.stringify({
|
|
650
|
+
name: '@acme/widgets',
|
|
651
|
+
version: '1.0.0',
|
|
652
|
+
files: ['index.mjs'],
|
|
653
|
+
exports: {'.': './index.mjs'},
|
|
654
|
+
})}\n`,
|
|
655
|
+
);
|
|
656
|
+
fs.writeFileSync(
|
|
657
|
+
path.join(tmpDir, 'index.mjs'),
|
|
658
|
+
'export const existing = 1;\n',
|
|
659
|
+
);
|
|
660
|
+
await integrationAddTemplate('account-page', {cwd: tmpDir, type: 'page'});
|
|
661
|
+
await integrationAddTemplate('info-card', {cwd: tmpDir, type: 'block'});
|
|
662
|
+
|
|
663
|
+
const pkg = JSON.parse(
|
|
664
|
+
fs.readFileSync(path.join(tmpDir, 'package.json'), 'utf-8'),
|
|
665
|
+
);
|
|
666
|
+
expect(pkg.exports['./templates/account-page']).toBe(
|
|
667
|
+
'./templates/account-page.tsx',
|
|
668
|
+
);
|
|
669
|
+
expect(pkg.exports['./templates/info-card']).toBe(
|
|
670
|
+
'./templates/info-card.tsx',
|
|
671
|
+
);
|
|
672
|
+
|
|
673
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
674
|
+
|
|
675
|
+
expect(result.data.packable).toBe(true);
|
|
676
|
+
expect(result.data.issues).not.toContainEqual(
|
|
677
|
+
expect.objectContaining({code: 'template_import_unresolvable'}),
|
|
678
|
+
);
|
|
679
|
+
expect(result.data.issues).not.toContainEqual(
|
|
680
|
+
expect.objectContaining({code: 'typescript_extension_in_specifier'}),
|
|
681
|
+
);
|
|
682
|
+
});
|
|
683
|
+
|
|
684
|
+
it('preserves condition-style exports sugar without creating a map', async () => {
|
|
685
|
+
// Package with condition-only exports (sugar, no subpaths)
|
|
686
|
+
fs.writeFileSync(
|
|
687
|
+
path.join(tmpDir, 'package.json'),
|
|
688
|
+
`${JSON.stringify({
|
|
689
|
+
name: '@acme/widgets',
|
|
690
|
+
version: '1.0.0',
|
|
691
|
+
files: ['index.mjs'],
|
|
692
|
+
exports: {import: './index.mjs', require: './index.cjs'},
|
|
693
|
+
})}\n`,
|
|
694
|
+
);
|
|
695
|
+
fs.writeFileSync(
|
|
696
|
+
path.join(tmpDir, 'index.mjs'),
|
|
697
|
+
'export const existing = 1;\n',
|
|
698
|
+
);
|
|
699
|
+
fs.writeFileSync(path.join(tmpDir, 'index.cjs'), 'exports.existing = 1;\n');
|
|
700
|
+
fs.writeFileSync(
|
|
701
|
+
path.join(tmpDir, 'astryx.integration.mjs'),
|
|
702
|
+
'export default {};\n',
|
|
703
|
+
);
|
|
704
|
+
|
|
705
|
+
await integrationAddComponent('AcmeWidget', {cwd: tmpDir});
|
|
706
|
+
|
|
707
|
+
const pkg = JSON.parse(
|
|
708
|
+
fs.readFileSync(path.join(tmpDir, 'package.json'), 'utf-8'),
|
|
709
|
+
);
|
|
710
|
+
// Condition sugar wrapped into subpath map with the component added
|
|
711
|
+
expect(pkg.exports['.']).toEqual({
|
|
712
|
+
import: './index.mjs',
|
|
713
|
+
require: './index.cjs',
|
|
714
|
+
});
|
|
715
|
+
expect(pkg.exports['./components/AcmeWidget']).toBe(
|
|
716
|
+
'./components/AcmeWidget.tsx',
|
|
717
|
+
);
|
|
718
|
+
});
|
|
719
|
+
|
|
720
|
+
it('no-map: pack-check fails when generated component has no exports map', async () => {
|
|
721
|
+
fs.writeFileSync(
|
|
722
|
+
path.join(tmpDir, 'package.json'),
|
|
723
|
+
`${JSON.stringify({
|
|
724
|
+
name: '@acme/widgets',
|
|
725
|
+
version: '1.0.0',
|
|
726
|
+
files: ['dist'],
|
|
727
|
+
})}\n`,
|
|
728
|
+
);
|
|
729
|
+
fs.writeFileSync(
|
|
730
|
+
path.join(tmpDir, 'astryx.integration.mjs'),
|
|
731
|
+
'export default {};\n',
|
|
732
|
+
);
|
|
733
|
+
|
|
734
|
+
await integrationAddComponent('AcmeWidget', {cwd: tmpDir});
|
|
735
|
+
await integrationAddTemplate('hero-page', {cwd: tmpDir, type: 'page'});
|
|
736
|
+
|
|
737
|
+
const pkg = JSON.parse(
|
|
738
|
+
fs.readFileSync(path.join(tmpDir, 'package.json'), 'utf-8'),
|
|
739
|
+
);
|
|
740
|
+
// No exports map created
|
|
741
|
+
expect(pkg.exports).toBeUndefined();
|
|
742
|
+
|
|
743
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
744
|
+
|
|
745
|
+
// The extensionless import cannot resolve without an exports map —
|
|
746
|
+
// pack-check must fail closed, not false-green.
|
|
747
|
+
expect(result.data.packable).toBe(false);
|
|
748
|
+
expect(result.data.issues).toContainEqual(
|
|
749
|
+
expect.objectContaining({
|
|
750
|
+
severity: 'error',
|
|
751
|
+
message: expect.stringContaining('AcmeWidget'),
|
|
752
|
+
}),
|
|
753
|
+
);
|
|
754
|
+
});
|
|
755
|
+
|
|
756
|
+
it('idempotent when extensionless export already exists', async () => {
|
|
757
|
+
fs.writeFileSync(
|
|
758
|
+
path.join(tmpDir, 'package.json'),
|
|
759
|
+
`${JSON.stringify({
|
|
760
|
+
name: '@acme/widgets',
|
|
761
|
+
version: '1.0.0',
|
|
762
|
+
files: ['index.mjs'],
|
|
763
|
+
exports: {
|
|
764
|
+
'.': './index.mjs',
|
|
765
|
+
'./components/AcmeWidget': './components/AcmeWidget.tsx',
|
|
766
|
+
},
|
|
767
|
+
})}\n`,
|
|
768
|
+
);
|
|
769
|
+
fs.writeFileSync(
|
|
770
|
+
path.join(tmpDir, 'index.mjs'),
|
|
771
|
+
'export const existing = 1;\n',
|
|
772
|
+
);
|
|
773
|
+
fs.writeFileSync(
|
|
774
|
+
path.join(tmpDir, 'astryx.integration.mjs'),
|
|
775
|
+
'export default {};\n',
|
|
776
|
+
);
|
|
777
|
+
|
|
778
|
+
await integrationAddComponent('AcmeWidget', {cwd: tmpDir});
|
|
779
|
+
|
|
780
|
+
const pkg = JSON.parse(
|
|
781
|
+
fs.readFileSync(path.join(tmpDir, 'package.json'), 'utf-8'),
|
|
782
|
+
);
|
|
783
|
+
// Export preserved, no duplicate
|
|
784
|
+
expect(
|
|
785
|
+
Object.keys(pkg.exports).filter(k => k.includes('AcmeWidget')),
|
|
786
|
+
).toEqual(['./components/AcmeWidget']);
|
|
787
|
+
});
|
|
788
|
+
});
|