@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.cjs
CHANGED
|
@@ -49,9 +49,14 @@ __export(src_exports, {
|
|
|
49
49
|
ProductApi: () => ProductApi,
|
|
50
50
|
QueryHooks: () => QueryHooks,
|
|
51
51
|
RateLimitError: () => RateLimitError,
|
|
52
|
+
ReadOnlyCollectionClient: () => ReadOnlyCollectionClient,
|
|
52
53
|
RealtimeConnection: () => RealtimeConnection,
|
|
53
54
|
SDKError: () => SDKError,
|
|
55
|
+
SERVER_COLLECTIONS: () => SERVER_COLLECTIONS,
|
|
56
|
+
SERVER_ONLY_COLLECTIONS: () => SERVER_ONLY_COLLECTIONS,
|
|
54
57
|
ServerClient: () => ServerClient,
|
|
58
|
+
ServerCollectionClient: () => ServerCollectionClient,
|
|
59
|
+
ServerCollectionQueryBuilder: () => ServerCollectionQueryBuilder,
|
|
55
60
|
ServerCommerceClient: () => ServerCommerceClient,
|
|
56
61
|
ServiceUnavailableError: () => ServiceUnavailableError,
|
|
57
62
|
ShippingApi: () => ShippingApi,
|
|
@@ -177,6 +182,46 @@ function resolveMetaImage(ref) {
|
|
|
177
182
|
}
|
|
178
183
|
|
|
179
184
|
// src/core/collection/query-builder.ts
|
|
185
|
+
var ReadOnlyCollectionQueryBuilder = class {
|
|
186
|
+
constructor(api, collection) {
|
|
187
|
+
this.api = api;
|
|
188
|
+
this.collection = collection;
|
|
189
|
+
}
|
|
190
|
+
async find(options) {
|
|
191
|
+
return this.api.requestFind(
|
|
192
|
+
`/api/${String(this.collection)}`,
|
|
193
|
+
options
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
async findById(id, options) {
|
|
197
|
+
return this.api.requestFindById(
|
|
198
|
+
`/api/${String(this.collection)}/${String(id)}`,
|
|
199
|
+
options
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
async count(options) {
|
|
203
|
+
return this.api.requestCount(
|
|
204
|
+
`/api/${String(this.collection)}/count`,
|
|
205
|
+
options
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
async findMetadata(options, metadataOptions) {
|
|
209
|
+
const { docs } = await this.find({ ...options, limit: 1, depth: 1 });
|
|
210
|
+
const doc = docs[0];
|
|
211
|
+
if (!doc) return null;
|
|
212
|
+
return generateMetadata(
|
|
213
|
+
extractSeo(doc),
|
|
214
|
+
metadataOptions
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
async findMetadataById(id, metadataOptions) {
|
|
218
|
+
const doc = await this.findById(id, { depth: 1 });
|
|
219
|
+
return generateMetadata(
|
|
220
|
+
extractSeo(doc),
|
|
221
|
+
metadataOptions
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
};
|
|
180
225
|
var CollectionQueryBuilder = class {
|
|
181
226
|
constructor(api, collection) {
|
|
182
227
|
this.api = api;
|
|
@@ -308,6 +353,8 @@ var CollectionQueryBuilder = class {
|
|
|
308
353
|
);
|
|
309
354
|
}
|
|
310
355
|
};
|
|
356
|
+
var ServerCollectionQueryBuilder = class extends CollectionQueryBuilder {
|
|
357
|
+
};
|
|
311
358
|
|
|
312
359
|
// src/core/collection/http-client.ts
|
|
313
360
|
var import_qs_esm = require("qs-esm");
|
|
@@ -350,8 +397,8 @@ var NetworkError = class extends SDKError {
|
|
|
350
397
|
}
|
|
351
398
|
};
|
|
352
399
|
var ValidationError = class extends SDKError {
|
|
353
|
-
constructor(message, details, userMessage, suggestion) {
|
|
354
|
-
super("VALIDATION_ERROR", message,
|
|
400
|
+
constructor(message, details, userMessage, suggestion, status = 400) {
|
|
401
|
+
super("VALIDATION_ERROR", message, status, details, userMessage, suggestion);
|
|
355
402
|
this.name = "ValidationError";
|
|
356
403
|
}
|
|
357
404
|
};
|
|
@@ -480,7 +527,7 @@ function isRateLimitError(error) {
|
|
|
480
527
|
return error instanceof RateLimitError;
|
|
481
528
|
}
|
|
482
529
|
var createNetworkError = (message, status, details, userMessage, suggestion) => new NetworkError(message, status, details, userMessage, suggestion);
|
|
483
|
-
var createValidationError = (message, details, userMessage, suggestion) => new ValidationError(message, details, userMessage, suggestion);
|
|
530
|
+
var createValidationError = (message, details, userMessage, suggestion, status) => new ValidationError(message, details, userMessage, suggestion, status);
|
|
484
531
|
var createApiError = (message, status, details, userMessage, suggestion) => new ApiError(message, status, details, userMessage, suggestion);
|
|
485
532
|
var createConfigError = (message, details, userMessage, suggestion) => new ConfigError(message, details, userMessage, suggestion);
|
|
486
533
|
var createTimeoutError = (message, details, userMessage, suggestion) => new TimeoutError(message, details, userMessage, suggestion);
|
|
@@ -491,6 +538,16 @@ var createNotFoundError = (message, details, userMessage, suggestion, requestId)
|
|
|
491
538
|
var createConflictError = (message, details, userMessage, suggestion, requestId) => new ConflictError(message, details, userMessage, suggestion, requestId);
|
|
492
539
|
var createRateLimitError = (message, retryAfter, details, userMessage, suggestion, requestId) => new RateLimitError(message, retryAfter, details, userMessage, suggestion, requestId);
|
|
493
540
|
|
|
541
|
+
// src/core/internal/utils/credentials.ts
|
|
542
|
+
function requirePublishableKeyForSecret(apiName, publishableKey, secretKey) {
|
|
543
|
+
if (secretKey && !publishableKey) {
|
|
544
|
+
throw createConfigError(
|
|
545
|
+
`publishableKey is required for ${apiName} when secretKey is used. It is sent as X-Publishable-Key for tenant routing, rate limiting, and quota enforcement.`
|
|
546
|
+
);
|
|
547
|
+
}
|
|
548
|
+
return publishableKey ?? "";
|
|
549
|
+
}
|
|
550
|
+
|
|
494
551
|
// src/core/client/types.ts
|
|
495
552
|
function resolveApiUrl() {
|
|
496
553
|
if (typeof process !== "undefined" && process.env) {
|
|
@@ -505,7 +562,7 @@ function resolveApiUrl() {
|
|
|
505
562
|
// src/core/internal/utils/http.ts
|
|
506
563
|
var DEFAULT_TIMEOUT = 3e4;
|
|
507
564
|
var DEFAULT_RETRYABLE_STATUSES = [408, 429, 500, 502, 503, 504];
|
|
508
|
-
var NON_RETRYABLE_STATUSES = [400, 401, 403, 404, 422];
|
|
565
|
+
var NON_RETRYABLE_STATUSES = [400, 401, 403, 404, 409, 422];
|
|
509
566
|
var SAFE_METHODS = ["GET", "HEAD", "OPTIONS"];
|
|
510
567
|
function debugLog(debug, type, message, data) {
|
|
511
568
|
if (!debug) return;
|
|
@@ -588,6 +645,80 @@ function attachRequestId(err, id) {
|
|
|
588
645
|
if (id) err.requestId = id;
|
|
589
646
|
return err;
|
|
590
647
|
}
|
|
648
|
+
function createHttpStatusError(status, parsed, details, requestId) {
|
|
649
|
+
const errorDetails = {
|
|
650
|
+
...details,
|
|
651
|
+
...parsed.errors && { errors: parsed.errors },
|
|
652
|
+
...parsed.body && { body: parsed.body }
|
|
653
|
+
};
|
|
654
|
+
const suggestion = getErrorSuggestion(status);
|
|
655
|
+
if (status === 400 || status === 422) {
|
|
656
|
+
return attachRequestId(
|
|
657
|
+
createValidationError(
|
|
658
|
+
parsed.errorMessage,
|
|
659
|
+
errorDetails,
|
|
660
|
+
parsed.userMessage,
|
|
661
|
+
suggestion,
|
|
662
|
+
status
|
|
663
|
+
),
|
|
664
|
+
requestId
|
|
665
|
+
);
|
|
666
|
+
}
|
|
667
|
+
if (status === 401) {
|
|
668
|
+
return attachRequestId(
|
|
669
|
+
createAuthError(
|
|
670
|
+
parsed.errorMessage,
|
|
671
|
+
errorDetails,
|
|
672
|
+
parsed.userMessage,
|
|
673
|
+
suggestion
|
|
674
|
+
),
|
|
675
|
+
requestId
|
|
676
|
+
);
|
|
677
|
+
}
|
|
678
|
+
if (status === 403) {
|
|
679
|
+
return attachRequestId(
|
|
680
|
+
createPermissionError(
|
|
681
|
+
parsed.errorMessage,
|
|
682
|
+
errorDetails,
|
|
683
|
+
parsed.userMessage,
|
|
684
|
+
suggestion
|
|
685
|
+
),
|
|
686
|
+
requestId
|
|
687
|
+
);
|
|
688
|
+
}
|
|
689
|
+
if (status === 404) {
|
|
690
|
+
return attachRequestId(
|
|
691
|
+
createNotFoundError(
|
|
692
|
+
parsed.errorMessage,
|
|
693
|
+
errorDetails,
|
|
694
|
+
parsed.userMessage,
|
|
695
|
+
suggestion
|
|
696
|
+
),
|
|
697
|
+
requestId
|
|
698
|
+
);
|
|
699
|
+
}
|
|
700
|
+
if (status === 409) {
|
|
701
|
+
return attachRequestId(
|
|
702
|
+
createConflictError(
|
|
703
|
+
parsed.errorMessage,
|
|
704
|
+
errorDetails,
|
|
705
|
+
parsed.userMessage,
|
|
706
|
+
suggestion
|
|
707
|
+
),
|
|
708
|
+
requestId
|
|
709
|
+
);
|
|
710
|
+
}
|
|
711
|
+
return attachRequestId(
|
|
712
|
+
createNetworkError(
|
|
713
|
+
parsed.errorMessage,
|
|
714
|
+
status,
|
|
715
|
+
errorDetails,
|
|
716
|
+
parsed.userMessage,
|
|
717
|
+
suggestion
|
|
718
|
+
),
|
|
719
|
+
requestId
|
|
720
|
+
);
|
|
721
|
+
}
|
|
591
722
|
async function httpFetch(url, options) {
|
|
592
723
|
const {
|
|
593
724
|
publishableKey,
|
|
@@ -692,14 +823,10 @@ async function httpFetch(url, options) {
|
|
|
692
823
|
attempt: attempt + 1
|
|
693
824
|
};
|
|
694
825
|
if (NON_RETRYABLE_STATUSES.includes(response.status)) {
|
|
695
|
-
throw
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
{ ...details, ...parsed.errors && { errors: parsed.errors } },
|
|
700
|
-
parsed.userMessage,
|
|
701
|
-
getErrorSuggestion(response.status)
|
|
702
|
-
),
|
|
826
|
+
throw createHttpStatusError(
|
|
827
|
+
response.status,
|
|
828
|
+
parsed,
|
|
829
|
+
details,
|
|
703
830
|
requestId
|
|
704
831
|
);
|
|
705
832
|
}
|
|
@@ -789,7 +916,11 @@ async function httpFetch(url, options) {
|
|
|
789
916
|
// src/core/collection/http-client.ts
|
|
790
917
|
var HttpClient = class {
|
|
791
918
|
constructor(publishableKey, secretKey, getCustomerToken, onUnauthorized, onRequestId) {
|
|
792
|
-
this.publishableKey =
|
|
919
|
+
this.publishableKey = requirePublishableKeyForSecret(
|
|
920
|
+
"CollectionClient",
|
|
921
|
+
publishableKey,
|
|
922
|
+
secretKey
|
|
923
|
+
);
|
|
793
924
|
this.secretKey = secretKey;
|
|
794
925
|
this.getCustomerToken = getCustomerToken;
|
|
795
926
|
this.onUnauthorized = onUnauthorized;
|
|
@@ -1062,6 +1193,40 @@ var CollectionClient = class extends HttpClient {
|
|
|
1062
1193
|
return this.parseMutationResponse(response);
|
|
1063
1194
|
}
|
|
1064
1195
|
};
|
|
1196
|
+
var ServerCollectionClient = class extends CollectionClient {
|
|
1197
|
+
from(collection) {
|
|
1198
|
+
return new ServerCollectionQueryBuilder(this, collection);
|
|
1199
|
+
}
|
|
1200
|
+
};
|
|
1201
|
+
var ReadOnlyCollectionClient = class extends HttpClient {
|
|
1202
|
+
from(collection) {
|
|
1203
|
+
return new ReadOnlyCollectionQueryBuilder(this, collection);
|
|
1204
|
+
}
|
|
1205
|
+
async requestFind(endpoint, options) {
|
|
1206
|
+
const url = this.buildUrl(endpoint, options);
|
|
1207
|
+
const response = await this.fetchWithTracking(url, {
|
|
1208
|
+
...this.defaultOptions,
|
|
1209
|
+
method: "GET"
|
|
1210
|
+
});
|
|
1211
|
+
return this.parseFindResponse(response);
|
|
1212
|
+
}
|
|
1213
|
+
async requestFindById(endpoint, options) {
|
|
1214
|
+
const url = this.buildUrl(endpoint, options);
|
|
1215
|
+
const response = await this.fetchWithTracking(url, {
|
|
1216
|
+
...this.defaultOptions,
|
|
1217
|
+
method: "GET"
|
|
1218
|
+
});
|
|
1219
|
+
return this.parseDocumentResponse(response);
|
|
1220
|
+
}
|
|
1221
|
+
async requestCount(endpoint, options) {
|
|
1222
|
+
const url = this.buildUrl(endpoint, options);
|
|
1223
|
+
const response = await this.fetchWithTracking(url, {
|
|
1224
|
+
...this.defaultOptions,
|
|
1225
|
+
method: "GET"
|
|
1226
|
+
});
|
|
1227
|
+
return this.parseDocumentResponse(response);
|
|
1228
|
+
}
|
|
1229
|
+
};
|
|
1065
1230
|
|
|
1066
1231
|
// src/core/collection/const.ts
|
|
1067
1232
|
var INTERNAL_COLLECTIONS = [
|
|
@@ -1084,6 +1249,7 @@ var INTERNAL_COLLECTIONS = [
|
|
|
1084
1249
|
"api-keys",
|
|
1085
1250
|
"personal-access-tokens",
|
|
1086
1251
|
"tenant-entitlements",
|
|
1252
|
+
"direct-upload-sessions",
|
|
1087
1253
|
"webhook-events",
|
|
1088
1254
|
"webhook-deliveries",
|
|
1089
1255
|
"audit-logs",
|
|
@@ -1113,8 +1279,8 @@ var COLLECTIONS = [
|
|
|
1113
1279
|
"transactions",
|
|
1114
1280
|
"customers",
|
|
1115
1281
|
"customer-profiles",
|
|
1282
|
+
"customer-profile-lists",
|
|
1116
1283
|
"customer-addresses",
|
|
1117
|
-
"customer-groups",
|
|
1118
1284
|
"carts",
|
|
1119
1285
|
"cart-items",
|
|
1120
1286
|
"discounts",
|
|
@@ -1170,6 +1336,11 @@ var COLLECTIONS = [
|
|
|
1170
1336
|
"event-occurrences",
|
|
1171
1337
|
"event-tags"
|
|
1172
1338
|
];
|
|
1339
|
+
var SERVER_ONLY_COLLECTIONS = ["customer-groups"];
|
|
1340
|
+
var SERVER_COLLECTIONS = [
|
|
1341
|
+
...COLLECTIONS,
|
|
1342
|
+
...SERVER_ONLY_COLLECTIONS
|
|
1343
|
+
];
|
|
1173
1344
|
|
|
1174
1345
|
// src/core/api/parse-response.ts
|
|
1175
1346
|
async function parseApiResponse(response, endpoint) {
|
|
@@ -1220,7 +1391,11 @@ async function parseApiResponse(response, endpoint) {
|
|
|
1220
1391
|
// src/core/community/community-client.ts
|
|
1221
1392
|
var CommunityClient = class {
|
|
1222
1393
|
constructor(options) {
|
|
1223
|
-
this.publishableKey =
|
|
1394
|
+
this.publishableKey = requirePublishableKeyForSecret(
|
|
1395
|
+
"CommunityClient",
|
|
1396
|
+
options.publishableKey,
|
|
1397
|
+
options.secretKey
|
|
1398
|
+
);
|
|
1224
1399
|
this.secretKey = options.secretKey;
|
|
1225
1400
|
this.customerToken = options.customerToken;
|
|
1226
1401
|
this.onUnauthorized = options.onUnauthorized;
|
|
@@ -1390,7 +1565,11 @@ var BaseApi = class {
|
|
|
1390
1565
|
if (!options.secretKey) {
|
|
1391
1566
|
throw createConfigError(`secretKey is required for ${apiName}.`);
|
|
1392
1567
|
}
|
|
1393
|
-
this.publishableKey =
|
|
1568
|
+
this.publishableKey = requirePublishableKeyForSecret(
|
|
1569
|
+
apiName,
|
|
1570
|
+
options.publishableKey,
|
|
1571
|
+
options.secretKey
|
|
1572
|
+
);
|
|
1394
1573
|
this.secretKey = options.secretKey;
|
|
1395
1574
|
this.onRequestId = options.onRequestId;
|
|
1396
1575
|
}
|
|
@@ -1684,7 +1863,11 @@ var CartApi = class {
|
|
|
1684
1863
|
"Either secretKey or customerToken is required for CartApi."
|
|
1685
1864
|
);
|
|
1686
1865
|
}
|
|
1687
|
-
this.publishableKey =
|
|
1866
|
+
this.publishableKey = requirePublishableKeyForSecret(
|
|
1867
|
+
"CartApi",
|
|
1868
|
+
options.publishableKey,
|
|
1869
|
+
options.secretKey
|
|
1870
|
+
);
|
|
1688
1871
|
this.secretKey = options.secretKey;
|
|
1689
1872
|
this.customerToken = options.customerToken;
|
|
1690
1873
|
this.onUnauthorized = options.onUnauthorized;
|
|
@@ -1880,8 +2063,13 @@ var OrderApi = class extends BaseApi {
|
|
|
1880
2063
|
// src/core/commerce/server-commerce-client.ts
|
|
1881
2064
|
var ServerCommerceClient = class {
|
|
1882
2065
|
constructor(options) {
|
|
2066
|
+
const publishableKey = requirePublishableKeyForSecret(
|
|
2067
|
+
"ServerCommerceClient",
|
|
2068
|
+
options.publishableKey,
|
|
2069
|
+
options.secretKey
|
|
2070
|
+
);
|
|
1883
2071
|
const serverOptions = {
|
|
1884
|
-
publishableKey
|
|
2072
|
+
publishableKey,
|
|
1885
2073
|
secretKey: options.secretKey,
|
|
1886
2074
|
onRequestId: options.onRequestId
|
|
1887
2075
|
};
|
|
@@ -2482,7 +2670,14 @@ var Client = class {
|
|
|
2482
2670
|
onUnauthorized,
|
|
2483
2671
|
onRequestId
|
|
2484
2672
|
});
|
|
2485
|
-
|
|
2673
|
+
const collectionClient = new CollectionClient(
|
|
2674
|
+
this.config.publishableKey,
|
|
2675
|
+
void 0,
|
|
2676
|
+
() => this.customer.auth.getToken(),
|
|
2677
|
+
onUnauthorized,
|
|
2678
|
+
onRequestId
|
|
2679
|
+
);
|
|
2680
|
+
this.collections = new ReadOnlyCollectionClient(
|
|
2486
2681
|
this.config.publishableKey,
|
|
2487
2682
|
void 0,
|
|
2488
2683
|
() => this.customer.auth.getToken(),
|
|
@@ -2491,7 +2686,7 @@ var Client = class {
|
|
|
2491
2686
|
);
|
|
2492
2687
|
this.query = new QueryHooks(
|
|
2493
2688
|
this.queryClient,
|
|
2494
|
-
|
|
2689
|
+
collectionClient,
|
|
2495
2690
|
this.customer.auth
|
|
2496
2691
|
);
|
|
2497
2692
|
}
|
|
@@ -2546,7 +2741,7 @@ var ServerClient = class {
|
|
|
2546
2741
|
unbanCustomer: moderationApi.unbanCustomer.bind(moderationApi)
|
|
2547
2742
|
}
|
|
2548
2743
|
});
|
|
2549
|
-
this.collections = new
|
|
2744
|
+
this.collections = new ServerCollectionClient(
|
|
2550
2745
|
this.config.publishableKey,
|
|
2551
2746
|
this.config.secretKey,
|
|
2552
2747
|
void 0,
|
|
@@ -2868,12 +3063,24 @@ function getVariantPrimaryImage(variant) {
|
|
|
2868
3063
|
if (!variant) return null;
|
|
2869
3064
|
return extractEntityId(variant.thumbnail) ?? getFirstMediaId(variant.images);
|
|
2870
3065
|
}
|
|
3066
|
+
function getFirstAvailableVariantPrimaryImage(variants) {
|
|
3067
|
+
const orderedVariants = [...variants].sort(compareVariantOrder);
|
|
3068
|
+
for (const variant of orderedVariants) {
|
|
3069
|
+
if (!isVariantAvailableForSale(variant)) continue;
|
|
3070
|
+
const image = getVariantPrimaryImage(variant);
|
|
3071
|
+
if (image != null) return image;
|
|
3072
|
+
}
|
|
3073
|
+
return null;
|
|
3074
|
+
}
|
|
2871
3075
|
function normalizeOptionValue(value, fallbackOptionId) {
|
|
2872
3076
|
return {
|
|
2873
3077
|
id: String(value.id),
|
|
2874
3078
|
optionId: getRelationID(value.option) ?? fallbackOptionId,
|
|
2875
3079
|
label: value.value || value.slug || String(value.id),
|
|
2876
3080
|
slug: value.slug ?? null,
|
|
3081
|
+
swatchColor: value.swatchColor ?? null,
|
|
3082
|
+
thumbnail: value.thumbnail ?? null,
|
|
3083
|
+
images: value.images ?? null,
|
|
2877
3084
|
order: value._order ?? value["_product-option-values_values_order"] ?? ""
|
|
2878
3085
|
};
|
|
2879
3086
|
}
|
|
@@ -2902,7 +3109,10 @@ function buildProductOptionMatrix({
|
|
|
2902
3109
|
const valuesById = /* @__PURE__ */ new Map();
|
|
2903
3110
|
for (const rawValue of option.values?.docs ?? []) {
|
|
2904
3111
|
if (!isProductOptionValueDoc(rawValue)) continue;
|
|
2905
|
-
const normalizedValue = normalizeOptionValue(
|
|
3112
|
+
const normalizedValue = normalizeOptionValue(
|
|
3113
|
+
rawValue,
|
|
3114
|
+
String(option.id)
|
|
3115
|
+
);
|
|
2906
3116
|
valuesById.set(normalizedValue.id, normalizedValue);
|
|
2907
3117
|
}
|
|
2908
3118
|
return {
|
|
@@ -2914,7 +3124,9 @@ function buildProductOptionMatrix({
|
|
|
2914
3124
|
)
|
|
2915
3125
|
};
|
|
2916
3126
|
}).sort((left, right) => compareOrder(left.order, right.order));
|
|
2917
|
-
const optionById = new Map(
|
|
3127
|
+
const optionById = new Map(
|
|
3128
|
+
normalizedOptions.map((option) => [option.id, option])
|
|
3129
|
+
);
|
|
2918
3130
|
const valueById = /* @__PURE__ */ new Map();
|
|
2919
3131
|
const valueToOptionId = /* @__PURE__ */ new Map();
|
|
2920
3132
|
for (const option of normalizedOptions) {
|
|
@@ -2993,10 +3205,12 @@ function compareVariantOrder(a, b) {
|
|
|
2993
3205
|
function isVariantAvailableForSale(variant) {
|
|
2994
3206
|
if (variant.isActive === false) return false;
|
|
2995
3207
|
if (variant.isUnlimited) return true;
|
|
2996
|
-
return (variant.stock ?? 0) > 0;
|
|
3208
|
+
return (variant.stock ?? 0) - (variant.reservedStock ?? 0) > 0;
|
|
2997
3209
|
}
|
|
2998
3210
|
function getMinMax(values) {
|
|
2999
|
-
const numbers = values.filter(
|
|
3211
|
+
const numbers = values.filter(
|
|
3212
|
+
(value) => typeof value === "number"
|
|
3213
|
+
);
|
|
3000
3214
|
if (numbers.length === 0) {
|
|
3001
3215
|
return { min: null, max: null };
|
|
3002
3216
|
}
|
|
@@ -3007,7 +3221,9 @@ function getMinMax(values) {
|
|
|
3007
3221
|
}
|
|
3008
3222
|
function buildProductListingProjection(product, variants) {
|
|
3009
3223
|
const orderedVariants = [...variants].sort(compareVariantOrder);
|
|
3010
|
-
const activeVariants = orderedVariants.filter(
|
|
3224
|
+
const activeVariants = orderedVariants.filter(
|
|
3225
|
+
(variant) => variant.isActive !== false
|
|
3226
|
+
);
|
|
3011
3227
|
const availableVariants = activeVariants.filter(isVariantAvailableForSale);
|
|
3012
3228
|
const selectionHintVariant = availableVariants[0] ?? activeVariants[0] ?? null;
|
|
3013
3229
|
const { min: minPrice, max: maxPrice } = getMinMax(
|
|
@@ -3046,7 +3262,9 @@ function buildProductListingGroupsByOption(args) {
|
|
|
3046
3262
|
return [];
|
|
3047
3263
|
}
|
|
3048
3264
|
const listingBase = buildProductListingProjection(void 0, variants);
|
|
3265
|
+
const optionValuePrimaryImage = extractEntityId(value.thumbnail) ?? getFirstMediaId(value.images);
|
|
3049
3266
|
const productFallbackImage = extractEntityId(args.product?.thumbnail) ?? getFirstMediaId(args.product?.images);
|
|
3267
|
+
const groupPrimaryImage = getFirstAvailableVariantPrimaryImage(variants) ?? optionValuePrimaryImage ?? productFallbackImage;
|
|
3050
3268
|
return [
|
|
3051
3269
|
{
|
|
3052
3270
|
optionId: primaryOption.id,
|
|
@@ -3054,12 +3272,15 @@ function buildProductListingGroupsByOption(args) {
|
|
|
3054
3272
|
optionValueId: value.id,
|
|
3055
3273
|
optionValueLabel: value.label,
|
|
3056
3274
|
optionValueSlug: value.slug,
|
|
3275
|
+
optionValueSwatchColor: value.swatchColor ?? null,
|
|
3276
|
+
optionValueThumbnail: value.thumbnail ?? null,
|
|
3277
|
+
optionValueImages: value.images ?? null,
|
|
3057
3278
|
variantIds: variants.map((variant) => String(variant.id)),
|
|
3058
3279
|
variantCount: variants.length,
|
|
3059
3280
|
variants,
|
|
3060
3281
|
listing: {
|
|
3061
3282
|
...listingBase,
|
|
3062
|
-
primaryImage:
|
|
3283
|
+
primaryImage: groupPrimaryImage
|
|
3063
3284
|
}
|
|
3064
3285
|
}
|
|
3065
3286
|
];
|