@salesforce/b2c-tooling-sdk 1.16.0 → 1.18.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.
Files changed (185) hide show
  1. package/data/content-schemas/componenttype.json +79 -17
  2. package/data/content-schemas/pagetype.json +4 -0
  3. package/data/content-schemas/regiondefinition.json +1 -0
  4. package/data/guides/enrichment.json +11264 -0
  5. package/data/guides/index.json +15166 -0
  6. package/data/job-steps/CatalogDeltaExport.md +31 -0
  7. package/data/job-steps/CreateSitemap.md +22 -0
  8. package/data/job-steps/CustomerListsDeltaExport.md +30 -0
  9. package/data/job-steps/DownloadActiveDataFromStorage.md +24 -0
  10. package/data/job-steps/ExecuteCategorizationRules.md +25 -0
  11. package/data/job-steps/ExecuteDataReplication.md +24 -0
  12. package/data/job-steps/ExecutePipeline.md +24 -0
  13. package/data/job-steps/ExecutePreconfiguredCodeReplicationProcess.md +24 -0
  14. package/data/job-steps/ExecutePreconfiguredDataReplicationProcess.md +24 -0
  15. package/data/job-steps/ExecuteScriptModule.md +27 -0
  16. package/data/job-steps/ExportABTests.md +30 -0
  17. package/data/job-steps/ExportAssignments.md +30 -0
  18. package/data/job-steps/ExportCatalog.md +37 -0
  19. package/data/job-steps/ExportContent.md +31 -0
  20. package/data/job-steps/ExportContentSlots.md +30 -0
  21. package/data/job-steps/ExportCouponCodes.md +33 -0
  22. package/data/job-steps/ExportCoupons.md +30 -0
  23. package/data/job-steps/ExportCustomObjects.md +31 -0
  24. package/data/job-steps/ExportCustomerGroups.md +30 -0
  25. package/data/job-steps/ExportCustomerList.md +31 -0
  26. package/data/job-steps/ExportCustomers.md +30 -0
  27. package/data/job-steps/ExportFacebookFeed.md +26 -0
  28. package/data/job-steps/ExportGiftCertificates.md +30 -0
  29. package/data/job-steps/ExportInventoryLists.md +31 -0
  30. package/data/job-steps/ExportMetaData.md +32 -0
  31. package/data/job-steps/ExportOrders.md +42 -0
  32. package/data/job-steps/ExportPageLocalization.md +34 -0
  33. package/data/job-steps/ExportPriceBook.md +31 -0
  34. package/data/job-steps/ExportProductLists.md +34 -0
  35. package/data/job-steps/ExportPromotions.md +30 -0
  36. package/data/job-steps/ExportShippingMethods.md +30 -0
  37. package/data/job-steps/ExportSourceCodeGroups.md +30 -0
  38. package/data/job-steps/ExportStores.md +31 -0
  39. package/data/job-steps/ExportTaxTable.md +30 -0
  40. package/data/job-steps/ImportABTests.md +34 -0
  41. package/data/job-steps/ImportActiveData.md +33 -0
  42. package/data/job-steps/ImportAssignments.md +34 -0
  43. package/data/job-steps/ImportCatalog.md +34 -0
  44. package/data/job-steps/ImportContent.md +34 -0
  45. package/data/job-steps/ImportContentSlots.md +34 -0
  46. package/data/job-steps/ImportCouponCodeRedemptions.md +34 -0
  47. package/data/job-steps/ImportCoupons.md +34 -0
  48. package/data/job-steps/ImportCustomObjects.md +34 -0
  49. package/data/job-steps/ImportCustomerGroups.md +34 -0
  50. package/data/job-steps/ImportCustomerList.md +34 -0
  51. package/data/job-steps/ImportCustomerLists.md +34 -0
  52. package/data/job-steps/ImportCustomers.md +34 -0
  53. package/data/job-steps/ImportGiftCertificates.md +34 -0
  54. package/data/job-steps/ImportInventoryLists.md +35 -0
  55. package/data/job-steps/ImportKeyValueMapping.md +35 -0
  56. package/data/job-steps/ImportPageLocalization.md +34 -0
  57. package/data/job-steps/ImportPriceBook.md +34 -0
  58. package/data/job-steps/ImportProductLists.md +34 -0
  59. package/data/job-steps/ImportPromotions.md +34 -0
  60. package/data/job-steps/ImportShippingMethods.md +34 -0
  61. package/data/job-steps/ImportSiteArchive.md +30 -0
  62. package/data/job-steps/ImportSourceCodeGroups.md +34 -0
  63. package/data/job-steps/ImportStores.md +34 -0
  64. package/data/job-steps/ImportTaxTable.md +34 -0
  65. package/data/job-steps/IncludeStepsFromJob.md +24 -0
  66. package/data/job-steps/InvalidateCache.md +26 -0
  67. package/data/job-steps/LibraryDeltaExport.md +30 -0
  68. package/data/job-steps/SearchReindex.md +27 -0
  69. package/data/job-steps/SiteExport.md +32 -0
  70. package/data/job-steps/UndoPreconfiguredCodeReplicationProcess.md +24 -0
  71. package/data/job-steps/UndoPreconfiguredDataReplicationProcess.md +24 -0
  72. package/data/job-steps/UpdateStorefrontURLs.md +22 -0
  73. package/data/job-steps/UploadActiveDataBackupToStorage.md +22 -0
  74. package/data/job-steps/UploadActiveDataToStorage.md +24 -0
  75. package/data/job-steps/index.json +496 -0
  76. package/data/job-steps/job-steps.json +2910 -0
  77. package/data/job-steps/job-steps.md +96 -0
  78. package/data/script-api/TopLevel.APIException.md +1 -1
  79. package/data/script-api/dw.catalog.CatalogMgr.md +8 -2
  80. package/data/script-api/dw.crypto.Cipher.md +5 -1
  81. package/data/script-api/dw.customer.Profile.md +45 -0
  82. package/data/script-api/dw.customer.consent.ConsentStatusEntry.md +92 -0
  83. package/data/script-api/dw.customer.consent.MarketingConsentSubscription.md +247 -0
  84. package/data/script-api/dw.customer.consent.ShopperConsentErrorCodes.md +74 -0
  85. package/data/script-api/dw.customer.consent.ShopperConsentException.md +63 -0
  86. package/data/script-api/dw.customer.consent.ShopperConsentMgr.md +152 -0
  87. package/data/script-api/dw.customer.consent.md +10 -0
  88. package/data/script-api/dw.extensions.payments.SalesforcePaymentsHooks.md +24 -0
  89. package/data/script-api/dw.extensions.payments.SalesforcePaymentsSiteConfiguration.md +76 -0
  90. package/data/script-api/dw.object.CustomAttributes.md +72 -29
  91. package/data/script-api/dw.object.md +1 -1
  92. package/data/script-api/dw.order.Basket.md +3 -2
  93. package/data/script-api/dw.order.GiftCertificateLineItem.md +1 -1
  94. package/data/script-api/dw.order.LineItem.md +88 -0
  95. package/data/script-api/dw.order.LineItemCtnr.md +41 -11
  96. package/data/script-api/dw.order.LineItemTax.md +142 -0
  97. package/data/script-api/dw.order.OrderMgr.md +8 -0
  98. package/data/script-api/dw.order.PriceAdjustment.md +1 -1
  99. package/data/script-api/dw.order.ProductLineItem.md +1 -1
  100. package/data/script-api/dw.order.ProductShippingLineItem.md +1 -1
  101. package/data/script-api/dw.order.Shipment.md +12 -4
  102. package/data/script-api/dw.order.ShippingLineItem.md +1 -1
  103. package/data/script-api/dw.order.TaxMgr.md +54 -0
  104. package/data/script-api/dw.order.hooks.TaxHooks.md +495 -0
  105. package/data/script-api/dw.order.hooks.md +1 -0
  106. package/data/script-api/dw.order.md +1 -0
  107. package/data/script-api/dw.sitemap.SitemapFile.md +1 -1
  108. package/data/script-api/dw.sitemap.SitemapMgr.md +23 -0
  109. package/data/script-api/dw.system.Request.md +0 -1
  110. package/data/script-api/dw.util.Assert.md +29 -0
  111. package/data/script-api/dw.util.Locale.md +5 -2
  112. package/data/script-api/dw.web.Cookie.md +0 -6
  113. package/data/script-api/dw.web.PageMetaTag.md +25 -1
  114. package/data/script-api/dw.ws.WSUtil.md +2 -2
  115. package/data/script-api/index.json +2192 -37
  116. package/data/script-api/index.md +2 -1
  117. package/data/tooling/index.json +222 -0
  118. package/data/xsd/commercefeaturestate.xsd +1 -0
  119. package/data/xsd/customer.xsd +11 -0
  120. package/data/xsd/eventrouting.xsd +257 -0
  121. package/data/xsd/index.json +6 -2
  122. package/data/xsd/order.xsd +53 -0
  123. package/data/xsd/store.xsd +8 -0
  124. package/data/xsd/storefronts.xsd +57 -1
  125. package/dist/esm/auth/client-credentials.d.ts +27 -0
  126. package/dist/esm/auth/client-credentials.js +60 -0
  127. package/dist/esm/auth/client-credentials.js.map +1 -0
  128. package/dist/esm/auth/index.d.ts +1 -0
  129. package/dist/esm/auth/index.js +2 -0
  130. package/dist/esm/auth/index.js.map +1 -1
  131. package/dist/esm/auth/oauth.js +2 -1
  132. package/dist/esm/auth/oauth.js.map +1 -1
  133. package/dist/esm/cli/base-command.d.ts +40 -0
  134. package/dist/esm/cli/base-command.js +66 -5
  135. package/dist/esm/cli/base-command.js.map +1 -1
  136. package/dist/esm/cli/index.d.ts +2 -2
  137. package/dist/esm/cli/index.js +1 -1
  138. package/dist/esm/cli/index.js.map +1 -1
  139. package/dist/esm/cli/instance-command.d.ts +1 -1
  140. package/dist/esm/cli/instance-command.js +5 -3
  141. package/dist/esm/cli/instance-command.js.map +1 -1
  142. package/dist/esm/cli/oauth-command.d.ts +1 -1
  143. package/dist/esm/cli/oauth-command.js +5 -3
  144. package/dist/esm/cli/oauth-command.js.map +1 -1
  145. package/dist/esm/cli/ods-command.d.ts +1 -1
  146. package/dist/esm/cli/webdav-command.d.ts +1 -1
  147. package/dist/esm/config/sources/env-source.js +1 -0
  148. package/dist/esm/config/sources/env-source.js.map +1 -1
  149. package/dist/esm/discovery/detector.d.ts +0 -5
  150. package/dist/esm/discovery/detector.js +24 -3
  151. package/dist/esm/discovery/detector.js.map +1 -1
  152. package/dist/esm/discovery/index.d.ts +1 -0
  153. package/dist/esm/discovery/index.js +1 -0
  154. package/dist/esm/discovery/index.js.map +1 -1
  155. package/dist/esm/discovery/patterns/index.d.ts +4 -2
  156. package/dist/esm/discovery/patterns/index.js +9 -3
  157. package/dist/esm/discovery/patterns/index.js.map +1 -1
  158. package/dist/esm/discovery/patterns/pwa-kit.d.ts +12 -0
  159. package/dist/esm/discovery/patterns/pwa-kit.js +18 -7
  160. package/dist/esm/discovery/patterns/pwa-kit.js.map +1 -1
  161. package/dist/esm/discovery/patterns/sfra.d.ts +5 -4
  162. package/dist/esm/discovery/patterns/sfra.js +1 -1
  163. package/dist/esm/discovery/patterns/sfra.js.map +1 -1
  164. package/dist/esm/discovery/patterns/storefront-next.js +18 -2
  165. package/dist/esm/discovery/patterns/storefront-next.js.map +1 -1
  166. package/dist/esm/discovery/types.d.ts +13 -4
  167. package/dist/esm/discovery/types.js +11 -1
  168. package/dist/esm/discovery/types.js.map +1 -1
  169. package/dist/esm/docs/index.d.ts +3 -3
  170. package/dist/esm/docs/index.js +1 -1
  171. package/dist/esm/docs/index.js.map +1 -1
  172. package/dist/esm/docs/search.d.ts +113 -37
  173. package/dist/esm/docs/search.js +424 -72
  174. package/dist/esm/docs/search.js.map +1 -1
  175. package/dist/esm/docs/types.d.ts +57 -6
  176. package/dist/esm/docs/types.js +3 -0
  177. package/dist/esm/docs/types.js.map +1 -1
  178. package/dist/esm/slas/token.d.ts +9 -2
  179. package/dist/esm/slas/token.js +25 -29
  180. package/dist/esm/slas/token.js.map +1 -1
  181. package/dist/esm/telemetry/telemetry.d.ts +1 -0
  182. package/dist/esm/telemetry/telemetry.js +32 -0
  183. package/dist/esm/telemetry/telemetry.js.map +1 -1
  184. package/dist/esm/telemetry/types.d.ts +6 -0
  185. package/package.json +9 -2
@@ -5,124 +5,476 @@
5
5
  */
6
6
  import * as fs from 'node:fs';
7
7
  import * as path from 'node:path';
8
- import Fuse from 'fuse.js';
9
- import { SCRIPT_API_DATA_DIR } from './types.js';
10
- // Singleton cache for loaded index and Fuse instance
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 cachedFuse = null;
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.
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
+ }
166
+ /**
167
+ * Loads one bundled index.json from the given directory, returning its entries
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.
170
+ */
171
+ function loadCorpus(dataDir) {
172
+ const indexPath = path.join(dataDir, 'index.json');
173
+ if (!fs.existsSync(indexPath)) {
174
+ return [];
175
+ }
176
+ const parsed = JSON.parse(fs.readFileSync(indexPath, 'utf-8'));
177
+ for (const entry of parsed.entries) {
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) {
183
+ entryDataDir.set(entry.id, dataDir);
184
+ }
185
+ }
186
+ return parsed.entries;
187
+ }
13
188
  /**
14
- * Loads the pre-built search index from the bundled data directory.
189
+ * Loads the combined search index from every bundled corpus directory.
15
190
  *
16
- * @returns The search index with all documentation entries
17
- * @throws Error if the index file cannot be read
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.
194
+ *
195
+ * @returns The combined search index with all documentation entries
18
196
  */
19
197
  export function loadSearchIndex() {
20
198
  if (cachedIndex)
21
199
  return cachedIndex;
22
- const indexPath = path.join(SCRIPT_API_DATA_DIR, 'index.json');
23
- const indexContent = fs.readFileSync(indexPath, 'utf-8');
24
- cachedIndex = JSON.parse(indexContent);
200
+ entryDataDir.clear();
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');
210
+ cachedIndex = {
211
+ version: '2.0.0',
212
+ generatedAt: new Date(0).toISOString(),
213
+ entries,
214
+ };
25
215
  return cachedIndex;
26
216
  }
27
217
  /**
28
- * Gets or creates the Fuse.js search instance.
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.
29
223
  */
30
- function getFuseInstance() {
31
- if (cachedFuse)
32
- return cachedFuse;
224
+ function getMiniSearch() {
225
+ if (cachedMiniSearch)
226
+ return cachedMiniSearch;
33
227
  const index = loadSearchIndex();
34
- cachedFuse = new Fuse(index.entries, {
35
- keys: [
36
- { name: 'title', weight: 0.5 },
37
- { name: 'id', weight: 0.5 },
38
- ],
39
- threshold: 0.4,
40
- includeScore: true,
41
- minMatchCharLength: 2,
42
- ignoreLocation: true,
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
+ },
43
243
  });
44
- return cachedFuse;
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));
45
264
  }
46
265
  /**
47
- * Searches the documentation index with fuzzy matching.
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.
48
277
  *
49
278
  * @param query - The search query string
50
- * @param limit - Maximum number of results to return (default: 20)
51
- * @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)
52
281
  *
53
282
  * @example
54
283
  * ```typescript
55
- * const results = searchDocs('ProductMgr');
56
- * results.forEach(r => console.log(r.entry.id, r.score));
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'});
57
288
  * ```
58
289
  */
59
- export function searchDocs(query, limit = 20) {
60
- const fuse = getFuseInstance();
61
- const results = fuse.search(query, { limit });
62
- return results.map((r) => ({
63
- entry: r.item,
64
- score: r.score ?? 0,
65
- }));
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;
66
333
  }
67
334
  /**
68
- * Reads the content of a documentation file by its ID.
69
- *
70
- * @param id - The documentation ID (filename without .md extension)
71
- * @returns The raw markdown content of the document
72
- * @throws Error if the document is not found
335
+ * Lists documentation entries, optionally filtered by category.
73
336
  *
74
- * @example
75
- * ```typescript
76
- * const content = readDoc('dw.catalog.ProductMgr');
77
- * console.log(content);
78
- * ```
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
79
342
  */
80
- export function readDoc(id) {
343
+ export function listDocs(category, enabledCategories) {
81
344
  const index = loadSearchIndex();
82
- const entry = index.entries.find((e) => e.id === id);
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);
83
366
  if (!entry) {
84
367
  throw new Error(`Documentation not found: ${id}`);
85
368
  }
86
- const filePath = path.join(SCRIPT_API_DATA_DIR, entry.filePath);
87
- return fs.readFileSync(filePath, 'utf-8');
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');
88
430
  }
89
431
  /**
90
432
  * Reads documentation by fuzzy-matching the query and returning the best match.
91
433
  *
92
434
  * @param query - The search query string
435
+ * @param options - Optional search constraints (e.g. category)
93
436
  * @returns The best matching entry and its content, or null if no match
94
437
  *
95
438
  * @example
96
439
  * ```typescript
97
- * const doc = readDocByQuery('ProductMgr');
98
- * if (doc) {
99
- * console.log(`Found: ${doc.entry.title}`);
100
- * console.log(doc.content);
101
- * }
440
+ * const doc = await readDocByQuery('ProductMgr');
441
+ * if (doc) console.log(doc.content);
102
442
  * ```
103
443
  */
104
- export function readDocByQuery(query) {
105
- const results = searchDocs(query, 1);
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 });
106
464
  if (results.length === 0) {
107
465
  return null;
108
466
  }
109
- const entry = results[0].entry;
110
- const content = readDoc(entry.id);
111
- return { entry, content };
467
+ const stored = entryById.get(results[0].entry.id) ?? results[0].entry;
468
+ return { entry: publicEntry(stored), content: await readEntryContent(stored) };
112
469
  }
113
470
  /**
114
- * Lists all available documentation entries.
115
- *
116
- * @returns Array of all documentation entries in the index
117
- *
118
- * @example
119
- * ```typescript
120
- * const docs = listDocs();
121
- * console.log(`${docs.length} documentation files available`);
122
- * ```
471
+ * Resets the in-memory index/search caches. Intended for tests that swap the
472
+ * bundled data on disk between assertions.
123
473
  */
124
- export function listDocs() {
125
- const index = loadSearchIndex();
126
- return index.entries;
474
+ export function resetDocsCache() {
475
+ cachedIndex = null;
476
+ cachedMiniSearch = null;
477
+ entryDataDir.clear();
478
+ entryById.clear();
127
479
  }
128
480
  //# sourceMappingURL=search.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"search.js","sourceRoot":"","sources":["../../../src/docs/search.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../../src/docs/search.ts"],"names":[],"mappings":"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"}
@@ -1,16 +1,67 @@
1
1
  export declare const SCRIPT_API_DATA_DIR: string;
2
2
  export declare const XSD_DATA_DIR: string;
3
+ export declare const JOB_STEPS_DATA_DIR: string;
4
+ export declare const GUIDES_DATA_DIR: string;
5
+ export declare const TOOLING_DATA_DIR: string;
6
+ /**
7
+ * The corpus a documentation entry belongs to. Used to tag and filter results
8
+ * so agents can narrow a search to a documentation set (e.g., only Storefront
9
+ * Next guides, or only the Script API reference).
10
+ *
11
+ * - `script-api` — B2C Commerce Script API class/module reference
12
+ * - `job-step` — standard (system) job step reference
13
+ * - `commerce-api` / `pwa-kit-managed-runtime` / `sfnext` / `sfra` / `b2c-commerce`
14
+ * — Developer Center prose guides, one category per Developer Center project
15
+ * - `tooling` — this project's own conceptual guides (CLI/MCP/SDK usage)
16
+ */
17
+ export type DocCategory = 'script-api' | 'job-step' | 'commerce-api' | 'pwa-kit-managed-runtime' | 'sfnext' | 'sfra' | 'b2c-commerce' | 'tooling';
3
18
  /**
4
19
  * A documentation entry in the search index.
20
+ *
21
+ * Entries span multiple corpora (Script API reference, job steps, Developer
22
+ * Center guides, and this project's own docs). Reference entries are bundled
23
+ * on disk and read via {@link DocEntry.filePath}; guide entries are indexed
24
+ * locally but their full content is fetched on demand from {@link DocEntry.url}.
5
25
  */
6
26
  export interface DocEntry {
7
- /** Unique identifier - the filename without .md extension (e.g., "dw.catalog.ProductMgr") */
27
+ /**
28
+ * Unique identifier. For bundled reference this is the filename without its
29
+ * extension (e.g., "dw.catalog.ProductMgr"); for guides it is namespaced by
30
+ * category to avoid cross-corpus collisions (e.g., "sfnext/sfnext-get-started").
31
+ */
8
32
  id: string;
9
- /** The title from the document heading (e.g., "Class ProductMgr") */
33
+ /** The title from the document's first heading (e.g., "Class ProductMgr"). */
10
34
  title: string;
11
- /** The filename (e.g., "dw.catalog.ProductMgr.md") */
12
- filePath: string;
13
- /** Optional preview/excerpt from the document */
35
+ /** The corpus/category this entry belongs to. */
36
+ category?: DocCategory;
37
+ /**
38
+ * Path of the bundled markdown file relative to its corpus data directory.
39
+ * Present for entries whose content ships in the package; absent for entries
40
+ * whose content is fetched online (see {@link DocEntry.sourceUrl}).
41
+ */
42
+ filePath?: string;
43
+ /**
44
+ * Canonical human-facing published URL (the rendered `.html` page, e.g. on
45
+ * developer.salesforce.com). This is the durable link to cite/open in a
46
+ * browser. Present for every corpus that has a public page (guides, Script
47
+ * API reference, tooling); absent for corpora with no public page (job steps).
48
+ */
49
+ url?: string;
50
+ /**
51
+ * The raw-markdown (`.md`) URL for the same document — the machine-readable
52
+ * source. For online-only entries (guides) this is what {@link readEntryContent}
53
+ * fetches at read time. Bundled corpora (Script API, tooling) also carry it so
54
+ * callers can retrieve the raw source on request even though content ships in
55
+ * the package. Absent for corpora with no public page (job steps).
56
+ */
57
+ sourceUrl?: string;
58
+ /** Section headings joined into a single searchable string (indexed, not for display). */
59
+ headings?: string;
60
+ /** One-line summary describing what task/topic the doc helps with (agent triage). */
61
+ summary?: string;
62
+ /** Search keywords/synonyms an agent or developer might use to find this doc. */
63
+ keywords?: string[];
64
+ /** Optional preview/excerpt from the document. */
14
65
  preview?: string;
15
66
  }
16
67
  /**
@@ -30,7 +81,7 @@ export interface SearchIndex {
30
81
  export interface SearchResult {
31
82
  /** The matching documentation entry */
32
83
  entry: DocEntry;
33
- /** Match score (lower is better in Fuse.js, 0 = perfect match) */
84
+ /** Relevance score (higher is better; scale is engine-relative, not normalized). */
34
85
  score: number;
35
86
  }
36
87
  /**