@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,139 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file Domain priority: when a component, hook, template, or theme ranks
|
|
5
|
+
* ahead of docs the reader did not ask for.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {sameWord} from './_words.mjs';
|
|
9
|
+
import {phraseWords, samePhraseWord, samePhrase} from './_query.mjs';
|
|
10
|
+
import {compoundHit, compoundOf} from './_compound.mjs';
|
|
11
|
+
import {
|
|
12
|
+
bestForToken,
|
|
13
|
+
FULL_COVERAGE_SCORE,
|
|
14
|
+
STRONG_TOKEN_SCORE,
|
|
15
|
+
} from './_score.mjs';
|
|
16
|
+
import {TITLE_PHRASE_SCORE, TITLE_IN_QUERY_SCORE} from './_titles.mjs';
|
|
17
|
+
import {scoreCandidate} from './_candidate-score.mjs';
|
|
18
|
+
|
|
19
|
+
/** @typedef {import('./_lexical.mjs').Candidate} Candidate */
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* A match's domain priority: 0 (none), 1, or 2 (a doc the whole query names).
|
|
23
|
+
* A component, hook, template, or theme with priority ranks ahead of any doc
|
|
24
|
+
* without it, whatever the two scores are. Docs among themselves rank by
|
|
25
|
+
* priority, then score; everything else ranks among itself by score.
|
|
26
|
+
*
|
|
27
|
+
* A component, hook, template, or theme has priority (1) when one of the
|
|
28
|
+
* query's words, or the whole query, hits its name or an authored keyword at
|
|
29
|
+
* {@link STRONG_TOKEN_SCORE} or above, or when it matches every word.
|
|
30
|
+
*
|
|
31
|
+
* A doc has priority when the reader asked for that doc:
|
|
32
|
+
* - 2: the whole query is the topic's name, its last route segment, or its
|
|
33
|
+
* own title, as words and whatever the plural (`font setup` is
|
|
34
|
+
* typography/font-setup, `side panel` is "Side panels");
|
|
35
|
+
* - 1: a word of the query is the topic's name (`illustration` in a longer
|
|
36
|
+
* question is the illustrations guide);
|
|
37
|
+
* - 1: a query of two or more words is one of the topic's own declared
|
|
38
|
+
* keywords, whatever the plural (`code review` on a guide that declares it);
|
|
39
|
+
* - 1: the query holds one of the doc's titles whole (`resizable side panels`
|
|
40
|
+
* names "Side panels"; `light dark mode button` names "Light/Dark Mode");
|
|
41
|
+
* - 1: the doc matches every word of the query and one of them is a word of
|
|
42
|
+
* its title (`switch to a dark theme` and "Use a theme").
|
|
43
|
+
* A section answers to its topic's name.
|
|
44
|
+
*
|
|
45
|
+
* A doc that matched only by a heading holding the query, by one word, or by
|
|
46
|
+
* words spread through its text has no priority. Docs are split into many
|
|
47
|
+
* small topics, each with its own headings, so a common phrase such as
|
|
48
|
+
* `font size` hits a heading exactly (170) while the component the reader is
|
|
49
|
+
* after matches one word by keyword (`Text`, 98). Ranked on text alone, every
|
|
50
|
+
* split adds another doc above the component. Broad reference pages match every word of many queries
|
|
51
|
+
* in their text the same way. The score stays the text-match strength the
|
|
52
|
+
* result reports, so callers that gate on it (`build`) see the same numbers.
|
|
53
|
+
*
|
|
54
|
+
* @param {string} term - Lowercased search term.
|
|
55
|
+
* @param {string[]} tokens - Content tokens from tokenizeQuery(term).
|
|
56
|
+
* @param {Candidate} candidate
|
|
57
|
+
* @param {{score: number, matched: number, total: number}} hit - The
|
|
58
|
+
* candidate's scoreQuery result.
|
|
59
|
+
* @returns {0 | 1 | 2}
|
|
60
|
+
*/
|
|
61
|
+
export function domainPriority(
|
|
62
|
+
term,
|
|
63
|
+
tokens,
|
|
64
|
+
candidate,
|
|
65
|
+
hit,
|
|
66
|
+
queryWords = phraseWords(term),
|
|
67
|
+
) {
|
|
68
|
+
const words = [term, ...tokens];
|
|
69
|
+
if (candidate.domain === 'doc') {
|
|
70
|
+
const topic = String(candidate._topic ?? candidate.name).toLowerCase();
|
|
71
|
+
// The whole query, read as words, is the topic's route, its last
|
|
72
|
+
// segment, or its own title, whatever the plural: `side panel` is
|
|
73
|
+
// layout/side-panels, and `header and footer` is "Headers and footers".
|
|
74
|
+
// A section's title is a heading inside a topic, not the topic's name.
|
|
75
|
+
const named = [topic, topic.slice(topic.lastIndexOf('/') + 1)];
|
|
76
|
+
if (candidate._section == null && candidate.titles?.[0]) {
|
|
77
|
+
named.push(candidate.titles[0]);
|
|
78
|
+
}
|
|
79
|
+
if (named.some(n => samePhrase(term, n))) {
|
|
80
|
+
return 2;
|
|
81
|
+
}
|
|
82
|
+
// A query of two or more words that is one of the doc's own declared
|
|
83
|
+
// keywords, read as words whatever the plural, is the author naming the
|
|
84
|
+
// doc for that phrase: `code review` on a guide that declares it. Only
|
|
85
|
+
// what the author declared counts: the code terms and table cells a
|
|
86
|
+
// doc's other keywords add (`missing_field`) name what it mentions, not
|
|
87
|
+
// what it is for. One word is left out too, and a section declares
|
|
88
|
+
// nothing.
|
|
89
|
+
if (
|
|
90
|
+
phraseWords(term).length >= 2 &&
|
|
91
|
+
candidate._section == null &&
|
|
92
|
+
(candidate._declared ?? []).some(k => samePhrase(term, String(k)))
|
|
93
|
+
) {
|
|
94
|
+
return 1;
|
|
95
|
+
}
|
|
96
|
+
if (
|
|
97
|
+
words.some(
|
|
98
|
+
w =>
|
|
99
|
+
(scoreCandidate(w, {name: topic}, {fuzzy: false})?.score ?? 0) >= 95,
|
|
100
|
+
)
|
|
101
|
+
) {
|
|
102
|
+
return 1;
|
|
103
|
+
}
|
|
104
|
+
// A whole title inside the query is the only path to 160-169.
|
|
105
|
+
if (hit.score >= TITLE_IN_QUERY_SCORE && hit.score < TITLE_PHRASE_SCORE) {
|
|
106
|
+
return 1;
|
|
107
|
+
}
|
|
108
|
+
// Every word matched, and one of them names the doc in its title.
|
|
109
|
+
if (
|
|
110
|
+
hit.score >= FULL_COVERAGE_SCORE &&
|
|
111
|
+
hit.score < TITLE_IN_QUERY_SCORE &&
|
|
112
|
+
hit.matched === hit.total
|
|
113
|
+
) {
|
|
114
|
+
const titleWords = phraseWords(candidate.titles?.[0] ?? '');
|
|
115
|
+
if (
|
|
116
|
+
(tokens.length ? tokens : [term]).some(t =>
|
|
117
|
+
titleWords.some(w => samePhraseWord(t, w) || sameWord(t, w)),
|
|
118
|
+
)
|
|
119
|
+
) {
|
|
120
|
+
return 1;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return 0;
|
|
124
|
+
}
|
|
125
|
+
if (hit.score >= FULL_COVERAGE_SCORE) return 1;
|
|
126
|
+
const compound = compoundOf.has(candidate)
|
|
127
|
+
? compoundOf.get(candidate)
|
|
128
|
+
: compoundHit(queryWords, candidate);
|
|
129
|
+
if ((compound?.score ?? 0) >= STRONG_TOKEN_SCORE) {
|
|
130
|
+
return 1;
|
|
131
|
+
}
|
|
132
|
+
const fuzzy = tokens.length <= 1;
|
|
133
|
+
return words.some(
|
|
134
|
+
w =>
|
|
135
|
+
(bestForToken(w, candidate, {fuzzy})?.score ?? 0) >= STRONG_TOKEN_SCORE,
|
|
136
|
+
)
|
|
137
|
+
? 1
|
|
138
|
+
: 0;
|
|
139
|
+
}
|
|
@@ -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
|
+
/** Plural folding: one fixed rule per suffix. @param {string} w */
|
|
5
|
+
export function fold(w: string): string;
|
|
6
|
+
/** A name's words: `DateRangeInput` is date, range, input. @param {string} name */
|
|
7
|
+
export function nameWords(name: string): string[];
|
|
8
|
+
/** @param {string} q @returns {string[]} unique words, then adjacent pairs */
|
|
9
|
+
export function queryTokens(q: string): string[];
|
|
10
|
+
/** The router's inputs: the query's tokens plus four shape flags. @param {string} q */
|
|
11
|
+
export function routerTokens(q: string): string[];
|
|
12
|
+
/**
|
|
13
|
+
* The router's probability for each class: the shared classifier over the
|
|
14
|
+
* query's tokens.
|
|
15
|
+
* @param {import('../../foundation/route/route.mjs').ClassifierWeights} weights
|
|
16
|
+
* @param {string} q
|
|
17
|
+
* @returns {number[]}
|
|
18
|
+
*/
|
|
19
|
+
export function routeProbs(weights: import("../../foundation/route/route.mjs").ClassifierWeights, q: string): number[];
|
|
20
|
+
/** The domains, in the order the weights files index them. */
|
|
21
|
+
export const DOMAINS: string[];
|
|
22
|
+
/** The router's classes: the domain a query wants, or none. */
|
|
23
|
+
export const ROUTES: string[];
|
|
24
|
+
export function words(text: string): string[];
|
|
25
|
+
export function queryWords(q: string): string[];
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file How search's searchers and classifier read a query: its words,
|
|
5
|
+
* folded forms, word pairs, and the classifier's tokens and class
|
|
6
|
+
* probabilities.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import {classify} from '../../foundation/route/route.mjs';
|
|
10
|
+
|
|
11
|
+
/** The domains, in the order the weights files index them. */
|
|
12
|
+
export const DOMAINS = ['component', 'hook', 'doc', 'template', 'theme'];
|
|
13
|
+
|
|
14
|
+
/** The router's classes: the domain a query wants, or none. */
|
|
15
|
+
export const ROUTES = [...DOMAINS, 'NONE'];
|
|
16
|
+
|
|
17
|
+
const STOP = new Set(
|
|
18
|
+
'a an the of for to with and or in on by is it my me i we you this that be as at from use using how what which show make add create get set any can do does not no into via'.split(
|
|
19
|
+
' ',
|
|
20
|
+
),
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
const QUESTION = new Set([
|
|
24
|
+
'how',
|
|
25
|
+
'what',
|
|
26
|
+
'why',
|
|
27
|
+
'when',
|
|
28
|
+
'where',
|
|
29
|
+
'can',
|
|
30
|
+
'does',
|
|
31
|
+
'is',
|
|
32
|
+
]);
|
|
33
|
+
|
|
34
|
+
/** @param {string} text @returns {string[]} */
|
|
35
|
+
export const words = text =>
|
|
36
|
+
(text || '').toLowerCase().match(/[a-z0-9]+/g) ?? [];
|
|
37
|
+
|
|
38
|
+
/** Plural folding: one fixed rule per suffix. @param {string} w */
|
|
39
|
+
export function fold(w) {
|
|
40
|
+
if (w.length > 4 && w.endsWith('ies')) return `${w.slice(0, -3)}y`;
|
|
41
|
+
if (w.length > 3 && w.endsWith('es') && 'sxz'.includes(w[w.length - 3])) {
|
|
42
|
+
return w.slice(0, -2);
|
|
43
|
+
}
|
|
44
|
+
if (w.length > 3 && w.endsWith('s') && !w.endsWith('ss'))
|
|
45
|
+
return w.slice(0, -1);
|
|
46
|
+
return w;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** A name's words: `DateRangeInput` is date, range, input. @param {string} name */
|
|
50
|
+
export function nameWords(name) {
|
|
51
|
+
const s = name
|
|
52
|
+
.replace(/[/-]/g, ' ')
|
|
53
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1 $2')
|
|
54
|
+
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2');
|
|
55
|
+
return words(s);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** The query's content words, folded. @param {string} q */
|
|
59
|
+
export const queryWords = q =>
|
|
60
|
+
words(q)
|
|
61
|
+
.filter(w => !STOP.has(w))
|
|
62
|
+
.map(fold);
|
|
63
|
+
|
|
64
|
+
/** @param {string} q @returns {string[]} unique words, then adjacent pairs */
|
|
65
|
+
export function queryTokens(q) {
|
|
66
|
+
const qw = queryWords(q);
|
|
67
|
+
const pairs = qw.slice(1).map((w, i) => `${qw[i]}_${w}`);
|
|
68
|
+
return [...new Set([...qw, ...pairs])];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** The router's inputs: the query's tokens plus four shape flags. @param {string} q */
|
|
72
|
+
export function routerTokens(q) {
|
|
73
|
+
const ws = words(q);
|
|
74
|
+
const flags = [`#n${Math.min(ws.length, 6)}`];
|
|
75
|
+
if (ws.length && QUESTION.has(ws[0])) flags.push('#question');
|
|
76
|
+
if (q.split(/\s+/).some(w => /^use[a-z]+/.test(w)) || /\buse[A-Z]/.test(q)) {
|
|
77
|
+
flags.push('#usehook');
|
|
78
|
+
}
|
|
79
|
+
if (/[A-Z][a-z]+[A-Z]/.test(q)) flags.push('#camel');
|
|
80
|
+
return [...queryTokens(q), ...flags, '#bias'];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* The router's probability for each class: the shared classifier over the
|
|
85
|
+
* query's tokens.
|
|
86
|
+
* @param {import('../../foundation/route/route.mjs').ClassifierWeights} weights
|
|
87
|
+
* @param {string} q
|
|
88
|
+
* @returns {number[]}
|
|
89
|
+
*/
|
|
90
|
+
export function routeProbs(weights, q) {
|
|
91
|
+
return classify(weights, routerTokens(q));
|
|
92
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
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
|
+
/**
|
|
5
|
+
* Split a query into meaningful content tokens (lowercased, stopwords + very
|
|
6
|
+
* short words removed). Empty for single-word queries (callers fall back to
|
|
7
|
+
* whole-phrase scoring).
|
|
8
|
+
* @param {string} term - Already-lowercased query.
|
|
9
|
+
* @returns {string[]}
|
|
10
|
+
*/
|
|
11
|
+
export function tokenizeQuery(term: string): string[];
|
|
12
|
+
/**
|
|
13
|
+
* Score a candidate against a query, handling multi-word natural language.
|
|
14
|
+
* Tries the whole phrase (so exact/near matches still win) AND a per-token
|
|
15
|
+
* pass (so "data table with filters" matches `table-page` via table+filter),
|
|
16
|
+
* and returns whichever is stronger.
|
|
17
|
+
*
|
|
18
|
+
* @param {string} term - Lowercased full query.
|
|
19
|
+
* @param {string[]} tokens - Content tokens from tokenizeQuery(term).
|
|
20
|
+
* @param {object} candidate
|
|
21
|
+
* @returns {{score: number, reason: string} | null}
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* The words of a title or query, lowercased, without punctuation or code ticks.
|
|
25
|
+
* @param {string} text
|
|
26
|
+
* @returns {string[]}
|
|
27
|
+
*/
|
|
28
|
+
export function phraseWords(text: string): string[];
|
|
29
|
+
/**
|
|
30
|
+
* Whether two words are the same word, allowing a plural on either side, so
|
|
31
|
+
* `data attributes selector` still reads "Data attribute selectors".
|
|
32
|
+
* @param {string} a
|
|
33
|
+
* @param {string} b
|
|
34
|
+
*/
|
|
35
|
+
export function samePhraseWord(a: string, b: string): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Whether two phrases are the same words, in order, ignoring case,
|
|
38
|
+
* punctuation, and a plural on any word: `side panel` is "Side panels", and
|
|
39
|
+
* `headers and footers` is `header-and-footer`.
|
|
40
|
+
* @param {string} a
|
|
41
|
+
* @param {string} b
|
|
42
|
+
* @returns {boolean}
|
|
43
|
+
*/
|
|
44
|
+
export function samePhrase(a: string, b: string): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Whether `plural` is the plural of `word`: `integrations` of `integration`,
|
|
47
|
+
* `boxes` of `box`. `es` only follows s, x, z, ch, or sh, so `notes` is not a
|
|
48
|
+
* plural of `not`.
|
|
49
|
+
* @param {string} plural
|
|
50
|
+
* @param {string} word
|
|
51
|
+
*/
|
|
52
|
+
export function pluralOf(plural: string, word: string): boolean;
|
|
53
|
+
/** Valid domain filters for `--type`. */
|
|
54
|
+
export const SEARCH_DOMAINS: string[];
|
|
55
|
+
/**
|
|
56
|
+
* The domains a search reads without @astryxdesign/core. An open search outside
|
|
57
|
+
* an app covers these alone.
|
|
58
|
+
*/
|
|
59
|
+
export const CORELESS_DOMAINS: string[];
|
|
60
|
+
/**
|
|
61
|
+
* Filler words stripped from multi-word queries so natural-language phrasing
|
|
62
|
+
* ("a page where you can see business stats") ranks on its content words.
|
|
63
|
+
* Exported for `build`, whose page ranker strips the same words.
|
|
64
|
+
*/
|
|
65
|
+
export const STOPWORDS: Set<string>;
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file Reading a search query: its domains, stopwords, content tokens, and
|
|
5
|
+
* phrase words.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {unlinkText} from '../../foundation/doc-compiler/links.mjs';
|
|
9
|
+
import {sameWord} from './_words.mjs';
|
|
10
|
+
|
|
11
|
+
/** Valid domain filters for `--type`. */
|
|
12
|
+
export const SEARCH_DOMAINS = ['component', 'hook', 'doc', 'template', 'theme'];
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The domains a search reads without @astryxdesign/core. An open search outside
|
|
16
|
+
* an app covers these alone.
|
|
17
|
+
*/
|
|
18
|
+
export const CORELESS_DOMAINS = ['doc', 'theme'];
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Filler words stripped from multi-word queries so natural-language phrasing
|
|
22
|
+
* ("a page where you can see business stats") ranks on its content words.
|
|
23
|
+
* Exported for `build`, whose page ranker strips the same words.
|
|
24
|
+
*/
|
|
25
|
+
export const STOPWORDS = new Set([
|
|
26
|
+
'a',
|
|
27
|
+
'an',
|
|
28
|
+
'the',
|
|
29
|
+
'of',
|
|
30
|
+
'for',
|
|
31
|
+
'to',
|
|
32
|
+
'with',
|
|
33
|
+
'and',
|
|
34
|
+
'or',
|
|
35
|
+
'in',
|
|
36
|
+
'on',
|
|
37
|
+
'at',
|
|
38
|
+
'by',
|
|
39
|
+
'that',
|
|
40
|
+
'this',
|
|
41
|
+
'my',
|
|
42
|
+
'your',
|
|
43
|
+
'our',
|
|
44
|
+
'their',
|
|
45
|
+
'is',
|
|
46
|
+
'are',
|
|
47
|
+
'be',
|
|
48
|
+
'it',
|
|
49
|
+
'its',
|
|
50
|
+
'as',
|
|
51
|
+
'from',
|
|
52
|
+
'page',
|
|
53
|
+
'screen',
|
|
54
|
+
'app',
|
|
55
|
+
'application',
|
|
56
|
+
'view',
|
|
57
|
+
'where',
|
|
58
|
+
'you',
|
|
59
|
+
'can',
|
|
60
|
+
'some',
|
|
61
|
+
'like',
|
|
62
|
+
'just',
|
|
63
|
+
'basically',
|
|
64
|
+
'kinda',
|
|
65
|
+
'want',
|
|
66
|
+
'wants',
|
|
67
|
+
'need',
|
|
68
|
+
'needs',
|
|
69
|
+
'something',
|
|
70
|
+
'thing',
|
|
71
|
+
'things',
|
|
72
|
+
'build',
|
|
73
|
+
'make',
|
|
74
|
+
'create',
|
|
75
|
+
'i',
|
|
76
|
+
'me',
|
|
77
|
+
'we',
|
|
78
|
+
'us',
|
|
79
|
+
'so',
|
|
80
|
+
'up',
|
|
81
|
+
'out',
|
|
82
|
+
'over',
|
|
83
|
+
'side',
|
|
84
|
+
'one',
|
|
85
|
+
'big',
|
|
86
|
+
]);
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Split a query into meaningful content tokens (lowercased, stopwords + very
|
|
90
|
+
* short words removed). Empty for single-word queries (callers fall back to
|
|
91
|
+
* whole-phrase scoring).
|
|
92
|
+
* @param {string} term - Already-lowercased query.
|
|
93
|
+
* @returns {string[]}
|
|
94
|
+
*/
|
|
95
|
+
export function tokenizeQuery(term) {
|
|
96
|
+
return (
|
|
97
|
+
term
|
|
98
|
+
.split(/\s+/)
|
|
99
|
+
// Strip only leading/trailing punctuation; keep joined identifiers intact
|
|
100
|
+
// (e.g. "foo_bar" stays one token) so gibberish stays gibberish.
|
|
101
|
+
.map(t => t.replace(/^[^a-z0-9]+|[^a-z0-9]+$/g, ''))
|
|
102
|
+
.filter(t => t.length >= 2 && !STOPWORDS.has(t))
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Score a candidate against a query, handling multi-word natural language.
|
|
108
|
+
* Tries the whole phrase (so exact/near matches still win) AND a per-token
|
|
109
|
+
* pass (so "data table with filters" matches `table-page` via table+filter),
|
|
110
|
+
* and returns whichever is stronger.
|
|
111
|
+
*
|
|
112
|
+
* @param {string} term - Lowercased full query.
|
|
113
|
+
* @param {string[]} tokens - Content tokens from tokenizeQuery(term).
|
|
114
|
+
* @param {object} candidate
|
|
115
|
+
* @returns {{score: number, reason: string} | null}
|
|
116
|
+
*/
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* The words of a title or query, lowercased, without punctuation or code ticks.
|
|
120
|
+
* @param {string} text
|
|
121
|
+
* @returns {string[]}
|
|
122
|
+
*/
|
|
123
|
+
export function phraseWords(text) {
|
|
124
|
+
return (
|
|
125
|
+
unlinkText(text)
|
|
126
|
+
.toLowerCase()
|
|
127
|
+
.match(/[a-z0-9]+/g) ?? []
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Whether two words are the same word, allowing a plural on either side, so
|
|
133
|
+
* `data attributes selector` still reads "Data attribute selectors".
|
|
134
|
+
* @param {string} a
|
|
135
|
+
* @param {string} b
|
|
136
|
+
*/
|
|
137
|
+
export function samePhraseWord(a, b) {
|
|
138
|
+
return (
|
|
139
|
+
a === b ||
|
|
140
|
+
`${a}s` === b ||
|
|
141
|
+
`${b}s` === a ||
|
|
142
|
+
`${a}es` === b ||
|
|
143
|
+
`${b}es` === a
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Whether two phrases are the same words, in order, ignoring case,
|
|
149
|
+
* punctuation, and a plural on any word: `side panel` is "Side panels", and
|
|
150
|
+
* `headers and footers` is `header-and-footer`.
|
|
151
|
+
* @param {string} a
|
|
152
|
+
* @param {string} b
|
|
153
|
+
* @returns {boolean}
|
|
154
|
+
*/
|
|
155
|
+
export function samePhrase(a, b) {
|
|
156
|
+
const x = phraseWords(a);
|
|
157
|
+
const y = phraseWords(b);
|
|
158
|
+
return (
|
|
159
|
+
x.length > 0 &&
|
|
160
|
+
x.length === y.length &&
|
|
161
|
+
x.every((w, k) => samePhraseWord(w, y[k]) || sameWord(w, y[k]))
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Whether `plural` is the plural of `word`: `integrations` of `integration`,
|
|
167
|
+
* `boxes` of `box`. `es` only follows s, x, z, ch, or sh, so `notes` is not a
|
|
168
|
+
* plural of `not`.
|
|
169
|
+
* @param {string} plural
|
|
170
|
+
* @param {string} word
|
|
171
|
+
*/
|
|
172
|
+
export function pluralOf(plural, word) {
|
|
173
|
+
if (word.length < 3) return false;
|
|
174
|
+
if (plural === `${word}s`) return true;
|
|
175
|
+
return /(?:s|x|z|ch|sh)$/.test(word) && plural === `${word}es`;
|
|
176
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
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
|
+
* Map a scored candidate to its public, actionable result shape. Each result
|
|
7
|
+
* carries enough to act on it: the domain, name, a one-line description, and
|
|
8
|
+
* the follow-up command (and import path where relevant).
|
|
9
|
+
*
|
|
10
|
+
* @param {Candidate} c - candidate
|
|
11
|
+
* @param {number} score
|
|
12
|
+
* @param {string} reason
|
|
13
|
+
* @param {number} matchedTerms - Query concepts this result answered.
|
|
14
|
+
* @param {number} queryTerms - Query concepts there were to answer.
|
|
15
|
+
* @param {boolean} [outside] - The search runs outside a project, where a
|
|
16
|
+
* theme cannot be added to an app, so its command forks the source instead
|
|
17
|
+
* (spec AST-081 FR3).
|
|
18
|
+
*/
|
|
19
|
+
export function toResult(c: Candidate, score: number, reason: string, matchedTerms: number, queryTerms: number, outside?: boolean): {
|
|
20
|
+
domain: "component" | "hook" | "theme" | "doc" | "template";
|
|
21
|
+
name: string;
|
|
22
|
+
package: string | undefined;
|
|
23
|
+
score: number;
|
|
24
|
+
reason: string;
|
|
25
|
+
description: string;
|
|
26
|
+
} | {
|
|
27
|
+
import: string | undefined;
|
|
28
|
+
command: string;
|
|
29
|
+
domain: "component" | "hook" | "theme" | "doc" | "template";
|
|
30
|
+
name: string;
|
|
31
|
+
package: string | undefined;
|
|
32
|
+
score: number;
|
|
33
|
+
reason: string;
|
|
34
|
+
description: string;
|
|
35
|
+
} | {
|
|
36
|
+
parent?: string | undefined;
|
|
37
|
+
title: string | undefined;
|
|
38
|
+
command: string;
|
|
39
|
+
section?: string | undefined;
|
|
40
|
+
name: string;
|
|
41
|
+
domain: "component" | "hook" | "theme" | "doc" | "template";
|
|
42
|
+
package: string | undefined;
|
|
43
|
+
score: number;
|
|
44
|
+
reason: string;
|
|
45
|
+
description: string;
|
|
46
|
+
} | {
|
|
47
|
+
displayName: string | undefined;
|
|
48
|
+
kind: "page" | "block" | undefined;
|
|
49
|
+
command: string;
|
|
50
|
+
domain: "component" | "hook" | "theme" | "doc" | "template";
|
|
51
|
+
name: string;
|
|
52
|
+
package: string | undefined;
|
|
53
|
+
score: number;
|
|
54
|
+
reason: string;
|
|
55
|
+
description: string;
|
|
56
|
+
} | {
|
|
57
|
+
displayName: string | undefined;
|
|
58
|
+
command: string;
|
|
59
|
+
domain: "component" | "hook" | "theme" | "doc" | "template";
|
|
60
|
+
name: string;
|
|
61
|
+
package: string | undefined;
|
|
62
|
+
score: number;
|
|
63
|
+
reason: string;
|
|
64
|
+
description: string;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Throws the search argument errors: an empty query, an unknown type, a limit
|
|
68
|
+
* that is not a positive integer.
|
|
69
|
+
*
|
|
70
|
+
* @param {string} query
|
|
71
|
+
* @param {{type?: string, limit?: number}} options
|
|
72
|
+
*/
|
|
73
|
+
export function checkSearchArgs(query: string, options: {
|
|
74
|
+
type?: string;
|
|
75
|
+
limit?: number;
|
|
76
|
+
}): void;
|
|
77
|
+
/**
|
|
78
|
+
* The components (name and keywords) a search response was scored against, or
|
|
79
|
+
* null when that search was narrowed away from components.
|
|
80
|
+
* @param {object} response
|
|
81
|
+
* @returns {{name: string, keywords: string[]}[] | null}
|
|
82
|
+
*/
|
|
83
|
+
export function searchedComponents(response: object): {
|
|
84
|
+
name: string;
|
|
85
|
+
keywords: string[];
|
|
86
|
+
}[] | null;
|
|
87
|
+
/**
|
|
88
|
+
* The components each search response was scored against, by response:
|
|
89
|
+
* `build` reads them to tell a part of a page from a page without gathering
|
|
90
|
+
* them again. Module-private, so they never enter search's JSON.
|
|
91
|
+
* @type {WeakMap<object, {name: string, keywords: string[]}[]>}
|
|
92
|
+
*/
|
|
93
|
+
export const searchedComponentsOf: WeakMap<object, {
|
|
94
|
+
name: string;
|
|
95
|
+
keywords: string[];
|
|
96
|
+
}[]>;
|
|
97
|
+
export type Candidate = import("./_lexical.mjs").Candidate;
|