@astryxdesign/cli 0.7.2 → 0.7.3-canary.02f5fe4
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 +104 -71
- package/api/build/_adapter.d.mts +58 -0
- package/api/build/_adapter.mjs +127 -3
- package/api/build/blocks/blocks.d.mts +92 -0
- package/api/build/blocks/blocks.mjs +528 -0
- package/api/build/blocks/blocks.test.mjs +238 -0
- package/api/build/blocks/blocks.weights.json +1 -0
- package/api/build/build.mjs +25 -6
- package/api/build/build.type.mjs +1 -1
- package/api/build/kit/answer.d.mts +18 -0
- package/api/build/kit/answer.mjs +195 -0
- package/api/build/kit/answer.test.mjs +108 -0
- package/api/build/kit/kind.d.mts +25 -0
- package/api/build/kit/kind.mjs +170 -0
- package/api/build/kit/kit.d.mts +2 -4
- package/api/build/kit/kit.mjs +8 -398
- package/api/build/kit/rank.d.mts +3 -32
- package/api/build/kit/rank.mjs +25 -342
- package/api/build/kit/rank.test.mjs +2 -1
- package/api/build/kit/signals.d.mts +79 -0
- package/api/build/kit/signals.mjs +295 -0
- package/api/build/kit/start.d.mts +32 -0
- package/api/build/kit/start.mjs +163 -0
- package/api/build/kit/words.d.mts +72 -0
- package/api/build/kit/words.mjs +202 -0
- package/api/build/tree.d.mts +20 -0
- package/api/build/tree.mjs +53 -0
- package/api/build/tree.test.mjs +185 -0
- package/api/build/tree.weights.json +1 -0
- package/api/component/_adapter.mjs +39 -5
- package/api/component/component-replacement.test.mjs +1 -0
- package/api/component/component.mjs +17 -3
- package/api/component/component.test.mjs +15 -0
- package/api/component/doc-links.test.mjs +2 -2
- package/api/discover/_adapter.d.mts +1 -2
- package/api/discover/_adapter.mjs +42 -17
- package/api/discover/_adapter.test.mjs +42 -0
- package/api/discover/discover.mjs +0 -1
- package/api/docs/_adapter.d.mts +2 -2
- package/api/docs/_adapter.mjs +82 -23
- package/api/docs/docs-homes.test.mjs +127 -0
- package/api/docs/docs.doc.mjs +3 -3
- package/api/docs/docs.test.mjs +35 -19
- package/api/docs/integration-tree.test.mjs +20 -20
- package/api/docs/integrationDocs.test.mjs +1 -1
- package/api/docs/namespace-section.test.mjs +6 -6
- package/api/docs/reference-blocks.test.mjs +2 -2
- package/api/doctor/_adapter.d.mts +33 -13
- package/api/doctor/_adapter.mjs +55 -25
- package/api/doctor/doctor.d.mts +23 -5
- package/api/doctor/doctor.mjs +183 -40
- package/api/doctor/doctor.test.mjs +95 -12
- package/api/hook/hook.mjs +1 -1
- package/api/init/init.doc.mjs +20 -6
- package/api/init/init.test.mjs +18 -2
- package/api/init/init.type.d.mts +3 -3
- package/api/init/init.type.mjs +3 -3
- package/api/init/remove/remove.mjs +17 -4
- package/api/init/remove/remove.test.mjs +114 -2
- package/api/init/run/run.mjs +69 -6
- package/api/integration/_adapter.d.mts +8 -0
- package/api/integration/_adapter.mjs +21 -1
- package/api/integration/authoring-checks.mjs +83 -9
- package/api/integration/authoring-checks.test.mjs +220 -0
- package/api/integration/pack-check.mjs +123 -4
- package/api/integration/pack-check.test.mjs +87 -0
- package/api/integration/validate-integration-case-disk.test.mjs +111 -0
- package/api/integration/validate-integration-fixes.test.mjs +6 -5
- package/api/integration/validate-integration-gaps.test.mjs +1975 -0
- package/api/integration/validate-integration.d.mts +15 -2
- package/api/integration/validate-integration.mjs +298 -39
- package/api/integration/validate-integration.type.d.mts +90 -1
- package/api/integration/validate-integration.type.mjs +67 -2
- package/api/integration/validateIntegration.doc.mjs +1 -1
- package/api/search/ORDERING.md +28 -0
- package/api/search/_adapter.d.mts +82 -2
- package/api/search/_adapter.mjs +157 -10
- package/api/search/_adapter.test.mjs +173 -0
- package/api/search/_candidate-score.d.mts +40 -0
- package/api/search/_candidate-score.mjs +238 -0
- package/api/search/_cards.json +6098 -0
- package/api/search/_compound.d.mts +50 -0
- package/api/search/_compound.mjs +170 -0
- package/api/search/_doc-searcher.d.mts +4 -0
- package/api/search/_doc-searcher.mjs +23 -0
- package/api/search/_doc-searcher.test.mjs +36 -0
- package/api/search/_doc-searcher.weights.json +1 -0
- package/api/search/_doc-text.d.mts +30 -0
- package/api/search/_doc-text.mjs +87 -0
- package/api/search/_entries.d.mts +63 -0
- package/api/search/_entries.mjs +232 -0
- package/api/search/_entries.test.mjs +48 -0
- package/api/search/_features.d.mts +35 -0
- package/api/search/_features.mjs +155 -0
- package/api/search/_gather-components.d.mts +26 -0
- package/api/search/_gather-components.mjs +284 -0
- package/api/search/_gather-docs.d.mts +20 -0
- package/api/search/_gather-docs.mjs +254 -0
- package/api/search/_gather-hooks.d.mts +12 -0
- package/api/search/_gather-hooks.mjs +52 -0
- package/api/search/_gather-templates.d.mts +25 -0
- package/api/search/_gather-templates.mjs +107 -0
- package/api/search/_lexical.d.mts +135 -0
- package/api/search/_lexical.mjs +351 -0
- package/api/search/_main-searcher.d.mts +19 -0
- package/api/search/_main-searcher.mjs +115 -0
- package/api/search/_main-searcher.test.mjs +106 -0
- package/api/search/_main-searcher.weights.json +1 -0
- package/api/search/_module-doc.d.mts +32 -0
- package/api/search/_module-doc.mjs +78 -0
- package/api/search/_order.d.mts +32 -0
- package/api/search/_order.mjs +162 -0
- package/api/search/_order.test.mjs +72 -0
- package/api/search/_priority.d.mts +50 -0
- package/api/search/_priority.mjs +139 -0
- package/api/search/_query-words.d.mts +25 -0
- package/api/search/_query-words.mjs +92 -0
- package/api/search/_query.d.mts +65 -0
- package/api/search/_query.mjs +176 -0
- package/api/search/_result.d.mts +97 -0
- package/api/search/_result.mjs +150 -0
- package/api/search/_score.d.mts +60 -0
- package/api/search/_score.mjs +283 -0
- package/api/search/_synonyms.d.mts +21 -0
- package/api/search/_synonyms.mjs +67 -0
- package/api/search/_template-searcher.d.mts +4 -0
- package/api/search/_template-searcher.mjs +23 -0
- package/api/search/_template-searcher.test.mjs +40 -0
- package/api/search/_template-searcher.weights.json +1 -0
- package/api/search/_titles.d.mts +33 -0
- package/api/search/_titles.mjs +65 -0
- package/api/search/_words.d.mts +64 -0
- package/api/search/_words.mjs +157 -0
- package/api/search/search.d.mts +22 -305
- package/api/search/search.doc.mjs +8 -6
- package/api/search/search.mjs +56 -2482
- package/api/search/search.test.mjs +14 -14
- package/api/search/search.type.d.mts +6 -1
- package/api/search/search.type.mjs +6 -1
- package/api/search/tree.d.mts +15 -0
- package/api/search/tree.mjs +40 -0
- package/api/search/tree.test.mjs +66 -0
- package/api/search/tree.weights.json +1 -0
- package/api/template/template.mjs +5 -1
- package/api/theme/build/build.packed-old-core.test.mjs +1 -0
- package/api/upgrade/_adapter.d.mts +57 -9
- package/api/upgrade/_adapter.mjs +198 -28
- package/api/upgrade/registry/registry.d.mts +10 -4
- package/api/upgrade/registry/registry.mjs +33 -16
- package/api/upgrade/registry/registry.test.mjs +85 -0
- package/api/upgrade/run/run.d.mts +4 -2
- package/api/upgrade/run/run.mjs +13 -2
- package/api/upgrade/run/run.test.mjs +417 -3
- package/api/upgrade/upgrade.doc.mjs +10 -5
- package/api/upgrade/upgrade.mjs +13 -2
- package/api/upgrade/upgrade.test.mjs +194 -0
- package/api/upgrade/upgrade.type.d.mts +5 -3
- package/api/upgrade/upgrade.type.mjs +8 -6
- package/assets/codemods/transforms/v0.7.0/__tests__/validate-data-token-ownership.test.mjs +11 -0
- package/assets/codemods/transforms/v0.7.0/validate-data-token-ownership.mjs +3 -3
- package/assets/docs/author-a-theme.doc.mjs +2 -2
- package/assets/docs/is-my-code-good.doc.mjs +287 -0
- package/assets/docs/tree/add-a-component.doc.mjs +1 -1
- package/assets/docs/tree/add-a-theme.doc.mjs +1 -1
- package/assets/docs/tree/add-a-topic.doc.mjs +2 -2
- package/assets/docs/tree/agent-guidance.doc.mjs +1 -1
- package/assets/docs/tree/api.doc.mjs +6 -0
- package/assets/docs/tree/{integrations.doc.mjs → authoring.doc.mjs} +15 -6
- package/assets/docs/tree/block-template.doc.mjs +1 -1
- package/assets/docs/tree/build-the-template.doc.mjs +1 -1
- package/assets/docs/tree/building-blocks.doc.mjs +2 -2
- package/assets/docs/tree/check-the-props.doc.mjs +1 -1
- package/assets/docs/tree/check-your-docs.doc.mjs +2 -2
- package/assets/docs/tree/checks.doc.mjs +3 -3
- package/assets/docs/tree/ci-and-containers.doc.mjs +13 -0
- package/assets/docs/tree/cli-command.doc.mjs +1 -1
- package/assets/docs/tree/cli.doc.mjs +1 -1
- package/assets/docs/tree/codemods.doc.mjs +1 -1
- package/assets/docs/tree/component-family.doc.mjs +1 -1
- package/assets/docs/tree/component-imports.doc.mjs +1 -1
- package/assets/docs/tree/components.doc.mjs +1 -1
- package/assets/docs/tree/configuration.doc.mjs +1 -1
- package/assets/docs/tree/debug-and-gap-reports.doc.mjs +1 -1
- package/assets/docs/tree/define-the-theme.doc.mjs +1 -1
- package/assets/docs/tree/describe-the-component.doc.mjs +1 -1
- package/assets/docs/tree/docs.doc.mjs +1 -1
- package/assets/docs/tree/document-the-template.doc.mjs +1 -1
- package/assets/docs/tree/document-the-theme.doc.mjs +1 -1
- package/assets/docs/tree/export-template-assets.doc.mjs +1 -1
- package/assets/docs/tree/extend-or-replace.doc.mjs +1 -1
- package/assets/docs/{authoring.doc.mjs → tree/field-reference.doc.mjs} +4 -3
- package/assets/docs/tree/fonts-and-assets.doc.mjs +1 -1
- package/assets/docs/tree/generate-a-palette.doc.mjs +1 -1
- package/assets/docs/tree/global-integrations.doc.mjs +2 -2
- package/assets/docs/tree/grade-template-with-agent.doc.mjs +4 -4
- package/assets/docs/tree/help.doc.mjs +2 -2
- package/assets/docs/tree/host-entry.doc.mjs +128 -0
- package/assets/docs/tree/links.doc.mjs +1 -1
- package/assets/docs/tree/package-and-test.doc.mjs +1 -1
- package/assets/docs/tree/page-template.doc.mjs +1 -1
- package/assets/docs/tree/publishing.doc.mjs +1 -1
- package/assets/docs/tree/quick-start.doc.mjs +1 -1
- package/assets/docs/tree/replace-a-core-component.doc.mjs +1 -1
- package/assets/docs/tree/replace-a-core-template.doc.mjs +1 -1
- package/assets/docs/tree/sections-and-placement.doc.mjs +1 -1
- package/assets/docs/tree/see-it-in-an-app.doc.mjs +1 -1
- package/assets/docs/tree/ship.doc.mjs +2 -2
- package/assets/docs/tree/short-and-findable.doc.mjs +1 -1
- package/assets/docs/tree/single-component.doc.mjs +1 -1
- package/assets/docs/tree/start-a-template.doc.mjs +1 -1
- package/assets/docs/tree/subcomponent.doc.mjs +1 -1
- package/assets/docs/tree/template-assets.doc.mjs +1 -1
- package/assets/docs/tree/template-doc-overview.doc.mjs +2 -2
- package/assets/docs/tree/template-fonts.doc.mjs +1 -1
- package/assets/docs/tree/template-grading-rubric.doc.mjs +17 -38
- 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 +1 -1
- package/assets/docs/tree/templates.doc.mjs +1 -1
- package/assets/docs/tree/test-in-an-app.doc.mjs +1 -1
- package/assets/docs/tree/test-template-in-app.doc.mjs +1 -1
- package/assets/docs/tree/themes.doc.mjs +1 -1
- package/assets/docs/tree/tokens-data.doc.mjs +2 -2
- package/assets/docs/tree/troubleshooting.doc.mjs +1 -1
- package/assets/docs/tree/upgrading.doc.mjs +1 -1
- package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +1 -1
- package/assets/docs/tree/verify-packed-template.doc.mjs +1 -1
- package/assets/docs/tree/versioning.doc.mjs +5 -1
- package/assets/docs/tree/write-good-templates.doc.mjs +1 -1
- package/assets/docs/tree/write-the-template-file.doc.mjs +1 -1
- package/assets/docs/use-integrations.doc.mjs +120 -0
- package/assets/docs/working-with-ai.doc.mjs +6 -2
- package/assets/templates/themes/butter/butterTheme.ts +4 -2
- package/assets/templates/themes/stone/stoneTheme.ts +4 -2
- package/assets/templates/themes/y2k/y2kTheme.ts +4 -2
- package/authoring/debug/parse.d.mts +1 -1
- package/authoring/doctypes/schema/schema.doc.mjs +1 -1
- package/authoring/integration/integration.doc.mjs +1 -1
- package/authoring/integration/type.ts +1 -1
- package/clients/cli/bin/astryx.mjs +7 -78
- package/clients/cli/command-result-coverage.test.mjs +6 -5
- package/clients/cli/commands/build-theme.color-scheme.test.mjs +1 -1
- package/clients/cli/commands/{component/index.mjs → component.mjs} +37 -37
- package/clients/cli/commands/component.test.mjs +6 -6
- package/clients/cli/commands/docs.doc.mjs +2 -2
- package/clients/cli/commands/docs.mjs +1 -1
- package/clients/cli/commands/docs.test.mjs +14 -14
- package/clients/cli/commands/doctor-integration.test.mjs +49 -1
- package/clients/cli/commands/doctor.doc.mjs +1 -1
- package/clients/cli/commands/doctor.mjs +40 -0
- package/clients/cli/commands/doctor.test.mjs +65 -0
- package/clients/cli/commands/{hook/index.mjs → hook.mjs} +22 -22
- package/clients/cli/commands/import-hint-correctness.test.mjs +1 -1
- package/clients/cli/commands/init.behavior.test.mjs +230 -1
- package/clients/cli/commands/init.doc.mjs +28 -9
- package/clients/cli/commands/init.flag-help.test.mjs +1 -0
- package/clients/cli/commands/init.mjs +2 -2
- package/clients/cli/commands/integration-check.test.mjs +48 -0
- package/clients/cli/commands/integration.doc.mjs +1 -1
- package/clients/cli/commands/manifest.doc.mjs +1 -1
- package/clients/cli/commands/manifest.mjs +67 -0
- package/clients/cli/commands/outside-project.test.mjs +101 -1
- package/clients/cli/commands/postinstall.doc.mjs +23 -0
- package/clients/cli/commands/postinstall.mjs +31 -0
- package/clients/cli/commands/setup-nudge.test.mjs +78 -0
- package/clients/cli/commands/{build-theme.mjs → theme.mjs} +1 -1
- package/clients/cli/commands/upgrade.doc.mjs +4 -2
- package/clients/cli/commands/upgrade.mjs +9 -2
- package/clients/cli/commands/upgrade.subfolder-path.test.mjs +97 -0
- package/clients/cli/index.mjs +54 -94
- package/clients/cli/lib/component-format.mjs +1 -1
- package/clients/cli/lib/define-command.mjs +12 -7
- package/clients/cli/lib/exit-codes.test.mjs +5 -0
- package/clients/cli/lib/manifest.test.mjs +12 -0
- package/clients/cli/lib/welcome-box.mjs +50 -0
- package/clients/cli/run.mjs +108 -0
- package/foundation/agent-docs/agent-doc-state.d.mts +32 -7
- package/foundation/agent-docs/agent-doc-state.mjs +58 -9
- package/foundation/agent-docs/agent-docs.d.mts +100 -12
- package/foundation/agent-docs/agent-docs.mjs +1017 -105
- package/foundation/agent-docs/agent-docs.path-safety.test.mjs +1239 -17
- package/foundation/agent-docs/agent-docs.test.mjs +683 -39
- package/foundation/agent-docs/computer-agent-text.d.mts +39 -2
- package/foundation/agent-docs/computer-agent-text.mjs +135 -8
- package/foundation/agent-docs/computer-agent-text.test.mjs +99 -2
- package/foundation/config/project.mjs +20 -22
- package/foundation/config/project.test.mjs +56 -0
- package/foundation/discovery/authoring-self-docs.d.mts +7 -0
- package/foundation/discovery/authoring-self-docs.mjs +16 -4
- package/foundation/discovery/authoring-self-docs.test.mjs +15 -3
- package/foundation/discovery/authoring-surface.d.mts +1 -1
- package/foundation/discovery/authoring-surface.mjs +2 -2
- package/foundation/discovery/authoring-surface.test.mjs +1 -1
- package/foundation/discovery/cli-self-docs.d.mts +2 -1
- package/foundation/discovery/cli-self-docs.mjs +4 -3
- package/foundation/discovery/cli-self-docs.test.mjs +2 -2
- package/foundation/discovery/component-discovery.d.mts +37 -0
- package/foundation/discovery/component-discovery.mjs +80 -5
- package/foundation/discovery/component-loader.d.mts +1 -1
- package/foundation/discovery/docs-discovery.mjs +14 -1
- package/foundation/discovery/module-exports.d.mts +41 -0
- package/foundation/discovery/module-exports.mjs +253 -0
- package/foundation/discovery/runner-allowlist.d.mts +2 -4
- package/foundation/discovery/runner-allowlist.mjs +2 -4
- package/foundation/discovery/runner-commands.d.mts +77 -0
- package/foundation/discovery/runner-commands.mjs +294 -0
- package/foundation/discovery/runner-commands.test.mjs +128 -0
- package/foundation/discovery/stray-pointers.test.mjs +1 -1
- package/foundation/discovery/template-adapter.mjs +18 -1
- package/foundation/discovery/template-needs.mjs +1 -44
- package/foundation/discovery/theme-discovery.mjs +147 -3
- package/foundation/doc-compiler/doc-loads.test.mjs +33 -9
- package/foundation/doc-compiler/read.mjs +59 -1
- package/foundation/doc-compiler/read.test.mjs +11 -2
- package/foundation/doc-compiler/split-topic-keywords.test.mjs +3 -2
- package/foundation/doc-compiler/tree.d.mts +32 -6
- package/foundation/doc-compiler/tree.mjs +77 -43
- package/foundation/doc-compiler/tree.test.mjs +7 -7
- package/foundation/fs/paths.d.mts +70 -8
- package/foundation/fs/paths.mjs +556 -38
- package/foundation/fs/paths.test.mjs +430 -54
- package/foundation/fs/read-record.d.mts +18 -0
- package/foundation/fs/read-record.mjs +131 -0
- package/foundation/fs/read-record.test.mjs +77 -0
- package/foundation/integrations/autolink.d.mts +2 -1
- package/foundation/integrations/autolink.mjs +4 -13
- package/foundation/integrations/cli-peer-version.d.mts +36 -0
- package/foundation/integrations/cli-peer-version.mjs +132 -0
- package/foundation/integrations/cli-peer-version.test.mjs +354 -0
- package/foundation/integrations/computer-integrations.d.mts +6 -3
- package/foundation/integrations/computer-integrations.mjs +38 -9
- package/foundation/integrations/contribution-inventory.d.mts +15 -20
- package/foundation/integrations/contribution-inventory.mjs +41 -5
- package/foundation/integrations/exports-subpaths.d.mts +57 -0
- package/foundation/integrations/exports-subpaths.mjs +113 -0
- package/foundation/integrations/integrations.d.mts +27 -1
- package/foundation/integrations/integrations.mjs +61 -2
- package/foundation/integrations/public-imports.d.mts +118 -0
- package/foundation/integrations/public-imports.mjs +1769 -0
- package/foundation/integrations/public-imports.test.mjs +1793 -0
- package/foundation/integrations/validate-contributions.d.mts +115 -0
- package/foundation/integrations/validate-contributions.mjs +1168 -13
- package/foundation/release/cache.test.mjs +24 -21
- package/foundation/release/global-state.d.mts +8 -4
- package/foundation/release/global-state.mjs +4 -2
- package/foundation/release/handoff.d.mts +23 -4
- package/foundation/release/handoff.mjs +175 -8
- package/foundation/release/notices.d.mts +62 -8
- package/foundation/release/notices.mjs +136 -25
- package/foundation/release/notices.test.mjs +21 -0
- package/foundation/release/run-context.mjs +14 -0
- package/foundation/response/response-types.doc.mjs +1 -1
- package/foundation/route/route.d.mts +285 -0
- package/foundation/route/route.mjs +324 -0
- package/foundation/route/route.test.mjs +153 -0
- package/foundation/runtime/hosted-runtime.test.mjs +403 -0
- package/foundation/runtime/locked-versions.d.mts +32 -0
- package/foundation/runtime/locked-versions.mjs +65 -0
- package/foundation/runtime/package-root.d.mts +91 -0
- package/foundation/runtime/package-root.mjs +174 -0
- package/foundation/runtime/package-set.d.mts +62 -0
- package/foundation/runtime/package-set.mjs +130 -0
- package/foundation/runtime/package-set.test.mjs +432 -0
- package/foundation/text/string-utils.d.mts +2 -1
- package/foundation/text/string-utils.mjs +16 -5
- package/foundation/text/suggest-order.d.mts +72 -0
- package/foundation/text/suggest-order.mjs +363 -0
- package/foundation/text/suggest-order.test.mjs +259 -0
- package/host/door-conformance.test.mjs +274 -0
- package/host/index.d.ts +116 -0
- package/host/index.mjs +295 -0
- package/host/index.test.mjs +302 -0
- package/package.json +14 -9
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file Search's component candidates: Core's components and the ones
|
|
5
|
+
* integrations contribute, read from their docs. Imported only by the adapter.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {discoverExternalPackages} from '../../foundation/fs/paths.mjs';
|
|
9
|
+
import {
|
|
10
|
+
discoverComponents,
|
|
11
|
+
discoverValidIntegrationComponents,
|
|
12
|
+
docStem,
|
|
13
|
+
familyMember,
|
|
14
|
+
findComponentReadme,
|
|
15
|
+
forEachIntegrationDoc,
|
|
16
|
+
integrationMemberEntry,
|
|
17
|
+
integrationRecordHold,
|
|
18
|
+
isIntegrationMember,
|
|
19
|
+
resolveImportPath,
|
|
20
|
+
resolveIntegrationImportPath,
|
|
21
|
+
CORE_PACKAGE,
|
|
22
|
+
} from '../../foundation/discovery/component-discovery.mjs';
|
|
23
|
+
import {
|
|
24
|
+
loadComponentReplacements,
|
|
25
|
+
loadIntegrationsSafely,
|
|
26
|
+
resolveLegacyExternalDoc,
|
|
27
|
+
} from '../component/_adapter.mjs';
|
|
28
|
+
import {loadModuleDoc, guidanceFrom} from './_module-doc.mjs';
|
|
29
|
+
|
|
30
|
+
/** @typedef {import('./_lexical.mjs').Candidate} Candidate */
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Build component candidates from core's own tree: name + keywords +
|
|
34
|
+
* usage/description from the component's .doc.mjs.
|
|
35
|
+
* @param {string} coreDir
|
|
36
|
+
* @returns {Promise<Candidate[]>}
|
|
37
|
+
*/
|
|
38
|
+
async function gatherCoreComponents(coreDir) {
|
|
39
|
+
const grouped = discoverComponents(coreDir);
|
|
40
|
+
const names = Object.values(grouped).flat();
|
|
41
|
+
/** @type {Candidate[]} */
|
|
42
|
+
const candidates = [];
|
|
43
|
+
for (const comp of names) {
|
|
44
|
+
const readme = findComponentReadme(coreDir, comp);
|
|
45
|
+
/** @type {string[]} */
|
|
46
|
+
let keywords = [];
|
|
47
|
+
let description = '';
|
|
48
|
+
/** @type {string[]} */
|
|
49
|
+
let guidance = [];
|
|
50
|
+
if (readme && readme.endsWith('.doc.mjs')) {
|
|
51
|
+
const loaded = await loadModuleDoc(readme);
|
|
52
|
+
// A member documented in its family's doc (VStack in Stack's doc) is
|
|
53
|
+
// indexed from its own entry: the family's keywords and guidance
|
|
54
|
+
// describe the family, not the member.
|
|
55
|
+
const doc = familyMember(loaded, comp) ?? loaded;
|
|
56
|
+
if (doc) {
|
|
57
|
+
keywords = Array.isArray(doc.keywords) ? doc.keywords : [];
|
|
58
|
+
description = doc.usage?.description || doc.description || '';
|
|
59
|
+
guidance = guidanceFrom(doc);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
candidates.push({
|
|
63
|
+
domain: 'component',
|
|
64
|
+
name: comp,
|
|
65
|
+
keywords,
|
|
66
|
+
description,
|
|
67
|
+
guidance,
|
|
68
|
+
_package: CORE_PACKAGE,
|
|
69
|
+
_import: resolveImportPath(coreDir, comp),
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return candidates;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Build component candidates contributed by the project's configured
|
|
77
|
+
* integrations (astryx.config's `integrations`): name + keywords +
|
|
78
|
+
* usage/description from each component's .doc.mjs, same as core. Without
|
|
79
|
+
* this, an integration component is invisible to `search`/`build` even
|
|
80
|
+
* though `component --list`/`component <Name>` already resolve it — the two
|
|
81
|
+
* discovery paths silently disagreed. Also returns, per name, the docs that
|
|
82
|
+
* hold it by their file name and the loadable docs that only record it.
|
|
83
|
+
* @param {import('../../foundation/integrations/integrations.mjs').LoadedIntegration[]} loadedIntegrations
|
|
84
|
+
* @returns {Promise<{candidates: Candidate[], fileNamed: Map<string, Set<string>>, documented: Map<string, Set<string>>}>}
|
|
85
|
+
*/
|
|
86
|
+
async function gatherIntegrationComponents(loadedIntegrations) {
|
|
87
|
+
/** @type {Candidate[]} */
|
|
88
|
+
const candidates = [];
|
|
89
|
+
// What the owner rule reads: the docs that hold a name by their file name,
|
|
90
|
+
// loadable or not and hidden ones too, and the loadable docs that only
|
|
91
|
+
// record it.
|
|
92
|
+
/** @type {Map<string, Set<string>>} */
|
|
93
|
+
const fileNamed = new Map();
|
|
94
|
+
/** @type {Map<string, Set<string>>} */
|
|
95
|
+
const documented = new Map();
|
|
96
|
+
/** @param {Map<string, Set<string>>} map @param {string} name @param {string} docPath */
|
|
97
|
+
const hold = (map, name, docPath) =>
|
|
98
|
+
map.set(name, (map.get(name) ?? new Set()).add(docPath));
|
|
99
|
+
for (const integration of loadedIntegrations) {
|
|
100
|
+
const {components, discovered} =
|
|
101
|
+
await discoverValidIntegrationComponents(integration);
|
|
102
|
+
const renamed = new Set(
|
|
103
|
+
discovered
|
|
104
|
+
.filter(rec => integrationRecordHold(rec) === 'doc')
|
|
105
|
+
.filter(rec => !isIntegrationMember(rec))
|
|
106
|
+
.map(rec => rec.docPath),
|
|
107
|
+
);
|
|
108
|
+
forEachIntegrationDoc(integration.components, (docPath, stem) => {
|
|
109
|
+
if (!renamed.has(docPath)) hold(fileNamed, stem, docPath);
|
|
110
|
+
});
|
|
111
|
+
for (const rec of components) {
|
|
112
|
+
const loaded = await loadModuleDoc(rec.docPath);
|
|
113
|
+
// A family member is indexed from its own entry: the family's keywords
|
|
114
|
+
// and guidance describe the family.
|
|
115
|
+
const member = isIntegrationMember(rec);
|
|
116
|
+
const doc = member ? integrationMemberEntry(loaded, rec) : loaded;
|
|
117
|
+
// A doc that names another export of its file still answers to the
|
|
118
|
+
// file's name, as `component <file name>` does.
|
|
119
|
+
const fileName = docStem(rec.docPath);
|
|
120
|
+
if (integrationRecordHold(rec) === 'doc') {
|
|
121
|
+
hold(documented, rec.name, rec.docPath);
|
|
122
|
+
}
|
|
123
|
+
if (renamed.has(rec.docPath) && !member) {
|
|
124
|
+
hold(documented, fileName, rec.docPath);
|
|
125
|
+
}
|
|
126
|
+
candidates.push({
|
|
127
|
+
domain: 'component',
|
|
128
|
+
name: rec.name,
|
|
129
|
+
aliases: !member && fileName !== rec.name ? [fileName] : [],
|
|
130
|
+
_hold: integrationRecordHold(rec),
|
|
131
|
+
_docPath: rec.docPath,
|
|
132
|
+
keywords: doc && Array.isArray(doc.keywords) ? doc.keywords : [],
|
|
133
|
+
description: doc ? doc.usage?.description || doc.description || '' : '',
|
|
134
|
+
guidance: guidanceFrom(doc),
|
|
135
|
+
_package: rec.package ?? integration.name,
|
|
136
|
+
// Exactly what `component` reports: a doc may state its own specifier
|
|
137
|
+
// (one entry point exporting several components), and only when it
|
|
138
|
+
// does not do we resolve the subpath against the owning package's
|
|
139
|
+
// exports — read off the integration, which the loader already parsed.
|
|
140
|
+
// Reporting the bare package name here handed out a path that does not
|
|
141
|
+
// resolve, and disagreed with what `component <Name>` said about the
|
|
142
|
+
// very same component.
|
|
143
|
+
_import: resolveIntegrationImportPath(
|
|
144
|
+
{
|
|
145
|
+
exportsMap: integration.__packageExports,
|
|
146
|
+
packageDir: integration.__packageDir,
|
|
147
|
+
docPath: rec.docPath,
|
|
148
|
+
packageName: rec.package,
|
|
149
|
+
},
|
|
150
|
+
rec.name,
|
|
151
|
+
loaded?.import,
|
|
152
|
+
),
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return {candidates, fileNamed, documented};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Build component candidates: core's own tree plus every configured
|
|
161
|
+
* integration's components.
|
|
162
|
+
* @param {string} coreDir
|
|
163
|
+
* @param {string} cwd
|
|
164
|
+
* @returns {Promise<Candidate[]>}
|
|
165
|
+
*/
|
|
166
|
+
export async function gatherComponents(coreDir, cwd) {
|
|
167
|
+
const loadedIntegrations = await loadIntegrationsSafely(cwd);
|
|
168
|
+
const [core, gathered, replacements] = await Promise.all([
|
|
169
|
+
gatherCoreComponents(coreDir),
|
|
170
|
+
gatherIntegrationComponents(loadedIntegrations),
|
|
171
|
+
loadComponentReplacements(coreDir, loadedIntegrations),
|
|
172
|
+
]);
|
|
173
|
+
const {candidates: integrations, fileNamed, documented} = gathered;
|
|
174
|
+
// An active replacement answers to the Core name it replaces, so a search
|
|
175
|
+
// for that name finds the replacement and not the Core original
|
|
176
|
+
// (spec:AST-035 FR11).
|
|
177
|
+
/** @type {Map<string, string>} */
|
|
178
|
+
const targetOf = new Map(
|
|
179
|
+
replacements.active.map(active => [
|
|
180
|
+
`${active.package}\0${active.name}`,
|
|
181
|
+
active.target,
|
|
182
|
+
]),
|
|
183
|
+
);
|
|
184
|
+
// The owner rule, as component detail applies it: a candidate `component
|
|
185
|
+
// <name>` does not open names its package and follows the owner, and a
|
|
186
|
+
// file-name alias that opens another owner is dropped.
|
|
187
|
+
const coreNames = new Set(core.map(candidate => candidate.name));
|
|
188
|
+
/** @param {string} name @param {Candidate} candidate */
|
|
189
|
+
const opens = (name, candidate) =>
|
|
190
|
+
!coreNames.has(name) &&
|
|
191
|
+
findComponentReadme(coreDir, name) == null &&
|
|
192
|
+
[...(fileNamed.get(name) ?? [])].every(doc => doc === candidate._docPath) &&
|
|
193
|
+
[...(documented.get(name) ?? [])].every(doc => doc === candidate._docPath);
|
|
194
|
+
// A legacy docs package keeps an exact name over an export name a doc records.
|
|
195
|
+
/** @type {ReturnType<typeof discoverExternalPackages> | undefined} */
|
|
196
|
+
let externals;
|
|
197
|
+
/** @param {string} name */
|
|
198
|
+
const legacyDocuments = name =>
|
|
199
|
+
(externals ??= discoverExternalPackages(cwd)).some(
|
|
200
|
+
ext => resolveLegacyExternalDoc(ext, name) != null,
|
|
201
|
+
);
|
|
202
|
+
const ruled = integrations.map(candidate => {
|
|
203
|
+
const aliases = (candidate.aliases ?? []).filter(alias =>
|
|
204
|
+
opens(alias, candidate),
|
|
205
|
+
);
|
|
206
|
+
return candidate._hold === 'doc' &&
|
|
207
|
+
(!opens(candidate.name, candidate) || legacyDocuments(candidate.name))
|
|
208
|
+
? {
|
|
209
|
+
...candidate,
|
|
210
|
+
aliases,
|
|
211
|
+
_command: `astryx component ${candidate.name} --package ${candidate._package}`,
|
|
212
|
+
}
|
|
213
|
+
: {...candidate, aliases};
|
|
214
|
+
});
|
|
215
|
+
return [
|
|
216
|
+
...core.filter(candidate => !replacements.forTarget(candidate.name)),
|
|
217
|
+
...[
|
|
218
|
+
...ruled.filter(candidate => !candidate._command),
|
|
219
|
+
...ruled.filter(candidate => candidate._command),
|
|
220
|
+
].map(candidate => {
|
|
221
|
+
const target = targetOf.get(`${candidate._package}\0${candidate.name}`);
|
|
222
|
+
if (target != null) {
|
|
223
|
+
return {...candidate, aliases: [...(candidate.aliases ?? []), target]};
|
|
224
|
+
}
|
|
225
|
+
// Another package's component named after a replaced Core component is
|
|
226
|
+
// shadowed for the bare name (FR14): its command names its package.
|
|
227
|
+
const shadowedBy = replacements.forTarget(candidate.name);
|
|
228
|
+
return shadowedBy && shadowedBy.package !== candidate._package
|
|
229
|
+
? {
|
|
230
|
+
...candidate,
|
|
231
|
+
_command: `astryx component ${candidate.name} --package ${candidate._package}`,
|
|
232
|
+
}
|
|
233
|
+
: candidate;
|
|
234
|
+
}),
|
|
235
|
+
];
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Every component the project can use, Core's and its integrations', with the
|
|
240
|
+
* keywords its own doc declares: the discovery and doc reads search's own
|
|
241
|
+
* candidates use, without the import paths and prose a result carries. `build`
|
|
242
|
+
* reads it to tell a part of a page from a page when its search was narrowed
|
|
243
|
+
* away from components.
|
|
244
|
+
* @param {string} coreDir
|
|
245
|
+
* @param {string} cwd
|
|
246
|
+
* @returns {Promise<{name: string, keywords: string[]}[]>}
|
|
247
|
+
*/
|
|
248
|
+
export async function componentKeywords(coreDir, cwd) {
|
|
249
|
+
/** @param {any} doc */
|
|
250
|
+
const keywordsOf = doc => (Array.isArray(doc?.keywords) ? doc.keywords : []);
|
|
251
|
+
const core = Object.values(discoverComponents(coreDir))
|
|
252
|
+
.flat()
|
|
253
|
+
.map(async name => {
|
|
254
|
+
const readme = findComponentReadme(coreDir, name);
|
|
255
|
+
const loaded =
|
|
256
|
+
readme && readme.endsWith('.doc.mjs')
|
|
257
|
+
? await loadModuleDoc(readme)
|
|
258
|
+
: null;
|
|
259
|
+
return {name, keywords: keywordsOf(familyMember(loaded, name) ?? loaded)};
|
|
260
|
+
});
|
|
261
|
+
const loadedIntegrations = await loadIntegrationsSafely(cwd);
|
|
262
|
+
const replacements = await loadComponentReplacements(
|
|
263
|
+
coreDir,
|
|
264
|
+
loadedIntegrations,
|
|
265
|
+
);
|
|
266
|
+
const integrations = loadedIntegrations.map(async integration => {
|
|
267
|
+
const {components} = await discoverValidIntegrationComponents(integration);
|
|
268
|
+
return Promise.all(
|
|
269
|
+
components.map(async rec => {
|
|
270
|
+
const loaded = await loadModuleDoc(rec.docPath);
|
|
271
|
+
return {
|
|
272
|
+
name: rec.name,
|
|
273
|
+
keywords: keywordsOf(integrationMemberEntry(loaded, rec) ?? loaded),
|
|
274
|
+
};
|
|
275
|
+
}),
|
|
276
|
+
);
|
|
277
|
+
});
|
|
278
|
+
return [
|
|
279
|
+
...(await Promise.all(core)).filter(
|
|
280
|
+
component => !replacements.forTarget(component.name),
|
|
281
|
+
),
|
|
282
|
+
...(await Promise.all(integrations)).flat(),
|
|
283
|
+
];
|
|
284
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// @generated by scripts/sync-api-types.mjs from the JSDoc in api/**/*.mjs.
|
|
2
|
+
// DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
|
|
3
|
+
|
|
4
|
+
/** @typedef {import('./_lexical.mjs').Candidate} Candidate */
|
|
5
|
+
/**
|
|
6
|
+
* Build doc candidates at the grain a reader reads them: each section of a
|
|
7
|
+
* topic, whose command reads just that section; each topic as a whole, whose
|
|
8
|
+
* command lists its sections; and each docs-tree node by its route. The tree's
|
|
9
|
+
* guides split into sections like topics, and its typed docs also match by
|
|
10
|
+
* their own name, so `assertResponse` finds `cli/api/functions/assert-response`.
|
|
11
|
+
*
|
|
12
|
+
* Reads the project's catalog rather than the CLI's own docs directory, so a
|
|
13
|
+
* topic an integration contributed (or replaced) is searchable exactly like a
|
|
14
|
+
* built-in one — otherwise the replacement is served by `astryx docs` but
|
|
15
|
+
* invisible to the command whose job is finding it.
|
|
16
|
+
* @param {string} cwd
|
|
17
|
+
* @returns {Promise<Candidate[]>}
|
|
18
|
+
*/
|
|
19
|
+
export function gatherDocs(cwd: string): Promise<Candidate[]>;
|
|
20
|
+
export type Candidate = import("./_lexical.mjs").Candidate;
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file Search's doc candidates: every topic, section, and docs-tree node,
|
|
5
|
+
* with its titles, prose, and code terms. Imported only by the adapter.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
guideEntry,
|
|
10
|
+
loadDocsCatalog,
|
|
11
|
+
lowerTopic,
|
|
12
|
+
projectTree,
|
|
13
|
+
holdsOwnName,
|
|
14
|
+
} from '../docs/_adapter.mjs';
|
|
15
|
+
import {nodeView} from '../docs/node/node.mjs';
|
|
16
|
+
import {
|
|
17
|
+
sectionKey,
|
|
18
|
+
sectionSummary,
|
|
19
|
+
} from '../../foundation/discovery/docs-section-key.mjs';
|
|
20
|
+
import {sectionProse, codeTerms, headings, plain} from './_doc-text.mjs';
|
|
21
|
+
|
|
22
|
+
/** @typedef {import('./_lexical.mjs').Candidate} Candidate */
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Build doc candidates at the grain a reader reads them: each section of a
|
|
26
|
+
* topic, whose command reads just that section; each topic as a whole, whose
|
|
27
|
+
* command lists its sections; and each docs-tree node by its route. The tree's
|
|
28
|
+
* guides split into sections like topics, and its typed docs also match by
|
|
29
|
+
* their own name, so `assertResponse` finds `cli/api/functions/assert-response`.
|
|
30
|
+
*
|
|
31
|
+
* Reads the project's catalog rather than the CLI's own docs directory, so a
|
|
32
|
+
* topic an integration contributed (or replaced) is searchable exactly like a
|
|
33
|
+
* built-in one — otherwise the replacement is served by `astryx docs` but
|
|
34
|
+
* invisible to the command whose job is finding it.
|
|
35
|
+
* @param {string} cwd
|
|
36
|
+
* @returns {Promise<Candidate[]>}
|
|
37
|
+
*/
|
|
38
|
+
export async function gatherDocs(cwd) {
|
|
39
|
+
/** @type {Candidate[]} */
|
|
40
|
+
const candidates = [];
|
|
41
|
+
let catalog;
|
|
42
|
+
try {
|
|
43
|
+
catalog = await loadDocsCatalog(cwd);
|
|
44
|
+
} catch {
|
|
45
|
+
return candidates;
|
|
46
|
+
}
|
|
47
|
+
let tree = null;
|
|
48
|
+
try {
|
|
49
|
+
tree = await projectTree(catalog);
|
|
50
|
+
} catch {
|
|
51
|
+
// `astryx doctor` reports a tree that fails to build; search still
|
|
52
|
+
// indexes the topics.
|
|
53
|
+
}
|
|
54
|
+
for (const entry of catalog.entries()) {
|
|
55
|
+
// A topic whose name opens another doc (spec:AST-046 FR11) is not
|
|
56
|
+
// offered: every hit's command must open the hit.
|
|
57
|
+
if (tree && !holdsOwnName(tree, catalog, entry)) continue;
|
|
58
|
+
let lowered = null;
|
|
59
|
+
try {
|
|
60
|
+
lowered = await lowerTopic(catalog, entry);
|
|
61
|
+
} catch {
|
|
62
|
+
// A topic that cannot be loaded is reported by the commands that own
|
|
63
|
+
// integration issues; search just cannot index it.
|
|
64
|
+
}
|
|
65
|
+
const doc = lowered?.doc ?? null;
|
|
66
|
+
// A flat topic lives in its topic level; its hits say so, and name
|
|
67
|
+
// the package each section came from.
|
|
68
|
+
const home = tree?.get(entry.name);
|
|
69
|
+
const placed = home?.ref?.flatTopic === entry.name ? home : null;
|
|
70
|
+
/** @type {Map<string, string>} */
|
|
71
|
+
const packages = new Map([
|
|
72
|
+
[entry.providerId ?? entry.package, entry.package],
|
|
73
|
+
...entry.extensions.map(
|
|
74
|
+
ext =>
|
|
75
|
+
/** @type {[string, string]} */ ([
|
|
76
|
+
ext.providerId ?? ext.package,
|
|
77
|
+
ext.package,
|
|
78
|
+
]),
|
|
79
|
+
),
|
|
80
|
+
]);
|
|
81
|
+
candidates.push(
|
|
82
|
+
...topicCandidates(
|
|
83
|
+
entry.name,
|
|
84
|
+
doc,
|
|
85
|
+
entry.title,
|
|
86
|
+
'',
|
|
87
|
+
placed && tree
|
|
88
|
+
? [
|
|
89
|
+
...tree.ancestors(placed).map(a => a.title),
|
|
90
|
+
doc?.title || entry.title || entry.name,
|
|
91
|
+
].join(' › ')
|
|
92
|
+
: undefined,
|
|
93
|
+
placed ? `astryx docs ${placed.parent}` : undefined,
|
|
94
|
+
entry.package,
|
|
95
|
+
key =>
|
|
96
|
+
packages.get(lowered?.sectionProviders?.[key] ?? '') ?? entry.package,
|
|
97
|
+
),
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
if (tree == null) return candidates;
|
|
101
|
+
for (const node of tree.nodes.values()) {
|
|
102
|
+
// A flat topic is indexed above, as a topic.
|
|
103
|
+
if (node.ref?.flatTopic) continue;
|
|
104
|
+
// A tree hit names where it lives: its ancestors' titles, then its own.
|
|
105
|
+
const path = [...tree.ancestors(node).map(a => a.title), node.title];
|
|
106
|
+
if (node.kind === 'generic') {
|
|
107
|
+
let doc = null;
|
|
108
|
+
try {
|
|
109
|
+
doc = (await lowerTopic(catalog, guideEntry(node))).doc;
|
|
110
|
+
} catch {
|
|
111
|
+
// As above: the owning commands report it.
|
|
112
|
+
}
|
|
113
|
+
candidates.push(
|
|
114
|
+
...topicCandidates(
|
|
115
|
+
node.route,
|
|
116
|
+
doc,
|
|
117
|
+
node.title,
|
|
118
|
+
node.summary,
|
|
119
|
+
path.join(' › '),
|
|
120
|
+
node.parent == null ? undefined : `astryx docs ${node.parent}`,
|
|
121
|
+
node.provider,
|
|
122
|
+
),
|
|
123
|
+
);
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
const selfDoc = /** @type {any} */ (node.ref)?.selfDoc;
|
|
127
|
+
// A typed doc's content is what `astryx docs <route>` prints. The first
|
|
128
|
+
// column of its tables names what the doc defines (an error code, an
|
|
129
|
+
// option, a parameter), so each is a keyword the doc answers to.
|
|
130
|
+
/** @type {any[]} */
|
|
131
|
+
const content = (await nodeView(catalog, tree, node)).content ?? [];
|
|
132
|
+
/** @type {string[]} */
|
|
133
|
+
const defined = [];
|
|
134
|
+
for (const block of content) {
|
|
135
|
+
if (block.type !== 'table' || !Array.isArray(block.rows)) continue;
|
|
136
|
+
for (const row of block.rows)
|
|
137
|
+
if (row[0] != null) defined.push(plain(row[0]));
|
|
138
|
+
}
|
|
139
|
+
candidates.push({
|
|
140
|
+
domain: 'doc',
|
|
141
|
+
name: node.name,
|
|
142
|
+
keywords: [
|
|
143
|
+
node.route.slice(node.route.lastIndexOf('/') + 1),
|
|
144
|
+
...(Array.isArray(selfDoc?.keywords) ? selfDoc.keywords : []),
|
|
145
|
+
// A namespace doc's own keywords, which it declares for search.
|
|
146
|
+
...(Array.isArray(node.keywords) ? node.keywords : []),
|
|
147
|
+
...defined,
|
|
148
|
+
...codeTerms({content}),
|
|
149
|
+
],
|
|
150
|
+
_declared: [
|
|
151
|
+
...(Array.isArray(selfDoc?.keywords) ? selfDoc.keywords : []),
|
|
152
|
+
...(Array.isArray(node.keywords) ? node.keywords : []),
|
|
153
|
+
],
|
|
154
|
+
description: node.summary || '',
|
|
155
|
+
prose: sectionProse({title: node.title, content}),
|
|
156
|
+
titles: [node.title],
|
|
157
|
+
_topic: node.route,
|
|
158
|
+
_title: path.join(' › '),
|
|
159
|
+
_command: `astryx docs ${node.route}`,
|
|
160
|
+
_parent:
|
|
161
|
+
node.parent == null ? 'astryx docs' : `astryx docs ${node.parent}`,
|
|
162
|
+
_package: node.provider,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
return candidates;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* The candidates one topic yields: the topic itself, and one per section when
|
|
170
|
+
* it has more than one. A topic's command lists its sections, and a section's
|
|
171
|
+
* command reads only that section, so a hit never costs a whole-topic read.
|
|
172
|
+
* @param {string} name - the topic name, or a placed guide's route
|
|
173
|
+
* @param {any} doc - the lowered topic, or null when it did not load
|
|
174
|
+
* @param {string} [title]
|
|
175
|
+
* @param {string} [summary]
|
|
176
|
+
* @param {string} [path] - where the topic lives in the docs tree, as titles
|
|
177
|
+
* joined by ` › `; a flat topic is its own title
|
|
178
|
+
* @param {string} [parent] - the command that opens the level above the
|
|
179
|
+
* topic: its namespace, or the topic level for a flat topic
|
|
180
|
+
* @param {string} [pkg] - the npm package that authored the topic
|
|
181
|
+
* @param {(key: string) => string} [sectionPackage] - the npm package a
|
|
182
|
+
* section came from: an extension's section names the extension's package
|
|
183
|
+
* @returns {Candidate[]}
|
|
184
|
+
*/
|
|
185
|
+
function topicCandidates(
|
|
186
|
+
name,
|
|
187
|
+
doc,
|
|
188
|
+
title,
|
|
189
|
+
summary = '',
|
|
190
|
+
path,
|
|
191
|
+
parent,
|
|
192
|
+
pkg,
|
|
193
|
+
sectionPackage,
|
|
194
|
+
) {
|
|
195
|
+
/** @type {any[]} */
|
|
196
|
+
const sections = doc?.sections ?? [];
|
|
197
|
+
const docTitle = path || doc?.title || title || name;
|
|
198
|
+
const split = sections.length > 1;
|
|
199
|
+
// A placed guide also answers to its last route segment's words:
|
|
200
|
+
// `quick start` is authoring/quick-start.
|
|
201
|
+
const leaf = name.slice(name.lastIndexOf('/') + 1);
|
|
202
|
+
/** @type {Candidate[]} */
|
|
203
|
+
const out = [
|
|
204
|
+
{
|
|
205
|
+
domain: 'doc',
|
|
206
|
+
name,
|
|
207
|
+
keywords: [
|
|
208
|
+
...(leaf !== name ? [leaf.replaceAll('-', ' ')] : []),
|
|
209
|
+
...(doc?.title || title ? [doc?.title || title] : []),
|
|
210
|
+
...(Array.isArray(doc?.keywords) ? doc.keywords : []),
|
|
211
|
+
],
|
|
212
|
+
_declared: Array.isArray(doc?.keywords) ? doc.keywords : [],
|
|
213
|
+
description: doc?.description || summary,
|
|
214
|
+
prose: split
|
|
215
|
+
? sections.map(section => section.title).filter(Boolean)
|
|
216
|
+
: sections.flatMap(sectionProse),
|
|
217
|
+
titles: [
|
|
218
|
+
doc?.title || title || name,
|
|
219
|
+
// A topic read whole answers for the headings inside it.
|
|
220
|
+
...(split ? [] : sections.flatMap(s => [s.title, ...headings(s)])),
|
|
221
|
+
].filter(Boolean),
|
|
222
|
+
_topic: name,
|
|
223
|
+
_title: docTitle,
|
|
224
|
+
_command: split ? `astryx docs ${name} --index` : `astryx docs ${name}`,
|
|
225
|
+
...(parent ? {_parent: parent} : {}),
|
|
226
|
+
...(pkg ? {_package: pkg} : {}),
|
|
227
|
+
},
|
|
228
|
+
];
|
|
229
|
+
if (!split) return out;
|
|
230
|
+
for (const section of sections) {
|
|
231
|
+
const key = sectionKey(section);
|
|
232
|
+
out.push({
|
|
233
|
+
domain: 'doc',
|
|
234
|
+
name: key,
|
|
235
|
+
keywords: [
|
|
236
|
+
...(section.title ? [section.title] : []),
|
|
237
|
+
...headings(section),
|
|
238
|
+
...codeTerms(section),
|
|
239
|
+
],
|
|
240
|
+
description: sectionSummary(section),
|
|
241
|
+
prose: sectionProse(section),
|
|
242
|
+
titles: [section.title, ...headings(section)].filter(Boolean),
|
|
243
|
+
_topic: name,
|
|
244
|
+
_section: key,
|
|
245
|
+
_title: `${docTitle} › ${section.title}`,
|
|
246
|
+
_command: `astryx docs ${name} ${key}`,
|
|
247
|
+
_parent: `astryx docs ${name} --index`,
|
|
248
|
+
...((sectionPackage?.(key) ?? pkg)
|
|
249
|
+
? {_package: sectionPackage?.(key) ?? pkg}
|
|
250
|
+
: {}),
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
return out;
|
|
254
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// @generated by scripts/sync-api-types.mjs from the JSDoc in api/**/*.mjs.
|
|
2
|
+
// DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
|
|
3
|
+
|
|
4
|
+
/** @typedef {import('./_lexical.mjs').Candidate} Candidate */
|
|
5
|
+
/**
|
|
6
|
+
* Build hook candidates: name + keywords + usage/description from the hook's
|
|
7
|
+
* .doc.mjs.
|
|
8
|
+
* @param {string} coreDir
|
|
9
|
+
* @returns {Promise<Candidate[]>}
|
|
10
|
+
*/
|
|
11
|
+
export function gatherHooks(coreDir: string): Promise<Candidate[]>;
|
|
12
|
+
export type Candidate = import("./_lexical.mjs").Candidate;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file Search's hook candidates, read from Core's hook docs. Imported only
|
|
5
|
+
* by the adapter.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {CORE_PACKAGE} from '../../foundation/discovery/component-discovery.mjs';
|
|
9
|
+
import {
|
|
10
|
+
discoverHooks,
|
|
11
|
+
findHookDoc,
|
|
12
|
+
} from '../../foundation/discovery/hook-discovery.mjs';
|
|
13
|
+
import {loadModuleDoc} from './_module-doc.mjs';
|
|
14
|
+
|
|
15
|
+
/** @typedef {import('./_lexical.mjs').Candidate} Candidate */
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Build hook candidates: name + keywords + usage/description from the hook's
|
|
19
|
+
* .doc.mjs.
|
|
20
|
+
* @param {string} coreDir
|
|
21
|
+
* @returns {Promise<Candidate[]>}
|
|
22
|
+
*/
|
|
23
|
+
export async function gatherHooks(coreDir) {
|
|
24
|
+
const grouped = discoverHooks(coreDir);
|
|
25
|
+
const names = Object.values(grouped).flat();
|
|
26
|
+
/** @type {Candidate[]} */
|
|
27
|
+
const candidates = [];
|
|
28
|
+
for (const hookName of names) {
|
|
29
|
+
const docPath = findHookDoc(coreDir, hookName);
|
|
30
|
+
/** @type {string[]} */
|
|
31
|
+
let keywords = [];
|
|
32
|
+
let description = '';
|
|
33
|
+
let importPath = '@astryxdesign/core/hooks';
|
|
34
|
+
if (docPath) {
|
|
35
|
+
const doc = await loadModuleDoc(docPath, 'docs', 'hooks');
|
|
36
|
+
if (doc) {
|
|
37
|
+
keywords = Array.isArray(doc.keywords) ? doc.keywords : [];
|
|
38
|
+
description = doc.usage?.description || doc.description || '';
|
|
39
|
+
importPath = doc.importPath || importPath;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
candidates.push({
|
|
43
|
+
domain: 'hook',
|
|
44
|
+
name: hookName,
|
|
45
|
+
keywords,
|
|
46
|
+
description,
|
|
47
|
+
_package: CORE_PACKAGE,
|
|
48
|
+
_import: importPath,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return candidates;
|
|
52
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// @generated by scripts/sync-api-types.mjs from the JSDoc in api/**/*.mjs.
|
|
2
|
+
// DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
|
|
3
|
+
|
|
4
|
+
/** @typedef {import('./_lexical.mjs').Candidate} Candidate */
|
|
5
|
+
/**
|
|
6
|
+
* Build template candidates (page + block) from the template discovery API.
|
|
7
|
+
* @param {string} cwd
|
|
8
|
+
* @returns {Promise<Candidate[]>}
|
|
9
|
+
*/
|
|
10
|
+
export function gatherTemplates(cwd: string): Promise<Candidate[]>;
|
|
11
|
+
/**
|
|
12
|
+
* Build theme candidates from bundled and integration-provided themes. Without
|
|
13
|
+
* this, an integration's themes are invisible to `search` even though
|
|
14
|
+
* `theme list` and `discover` already resolve them.
|
|
15
|
+
*
|
|
16
|
+
* A theme's slug and display name are its names, and its description is prose
|
|
17
|
+
* (`spec:AST-050/FR14`). A theme declares no keywords, so a word it shares with
|
|
18
|
+
* the query only through its description is a description mention: read as a
|
|
19
|
+
* keyword, every word of the description would outrank the components and docs
|
|
20
|
+
* that declare that word.
|
|
21
|
+
* @param {string} cwd
|
|
22
|
+
* @returns {Promise<Candidate[]>}
|
|
23
|
+
*/
|
|
24
|
+
export function gatherThemes(cwd: string): Promise<Candidate[]>;
|
|
25
|
+
export type Candidate = import("./_lexical.mjs").Candidate;
|