@astryxdesign/cli 0.6.4 → 0.6.5-canary.01972bc
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 +56 -0
- package/README.md +103 -95
- package/api/build/_adapter.d.mts +36 -2
- package/api/build/_adapter.mjs +41 -10
- package/api/build/build.doc.mjs +8 -3
- package/api/build/build.test.mjs +60 -2
- package/api/build/kit/kit.mjs +109 -26
- package/api/build/kit/rank.d.mts +24 -8
- package/api/build/kit/rank.mjs +277 -97
- package/api/build/kit/rank.test.mjs +231 -48
- package/api/component/_adapter.d.mts +25 -0
- package/api/component/_adapter.mjs +59 -5
- package/api/component/component.d.mts +6 -3
- package/api/component/component.doc.mjs +37 -17
- package/api/component/component.mjs +249 -9
- package/api/component/component.type.d.mts +25 -0
- package/api/component/component.type.mjs +44 -0
- package/api/discover/_adapter.d.mts +114 -6
- package/api/discover/_adapter.mjs +372 -17
- package/api/discover/_adapter.test.mjs +215 -0
- package/api/discover/_catalog-view.d.mts +115 -0
- package/api/discover/_catalog-view.mjs +203 -0
- package/api/discover/_catalog-view.test.mjs +128 -0
- package/api/discover/detail/detail.d.mts +18 -6
- package/api/discover/detail/detail.mjs +67 -13
- package/api/discover/detail/detail.test.mjs +85 -0
- package/api/discover/detail/item/item.d.mts +26 -0
- package/api/discover/detail/item/item.mjs +78 -0
- package/api/discover/detail/item/item.test.mjs +73 -0
- package/api/discover/discover.d.mts +3 -9
- package/api/discover/discover.doc.mjs +61 -18
- package/api/discover/discover.mjs +220 -36
- package/api/discover/discover.test.mjs +11 -2
- package/api/discover/discover.type.d.mts +147 -8
- package/api/discover/discover.type.mjs +102 -12
- package/api/discover/list/list.d.mts +20 -6
- package/api/discover/list/list.mjs +45 -12
- package/api/discover/list/list.test.mjs +46 -0
- package/api/discover/search/search.d.mts +18 -16
- package/api/discover/search/search.mjs +102 -56
- package/api/discover/search/search.test.mjs +144 -10
- package/api/docs/_adapter.d.mts +8 -3
- package/api/docs/_adapter.mjs +14 -6
- package/api/docs/docOverlays.test.mjs +27 -1
- package/api/docs/docs.doc.mjs +2 -2
- package/api/docs/docs.test.mjs +54 -18
- package/api/docs/integration-tree.test.mjs +17 -0
- package/api/docs/integrationDocs.test.mjs +27 -5
- package/api/doctor/doctor.d.mts +8 -3
- package/api/doctor/doctor.doc.mjs +17 -8
- package/api/doctor/doctor.mjs +90 -9
- package/api/doctor/doctor.test.mjs +122 -10
- package/api/doctor/doctor.type.d.mts +1 -1
- package/api/doctor/doctor.type.mjs +1 -1
- package/api/error.d.mts +22 -0
- package/api/error.mjs +42 -0
- package/api/gap-report/gap-report.doc.mjs +19 -10
- package/api/hook/hook.doc.mjs +6 -3
- package/api/index.d.mts +1 -0
- package/api/index.mjs +5 -3
- package/api/init/init.doc.mjs +17 -12
- package/api/integration/add-contribution.d.mts +2 -1
- package/api/integration/add-contribution.mjs +7 -3
- package/api/integration/add-contribution.test.mjs +3 -3
- package/api/integration/add-helpers.d.mts +5 -2
- package/api/integration/add-helpers.mjs +36 -9
- package/api/integration/add-theme.mjs +266 -23
- package/api/integration/add-theme.test.mjs +247 -0
- package/api/integration/authoring-checks.mjs +12 -9
- package/api/integration/authoring-checks.type.d.mts +8 -0
- package/api/integration/authoring-checks.type.mjs +7 -3
- package/api/integration/integration-authoring.type.d.mts +4 -1
- package/api/integration/integration-authoring.type.mjs +6 -1
- package/api/integration/integrationAdd.doc.mjs +6 -0
- package/api/integration/integrationAddTheme.doc.mjs +10 -0
- package/api/integration/integrationComponentConflicts.doc.mjs +1 -1
- package/api/integration/integrationDocConflicts.doc.mjs +1 -1
- package/api/integration/integrationPackCheck.doc.mjs +3 -3
- package/api/integration/integrationTemplateConflicts.doc.mjs +1 -1
- package/api/integration/pack-check.lifecycle-output.test.mjs +107 -0
- package/api/integration/pack-check.mjs +92 -10
- package/api/integration/pack-check.test.mjs +140 -1
- package/api/integration/pack-check.type.mjs +1 -1
- package/api/integration/validate-integration.d.mts +4 -2
- package/api/integration/validate-integration.mjs +7 -2
- package/api/integration/validate-integration.test.mjs +55 -0
- package/api/integration/validate-integration.type.d.mts +5 -0
- package/api/integration/validate-integration.type.mjs +5 -1
- package/api/integration/validateIntegration.doc.mjs +1 -1
- package/api/json/assertResponse.doc.mjs +1 -1
- package/api/json/isError.doc.mjs +1 -1
- package/api/layout/expand/expand.mjs +12 -7
- package/api/layout/expand/expand.receipt.test.mjs +74 -0
- package/api/layout/layout.type.d.mts +1 -0
- package/api/layout/layout.type.mjs +1 -0
- package/api/layout/layoutExpand.doc.mjs +1 -1
- package/api/search/search.d.mts +51 -1
- package/api/search/search.doc.mjs +2 -2
- package/api/search/search.mjs +299 -17
- package/api/search/search.test.mjs +216 -18
- package/api/swizzle/copy/copy.mjs +66 -3
- package/api/swizzle/swizzle.doc.mjs +11 -5
- package/api/template/copy/copy.mjs +15 -9
- package/api/template/copy/copy.receipt.test.mjs +77 -0
- package/api/template/copy/copy.test.mjs +9 -0
- package/api/template/show/show.mjs +15 -4
- package/api/template/show/show.test.mjs +76 -0
- package/api/template/template-integration.test.mjs +14 -0
- package/api/template/template.d.mts +1 -1
- package/api/template/template.doc.mjs +8 -3
- package/api/template/template.mjs +1 -0
- package/api/template/template.type.d.mts +2 -0
- package/api/template/template.type.mjs +2 -0
- package/api/theme/add/add.mjs +17 -25
- package/api/theme/add/add.rollback.test.mjs +158 -0
- package/api/theme/add/add.staging.test.mjs +40 -23
- package/api/theme/build/build.d.mts +24 -0
- package/api/theme/build/build.family.test.mjs +7 -12
- package/api/theme/build/build.mjs +243 -26
- package/api/theme/build/build.project-core.test.mjs +165 -0
- package/api/theme/build/build.rollback.test.mjs +148 -0
- package/api/theme/generateTonalPalette.doc.mjs +1 -2
- package/api/theme/listThemes.doc.mjs +1 -1
- package/api/theme/themeAdd.doc.mjs +9 -10
- package/api/theme/themeBuild.doc.mjs +13 -13
- package/api/theme/themeList.doc.mjs +1 -1
- package/api/theme/themeListAvailable.doc.mjs +2 -1
- package/api/theme/themePaletteGenerate.doc.mjs +15 -8
- package/api/theme/themeTargets.doc.mjs +3 -2
- package/api/theme/themeTemplate.doc.mjs +2 -1
- package/api/upgrade/run/files-changed.test.mjs +111 -0
- package/api/upgrade/run/run.mjs +25 -6
- package/api/upgrade/run/run.test.mjs +45 -1
- package/api/upgrade/upgrade.doc.mjs +24 -22
- package/api/upgrade/upgrade.type.d.mts +1 -0
- package/api/upgrade/upgrade.type.mjs +3 -2
- package/assets/codemods/__tests__/runner.test.mjs +3 -1
- package/assets/codemods/file-count.test.mjs +163 -0
- package/assets/codemods/integration-runner.mjs +3 -3
- package/assets/codemods/runner.mjs +5 -4
- package/assets/docs/README.md +4 -2
- package/assets/docs/browser-support.doc.mjs +11 -11
- package/assets/docs/color.doc.mjs +8 -2
- package/assets/docs/elevation.doc.mjs +6 -4
- package/assets/docs/getting-started.doc.mjs +5 -16
- package/assets/docs/icons.doc.mjs +3 -21
- package/assets/docs/illustrations.doc.mjs +7 -15
- package/assets/docs/internationalization.doc.mjs +7 -5
- package/assets/docs/layout.doc.dense.mjs +130 -82
- package/assets/docs/layout.doc.mjs +133 -77
- package/assets/docs/migration.doc.mjs +19 -21
- package/assets/docs/motion.doc.mjs +16 -3
- package/assets/docs/principles.doc.dense.mjs +5 -5
- package/assets/docs/principles.doc.mjs +8 -0
- package/assets/docs/principles.doc.zh.mjs +6 -6
- package/assets/docs/shape.doc.mjs +8 -3
- package/assets/docs/spacing.doc.mjs +7 -2
- package/assets/docs/styling-libraries.doc.mjs +6 -2
- package/assets/docs/styling.doc.mjs +19 -23
- package/assets/docs/theme.doc.dense.mjs +58 -18
- package/assets/docs/theme.doc.mjs +57 -47
- package/assets/docs/theme.doc.zh.mjs +9 -8
- package/assets/docs/tokens.doc.dense.mjs +2 -2
- package/assets/docs/tokens.doc.mjs +389 -8
- package/assets/docs/tokens.doc.zh.mjs +2 -2
- package/assets/docs/tree/add-a-component.doc.mjs +75 -0
- package/assets/docs/tree/add-a-theme.doc.mjs +85 -0
- package/assets/docs/tree/add-a-topic.doc.mjs +144 -0
- package/assets/docs/tree/agent-guidance.doc.mjs +138 -0
- package/assets/docs/tree/block-template.doc.mjs +130 -0
- package/assets/docs/tree/build-the-template.doc.mjs +28 -0
- package/assets/docs/tree/building-blocks.doc.mjs +46 -0
- package/assets/docs/tree/check-your-docs.doc.mjs +137 -0
- package/assets/docs/tree/checks.doc.mjs +119 -0
- package/assets/docs/tree/codemods.doc.mjs +147 -0
- package/assets/docs/tree/component-family.doc.mjs +113 -0
- package/assets/docs/tree/component-imports.doc.mjs +69 -0
- package/assets/docs/tree/component-lookups.doc.mjs +149 -0
- package/assets/docs/tree/components.doc.mjs +23 -0
- package/assets/docs/tree/configuration.doc.mjs +23 -0
- package/assets/docs/tree/debug-and-gap-reports.doc.mjs +182 -0
- package/assets/docs/tree/define-the-theme.doc.mjs +118 -0
- package/assets/docs/tree/describe-the-component.doc.mjs +57 -0
- package/assets/docs/tree/docs.doc.mjs +21 -0
- package/assets/docs/tree/document-the-template.doc.mjs +28 -0
- package/assets/docs/tree/document-the-theme.doc.mjs +68 -0
- package/assets/docs/tree/export-template-assets.doc.mjs +147 -0
- package/assets/docs/tree/extend-or-replace.doc.mjs +103 -0
- package/assets/docs/tree/fonts-and-assets.doc.mjs +106 -0
- package/assets/docs/tree/generate-a-palette.doc.mjs +66 -0
- package/assets/docs/tree/grade-template-with-agent.doc.mjs +105 -0
- package/assets/docs/tree/help.doc.mjs +16 -0
- package/assets/docs/tree/integrations.doc.mjs +25 -451
- package/assets/docs/tree/links.doc.mjs +98 -0
- package/assets/docs/tree/package-and-test.doc.mjs +32 -0
- package/assets/docs/tree/page-template.doc.mjs +71 -0
- package/assets/docs/tree/publishing.doc.mjs +111 -0
- package/assets/docs/tree/quick-start.doc.mjs +272 -0
- package/assets/docs/tree/replace-a-core-component.doc.mjs +104 -0
- package/assets/docs/tree/replace-a-core-template.doc.mjs +172 -0
- package/assets/docs/tree/sections-and-placement.doc.mjs +108 -0
- package/assets/docs/tree/see-it-in-an-app.doc.mjs +59 -0
- package/assets/docs/tree/ship.doc.mjs +16 -0
- package/assets/docs/tree/short-and-findable.doc.mjs +108 -0
- package/assets/docs/tree/single-component.doc.mjs +165 -0
- package/assets/docs/tree/start-a-template.doc.mjs +143 -0
- package/assets/docs/tree/subcomponent.doc.mjs +115 -0
- package/assets/docs/tree/template-assets.doc.mjs +64 -0
- package/assets/docs/tree/template-doc-overview.doc.mjs +121 -0
- package/assets/docs/tree/template-fonts.doc.mjs +102 -0
- package/assets/docs/tree/template-grading-rubric.doc.mjs +452 -0
- package/assets/docs/tree/template-icons.doc.mjs +97 -0
- package/assets/docs/tree/template-images-media.doc.mjs +127 -0
- package/assets/docs/tree/template-styles.doc.mjs +93 -0
- package/assets/docs/tree/templates.doc.mjs +34 -0
- package/assets/docs/tree/test-in-an-app.doc.mjs +115 -0
- package/assets/docs/tree/test-template-in-app.doc.mjs +128 -0
- package/assets/docs/tree/themes.doc.mjs +39 -0
- package/assets/docs/tree/troubleshooting.doc.mjs +153 -0
- package/assets/docs/tree/upgrading.doc.mjs +103 -0
- package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +51 -0
- package/assets/docs/tree/verify-packed-template.doc.mjs +77 -0
- package/assets/docs/tree/versioning.doc.mjs +162 -0
- package/assets/docs/tree/write-good-templates.doc.mjs +64 -0
- package/assets/docs/tree/write-the-template-file.doc.mjs +154 -0
- package/assets/docs/typography.doc.mjs +24 -4
- package/assets/docs/working-with-ai.doc.mjs +30 -22
- package/assets/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.tsx +1 -1
- package/assets/templates/pages/ai-chat/template.doc.mjs +16 -1
- package/assets/templates/pages/ai-chat-landing/template.doc.mjs +9 -1
- package/assets/templates/pages/blank/template.doc.mjs +3 -1
- package/assets/templates/pages/canvas-editor/template.doc.mjs +9 -1
- package/assets/templates/pages/centered-hero/template.doc.mjs +3 -1
- package/assets/templates/pages/checkout-wizard/template.doc.mjs +1 -0
- package/assets/templates/pages/classic-gallery/template.doc.mjs +3 -1
- package/assets/templates/pages/contact-form/template.doc.mjs +16 -1
- package/assets/templates/pages/dashboard/template.doc.mjs +15 -1
- package/assets/templates/pages/dashboard-alert-rail/template.doc.mjs +23 -1
- package/assets/templates/pages/dashboard-cohort-funnel/template.doc.mjs +10 -1
- package/assets/templates/pages/dashboard-comparison/template.doc.mjs +9 -1
- package/assets/templates/pages/dashboard-composition/template.doc.mjs +10 -1
- package/assets/templates/pages/dashboard-progress/template.doc.mjs +17 -1
- package/assets/templates/pages/dashboard-scorecard/template.doc.mjs +2 -1
- package/assets/templates/pages/detail-page/template.doc.mjs +8 -0
- package/assets/templates/pages/documentation/template.doc.mjs +10 -1
- package/assets/templates/pages/documentation-design/template.doc.mjs +10 -1
- package/assets/templates/pages/documentation-technical/template.doc.mjs +10 -1
- package/assets/templates/pages/editor/template.doc.mjs +9 -1
- package/assets/templates/pages/file-explorer/template.doc.mjs +3 -1
- package/assets/templates/pages/form-two-column/template.doc.mjs +17 -1
- package/assets/templates/pages/form-wizard/template.doc.mjs +14 -1
- package/assets/templates/pages/form-wizard-dialog/template.doc.mjs +1 -0
- package/assets/templates/pages/gallery-hero/template.doc.mjs +10 -1
- package/assets/templates/pages/ide/template.doc.mjs +9 -1
- package/assets/templates/pages/incident-console/template.doc.mjs +10 -1
- package/assets/templates/pages/kanban-board/template.doc.mjs +11 -1
- package/assets/templates/pages/library/template.doc.mjs +15 -1
- package/assets/templates/pages/login/template.doc.mjs +10 -1
- package/assets/templates/pages/login-card/template.doc.mjs +11 -1
- package/assets/templates/pages/login-split/template.doc.mjs +10 -1
- package/assets/templates/pages/login-sso/template.doc.mjs +10 -1
- package/assets/templates/pages/messaging-shell/template.doc.mjs +11 -1
- package/assets/templates/pages/mixed-gallery/template.doc.mjs +10 -1
- package/assets/templates/pages/payment-form/template.doc.mjs +3 -1
- package/assets/templates/pages/product-detail/template.doc.mjs +9 -1
- package/assets/templates/pages/product-gallery/template.doc.mjs +10 -1
- package/assets/templates/pages/settings/template.doc.mjs +3 -1
- package/assets/templates/pages/settings-dialog/template.doc.mjs +9 -1
- package/assets/templates/pages/settings-sidebar/template.doc.mjs +9 -1
- package/assets/templates/pages/shell-nav/template.doc.mjs +10 -1
- package/assets/templates/pages/shell-side-nav/template.doc.mjs +14 -1
- package/assets/templates/pages/shell-top-nav/template.doc.mjs +11 -1
- package/assets/templates/pages/side-gallery/template.doc.mjs +3 -1
- package/assets/templates/pages/table/template.doc.mjs +11 -1
- package/assets/templates/pages/table-filter/template.doc.mjs +21 -1
- package/assets/templates/pages/table-grouped/template.doc.mjs +15 -1
- package/assets/templates/pages/table-inbox/template.doc.mjs +18 -6
- package/assets/templates/pages/table-page/template.doc.mjs +20 -1
- package/assets/templates/pages/table-tree/template.doc.mjs +14 -1
- package/assets/templates/pages/theme-showcase/template.doc.mjs +10 -1
- package/assets/templates/pages/work-item-detail/template.doc.mjs +10 -0
- package/assets/templates/themes/butter/icons.tsx +2 -0
- package/assets/templates/themes/chocolate/icons.tsx +2 -0
- package/assets/templates/themes/gothic/icons.tsx +2 -0
- package/assets/templates/themes/matcha/icons.tsx +2 -0
- package/assets/templates/themes/neutral/icons.tsx +2 -0
- package/assets/templates/themes/stone/icons.tsx +2 -0
- package/assets/templates/themes/y2k/icons.tsx +2 -0
- package/authoring/config/config.doc.mjs +9 -1
- package/authoring/config/parse.d.mts +2 -0
- package/authoring/config/parse.mjs +19 -0
- package/authoring/config/parse.test.mjs +8 -0
- package/authoring/config/type.ts +11 -0
- package/authoring/discover/discover.doc.d.mts +13 -0
- package/authoring/discover/discover.doc.mjs +138 -0
- package/authoring/discover/parse.d.mts +24 -0
- package/authoring/discover/parse.mjs +128 -0
- package/authoring/discover/parse.test.mjs +124 -0
- package/authoring/discover/type.ts +87 -0
- package/authoring/doctypes/_schema.d.mts +3 -2
- package/authoring/doctypes/_schema.mjs +6 -0
- package/authoring/doctypes/base/graph-fields.doc.mjs +3 -3
- package/authoring/doctypes/base/type.ts +4 -2
- package/authoring/doctypes/component/component.doc.mjs +6 -0
- package/authoring/doctypes/component/type.ts +8 -0
- package/authoring/doctypes/reference/reference.doc.mjs +7 -0
- package/authoring/doctypes/reference/type.ts +5 -0
- package/authoring/doctypes/schema/schema.doc.mjs +2 -2
- package/authoring/doctypes/template/parse.d.mts +2 -0
- package/authoring/doctypes/template/parse.mjs +1 -0
- package/authoring/doctypes/template/parse.test.mjs +21 -0
- package/authoring/doctypes/template/template.doc.mjs +7 -1
- package/authoring/doctypes/template/type.ts +12 -2
- package/authoring/index.d.mts +1 -0
- package/authoring/index.d.ts +10 -0
- package/authoring/index.mjs +1 -0
- package/authoring/integration/integration.doc.mjs +12 -10
- package/clients/cli/commands/component/index.mjs +152 -55
- package/clients/cli/commands/component-batch.test.mjs +341 -0
- package/clients/cli/commands/component-ownership.test.mjs +89 -0
- package/clients/cli/commands/component.doc.mjs +27 -9
- package/clients/cli/commands/discover.doc.mjs +53 -9
- package/clients/cli/commands/discover.mjs +393 -118
- package/clients/cli/commands/discover.sources.test.mjs +267 -0
- package/clients/cli/commands/docs.doc.mjs +1 -1
- package/clients/cli/commands/docs.mjs +60 -17
- package/clients/cli/commands/docs.test.mjs +113 -24
- package/clients/cli/commands/doctor-integration-docs.doc.mjs +3 -2
- package/clients/cli/commands/doctor-integration.test.mjs +53 -0
- package/clients/cli/commands/doctor.doc.mjs +3 -1
- package/clients/cli/commands/doctor.mjs +53 -9
- package/clients/cli/commands/gap-report.doc.mjs +10 -9
- package/clients/cli/commands/init.doc.mjs +9 -6
- package/clients/cli/commands/integration-add.doc.mjs +17 -7
- package/clients/cli/commands/integration-authoring.test.mjs +70 -9
- package/clients/cli/commands/integration-pack.doc.mjs +5 -9
- package/clients/cli/commands/integration-real-world.test.mjs +1 -1
- package/clients/cli/commands/integration-verify.doc.mjs +22 -0
- package/clients/cli/commands/integration.doc.mjs +4 -4
- package/clients/cli/commands/integration.mjs +76 -43
- package/clients/cli/commands/layout-expand.doc.mjs +3 -1
- package/clients/cli/commands/layout.expand-receipt.test.mjs +94 -0
- package/clients/cli/commands/layout.mjs +16 -0
- package/clients/cli/commands/manifest.doc.mjs +1 -1
- package/clients/cli/commands/search.doc.mjs +10 -3
- package/clients/cli/commands/search.mjs +21 -2
- package/clients/cli/commands/search.test.mjs +21 -4
- package/clients/cli/commands/swizzle.doc.mjs +1 -1
- package/clients/cli/commands/template.copy-receipt.test.mjs +60 -0
- package/clients/cli/commands/template.doc.mjs +1 -1
- package/clients/cli/commands/template.mjs +19 -5
- package/clients/cli/commands/template.show-media.test.mjs +62 -0
- package/clients/cli/commands/text-json-parity.test.mjs +7 -1
- package/clients/cli/commands/theme-add.doc.mjs +1 -1
- package/clients/cli/commands/theme-palette-generate.doc.mjs +3 -2
- package/clients/cli/commands/theme-palette.doc.mjs +1 -2
- package/clients/cli/commands/theme-targets.doc.mjs +2 -2
- package/clients/cli/commands/theme.doc.mjs +2 -1
- package/clients/cli/commands/upgrade.ascii-output.test.mjs +14 -0
- package/clients/cli/commands/upgrade.doc.mjs +62 -3
- package/clients/cli/commands/write-failure.test.mjs +175 -0
- package/clients/cli/index.mjs +28 -6
- package/clients/cli/lib/define-command.mjs +28 -4
- package/clients/cli/lib/define-command.test.mjs +54 -0
- package/clients/cli/lib/exit-codes.test.mjs +17 -1
- package/clients/cli/lib/json-shim.mjs +24 -14
- package/clients/cli/lib/manifest.mjs +48 -156
- package/clients/cli/lib/manifest.test.mjs +103 -9
- package/clients/cli/lib/parse-error-format.test.mjs +81 -0
- package/foundation/agent-docs/agent-docs.mjs +1 -1
- package/foundation/agent-docs/agent-docs.test.mjs +3 -2
- package/foundation/discovery/authoring-self-docs.mjs +1 -0
- package/foundation/discovery/authoring-self-docs.test.mjs +6 -2
- package/foundation/discovery/cli-self-docs.mjs +16 -2
- package/foundation/discovery/cli-self-docs.test.mjs +20 -0
- package/foundation/discovery/docs-discovery.mjs +5 -1
- package/foundation/discovery/docs-discovery.test.mjs +21 -0
- package/foundation/discovery/docs-section-key.d.mts +1 -1
- package/foundation/discovery/docs-section-key.mjs +1 -1
- package/foundation/discovery/template-adapter.d.mts +14 -0
- package/foundation/discovery/template-adapter.fixture-refs.test.mjs +37 -1
- package/foundation/discovery/template-adapter.mjs +21 -1
- package/foundation/doc-compiler/doc-loads.test.mjs +5 -4
- package/foundation/doc-compiler/inputs.test.mjs +0 -1
- package/foundation/doc-compiler/tree.d.mts +4 -0
- package/foundation/doc-compiler/tree.mjs +6 -1
- package/foundation/doc-compiler/tree.test.mjs +65 -14
- package/foundation/integrations/cli-requirement.d.mts +75 -11
- package/foundation/integrations/cli-requirement.mjs +120 -23
- package/foundation/integrations/cli-requirement.test.mjs +141 -9
- package/foundation/integrations/contribution-inventory.mjs +1 -1
- package/foundation/integrations/integrations.d.mts +14 -1
- package/foundation/integrations/integrations.mjs +41 -1
- package/foundation/integrations/integrations.test.mjs +31 -0
- package/foundation/response/batch.type.d.mts +33 -0
- package/foundation/response/batch.type.mjs +34 -0
- package/foundation/response/error-codes.doc.mjs +6 -8
- package/foundation/response/error-codes.test.mjs +30 -5
- package/foundation/response/response-types.doc.d.mts +5 -4
- package/foundation/response/response-types.doc.mjs +49 -19
- package/foundation/response/response-types.doc.test.mjs +23 -0
- package/foundation/response/response.doc.mjs +11 -10
- package/package.json +9 -9
- package/assets/docs/tree/integrations.test.mjs +0 -62
- package/assets/docs/tree/writing-docs.doc.mjs +0 -286
|
@@ -92,6 +92,7 @@ function addErrors(issues, errors, code) {
|
|
|
92
92
|
export async function integrationTemplateConflicts(pkg, options = {}) {
|
|
93
93
|
const {cwd = process.cwd()} = options;
|
|
94
94
|
const resolved = await resolveIntegration(pkg, cwd);
|
|
95
|
+
const validated = resolved.found;
|
|
95
96
|
const name = resolved.found ? (resolved.name ?? null) : null;
|
|
96
97
|
const version = resolved.found ? (resolved.version ?? null) : null;
|
|
97
98
|
const issues = [...resolved.issues];
|
|
@@ -99,7 +100,7 @@ export async function integrationTemplateConflicts(pkg, options = {}) {
|
|
|
99
100
|
if (!resolved.integration || name == null) {
|
|
100
101
|
return {
|
|
101
102
|
type: 'integration.template-conflicts',
|
|
102
|
-
data: {name, version, conflicts: [], issues},
|
|
103
|
+
data: {validated, name, version, conflicts: [], issues},
|
|
103
104
|
};
|
|
104
105
|
}
|
|
105
106
|
|
|
@@ -215,7 +216,7 @@ export async function integrationTemplateConflicts(pkg, options = {}) {
|
|
|
215
216
|
|
|
216
217
|
return {
|
|
217
218
|
type: 'integration.template-conflicts',
|
|
218
|
-
data: {name, version, conflicts, issues},
|
|
219
|
+
data: {validated, name, version, conflicts, issues},
|
|
219
220
|
};
|
|
220
221
|
}
|
|
221
222
|
|
|
@@ -228,6 +229,7 @@ export async function integrationTemplateConflicts(pkg, options = {}) {
|
|
|
228
229
|
export async function integrationComponentConflicts(pkg, options = {}) {
|
|
229
230
|
const {cwd = process.cwd()} = options;
|
|
230
231
|
const resolved = await resolveIntegration(pkg, cwd);
|
|
232
|
+
const validated = resolved.found;
|
|
231
233
|
const name = resolved.found ? (resolved.name ?? null) : null;
|
|
232
234
|
const version = resolved.found ? (resolved.version ?? null) : null;
|
|
233
235
|
const issues = [...resolved.issues];
|
|
@@ -235,7 +237,7 @@ export async function integrationComponentConflicts(pkg, options = {}) {
|
|
|
235
237
|
if (!resolved.integration?.components || name == null) {
|
|
236
238
|
return {
|
|
237
239
|
type: 'integration.component-conflicts',
|
|
238
|
-
data: {name, version, conflicts: [], issues},
|
|
240
|
+
data: {validated, name, version, conflicts: [], issues},
|
|
239
241
|
};
|
|
240
242
|
}
|
|
241
243
|
|
|
@@ -249,7 +251,7 @@ export async function integrationComponentConflicts(pkg, options = {}) {
|
|
|
249
251
|
});
|
|
250
252
|
return {
|
|
251
253
|
type: 'integration.component-conflicts',
|
|
252
|
-
data: {name, version, conflicts: [], issues},
|
|
254
|
+
data: {validated, name, version, conflicts: [], issues},
|
|
253
255
|
};
|
|
254
256
|
}
|
|
255
257
|
|
|
@@ -274,7 +276,7 @@ export async function integrationComponentConflicts(pkg, options = {}) {
|
|
|
274
276
|
|
|
275
277
|
return {
|
|
276
278
|
type: 'integration.component-conflicts',
|
|
277
|
-
data: {name, version, conflicts, issues},
|
|
279
|
+
data: {validated, name, version, conflicts, issues},
|
|
278
280
|
};
|
|
279
281
|
}
|
|
280
282
|
|
|
@@ -287,6 +289,7 @@ export async function integrationComponentConflicts(pkg, options = {}) {
|
|
|
287
289
|
export async function integrationDocConflicts(pkg, options = {}) {
|
|
288
290
|
const {cwd = process.cwd()} = options;
|
|
289
291
|
const resolved = await resolveIntegration(pkg, cwd);
|
|
292
|
+
const validated = resolved.found;
|
|
290
293
|
const name = resolved.found ? (resolved.name ?? null) : null;
|
|
291
294
|
const version = resolved.found ? (resolved.version ?? null) : null;
|
|
292
295
|
const issues = [...resolved.issues];
|
|
@@ -294,7 +297,7 @@ export async function integrationDocConflicts(pkg, options = {}) {
|
|
|
294
297
|
if (!resolved.integration?.docs || name == null) {
|
|
295
298
|
return {
|
|
296
299
|
type: 'integration.doc-conflicts',
|
|
297
|
-
data: {name, version, findings: [], issues},
|
|
300
|
+
data: {validated, name, version, findings: [], issues},
|
|
298
301
|
};
|
|
299
302
|
}
|
|
300
303
|
|
|
@@ -368,11 +371,11 @@ export async function integrationDocConflicts(pkg, options = {}) {
|
|
|
368
371
|
// and placed guides this package adds to the docs tree, and every link in
|
|
369
372
|
// its docs (spec:AST-046, spec:AST-047).
|
|
370
373
|
if (errors.length === 0) {
|
|
371
|
-
for (const message of await packageDocsProblems(
|
|
374
|
+
for (const {severity, message} of await packageDocsProblems(
|
|
372
375
|
/** @type {{name: string}} */ (resolved.integration),
|
|
373
376
|
discovered,
|
|
374
377
|
)) {
|
|
375
|
-
issues.push({code: 'invalid_doc_graph', severity
|
|
378
|
+
issues.push({code: 'invalid_doc_graph', severity, message});
|
|
376
379
|
}
|
|
377
380
|
|
|
378
381
|
// A reference block includes content rather than linking to it, so one
|
|
@@ -388,6 +391,6 @@ export async function integrationDocConflicts(pkg, options = {}) {
|
|
|
388
391
|
|
|
389
392
|
return {
|
|
390
393
|
type: 'integration.doc-conflicts',
|
|
391
|
-
data: {name, version, findings, issues},
|
|
394
|
+
data: {validated, name, version, findings, issues},
|
|
392
395
|
};
|
|
393
396
|
}
|
|
@@ -32,9 +32,15 @@ export type IntegrationDocFinding = {
|
|
|
32
32
|
coreTopic: string;
|
|
33
33
|
message: string;
|
|
34
34
|
};
|
|
35
|
+
/**
|
|
36
|
+
* Each of the three authoring checks reports `validated`: false means no
|
|
37
|
+
* integration manifest was found, so nothing was inspected and the empty
|
|
38
|
+
* conflicts/findings list carries no information about the package.
|
|
39
|
+
*/
|
|
35
40
|
export type IntegrationTemplateConflictResponse = {
|
|
36
41
|
type: "integration.template-conflicts";
|
|
37
42
|
data: {
|
|
43
|
+
validated: boolean;
|
|
38
44
|
name: string | null;
|
|
39
45
|
version: string | null;
|
|
40
46
|
conflicts: IntegrationTemplateConflict[];
|
|
@@ -44,6 +50,7 @@ export type IntegrationTemplateConflictResponse = {
|
|
|
44
50
|
export type IntegrationComponentConflictResponse = {
|
|
45
51
|
type: "integration.component-conflicts";
|
|
46
52
|
data: {
|
|
53
|
+
validated: boolean;
|
|
47
54
|
name: string | null;
|
|
48
55
|
version: string | null;
|
|
49
56
|
conflicts: IntegrationComponentConflict[];
|
|
@@ -53,6 +60,7 @@ export type IntegrationComponentConflictResponse = {
|
|
|
53
60
|
export type IntegrationDocConflictResponse = {
|
|
54
61
|
type: "integration.doc-conflicts";
|
|
55
62
|
data: {
|
|
63
|
+
validated: boolean;
|
|
56
64
|
name: string | null;
|
|
57
65
|
version: string | null;
|
|
58
66
|
findings: IntegrationDocFinding[];
|
|
@@ -49,21 +49,25 @@
|
|
|
49
49
|
*/
|
|
50
50
|
|
|
51
51
|
/**
|
|
52
|
+
* Each of the three authoring checks reports `validated`: false means no
|
|
53
|
+
* integration manifest was found, so nothing was inspected and the empty
|
|
54
|
+
* conflicts/findings list carries no information about the package.
|
|
55
|
+
*
|
|
52
56
|
* @typedef {object} IntegrationTemplateConflictResponse
|
|
53
57
|
* @property {'integration.template-conflicts'} type
|
|
54
|
-
* @property {{name: string | null, version: string | null, conflicts: IntegrationTemplateConflict[], issues: import('../../foundation/integrations/issue').AstryxIntegrationIssue[]}} data
|
|
58
|
+
* @property {{validated: boolean, name: string | null, version: string | null, conflicts: IntegrationTemplateConflict[], issues: import('../../foundation/integrations/issue').AstryxIntegrationIssue[]}} data
|
|
55
59
|
*/
|
|
56
60
|
|
|
57
61
|
/**
|
|
58
62
|
* @typedef {object} IntegrationComponentConflictResponse
|
|
59
63
|
* @property {'integration.component-conflicts'} type
|
|
60
|
-
* @property {{name: string | null, version: string | null, conflicts: IntegrationComponentConflict[], issues: import('../../foundation/integrations/issue').AstryxIntegrationIssue[]}} data
|
|
64
|
+
* @property {{validated: boolean, name: string | null, version: string | null, conflicts: IntegrationComponentConflict[], issues: import('../../foundation/integrations/issue').AstryxIntegrationIssue[]}} data
|
|
61
65
|
*/
|
|
62
66
|
|
|
63
67
|
/**
|
|
64
68
|
* @typedef {object} IntegrationDocConflictResponse
|
|
65
69
|
* @property {'integration.doc-conflicts'} type
|
|
66
|
-
* @property {{name: string | null, version: string | null, findings: IntegrationDocFinding[], issues: import('../../foundation/integrations/issue').AstryxIntegrationIssue[]}} data
|
|
70
|
+
* @property {{validated: boolean, name: string | null, version: string | null, findings: IntegrationDocFinding[], issues: import('../../foundation/integrations/issue').AstryxIntegrationIssue[]}} data
|
|
67
71
|
*/
|
|
68
72
|
|
|
69
73
|
export {};
|
|
@@ -19,7 +19,9 @@ export type IntegrationAddCodemodOptions = IntegrationAddBaseOptions & {
|
|
|
19
19
|
to: string;
|
|
20
20
|
};
|
|
21
21
|
export type IntegrationAddAgentDocOptions = IntegrationAddBaseOptions;
|
|
22
|
-
export type IntegrationAddThemeOptions = IntegrationAddBaseOptions
|
|
22
|
+
export type IntegrationAddThemeOptions = IntegrationAddBaseOptions & {
|
|
23
|
+
from?: string;
|
|
24
|
+
};
|
|
23
25
|
/**
|
|
24
26
|
* Options for the generic `integrationAdd` dispatcher. Prefer a per-kind API
|
|
25
27
|
* when the contribution kind is known so the accepted options stay narrow.
|
|
@@ -54,4 +56,5 @@ export type IntegrationAddData = {
|
|
|
54
56
|
files: string[];
|
|
55
57
|
written: boolean;
|
|
56
58
|
dryRun: boolean;
|
|
59
|
+
from?: string | undefined;
|
|
57
60
|
};
|
|
@@ -37,7 +37,11 @@
|
|
|
37
37
|
*/
|
|
38
38
|
|
|
39
39
|
/** @typedef {IntegrationAddBaseOptions} IntegrationAddAgentDocOptions */
|
|
40
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* @typedef {IntegrationAddBaseOptions & {
|
|
42
|
+
* from?: string,
|
|
43
|
+
* }} IntegrationAddThemeOptions
|
|
44
|
+
*/
|
|
41
45
|
|
|
42
46
|
/**
|
|
43
47
|
* Options for the generic `integrationAdd` dispatcher. Prefer a per-kind API
|
|
@@ -73,6 +77,7 @@
|
|
|
73
77
|
* @property {string[]} files
|
|
74
78
|
* @property {boolean} written
|
|
75
79
|
* @property {boolean} dryRun
|
|
80
|
+
* @property {string} [from]
|
|
76
81
|
*/
|
|
77
82
|
|
|
78
83
|
export {};
|
|
@@ -78,6 +78,12 @@ export const doc = {
|
|
|
78
78
|
type: 'string',
|
|
79
79
|
description: 'Exact target semver (e.g. 1.2.0). Required for codemod and only valid there.',
|
|
80
80
|
},
|
|
81
|
+
{
|
|
82
|
+
name: 'options.from',
|
|
83
|
+
type: 'string',
|
|
84
|
+
description:
|
|
85
|
+
'Slug of an existing theme to fork as the starting point. Only valid for theme.',
|
|
86
|
+
},
|
|
81
87
|
],
|
|
82
88
|
returns: [
|
|
83
89
|
{
|
|
@@ -33,6 +33,12 @@ export const doc = {
|
|
|
33
33
|
'Validate and return the same receipt without writing; data.written is false and data.dryRun is true.',
|
|
34
34
|
default: 'false',
|
|
35
35
|
},
|
|
36
|
+
{
|
|
37
|
+
name: 'options.from',
|
|
38
|
+
type: 'string',
|
|
39
|
+
description:
|
|
40
|
+
'Slug of an existing theme to fork as the starting point. The new theme copies the base and has no link back.',
|
|
41
|
+
},
|
|
36
42
|
],
|
|
37
43
|
returns: [
|
|
38
44
|
{
|
|
@@ -76,6 +82,10 @@ export const doc = {
|
|
|
76
82
|
label: 'Add a theme',
|
|
77
83
|
code: "await integrationAddTheme('ocean');",
|
|
78
84
|
},
|
|
85
|
+
{
|
|
86
|
+
label: 'Fork an existing theme',
|
|
87
|
+
code: "await integrationAddTheme('ocean', {from: 'neutral'});",
|
|
88
|
+
},
|
|
79
89
|
{
|
|
80
90
|
label: 'Preview writes',
|
|
81
91
|
code: "await integrationAddTheme('ocean', {dryRun: true});",
|
|
@@ -26,7 +26,7 @@ export const doc = {
|
|
|
26
26
|
{
|
|
27
27
|
type: 'integration.component-conflicts',
|
|
28
28
|
description:
|
|
29
|
-
'
|
|
29
|
+
'`validated` (false when no integration manifest was found, so nothing was inspected), integration identity, structural issues, and Core component-name conflicts with package-qualified commands.',
|
|
30
30
|
},
|
|
31
31
|
],
|
|
32
32
|
examples: [
|
|
@@ -26,7 +26,7 @@ export const doc = {
|
|
|
26
26
|
{
|
|
27
27
|
type: 'integration.doc-conflicts',
|
|
28
28
|
description:
|
|
29
|
-
'
|
|
29
|
+
'`validated` (false when no integration manifest was found, so nothing was inspected), integration identity, structural issues, and classified Core doc relationships.',
|
|
30
30
|
},
|
|
31
31
|
],
|
|
32
32
|
examples: [
|
|
@@ -7,13 +7,13 @@ export const doc = {
|
|
|
7
7
|
name: 'integrationPackCheck',
|
|
8
8
|
namespace: 'cli/api',
|
|
9
9
|
displayName: 'integrationPackCheck()',
|
|
10
|
-
summary: '
|
|
10
|
+
summary: 'Check an integration package the way npm will publish it.',
|
|
11
11
|
description:
|
|
12
12
|
"Validates the local integration, runs the package lifecycle, packs with npm, checks required files against npm's authoritative tarball list, extracts the real tarball into a scratch consumer, compares local and packed contribution inventories, and resolves every packed component through its documented public import to verify that module exports the component. A package that ships a namespace doc or a placed guide, or has a template that sets `replaces`, fails unless its `@astryxdesign/cli` peer range admits only CLIs that read them.",
|
|
13
13
|
importPath: '@astryxdesign/cli/api',
|
|
14
14
|
signature:
|
|
15
15
|
'integrationPackCheck(options?: IntegrationPackCheckOptions): Promise<IntegrationPackCheckResponse>',
|
|
16
|
-
keywords: ['
|
|
16
|
+
keywords: ['verify', 'pack', 'publish', 'tarball', 'consumer'],
|
|
17
17
|
params: [
|
|
18
18
|
{
|
|
19
19
|
name: 'options.cwd',
|
|
@@ -31,6 +31,6 @@ export const doc = {
|
|
|
31
31
|
examples: [
|
|
32
32
|
{label: 'Check the local package', code: 'await integrationPackCheck();'},
|
|
33
33
|
],
|
|
34
|
-
command: 'integration
|
|
34
|
+
command: 'integration verify',
|
|
35
35
|
related: ['integrationAdd', 'validateIntegration'],
|
|
36
36
|
};
|
|
@@ -41,7 +41,7 @@ export const doc = {
|
|
|
41
41
|
{
|
|
42
42
|
type: 'integration.template-conflicts',
|
|
43
43
|
description:
|
|
44
|
-
'
|
|
44
|
+
'`validated` (false when no integration manifest was found, so nothing was inspected and the empty conflict list carries no information), the integration identity, structural issues, and every Core template-id conflict with a package-qualified command.',
|
|
45
45
|
},
|
|
46
46
|
],
|
|
47
47
|
examples: [
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
import {afterEach, beforeEach, describe, expect, it} from 'vitest';
|
|
4
|
+
import * as fs from 'node:fs';
|
|
5
|
+
import * as path from 'node:path';
|
|
6
|
+
import {integrationPackCheck} from './pack-check.mjs';
|
|
7
|
+
|
|
8
|
+
let tmpDir;
|
|
9
|
+
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
tmpDir = fs.mkdtempSync(path.join(process.cwd(), '.astryx-pack-check-'));
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
afterEach(() => {
|
|
15
|
+
fs.rmSync(tmpDir, {recursive: true, force: true});
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
/** @param {Record<string, string>} scripts */
|
|
19
|
+
function writeThemePackage(scripts) {
|
|
20
|
+
fs.writeFileSync(
|
|
21
|
+
path.join(tmpDir, 'package.json'),
|
|
22
|
+
`${JSON.stringify(
|
|
23
|
+
{
|
|
24
|
+
name: '@acme/widgets',
|
|
25
|
+
version: '1.0.0',
|
|
26
|
+
files: ['astryx.integration.mjs', 'themes'],
|
|
27
|
+
peerDependencies: {'@astryxdesign/cli': '>=0.7.0'},
|
|
28
|
+
peerDependenciesMeta: {'@astryxdesign/cli': {optional: true}},
|
|
29
|
+
scripts,
|
|
30
|
+
},
|
|
31
|
+
null,
|
|
32
|
+
2,
|
|
33
|
+
)}\n`,
|
|
34
|
+
);
|
|
35
|
+
fs.writeFileSync(
|
|
36
|
+
path.join(tmpDir, 'astryx.integration.mjs'),
|
|
37
|
+
"export default {themes: './themes'};\n",
|
|
38
|
+
);
|
|
39
|
+
const root = path.join(tmpDir, 'themes');
|
|
40
|
+
fs.mkdirSync(path.join(root, 'ocean'), {recursive: true});
|
|
41
|
+
fs.writeFileSync(
|
|
42
|
+
path.join(root, 'ocean', 'oceanTheme.ts'),
|
|
43
|
+
"import {defineTheme} from '@astryxdesign/core/theme';\n\nexport const oceanTheme = defineTheme({name: 'ocean'});\n",
|
|
44
|
+
);
|
|
45
|
+
fs.writeFileSync(
|
|
46
|
+
path.join(root, 'ocean', 'oceanTheme.doc.mjs'),
|
|
47
|
+
`/** @type {import('@astryxdesign/cli/authoring').ThemeDoc} */
|
|
48
|
+
export default {type: 'theme', name: 'ocean', displayName: 'Ocean', description: 'Ocean theme.', maintained: true};
|
|
49
|
+
`,
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
describe('integrationPackCheck with lifecycle script output', () => {
|
|
54
|
+
it('checks the tarball when lifecycle scripts print to stdout', async () => {
|
|
55
|
+
writeThemePackage({
|
|
56
|
+
prepack: 'node -e "console.log(\'building the package\')"',
|
|
57
|
+
prepare: 'node -e "console.log(\'preparing\')"',
|
|
58
|
+
postpack: 'node -e "console.log(\'packed\')"',
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
62
|
+
|
|
63
|
+
expect(result.data.issues).toEqual([]);
|
|
64
|
+
expect(result.data.packable).toBe(true);
|
|
65
|
+
expect(result.data.tarball?.filename).toBe('acme-widgets-1.0.0.tgz');
|
|
66
|
+
expect(result.data.contributions.packed).toEqual(
|
|
67
|
+
result.data.contributions.local,
|
|
68
|
+
);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('still runs a chatty lifecycle script and compares what it packed', async () => {
|
|
72
|
+
const renameTheme = [
|
|
73
|
+
"console.log('renaming ocean to storm')",
|
|
74
|
+
"const fs=require('fs')",
|
|
75
|
+
"fs.renameSync('themes/ocean','themes/storm')",
|
|
76
|
+
"const p='themes/storm/oceanTheme.doc.mjs'",
|
|
77
|
+
"let x=fs.readFileSync(p,'utf8')",
|
|
78
|
+
"x=x.replace(/name: 'ocean'/, 'name: '+String.fromCharCode(39)+'storm'+String.fromCharCode(39))",
|
|
79
|
+
'fs.writeFileSync(p,x)',
|
|
80
|
+
].join(';');
|
|
81
|
+
writeThemePackage({prepack: `node -e "${renameTheme}"`});
|
|
82
|
+
|
|
83
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
84
|
+
const codes = result.data.issues.map(issue => issue.code);
|
|
85
|
+
|
|
86
|
+
expect(codes).not.toContain('pack_failed');
|
|
87
|
+
expect(codes).toContain('identity_not_packed');
|
|
88
|
+
expect(codes).toContain('packed_identity_unexpected');
|
|
89
|
+
expect(result.data.packable).toBe(false);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('keeps a failing lifecycle script output in the pack_failed issue', async () => {
|
|
93
|
+
writeThemePackage({
|
|
94
|
+
prepack:
|
|
95
|
+
'node -e "console.error(\'prepack exploded\'); process.exit(3)"',
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
const result = await integrationPackCheck({cwd: tmpDir});
|
|
99
|
+
const failure = result.data.issues.find(
|
|
100
|
+
issue => issue.code === 'pack_failed',
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
expect(result.data.packable).toBe(false);
|
|
104
|
+
expect(failure?.message).toContain('npm pack failed (exit 3)');
|
|
105
|
+
expect(failure?.message).toContain('prepack exploded');
|
|
106
|
+
});
|
|
107
|
+
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* @file `astryx integration
|
|
4
|
+
* @file `astryx integration verify` — verify an integration package is
|
|
5
5
|
* ready to publish by cross-referencing its declared contributions against the
|
|
6
6
|
* real npm tarball.
|
|
7
7
|
*
|
|
@@ -29,9 +29,15 @@ import {assertWithin} from '../../foundation/fs/path-safety.mjs';
|
|
|
29
29
|
import {resolvePackageDir} from '../../foundation/integrations/integrations.mjs';
|
|
30
30
|
import {
|
|
31
31
|
docsTreeCliProblem,
|
|
32
|
+
keywordsCliProblem,
|
|
32
33
|
replacesCliProblem,
|
|
34
|
+
sectionIdsCliProblem,
|
|
35
|
+
themesCliProblem,
|
|
33
36
|
} from '../../foundation/integrations/cli-requirement.mjs';
|
|
34
|
-
import {
|
|
37
|
+
import {
|
|
38
|
+
discoverIntegrationDocs,
|
|
39
|
+
loadTopicModule,
|
|
40
|
+
} from '../../foundation/discovery/docs-discovery.mjs';
|
|
35
41
|
import {
|
|
36
42
|
discoverIntegrationComponents,
|
|
37
43
|
resolveIntegrationImportPath,
|
|
@@ -162,6 +168,22 @@ export function parseNpmPackOutput(output) {
|
|
|
162
168
|
};
|
|
163
169
|
}
|
|
164
170
|
|
|
171
|
+
/**
|
|
172
|
+
* Summarize the JSON error npm prints on stdout when `--json` pack fails.
|
|
173
|
+
* @param {string} output
|
|
174
|
+
* @returns {string}
|
|
175
|
+
*/
|
|
176
|
+
function npmPackErrorDetail(output) {
|
|
177
|
+
try {
|
|
178
|
+
const error = JSON.parse(output)?.error;
|
|
179
|
+
return [error?.summary, error?.detail]
|
|
180
|
+
.filter(part => typeof part === 'string' && part.trim() !== '')
|
|
181
|
+
.join(': ');
|
|
182
|
+
} catch {
|
|
183
|
+
return (output || '').trim();
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
165
187
|
/**
|
|
166
188
|
* Run `npm pack --json` with output directed to `destDir` so no preexisting
|
|
167
189
|
* tgz is overwritten. This intentionally runs the package lifecycle, matching
|
|
@@ -175,16 +197,25 @@ export function parseNpmPackOutput(output) {
|
|
|
175
197
|
function runNpmPack(packageDir, destDir) {
|
|
176
198
|
const result = spawnSync(
|
|
177
199
|
'npm',
|
|
178
|
-
[
|
|
200
|
+
[
|
|
201
|
+
'pack',
|
|
202
|
+
'--json',
|
|
203
|
+
'--silent',
|
|
204
|
+
// Lifecycle scripts still run; background mode keeps their output off
|
|
205
|
+
// the stdout that carries the JSON result.
|
|
206
|
+
'--foreground-scripts=false',
|
|
207
|
+
`--pack-destination=${destDir}`,
|
|
208
|
+
],
|
|
179
209
|
{cwd: packageDir, encoding: 'utf-8', timeout: 60_000},
|
|
180
210
|
);
|
|
181
211
|
if (result.error) {
|
|
182
212
|
throw new Error(`Could not start npm pack: ${result.error.message}`);
|
|
183
213
|
}
|
|
184
214
|
if (result.status !== 0) {
|
|
185
|
-
const
|
|
215
|
+
const detail =
|
|
216
|
+
(result.stderr || '').trim() || npmPackErrorDetail(result.stdout);
|
|
186
217
|
throw new Error(
|
|
187
|
-
`npm pack failed (exit ${result.status})${
|
|
218
|
+
`npm pack failed (exit ${result.status})${detail ? `: ${detail}` : ''}.`,
|
|
188
219
|
);
|
|
189
220
|
}
|
|
190
221
|
return parseNpmPackOutput(result.stdout);
|
|
@@ -308,6 +339,23 @@ function moduleExportsName(file, exportName, seen = new Set()) {
|
|
|
308
339
|
return found;
|
|
309
340
|
}
|
|
310
341
|
|
|
342
|
+
/**
|
|
343
|
+
* Whether any of these doc files has a section that sets `id`.
|
|
344
|
+
* @param {string[]} files
|
|
345
|
+
* @returns {Promise<boolean>}
|
|
346
|
+
*/
|
|
347
|
+
async function setsSectionIds(files) {
|
|
348
|
+
for (const file of files) {
|
|
349
|
+
if (typeof file !== 'string') continue;
|
|
350
|
+
const doc = /** @type {any} */ (await loadTopicModule(file).catch(() => null));
|
|
351
|
+
const sections = Array.isArray(doc?.sections) ? doc.sections : [];
|
|
352
|
+
if (sections.some((/** @type {any} */ section) => section?.id != null)) {
|
|
353
|
+
return true;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
return false;
|
|
357
|
+
}
|
|
358
|
+
|
|
311
359
|
/**
|
|
312
360
|
* Resolve package specifiers through Node's real ESM resolver from the scratch
|
|
313
361
|
* consumer. Resolution does not execute the target module, so source `.tsx`
|
|
@@ -600,19 +648,32 @@ export async function integrationPackCheck(options = {}) {
|
|
|
600
648
|
// (spec:AST-046 FR11): an older CLI can hide every doc topic the package
|
|
601
649
|
// ships, so the declared CLI range must admit only CLIs that read it.
|
|
602
650
|
if (loaded.docs) {
|
|
603
|
-
const {namespaces, guides} = await discoverIntegrationDocs(
|
|
604
|
-
|
|
605
|
-
);
|
|
651
|
+
const {records, namespaces, guides} = await discoverIntegrationDocs(
|
|
652
|
+
loaded,
|
|
653
|
+
).catch(() => ({records: [], namespaces: [], guides: []}));
|
|
606
654
|
const problem =
|
|
607
655
|
namespaces.length > 0 || guides.length > 0
|
|
608
656
|
? docsTreeCliProblem(pkg)
|
|
609
657
|
: null;
|
|
610
658
|
if (problem != null) {
|
|
611
659
|
issues.push(error('docs_tree_needs_cli', problem));
|
|
660
|
+
} else if (
|
|
661
|
+
await setsSectionIds([
|
|
662
|
+
...records.map(record => record.path),
|
|
663
|
+
...guides.map(guide => /** @type {any} */ (guide.ref).topicFile),
|
|
664
|
+
])
|
|
665
|
+
) {
|
|
666
|
+
// A section `id` is also a field an older CLI rejects, hiding the
|
|
667
|
+
// package's doc topics. It needs an older CLI than the docs tree does.
|
|
668
|
+
const idProblem = sectionIdsCliProblem(pkg);
|
|
669
|
+
if (idProblem != null) {
|
|
670
|
+
issues.push(error('section_ids_need_cli', idProblem));
|
|
671
|
+
}
|
|
612
672
|
}
|
|
613
673
|
}
|
|
614
|
-
// A template that sets `replaces` needs a CLI
|
|
615
|
-
//
|
|
674
|
+
// A template that sets `replaces` (spec:AST-035) or `keywords` needs a CLI
|
|
675
|
+
// that reads the field: an older CLI drops that template and hides the
|
|
676
|
+
// package's docs.
|
|
616
677
|
if (loaded.templates) {
|
|
617
678
|
const found = await discoverIntegrationTemplatesForOne(loaded).catch(
|
|
618
679
|
() => ({templates: [], errors: []}),
|
|
@@ -624,6 +685,19 @@ export async function integrationPackCheck(options = {}) {
|
|
|
624
685
|
);
|
|
625
686
|
const problem = setsReplaces ? replacesCliProblem(pkg) : null;
|
|
626
687
|
if (problem != null) issues.push(error('replaces_needs_cli', problem));
|
|
688
|
+
const setsKeywords = found.templates.some(
|
|
689
|
+
template => template.keywords != null && template.keywords.length > 0,
|
|
690
|
+
);
|
|
691
|
+
const keywordsProblem = setsKeywords ? keywordsCliProblem(pkg) : null;
|
|
692
|
+
if (keywordsProblem != null) {
|
|
693
|
+
issues.push(error('keywords_needs_cli', keywordsProblem));
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
// A theme needs a CLI that reads typed theme descriptors: an older CLI
|
|
697
|
+
// rejects the themes root and withholds the package's themes and docs.
|
|
698
|
+
if (localIdentities.themes.length > 0) {
|
|
699
|
+
const problem = themesCliProblem(pkg);
|
|
700
|
+
if (problem != null) issues.push(error('themes_need_cli', problem));
|
|
627
701
|
}
|
|
628
702
|
|
|
629
703
|
// Temp resources — always cleaned up
|
|
@@ -657,6 +731,14 @@ export async function integrationPackCheck(options = {}) {
|
|
|
657
731
|
// package's already-installed dependencies. The unique suffix makes
|
|
658
732
|
// concurrent checks independent.
|
|
659
733
|
scratchBase = fs.mkdtempSync(path.join(packageDir, '.astryx-pack-check-'));
|
|
734
|
+
// The consumer's own package.json makes it the package scope for its
|
|
735
|
+
// imports. Without one, Node resolves the package's name through the
|
|
736
|
+
// SOURCE package.json (self-reference), so an export target left out of
|
|
737
|
+
// the tarball would still resolve.
|
|
738
|
+
fs.writeFileSync(
|
|
739
|
+
path.join(scratchBase, 'package.json'),
|
|
740
|
+
`${JSON.stringify({name: 'astryx-verify-consumer', private: true})}\n`,
|
|
741
|
+
);
|
|
660
742
|
|
|
661
743
|
// Cross-reference file inventory vs pack list
|
|
662
744
|
if (!packResult.packedPaths.has(fileInv.manifest)) {
|