@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
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
export const doc = {
|
|
11
11
|
type: 'schema',
|
|
12
12
|
name: 'config',
|
|
13
|
-
displayName: '
|
|
13
|
+
displayName: 'astryx.config',
|
|
14
14
|
namespace: 'authoring',
|
|
15
15
|
description:
|
|
16
16
|
'The optional astryx.config.* file at your project root. Declares which ' +
|
|
@@ -60,6 +60,14 @@ export const doc = {
|
|
|
60
60
|
example:
|
|
61
61
|
"{ audience: 'internal', async handle(report, {signal}) { return sendGap(report, {signal}); } }",
|
|
62
62
|
},
|
|
63
|
+
{
|
|
64
|
+
name: 'discover',
|
|
65
|
+
type: 'DiscoverSource',
|
|
66
|
+
description:
|
|
67
|
+
'Tell `astryx discover` which integrations this project could add: an async function that returns a catalog. An integration can provide one too, as a `discover` named export from its manifest. Discover calls every source, yours first, and one that fails never hides the others. Discover only reads; your package manager installs.',
|
|
68
|
+
example:
|
|
69
|
+
"async ({signal, package: name, version}) => fetchCatalog({signal, name, version})",
|
|
70
|
+
},
|
|
63
71
|
{
|
|
64
72
|
name: 'experimental',
|
|
65
73
|
type: '{ xle?: { components?: Record<string, XleComponent> } }',
|
|
@@ -30,6 +30,7 @@ export type XleComponent = import("./type.js").XleComponent;
|
|
|
30
30
|
export type DebugConfig = import("./type.js").DebugConfig;
|
|
31
31
|
export type DebugEventHandler = import("../debug/type.js").DebugEventHandler;
|
|
32
32
|
export type GapReportHandler = import("../gap-report/type.js").GapReportHandler;
|
|
33
|
+
export type DiscoverSource = import("../discover/type.js").DiscoverSource;
|
|
33
34
|
import { z } from 'zod';
|
|
34
35
|
declare const configSchema: z.ZodObject<{
|
|
35
36
|
integrations: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -48,6 +49,7 @@ declare const configSchema: z.ZodObject<{
|
|
|
48
49
|
}, z.core.$strict>>;
|
|
49
50
|
debug: z.ZodOptional<z.ZodType<import("../debug/type.js").DebugEventHandler, any, z.core.$ZodTypeInternals<import("../debug/type.js").DebugEventHandler, any>>>;
|
|
50
51
|
gapReport: z.ZodOptional<z.ZodType<import("../gap-report/type.js").GapReportHandler, any, z.core.$ZodTypeInternals<import("../gap-report/type.js").GapReportHandler, any>>>;
|
|
52
|
+
discover: z.ZodOptional<z.ZodType<import("../discover/type.js").DiscoverSource, any, z.core.$ZodTypeInternals<import("../discover/type.js").DiscoverSource, any>>>;
|
|
51
53
|
experimental: z.ZodOptional<z.ZodObject<{
|
|
52
54
|
xle: z.ZodOptional<z.ZodObject<{
|
|
53
55
|
components: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
import {z} from 'zod';
|
|
13
13
|
import {formatZodError} from '../_shared/errors.mjs';
|
|
14
14
|
import {parseGapReportHandler} from '../gap-report/parse.mjs';
|
|
15
|
+
import {parseDiscoverSource} from '../discover/parse.mjs';
|
|
15
16
|
|
|
16
17
|
/** @typedef {import('./type.js').AstryxConfig} AstryxConfig */
|
|
17
18
|
/** @typedef {import('./type.js').PostCodemodHook} PostCodemodHook */
|
|
@@ -19,6 +20,7 @@ import {parseGapReportHandler} from '../gap-report/parse.mjs';
|
|
|
19
20
|
/** @typedef {import('./type.js').DebugConfig} DebugConfig */
|
|
20
21
|
/** @typedef {import('../debug/type.js').DebugEventHandler} DebugEventHandler */
|
|
21
22
|
/** @typedef {import('../gap-report/type.js').GapReportHandler} GapReportHandler */
|
|
23
|
+
/** @typedef {import('../discover/type.js').DiscoverSource} DiscoverSource */
|
|
22
24
|
|
|
23
25
|
// Typed `z.custom` so `z.infer` reproduces the real function type (not `unknown`).
|
|
24
26
|
const buildCommand = /** @type {z.ZodType<PostCodemodHook['buildCommand']>} */ (
|
|
@@ -66,6 +68,22 @@ const gapReportHandlerSchema = /** @type {z.ZodType<GapReportHandler>} */ (
|
|
|
66
68
|
)
|
|
67
69
|
);
|
|
68
70
|
|
|
71
|
+
// The same check an integration's `discover` named export passes. Typed
|
|
72
|
+
// z.custom preserves the public function type.
|
|
73
|
+
const discoverSourceSchema = /** @type {z.ZodType<DiscoverSource>} */ (
|
|
74
|
+
z.custom(
|
|
75
|
+
value => {
|
|
76
|
+
try {
|
|
77
|
+
parseDiscoverSource(value, 'discover');
|
|
78
|
+
return true;
|
|
79
|
+
} catch {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
{message: 'Expected a discover source function'},
|
|
84
|
+
)
|
|
85
|
+
);
|
|
86
|
+
|
|
69
87
|
const configSchema = z
|
|
70
88
|
.object({
|
|
71
89
|
integrations: z.array(z.string()).optional(),
|
|
@@ -76,6 +94,7 @@ const configSchema = z
|
|
|
76
94
|
.optional(),
|
|
77
95
|
debug: debugSchema.optional(),
|
|
78
96
|
gapReport: gapReportHandlerSchema.optional(),
|
|
97
|
+
discover: discoverSourceSchema.optional(),
|
|
79
98
|
experimental: z
|
|
80
99
|
.object({
|
|
81
100
|
xle: z
|
|
@@ -63,6 +63,14 @@ describe('parseConfig (load boundary)', () => {
|
|
|
63
63
|
).toEqual({audience: 'internal', handle});
|
|
64
64
|
});
|
|
65
65
|
|
|
66
|
+
it('accepts a discover source function and refuses anything else', () => {
|
|
67
|
+
const discover = async () => ({});
|
|
68
|
+
expect(parseConfig({discover}).discover).toBe(discover);
|
|
69
|
+
expect(reason({discover: 'https://example.com/catalog.json'})).toContain(
|
|
70
|
+
'discover',
|
|
71
|
+
);
|
|
72
|
+
});
|
|
73
|
+
|
|
66
74
|
it('rejects obsolete or extended gap-report handler shapes', () => {
|
|
67
75
|
expect(reason({gapReport: {command: './report.mjs'}})).toContain(
|
|
68
76
|
'gapReport',
|
package/authoring/config/type.ts
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
import type {DebugEventHandler} from '../debug/type.js';
|
|
13
13
|
import type {GapReportHandler} from '../gap-report/type.js';
|
|
14
|
+
import type {DiscoverSource} from '../discover/type.js';
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* A command to run as part of a post-codemod hook. Returned by a hook's
|
|
@@ -96,6 +97,16 @@ export interface AstryxConfig {
|
|
|
96
97
|
debug?: DebugConfig;
|
|
97
98
|
/** Route gap reports through a project-owned handler. See {@link GapReportHandler}. */
|
|
98
99
|
gapReport?: GapReportHandler;
|
|
100
|
+
/**
|
|
101
|
+
* Tell `astryx discover` about integrations this project could add. See
|
|
102
|
+
* {@link DiscoverSource}.
|
|
103
|
+
*
|
|
104
|
+
* An integration can provide a source too, as a `discover` named export from
|
|
105
|
+
* its `astryx.integration.*` module. Discover calls every source: this one
|
|
106
|
+
* first, then each integration's in load order, and one that fails never
|
|
107
|
+
* hides the others.
|
|
108
|
+
*/
|
|
109
|
+
discover?: DiscoverSource;
|
|
99
110
|
/**
|
|
100
111
|
* EXPERIMENTAL — shape may change and is not part of the stable config
|
|
101
112
|
* contract. Provisional home for features still being proven out.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// @generated by scripts/sync-api-types.mjs from the JSDoc in authoring/**/*.mjs.
|
|
2
|
+
// DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @file SchemaDoc for DiscoverSource, the function `astryx discover` calls to
|
|
6
|
+
* learn which integrations a project could add.
|
|
7
|
+
* @input The DiscoverSource type and the catalog types beside it (`type.ts`),
|
|
8
|
+
* which `parse.mjs` validates.
|
|
9
|
+
* @output The `discover-source` section of `astryx docs authoring`.
|
|
10
|
+
* @position packages/cli/authoring/discover — schema documentation
|
|
11
|
+
*/
|
|
12
|
+
/** @type {import('@astryxdesign/cli/authoring').SchemaDoc} */
|
|
13
|
+
export const doc: import("@astryxdesign/cli/authoring").SchemaDoc;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file SchemaDoc for DiscoverSource, the function `astryx discover` calls to
|
|
5
|
+
* learn which integrations a project could add.
|
|
6
|
+
* @input The DiscoverSource type and the catalog types beside it (`type.ts`),
|
|
7
|
+
* which `parse.mjs` validates.
|
|
8
|
+
* @output The `discover-source` section of `astryx docs authoring`.
|
|
9
|
+
* @position packages/cli/authoring/discover — schema documentation
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/** @type {import('@astryxdesign/cli/authoring').SchemaDoc} */
|
|
13
|
+
export const doc = {
|
|
14
|
+
type: 'schema',
|
|
15
|
+
name: 'discover-source',
|
|
16
|
+
displayName: 'DiscoverSource',
|
|
17
|
+
namespace: 'authoring',
|
|
18
|
+
description:
|
|
19
|
+
'A source for `astryx discover`: an async function that returns a catalog of packages a project could add, their versions, and what each version adds. Set it as `discover` in astryx.config, or export it as `discover` from an integration manifest. Discover calls every source, the project one first, and one that throws, runs past 30 seconds, or returns an invalid catalog never hides the others; discover then uses the last good answer it saved for that source. Discover only reads: it prints the command that adds a package and never runs it.',
|
|
20
|
+
appliesTo:
|
|
21
|
+
'`discover` in astryx.config.*, or the `discover` named export of astryx.integration.*',
|
|
22
|
+
fields: [
|
|
23
|
+
{
|
|
24
|
+
name: 'context',
|
|
25
|
+
type: 'DiscoverSourceContext',
|
|
26
|
+
description: 'The one argument the source is called with.',
|
|
27
|
+
required: true,
|
|
28
|
+
fields: [
|
|
29
|
+
{
|
|
30
|
+
name: 'context.signal',
|
|
31
|
+
type: 'AbortSignal',
|
|
32
|
+
description: 'Aborted when the source runs past 30 seconds.',
|
|
33
|
+
required: true,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'context.package',
|
|
37
|
+
type: 'string',
|
|
38
|
+
description:
|
|
39
|
+
'Set when discover shows one package: return that package with every version.',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: 'context.version',
|
|
43
|
+
type: 'string',
|
|
44
|
+
description:
|
|
45
|
+
"With `package`: return that version's contributions. Without it, the latest release's.",
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: 'returns',
|
|
51
|
+
type: 'Promise<DiscoverCatalog>',
|
|
52
|
+
description:
|
|
53
|
+
'The catalog. Discover checks it, ignores fields and item kinds it does not know, and refuses any schemaVersion but 1.',
|
|
54
|
+
required: true,
|
|
55
|
+
fields: [
|
|
56
|
+
{
|
|
57
|
+
name: 'schemaVersion',
|
|
58
|
+
type: '1',
|
|
59
|
+
description: 'Version of the catalog shape.',
|
|
60
|
+
required: true,
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: 'source',
|
|
64
|
+
type: '{name: string, generatedAt: string, complete: boolean}',
|
|
65
|
+
description:
|
|
66
|
+
'Who answered, when the data was produced (ISO 8601), and false when the source knows its list is partial.',
|
|
67
|
+
required: true,
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: 'packages',
|
|
71
|
+
type: 'DiscoverPackage[]',
|
|
72
|
+
description:
|
|
73
|
+
'One entry per npm package. When two sources list the same package, the earlier source wins.',
|
|
74
|
+
required: true,
|
|
75
|
+
fields: [
|
|
76
|
+
{
|
|
77
|
+
name: 'packages[].package',
|
|
78
|
+
type: 'string',
|
|
79
|
+
description: 'The npm name.',
|
|
80
|
+
required: true,
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
name: 'packages[].integration',
|
|
84
|
+
type: 'string',
|
|
85
|
+
description:
|
|
86
|
+
'Shared by every npm name that publishes the same integration. Discover lists an integration once.',
|
|
87
|
+
required: true,
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
name: 'packages[].aliases',
|
|
91
|
+
type: 'string[]',
|
|
92
|
+
description:
|
|
93
|
+
"The integration's other npm names. Discover never offers a package the project has under another name.",
|
|
94
|
+
required: true,
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: 'packages[].description',
|
|
98
|
+
type: 'string',
|
|
99
|
+
description: 'One line, for the list and search.',
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: 'packages[].latest',
|
|
103
|
+
type: 'string | null',
|
|
104
|
+
description: 'The latest release. Null when there are only prereleases.',
|
|
105
|
+
required: true,
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
name: 'packages[].versions',
|
|
109
|
+
type: 'DiscoverVersion[]',
|
|
110
|
+
description:
|
|
111
|
+
'Every version, newest first: `{version, publishedAt, prerelease, status}`, where status is `ok` or why the version could not be read.',
|
|
112
|
+
required: true,
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
name: 'packages[].contributions',
|
|
116
|
+
type: 'DiscoverContribution[]',
|
|
117
|
+
description:
|
|
118
|
+
"What the requested (else latest) version adds: `{kind, name, title?, summary?, keywords?}`, where kind is `component`, `template`, `doc`, `theme`, `codemod`, or `agent-doc` (a DiscoverKind) and name is the name the CLI uses for it.",
|
|
119
|
+
required: true,
|
|
120
|
+
},
|
|
121
|
+
],
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
},
|
|
125
|
+
],
|
|
126
|
+
examples: [
|
|
127
|
+
{
|
|
128
|
+
label: 'A project source in astryx.config',
|
|
129
|
+
code:
|
|
130
|
+
'export default {\n' +
|
|
131
|
+
' async discover({signal, package: name, version}) {\n' +
|
|
132
|
+
' const res = await fetch(catalogUrl(name, version), {signal});\n' +
|
|
133
|
+
' return res.json();\n' +
|
|
134
|
+
' },\n' +
|
|
135
|
+
'};',
|
|
136
|
+
},
|
|
137
|
+
],
|
|
138
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// @generated by scripts/sync-api-types.mjs from the JSDoc in authoring/**/*.mjs.
|
|
2
|
+
// DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Check a catalog a discover source returned. Throws an Error naming the first
|
|
6
|
+
* problem. Items of a kind this CLI does not know are dropped, and versions are
|
|
7
|
+
* put newest first whatever order the source used.
|
|
8
|
+
*
|
|
9
|
+
* @param {unknown} value
|
|
10
|
+
* @param {string} [label]
|
|
11
|
+
* @returns {import('./type.js').DiscoverCatalog}
|
|
12
|
+
*/
|
|
13
|
+
export function parseDiscoverCatalog(value: unknown, label?: string): import("./type.js").DiscoverCatalog;
|
|
14
|
+
/**
|
|
15
|
+
* Check a discover source itself: an async function, like `debug`, that takes
|
|
16
|
+
* `{signal, package?, version?}` and resolves to a catalog.
|
|
17
|
+
*
|
|
18
|
+
* @param {unknown} value
|
|
19
|
+
* @param {string} label
|
|
20
|
+
* @returns {import('./type.js').DiscoverSource}
|
|
21
|
+
*/
|
|
22
|
+
export function parseDiscoverSource(value: unknown, label: string): import("./type.js").DiscoverSource;
|
|
23
|
+
/** Item kinds a catalog may list, in display order. */
|
|
24
|
+
export const DISCOVER_KINDS: readonly ["component", "template", "doc", "theme", "codemod", "agent-doc"];
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file Runtime checks for discover sources and the catalogs they return.
|
|
5
|
+
*
|
|
6
|
+
* The catalog schema is deliberately not strict: a source may add fields this
|
|
7
|
+
* CLI does not know, and they are dropped. An unknown `schemaVersion` is
|
|
8
|
+
* refused, and an item of a kind this CLI does not know is skipped, so a newer
|
|
9
|
+
* source never breaks an older CLI.
|
|
10
|
+
*
|
|
11
|
+
* @position packages/cli/authoring/discover — parse + validate, no I/O.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import {z} from 'zod';
|
|
15
|
+
|
|
16
|
+
/** Item kinds a catalog may list, in display order. */
|
|
17
|
+
export const DISCOVER_KINDS = /** @type {const} */ ([
|
|
18
|
+
'component',
|
|
19
|
+
'template',
|
|
20
|
+
'doc',
|
|
21
|
+
'theme',
|
|
22
|
+
'codemod',
|
|
23
|
+
'agent-doc',
|
|
24
|
+
]);
|
|
25
|
+
|
|
26
|
+
const text = (/** @type {number} */ max) => z.string().min(1).max(max);
|
|
27
|
+
|
|
28
|
+
const contributionSchema = z.object({
|
|
29
|
+
kind: text(32),
|
|
30
|
+
name: text(512),
|
|
31
|
+
title: z.string().max(512).optional(),
|
|
32
|
+
summary: z.string().max(4096).optional(),
|
|
33
|
+
keywords: z.array(z.string().max(128)).max(64).optional(),
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const versionSchema = z.object({
|
|
37
|
+
version: text(256),
|
|
38
|
+
publishedAt: z.string().max(64).nullable(),
|
|
39
|
+
prerelease: z.boolean(),
|
|
40
|
+
status: text(64),
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const packageSchema = z.object({
|
|
44
|
+
package: text(214),
|
|
45
|
+
integration: text(214),
|
|
46
|
+
aliases: z.array(text(214)).max(64),
|
|
47
|
+
description: z.string().max(1024).optional(),
|
|
48
|
+
latest: text(256).nullable(),
|
|
49
|
+
versions: z.array(versionSchema).max(50_000),
|
|
50
|
+
contributions: z.array(contributionSchema).max(50_000),
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const catalogSchema = z.object({
|
|
54
|
+
schemaVersion: z.literal(1),
|
|
55
|
+
source: z.object({
|
|
56
|
+
name: text(256),
|
|
57
|
+
generatedAt: text(64),
|
|
58
|
+
complete: z.boolean(),
|
|
59
|
+
}),
|
|
60
|
+
packages: z.array(packageSchema).max(20_000),
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Newest first by publish time. A version with no known publish time goes
|
|
65
|
+
* last, and ties fall back to the version number.
|
|
66
|
+
* @param {{version: string, publishedAt: string | null}} a
|
|
67
|
+
* @param {{version: string, publishedAt: string | null}} b
|
|
68
|
+
*/
|
|
69
|
+
function newestFirst(a, b) {
|
|
70
|
+
const at = Date.parse(a.publishedAt ?? '');
|
|
71
|
+
const bt = Date.parse(b.publishedAt ?? '');
|
|
72
|
+
if (Number.isNaN(at) !== Number.isNaN(bt)) return Number.isNaN(at) ? 1 : -1;
|
|
73
|
+
if (!Number.isNaN(at) && at !== bt) return bt - at;
|
|
74
|
+
return b.version.localeCompare(a.version, 'en', {numeric: true});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Check a catalog a discover source returned. Throws an Error naming the first
|
|
79
|
+
* problem. Items of a kind this CLI does not know are dropped, and versions are
|
|
80
|
+
* put newest first whatever order the source used.
|
|
81
|
+
*
|
|
82
|
+
* @param {unknown} value
|
|
83
|
+
* @param {string} [label]
|
|
84
|
+
* @returns {import('./type.js').DiscoverCatalog}
|
|
85
|
+
*/
|
|
86
|
+
export function parseDiscoverCatalog(value, label = 'discover source') {
|
|
87
|
+
const version =
|
|
88
|
+
value != null && typeof value === 'object'
|
|
89
|
+
? /** @type {{schemaVersion?: unknown}} */ (value).schemaVersion
|
|
90
|
+
: undefined;
|
|
91
|
+
if (version !== undefined && version !== 1) {
|
|
92
|
+
throw new Error(
|
|
93
|
+
`${label} returned schemaVersion ${String(version)}; this CLI reads schemaVersion 1`,
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
const parsed = catalogSchema.safeParse(value);
|
|
97
|
+
if (!parsed.success) {
|
|
98
|
+
const issue = parsed.error.issues[0];
|
|
99
|
+
const where = issue?.path.length ? ` at ${issue.path.join('.')}` : '';
|
|
100
|
+
throw new Error(
|
|
101
|
+
`${label} returned an invalid catalog${where}: ${issue?.message}`,
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
const known = /** @type {readonly string[]} */ (DISCOVER_KINDS);
|
|
105
|
+
return /** @type {import('./type.js').DiscoverCatalog} */ ({
|
|
106
|
+
...parsed.data,
|
|
107
|
+
packages: parsed.data.packages.map(pkg => ({
|
|
108
|
+
...pkg,
|
|
109
|
+
versions: [...pkg.versions].sort(newestFirst),
|
|
110
|
+
contributions: pkg.contributions.filter(c => known.includes(c.kind)),
|
|
111
|
+
})),
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Check a discover source itself: an async function, like `debug`, that takes
|
|
117
|
+
* `{signal, package?, version?}` and resolves to a catalog.
|
|
118
|
+
*
|
|
119
|
+
* @param {unknown} value
|
|
120
|
+
* @param {string} label
|
|
121
|
+
* @returns {import('./type.js').DiscoverSource}
|
|
122
|
+
*/
|
|
123
|
+
export function parseDiscoverSource(value, label) {
|
|
124
|
+
if (typeof value !== 'function') {
|
|
125
|
+
throw new Error(`${label} must be a function`);
|
|
126
|
+
}
|
|
127
|
+
return /** @type {import('./type.js').DiscoverSource} */ (value);
|
|
128
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file Tests for the discover source and catalog checks.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {describe, it, expect} from 'vitest';
|
|
8
|
+
import {
|
|
9
|
+
DISCOVER_KINDS,
|
|
10
|
+
parseDiscoverCatalog,
|
|
11
|
+
parseDiscoverSource,
|
|
12
|
+
} from './parse.mjs';
|
|
13
|
+
|
|
14
|
+
function catalog(overrides = {}) {
|
|
15
|
+
return {
|
|
16
|
+
schemaVersion: 1,
|
|
17
|
+
source: {
|
|
18
|
+
name: 'Acme catalog',
|
|
19
|
+
generatedAt: '2026-09-30T14:00:00.000Z',
|
|
20
|
+
complete: true,
|
|
21
|
+
},
|
|
22
|
+
packages: [
|
|
23
|
+
{
|
|
24
|
+
package: '@acme/ui',
|
|
25
|
+
integration: 'acme-ui',
|
|
26
|
+
aliases: [],
|
|
27
|
+
latest: '2.0.0',
|
|
28
|
+
versions: [
|
|
29
|
+
{
|
|
30
|
+
version: '2.0.0',
|
|
31
|
+
publishedAt: '2026-09-29T00:00:00.000Z',
|
|
32
|
+
prerelease: false,
|
|
33
|
+
status: 'ok',
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
contributions: [{kind: 'component', name: 'Button'}],
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
...overrides,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
describe('parseDiscoverCatalog', () => {
|
|
44
|
+
it('accepts a catalog', () => {
|
|
45
|
+
expect(parseDiscoverCatalog(catalog())).toEqual(catalog());
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('drops fields it does not know, so a newer source still works', () => {
|
|
49
|
+
const parsed = parseDiscoverCatalog({...catalog(), cursor: 'next'});
|
|
50
|
+
expect(parsed).not.toHaveProperty('cursor');
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('drops items of a kind it does not know', () => {
|
|
54
|
+
const value = catalog();
|
|
55
|
+
value.packages[0].contributions.push({kind: 'widget', name: 'Spinner'});
|
|
56
|
+
expect(parseDiscoverCatalog(value).packages[0].contributions).toEqual([
|
|
57
|
+
{kind: 'component', name: 'Button'},
|
|
58
|
+
]);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('puts versions newest first whatever order the source used', () => {
|
|
62
|
+
const value = catalog();
|
|
63
|
+
value.packages[0].versions = [
|
|
64
|
+
{
|
|
65
|
+
version: '1.0.0',
|
|
66
|
+
publishedAt: '2026-01-05T00:00:00.000Z',
|
|
67
|
+
prerelease: false,
|
|
68
|
+
status: 'ok',
|
|
69
|
+
},
|
|
70
|
+
{version: '1.5.0', publishedAt: null, prerelease: false, status: 'ok'},
|
|
71
|
+
{
|
|
72
|
+
version: '2.0.0',
|
|
73
|
+
publishedAt: '2026-09-29T00:00:00.000Z',
|
|
74
|
+
prerelease: false,
|
|
75
|
+
status: 'ok',
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
version: '2.0.0-rc.1',
|
|
79
|
+
publishedAt: '2026-09-01T00:00:00.000Z',
|
|
80
|
+
prerelease: true,
|
|
81
|
+
status: 'ok',
|
|
82
|
+
},
|
|
83
|
+
];
|
|
84
|
+
expect(
|
|
85
|
+
parseDiscoverCatalog(value).packages[0].versions.map(v => v.version),
|
|
86
|
+
).toEqual(['2.0.0', '2.0.0-rc.1', '1.0.0', '1.5.0']);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('refuses a schemaVersion it does not read', () => {
|
|
90
|
+
expect(() => parseDiscoverCatalog(catalog({schemaVersion: 2}))).toThrow(
|
|
91
|
+
'this CLI reads schemaVersion 1',
|
|
92
|
+
);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('names the first problem and where it is', () => {
|
|
96
|
+
expect(() =>
|
|
97
|
+
parseDiscoverCatalog(catalog({packages: [{package: ''}]}), 'the source'),
|
|
98
|
+
).toThrow(/^the source returned an invalid catalog at packages\.0\./);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('lists the kinds in display order', () => {
|
|
102
|
+
expect(DISCOVER_KINDS).toEqual([
|
|
103
|
+
'component',
|
|
104
|
+
'template',
|
|
105
|
+
'doc',
|
|
106
|
+
'theme',
|
|
107
|
+
'codemod',
|
|
108
|
+
'agent-doc',
|
|
109
|
+
]);
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
describe('parseDiscoverSource', () => {
|
|
114
|
+
it('accepts a function', () => {
|
|
115
|
+
const source = async () => catalog();
|
|
116
|
+
expect(parseDiscoverSource(source, 'discover')).toBe(source);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it('refuses anything else, such as a URL', () => {
|
|
120
|
+
expect(() =>
|
|
121
|
+
parseDiscoverSource('https://example.com/catalog.json', 'discover'),
|
|
122
|
+
).toThrow('discover must be a function');
|
|
123
|
+
});
|
|
124
|
+
});
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Public type surface for discover sources.
|
|
5
|
+
*
|
|
6
|
+
* A discover source tells `astryx discover` which integrations exist beyond the
|
|
7
|
+
* ones a project already has. A project sets one as `discover` in
|
|
8
|
+
* `astryx.config`; an integration exports one as a `discover` NAMED export from
|
|
9
|
+
* its manifest. Discover calls every source, checks each answer, keeps a saved
|
|
10
|
+
* copy of the last good one, and never installs, enables, or runs anything a
|
|
11
|
+
* catalog names.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/** Kinds of item a package can add. */
|
|
15
|
+
export type DiscoverKind =
|
|
16
|
+
'component' | 'template' | 'doc' | 'theme' | 'codemod' | 'agent-doc';
|
|
17
|
+
|
|
18
|
+
/** One item a package version adds. */
|
|
19
|
+
export interface DiscoverContribution {
|
|
20
|
+
kind: DiscoverKind;
|
|
21
|
+
/**
|
|
22
|
+
* The name the CLI uses for it: a component name, template id, doc topic,
|
|
23
|
+
* theme slug, or codemod id.
|
|
24
|
+
*/
|
|
25
|
+
name: string;
|
|
26
|
+
title?: string;
|
|
27
|
+
summary?: string;
|
|
28
|
+
keywords?: string[];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** One published version of a package. */
|
|
32
|
+
export interface DiscoverVersion {
|
|
33
|
+
version: string;
|
|
34
|
+
/** ISO 8601 publish time, or null when the source does not know it. */
|
|
35
|
+
publishedAt: string | null;
|
|
36
|
+
prerelease: boolean;
|
|
37
|
+
/** `ok`, or why the source could not read this version. */
|
|
38
|
+
status: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** One npm package a source knows about. */
|
|
42
|
+
export interface DiscoverPackage {
|
|
43
|
+
package: string;
|
|
44
|
+
/** Shared by every npm name that publishes the same integration. */
|
|
45
|
+
integration: string;
|
|
46
|
+
/** The integration's other npm names. Discover never offers one the project has. */
|
|
47
|
+
aliases: string[];
|
|
48
|
+
description?: string;
|
|
49
|
+
/** The latest release, or null when the package has only prereleases. */
|
|
50
|
+
latest: string | null;
|
|
51
|
+
/** Every version, newest first. */
|
|
52
|
+
versions: DiscoverVersion[];
|
|
53
|
+
/** What the requested version adds, or the latest when none was requested. */
|
|
54
|
+
contributions: DiscoverContribution[];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** What a discover source returns. */
|
|
58
|
+
export interface DiscoverCatalog {
|
|
59
|
+
schemaVersion: 1;
|
|
60
|
+
source: {
|
|
61
|
+
/** Shown to people, for example "Acme catalog". */
|
|
62
|
+
name: string;
|
|
63
|
+
/** ISO 8601 time the source's data was produced. */
|
|
64
|
+
generatedAt: string;
|
|
65
|
+
/** False when the source knows its list is partial. */
|
|
66
|
+
complete: boolean;
|
|
67
|
+
};
|
|
68
|
+
packages: DiscoverPackage[];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** One call to a discover source. */
|
|
72
|
+
export interface DiscoverSourceContext {
|
|
73
|
+
/** Aborted when the source exceeds its 30-second budget. */
|
|
74
|
+
readonly signal: AbortSignal;
|
|
75
|
+
/** Asks for one package: every version, and `version`'s contributions. */
|
|
76
|
+
readonly package?: string;
|
|
77
|
+
/** With `package`: the version whose contributions to return. Defaults to the latest. */
|
|
78
|
+
readonly version?: string;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* A discover source: an async function, like `debug`. Set it as `discover` in
|
|
83
|
+
* astryx.config, or export it as `discover` from an integration manifest.
|
|
84
|
+
*/
|
|
85
|
+
export type DiscoverSource = (
|
|
86
|
+
context: DiscoverSourceContext,
|
|
87
|
+
) => Promise<DiscoverCatalog>;
|
|
@@ -216,6 +216,7 @@ export const ComponentDocKindSchema: z.ZodObject<{
|
|
|
216
216
|
theming: z.ZodOptional<z.ZodUnknown>;
|
|
217
217
|
playground: z.ZodOptional<z.ZodUnknown>;
|
|
218
218
|
examples: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
|
|
219
|
+
replaces: z.ZodOptional<z.ZodString>;
|
|
219
220
|
name: z.ZodString;
|
|
220
221
|
displayName: z.ZodOptional<z.ZodString>;
|
|
221
222
|
description: z.ZodOptional<z.ZodString>;
|
|
@@ -316,6 +317,7 @@ export const FunctionDocKindSchema: z.ZodObject<{
|
|
|
316
317
|
export const GenericDocKindSchema: z.ZodObject<{
|
|
317
318
|
type: z.ZodLiteral<"generic">;
|
|
318
319
|
title: z.ZodOptional<z.ZodString>;
|
|
320
|
+
keywords: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
319
321
|
sections: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
320
322
|
id: z.ZodOptional<z.ZodString>;
|
|
321
323
|
title: z.ZodString;
|
|
@@ -384,7 +386,6 @@ export const GenericDocKindSchema: z.ZodObject<{
|
|
|
384
386
|
import: z.ZodOptional<z.ZodString>;
|
|
385
387
|
group: z.ZodOptional<z.ZodString>;
|
|
386
388
|
category: z.ZodOptional<z.ZodString>;
|
|
387
|
-
keywords: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
388
389
|
parent: z.ZodOptional<z.ZodString>;
|
|
389
390
|
relatedDocs: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
390
391
|
hidden: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -840,7 +841,6 @@ export const LegacyDocSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
840
841
|
displayName: z.ZodOptional<z.ZodString>;
|
|
841
842
|
group: z.ZodOptional<z.ZodString>;
|
|
842
843
|
category: z.ZodOptional<z.ZodString>;
|
|
843
|
-
keywords: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
844
844
|
isHiddenFromOverview: z.ZodOptional<z.ZodBoolean>;
|
|
845
845
|
hidden: z.ZodOptional<z.ZodBoolean>;
|
|
846
846
|
hiddenComponents: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -865,6 +865,7 @@ export const LegacyDocSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
865
865
|
}>>;
|
|
866
866
|
title: z.ZodString;
|
|
867
867
|
description: z.ZodString;
|
|
868
|
+
keywords: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
868
869
|
sections: z.ZodArray<z.ZodObject<{
|
|
869
870
|
id: z.ZodOptional<z.ZodString>;
|
|
870
871
|
title: z.ZodString;
|