@01.software/sdk 0.21.0 → 0.23.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 +97 -71
- package/dist/analytics.cjs.map +1 -1
- package/dist/analytics.js.map +1 -1
- package/dist/const-CMdmNgEs.d.ts +34 -0
- package/dist/const-Cgd4op4V.d.cts +34 -0
- package/dist/index.cjs +248 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -1379
- package/dist/index.d.ts +13 -1379
- package/dist/index.js +248 -27
- package/dist/index.js.map +1 -1
- package/dist/{payload-types-D7lnu9By.d.cts → payload-types-D8-G1PiT.d.cts} +205 -10
- package/dist/{payload-types-D7lnu9By.d.ts → payload-types-D8-G1PiT.d.ts} +205 -10
- 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-D7FcHj7J.d.ts +1420 -0
- package/dist/server-DJcDyOmM.d.cts +1420 -0
- package/dist/server.cjs +2057 -0
- package/dist/server.cjs.map +1 -0
- package/dist/server.d.cts +7 -0
- package/dist/server.d.ts +7 -0
- package/dist/server.js +2052 -0
- package/dist/server.js.map +1 -0
- package/dist/types-BQqfXbB2.d.ts +39 -0
- package/dist/types-C_kwEIvY.d.cts +39 -0
- 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.d.cts +42 -3
- package/dist/webhook.d.ts +42 -3
- package/package.json +15 -4
- package/dist/const-BApEF1Hu.d.cts +0 -24
- package/dist/const-BNJRuk3V.d.ts +0 -24
- package/dist/webhook-C4BwXP5T.d.cts +0 -61
- package/dist/webhook-C6vne8Ve.d.ts +0 -61
package/dist/index.js
CHANGED
|
@@ -63,6 +63,46 @@ function resolveMetaImage(ref) {
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
// src/core/collection/query-builder.ts
|
|
66
|
+
var ReadOnlyCollectionQueryBuilder = class {
|
|
67
|
+
constructor(api, collection) {
|
|
68
|
+
this.api = api;
|
|
69
|
+
this.collection = collection;
|
|
70
|
+
}
|
|
71
|
+
async find(options) {
|
|
72
|
+
return this.api.requestFind(
|
|
73
|
+
`/api/${String(this.collection)}`,
|
|
74
|
+
options
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
async findById(id, options) {
|
|
78
|
+
return this.api.requestFindById(
|
|
79
|
+
`/api/${String(this.collection)}/${String(id)}`,
|
|
80
|
+
options
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
async count(options) {
|
|
84
|
+
return this.api.requestCount(
|
|
85
|
+
`/api/${String(this.collection)}/count`,
|
|
86
|
+
options
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
async findMetadata(options, metadataOptions) {
|
|
90
|
+
const { docs } = await this.find({ ...options, limit: 1, depth: 1 });
|
|
91
|
+
const doc = docs[0];
|
|
92
|
+
if (!doc) return null;
|
|
93
|
+
return generateMetadata(
|
|
94
|
+
extractSeo(doc),
|
|
95
|
+
metadataOptions
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
async findMetadataById(id, metadataOptions) {
|
|
99
|
+
const doc = await this.findById(id, { depth: 1 });
|
|
100
|
+
return generateMetadata(
|
|
101
|
+
extractSeo(doc),
|
|
102
|
+
metadataOptions
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
66
106
|
var CollectionQueryBuilder = class {
|
|
67
107
|
constructor(api, collection) {
|
|
68
108
|
this.api = api;
|
|
@@ -194,6 +234,8 @@ var CollectionQueryBuilder = class {
|
|
|
194
234
|
);
|
|
195
235
|
}
|
|
196
236
|
};
|
|
237
|
+
var ServerCollectionQueryBuilder = class extends CollectionQueryBuilder {
|
|
238
|
+
};
|
|
197
239
|
|
|
198
240
|
// src/core/collection/http-client.ts
|
|
199
241
|
import { stringify } from "qs-esm";
|
|
@@ -236,8 +278,8 @@ var NetworkError = class extends SDKError {
|
|
|
236
278
|
}
|
|
237
279
|
};
|
|
238
280
|
var ValidationError = class extends SDKError {
|
|
239
|
-
constructor(message, details, userMessage, suggestion) {
|
|
240
|
-
super("VALIDATION_ERROR", message,
|
|
281
|
+
constructor(message, details, userMessage, suggestion, status = 400) {
|
|
282
|
+
super("VALIDATION_ERROR", message, status, details, userMessage, suggestion);
|
|
241
283
|
this.name = "ValidationError";
|
|
242
284
|
}
|
|
243
285
|
};
|
|
@@ -366,7 +408,7 @@ function isRateLimitError(error) {
|
|
|
366
408
|
return error instanceof RateLimitError;
|
|
367
409
|
}
|
|
368
410
|
var createNetworkError = (message, status, details, userMessage, suggestion) => new NetworkError(message, status, details, userMessage, suggestion);
|
|
369
|
-
var createValidationError = (message, details, userMessage, suggestion) => new ValidationError(message, details, userMessage, suggestion);
|
|
411
|
+
var createValidationError = (message, details, userMessage, suggestion, status) => new ValidationError(message, details, userMessage, suggestion, status);
|
|
370
412
|
var createApiError = (message, status, details, userMessage, suggestion) => new ApiError(message, status, details, userMessage, suggestion);
|
|
371
413
|
var createConfigError = (message, details, userMessage, suggestion) => new ConfigError(message, details, userMessage, suggestion);
|
|
372
414
|
var createTimeoutError = (message, details, userMessage, suggestion) => new TimeoutError(message, details, userMessage, suggestion);
|
|
@@ -377,6 +419,16 @@ var createNotFoundError = (message, details, userMessage, suggestion, requestId)
|
|
|
377
419
|
var createConflictError = (message, details, userMessage, suggestion, requestId) => new ConflictError(message, details, userMessage, suggestion, requestId);
|
|
378
420
|
var createRateLimitError = (message, retryAfter, details, userMessage, suggestion, requestId) => new RateLimitError(message, retryAfter, details, userMessage, suggestion, requestId);
|
|
379
421
|
|
|
422
|
+
// src/core/internal/utils/credentials.ts
|
|
423
|
+
function requirePublishableKeyForSecret(apiName, publishableKey, secretKey) {
|
|
424
|
+
if (secretKey && !publishableKey) {
|
|
425
|
+
throw createConfigError(
|
|
426
|
+
`publishableKey is required for ${apiName} when secretKey is used. It is sent as X-Publishable-Key for tenant routing, rate limiting, and quota enforcement.`
|
|
427
|
+
);
|
|
428
|
+
}
|
|
429
|
+
return publishableKey ?? "";
|
|
430
|
+
}
|
|
431
|
+
|
|
380
432
|
// src/core/client/types.ts
|
|
381
433
|
function resolveApiUrl() {
|
|
382
434
|
if (typeof process !== "undefined" && process.env) {
|
|
@@ -391,7 +443,7 @@ function resolveApiUrl() {
|
|
|
391
443
|
// src/core/internal/utils/http.ts
|
|
392
444
|
var DEFAULT_TIMEOUT = 3e4;
|
|
393
445
|
var DEFAULT_RETRYABLE_STATUSES = [408, 429, 500, 502, 503, 504];
|
|
394
|
-
var NON_RETRYABLE_STATUSES = [400, 401, 403, 404, 422];
|
|
446
|
+
var NON_RETRYABLE_STATUSES = [400, 401, 403, 404, 409, 422];
|
|
395
447
|
var SAFE_METHODS = ["GET", "HEAD", "OPTIONS"];
|
|
396
448
|
function debugLog(debug, type, message, data) {
|
|
397
449
|
if (!debug) return;
|
|
@@ -474,6 +526,80 @@ function attachRequestId(err, id) {
|
|
|
474
526
|
if (id) err.requestId = id;
|
|
475
527
|
return err;
|
|
476
528
|
}
|
|
529
|
+
function createHttpStatusError(status, parsed, details, requestId) {
|
|
530
|
+
const errorDetails = {
|
|
531
|
+
...details,
|
|
532
|
+
...parsed.errors && { errors: parsed.errors },
|
|
533
|
+
...parsed.body && { body: parsed.body }
|
|
534
|
+
};
|
|
535
|
+
const suggestion = getErrorSuggestion(status);
|
|
536
|
+
if (status === 400 || status === 422) {
|
|
537
|
+
return attachRequestId(
|
|
538
|
+
createValidationError(
|
|
539
|
+
parsed.errorMessage,
|
|
540
|
+
errorDetails,
|
|
541
|
+
parsed.userMessage,
|
|
542
|
+
suggestion,
|
|
543
|
+
status
|
|
544
|
+
),
|
|
545
|
+
requestId
|
|
546
|
+
);
|
|
547
|
+
}
|
|
548
|
+
if (status === 401) {
|
|
549
|
+
return attachRequestId(
|
|
550
|
+
createAuthError(
|
|
551
|
+
parsed.errorMessage,
|
|
552
|
+
errorDetails,
|
|
553
|
+
parsed.userMessage,
|
|
554
|
+
suggestion
|
|
555
|
+
),
|
|
556
|
+
requestId
|
|
557
|
+
);
|
|
558
|
+
}
|
|
559
|
+
if (status === 403) {
|
|
560
|
+
return attachRequestId(
|
|
561
|
+
createPermissionError(
|
|
562
|
+
parsed.errorMessage,
|
|
563
|
+
errorDetails,
|
|
564
|
+
parsed.userMessage,
|
|
565
|
+
suggestion
|
|
566
|
+
),
|
|
567
|
+
requestId
|
|
568
|
+
);
|
|
569
|
+
}
|
|
570
|
+
if (status === 404) {
|
|
571
|
+
return attachRequestId(
|
|
572
|
+
createNotFoundError(
|
|
573
|
+
parsed.errorMessage,
|
|
574
|
+
errorDetails,
|
|
575
|
+
parsed.userMessage,
|
|
576
|
+
suggestion
|
|
577
|
+
),
|
|
578
|
+
requestId
|
|
579
|
+
);
|
|
580
|
+
}
|
|
581
|
+
if (status === 409) {
|
|
582
|
+
return attachRequestId(
|
|
583
|
+
createConflictError(
|
|
584
|
+
parsed.errorMessage,
|
|
585
|
+
errorDetails,
|
|
586
|
+
parsed.userMessage,
|
|
587
|
+
suggestion
|
|
588
|
+
),
|
|
589
|
+
requestId
|
|
590
|
+
);
|
|
591
|
+
}
|
|
592
|
+
return attachRequestId(
|
|
593
|
+
createNetworkError(
|
|
594
|
+
parsed.errorMessage,
|
|
595
|
+
status,
|
|
596
|
+
errorDetails,
|
|
597
|
+
parsed.userMessage,
|
|
598
|
+
suggestion
|
|
599
|
+
),
|
|
600
|
+
requestId
|
|
601
|
+
);
|
|
602
|
+
}
|
|
477
603
|
async function httpFetch(url, options) {
|
|
478
604
|
const {
|
|
479
605
|
publishableKey,
|
|
@@ -578,14 +704,10 @@ async function httpFetch(url, options) {
|
|
|
578
704
|
attempt: attempt + 1
|
|
579
705
|
};
|
|
580
706
|
if (NON_RETRYABLE_STATUSES.includes(response.status)) {
|
|
581
|
-
throw
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
{ ...details, ...parsed.errors && { errors: parsed.errors } },
|
|
586
|
-
parsed.userMessage,
|
|
587
|
-
getErrorSuggestion(response.status)
|
|
588
|
-
),
|
|
707
|
+
throw createHttpStatusError(
|
|
708
|
+
response.status,
|
|
709
|
+
parsed,
|
|
710
|
+
details,
|
|
589
711
|
requestId
|
|
590
712
|
);
|
|
591
713
|
}
|
|
@@ -675,7 +797,11 @@ async function httpFetch(url, options) {
|
|
|
675
797
|
// src/core/collection/http-client.ts
|
|
676
798
|
var HttpClient = class {
|
|
677
799
|
constructor(publishableKey, secretKey, getCustomerToken, onUnauthorized, onRequestId) {
|
|
678
|
-
this.publishableKey =
|
|
800
|
+
this.publishableKey = requirePublishableKeyForSecret(
|
|
801
|
+
"CollectionClient",
|
|
802
|
+
publishableKey,
|
|
803
|
+
secretKey
|
|
804
|
+
);
|
|
679
805
|
this.secretKey = secretKey;
|
|
680
806
|
this.getCustomerToken = getCustomerToken;
|
|
681
807
|
this.onUnauthorized = onUnauthorized;
|
|
@@ -948,6 +1074,40 @@ var CollectionClient = class extends HttpClient {
|
|
|
948
1074
|
return this.parseMutationResponse(response);
|
|
949
1075
|
}
|
|
950
1076
|
};
|
|
1077
|
+
var ServerCollectionClient = class extends CollectionClient {
|
|
1078
|
+
from(collection) {
|
|
1079
|
+
return new ServerCollectionQueryBuilder(this, collection);
|
|
1080
|
+
}
|
|
1081
|
+
};
|
|
1082
|
+
var ReadOnlyCollectionClient = class extends HttpClient {
|
|
1083
|
+
from(collection) {
|
|
1084
|
+
return new ReadOnlyCollectionQueryBuilder(this, collection);
|
|
1085
|
+
}
|
|
1086
|
+
async requestFind(endpoint, options) {
|
|
1087
|
+
const url = this.buildUrl(endpoint, options);
|
|
1088
|
+
const response = await this.fetchWithTracking(url, {
|
|
1089
|
+
...this.defaultOptions,
|
|
1090
|
+
method: "GET"
|
|
1091
|
+
});
|
|
1092
|
+
return this.parseFindResponse(response);
|
|
1093
|
+
}
|
|
1094
|
+
async requestFindById(endpoint, options) {
|
|
1095
|
+
const url = this.buildUrl(endpoint, options);
|
|
1096
|
+
const response = await this.fetchWithTracking(url, {
|
|
1097
|
+
...this.defaultOptions,
|
|
1098
|
+
method: "GET"
|
|
1099
|
+
});
|
|
1100
|
+
return this.parseDocumentResponse(response);
|
|
1101
|
+
}
|
|
1102
|
+
async requestCount(endpoint, options) {
|
|
1103
|
+
const url = this.buildUrl(endpoint, options);
|
|
1104
|
+
const response = await this.fetchWithTracking(url, {
|
|
1105
|
+
...this.defaultOptions,
|
|
1106
|
+
method: "GET"
|
|
1107
|
+
});
|
|
1108
|
+
return this.parseDocumentResponse(response);
|
|
1109
|
+
}
|
|
1110
|
+
};
|
|
951
1111
|
|
|
952
1112
|
// src/core/collection/const.ts
|
|
953
1113
|
var INTERNAL_COLLECTIONS = [
|
|
@@ -970,6 +1130,7 @@ var INTERNAL_COLLECTIONS = [
|
|
|
970
1130
|
"api-keys",
|
|
971
1131
|
"personal-access-tokens",
|
|
972
1132
|
"tenant-entitlements",
|
|
1133
|
+
"direct-upload-sessions",
|
|
973
1134
|
"webhook-events",
|
|
974
1135
|
"webhook-deliveries",
|
|
975
1136
|
"audit-logs",
|
|
@@ -999,8 +1160,8 @@ var COLLECTIONS = [
|
|
|
999
1160
|
"transactions",
|
|
1000
1161
|
"customers",
|
|
1001
1162
|
"customer-profiles",
|
|
1163
|
+
"customer-profile-lists",
|
|
1002
1164
|
"customer-addresses",
|
|
1003
|
-
"customer-groups",
|
|
1004
1165
|
"carts",
|
|
1005
1166
|
"cart-items",
|
|
1006
1167
|
"discounts",
|
|
@@ -1056,6 +1217,11 @@ var COLLECTIONS = [
|
|
|
1056
1217
|
"event-occurrences",
|
|
1057
1218
|
"event-tags"
|
|
1058
1219
|
];
|
|
1220
|
+
var SERVER_ONLY_COLLECTIONS = ["customer-groups"];
|
|
1221
|
+
var SERVER_COLLECTIONS = [
|
|
1222
|
+
...COLLECTIONS,
|
|
1223
|
+
...SERVER_ONLY_COLLECTIONS
|
|
1224
|
+
];
|
|
1059
1225
|
|
|
1060
1226
|
// src/core/api/parse-response.ts
|
|
1061
1227
|
async function parseApiResponse(response, endpoint) {
|
|
@@ -1106,7 +1272,11 @@ async function parseApiResponse(response, endpoint) {
|
|
|
1106
1272
|
// src/core/community/community-client.ts
|
|
1107
1273
|
var CommunityClient = class {
|
|
1108
1274
|
constructor(options) {
|
|
1109
|
-
this.publishableKey =
|
|
1275
|
+
this.publishableKey = requirePublishableKeyForSecret(
|
|
1276
|
+
"CommunityClient",
|
|
1277
|
+
options.publishableKey,
|
|
1278
|
+
options.secretKey
|
|
1279
|
+
);
|
|
1110
1280
|
this.secretKey = options.secretKey;
|
|
1111
1281
|
this.customerToken = options.customerToken;
|
|
1112
1282
|
this.onUnauthorized = options.onUnauthorized;
|
|
@@ -1276,7 +1446,11 @@ var BaseApi = class {
|
|
|
1276
1446
|
if (!options.secretKey) {
|
|
1277
1447
|
throw createConfigError(`secretKey is required for ${apiName}.`);
|
|
1278
1448
|
}
|
|
1279
|
-
this.publishableKey =
|
|
1449
|
+
this.publishableKey = requirePublishableKeyForSecret(
|
|
1450
|
+
apiName,
|
|
1451
|
+
options.publishableKey,
|
|
1452
|
+
options.secretKey
|
|
1453
|
+
);
|
|
1280
1454
|
this.secretKey = options.secretKey;
|
|
1281
1455
|
this.onRequestId = options.onRequestId;
|
|
1282
1456
|
}
|
|
@@ -1570,7 +1744,11 @@ var CartApi = class {
|
|
|
1570
1744
|
"Either secretKey or customerToken is required for CartApi."
|
|
1571
1745
|
);
|
|
1572
1746
|
}
|
|
1573
|
-
this.publishableKey =
|
|
1747
|
+
this.publishableKey = requirePublishableKeyForSecret(
|
|
1748
|
+
"CartApi",
|
|
1749
|
+
options.publishableKey,
|
|
1750
|
+
options.secretKey
|
|
1751
|
+
);
|
|
1574
1752
|
this.secretKey = options.secretKey;
|
|
1575
1753
|
this.customerToken = options.customerToken;
|
|
1576
1754
|
this.onUnauthorized = options.onUnauthorized;
|
|
@@ -1766,8 +1944,13 @@ var OrderApi = class extends BaseApi {
|
|
|
1766
1944
|
// src/core/commerce/server-commerce-client.ts
|
|
1767
1945
|
var ServerCommerceClient = class {
|
|
1768
1946
|
constructor(options) {
|
|
1947
|
+
const publishableKey = requirePublishableKeyForSecret(
|
|
1948
|
+
"ServerCommerceClient",
|
|
1949
|
+
options.publishableKey,
|
|
1950
|
+
options.secretKey
|
|
1951
|
+
);
|
|
1769
1952
|
const serverOptions = {
|
|
1770
|
-
publishableKey
|
|
1953
|
+
publishableKey,
|
|
1771
1954
|
secretKey: options.secretKey,
|
|
1772
1955
|
onRequestId: options.onRequestId
|
|
1773
1956
|
};
|
|
@@ -2386,7 +2569,14 @@ var Client = class {
|
|
|
2386
2569
|
onUnauthorized,
|
|
2387
2570
|
onRequestId
|
|
2388
2571
|
});
|
|
2389
|
-
|
|
2572
|
+
const collectionClient = new CollectionClient(
|
|
2573
|
+
this.config.publishableKey,
|
|
2574
|
+
void 0,
|
|
2575
|
+
() => this.customer.auth.getToken(),
|
|
2576
|
+
onUnauthorized,
|
|
2577
|
+
onRequestId
|
|
2578
|
+
);
|
|
2579
|
+
this.collections = new ReadOnlyCollectionClient(
|
|
2390
2580
|
this.config.publishableKey,
|
|
2391
2581
|
void 0,
|
|
2392
2582
|
() => this.customer.auth.getToken(),
|
|
@@ -2395,7 +2585,7 @@ var Client = class {
|
|
|
2395
2585
|
);
|
|
2396
2586
|
this.query = new QueryHooks(
|
|
2397
2587
|
this.queryClient,
|
|
2398
|
-
|
|
2588
|
+
collectionClient,
|
|
2399
2589
|
this.customer.auth
|
|
2400
2590
|
);
|
|
2401
2591
|
}
|
|
@@ -2450,7 +2640,7 @@ var ServerClient = class {
|
|
|
2450
2640
|
unbanCustomer: moderationApi.unbanCustomer.bind(moderationApi)
|
|
2451
2641
|
}
|
|
2452
2642
|
});
|
|
2453
|
-
this.collections = new
|
|
2643
|
+
this.collections = new ServerCollectionClient(
|
|
2454
2644
|
this.config.publishableKey,
|
|
2455
2645
|
this.config.secretKey,
|
|
2456
2646
|
void 0,
|
|
@@ -2772,12 +2962,24 @@ function getVariantPrimaryImage(variant) {
|
|
|
2772
2962
|
if (!variant) return null;
|
|
2773
2963
|
return extractEntityId(variant.thumbnail) ?? getFirstMediaId(variant.images);
|
|
2774
2964
|
}
|
|
2965
|
+
function getFirstAvailableVariantPrimaryImage(variants) {
|
|
2966
|
+
const orderedVariants = [...variants].sort(compareVariantOrder);
|
|
2967
|
+
for (const variant of orderedVariants) {
|
|
2968
|
+
if (!isVariantAvailableForSale(variant)) continue;
|
|
2969
|
+
const image = getVariantPrimaryImage(variant);
|
|
2970
|
+
if (image != null) return image;
|
|
2971
|
+
}
|
|
2972
|
+
return null;
|
|
2973
|
+
}
|
|
2775
2974
|
function normalizeOptionValue(value, fallbackOptionId) {
|
|
2776
2975
|
return {
|
|
2777
2976
|
id: String(value.id),
|
|
2778
2977
|
optionId: getRelationID(value.option) ?? fallbackOptionId,
|
|
2779
2978
|
label: value.value || value.slug || String(value.id),
|
|
2780
2979
|
slug: value.slug ?? null,
|
|
2980
|
+
swatchColor: value.swatchColor ?? null,
|
|
2981
|
+
thumbnail: value.thumbnail ?? null,
|
|
2982
|
+
images: value.images ?? null,
|
|
2781
2983
|
order: value._order ?? value["_product-option-values_values_order"] ?? ""
|
|
2782
2984
|
};
|
|
2783
2985
|
}
|
|
@@ -2806,7 +3008,10 @@ function buildProductOptionMatrix({
|
|
|
2806
3008
|
const valuesById = /* @__PURE__ */ new Map();
|
|
2807
3009
|
for (const rawValue of option.values?.docs ?? []) {
|
|
2808
3010
|
if (!isProductOptionValueDoc(rawValue)) continue;
|
|
2809
|
-
const normalizedValue = normalizeOptionValue(
|
|
3011
|
+
const normalizedValue = normalizeOptionValue(
|
|
3012
|
+
rawValue,
|
|
3013
|
+
String(option.id)
|
|
3014
|
+
);
|
|
2810
3015
|
valuesById.set(normalizedValue.id, normalizedValue);
|
|
2811
3016
|
}
|
|
2812
3017
|
return {
|
|
@@ -2818,7 +3023,9 @@ function buildProductOptionMatrix({
|
|
|
2818
3023
|
)
|
|
2819
3024
|
};
|
|
2820
3025
|
}).sort((left, right) => compareOrder(left.order, right.order));
|
|
2821
|
-
const optionById = new Map(
|
|
3026
|
+
const optionById = new Map(
|
|
3027
|
+
normalizedOptions.map((option) => [option.id, option])
|
|
3028
|
+
);
|
|
2822
3029
|
const valueById = /* @__PURE__ */ new Map();
|
|
2823
3030
|
const valueToOptionId = /* @__PURE__ */ new Map();
|
|
2824
3031
|
for (const option of normalizedOptions) {
|
|
@@ -2897,10 +3104,12 @@ function compareVariantOrder(a, b) {
|
|
|
2897
3104
|
function isVariantAvailableForSale(variant) {
|
|
2898
3105
|
if (variant.isActive === false) return false;
|
|
2899
3106
|
if (variant.isUnlimited) return true;
|
|
2900
|
-
return (variant.stock ?? 0) > 0;
|
|
3107
|
+
return (variant.stock ?? 0) - (variant.reservedStock ?? 0) > 0;
|
|
2901
3108
|
}
|
|
2902
3109
|
function getMinMax(values) {
|
|
2903
|
-
const numbers = values.filter(
|
|
3110
|
+
const numbers = values.filter(
|
|
3111
|
+
(value) => typeof value === "number"
|
|
3112
|
+
);
|
|
2904
3113
|
if (numbers.length === 0) {
|
|
2905
3114
|
return { min: null, max: null };
|
|
2906
3115
|
}
|
|
@@ -2911,7 +3120,9 @@ function getMinMax(values) {
|
|
|
2911
3120
|
}
|
|
2912
3121
|
function buildProductListingProjection(product, variants) {
|
|
2913
3122
|
const orderedVariants = [...variants].sort(compareVariantOrder);
|
|
2914
|
-
const activeVariants = orderedVariants.filter(
|
|
3123
|
+
const activeVariants = orderedVariants.filter(
|
|
3124
|
+
(variant) => variant.isActive !== false
|
|
3125
|
+
);
|
|
2915
3126
|
const availableVariants = activeVariants.filter(isVariantAvailableForSale);
|
|
2916
3127
|
const selectionHintVariant = availableVariants[0] ?? activeVariants[0] ?? null;
|
|
2917
3128
|
const { min: minPrice, max: maxPrice } = getMinMax(
|
|
@@ -2950,7 +3161,9 @@ function buildProductListingGroupsByOption(args) {
|
|
|
2950
3161
|
return [];
|
|
2951
3162
|
}
|
|
2952
3163
|
const listingBase = buildProductListingProjection(void 0, variants);
|
|
3164
|
+
const optionValuePrimaryImage = extractEntityId(value.thumbnail) ?? getFirstMediaId(value.images);
|
|
2953
3165
|
const productFallbackImage = extractEntityId(args.product?.thumbnail) ?? getFirstMediaId(args.product?.images);
|
|
3166
|
+
const groupPrimaryImage = getFirstAvailableVariantPrimaryImage(variants) ?? optionValuePrimaryImage ?? productFallbackImage;
|
|
2954
3167
|
return [
|
|
2955
3168
|
{
|
|
2956
3169
|
optionId: primaryOption.id,
|
|
@@ -2958,12 +3171,15 @@ function buildProductListingGroupsByOption(args) {
|
|
|
2958
3171
|
optionValueId: value.id,
|
|
2959
3172
|
optionValueLabel: value.label,
|
|
2960
3173
|
optionValueSlug: value.slug,
|
|
3174
|
+
optionValueSwatchColor: value.swatchColor ?? null,
|
|
3175
|
+
optionValueThumbnail: value.thumbnail ?? null,
|
|
3176
|
+
optionValueImages: value.images ?? null,
|
|
2961
3177
|
variantIds: variants.map((variant) => String(variant.id)),
|
|
2962
3178
|
variantCount: variants.length,
|
|
2963
3179
|
variants,
|
|
2964
3180
|
listing: {
|
|
2965
3181
|
...listingBase,
|
|
2966
|
-
primaryImage:
|
|
3182
|
+
primaryImage: groupPrimaryImage
|
|
2967
3183
|
}
|
|
2968
3184
|
}
|
|
2969
3185
|
];
|
|
@@ -3284,9 +3500,14 @@ export {
|
|
|
3284
3500
|
ProductApi,
|
|
3285
3501
|
QueryHooks,
|
|
3286
3502
|
RateLimitError,
|
|
3503
|
+
ReadOnlyCollectionClient,
|
|
3287
3504
|
RealtimeConnection,
|
|
3288
3505
|
SDKError,
|
|
3506
|
+
SERVER_COLLECTIONS,
|
|
3507
|
+
SERVER_ONLY_COLLECTIONS,
|
|
3289
3508
|
ServerClient,
|
|
3509
|
+
ServerCollectionClient,
|
|
3510
|
+
ServerCollectionQueryBuilder,
|
|
3290
3511
|
ServerCommerceClient,
|
|
3291
3512
|
ServiceUnavailableError,
|
|
3292
3513
|
ShippingApi,
|