@astryxdesign/cli 0.6.4-canary.f0355e3 → 0.6.4
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 +96 -99
- package/api/build/build.doc.mjs +1 -6
- package/api/build/build.test.mjs +0 -22
- package/api/build/kit/kit.mjs +5 -44
- package/api/component/_adapter.d.mts +0 -25
- package/api/component/_adapter.mjs +5 -59
- package/api/component/component.d.mts +3 -6
- package/api/component/component.doc.mjs +17 -37
- package/api/component/component.mjs +9 -249
- package/api/component/component.type.d.mts +0 -25
- package/api/component/component.type.mjs +0 -44
- package/api/discover/_adapter.d.mts +6 -114
- package/api/discover/_adapter.mjs +17 -372
- package/api/discover/detail/detail.d.mts +6 -18
- package/api/discover/detail/detail.mjs +13 -67
- package/api/discover/detail/detail.test.mjs +0 -85
- package/api/discover/discover.d.mts +9 -3
- package/api/discover/discover.doc.mjs +18 -61
- package/api/discover/discover.mjs +36 -220
- package/api/discover/discover.test.mjs +2 -11
- package/api/discover/discover.type.d.mts +8 -147
- package/api/discover/discover.type.mjs +12 -102
- package/api/discover/list/list.d.mts +6 -20
- package/api/discover/list/list.mjs +12 -45
- package/api/discover/list/list.test.mjs +0 -46
- package/api/discover/search/search.d.mts +16 -18
- package/api/discover/search/search.mjs +56 -102
- package/api/discover/search/search.test.mjs +10 -144
- package/api/docs/_adapter.d.mts +3 -8
- package/api/docs/_adapter.mjs +6 -14
- package/api/docs/docOverlays.test.mjs +1 -27
- package/api/docs/docs.doc.mjs +2 -2
- package/api/docs/docs.test.mjs +243 -0
- package/api/docs/integration-tree.test.mjs +555 -0
- package/api/docs/integrationDocs.test.mjs +314 -0
- package/api/doctor/doctor.d.mts +3 -8
- package/api/doctor/doctor.doc.mjs +8 -17
- package/api/doctor/doctor.mjs +9 -90
- package/api/doctor/doctor.test.mjs +10 -122
- package/api/doctor/doctor.type.d.mts +1 -1
- package/api/doctor/doctor.type.mjs +1 -1
- package/api/gap-report/gap-report.doc.mjs +10 -19
- package/api/hook/hook.doc.mjs +3 -6
- package/api/index.d.mts +2 -1
- package/api/index.mjs +5 -5
- package/api/init/init.doc.mjs +12 -17
- package/api/integration/add-helpers.d.mts +2 -5
- package/api/integration/add-helpers.mjs +9 -36
- package/api/integration/add-theme.mjs +1 -22
- package/api/integration/add-theme.test.mjs +0 -34
- package/api/integration/authoring-checks.mjs +2 -2
- package/api/integration/integrationPackCheck.doc.mjs +3 -3
- package/api/integration/pack-check.mjs +9 -82
- package/api/integration/pack-check.test.mjs +0 -90
- package/api/integration/pack-check.type.mjs +1 -1
- package/api/json/assertResponse.doc.mjs +1 -1
- package/api/json/index.ts +1 -0
- package/api/json/isError.doc.mjs +1 -1
- package/api/layout/_adapter.d.mts +34 -0
- package/api/layout/_adapter.mjs +148 -0
- package/api/layout/check/check.d.mts +16 -0
- package/api/layout/check/check.mjs +40 -0
- package/api/layout/expand/expand.d.mts +22 -0
- package/api/layout/expand/expand.mjs +155 -0
- package/api/layout/expand/expand.path-safety.test.mjs +53 -0
- package/api/layout/grammar/grammar.d.mts +13 -0
- package/api/layout/grammar/grammar.mjs +87 -0
- package/api/layout/layout.d.mts +6 -0
- package/api/layout/layout.mjs +17 -0
- package/api/layout/layout.test.mjs +297 -0
- package/api/layout/layout.type.d.mts +89 -0
- package/api/layout/layout.type.mjs +103 -0
- package/api/layout/layoutCheck.doc.d.mts +11 -0
- package/api/layout/layoutCheck.doc.mjs +85 -0
- package/api/layout/layoutExpand.doc.d.mts +11 -0
- package/api/layout/layoutExpand.doc.mjs +107 -0
- package/api/layout/layoutGrammar.doc.d.mts +11 -0
- package/api/layout/layoutGrammar.doc.mjs +57 -0
- package/api/search/search.d.mts +1 -27
- package/api/search/search.doc.mjs +2 -2
- package/api/search/search.mjs +16 -228
- package/api/search/search.test.mjs +512 -0
- package/api/swizzle/swizzle.doc.mjs +5 -7
- package/api/template/copy/copy.mjs +1 -1
- package/api/template/copy/copy.test.mjs +0 -9
- package/api/template/template-integration.test.mjs +65 -1
- package/api/template/template.doc.mjs +1 -2
- package/api/template/template.mjs +1 -1
- package/api/theme/add/add.mjs +25 -17
- package/api/theme/add/add.staging.test.mjs +23 -40
- package/api/theme/build/build.family.test.mjs +12 -7
- package/api/theme/build/build.mjs +18 -8
- package/api/theme/generateTonalPalette.doc.mjs +2 -1
- package/api/theme/listThemes.doc.mjs +1 -1
- package/api/theme/themeAdd.doc.mjs +10 -9
- package/api/theme/themeBuild.doc.mjs +13 -13
- package/api/theme/themeList.doc.mjs +1 -1
- package/api/theme/themeListAvailable.doc.mjs +1 -2
- package/api/theme/themePaletteGenerate.doc.mjs +8 -15
- package/api/theme/themeTargets.doc.mjs +2 -3
- package/api/theme/themeTemplate.doc.mjs +1 -2
- package/api/upgrade/run/run.mjs +4 -6
- package/api/upgrade/upgrade.doc.mjs +22 -24
- package/api/upgrade/upgrade.type.mjs +2 -2
- package/assets/codemods/__tests__/runner.test.mjs +1 -3
- package/assets/codemods/integration-runner.mjs +3 -3
- package/assets/codemods/runner.mjs +4 -5
- package/assets/docs/README.md +2 -4
- package/assets/docs/browser-support.doc.mjs +11 -11
- package/assets/docs/color.doc.mjs +2 -8
- package/assets/docs/elevation.doc.mjs +4 -6
- package/assets/docs/getting-started.doc.mjs +16 -5
- package/assets/docs/icons.doc.mjs +21 -2
- package/assets/docs/illustrations.doc.mjs +15 -7
- package/assets/docs/internationalization.doc.mjs +5 -7
- package/assets/docs/layout.doc.dense.mjs +82 -130
- package/assets/docs/layout.doc.mjs +77 -133
- package/assets/docs/migration.doc.mjs +21 -19
- package/assets/docs/motion.doc.mjs +3 -16
- package/assets/docs/principles.doc.dense.mjs +5 -5
- package/assets/docs/principles.doc.mjs +0 -8
- package/assets/docs/principles.doc.zh.mjs +6 -6
- package/assets/docs/shape.doc.mjs +3 -8
- package/assets/docs/spacing.doc.mjs +2 -7
- package/assets/docs/styling-libraries.doc.mjs +2 -6
- package/assets/docs/styling.doc.mjs +23 -19
- package/assets/docs/theme.doc.dense.mjs +18 -58
- package/assets/docs/theme.doc.mjs +46 -56
- package/assets/docs/theme.doc.zh.mjs +8 -9
- package/assets/docs/tokens.doc.dense.mjs +2 -2
- package/assets/docs/tokens.doc.mjs +8 -389
- package/assets/docs/tokens.doc.zh.mjs +2 -2
- package/assets/docs/tree/integrations.doc.mjs +451 -25
- package/assets/docs/tree/integrations.test.mjs +62 -0
- package/assets/docs/tree/writing-docs.doc.mjs +286 -0
- package/assets/docs/typography.doc.mjs +4 -24
- package/assets/docs/working-with-ai.doc.mjs +22 -30
- package/assets/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.tsx +1 -1
- package/authoring/config/config.doc.mjs +2 -10
- package/authoring/config/parse.d.mts +0 -2
- package/authoring/config/parse.mjs +0 -19
- package/authoring/config/parse.test.mjs +0 -8
- package/authoring/config/type.ts +2 -13
- package/authoring/doctypes/_schema.d.mts +2 -3
- package/authoring/doctypes/_schema.mjs +0 -6
- package/authoring/doctypes/base/graph-fields.doc.mjs +3 -3
- package/authoring/doctypes/base/type.ts +2 -4
- package/authoring/doctypes/command/command.doc.mjs +1 -1
- package/authoring/doctypes/command/type.ts +1 -1
- package/authoring/doctypes/component/component.doc.mjs +0 -6
- package/authoring/doctypes/component/type.ts +0 -8
- package/authoring/doctypes/reference/reference.doc.mjs +0 -7
- package/authoring/doctypes/reference/type.ts +0 -5
- package/authoring/doctypes/schema/schema.doc.mjs +2 -2
- package/authoring/doctypes/template/template.doc.mjs +1 -1
- package/authoring/doctypes/template/type.ts +2 -2
- package/authoring/index.d.mts +0 -1
- package/authoring/index.d.ts +0 -10
- package/authoring/index.mjs +0 -1
- package/authoring/integration/integration.doc.mjs +10 -12
- package/clients/cli/command-result-coverage.test.mjs +7 -7
- package/clients/cli/commands/component/index.mjs +55 -152
- package/clients/cli/commands/component-ownership.test.mjs +0 -89
- package/clients/cli/commands/component.doc.mjs +9 -27
- package/clients/cli/commands/debug-result-summary.test.mjs +2 -2
- package/clients/cli/commands/discover.doc.mjs +9 -53
- package/clients/cli/commands/discover.mjs +118 -393
- package/clients/cli/commands/docs.doc.mjs +1 -1
- package/clients/cli/commands/docs.mjs +17 -60
- package/clients/cli/commands/docs.test.mjs +294 -0
- package/clients/cli/commands/doctor-integration-docs.doc.mjs +2 -3
- package/clients/cli/commands/doctor-integration.test.mjs +0 -53
- package/clients/cli/commands/doctor.doc.mjs +1 -3
- package/clients/cli/commands/doctor.mjs +5 -49
- package/clients/cli/commands/gap-report.doc.mjs +9 -10
- package/clients/cli/commands/init.doc.mjs +6 -9
- package/clients/cli/commands/integration-add.doc.mjs +9 -9
- package/clients/cli/commands/integration-authoring.test.mjs +10 -61
- package/clients/cli/commands/integration-pack.doc.mjs +9 -5
- package/clients/cli/commands/integration-real-world.test.mjs +1 -1
- package/clients/cli/commands/integration.doc.mjs +4 -4
- package/clients/cli/commands/integration.mjs +43 -74
- package/clients/cli/commands/layout-check.doc.mjs +65 -0
- package/clients/cli/commands/layout-expand.doc.mjs +83 -0
- package/clients/cli/commands/layout-grammar.doc.mjs +30 -0
- package/clients/cli/commands/layout.doc.mjs +34 -0
- package/clients/cli/commands/layout.error-codes.test.mjs +66 -0
- package/clients/cli/commands/layout.exit-parity.test.mjs +41 -0
- package/clients/cli/commands/layout.mjs +275 -0
- package/clients/cli/commands/layout.path-help.test.mjs +33 -0
- package/clients/cli/commands/layout.stdin-cap.test.mjs +47 -0
- package/clients/cli/commands/layout.text-fields.test.mjs +39 -0
- package/clients/cli/commands/manifest.doc.mjs +1 -1
- package/clients/cli/commands/search.doc.mjs +3 -10
- package/clients/cli/commands/search.mjs +2 -21
- package/clients/cli/commands/search.test.mjs +4 -21
- package/clients/cli/commands/swizzle.doc.mjs +1 -1
- package/clients/cli/commands/template.doc.mjs +1 -1
- package/clients/cli/commands/text-json-parity.test.mjs +16 -5
- package/clients/cli/commands/theme-add.doc.mjs +1 -1
- package/clients/cli/commands/theme-palette-generate.doc.mjs +2 -3
- package/clients/cli/commands/theme-palette.doc.mjs +2 -1
- package/clients/cli/commands/theme-targets.doc.mjs +2 -2
- package/clients/cli/commands/theme.doc.mjs +1 -2
- package/clients/cli/commands/upgrade.doc.mjs +3 -62
- package/clients/cli/index.mjs +10 -28
- package/clients/cli/lib/define-command.mjs +4 -28
- package/clients/cli/lib/define-command.test.mjs +0 -54
- package/clients/cli/lib/exit-codes.test.mjs +9 -18
- package/clients/cli/lib/json-shim.mjs +14 -24
- package/clients/cli/lib/json-shim.test.mjs +20 -6
- package/clients/cli/lib/manifest.mjs +13 -18
- package/clients/cli/lib/manifest.test.mjs +2 -5
- package/foundation/agent-docs/agent-docs.mjs +1 -1
- package/foundation/agent-docs/agent-docs.test.mjs +1159 -0
- package/foundation/discovery/authoring-self-docs.mjs +0 -1
- package/foundation/discovery/authoring-self-docs.test.mjs +2 -6
- package/foundation/discovery/cli-self-docs.mjs +2 -16
- package/foundation/discovery/cli-self-docs.test.mjs +0 -20
- package/foundation/discovery/docs-discovery.mjs +1 -5
- package/foundation/discovery/docs-discovery.test.mjs +0 -21
- package/foundation/discovery/docs-section-key.d.mts +1 -1
- package/foundation/discovery/docs-section-key.mjs +1 -1
- package/foundation/discovery/template-adapter.mjs +1 -1
- package/foundation/doc-compiler/doc-loads.test.mjs +14 -3
- package/foundation/doc-compiler/tree.d.mts +0 -4
- package/foundation/doc-compiler/tree.mjs +1 -6
- package/foundation/doc-compiler/tree.test.mjs +598 -0
- package/foundation/integrations/cli-requirement.d.mts +6 -26
- package/foundation/integrations/cli-requirement.mjs +11 -46
- package/foundation/integrations/cli-requirement.test.mjs +2 -7
- package/foundation/integrations/contribution-inventory.mjs +1 -1
- package/foundation/integrations/integrations.d.mts +1 -14
- package/foundation/integrations/integrations.mjs +1 -41
- package/foundation/integrations/integrations.test.mjs +0 -31
- package/foundation/response/error-codes.doc.mjs +8 -6
- package/foundation/response/error-codes.test.mjs +5 -30
- package/foundation/response/response-types.doc.d.mts +3 -4
- package/foundation/response/response-types.doc.mjs +27 -40
- package/foundation/response/response-types.doc.test.mjs +0 -23
- package/foundation/response/response.doc.mjs +10 -11
- package/foundation/xle/browser.d.mts +3 -3
- package/foundation/xle/browser.mjs +3 -3
- package/foundation/xle/expand.mjs +2 -2
- package/foundation/xle/parse.mjs +1 -1
- package/foundation/xle/print.mjs +2 -2
- package/foundation/xle/splice.mjs +1 -1
- package/package.json +9 -9
- package/api/discover/_adapter.test.mjs +0 -215
- package/api/discover/_catalog-view.d.mts +0 -115
- package/api/discover/_catalog-view.mjs +0 -203
- package/api/discover/_catalog-view.test.mjs +0 -128
- package/api/discover/detail/item/item.d.mts +0 -26
- package/api/discover/detail/item/item.mjs +0 -78
- package/api/discover/detail/item/item.test.mjs +0 -73
- package/api/integration/pack-check.lifecycle-output.test.mjs +0 -107
- package/api/theme/add/add.rollback.test.mjs +0 -158
- package/api/theme/build/build.rollback.test.mjs +0 -148
- package/api/upgrade/run/files-changed.test.mjs +0 -111
- package/assets/codemods/file-count.test.mjs +0 -163
- package/assets/docs/tree/add-a-component.doc.mjs +0 -75
- package/assets/docs/tree/add-a-theme.doc.mjs +0 -85
- package/assets/docs/tree/add-a-topic.doc.mjs +0 -144
- package/assets/docs/tree/agent-guidance.doc.mjs +0 -138
- package/assets/docs/tree/block-template.doc.mjs +0 -130
- package/assets/docs/tree/build-the-template.doc.mjs +0 -28
- package/assets/docs/tree/building-blocks.doc.mjs +0 -46
- package/assets/docs/tree/check-your-docs.doc.mjs +0 -137
- package/assets/docs/tree/checks.doc.mjs +0 -119
- package/assets/docs/tree/codemods.doc.mjs +0 -147
- package/assets/docs/tree/component-family.doc.mjs +0 -113
- package/assets/docs/tree/component-imports.doc.mjs +0 -69
- package/assets/docs/tree/component-lookups.doc.mjs +0 -149
- package/assets/docs/tree/components.doc.mjs +0 -23
- package/assets/docs/tree/configuration.doc.mjs +0 -23
- package/assets/docs/tree/debug-and-gap-reports.doc.mjs +0 -182
- package/assets/docs/tree/define-the-theme.doc.mjs +0 -118
- package/assets/docs/tree/describe-the-component.doc.mjs +0 -57
- package/assets/docs/tree/docs.doc.mjs +0 -21
- package/assets/docs/tree/document-the-template.doc.mjs +0 -28
- package/assets/docs/tree/document-the-theme.doc.mjs +0 -68
- package/assets/docs/tree/export-template-assets.doc.mjs +0 -147
- package/assets/docs/tree/extend-or-replace.doc.mjs +0 -103
- package/assets/docs/tree/fonts-and-assets.doc.mjs +0 -106
- package/assets/docs/tree/generate-a-palette.doc.mjs +0 -66
- package/assets/docs/tree/grade-template-with-agent.doc.mjs +0 -105
- package/assets/docs/tree/help.doc.mjs +0 -16
- package/assets/docs/tree/links.doc.mjs +0 -98
- package/assets/docs/tree/package-and-test.doc.mjs +0 -32
- package/assets/docs/tree/page-template.doc.mjs +0 -71
- package/assets/docs/tree/publishing.doc.mjs +0 -111
- package/assets/docs/tree/quick-start.doc.mjs +0 -272
- package/assets/docs/tree/replace-a-core-component.doc.mjs +0 -104
- package/assets/docs/tree/replace-a-core-template.doc.mjs +0 -172
- package/assets/docs/tree/sections-and-placement.doc.mjs +0 -108
- package/assets/docs/tree/see-it-in-an-app.doc.mjs +0 -59
- package/assets/docs/tree/ship.doc.mjs +0 -16
- package/assets/docs/tree/short-and-findable.doc.mjs +0 -108
- package/assets/docs/tree/single-component.doc.mjs +0 -165
- package/assets/docs/tree/start-a-template.doc.mjs +0 -143
- package/assets/docs/tree/subcomponent.doc.mjs +0 -115
- package/assets/docs/tree/template-assets.doc.mjs +0 -64
- package/assets/docs/tree/template-doc-overview.doc.mjs +0 -109
- package/assets/docs/tree/template-fonts.doc.mjs +0 -102
- package/assets/docs/tree/template-grading-rubric.doc.mjs +0 -452
- package/assets/docs/tree/template-icons.doc.mjs +0 -97
- package/assets/docs/tree/template-images-media.doc.mjs +0 -127
- package/assets/docs/tree/template-styles.doc.mjs +0 -93
- package/assets/docs/tree/templates.doc.mjs +0 -34
- package/assets/docs/tree/test-in-an-app.doc.mjs +0 -115
- package/assets/docs/tree/test-template-in-app.doc.mjs +0 -128
- package/assets/docs/tree/themes.doc.mjs +0 -39
- package/assets/docs/tree/troubleshooting.doc.mjs +0 -149
- package/assets/docs/tree/upgrading.doc.mjs +0 -103
- package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +0 -51
- package/assets/docs/tree/verify-packed-template.doc.mjs +0 -77
- package/assets/docs/tree/versioning.doc.mjs +0 -161
- package/assets/docs/tree/write-good-templates.doc.mjs +0 -64
- package/assets/docs/tree/write-the-template-file.doc.mjs +0 -154
- package/authoring/discover/discover.doc.d.mts +0 -13
- package/authoring/discover/discover.doc.mjs +0 -138
- package/authoring/discover/parse.d.mts +0 -24
- package/authoring/discover/parse.mjs +0 -128
- package/authoring/discover/parse.test.mjs +0 -124
- package/authoring/discover/type.ts +0 -87
- package/clients/cli/commands/component-batch.test.mjs +0 -341
- package/clients/cli/commands/discover.sources.test.mjs +0 -267
- package/clients/cli/commands/integration-verify.doc.mjs +0 -22
- package/clients/cli/lib/parse-error-format.test.mjs +0 -81
- package/foundation/response/batch.type.d.mts +0 -33
- package/foundation/response/batch.type.mjs +0 -34
|
@@ -1,76 +1,44 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* @file discover.search leaf — free-text search across
|
|
5
|
-
* when the project has discover sources, everything it could add.
|
|
4
|
+
* @file discover.search leaf — free-text search across external packages.
|
|
6
5
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* packages, and every item a source lists for a package the project could add.
|
|
14
|
-
* A caller opens one item by its package path, which ../detail answers.
|
|
6
|
+
* Resolution order (matching the flat command exactly):
|
|
7
|
+
* 1. exact component name -> discover.detail.doc
|
|
8
|
+
* 2. single substring hit -> discover.detail.doc
|
|
9
|
+
* 3. multiple substring hits -> discover.search
|
|
10
|
+
* 4. fuzzy hits (distance <= 3) -> throw ERR_NOT_FOUND with suggestions
|
|
11
|
+
* 5. otherwise -> throw ERR_NOT_FOUND
|
|
15
12
|
*
|
|
16
|
-
* @position api/discover/search —
|
|
17
|
-
*
|
|
13
|
+
* @position api/discover/search — projection over ../_adapter's resolver;
|
|
14
|
+
* delegates the single-component cases to ../detail/doc.
|
|
18
15
|
*/
|
|
19
16
|
|
|
17
|
+
import {findComponent} from '../_adapter.mjs';
|
|
18
|
+
import {docFromResult} from '../detail/doc/doc.mjs';
|
|
20
19
|
import {levenshteinDistance} from '../../../foundation/text/string-utils.mjs';
|
|
21
20
|
import {AstryxError} from '../../error.mjs';
|
|
22
21
|
import {ERROR_CODES} from '../../../foundation/response/error-codes.mjs';
|
|
23
|
-
import {DISCOVER_KINDS} from '../../../authoring/discover/parse.mjs';
|
|
24
22
|
|
|
25
23
|
/**
|
|
26
24
|
* @typedef {import('../_package-scanner.mjs').ScannedPackage} ScannedPackage
|
|
27
|
-
* @typedef {import('../_catalog-view.mjs').SearchItem} SearchItem
|
|
28
25
|
*/
|
|
29
26
|
|
|
30
|
-
const KIND_ORDER = ['package', ...DISCOVER_KINDS];
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* How well an item matches: 0 exact name, 1 name prefix, 2 name substring,
|
|
34
|
-
* 3 title, summary, keyword, or description; null for no match.
|
|
35
|
-
* @param {SearchItem} item
|
|
36
|
-
* @param {string} lower
|
|
37
|
-
* @returns {number | null}
|
|
38
|
-
*/
|
|
39
|
-
function rank(item, lower) {
|
|
40
|
-
const name = item.name.toLowerCase();
|
|
41
|
-
if (name === lower) return 0;
|
|
42
|
-
if (name.startsWith(lower)) return 1;
|
|
43
|
-
if (name.includes(lower)) return 2;
|
|
44
|
-
const text = [
|
|
45
|
-
item.title,
|
|
46
|
-
item.summary,
|
|
47
|
-
item.description,
|
|
48
|
-
...(item.keywords ?? []),
|
|
49
|
-
]
|
|
50
|
-
.filter(Boolean)
|
|
51
|
-
.join('\n')
|
|
52
|
-
.toLowerCase();
|
|
53
|
-
return text.includes(lower) ? 3 : null;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
27
|
/**
|
|
57
28
|
* Search all packages for `query` (a free-text term that never starts with
|
|
58
|
-
* `@`). Resolves to a
|
|
59
|
-
*
|
|
60
|
-
*
|
|
29
|
+
* `@`). Resolves to a single component's docs when unambiguous, a search
|
|
30
|
+
* response when several match, or throws AstryxError (ERR_NOT_FOUND) — with
|
|
31
|
+
* fuzzy suggestions when any exist.
|
|
61
32
|
*
|
|
62
|
-
* @param {ScannedPackage[]} packages
|
|
33
|
+
* @param {ScannedPackage[]} packages
|
|
63
34
|
* @param {string} query
|
|
64
|
-
* @param {{
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* }} opts
|
|
70
|
-
* @returns {Promise<import('../discover.type.mjs').DiscoverSearchResponse>}
|
|
35
|
+
* @param {{lang?: string | null, zh?: boolean}} opts
|
|
36
|
+
* @returns {Promise<
|
|
37
|
+
* import('../discover.type.mjs').DiscoverDetailDocResponse |
|
|
38
|
+
* import('../discover.type.mjs').DiscoverSearchResponse
|
|
39
|
+
* >}
|
|
71
40
|
*/
|
|
72
|
-
export async function search(packages, query,
|
|
73
|
-
const {items = [], type, only, limit} = opts;
|
|
41
|
+
export async function search(packages, query, {lang, zh}) {
|
|
74
42
|
// An empty query must error, not match every component via `.includes('')`
|
|
75
43
|
// (parity with the api/search leaf). The discover() dispatcher already routes
|
|
76
44
|
// an empty query to list, but the leaf must be safe on its own.
|
|
@@ -83,64 +51,50 @@ export async function search(packages, query, opts) {
|
|
|
83
51
|
}
|
|
84
52
|
const lower = query.toLowerCase();
|
|
85
53
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
pkg.components.map(name => ({
|
|
89
|
-
package: pkg.name,
|
|
90
|
-
kind: /** @type {const} */ ('component'),
|
|
91
|
-
name,
|
|
92
|
-
installed: true,
|
|
93
|
-
})),
|
|
94
|
-
);
|
|
54
|
+
const exact = findComponent(packages, query);
|
|
55
|
+
if (exact) return await docFromResult(exact, {lang, zh});
|
|
95
56
|
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
.map(item => ({item, score: rank(item, lower)}))
|
|
106
|
-
.filter(
|
|
107
|
-
/** @returns {m is {item: SearchItem, score: number}} */
|
|
108
|
-
m => m.score != null,
|
|
109
|
-
)
|
|
110
|
-
.sort(
|
|
111
|
-
(a, b) =>
|
|
112
|
-
a.score - b.score ||
|
|
113
|
-
Number(b.item.installed) - Number(a.item.installed) ||
|
|
114
|
-
KIND_ORDER.indexOf(a.item.kind) - KIND_ORDER.indexOf(b.item.kind) ||
|
|
115
|
-
a.item.package.localeCompare(b.item.package) ||
|
|
116
|
-
a.item.name.localeCompare(b.item.name),
|
|
117
|
-
);
|
|
57
|
+
const substringMatches =
|
|
58
|
+
/** @type {Array<{pkg: ScannedPackage, comp: string}>} */ ([]);
|
|
59
|
+
for (const pkg of packages) {
|
|
60
|
+
for (const comp of pkg.components) {
|
|
61
|
+
if (comp.toLowerCase().includes(lower)) {
|
|
62
|
+
substringMatches.push({pkg, comp});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
118
66
|
|
|
119
|
-
if (
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
...(item.summary ? {summary: item.summary} : {}),
|
|
127
|
-
}));
|
|
128
|
-
const shown = limit == null ? matches : matches.slice(0, limit);
|
|
67
|
+
if (substringMatches.length === 1) {
|
|
68
|
+
const match = substringMatches[0];
|
|
69
|
+
const result = findComponent([match.pkg], match.comp);
|
|
70
|
+
if (result) return await docFromResult(result, {lang, zh});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (substringMatches.length > 1) {
|
|
129
74
|
return {
|
|
130
75
|
type: 'discover.search',
|
|
131
76
|
data: {
|
|
132
77
|
query,
|
|
133
|
-
matches:
|
|
134
|
-
|
|
78
|
+
matches: substringMatches.map(m => ({
|
|
79
|
+
package: m.pkg.name,
|
|
80
|
+
component: m.comp,
|
|
81
|
+
})),
|
|
135
82
|
},
|
|
136
83
|
};
|
|
137
84
|
}
|
|
138
85
|
|
|
139
|
-
// Fuzzy fallback
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
86
|
+
// Fuzzy fallback
|
|
87
|
+
const allComponents =
|
|
88
|
+
/** @type {Array<{pkg: ScannedPackage, comp: string}>} */ ([]);
|
|
89
|
+
for (const pkg of packages) {
|
|
90
|
+
for (const comp of pkg.components) {
|
|
91
|
+
allComponents.push({pkg, comp});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const fuzzyMatches = allComponents
|
|
95
|
+
.map(item => ({
|
|
96
|
+
...item,
|
|
97
|
+
distance: levenshteinDistance(lower, item.comp.toLowerCase()),
|
|
144
98
|
}))
|
|
145
99
|
.filter(m => m.distance <= 3)
|
|
146
100
|
.sort((a, b) => a.distance - b.distance)
|
|
@@ -150,7 +104,7 @@ export async function search(packages, query, opts) {
|
|
|
150
104
|
throw new AstryxError(
|
|
151
105
|
`"${query}" not found`,
|
|
152
106
|
fuzzyMatches.map(m => ({
|
|
153
|
-
name: m.
|
|
107
|
+
name: m.pkg.name + '/' + m.comp,
|
|
154
108
|
reason: 'similar name',
|
|
155
109
|
})),
|
|
156
110
|
ERROR_CODES.ERR_NOT_FOUND,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* @file Colocated tests for the discover.search leaf
|
|
5
|
-
*
|
|
4
|
+
* @file Colocated tests for the discover.search leaf. Exact/single matches load
|
|
5
|
+
* a real `.doc.mjs`, so these drive a small temp docs directory.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import {describe, it, expect, beforeAll, afterAll} from 'vitest';
|
|
@@ -47,31 +47,16 @@ afterAll(() => {
|
|
|
47
47
|
});
|
|
48
48
|
|
|
49
49
|
describe('discover.search leaf', () => {
|
|
50
|
-
it('
|
|
50
|
+
it('an exact component name resolves to its docs', async () => {
|
|
51
51
|
const res = await search(packages, 'Alpha', {});
|
|
52
|
-
expect(res.type).toBe('discover.
|
|
53
|
-
expect(res.data.
|
|
54
|
-
'Alpha',
|
|
55
|
-
'AlphaCard',
|
|
56
|
-
]);
|
|
52
|
+
expect(res.type).toBe('discover.detail.doc');
|
|
53
|
+
expect(res.data.name).toBe('Alpha');
|
|
57
54
|
});
|
|
58
55
|
|
|
59
|
-
it('
|
|
56
|
+
it('a single substring match resolves to its docs', async () => {
|
|
60
57
|
const res = await search(packages, 'card', {});
|
|
61
|
-
expect(res).
|
|
62
|
-
|
|
63
|
-
data: {
|
|
64
|
-
query: 'card',
|
|
65
|
-
matches: [
|
|
66
|
-
{
|
|
67
|
-
package: '@acme/widgets',
|
|
68
|
-
component: 'AlphaCard',
|
|
69
|
-
kind: 'component',
|
|
70
|
-
installed: true,
|
|
71
|
-
},
|
|
72
|
-
],
|
|
73
|
-
},
|
|
74
|
-
});
|
|
58
|
+
expect(res.type).toBe('discover.detail.doc');
|
|
59
|
+
expect(res.data.name).toBe('AlphaCard');
|
|
75
60
|
});
|
|
76
61
|
|
|
77
62
|
it('multiple substring matches return a search response', async () => {
|
|
@@ -81,18 +66,8 @@ describe('discover.search leaf', () => {
|
|
|
81
66
|
data: {
|
|
82
67
|
query: 'alph',
|
|
83
68
|
matches: [
|
|
84
|
-
{
|
|
85
|
-
|
|
86
|
-
component: 'Alpha',
|
|
87
|
-
kind: 'component',
|
|
88
|
-
installed: true,
|
|
89
|
-
},
|
|
90
|
-
{
|
|
91
|
-
package: '@acme/widgets',
|
|
92
|
-
component: 'AlphaCard',
|
|
93
|
-
kind: 'component',
|
|
94
|
-
installed: true,
|
|
95
|
-
},
|
|
69
|
+
{package: '@acme/widgets', component: 'Alpha'},
|
|
70
|
+
{package: '@acme/widgets', component: 'AlphaCard'},
|
|
96
71
|
],
|
|
97
72
|
},
|
|
98
73
|
});
|
|
@@ -141,112 +116,3 @@ describe('discover.search leaf — empty query (parity with api/search)', () =>
|
|
|
141
116
|
});
|
|
142
117
|
});
|
|
143
118
|
});
|
|
144
|
-
|
|
145
|
-
describe('discover.search leaf across every kind and source', () => {
|
|
146
|
-
/** @type {any[]} */
|
|
147
|
-
const items = [
|
|
148
|
-
{
|
|
149
|
-
package: '@acme/widgets',
|
|
150
|
-
kind: 'template',
|
|
151
|
-
name: 'pages/AlphaHome',
|
|
152
|
-
installed: true,
|
|
153
|
-
},
|
|
154
|
-
{
|
|
155
|
-
package: '@acme/charts',
|
|
156
|
-
kind: 'package',
|
|
157
|
-
name: '@acme/charts',
|
|
158
|
-
installed: false,
|
|
159
|
-
description: 'Charts for alpha dashboards',
|
|
160
|
-
},
|
|
161
|
-
{
|
|
162
|
-
package: '@acme/charts',
|
|
163
|
-
kind: 'component',
|
|
164
|
-
name: 'AlphaChart',
|
|
165
|
-
installed: false,
|
|
166
|
-
},
|
|
167
|
-
{
|
|
168
|
-
package: '@acme/charts',
|
|
169
|
-
kind: 'doc',
|
|
170
|
-
name: 'guide',
|
|
171
|
-
installed: false,
|
|
172
|
-
summary: 'How to chart',
|
|
173
|
-
},
|
|
174
|
-
];
|
|
175
|
-
|
|
176
|
-
it('ranks every match by how closely its name matches, installed first among equals', async () => {
|
|
177
|
-
const res = await search(packages, 'alph', {items});
|
|
178
|
-
expect(res.type).toBe('discover.search');
|
|
179
|
-
expect(
|
|
180
|
-
res.data.matches.map(m => [m.kind, m.component, m.installed]),
|
|
181
|
-
).toEqual([
|
|
182
|
-
['component', 'Alpha', true],
|
|
183
|
-
['component', 'AlphaCard', true],
|
|
184
|
-
['component', 'AlphaChart', false],
|
|
185
|
-
['template', 'pages/AlphaHome', true],
|
|
186
|
-
['package', '@acme/charts', false],
|
|
187
|
-
]);
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
it('lists an exact installed component name with the matches from every source', async () => {
|
|
191
|
-
const res = await search(packages, 'Alpha', {items});
|
|
192
|
-
expect(res.type).toBe('discover.search');
|
|
193
|
-
expect(res.data.matches[0]).toEqual({
|
|
194
|
-
package: '@acme/widgets',
|
|
195
|
-
component: 'Alpha',
|
|
196
|
-
kind: 'component',
|
|
197
|
-
installed: true,
|
|
198
|
-
});
|
|
199
|
-
expect(res.data.matches.map(m => m.component)).toContain('AlphaChart');
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
it('lists a single partial component match when other items match too', async () => {
|
|
203
|
-
const res = await search(packages, 'card', {
|
|
204
|
-
items: [
|
|
205
|
-
...items,
|
|
206
|
-
{
|
|
207
|
-
package: '@acme/charts',
|
|
208
|
-
kind: 'template',
|
|
209
|
-
name: 'pages/CardGrid',
|
|
210
|
-
installed: false,
|
|
211
|
-
},
|
|
212
|
-
],
|
|
213
|
-
});
|
|
214
|
-
expect(res.type).toBe('discover.search');
|
|
215
|
-
expect(res.data.matches.map(m => m.component)).toEqual([
|
|
216
|
-
'AlphaCard',
|
|
217
|
-
'pages/CardGrid',
|
|
218
|
-
]);
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
it('lists one installed component when nothing else matches', async () => {
|
|
222
|
-
const res = await search(packages, 'card', {items});
|
|
223
|
-
expect(res.type).toBe('discover.search');
|
|
224
|
-
expect(res.data.matches.map(m => m.component)).toEqual(['AlphaCard']);
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
it('keeps one kind with type, and one side with only', async () => {
|
|
228
|
-
const templates = await search(packages, 'alph', {items, type: 'template'});
|
|
229
|
-
expect(templates.data.matches.map(m => m.component)).toEqual([
|
|
230
|
-
'pages/AlphaHome',
|
|
231
|
-
]);
|
|
232
|
-
const available = await search(packages, 'alph', {
|
|
233
|
-
items,
|
|
234
|
-
only: 'available',
|
|
235
|
-
});
|
|
236
|
-
expect(available.data.matches.map(m => m.component)).toEqual([
|
|
237
|
-
'AlphaChart',
|
|
238
|
-
'@acme/charts',
|
|
239
|
-
]);
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
it('caps the list at limit and reports the total', async () => {
|
|
243
|
-
const res = await search(packages, 'alph', {items, limit: 2});
|
|
244
|
-
expect(res.data.matches).toHaveLength(2);
|
|
245
|
-
expect(res.data.total).toBe(5);
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
it('matches titles, summaries, keywords, and descriptions too', async () => {
|
|
249
|
-
const res = await search(packages, 'how to chart', {items});
|
|
250
|
-
expect(res.data.matches.map(m => m.component)).toEqual(['guide']);
|
|
251
|
-
});
|
|
252
|
-
});
|
package/api/docs/_adapter.d.mts
CHANGED
|
@@ -77,12 +77,10 @@ export function docsLinkProblems(catalog: DocsCatalog, tree: DocsTree, { owner,
|
|
|
77
77
|
/**
|
|
78
78
|
* What \`astryx doctor integration docs\` checks in one integration's docs: the
|
|
79
79
|
* docs tree they build beside the CLI's (namespaces, placements, routes) and
|
|
80
|
-
* every link in them (spec:AST-046, spec:AST-047).
|
|
81
|
-
* so it is an error; a link that names no doc prints as written, so it is a
|
|
82
|
-
* warning.
|
|
80
|
+
* every link in them (spec:AST-046, spec:AST-047).
|
|
83
81
|
* @param {{name: string}} integration
|
|
84
82
|
* @param {{records: import('../../foundation/discovery/docs-discovery.mjs').DocsTopicRecord[], namespaces: import('../../foundation/doc-compiler/tree.mjs').TreeNamespaceInput[], guides: import('../../foundation/doc-compiler/tree.mjs').TreeDocInput[]}} discovered
|
|
85
|
-
* @returns {Promise<
|
|
83
|
+
* @returns {Promise<string[]>}
|
|
86
84
|
*/
|
|
87
85
|
export function packageDocsProblems(integration: {
|
|
88
86
|
name: string;
|
|
@@ -90,10 +88,7 @@ export function packageDocsProblems(integration: {
|
|
|
90
88
|
records: import("../../foundation/discovery/docs-discovery.mjs").DocsTopicRecord[];
|
|
91
89
|
namespaces: import("../../foundation/doc-compiler/tree.mjs").TreeNamespaceInput[];
|
|
92
90
|
guides: import("../../foundation/doc-compiler/tree.mjs").TreeDocInput[];
|
|
93
|
-
}): Promise<
|
|
94
|
-
severity: "error" | "warning";
|
|
95
|
-
message: string;
|
|
96
|
-
}>>;
|
|
91
|
+
}): Promise<string[]>;
|
|
97
92
|
/**
|
|
98
93
|
* How a token reference finds its target: the topic it names in `catalog`,
|
|
99
94
|
* lowered for the same language.
|
package/api/docs/_adapter.mjs
CHANGED
|
@@ -667,12 +667,10 @@ export async function docsLinkProblems(
|
|
|
667
667
|
/**
|
|
668
668
|
* What \`astryx doctor integration docs\` checks in one integration's docs: the
|
|
669
669
|
* docs tree they build beside the CLI's (namespaces, placements, routes) and
|
|
670
|
-
* every link in them (spec:AST-046, spec:AST-047).
|
|
671
|
-
* so it is an error; a link that names no doc prints as written, so it is a
|
|
672
|
-
* warning.
|
|
670
|
+
* every link in them (spec:AST-046, spec:AST-047).
|
|
673
671
|
* @param {{name: string}} integration
|
|
674
672
|
* @param {{records: import('../../foundation/discovery/docs-discovery.mjs').DocsTopicRecord[], namespaces: import('../../foundation/doc-compiler/tree.mjs').TreeNamespaceInput[], guides: import('../../foundation/doc-compiler/tree.mjs').TreeDocInput[]}} discovered
|
|
675
|
-
* @returns {Promise<
|
|
673
|
+
* @returns {Promise<string[]>}
|
|
676
674
|
*/
|
|
677
675
|
export async function packageDocsProblems(integration, discovered) {
|
|
678
676
|
const catalog = DocsCatalog.fromBuiltins();
|
|
@@ -682,18 +680,12 @@ export async function packageDocsProblems(integration, discovered) {
|
|
|
682
680
|
guides: discovered.guides.map(input => ({...input, rank: 1})),
|
|
683
681
|
});
|
|
684
682
|
const tree = await projectTree(catalog);
|
|
685
|
-
/** @type {Array<{severity: 'error' | 'warning', message: string}>} */
|
|
686
683
|
const problems = tree.diagnostics
|
|
687
684
|
.filter(d => d.severity === 'error' && d.provider === integration.name)
|
|
688
|
-
.map(d =>
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
for (const message of await docsLinkProblems(catalog, tree, {
|
|
693
|
-
owner: integration.name,
|
|
694
|
-
})) {
|
|
695
|
-
problems.push({severity: 'warning', message});
|
|
696
|
-
}
|
|
685
|
+
.map(d => `${d.source ?? integration.name}: ${d.message}`);
|
|
686
|
+
problems.push(
|
|
687
|
+
...(await docsLinkProblems(catalog, tree, {owner: integration.name})),
|
|
688
|
+
);
|
|
697
689
|
return problems;
|
|
698
690
|
}
|
|
699
691
|
|
|
@@ -76,32 +76,6 @@ describe('reference doc overlays (#2182)', () => {
|
|
|
76
76
|
).toEqual([]);
|
|
77
77
|
});
|
|
78
78
|
|
|
79
|
-
it(`${topic} --${variant}: every content override lands on a block of its own type`, async () => {
|
|
80
|
-
// Blocks are matched by index and type, and a mismatch is dropped with
|
|
81
|
-
// no warning: a prose override aimed at a code block leaves the base
|
|
82
|
-
// text in place, so the reader gets a translated title over an English
|
|
83
|
-
// body. Pad with null to reach the block you mean.
|
|
84
|
-
const base = await load(basePath);
|
|
85
|
-
const overlayMod = await load(overlayPath);
|
|
86
|
-
const overlay = overlayMod.docsDense || overlayMod.docsZh;
|
|
87
|
-
const byTitle = new Map(base.docs.sections.map(s => [s.title, s]));
|
|
88
|
-
const dropped = [];
|
|
89
|
-
for (const entry of overlay.sections || []) {
|
|
90
|
-
const section = byTitle.get(entry.section);
|
|
91
|
-
if (!section) continue;
|
|
92
|
-
(entry.content || []).forEach((block, i) => {
|
|
93
|
-
if (block == null) return;
|
|
94
|
-
const target = section.content[i];
|
|
95
|
-
if (target?.type !== block.type) {
|
|
96
|
-
dropped.push(
|
|
97
|
-
`${entry.section} block ${i}: ${block.type} over ${target?.type ?? 'nothing'}`,
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
expect(dropped, `${topic}.doc.${variant}.mjs overrides that never apply`).toEqual([]);
|
|
103
|
-
});
|
|
104
|
-
|
|
105
79
|
it(`${topic} --${variant}: no base section is overridden twice`, async () => {
|
|
106
80
|
const overlayMod = await load(overlayPath);
|
|
107
81
|
const overlay = overlayMod.docsDense || overlayMod.docsZh;
|
|
@@ -153,7 +127,7 @@ describe('the reported defect: docs tokens --dense (#2182)', () => {
|
|
|
153
127
|
const zh = await docs('theme', null, {zh: true});
|
|
154
128
|
const titles = zh.data.sections.map(s => s.title);
|
|
155
129
|
// Every section the overlay translates must appear once, in Chinese only.
|
|
156
|
-
expect(titles).not.toContain('Dark
|
|
130
|
+
expect(titles).not.toContain('Light/Dark Mode');
|
|
157
131
|
expect(titles).toContain('亮/暗模式');
|
|
158
132
|
});
|
|
159
133
|
});
|
package/api/docs/docs.doc.mjs
CHANGED
|
@@ -27,7 +27,7 @@ export const doc = {
|
|
|
27
27
|
'A route opens a node of the docs tree instead: a namespace such as ' +
|
|
28
28
|
"`cli/api` returns its children one level down, a typed doc such as " +
|
|
29
29
|
"`cli/api/functions/search` returns its content, and a guide the tree " +
|
|
30
|
-
'places (`cli/integrations
|
|
30
|
+
'places (`cli/integrations`) reads like any topic. ' +
|
|
31
31
|
'Every read but the list carries `links`, the commands that move from it: ' +
|
|
32
32
|
'`up` to the level it sits in, `previous` and `next` to its neighbors, and, ' +
|
|
33
33
|
'for a typed doc, `related` to the docs it names (its command or function, ' +
|
|
@@ -137,7 +137,7 @@ export const doc = {
|
|
|
137
137
|
{label: 'One API function', code: "await docs('cli/api/functions/search');"},
|
|
138
138
|
{
|
|
139
139
|
label: 'A whole guide from the docs tree',
|
|
140
|
-
code: "await docs('cli/integrations
|
|
140
|
+
code: "await docs('cli/integrations');",
|
|
141
141
|
},
|
|
142
142
|
{label: 'One section by key', code: "await docs('tokens', 'spacing');"},
|
|
143
143
|
],
|