@wix/himalaya-cli 0.1321.0 → 0.1322.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/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/webview/src/index.d.ts +4 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/webview-page/src/index.d.ts +16 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/stores-v1/src/display.d.ts +21 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/webview-page.mjs +78 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/webview.mjs +16 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-stores.mjs +13 -4
- package/dist/cli.mjs +25 -0
- package/guides/sdk-reference.json +33 -3
- package/guides/web-page-native-sdk.md +154 -33
- package/guides/webview-page-sdk.md +11 -0
- package/package.json +2 -2
- package/templates/beauty-salon/dev/index.ts +492 -0
- package/templates/beauty-salon/tier5-src/wix-spaces-collection-detail/index.ts +146 -30
- package/templates/branded-lite/dev/index.ts +492 -0
- package/templates/branded-lite/tier5-src/wix-spaces-collection-detail/index.ts +146 -30
- package/templates/gym-fitness/dev/index.ts +492 -0
- package/templates/gym-fitness/tier5-src/wix-spaces-collection-detail/index.ts +146 -30
- package/templates/portfolio-creative/dev/index.ts +492 -0
- package/templates/portfolio-creative/tier5-src/wix-spaces-collection-detail/index.ts +146 -30
- package/templates/retail-store/dev/index.ts +492 -0
- package/templates/retail-store/tier5-src/wix-spaces-collection-detail/index.ts +146 -30
|
@@ -28,6 +28,10 @@ export interface PageCapabilityResponse {
|
|
|
28
28
|
code?: string;
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
|
+
/** `call("himalaya", "capabilities")` answers `{ v: 1, capabilities: { <id>: [<method>…] } }`:
|
|
32
|
+
* exactly the allowlist this worker was given. Reserved, so no real capability can take it. */
|
|
33
|
+
export declare const PAGE_HANDSHAKE_CAPABILITY = "himalaya";
|
|
34
|
+
export declare const PAGE_HANDSHAKE_METHOD = "capabilities";
|
|
31
35
|
export interface ExposedPageCapability {
|
|
32
36
|
module: Record<string, unknown>;
|
|
33
37
|
methods: readonly string[];
|
|
@@ -18,8 +18,23 @@ export interface WebViewPageResponse {
|
|
|
18
18
|
result?: unknown;
|
|
19
19
|
error?: WebViewPageError;
|
|
20
20
|
}
|
|
21
|
-
/** Invoke one method through the companion worker. Primarily useful to generated bindings.
|
|
21
|
+
/** Invoke one method through the companion worker. Primarily useful to generated bindings.
|
|
22
|
+
* A call that shows native UI (a permission prompt, the share sheet) answers only when the user
|
|
23
|
+
* is done with it: pass a long `timeoutMs` (e.g. 120_000) rather than the 30-second default. */
|
|
22
24
|
export declare function call<T>(capability: string, method: string, args?: unknown[], timeoutMs?: number): Promise<T>;
|
|
25
|
+
/**
|
|
26
|
+
* The capabilities and methods this page's companion worker answers, as `{ <id>: [<method>…] }`;
|
|
27
|
+
* `null` outside the app, when the app is older than the handshake, or nothing answered in
|
|
28
|
+
* `timeoutMs`. A list is remembered (and returned at once, whatever `timeoutMs`); a miss is not,
|
|
29
|
+
* because a worker that is still booting drops the first messages.
|
|
30
|
+
*/
|
|
31
|
+
export declare function enabledCapabilities(timeoutMs?: number): Promise<Record<string, string[]> | null>;
|
|
32
|
+
/** Whether the companion worker lets this page call `capability.method`, read from
|
|
33
|
+
* enabledCapabilities() — nothing is called. `false` when there is no list. */
|
|
34
|
+
export declare function isEnabled(capability: string, method: string, timeoutMs?: number): Promise<boolean>;
|
|
35
|
+
/** For an app older than the handshake: CALL `capability.method` and report whether it answered
|
|
36
|
+
* (even with an error). It runs the method, so pass only a read-only one. */
|
|
37
|
+
export declare function probe(capability: string, method: string, args?: unknown[], timeoutMs?: number): Promise<boolean>;
|
|
23
38
|
/**
|
|
24
39
|
* Typed SDK proxy for every request/response capability in CAPABILITY_REGISTRY.
|
|
25
40
|
* A namespace is usable only when this screen's companion worker explicitly imported and
|
|
@@ -106,11 +106,32 @@ export interface StoreProductSearch {
|
|
|
106
106
|
query?: string;
|
|
107
107
|
sort?: 'default' | 'az' | 'za';
|
|
108
108
|
ids?: string[];
|
|
109
|
+
/**
|
|
110
|
+
* Only products in this category (V3) / collection (V1) — a category screen's
|
|
111
|
+
* "products in X". ANDed with `ids` when both are given.
|
|
112
|
+
*
|
|
113
|
+
* V3 matches `allCategoriesInfo.categories`, so a parent category also lists its
|
|
114
|
+
* subcategories' products, as the site does. Only Search Products can filter by
|
|
115
|
+
* category — Query Products answers `not declared as filterable` — so a
|
|
116
|
+
* `categoryId` always routes the V3 read to `/products/search`. V1 matches
|
|
117
|
+
* `collections.id`.
|
|
118
|
+
*/
|
|
119
|
+
categoryId?: string;
|
|
109
120
|
limit?: number;
|
|
110
121
|
cursor?: string;
|
|
111
122
|
/** Extra v3 fieldsets. Additive — widens the default, never replaces it. */
|
|
112
123
|
fields?: readonly string[];
|
|
113
124
|
}
|
|
125
|
+
/**
|
|
126
|
+
* Search, sort, and filter products on whichever catalog this site runs — the read
|
|
127
|
+
* behind a shop list, a saved-products list, and a category screen.
|
|
128
|
+
*
|
|
129
|
+
* `categoryId` narrows to one category's products (V3 `allCategoriesInfo`, so a parent
|
|
130
|
+
* category includes its subcategories; V1 `collections.id`), ANDed with `ids`. An
|
|
131
|
+
* empty `ids` array resolves to an empty page WITHOUT a request. Paging is one
|
|
132
|
+
* contract on both catalogs: pass back `pagingMetadata.cursors.next` as `cursor`.
|
|
133
|
+
* A non-catalog failure (401/403, offline) rejects; it is never retried on V1.
|
|
134
|
+
*/
|
|
114
135
|
export declare function searchStoreProducts(options?: StoreProductSearch): Promise<StoreProductsResponse>;
|
|
115
136
|
/** Read one product from whichever catalog this site runs. `fields` is additive —
|
|
116
137
|
* it WIDENS the default v3 display fieldset rather than replacing it. */
|
|
@@ -51,6 +51,81 @@ function call(capability, method, args = [], timeoutMs = 3e4) {
|
|
|
51
51
|
}
|
|
52
52
|
});
|
|
53
53
|
}
|
|
54
|
+
var manifest;
|
|
55
|
+
function currentBridge() {
|
|
56
|
+
try {
|
|
57
|
+
return workerBridge();
|
|
58
|
+
} catch {
|
|
59
|
+
return void 0;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function timedOut(error) {
|
|
63
|
+
return error instanceof Error && error.message.startsWith("Himalaya capability call timed out");
|
|
64
|
+
}
|
|
65
|
+
var asking;
|
|
66
|
+
function askShared(target, budget) {
|
|
67
|
+
const until = Date.now() + budget;
|
|
68
|
+
if (asking?.on === target) {
|
|
69
|
+
asking.until = Math.max(asking.until, until);
|
|
70
|
+
return asking.answer;
|
|
71
|
+
}
|
|
72
|
+
const state = { on: target, until, answer: Promise.resolve(null) };
|
|
73
|
+
asking = state;
|
|
74
|
+
state.answer = new Promise((resolve) => {
|
|
75
|
+
let done = false;
|
|
76
|
+
const finish = (list) => {
|
|
77
|
+
if (done) return;
|
|
78
|
+
done = true;
|
|
79
|
+
clearInterval(again);
|
|
80
|
+
if (asking === state) asking = void 0;
|
|
81
|
+
if (list) manifest = { on: target, list };
|
|
82
|
+
resolve(list);
|
|
83
|
+
};
|
|
84
|
+
const ask = () => {
|
|
85
|
+
if (done) return;
|
|
86
|
+
const left = state.until - Date.now();
|
|
87
|
+
if (left <= 0 || currentBridge() !== target) return finish(null);
|
|
88
|
+
call("himalaya", "capabilities", [], Math.max(1, Math.min(2e3, left))).then(
|
|
89
|
+
(reply) => finish(reply?.capabilities ?? null),
|
|
90
|
+
// A timed-out question is not an answer; the deadline decides. Anything else is final.
|
|
91
|
+
(error) => {
|
|
92
|
+
if (!timedOut(error)) finish(null);
|
|
93
|
+
}
|
|
94
|
+
);
|
|
95
|
+
};
|
|
96
|
+
const again = setInterval(ask, 500);
|
|
97
|
+
ask();
|
|
98
|
+
});
|
|
99
|
+
return state.answer;
|
|
100
|
+
}
|
|
101
|
+
async function enabledCapabilities(timeoutMs = 3e3) {
|
|
102
|
+
const bridge = currentBridge();
|
|
103
|
+
if (!bridge) return null;
|
|
104
|
+
if (manifest?.on === bridge) return manifest.list;
|
|
105
|
+
if (!(timeoutMs > 0)) return null;
|
|
106
|
+
const budget = Math.min(timeoutMs, 2147483647);
|
|
107
|
+
const answer = askShared(bridge, budget);
|
|
108
|
+
return new Promise((resolve) => {
|
|
109
|
+
const stop = setTimeout(() => resolve(manifest?.on === bridge ? manifest.list : null), budget);
|
|
110
|
+
void answer.then((list) => {
|
|
111
|
+
clearTimeout(stop);
|
|
112
|
+
resolve(list);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
async function isEnabled(capability, method, timeoutMs = 3e3) {
|
|
117
|
+
const enabled = await enabledCapabilities(timeoutMs);
|
|
118
|
+
return enabled?.[capability]?.includes(method) ?? false;
|
|
119
|
+
}
|
|
120
|
+
async function probe(capability, method, args = [], timeoutMs = 3e3) {
|
|
121
|
+
if (!currentBridge()) return false;
|
|
122
|
+
try {
|
|
123
|
+
await call(capability, method, args, timeoutMs);
|
|
124
|
+
return true;
|
|
125
|
+
} catch (error) {
|
|
126
|
+
return !(timedOut(error) || /refused the request/.test(error.message));
|
|
127
|
+
}
|
|
128
|
+
}
|
|
54
129
|
var members = /* @__PURE__ */ new Map();
|
|
55
130
|
function pageMember(capability, path) {
|
|
56
131
|
const key = `${capability}:${path.join(".")}`;
|
|
@@ -81,8 +156,11 @@ var health = himalaya.health;
|
|
|
81
156
|
var version = 1;
|
|
82
157
|
export {
|
|
83
158
|
call,
|
|
159
|
+
enabledCapabilities,
|
|
84
160
|
health,
|
|
85
161
|
himalaya,
|
|
162
|
+
isEnabled,
|
|
163
|
+
probe,
|
|
86
164
|
version
|
|
87
165
|
};
|
|
88
166
|
//# sourceMappingURL=webview-page.mjs.map
|
|
@@ -14,6 +14,8 @@ function postToPage(msg) {
|
|
|
14
14
|
function onPageMessage(cb) {
|
|
15
15
|
runtime().onPageMessage(cb);
|
|
16
16
|
}
|
|
17
|
+
var PAGE_HANDSHAKE_CAPABILITY = "himalaya";
|
|
18
|
+
var PAGE_HANDSHAKE_METHOD = "capabilities";
|
|
17
19
|
function pageRequest(value) {
|
|
18
20
|
if (!value || typeof value !== "object") return null;
|
|
19
21
|
const request = value;
|
|
@@ -29,15 +31,27 @@ function pageError(value) {
|
|
|
29
31
|
};
|
|
30
32
|
}
|
|
31
33
|
function exposeCapabilitiesToPage(capabilities) {
|
|
34
|
+
if (Object.prototype.hasOwnProperty.call(capabilities, PAGE_HANDSHAKE_CAPABILITY)) {
|
|
35
|
+
throw new Error(`"${PAGE_HANDSHAKE_CAPABILITY}" is reserved for the page handshake and cannot be exposed`);
|
|
36
|
+
}
|
|
32
37
|
const allowed = new Map(
|
|
33
38
|
Object.entries(capabilities).map(([id, entry]) => [id, {
|
|
34
39
|
module: entry.module,
|
|
35
40
|
methods: new Set(entry.methods)
|
|
36
41
|
}])
|
|
37
42
|
);
|
|
43
|
+
const manifest = Object.fromEntries(
|
|
44
|
+
[...allowed].map(([id, entry]) => [id, [...entry.methods].sort()])
|
|
45
|
+
);
|
|
38
46
|
onPageMessage((message) => {
|
|
39
47
|
const request = pageRequest(message);
|
|
40
48
|
if (!request) return;
|
|
49
|
+
if (request.capability === PAGE_HANDSHAKE_CAPABILITY) {
|
|
50
|
+
if (request.method === PAGE_HANDSHAKE_METHOD) {
|
|
51
|
+
postToPage({ v: 1, id: request.id, ok: true, result: { v: 1, capabilities: manifest } });
|
|
52
|
+
}
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
41
55
|
const capability = allowed.get(request.capability);
|
|
42
56
|
let candidate = capability?.module;
|
|
43
57
|
let receiver = void 0;
|
|
@@ -58,6 +72,8 @@ function exposeCapabilitiesToPage(capabilities) {
|
|
|
58
72
|
}
|
|
59
73
|
var version = 1;
|
|
60
74
|
export {
|
|
75
|
+
PAGE_HANDSHAKE_CAPABILITY,
|
|
76
|
+
PAGE_HANDSHAKE_METHOD,
|
|
61
77
|
exposeCapabilitiesToPage,
|
|
62
78
|
onPageMessage,
|
|
63
79
|
postToPage,
|
|
@@ -369,21 +369,30 @@ async function searchStoreProducts(options = {}) {
|
|
|
369
369
|
const limit = Math.max(1, Math.min(100, Math.floor(options.limit ?? 50) || 50));
|
|
370
370
|
const ids = options.ids === void 0 ? void 0 : [...new Set(options.ids.filter((id) => typeof id === "string" && !!id))].slice(0, 500);
|
|
371
371
|
if (ids && !ids.length) return { products: [], pagingMetadata: { total: 0, count: 0, cursors: { next: null }, hasNext: false } };
|
|
372
|
+
const categoryId = typeof options.categoryId === "string" ? options.categoryId.trim() : "";
|
|
372
373
|
const ascending = options.sort === "az", sorted = ascending || options.sort === "za";
|
|
373
374
|
return readWithCatalogFallback((version) => {
|
|
374
375
|
if (version === "v1") {
|
|
375
376
|
const offset = v1Offset(options.cursor);
|
|
376
|
-
const
|
|
377
|
+
const filter2 = {
|
|
378
|
+
...query ? { name: { $contains: query } } : {},
|
|
379
|
+
...ids ? { id: { $hasSome: ids } } : {},
|
|
380
|
+
...categoryId ? { "collections.id": { $hasSome: [categoryId] } } : {}
|
|
381
|
+
};
|
|
377
382
|
return wixCall("POST", "/stores/v1/products/query", { query: {
|
|
378
383
|
paging: { limit, offset },
|
|
379
|
-
...Object.keys(
|
|
384
|
+
...Object.keys(filter2).length ? { filter: JSON.stringify(filter2) } : {},
|
|
380
385
|
...sorted ? { sort: JSON.stringify([{ name: ascending ? "asc" : "desc" }]) } : {}
|
|
381
386
|
} }).then((res) => fromV1(res, offset));
|
|
382
387
|
}
|
|
383
|
-
const
|
|
388
|
+
const filter = {
|
|
389
|
+
...ids ? { id: { $in: ids } } : {},
|
|
390
|
+
...categoryId ? { "allCategoriesInfo.categories": { $matchItems: [{ id: categoryId }] } } : {}
|
|
391
|
+
};
|
|
392
|
+
const search = !!query || sorted || !!categoryId;
|
|
384
393
|
const criteria = {
|
|
385
394
|
cursorPaging: { limit, ...options.cursor ? { cursor: options.cursor } : {} },
|
|
386
|
-
...
|
|
395
|
+
...Object.keys(filter).length ? { filter } : {},
|
|
387
396
|
...query ? { search: { expression: query, fields: ["name"] } } : {},
|
|
388
397
|
...sorted ? { sort: [{ fieldName: "name", order: ascending ? "ASC" : "DESC" }] } : {}
|
|
389
398
|
};
|
package/dist/cli.mjs
CHANGED
|
@@ -149133,6 +149133,7 @@ __export(nav_lint_exports, {
|
|
|
149133
149133
|
NAV_KINDS: () => NAV_KINDS,
|
|
149134
149134
|
SERVED_ONLY_NAV_KEYS: () => SERVED_ONLY_NAV_KEYS,
|
|
149135
149135
|
navIssues: () => navIssues,
|
|
149136
|
+
navSharedIdErrors: () => navSharedIdErrors,
|
|
149136
149137
|
pushRouteAdvisories: () => pushRouteAdvisories
|
|
149137
149138
|
});
|
|
149138
149139
|
async function navIssues(dir, strict) {
|
|
@@ -149209,6 +149210,7 @@ async function navIssues(dir, strict) {
|
|
|
149209
149210
|
for (const message of navConfigPathErrors({ ...nav, homeScreenId: servedHome })) {
|
|
149210
149211
|
error("nav-path-malformed", `navigation.${message}`);
|
|
149211
149212
|
}
|
|
149213
|
+
for (const message of navSharedIdErrors(nav)) error("nav-row-id-shadows-tab", `navigation.${message}`);
|
|
149212
149214
|
const navKind = nav.navKind;
|
|
149213
149215
|
const effectiveBottomTabs = navKind === void 0 || navKind === "bottomTabs" || typeof navKind !== "string" || !NAV_KINDS.has(navKind);
|
|
149214
149216
|
const declaresOtherChrome = itemCount(nav.drawer) > 0 || itemCount(nav.sidebar) > 0;
|
|
@@ -149316,6 +149318,29 @@ function unmappedAdvisory({ destination, vertical, reason, screenId, paramKey })
|
|
|
149316
149318
|
}
|
|
149317
149319
|
return `push-route-unmapped: the site has ${vertical}, but no screen opens "${destination}" notifications. Name that screen "${canonical4}", or map it: push.screens: { "${destination}": "<screenId>" }.`;
|
|
149318
149320
|
}
|
|
149321
|
+
function navSharedIdErrors(nav) {
|
|
149322
|
+
const items = (key2) => {
|
|
149323
|
+
const block = nav[key2];
|
|
149324
|
+
const list = isPlainObject2(block) ? block.items : void 0;
|
|
149325
|
+
return Array.isArray(list) ? list.flatMap((x2, i2) => isPlainObject2(x2) ? [[x2, i2]] : []) : [];
|
|
149326
|
+
};
|
|
149327
|
+
const tabScreens = /* @__PURE__ */ new Map();
|
|
149328
|
+
for (const [tab] of items("tabBar")) if (typeof tab.id === "string" && !tabScreens.has(tab.id)) tabScreens.set(tab.id, tab.screenId);
|
|
149329
|
+
const out2 = [];
|
|
149330
|
+
for (const key2 of ["drawer", "sidebar"]) {
|
|
149331
|
+
for (const [row, i2] of items(key2)) {
|
|
149332
|
+
if (typeof row.id !== "string" || !tabScreens.has(row.id)) continue;
|
|
149333
|
+
const tabScreen = tabScreens.get(row.id);
|
|
149334
|
+
if (typeof tabScreen !== "string") continue;
|
|
149335
|
+
if (key2 === "drawer" && (row.role === "section" || row.role === "note")) continue;
|
|
149336
|
+
if (typeof row.screenId !== "string" || row.screenId === "" || row.screenId === tabScreen) continue;
|
|
149337
|
+
out2.push(
|
|
149338
|
+
`${key2}.items[${i2}] "${row.id}": a tab has this id but opens ${JSON.stringify(tabScreen)}, not "${row.screenId}" \u2014 every shell hands its host one id and the host resolves tabs first, so this row would open the tab's screen. Give the row its own id.`
|
|
149339
|
+
);
|
|
149340
|
+
}
|
|
149341
|
+
}
|
|
149342
|
+
return out2;
|
|
149343
|
+
}
|
|
149319
149344
|
var NAVIGATION_KEYS, NAV_KINDS, ITEMS_BLOCKS, SERVED_ONLY_NAV_KEYS, MISPLACED_TOP_LEVEL_KEYS, isPlainObject2, itemCount;
|
|
149320
149345
|
var init_nav_lint = __esm({
|
|
149321
149346
|
"src/nav-lint.ts"() {
|
|
@@ -4188,6 +4188,18 @@
|
|
|
4188
4188
|
"jsdoc": "",
|
|
4189
4189
|
"decl": "export interface PageCapabilityResponse {\n v: 1;\n id: string;\n ok: boolean;\n result?: unknown;\n error?: { message: string; code?: string };\n}"
|
|
4190
4190
|
},
|
|
4191
|
+
{
|
|
4192
|
+
"name": "PAGE_HANDSHAKE_CAPABILITY",
|
|
4193
|
+
"kind": "const",
|
|
4194
|
+
"jsdoc": "/** `call(\"himalaya\", \"capabilities\")` answers `{ v: 1, capabilities: { <id>: [<method>…] } }`:\n * exactly the allowlist this worker was given. Reserved, so no real capability can take it. */",
|
|
4195
|
+
"decl": "export const PAGE_HANDSHAKE_CAPABILITY = \"himalaya\";"
|
|
4196
|
+
},
|
|
4197
|
+
{
|
|
4198
|
+
"name": "PAGE_HANDSHAKE_METHOD",
|
|
4199
|
+
"kind": "const",
|
|
4200
|
+
"jsdoc": "",
|
|
4201
|
+
"decl": "export const PAGE_HANDSHAKE_METHOD = \"capabilities\";"
|
|
4202
|
+
},
|
|
4191
4203
|
{
|
|
4192
4204
|
"name": "ExposedPageCapability",
|
|
4193
4205
|
"kind": "interface",
|
|
@@ -4240,9 +4252,27 @@
|
|
|
4240
4252
|
{
|
|
4241
4253
|
"name": "call",
|
|
4242
4254
|
"kind": "function",
|
|
4243
|
-
"jsdoc": "/** Invoke one method through the companion worker. Primarily useful to generated bindings. */",
|
|
4255
|
+
"jsdoc": "/** Invoke one method through the companion worker. Primarily useful to generated bindings.\n * A call that shows native UI (a permission prompt, the share sheet) answers only when the user\n * is done with it: pass a long `timeoutMs` (e.g. 120_000) rather than the 30-second default. */",
|
|
4244
4256
|
"decl": "export function call<T>(\n capability: string,\n method: string,\n args: unknown[] = [],\n timeoutMs = 30_000,\n): Promise<T>;"
|
|
4245
4257
|
},
|
|
4258
|
+
{
|
|
4259
|
+
"name": "enabledCapabilities",
|
|
4260
|
+
"kind": "function",
|
|
4261
|
+
"jsdoc": "/**\n * The capabilities and methods this page's companion worker answers, as `{ <id>: [<method>…] }`;\n * `null` outside the app, when the app is older than the handshake, or nothing answered in\n * `timeoutMs`. A list is remembered (and returned at once, whatever `timeoutMs`); a miss is not,\n * because a worker that is still booting drops the first messages.\n */",
|
|
4262
|
+
"decl": "export async function enabledCapabilities(timeoutMs = 3_000): Promise<Record<string, string[]> | null>;"
|
|
4263
|
+
},
|
|
4264
|
+
{
|
|
4265
|
+
"name": "isEnabled",
|
|
4266
|
+
"kind": "function",
|
|
4267
|
+
"jsdoc": "/** Whether the companion worker lets this page call `capability.method`, read from\n * enabledCapabilities() — nothing is called. `false` when there is no list. */",
|
|
4268
|
+
"decl": "export async function isEnabled(capability: string, method: string, timeoutMs = 3_000): Promise<boolean>;"
|
|
4269
|
+
},
|
|
4270
|
+
{
|
|
4271
|
+
"name": "probe",
|
|
4272
|
+
"kind": "function",
|
|
4273
|
+
"jsdoc": "/** For an app older than the handshake: CALL `capability.method` and report whether it answered\n * (even with an error). It runs the method, so pass only a read-only one. */",
|
|
4274
|
+
"decl": "export async function probe(capability: string, method: string, args: unknown[] = [], timeoutMs = 3_000): Promise<boolean>;"
|
|
4275
|
+
},
|
|
4246
4276
|
{
|
|
4247
4277
|
"name": "himalaya",
|
|
4248
4278
|
"kind": "const",
|
|
@@ -23108,12 +23138,12 @@
|
|
|
23108
23138
|
"name": "StoreProductSearch",
|
|
23109
23139
|
"kind": "interface",
|
|
23110
23140
|
"jsdoc": "/** User-facing product discovery. V3 name search/sorting belong to Search\n * Products; Query Products deliberately does not support the name field.\n * V1 uses its documented JSON-string filter/sort dialect. */",
|
|
23111
|
-
"decl": "export interface StoreProductSearch {\n query?: string;\n sort?: 'default' | 'az' | 'za';\n ids?: string[];\n limit?: number;\n cursor?: string;\n /** Extra v3 fieldsets. Additive — widens the default, never replaces it. */\n fields?: readonly string[];\n}"
|
|
23141
|
+
"decl": "export interface StoreProductSearch {\n query?: string;\n sort?: 'default' | 'az' | 'za';\n ids?: string[];\n /**\n * Only products in this category (V3) / collection (V1) — a category screen's\n * \"products in X\". ANDed with `ids` when both are given.\n *\n * V3 matches `allCategoriesInfo.categories`, so a parent category also lists its\n * subcategories' products, as the site does. Only Search Products can filter by\n * category — Query Products answers `not declared as filterable` — so a\n * `categoryId` always routes the V3 read to `/products/search`. V1 matches\n * `collections.id`.\n */\n categoryId?: string;\n limit?: number;\n cursor?: string;\n /** Extra v3 fieldsets. Additive — widens the default, never replaces it. */\n fields?: readonly string[];\n}"
|
|
23112
23142
|
},
|
|
23113
23143
|
{
|
|
23114
23144
|
"name": "searchStoreProducts",
|
|
23115
23145
|
"kind": "function",
|
|
23116
|
-
"jsdoc": "",
|
|
23146
|
+
"jsdoc": "/**\n * Search, sort, and filter products on whichever catalog this site runs — the read\n * behind a shop list, a saved-products list, and a category screen.\n *\n * `categoryId` narrows to one category's products (V3 `allCategoriesInfo`, so a parent\n * category includes its subcategories; V1 `collections.id`), ANDed with `ids`. An\n * empty `ids` array resolves to an empty page WITHOUT a request. Paging is one\n * contract on both catalogs: pass back `pagingMetadata.cursors.next` as `cursor`.\n * A non-catalog failure (401/403, offline) rejects; it is never retried on V1.\n */",
|
|
23117
23147
|
"decl": "export async function searchStoreProducts(options: StoreProductSearch = {}): Promise<StoreProductsResponse>;",
|
|
23118
23148
|
"http": "POST /stores/v1/products/query"
|
|
23119
23149
|
},
|