@wix/himalaya-cli 0.941.0 → 0.943.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/stdlib/wix-sdk/bookings-v2/src/index.d.ts +10 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/wix-data/src/index.d.ts +50 -3
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-data.mjs +16 -2
- package/dist/cli.mjs +6 -1
- package/guides/sdk-reference.json +45 -21
- package/package.json +2 -2
- package/templates/beauty-salon/tier5-src/wix-spaces-collections/index.ts +60 -12
- package/templates/branded-lite/dev/index.ts +224 -14
- package/templates/branded-lite/tier5-src/himi-branded-lite-badges/index.ts +11 -8
- package/templates/branded-lite/tier5-src/himi-branded-lite-coupons/index.ts +17 -6
- package/templates/branded-lite/tier5-src/himi-branded-lite-donations/index.ts +11 -8
- package/templates/branded-lite/tier5-src/himi-branded-lite-forms/index.ts +11 -10
- package/templates/branded-lite/tier5-src/himi-branded-lite-galleries/index.ts +12 -9
- package/templates/branded-lite/tier5-src/himi-branded-lite-giftcards/index.ts +11 -8
- package/templates/branded-lite/tier5-src/himi-branded-lite-inbox/index.ts +11 -8
- package/templates/branded-lite/tier5-src/himi-branded-lite-invoices/index.ts +11 -8
- package/templates/branded-lite/tier5-src/himi-branded-lite-loyalty/index.ts +11 -8
- package/templates/branded-lite/tier5-src/himi-branded-lite-notifications/index.ts +13 -8
- package/templates/branded-lite/tier5-src/himi-branded-lite-notifsettings/index.ts +11 -8
- package/templates/branded-lite/tier5-src/himi-branded-lite-reservations/index.ts +11 -8
- package/templates/branded-lite/tier5-src/himi-branded-lite-reviews/index.ts +11 -8
- package/templates/branded-lite/tier5-src/himi-branded-lite-videos/index.ts +12 -9
- package/templates/branded-lite/tier5-src/wix-spaces-collections/index.ts +60 -12
- package/templates/gym-fitness/tier5-src/wix-spaces-collections/index.ts +60 -12
- package/templates/portfolio-creative/tier5-src/wix-spaces-collections/index.ts +60 -12
- package/templates/retail-store/tier5-src/wix-spaces-collections/index.ts +60 -12
|
@@ -185,7 +185,17 @@ export interface WixUpdateBookingResponse {
|
|
|
185
185
|
export interface WixRescheduleBookingResponse {
|
|
186
186
|
booking: WixBooking;
|
|
187
187
|
}
|
|
188
|
+
/**
|
|
189
|
+
* @scope owner — requires an owner / business identity — a visitor session gets 403.
|
|
190
|
+
*
|
|
191
|
+
* POST /bookings/v2/bookings/query
|
|
192
|
+
*/
|
|
188
193
|
export declare function queryBookings(req?: WixQueryBookingsRequest, opts?: WixCallOptions): Promise<WixQueryBookingsResponse>;
|
|
194
|
+
/**
|
|
195
|
+
* @scope owner — requires an owner / business identity — a visitor session gets 403.
|
|
196
|
+
*
|
|
197
|
+
* GET /bookings/v1/bookings
|
|
198
|
+
*/
|
|
189
199
|
export declare function listBookings(req?: WixListBookingsRequest, opts?: WixCallOptions): Promise<WixListBookingsResponse>;
|
|
190
200
|
export declare function getBooking(bookingId: string, opts?: WixCallOptions): Promise<WixGetBookingResponse>;
|
|
191
201
|
export declare function createBooking(req?: WixCreateBookingRequest, opts?: WixCallOptions): Promise<WixCreateBookingResponse>;
|
|
@@ -50,9 +50,56 @@ export interface WixUpdateDataItemRequest {
|
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
52
|
/** Query items in a collection — POST /wix-data/v2/items/query.
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
|
|
53
|
+
*
|
|
54
|
+
* `filter` is the Wix Data v2 filter object, which the type cannot express (it is
|
|
55
|
+
* `Record<string, unknown>` by construction). A field name maps to a value for
|
|
56
|
+
* equality, or to an operator object:
|
|
57
|
+
*
|
|
58
|
+
* ```ts
|
|
59
|
+
* await queryDataItems("Listings", 20, { city: "Tel Aviv" });
|
|
60
|
+
* await queryDataItems("Listings", 20, { price: { $lte: 2_500_000 } });
|
|
61
|
+
* await queryDataItems("Listings", 20, { _id: { $in: [a, b] } });
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* `offset` pages: ask for `limit` rows starting at `offset`. Pair it with
|
|
65
|
+
* `returnTotalCount: true`, which fills `pagingMetadata.total` so a caller knows
|
|
66
|
+
* when to stop — it is omitted by default because counting is extra work, and it
|
|
67
|
+
* reports total for OFFSET paging only, which is the mode this function uses.
|
|
68
|
+
*
|
|
69
|
+
* ```ts
|
|
70
|
+
* const first = await queryDataItems("Listings", 50, undefined, true);
|
|
71
|
+
* const total = first.pagingMetadata?.total ?? 0;
|
|
72
|
+
* const rest = await queryDataItems("Listings", 50, undefined, false, 50);
|
|
73
|
+
* ```
|
|
74
|
+
*
|
|
75
|
+
* To read ONE row, use `getDataItem` rather than a page plus a client-side
|
|
76
|
+
* `.find()` — that pattern breaks silently once the collection outgrows `limit`. */
|
|
77
|
+
export declare function queryDataItems(dataCollectionId: string, limit?: number, filter?: Record<string, unknown>, returnTotalCount?: boolean, offset?: number): Promise<WixQueryDataItemsResponse>;
|
|
78
|
+
/** Read ONE item by id — GET /wix-data/v2/items/{dataItemId}?dataCollectionId=…
|
|
79
|
+
*
|
|
80
|
+
* Reach for this on a detail screen. Before it existed the only read this package
|
|
81
|
+
* offered was `queryDataItems`, so a detail worker had to fetch a bounded page and
|
|
82
|
+
* find its row client-side:
|
|
83
|
+
*
|
|
84
|
+
* ```ts
|
|
85
|
+
* const res = await queryDataItems("Listings", 50); // ← DON'T
|
|
86
|
+
* const row = (res.dataItems ?? []).find((it) => it.id === id);
|
|
87
|
+
* ```
|
|
88
|
+
*
|
|
89
|
+
* That is correct against a handful of seeded rows and silently wrong once the
|
|
90
|
+
* collection outgrows `limit`. Ask for the row instead:
|
|
91
|
+
*
|
|
92
|
+
* ```ts
|
|
93
|
+
* const { dataItem } = await getDataItem("Listings", id); // ← DO
|
|
94
|
+
* ```
|
|
95
|
+
*
|
|
96
|
+
* The collection id rides the query string rather than a body, because the Wix
|
|
97
|
+
* gateway drops a GET body — and the string is built with `encodeURIComponent`
|
|
98
|
+
* rather than `URLSearchParams`, which the bare Tier-5 worker runtimes (JSCore /
|
|
99
|
+
* Hermes / QuickJS-ng) do not provide. */
|
|
100
|
+
export declare function getDataItem(dataCollectionId: string, dataItemId: string): Promise<{
|
|
101
|
+
dataItem?: WixDataItem;
|
|
102
|
+
}>;
|
|
56
103
|
/** Insert an item — POST /wix-data/v2/items. */
|
|
57
104
|
export declare function insertDataItem(dataCollectionId: string, data: Record<string, unknown>): Promise<{
|
|
58
105
|
dataItem?: WixDataItem;
|
|
@@ -7,15 +7,28 @@ function wixCall(method, path, body) {
|
|
|
7
7
|
}
|
|
8
8
|
return globalThis.himalaya.wixApi.call(method, path, body);
|
|
9
9
|
}
|
|
10
|
-
function queryDataItems(dataCollectionId, limit = 50, filter, returnTotalCount = false) {
|
|
10
|
+
function queryDataItems(dataCollectionId, limit = 50, filter, returnTotalCount = false, offset = 0) {
|
|
11
11
|
if (!dataCollectionId) throw new Error("queryDataItems: dataCollectionId is required");
|
|
12
12
|
const body = {
|
|
13
13
|
dataCollectionId,
|
|
14
|
-
query: {
|
|
14
|
+
query: {
|
|
15
|
+
// `offset` is omitted when 0 so a caller that does not page sends the byte-identical
|
|
16
|
+
// body it sent before this parameter existed.
|
|
17
|
+
paging: { limit, ...offset ? { offset } : {} },
|
|
18
|
+
...filter ? { filter } : {}
|
|
19
|
+
},
|
|
15
20
|
...returnTotalCount ? { returnTotalCount: true } : {}
|
|
16
21
|
};
|
|
17
22
|
return wixCall("POST", "/wix-data/v2/items/query", body);
|
|
18
23
|
}
|
|
24
|
+
function getDataItem(dataCollectionId, dataItemId) {
|
|
25
|
+
if (!dataCollectionId) throw new Error("getDataItem: dataCollectionId is required");
|
|
26
|
+
if (!dataItemId) throw new Error("getDataItem: dataItemId is required");
|
|
27
|
+
return wixCall(
|
|
28
|
+
"GET",
|
|
29
|
+
`/wix-data/v2/items/${encodeURIComponent(dataItemId)}?dataCollectionId=${encodeURIComponent(dataCollectionId)}`
|
|
30
|
+
);
|
|
31
|
+
}
|
|
19
32
|
function insertDataItem(dataCollectionId, data) {
|
|
20
33
|
if (!dataCollectionId) throw new Error("insertDataItem: dataCollectionId is required");
|
|
21
34
|
return wixCall("POST", "/wix-data/v2/items", {
|
|
@@ -36,6 +49,7 @@ function removeDataItem(dataCollectionId, id) {
|
|
|
36
49
|
return wixCall("DELETE", `/wix-data/v2/items/${encodeURIComponent(id)}?${q}`);
|
|
37
50
|
}
|
|
38
51
|
export {
|
|
52
|
+
getDataItem,
|
|
39
53
|
insertDataItem,
|
|
40
54
|
queryDataItems,
|
|
41
55
|
removeDataItem,
|
package/dist/cli.mjs
CHANGED
|
@@ -1378,7 +1378,12 @@ function readTemplateFiles(srcRoot) {
|
|
|
1378
1378
|
function scaffoldFromTemplate(name, dir, template) {
|
|
1379
1379
|
const srcRoot = templateSourceDir(template);
|
|
1380
1380
|
if (!existsSync2(join3(srcRoot, "himalaya.content.json"))) {
|
|
1381
|
-
throw new Error(
|
|
1381
|
+
throw new Error(
|
|
1382
|
+
`unknown template "${template}" \u2014 not bundled with this CLI.
|
|
1383
|
+
bundled: ${availableTemplates().join(", ") || "none"}
|
|
1384
|
+
The published catalog is larger: \`himi template list --remote\` lists it, and
|
|
1385
|
+
\`himi init <app> --template ${template} --remote\` fetches one from there.`
|
|
1386
|
+
);
|
|
1382
1387
|
}
|
|
1383
1388
|
return finishScaffold(materializeSource(readTemplateFiles(srcRoot), name, dir), template);
|
|
1384
1389
|
}
|
|
@@ -6955,16 +6955,18 @@
|
|
|
6955
6955
|
{
|
|
6956
6956
|
"name": "queryBookings",
|
|
6957
6957
|
"kind": "function",
|
|
6958
|
-
"jsdoc": "",
|
|
6958
|
+
"jsdoc": "/**\n * @scope owner — requires an owner / business identity — a visitor session gets 403.\n *\n * POST /bookings/v2/bookings/query\n */",
|
|
6959
6959
|
"decl": "export function queryBookings(\n req: WixQueryBookingsRequest = {} as WixQueryBookingsRequest,\n opts?: WixCallOptions,\n): Promise<WixQueryBookingsResponse>;",
|
|
6960
|
-
"http": "POST /bookings/v2/bookings/query"
|
|
6960
|
+
"http": "POST /bookings/v2/bookings/query",
|
|
6961
|
+
"scope": "owner"
|
|
6961
6962
|
},
|
|
6962
6963
|
{
|
|
6963
6964
|
"name": "listBookings",
|
|
6964
6965
|
"kind": "function",
|
|
6965
|
-
"jsdoc": "",
|
|
6966
|
+
"jsdoc": "/**\n * @scope owner — requires an owner / business identity — a visitor session gets 403.\n *\n * GET /bookings/v1/bookings\n */",
|
|
6966
6967
|
"decl": "export function listBookings(\n req: WixListBookingsRequest = {} as WixListBookingsRequest,\n opts?: WixCallOptions,\n): Promise<WixListBookingsResponse>;",
|
|
6967
|
-
"http": "GET /bookings/v1/bookings"
|
|
6968
|
+
"http": "GET /bookings/v1/bookings",
|
|
6969
|
+
"scope": "owner"
|
|
6968
6970
|
},
|
|
6969
6971
|
{
|
|
6970
6972
|
"name": "getBooking",
|
|
@@ -10524,10 +10526,17 @@
|
|
|
10524
10526
|
{
|
|
10525
10527
|
"name": "queryDataItems",
|
|
10526
10528
|
"kind": "function",
|
|
10527
|
-
"jsdoc": "/** Query items in a collection — POST /wix-data/v2/items/query.\n *
|
|
10528
|
-
"decl": "export function queryDataItems(\n dataCollectionId: string,\n limit = 50,\n filter?: Record<string, unknown>,\n returnTotalCount = false,\n): Promise<WixQueryDataItemsResponse>;",
|
|
10529
|
+
"jsdoc": "/** Query items in a collection — POST /wix-data/v2/items/query.\n *\n * `filter` is the Wix Data v2 filter object, which the type cannot express (it is\n * `Record<string, unknown>` by construction). A field name maps to a value for\n * equality, or to an operator object:\n *\n * ```ts\n * await queryDataItems(\"Listings\", 20, { city: \"Tel Aviv\" });\n * await queryDataItems(\"Listings\", 20, { price: { $lte: 2_500_000 } });\n * await queryDataItems(\"Listings\", 20, { _id: { $in: [a, b] } });\n * ```\n *\n * `offset` pages: ask for `limit` rows starting at `offset`. Pair it with\n * `returnTotalCount: true`, which fills `pagingMetadata.total` so a caller knows\n * when to stop — it is omitted by default because counting is extra work, and it\n * reports total for OFFSET paging only, which is the mode this function uses.\n *\n * ```ts\n * const first = await queryDataItems(\"Listings\", 50, undefined, true);\n * const total = first.pagingMetadata?.total ?? 0;\n * const rest = await queryDataItems(\"Listings\", 50, undefined, false, 50);\n * ```\n *\n * To read ONE row, use `getDataItem` rather than a page plus a client-side\n * `.find()` — that pattern breaks silently once the collection outgrows `limit`. */",
|
|
10530
|
+
"decl": "export function queryDataItems(\n dataCollectionId: string,\n limit = 50,\n filter?: Record<string, unknown>,\n returnTotalCount = false,\n offset = 0,\n): Promise<WixQueryDataItemsResponse>;",
|
|
10529
10531
|
"http": "POST /wix-data/v2/items/query"
|
|
10530
10532
|
},
|
|
10533
|
+
{
|
|
10534
|
+
"name": "getDataItem",
|
|
10535
|
+
"kind": "function",
|
|
10536
|
+
"jsdoc": "/** Read ONE item by id — GET /wix-data/v2/items/{dataItemId}?dataCollectionId=…\n *\n * Reach for this on a detail screen. Before it existed the only read this package\n * offered was `queryDataItems`, so a detail worker had to fetch a bounded page and\n * find its row client-side:\n *\n * ```ts\n * const res = await queryDataItems(\"Listings\", 50); // ← DON'T\n * const row = (res.dataItems ?? []).find((it) => it.id === id);\n * ```\n *\n * That is correct against a handful of seeded rows and silently wrong once the\n * collection outgrows `limit`. Ask for the row instead:\n *\n * ```ts\n * const { dataItem } = await getDataItem(\"Listings\", id); // ← DO\n * ```\n *\n * The collection id rides the query string rather than a body, because the Wix\n * gateway drops a GET body — and the string is built with `encodeURIComponent`\n * rather than `URLSearchParams`, which the bare Tier-5 worker runtimes (JSCore /\n * Hermes / QuickJS-ng) do not provide. */",
|
|
10537
|
+
"decl": "export function getDataItem(\n dataCollectionId: string,\n dataItemId: string,\n): Promise<{ dataItem?: WixDataItem }>;",
|
|
10538
|
+
"http": "GET /wix-data/v2/items/{…}?dataCollectionId={…}"
|
|
10539
|
+
},
|
|
10531
10540
|
{
|
|
10532
10541
|
"name": "insertDataItem",
|
|
10533
10542
|
"kind": "function",
|
|
@@ -19013,91 +19022,106 @@
|
|
|
19013
19022
|
"name": "MuteStatus",
|
|
19014
19023
|
"kind": "type",
|
|
19015
19024
|
"jsdoc": "/** \"MUTED\" silences the topic on this channel; \"UNMUTED\" delivers it. */",
|
|
19016
|
-
"decl": "export type MuteStatus = \"MUTED\" | \"UNMUTED\";"
|
|
19025
|
+
"decl": "export type MuteStatus = \"MUTED\" | \"UNMUTED\";",
|
|
19026
|
+
"verified": false
|
|
19017
19027
|
},
|
|
19018
19028
|
{
|
|
19019
19029
|
"name": "Channel",
|
|
19020
19030
|
"kind": "type",
|
|
19021
19031
|
"jsdoc": "/** Delivery channel. The mobile push channel value is unconfirmed; \"MOBILE\" is\n * the working default the bundle passes. */",
|
|
19022
|
-
"decl": "export type Channel = \"MOBILE\" | string;"
|
|
19032
|
+
"decl": "export type Channel = \"MOBILE\" | string;",
|
|
19033
|
+
"verified": false
|
|
19023
19034
|
},
|
|
19024
19035
|
{
|
|
19025
19036
|
"name": "PreferenceState",
|
|
19026
19037
|
"kind": "interface",
|
|
19027
19038
|
"jsdoc": "",
|
|
19028
|
-
"decl": "export interface PreferenceState {\n /** \"MUTED\" | \"UNMUTED\" — whether the topic is delivered on this channel. */\n muteStatus?: MuteStatus;\n}"
|
|
19039
|
+
"decl": "export interface PreferenceState {\n /** \"MUTED\" | \"UNMUTED\" — whether the topic is delivered on this channel. */\n muteStatus?: MuteStatus;\n}",
|
|
19040
|
+
"verified": false
|
|
19029
19041
|
},
|
|
19030
19042
|
{
|
|
19031
19043
|
"name": "PreferenceStateData",
|
|
19032
19044
|
"kind": "interface",
|
|
19033
19045
|
"jsdoc": "",
|
|
19034
|
-
"decl": "export interface PreferenceStateData {\n state?: PreferenceState;\n}"
|
|
19046
|
+
"decl": "export interface PreferenceStateData {\n state?: PreferenceState;\n}",
|
|
19047
|
+
"verified": false
|
|
19035
19048
|
},
|
|
19036
19049
|
{
|
|
19037
19050
|
"name": "PreferenceInfo",
|
|
19038
19051
|
"kind": "interface",
|
|
19039
19052
|
"jsdoc": "/** One topic×channel preference for the implicit recipient. */",
|
|
19040
|
-
"decl": "export interface PreferenceInfo {\n /** The notification topic id (matches NotificationTopic.id). */\n topicId: string;\n /** Delivery channel this preference applies to (e.g. \"MOBILE\"). */\n channel?: Channel;\n stateData?: PreferenceStateData;\n}"
|
|
19053
|
+
"decl": "export interface PreferenceInfo {\n /** The notification topic id (matches NotificationTopic.id). */\n topicId: string;\n /** Delivery channel this preference applies to (e.g. \"MOBILE\"). */\n channel?: Channel;\n stateData?: PreferenceStateData;\n}",
|
|
19054
|
+
"verified": false
|
|
19041
19055
|
},
|
|
19042
19056
|
{
|
|
19043
19057
|
"name": "NotificationPreferences",
|
|
19044
19058
|
"kind": "interface",
|
|
19045
19059
|
"jsdoc": "",
|
|
19046
|
-
"decl": "export interface NotificationPreferences {\n preferencesInfo?: PreferenceInfo[];\n}"
|
|
19060
|
+
"decl": "export interface NotificationPreferences {\n preferencesInfo?: PreferenceInfo[];\n}",
|
|
19061
|
+
"verified": false
|
|
19047
19062
|
},
|
|
19048
19063
|
{
|
|
19049
19064
|
"name": "GetMyNotificationPreferencesResponse",
|
|
19050
19065
|
"kind": "interface",
|
|
19051
19066
|
"jsdoc": "",
|
|
19052
|
-
"decl": "export interface GetMyNotificationPreferencesResponse {\n preferences?: NotificationPreferences;\n}"
|
|
19067
|
+
"decl": "export interface GetMyNotificationPreferencesResponse {\n preferences?: NotificationPreferences;\n}",
|
|
19068
|
+
"verified": false
|
|
19053
19069
|
},
|
|
19054
19070
|
{
|
|
19055
19071
|
"name": "NotificationTopic",
|
|
19056
19072
|
"kind": "interface",
|
|
19057
19073
|
"jsdoc": "/** A notification topic — its id is the PreferenceInfo.topicId; displayName is\n * the row label shown in the UI. */",
|
|
19058
|
-
"decl": "export interface NotificationTopic {\n id: string;\n displayName?: string;\n}"
|
|
19074
|
+
"decl": "export interface NotificationTopic {\n id: string;\n displayName?: string;\n}",
|
|
19075
|
+
"verified": false
|
|
19059
19076
|
},
|
|
19060
19077
|
{
|
|
19061
19078
|
"name": "GetNotificationTopicsResponse",
|
|
19062
19079
|
"kind": "interface",
|
|
19063
19080
|
"jsdoc": "",
|
|
19064
|
-
"decl": "export interface GetNotificationTopicsResponse {\n topics?: NotificationTopic[];\n}"
|
|
19081
|
+
"decl": "export interface GetNotificationTopicsResponse {\n topics?: NotificationTopic[];\n}",
|
|
19082
|
+
"verified": false
|
|
19065
19083
|
},
|
|
19066
19084
|
{
|
|
19067
19085
|
"name": "UpsertMyNotificationPreferencesRequest",
|
|
19068
19086
|
"kind": "interface",
|
|
19069
19087
|
"jsdoc": "",
|
|
19070
|
-
"decl": "export interface UpsertMyNotificationPreferencesRequest {\n preferencesInfo: PreferenceInfo[];\n}"
|
|
19088
|
+
"decl": "export interface UpsertMyNotificationPreferencesRequest {\n preferencesInfo: PreferenceInfo[];\n}",
|
|
19089
|
+
"verified": false
|
|
19071
19090
|
},
|
|
19072
19091
|
{
|
|
19073
19092
|
"name": "UpsertMyNotificationPreferencesResponse",
|
|
19074
19093
|
"kind": "interface",
|
|
19075
19094
|
"jsdoc": "",
|
|
19076
|
-
"decl": "export interface UpsertMyNotificationPreferencesResponse {\n preferences?: NotificationPreferences;\n}"
|
|
19095
|
+
"decl": "export interface UpsertMyNotificationPreferencesResponse {\n preferences?: NotificationPreferences;\n}",
|
|
19096
|
+
"verified": false
|
|
19077
19097
|
},
|
|
19078
19098
|
{
|
|
19079
19099
|
"name": "muteStatusFor",
|
|
19080
19100
|
"kind": "function",
|
|
19081
19101
|
"jsdoc": "/** Map a UI \"on\" boolean to a MuteStatus: on ⇒ delivered (\"UNMUTED\"). */",
|
|
19082
|
-
"decl": "export function muteStatusFor(on: boolean): MuteStatus;"
|
|
19102
|
+
"decl": "export function muteStatusFor(on: boolean): MuteStatus;",
|
|
19103
|
+
"verified": false
|
|
19083
19104
|
},
|
|
19084
19105
|
{
|
|
19085
19106
|
"name": "getMyNotificationPreferences",
|
|
19086
19107
|
"kind": "function",
|
|
19087
19108
|
"jsdoc": "/** Get the signed-in member's notification preferences —\n * GET /notifications/v1/preferences-by-implicit-recipient. */",
|
|
19088
|
-
"decl": "export function getMyNotificationPreferences(): Promise<GetMyNotificationPreferencesResponse>;"
|
|
19109
|
+
"decl": "export function getMyNotificationPreferences(): Promise<GetMyNotificationPreferencesResponse>;",
|
|
19110
|
+
"verified": false
|
|
19089
19111
|
},
|
|
19090
19112
|
{
|
|
19091
19113
|
"name": "getNotificationTopics",
|
|
19092
19114
|
"kind": "function",
|
|
19093
19115
|
"jsdoc": "/** List the available notification topics (id + displayName for labels) —\n * GET /notifications/v1/preferences/topics. */",
|
|
19094
|
-
"decl": "export function getNotificationTopics(): Promise<GetNotificationTopicsResponse>;"
|
|
19116
|
+
"decl": "export function getNotificationTopics(): Promise<GetNotificationTopicsResponse>;",
|
|
19117
|
+
"verified": false
|
|
19095
19118
|
},
|
|
19096
19119
|
{
|
|
19097
19120
|
"name": "upsertMyNotificationPreferences",
|
|
19098
19121
|
"kind": "function",
|
|
19099
19122
|
"jsdoc": "/** Upsert one or more of the signed-in member's preferences —\n * POST /notifications/v1/preferences-by-implicit-recipient, body\n * { preferencesInfo }. Pass only the rows that changed. */",
|
|
19100
|
-
"decl": "export function upsertMyNotificationPreferences(\n preferencesInfo: PreferenceInfo[]\n): Promise<UpsertMyNotificationPreferencesResponse>;"
|
|
19123
|
+
"decl": "export function upsertMyNotificationPreferences(\n preferencesInfo: PreferenceInfo[]\n): Promise<UpsertMyNotificationPreferencesResponse>;",
|
|
19124
|
+
"verified": false
|
|
19101
19125
|
}
|
|
19102
19126
|
]
|
|
19103
19127
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/himalaya-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.943.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "himi — the Himalaya authoring CLI. Build a Tier-5 content package on your own machine, push it to the production serve as a draft, preview it on web + Himi Player, and read worker logs back — the remote dev loop. Wraps @himalaya/serve-cli for transport.",
|
|
6
6
|
"keywords": [
|
|
@@ -64,5 +64,5 @@
|
|
|
64
64
|
"artifactId": "himalaya-cli"
|
|
65
65
|
}
|
|
66
66
|
},
|
|
67
|
-
"falconPackageHash": "
|
|
67
|
+
"falconPackageHash": "20d4d02bfd992d1556a2c7e77e8eae63a7b4ec23e7c9e082ff43e951"
|
|
68
68
|
}
|
|
@@ -11,7 +11,12 @@ import {
|
|
|
11
11
|
} from "@himalaya/wix-stores-collections";
|
|
12
12
|
|
|
13
13
|
interface Row { id: string; name: string; subtitle: string }
|
|
14
|
-
interface S {
|
|
14
|
+
interface S {
|
|
15
|
+
status: "loading" | "ready" | "error";
|
|
16
|
+
collections: Row[];
|
|
17
|
+
emptyText: string;
|
|
18
|
+
error: string;
|
|
19
|
+
}
|
|
15
20
|
|
|
16
21
|
function fromCategory(c: StoreCategory): Row {
|
|
17
22
|
return { id: c.id || "", name: c.name || "Category", subtitle: categoryCount(c) };
|
|
@@ -23,26 +28,69 @@ function fromCollection(c: WixCollection): Row {
|
|
|
23
28
|
return { id: cc.id || cc.name || "collection", name: cc.name || "Collection", subtitle: n != null ? `${n} ${n === 1 ? "product" : "products"}` : "" };
|
|
24
29
|
}
|
|
25
30
|
|
|
26
|
-
|
|
31
|
+
type Loaded = { ok: true; rows: Row[] } | { ok: false; error: string };
|
|
32
|
+
|
|
33
|
+
async function loadCollections(): Promise<Loaded> {
|
|
27
34
|
try {
|
|
28
35
|
const r = await queryStoreCategories(50);
|
|
29
|
-
|
|
30
|
-
if (rows.length) return rows
|
|
31
|
-
|
|
36
|
+
// A V3 SUCCESS with zero rows is an empty catalogue, not a reason to try V1, and this is the
|
|
37
|
+
// line that matters. Written as `if (rows.length) return rows`, a modern (stores-v3) site
|
|
38
|
+
// that simply has no categories fell through to the V1 call — which `himi sdk
|
|
39
|
+
// wix-stores-collections` documents as answering HTTP 428 on exactly those sites — and the
|
|
40
|
+
// catch below turned that 428 into an empty list. The screen then told the visitor "No
|
|
41
|
+
// categories yet" over a dead endpoint.
|
|
42
|
+
//
|
|
43
|
+
// Only a V3 THROW earns the fallback, because a legacy V1-catalogue site is the single case
|
|
44
|
+
// the fallback exists for.
|
|
45
|
+
//
|
|
46
|
+
// WHAT IS ESTABLISHED vs WHAT IS ASSUMED, because the two are not the same here and a
|
|
47
|
+
// reviewer was right to ask. Established: V1-on-V3 answers HTTP 428 — `himi sdk
|
|
48
|
+
// wix-stores-collections` documents it and names the message. ASSUMED, and not yet
|
|
49
|
+
// verified against a live legacy site: that the reverse — the V3 Categories API, a separate
|
|
50
|
+
// app-namespaced service, called on a Catalog-V1 site — THROWS rather than answering
|
|
51
|
+
// `200 {}`. If it answers 200-empty, a legacy site stops reaching the fallback and shows
|
|
52
|
+
// "No categories yet" instead of its collections: the same wrong-empty-state this change
|
|
53
|
+
// fixes, moved to the other site type.
|
|
54
|
+
//
|
|
55
|
+
// It is left as a throw-only fallback deliberately, because the alternative is worse:
|
|
56
|
+
// falling back on a V3 empty result sends every modern site with a genuinely empty
|
|
57
|
+
// catalogue into the 428 path, and the catch below now surfaces that as "Couldn't load
|
|
58
|
+
// categories" over a catalogue that is simply empty. Confirm against a Catalog-V1 site
|
|
59
|
+
// before changing this; five templates carry this file.
|
|
60
|
+
return { ok: true, rows: (r.categories ?? []).map(fromCategory).filter((row) => row.id) };
|
|
61
|
+
} catch { /* V3 unavailable — a legacy V1 site is what the fallback is for */ }
|
|
32
62
|
try {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
63
|
+
// No `as never` here: `WixQueryCollectionsRequest.query` is `WixCollectionsQuery`, which
|
|
64
|
+
// declares `paging`, so this argument type-checks as written. Reach for a cast only when the
|
|
65
|
+
// types really cannot express the call — silencing them by habit hides the next real
|
|
66
|
+
// mismatch.
|
|
67
|
+
const r = await queryCollections({ query: { paging: { limit: 50 } } });
|
|
68
|
+
return { ok: true, rows: (((r as unknown as { collections?: WixCollection[] }).collections) ?? []).map(fromCollection) };
|
|
69
|
+
} catch (e) {
|
|
70
|
+
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
37
71
|
}
|
|
38
72
|
}
|
|
39
73
|
|
|
40
74
|
const svc = defineService<S, { load: (s: S) => Promise<S> }>("spacesCollections", {
|
|
41
|
-
state: { status: "loading", collections: [], emptyText: "" },
|
|
75
|
+
state: { status: "loading", collections: [], emptyText: "", error: "" },
|
|
42
76
|
actions: {
|
|
43
77
|
load: async () => {
|
|
44
|
-
const
|
|
45
|
-
|
|
78
|
+
const res = await loadCollections();
|
|
79
|
+
if (!res.ok) {
|
|
80
|
+
// `emptyText` carries the honest line as well as `error`, deliberately: this screen's
|
|
81
|
+
// descriptor binds only `emptyText`, so writing the failure there is what stops the
|
|
82
|
+
// visitor being told the catalogue is empty when the call actually failed. `status` and
|
|
83
|
+
// `error` are what an error-state binding and `himi test` read — bind them when you add
|
|
84
|
+
// a dedicated error view.
|
|
85
|
+
const line = "Couldn't load categories. Pull to refresh.";
|
|
86
|
+
return { status: "error", collections: [], emptyText: line, error: res.error };
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
status: "ready",
|
|
90
|
+
collections: res.rows,
|
|
91
|
+
emptyText: res.rows.length ? "" : "No categories yet",
|
|
92
|
+
error: "",
|
|
93
|
+
};
|
|
46
94
|
},
|
|
47
95
|
},
|
|
48
96
|
});
|