@astryxdesign/cli 0.7.2-canary.fdd384f → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +119 -0
- package/README.md +169 -149
- package/api/build/_adapter.d.mts +8 -0
- package/api/build/_adapter.mjs +12 -1
- package/api/build/build.doc.mjs +4 -0
- package/api/build/kit/kit.mjs +3 -11
- package/api/component/_adapter.d.mts +31 -0
- package/api/component/_adapter.mjs +119 -11
- package/api/component/component.doc.mjs +6 -1
- package/api/component/component.mjs +60 -10
- package/api/component/doc-links.test.mjs +386 -0
- package/api/discover/_adapter.d.mts +132 -12
- package/api/discover/_adapter.mjs +488 -27
- package/api/discover/_adapter.test.mjs +599 -17
- package/api/discover/_catalog-view.d.mts +16 -5
- package/api/discover/_catalog-view.mjs +32 -8
- package/api/discover/detail/doc/doc.mjs +9 -1
- package/api/discover/discover.d.mts +11 -0
- package/api/discover/discover.doc.mjs +9 -7
- package/api/discover/discover.mjs +121 -19
- package/api/discover/discover.type.d.mts +20 -7
- package/api/discover/discover.type.mjs +17 -7
- package/api/discover/list/list.d.mts +4 -3
- package/api/discover/list/list.mjs +17 -10
- package/api/docs/_adapter.d.mts +63 -0
- package/api/docs/_adapter.mjs +312 -18
- package/api/docs/docs.doc.mjs +2 -1
- package/api/docs/docs.mjs +2 -1
- package/api/docs/docs.test.mjs +5 -2
- package/api/docs/integration-tree.test.mjs +22 -0
- package/api/docs/list/list.mjs +12 -2
- package/api/docs/reference-blocks.test.mjs +1 -3
- package/api/doctor/_adapter.d.mts +108 -0
- package/api/doctor/_adapter.mjs +223 -4
- package/api/doctor/doctor.d.mts +199 -0
- package/api/doctor/doctor.doc.mjs +3 -2
- package/api/doctor/doctor.mjs +530 -34
- package/api/doctor/doctor.test.mjs +180 -14
- package/api/doctor/release-checks.test.mjs +156 -0
- package/api/doctor/theme-checks.mjs +16 -3
- package/api/doctor/theme-checks.test.mjs +223 -7
- package/api/error.d.mts +10 -0
- package/api/error.mjs +25 -0
- package/api/gap-report/gap-report.d.mts +3 -0
- package/api/gap-report/gap-report.doc.mjs +11 -3
- package/api/gap-report/gap-report.mjs +152 -48
- package/api/gap-report/gap-report.test.mjs +233 -0
- package/api/gap-report/gap-report.type.d.mts +41 -0
- package/api/gap-report/gap-report.type.mjs +18 -0
- package/api/hook/_adapter.mjs +3 -11
- package/api/hook/hook.doc.mjs +4 -0
- package/api/hook/list/list.d.mts +1 -1
- package/api/init/_adapter.d.mts +22 -0
- package/api/init/_adapter.mjs +59 -0
- package/api/init/init.d.mts +7 -5
- package/api/init/init.doc.mjs +28 -7
- package/api/init/init.mjs +28 -4
- package/api/init/init.type.d.mts +48 -3
- package/api/init/init.type.mjs +37 -3
- package/api/init/run/run.d.mts +1 -1
- package/api/init/run/run.mjs +15 -4
- package/api/init/user/user.d.mts +14 -0
- package/api/init/user/user.mjs +87 -0
- package/api/init/user/user.test.mjs +232 -0
- package/api/integration/_adapter.d.mts +33 -0
- package/api/integration/_adapter.mjs +58 -0
- package/api/integration/authoring-checks.mjs +100 -5
- package/api/integration/authoring-checks.test.mjs +769 -0
- package/api/integration/authoring-checks.type.d.mts +134 -0
- package/api/integration/authoring-checks.type.mjs +60 -1
- package/api/integration/integrationCheck.doc.mjs +1 -1
- package/api/integration/integrationComponentConflicts.doc.mjs +11 -3
- package/api/integration/integrationDocConflicts.doc.mjs +22 -5
- package/api/integration/pack-check.mjs +303 -13
- package/api/integration/pack-check.test.mjs +371 -10
- package/api/integration/validate-integration-fixes.test.mjs +67 -0
- package/api/integration/validate-integration.d.mts +8 -0
- package/api/integration/validate-integration.mjs +55 -9
- package/api/integration/validate-integration.test.mjs +77 -8
- package/api/integration/validate-integration.type.d.mts +8 -0
- package/api/integration/validate-integration.type.mjs +3 -1
- package/api/integration/validate-unread-theme-folders.test.mjs +3 -2
- package/api/integration/validateIntegration.doc.mjs +4 -2
- package/api/search/_adapter.d.mts +11 -0
- package/api/search/_adapter.mjs +25 -0
- package/api/search/search.d.mts +73 -13
- package/api/search/search.doc.mjs +8 -3
- package/api/search/search.domain-priority.test.mjs +108 -18
- package/api/search/search.mjs +541 -52
- package/api/search/search.test.mjs +143 -1
- package/api/search/search.type.d.mts +14 -1
- package/api/search/search.type.mjs +6 -1
- package/api/swizzle/_adapter.mjs +2 -2
- package/api/swizzle/copy/copy.mjs +1 -1
- package/api/template/template-integration.test.mjs +1 -1
- package/api/theme/_adapter.d.mts +16 -0
- package/api/theme/_adapter.mjs +32 -5
- package/api/theme/build/build.d.mts +2 -1
- package/api/theme/build/build.mjs +70 -14
- package/api/theme/build/build.packed-old-core.test.mjs +20 -3
- package/api/theme/build/font-warning.mjs +5 -3
- package/api/theme/build/font-warning.test.mjs +2 -1
- package/api/theme/remove/remove.test.mjs +2 -2
- package/api/theme/targets/targets.mjs +3 -10
- package/api/theme/themeTargets.doc.mjs +4 -0
- package/api/theme/use/use.test.mjs +1 -1
- package/api/upgrade/_adapter.d.mts +40 -2
- package/api/upgrade/_adapter.mjs +118 -5
- package/api/upgrade/run/cli-behind-core.test.mjs +438 -0
- package/api/upgrade/run/run.mjs +35 -2
- package/api/upgrade/status/status.d.mts +21 -5
- package/api/upgrade/status/status.mjs +45 -8
- package/api/upgrade/upgrade.doc.mjs +6 -3
- package/api/upgrade/upgrade.mjs +5 -1
- package/api/upgrade/upgrade.type.d.mts +23 -0
- package/api/upgrade/upgrade.type.mjs +16 -1
- package/assets/codemods/__tests__/registry.test.mjs +1 -0
- package/assets/codemods/registry.mjs +1 -0
- package/assets/codemods/runner.mjs +7 -1
- package/assets/codemods/transforms/next/index.mjs +1 -11
- package/assets/codemods/transforms/v0.7.2/index.mjs +20 -0
- package/assets/discover/official-packages.json +367 -0
- package/assets/docs/author-a-theme.doc.mjs +2 -2
- package/assets/docs/browser-support.doc.mjs +1 -1
- package/assets/docs/getting-started.doc.mjs +23 -3
- package/assets/docs/styling-overview.doc.mjs +1 -1
- package/assets/docs/theme.doc.mjs +1 -1
- package/assets/docs/tree/add-a-component.doc.mjs +12 -2
- package/assets/docs/tree/add-a-theme.doc.mjs +13 -3
- package/assets/docs/tree/add-a-topic.doc.mjs +54 -9
- package/assets/docs/tree/agent-guidance.doc.mjs +19 -5
- package/assets/docs/tree/block-template.doc.mjs +6 -18
- package/assets/docs/tree/build-the-template.doc.mjs +1 -1
- package/assets/docs/tree/building-blocks.doc.mjs +4 -0
- package/assets/docs/tree/check-the-props.doc.mjs +8 -3
- package/assets/docs/tree/check-your-docs.doc.mjs +30 -13
- package/assets/docs/tree/checks.doc.mjs +17 -17
- package/assets/docs/tree/ci-and-containers.doc.mjs +88 -0
- package/assets/docs/tree/cli-command.doc.mjs +142 -0
- package/assets/docs/tree/cli.doc.mjs +6 -0
- package/assets/docs/tree/codemods.doc.mjs +17 -7
- package/assets/docs/tree/commands.doc.mjs +7 -1
- package/assets/docs/tree/component-family.doc.mjs +3 -5
- package/assets/docs/tree/component-imports.doc.mjs +13 -3
- package/assets/docs/tree/components.doc.mjs +7 -1
- package/assets/docs/tree/computer-agent-guide.doc.mjs +160 -0
- package/assets/docs/tree/computer-integrations.doc.mjs +93 -0
- package/assets/docs/tree/configuration.doc.mjs +7 -3
- package/assets/docs/tree/debug-and-gap-reports.doc.mjs +41 -22
- package/assets/docs/tree/define-the-theme.doc.mjs +6 -5
- package/assets/docs/tree/describe-the-component.doc.mjs +2 -2
- package/assets/docs/tree/docs.doc.mjs +9 -3
- package/assets/docs/tree/document-the-template.doc.mjs +1 -1
- package/assets/docs/tree/document-the-theme.doc.mjs +3 -3
- package/assets/docs/tree/export-template-assets.doc.mjs +1 -1
- package/assets/docs/tree/extend-or-replace.doc.mjs +19 -9
- package/assets/docs/tree/fonts-and-assets.doc.mjs +2 -2
- package/assets/docs/tree/generate-a-palette.doc.mjs +7 -5
- package/assets/docs/tree/global-integrations.doc.mjs +124 -0
- package/assets/docs/tree/global.doc.mjs +131 -0
- package/assets/docs/tree/grade-template-with-agent.doc.mjs +5 -5
- package/assets/docs/tree/install-once.doc.mjs +105 -0
- package/assets/docs/tree/integrations.doc.mjs +13 -1
- package/assets/docs/tree/layout-spacing.doc.mjs +2 -3
- package/assets/docs/tree/layout.doc.mjs +6 -6
- package/assets/docs/tree/links.doc.mjs +6 -5
- package/assets/docs/tree/migration-setup.doc.mjs +3 -2
- package/assets/docs/tree/migration-verification.doc.mjs +0 -1
- package/assets/docs/tree/migration.doc.mjs +0 -1
- package/assets/docs/tree/monorepos.doc.mjs +84 -0
- package/assets/docs/tree/package-and-test.doc.mjs +1 -1
- package/assets/docs/tree/page-template.doc.mjs +3 -7
- package/assets/docs/tree/problems.doc.mjs +205 -0
- package/assets/docs/tree/project-global-or-both.doc.mjs +131 -0
- package/assets/docs/tree/publishing.doc.mjs +6 -6
- package/assets/docs/tree/quick-start.doc.mjs +52 -26
- package/assets/docs/tree/reference.doc.mjs +192 -0
- package/assets/docs/tree/replace-a-core-component.doc.mjs +15 -7
- package/assets/docs/tree/replace-a-core-template.doc.mjs +9 -11
- package/assets/docs/tree/scaffold.doc.mjs +1 -1
- package/assets/docs/tree/sections-and-placement.doc.mjs +9 -11
- package/assets/docs/tree/see-it-in-an-app.doc.mjs +17 -5
- package/assets/docs/tree/short-and-findable.doc.mjs +9 -8
- package/assets/docs/tree/single-component.doc.mjs +14 -6
- package/assets/docs/tree/start-a-template.doc.mjs +18 -8
- package/assets/docs/tree/subcomponent.doc.mjs +6 -6
- package/assets/docs/tree/template-assets.doc.mjs +2 -2
- package/assets/docs/tree/template-doc-overview.doc.mjs +6 -17
- package/assets/docs/tree/template-fonts.doc.mjs +1 -1
- package/assets/docs/tree/template-icons.doc.mjs +1 -1
- package/assets/docs/tree/template-images-media.doc.mjs +1 -1
- package/assets/docs/tree/template-styles.doc.mjs +2 -2
- package/assets/docs/tree/templates.doc.mjs +7 -1
- package/assets/docs/tree/test-in-an-app.doc.mjs +7 -7
- package/assets/docs/tree/test-template-in-app.doc.mjs +5 -5
- package/assets/docs/tree/themes.doc.mjs +4 -0
- package/assets/docs/tree/tokens-and-setup.doc.mjs +19 -15
- package/assets/docs/tree/troubleshooting.doc.mjs +22 -14
- package/assets/docs/tree/uninstall.doc.mjs +109 -0
- package/assets/docs/tree/updates.doc.mjs +92 -0
- package/assets/docs/tree/upgrading.doc.mjs +6 -6
- package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +14 -2
- package/assets/docs/tree/verify-packed-template.doc.mjs +3 -3
- package/assets/docs/tree/versioning.doc.mjs +9 -9
- package/assets/docs/tree/who-answers.doc.mjs +119 -0
- package/assets/docs/tree/write-the-template-file.doc.mjs +5 -5
- package/assets/docs/working-with-ai.doc.mjs +23 -9
- package/authoring/codemod/codemod.doc.mjs +7 -3
- package/authoring/config/config.doc.mjs +9 -6
- package/authoring/config/type.ts +4 -2
- package/authoring/debug/parse.d.mts +5 -5
- package/authoring/discover/discover.doc.mjs +7 -1
- package/authoring/doctypes/_schema.d.mts +8 -3
- package/authoring/doctypes/_schema.mjs +1 -0
- package/authoring/doctypes/base/graph-fields.doc.mjs +6 -4
- package/authoring/doctypes/command/command.doc.mjs +20 -12
- package/authoring/doctypes/command/type.ts +14 -0
- package/authoring/doctypes/component/component.doc.mjs +29 -26
- package/authoring/doctypes/component/type.ts +15 -5
- package/authoring/doctypes/enum/enum.doc.mjs +7 -4
- package/authoring/doctypes/function/function.doc.mjs +9 -8
- package/authoring/doctypes/hook/hook.doc.mjs +5 -4
- package/authoring/doctypes/hook/type.ts +4 -0
- package/authoring/doctypes/namespace/namespace.doc.mjs +7 -6
- package/authoring/doctypes/reference/reference.doc.mjs +12 -11
- package/authoring/doctypes/schema/schema.doc.mjs +9 -9
- package/authoring/doctypes/template/template.doc.mjs +2 -2
- package/authoring/doctypes/theme/theme.doc.mjs +2 -2
- package/authoring/gap-report/gap-report.doc.mjs +2 -2
- package/authoring/identity/identity.doc.mjs +3 -3
- package/authoring/index.d.ts +1 -0
- package/authoring/integration/integration.doc.mjs +22 -5
- package/authoring/integration/parse.test.mjs +11 -0
- package/authoring/integration/schema.d.mts +14 -3
- package/authoring/integration/schema.mjs +33 -2
- package/authoring/integration/type.ts +8 -0
- package/clients/cli/bin/astryx.mjs +20 -3
- package/clients/cli/cli-command.test.mjs +166 -0
- package/clients/cli/commands/blog.doc.mjs +1 -0
- package/clients/cli/commands/build-theme.batch-report.test.mjs +14 -2
- package/clients/cli/commands/build-theme.font-warning.test.mjs +3 -3
- package/clients/cli/commands/build-theme.mjs +25 -12
- package/clients/cli/commands/build.doc.mjs +1 -0
- package/clients/cli/commands/build.exit-codes-doc.test.mjs +4 -0
- package/clients/cli/commands/cli-postinstall.test.mjs +49 -1
- package/clients/cli/commands/component.doc.mjs +1 -0
- package/clients/cli/commands/discover.broken-integration.test.mjs +11 -7
- package/clients/cli/commands/discover.doc.mjs +9 -1
- package/clients/cli/commands/discover.mjs +144 -93
- package/clients/cli/commands/discover.no-source.test.mjs +448 -33
- package/clients/cli/commands/discover.sources.test.mjs +20 -1
- package/clients/cli/commands/docs.doc.mjs +1 -0
- package/clients/cli/commands/docs.mjs +49 -19
- package/clients/cli/commands/docs.test.mjs +2 -2
- package/clients/cli/commands/doctor-integration-components.doc.mjs +7 -3
- package/clients/cli/commands/doctor-integration-docs.doc.mjs +20 -5
- package/clients/cli/commands/doctor-integration-templates.doc.mjs +1 -0
- package/clients/cli/commands/doctor-integration-validate.doc.mjs +13 -2
- package/clients/cli/commands/doctor-integration.test.mjs +52 -4
- package/clients/cli/commands/doctor.doc.mjs +12 -2
- package/clients/cli/commands/doctor.mjs +102 -7
- package/clients/cli/commands/doctor.test.mjs +10 -4
- package/clients/cli/commands/gap-report.doc.mjs +15 -2
- package/clients/cli/commands/gap-report.mjs +24 -2
- package/clients/cli/commands/gap-report.test.mjs +79 -0
- package/clients/cli/commands/hook.doc.mjs +1 -0
- package/clients/cli/commands/init.behavior.test.mjs +5 -0
- package/clients/cli/commands/init.doc.mjs +29 -3
- package/clients/cli/commands/integration-add.doc.mjs +7 -0
- package/clients/cli/commands/integration-authoring.test.mjs +49 -3
- package/clients/cli/commands/integration-check.doc.mjs +10 -2
- package/clients/cli/commands/integration-check.test.mjs +175 -1
- package/clients/cli/commands/integration-pack.doc.mjs +8 -1
- package/clients/cli/commands/integration-verify.doc.mjs +8 -1
- package/clients/cli/commands/integration.mjs +15 -9
- package/clients/cli/commands/json-contract.test.mjs +11 -2
- package/clients/cli/commands/manifest.doc.mjs +1 -0
- package/clients/cli/commands/outside-project.test.mjs +774 -0
- package/clients/cli/commands/search.doc.mjs +1 -0
- package/clients/cli/commands/search.mjs +16 -11
- package/clients/cli/commands/search.test.mjs +429 -296
- package/clients/cli/commands/setup-nudge.test.mjs +102 -2
- package/clients/cli/commands/swizzle.doc.mjs +7 -0
- package/clients/cli/commands/swizzle.mjs +5 -3
- package/clients/cli/commands/swizzle.routing.test.mjs +19 -2
- package/clients/cli/commands/template.doc.mjs +1 -0
- package/clients/cli/commands/theme-add-lifecycle.test.mjs +3 -3
- package/clients/cli/commands/theme-add.doc.mjs +8 -1
- package/clients/cli/commands/theme-build.doc.mjs +1 -0
- package/clients/cli/commands/theme-eject.doc.mjs +1 -0
- package/clients/cli/commands/theme-list.behavior.test.mjs +6 -0
- package/clients/cli/commands/theme-list.doc.mjs +1 -0
- package/clients/cli/commands/theme-palette-generate.doc.mjs +1 -0
- package/clients/cli/commands/theme-remove.doc.mjs +7 -0
- package/clients/cli/commands/theme-targets.doc.mjs +1 -0
- package/clients/cli/commands/theme-template.doc.mjs +1 -0
- package/clients/cli/commands/theme-use.doc.mjs +7 -0
- package/clients/cli/commands/upgrade.config-ordering.test.mjs +2 -1
- package/clients/cli/commands/upgrade.doc.mjs +22 -1
- package/clients/cli/commands/upgrade.file-protection.test.mjs +3 -2
- package/clients/cli/commands/upgrade.hook-output.test.mjs +2 -1
- package/clients/cli/commands/upgrade.older-cli.test.mjs +160 -0
- package/clients/cli/index.mjs +111 -16
- package/clients/cli/lib/cli-error.mjs +4 -1
- package/clients/cli/lib/component-format.test.mjs +1 -1
- package/clients/cli/lib/define-command.mjs +2 -2
- package/clients/cli/lib/json-shim.mjs +3 -1
- package/clients/cli/lib/manifest.d.ts +9 -0
- package/clients/cli/lib/manifest.mjs +17 -1
- package/clients/cli/lib/manifest.test.mjs +25 -0
- package/foundation/agent-docs/agent-doc-state.d.mts +35 -6
- package/foundation/agent-docs/agent-doc-state.mjs +66 -6
- package/foundation/agent-docs/agent-docs.d.mts +4 -3
- package/foundation/agent-docs/agent-docs.mjs +11 -9
- package/foundation/agent-docs/computer-agent-text.d.mts +133 -0
- package/foundation/agent-docs/computer-agent-text.mjs +623 -0
- package/foundation/agent-docs/computer-agent-text.test.mjs +602 -0
- package/foundation/config/project.d.mts +35 -3
- package/foundation/config/project.mjs +145 -8
- package/foundation/config/project.test.mjs +66 -0
- package/foundation/config/theme-state.mjs +5 -4
- package/foundation/discovery/authoring-self-docs.mjs +1 -1
- package/foundation/discovery/cli-self-docs.mjs +20 -3
- package/foundation/discovery/cli-self-docs.test.mjs +3 -2
- package/foundation/discovery/component-replacement.mjs +2 -1
- package/foundation/discovery/copied-passages.d.mts +216 -0
- package/foundation/discovery/copied-passages.mjs +720 -0
- package/foundation/discovery/copied-passages.test.mjs +124 -0
- package/foundation/discovery/doc-consistency.d.mts +34 -0
- package/foundation/discovery/doc-consistency.mjs +513 -0
- package/foundation/discovery/doc-consistency.test.mjs +347 -0
- package/foundation/discovery/doc-fluff.d.mts +112 -0
- package/foundation/discovery/doc-fluff.mjs +328 -0
- package/foundation/discovery/doc-fluff.test.mjs +142 -0
- package/foundation/discovery/doc-types.d.mts +1 -1
- package/foundation/discovery/doc-types.mjs +15 -8
- package/foundation/discovery/doc-types.test.mjs +94 -2
- package/foundation/discovery/docs-discovery.d.mts +7 -0
- package/foundation/discovery/docs-discovery.mjs +26 -2
- package/foundation/discovery/project-typescript.d.mts +11 -2
- package/foundation/discovery/project-typescript.mjs +32 -4
- package/foundation/discovery/prop-drift.d.mts +26 -7
- package/foundation/discovery/prop-drift.mjs +173 -8
- package/foundation/discovery/prop-drift.test.mjs +120 -2
- package/foundation/discovery/runner-allowlist.d.mts +40 -0
- package/foundation/discovery/runner-allowlist.mjs +53 -0
- package/foundation/discovery/stray-pointers.d.mts +52 -0
- package/foundation/discovery/stray-pointers.mjs +293 -0
- package/foundation/discovery/stray-pointers.test.mjs +86 -0
- package/foundation/discovery/template-needs.mjs +5 -2
- package/foundation/discovery/theme-imports.mjs +8 -4
- package/foundation/discovery/theme-imports.test.mjs +1 -1
- package/foundation/discovery/type-text.mjs +1 -1
- package/foundation/discovery/type-text.test.mjs +1 -1
- package/foundation/doc-compiler/doc-loads.test.mjs +42 -2
- package/foundation/doc-compiler/inputs.mjs +4 -1
- package/foundation/doc-compiler/links.d.mts +32 -0
- package/foundation/doc-compiler/links.mjs +163 -26
- package/foundation/doc-compiler/links.test.mjs +97 -4
- package/foundation/doc-compiler/read.d.mts +1 -1
- package/foundation/doc-compiler/tree.mjs +30 -1
- package/foundation/doc-compiler/tree.test.mjs +8 -1
- package/foundation/env/cli-command.d.mts +83 -0
- package/foundation/env/cli-command.mjs +152 -0
- package/foundation/env/cli-command.test.mjs +129 -0
- package/foundation/env/node-version.test.mjs +15 -3
- package/foundation/env/package-manager.d.mts +93 -9
- package/foundation/env/package-manager.global.test.mjs +66 -0
- package/foundation/env/package-manager.mjs +184 -13
- package/foundation/env/package-manager.test.mjs +341 -15
- package/foundation/env/project-scope.d.mts +9 -0
- package/foundation/env/project-scope.mjs +33 -0
- package/foundation/env/search-path.d.mts +42 -0
- package/foundation/env/search-path.mjs +205 -0
- package/foundation/env/search-path.test.mjs +122 -0
- package/foundation/env/user-dirs.d.mts +39 -0
- package/foundation/env/user-dirs.mjs +93 -0
- package/foundation/env/user-dirs.test.mjs +72 -0
- package/foundation/env/user-settings.d.mts +46 -0
- package/foundation/env/user-settings.mjs +106 -0
- package/foundation/env/user-settings.test.mjs +64 -0
- package/foundation/fs/file-protection.mjs +15 -1
- package/foundation/fs/module-loader.d.mts +2 -1
- package/foundation/fs/module-loader.mjs +60 -4
- package/foundation/fs/module-loader.stdout.test.mjs +3 -2
- package/foundation/fs/module-loader.test.mjs +194 -0
- package/foundation/fs/path-compare.d.mts +33 -0
- package/foundation/fs/path-compare.mjs +73 -0
- package/foundation/fs/paths.d.mts +57 -1
- package/foundation/fs/paths.mjs +131 -3
- package/foundation/fs/paths.test.mjs +10 -1
- package/foundation/integrations/computer-integrations.d.mts +78 -0
- package/foundation/integrations/computer-integrations.mjs +316 -0
- package/foundation/integrations/computer-integrations.test.mjs +292 -0
- package/foundation/integrations/contribution-inventory.d.mts +11 -0
- package/foundation/integrations/contribution-inventory.mjs +50 -2
- package/foundation/integrations/integration-warnings.mjs +3 -2
- package/foundation/integrations/integration-warnings.test.mjs +8 -9
- package/foundation/integrations/integrations.d.mts +25 -1
- package/foundation/integrations/integrations.mjs +46 -3
- package/foundation/integrations/issue.ts +6 -0
- package/foundation/integrations/validate-contributions.d.mts +2 -0
- package/foundation/integrations/validate-contributions.mjs +41 -1
- package/foundation/release/agent-text-worker.d.mts +4 -0
- package/foundation/release/agent-text-worker.mjs +52 -0
- package/foundation/release/cache.d.mts +310 -0
- package/foundation/release/cache.mjs +1216 -0
- package/foundation/release/cache.test.mjs +920 -0
- package/foundation/release/choose.d.mts +207 -0
- package/foundation/release/choose.mjs +677 -0
- package/foundation/release/choose.test.mjs +427 -0
- package/foundation/release/core-worker.d.mts +4 -0
- package/foundation/release/core-worker.mjs +38 -0
- package/foundation/release/global-state.d.mts +259 -0
- package/foundation/release/global-state.mjs +472 -0
- package/foundation/release/global-state.test.mjs +381 -0
- package/foundation/release/handoff.d.mts +60 -0
- package/foundation/release/handoff.e2e.test.mjs +278 -0
- package/foundation/release/handoff.mjs +357 -0
- package/foundation/release/lock-lease.d.mts +23 -0
- package/foundation/release/lock-lease.mjs +80 -0
- package/foundation/release/notices.d.mts +253 -0
- package/foundation/release/notices.mjs +596 -0
- package/foundation/release/notices.test.mjs +565 -0
- package/foundation/release/npm-guard.d.mts +4 -0
- package/foundation/release/npm-guard.mjs +126 -0
- package/foundation/release/project.d.mts +141 -0
- package/foundation/release/project.mjs +466 -0
- package/foundation/release/project.test.mjs +288 -0
- package/foundation/release/refresh-worker.d.mts +4 -0
- package/foundation/release/refresh-worker.mjs +27 -0
- package/foundation/release/run-context.d.mts +47 -0
- package/foundation/release/run-context.mjs +149 -0
- package/foundation/release/update-notice-env.d.mts +28 -0
- package/foundation/release/update-notice-env.mjs +39 -0
- package/foundation/response/base.d.ts +26 -3
- package/foundation/response/error-codes.d.mts +3 -1
- package/foundation/response/error-codes.doc.mjs +12 -0
- package/foundation/response/error-codes.mjs +17 -0
- package/foundation/response/error-codes.test.mjs +2 -0
- package/foundation/response/json-contract.test.mjs +7 -2
- package/foundation/response/json.mjs +4 -1
- package/foundation/response/response-types.doc.mjs +17 -11
- package/foundation/response/response-types.doc.test.mjs +46 -0
- package/foundation/response/response.doc.mjs +3 -3
- package/foundation/xle/browser-imports.test.mjs +74 -0
- package/package.json +11 -11
- package/scripts/postinstall.mjs +24 -5
- /package/assets/codemods/transforms/{next → v0.7.2}/__tests__/migrate-list-edge-compensation-to-edge.test.mjs +0 -0
- /package/assets/codemods/transforms/{next → v0.7.2}/migrate-list-edge-compensation-to-edge.mjs +0 -0
|
@@ -29,6 +29,8 @@
|
|
|
29
29
|
* @property {string} target the target as written
|
|
30
30
|
* @property {string} message
|
|
31
31
|
* @property {string} [section] the key of the section the link sits in
|
|
32
|
+
* @property {string} [field] the field the link sits in, outside any section:
|
|
33
|
+
* `description`, or a path such as `props[2].description`
|
|
32
34
|
* @property {true} [include] the problem is in a `reference` block, which
|
|
33
35
|
* includes content rather than linking to it: a reader loses that content,
|
|
34
36
|
* so the authoring check fails on it
|
|
@@ -55,6 +57,31 @@ export function parseLinkTarget(target: unknown): LinkTarget | {
|
|
|
55
57
|
* @returns {string}
|
|
56
58
|
*/
|
|
57
59
|
export function unlinkText(text: string): string;
|
|
60
|
+
/**
|
|
61
|
+
* Every text field of a doc object, in authored order, by the same rules
|
|
62
|
+
* {@link linkFields} resolves links by: the strings a reader reads, never a
|
|
63
|
+
* name, type, default, or code.
|
|
64
|
+
* @param {unknown} doc
|
|
65
|
+
* @returns {{field: string, text: string}[]}
|
|
66
|
+
*/
|
|
67
|
+
export function textFields(doc: unknown): {
|
|
68
|
+
field: string;
|
|
69
|
+
text: string;
|
|
70
|
+
}[];
|
|
71
|
+
/**
|
|
72
|
+
* Resolve every inline link in the text fields of a doc object, such as a
|
|
73
|
+
* component doc or a topic's summary fields (spec:AST-047 FR9): its
|
|
74
|
+
* description, its usage and best practices, each prop's and example's
|
|
75
|
+
* description, at any depth. Code and code ticks show link syntax as written.
|
|
76
|
+
* @template T
|
|
77
|
+
* @param {T} doc
|
|
78
|
+
* @param {LinkResolver} resolve
|
|
79
|
+
* @returns {Promise<{doc: T, problems: LinkProblem[]}>}
|
|
80
|
+
*/
|
|
81
|
+
export function linkFields<T>(doc: T, resolve: LinkResolver): Promise<{
|
|
82
|
+
doc: T;
|
|
83
|
+
problems: LinkProblem[];
|
|
84
|
+
}>;
|
|
58
85
|
/**
|
|
59
86
|
* Resolve every link in a list of content blocks, in order.
|
|
60
87
|
* @param {any[]} blocks
|
|
@@ -148,6 +175,11 @@ export type LinkProblem = {
|
|
|
148
175
|
* the key of the section the link sits in
|
|
149
176
|
*/
|
|
150
177
|
section?: string | undefined;
|
|
178
|
+
/**
|
|
179
|
+
* the field the link sits in, outside any section:
|
|
180
|
+
* `description`, or a path such as `props[2].description`
|
|
181
|
+
*/
|
|
182
|
+
field?: string | undefined;
|
|
151
183
|
/**
|
|
152
184
|
* the problem is in a `reference` block, which
|
|
153
185
|
* includes content rather than linking to it: a reader loses that content,
|
|
@@ -65,6 +65,8 @@ const CODE_SPAN = /(`[^`]*`)/;
|
|
|
65
65
|
* @property {string} target the target as written
|
|
66
66
|
* @property {string} message
|
|
67
67
|
* @property {string} [section] the key of the section the link sits in
|
|
68
|
+
* @property {string} [field] the field the link sits in, outside any section:
|
|
69
|
+
* `description`, or a path such as `props[2].description`
|
|
68
70
|
* @property {true} [include] the problem is in a `reference` block, which
|
|
69
71
|
* includes content rather than linking to it: a reader loses that content,
|
|
70
72
|
* so the authoring check fails on it
|
|
@@ -91,7 +93,11 @@ export function parseLinkTarget(target) {
|
|
|
91
93
|
};
|
|
92
94
|
}
|
|
93
95
|
const parts = target.trim().split(':');
|
|
94
|
-
if (
|
|
96
|
+
if (
|
|
97
|
+
parts.length < 2 ||
|
|
98
|
+
parts.length > 3 ||
|
|
99
|
+
parts.some(p => p.trim() === '')
|
|
100
|
+
) {
|
|
95
101
|
return {error: `"${target}" is not \`[<provider>:]<kind>:<name>\``};
|
|
96
102
|
}
|
|
97
103
|
const provider = parts.length === 3 ? parts[0].trim() : null;
|
|
@@ -127,6 +133,159 @@ export function unlinkText(text) {
|
|
|
127
133
|
.join('');
|
|
128
134
|
}
|
|
129
135
|
|
|
136
|
+
/**
|
|
137
|
+
* Text with each inline link replaced by the command that opens its doc. A
|
|
138
|
+
* link written inside code ticks is shown as written: it documents the syntax,
|
|
139
|
+
* it does not link. A link that names no doc prints as written: text that was
|
|
140
|
+
* never meant as a link reads the way it did, and doctor names the problem.
|
|
141
|
+
* @param {unknown} text
|
|
142
|
+
* @param {(target: string) => Promise<DocLink | null>} find
|
|
143
|
+
* @returns {Promise<any>}
|
|
144
|
+
*/
|
|
145
|
+
async function resolveInline(text, find) {
|
|
146
|
+
if (typeof text !== 'string' || !text.includes('{@link')) return text;
|
|
147
|
+
let out = '';
|
|
148
|
+
for (const part of text.split(CODE_SPAN)) {
|
|
149
|
+
if (part.startsWith('`')) {
|
|
150
|
+
out += part;
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
let last = 0;
|
|
154
|
+
for (const match of part.matchAll(INLINE_LINK)) {
|
|
155
|
+
const link = await find(match[1]);
|
|
156
|
+
const at = /** @type {number} */ (match.index);
|
|
157
|
+
out += part.slice(last, at);
|
|
158
|
+
out += link ? `\`${link.command}\`` : match[0];
|
|
159
|
+
last = at + match[0].length;
|
|
160
|
+
}
|
|
161
|
+
out += part.slice(last);
|
|
162
|
+
}
|
|
163
|
+
return out;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* The fields of a doc that hold text a reader reads, where a link resolves:
|
|
168
|
+
* a description or summary, an example's label, and each value of a
|
|
169
|
+
* `propDescriptions` overlay. Every other string is a name, a type, a
|
|
170
|
+
* default, or code, and is shown as written.
|
|
171
|
+
*/
|
|
172
|
+
const TEXT_FIELDS = new Set(['description', 'summary', 'label']);
|
|
173
|
+
|
|
174
|
+
/** Fields that hold code or data, never text: nothing below them links. */
|
|
175
|
+
const CODE_FIELDS = new Set([
|
|
176
|
+
'code',
|
|
177
|
+
'playground',
|
|
178
|
+
'slotElements',
|
|
179
|
+
'registry',
|
|
180
|
+
'keywords',
|
|
181
|
+
]);
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Every text field of a doc object, in authored order, by the same rules
|
|
185
|
+
* {@link linkFields} resolves links by: the strings a reader reads, never a
|
|
186
|
+
* name, type, default, or code.
|
|
187
|
+
* @param {unknown} doc
|
|
188
|
+
* @returns {{field: string, text: string}[]}
|
|
189
|
+
*/
|
|
190
|
+
export function textFields(doc) {
|
|
191
|
+
/** @type {{field: string, text: string}[]} */
|
|
192
|
+
const out = [];
|
|
193
|
+
/**
|
|
194
|
+
* @param {unknown} value
|
|
195
|
+
* @param {string} at
|
|
196
|
+
* @param {boolean} text
|
|
197
|
+
*/
|
|
198
|
+
const walk = (value, at, text) => {
|
|
199
|
+
if (typeof value === 'string') {
|
|
200
|
+
if (text) out.push({field: at, text: value});
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
if (Array.isArray(value)) {
|
|
204
|
+
value.forEach((item, i) => walk(item, `${at}[${i}]`, false));
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
if (value == null || typeof value !== 'object') return;
|
|
208
|
+
for (const [key, field] of Object.entries(value)) {
|
|
209
|
+
const path = at === '' ? key : `${at}.${key}`;
|
|
210
|
+
if (CODE_FIELDS.has(key)) continue;
|
|
211
|
+
if (key === 'propDescriptions' && field && typeof field === 'object') {
|
|
212
|
+
for (const [prop, description] of Object.entries(field)) {
|
|
213
|
+
walk(description, `${path}.${prop}`, true);
|
|
214
|
+
}
|
|
215
|
+
} else {
|
|
216
|
+
walk(field, path, TEXT_FIELDS.has(key));
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
walk(doc, '', false);
|
|
221
|
+
return out;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Resolve every inline link in the text fields of a doc object, such as a
|
|
226
|
+
* component doc or a topic's summary fields (spec:AST-047 FR9): its
|
|
227
|
+
* description, its usage and best practices, each prop's and example's
|
|
228
|
+
* description, at any depth. Code and code ticks show link syntax as written.
|
|
229
|
+
* @template T
|
|
230
|
+
* @param {T} doc
|
|
231
|
+
* @param {LinkResolver} resolve
|
|
232
|
+
* @returns {Promise<{doc: T, problems: LinkProblem[]}>}
|
|
233
|
+
*/
|
|
234
|
+
export async function linkFields(doc, resolve) {
|
|
235
|
+
/** @type {LinkProblem[]} */
|
|
236
|
+
const problems = [];
|
|
237
|
+
/**
|
|
238
|
+
* @param {unknown} value
|
|
239
|
+
* @param {string} at the field path, e.g. `usage.bestPractices[0].description`
|
|
240
|
+
* @param {boolean} text whether a string here is text
|
|
241
|
+
* @returns {Promise<any>}
|
|
242
|
+
*/
|
|
243
|
+
const walk = async (value, at, text) => {
|
|
244
|
+
if (typeof value === 'string') {
|
|
245
|
+
if (!text) return value;
|
|
246
|
+
return resolveInline(value, async target => {
|
|
247
|
+
const found = await resolve(target);
|
|
248
|
+
if ('problem' in found) {
|
|
249
|
+
problems.push({target, message: found.problem, field: at});
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
252
|
+
return found;
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
if (Array.isArray(value)) {
|
|
256
|
+
const out = [];
|
|
257
|
+
for (let i = 0; i < value.length; i++) {
|
|
258
|
+
out.push(await walk(value[i], `${at}[${i}]`, false));
|
|
259
|
+
}
|
|
260
|
+
return out;
|
|
261
|
+
}
|
|
262
|
+
if (value == null || typeof value !== 'object') return value;
|
|
263
|
+
/** @type {Record<string, unknown>} */
|
|
264
|
+
const out = {};
|
|
265
|
+
for (const [key, field] of Object.entries(value)) {
|
|
266
|
+
const path = at === '' ? key : `${at}.${key}`;
|
|
267
|
+
if (CODE_FIELDS.has(key)) {
|
|
268
|
+
out[key] = field;
|
|
269
|
+
} else if (
|
|
270
|
+
key === 'propDescriptions' &&
|
|
271
|
+
field &&
|
|
272
|
+
typeof field === 'object'
|
|
273
|
+
) {
|
|
274
|
+
/** @type {Record<string, unknown>} */
|
|
275
|
+
const described = {};
|
|
276
|
+
for (const [prop, description] of Object.entries(field)) {
|
|
277
|
+
described[prop] = await walk(description, `${path}.${prop}`, true);
|
|
278
|
+
}
|
|
279
|
+
out[key] = described;
|
|
280
|
+
} else {
|
|
281
|
+
out[key] = await walk(field, path, TEXT_FIELDS.has(key));
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return out;
|
|
285
|
+
};
|
|
286
|
+
return {doc: await walk(doc, '', false), problems};
|
|
287
|
+
}
|
|
288
|
+
|
|
130
289
|
/**
|
|
131
290
|
* Resolve every link in a list of content blocks, in order.
|
|
132
291
|
* @param {any[]} blocks
|
|
@@ -156,30 +315,7 @@ export async function linkBlocks(blocks, resolve, at = {}, include) {
|
|
|
156
315
|
* @param {unknown} text
|
|
157
316
|
* @returns {Promise<any>}
|
|
158
317
|
*/
|
|
159
|
-
const linkText =
|
|
160
|
-
if (typeof text !== 'string' || !text.includes('{@link')) return text;
|
|
161
|
-
let out = '';
|
|
162
|
-
// A link written inside code ticks is shown as written: it documents the
|
|
163
|
-
// syntax, it does not link.
|
|
164
|
-
for (const part of text.split(CODE_SPAN)) {
|
|
165
|
-
if (part.startsWith('`')) {
|
|
166
|
-
out += part;
|
|
167
|
-
continue;
|
|
168
|
-
}
|
|
169
|
-
let last = 0;
|
|
170
|
-
for (const match of part.matchAll(INLINE_LINK)) {
|
|
171
|
-
const link = await find(match[1]);
|
|
172
|
-
const at = /** @type {number} */ (match.index);
|
|
173
|
-
out += part.slice(last, at);
|
|
174
|
-
// A link that names no doc prints as written: text that was never
|
|
175
|
-
// meant as a link reads the way it did, and doctor names the problem.
|
|
176
|
-
out += link ? `\`${link.command}\`` : match[0];
|
|
177
|
-
last = at + match[0].length;
|
|
178
|
-
}
|
|
179
|
-
out += part.slice(last);
|
|
180
|
-
}
|
|
181
|
-
return out;
|
|
182
|
-
};
|
|
318
|
+
const linkText = text => resolveInline(text, find);
|
|
183
319
|
/**
|
|
184
320
|
* @param {unknown[]} values
|
|
185
321
|
* @returns {Promise<any[]>}
|
|
@@ -251,7 +387,8 @@ export async function linkBlocks(blocks, resolve, at = {}, include) {
|
|
|
251
387
|
}
|
|
252
388
|
if (Array.isArray(step.references)) {
|
|
253
389
|
const links = [];
|
|
254
|
-
for (const target of step.references)
|
|
390
|
+
for (const target of step.references)
|
|
391
|
+
links.push(await find(target));
|
|
255
392
|
linked.links = links;
|
|
256
393
|
}
|
|
257
394
|
steps.push(linked);
|
|
@@ -8,8 +8,10 @@
|
|
|
8
8
|
import {describe, expect, it} from 'vitest';
|
|
9
9
|
import {
|
|
10
10
|
linkBlocks,
|
|
11
|
+
linkFields,
|
|
11
12
|
linkSections,
|
|
12
13
|
parseLinkTarget,
|
|
14
|
+
textFields,
|
|
13
15
|
unlinkText,
|
|
14
16
|
} from './links.mjs';
|
|
15
17
|
|
|
@@ -58,14 +60,20 @@ describe('linkBlocks', () => {
|
|
|
58
60
|
const {content, problems} = await linkBlocks(
|
|
59
61
|
[
|
|
60
62
|
{type: 'prose', text: 'Check it with {@link command:doctor}.'},
|
|
61
|
-
{
|
|
63
|
+
{
|
|
64
|
+
type: 'list',
|
|
65
|
+
style: 'unordered',
|
|
66
|
+
items: ['See {@link @acme/kit:generic:setup}'],
|
|
67
|
+
},
|
|
62
68
|
{type: 'table', headers: ['Doc'], rows: [['{@link command:doctor}']]},
|
|
63
69
|
{type: 'code', lang: 'js', code: '{@link command:doctor}'},
|
|
64
70
|
],
|
|
65
71
|
resolve,
|
|
66
72
|
);
|
|
67
73
|
expect(problems).toEqual([]);
|
|
68
|
-
expect(content[0].text).toBe(
|
|
74
|
+
expect(content[0].text).toBe(
|
|
75
|
+
'Check it with `astryx docs cli/commands/doctor`.',
|
|
76
|
+
);
|
|
69
77
|
expect(content[1].items).toEqual(['See `astryx docs acme/setup`']);
|
|
70
78
|
expect(content[2].rows).toEqual([['`astryx docs cli/commands/doctor`']]);
|
|
71
79
|
// Code is an example: it is shown as written.
|
|
@@ -74,7 +82,12 @@ describe('linkBlocks', () => {
|
|
|
74
82
|
|
|
75
83
|
it('shows a link written in code ticks as written', async () => {
|
|
76
84
|
const {content, problems} = await linkBlocks(
|
|
77
|
-
[
|
|
85
|
+
[
|
|
86
|
+
{
|
|
87
|
+
type: 'prose',
|
|
88
|
+
text: 'Write `{@link <target>}` to link; {@link command:doctor} checks it.',
|
|
89
|
+
},
|
|
90
|
+
],
|
|
78
91
|
resolve,
|
|
79
92
|
);
|
|
80
93
|
expect(problems).toEqual([]);
|
|
@@ -172,7 +185,10 @@ describe('linkBlocks', () => {
|
|
|
172
185
|
},
|
|
173
186
|
],
|
|
174
187
|
resolve,
|
|
175
|
-
).then(({sections, problems}) => ({
|
|
188
|
+
).then(({sections, problems}) => ({
|
|
189
|
+
content: sections[0].content,
|
|
190
|
+
problems,
|
|
191
|
+
}));
|
|
176
192
|
expect(content[0].text).toBe('See {@link command:nope}.');
|
|
177
193
|
expect(content[1].link).toBeNull();
|
|
178
194
|
expect(problems.map(p => [p.section, p.target])).toEqual([
|
|
@@ -190,3 +206,80 @@ describe('unlinkText', () => {
|
|
|
190
206
|
);
|
|
191
207
|
});
|
|
192
208
|
});
|
|
209
|
+
|
|
210
|
+
describe('linkFields', () => {
|
|
211
|
+
/** A component doc with a link in every kind of text field, and in code. */
|
|
212
|
+
const DOC = {
|
|
213
|
+
name: 'AcmeButton',
|
|
214
|
+
description: 'Run {@link command:doctor} first.',
|
|
215
|
+
usage: {
|
|
216
|
+
description: 'Set it up: {@link @acme/kit:generic:setup}.',
|
|
217
|
+
bestPractices: [
|
|
218
|
+
{guidance: true, description: 'Check with {@link command:doctor}.'},
|
|
219
|
+
],
|
|
220
|
+
},
|
|
221
|
+
props: [
|
|
222
|
+
{
|
|
223
|
+
name: 'tone',
|
|
224
|
+
type: '{@link command:doctor}',
|
|
225
|
+
default: "'{@link command:doctor}'",
|
|
226
|
+
description: 'Like `{@link command:doctor}`, or {@link generic:nope}.',
|
|
227
|
+
},
|
|
228
|
+
],
|
|
229
|
+
propDescriptions: {tone: 'See {@link command:doctor}.'},
|
|
230
|
+
examples: [
|
|
231
|
+
{label: 'From {@link command:doctor}', code: '{@link command:doctor}'},
|
|
232
|
+
],
|
|
233
|
+
playground: {defaults: {label: '{@link command:doctor}'}},
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
it('resolves each text field and leaves names, types, defaults, and code as written', async () => {
|
|
237
|
+
const {doc, problems} = await linkFields(DOC, resolve);
|
|
238
|
+
expect(doc).toEqual({
|
|
239
|
+
...DOC,
|
|
240
|
+
description: 'Run `astryx docs cli/commands/doctor` first.',
|
|
241
|
+
usage: {
|
|
242
|
+
description: 'Set it up: `astryx docs acme/setup`.',
|
|
243
|
+
bestPractices: [
|
|
244
|
+
{
|
|
245
|
+
guidance: true,
|
|
246
|
+
description: 'Check with `astryx docs cli/commands/doctor`.',
|
|
247
|
+
},
|
|
248
|
+
],
|
|
249
|
+
},
|
|
250
|
+
props: [
|
|
251
|
+
{
|
|
252
|
+
...DOC.props[0],
|
|
253
|
+
description:
|
|
254
|
+
'Like `{@link command:doctor}`, or {@link generic:nope}.',
|
|
255
|
+
},
|
|
256
|
+
],
|
|
257
|
+
propDescriptions: {tone: 'See `astryx docs cli/commands/doctor`.'},
|
|
258
|
+
examples: [
|
|
259
|
+
{
|
|
260
|
+
label: 'From `astryx docs cli/commands/doctor`',
|
|
261
|
+
code: '{@link command:doctor}',
|
|
262
|
+
},
|
|
263
|
+
],
|
|
264
|
+
});
|
|
265
|
+
expect(problems).toEqual([
|
|
266
|
+
{
|
|
267
|
+
target: 'generic:nope',
|
|
268
|
+
message: expect.any(String),
|
|
269
|
+
field: 'props[0].description',
|
|
270
|
+
},
|
|
271
|
+
]);
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
it('names the same text fields textFields reads', async () => {
|
|
275
|
+
const {problems} = await linkFields(DOC, async target => ({
|
|
276
|
+
problem: `no ${target}`,
|
|
277
|
+
}));
|
|
278
|
+
const fields = textFields(DOC)
|
|
279
|
+
.filter(({text}) => text.replace(/`[^`]*`/g, '').includes('{@link'))
|
|
280
|
+
.map(({field}) => field);
|
|
281
|
+
expect([...new Set(problems.map(problem => problem.field))]).toEqual(
|
|
282
|
+
fields,
|
|
283
|
+
);
|
|
284
|
+
});
|
|
285
|
+
});
|
|
@@ -102,7 +102,7 @@ export type ReadOptions = {
|
|
|
102
102
|
* how to import the module (default
|
|
103
103
|
* `user`)
|
|
104
104
|
*/
|
|
105
|
-
loader?: "template" | "
|
|
105
|
+
loader?: "template" | "user" | "native" | undefined;
|
|
106
106
|
/**
|
|
107
107
|
* which exports name the doc, in
|
|
108
108
|
* precedence order, for a reader that has always read a narrower set than its
|
|
@@ -242,7 +242,8 @@ export function buildDocsTree({namespaces, docs, topics = []}) {
|
|
|
242
242
|
// without case, as topic names do, so `CLI` claims `cli`.
|
|
243
243
|
const cliRoutes = new Set(topics.length > 0 ? [UNORGANIZED] : []);
|
|
244
244
|
for (const topic of topics) {
|
|
245
|
-
if (topic.provider === CLI_PROVIDER)
|
|
245
|
+
if (topic.provider === CLI_PROVIDER)
|
|
246
|
+
cliRoutes.add(topic.name.toLowerCase());
|
|
246
247
|
}
|
|
247
248
|
// Every other name a topic answers to (the topics it replaced, directly or
|
|
248
249
|
// through a chain) is that topic's route too: `astryx docs <name>` opens the
|
|
@@ -375,6 +376,34 @@ export function buildDocsTree({namespaces, docs, topics = []}) {
|
|
|
375
376
|
return false;
|
|
376
377
|
}
|
|
377
378
|
const taken = byFoldedRoute.get(folded);
|
|
379
|
+
if (
|
|
380
|
+
taken &&
|
|
381
|
+
taken.provider === CLI_PROVIDER &&
|
|
382
|
+
node.provider !== CLI_PROVIDER &&
|
|
383
|
+
!node.generated
|
|
384
|
+
) {
|
|
385
|
+
// Astryx's own doc keeps its route: name both docs as an author knows
|
|
386
|
+
// them, never by their ids, and say what to change.
|
|
387
|
+
const what = (/** @type {TreeNode} */ n) =>
|
|
388
|
+
n.kind === 'namespace'
|
|
389
|
+
? 'namespace'
|
|
390
|
+
: n.kind === 'generic'
|
|
391
|
+
? 'topic'
|
|
392
|
+
: `${n.kind} doc`;
|
|
393
|
+
const scope = String(node.provider).split('/').pop() ?? '';
|
|
394
|
+
const suggestion = `${
|
|
395
|
+
scope
|
|
396
|
+
.replace(/[^a-z0-9]+/gi, '-')
|
|
397
|
+
.replace(/^-|-$/g, '')
|
|
398
|
+
.toLowerCase() || 'my'
|
|
399
|
+
}-${node.name.toLowerCase()}`;
|
|
400
|
+
report(
|
|
401
|
+
'duplicate_route',
|
|
402
|
+
at,
|
|
403
|
+
`The ${what(node)} "${node.name}" from ${node.provider} and Astryx's own ${what(taken)} "${taken.name}" both have the route "${node.route}", so \`astryx docs ${node.route}\` cannot open both. Fix: rename "${node.name}" (its \`name\` and its file), such as \`name: '${suggestion}'\`${node.route.includes('/') ? ', or place it elsewhere' : ''}.`,
|
|
404
|
+
);
|
|
405
|
+
return false;
|
|
406
|
+
}
|
|
378
407
|
if (taken) {
|
|
379
408
|
report(
|
|
380
409
|
'duplicate_route',
|
|
@@ -171,6 +171,13 @@ describe('buildDocsTree', () => {
|
|
|
171
171
|
['duplicate_route', expect.stringContaining('takes the route "UNORGANIZED", which the CLI\'s own docs keep')],
|
|
172
172
|
]),
|
|
173
173
|
);
|
|
174
|
+
// It names both docs as their authors know them, never by artifact id,
|
|
175
|
+
// and says what to change.
|
|
176
|
+
const taken = problems(tree).find(([, message]) => message.includes('route "CLI"'))?.[1];
|
|
177
|
+
expect(taken).toBe(
|
|
178
|
+
`The topic "CLI" from ${P} and Astryx's own namespace "cli" both have the route "CLI", so \`astryx docs CLI\` cannot open both. Fix: rename "CLI" (its \`name\` and its file), such as \`name: 'kit-cli'\`.`,
|
|
179
|
+
);
|
|
180
|
+
expect(taken).not.toContain('astryx:artifact');
|
|
174
181
|
expect(tree.getFolded('THEME')?.provider).toBe(CLI);
|
|
175
182
|
// A CLI topic whose own name has capitals keeps its route against a
|
|
176
183
|
// lowercase namespace, although namespaces go into the tree first.
|
|
@@ -495,7 +502,7 @@ describe("the CLI's own docs tree", () => {
|
|
|
495
502
|
async () => {
|
|
496
503
|
const tree = await loadDocsTree({fresh: true});
|
|
497
504
|
expect(tree.diagnostics).toEqual([]);
|
|
498
|
-
expect(tree.roots().map(node => node.route)).toEqual(['cli', 'internationalization', 'layout', 'migration', 'styling', 'styling-libraries', 'tokens', 'typography']);
|
|
505
|
+
expect(tree.roots().map(node => node.route)).toEqual(['cli', 'global', 'internationalization', 'layout', 'migration', 'styling', 'styling-libraries', 'tokens', 'typography']);
|
|
499
506
|
// Every slot child is a node one level below the namespace that places
|
|
500
507
|
// it, and every node but the root is placed. Read from the tree, so a
|
|
501
508
|
// restructure of the guides does not need this test edited.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// @generated by scripts/sync-api-types.mjs from the JSDoc in foundation/**/*.mjs.
|
|
2
|
+
// DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Run `fn` with `command` as the door printed commands start with. The slot a
|
|
6
|
+
* host fills for one call. An integration's `cliCommand` still comes first,
|
|
7
|
+
* and conflicting ones still fall back to the guess.
|
|
8
|
+
* @template T
|
|
9
|
+
* @param {string} command e.g. `astryx` for a global launcher
|
|
10
|
+
* @param {() => T} fn
|
|
11
|
+
* @returns {T}
|
|
12
|
+
*/
|
|
13
|
+
export function runWithCliDoor<T>(command: string, fn: () => T): T;
|
|
14
|
+
/**
|
|
15
|
+
* The door of the current call, if a host set one.
|
|
16
|
+
* @returns {string | undefined}
|
|
17
|
+
*/
|
|
18
|
+
export function cliDoor(): string | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* The commands a set of loaded integrations declares, in load order. An
|
|
21
|
+
* integration that failed to load, or was set aside for a provider conflict,
|
|
22
|
+
* contributes nothing, so it declares nothing either.
|
|
23
|
+
* @param {ReadonlyArray<{name?: string, __spec?: string, cliCommand?: string, __loadError?: string, __providerConflict?: unknown}>} integrations
|
|
24
|
+
* @returns {DeclaredCliCommand[]}
|
|
25
|
+
*/
|
|
26
|
+
export function declaredCliCommandsOf(integrations: ReadonlyArray<{
|
|
27
|
+
name?: string;
|
|
28
|
+
__spec?: string;
|
|
29
|
+
cliCommand?: string;
|
|
30
|
+
__loadError?: string;
|
|
31
|
+
__providerConflict?: unknown;
|
|
32
|
+
}>): DeclaredCliCommand[];
|
|
33
|
+
/**
|
|
34
|
+
* Choose among declarations: one command, declared by one or more
|
|
35
|
+
* integrations, is used; different commands are a conflict.
|
|
36
|
+
* @param {DeclaredCliCommand[]} declared
|
|
37
|
+
* @returns {{command?: string, conflict: boolean, declared: DeclaredCliCommand[]}}
|
|
38
|
+
*/
|
|
39
|
+
export function chooseDeclaredCliCommand(declared: DeclaredCliCommand[]): {
|
|
40
|
+
command?: string;
|
|
41
|
+
conflict: boolean;
|
|
42
|
+
declared: DeclaredCliCommand[];
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Record the commands a project's loaded integrations declare. Called by
|
|
46
|
+
* `Project.load` each time it resolves the integration set; the latest load
|
|
47
|
+
* wins.
|
|
48
|
+
* @param {string} projectDir
|
|
49
|
+
* @param {Parameters<typeof declaredCliCommandsOf>[0]} integrations
|
|
50
|
+
* @returns {void}
|
|
51
|
+
*/
|
|
52
|
+
export function recordDeclaredCliCommands(projectDir: string, integrations: Parameters<typeof declaredCliCommandsOf>[0]): void;
|
|
53
|
+
/**
|
|
54
|
+
* Whether this process has loaded the project at `targetDir`.
|
|
55
|
+
* @param {string} [targetDir=process.cwd()]
|
|
56
|
+
* @returns {boolean}
|
|
57
|
+
*/
|
|
58
|
+
export function hasRecordedProject(targetDir?: string): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* What the integrations of the project at `targetDir` declare, as recorded by
|
|
61
|
+
* its last `Project.load` in this process; see
|
|
62
|
+
* {@link chooseDeclaredCliCommand}.
|
|
63
|
+
* @param {string} [targetDir=process.cwd()]
|
|
64
|
+
* @returns {{command?: string, conflict: boolean, declared: DeclaredCliCommand[]}}
|
|
65
|
+
*/
|
|
66
|
+
export function declaredCliCommand(targetDir?: string): {
|
|
67
|
+
command?: string;
|
|
68
|
+
conflict: boolean;
|
|
69
|
+
declared: DeclaredCliCommand[];
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* One integration's declared command.
|
|
73
|
+
*/
|
|
74
|
+
export type DeclaredCliCommand = {
|
|
75
|
+
/**
|
|
76
|
+
* the integration package that declared it
|
|
77
|
+
*/
|
|
78
|
+
package: string;
|
|
79
|
+
/**
|
|
80
|
+
* its `cliCommand` value
|
|
81
|
+
*/
|
|
82
|
+
command: string;
|
|
83
|
+
};
|