@astryxdesign/cli 0.6.3-canary.db4e378 → 0.6.3-canary.db52d98
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -15
- package/api/blog/blog.doc.mjs +1 -0
- package/api/build/_adapter.d.mts +50 -0
- package/api/build/_adapter.mjs +60 -0
- package/api/build/build.doc.mjs +14 -7
- package/api/build/build.test.mjs +184 -6
- package/api/build/build.type.d.mts +57 -2
- package/api/build/build.type.mjs +30 -7
- package/api/build/help/help.d.mts +4 -0
- package/api/build/help/help.mjs +24 -11
- package/api/build/kit/kit.d.mts +4 -1
- package/api/build/kit/kit.mjs +165 -49
- package/api/build/kit/rank.d.mts +44 -0
- package/api/build/kit/rank.mjs +432 -0
- package/api/build/kit/rank.test.mjs +196 -0
- package/api/component/_adapter.d.mts +6 -12
- package/api/component/_adapter.mjs +20 -10
- package/api/component/component.doc.mjs +1 -0
- package/api/component/component.mjs +60 -12
- package/api/component/list/list.mjs +3 -2
- package/api/discover/discover.doc.mjs +1 -0
- package/api/docs/_adapter.d.mts +252 -34
- package/api/docs/_adapter.mjs +923 -132
- package/api/docs/detail/detail.mjs +11 -3
- package/api/docs/detail/section/section.mjs +24 -13
- package/api/docs/detail/section/section.test.mjs +15 -6
- package/api/docs/docs.d.mts +5 -3
- package/api/docs/docs.doc.mjs +39 -17
- package/api/docs/docs.mjs +44 -8
- package/api/docs/docs.test.mjs +158 -4
- package/api/docs/docs.type.d.mts +181 -2
- package/api/docs/docs.type.mjs +117 -3
- package/api/docs/index/index.mjs +11 -3
- package/api/docs/index/index.test.mjs +1 -1
- package/api/docs/integration-tree.test.mjs +555 -0
- package/api/docs/integrationDocs.test.mjs +14 -14
- package/api/docs/list/list.mjs +28 -12
- package/api/docs/node/node.d.mts +43 -0
- package/api/docs/node/node.mjs +192 -0
- package/api/docs/reference-blocks.test.mjs +406 -0
- package/api/doctor/doctor.d.mts +54 -4
- package/api/doctor/doctor.doc.mjs +1 -0
- package/api/doctor/doctor.mjs +331 -16
- package/api/doctor/doctor.test.mjs +420 -7
- package/api/gap-report/gap-report.doc.mjs +1 -0
- package/api/hook/_adapter.mjs +19 -5
- package/api/hook/hook.doc.mjs +1 -0
- package/api/hook/list/list.d.mts +1 -1
- package/api/hook/list/list.mjs +69 -17
- package/api/index.d.mts +1 -1
- package/api/index.mjs +1 -0
- package/api/init/init.doc.mjs +2 -1
- package/api/integration/add-contribution.d.mts +2 -1
- package/api/integration/add-contribution.mjs +114 -12
- package/api/integration/add-contribution.test.mjs +174 -3
- package/api/integration/add-theme.mjs +34 -64
- package/api/integration/add-theme.test.mjs +105 -21
- package/api/integration/authoring-checks.mjs +138 -28
- package/api/integration/authoring-checks.test.mjs +179 -7
- package/api/integration/authoring-checks.type.mjs +6 -1
- package/api/integration/integration-authoring.type.d.mts +2 -0
- package/api/integration/integration-authoring.type.mjs +2 -0
- package/api/integration/integration-block-exports.test.mjs +10 -6
- package/api/integration/integrationAdd.doc.mjs +7 -0
- package/api/integration/integrationAddAgentDoc.doc.mjs +1 -0
- package/api/integration/integrationAddCodemod.doc.mjs +1 -0
- package/api/integration/integrationAddComponent.doc.mjs +1 -0
- package/api/integration/integrationAddDoc.doc.mjs +8 -1
- package/api/integration/integrationAddTemplate.doc.mjs +1 -0
- package/api/integration/integrationAddTheme.doc.mjs +6 -5
- package/api/integration/integrationComponentConflicts.doc.mjs +1 -0
- package/api/integration/integrationDocConflicts.doc.mjs +2 -1
- package/api/integration/integrationPackCheck.doc.mjs +2 -1
- package/api/integration/integrationTemplateConflicts.doc.d.mts +3 -0
- package/api/integration/integrationTemplateConflicts.doc.mjs +4 -0
- package/api/integration/pack-check.mjs +34 -0
- package/api/integration/pack-check.test.mjs +138 -47
- package/api/integration/pack-check.type.d.mts +26 -2
- package/api/integration/pack-check.type.mjs +14 -1
- package/api/integration/summarizeIssues.doc.mjs +1 -0
- package/api/integration/template-conflict-compatibility.test.mjs +73 -0
- package/api/integration/validate-integration-fixes.test.mjs +1389 -0
- package/api/integration/validate-integration.mjs +50 -102
- package/api/integration/validate-integration.test.mjs +88 -26
- package/api/integration/validate-unread-theme-folders.test.mjs +110 -0
- package/api/integration/validateIntegration.doc.mjs +2 -1
- package/api/json/assertResponse.doc.mjs +1 -0
- package/api/json/index.ts +2 -0
- package/api/json/isError.doc.mjs +1 -0
- package/api/json/parseResponse.doc.mjs +1 -0
- package/api/layout/_adapter.mjs +20 -5
- package/api/layout/layoutCheck.doc.mjs +1 -0
- package/api/layout/layoutExpand.doc.mjs +1 -0
- package/api/layout/layoutGrammar.doc.mjs +1 -0
- package/api/search/search.d.mts +59 -1
- package/api/search/search.doc.mjs +5 -3
- package/api/search/search.mjs +458 -77
- package/api/search/search.test.mjs +91 -2
- package/api/search/search.type.d.mts +13 -1
- package/api/search/search.type.mjs +4 -1
- package/api/swizzle/swizzle.doc.mjs +1 -0
- package/api/template/list/list.mjs +1 -0
- package/api/template/table-floating-bulk-actions.test.mjs +66 -0
- package/api/template/template-integration.test.mjs +1072 -3
- package/api/template/template-suffix.test.mjs +41 -21
- package/api/template/template.doc.mjs +28 -7
- package/api/template/template.mjs +45 -8
- package/api/template/template.type.d.mts +6 -8
- package/api/template/template.type.mjs +3 -2
- package/api/theme/_adapter.d.mts +2 -3
- package/api/theme/_adapter.mjs +4 -5
- package/api/theme/add/add.binary.test.mjs +10 -17
- package/api/theme/add/add.test.mjs +14 -1
- package/api/theme/generateTonalPalette.doc.mjs +1 -0
- package/api/theme/integration-themes.test.mjs +39 -28
- package/api/theme/list/list.test.mjs +19 -20
- package/api/theme/listThemes.doc.mjs +6 -5
- package/api/theme/template/template.test.mjs +5 -0
- package/api/theme/themeAdd.doc.mjs +4 -3
- package/api/theme/themeBuild.doc.mjs +1 -0
- package/api/theme/themeList.doc.mjs +6 -3
- package/api/theme/themeListAvailable.doc.mjs +5 -3
- package/api/theme/themePaletteGenerate.doc.mjs +1 -0
- package/api/theme/themeTargets.doc.mjs +1 -0
- package/api/theme/themeTemplate.doc.mjs +2 -1
- package/api/upgrade/_adapter.d.mts +32 -5
- package/api/upgrade/_adapter.mjs +97 -69
- package/api/upgrade/provider-agreement.test.mjs +152 -0
- package/api/upgrade/run/run.mjs +356 -59
- package/api/upgrade/upgrade.doc.mjs +6 -1
- package/api/upgrade/upgrade.type.d.mts +34 -0
- package/api/upgrade/upgrade.type.mjs +15 -0
- package/assets/codemods/__tests__/runner.test.mjs +330 -8
- package/assets/codemods/integration-discovery.mjs +8 -2
- package/assets/codemods/integration-discovery.test.mjs +15 -0
- package/assets/codemods/integration-runner.mjs +56 -4
- package/assets/codemods/integration-runner.protection.test.mjs +153 -0
- package/assets/codemods/run-codemod.mjs +177 -34
- package/assets/codemods/runner.mjs +350 -102
- package/assets/codemods/transforms/next/__tests__/migrate-native-picker-to-presentation.test.mjs +63 -0
- package/assets/codemods/transforms/next/__tests__/migrate-theme-catalog-to-descriptors.test.mjs +220 -0
- package/assets/codemods/transforms/next/index.mjs +19 -1
- package/assets/codemods/transforms/next/migrate-native-picker-to-presentation.mjs +148 -0
- package/assets/codemods/transforms/next/migrate-theme-catalog-to-descriptors.mjs +141 -0
- package/assets/docs/getting-started.doc.mjs +2 -2
- package/assets/docs/layout.doc.dense.mjs +2 -2
- package/assets/docs/layout.doc.mjs +1 -1
- package/assets/docs/principles.doc.mjs +6 -6
- package/assets/docs/styling-libraries.doc.mjs +3 -3
- package/assets/docs/styling.doc.mjs +4 -4
- package/assets/docs/theme.doc.mjs +5 -5
- package/assets/docs/tokens.doc.mjs +1 -1
- package/assets/docs/tree/api.doc.mjs +30 -0
- package/assets/docs/tree/cli.doc.mjs +23 -0
- package/assets/docs/tree/commands.doc.mjs +25 -0
- package/assets/docs/{cli-integrations.doc.mjs → tree/integrations.doc.mjs} +66 -38
- package/assets/docs/tree/integrations.test.mjs +62 -0
- package/assets/docs/tree/writing-docs.doc.mjs +286 -0
- package/assets/docs/working-with-ai.doc.mjs +3 -3
- package/assets/templates/blocks/components/CheckboxList/CheckboxListSelectAllPattern.doc.mjs +1 -1
- package/assets/templates/blocks/components/CheckboxList/CheckboxListSelectAllPattern.tsx +1 -3
- package/assets/templates/blocks/components/DateInput/DateInputDateRange.tsx +1 -1
- package/assets/templates/blocks/components/Item/ItemDocumentTabs.doc.mjs +14 -0
- package/assets/templates/blocks/components/Item/ItemDocumentTabs.tsx +100 -0
- package/assets/templates/blocks/components/Table/TableBulkActionsTable.doc.mjs +14 -0
- package/assets/templates/blocks/components/Table/TableBulkActionsTable.tsx +71 -0
- package/assets/templates/blocks/components/Table/TableFloatingBulkActionsTable.doc.mjs +19 -0
- package/assets/templates/blocks/components/Table/TableFloatingBulkActionsTable.tsx +139 -0
- package/assets/templates/blocks/components/TimeInput/TimeInputConstrained.tsx +1 -0
- package/assets/templates/themes/butter/butterTheme.doc.mjs +11 -0
- package/assets/templates/themes/chocolate/chocolateTheme.doc.mjs +11 -0
- package/assets/templates/themes/gothic/gothicTheme.doc.mjs +11 -0
- package/assets/templates/themes/matcha/matchaTheme.doc.mjs +11 -0
- package/assets/templates/themes/neutral/neutralTheme.doc.mjs +11 -0
- package/assets/templates/themes/stone/stoneTheme.doc.mjs +11 -0
- package/assets/templates/themes/y2k/y2kTheme.doc.mjs +11 -0
- package/authoring/codemod/codemod.doc.mjs +1 -1
- package/authoring/codemod/type.ts +12 -0
- package/authoring/config/config.doc.mjs +1 -1
- package/authoring/debug/debug.doc.d.mts +11 -0
- package/authoring/debug/debug.doc.mjs +182 -0
- package/authoring/debug/parse.d.mts +3 -3
- package/authoring/doctypes/_schema.d.mts +119 -117
- package/authoring/doctypes/_schema.mjs +54 -3
- package/authoring/doctypes/base/graph-fields.doc.mjs +8 -6
- package/authoring/doctypes/base/type.ts +6 -5
- package/authoring/doctypes/command/command.doc.mjs +1 -1
- package/authoring/doctypes/command/type.ts +2 -2
- package/authoring/doctypes/component/type.ts +2 -2
- package/authoring/doctypes/doctypes-new.test.mjs +48 -6
- package/authoring/doctypes/enum/enum.doc.mjs +1 -1
- package/authoring/doctypes/enum/type.ts +1 -1
- package/authoring/doctypes/function/function.doc.mjs +3 -2
- package/authoring/doctypes/function/type.ts +3 -2
- package/authoring/doctypes/hook/type.ts +2 -2
- package/authoring/doctypes/load-contract.test.mjs +28 -2
- package/authoring/doctypes/namespace/namespace.doc.mjs +6 -10
- package/authoring/doctypes/namespace/parse.test.mjs +23 -25
- package/authoring/doctypes/namespace/type.ts +5 -2
- package/authoring/doctypes/parse.d.mts +4 -2
- package/authoring/doctypes/parse.mjs +10 -5
- package/authoring/doctypes/reference/reference.doc.mjs +35 -6
- package/authoring/doctypes/reference/type.ts +30 -13
- package/authoring/doctypes/schema/schema.doc.mjs +1 -1
- package/authoring/doctypes/schema/type.ts +1 -2
- package/authoring/doctypes/template/parse.d.mts +2 -0
- package/authoring/doctypes/template/parse.mjs +4 -0
- package/authoring/doctypes/template/parse.test.mjs +18 -0
- package/authoring/doctypes/template/template.doc.mjs +9 -3
- package/authoring/doctypes/template/type.ts +8 -0
- package/authoring/doctypes/theme/parse.d.mts +35 -0
- package/authoring/doctypes/theme/parse.mjs +76 -0
- package/authoring/doctypes/theme/theme.doc.d.mts +9 -0
- package/authoring/doctypes/theme/theme.doc.mjs +79 -0
- package/authoring/doctypes/theme/type.ts +42 -0
- package/authoring/doctypes/types.ts +2 -1
- package/authoring/gap-report/gap-report.doc.d.mts +12 -0
- package/authoring/gap-report/gap-report.doc.mjs +183 -0
- package/authoring/identity/identity.doc.mjs +2 -2
- package/authoring/index.d.mts +1 -0
- package/authoring/index.d.ts +7 -4
- package/authoring/index.mjs +2 -1
- package/authoring/integration/integration.doc.mjs +2 -2
- package/authoring/integration/type.ts +4 -10
- package/clients/cli/__tests__/cliManifest.test.ts +27 -29
- package/clients/cli/commands/blog.doc.mjs +1 -1
- package/clients/cli/commands/build-theme.adaptations.test.mjs +100 -1
- package/clients/cli/commands/build-theme.mjs +11 -45
- package/clients/cli/commands/build.doc.mjs +12 -7
- package/clients/cli/commands/build.mjs +105 -67
- package/clients/cli/commands/build.text-fields.test.mjs +41 -0
- package/clients/cli/commands/component/index.mjs +1 -1
- package/clients/cli/commands/component-ownership.test.mjs +3 -3
- package/clients/cli/commands/component.doc.mjs +1 -1
- package/clients/cli/commands/discover.broken-integration.test.mjs +7 -8
- package/clients/cli/commands/discover.doc.mjs +1 -1
- package/clients/cli/commands/discover.mjs +1 -1
- package/clients/cli/commands/docs.doc.mjs +21 -9
- package/clients/cli/commands/docs.mjs +184 -70
- package/clients/cli/commands/docs.test.mjs +120 -16
- package/clients/cli/commands/doctor-integration-components.doc.mjs +1 -1
- package/clients/cli/commands/doctor-integration-docs.doc.mjs +3 -3
- package/clients/cli/commands/doctor-integration-templates.doc.mjs +15 -8
- package/clients/cli/commands/doctor-integration-validate.doc.mjs +1 -1
- package/clients/cli/commands/doctor-integration.doc.mjs +1 -1
- package/clients/cli/commands/doctor-integration.test.mjs +90 -8
- package/clients/cli/commands/doctor.doc.mjs +1 -1
- package/clients/cli/commands/doctor.mjs +53 -16
- package/clients/cli/commands/gap-report.doc.mjs +1 -1
- package/clients/cli/commands/hook.doc.mjs +1 -1
- package/clients/cli/commands/init.doc.mjs +1 -1
- package/clients/cli/commands/integration-add.controls.test.mjs +1 -1
- package/clients/cli/commands/integration-add.doc.mjs +11 -1
- package/clients/cli/commands/integration-pack.doc.mjs +1 -1
- package/clients/cli/commands/integration-real-world.test.mjs +3 -9
- package/clients/cli/commands/integration.doc.mjs +1 -1
- package/clients/cli/commands/integration.mjs +1 -0
- package/clients/cli/commands/layout-check.doc.mjs +1 -1
- package/clients/cli/commands/layout-expand.doc.mjs +1 -1
- package/clients/cli/commands/layout-grammar.doc.mjs +1 -1
- package/clients/cli/commands/layout.doc.mjs +1 -1
- package/clients/cli/commands/manifest.doc.mjs +1 -1
- package/clients/cli/commands/search.doc.mjs +1 -1
- package/clients/cli/commands/search.mjs +11 -2
- package/clients/cli/commands/setup-nudge.test.mjs +6 -0
- package/clients/cli/commands/swizzle.doc.mjs +1 -1
- package/clients/cli/commands/template.doc.mjs +24 -7
- package/clients/cli/commands/template.mjs +4 -91
- package/clients/cli/commands/text-json-parity.test.mjs +719 -0
- package/clients/cli/commands/theme-add.doc.mjs +2 -2
- package/clients/cli/commands/theme-build.doc.mjs +1 -1
- package/clients/cli/commands/theme-list.doc.mjs +2 -2
- package/clients/cli/commands/theme-palette-generate.doc.mjs +3 -3
- package/clients/cli/commands/theme-palette.doc.mjs +1 -1
- package/clients/cli/commands/theme-targets.behavior.test.mjs +4 -3
- package/clients/cli/commands/theme-targets.doc.mjs +1 -1
- package/clients/cli/commands/theme-template.doc.mjs +1 -1
- package/clients/cli/commands/theme.doc.mjs +1 -1
- package/clients/cli/commands/upgrade.doc.mjs +3 -2
- package/clients/cli/commands/upgrade.file-protection.test.mjs +228 -0
- package/clients/cli/commands/upgrade.mjs +29 -7
- package/clients/cli/formatters/index.mjs +2 -0
- package/clients/cli/formatters/index.test.mjs +6 -0
- package/clients/cli/index.mjs +8 -0
- package/clients/cli/lib/hook-format.mjs +14 -5
- package/clients/cli/lib/manifest.mjs +9 -2
- package/foundation/agent-docs/agent-docs.d.mts +3 -2
- package/foundation/agent-docs/agent-docs.mjs +13 -9
- package/foundation/agent-docs/agent-docs.test.mjs +19 -1
- package/foundation/config/project-themes.test.mjs +11 -19
- package/foundation/config/project.d.mts +20 -11
- package/foundation/config/project.mjs +123 -80
- package/foundation/config/project.test.mjs +144 -21
- package/foundation/discovery/authoring-self-docs.d.mts +18 -0
- package/foundation/discovery/authoring-self-docs.mjs +37 -15
- package/foundation/discovery/authoring-self-docs.test.mjs +25 -9
- package/foundation/discovery/authoring-surface.d.mts +74 -0
- package/foundation/discovery/authoring-surface.mjs +525 -0
- package/foundation/discovery/authoring-surface.test.mjs +392 -0
- package/foundation/discovery/cli-self-docs.d.mts +119 -0
- package/foundation/discovery/cli-self-docs.mjs +490 -0
- package/foundation/discovery/cli-self-docs.test.mjs +375 -0
- package/foundation/discovery/component-discovery.d.mts +38 -0
- package/foundation/discovery/component-discovery.mjs +48 -0
- package/foundation/discovery/component-loader.d.mts +35 -38
- package/foundation/discovery/component-loader.mjs +53 -222
- package/foundation/discovery/docs-discovery.d.mts +112 -11
- package/foundation/discovery/docs-discovery.mjs +231 -36
- package/foundation/discovery/docs-discovery.test.mjs +111 -32
- package/foundation/discovery/docs-output-budget.d.mts +2 -2
- package/foundation/discovery/docs-output-budget.mjs +1 -1
- package/foundation/discovery/docs-section-key.d.mts +28 -10
- package/foundation/discovery/docs-section-key.mjs +134 -33
- package/foundation/discovery/docs-section-key.test.mjs +41 -19
- package/foundation/discovery/template-adapter.d.mts +99 -6
- package/foundation/discovery/template-adapter.mjs +480 -57
- package/foundation/discovery/template-adapter.test.mjs +57 -0
- package/foundation/discovery/template-conflict-release.d.mts +13 -0
- package/foundation/discovery/template-conflict-release.mjs +40 -0
- package/foundation/discovery/template-conflict-release.test.mjs +40 -0
- package/foundation/discovery/theme-discovery.d.mts +67 -7
- package/foundation/discovery/theme-discovery.mjs +916 -186
- package/foundation/discovery/theme-discovery.test.mjs +613 -219
- package/foundation/doc-compiler/bundle.d.mts +47 -0
- package/foundation/doc-compiler/bundle.mjs +278 -0
- package/foundation/doc-compiler/bundle.test.mjs +266 -0
- package/foundation/doc-compiler/compile.d.mts +220 -39
- package/foundation/doc-compiler/compile.mjs +311 -15
- package/foundation/doc-compiler/diagnostics.d.mts +126 -0
- package/foundation/doc-compiler/diagnostics.mjs +305 -0
- package/foundation/doc-compiler/doc-compiler.test.mjs +28 -1
- package/foundation/doc-compiler/doc-loads.test.mjs +1642 -0
- package/foundation/doc-compiler/import.d.mts +24 -0
- package/foundation/doc-compiler/import.mjs +59 -0
- package/foundation/doc-compiler/inputs.d.mts +102 -0
- package/foundation/doc-compiler/inputs.mjs +291 -0
- package/foundation/doc-compiler/inputs.test.mjs +299 -0
- package/foundation/doc-compiler/ir.d.mts +13 -0
- package/foundation/doc-compiler/ir.mjs +196 -12
- package/foundation/doc-compiler/lenses.d.mts +8 -5
- package/foundation/doc-compiler/lenses.mjs +50 -4
- package/foundation/doc-compiler/links.d.mts +162 -0
- package/foundation/doc-compiler/links.mjs +294 -0
- package/foundation/doc-compiler/links.test.mjs +192 -0
- package/foundation/doc-compiler/lower-doc.test.mjs +495 -0
- package/foundation/doc-compiler/overlays.d.mts +37 -0
- package/foundation/doc-compiler/overlays.mjs +206 -0
- package/foundation/doc-compiler/parse-readable.d.mts +9 -0
- package/foundation/doc-compiler/parse-readable.mjs +29 -0
- package/foundation/doc-compiler/read.d.mts +127 -0
- package/foundation/doc-compiler/read.mjs +325 -0
- package/foundation/doc-compiler/read.test.mjs +313 -0
- package/foundation/doc-compiler/source.d.mts +33 -0
- package/foundation/doc-compiler/source.mjs +128 -0
- package/foundation/doc-compiler/tree.d.mts +288 -0
- package/foundation/doc-compiler/tree.mjs +876 -0
- package/foundation/doc-compiler/tree.test.mjs +598 -0
- package/foundation/fs/file-protection.d.mts +33 -0
- package/foundation/fs/file-protection.mjs +825 -0
- package/foundation/fs/file-protection.test.mjs +250 -0
- package/foundation/integrations/autolink.d.mts +58 -1
- package/foundation/integrations/autolink.mjs +143 -57
- package/foundation/integrations/autolink.test.mjs +1 -1
- package/foundation/integrations/cli-requirement.d.mts +45 -0
- package/foundation/integrations/cli-requirement.mjs +154 -0
- package/foundation/integrations/cli-requirement.test.mjs +84 -0
- package/foundation/integrations/contribution-fixes.d.mts +145 -0
- package/foundation/integrations/contribution-fixes.mjs +1284 -0
- package/foundation/integrations/contribution-inventory.d.mts +3 -2
- package/foundation/integrations/contribution-inventory.mjs +27 -24
- package/foundation/integrations/contribution-inventory.test.mjs +86 -27
- package/foundation/integrations/integration-warnings.d.mts +9 -2
- package/foundation/integrations/integration-warnings.mjs +51 -26
- package/foundation/integrations/integration-warnings.test.mjs +74 -1
- package/foundation/integrations/integrations.d.mts +3 -0
- package/foundation/integrations/integrations.mjs +11 -97
- package/foundation/integrations/provider-ledger.test.mjs +275 -0
- package/foundation/integrations/provider-resolution.d.mts +152 -0
- package/foundation/integrations/provider-resolution.mjs +576 -0
- package/foundation/integrations/provider-resolution.test.mjs +369 -0
- package/foundation/integrations/theme-descriptor.d.mts +8 -0
- package/foundation/integrations/theme-descriptor.mjs +44 -0
- package/foundation/integrations/validate-contributions.mjs +121 -29
- package/foundation/response/error-codes.d.mts +3 -1
- package/foundation/response/error-codes.d.ts +2 -0
- package/foundation/response/error-codes.doc.mjs +12 -2
- package/foundation/response/error-codes.mjs +7 -1
- package/foundation/response/error-codes.test.mjs +55 -11
- package/foundation/response/response-types.doc.d.mts +5 -1
- package/foundation/response/response-types.doc.mjs +20 -11
- package/foundation/response/response.doc.mjs +1 -1
- package/foundation/text/string-utils.d.mts +8 -0
- package/foundation/text/string-utils.mjs +40 -10
- package/foundation/xle/expand.mjs +1 -1
- package/foundation/xle/xle.test.mjs +13 -0
- package/package.json +10 -9
- package/assets/templates/themes/manifest.json +0 -95
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
import {linkReferenceTopic} from '../../../foundation/doc-compiler/compile.mjs';
|
|
15
15
|
import {detailView} from '../../../foundation/doc-compiler/lenses.mjs';
|
|
16
|
-
import {referenceTargets, resolveTopicDocs} from '../_adapter.mjs';
|
|
16
|
+
import {referenceTargets, resolveTopicDocs, topicLinks} from '../_adapter.mjs';
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* @param {string} topic
|
|
@@ -25,10 +25,18 @@ import {referenceTargets, resolveTopicDocs} from '../_adapter.mjs';
|
|
|
25
25
|
* @returns {Promise<import('../docs.type.mjs').DocsDetailResponse>}
|
|
26
26
|
*/
|
|
27
27
|
export async function detail(topic, options = {}) {
|
|
28
|
-
const {catalog, node, lang} = await resolveTopicDocs(topic, options);
|
|
28
|
+
const {catalog, node, lang, entry} = await resolveTopicDocs(topic, options);
|
|
29
29
|
const linked = await linkReferenceTopic(
|
|
30
30
|
node,
|
|
31
31
|
referenceTargets(catalog, lang),
|
|
32
32
|
);
|
|
33
|
-
return {
|
|
33
|
+
return {
|
|
34
|
+
type: 'docs.detail',
|
|
35
|
+
data: {
|
|
36
|
+
...detailView(linked),
|
|
37
|
+
// A guide the docs tree places is read by its route, not its doc name.
|
|
38
|
+
...(entry.tree ? {name: entry.name} : {}),
|
|
39
|
+
links: await topicLinks(catalog, entry),
|
|
40
|
+
},
|
|
41
|
+
};
|
|
34
42
|
}
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* @file docs.detail.section leaf — load a single section of a topic.
|
|
5
5
|
*
|
|
6
6
|
* @input A topic name, a section query, and optional {lang, zh, dense}. Resolves
|
|
7
|
-
* the topic via the shared adapter,
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* the topic via the shared adapter, keeps the 0.6.x first title-substring
|
|
8
|
+
* match, then falls back to a stable key or normalized title key, and links
|
|
9
|
+
* only that section.
|
|
10
10
|
* @output { type: 'docs.detail.section', data: ReferenceSection } with any
|
|
11
11
|
* token-ref blocks inlined — matching `astryx --json docs <topic> <section>`.
|
|
12
12
|
* Throws ERR_UNKNOWN_SECTION when nothing matches, or when the query matches
|
|
@@ -50,18 +50,15 @@ export async function section(topic, sectionName, options = {}) {
|
|
|
50
50
|
);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
const {catalog, node, lang} = await resolveTopicDocs(topic, options);
|
|
53
|
+
const {catalog, node, lang, entry} = await resolveTopicDocs(topic, options);
|
|
54
54
|
const sections = readerSections(node);
|
|
55
|
-
const {section: match
|
|
55
|
+
const {section: match} = findDocSection(sections, sectionName);
|
|
56
56
|
if (!match) {
|
|
57
|
-
const ambiguous = candidates.length > 1;
|
|
58
57
|
throw new AstryxError(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
:
|
|
62
|
-
|
|
63
|
-
name: sectionKey(s),
|
|
64
|
-
reason: s.title,
|
|
58
|
+
`Section "${sectionName}" not found in "${topic}"`,
|
|
59
|
+
sections.map(s => ({
|
|
60
|
+
name: s.title,
|
|
61
|
+
reason: 'available section',
|
|
65
62
|
})),
|
|
66
63
|
ERROR_CODES.ERR_UNKNOWN_SECTION,
|
|
67
64
|
);
|
|
@@ -74,5 +71,19 @@ export async function section(topic, sectionName, options = {}) {
|
|
|
74
71
|
match,
|
|
75
72
|
referenceTargets(catalog, lang),
|
|
76
73
|
);
|
|
77
|
-
|
|
74
|
+
// The moves from one section (spec:AST-047): up to its topic's index, and
|
|
75
|
+
// across to the sections before and after it.
|
|
76
|
+
const at = sections.indexOf(match);
|
|
77
|
+
/** @type {import('../../docs.type.mjs').DocsLinks} */
|
|
78
|
+
const links = {up: `astryx docs ${entry.name} --index`};
|
|
79
|
+
if (at > 0) {
|
|
80
|
+
links.previous = `astryx docs ${entry.name} ${sectionKey(sections[at - 1])}`;
|
|
81
|
+
}
|
|
82
|
+
if (at !== -1 && at < sections.length - 1) {
|
|
83
|
+
links.next = `astryx docs ${entry.name} ${sectionKey(sections[at + 1])}`;
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
type: 'docs.detail.section',
|
|
87
|
+
data: {...sectionView(node, linked), links},
|
|
88
|
+
};
|
|
78
89
|
}
|
|
@@ -30,6 +30,17 @@ describe('docs.detail.section leaf', () => {
|
|
|
30
30
|
}
|
|
31
31
|
expect(err).toBeInstanceOf(AstryxError);
|
|
32
32
|
expect(err.code).toBe('ERR_UNKNOWN_SECTION');
|
|
33
|
+
expect(err.suggestions).toEqual(
|
|
34
|
+
expect.arrayContaining([
|
|
35
|
+
expect.objectContaining({
|
|
36
|
+
name: expect.any(String),
|
|
37
|
+
reason: 'available section',
|
|
38
|
+
}),
|
|
39
|
+
]),
|
|
40
|
+
);
|
|
41
|
+
expect(err.suggestions.some(suggestion => /\s/u.test(suggestion.name))).toBe(
|
|
42
|
+
true,
|
|
43
|
+
);
|
|
33
44
|
}, SLOW);
|
|
34
45
|
|
|
35
46
|
it('does not return the first section for an empty section name', async () => {
|
|
@@ -50,12 +61,10 @@ describe('docs.detail.section leaf', () => {
|
|
|
50
61
|
expect(res.data.id).toBe(target.id);
|
|
51
62
|
}, SLOW);
|
|
52
63
|
|
|
53
|
-
it('
|
|
54
|
-
const
|
|
55
|
-
expect(
|
|
56
|
-
expect(
|
|
57
|
-
expect(err.message).toMatch(/matches \d+ sections/);
|
|
58
|
-
expect(err.suggestions.length).toBeGreaterThan(1);
|
|
64
|
+
it('keeps a previously accepted ambiguous query on its first match', async () => {
|
|
65
|
+
const res = await section('theme', 'e');
|
|
66
|
+
expect(res.type).toBe('docs.detail.section');
|
|
67
|
+
expect(res.data).toBeDefined();
|
|
59
68
|
}, SLOW);
|
|
60
69
|
|
|
61
70
|
it.each([null, 'zh', 'dense'])(
|
package/api/docs/docs.d.mts
CHANGED
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
* import('./docs.type.mjs').DocsListResponse |
|
|
16
16
|
* import('./docs.type.mjs').DocsIndexResponse |
|
|
17
17
|
* import('./docs.type.mjs').DocsDetailResponse |
|
|
18
|
-
* import('./docs.type.mjs').DocsDetailSectionResponse
|
|
18
|
+
* import('./docs.type.mjs').DocsDetailSectionResponse |
|
|
19
|
+
* import('./docs.type.mjs').DocsNodeResponse
|
|
19
20
|
* >}
|
|
20
21
|
*/
|
|
21
22
|
export function docs(topic?: string, section?: string, options?: {
|
|
@@ -24,9 +25,10 @@ export function docs(topic?: string, section?: string, options?: {
|
|
|
24
25
|
dense?: boolean | undefined;
|
|
25
26
|
index?: boolean | undefined;
|
|
26
27
|
cwd?: string | undefined;
|
|
27
|
-
}): Promise<import("./docs.type.mjs").DocsListResponse | import("./docs.type.mjs").DocsIndexResponse | import("./docs.type.mjs").DocsDetailResponse | import("./docs.type.mjs").DocsDetailSectionResponse>;
|
|
28
|
+
}): Promise<import("./docs.type.mjs").DocsListResponse | import("./docs.type.mjs").DocsIndexResponse | import("./docs.type.mjs").DocsDetailResponse | import("./docs.type.mjs").DocsDetailSectionResponse | import("./docs.type.mjs").DocsNodeResponse>;
|
|
28
29
|
import { list } from './list/list.mjs';
|
|
29
30
|
import { index } from './index/index.mjs';
|
|
30
31
|
import { detail } from './detail/detail.mjs';
|
|
31
32
|
import { section as sectionLeaf } from './detail/section/section.mjs';
|
|
32
|
-
|
|
33
|
+
import { node as nodeLeaf } from './node/node.mjs';
|
|
34
|
+
export { list, index, detail, sectionLeaf as section, nodeLeaf as node };
|
package/api/docs/docs.doc.mjs
CHANGED
|
@@ -11,22 +11,32 @@ export const doc = {
|
|
|
11
11
|
type: 'function',
|
|
12
12
|
kind: 'api',
|
|
13
13
|
name: 'docs',
|
|
14
|
+
namespace: 'cli/api',
|
|
14
15
|
displayName: 'docs()',
|
|
15
16
|
summary:
|
|
16
17
|
'Read the reference docs: list every topic, one topic\'s sections, one section, or a whole topic.',
|
|
17
18
|
description:
|
|
18
|
-
'No topic lists every reference-doc topic; a topic returns
|
|
19
|
-
'ReferenceDoc
|
|
20
|
-
'
|
|
21
|
-
'that one section
|
|
22
|
-
'
|
|
23
|
-
'
|
|
19
|
+
'No topic lists every reference-doc topic; a topic returns its whole ' +
|
|
20
|
+
'ReferenceDoc, and `index: true` returns its section index (each ' +
|
|
21
|
+
'section\'s key, title, and summary); a topic plus a section returns ' +
|
|
22
|
+
'that one section. Token-ref blocks are ' +
|
|
23
|
+
'inlined in every read, and so is a section\'s reference block: the doc it ' +
|
|
24
|
+
'includes, then the command that opens that doc. The topic set is the CLI\'s own docs plus the ' +
|
|
24
25
|
'ones the project\'s configured integrations contribute, including any ' +
|
|
25
26
|
'topic an integration replaces or extends, so it depends on the cwd. ' +
|
|
27
|
+
'A route opens a node of the docs tree instead: a namespace such as ' +
|
|
28
|
+
"`cli/api` returns its children one level down, a typed doc such as " +
|
|
29
|
+
"`cli/api/functions/search` returns its content, and a guide the tree " +
|
|
30
|
+
'places (`cli/integrations`) reads like any topic. ' +
|
|
31
|
+
'Every read but the list carries `links`, the commands that move from it: ' +
|
|
32
|
+
'`up` to the level it sits in, `previous` and `next` to its neighbors, and, ' +
|
|
33
|
+
'for a typed doc, `related` to the docs it names (its command or function, ' +
|
|
34
|
+
'and its related docs); `previous` and `next` ' +
|
|
35
|
+
'to the section or node before and after it. ' +
|
|
26
36
|
'Overlay options select localized or dense variants.',
|
|
27
37
|
importPath: '@astryxdesign/cli/api',
|
|
28
38
|
signature:
|
|
29
|
-
'docs(topic?: string, section?: string, options?: DocsOptions): Promise<DocsListResponse | DocsIndexResponse | DocsDetailResponse | DocsDetailSectionResponse>',
|
|
39
|
+
'docs(topic?: string, section?: string, options?: DocsOptions): Promise<DocsListResponse | DocsIndexResponse | DocsDetailResponse | DocsDetailSectionResponse | DocsNodeResponse>',
|
|
30
40
|
keywords: [
|
|
31
41
|
'docs',
|
|
32
42
|
'documentation',
|
|
@@ -42,7 +52,7 @@ export const doc = {
|
|
|
42
52
|
name: 'topic',
|
|
43
53
|
type: 'string',
|
|
44
54
|
description:
|
|
45
|
-
"Doc topic to load (e.g. 'principles'). Omit to list all topics.",
|
|
55
|
+
"Doc topic to load (e.g. 'principles'), or a docs-tree route (e.g. 'cli/api/functions/search'). Omit to list all topics.",
|
|
46
56
|
},
|
|
47
57
|
{
|
|
48
58
|
name: 'section',
|
|
@@ -63,13 +73,14 @@ export const doc = {
|
|
|
63
73
|
{
|
|
64
74
|
name: 'options.dense',
|
|
65
75
|
type: 'boolean',
|
|
66
|
-
description:
|
|
76
|
+
description:
|
|
77
|
+
'Return the token-efficient dense doc variant. It is written to be read whole, so it returns the whole doc.',
|
|
67
78
|
},
|
|
68
79
|
{
|
|
69
80
|
name: 'options.index',
|
|
70
81
|
type: 'boolean',
|
|
71
82
|
description:
|
|
72
|
-
"Return the topic's section index (each section's key, title, and summary)
|
|
83
|
+
"Return the topic's section index (each section's key, title, and summary), even for a topic with one section.",
|
|
73
84
|
},
|
|
74
85
|
{
|
|
75
86
|
name: 'options.cwd',
|
|
@@ -82,41 +93,52 @@ export const doc = {
|
|
|
82
93
|
{
|
|
83
94
|
type: 'docs.list',
|
|
84
95
|
description:
|
|
85
|
-
|
|
96
|
+
"Every reference-doc topic in read order, as DocsListEntry[] ({topic, description, package, replaces?}), each readable with docs(topic). meta.namespaces lists the docs tree's top-level namespaces ({topic, description, package}), and meta.notLoaded each package whose docs did not load ({package, message}).",
|
|
86
97
|
},
|
|
87
98
|
{
|
|
88
99
|
type: 'docs.detail',
|
|
89
100
|
description:
|
|
90
|
-
"One topic's full ReferenceDoc, with token-ref blocks inlined.",
|
|
101
|
+
"One topic's full ReferenceDoc, with token-ref and reference blocks inlined, plus links.",
|
|
91
102
|
},
|
|
92
103
|
{
|
|
93
104
|
type: 'docs.index',
|
|
94
105
|
description:
|
|
95
|
-
"One topic's section index (index: true): {name, title, description, sections: [{id, title, summary}]}.",
|
|
106
|
+
"One topic's section index (index: true): {name, title, description, sections: [{id, title, summary}], links}.",
|
|
96
107
|
},
|
|
97
108
|
{
|
|
98
109
|
type: 'docs.detail.section',
|
|
99
110
|
description:
|
|
100
|
-
'One ReferenceSection of the topic, found by key or title, with token-ref blocks inlined.',
|
|
111
|
+
'One ReferenceSection of the topic, found by key or title, with token-ref and reference blocks inlined.',
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
type: 'docs.node',
|
|
115
|
+
description:
|
|
116
|
+
"A namespace or typed doc in the docs tree, read by its route: {id, route, kind, package, title, summary, breadcrumb, slots, content}. A namespace lists each slot's children one level down; a typed doc carries its content.",
|
|
101
117
|
},
|
|
102
118
|
],
|
|
103
119
|
throws: [
|
|
104
120
|
{
|
|
105
121
|
code: 'ERR_UNKNOWN_TOPIC',
|
|
106
|
-
when: 'the topic is not a string or matches no
|
|
122
|
+
when: 'the topic is not a string, or matches no topic and no docs-tree route',
|
|
107
123
|
},
|
|
108
124
|
{
|
|
109
125
|
code: 'ERR_UNKNOWN_SECTION',
|
|
110
|
-
when: 'a section is requested but is empty, matches no section,
|
|
126
|
+
when: 'a section is requested but is empty, matches no section, matches more than one, or is asked of a docs-tree namespace or typed doc, which have no sections',
|
|
111
127
|
},
|
|
112
128
|
],
|
|
113
129
|
examples: [
|
|
114
130
|
{label: 'List topics', code: 'const r = await docs();'},
|
|
115
|
-
{label: '
|
|
131
|
+
{label: 'A whole topic', code: "await docs('principles');"},
|
|
116
132
|
{
|
|
117
133
|
label: "A topic's sections",
|
|
118
134
|
code: "await docs('principles', undefined, {index: true});",
|
|
119
135
|
},
|
|
136
|
+
{label: 'A docs-tree namespace', code: "await docs('cli/api');"},
|
|
137
|
+
{label: 'One API function', code: "await docs('cli/api/functions/search');"},
|
|
138
|
+
{
|
|
139
|
+
label: 'A whole guide from the docs tree',
|
|
140
|
+
code: "await docs('cli/integrations');",
|
|
141
|
+
},
|
|
120
142
|
{label: 'One section by key', code: "await docs('tokens', 'spacing');"},
|
|
121
143
|
],
|
|
122
144
|
command: 'docs',
|
package/api/docs/docs.mjs
CHANGED
|
@@ -3,27 +3,35 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* @file Programmatic API for the docs command.
|
|
5
5
|
*
|
|
6
|
-
* Dispatcher + barrel. `docs()` routes by argument shape into one of
|
|
6
|
+
* Dispatcher + barrel. `docs()` routes by argument shape into one of five
|
|
7
7
|
* leaves, each projecting into a single { type, data } envelope:
|
|
8
8
|
*
|
|
9
9
|
* docs() -> list -> docs.list
|
|
10
10
|
* docs(topic) -> detail -> docs.detail
|
|
11
11
|
* docs(topic, undefined, {index: true}) -> index -> docs.index
|
|
12
12
|
* docs(topic, section) -> section -> docs.detail.section
|
|
13
|
+
* docs(route) -> node -> docs.node
|
|
13
14
|
*
|
|
14
|
-
* A topic read returns the whole doc, as it always has
|
|
15
|
-
* reader
|
|
16
|
-
*
|
|
17
|
-
* the
|
|
18
|
-
*
|
|
15
|
+
* A topic read returns the whole doc, as it always has; `index` returns its
|
|
16
|
+
* sections, so a reader can open one by its key (spec:AST-047). The CLI's text
|
|
17
|
+
* view lists the sections by default. A route names a node
|
|
18
|
+
* of the docs tree (spec:AST-046): a namespace lists its children, a guide the
|
|
19
|
+
* tree places reads like any topic, and a typed doc prints its content. The
|
|
20
|
+
* leaves
|
|
21
|
+
* live in list/, index/, detail/, detail/section/, and node/; the discovery,
|
|
22
|
+
* overlay loading, and resolution they share sit in _adapter.mjs.
|
|
19
23
|
*/
|
|
20
24
|
|
|
21
25
|
import {list} from './list/list.mjs';
|
|
22
26
|
import {index} from './index/index.mjs';
|
|
23
27
|
import {detail} from './detail/detail.mjs';
|
|
24
28
|
import {section as sectionLeaf} from './detail/section/section.mjs';
|
|
29
|
+
import {node as nodeLeaf, nodeView} from './node/node.mjs';
|
|
30
|
+
import {resolveDocsArgument} from './_adapter.mjs';
|
|
31
|
+
import {AstryxError} from '../error.mjs';
|
|
32
|
+
import {ERROR_CODES} from '../../foundation/response/error-codes.mjs';
|
|
25
33
|
|
|
26
|
-
export {list, index, detail, sectionLeaf as section};
|
|
34
|
+
export {list, index, detail, sectionLeaf as section, nodeLeaf as node};
|
|
27
35
|
|
|
28
36
|
/**
|
|
29
37
|
* @param {string} [topic]
|
|
@@ -39,11 +47,39 @@ export {list, index, detail, sectionLeaf as section};
|
|
|
39
47
|
* import('./docs.type.mjs').DocsListResponse |
|
|
40
48
|
* import('./docs.type.mjs').DocsIndexResponse |
|
|
41
49
|
* import('./docs.type.mjs').DocsDetailResponse |
|
|
42
|
-
* import('./docs.type.mjs').DocsDetailSectionResponse
|
|
50
|
+
* import('./docs.type.mjs').DocsDetailSectionResponse |
|
|
51
|
+
* import('./docs.type.mjs').DocsNodeResponse
|
|
43
52
|
* >}
|
|
44
53
|
*/
|
|
45
54
|
export async function docs(topic, section, options = {}) {
|
|
46
55
|
if (!topic) return list(options);
|
|
56
|
+
const found = await resolveDocsArgument(topic, options);
|
|
57
|
+
if (found.kind === 'node') {
|
|
58
|
+
// A namespace or a typed doc has no sections: it is one read. `--index`
|
|
59
|
+
// asks for what the node read already is.
|
|
60
|
+
if (section) {
|
|
61
|
+
throw new AstryxError(
|
|
62
|
+
`"${found.node.route}" has no sections. ${
|
|
63
|
+
found.node.kind === 'namespace'
|
|
64
|
+
? 'Open one of its children instead.'
|
|
65
|
+
: `Read it whole: astryx docs ${found.node.route}.`
|
|
66
|
+
}`,
|
|
67
|
+
found.node.kind === 'namespace'
|
|
68
|
+
? found.node.slots.flatMap(slot =>
|
|
69
|
+
slot.children.map(route => ({
|
|
70
|
+
name: route,
|
|
71
|
+
reason: found.tree.get(route)?.summary ?? '',
|
|
72
|
+
})),
|
|
73
|
+
)
|
|
74
|
+
: [{name: found.node.route, reason: found.node.summary}],
|
|
75
|
+
ERROR_CODES.ERR_UNKNOWN_SECTION,
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
type: 'docs.node',
|
|
80
|
+
data: await nodeView(found.catalog, found.tree, found.node),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
47
83
|
if (section) return sectionLeaf(topic, section, options);
|
|
48
84
|
if (options.index) return index(topic, options);
|
|
49
85
|
return detail(topic, options);
|
package/api/docs/docs.test.mjs
CHANGED
|
@@ -26,11 +26,9 @@ describe('docs() dispatcher routing', () => {
|
|
|
26
26
|
expect((await docs('')).type).toBe('docs.list');
|
|
27
27
|
}, SLOW);
|
|
28
28
|
|
|
29
|
-
it('topic only -> docs.detail', async () => {
|
|
29
|
+
it('topic only -> docs.detail, the whole doc', async () => {
|
|
30
30
|
const {data} = await docs();
|
|
31
|
-
|
|
32
|
-
const r = await docs(topic);
|
|
33
|
-
expect(r.type).toBe('docs.detail');
|
|
31
|
+
expect((await docs(data[0].topic)).type).toBe('docs.detail');
|
|
34
32
|
}, SLOW);
|
|
35
33
|
|
|
36
34
|
it('topic + index -> docs.index', async () => {
|
|
@@ -69,6 +67,162 @@ describe('docs() dispatcher routing', () => {
|
|
|
69
67
|
});
|
|
70
68
|
}, SLOW);
|
|
71
69
|
|
|
70
|
+
it("lists the docs tree's namespaces in meta, so every data entry reads as a topic", async () => {
|
|
71
|
+
const res = await docs();
|
|
72
|
+
expect(res.meta.namespaces.map(entry => entry.topic)).toEqual(['cli', 'unorganized']);
|
|
73
|
+
for (const entry of res.data) {
|
|
74
|
+
expect((await docs(entry.topic)).type).toBe('docs.detail');
|
|
75
|
+
}
|
|
76
|
+
}, SLOW);
|
|
77
|
+
|
|
78
|
+
it('opens a route typed in another case', async () => {
|
|
79
|
+
const r = await docs('CLI/API');
|
|
80
|
+
expect(r.type).toBe('docs.node');
|
|
81
|
+
expect(r.data).toMatchObject({route: 'cli/api', links: {up: 'astryx docs cli'}});
|
|
82
|
+
}, SLOW);
|
|
83
|
+
|
|
84
|
+
it('a section of a typed doc -> ERR_UNKNOWN_SECTION, suggesting the doc itself', async () => {
|
|
85
|
+
const err = await docs('cli/api/functions/search', 'x').catch(e => e);
|
|
86
|
+
expect(err.code).toBe('ERR_UNKNOWN_SECTION');
|
|
87
|
+
expect(err.message).toContain('astryx docs cli/api/functions/search');
|
|
88
|
+
expect(err.suggestions.map(s => s.name)).toEqual(['cli/api/functions/search']);
|
|
89
|
+
}, SLOW);
|
|
90
|
+
|
|
91
|
+
it('a namespace route -> docs.node, one level of children', async () => {
|
|
92
|
+
const r = await docs('cli/api');
|
|
93
|
+
expect(r.type).toBe('docs.node');
|
|
94
|
+
expect(r.data).toMatchObject({
|
|
95
|
+
id: 'astryx:artifact:v1/%40astryxdesign%2Fcli/namespace/api',
|
|
96
|
+
route: 'cli/api',
|
|
97
|
+
kind: 'namespace',
|
|
98
|
+
package: '@astryxdesign/cli',
|
|
99
|
+
breadcrumb: [{route: 'cli', title: 'Astryx CLI'}],
|
|
100
|
+
content: [],
|
|
101
|
+
});
|
|
102
|
+
expect(r.data.slots.flatMap(slot => slot.children.map(c => c.route))).toEqual([
|
|
103
|
+
'cli/api/functions',
|
|
104
|
+
'cli/api/schemas',
|
|
105
|
+
'cli/api/enums',
|
|
106
|
+
]);
|
|
107
|
+
}, SLOW);
|
|
108
|
+
|
|
109
|
+
it('a typed doc route -> docs.node with its content', async () => {
|
|
110
|
+
const r = await docs('cli/api/functions/search');
|
|
111
|
+
expect(r.type).toBe('docs.node');
|
|
112
|
+
expect(r.data).toMatchObject({
|
|
113
|
+
id: 'astryx:artifact:v1/%40astryxdesign%2Fcli/function/search',
|
|
114
|
+
kind: 'function',
|
|
115
|
+
title: 'search()',
|
|
116
|
+
slots: [],
|
|
117
|
+
});
|
|
118
|
+
expect(r.data.breadcrumb.map(link => link.route)).toEqual([
|
|
119
|
+
'cli',
|
|
120
|
+
'cli/api',
|
|
121
|
+
'cli/api/functions',
|
|
122
|
+
]);
|
|
123
|
+
expect(JSON.stringify(r.data.content)).toContain(
|
|
124
|
+
'`astryx search` runs it. Read it with `astryx docs cli/commands/search`.',
|
|
125
|
+
);
|
|
126
|
+
}, SLOW);
|
|
127
|
+
|
|
128
|
+
it('a guide the tree places reads like a topic: the whole doc, its index, a section', async () => {
|
|
129
|
+
expect((await docs('cli/integrations')).type).toBe('docs.detail');
|
|
130
|
+
const index = await docs('cli/integrations', undefined, {index: true});
|
|
131
|
+
expect(index).toMatchObject({type: 'docs.index', data: {name: 'cli/integrations'}});
|
|
132
|
+
expect(index.data.sections.length).toBeGreaterThan(1);
|
|
133
|
+
expect((await docs('cli/integrations', 'components')).type).toBe(
|
|
134
|
+
'docs.detail.section',
|
|
135
|
+
);
|
|
136
|
+
}, SLOW);
|
|
137
|
+
|
|
138
|
+
it('every read carries its moves (spec:AST-047)', async () => {
|
|
139
|
+
const root = (await docs('cli')).data;
|
|
140
|
+
expect(root.links).toEqual({up: 'astryx docs'});
|
|
141
|
+
const leaf = (await docs('cli/api/functions/search')).data;
|
|
142
|
+
expect(leaf.links.up).toBe('astryx docs cli/api/functions');
|
|
143
|
+
expect(leaf.links.previous).toMatch(/^astryx docs cli\/api\/functions\/[a-z-]+$/);
|
|
144
|
+
expect(leaf.links.next).toMatch(/^astryx docs cli\/api\/functions\/[a-z-]+$/);
|
|
145
|
+
const index = await docs('cli/integrations', undefined, {index: true});
|
|
146
|
+
// A guide moves across its namespace's slot, as any tree node does.
|
|
147
|
+
expect(index.data.links).toEqual({
|
|
148
|
+
up: 'astryx docs cli',
|
|
149
|
+
next: 'astryx docs cli/writing-docs',
|
|
150
|
+
});
|
|
151
|
+
const first = (await docs('cli/integrations', index.data.sections[0].id)).data;
|
|
152
|
+
expect(first.links).toEqual({
|
|
153
|
+
up: 'astryx docs cli/integrations --index',
|
|
154
|
+
next: `astryx docs cli/integrations ${index.data.sections[1].id}`,
|
|
155
|
+
});
|
|
156
|
+
const last = index.data.sections.at(-1).id;
|
|
157
|
+
const end = (await docs('cli/integrations', last)).data;
|
|
158
|
+
expect(end.links.next).toBeUndefined();
|
|
159
|
+
expect(end.links.previous).toBe(
|
|
160
|
+
`astryx docs cli/integrations ${index.data.sections.at(-2).id}`,
|
|
161
|
+
);
|
|
162
|
+
// A flat topic's home is the Unorganized level, and it moves across it.
|
|
163
|
+
const flat = (await docs('principles')).data.links;
|
|
164
|
+
expect(flat.up).toBe('astryx docs unorganized');
|
|
165
|
+
expect(flat.previous).toMatch(/^astryx docs [a-z-]+$/);
|
|
166
|
+
expect(flat.next).toMatch(/^astryx docs [a-z-]+$/);
|
|
167
|
+
const home = (await docs('unorganized')).data;
|
|
168
|
+
expect(home).toMatchObject({id: null, kind: 'namespace', links: {up: 'astryx docs'}});
|
|
169
|
+
expect(home.slots[0].children.map(child => child.route)).toEqual(
|
|
170
|
+
(await docs()).data.map(entry => entry.topic),
|
|
171
|
+
);
|
|
172
|
+
}, SLOW);
|
|
173
|
+
|
|
174
|
+
it('names a node by its doc identity; a generated level has id null', async () => {
|
|
175
|
+
const level = (await docs('cli/api/functions')).data;
|
|
176
|
+
expect(level).toHaveProperty('id', null);
|
|
177
|
+
expect(level.route).toBe('cli/api/functions');
|
|
178
|
+
}, SLOW);
|
|
179
|
+
|
|
180
|
+
it("offers a typed doc's related docs as moves", async () => {
|
|
181
|
+
const fn = (await docs('cli/api/functions/search')).data;
|
|
182
|
+
expect(fn.links.related).toContain('astryx docs cli/commands/search');
|
|
183
|
+
const cmd = (await docs('cli/commands/search')).data;
|
|
184
|
+
expect(cmd.links.related).toContain('astryx docs cli/api/functions/search');
|
|
185
|
+
}, SLOW);
|
|
186
|
+
|
|
187
|
+
it('a topic read returns the whole doc; index returns its sections', async () => {
|
|
188
|
+
expect((await docs('principles')).type).toBe('docs.detail');
|
|
189
|
+
const index = await docs('principles', undefined, {index: true});
|
|
190
|
+
expect(index.type).toBe('docs.index');
|
|
191
|
+
expect(index.data.sections.length).toBeGreaterThan(1);
|
|
192
|
+
expect((await docs('principles', undefined, {dense: true})).type).toBe(
|
|
193
|
+
'docs.detail',
|
|
194
|
+
);
|
|
195
|
+
}, SLOW);
|
|
196
|
+
|
|
197
|
+
it("the guide's old flat name is gone, and its error names the new route", async () => {
|
|
198
|
+
await expect(docs('cli-integrations')).rejects.toMatchObject({
|
|
199
|
+
code: 'ERR_UNKNOWN_TOPIC',
|
|
200
|
+
suggestions: [expect.objectContaining({name: 'cli/integrations'})],
|
|
201
|
+
});
|
|
202
|
+
expect((await docs()).data.map(entry => entry.topic)).not.toContain(
|
|
203
|
+
'cli-integrations',
|
|
204
|
+
);
|
|
205
|
+
}, SLOW);
|
|
206
|
+
|
|
207
|
+
it('a section of a namespace -> ERR_UNKNOWN_SECTION, naming its children', async () => {
|
|
208
|
+
const err = await docs('cli', 'commands').catch(e => e);
|
|
209
|
+
expect(err).toBeInstanceOf(AstryxError);
|
|
210
|
+
expect(err.code).toBe('ERR_UNKNOWN_SECTION');
|
|
211
|
+
expect(err.suggestions.map(s => s.name)).toEqual([
|
|
212
|
+
'cli/integrations',
|
|
213
|
+
'cli/writing-docs',
|
|
214
|
+
'cli/commands',
|
|
215
|
+
'cli/api',
|
|
216
|
+
]);
|
|
217
|
+
}, SLOW);
|
|
218
|
+
|
|
219
|
+
it('an unknown route suggests the children of the deepest namespace it reaches', async () => {
|
|
220
|
+
const err = await docs('cli/api/functions/serch').catch(e => e);
|
|
221
|
+
expect(err.code).toBe('ERR_UNKNOWN_TOPIC');
|
|
222
|
+
expect(err.suggestions.map(s => s.name)).toContain('cli/api/functions/search');
|
|
223
|
+
expect(err.suggestions.every(s => s.name.startsWith('cli/api/functions/'))).toBe(true);
|
|
224
|
+
}, SLOW);
|
|
225
|
+
|
|
72
226
|
it('non-string topic -> ERR_UNKNOWN_TOPIC (not a raw TypeError)', async () => {
|
|
73
227
|
for (const bad of [123, {}, ['tokens'], true]) {
|
|
74
228
|
const err = await docs(/** @type {any} */ (bad)).catch(e => e);
|