@salesforce/b2c-tooling-sdk 1.17.0 → 1.19.0
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/data/content-schemas/componenttype.json +79 -17
- package/data/content-schemas/pagetype.json +4 -0
- package/data/guides/enrichment.json +11264 -0
- package/data/guides/index.json +15166 -0
- package/data/job-steps/index.json +71 -1
- package/data/job-steps/job-steps.json +1 -1
- package/data/script-api/index.json +2145 -37
- package/data/tooling/index.json +222 -0
- package/data/xsd/index.json +1 -1
- package/dist/esm/auth/client-credentials.d.ts +27 -0
- package/dist/esm/auth/client-credentials.js +60 -0
- package/dist/esm/auth/client-credentials.js.map +1 -0
- package/dist/esm/auth/index.d.ts +1 -0
- package/dist/esm/auth/index.js +2 -0
- package/dist/esm/auth/index.js.map +1 -1
- package/dist/esm/auth/oauth.js +2 -1
- package/dist/esm/auth/oauth.js.map +1 -1
- package/dist/esm/cli/base-command.d.ts +40 -0
- package/dist/esm/cli/base-command.js +66 -5
- package/dist/esm/cli/base-command.js.map +1 -1
- package/dist/esm/cli/index.d.ts +2 -2
- package/dist/esm/cli/index.js +1 -1
- package/dist/esm/cli/index.js.map +1 -1
- package/dist/esm/cli/instance-command.d.ts +1 -1
- package/dist/esm/cli/instance-command.js +5 -3
- package/dist/esm/cli/instance-command.js.map +1 -1
- package/dist/esm/cli/oauth-command.d.ts +1 -1
- package/dist/esm/cli/oauth-command.js +5 -3
- package/dist/esm/cli/oauth-command.js.map +1 -1
- package/dist/esm/cli/ods-command.d.ts +1 -1
- package/dist/esm/cli/webdav-command.d.ts +1 -1
- package/dist/esm/clients/index.d.ts +2 -0
- package/dist/esm/clients/index.js +1 -0
- package/dist/esm/clients/index.js.map +1 -1
- package/dist/esm/clients/metrics.d.ts +123 -0
- package/dist/esm/clients/metrics.generated.d.ts +1016 -0
- package/dist/esm/clients/metrics.generated.js +6 -0
- package/dist/esm/clients/metrics.generated.js.map +1 -0
- package/dist/esm/clients/metrics.js +65 -0
- package/dist/esm/clients/metrics.js.map +1 -0
- package/dist/esm/clients/middleware-registry.d.ts +1 -1
- package/dist/esm/clients/middleware-registry.js.map +1 -1
- package/dist/esm/config/sources/env-source.js +1 -0
- package/dist/esm/config/sources/env-source.js.map +1 -1
- package/dist/esm/discovery/detector.d.ts +0 -5
- package/dist/esm/discovery/detector.js +24 -3
- package/dist/esm/discovery/detector.js.map +1 -1
- package/dist/esm/discovery/index.d.ts +1 -0
- package/dist/esm/discovery/index.js +1 -0
- package/dist/esm/discovery/index.js.map +1 -1
- package/dist/esm/discovery/patterns/index.d.ts +4 -2
- package/dist/esm/discovery/patterns/index.js +9 -3
- package/dist/esm/discovery/patterns/index.js.map +1 -1
- package/dist/esm/discovery/patterns/pwa-kit.d.ts +12 -0
- package/dist/esm/discovery/patterns/pwa-kit.js +18 -7
- package/dist/esm/discovery/patterns/pwa-kit.js.map +1 -1
- package/dist/esm/discovery/patterns/sfra.d.ts +5 -4
- package/dist/esm/discovery/patterns/sfra.js +1 -1
- package/dist/esm/discovery/patterns/sfra.js.map +1 -1
- package/dist/esm/discovery/patterns/storefront-next.js +18 -2
- package/dist/esm/discovery/patterns/storefront-next.js.map +1 -1
- package/dist/esm/discovery/types.d.ts +13 -4
- package/dist/esm/discovery/types.js +11 -1
- package/dist/esm/discovery/types.js.map +1 -1
- package/dist/esm/docs/index.d.ts +3 -3
- package/dist/esm/docs/index.js +1 -1
- package/dist/esm/docs/index.js.map +1 -1
- package/dist/esm/docs/search.d.ts +111 -38
- package/dist/esm/docs/search.js +402 -81
- package/dist/esm/docs/search.js.map +1 -1
- package/dist/esm/docs/types.d.ts +56 -6
- package/dist/esm/docs/types.js +2 -0
- package/dist/esm/docs/types.js.map +1 -1
- package/dist/esm/index.d.ts +4 -2
- package/dist/esm/index.js +3 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/operations/logs/filter.d.ts +6 -1
- package/dist/esm/operations/logs/filter.js +7 -2
- package/dist/esm/operations/logs/filter.js.map +1 -1
- package/dist/esm/operations/metrics/index.d.ts +371 -0
- package/dist/esm/operations/metrics/index.js +478 -0
- package/dist/esm/operations/metrics/index.js.map +1 -0
- package/dist/esm/operations/metrics/tags.d.ts +148 -0
- package/dist/esm/operations/metrics/tags.js +235 -0
- package/dist/esm/operations/metrics/tags.js.map +1 -0
- package/dist/esm/slas/token.d.ts +9 -2
- package/dist/esm/slas/token.js +25 -29
- package/dist/esm/slas/token.js.map +1 -1
- package/dist/esm/telemetry/telemetry.d.ts +1 -0
- package/dist/esm/telemetry/telemetry.js +32 -0
- package/dist/esm/telemetry/telemetry.js.map +1 -1
- package/dist/esm/telemetry/types.d.ts +6 -0
- package/package.json +12 -3
- package/specs/metrics-v1.json +1713 -0
package/dist/esm/docs/search.js
CHANGED
|
@@ -5,18 +5,168 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import * as fs from 'node:fs';
|
|
7
7
|
import * as path from 'node:path';
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
10
|
-
|
|
8
|
+
import MiniSearch from 'minisearch';
|
|
9
|
+
import { getLogger } from '../logging/logger.js';
|
|
10
|
+
import { GUIDES_DATA_DIR, JOB_STEPS_DATA_DIR, SCRIPT_API_DATA_DIR, TOOLING_DATA_DIR, } from './types.js';
|
|
11
|
+
/**
|
|
12
|
+
* The bundled corpora, loaded (and combined) in priority order. Earlier corpora
|
|
13
|
+
* win on id collisions. Each directory holds an `index.json` ({@link SearchIndex})
|
|
14
|
+
* and, for corpora whose content ships in the package, the referenced files.
|
|
15
|
+
*/
|
|
16
|
+
const CORPUS_DIRS = [SCRIPT_API_DATA_DIR, JOB_STEPS_DATA_DIR, GUIDES_DATA_DIR, TOOLING_DATA_DIR];
|
|
17
|
+
/** Multiplier applied to a detected workspace's relevant categories. */
|
|
18
|
+
const WORKSPACE_BOOST = 1.4;
|
|
19
|
+
/**
|
|
20
|
+
* Timeout (ms) for fetching an online-only guide's content. Without a bound a
|
|
21
|
+
* stalled connection hangs the caller indefinitely (observed hanging Windows CI
|
|
22
|
+
* for 6h); on timeout we fall back to the indexed offline summary instead.
|
|
23
|
+
*/
|
|
24
|
+
const ONLINE_FETCH_TIMEOUT_MS = 10_000;
|
|
25
|
+
/**
|
|
26
|
+
* Multiplier applied to a COMPETING storefront framework's guides when a
|
|
27
|
+
* workspace is known — i.e. the storefront-framework guide categories that are
|
|
28
|
+
* NOT relevant to the detected workspace (e.g. `sfnext`/`sfra` for a PWA Kit
|
|
29
|
+
* project). These are mutually exclusive storefront implementations, so their
|
|
30
|
+
* how-to guides are usually the wrong answer for a different storefront. Kept
|
|
31
|
+
* as a de-boost (not a hard filter) so the docs still surface, just demoted —
|
|
32
|
+
* a strong exact-title match (e.g. an "SEO and Metadata" sfnext guide) should
|
|
33
|
+
* not outrank the current storefront's own guide for the same query.
|
|
34
|
+
*/
|
|
35
|
+
const COMPETING_STOREFRONT_PENALTY = 0.3;
|
|
36
|
+
/**
|
|
37
|
+
* The storefront-FRAMEWORK guide categories: one per mutually-exclusive
|
|
38
|
+
* storefront implementation. Only these are de-boosted when they belong to a
|
|
39
|
+
* different storefront than the detected workspace. Reference/platform corpora
|
|
40
|
+
* (`script-api`, `job-step`, `commerce-api`, `b2c-commerce`, `tooling`) are
|
|
41
|
+
* never treated as "competing" — they apply across storefronts.
|
|
42
|
+
*/
|
|
43
|
+
const STOREFRONT_FRAMEWORK_CATEGORIES = ['sfra', 'pwa-kit-managed-runtime', 'sfnext'];
|
|
44
|
+
/**
|
|
45
|
+
* Canonical per-category metadata, keyed by {@link DocCategory}. Insertion order
|
|
46
|
+
* defines the display order in {@link DOC_CATEGORIES}. `alwaysRelevant` marks the
|
|
47
|
+
* categories that are boosted whenever ANY workspace is detected, regardless of
|
|
48
|
+
* which framework it is (general platform docs + this tooling's own docs).
|
|
49
|
+
*
|
|
50
|
+
* Typed `Record<DocCategory, …>`, so adding a new `DocCategory` to the union in
|
|
51
|
+
* `types.ts` is a compile error until it is listed here (keeps the category list
|
|
52
|
+
* and its metadata from drifting).
|
|
53
|
+
*/
|
|
54
|
+
const CATEGORY_TAXONOMY = {
|
|
55
|
+
'script-api': {},
|
|
56
|
+
'job-step': {},
|
|
57
|
+
'commerce-api': {},
|
|
58
|
+
'pwa-kit-managed-runtime': {},
|
|
59
|
+
sfnext: {},
|
|
60
|
+
sfra: {},
|
|
61
|
+
'b2c-commerce': { alwaysRelevant: true },
|
|
62
|
+
tooling: { alwaysRelevant: true },
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* The canonical list of documentation categories, in a stable display order.
|
|
66
|
+
* Exported so the CLI and MCP surfaces validate against a single source of truth
|
|
67
|
+
* instead of maintaining their own copies. Derived from {@link CATEGORY_TAXONOMY}.
|
|
68
|
+
*/
|
|
69
|
+
export const DOC_CATEGORIES = Object.keys(CATEGORY_TAXONOMY);
|
|
70
|
+
/** Categories relevant to every detected workspace. Derived from {@link CATEGORY_TAXONOMY}. */
|
|
71
|
+
const ALWAYS_RELEVANT = DOC_CATEGORIES.filter((c) => CATEGORY_TAXONOMY[c].alwaysRelevant);
|
|
72
|
+
/**
|
|
73
|
+
* Maps each workspace marker to the doc categories it makes relevant. The final
|
|
74
|
+
* relevant set for a workspace is {@link ALWAYS_RELEVANT} plus the union of the
|
|
75
|
+
* markers' categories (merged, never summed — a category shared by two markers
|
|
76
|
+
* is still boosted once).
|
|
77
|
+
*
|
|
78
|
+
* `sfra` is a refinement of `cartridges`: an SFRA project detects as both, so it
|
|
79
|
+
* gets the cartridge categories (Script API, job steps) AND the `sfra` guides. A
|
|
80
|
+
* non-SFRA cartridge project (custom APIs, or a PWA Kit / Storefront Next repo
|
|
81
|
+
* that also ships cartridges) gets the cartridge categories but NOT `sfra`.
|
|
82
|
+
*
|
|
83
|
+
* Typed `Record<ProjectType, …>`, so adding a new workspace marker is a compile
|
|
84
|
+
* error until its categories are declared here.
|
|
85
|
+
*/
|
|
86
|
+
const WORKSPACE_CATEGORIES = {
|
|
87
|
+
cartridges: ['script-api', 'job-step'],
|
|
88
|
+
sfra: ['sfra'],
|
|
89
|
+
'pwa-kit-v3': ['pwa-kit-managed-runtime', 'commerce-api'],
|
|
90
|
+
'storefront-next': ['sfnext', 'commerce-api'],
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Parses and validates a user-supplied set of documentation categories into a
|
|
94
|
+
* "topics" allowlist that bounds the entire available corpus (see
|
|
95
|
+
* {@link SearchDocsOptions.enabledCategories}). Accepts a comma-separated string
|
|
96
|
+
* or an array; names are trimmed and lower-cased.
|
|
97
|
+
*
|
|
98
|
+
* Unknown names are dropped (and reported via `onInvalid`, if provided). Returns
|
|
99
|
+
* `undefined` when the input is empty or contains no valid categories, which
|
|
100
|
+
* means "no restriction" — matching the tolerant behavior of the MCP `--toolsets`
|
|
101
|
+
* flag, so a typo yields a warning and the full corpus rather than a dead tool.
|
|
102
|
+
*
|
|
103
|
+
* @param input - Comma-separated category names, or an array of names
|
|
104
|
+
* @param onInvalid - Optional callback invoked with any unrecognized names
|
|
105
|
+
* @returns The validated, de-duplicated categories, or `undefined` for no restriction
|
|
106
|
+
*/
|
|
107
|
+
export function resolveEnabledCategories(input, onInvalid) {
|
|
108
|
+
if (input == undefined)
|
|
109
|
+
return undefined;
|
|
110
|
+
const raw = Array.isArray(input) ? input : String(input).split(',');
|
|
111
|
+
const names = raw.map((s) => s.trim().toLowerCase()).filter((s) => s.length > 0);
|
|
112
|
+
if (names.length === 0)
|
|
113
|
+
return undefined;
|
|
114
|
+
const known = new Set(DOC_CATEGORIES);
|
|
115
|
+
const valid = [];
|
|
116
|
+
const invalid = [];
|
|
117
|
+
for (const name of names) {
|
|
118
|
+
if (known.has(name))
|
|
119
|
+
valid.push(name);
|
|
120
|
+
else
|
|
121
|
+
invalid.push(name);
|
|
122
|
+
}
|
|
123
|
+
if (invalid.length > 0)
|
|
124
|
+
onInvalid?.(invalid);
|
|
125
|
+
return valid.length > 0 ? [...new Set(valid)] : undefined;
|
|
126
|
+
}
|
|
127
|
+
/** Normalizes a workspace option to an array of project-type markers. */
|
|
128
|
+
function toWorkspaceList(workspace) {
|
|
129
|
+
if (!workspace)
|
|
130
|
+
return undefined;
|
|
131
|
+
const list = Array.isArray(workspace) ? workspace : [workspace];
|
|
132
|
+
return list.length ? list : undefined;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Computes the set of doc categories relevant to the given workspace marker(s):
|
|
136
|
+
* the always-relevant categories plus the union of each marker's categories
|
|
137
|
+
* (merged, not summed).
|
|
138
|
+
*/
|
|
139
|
+
export function categoriesForWorkspace(workspace) {
|
|
140
|
+
const list = toWorkspaceList(workspace) ?? [];
|
|
141
|
+
const set = new Set(ALWAYS_RELEVANT);
|
|
142
|
+
for (const marker of list) {
|
|
143
|
+
for (const cat of WORKSPACE_CATEGORIES[marker] ?? [])
|
|
144
|
+
set.add(cat);
|
|
145
|
+
}
|
|
146
|
+
return [...set];
|
|
147
|
+
}
|
|
148
|
+
// Singleton caches for the combined index and the MiniSearch instance.
|
|
11
149
|
let cachedIndex = null;
|
|
12
|
-
let
|
|
13
|
-
// Maps each entry id to the absolute data directory that holds its file.
|
|
14
|
-
//
|
|
15
|
-
//
|
|
150
|
+
let cachedMiniSearch = null;
|
|
151
|
+
// Maps each entry id to the absolute data directory that holds its bundled file.
|
|
152
|
+
// Lets a single combined index span multiple bundled corpora without changing
|
|
153
|
+
// the public DocEntry shape. Online-only entries (guides) are not recorded here.
|
|
16
154
|
const entryDataDir = new Map();
|
|
155
|
+
// Maps each entry id to its full DocEntry, for O(1) lookup on read.
|
|
156
|
+
const entryById = new Map();
|
|
157
|
+
/**
|
|
158
|
+
* Projects a stored entry to the shape returned to callers. Drops `headings`,
|
|
159
|
+
* which exists only to feed the search index (a long ` • `-joined string with
|
|
160
|
+
* no triage value) and would otherwise bloat search/list payloads for agents.
|
|
161
|
+
*/
|
|
162
|
+
function publicEntry(entry) {
|
|
163
|
+
const { headings: _headings, ...rest } = entry;
|
|
164
|
+
return rest;
|
|
165
|
+
}
|
|
17
166
|
/**
|
|
18
167
|
* Loads one bundled index.json from the given directory, returning its entries
|
|
19
|
-
* and recording the directory for each
|
|
168
|
+
* and recording the directory for each id that ships its content on disk.
|
|
169
|
+
* Missing indexes are ignored so a not-yet-generated corpus is simply absent.
|
|
20
170
|
*/
|
|
21
171
|
function loadCorpus(dataDir) {
|
|
22
172
|
const indexPath = path.join(dataDir, 'index.json');
|
|
@@ -25,135 +175,306 @@ function loadCorpus(dataDir) {
|
|
|
25
175
|
}
|
|
26
176
|
const parsed = JSON.parse(fs.readFileSync(indexPath, 'utf-8'));
|
|
27
177
|
for (const entry of parsed.entries) {
|
|
28
|
-
|
|
29
|
-
|
|
178
|
+
if (entryById.has(entry.id))
|
|
179
|
+
continue; // first corpus wins on id collision
|
|
180
|
+
entryById.set(entry.id, entry);
|
|
181
|
+
// Only record a data dir for entries whose content is bundled on disk.
|
|
182
|
+
if (entry.filePath) {
|
|
30
183
|
entryDataDir.set(entry.id, dataDir);
|
|
31
184
|
}
|
|
32
185
|
}
|
|
33
186
|
return parsed.entries;
|
|
34
187
|
}
|
|
35
188
|
/**
|
|
36
|
-
* Loads the
|
|
189
|
+
* Loads the combined search index from every bundled corpus directory.
|
|
37
190
|
*
|
|
38
|
-
* Combines the Script API
|
|
39
|
-
*
|
|
191
|
+
* Combines the Script API reference, standard job steps, Developer Center
|
|
192
|
+
* guides, and this project's own docs so all are searchable through the same
|
|
193
|
+
* functions. Corpora that have not been generated are skipped.
|
|
40
194
|
*
|
|
41
195
|
* @returns The combined search index with all documentation entries
|
|
42
|
-
* @throws Error if the Script API index file cannot be read
|
|
43
196
|
*/
|
|
44
197
|
export function loadSearchIndex() {
|
|
45
198
|
if (cachedIndex)
|
|
46
199
|
return cachedIndex;
|
|
47
200
|
entryDataDir.clear();
|
|
48
|
-
|
|
49
|
-
const
|
|
201
|
+
entryById.clear();
|
|
202
|
+
const entries = [];
|
|
203
|
+
const perCorpus = {};
|
|
204
|
+
for (const dir of CORPUS_DIRS) {
|
|
205
|
+
const loaded = loadCorpus(dir);
|
|
206
|
+
perCorpus[path.basename(dir)] = loaded.length;
|
|
207
|
+
entries.push(...loaded);
|
|
208
|
+
}
|
|
209
|
+
getLogger().debug({ total: entries.length, perCorpus }, 'Loaded combined documentation search index');
|
|
50
210
|
cachedIndex = {
|
|
51
|
-
version: '
|
|
211
|
+
version: '2.0.0',
|
|
52
212
|
generatedAt: new Date(0).toISOString(),
|
|
53
|
-
entries
|
|
213
|
+
entries,
|
|
54
214
|
};
|
|
55
215
|
return cachedIndex;
|
|
56
216
|
}
|
|
57
217
|
/**
|
|
58
|
-
* Gets or creates the
|
|
218
|
+
* Gets or creates the MiniSearch instance over the combined index.
|
|
219
|
+
*
|
|
220
|
+
* MiniSearch gives tokenized, BM25-style ranking with field boosting — far
|
|
221
|
+
* better recall on prose (Developer Center guides) than a title-only fuzzy
|
|
222
|
+
* match, while still returning class-name lookups (e.g. "ProductMgr") first.
|
|
59
223
|
*/
|
|
60
|
-
function
|
|
61
|
-
if (
|
|
62
|
-
return
|
|
224
|
+
function getMiniSearch() {
|
|
225
|
+
if (cachedMiniSearch)
|
|
226
|
+
return cachedMiniSearch;
|
|
63
227
|
const index = loadSearchIndex();
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
],
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
228
|
+
const ms = new MiniSearch({
|
|
229
|
+
idField: 'id',
|
|
230
|
+
fields: ['title', 'id', 'headings', 'keywords', 'summary'],
|
|
231
|
+
// We look entries up in entryById on read, so nothing extra needs storing.
|
|
232
|
+
storeFields: ['category'],
|
|
233
|
+
searchOptions: {
|
|
234
|
+
boost: { title: 3, id: 2.5, keywords: 2, headings: 2, summary: 1.5 },
|
|
235
|
+
fuzzy: 0.2,
|
|
236
|
+
prefix: true,
|
|
237
|
+
// OR-combine: relevance ranking surfaces the best (near-AND) matches first
|
|
238
|
+
// while still finding prose docs from natural-language queries whose
|
|
239
|
+
// stopwords ("how", "the") are not indexed. Verified best recall in eval.
|
|
240
|
+
// NOTE: the per-document category boost is applied per-search in
|
|
241
|
+
// searchDocs (it depends on runtime workspace context), not baked here.
|
|
242
|
+
},
|
|
73
243
|
});
|
|
74
|
-
|
|
244
|
+
ms.addAll(index.entries.map((e) => ({
|
|
245
|
+
id: e.id,
|
|
246
|
+
title: e.title ?? '',
|
|
247
|
+
category: e.category ?? '',
|
|
248
|
+
headings: e.headings ?? '',
|
|
249
|
+
summary: e.summary ?? '',
|
|
250
|
+
keywords: Array.isArray(e.keywords) ? e.keywords.join(' ') : '',
|
|
251
|
+
})));
|
|
252
|
+
getLogger().debug({ documentCount: index.entries.length }, 'Built MiniSearch index for documentation search');
|
|
253
|
+
cachedMiniSearch = ms;
|
|
254
|
+
return ms;
|
|
255
|
+
}
|
|
256
|
+
/** Intersects two category lists; `undefined` on either side means "no constraint on that side". */
|
|
257
|
+
function intersectCategories(a, b) {
|
|
258
|
+
if (!a)
|
|
259
|
+
return b ? [...b] : undefined;
|
|
260
|
+
if (!b)
|
|
261
|
+
return [...a];
|
|
262
|
+
const bSet = new Set(b);
|
|
263
|
+
return a.filter((c) => bSet.has(c));
|
|
75
264
|
}
|
|
76
265
|
/**
|
|
77
|
-
* Searches the documentation index
|
|
266
|
+
* Searches the combined documentation index.
|
|
267
|
+
*
|
|
268
|
+
* Higher scores are better. Results carry the full {@link DocEntry} (including
|
|
269
|
+
* `category`, `summary`, `keywords`, and `url` when available) so callers can
|
|
270
|
+
* triage matches without a follow-up read.
|
|
271
|
+
*
|
|
272
|
+
* When `workspace` is provided, the categories relevant to those markers (e.g.
|
|
273
|
+
* `sfra` for an SFRA project, `script-api`/`job-step` for any cartridge project,
|
|
274
|
+
* `pwa-kit-managed-runtime`/`commerce-api` for PWA Kit, `sfnext`/`commerce-api`
|
|
275
|
+
* for Storefront Next — plus the always-relevant docs) are boosted. It only ever
|
|
276
|
+
* reorders results; use `category`/`enabledCategories` to hard-scope.
|
|
78
277
|
*
|
|
79
278
|
* @param query - The search query string
|
|
80
|
-
* @param
|
|
81
|
-
* @returns Array of search results sorted by relevance
|
|
279
|
+
* @param limitOrOptions - Result limit (number) or {@link SearchDocsOptions}
|
|
280
|
+
* @returns Array of search results sorted by relevance (best first)
|
|
82
281
|
*
|
|
83
282
|
* @example
|
|
84
283
|
* ```typescript
|
|
85
|
-
*
|
|
86
|
-
*
|
|
284
|
+
* // Favor the current workspace's docs (nothing hidden)
|
|
285
|
+
* searchDocs('deploy bundle', {workspace: 'pwa-kit-v3'});
|
|
286
|
+
* // Hard-scope to one category instead
|
|
287
|
+
* searchDocs('components', {category: 'sfnext'});
|
|
87
288
|
* ```
|
|
88
289
|
*/
|
|
89
|
-
export function searchDocs(query,
|
|
90
|
-
const
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
290
|
+
export function searchDocs(query, limitOrOptions) {
|
|
291
|
+
const opts = typeof limitOrOptions === 'number' ? { limit: limitOrOptions } : (limitOrOptions ?? {});
|
|
292
|
+
const limit = opts.limit ?? 20;
|
|
293
|
+
const workspaces = toWorkspaceList(opts.workspace);
|
|
294
|
+
// Only an explicit category is a hard filter now; a workspace never hides docs.
|
|
295
|
+
const explicit = opts.category ? (Array.isArray(opts.category) ? opts.category : [opts.category]) : undefined;
|
|
296
|
+
// The launch-time allowlist bounds the whole corpus; the per-query category
|
|
297
|
+
// narrows within it. Their intersection is the effective hard filter.
|
|
298
|
+
const filterCategories = intersectCategories(opts.enabledCategories, explicit);
|
|
299
|
+
// A known workspace boosts its relevant categories, and DE-BOOSTS the guides
|
|
300
|
+
// of competing storefront frameworks (a different storefront's how-to guides
|
|
301
|
+
// are usually the wrong answer). Neither hides anything — both only reweight.
|
|
302
|
+
const boostSet = workspaces ? new Set(categoriesForWorkspace(workspaces)) : undefined;
|
|
303
|
+
const competingSet = boostSet
|
|
304
|
+
? new Set(STOREFRONT_FRAMEWORK_CATEGORIES.filter((c) => !boostSet.has(c)))
|
|
305
|
+
: undefined;
|
|
306
|
+
const ms = getMiniSearch();
|
|
307
|
+
const raw = ms.search(query, {
|
|
308
|
+
filter: filterCategories ? (r) => filterCategories.includes(r.category) : undefined,
|
|
309
|
+
boostDocument: (_id, _term, storedFields) => {
|
|
310
|
+
const category = storedFields?.category;
|
|
311
|
+
if (!category)
|
|
312
|
+
return 1;
|
|
313
|
+
if (boostSet?.has(category))
|
|
314
|
+
return WORKSPACE_BOOST;
|
|
315
|
+
if (competingSet?.has(category))
|
|
316
|
+
return COMPETING_STOREFRONT_PENALTY;
|
|
317
|
+
return 1;
|
|
318
|
+
},
|
|
319
|
+
});
|
|
320
|
+
const results = [];
|
|
321
|
+
for (const r of raw) {
|
|
322
|
+
const entry = entryById.get(r.id);
|
|
323
|
+
if (!entry)
|
|
324
|
+
continue;
|
|
325
|
+
results.push({ entry: publicEntry(entry), score: r.score });
|
|
326
|
+
if (results.length >= limit)
|
|
327
|
+
break;
|
|
328
|
+
}
|
|
329
|
+
const logger = getLogger();
|
|
330
|
+
logger.debug({ query, filterCategories, workspaces, limit, matched: raw.length, returned: results.length }, 'docs searchDocs completed');
|
|
331
|
+
logger.trace({ query, top: results.slice(0, 5).map((r) => ({ id: r.entry.id, score: r.score })) }, 'docs search top hits');
|
|
332
|
+
return results;
|
|
96
333
|
}
|
|
97
334
|
/**
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
* @param id - The documentation ID (filename without .md extension)
|
|
101
|
-
* @returns The raw markdown content of the document
|
|
102
|
-
* @throws Error if the document is not found
|
|
335
|
+
* Lists documentation entries, optionally filtered by category.
|
|
103
336
|
*
|
|
104
|
-
* @
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
337
|
+
* @param category - Optional corpus/category (or list) to restrict to
|
|
338
|
+
* @param enabledCategories - Optional launch-time allowlist that bounds the
|
|
339
|
+
* entire corpus (see {@link SearchDocsOptions.enabledCategories}). When set,
|
|
340
|
+
* only entries in these categories are eligible; `category` narrows within it.
|
|
341
|
+
* @returns Array of matching documentation entries
|
|
109
342
|
*/
|
|
110
|
-
export function
|
|
343
|
+
export function listDocs(category, enabledCategories) {
|
|
111
344
|
const index = loadSearchIndex();
|
|
112
|
-
const
|
|
345
|
+
const explicit = category ? (Array.isArray(category) ? category : [category]) : undefined;
|
|
346
|
+
const categories = intersectCategories(enabledCategories, explicit);
|
|
347
|
+
const entries = categories
|
|
348
|
+
? index.entries.filter((e) => e.category && categories.includes(e.category))
|
|
349
|
+
: index.entries;
|
|
350
|
+
return entries.map(publicEntry);
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Reads the full content of a documentation entry by its exact id.
|
|
354
|
+
*
|
|
355
|
+
* Bundled entries are read from disk. Entries whose content is published online
|
|
356
|
+
* (Developer Center guides) are fetched from their canonical URL; on network
|
|
357
|
+
* failure a readable fallback assembled from the indexed metadata is returned.
|
|
358
|
+
*
|
|
359
|
+
* @param id - The documentation id
|
|
360
|
+
* @returns The document content (markdown)
|
|
361
|
+
* @throws Error if the id is unknown
|
|
362
|
+
*/
|
|
363
|
+
export async function readDoc(id) {
|
|
364
|
+
loadSearchIndex();
|
|
365
|
+
const entry = entryById.get(id);
|
|
113
366
|
if (!entry) {
|
|
114
367
|
throw new Error(`Documentation not found: ${id}`);
|
|
115
368
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
369
|
+
return readEntryContent(entry);
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Reads the content of a resolved {@link DocEntry}, choosing bundled-file vs.
|
|
373
|
+
* online fetch based on whether the entry ships its content on disk.
|
|
374
|
+
*/
|
|
375
|
+
export async function readEntryContent(entry) {
|
|
376
|
+
const logger = getLogger();
|
|
377
|
+
const dataDir = entryDataDir.get(entry.id);
|
|
378
|
+
if (dataDir && entry.filePath) {
|
|
379
|
+
logger.debug({ id: entry.id, source: 'bundled', filePath: entry.filePath }, 'Reading bundled documentation entry');
|
|
380
|
+
return fs.readFileSync(path.join(dataDir, entry.filePath), 'utf-8');
|
|
381
|
+
}
|
|
382
|
+
// Online-only entries (guides): fetch the raw markdown. Prefer `sourceUrl`
|
|
383
|
+
// (the `.md`); fall back to `url` for any entry that only carries one.
|
|
384
|
+
const fetchUrl = entry.sourceUrl ?? entry.url;
|
|
385
|
+
if (fetchUrl) {
|
|
386
|
+
logger.debug({ id: entry.id, source: 'online', fetchUrl }, 'Reading online documentation entry');
|
|
387
|
+
return fetchOnlineContent(entry, fetchUrl);
|
|
388
|
+
}
|
|
389
|
+
throw new Error(`No content source for documentation entry: ${entry.id}`);
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Fetches a guide's markdown from `fetchUrl`, falling back to a summary
|
|
393
|
+
* assembled from indexed metadata if the request fails (offline, 404, etc.).
|
|
394
|
+
*/
|
|
395
|
+
async function fetchOnlineContent(entry, fetchUrl) {
|
|
396
|
+
const logger = getLogger();
|
|
397
|
+
try {
|
|
398
|
+
logger.trace({ fetchUrl }, 'Fetching online documentation content');
|
|
399
|
+
const res = await fetch(fetchUrl, {
|
|
400
|
+
headers: { accept: 'text/markdown, text/plain, */*' },
|
|
401
|
+
signal: AbortSignal.timeout(ONLINE_FETCH_TIMEOUT_MS),
|
|
402
|
+
});
|
|
403
|
+
if (!res.ok) {
|
|
404
|
+
logger.debug({ fetchUrl, status: res.status }, 'Online doc fetch returned non-OK status');
|
|
405
|
+
return offlineFallback(entry, `HTTP ${res.status}`);
|
|
406
|
+
}
|
|
407
|
+
const text = await res.text();
|
|
408
|
+
logger.trace({ fetchUrl, bytes: text.length }, 'Fetched online documentation content');
|
|
409
|
+
return text;
|
|
410
|
+
}
|
|
411
|
+
catch (err) {
|
|
412
|
+
logger.debug({ fetchUrl, err }, 'Online doc fetch failed');
|
|
413
|
+
return offlineFallback(entry, err instanceof Error ? err.message : String(err));
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
/** Assembles a minimal readable document from indexed metadata when fetch fails. */
|
|
417
|
+
function offlineFallback(entry, reason) {
|
|
418
|
+
const lines = [`# ${entry.title}`, ''];
|
|
419
|
+
if (entry.summary)
|
|
420
|
+
lines.push(entry.summary, '');
|
|
421
|
+
if (entry.headings)
|
|
422
|
+
lines.push('## Sections', '', entry.headings
|
|
423
|
+
.split(' • ')
|
|
424
|
+
.map((h) => `- ${h}`)
|
|
425
|
+
.join('\n'), '');
|
|
426
|
+
if (entry.url)
|
|
427
|
+
lines.push(`Full documentation: ${entry.url}`, '');
|
|
428
|
+
lines.push(`> Note: live content could not be fetched (${reason}); showing indexed summary only.`);
|
|
429
|
+
return lines.join('\n');
|
|
119
430
|
}
|
|
120
431
|
/**
|
|
121
432
|
* Reads documentation by fuzzy-matching the query and returning the best match.
|
|
122
433
|
*
|
|
123
434
|
* @param query - The search query string
|
|
435
|
+
* @param options - Optional search constraints (e.g. category)
|
|
124
436
|
* @returns The best matching entry and its content, or null if no match
|
|
125
437
|
*
|
|
126
438
|
* @example
|
|
127
439
|
* ```typescript
|
|
128
|
-
* const doc = readDocByQuery('ProductMgr');
|
|
129
|
-
* if (doc)
|
|
130
|
-
* console.log(`Found: ${doc.entry.title}`);
|
|
131
|
-
* console.log(doc.content);
|
|
132
|
-
* }
|
|
440
|
+
* const doc = await readDocByQuery('ProductMgr');
|
|
441
|
+
* if (doc) console.log(doc.content);
|
|
133
442
|
* ```
|
|
134
443
|
*/
|
|
135
|
-
export function readDocByQuery(query) {
|
|
136
|
-
|
|
444
|
+
export async function readDocByQuery(query, options) {
|
|
445
|
+
// Prefer an exact id match so precise lookups are deterministic. Honor both
|
|
446
|
+
// the per-query category constraint and the launch-time allowlist so an exact
|
|
447
|
+
// id in a non-requested (or disabled) corpus does not win.
|
|
448
|
+
loadSearchIndex();
|
|
449
|
+
const exact = entryById.get(query);
|
|
450
|
+
if (exact) {
|
|
451
|
+
const perQuery = options?.category
|
|
452
|
+
? Array.isArray(options.category)
|
|
453
|
+
? options.category
|
|
454
|
+
: [options.category]
|
|
455
|
+
: undefined;
|
|
456
|
+
const categories = intersectCategories(options?.enabledCategories, perQuery);
|
|
457
|
+
if (!categories || (exact.category && categories.includes(exact.category))) {
|
|
458
|
+
// Resolve content from the stored entry (keeps headings for offline
|
|
459
|
+
// fallback), but return the public entry (headings stripped).
|
|
460
|
+
return { entry: publicEntry(exact), content: await readEntryContent(exact) };
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
const results = searchDocs(query, { ...options, limit: 1 });
|
|
137
464
|
if (results.length === 0) {
|
|
138
465
|
return null;
|
|
139
466
|
}
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
return { entry, content };
|
|
467
|
+
const stored = entryById.get(results[0].entry.id) ?? results[0].entry;
|
|
468
|
+
return { entry: publicEntry(stored), content: await readEntryContent(stored) };
|
|
143
469
|
}
|
|
144
470
|
/**
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
* @returns Array of all documentation entries in the index
|
|
148
|
-
*
|
|
149
|
-
* @example
|
|
150
|
-
* ```typescript
|
|
151
|
-
* const docs = listDocs();
|
|
152
|
-
* console.log(`${docs.length} documentation files available`);
|
|
153
|
-
* ```
|
|
471
|
+
* Resets the in-memory index/search caches. Intended for tests that swap the
|
|
472
|
+
* bundled data on disk between assertions.
|
|
154
473
|
*/
|
|
155
|
-
export function
|
|
156
|
-
|
|
157
|
-
|
|
474
|
+
export function resetDocsCache() {
|
|
475
|
+
cachedIndex = null;
|
|
476
|
+
cachedMiniSearch = null;
|
|
477
|
+
entryDataDir.clear();
|
|
478
|
+
entryById.clear();
|
|
158
479
|
}
|
|
159
480
|
//# sourceMappingURL=search.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../../src/docs/search.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,IAAI,MAAM,SAAS,CAAC;AAC3B,OAAO,EAAC,kBAAkB,EAAE,mBAAmB,EAAqD,MAAM,YAAY,CAAC;AAEvH,qDAAqD;AACrD,IAAI,WAAW,GAAuB,IAAI,CAAC;AAC3C,IAAI,UAAU,GAA0B,IAAI,CAAC;AAE7C,8EAA8E;AAC9E,8EAA8E;AAC9E,mFAAmF;AACnF,MAAM,YAAY,GAAG,IAAI,GAAG,EAAkB,CAAC;AAE/C;;;GAGG;AACH,SAAS,UAAU,CAAC,OAAe;IACjC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IACnD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAgB,CAAC;IAC9E,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnC,kEAAkE;QAClE,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;YAChC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC,OAAO,CAAC;AACxB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe;IAC7B,IAAI,WAAW;QAAE,OAAO,WAAW,CAAC;IAEpC,YAAY,CAAC,KAAK,EAAE,CAAC;IACrB,MAAM,gBAAgB,GAAG,UAAU,CAAC,mBAAmB,CAAC,CAAC;IACzD,MAAM,cAAc,GAAG,UAAU,CAAC,kBAAkB,CAAC,CAAC;IAEtD,WAAW,GAAG;QACZ,OAAO,EAAE,OAAO;QAChB,WAAW,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;QACtC,OAAO,EAAE,CAAC,GAAG,gBAAgB,EAAE,GAAG,cAAc,CAAC;KAClD,CAAC;IACF,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,SAAS,eAAe;IACtB,IAAI,UAAU;QAAE,OAAO,UAAU,CAAC;IAElC,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;IAEhC,UAAU,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE;QACnC,IAAI,EAAE;YACJ,EAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAC;YAC5B,EAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAC;SAC1B;QACD,SAAS,EAAE,GAAG;QACd,YAAY,EAAE,IAAI;QAClB,kBAAkB,EAAE,CAAC;QACrB,cAAc,EAAE,IAAI;KACrB,CAAC,CAAC;IAEH,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,UAAU,CAAC,KAAa,EAAE,KAAK,GAAG,EAAE;IAClD,MAAM,IAAI,GAAG,eAAe,EAAE,CAAC;IAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,EAAC,KAAK,EAAC,CAAC,CAAC;IAE5C,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACzB,KAAK,EAAE,CAAC,CAAC,IAAI;QACb,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;KACpB,CAAC,CAAC,CAAC;AACN,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,OAAO,CAAC,EAAU;IAChC,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IAErD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,4BAA4B,EAAE,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,mBAAmB,CAAC;IAClE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IACpD,OAAO,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAErC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAC/B,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAElC,OAAO,EAAC,KAAK,EAAE,OAAO,EAAC,CAAC;AAC1B,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,QAAQ;IACtB,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;IAChC,OAAO,KAAK,CAAC,OAAO,CAAC;AACvB,CAAC"}
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../../src/docs/search.ts"],"names":[],"mappings":"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"}
|