@01.software/sdk 0.33.0 → 0.35.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/README.md +214 -22
- package/dist/analytics/react.cjs.map +1 -1
- package/dist/analytics/react.js.map +1 -1
- package/dist/analytics.cjs.map +1 -1
- package/dist/analytics.js.map +1 -1
- package/dist/client.cjs +342 -27
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +7 -6
- package/dist/client.d.ts +7 -6
- package/dist/client.js +342 -27
- package/dist/client.js.map +1 -1
- package/dist/{collection-client-De6eKW1J.d.cts → collection-client-CR2B8c1v.d.cts} +7 -3
- package/dist/{collection-client-B6SlhzIP.d.ts → collection-client-DkREjhQ9.d.ts} +7 -3
- package/dist/{const-sPR2IkCe.d.cts → const-BTvdrXtY.d.cts} +4 -4
- package/dist/{const-DwmSDeWq.d.ts → const-CdqCauHQ.d.ts} +4 -4
- package/dist/errors.cjs +300 -0
- package/dist/errors.cjs.map +1 -0
- package/dist/{index-BGEhoDUs.d.cts → errors.d.cts} +13 -1
- package/dist/{index-BGEhoDUs.d.ts → errors.d.ts} +13 -1
- package/dist/errors.js +277 -0
- package/dist/errors.js.map +1 -0
- package/dist/index-CjA3U6X3.d.cts +186 -0
- package/dist/index-DK8_NXkh.d.ts +186 -0
- package/dist/index.cjs +1402 -177
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +75 -10
- package/dist/index.d.ts +75 -10
- package/dist/index.js +1402 -177
- package/dist/index.js.map +1 -1
- package/dist/{payload-types-dkeQyrDC.d.cts → payload-types-C7tb7Xbs.d.cts} +208 -52
- package/dist/{payload-types-dkeQyrDC.d.ts → payload-types-C7tb7Xbs.d.ts} +208 -52
- package/dist/query.cjs +195 -36
- package/dist/query.cjs.map +1 -1
- package/dist/query.d.cts +45 -18
- package/dist/query.d.ts +45 -18
- package/dist/query.js +195 -36
- package/dist/query.js.map +1 -1
- package/dist/realtime.cjs.map +1 -1
- package/dist/realtime.d.cts +2 -2
- package/dist/realtime.d.ts +2 -2
- package/dist/realtime.js.map +1 -1
- package/dist/{server-CrsPyqEc.d.cts → server-nXOezi4b.d.cts} +22 -6
- package/dist/{server-CrsPyqEc.d.ts → server-nXOezi4b.d.ts} +22 -6
- package/dist/server.cjs +440 -33
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +11 -179
- package/dist/server.d.ts +11 -179
- package/dist/server.js +440 -33
- package/dist/server.js.map +1 -1
- package/dist/{types-Cel_4L9t.d.ts → types-1ylMrCuW.d.ts} +1 -1
- package/dist/{types-B3YT092I.d.cts → types-Bx558PU6.d.cts} +1 -1
- package/dist/{types-BHh0YLmq.d.ts → types-Byo_Rty4.d.ts} +705 -69
- package/dist/{types-BZKxss8Y.d.cts → types-DDhtZI6E.d.cts} +705 -69
- package/dist/ui/canvas/server.cjs +231 -38
- package/dist/ui/canvas/server.cjs.map +1 -1
- package/dist/ui/canvas/server.d.cts +1 -1
- package/dist/ui/canvas/server.d.ts +1 -1
- package/dist/ui/canvas/server.js +221 -38
- package/dist/ui/canvas/server.js.map +1 -1
- package/dist/ui/canvas.cjs +320 -257
- package/dist/ui/canvas.cjs.map +1 -1
- package/dist/ui/canvas.d.cts +5 -19
- package/dist/ui/canvas.d.ts +5 -19
- package/dist/ui/canvas.js +323 -260
- package/dist/ui/canvas.js.map +1 -1
- package/dist/ui/form.d.cts +1 -1
- package/dist/ui/form.d.ts +1 -1
- package/dist/ui/video.d.cts +1 -1
- package/dist/ui/video.d.ts +1 -1
- package/dist/webhook.cjs +2 -1
- package/dist/webhook.cjs.map +1 -1
- package/dist/webhook.d.cts +20 -179
- package/dist/webhook.d.ts +20 -179
- package/dist/webhook.js +2 -1
- package/dist/webhook.js.map +1 -1
- package/package.json +12 -3
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/core/collection/http-client.ts
|
|
2
2
|
import { stringify } from "qs-esm";
|
|
3
3
|
|
|
4
|
-
// src/core/
|
|
4
|
+
// src/core/errors.ts
|
|
5
5
|
var SDKError = class extends Error {
|
|
6
6
|
constructor(code, message, status, details, userMessage, suggestion, requestId) {
|
|
7
7
|
super(message);
|
|
@@ -253,9 +253,12 @@ function resolveApiUrl(apiUrl) {
|
|
|
253
253
|
|
|
254
254
|
// src/core/internal/utils/http.ts
|
|
255
255
|
var DEFAULT_TIMEOUT = 3e4;
|
|
256
|
+
var STOREFRONT_BROWSER_TIMEOUT = 15e3;
|
|
256
257
|
var DEFAULT_RETRYABLE_STATUSES = [408, 429, 500, 502, 503, 504];
|
|
257
258
|
var NON_RETRYABLE_STATUSES = [400, 401, 403, 404, 409, 422];
|
|
258
259
|
var SAFE_METHODS = ["GET", "HEAD", "OPTIONS"];
|
|
260
|
+
var DEFAULT_MAX_RETRIES = 3;
|
|
261
|
+
var STOREFRONT_BROWSER_MAX_RETRIES = 1;
|
|
259
262
|
function debugLog(debug, type, message, data) {
|
|
260
263
|
if (!debug) return;
|
|
261
264
|
const shouldLog = debug === true || type === "request" && debug.logRequests || type === "response" && debug.logResponses || type === "error" && debug.logErrors;
|
|
@@ -448,15 +451,18 @@ async function httpFetch(url, options) {
|
|
|
448
451
|
publishableKey,
|
|
449
452
|
secretKey,
|
|
450
453
|
customerToken,
|
|
451
|
-
timeout = DEFAULT_TIMEOUT,
|
|
454
|
+
timeout: timeoutOption = DEFAULT_TIMEOUT,
|
|
452
455
|
debug,
|
|
453
456
|
retry,
|
|
454
457
|
onUnauthorized,
|
|
455
458
|
...requestInit
|
|
456
459
|
} = options || {};
|
|
457
460
|
const baseUrl = resolveApiUrl(apiUrl);
|
|
461
|
+
const method = (requestInit.method || "GET").toUpperCase();
|
|
462
|
+
const isPublishableKeyBrowserGet = typeof window !== "undefined" && !secretKey && !customerToken && Boolean(publishableKey) && SAFE_METHODS.includes(method);
|
|
463
|
+
const timeout = timeoutOption === DEFAULT_TIMEOUT && isPublishableKeyBrowserGet ? STOREFRONT_BROWSER_TIMEOUT : timeoutOption;
|
|
458
464
|
const retryConfig = {
|
|
459
|
-
maxRetries: retry?.maxRetries ??
|
|
465
|
+
maxRetries: retry?.maxRetries ?? (isPublishableKeyBrowserGet ? STOREFRONT_BROWSER_MAX_RETRIES : DEFAULT_MAX_RETRIES),
|
|
460
466
|
retryableStatuses: retry?.retryableStatuses ?? DEFAULT_RETRYABLE_STATUSES,
|
|
461
467
|
retryDelay: retry?.retryDelay ?? ((attempt) => Math.min(1e3 * 2 ** attempt, 1e4))
|
|
462
468
|
};
|
|
@@ -564,8 +570,8 @@ async function httpFetch(url, options) {
|
|
|
564
570
|
),
|
|
565
571
|
requestId
|
|
566
572
|
);
|
|
567
|
-
const
|
|
568
|
-
if (attempt < retryConfig.maxRetries && SAFE_METHODS.includes(
|
|
573
|
+
const method2 = (requestInit.method || "GET").toUpperCase();
|
|
574
|
+
if (attempt < retryConfig.maxRetries && SAFE_METHODS.includes(method2) && retryConfig.retryableStatuses.includes(response.status)) {
|
|
569
575
|
lastError = error;
|
|
570
576
|
const retryDelay = retryConfig.retryDelay(attempt);
|
|
571
577
|
debugLog(debug, "error", `Retrying in ${retryDelay}ms...`, error);
|
|
@@ -577,8 +583,8 @@ async function httpFetch(url, options) {
|
|
|
577
583
|
return response;
|
|
578
584
|
} catch (error) {
|
|
579
585
|
debugLog(debug, "error", url, error);
|
|
580
|
-
const
|
|
581
|
-
const isSafe = SAFE_METHODS.includes(
|
|
586
|
+
const method2 = (requestInit.method || "GET").toUpperCase();
|
|
587
|
+
const isSafe = SAFE_METHODS.includes(method2);
|
|
582
588
|
if (error instanceof Error && error.name === "AbortError") {
|
|
583
589
|
const timeoutError = createTimeoutError(
|
|
584
590
|
`Request timed out after ${timeout}ms.`,
|
|
@@ -637,6 +643,35 @@ async function httpFetch(url, options) {
|
|
|
637
643
|
throw lastError ?? new NetworkError("Request failed after retries");
|
|
638
644
|
}
|
|
639
645
|
|
|
646
|
+
// src/core/internal/utils/query-string.ts
|
|
647
|
+
function productDetailQuery(params) {
|
|
648
|
+
const search = new URLSearchParams();
|
|
649
|
+
if ("slug" in params) {
|
|
650
|
+
search.set("slug", params.slug);
|
|
651
|
+
} else {
|
|
652
|
+
search.set("id", params.id);
|
|
653
|
+
}
|
|
654
|
+
return `/api/products/detail?${search}`;
|
|
655
|
+
}
|
|
656
|
+
function productDetailCatalogQuery(params) {
|
|
657
|
+
const search = new URLSearchParams();
|
|
658
|
+
if ("slug" in params) {
|
|
659
|
+
search.set("slug", params.slug);
|
|
660
|
+
} else {
|
|
661
|
+
search.set("id", params.id);
|
|
662
|
+
}
|
|
663
|
+
return `/api/products/detail/catalog?${search}`;
|
|
664
|
+
}
|
|
665
|
+
function listingGroupsQuery(params) {
|
|
666
|
+
return `/api/products/listing-groups?ids=${params.productIds.map(encodeURIComponent).join(",")}`;
|
|
667
|
+
}
|
|
668
|
+
function listingGroupsCatalogQuery(params) {
|
|
669
|
+
return `/api/products/listing-groups/catalog?ids=${params.productIds.map(encodeURIComponent).join(",")}`;
|
|
670
|
+
}
|
|
671
|
+
function stockSnapshotQuery(params) {
|
|
672
|
+
return `/api/products/stock?variantIds=${params.variantIds.map(encodeURIComponent).join(",")}`;
|
|
673
|
+
}
|
|
674
|
+
|
|
640
675
|
// src/core/collection/http-client.ts
|
|
641
676
|
var HttpClient = class {
|
|
642
677
|
constructor(publishableKey, secretKey, getCustomerToken, onUnauthorized, onRequestId, apiUrl) {
|
|
@@ -955,6 +990,8 @@ async function parseApiResponse(response, endpoint) {
|
|
|
955
990
|
}
|
|
956
991
|
|
|
957
992
|
// src/core/community/community-client.ts
|
|
993
|
+
var DEFAULT_POST_LIST_SORT = "-lastActivityAt";
|
|
994
|
+
var DEFAULT_COMMENT_LIST_SORT = "-createdAt";
|
|
958
995
|
var CommunityClient = class {
|
|
959
996
|
constructor(options) {
|
|
960
997
|
this.publishableKey = requirePublishableKeyForSecret(
|
|
@@ -973,6 +1010,40 @@ var CommunityClient = class {
|
|
|
973
1010
|
const entries = Object.entries(params).filter((e) => e[1] !== void 0).map(([k, v]) => [k, String(v)]);
|
|
974
1011
|
return entries.length ? `?${new URLSearchParams(entries).toString()}` : "";
|
|
975
1012
|
}
|
|
1013
|
+
buildPostsListQuery(params) {
|
|
1014
|
+
const urlParams = new URLSearchParams();
|
|
1015
|
+
const sort = params?.sort ?? DEFAULT_POST_LIST_SORT;
|
|
1016
|
+
urlParams.set("sort", sort);
|
|
1017
|
+
if (params?.limit !== void 0) urlParams.set("limit", String(params.limit));
|
|
1018
|
+
if (params?.page !== void 0) urlParams.set("page", String(params.page));
|
|
1019
|
+
if (params?.categoryId !== void 0) {
|
|
1020
|
+
urlParams.set("where[categories][in]", params.categoryId);
|
|
1021
|
+
}
|
|
1022
|
+
if (params?.tagId !== void 0) {
|
|
1023
|
+
urlParams.set("where[tags][in]", params.tagId);
|
|
1024
|
+
}
|
|
1025
|
+
return `/api/posts?${urlParams.toString()}`;
|
|
1026
|
+
}
|
|
1027
|
+
buildCommentsListQuery(params) {
|
|
1028
|
+
const urlParams = new URLSearchParams();
|
|
1029
|
+
const sort = params.sort ?? DEFAULT_COMMENT_LIST_SORT;
|
|
1030
|
+
urlParams.set("sort", sort);
|
|
1031
|
+
if (params.postId !== void 0) {
|
|
1032
|
+
urlParams.set("where[post][equals]", params.postId);
|
|
1033
|
+
}
|
|
1034
|
+
if (params.parentId !== void 0) {
|
|
1035
|
+
urlParams.set("where[parent][equals]", params.parentId);
|
|
1036
|
+
}
|
|
1037
|
+
if (params.rootComment !== void 0) {
|
|
1038
|
+
urlParams.set("where[rootComment][equals]", params.rootComment);
|
|
1039
|
+
}
|
|
1040
|
+
if (params.topLevelOnly) {
|
|
1041
|
+
urlParams.set("where[parent][exists]", "false");
|
|
1042
|
+
}
|
|
1043
|
+
if (params.limit !== void 0) urlParams.set("limit", String(params.limit));
|
|
1044
|
+
if (params.page !== void 0) urlParams.set("page", String(params.page));
|
|
1045
|
+
return `/api/comments?${urlParams.toString()}`;
|
|
1046
|
+
}
|
|
976
1047
|
async execute(endpoint, method, body) {
|
|
977
1048
|
const token = typeof this.customerToken === "function" ? this.customerToken() : this.customerToken;
|
|
978
1049
|
try {
|
|
@@ -996,6 +1067,28 @@ var CommunityClient = class {
|
|
|
996
1067
|
createPost(params) {
|
|
997
1068
|
return this.execute("/api/posts", "POST", params);
|
|
998
1069
|
}
|
|
1070
|
+
/**
|
|
1071
|
+
* Public post feed. Server applies the same visibility contract as
|
|
1072
|
+
* `communityPostRead` (published + visible + moderation-safe).
|
|
1073
|
+
*/
|
|
1074
|
+
listPosts(params) {
|
|
1075
|
+
return this.execute(
|
|
1076
|
+
this.buildPostsListQuery(params),
|
|
1077
|
+
"GET"
|
|
1078
|
+
);
|
|
1079
|
+
}
|
|
1080
|
+
listPostCategories(params) {
|
|
1081
|
+
return this.execute(
|
|
1082
|
+
`/api/post-categories${this.buildQuery(params)}`,
|
|
1083
|
+
"GET"
|
|
1084
|
+
);
|
|
1085
|
+
}
|
|
1086
|
+
listPostTags(params) {
|
|
1087
|
+
return this.execute(
|
|
1088
|
+
`/api/post-tags${this.buildQuery(params)}`,
|
|
1089
|
+
"GET"
|
|
1090
|
+
);
|
|
1091
|
+
}
|
|
999
1092
|
getMyPosts(params) {
|
|
1000
1093
|
return this.execute(
|
|
1001
1094
|
`/api/posts/my${this.buildQuery(params)}`,
|
|
@@ -1031,16 +1124,37 @@ var CommunityClient = class {
|
|
|
1031
1124
|
}
|
|
1032
1125
|
return this.execute("/api/comments", "POST", body);
|
|
1033
1126
|
}
|
|
1127
|
+
/**
|
|
1128
|
+
* List comments for a post.
|
|
1129
|
+
*
|
|
1130
|
+
* - Default: all visible comments on the post (any depth).
|
|
1131
|
+
* - `topLevelOnly: true`: only root comments (`parent` unset).
|
|
1132
|
+
* - `rootComment`: comments belonging to a thread rooted at that comment.
|
|
1133
|
+
*/
|
|
1034
1134
|
listComments(params) {
|
|
1035
|
-
const { postId, page, limit, rootComment } = params;
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1135
|
+
const { postId, page, limit, rootComment, topLevelOnly, sort } = params;
|
|
1136
|
+
return this.execute(
|
|
1137
|
+
this.buildCommentsListQuery({
|
|
1138
|
+
postId,
|
|
1139
|
+
page,
|
|
1140
|
+
limit,
|
|
1141
|
+
rootComment,
|
|
1142
|
+
topLevelOnly,
|
|
1143
|
+
sort
|
|
1144
|
+
}),
|
|
1145
|
+
"GET"
|
|
1146
|
+
);
|
|
1147
|
+
}
|
|
1148
|
+
/** Direct replies to a comment (`where[parent][equals]`). */
|
|
1149
|
+
listReplies(params) {
|
|
1150
|
+
const { commentId, page, limit, sort } = params;
|
|
1042
1151
|
return this.execute(
|
|
1043
|
-
|
|
1152
|
+
this.buildCommentsListQuery({
|
|
1153
|
+
parentId: commentId,
|
|
1154
|
+
page,
|
|
1155
|
+
limit,
|
|
1156
|
+
sort
|
|
1157
|
+
}),
|
|
1044
1158
|
"GET"
|
|
1045
1159
|
);
|
|
1046
1160
|
}
|
|
@@ -1068,10 +1182,18 @@ var CommunityClient = class {
|
|
|
1068
1182
|
}
|
|
1069
1183
|
// Reactions
|
|
1070
1184
|
addReaction(params) {
|
|
1071
|
-
const { postId, type } = params;
|
|
1185
|
+
const { postId, typeSlug, type } = params;
|
|
1186
|
+
const reactionType = typeSlug ?? type;
|
|
1187
|
+
if (!reactionType) {
|
|
1188
|
+
throw new SDKError(
|
|
1189
|
+
"validation_failed",
|
|
1190
|
+
"addReaction requires typeSlug (or deprecated type)",
|
|
1191
|
+
400
|
|
1192
|
+
);
|
|
1193
|
+
}
|
|
1072
1194
|
return this.execute("/api/reactions", "POST", {
|
|
1073
1195
|
post: postId,
|
|
1074
|
-
type
|
|
1196
|
+
type: reactionType
|
|
1075
1197
|
});
|
|
1076
1198
|
}
|
|
1077
1199
|
removeReaction(params) {
|
|
@@ -1082,10 +1204,18 @@ var CommunityClient = class {
|
|
|
1082
1204
|
);
|
|
1083
1205
|
}
|
|
1084
1206
|
addCommentReaction(params) {
|
|
1085
|
-
const { commentId, type } = params;
|
|
1207
|
+
const { commentId, typeSlug, type } = params;
|
|
1208
|
+
const reactionType = typeSlug ?? type;
|
|
1209
|
+
if (!reactionType) {
|
|
1210
|
+
throw new SDKError(
|
|
1211
|
+
"validation_failed",
|
|
1212
|
+
"addCommentReaction requires typeSlug (or deprecated type)",
|
|
1213
|
+
400
|
|
1214
|
+
);
|
|
1215
|
+
}
|
|
1086
1216
|
return this.execute("/api/reactions", "POST", {
|
|
1087
1217
|
comment: commentId,
|
|
1088
|
-
type
|
|
1218
|
+
type: reactionType
|
|
1089
1219
|
});
|
|
1090
1220
|
}
|
|
1091
1221
|
removeCommentReaction(params) {
|
|
@@ -1101,6 +1231,12 @@ var CommunityClient = class {
|
|
|
1101
1231
|
"GET"
|
|
1102
1232
|
);
|
|
1103
1233
|
}
|
|
1234
|
+
getCommentReactionSummary(params) {
|
|
1235
|
+
return this.execute(
|
|
1236
|
+
`/api/comments/${params.commentId}/reactions`,
|
|
1237
|
+
"GET"
|
|
1238
|
+
);
|
|
1239
|
+
}
|
|
1104
1240
|
getReactionTypes() {
|
|
1105
1241
|
return this.execute(
|
|
1106
1242
|
"/api/reaction-types?limit=100",
|
|
@@ -1125,6 +1261,25 @@ var CommunityClient = class {
|
|
|
1125
1261
|
"GET"
|
|
1126
1262
|
);
|
|
1127
1263
|
}
|
|
1264
|
+
// Profiles
|
|
1265
|
+
listProfileLists(params) {
|
|
1266
|
+
return this.execute(
|
|
1267
|
+
`/api/customer-profile-lists${this.buildQuery(params)}`,
|
|
1268
|
+
"GET"
|
|
1269
|
+
);
|
|
1270
|
+
}
|
|
1271
|
+
async getProfileList(params) {
|
|
1272
|
+
const query = "slug" in params ? `?where[slug][equals]=${encodeURIComponent(params.slug)}&limit=1` : `?where[id][equals]=${encodeURIComponent(params.id)}&limit=1`;
|
|
1273
|
+
const res = await this.execute(`/api/customer-profile-lists${query}`, "GET");
|
|
1274
|
+
return res.docs[0] ?? null;
|
|
1275
|
+
}
|
|
1276
|
+
updatePublicProfile(body) {
|
|
1277
|
+
return this.execute(
|
|
1278
|
+
"/api/customers/me/profile",
|
|
1279
|
+
"PATCH",
|
|
1280
|
+
body
|
|
1281
|
+
);
|
|
1282
|
+
}
|
|
1128
1283
|
};
|
|
1129
1284
|
|
|
1130
1285
|
// src/core/customer/customer-auth.ts
|
|
@@ -1469,6 +1624,45 @@ function productDetailResultFromError(error) {
|
|
|
1469
1624
|
if (!reason) return void 0;
|
|
1470
1625
|
return { found: false, reason };
|
|
1471
1626
|
}
|
|
1627
|
+
function rejectLegacyOptionValueSwatchColor(value) {
|
|
1628
|
+
if (Object.prototype.hasOwnProperty.call(
|
|
1629
|
+
value,
|
|
1630
|
+
"swatchColor"
|
|
1631
|
+
)) {
|
|
1632
|
+
throw new TypeError(
|
|
1633
|
+
'Product upsert option values no longer accept legacy flat "swatchColor"; use nested "swatch" instead.'
|
|
1634
|
+
);
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
function normalizeProductUpsertOptionValue(value) {
|
|
1638
|
+
rejectLegacyOptionValueSwatchColor(value);
|
|
1639
|
+
return value;
|
|
1640
|
+
}
|
|
1641
|
+
function normalizeProductUpsertParams(params) {
|
|
1642
|
+
const options = params.options ?? [];
|
|
1643
|
+
const variants = params.variants ?? [];
|
|
1644
|
+
if (!options.length) {
|
|
1645
|
+
return { ...params, options, variants };
|
|
1646
|
+
}
|
|
1647
|
+
return {
|
|
1648
|
+
...params,
|
|
1649
|
+
options: options.map((option) => ({
|
|
1650
|
+
...option,
|
|
1651
|
+
values: option.values.map(
|
|
1652
|
+
(value) => normalizeProductUpsertOptionValue(value)
|
|
1653
|
+
)
|
|
1654
|
+
})),
|
|
1655
|
+
variants
|
|
1656
|
+
};
|
|
1657
|
+
}
|
|
1658
|
+
var PRODUCT_UPSERT_UNKNOWN_FIELD_REASON = "unknown_field";
|
|
1659
|
+
var PRODUCT_UPSERT_READONLY_FIELD_REASON = "product_field_readonly";
|
|
1660
|
+
function isProductUpsertFieldValidationErrorBody(value) {
|
|
1661
|
+
if (typeof value !== "object" || value === null) return false;
|
|
1662
|
+
const body = value;
|
|
1663
|
+
const reason = body.reason;
|
|
1664
|
+
return typeof body.error === "string" && typeof body.field === "string" && (reason === PRODUCT_UPSERT_UNKNOWN_FIELD_REASON || reason === PRODUCT_UPSERT_READONLY_FIELD_REASON);
|
|
1665
|
+
}
|
|
1472
1666
|
var ProductApi = class extends BaseApi {
|
|
1473
1667
|
constructor(options) {
|
|
1474
1668
|
super("ProductApi", options);
|
|
@@ -1481,10 +1675,25 @@ var ProductApi = class extends BaseApi {
|
|
|
1481
1675
|
stockCheck(params) {
|
|
1482
1676
|
return this.request("/api/products/stock-check", params);
|
|
1483
1677
|
}
|
|
1678
|
+
stockSnapshot(params) {
|
|
1679
|
+
return this.request(
|
|
1680
|
+
stockSnapshotQuery(params),
|
|
1681
|
+
void 0,
|
|
1682
|
+
{ method: "GET" }
|
|
1683
|
+
);
|
|
1684
|
+
}
|
|
1484
1685
|
listingGroups(params) {
|
|
1485
1686
|
return this.request(
|
|
1486
|
-
|
|
1487
|
-
|
|
1687
|
+
listingGroupsQuery(params),
|
|
1688
|
+
void 0,
|
|
1689
|
+
{ method: "GET" }
|
|
1690
|
+
);
|
|
1691
|
+
}
|
|
1692
|
+
listingGroupsCatalog(params) {
|
|
1693
|
+
return this.request(
|
|
1694
|
+
listingGroupsCatalogQuery(params),
|
|
1695
|
+
void 0,
|
|
1696
|
+
{ method: "GET" }
|
|
1488
1697
|
);
|
|
1489
1698
|
}
|
|
1490
1699
|
/**
|
|
@@ -1500,8 +1709,9 @@ var ProductApi = class extends BaseApi {
|
|
|
1500
1709
|
async detail(params) {
|
|
1501
1710
|
try {
|
|
1502
1711
|
const product = await this.request(
|
|
1503
|
-
|
|
1504
|
-
|
|
1712
|
+
productDetailQuery(params),
|
|
1713
|
+
void 0,
|
|
1714
|
+
{ method: "GET" }
|
|
1505
1715
|
);
|
|
1506
1716
|
return { found: true, product };
|
|
1507
1717
|
} catch (err) {
|
|
@@ -1510,6 +1720,20 @@ var ProductApi = class extends BaseApi {
|
|
|
1510
1720
|
throw err;
|
|
1511
1721
|
}
|
|
1512
1722
|
}
|
|
1723
|
+
async detailCatalog(params) {
|
|
1724
|
+
try {
|
|
1725
|
+
const product = await this.request(
|
|
1726
|
+
productDetailCatalogQuery(params),
|
|
1727
|
+
void 0,
|
|
1728
|
+
{ method: "GET" }
|
|
1729
|
+
);
|
|
1730
|
+
return { found: true, product };
|
|
1731
|
+
} catch (err) {
|
|
1732
|
+
const notFoundResult = productDetailResultFromError(err);
|
|
1733
|
+
if (notFoundResult?.found === false) return notFoundResult;
|
|
1734
|
+
throw err;
|
|
1735
|
+
}
|
|
1736
|
+
}
|
|
1513
1737
|
/**
|
|
1514
1738
|
* Atomically create or update a product together with its options,
|
|
1515
1739
|
* option-values, and variants in a single transaction. Mirrors Shopify's
|
|
@@ -1517,7 +1741,104 @@ var ProductApi = class extends BaseApi {
|
|
|
1517
1741
|
* `product-upsert` tool.
|
|
1518
1742
|
*/
|
|
1519
1743
|
upsert(params) {
|
|
1520
|
-
return this.request(
|
|
1744
|
+
return this.request(
|
|
1745
|
+
"/api/products/upsert",
|
|
1746
|
+
normalizeProductUpsertParams(params)
|
|
1747
|
+
);
|
|
1748
|
+
}
|
|
1749
|
+
};
|
|
1750
|
+
|
|
1751
|
+
// src/core/api/order-api.ts
|
|
1752
|
+
function idempotencyRequestOptions(idempotencyKey) {
|
|
1753
|
+
return idempotencyKey ? { headers: { "X-Idempotency-Key": idempotencyKey } } : void 0;
|
|
1754
|
+
}
|
|
1755
|
+
function splitIdempotencyKey(params) {
|
|
1756
|
+
const { idempotencyKey, ...body } = params;
|
|
1757
|
+
return { body, idempotencyKey };
|
|
1758
|
+
}
|
|
1759
|
+
var OrderApi = class extends BaseApi {
|
|
1760
|
+
constructor(options) {
|
|
1761
|
+
super("OrderApi", options);
|
|
1762
|
+
}
|
|
1763
|
+
createOrder(params) {
|
|
1764
|
+
const { body, idempotencyKey } = splitIdempotencyKey(params);
|
|
1765
|
+
return this.request(
|
|
1766
|
+
"/api/orders/create",
|
|
1767
|
+
body,
|
|
1768
|
+
idempotencyRequestOptions(idempotencyKey)
|
|
1769
|
+
);
|
|
1770
|
+
}
|
|
1771
|
+
updateOrder(params) {
|
|
1772
|
+
return this.request("/api/orders/update", params);
|
|
1773
|
+
}
|
|
1774
|
+
updateTransaction(params) {
|
|
1775
|
+
return this.request("/api/transactions/update", params);
|
|
1776
|
+
}
|
|
1777
|
+
confirmPayment(params) {
|
|
1778
|
+
const { body, idempotencyKey } = splitIdempotencyKey(params);
|
|
1779
|
+
const headerKey = idempotencyKey ?? params.providerEventId;
|
|
1780
|
+
return this.request(
|
|
1781
|
+
"/api/orders/confirm-payment",
|
|
1782
|
+
body,
|
|
1783
|
+
idempotencyRequestOptions(headerKey)
|
|
1784
|
+
);
|
|
1785
|
+
}
|
|
1786
|
+
cancelOrder(params) {
|
|
1787
|
+
const { idempotencyKey } = params;
|
|
1788
|
+
const body = {
|
|
1789
|
+
orderNumber: params.orderNumber,
|
|
1790
|
+
reasonCode: params.reasonCode,
|
|
1791
|
+
reasonDetail: params.reasonDetail
|
|
1792
|
+
};
|
|
1793
|
+
return this.request(
|
|
1794
|
+
"/api/orders/cancel",
|
|
1795
|
+
body,
|
|
1796
|
+
idempotencyKey ? { headers: { "X-Idempotency-Key": idempotencyKey } } : void 0
|
|
1797
|
+
);
|
|
1798
|
+
}
|
|
1799
|
+
checkout(params) {
|
|
1800
|
+
const { body, idempotencyKey } = splitIdempotencyKey(params);
|
|
1801
|
+
return this.request(
|
|
1802
|
+
"/api/orders/checkout",
|
|
1803
|
+
body,
|
|
1804
|
+
idempotencyRequestOptions(idempotencyKey)
|
|
1805
|
+
);
|
|
1806
|
+
}
|
|
1807
|
+
createFulfillment(params) {
|
|
1808
|
+
const { body, idempotencyKey } = splitIdempotencyKey(params);
|
|
1809
|
+
return this.request(
|
|
1810
|
+
"/api/orders/create-fulfillment",
|
|
1811
|
+
body,
|
|
1812
|
+
idempotencyRequestOptions(idempotencyKey)
|
|
1813
|
+
);
|
|
1814
|
+
}
|
|
1815
|
+
updateFulfillment(params) {
|
|
1816
|
+
return this.request("/api/orders/update-fulfillment", params);
|
|
1817
|
+
}
|
|
1818
|
+
bulkImportFulfillments(params) {
|
|
1819
|
+
return this.request(
|
|
1820
|
+
"/api/fulfillments/bulk-import",
|
|
1821
|
+
params
|
|
1822
|
+
);
|
|
1823
|
+
}
|
|
1824
|
+
returnWithRefund(params) {
|
|
1825
|
+
const { body, idempotencyKey } = splitIdempotencyKey(params);
|
|
1826
|
+
return this.request(
|
|
1827
|
+
"/api/returns/return-refund",
|
|
1828
|
+
body,
|
|
1829
|
+
idempotencyRequestOptions(idempotencyKey)
|
|
1830
|
+
);
|
|
1831
|
+
}
|
|
1832
|
+
createReturn(params) {
|
|
1833
|
+
const { body, idempotencyKey } = splitIdempotencyKey(params);
|
|
1834
|
+
return this.request(
|
|
1835
|
+
"/api/returns/create",
|
|
1836
|
+
body,
|
|
1837
|
+
idempotencyRequestOptions(idempotencyKey)
|
|
1838
|
+
);
|
|
1839
|
+
}
|
|
1840
|
+
updateReturn(params) {
|
|
1841
|
+
return this.request("/api/returns/update", params);
|
|
1521
1842
|
}
|
|
1522
1843
|
};
|
|
1523
1844
|
|
|
@@ -1531,7 +1852,7 @@ var CommerceClient = class {
|
|
|
1531
1852
|
onUnauthorized: options.onUnauthorized,
|
|
1532
1853
|
onRequestId: options.onRequestId
|
|
1533
1854
|
});
|
|
1534
|
-
const execute = async (endpoint, body) => {
|
|
1855
|
+
const execute = async (endpoint, body, requestOptions) => {
|
|
1535
1856
|
const token = options.customerToken();
|
|
1536
1857
|
try {
|
|
1537
1858
|
const response = await httpFetch(endpoint, {
|
|
@@ -1540,7 +1861,26 @@ var CommerceClient = class {
|
|
|
1540
1861
|
publishableKey: options.publishableKey,
|
|
1541
1862
|
customerToken: token ?? void 0,
|
|
1542
1863
|
...token && options.onUnauthorized && { onUnauthorized: options.onUnauthorized },
|
|
1543
|
-
body: JSON.stringify(body)
|
|
1864
|
+
body: JSON.stringify(body),
|
|
1865
|
+
...requestOptions?.headers && { headers: requestOptions.headers }
|
|
1866
|
+
});
|
|
1867
|
+
options.onRequestId?.(response.headers.get("x-request-id") ?? null);
|
|
1868
|
+
return parseApiResponse(response, endpoint);
|
|
1869
|
+
} catch (err) {
|
|
1870
|
+
const id = err instanceof SDKError ? err.requestId ?? null : null;
|
|
1871
|
+
options.onRequestId?.(id);
|
|
1872
|
+
throw err;
|
|
1873
|
+
}
|
|
1874
|
+
};
|
|
1875
|
+
const executeGet = async (endpoint) => {
|
|
1876
|
+
const token = options.customerToken();
|
|
1877
|
+
try {
|
|
1878
|
+
const response = await httpFetch(endpoint, {
|
|
1879
|
+
method: "GET",
|
|
1880
|
+
apiUrl: options.apiUrl,
|
|
1881
|
+
publishableKey: options.publishableKey,
|
|
1882
|
+
customerToken: token ?? void 0,
|
|
1883
|
+
...token && options.onUnauthorized && { onUnauthorized: options.onUnauthorized }
|
|
1544
1884
|
});
|
|
1545
1885
|
options.onRequestId?.(response.headers.get("x-request-id") ?? null);
|
|
1546
1886
|
return parseApiResponse(response, endpoint);
|
|
@@ -1552,19 +1892,30 @@ var CommerceClient = class {
|
|
|
1552
1892
|
};
|
|
1553
1893
|
this.product = {
|
|
1554
1894
|
stockCheck: (params) => execute("/api/products/stock-check", params),
|
|
1555
|
-
|
|
1895
|
+
stockSnapshot: (params) => executeGet(stockSnapshotQuery(params)),
|
|
1896
|
+
listingGroups: (params) => executeGet(listingGroupsQuery(params)),
|
|
1897
|
+
listingGroupsCatalog: (params) => executeGet(listingGroupsCatalogQuery(params)),
|
|
1556
1898
|
detail: async (params) => {
|
|
1557
1899
|
try {
|
|
1558
|
-
const product = await
|
|
1559
|
-
"/api/products/detail",
|
|
1560
|
-
params
|
|
1561
|
-
);
|
|
1900
|
+
const product = await executeGet(productDetailQuery(params));
|
|
1562
1901
|
return { found: true, product };
|
|
1563
1902
|
} catch (err) {
|
|
1564
1903
|
const notFoundResult = productDetailResultFromError(err);
|
|
1565
1904
|
if (notFoundResult) return notFoundResult;
|
|
1566
1905
|
throw err;
|
|
1567
1906
|
}
|
|
1907
|
+
},
|
|
1908
|
+
detailCatalog: async (params) => {
|
|
1909
|
+
try {
|
|
1910
|
+
const product = await executeGet(
|
|
1911
|
+
productDetailCatalogQuery(params)
|
|
1912
|
+
);
|
|
1913
|
+
return { found: true, product };
|
|
1914
|
+
} catch (err) {
|
|
1915
|
+
const notFoundResult = productDetailResultFromError(err);
|
|
1916
|
+
if (notFoundResult?.found === false) return notFoundResult;
|
|
1917
|
+
throw err;
|
|
1918
|
+
}
|
|
1568
1919
|
}
|
|
1569
1920
|
};
|
|
1570
1921
|
this.cart = {
|
|
@@ -1577,7 +1928,14 @@ var CommerceClient = class {
|
|
|
1577
1928
|
clear: cartApi.clearCart.bind(cartApi)
|
|
1578
1929
|
};
|
|
1579
1930
|
this.orders = {
|
|
1580
|
-
checkout: (params) =>
|
|
1931
|
+
checkout: (params) => {
|
|
1932
|
+
const { body, idempotencyKey } = splitIdempotencyKey(params);
|
|
1933
|
+
return execute(
|
|
1934
|
+
"/api/orders/checkout",
|
|
1935
|
+
body,
|
|
1936
|
+
idempotencyRequestOptions(idempotencyKey)
|
|
1937
|
+
);
|
|
1938
|
+
},
|
|
1581
1939
|
listMine: (params) => options.customerAuth.getMyOrders(params)
|
|
1582
1940
|
};
|
|
1583
1941
|
this.discounts = {
|
|
@@ -1589,6 +1947,113 @@ var CommerceClient = class {
|
|
|
1589
1947
|
}
|
|
1590
1948
|
};
|
|
1591
1949
|
|
|
1950
|
+
// src/core/events/events-client.ts
|
|
1951
|
+
var EventsClient = class {
|
|
1952
|
+
constructor(options) {
|
|
1953
|
+
const secretKey = options.secretKey;
|
|
1954
|
+
this.publishableKey = requirePublishableKeyForSecret(
|
|
1955
|
+
"EventsClient",
|
|
1956
|
+
options.publishableKey,
|
|
1957
|
+
secretKey
|
|
1958
|
+
);
|
|
1959
|
+
this.apiUrl = options.apiUrl;
|
|
1960
|
+
this.customerToken = options.customerToken;
|
|
1961
|
+
this.onUnauthorized = options.onUnauthorized;
|
|
1962
|
+
this.onRequestId = options.onRequestId;
|
|
1963
|
+
}
|
|
1964
|
+
getRange(params) {
|
|
1965
|
+
return this.execute(
|
|
1966
|
+
buildRangeEndpoint(params),
|
|
1967
|
+
"GET",
|
|
1968
|
+
void 0,
|
|
1969
|
+
{ useCustomerAuth: false }
|
|
1970
|
+
);
|
|
1971
|
+
}
|
|
1972
|
+
register(params) {
|
|
1973
|
+
return this.execute(
|
|
1974
|
+
"/api/event-registrations/register",
|
|
1975
|
+
"POST",
|
|
1976
|
+
buildRegistrationRequestBody(params),
|
|
1977
|
+
{ useCustomerAuth: true }
|
|
1978
|
+
);
|
|
1979
|
+
}
|
|
1980
|
+
getGuestRegistration(token) {
|
|
1981
|
+
return this.execute(
|
|
1982
|
+
"/api/event-registrations/guest/lookup",
|
|
1983
|
+
"POST",
|
|
1984
|
+
{ token },
|
|
1985
|
+
{ useCustomerAuth: false }
|
|
1986
|
+
);
|
|
1987
|
+
}
|
|
1988
|
+
cancelGuestRegistration(token, params = {}) {
|
|
1989
|
+
return this.execute(
|
|
1990
|
+
"/api/event-registrations/guest/cancel",
|
|
1991
|
+
"POST",
|
|
1992
|
+
buildGuestCancelRequestBody(token, params),
|
|
1993
|
+
{ useCustomerAuth: false }
|
|
1994
|
+
);
|
|
1995
|
+
}
|
|
1996
|
+
async execute(endpoint, method, body, options = {}) {
|
|
1997
|
+
const useCustomerAuth = options.useCustomerAuth === true;
|
|
1998
|
+
const token = useCustomerAuth ? typeof this.customerToken === "function" ? this.customerToken() : this.customerToken : void 0;
|
|
1999
|
+
try {
|
|
2000
|
+
const response = await httpFetch(endpoint, {
|
|
2001
|
+
method,
|
|
2002
|
+
apiUrl: this.apiUrl,
|
|
2003
|
+
publishableKey: this.publishableKey,
|
|
2004
|
+
...useCustomerAuth && token ? { customerToken: token } : {},
|
|
2005
|
+
...useCustomerAuth && token && this.onUnauthorized && { onUnauthorized: this.onUnauthorized },
|
|
2006
|
+
...body !== void 0 && { body: JSON.stringify(body) }
|
|
2007
|
+
});
|
|
2008
|
+
this.onRequestId?.(response.headers.get("x-request-id") ?? null);
|
|
2009
|
+
return parseApiResponse(response, endpoint);
|
|
2010
|
+
} catch (err) {
|
|
2011
|
+
const id = err instanceof SDKError ? err.requestId ?? null : null;
|
|
2012
|
+
this.onRequestId?.(id);
|
|
2013
|
+
throw err;
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
};
|
|
2017
|
+
function buildRegistrationRequestBody(params) {
|
|
2018
|
+
return {
|
|
2019
|
+
event: params.event,
|
|
2020
|
+
occurrence: params.occurrence,
|
|
2021
|
+
...params.quantity !== void 0 && { quantity: params.quantity },
|
|
2022
|
+
...params.attendee !== void 0 && { attendee: params.attendee },
|
|
2023
|
+
...params.answers !== void 0 && { answers: params.answers }
|
|
2024
|
+
};
|
|
2025
|
+
}
|
|
2026
|
+
function buildGuestCancelRequestBody(token, params) {
|
|
2027
|
+
return {
|
|
2028
|
+
token,
|
|
2029
|
+
...params.reason !== void 0 && { reason: params.reason }
|
|
2030
|
+
};
|
|
2031
|
+
}
|
|
2032
|
+
function buildRangeEndpoint(params) {
|
|
2033
|
+
const urlParams = new URLSearchParams();
|
|
2034
|
+
urlParams.set("start", formatDateParam(params.start));
|
|
2035
|
+
urlParams.set("end", formatDateParam(params.end));
|
|
2036
|
+
if (params.limit !== void 0) urlParams.set("limit", String(params.limit));
|
|
2037
|
+
if (params.page !== void 0) urlParams.set("page", String(params.page));
|
|
2038
|
+
appendValues(urlParams, "calendar", params.calendar);
|
|
2039
|
+
appendValues(urlParams, "calendarSlug", params.calendarSlug);
|
|
2040
|
+
appendValues(urlParams, "category", params.category);
|
|
2041
|
+
appendValues(urlParams, "categorySlug", params.categorySlug);
|
|
2042
|
+
appendValues(urlParams, "tag", params.tag);
|
|
2043
|
+
appendValues(urlParams, "tagSlug", params.tagSlug);
|
|
2044
|
+
return `/api/event-occurrences/range?${urlParams.toString()}`;
|
|
2045
|
+
}
|
|
2046
|
+
function formatDateParam(value) {
|
|
2047
|
+
return value instanceof Date ? value.toISOString() : value;
|
|
2048
|
+
}
|
|
2049
|
+
function appendValues(params, key, value) {
|
|
2050
|
+
if (value === void 0) return;
|
|
2051
|
+
const values = Array.isArray(value) ? value : [value];
|
|
2052
|
+
for (const entry of values) {
|
|
2053
|
+
if (entry) params.append(key, entry);
|
|
2054
|
+
}
|
|
2055
|
+
}
|
|
2056
|
+
|
|
1592
2057
|
// src/core/client/client.ts
|
|
1593
2058
|
var Client = class {
|
|
1594
2059
|
constructor(options) {
|
|
@@ -1634,6 +2099,13 @@ var Client = class {
|
|
|
1634
2099
|
onUnauthorized,
|
|
1635
2100
|
onRequestId
|
|
1636
2101
|
});
|
|
2102
|
+
this.events = new EventsClient({
|
|
2103
|
+
publishableKey: this.config.publishableKey,
|
|
2104
|
+
apiUrl: this.config.apiUrl,
|
|
2105
|
+
customerToken: () => this.customer.auth.getToken(),
|
|
2106
|
+
onUnauthorized,
|
|
2107
|
+
onRequestId
|
|
2108
|
+
});
|
|
1637
2109
|
this.collections = new ReadOnlyCollectionClient(
|
|
1638
2110
|
this.config.publishableKey,
|
|
1639
2111
|
void 0,
|
|
@@ -1654,56 +2126,6 @@ function createClient(options) {
|
|
|
1654
2126
|
return new Client(options);
|
|
1655
2127
|
}
|
|
1656
2128
|
|
|
1657
|
-
// src/core/api/order-api.ts
|
|
1658
|
-
var OrderApi = class extends BaseApi {
|
|
1659
|
-
constructor(options) {
|
|
1660
|
-
super("OrderApi", options);
|
|
1661
|
-
}
|
|
1662
|
-
createOrder(params) {
|
|
1663
|
-
return this.request("/api/orders/create", params);
|
|
1664
|
-
}
|
|
1665
|
-
updateOrder(params) {
|
|
1666
|
-
return this.request("/api/orders/update", params);
|
|
1667
|
-
}
|
|
1668
|
-
updateTransaction(params) {
|
|
1669
|
-
return this.request("/api/transactions/update", params);
|
|
1670
|
-
}
|
|
1671
|
-
confirmPayment(params) {
|
|
1672
|
-
return this.request(
|
|
1673
|
-
"/api/orders/confirm-payment",
|
|
1674
|
-
params,
|
|
1675
|
-
params.providerEventId ? { headers: { "X-Idempotency-Key": params.providerEventId } } : void 0
|
|
1676
|
-
);
|
|
1677
|
-
}
|
|
1678
|
-
checkout(params) {
|
|
1679
|
-
return this.request("/api/orders/checkout", params);
|
|
1680
|
-
}
|
|
1681
|
-
createFulfillment(params) {
|
|
1682
|
-
return this.request("/api/orders/create-fulfillment", params);
|
|
1683
|
-
}
|
|
1684
|
-
updateFulfillment(params) {
|
|
1685
|
-
return this.request("/api/orders/update-fulfillment", params);
|
|
1686
|
-
}
|
|
1687
|
-
bulkImportFulfillments(params) {
|
|
1688
|
-
return this.request(
|
|
1689
|
-
"/api/fulfillments/bulk-import",
|
|
1690
|
-
params
|
|
1691
|
-
);
|
|
1692
|
-
}
|
|
1693
|
-
returnWithRefund(params) {
|
|
1694
|
-
return this.request(
|
|
1695
|
-
"/api/returns/return-refund",
|
|
1696
|
-
params
|
|
1697
|
-
);
|
|
1698
|
-
}
|
|
1699
|
-
createReturn(params) {
|
|
1700
|
-
return this.request("/api/returns/create", params);
|
|
1701
|
-
}
|
|
1702
|
-
updateReturn(params) {
|
|
1703
|
-
return this.request("/api/returns/update", params);
|
|
1704
|
-
}
|
|
1705
|
-
};
|
|
1706
|
-
|
|
1707
2129
|
// src/core/api/discount-api.ts
|
|
1708
2130
|
var DiscountApi = class extends BaseApi {
|
|
1709
2131
|
constructor(options) {
|
|
@@ -1724,6 +2146,44 @@ var ShippingApi = class extends BaseApi {
|
|
|
1724
2146
|
}
|
|
1725
2147
|
};
|
|
1726
2148
|
|
|
2149
|
+
// src/core/commerce/merge-catalog-stock.ts
|
|
2150
|
+
function mergeProductDetailWithStock(catalog, snapshot) {
|
|
2151
|
+
const snapshotByVariantId = new Map(
|
|
2152
|
+
snapshot.snapshots.map((item) => [item.variantId, item])
|
|
2153
|
+
);
|
|
2154
|
+
let missingSnapshotCount = 0;
|
|
2155
|
+
const variants = catalog.variants.map((variant) => {
|
|
2156
|
+
const snap = snapshotByVariantId.get(String(variant.id));
|
|
2157
|
+
if (!snap) {
|
|
2158
|
+
missingSnapshotCount += 1;
|
|
2159
|
+
return { ...variant, stock: 0, reservedStock: 0 };
|
|
2160
|
+
}
|
|
2161
|
+
return {
|
|
2162
|
+
...variant,
|
|
2163
|
+
stock: snap.isUnlimited ? 0 : snap.availableStock,
|
|
2164
|
+
reservedStock: 0
|
|
2165
|
+
};
|
|
2166
|
+
});
|
|
2167
|
+
const trackedVariants = variants.filter((variant) => !variant.isUnlimited);
|
|
2168
|
+
const totalInventory = trackedVariants.length === 0 ? null : trackedVariants.reduce(
|
|
2169
|
+
(sum, variant) => sum + Math.max(0, (variant.stock ?? 0) - (variant.reservedStock ?? 0)),
|
|
2170
|
+
0
|
|
2171
|
+
);
|
|
2172
|
+
const { liveStockRequired: _liveStockRequired, ...listingBase } = catalog.listing;
|
|
2173
|
+
const availableForSale = snapshot.snapshots.some(
|
|
2174
|
+
(item) => item.status === "available" && item.availableForSale
|
|
2175
|
+
);
|
|
2176
|
+
return {
|
|
2177
|
+
stockMergeStatus: missingSnapshotCount === 0 ? "complete" : "partial",
|
|
2178
|
+
product: {
|
|
2179
|
+
...catalog,
|
|
2180
|
+
product: { ...catalog.product, totalInventory },
|
|
2181
|
+
variants,
|
|
2182
|
+
listing: { ...listingBase, availableForSale }
|
|
2183
|
+
}
|
|
2184
|
+
};
|
|
2185
|
+
}
|
|
2186
|
+
|
|
1727
2187
|
// src/core/webhook/index.ts
|
|
1728
2188
|
var ORDER_CHANGED_EVENT_TYPE = "collection.orderChanged";
|
|
1729
2189
|
var COMMERCE_NOTIFICATION_EVENT_TYPE = "commerce.notification";
|
|
@@ -1735,6 +2195,7 @@ function isValidWebhookEvent(data) {
|
|
|
1735
2195
|
var COMMERCE_NOTIFICATION_OPERATION = "notification";
|
|
1736
2196
|
var COMMERCE_NOTIFICATION_EVENTS = [
|
|
1737
2197
|
"orderPaid",
|
|
2198
|
+
"orderCanceled",
|
|
1738
2199
|
"fulfillmentShipped",
|
|
1739
2200
|
"orderDelivered",
|
|
1740
2201
|
"returnRequested",
|
|
@@ -1820,7 +2281,7 @@ function isCommerceNotificationWebhookEvent(event) {
|
|
|
1820
2281
|
if (!matchesOptionalId(change.sourceId, sourceId)) return false;
|
|
1821
2282
|
}
|
|
1822
2283
|
const changeSourceId = isWebhookCommerceNotificationChange(change) ? change.sourceId : void 0;
|
|
1823
|
-
if (notification.event === "orderPaid" || notification.event === "orderDelivered") {
|
|
2284
|
+
if (notification.event === "orderPaid" || notification.event === "orderCanceled" || notification.event === "orderDelivered") {
|
|
1824
2285
|
return sourceCollection === "orders" && typeof notification.orderId === "string" && notification.orderId.length > 0 && matchesOptionalId(data.orderId, sourceId) && matchesOptionalId(notification.orderId, sourceId) && matchesOptionalId(data.orderId, notification.orderId) && matchesOptionalId(changeSourceId, data.orderId ?? notification.orderId);
|
|
1825
2286
|
}
|
|
1826
2287
|
if (notification.event === "fulfillmentShipped") {
|
|
@@ -2075,6 +2536,7 @@ var COLLECTIONS = [
|
|
|
2075
2536
|
"reaction-types",
|
|
2076
2537
|
"bookmarks",
|
|
2077
2538
|
"post-categories",
|
|
2539
|
+
"post-tags",
|
|
2078
2540
|
"customer-profile-lists",
|
|
2079
2541
|
// Events
|
|
2080
2542
|
"event-calendars",
|
|
@@ -2223,22 +2685,252 @@ var RealtimeConnection = class {
|
|
|
2223
2685
|
}
|
|
2224
2686
|
}
|
|
2225
2687
|
}
|
|
2226
|
-
scheduleReconnect() {
|
|
2227
|
-
if (this.reconnectTimer) return;
|
|
2228
|
-
const delay2 = Math.min(
|
|
2229
|
-
INITIAL_RECONNECT_DELAY * Math.pow(RECONNECT_BACKOFF_FACTOR, this.reconnectAttempt),
|
|
2230
|
-
MAX_RECONNECT_DELAY
|
|
2231
|
-
);
|
|
2232
|
-
this.reconnectAttempt++;
|
|
2233
|
-
this.reconnectTimer = setTimeout(() => {
|
|
2234
|
-
this.reconnectTimer = null;
|
|
2235
|
-
this.abortController = new AbortController();
|
|
2236
|
-
this.startStream(this.abortController.signal);
|
|
2237
|
-
}, delay2);
|
|
2688
|
+
scheduleReconnect() {
|
|
2689
|
+
if (this.reconnectTimer) return;
|
|
2690
|
+
const delay2 = Math.min(
|
|
2691
|
+
INITIAL_RECONNECT_DELAY * Math.pow(RECONNECT_BACKOFF_FACTOR, this.reconnectAttempt),
|
|
2692
|
+
MAX_RECONNECT_DELAY
|
|
2693
|
+
);
|
|
2694
|
+
this.reconnectAttempt++;
|
|
2695
|
+
this.reconnectTimer = setTimeout(() => {
|
|
2696
|
+
this.reconnectTimer = null;
|
|
2697
|
+
this.abortController = new AbortController();
|
|
2698
|
+
this.startStream(this.abortController.signal);
|
|
2699
|
+
}, delay2);
|
|
2700
|
+
}
|
|
2701
|
+
};
|
|
2702
|
+
|
|
2703
|
+
// src/utils/product-selection-media.ts
|
|
2704
|
+
function selectedSwatchMediaItemId(swatch) {
|
|
2705
|
+
if (!swatch || swatch.type !== "media") return null;
|
|
2706
|
+
const id = swatch.mediaItemId;
|
|
2707
|
+
if (id == null || id === "") return null;
|
|
2708
|
+
return String(id);
|
|
2709
|
+
}
|
|
2710
|
+
function getMediaId(value) {
|
|
2711
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
2712
|
+
return String(value);
|
|
2713
|
+
}
|
|
2714
|
+
if (typeof value === "object" && value !== null && "id" in value) {
|
|
2715
|
+
const id = value.id;
|
|
2716
|
+
if (typeof id === "string" || typeof id === "number") return String(id);
|
|
2717
|
+
}
|
|
2718
|
+
return null;
|
|
2719
|
+
}
|
|
2720
|
+
function toPointerId(value) {
|
|
2721
|
+
return getMediaId(value);
|
|
2722
|
+
}
|
|
2723
|
+
function mediaArray(value) {
|
|
2724
|
+
if (!Array.isArray(value)) return [];
|
|
2725
|
+
return value.filter((entry) => entry != null);
|
|
2726
|
+
}
|
|
2727
|
+
function uniqueWithPrimaryFirst(primary, items) {
|
|
2728
|
+
const unique = /* @__PURE__ */ new Map();
|
|
2729
|
+
for (const item of items) {
|
|
2730
|
+
const id = getMediaId(item);
|
|
2731
|
+
const key = id ?? `inline:${unique.size}`;
|
|
2732
|
+
if (!unique.has(key)) unique.set(key, item);
|
|
2733
|
+
}
|
|
2734
|
+
if (primary) {
|
|
2735
|
+
const primaryId = getMediaId(primary);
|
|
2736
|
+
const prefixed = /* @__PURE__ */ new Map();
|
|
2737
|
+
const primaryKey = primaryId ?? "inline:primary";
|
|
2738
|
+
prefixed.set(primaryKey, primary);
|
|
2739
|
+
for (const [key, value] of unique.entries()) {
|
|
2740
|
+
if (!prefixed.has(key)) prefixed.set(key, value);
|
|
2741
|
+
}
|
|
2742
|
+
return Array.from(prefixed.values());
|
|
2743
|
+
}
|
|
2744
|
+
return Array.from(unique.values());
|
|
2745
|
+
}
|
|
2746
|
+
function buildPoolById(pool) {
|
|
2747
|
+
const poolById = /* @__PURE__ */ new Map();
|
|
2748
|
+
for (const item of pool) {
|
|
2749
|
+
const id = getMediaId(item);
|
|
2750
|
+
if (id) poolById.set(id, item);
|
|
2751
|
+
}
|
|
2752
|
+
return poolById;
|
|
2753
|
+
}
|
|
2754
|
+
function resolveVariantImageItems(variant, poolById) {
|
|
2755
|
+
if (!variant || !Array.isArray(variant.images)) return [];
|
|
2756
|
+
const resolved = [];
|
|
2757
|
+
for (const entry of variant.images) {
|
|
2758
|
+
if (entry == null) continue;
|
|
2759
|
+
if (typeof entry === "string" || typeof entry === "number") {
|
|
2760
|
+
const pooled = poolById.get(String(entry));
|
|
2761
|
+
if (pooled) resolved.push(pooled);
|
|
2762
|
+
continue;
|
|
2763
|
+
}
|
|
2764
|
+
const mediaId2 = getMediaId(entry);
|
|
2765
|
+
if (mediaId2) {
|
|
2766
|
+
const pooled = poolById.get(mediaId2);
|
|
2767
|
+
if (pooled) {
|
|
2768
|
+
resolved.push(pooled);
|
|
2769
|
+
}
|
|
2770
|
+
continue;
|
|
2771
|
+
}
|
|
2772
|
+
}
|
|
2773
|
+
return resolved;
|
|
2774
|
+
}
|
|
2775
|
+
function resolveOptionSwatchPrimary(selectedOptionValues, poolById) {
|
|
2776
|
+
if (!selectedOptionValues?.length) return null;
|
|
2777
|
+
for (const optionValue of selectedOptionValues) {
|
|
2778
|
+
const swatch = optionValue?.swatch;
|
|
2779
|
+
const swatchPointer = selectedSwatchMediaItemId(swatch);
|
|
2780
|
+
if (swatchPointer) {
|
|
2781
|
+
const pooled = poolById.get(swatchPointer);
|
|
2782
|
+
if (pooled) return pooled;
|
|
2783
|
+
}
|
|
2784
|
+
const inline = swatch?.inlineMedia;
|
|
2785
|
+
if (inline != null && typeof inline === "object") {
|
|
2786
|
+
return inline;
|
|
2787
|
+
}
|
|
2788
|
+
}
|
|
2789
|
+
return null;
|
|
2790
|
+
}
|
|
2791
|
+
function resolveProductSelectionMedia(input) {
|
|
2792
|
+
const pool = mediaArray(input.productMediaPool);
|
|
2793
|
+
const poolById = buildPoolById(pool);
|
|
2794
|
+
const selectedVariantImages = resolveVariantImageItems(
|
|
2795
|
+
input.selectedVariant,
|
|
2796
|
+
poolById
|
|
2797
|
+
);
|
|
2798
|
+
if (selectedVariantImages.length > 0) {
|
|
2799
|
+
const primaryImage = selectedVariantImages[0] ?? null;
|
|
2800
|
+
return {
|
|
2801
|
+
primaryImage,
|
|
2802
|
+
images: uniqueWithPrimaryFirst(primaryImage, selectedVariantImages),
|
|
2803
|
+
source: "variant_media_selected"
|
|
2804
|
+
};
|
|
2805
|
+
}
|
|
2806
|
+
if (input.selectedVariant == null && (input.matchingVariants?.length ?? 0) > 0) {
|
|
2807
|
+
const mergedMatchingImages = [];
|
|
2808
|
+
for (const matchingVariant of input.matchingVariants ?? []) {
|
|
2809
|
+
mergedMatchingImages.push(
|
|
2810
|
+
...resolveVariantImageItems(matchingVariant, poolById)
|
|
2811
|
+
);
|
|
2812
|
+
}
|
|
2813
|
+
if (mergedMatchingImages.length > 0) {
|
|
2814
|
+
const primaryImage = mergedMatchingImages[0] ?? null;
|
|
2815
|
+
return {
|
|
2816
|
+
primaryImage,
|
|
2817
|
+
images: uniqueWithPrimaryFirst(primaryImage, mergedMatchingImages),
|
|
2818
|
+
source: "variant_media_matching"
|
|
2819
|
+
};
|
|
2820
|
+
}
|
|
2821
|
+
}
|
|
2822
|
+
const optionSwatchPrimary = resolveOptionSwatchPrimary(
|
|
2823
|
+
input.selectedOptionValues,
|
|
2824
|
+
poolById
|
|
2825
|
+
);
|
|
2826
|
+
if (optionSwatchPrimary) {
|
|
2827
|
+
return {
|
|
2828
|
+
primaryImage: optionSwatchPrimary,
|
|
2829
|
+
images: [optionSwatchPrimary],
|
|
2830
|
+
source: "option_swatch"
|
|
2831
|
+
};
|
|
2238
2832
|
}
|
|
2239
|
-
|
|
2833
|
+
return {
|
|
2834
|
+
primaryImage: null,
|
|
2835
|
+
images: [],
|
|
2836
|
+
source: "none"
|
|
2837
|
+
};
|
|
2838
|
+
}
|
|
2839
|
+
function resolveProductDisplayMedia(input) {
|
|
2840
|
+
const pool = mediaArray(input.productMediaPool);
|
|
2841
|
+
const poolById = buildPoolById(pool);
|
|
2842
|
+
const listingPointer = toPointerId(input.listingPrimaryImage);
|
|
2843
|
+
if (listingPointer) {
|
|
2844
|
+
const listingPrimary = poolById.get(listingPointer);
|
|
2845
|
+
if (listingPrimary) {
|
|
2846
|
+
return {
|
|
2847
|
+
primaryImage: listingPrimary,
|
|
2848
|
+
images: uniqueWithPrimaryFirst(listingPrimary, pool),
|
|
2849
|
+
source: "listing_primary"
|
|
2850
|
+
};
|
|
2851
|
+
}
|
|
2852
|
+
}
|
|
2853
|
+
const productPrimaryPointer = getMediaId(input.productPrimaryMediaItemId);
|
|
2854
|
+
if (productPrimaryPointer) {
|
|
2855
|
+
const productPrimary = poolById.get(productPrimaryPointer);
|
|
2856
|
+
if (productPrimary) {
|
|
2857
|
+
return {
|
|
2858
|
+
primaryImage: productPrimary,
|
|
2859
|
+
images: uniqueWithPrimaryFirst(productPrimary, pool),
|
|
2860
|
+
source: "product_primary"
|
|
2861
|
+
};
|
|
2862
|
+
}
|
|
2863
|
+
}
|
|
2864
|
+
if (pool.length > 0) {
|
|
2865
|
+
const productPoolPrimary = pool[0] ?? null;
|
|
2866
|
+
if (productPoolPrimary) {
|
|
2867
|
+
return {
|
|
2868
|
+
primaryImage: productPoolPrimary,
|
|
2869
|
+
images: uniqueWithPrimaryFirst(productPoolPrimary, pool),
|
|
2870
|
+
source: "product_pool"
|
|
2871
|
+
};
|
|
2872
|
+
}
|
|
2873
|
+
}
|
|
2874
|
+
return {
|
|
2875
|
+
primaryImage: null,
|
|
2876
|
+
images: [],
|
|
2877
|
+
source: "none"
|
|
2878
|
+
};
|
|
2879
|
+
}
|
|
2880
|
+
function resolveListingPrimaryImagePointer(input) {
|
|
2881
|
+
const pool = mediaArray(input.productMediaPool);
|
|
2882
|
+
const resolvedPointer = getMediaId(input.resolvedPrimary);
|
|
2883
|
+
if (resolvedPointer && input.resolvedSource !== "product_pool" && input.resolvedSource !== "none") {
|
|
2884
|
+
return resolvedPointer;
|
|
2885
|
+
}
|
|
2886
|
+
const poolById = buildPoolById(pool);
|
|
2887
|
+
const listingPointer = getMediaId(input.listingPrimaryImage);
|
|
2888
|
+
if (listingPointer && poolById.has(listingPointer)) {
|
|
2889
|
+
return listingPointer;
|
|
2890
|
+
}
|
|
2891
|
+
const primaryPointer = toPointerId(input.productPrimaryMediaItemId);
|
|
2892
|
+
if (primaryPointer && poolById.has(primaryPointer)) return primaryPointer;
|
|
2893
|
+
const thumbnailPointer = getMediaId(input.productThumbnail);
|
|
2894
|
+
if (thumbnailPointer && poolById.has(thumbnailPointer)) {
|
|
2895
|
+
return thumbnailPointer;
|
|
2896
|
+
}
|
|
2897
|
+
if (pool.length > 0) {
|
|
2898
|
+
const firstPoolId = getMediaId(pool[0]);
|
|
2899
|
+
if (firstPoolId) return firstPoolId;
|
|
2900
|
+
}
|
|
2901
|
+
return null;
|
|
2902
|
+
}
|
|
2240
2903
|
|
|
2241
2904
|
// src/utils/ecommerce.ts
|
|
2905
|
+
function normalizeMatrixSwatch(swatch) {
|
|
2906
|
+
if (!swatch) return null;
|
|
2907
|
+
const rawMedia = swatch.mediaItemId;
|
|
2908
|
+
const inlineMedia = rawMedia != null && typeof rawMedia === "object" && "url" in rawMedia && typeof rawMedia.url === "string" ? rawMedia : null;
|
|
2909
|
+
return {
|
|
2910
|
+
type: swatch.type ?? null,
|
|
2911
|
+
color: swatch.color ?? null,
|
|
2912
|
+
mediaItemId: extractEntityId(rawMedia),
|
|
2913
|
+
inlineMedia
|
|
2914
|
+
};
|
|
2915
|
+
}
|
|
2916
|
+
var DEFAULT_PRODUCT_SELECTION_URL_EMIT = "slug-compat";
|
|
2917
|
+
function resolveProductSelectionUrlEmit(emit) {
|
|
2918
|
+
return emit ?? DEFAULT_PRODUCT_SELECTION_URL_EMIT;
|
|
2919
|
+
}
|
|
2920
|
+
function appendSlugCompatSelectionParam(params, matrix, optionId, valueId) {
|
|
2921
|
+
const option = matrix.optionById.get(optionId);
|
|
2922
|
+
const value = matrix.valueById.get(valueId);
|
|
2923
|
+
if (!option?.slug || !value?.slug) return false;
|
|
2924
|
+
const slugMatches = option.values.filter(
|
|
2925
|
+
(candidate) => candidate.slug === value.slug
|
|
2926
|
+
);
|
|
2927
|
+
if (slugMatches.length !== 1) return false;
|
|
2928
|
+
params.append(`opt.${option.slug}`, value.slug);
|
|
2929
|
+
return true;
|
|
2930
|
+
}
|
|
2931
|
+
function appendCanonicalSelectionParam(params, optionId, valueId) {
|
|
2932
|
+
params.append(`opt.${optionId}`, valueId);
|
|
2933
|
+
}
|
|
2242
2934
|
var ProductSelectionCodecError = class extends Error {
|
|
2243
2935
|
constructor(message) {
|
|
2244
2936
|
super(message);
|
|
@@ -2283,6 +2975,18 @@ function getVariantPrimaryImage(variant) {
|
|
|
2283
2975
|
if (!variant) return null;
|
|
2284
2976
|
return extractEntityId(variant.thumbnail) ?? getFirstMediaId(variant.images);
|
|
2285
2977
|
}
|
|
2978
|
+
function resolveGenericListingPrimaryImage(product, resolvedPrimary, resolvedSource) {
|
|
2979
|
+
return resolveListingPrimaryImagePointer({
|
|
2980
|
+
productMediaPool: product?.images ?? [],
|
|
2981
|
+
productPrimaryMediaItemId: getRelationID(
|
|
2982
|
+
product?.primaryMediaItemId ?? null
|
|
2983
|
+
),
|
|
2984
|
+
productThumbnail: product?.thumbnail ?? null,
|
|
2985
|
+
listingPrimaryImage: product?.listing?.primaryImage ?? null,
|
|
2986
|
+
resolvedPrimary,
|
|
2987
|
+
resolvedSource
|
|
2988
|
+
});
|
|
2989
|
+
}
|
|
2286
2990
|
function getFirstAvailableVariantPrimaryImage(variants) {
|
|
2287
2991
|
const orderedVariants = [...variants].sort(compareVariantOrder);
|
|
2288
2992
|
for (const variant of orderedVariants) {
|
|
@@ -2292,6 +2996,27 @@ function getFirstAvailableVariantPrimaryImage(variants) {
|
|
|
2292
2996
|
}
|
|
2293
2997
|
return null;
|
|
2294
2998
|
}
|
|
2999
|
+
function normalizeProductOptionValueSwatch(swatch) {
|
|
3000
|
+
if (swatch == null) return null;
|
|
3001
|
+
if (typeof swatch !== "object") return null;
|
|
3002
|
+
const raw = swatch;
|
|
3003
|
+
const mediaItemId = extractEntityId(raw.mediaItemId);
|
|
3004
|
+
const color = typeof raw.color === "string" ? raw.color.trim() : "";
|
|
3005
|
+
const hasColor = color.length > 0;
|
|
3006
|
+
if (raw.type === "media" || mediaItemId && raw.type !== "color") {
|
|
3007
|
+
if (!mediaItemId || hasColor) return null;
|
|
3008
|
+
return {
|
|
3009
|
+
type: "media",
|
|
3010
|
+
mediaItemId,
|
|
3011
|
+
color: null
|
|
3012
|
+
};
|
|
3013
|
+
}
|
|
3014
|
+
if (raw.type === "color" || hasColor) {
|
|
3015
|
+
if (mediaItemId || !hasColor) return null;
|
|
3016
|
+
return { type: "color", color, mediaItemId: null };
|
|
3017
|
+
}
|
|
3018
|
+
return null;
|
|
3019
|
+
}
|
|
2295
3020
|
function normalizeOptionValue(value, fallbackOptionId, fallbackOptionSlug) {
|
|
2296
3021
|
return {
|
|
2297
3022
|
id: String(value.id),
|
|
@@ -2299,9 +3024,7 @@ function normalizeOptionValue(value, fallbackOptionId, fallbackOptionSlug) {
|
|
|
2299
3024
|
optionSlug: fallbackOptionSlug,
|
|
2300
3025
|
label: value.value || value.slug || String(value.id),
|
|
2301
3026
|
slug: value.slug ?? null,
|
|
2302
|
-
|
|
2303
|
-
thumbnail: value.thumbnail ?? null,
|
|
2304
|
-
images: value.images ?? null,
|
|
3027
|
+
swatch: normalizeProductOptionValueSwatch(value.swatch),
|
|
2305
3028
|
order: value._order ?? value["_product-option-values_values_order"] ?? ""
|
|
2306
3029
|
};
|
|
2307
3030
|
}
|
|
@@ -2407,9 +3130,7 @@ function buildProductOptionMatrixFromDetail(detail) {
|
|
|
2407
3130
|
optionSlug: option.slug,
|
|
2408
3131
|
label: value.value || value.slug || String(value.id),
|
|
2409
3132
|
slug: value.slug,
|
|
2410
|
-
|
|
2411
|
-
thumbnail: value.thumbnail ?? null,
|
|
2412
|
-
images: value.images ?? null,
|
|
3133
|
+
swatch: normalizeProductOptionValueSwatch(value.swatch),
|
|
2413
3134
|
order: matrixOrder(valueIndex)
|
|
2414
3135
|
}))
|
|
2415
3136
|
}));
|
|
@@ -2845,13 +3566,19 @@ function stringifyProductSelection(detail, selection = {}, options) {
|
|
|
2845
3566
|
return params.toString();
|
|
2846
3567
|
}
|
|
2847
3568
|
}
|
|
3569
|
+
const emit = resolveProductSelectionUrlEmit(options?.emit);
|
|
2848
3570
|
for (const optionId of matrix.optionIds) {
|
|
2849
3571
|
const valueId = normalized.byOptionId[optionId];
|
|
2850
3572
|
if (!valueId) continue;
|
|
2851
3573
|
if (!matrix.optionById.has(optionId) || !matrix.valueById.has(valueId)) {
|
|
2852
3574
|
continue;
|
|
2853
3575
|
}
|
|
2854
|
-
|
|
3576
|
+
if (emit === "slug-compat") {
|
|
3577
|
+
if (appendSlugCompatSelectionParam(params, matrix, optionId, valueId)) {
|
|
3578
|
+
continue;
|
|
3579
|
+
}
|
|
3580
|
+
}
|
|
3581
|
+
appendCanonicalSelectionParam(params, optionId, valueId);
|
|
2855
3582
|
}
|
|
2856
3583
|
return params.toString();
|
|
2857
3584
|
}
|
|
@@ -2890,6 +3617,100 @@ function getExactSelectedVariantEntry(matrix, selection, matchingVariants) {
|
|
|
2890
3617
|
)
|
|
2891
3618
|
) ?? null;
|
|
2892
3619
|
}
|
|
3620
|
+
function normalizedSelectionFromByOptionId(matrix, selectedByOptionId, variantId) {
|
|
3621
|
+
const byOptionId = Object.fromEntries(
|
|
3622
|
+
matrix.optionIds.map((optionId) => [optionId, selectedByOptionId.get(optionId)]).filter((entry) => Boolean(entry[1]))
|
|
3623
|
+
);
|
|
3624
|
+
const byOptionSlug = Object.fromEntries(
|
|
3625
|
+
matrix.options.map((option) => {
|
|
3626
|
+
const valueId = selectedByOptionId.get(option.id);
|
|
3627
|
+
const value = valueId ? matrix.valueById.get(valueId) : void 0;
|
|
3628
|
+
return [option.slug, value?.slug ?? void 0];
|
|
3629
|
+
}).filter((entry) => Boolean(entry[1]))
|
|
3630
|
+
);
|
|
3631
|
+
return {
|
|
3632
|
+
byOptionSlug,
|
|
3633
|
+
byOptionId,
|
|
3634
|
+
valueIds: matrix.optionIds.map((optionId) => byOptionId[optionId]).filter((valueId) => Boolean(valueId)),
|
|
3635
|
+
variantId
|
|
3636
|
+
};
|
|
3637
|
+
}
|
|
3638
|
+
function buildFilledNormalizedSelection(matrix, normalizedSelection, listing) {
|
|
3639
|
+
const selectedByOptionId = new Map(
|
|
3640
|
+
Object.entries(normalizedSelection.byOptionId)
|
|
3641
|
+
);
|
|
3642
|
+
if (matrix.optionIds.every((optionId) => selectedByOptionId.has(optionId))) {
|
|
3643
|
+
const variantId = normalizedSelection.variantId ?? resolveVariantIdForCompleteSelection(matrix, selectedByOptionId);
|
|
3644
|
+
if (variantId === normalizedSelection.variantId) {
|
|
3645
|
+
return normalizedSelection;
|
|
3646
|
+
}
|
|
3647
|
+
return normalizedSelectionFromByOptionId(
|
|
3648
|
+
matrix,
|
|
3649
|
+
selectedByOptionId,
|
|
3650
|
+
variantId
|
|
3651
|
+
);
|
|
3652
|
+
}
|
|
3653
|
+
for (const option of matrix.options) {
|
|
3654
|
+
if (selectedByOptionId.has(option.id)) continue;
|
|
3655
|
+
if (option.values.length === 1) {
|
|
3656
|
+
selectedByOptionId.set(option.id, option.values[0].id);
|
|
3657
|
+
}
|
|
3658
|
+
}
|
|
3659
|
+
if (matrix.optionIds.every((optionId) => selectedByOptionId.has(optionId))) {
|
|
3660
|
+
const variantId = normalizedSelection.variantId ?? resolveVariantIdForCompleteSelection(matrix, selectedByOptionId);
|
|
3661
|
+
return normalizedSelectionFromByOptionId(
|
|
3662
|
+
matrix,
|
|
3663
|
+
selectedByOptionId,
|
|
3664
|
+
variantId
|
|
3665
|
+
);
|
|
3666
|
+
}
|
|
3667
|
+
const partialNormalized = normalizedSelectionFromByOptionId(
|
|
3668
|
+
matrix,
|
|
3669
|
+
selectedByOptionId,
|
|
3670
|
+
normalizedSelection.variantId
|
|
3671
|
+
);
|
|
3672
|
+
const matchingVariantEntries = getMatchingVariantEntries(
|
|
3673
|
+
matrix,
|
|
3674
|
+
partialNormalized
|
|
3675
|
+
);
|
|
3676
|
+
const orderedMatches = [...matchingVariantEntries].sort(
|
|
3677
|
+
(left, right) => compareVariantOrder(left.source, right.source)
|
|
3678
|
+
);
|
|
3679
|
+
const hintVariantId = listing.selectionHintVariant != null ? String(listing.selectionHintVariant) : null;
|
|
3680
|
+
const hintedEntry = hintVariantId != null ? orderedMatches.find((entry) => entry.id === hintVariantId) : void 0;
|
|
3681
|
+
const availableEntry = orderedMatches.find(
|
|
3682
|
+
(entry) => isVariantAvailableForSale(entry.source)
|
|
3683
|
+
);
|
|
3684
|
+
const chosenEntry = hintedEntry ?? availableEntry ?? orderedMatches[0];
|
|
3685
|
+
if (!chosenEntry) {
|
|
3686
|
+
return normalizedSelection;
|
|
3687
|
+
}
|
|
3688
|
+
for (const optionId of matrix.optionIds) {
|
|
3689
|
+
if (selectedByOptionId.has(optionId)) continue;
|
|
3690
|
+
const valueId = chosenEntry.optionValueByOptionId.get(optionId);
|
|
3691
|
+
if (valueId) selectedByOptionId.set(optionId, valueId);
|
|
3692
|
+
}
|
|
3693
|
+
const filledVariantId = matrix.optionIds.every(
|
|
3694
|
+
(optionId) => selectedByOptionId.has(optionId)
|
|
3695
|
+
) ? resolveVariantIdForCompleteSelection(matrix, selectedByOptionId) ?? chosenEntry.id : normalizedSelection.variantId;
|
|
3696
|
+
return normalizedSelectionFromByOptionId(
|
|
3697
|
+
matrix,
|
|
3698
|
+
selectedByOptionId,
|
|
3699
|
+
filledVariantId
|
|
3700
|
+
);
|
|
3701
|
+
}
|
|
3702
|
+
function resolveVariantIdForCompleteSelection(matrix, selectedByOptionId) {
|
|
3703
|
+
if (!matrix.optionIds.every((optionId) => selectedByOptionId.has(optionId))) {
|
|
3704
|
+
return null;
|
|
3705
|
+
}
|
|
3706
|
+
const normalized = normalizedSelectionFromByOptionId(
|
|
3707
|
+
matrix,
|
|
3708
|
+
selectedByOptionId,
|
|
3709
|
+
null
|
|
3710
|
+
);
|
|
3711
|
+
const matchingVariantEntries = getMatchingVariantEntries(matrix, normalized);
|
|
3712
|
+
return getExactSelectedVariantEntry(matrix, normalized, matchingVariantEntries)?.id ?? null;
|
|
3713
|
+
}
|
|
2893
3714
|
function buildSelectionPrice(variants) {
|
|
2894
3715
|
const { min, max } = getMinMax(variants.map((variant) => variant.price));
|
|
2895
3716
|
const { min: compareAtMin, max: compareAtMax } = getMinMax(
|
|
@@ -2903,38 +3724,51 @@ function buildSelectionPrice(variants) {
|
|
|
2903
3724
|
isRange: min !== null && max !== null ? min !== max : false
|
|
2904
3725
|
};
|
|
2905
3726
|
}
|
|
2906
|
-
function firstMedia(value) {
|
|
2907
|
-
if (value == null) return null;
|
|
2908
|
-
if (Array.isArray(value)) return firstMedia(value[0]);
|
|
2909
|
-
return value;
|
|
2910
|
-
}
|
|
2911
3727
|
function isPresentMedia(value) {
|
|
2912
3728
|
return value != null;
|
|
2913
3729
|
}
|
|
2914
|
-
function
|
|
3730
|
+
function mediaArray2(values) {
|
|
2915
3731
|
if (!Array.isArray(values)) return [];
|
|
2916
3732
|
return values.filter(isPresentMedia);
|
|
2917
3733
|
}
|
|
2918
3734
|
function buildSelectionMedia(detail, selectedVariant, matchingVariants, selectedValues) {
|
|
2919
|
-
const
|
|
2920
|
-
const
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
3735
|
+
const productPool = mediaArray2(detail.images);
|
|
3736
|
+
const resolvedMedia = resolveProductSelectionMedia({
|
|
3737
|
+
productMediaPool: productPool,
|
|
3738
|
+
productPrimaryMediaItemId: getRelationID(detail.primaryMediaItemId),
|
|
3739
|
+
selectedVariant: selectedVariant ? {
|
|
3740
|
+
id: selectedVariant.id,
|
|
3741
|
+
images: selectedVariant.images
|
|
3742
|
+
} : null,
|
|
3743
|
+
matchingVariants: matchingVariants.map((variant) => ({
|
|
3744
|
+
id: variant.id,
|
|
3745
|
+
images: variant.images
|
|
3746
|
+
})),
|
|
3747
|
+
selectedOptionValues: selectedValues.map((value) => ({
|
|
3748
|
+
id: value.id,
|
|
3749
|
+
swatch: normalizeMatrixSwatch(value.swatch)
|
|
3750
|
+
}))
|
|
3751
|
+
});
|
|
3752
|
+
if (resolvedMedia.source !== "none") {
|
|
3753
|
+
return {
|
|
3754
|
+
primaryImage: resolvedMedia.primaryImage,
|
|
3755
|
+
images: resolvedMedia.images,
|
|
3756
|
+
source: resolvedMedia.source
|
|
3757
|
+
};
|
|
3758
|
+
}
|
|
3759
|
+
const displayMedia = resolveProductDisplayMedia({
|
|
3760
|
+
productMediaPool: productPool,
|
|
3761
|
+
productPrimaryMediaItemId: getRelationID(detail.primaryMediaItemId),
|
|
3762
|
+
listingPrimaryImage: detail.listing.primaryImage ?? null
|
|
3763
|
+
});
|
|
3764
|
+
if (displayMedia.source !== "none") {
|
|
3765
|
+
return {
|
|
3766
|
+
primaryImage: displayMedia.primaryImage,
|
|
3767
|
+
images: displayMedia.images,
|
|
3768
|
+
source: displayMedia.source
|
|
3769
|
+
};
|
|
3770
|
+
}
|
|
3771
|
+
return { primaryImage: null, images: [], source: "none" };
|
|
2938
3772
|
}
|
|
2939
3773
|
function buildSelectionStock(selectedVariant, matchingVariants) {
|
|
2940
3774
|
if (selectedVariant) {
|
|
@@ -2957,7 +3791,9 @@ function buildSelectionStock(selectedVariant, matchingVariants) {
|
|
|
2957
3791
|
};
|
|
2958
3792
|
}
|
|
2959
3793
|
function buildAvailableValueStock(variants) {
|
|
2960
|
-
const activeVariants = variants.filter(
|
|
3794
|
+
const activeVariants = variants.filter(
|
|
3795
|
+
(variant) => variant.isActive !== false
|
|
3796
|
+
);
|
|
2961
3797
|
const isUnlimited = activeVariants.some((variant) => variant.isUnlimited);
|
|
2962
3798
|
const availableStock = isUnlimited ? null : activeVariants.reduce(
|
|
2963
3799
|
(sum, variant) => sum + Math.max(0, variant.stock - variant.reservedStock),
|
|
@@ -2969,6 +3805,19 @@ function buildAvailableValueStock(variants) {
|
|
|
2969
3805
|
availableStock
|
|
2970
3806
|
};
|
|
2971
3807
|
}
|
|
3808
|
+
function buildProductSelectionAvailableValue(matrixValue, _productImages, selected, available, stock) {
|
|
3809
|
+
return {
|
|
3810
|
+
valueId: matrixValue.id,
|
|
3811
|
+
value: matrixValue.label,
|
|
3812
|
+
label: matrixValue.label,
|
|
3813
|
+
slug: matrixValue.slug ?? "",
|
|
3814
|
+
selected,
|
|
3815
|
+
available,
|
|
3816
|
+
exists: available,
|
|
3817
|
+
...stock,
|
|
3818
|
+
swatch: matrixValue.swatch ?? null
|
|
3819
|
+
};
|
|
3820
|
+
}
|
|
2972
3821
|
function getCandidateVariantsForValue(matrix, optionId, valueId, selectedValueIds) {
|
|
2973
3822
|
const selectedByOption = getSelectedValueByOptionId(matrix, selectedValueIds);
|
|
2974
3823
|
selectedByOption.set(optionId, valueId);
|
|
@@ -2981,17 +3830,25 @@ function getCandidateVariantsForValue(matrix, optionId, valueId, selectedValueId
|
|
|
2981
3830
|
function getResolutionContext(context) {
|
|
2982
3831
|
return {
|
|
2983
3832
|
images: context?.images ?? context?.detail?.images ?? [],
|
|
2984
|
-
listing: context?.listing ?? context?.detail?.listing ?? {}
|
|
3833
|
+
listing: context?.listing ?? context?.detail?.listing ?? {},
|
|
3834
|
+
primaryMediaItemId: context?.primaryMediaItemId ?? context?.detail?.primaryMediaItemId ?? null
|
|
2985
3835
|
};
|
|
2986
3836
|
}
|
|
2987
3837
|
function resolveProductSelectionFromMatrix(matrix, selection = {}, options, context) {
|
|
2988
|
-
const { images, listing } = getResolutionContext(context);
|
|
3838
|
+
const { images, listing, primaryMediaItemId } = getResolutionContext(context);
|
|
2989
3839
|
const effectiveSelection = hasExplicitSelection(selection) || listing.selectionHintVariant == null ? selection : { ...selection, variantId: listing.selectionHintVariant };
|
|
2990
|
-
|
|
3840
|
+
let normalizedSelection = normalizeProductSelectionFromMatrix(
|
|
2991
3841
|
matrix,
|
|
2992
3842
|
effectiveSelection,
|
|
2993
3843
|
options
|
|
2994
3844
|
);
|
|
3845
|
+
if (options?.fillDefaults) {
|
|
3846
|
+
normalizedSelection = buildFilledNormalizedSelection(
|
|
3847
|
+
matrix,
|
|
3848
|
+
normalizedSelection,
|
|
3849
|
+
listing
|
|
3850
|
+
);
|
|
3851
|
+
}
|
|
2995
3852
|
const matchingVariantEntries = getMatchingVariantEntries(
|
|
2996
3853
|
matrix,
|
|
2997
3854
|
normalizedSelection
|
|
@@ -3020,24 +3877,22 @@ function resolveProductSelectionFromMatrix(matrix, selection = {}, options, cont
|
|
|
3020
3877
|
);
|
|
3021
3878
|
return [
|
|
3022
3879
|
option.id,
|
|
3023
|
-
option.values.map(
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3880
|
+
option.values.map(
|
|
3881
|
+
(value) => buildProductSelectionAvailableValue(
|
|
3882
|
+
value,
|
|
3883
|
+
images,
|
|
3884
|
+
normalizedSelection.byOptionId[option.id] === value.id,
|
|
3885
|
+
availableValueIds.has(value.id),
|
|
3886
|
+
buildAvailableValueStock(
|
|
3887
|
+
getCandidateVariantsForValue(
|
|
3888
|
+
matrix,
|
|
3889
|
+
option.id,
|
|
3890
|
+
value.id,
|
|
3891
|
+
normalizedSelection.valueIds
|
|
3892
|
+
)
|
|
3035
3893
|
)
|
|
3036
|
-
)
|
|
3037
|
-
|
|
3038
|
-
thumbnail: value.thumbnail ?? null,
|
|
3039
|
-
images: value.images ?? null
|
|
3040
|
-
}))
|
|
3894
|
+
)
|
|
3895
|
+
)
|
|
3041
3896
|
];
|
|
3042
3897
|
})
|
|
3043
3898
|
);
|
|
@@ -3065,7 +3920,8 @@ function resolveProductSelectionFromMatrix(matrix, selection = {}, options, cont
|
|
|
3065
3920
|
images,
|
|
3066
3921
|
listing: {
|
|
3067
3922
|
primaryImage: listing.primaryImage ?? null
|
|
3068
|
-
}
|
|
3923
|
+
},
|
|
3924
|
+
primaryMediaItemId
|
|
3069
3925
|
},
|
|
3070
3926
|
selectedVariant,
|
|
3071
3927
|
matchingVariants,
|
|
@@ -3080,6 +3936,78 @@ function resolveProductSelection(detail, selection = {}, options) {
|
|
|
3080
3936
|
detail
|
|
3081
3937
|
});
|
|
3082
3938
|
}
|
|
3939
|
+
function selectNext(detail, current = {}, optionSlug, valueSlug, options) {
|
|
3940
|
+
const matrix = buildProductOptionMatrixFromDetail(detail);
|
|
3941
|
+
const listing = detail.listing ?? {};
|
|
3942
|
+
const normalizedCurrent = normalizeProductSelectionFromMatrix(
|
|
3943
|
+
matrix,
|
|
3944
|
+
current,
|
|
3945
|
+
options
|
|
3946
|
+
);
|
|
3947
|
+
const option = matrix.optionBySlug.get(optionSlug);
|
|
3948
|
+
if (!option) return normalizedCurrent;
|
|
3949
|
+
const valueMatches = option.values.filter(
|
|
3950
|
+
(candidate) => candidate.slug === valueSlug
|
|
3951
|
+
);
|
|
3952
|
+
if (valueMatches.length !== 1) return normalizedCurrent;
|
|
3953
|
+
const clickedValueId = valueMatches[0].id;
|
|
3954
|
+
const keepClickedSelection = () => {
|
|
3955
|
+
const selectedByOptionId = /* @__PURE__ */ new Map();
|
|
3956
|
+
selectedByOptionId.set(option.id, clickedValueId);
|
|
3957
|
+
for (const otherOptionId of matrix.optionIds) {
|
|
3958
|
+
if (otherOptionId === option.id) continue;
|
|
3959
|
+
const otherValueId = normalizedCurrent.byOptionId[otherOptionId];
|
|
3960
|
+
if (!otherValueId) continue;
|
|
3961
|
+
const constraintIds = normalizeSelectedValueIds(
|
|
3962
|
+
matrix,
|
|
3963
|
+
Array.from(selectedByOptionId.values())
|
|
3964
|
+
);
|
|
3965
|
+
const available = getAvailableOptionValues(
|
|
3966
|
+
matrix,
|
|
3967
|
+
otherOptionId,
|
|
3968
|
+
constraintIds
|
|
3969
|
+
);
|
|
3970
|
+
if (available.some((candidate) => candidate.id === otherValueId)) {
|
|
3971
|
+
selectedByOptionId.set(otherOptionId, otherValueId);
|
|
3972
|
+
}
|
|
3973
|
+
}
|
|
3974
|
+
return buildFilledNormalizedSelection(
|
|
3975
|
+
matrix,
|
|
3976
|
+
normalizedSelectionFromByOptionId(matrix, selectedByOptionId, null),
|
|
3977
|
+
listing
|
|
3978
|
+
);
|
|
3979
|
+
};
|
|
3980
|
+
const keepPriorSelection = () => {
|
|
3981
|
+
const selectedByOptionId = new Map(
|
|
3982
|
+
Object.entries(normalizedCurrent.byOptionId)
|
|
3983
|
+
);
|
|
3984
|
+
selectedByOptionId.delete(option.id);
|
|
3985
|
+
return buildFilledNormalizedSelection(
|
|
3986
|
+
matrix,
|
|
3987
|
+
normalizedSelectionFromByOptionId(matrix, selectedByOptionId, null),
|
|
3988
|
+
listing
|
|
3989
|
+
);
|
|
3990
|
+
};
|
|
3991
|
+
const clickedResult = keepClickedSelection();
|
|
3992
|
+
const clickedVariantId = resolveVariantIdForCompleteSelection(
|
|
3993
|
+
matrix,
|
|
3994
|
+
new Map(Object.entries(clickedResult.byOptionId))
|
|
3995
|
+
);
|
|
3996
|
+
const priorValueIds = Object.entries(normalizedCurrent.byOptionId).filter(([otherOptionId]) => otherOptionId !== option.id).map(([, valueId]) => valueId);
|
|
3997
|
+
const clickedAvailableWithPrior = priorValueIds.length === 0 || getAvailableOptionValues(matrix, option.id, priorValueIds).some(
|
|
3998
|
+
(candidate) => candidate.id === clickedValueId
|
|
3999
|
+
);
|
|
4000
|
+
if (clickedVariantId != null) {
|
|
4001
|
+
const priorClickedValue = normalizedCurrent.byOptionId[option.id];
|
|
4002
|
+
if (priorClickedValue != null && priorClickedValue !== clickedValueId) {
|
|
4003
|
+
return clickedResult;
|
|
4004
|
+
}
|
|
4005
|
+
if (clickedAvailableWithPrior) {
|
|
4006
|
+
return clickedResult;
|
|
4007
|
+
}
|
|
4008
|
+
}
|
|
4009
|
+
return keepPriorSelection();
|
|
4010
|
+
}
|
|
3083
4011
|
function isProductDetailImageMedia(value) {
|
|
3084
4012
|
return typeof value === "object" && value !== null;
|
|
3085
4013
|
}
|
|
@@ -3120,18 +4048,47 @@ function joinProductPath(basePath, slug, trailingSlash) {
|
|
|
3120
4048
|
function getProductHrefGroupSelection(group, matrix) {
|
|
3121
4049
|
if (!group) return null;
|
|
3122
4050
|
if (group.variantId != null) return { variantId: group.variantId };
|
|
3123
|
-
const listingVariantId = group.listing?.selectionHintVariant;
|
|
3124
4051
|
const optionId = group.optionId != null ? String(group.optionId) : group.optionSlug ? matrix?.optionBySlug.get(group.optionSlug)?.id : void 0;
|
|
3125
|
-
if (!optionId)
|
|
3126
|
-
return listingVariantId != null ? { variantId: listingVariantId } : null;
|
|
3127
|
-
}
|
|
4052
|
+
if (!optionId) return null;
|
|
3128
4053
|
const option = matrix?.optionById.get(optionId);
|
|
3129
4054
|
const optionValueId = group.optionValueId != null ? String(group.optionValueId) : group.optionValueSlug && option ? option.values.find((value) => value.slug === group.optionValueSlug)?.id : void 0;
|
|
3130
|
-
if (!optionValueId)
|
|
3131
|
-
return listingVariantId != null ? { variantId: listingVariantId } : null;
|
|
3132
|
-
}
|
|
4055
|
+
if (!optionValueId) return null;
|
|
3133
4056
|
return { byOptionId: { [optionId]: optionValueId } };
|
|
3134
4057
|
}
|
|
4058
|
+
function getProductHrefCodecOptions(options) {
|
|
4059
|
+
return options.emit != null ? { emit: options.emit } : void 0;
|
|
4060
|
+
}
|
|
4061
|
+
function appendGroupByOptionIdHrefParams(params, group, groupSelection, options) {
|
|
4062
|
+
const emit = resolveProductSelectionUrlEmit(options.emit);
|
|
4063
|
+
const byOptionId = groupSelection.byOptionId ?? {};
|
|
4064
|
+
const entries = Object.entries(byOptionId);
|
|
4065
|
+
if (entries.length === 0) return false;
|
|
4066
|
+
for (const [optionId, valueId] of entries) {
|
|
4067
|
+
const optionSlug = group?.optionSlug ?? options.matrix?.optionById.get(optionId)?.slug ?? null;
|
|
4068
|
+
const valueSlug = group?.optionValueSlug ?? options.matrix?.valueById.get(String(valueId))?.slug ?? null;
|
|
4069
|
+
if (emit === "slug-compat" && optionSlug && valueSlug && entries.length === 1) {
|
|
4070
|
+
params.set(`opt.${optionSlug}`, valueSlug);
|
|
4071
|
+
return true;
|
|
4072
|
+
}
|
|
4073
|
+
if (emit === "slug-compat" && options.matrix && appendSlugCompatSelectionParam(
|
|
4074
|
+
params,
|
|
4075
|
+
options.matrix,
|
|
4076
|
+
optionId,
|
|
4077
|
+
String(valueId)
|
|
4078
|
+
)) {
|
|
4079
|
+
continue;
|
|
4080
|
+
}
|
|
4081
|
+
appendCanonicalSelectionParam(params, optionId, String(valueId));
|
|
4082
|
+
}
|
|
4083
|
+
return params.size > 0;
|
|
4084
|
+
}
|
|
4085
|
+
function getPreferCompleteVariantFromHintSelection(group, options) {
|
|
4086
|
+
if (!options.preferCompleteVariantFromHint) return null;
|
|
4087
|
+
if (group?.optionValueId != null || group?.optionValueSlug) return null;
|
|
4088
|
+
const hintVariantId = group?.listing?.selectionHintVariant;
|
|
4089
|
+
if (hintVariantId == null) return null;
|
|
4090
|
+
return { variantId: hintVariantId };
|
|
4091
|
+
}
|
|
3135
4092
|
function buildProductHref(product, group, options = {}) {
|
|
3136
4093
|
const path = joinProductPath(
|
|
3137
4094
|
options.basePath ?? "/products",
|
|
@@ -3140,23 +4097,46 @@ function buildProductHref(product, group, options = {}) {
|
|
|
3140
4097
|
);
|
|
3141
4098
|
const params = new URLSearchParams();
|
|
3142
4099
|
if (options.detail && options.selection) {
|
|
3143
|
-
const selection = stringifyProductSelection(
|
|
4100
|
+
const selection = stringifyProductSelection(
|
|
4101
|
+
options.detail,
|
|
4102
|
+
options.selection,
|
|
4103
|
+
getProductHrefCodecOptions(options)
|
|
4104
|
+
);
|
|
3144
4105
|
return selection ? `${path}?${selection}` : path;
|
|
3145
4106
|
}
|
|
4107
|
+
const preferVariantSelection = getPreferCompleteVariantFromHintSelection(
|
|
4108
|
+
group,
|
|
4109
|
+
options
|
|
4110
|
+
);
|
|
4111
|
+
if (preferVariantSelection) {
|
|
4112
|
+
if (options.detail) {
|
|
4113
|
+
const selection = stringifyProductSelection(
|
|
4114
|
+
options.detail,
|
|
4115
|
+
preferVariantSelection,
|
|
4116
|
+
getProductHrefCodecOptions(options)
|
|
4117
|
+
);
|
|
4118
|
+
return selection ? `${path}?${selection}` : path;
|
|
4119
|
+
}
|
|
4120
|
+
if (preferVariantSelection.variantId != null) {
|
|
4121
|
+
params.set("variant", String(preferVariantSelection.variantId));
|
|
4122
|
+
return `${path}?${params.toString()}`;
|
|
4123
|
+
}
|
|
4124
|
+
}
|
|
3146
4125
|
const groupSelection = getProductHrefGroupSelection(group, options.matrix);
|
|
3147
4126
|
if (groupSelection) {
|
|
3148
4127
|
if (options.detail) {
|
|
3149
|
-
const selection = stringifyProductSelection(
|
|
4128
|
+
const selection = stringifyProductSelection(
|
|
4129
|
+
options.detail,
|
|
4130
|
+
groupSelection,
|
|
4131
|
+
getProductHrefCodecOptions(options)
|
|
4132
|
+
);
|
|
3150
4133
|
return selection ? `${path}?${selection}` : path;
|
|
3151
4134
|
}
|
|
3152
4135
|
if (groupSelection.variantId != null) {
|
|
3153
4136
|
params.set("variant", String(groupSelection.variantId));
|
|
3154
4137
|
return `${path}?${params.toString()}`;
|
|
3155
4138
|
}
|
|
3156
|
-
|
|
3157
|
-
if (selectionEntry) {
|
|
3158
|
-
const [optionId, valueId] = selectionEntry;
|
|
3159
|
-
params.set(`opt.${optionId}`, String(valueId));
|
|
4139
|
+
if (appendGroupByOptionIdHrefParams(params, group, groupSelection, options)) {
|
|
3160
4140
|
return `${path}?${params.toString()}`;
|
|
3161
4141
|
}
|
|
3162
4142
|
}
|
|
@@ -3183,6 +4163,26 @@ function isVariantAvailableForSale(variant) {
|
|
|
3183
4163
|
if (variant.isUnlimited) return true;
|
|
3184
4164
|
return (variant.stock ?? 0) - (variant.reservedStock ?? 0) > 0;
|
|
3185
4165
|
}
|
|
4166
|
+
function sortVariantsForMediaSelection(variants) {
|
|
4167
|
+
const orderedVariants = [...variants].sort(compareVariantOrder);
|
|
4168
|
+
const activeVariants = orderedVariants.filter(
|
|
4169
|
+
(variant) => variant.isActive !== false
|
|
4170
|
+
);
|
|
4171
|
+
const availableVariants = activeVariants.filter(isVariantAvailableForSale);
|
|
4172
|
+
const unavailableActiveVariants = activeVariants.filter(
|
|
4173
|
+
(variant) => !isVariantAvailableForSale(variant)
|
|
4174
|
+
);
|
|
4175
|
+
return [...availableVariants, ...unavailableActiveVariants];
|
|
4176
|
+
}
|
|
4177
|
+
function variantHasPoolMedia(variant, productMediaPool) {
|
|
4178
|
+
if (!variant?.images?.length) return false;
|
|
4179
|
+
return variant.images.some((image) => {
|
|
4180
|
+
const imageId = getRelationID(image);
|
|
4181
|
+
return Boolean(
|
|
4182
|
+
imageId && productMediaPool.some((poolItem) => getRelationID(poolItem) === imageId)
|
|
4183
|
+
);
|
|
4184
|
+
});
|
|
4185
|
+
}
|
|
3186
4186
|
function getMinMax(values) {
|
|
3187
4187
|
const numbers = values.filter(
|
|
3188
4188
|
(value) => typeof value === "number"
|
|
@@ -3208,11 +4208,28 @@ function buildProductListingProjection(product, variants) {
|
|
|
3208
4208
|
const { min: minCompareAtPrice, max: maxCompareAtPrice } = getMinMax(
|
|
3209
4209
|
activeVariants.map((variant) => variant.compareAtPrice)
|
|
3210
4210
|
);
|
|
3211
|
-
const
|
|
3212
|
-
const
|
|
4211
|
+
const productMediaPool = product?.images ?? [];
|
|
4212
|
+
const selectionHintHasPoolMedia = variantHasPoolMedia(
|
|
4213
|
+
selectionHintVariant,
|
|
4214
|
+
productMediaPool
|
|
4215
|
+
);
|
|
4216
|
+
const mediaSelectionVariants = sortVariantsForMediaSelection(variants);
|
|
4217
|
+
const resolvedProductMedia = resolveProductSelectionMedia({
|
|
4218
|
+
productMediaPool,
|
|
4219
|
+
productPrimaryMediaItemId: getRelationID(product?.primaryMediaItemId),
|
|
4220
|
+
selectedVariant: selectionHintVariant && selectionHintHasPoolMedia ? {
|
|
4221
|
+
id: selectionHintVariant.id,
|
|
4222
|
+
images: selectionHintVariant.images
|
|
4223
|
+
} : null,
|
|
4224
|
+
matchingVariants: selectionHintHasPoolMedia ? [] : mediaSelectionVariants
|
|
4225
|
+
});
|
|
3213
4226
|
return {
|
|
3214
4227
|
selectionHintVariant: getRelationID(selectionHintVariant?.id) ?? null,
|
|
3215
|
-
primaryImage:
|
|
4228
|
+
primaryImage: resolveGenericListingPrimaryImage(
|
|
4229
|
+
product,
|
|
4230
|
+
resolvedProductMedia.primaryImage,
|
|
4231
|
+
resolvedProductMedia.source
|
|
4232
|
+
),
|
|
3216
4233
|
minPrice,
|
|
3217
4234
|
maxPrice,
|
|
3218
4235
|
minCompareAtPrice,
|
|
@@ -3231,7 +4248,33 @@ function buildProductListingCard(item, options = {}) {
|
|
|
3231
4248
|
variants,
|
|
3232
4249
|
selectionHintVariant
|
|
3233
4250
|
);
|
|
3234
|
-
const
|
|
4251
|
+
const productMediaPool = mediaArray2(product.images);
|
|
4252
|
+
const representativeHasPoolMedia = Boolean(
|
|
4253
|
+
representativeVariant?.images?.some(
|
|
4254
|
+
(image) => productMediaPool.some(
|
|
4255
|
+
(poolItem) => getRelationID(poolItem) === getRelationID(image)
|
|
4256
|
+
)
|
|
4257
|
+
)
|
|
4258
|
+
);
|
|
4259
|
+
const resolvedPrimaryMedia = resolveProductSelectionMedia(
|
|
4260
|
+
{
|
|
4261
|
+
productMediaPool,
|
|
4262
|
+
productPrimaryMediaItemId: getRelationID(product.primaryMediaItemId),
|
|
4263
|
+
selectedVariant: representativeHasPoolMedia ? representativeVariant : null,
|
|
4264
|
+
matchingVariants: representativeHasPoolMedia ? [] : variants
|
|
4265
|
+
}
|
|
4266
|
+
);
|
|
4267
|
+
const listingPrimaryPointer = resolveListingPrimaryImagePointer({
|
|
4268
|
+
productMediaPool,
|
|
4269
|
+
productPrimaryMediaItemId: getRelationID(product.primaryMediaItemId),
|
|
4270
|
+
productThumbnail: product.thumbnail ?? null,
|
|
4271
|
+
listingPrimaryImage: product.listing?.primaryImage ?? null,
|
|
4272
|
+
resolvedPrimary: resolvedPrimaryMedia.primaryImage,
|
|
4273
|
+
resolvedSource: resolvedPrimaryMedia.source
|
|
4274
|
+
});
|
|
4275
|
+
const listingPrimaryMedia = listingPrimaryPointer ? productMediaPool.find(
|
|
4276
|
+
(item2) => getRelationID(item2) === listingPrimaryPointer
|
|
4277
|
+
) ?? resolvedPrimaryMedia.primaryImage ?? null : null;
|
|
3235
4278
|
const priceRange = aggregateListingPriceRange(groups);
|
|
3236
4279
|
const availableForSale = groups.some(
|
|
3237
4280
|
(group) => group.listing.availableForSale
|
|
@@ -3246,7 +4289,7 @@ function buildProductListingCard(item, options = {}) {
|
|
|
3246
4289
|
),
|
|
3247
4290
|
title: product.title,
|
|
3248
4291
|
representativeVariant,
|
|
3249
|
-
primaryImage,
|
|
4292
|
+
primaryImage: listingPrimaryMedia,
|
|
3250
4293
|
priceRange,
|
|
3251
4294
|
availableForSale,
|
|
3252
4295
|
swatches
|
|
@@ -3294,17 +4337,16 @@ function aggregateListingPriceRange(groups) {
|
|
|
3294
4337
|
};
|
|
3295
4338
|
}
|
|
3296
4339
|
function buildListingSwatch(product, group, options) {
|
|
3297
|
-
const thumbnail = firstMedia(group.optionValueThumbnail) ?? firstMedia(group.optionValueImages) ?? null;
|
|
3298
4340
|
return {
|
|
3299
4341
|
optionId: group.optionId,
|
|
3300
4342
|
optionValueId: group.optionValueId,
|
|
3301
4343
|
label: group.optionValueLabel,
|
|
3302
|
-
|
|
3303
|
-
thumbnail,
|
|
4344
|
+
swatch: group.optionValueSwatch ?? null,
|
|
3304
4345
|
href: buildProductHref(
|
|
3305
4346
|
{ slug: product.slug },
|
|
3306
4347
|
{
|
|
3307
4348
|
optionId: group.optionId,
|
|
4349
|
+
optionSlug: group.optionSlug,
|
|
3308
4350
|
optionValueId: group.optionValueId,
|
|
3309
4351
|
optionValueSlug: group.optionValueSlug,
|
|
3310
4352
|
listing: group.listing
|
|
@@ -3339,19 +4381,34 @@ function buildProductListingGroupsByOption(args) {
|
|
|
3339
4381
|
return [];
|
|
3340
4382
|
}
|
|
3341
4383
|
const listingBase = buildProductListingProjection(void 0, variants);
|
|
3342
|
-
const
|
|
3343
|
-
const
|
|
3344
|
-
|
|
4384
|
+
const orderedVariants = sortVariantsForMediaSelection(variants);
|
|
4385
|
+
const productMediaPool = (args.product?.images ?? []).filter(
|
|
4386
|
+
(image) => image != null && typeof image === "object"
|
|
4387
|
+
);
|
|
4388
|
+
const resolvedMedia = resolveProductSelectionMedia({
|
|
4389
|
+
productMediaPool,
|
|
4390
|
+
productPrimaryMediaItemId: extractEntityId(
|
|
4391
|
+
args.product?.primaryMediaItemId ?? null
|
|
4392
|
+
),
|
|
4393
|
+
selectedVariant: null,
|
|
4394
|
+
matchingVariants: orderedVariants,
|
|
4395
|
+
selectedOptionValues: [
|
|
4396
|
+
{
|
|
4397
|
+
id: value.id,
|
|
4398
|
+
swatch: normalizeMatrixSwatch(value.swatch)
|
|
4399
|
+
}
|
|
4400
|
+
]
|
|
4401
|
+
});
|
|
4402
|
+
const groupPrimaryImage = extractEntityId(resolvedMedia.primaryImage) ?? getFirstAvailableVariantPrimaryImage(variants) ?? extractEntityId(args.product?.thumbnail) ?? getFirstMediaId(args.product?.images);
|
|
3345
4403
|
return [
|
|
3346
4404
|
{
|
|
3347
4405
|
optionId: primaryOption.id,
|
|
3348
4406
|
optionTitle: primaryOption.title,
|
|
4407
|
+
optionSlug: primaryOption.slug,
|
|
3349
4408
|
optionValueId: value.id,
|
|
3350
4409
|
optionValueLabel: value.label,
|
|
3351
4410
|
optionValueSlug: value.slug,
|
|
3352
|
-
|
|
3353
|
-
optionValueThumbnail: value.thumbnail ?? null,
|
|
3354
|
-
optionValueImages: value.images ?? null,
|
|
4411
|
+
optionValueSwatch: value.swatch ?? null,
|
|
3355
4412
|
variantIds: variants.map((variant) => String(variant.id)),
|
|
3356
4413
|
variantCount: variants.length,
|
|
3357
4414
|
variants,
|
|
@@ -3364,6 +4421,162 @@ function buildProductListingGroupsByOption(args) {
|
|
|
3364
4421
|
});
|
|
3365
4422
|
}
|
|
3366
4423
|
|
|
4424
|
+
// src/utils/product-media.ts
|
|
4425
|
+
function mediaPointerOptionValues(values) {
|
|
4426
|
+
return (values ?? []).filter((value) => value != null && value !== "").map((value) => ({
|
|
4427
|
+
swatch: {
|
|
4428
|
+
type: "media",
|
|
4429
|
+
mediaItemId: value
|
|
4430
|
+
}
|
|
4431
|
+
}));
|
|
4432
|
+
}
|
|
4433
|
+
function resolveProductMedia(input) {
|
|
4434
|
+
const resolved = resolveProductSelectionMedia({
|
|
4435
|
+
...input,
|
|
4436
|
+
selectedVariant: input.selectedVariant ?? (input.variantFeaturedMediaItemId ? { images: [input.variantFeaturedMediaItemId] } : null),
|
|
4437
|
+
selectedOptionValues: input.selectedOptionValues ?? mediaPointerOptionValues(input.selectedOptionValueMediaItemIds)
|
|
4438
|
+
});
|
|
4439
|
+
if (resolved.source !== "none") {
|
|
4440
|
+
return {
|
|
4441
|
+
...resolved,
|
|
4442
|
+
source: resolved.source === "variant_media_selected" ? "variant_featured" : resolved.source
|
|
4443
|
+
};
|
|
4444
|
+
}
|
|
4445
|
+
const display = resolveProductDisplayMedia({
|
|
4446
|
+
productMediaPool: input.productMediaPool,
|
|
4447
|
+
productPrimaryMediaItemId: input.productPrimaryMediaItemId
|
|
4448
|
+
});
|
|
4449
|
+
return {
|
|
4450
|
+
primaryImage: display.primaryImage,
|
|
4451
|
+
images: display.images,
|
|
4452
|
+
source: display.source
|
|
4453
|
+
};
|
|
4454
|
+
}
|
|
4455
|
+
|
|
4456
|
+
// src/utils/product-gallery.ts
|
|
4457
|
+
function mediaId(value) {
|
|
4458
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
4459
|
+
return String(value);
|
|
4460
|
+
}
|
|
4461
|
+
if (typeof value === "object" && value !== null && "id" in value) {
|
|
4462
|
+
const id = value.id;
|
|
4463
|
+
if (typeof id === "string" || typeof id === "number") return String(id);
|
|
4464
|
+
}
|
|
4465
|
+
return null;
|
|
4466
|
+
}
|
|
4467
|
+
function relationshipIds(values) {
|
|
4468
|
+
if (!Array.isArray(values)) return [];
|
|
4469
|
+
return values.map((value) => mediaId(value)).filter((value) => Boolean(value));
|
|
4470
|
+
}
|
|
4471
|
+
function buildPoolById2(pool) {
|
|
4472
|
+
const poolById = /* @__PURE__ */ new Map();
|
|
4473
|
+
for (const item of pool) {
|
|
4474
|
+
const id = mediaId(item);
|
|
4475
|
+
if (id) poolById.set(id, item);
|
|
4476
|
+
}
|
|
4477
|
+
return poolById;
|
|
4478
|
+
}
|
|
4479
|
+
function mediaSetItemsInPool(mediaSet, poolById) {
|
|
4480
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4481
|
+
const items = [];
|
|
4482
|
+
const primaryId = mediaId(mediaSet.primaryMediaItemId);
|
|
4483
|
+
if (primaryId) {
|
|
4484
|
+
const primary = poolById.get(primaryId);
|
|
4485
|
+
if (primary) {
|
|
4486
|
+
seen.add(primaryId);
|
|
4487
|
+
items.push(primary);
|
|
4488
|
+
}
|
|
4489
|
+
}
|
|
4490
|
+
for (const itemId of relationshipIds(mediaSet.items)) {
|
|
4491
|
+
if (seen.has(itemId)) continue;
|
|
4492
|
+
const item = poolById.get(itemId);
|
|
4493
|
+
if (!item) continue;
|
|
4494
|
+
seen.add(itemId);
|
|
4495
|
+
items.push(item);
|
|
4496
|
+
}
|
|
4497
|
+
return items;
|
|
4498
|
+
}
|
|
4499
|
+
function resolveLegacyMediaSet(input) {
|
|
4500
|
+
if (!Array.isArray(input.mediaSets)) return null;
|
|
4501
|
+
const pool = input.productMediaPool ?? input.pool ?? [];
|
|
4502
|
+
const poolById = buildPoolById2(pool);
|
|
4503
|
+
const selectedVariantId = mediaId(input.selectedVariantId);
|
|
4504
|
+
if (selectedVariantId) {
|
|
4505
|
+
const exactSet = input.mediaSets.find(
|
|
4506
|
+
(set) => set.matchType === "exact-variant" && relationshipIds(set.variantIds).includes(selectedVariantId)
|
|
4507
|
+
);
|
|
4508
|
+
if (exactSet) {
|
|
4509
|
+
const images = mediaSetItemsInPool(exactSet, poolById);
|
|
4510
|
+
if (images.length > 0) {
|
|
4511
|
+
return {
|
|
4512
|
+
primaryImage: images[0] ?? null,
|
|
4513
|
+
images,
|
|
4514
|
+
source: "exact_variant_set"
|
|
4515
|
+
};
|
|
4516
|
+
}
|
|
4517
|
+
}
|
|
4518
|
+
}
|
|
4519
|
+
const selectedOptionValueIds = new Set(
|
|
4520
|
+
relationshipIds(input.selectedOptionValueIds)
|
|
4521
|
+
);
|
|
4522
|
+
const optionSetMatches = input.mediaSets.filter((set) => set.matchType === "option-values").map((set) => {
|
|
4523
|
+
const optionValueIds = relationshipIds(set.optionValueIds);
|
|
4524
|
+
if (optionValueIds.length === 0) return null;
|
|
4525
|
+
if (!optionValueIds.every((id) => selectedOptionValueIds.has(id))) {
|
|
4526
|
+
return null;
|
|
4527
|
+
}
|
|
4528
|
+
const images = mediaSetItemsInPool(set, poolById);
|
|
4529
|
+
if (images.length === 0) return null;
|
|
4530
|
+
return { optionValueCount: optionValueIds.length, images };
|
|
4531
|
+
}).filter(
|
|
4532
|
+
(match) => Boolean(match)
|
|
4533
|
+
).sort((a, b) => b.optionValueCount - a.optionValueCount);
|
|
4534
|
+
if (optionSetMatches.length > 0) {
|
|
4535
|
+
const images = optionSetMatches[0].images;
|
|
4536
|
+
return {
|
|
4537
|
+
primaryImage: images[0] ?? null,
|
|
4538
|
+
images,
|
|
4539
|
+
source: "option_value_set"
|
|
4540
|
+
};
|
|
4541
|
+
}
|
|
4542
|
+
const defaultSet = input.mediaSets.find((set) => set.matchType === "default");
|
|
4543
|
+
if (defaultSet) {
|
|
4544
|
+
const images = mediaSetItemsInPool(defaultSet, poolById);
|
|
4545
|
+
if (images.length > 0) {
|
|
4546
|
+
return {
|
|
4547
|
+
primaryImage: images[0] ?? null,
|
|
4548
|
+
images,
|
|
4549
|
+
source: "default_set"
|
|
4550
|
+
};
|
|
4551
|
+
}
|
|
4552
|
+
}
|
|
4553
|
+
return {
|
|
4554
|
+
primaryImage: null,
|
|
4555
|
+
images: [],
|
|
4556
|
+
source: "none"
|
|
4557
|
+
};
|
|
4558
|
+
}
|
|
4559
|
+
function resolveProductGallery(input) {
|
|
4560
|
+
const legacyResolved = resolveLegacyMediaSet(input);
|
|
4561
|
+
if (legacyResolved && legacyResolved.source !== "none") return legacyResolved;
|
|
4562
|
+
const selectedVariantId = mediaId(input.selectedVariantId);
|
|
4563
|
+
const selectedOptionValueIds = relationshipIds(input.selectedOptionValueIds);
|
|
4564
|
+
const selection = resolveProductSelectionMedia({
|
|
4565
|
+
...input,
|
|
4566
|
+
productMediaPool: input.productMediaPool ?? input.pool ?? null,
|
|
4567
|
+
selectedVariant: input.selectedVariant ?? (selectedVariantId ? { id: selectedVariantId } : null),
|
|
4568
|
+
selectedOptionValues: input.selectedOptionValues ?? selectedOptionValueIds.map((id) => ({ id }))
|
|
4569
|
+
});
|
|
4570
|
+
if (selection.source !== "none") {
|
|
4571
|
+
return selection;
|
|
4572
|
+
}
|
|
4573
|
+
return resolveProductDisplayMedia({
|
|
4574
|
+
productMediaPool: input.productMediaPool ?? input.pool ?? null,
|
|
4575
|
+
productPrimaryMediaItemId: input.productPrimaryMediaItemId,
|
|
4576
|
+
listingPrimaryImage: input.listingPrimaryImage
|
|
4577
|
+
});
|
|
4578
|
+
}
|
|
4579
|
+
|
|
3367
4580
|
// src/utils/image.ts
|
|
3368
4581
|
var IMAGE_SIZES = [384, 768, 1536];
|
|
3369
4582
|
function getImageUrl(image, displayWidth, dpr = 1) {
|
|
@@ -3670,6 +4883,7 @@ export {
|
|
|
3670
4883
|
CustomerAuth,
|
|
3671
4884
|
CustomerNamespace,
|
|
3672
4885
|
DiscountApi,
|
|
4886
|
+
EventsClient,
|
|
3673
4887
|
GoneError,
|
|
3674
4888
|
IMAGE_SIZES,
|
|
3675
4889
|
INTERNAL_COLLECTIONS,
|
|
@@ -3677,6 +4891,8 @@ export {
|
|
|
3677
4891
|
NotFoundError,
|
|
3678
4892
|
ORDER_CHANGED_EVENT_TYPE,
|
|
3679
4893
|
OrderApi,
|
|
4894
|
+
PRODUCT_UPSERT_READONLY_FIELD_REASON,
|
|
4895
|
+
PRODUCT_UPSERT_UNKNOWN_FIELD_REASON,
|
|
3680
4896
|
PermissionError,
|
|
3681
4897
|
ProductApi,
|
|
3682
4898
|
ProductSelectionCodecError,
|
|
@@ -3736,6 +4952,7 @@ export {
|
|
|
3736
4952
|
isNotFoundError,
|
|
3737
4953
|
isOrderChangedWebhookEvent,
|
|
3738
4954
|
isPermissionError,
|
|
4955
|
+
isProductUpsertFieldValidationErrorBody,
|
|
3739
4956
|
isRateLimitError,
|
|
3740
4957
|
isSDKError,
|
|
3741
4958
|
isServiceUnavailableError,
|
|
@@ -3745,14 +4962,22 @@ export {
|
|
|
3745
4962
|
isValidationError,
|
|
3746
4963
|
isWebhookCollection,
|
|
3747
4964
|
isWebhookOperation,
|
|
4965
|
+
mergeProductDetailWithStock,
|
|
3748
4966
|
normalizeProductSelection,
|
|
3749
4967
|
normalizeProductSelectionFromMatrix,
|
|
3750
4968
|
normalizeSelectedValueIds,
|
|
3751
4969
|
parseProductSelection,
|
|
4970
|
+
resolveListingPrimaryImagePointer,
|
|
4971
|
+
resolveProductDisplayMedia,
|
|
4972
|
+
resolveProductGallery,
|
|
4973
|
+
resolveProductMedia,
|
|
3752
4974
|
resolveProductSelection,
|
|
3753
4975
|
resolveProductSelectionFromMatrix,
|
|
4976
|
+
resolveProductSelectionMedia,
|
|
3754
4977
|
resolveRelation,
|
|
3755
4978
|
resolveVariantForSelection,
|
|
4979
|
+
selectNext,
|
|
4980
|
+
selectedSwatchMediaItemId,
|
|
3756
4981
|
stringifyProductSelection
|
|
3757
4982
|
};
|
|
3758
4983
|
//# sourceMappingURL=index.js.map
|