@01.software/sdk 0.48.0 → 0.51.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/CHANGELOG.md +157 -1
- package/MIGRATION.md +56 -0
- package/README.md +276 -49
- package/dist/client.cjs +375 -161
- 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 +375 -161
- package/dist/client.js.map +1 -1
- package/dist/{collection-client-CBup9yOx.d.cts → collection-client-CWAeuzV4.d.cts} +6 -4
- package/dist/{collection-client-D3ExJU-7.d.ts → collection-client-hYvVfHIm.d.ts} +6 -4
- package/dist/{const-k9gHylYa.d.ts → const-D8LixhAJ.d.cts} +5 -5
- package/dist/{const-BXEi1Kix.d.cts → const-JD8obaKg.d.ts} +5 -5
- package/dist/embedded-admin/server.cjs +306 -0
- package/dist/embedded-admin/server.cjs.map +1 -0
- package/dist/embedded-admin/server.d.cts +33 -0
- package/dist/embedded-admin/server.d.ts +33 -0
- package/dist/embedded-admin/server.js +288 -0
- package/dist/embedded-admin/server.js.map +1 -0
- package/dist/embedded-admin.cjs +400 -0
- package/dist/embedded-admin.cjs.map +1 -0
- package/dist/embedded-admin.d.cts +61 -0
- package/dist/embedded-admin.d.ts +61 -0
- package/dist/embedded-admin.js +377 -0
- package/dist/embedded-admin.js.map +1 -0
- package/dist/errors.cjs +64 -15
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.cts +13 -4
- package/dist/errors.d.ts +13 -4
- package/dist/errors.js +64 -15
- package/dist/errors.js.map +1 -1
- package/dist/{index-BCM9CTL7.d.cts → index-B0Hjh3Ey.d.ts} +72 -10
- package/dist/{index-CHGGkcLj.d.ts → index-Bu0kCc6o.d.cts} +72 -10
- package/dist/index.cjs +470 -429
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -67
- package/dist/index.d.ts +9 -67
- package/dist/index.js +470 -429
- package/dist/index.js.map +1 -1
- package/dist/{payload-types-B6AZQcB7.d.cts → payload-types-BOsckg8B.d.cts} +396 -57
- package/dist/{payload-types-B6AZQcB7.d.ts → payload-types-BOsckg8B.d.ts} +396 -57
- package/dist/query.cjs +115 -70
- package/dist/query.cjs.map +1 -1
- package/dist/query.d.cts +5 -5
- package/dist/query.d.ts +5 -5
- package/dist/query.js +115 -70
- package/dist/query.js.map +1 -1
- package/dist/realtime.d.cts +2 -2
- package/dist/realtime.d.ts +2 -2
- package/dist/server.cjs +591 -186
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +8 -7
- package/dist/server.d.ts +8 -7
- package/dist/server.js +591 -186
- package/dist/server.js.map +1 -1
- package/dist/storefront-cache.cjs +22 -0
- package/dist/storefront-cache.cjs.map +1 -1
- package/dist/storefront-cache.js +22 -0
- package/dist/storefront-cache.js.map +1 -1
- package/dist/{types-ByD2zii1.d.ts → types-5ZlcAFuU.d.ts} +2 -2
- package/dist/{types-8us-_C-Q.d.cts → types-B14sEt1z.d.cts} +2 -2
- package/dist/{types-CM2je9Kw.d.cts → types-Bj8j7VHU.d.ts} +107 -26
- package/dist/{types-DbA5V3mt.d.ts → types-CM5qiR2k.d.cts} +107 -26
- 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 +124 -80
- package/dist/webhook.cjs.map +1 -1
- package/dist/webhook.d.cts +21 -5
- package/dist/webhook.d.ts +21 -5
- package/dist/webhook.js +124 -80
- package/dist/webhook.js.map +1 -1
- package/package.json +27 -5
package/dist/index.js
CHANGED
|
@@ -2,6 +2,24 @@
|
|
|
2
2
|
import { stringify } from "qs-esm";
|
|
3
3
|
|
|
4
4
|
// src/core/errors.ts
|
|
5
|
+
var SDK_ERROR_BRAND = /* @__PURE__ */ Symbol.for("@01.software/sdk/SDKError");
|
|
6
|
+
var SDK_ERROR_TYPE_BRAND = /* @__PURE__ */ Symbol.for("@01.software/sdk/SDKError.type");
|
|
7
|
+
function defineSDKErrorBrand(error) {
|
|
8
|
+
Object.defineProperty(error, SDK_ERROR_BRAND, {
|
|
9
|
+
value: true,
|
|
10
|
+
enumerable: false,
|
|
11
|
+
configurable: false,
|
|
12
|
+
writable: false
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
function defineSDKErrorType(error, type) {
|
|
16
|
+
Object.defineProperty(error, SDK_ERROR_TYPE_BRAND, {
|
|
17
|
+
value: type,
|
|
18
|
+
enumerable: false,
|
|
19
|
+
configurable: false,
|
|
20
|
+
writable: false
|
|
21
|
+
});
|
|
22
|
+
}
|
|
5
23
|
var SDKError = class extends Error {
|
|
6
24
|
constructor(code, message, status, details, userMessage, suggestion, requestId) {
|
|
7
25
|
super(message);
|
|
@@ -12,6 +30,7 @@ var SDKError = class extends Error {
|
|
|
12
30
|
this.userMessage = userMessage;
|
|
13
31
|
this.suggestion = suggestion;
|
|
14
32
|
this.requestId = requestId;
|
|
33
|
+
defineSDKErrorBrand(this);
|
|
15
34
|
if (Error.captureStackTrace) {
|
|
16
35
|
Error.captureStackTrace(this, new.target);
|
|
17
36
|
}
|
|
@@ -32,6 +51,7 @@ var SDKError = class extends Error {
|
|
|
32
51
|
...this.kind !== void 0 && { kind: this.kind },
|
|
33
52
|
...this.reason !== void 0 && { reason: this.reason },
|
|
34
53
|
...this.rawReason !== void 0 && { rawReason: this.rawReason },
|
|
54
|
+
...this.apiReason !== void 0 && { apiReason: this.apiReason },
|
|
35
55
|
...this.retryable !== void 0 && { retryable: this.retryable },
|
|
36
56
|
...this.retryAfter !== void 0 && { retryAfter: this.retryAfter }
|
|
37
57
|
};
|
|
@@ -77,6 +97,7 @@ var COMMERCE_ERROR_CODES = [
|
|
|
77
97
|
"payment_session_not_cancelable",
|
|
78
98
|
"payment_session_conflict",
|
|
79
99
|
"provider_identity_mismatch",
|
|
100
|
+
"managed_refund_attestation_forbidden",
|
|
80
101
|
"payment_method_unavailable",
|
|
81
102
|
"provider_unavailable",
|
|
82
103
|
"lock_timeout",
|
|
@@ -205,8 +226,16 @@ function enhanceCommerceError(error, body, headerRequestId) {
|
|
|
205
226
|
});
|
|
206
227
|
return error;
|
|
207
228
|
}
|
|
229
|
+
function enhanceNonCommerceError(error, reason) {
|
|
230
|
+
if (typeof reason === "string") Object.assign(error, { apiReason: reason });
|
|
231
|
+
return error;
|
|
232
|
+
}
|
|
233
|
+
function getSDKErrorReason(error) {
|
|
234
|
+
if (error.kind !== "commerce") return error.apiReason;
|
|
235
|
+
return error.reason === "unknown_commerce_error" ? error.rawReason : error.reason;
|
|
236
|
+
}
|
|
208
237
|
function isCommerceSDKError(error) {
|
|
209
|
-
if (!(error
|
|
238
|
+
if (!isSDKError(error) || error.kind !== "commerce") return false;
|
|
210
239
|
if (typeof error.requestId !== "string" || typeof error.retryable !== "boolean" || error.retryAfter !== void 0 && (!Number.isSafeInteger(error.retryAfter) || error.retryAfter < 0) || typeof error.reason !== "string") {
|
|
211
240
|
return false;
|
|
212
241
|
}
|
|
@@ -216,12 +245,14 @@ var NetworkError = class extends SDKError {
|
|
|
216
245
|
constructor(message, status, details, userMessage, suggestion) {
|
|
217
246
|
super("NETWORK_ERROR", message, status, details, userMessage, suggestion);
|
|
218
247
|
this.name = "NetworkError";
|
|
248
|
+
defineSDKErrorType(this, "NetworkError");
|
|
219
249
|
}
|
|
220
250
|
};
|
|
221
251
|
var ValidationError = class extends SDKError {
|
|
222
252
|
constructor(message, details, userMessage, suggestion, status = 400) {
|
|
223
253
|
super("VALIDATION_ERROR", message, status, details, userMessage, suggestion);
|
|
224
254
|
this.name = "ValidationError";
|
|
255
|
+
defineSDKErrorType(this, "ValidationError");
|
|
225
256
|
}
|
|
226
257
|
};
|
|
227
258
|
var ApiError = class extends SDKError {
|
|
@@ -236,24 +267,28 @@ var ApiError = class extends SDKError {
|
|
|
236
267
|
requestId
|
|
237
268
|
);
|
|
238
269
|
this.name = "ApiError";
|
|
270
|
+
defineSDKErrorType(this, "ApiError");
|
|
239
271
|
}
|
|
240
272
|
};
|
|
241
273
|
var ConfigError = class extends SDKError {
|
|
242
274
|
constructor(message, details, userMessage, suggestion) {
|
|
243
275
|
super("CONFIG_ERROR", message, void 0, details, userMessage, suggestion);
|
|
244
276
|
this.name = "ConfigError";
|
|
277
|
+
defineSDKErrorType(this, "ConfigError");
|
|
245
278
|
}
|
|
246
279
|
};
|
|
247
280
|
var TimeoutError = class extends SDKError {
|
|
248
281
|
constructor(message = "Request timed out.", details, userMessage, suggestion) {
|
|
249
282
|
super("TIMEOUT_ERROR", message, 408, details, userMessage, suggestion);
|
|
250
283
|
this.name = "TimeoutError";
|
|
284
|
+
defineSDKErrorType(this, "TimeoutError");
|
|
251
285
|
}
|
|
252
286
|
};
|
|
253
287
|
var GoneError = class extends SDKError {
|
|
254
288
|
constructor(message = "The requested resource is no longer available.", details, userMessage, suggestion) {
|
|
255
289
|
super("GONE_ERROR", message, 410, details, userMessage, suggestion);
|
|
256
290
|
this.name = "GoneError";
|
|
291
|
+
defineSDKErrorType(this, "GoneError");
|
|
257
292
|
}
|
|
258
293
|
};
|
|
259
294
|
var ServiceUnavailableError = class extends SDKError {
|
|
@@ -268,6 +303,7 @@ var ServiceUnavailableError = class extends SDKError {
|
|
|
268
303
|
);
|
|
269
304
|
this.name = "ServiceUnavailableError";
|
|
270
305
|
this.retryAfter = retryAfter;
|
|
306
|
+
defineSDKErrorType(this, "ServiceUnavailableError");
|
|
271
307
|
}
|
|
272
308
|
};
|
|
273
309
|
var UsageLimitError = class extends SDKError {
|
|
@@ -275,6 +311,7 @@ var UsageLimitError = class extends SDKError {
|
|
|
275
311
|
super("USAGE_LIMIT_ERROR", message, 429, details, userMessage, suggestion);
|
|
276
312
|
this.name = "UsageLimitError";
|
|
277
313
|
this.usage = usage;
|
|
314
|
+
defineSDKErrorType(this, "UsageLimitError");
|
|
278
315
|
}
|
|
279
316
|
toJSON() {
|
|
280
317
|
return {
|
|
@@ -295,6 +332,7 @@ var AuthError = class extends SDKError {
|
|
|
295
332
|
requestId
|
|
296
333
|
);
|
|
297
334
|
this.name = "AuthError";
|
|
335
|
+
defineSDKErrorType(this, "AuthError");
|
|
298
336
|
}
|
|
299
337
|
};
|
|
300
338
|
var PermissionError = class extends SDKError {
|
|
@@ -309,6 +347,7 @@ var PermissionError = class extends SDKError {
|
|
|
309
347
|
requestId
|
|
310
348
|
);
|
|
311
349
|
this.name = "PermissionError";
|
|
350
|
+
defineSDKErrorType(this, "PermissionError");
|
|
312
351
|
}
|
|
313
352
|
};
|
|
314
353
|
var NotFoundError = class extends SDKError {
|
|
@@ -323,12 +362,14 @@ var NotFoundError = class extends SDKError {
|
|
|
323
362
|
requestId
|
|
324
363
|
);
|
|
325
364
|
this.name = "NotFoundError";
|
|
365
|
+
defineSDKErrorType(this, "NotFoundError");
|
|
326
366
|
}
|
|
327
367
|
};
|
|
328
368
|
var ConflictError = class extends SDKError {
|
|
329
369
|
constructor(message, details, userMessage, suggestion, requestId) {
|
|
330
370
|
super("conflict", message, 409, details, userMessage, suggestion, requestId);
|
|
331
371
|
this.name = "ConflictError";
|
|
372
|
+
defineSDKErrorType(this, "ConflictError");
|
|
332
373
|
}
|
|
333
374
|
};
|
|
334
375
|
var RateLimitError = class extends SDKError {
|
|
@@ -344,52 +385,63 @@ var RateLimitError = class extends SDKError {
|
|
|
344
385
|
);
|
|
345
386
|
this.name = "RateLimitError";
|
|
346
387
|
this.retryAfter = retryAfter;
|
|
388
|
+
defineSDKErrorType(this, "RateLimitError");
|
|
347
389
|
}
|
|
348
390
|
};
|
|
391
|
+
function hasBrandedSDKErrorShape(error) {
|
|
392
|
+
if (error === null || typeof error !== "object") return false;
|
|
393
|
+
const candidate = error;
|
|
394
|
+
return candidate[SDK_ERROR_BRAND] === true && typeof candidate.name === "string" && typeof candidate.code === "string" && typeof candidate.message === "string" && (candidate.status === void 0 || typeof candidate.status === "number") && (candidate.userMessage === void 0 || typeof candidate.userMessage === "string") && (candidate.suggestion === void 0 || typeof candidate.suggestion === "string") && (candidate.requestId === void 0 || typeof candidate.requestId === "string") && (candidate.kind === void 0 || candidate.kind === "commerce") && (candidate.reason === void 0 || typeof candidate.reason === "string") && (candidate.rawReason === void 0 || typeof candidate.rawReason === "string") && (candidate.apiReason === void 0 || typeof candidate.apiReason === "string") && (candidate.retryable === void 0 || typeof candidate.retryable === "boolean") && (candidate.retryAfter === void 0 || typeof candidate.retryAfter === "number") && typeof candidate.getUserMessage === "function" && typeof candidate.toJSON === "function";
|
|
395
|
+
}
|
|
396
|
+
function hasSDKErrorType(error, type) {
|
|
397
|
+
return hasBrandedSDKErrorShape(error) && error[SDK_ERROR_TYPE_BRAND] === type;
|
|
398
|
+
}
|
|
349
399
|
function isSDKError(error) {
|
|
350
|
-
return error instanceof SDKError;
|
|
400
|
+
return error instanceof SDKError || hasBrandedSDKErrorShape(error);
|
|
351
401
|
}
|
|
352
402
|
function isNetworkError(error) {
|
|
353
|
-
return error instanceof NetworkError;
|
|
403
|
+
return error instanceof NetworkError || hasSDKErrorType(error, "NetworkError");
|
|
354
404
|
}
|
|
355
405
|
function isValidationError(error) {
|
|
356
|
-
if (error instanceof ValidationError)
|
|
406
|
+
if (error instanceof ValidationError || hasSDKErrorType(error, "ValidationError")) {
|
|
407
|
+
return true;
|
|
408
|
+
}
|
|
357
409
|
if (error == null || typeof error !== "object") return false;
|
|
358
410
|
const candidate = error;
|
|
359
411
|
return candidate.name === "ValidationError" && candidate.code === "VALIDATION_ERROR" && typeof candidate.message === "string" && typeof candidate.getUserMessage === "function" && typeof candidate.toJSON === "function";
|
|
360
412
|
}
|
|
361
413
|
function isApiError(error) {
|
|
362
|
-
return error instanceof ApiError;
|
|
414
|
+
return error instanceof ApiError || hasSDKErrorType(error, "ApiError");
|
|
363
415
|
}
|
|
364
416
|
function isConfigError(error) {
|
|
365
|
-
return error instanceof ConfigError;
|
|
417
|
+
return error instanceof ConfigError || hasSDKErrorType(error, "ConfigError");
|
|
366
418
|
}
|
|
367
419
|
function isTimeoutError(error) {
|
|
368
|
-
return error instanceof TimeoutError;
|
|
420
|
+
return error instanceof TimeoutError || hasSDKErrorType(error, "TimeoutError");
|
|
369
421
|
}
|
|
370
422
|
function isGoneError(error) {
|
|
371
|
-
return error instanceof GoneError;
|
|
423
|
+
return error instanceof GoneError || hasSDKErrorType(error, "GoneError");
|
|
372
424
|
}
|
|
373
425
|
function isServiceUnavailableError(error) {
|
|
374
|
-
return error instanceof ServiceUnavailableError;
|
|
426
|
+
return error instanceof ServiceUnavailableError || hasSDKErrorType(error, "ServiceUnavailableError");
|
|
375
427
|
}
|
|
376
428
|
function isUsageLimitError(error) {
|
|
377
|
-
return error instanceof UsageLimitError;
|
|
429
|
+
return error instanceof UsageLimitError || hasSDKErrorType(error, "UsageLimitError");
|
|
378
430
|
}
|
|
379
431
|
function isAuthError(error) {
|
|
380
|
-
return error instanceof AuthError;
|
|
432
|
+
return error instanceof AuthError || hasSDKErrorType(error, "AuthError");
|
|
381
433
|
}
|
|
382
434
|
function isPermissionError(error) {
|
|
383
|
-
return error instanceof PermissionError;
|
|
435
|
+
return error instanceof PermissionError || hasSDKErrorType(error, "PermissionError");
|
|
384
436
|
}
|
|
385
437
|
function isNotFoundError(error) {
|
|
386
|
-
return error instanceof NotFoundError;
|
|
438
|
+
return error instanceof NotFoundError || hasSDKErrorType(error, "NotFoundError");
|
|
387
439
|
}
|
|
388
440
|
function isConflictError(error) {
|
|
389
|
-
return error instanceof ConflictError;
|
|
441
|
+
return error instanceof ConflictError || hasSDKErrorType(error, "ConflictError");
|
|
390
442
|
}
|
|
391
443
|
function isRateLimitError(error) {
|
|
392
|
-
return error instanceof RateLimitError;
|
|
444
|
+
return error instanceof RateLimitError || hasSDKErrorType(error, "RateLimitError");
|
|
393
445
|
}
|
|
394
446
|
var createNetworkError = (message, status, details, userMessage, suggestion) => new NetworkError(message, status, details, userMessage, suggestion);
|
|
395
447
|
var createValidationError = (message, details, userMessage, suggestion, status) => new ValidationError(message, details, userMessage, suggestion, status);
|
|
@@ -588,11 +640,11 @@ function parseRetryAfter(response) {
|
|
|
588
640
|
permitsAutomaticRetry: seconds <= MAX_AUTOMATIC_RETRY_AFTER_SECONDS
|
|
589
641
|
};
|
|
590
642
|
}
|
|
591
|
-
function mapResponseToError(status, parsed, details, requestId, retryAfter,
|
|
643
|
+
function mapResponseToError(status, parsed, details, requestId, retryAfter, canonicalCommerceError) {
|
|
592
644
|
const errorDetails = {
|
|
593
645
|
...details,
|
|
594
646
|
...parsed.errors && { errors: parsed.errors },
|
|
595
|
-
|
|
647
|
+
...!canonicalCommerceError && parsed.body && { body: parsed.body }
|
|
596
648
|
};
|
|
597
649
|
const suggestion = getParsedErrorSuggestion(status, parsed);
|
|
598
650
|
const finalize = (error) => {
|
|
@@ -600,7 +652,7 @@ function mapResponseToError(status, parsed, details, requestId, retryAfter, erro
|
|
|
600
652
|
if (retryAfter !== void 0) {
|
|
601
653
|
Object.assign(withRequestId, { retryAfter });
|
|
602
654
|
}
|
|
603
|
-
return
|
|
655
|
+
return canonicalCommerceError ? enhanceCommerceError(withRequestId, parsed.body, requestId) : enhanceNonCommerceError(withRequestId, parsed.reason);
|
|
604
656
|
};
|
|
605
657
|
if (status === 400 || status === 422) {
|
|
606
658
|
return finalize(
|
|
@@ -706,6 +758,7 @@ async function httpFetch(url, options) {
|
|
|
706
758
|
retry,
|
|
707
759
|
onUnauthorized,
|
|
708
760
|
errorFamily,
|
|
761
|
+
typedCommerceErrorReasons,
|
|
709
762
|
...requestInit
|
|
710
763
|
} = options || {};
|
|
711
764
|
const baseUrl = resolveApiUrl(apiUrl);
|
|
@@ -759,7 +812,8 @@ async function httpFetch(url, options) {
|
|
|
759
812
|
});
|
|
760
813
|
if (!response.ok) {
|
|
761
814
|
const parsed = await parseErrorBody(response);
|
|
762
|
-
const
|
|
815
|
+
const canonicalCommerceError = errorFamily === "commerce" || typeof parsed.reason === "string" && typedCommerceErrorReasons?.includes(parsed.reason) === true;
|
|
816
|
+
const commerceEnvelope = canonicalCommerceError ? parseCommerceErrorEnvelope(parsed.body, requestId) : void 0;
|
|
763
817
|
if (isUsageLimitExceededResponse(response)) {
|
|
764
818
|
const limit = parseInt(
|
|
765
819
|
response.headers.get("X-Usage-Limit") || "0",
|
|
@@ -787,7 +841,7 @@ async function httpFetch(url, options) {
|
|
|
787
841
|
),
|
|
788
842
|
requestId
|
|
789
843
|
);
|
|
790
|
-
throw
|
|
844
|
+
throw canonicalCommerceError ? enhanceCommerceError(usageError, parsed.body, requestId) : enhanceNonCommerceError(usageError, parsed.reason);
|
|
791
845
|
}
|
|
792
846
|
if (response.status === 401 && onUnauthorized && customerToken && !hasRetried401 && (commerceEnvelope?.reason ?? parsed.reason) === "token_expired") {
|
|
793
847
|
hasRetried401 = true;
|
|
@@ -812,7 +866,7 @@ async function httpFetch(url, options) {
|
|
|
812
866
|
details,
|
|
813
867
|
requestId,
|
|
814
868
|
retryAfter.seconds,
|
|
815
|
-
|
|
869
|
+
canonicalCommerceError
|
|
816
870
|
);
|
|
817
871
|
const method2 = (requestInit.method || "GET").toUpperCase();
|
|
818
872
|
const isTerminal = error instanceof RateLimitError || error instanceof UsageLimitError;
|
|
@@ -990,15 +1044,15 @@ var HttpClient = class {
|
|
|
990
1044
|
throw err;
|
|
991
1045
|
}
|
|
992
1046
|
}
|
|
993
|
-
buildUrl(
|
|
994
|
-
if (!options) return
|
|
1047
|
+
buildUrl(endpoint, options) {
|
|
1048
|
+
if (!options) return endpoint;
|
|
995
1049
|
const { fallbackLocale, ...rest } = options;
|
|
996
1050
|
const queryOptions = fallbackLocale === void 0 ? rest : {
|
|
997
1051
|
...rest,
|
|
998
1052
|
"fallback-locale": fallbackLocale === false ? "none" : fallbackLocale
|
|
999
1053
|
};
|
|
1000
1054
|
const queryString = stringify(queryOptions, { addQueryPrefix: true });
|
|
1001
|
-
return queryString ? `${
|
|
1055
|
+
return queryString ? `${endpoint}${queryString}` : endpoint;
|
|
1002
1056
|
}
|
|
1003
1057
|
assertJsonResponse(response) {
|
|
1004
1058
|
const contentType = response.headers.get("content-type");
|
|
@@ -1147,39 +1201,39 @@ var ReadOnlyCollectionClient = class extends HttpClient {
|
|
|
1147
1201
|
from(collection) {
|
|
1148
1202
|
return new ReadOnlyCollectionQueryBuilder(this, collection);
|
|
1149
1203
|
}
|
|
1150
|
-
async requestFind(
|
|
1151
|
-
const url = this.buildUrl(
|
|
1204
|
+
async requestFind(endpoint, options) {
|
|
1205
|
+
const url = this.buildUrl(endpoint, options);
|
|
1152
1206
|
const response = await this.fetchWithTracking(url, {
|
|
1153
1207
|
...this.defaultOptions,
|
|
1154
1208
|
method: "GET"
|
|
1155
1209
|
});
|
|
1156
1210
|
return this.parseFindResponse(response);
|
|
1157
1211
|
}
|
|
1158
|
-
async requestFindEndpoint(
|
|
1159
|
-
const response = await this.fetchWithTracking(
|
|
1212
|
+
async requestFindEndpoint(endpoint, data) {
|
|
1213
|
+
const response = await this.fetchWithTracking(endpoint, {
|
|
1160
1214
|
...this.defaultOptions,
|
|
1161
1215
|
method: "POST",
|
|
1162
1216
|
body: data ? JSON.stringify(data) : void 0
|
|
1163
1217
|
});
|
|
1164
1218
|
return this.parseFindResponse(response);
|
|
1165
1219
|
}
|
|
1166
|
-
async requestFindEndpointGet(
|
|
1167
|
-
const response = await this.fetchWithTracking(
|
|
1220
|
+
async requestFindEndpointGet(endpoint) {
|
|
1221
|
+
const response = await this.fetchWithTracking(endpoint, {
|
|
1168
1222
|
...this.defaultOptions,
|
|
1169
1223
|
method: "GET"
|
|
1170
1224
|
});
|
|
1171
1225
|
return this.parseFindResponse(response);
|
|
1172
1226
|
}
|
|
1173
|
-
async requestFindById(
|
|
1174
|
-
const url = this.buildUrl(
|
|
1227
|
+
async requestFindById(endpoint, options) {
|
|
1228
|
+
const url = this.buildUrl(endpoint, options);
|
|
1175
1229
|
const response = await this.fetchWithTracking(url, {
|
|
1176
1230
|
...this.defaultOptions,
|
|
1177
1231
|
method: "GET"
|
|
1178
1232
|
});
|
|
1179
1233
|
return this.parseDocumentResponse(response);
|
|
1180
1234
|
}
|
|
1181
|
-
async requestCount(
|
|
1182
|
-
const url = this.buildUrl(
|
|
1235
|
+
async requestCount(endpoint, options) {
|
|
1236
|
+
const url = this.buildUrl(endpoint, options);
|
|
1183
1237
|
const response = await this.fetchWithTracking(url, {
|
|
1184
1238
|
...this.defaultOptions,
|
|
1185
1239
|
method: "GET"
|
|
@@ -1189,7 +1243,7 @@ var ReadOnlyCollectionClient = class extends HttpClient {
|
|
|
1189
1243
|
};
|
|
1190
1244
|
|
|
1191
1245
|
// src/core/api/parse-response.ts
|
|
1192
|
-
async function parseApiResponse(response,
|
|
1246
|
+
async function parseApiResponse(response, endpoint, options = {}) {
|
|
1193
1247
|
if (response.status === 204 || response.headers.get("content-length") === "0") {
|
|
1194
1248
|
return void 0;
|
|
1195
1249
|
}
|
|
@@ -1198,7 +1252,7 @@ async function parseApiResponse(response, endpoint2, options = {}) {
|
|
|
1198
1252
|
parsed = await response.json();
|
|
1199
1253
|
} catch {
|
|
1200
1254
|
throw createApiError(
|
|
1201
|
-
`Invalid JSON response from ${
|
|
1255
|
+
`Invalid JSON response from ${endpoint}`,
|
|
1202
1256
|
response.status,
|
|
1203
1257
|
void 0,
|
|
1204
1258
|
"Server returned an invalid response.",
|
|
@@ -1241,13 +1295,14 @@ async function parseApiResponse(response, endpoint2, options = {}) {
|
|
|
1241
1295
|
}
|
|
1242
1296
|
const withRequestId = attachRequestId(error, requestId);
|
|
1243
1297
|
if (retryAfter !== void 0) Object.assign(withRequestId, { retryAfter });
|
|
1244
|
-
throw options.errorFamily === "commerce" ? enhanceCommerceError(withRequestId, data, requestId) : withRequestId;
|
|
1298
|
+
throw options.errorFamily === "commerce" ? enhanceCommerceError(withRequestId, data, requestId) : enhanceNonCommerceError(withRequestId, reason);
|
|
1245
1299
|
}
|
|
1246
1300
|
return data;
|
|
1247
1301
|
}
|
|
1248
1302
|
|
|
1249
1303
|
// ../../internal/http-contracts/src/index.ts
|
|
1250
1304
|
var operationBrand = /* @__PURE__ */ Symbol("sdk-http-operation");
|
|
1305
|
+
var PORTONE_STANDARD_ACTION_CAPABILITIES_MEDIA_TYPE = "application/vnd.01software.portone-action-capabilities.v1+json";
|
|
1251
1306
|
var operation = (collection, method, path, errorFamily) => Object.freeze({
|
|
1252
1307
|
[operationBrand]: true,
|
|
1253
1308
|
collection,
|
|
@@ -1256,6 +1311,10 @@ var operation = (collection, method, path, errorFamily) => Object.freeze({
|
|
|
1256
1311
|
...errorFamily && { errorFamily }
|
|
1257
1312
|
});
|
|
1258
1313
|
var strictCommerceOperation = (collection, method, path) => operation(collection, method, path, "commerce");
|
|
1314
|
+
var selectiveCommerceOperation = (collection, method, path, typedCommerceErrorReasons) => Object.freeze({
|
|
1315
|
+
...operation(collection, method, path),
|
|
1316
|
+
typedCommerceErrorReasons: Object.freeze([...typedCommerceErrorReasons])
|
|
1317
|
+
});
|
|
1259
1318
|
var COMMERCE_ENDPOINT_OPERATIONS = {
|
|
1260
1319
|
products: {
|
|
1261
1320
|
detail: operation("products", "get", "/detail"),
|
|
@@ -1287,7 +1346,12 @@ var COMMERCE_ENDPOINT_OPERATIONS = {
|
|
|
1287
1346
|
confirmPayment: operation("orders", "post", "/confirm-payment"),
|
|
1288
1347
|
byPayment: operation("orders", "get", "/by-payment"),
|
|
1289
1348
|
cancel: operation("orders", "post", "/cancel"),
|
|
1290
|
-
resolveCancelRefund:
|
|
1349
|
+
resolveCancelRefund: selectiveCommerceOperation(
|
|
1350
|
+
"orders",
|
|
1351
|
+
"post",
|
|
1352
|
+
"/resolve-cancel-refund",
|
|
1353
|
+
["managed_refund_attestation_forbidden"]
|
|
1354
|
+
),
|
|
1291
1355
|
checkout: strictCommerceOperation("orders", "post", "/checkout"),
|
|
1292
1356
|
createFulfillment: operation("orders", "post", "/create-fulfillment"),
|
|
1293
1357
|
updateFulfillment: operation("orders", "post", "/update-fulfillment")
|
|
@@ -1358,6 +1422,16 @@ var COMMERCE_ENDPOINT_OPERATIONS = {
|
|
|
1358
1422
|
"payment-sessions",
|
|
1359
1423
|
"post",
|
|
1360
1424
|
"/server/confirm"
|
|
1425
|
+
),
|
|
1426
|
+
findPortOne: strictCommerceOperation(
|
|
1427
|
+
"payment-sessions",
|
|
1428
|
+
"post",
|
|
1429
|
+
"/server/portone/find"
|
|
1430
|
+
),
|
|
1431
|
+
reconcilePortOne: strictCommerceOperation(
|
|
1432
|
+
"payment-sessions",
|
|
1433
|
+
"post",
|
|
1434
|
+
"/server/portone/reconcile"
|
|
1361
1435
|
)
|
|
1362
1436
|
},
|
|
1363
1437
|
custom: {
|
|
@@ -1377,12 +1451,26 @@ var COMMERCE_ENDPOINT_OPERATIONS = {
|
|
|
1377
1451
|
validate: operation("discounts", "post", "/validate")
|
|
1378
1452
|
}
|
|
1379
1453
|
};
|
|
1454
|
+
var portOneStandardActionCapabilityOperations = /* @__PURE__ */ new Set([
|
|
1455
|
+
COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.create,
|
|
1456
|
+
COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.retrieve,
|
|
1457
|
+
COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.server.create,
|
|
1458
|
+
COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.server.retrieve
|
|
1459
|
+
]);
|
|
1380
1460
|
var MEMBERSHIP_ENDPOINT_OPERATIONS = {
|
|
1381
1461
|
subscribe: operation(null, "post", "/memberships/subscribe"),
|
|
1382
1462
|
cancel: operation(null, "post", "/memberships/:id/cancel"),
|
|
1383
1463
|
me: operation(null, "get", "/memberships/me")
|
|
1384
1464
|
};
|
|
1465
|
+
var EMBEDDED_ADMIN_ENDPOINT_OPERATIONS = {
|
|
1466
|
+
show: operation("tenants", "get", "/embedded-admin-app"),
|
|
1467
|
+
configure: operation("tenants", "patch", "/embedded-admin-app"),
|
|
1468
|
+
disable: operation("tenants", "delete", "/embedded-admin-app")
|
|
1469
|
+
};
|
|
1385
1470
|
var EVENTS_ENDPOINT_OPERATIONS = {
|
|
1471
|
+
events: {
|
|
1472
|
+
convertSchedule: operation("events", "post", "/:id/schedule")
|
|
1473
|
+
},
|
|
1386
1474
|
occurrences: {
|
|
1387
1475
|
range: operation("event-occurrences", "get", "/range"),
|
|
1388
1476
|
admissionAvailability: operation(
|
|
@@ -1423,46 +1511,51 @@ function resolveOperationMethod(descriptor) {
|
|
|
1423
1511
|
}
|
|
1424
1512
|
|
|
1425
1513
|
// src/core/api/endpoints.ts
|
|
1426
|
-
var endpoint = (method, path) => ({ method, path });
|
|
1427
1514
|
var sharedEndpoint = (descriptor) => descriptor;
|
|
1428
|
-
function resolveOperationMethod2(descriptor) {
|
|
1429
|
-
return "collection" in descriptor ? resolveOperationMethod(descriptor) : descriptor.method;
|
|
1430
|
-
}
|
|
1431
1515
|
function resolveOperationErrorFamily(descriptor) {
|
|
1432
|
-
return
|
|
1433
|
-
}
|
|
1434
|
-
function resolveOperationPath2(descriptor, options) {
|
|
1435
|
-
if ("collection" in descriptor) {
|
|
1436
|
-
return resolveOperationPath(descriptor, options);
|
|
1437
|
-
}
|
|
1438
|
-
const query = options?.query?.toString().replace(/^\?/, "");
|
|
1439
|
-
return query ? `${descriptor.path}?${query}` : descriptor.path;
|
|
1516
|
+
return descriptor.errorFamily;
|
|
1440
1517
|
}
|
|
1441
1518
|
var COMMERCE_ENDPOINTS = {
|
|
1442
1519
|
products: {
|
|
1443
|
-
detail:
|
|
1444
|
-
detailCatalog:
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1520
|
+
detail: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.products.detail),
|
|
1521
|
+
detailCatalog: sharedEndpoint(
|
|
1522
|
+
COMMERCE_ENDPOINT_OPERATIONS.products.detailCatalog
|
|
1523
|
+
),
|
|
1524
|
+
listingGroups: sharedEndpoint(
|
|
1525
|
+
COMMERCE_ENDPOINT_OPERATIONS.products.listingGroups
|
|
1526
|
+
),
|
|
1527
|
+
listingGroupsCatalog: sharedEndpoint(
|
|
1528
|
+
COMMERCE_ENDPOINT_OPERATIONS.products.listingGroupsCatalog
|
|
1529
|
+
),
|
|
1530
|
+
// The manifest keeps the GET read and the POST body-query apart; this
|
|
1531
|
+
// semantic name has always resolved to the GET one.
|
|
1532
|
+
listingGroupsQuery: sharedEndpoint(
|
|
1533
|
+
COMMERCE_ENDPOINT_OPERATIONS.products.listingGroupsQueryGet
|
|
1534
|
+
),
|
|
1535
|
+
listingGroupsQueryCatalog: sharedEndpoint(
|
|
1536
|
+
COMMERCE_ENDPOINT_OPERATIONS.products.listingGroupsQueryCatalog
|
|
1537
|
+
),
|
|
1538
|
+
stockCheck: sharedEndpoint(
|
|
1539
|
+
COMMERCE_ENDPOINT_OPERATIONS.products.stockCheck
|
|
1449
1540
|
),
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
"GET",
|
|
1453
|
-
"/api/products/listing-groups/query/catalog"
|
|
1541
|
+
stockSnapshot: sharedEndpoint(
|
|
1542
|
+
COMMERCE_ENDPOINT_OPERATIONS.products.stockSnapshot
|
|
1454
1543
|
),
|
|
1455
|
-
|
|
1456
|
-
stockSnapshot: endpoint("GET", "/api/products/stock"),
|
|
1457
|
-
upsert: endpoint("POST", "/api/products/upsert")
|
|
1544
|
+
upsert: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.products.upsert)
|
|
1458
1545
|
},
|
|
1459
1546
|
orders: {
|
|
1460
|
-
update:
|
|
1461
|
-
byPayment:
|
|
1462
|
-
cancel:
|
|
1463
|
-
resolveCancelRefund:
|
|
1464
|
-
|
|
1465
|
-
|
|
1547
|
+
update: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.orders.update),
|
|
1548
|
+
byPayment: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.orders.byPayment),
|
|
1549
|
+
cancel: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.orders.cancel),
|
|
1550
|
+
resolveCancelRefund: sharedEndpoint(
|
|
1551
|
+
COMMERCE_ENDPOINT_OPERATIONS.orders.resolveCancelRefund
|
|
1552
|
+
),
|
|
1553
|
+
createFulfillment: sharedEndpoint(
|
|
1554
|
+
COMMERCE_ENDPOINT_OPERATIONS.orders.createFulfillment
|
|
1555
|
+
),
|
|
1556
|
+
updateFulfillment: sharedEndpoint(
|
|
1557
|
+
COMMERCE_ENDPOINT_OPERATIONS.orders.updateFulfillment
|
|
1558
|
+
)
|
|
1466
1559
|
},
|
|
1467
1560
|
checkouts: {
|
|
1468
1561
|
create: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.orders.checkout),
|
|
@@ -1474,18 +1567,21 @@ var COMMERCE_ENDPOINTS = {
|
|
|
1474
1567
|
}
|
|
1475
1568
|
},
|
|
1476
1569
|
returns: {
|
|
1477
|
-
create:
|
|
1478
|
-
update:
|
|
1479
|
-
returnRefund:
|
|
1570
|
+
create: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.returns.create),
|
|
1571
|
+
update: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.returns.update),
|
|
1572
|
+
returnRefund: sharedEndpoint(
|
|
1573
|
+
COMMERCE_ENDPOINT_OPERATIONS.returns.returnRefund
|
|
1574
|
+
)
|
|
1480
1575
|
},
|
|
1481
1576
|
fulfillmentOrders: {
|
|
1482
|
-
prepare:
|
|
1483
|
-
|
|
1484
|
-
"/api/fulfillment-orders/prepare-fulfillment-order"
|
|
1577
|
+
prepare: sharedEndpoint(
|
|
1578
|
+
COMMERCE_ENDPOINT_OPERATIONS.fulfillmentOrders.prepare
|
|
1485
1579
|
)
|
|
1486
1580
|
},
|
|
1487
1581
|
fulfillments: {
|
|
1488
|
-
bulkImport:
|
|
1582
|
+
bulkImport: sharedEndpoint(
|
|
1583
|
+
COMMERCE_ENDPOINT_OPERATIONS.fulfillments.bulkImport
|
|
1584
|
+
)
|
|
1489
1585
|
},
|
|
1490
1586
|
carts: {
|
|
1491
1587
|
create: sharedEndpoint(COMMERCE_ENDPOINT_OPERATIONS.carts.create),
|
|
@@ -1550,42 +1646,21 @@ var COMMERCE_ENDPOINTS = {
|
|
|
1550
1646
|
),
|
|
1551
1647
|
confirm: sharedEndpoint(
|
|
1552
1648
|
COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.server.confirm
|
|
1649
|
+
),
|
|
1650
|
+
findPortOne: sharedEndpoint(
|
|
1651
|
+
COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.server.findPortOne
|
|
1652
|
+
),
|
|
1653
|
+
reconcilePortOne: sharedEndpoint(
|
|
1654
|
+
COMMERCE_ENDPOINT_OPERATIONS.paymentSessions.server.reconcilePortOne
|
|
1553
1655
|
)
|
|
1554
1656
|
}
|
|
1555
1657
|
},
|
|
1556
1658
|
shippingPolicies: {
|
|
1557
|
-
calculate:
|
|
1659
|
+
calculate: sharedEndpoint(
|
|
1660
|
+
COMMERCE_ENDPOINT_OPERATIONS.shippingPolicies.calculate
|
|
1661
|
+
)
|
|
1558
1662
|
}
|
|
1559
1663
|
};
|
|
1560
|
-
function isCommerceEndpointDescriptor(value) {
|
|
1561
|
-
if (!value || typeof value !== "object") return false;
|
|
1562
|
-
const candidate = value;
|
|
1563
|
-
return typeof candidate.method === "string" && typeof candidate.path === "string";
|
|
1564
|
-
}
|
|
1565
|
-
function flattenEndpointPaths(value) {
|
|
1566
|
-
if (isCommerceEndpointDescriptor(value)) return [resolveOperationPath2(value)];
|
|
1567
|
-
if (!value || typeof value !== "object") return [];
|
|
1568
|
-
return Object.values(value).flatMap((entry) => flattenEndpointPaths(entry));
|
|
1569
|
-
}
|
|
1570
|
-
function flattenEndpointDescriptors(value) {
|
|
1571
|
-
if (isCommerceEndpointDescriptor(value)) return [value];
|
|
1572
|
-
if (!value || typeof value !== "object") return [];
|
|
1573
|
-
return Object.values(value).flatMap(
|
|
1574
|
-
(entry) => flattenEndpointDescriptors(entry)
|
|
1575
|
-
);
|
|
1576
|
-
}
|
|
1577
|
-
var COMMERCE_ENDPOINT_PATHS = flattenEndpointPaths(COMMERCE_ENDPOINTS);
|
|
1578
|
-
var COMMERCE_ENDPOINT_DESCRIPTORS = flattenEndpointDescriptors(COMMERCE_ENDPOINTS);
|
|
1579
|
-
var MEMBERSHIP_ENDPOINTS = {
|
|
1580
|
-
subscribe: "/api/memberships/subscribe",
|
|
1581
|
-
cancel: (id) => `/api/memberships/${id}/cancel`,
|
|
1582
|
-
me: "/api/memberships/me"
|
|
1583
|
-
};
|
|
1584
|
-
var MEMBERSHIP_ENDPOINT_PATHS = [
|
|
1585
|
-
MEMBERSHIP_ENDPOINTS.subscribe,
|
|
1586
|
-
MEMBERSHIP_ENDPOINTS.cancel(":id"),
|
|
1587
|
-
MEMBERSHIP_ENDPOINTS.me
|
|
1588
|
-
];
|
|
1589
1664
|
|
|
1590
1665
|
// src/core/api/customer-scoped-api.ts
|
|
1591
1666
|
var CustomerScopedTransport = class {
|
|
@@ -1606,10 +1681,10 @@ var CustomerScopedTransport = class {
|
|
|
1606
1681
|
this.onUnauthorized = options.onUnauthorized;
|
|
1607
1682
|
this.onRequestId = options.onRequestId;
|
|
1608
1683
|
}
|
|
1609
|
-
async request(
|
|
1684
|
+
async request(endpoint, options) {
|
|
1610
1685
|
const token = typeof this.customerToken === "function" ? this.customerToken() : this.customerToken;
|
|
1611
1686
|
try {
|
|
1612
|
-
const response = await httpFetch(
|
|
1687
|
+
const response = await httpFetch(endpoint, {
|
|
1613
1688
|
method: options.method,
|
|
1614
1689
|
apiUrl: this.apiUrl,
|
|
1615
1690
|
publishableKey: this.publishableKey,
|
|
@@ -1623,7 +1698,7 @@ var CustomerScopedTransport = class {
|
|
|
1623
1698
|
...options.errorFamily && { errorFamily: options.errorFamily }
|
|
1624
1699
|
});
|
|
1625
1700
|
this.onRequestId?.(response.headers.get("x-request-id") ?? null);
|
|
1626
|
-
return parseApiResponse(response,
|
|
1701
|
+
return parseApiResponse(response, endpoint, {
|
|
1627
1702
|
errorFamily: options.errorFamily
|
|
1628
1703
|
});
|
|
1629
1704
|
} catch (err) {
|
|
@@ -1637,12 +1712,12 @@ var CustomerScopedApi = class {
|
|
|
1637
1712
|
constructor(apiName, options) {
|
|
1638
1713
|
this.transport = new CustomerScopedTransport(apiName, options);
|
|
1639
1714
|
}
|
|
1640
|
-
requestEndpoint(
|
|
1641
|
-
return this.transport.request(
|
|
1642
|
-
method:
|
|
1715
|
+
requestEndpoint(endpoint, body, options) {
|
|
1716
|
+
return this.transport.request(resolveOperationPath(endpoint, options), {
|
|
1717
|
+
method: resolveOperationMethod(endpoint),
|
|
1643
1718
|
body,
|
|
1644
1719
|
headers: options?.headers,
|
|
1645
|
-
errorFamily: resolveOperationErrorFamily(
|
|
1720
|
+
errorFamily: resolveOperationErrorFamily(endpoint)
|
|
1646
1721
|
});
|
|
1647
1722
|
}
|
|
1648
1723
|
};
|
|
@@ -1650,8 +1725,8 @@ var RawCustomerScopedApi = class {
|
|
|
1650
1725
|
constructor(apiName, options) {
|
|
1651
1726
|
this.transport = new CustomerScopedTransport(apiName, options);
|
|
1652
1727
|
}
|
|
1653
|
-
request(
|
|
1654
|
-
return this.transport.request(
|
|
1728
|
+
request(endpoint, options) {
|
|
1729
|
+
return this.transport.request(endpoint, options);
|
|
1655
1730
|
}
|
|
1656
1731
|
};
|
|
1657
1732
|
|
|
@@ -1665,13 +1740,7 @@ function unwrapPayloadDoc(value) {
|
|
|
1665
1740
|
return value;
|
|
1666
1741
|
}
|
|
1667
1742
|
function hasCanonicalNotFoundReason(error) {
|
|
1668
|
-
|
|
1669
|
-
if (typeof details !== "object" || details === null) return false;
|
|
1670
|
-
if ("reason" in details && details.reason === "not_found") return true;
|
|
1671
|
-
if (!("body" in details) || typeof details.body !== "object" || details.body === null) {
|
|
1672
|
-
return false;
|
|
1673
|
-
}
|
|
1674
|
-
return "reason" in details.body && details.body.reason === "not_found";
|
|
1743
|
+
return getSDKErrorReason(error) === "not_found";
|
|
1675
1744
|
}
|
|
1676
1745
|
var CommunityClient = class extends RawCustomerScopedApi {
|
|
1677
1746
|
constructor(options) {
|
|
@@ -1732,11 +1801,11 @@ var CommunityClient = class extends RawCustomerScopedApi {
|
|
|
1732
1801
|
if (params.page !== void 0) urlParams.set("page", String(params.page));
|
|
1733
1802
|
return `/api/comments/public?${urlParams.toString()}`;
|
|
1734
1803
|
}
|
|
1735
|
-
async execute(
|
|
1736
|
-
return this.request(
|
|
1804
|
+
async execute(endpoint, method, body) {
|
|
1805
|
+
return this.request(endpoint, { method, body });
|
|
1737
1806
|
}
|
|
1738
|
-
async executeDoc(
|
|
1739
|
-
const response = await this.execute(
|
|
1807
|
+
async executeDoc(endpoint, method, body) {
|
|
1808
|
+
const response = await this.execute(endpoint, method, body);
|
|
1740
1809
|
return unwrapPayloadDoc(response);
|
|
1741
1810
|
}
|
|
1742
1811
|
createPost(params) {
|
|
@@ -2002,8 +2071,8 @@ var CommunityClient = class extends RawCustomerScopedApi {
|
|
|
2002
2071
|
|
|
2003
2072
|
// src/core/content/content-client.ts
|
|
2004
2073
|
var PublicContentApi = class extends RawCustomerScopedApi {
|
|
2005
|
-
get(
|
|
2006
|
-
return this.request(
|
|
2074
|
+
get(endpoint) {
|
|
2075
|
+
return this.request(endpoint, { method: "GET" });
|
|
2007
2076
|
}
|
|
2008
2077
|
};
|
|
2009
2078
|
function appendCommonParams(search, options, defaultSort) {
|
|
@@ -2184,6 +2253,9 @@ function nullableString(value, resource, path) {
|
|
|
2184
2253
|
fail(resource, path, "string or null");
|
|
2185
2254
|
}
|
|
2186
2255
|
}
|
|
2256
|
+
function nullableNonEmptyString(value, resource, path) {
|
|
2257
|
+
if (value !== null) string(value, resource, path);
|
|
2258
|
+
}
|
|
2187
2259
|
function cartLineQuantity(value, resource, path) {
|
|
2188
2260
|
const quantity = positiveInteger(value, resource, path);
|
|
2189
2261
|
if (quantity > MAX_CART_LINE_QUANTITY) {
|
|
@@ -2693,8 +2765,8 @@ function validatePublicOrderItem(value, resource, path) {
|
|
|
2693
2765
|
validateReference(item.variant, resource, `${path}.variant`);
|
|
2694
2766
|
}
|
|
2695
2767
|
string(item.productTitle, resource, `${path}.productTitle`);
|
|
2696
|
-
|
|
2697
|
-
|
|
2768
|
+
nullableNonEmptyString(item.variantTitle, resource, `${path}.variantTitle`);
|
|
2769
|
+
nullableNonEmptyString(item.sku, resource, `${path}.sku`);
|
|
2698
2770
|
validateAdmissions(item.admissions, resource, `${path}.admissions`);
|
|
2699
2771
|
const quantity = positiveInteger(item.quantity, resource, `${path}.quantity`);
|
|
2700
2772
|
const unitPrice = safeMinor(
|
|
@@ -2945,8 +3017,8 @@ function validateCheckoutItem(value, resource, path) {
|
|
|
2945
3017
|
validateReference(item.product, resource, `${path}.product`);
|
|
2946
3018
|
validateReference(item.variant, resource, `${path}.variant`);
|
|
2947
3019
|
string(item.productTitle, resource, `${path}.productTitle`);
|
|
2948
|
-
|
|
2949
|
-
|
|
3020
|
+
nullableNonEmptyString(item.variantTitle, resource, `${path}.variantTitle`);
|
|
3021
|
+
nullableNonEmptyString(item.sku, resource, `${path}.sku`);
|
|
2950
3022
|
validateAdmissions(item.admissions, resource, `${path}.admissions`);
|
|
2951
3023
|
cartLineQuantity(item.quantity, resource, `${path}.quantity`);
|
|
2952
3024
|
const unitPrice = safeMinor(
|
|
@@ -3277,9 +3349,96 @@ function validateRequiredReconciliation(value, allowed, resource, path) {
|
|
|
3277
3349
|
function validateNextAction(value, provider, resource, path) {
|
|
3278
3350
|
const action = record(value, resource, path);
|
|
3279
3351
|
if (provider === "portone") {
|
|
3352
|
+
if (action.type === "portone_sdk") {
|
|
3353
|
+
const hasCancelable = "cancelable" in action;
|
|
3354
|
+
const hasRetryPolicy = "retryPolicy" in action;
|
|
3355
|
+
if (hasCancelable !== hasRetryPolicy) {
|
|
3356
|
+
fail(
|
|
3357
|
+
resource,
|
|
3358
|
+
path,
|
|
3359
|
+
"exact released action or exact negotiated capability action"
|
|
3360
|
+
);
|
|
3361
|
+
}
|
|
3362
|
+
exact(
|
|
3363
|
+
action,
|
|
3364
|
+
[
|
|
3365
|
+
"type",
|
|
3366
|
+
"version",
|
|
3367
|
+
...hasCancelable ? ["cancelable", "retryPolicy"] : [],
|
|
3368
|
+
"storeId",
|
|
3369
|
+
"channelKey",
|
|
3370
|
+
"paymentId",
|
|
3371
|
+
"orderName",
|
|
3372
|
+
"totalAmount",
|
|
3373
|
+
"currency",
|
|
3374
|
+
"payMethod",
|
|
3375
|
+
"redirectUrl"
|
|
3376
|
+
],
|
|
3377
|
+
[],
|
|
3378
|
+
resource,
|
|
3379
|
+
path
|
|
3380
|
+
);
|
|
3381
|
+
if (action.version !== "v2") fail(resource, `${path}.version`, "v2");
|
|
3382
|
+
if (hasCancelable && action.cancelable !== false)
|
|
3383
|
+
fail(resource, `${path}.cancelable`, "false");
|
|
3384
|
+
if (hasRetryPolicy && action.retryPolicy !== "same_action_only") {
|
|
3385
|
+
fail(resource, `${path}.retryPolicy`, "same_action_only");
|
|
3386
|
+
}
|
|
3387
|
+
for (const key of ["storeId", "channelKey"]) {
|
|
3388
|
+
boundedString(action[key], 255, resource, `${path}.${key}`);
|
|
3389
|
+
}
|
|
3390
|
+
const paymentId = boundedString(
|
|
3391
|
+
action.paymentId,
|
|
3392
|
+
40,
|
|
3393
|
+
resource,
|
|
3394
|
+
`${path}.paymentId`
|
|
3395
|
+
);
|
|
3396
|
+
if (!/^[A-Za-z0-9]{6,40}$/.test(paymentId)) {
|
|
3397
|
+
fail(
|
|
3398
|
+
resource,
|
|
3399
|
+
`${path}.paymentId`,
|
|
3400
|
+
"6-40 ASCII alphanumeric characters"
|
|
3401
|
+
);
|
|
3402
|
+
}
|
|
3403
|
+
boundedString(
|
|
3404
|
+
action.orderName,
|
|
3405
|
+
MAX_COMMERCE_SHORT_TEXT_LENGTH,
|
|
3406
|
+
resource,
|
|
3407
|
+
`${path}.orderName`
|
|
3408
|
+
);
|
|
3409
|
+
positiveInteger(action.totalAmount, resource, `${path}.totalAmount`);
|
|
3410
|
+
if (action.currency !== "CURRENCY_KRW") {
|
|
3411
|
+
fail(resource, `${path}.currency`, "CURRENCY_KRW");
|
|
3412
|
+
}
|
|
3413
|
+
if (action.payMethod !== "CARD")
|
|
3414
|
+
fail(resource, `${path}.payMethod`, "CARD");
|
|
3415
|
+
const redirectUrl = boundedString(
|
|
3416
|
+
action.redirectUrl,
|
|
3417
|
+
2048,
|
|
3418
|
+
resource,
|
|
3419
|
+
`${path}.redirectUrl`
|
|
3420
|
+
);
|
|
3421
|
+
try {
|
|
3422
|
+
const parsed = new URL(redirectUrl);
|
|
3423
|
+
const loopback = parsed.protocol === "http:" && (parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1");
|
|
3424
|
+
if (!loopback && parsed.protocol !== "https:" || parsed.username || parsed.password)
|
|
3425
|
+
throw new Error("unsafe redirect URL");
|
|
3426
|
+
} catch {
|
|
3427
|
+
fail(
|
|
3428
|
+
resource,
|
|
3429
|
+
`${path}.redirectUrl`,
|
|
3430
|
+
"HTTPS or loopback URL without embedded credentials"
|
|
3431
|
+
);
|
|
3432
|
+
}
|
|
3433
|
+
if (!hasCancelable) {
|
|
3434
|
+
action.cancelable = false;
|
|
3435
|
+
action.retryPolicy = "same_action_only";
|
|
3436
|
+
}
|
|
3437
|
+
return;
|
|
3438
|
+
}
|
|
3280
3439
|
exact(action, ["type", "checkoutUrl"], [], resource, path);
|
|
3281
3440
|
if (action.type !== "portone_checkout") {
|
|
3282
|
-
fail(resource, `${path}.type`, "portone_checkout");
|
|
3441
|
+
fail(resource, `${path}.type`, "portone_checkout | portone_sdk");
|
|
3283
3442
|
}
|
|
3284
3443
|
const checkoutUrl = boundedString(
|
|
3285
3444
|
action.checkoutUrl,
|
|
@@ -4009,8 +4168,8 @@ var CartApi = class extends CustomerScopedApi {
|
|
|
4009
4168
|
endpoint(key) {
|
|
4010
4169
|
return this.serverTransport ? COMMERCE_ENDPOINTS.carts.server[key] : COMMERCE_ENDPOINTS.carts[key];
|
|
4011
4170
|
}
|
|
4012
|
-
execute(
|
|
4013
|
-
return this.requestEndpoint(
|
|
4171
|
+
execute(endpoint, body, idempotencyKey) {
|
|
4172
|
+
return this.requestEndpoint(endpoint, body, {
|
|
4014
4173
|
...idempotencyKey && {
|
|
4015
4174
|
headers: { "X-Idempotency-Key": idempotencyKey }
|
|
4016
4175
|
}
|
|
@@ -4027,26 +4186,26 @@ var CartApi = class extends CustomerScopedApi {
|
|
|
4027
4186
|
);
|
|
4028
4187
|
}
|
|
4029
4188
|
mine(params = {}) {
|
|
4030
|
-
const
|
|
4031
|
-
return this.execute(
|
|
4189
|
+
const endpoint = this.endpoint("mine");
|
|
4190
|
+
return this.execute(endpoint, params).then(
|
|
4032
4191
|
(value) => validateCartMineResult(value)
|
|
4033
4192
|
);
|
|
4034
4193
|
}
|
|
4035
4194
|
merge(params) {
|
|
4036
4195
|
const { idempotencyKey, ...body } = params;
|
|
4037
4196
|
assertCommerceIdempotencyKey(idempotencyKey);
|
|
4038
|
-
const
|
|
4039
|
-
return this.execute(
|
|
4197
|
+
const endpoint = this.endpoint("merge");
|
|
4198
|
+
return this.execute(endpoint, body, idempotencyKey).then(
|
|
4040
4199
|
(value) => validateCartMergeResult(value)
|
|
4041
4200
|
);
|
|
4042
4201
|
}
|
|
4043
4202
|
addItem(params) {
|
|
4044
4203
|
return this.mutate(this.endpoint("addItem"), params);
|
|
4045
4204
|
}
|
|
4046
|
-
mutate(
|
|
4205
|
+
mutate(endpoint, params) {
|
|
4047
4206
|
const { idempotencyKey, ...body } = params;
|
|
4048
4207
|
assertCommerceIdempotencyKey(idempotencyKey);
|
|
4049
|
-
return this.execute(
|
|
4208
|
+
return this.execute(endpoint, body, idempotencyKey).then(
|
|
4050
4209
|
(value) => validateCartMutationResult(value)
|
|
4051
4210
|
);
|
|
4052
4211
|
}
|
|
@@ -4072,8 +4231,8 @@ var CheckoutApi = class extends CustomerScopedApi {
|
|
|
4072
4231
|
constructor(options) {
|
|
4073
4232
|
super("CheckoutApi", { ...options, requiresCredential: false });
|
|
4074
4233
|
}
|
|
4075
|
-
post(
|
|
4076
|
-
return this.requestEndpoint(
|
|
4234
|
+
post(endpoint, body, idempotencyKey) {
|
|
4235
|
+
return this.requestEndpoint(endpoint, body, {
|
|
4077
4236
|
...idempotencyKey && {
|
|
4078
4237
|
headers: { "X-Idempotency-Key": idempotencyKey }
|
|
4079
4238
|
}
|
|
@@ -4140,11 +4299,15 @@ var PaymentSessionApi = class extends CustomerScopedApi {
|
|
|
4140
4299
|
super("PaymentSessionApi", { ...options, requiresCredential: false });
|
|
4141
4300
|
this.serverTransport = Boolean(options.secretKey);
|
|
4142
4301
|
}
|
|
4143
|
-
post(
|
|
4144
|
-
|
|
4145
|
-
...idempotencyKey && {
|
|
4146
|
-
|
|
4302
|
+
post(endpoint, body, idempotencyKey, negotiateStandardActionCapabilities = false) {
|
|
4303
|
+
const headers = {
|
|
4304
|
+
...idempotencyKey && { "X-Idempotency-Key": idempotencyKey },
|
|
4305
|
+
...negotiateStandardActionCapabilities && {
|
|
4306
|
+
Accept: PORTONE_STANDARD_ACTION_CAPABILITIES_MEDIA_TYPE
|
|
4147
4307
|
}
|
|
4308
|
+
};
|
|
4309
|
+
return this.requestEndpoint(endpoint, body, {
|
|
4310
|
+
...Object.keys(headers).length > 0 && { headers }
|
|
4148
4311
|
});
|
|
4149
4312
|
}
|
|
4150
4313
|
async paymentSession(result, expectedProvider) {
|
|
@@ -4169,40 +4332,41 @@ var PaymentSessionApi = class extends CustomerScopedApi {
|
|
|
4169
4332
|
this.post(
|
|
4170
4333
|
this.serverTransport ? COMMERCE_ENDPOINTS.paymentSessions.server.create : COMMERCE_ENDPOINTS.paymentSessions.create,
|
|
4171
4334
|
body,
|
|
4172
|
-
idempotencyKey
|
|
4335
|
+
idempotencyKey,
|
|
4336
|
+
body.providerOptions.profile === "standard_v2"
|
|
4173
4337
|
),
|
|
4174
4338
|
"portone"
|
|
4175
4339
|
);
|
|
4176
4340
|
}
|
|
4177
4341
|
retrieve(params) {
|
|
4178
|
-
const
|
|
4342
|
+
const endpoint = this.serverTransport ? COMMERCE_ENDPOINTS.paymentSessions.server.retrieve : COMMERCE_ENDPOINTS.paymentSessions.retrieve;
|
|
4179
4343
|
return this.paymentSession(
|
|
4180
|
-
this.post(
|
|
4344
|
+
this.post(endpoint, params),
|
|
4181
4345
|
"toss"
|
|
4182
4346
|
);
|
|
4183
4347
|
}
|
|
4184
4348
|
retrievePortOne(params) {
|
|
4185
|
-
const
|
|
4349
|
+
const endpoint = this.serverTransport ? COMMERCE_ENDPOINTS.paymentSessions.server.retrieve : COMMERCE_ENDPOINTS.paymentSessions.retrieve;
|
|
4186
4350
|
return this.paymentSession(
|
|
4187
|
-
this.post(
|
|
4351
|
+
this.post(endpoint, params, void 0, true),
|
|
4188
4352
|
"portone"
|
|
4189
4353
|
);
|
|
4190
4354
|
}
|
|
4191
4355
|
cancel(params) {
|
|
4192
4356
|
const { idempotencyKey, ...body } = params;
|
|
4193
4357
|
assertCommerceIdempotencyKey(idempotencyKey);
|
|
4194
|
-
const
|
|
4358
|
+
const endpoint = this.serverTransport ? COMMERCE_ENDPOINTS.paymentSessions.server.cancel : COMMERCE_ENDPOINTS.paymentSessions.cancel;
|
|
4195
4359
|
return this.paymentSession(
|
|
4196
|
-
this.post(
|
|
4360
|
+
this.post(endpoint, body, idempotencyKey),
|
|
4197
4361
|
"toss"
|
|
4198
4362
|
);
|
|
4199
4363
|
}
|
|
4200
4364
|
cancelPortOne(params) {
|
|
4201
4365
|
const { idempotencyKey, ...body } = params;
|
|
4202
4366
|
assertCommerceIdempotencyKey(idempotencyKey);
|
|
4203
|
-
const
|
|
4367
|
+
const endpoint = this.serverTransport ? COMMERCE_ENDPOINTS.paymentSessions.server.cancel : COMMERCE_ENDPOINTS.paymentSessions.cancel;
|
|
4204
4368
|
return this.paymentSession(
|
|
4205
|
-
this.post(
|
|
4369
|
+
this.post(endpoint, body, idempotencyKey),
|
|
4206
4370
|
"portone"
|
|
4207
4371
|
);
|
|
4208
4372
|
}
|
|
@@ -4281,9 +4445,9 @@ function resolveVariantImageItems(variant, poolById) {
|
|
|
4281
4445
|
if (pooled) resolved.push(pooled);
|
|
4282
4446
|
continue;
|
|
4283
4447
|
}
|
|
4284
|
-
const
|
|
4285
|
-
if (
|
|
4286
|
-
const pooled = poolById.get(
|
|
4448
|
+
const mediaId = getMediaId(entry);
|
|
4449
|
+
if (mediaId) {
|
|
4450
|
+
const pooled = poolById.get(mediaId);
|
|
4287
4451
|
if (pooled) {
|
|
4288
4452
|
resolved.push(pooled);
|
|
4289
4453
|
}
|
|
@@ -4474,11 +4638,11 @@ function getFirstMediaId(values) {
|
|
|
4474
4638
|
}
|
|
4475
4639
|
return null;
|
|
4476
4640
|
}
|
|
4477
|
-
function inProductMediaPool(product,
|
|
4478
|
-
if (
|
|
4641
|
+
function inProductMediaPool(product, mediaId) {
|
|
4642
|
+
if (mediaId == null) return null;
|
|
4479
4643
|
const images = Array.isArray(product?.images) ? product.images : [];
|
|
4480
4644
|
for (const image of images) {
|
|
4481
|
-
if (extractEntityId(image) ===
|
|
4645
|
+
if (extractEntityId(image) === mediaId) return mediaId;
|
|
4482
4646
|
}
|
|
4483
4647
|
return null;
|
|
4484
4648
|
}
|
|
@@ -5954,21 +6118,11 @@ var PRODUCT_DETAIL_UNAVAILABLE_REASONS = /* @__PURE__ */ new Set([
|
|
|
5954
6118
|
"not_published",
|
|
5955
6119
|
"feature_disabled"
|
|
5956
6120
|
]);
|
|
5957
|
-
function isRecord(value) {
|
|
5958
|
-
return typeof value === "object" && value !== null;
|
|
5959
|
-
}
|
|
5960
|
-
function readProductDetailUnavailableReason(value) {
|
|
5961
|
-
if (!isRecord(value)) return void 0;
|
|
5962
|
-
const directReason = value.reason ?? value.code;
|
|
5963
|
-
if (typeof directReason === "string" && PRODUCT_DETAIL_UNAVAILABLE_REASONS.has(directReason)) {
|
|
5964
|
-
return directReason;
|
|
5965
|
-
}
|
|
5966
|
-
return readProductDetailUnavailableReason(value.body);
|
|
5967
|
-
}
|
|
5968
6121
|
function productDetailResultFromError(error) {
|
|
5969
6122
|
if (!(error instanceof SDKError) || error.status !== 404) return void 0;
|
|
5970
|
-
const reason =
|
|
5971
|
-
if (!reason
|
|
6123
|
+
const reason = getSDKErrorReason(error);
|
|
6124
|
+
if (!reason || !PRODUCT_DETAIL_UNAVAILABLE_REASONS.has(reason))
|
|
6125
|
+
return void 0;
|
|
5972
6126
|
return { found: false, reason };
|
|
5973
6127
|
}
|
|
5974
6128
|
var MARKET_PRICE_QUERY_UNSUPPORTED_MESSAGE = "Market listing pages do not support base price filters or price sorts.";
|
|
@@ -6069,8 +6223,8 @@ function isProductUpsertFieldValidationErrorBody(value) {
|
|
|
6069
6223
|
|
|
6070
6224
|
// src/core/commerce/commerce-client.ts
|
|
6071
6225
|
var BrowserCommerceApi = class extends CustomerScopedApi {
|
|
6072
|
-
requestEndpoint(
|
|
6073
|
-
return super.requestEndpoint(
|
|
6226
|
+
requestEndpoint(endpoint, body, options) {
|
|
6227
|
+
return super.requestEndpoint(endpoint, body, options);
|
|
6074
6228
|
}
|
|
6075
6229
|
};
|
|
6076
6230
|
var CommerceClient = class {
|
|
@@ -6270,11 +6424,11 @@ var EventsClient = class {
|
|
|
6270
6424
|
{ useCustomerAuth: false }
|
|
6271
6425
|
);
|
|
6272
6426
|
}
|
|
6273
|
-
async execute(
|
|
6427
|
+
async execute(endpoint, method, body, options = {}) {
|
|
6274
6428
|
const useCustomerAuth = options.useCustomerAuth === true;
|
|
6275
6429
|
const token = useCustomerAuth ? typeof this.customerToken === "function" ? this.customerToken() : this.customerToken : void 0;
|
|
6276
6430
|
try {
|
|
6277
|
-
const response = await httpFetch(
|
|
6431
|
+
const response = await httpFetch(endpoint, {
|
|
6278
6432
|
method,
|
|
6279
6433
|
apiUrl: this.apiUrl,
|
|
6280
6434
|
publishableKey: this.publishableKey,
|
|
@@ -6283,7 +6437,7 @@ var EventsClient = class {
|
|
|
6283
6437
|
...body !== void 0 && { body: JSON.stringify(body) }
|
|
6284
6438
|
});
|
|
6285
6439
|
this.onRequestId?.(response.headers.get("x-request-id") ?? null);
|
|
6286
|
-
return parseApiResponse(response,
|
|
6440
|
+
return parseApiResponse(response, endpoint);
|
|
6287
6441
|
} catch (err) {
|
|
6288
6442
|
const id = err instanceof SDKError ? err.requestId ?? null : null;
|
|
6289
6443
|
this.onRequestId?.(id);
|
|
@@ -6541,13 +6695,106 @@ function mergeProductDetailWithStock(catalog, snapshot) {
|
|
|
6541
6695
|
};
|
|
6542
6696
|
}
|
|
6543
6697
|
|
|
6698
|
+
// src/core/webhook/validation.ts
|
|
6699
|
+
function isValidWebhookEventData(data) {
|
|
6700
|
+
if (typeof data !== "object" || data === null) return false;
|
|
6701
|
+
const event = data;
|
|
6702
|
+
return typeof event.collection === "string" && typeof event.operation === "string" && event.operation.length > 0 && typeof event.data === "object" && event.data !== null;
|
|
6703
|
+
}
|
|
6704
|
+
|
|
6705
|
+
// src/core/webhook/receiver.ts
|
|
6706
|
+
async function verifySignature(rawBody, secret, signature, timestamp2, deliveryId) {
|
|
6707
|
+
const encoder = new TextEncoder();
|
|
6708
|
+
const signedPrefix = encoder.encode(`${timestamp2}.${deliveryId}.`);
|
|
6709
|
+
const signedPayload = new Uint8Array(signedPrefix.length + rawBody.length);
|
|
6710
|
+
signedPayload.set(signedPrefix);
|
|
6711
|
+
signedPayload.set(rawBody, signedPrefix.length);
|
|
6712
|
+
const key = await crypto.subtle.importKey(
|
|
6713
|
+
"raw",
|
|
6714
|
+
encoder.encode(secret),
|
|
6715
|
+
{ name: "HMAC", hash: "SHA-256" },
|
|
6716
|
+
false,
|
|
6717
|
+
["verify"]
|
|
6718
|
+
);
|
|
6719
|
+
if (signature.length % 2 !== 0 || !/^[0-9a-fA-F]*$/.test(signature)) {
|
|
6720
|
+
return false;
|
|
6721
|
+
}
|
|
6722
|
+
const sigBytes = new Uint8Array(
|
|
6723
|
+
(signature.match(/.{2}/g) ?? []).map((byte) => parseInt(byte, 16))
|
|
6724
|
+
);
|
|
6725
|
+
return crypto.subtle.verify("HMAC", key, sigBytes, signedPayload);
|
|
6726
|
+
}
|
|
6727
|
+
function timestampIsFresh(timestamp2, toleranceSeconds) {
|
|
6728
|
+
if (!/^\d+$/.test(timestamp2)) return false;
|
|
6729
|
+
const timestampMs = Number(timestamp2);
|
|
6730
|
+
if (!Number.isFinite(timestampMs)) return false;
|
|
6731
|
+
const skewMs = Math.abs(Date.now() - timestampMs);
|
|
6732
|
+
return skewMs <= toleranceSeconds * 1e3;
|
|
6733
|
+
}
|
|
6734
|
+
var MAX_TOLERANCE_SECONDS = 86400;
|
|
6735
|
+
function toleranceIsValid(toleranceSeconds) {
|
|
6736
|
+
return typeof toleranceSeconds === "number" && Number.isFinite(toleranceSeconds) && toleranceSeconds >= 0 && toleranceSeconds <= MAX_TOLERANCE_SECONDS;
|
|
6737
|
+
}
|
|
6738
|
+
async function processWebhookRequest(request, handler, verify) {
|
|
6739
|
+
try {
|
|
6740
|
+
const rawBody = new Uint8Array(await request.arrayBuffer());
|
|
6741
|
+
const verificationFailure = await verify?.(rawBody);
|
|
6742
|
+
if (verificationFailure) return verificationFailure;
|
|
6743
|
+
const body = JSON.parse(new TextDecoder().decode(rawBody));
|
|
6744
|
+
if (!isValidWebhookEventData(body)) {
|
|
6745
|
+
return new Response(
|
|
6746
|
+
JSON.stringify({ error: "Invalid webhook event format" }),
|
|
6747
|
+
{ status: 400, headers: { "Content-Type": "application/json" } }
|
|
6748
|
+
);
|
|
6749
|
+
}
|
|
6750
|
+
await handler(body);
|
|
6751
|
+
return new Response(
|
|
6752
|
+
JSON.stringify({ success: true, message: "Webhook processed" }),
|
|
6753
|
+
{ status: 200, headers: { "Content-Type": "application/json" } }
|
|
6754
|
+
);
|
|
6755
|
+
} catch (error) {
|
|
6756
|
+
console.error("Webhook processing error:", error);
|
|
6757
|
+
return new Response(JSON.stringify({ error: "Internal server error" }), {
|
|
6758
|
+
status: 500,
|
|
6759
|
+
headers: { "Content-Type": "application/json" }
|
|
6760
|
+
});
|
|
6761
|
+
}
|
|
6762
|
+
}
|
|
6763
|
+
async function handleSignedWebhook(request, handler, options) {
|
|
6764
|
+
const secret = options?.secret;
|
|
6765
|
+
const configuredTolerance = options?.toleranceSeconds;
|
|
6766
|
+
const toleranceSeconds = configuredTolerance ?? 300;
|
|
6767
|
+
if (typeof secret !== "string" || secret.trim().length === 0) {
|
|
6768
|
+
return new Response(
|
|
6769
|
+
JSON.stringify({ error: "Webhook signing secret is not configured" }),
|
|
6770
|
+
{ status: 500, headers: { "Content-Type": "application/json" } }
|
|
6771
|
+
);
|
|
6772
|
+
}
|
|
6773
|
+
if (!toleranceIsValid(toleranceSeconds)) {
|
|
6774
|
+
return new Response(
|
|
6775
|
+
JSON.stringify({ error: "Webhook signature tolerance is not valid" }),
|
|
6776
|
+
{ status: 500, headers: { "Content-Type": "application/json" } }
|
|
6777
|
+
);
|
|
6778
|
+
}
|
|
6779
|
+
return processWebhookRequest(request, handler, async (rawBody) => {
|
|
6780
|
+
const signature = request.headers.get("x-webhook-signature") || "";
|
|
6781
|
+
const timestamp2 = request.headers.get("x-webhook-timestamp") || "";
|
|
6782
|
+
const deliveryId = request.headers.get("x-webhook-delivery-id") || "";
|
|
6783
|
+
const valid = Boolean(timestamp2 && deliveryId) && timestampIsFresh(timestamp2, toleranceSeconds) && await verifySignature(rawBody, secret, signature, timestamp2, deliveryId);
|
|
6784
|
+
if (!valid) {
|
|
6785
|
+
return new Response(
|
|
6786
|
+
JSON.stringify({ error: "Invalid webhook signature" }),
|
|
6787
|
+
{ status: 401, headers: { "Content-Type": "application/json" } }
|
|
6788
|
+
);
|
|
6789
|
+
}
|
|
6790
|
+
});
|
|
6791
|
+
}
|
|
6792
|
+
|
|
6544
6793
|
// src/core/webhook/index.ts
|
|
6545
6794
|
var ORDER_CHANGED_EVENT_TYPE = "collection.orderChanged";
|
|
6546
6795
|
var COMMERCE_NOTIFICATION_EVENT_TYPE = "commerce.notification";
|
|
6547
6796
|
function isValidWebhookEvent(data) {
|
|
6548
|
-
|
|
6549
|
-
const obj = data;
|
|
6550
|
-
return typeof obj.collection === "string" && typeof obj.operation === "string" && obj.operation.length > 0 && typeof obj.data === "object" && obj.data !== null;
|
|
6797
|
+
return isValidWebhookEventData(data);
|
|
6551
6798
|
}
|
|
6552
6799
|
var COMMERCE_NOTIFICATION_OPERATION = "notification";
|
|
6553
6800
|
var COMMERCE_NOTIFICATION_EVENTS = [
|
|
@@ -6559,13 +6806,15 @@ var COMMERCE_NOTIFICATION_EVENTS = [
|
|
|
6559
6806
|
"returnApproved",
|
|
6560
6807
|
"returnRejected",
|
|
6561
6808
|
"returnCanceled",
|
|
6562
|
-
"returnCompleted"
|
|
6809
|
+
"returnCompleted",
|
|
6810
|
+
"paymentReconciliationRequired",
|
|
6811
|
+
"paymentRefundRequiresAttention"
|
|
6563
6812
|
];
|
|
6564
6813
|
function isStringOrNumber(value) {
|
|
6565
6814
|
return typeof value === "string" || typeof value === "number";
|
|
6566
6815
|
}
|
|
6567
6816
|
function isWebhookOrderScope(value) {
|
|
6568
|
-
if (!
|
|
6817
|
+
if (!isRecord(value)) return false;
|
|
6569
6818
|
if (value.kind === "collection") {
|
|
6570
6819
|
return typeof value.collection === "string";
|
|
6571
6820
|
}
|
|
@@ -6575,35 +6824,42 @@ function isWebhookOrderScope(value) {
|
|
|
6575
6824
|
return false;
|
|
6576
6825
|
}
|
|
6577
6826
|
function isWebhookOrderMoved(value) {
|
|
6578
|
-
if (!
|
|
6827
|
+
if (!isRecord(value)) return false;
|
|
6579
6828
|
return typeof value.collection === "string" && isStringOrNumber(value.id) && (value.relatedCollection === void 0 || typeof value.relatedCollection === "string") && (value.relatedId === void 0 || isStringOrNumber(value.relatedId));
|
|
6580
6829
|
}
|
|
6581
6830
|
function hasOptionalOrderValue(value, key) {
|
|
6582
6831
|
return value[key] === void 0 || value[key] === null || typeof value[key] === "string";
|
|
6583
6832
|
}
|
|
6584
6833
|
function isWebhookOrderChange(value) {
|
|
6585
|
-
if (!
|
|
6834
|
+
if (!isRecord(value)) return false;
|
|
6586
6835
|
return value.type === "order" && value.source === "payload-orderable" && (value.orderableFieldName === void 0 || typeof value.orderableFieldName === "string") && hasOptionalOrderValue(value, "previousOrder") && hasOptionalOrderValue(value, "nextOrder") && isWebhookOrderScope(value.scope) && isWebhookOrderMoved(value.moved);
|
|
6587
6836
|
}
|
|
6588
6837
|
function isCommerceNotificationEventName(value) {
|
|
6589
6838
|
return typeof value === "string" && COMMERCE_NOTIFICATION_EVENTS.includes(value);
|
|
6590
6839
|
}
|
|
6591
6840
|
function isCommerceNotificationSourceCollection(value) {
|
|
6592
|
-
return value === "orders" || value === "fulfillments" || value === "returns";
|
|
6841
|
+
return value === "orders" || value === "fulfillments" || value === "returns" || value === "payment-sessions" || value === "payment-refund-attempts";
|
|
6593
6842
|
}
|
|
6594
6843
|
function isCommerceNotificationData(value) {
|
|
6595
|
-
if (!
|
|
6596
|
-
if (value.source !== void 0 && (!
|
|
6844
|
+
if (!isRecord(value)) return false;
|
|
6845
|
+
if (value.source !== void 0 && (!isRecord(value.source) || !isCommerceNotificationSourceCollection(value.source.collection) || !isStringOrNumber(value.source.id))) {
|
|
6597
6846
|
return false;
|
|
6598
6847
|
}
|
|
6599
|
-
return (value.orderId === void 0 || isStringOrNumber(value.orderId)) && (value.orderNumber === void 0 || typeof value.orderNumber === "string") && (value.status === void 0 || typeof value.status === "string") && (value.totalAmount === void 0 || typeof value.totalAmount === "number") && (value.currency === void 0 || typeof value.currency === "string") && (value.fulfillmentId === void 0 || isStringOrNumber(value.fulfillmentId)) && (value.fulfillmentStatus === void 0 || typeof value.fulfillmentStatus === "string") && (value.shippedAt === void 0 || typeof value.shippedAt === "string") && (value.returnId === void 0 || isStringOrNumber(value.returnId)) && (value.returnStatus === void 0 || typeof value.returnStatus === "string") && (value.refundAmount === void 0 || typeof value.refundAmount === "number") && (value.completedAt === void 0 || typeof value.completedAt === "string");
|
|
6848
|
+
return (value.orderId === void 0 || isStringOrNumber(value.orderId)) && (value.orderNumber === void 0 || typeof value.orderNumber === "string") && (value.status === void 0 || typeof value.status === "string") && (value.totalAmount === void 0 || typeof value.totalAmount === "number") && (value.currency === void 0 || typeof value.currency === "string") && (value.fulfillmentId === void 0 || isStringOrNumber(value.fulfillmentId)) && (value.fulfillmentStatus === void 0 || typeof value.fulfillmentStatus === "string") && (value.shippedAt === void 0 || typeof value.shippedAt === "string") && (value.returnId === void 0 || isStringOrNumber(value.returnId)) && (value.returnStatus === void 0 || typeof value.returnStatus === "string") && (value.refundAmount === void 0 || typeof value.refundAmount === "number") && (value.completedAt === void 0 || typeof value.completedAt === "string") && (value.paymentSessionId === void 0 || typeof value.paymentSessionId === "string") && (value.checkoutId === void 0 || typeof value.checkoutId === "string") && (value.refundAttemptId === void 0 || typeof value.refundAttemptId === "string") && (value.reason === void 0 || typeof value.reason === "string") && (value.observedAt === void 0 || typeof value.observedAt === "string") && (value.providerObject === void 0 || isRecord(value.providerObject) && typeof value.providerObject.provider === "string" && (value.providerObject.kind === "payment" || value.providerObject.kind === "refund") && typeof value.providerObject.id === "string") && (value.money === void 0 || isRecord(value.money) && Number.isSafeInteger(value.money.amountMinor) && Number(value.money.amountMinor) > 0 && typeof value.money.currency === "string");
|
|
6600
6849
|
}
|
|
6601
6850
|
function isCommerceNotification(value) {
|
|
6602
|
-
if (!
|
|
6603
|
-
return isCommerceNotificationEventName(value.event) && typeof value.intentId === "string" && value.intentId.length > 0 && typeof value.dedupeKey === "string" && value.dedupeKey.length > 0 && (value.orderId === void 0 || typeof value.orderId === "string") && (value.fulfillmentId === void 0 || typeof value.fulfillmentId === "string") && (value.returnId === void 0 || typeof value.returnId === "string");
|
|
6851
|
+
if (!isRecord(value)) return false;
|
|
6852
|
+
return isCommerceNotificationEventName(value.event) && typeof value.intentId === "string" && value.intentId.length > 0 && typeof value.dedupeKey === "string" && value.dedupeKey.length > 0 && (value.orderId === void 0 || typeof value.orderId === "string") && (value.fulfillmentId === void 0 || typeof value.fulfillmentId === "string") && (value.returnId === void 0 || typeof value.returnId === "string") && (value.paymentSessionId === void 0 || typeof value.paymentSessionId === "string") && (value.refundAttemptId === void 0 || typeof value.refundAttemptId === "string");
|
|
6853
|
+
}
|
|
6854
|
+
function isPaymentIncidentNotificationData(value, event) {
|
|
6855
|
+
const reconciliation = event === "paymentReconciliationRequired";
|
|
6856
|
+
const expectedCollection = reconciliation ? "payment-sessions" : "payment-refund-attempts";
|
|
6857
|
+
const expectedStatus = reconciliation ? "reconciliation_required" : "requires_attention";
|
|
6858
|
+
const expectedReason = reconciliation ? "orderless_capture" : "local_commit_ambiguous";
|
|
6859
|
+
return value.source?.collection === expectedCollection && typeof value.source.id === "string" && value.source.id.length > 0 && typeof value.paymentSessionId === "string" && value.paymentSessionId.length > 0 && isRecord(value.providerObject) && typeof value.providerObject.provider === "string" && value.providerObject.provider.length > 0 && (value.providerObject.kind === "payment" || value.providerObject.kind === "refund") && typeof value.providerObject.id === "string" && value.providerObject.id.length > 0 && isRecord(value.money) && Number.isSafeInteger(value.money.amountMinor) && Number(value.money.amountMinor) > 0 && typeof value.money.currency === "string" && value.money.currency.length > 0 && value.status === expectedStatus && value.reason === expectedReason && typeof value.observedAt === "string" && value.observedAt.length > 0 && !Number.isNaN(Date.parse(value.observedAt)) && (value.checkoutId === void 0 || typeof value.checkoutId === "string" && value.checkoutId.length > 0) && (value.orderId === void 0 || typeof value.orderId === "string" && value.orderId.length > 0) && (reconciliation ? value.source.id === value.paymentSessionId && value.providerObject.kind === "payment" && value.refundAttemptId === void 0 : typeof value.refundAttemptId === "string" && value.refundAttemptId.length > 0 && value.source.id === value.refundAttemptId);
|
|
6604
6860
|
}
|
|
6605
6861
|
function isWebhookCommerceNotificationChange(value) {
|
|
6606
|
-
if (!
|
|
6862
|
+
if (!isRecord(value)) return false;
|
|
6607
6863
|
return value.type === "notification" && value.source === "commerce-notifications" && isCommerceNotificationEventName(value.event) && isCommerceNotificationSourceCollection(value.sourceCollection) && isStringOrNumber(value.sourceId);
|
|
6608
6864
|
}
|
|
6609
6865
|
function matchesOptionalId(actual, expected) {
|
|
@@ -6641,6 +6897,15 @@ function isCommerceNotificationWebhookEvent(event) {
|
|
|
6641
6897
|
if (!matchesOptionalId(change.sourceId, sourceId)) return false;
|
|
6642
6898
|
}
|
|
6643
6899
|
const changeSourceId = isWebhookCommerceNotificationChange(change) ? change.sourceId : void 0;
|
|
6900
|
+
if (notification.event === "paymentReconciliationRequired" || notification.event === "paymentRefundRequiresAttention") {
|
|
6901
|
+
if (!isPaymentIncidentNotificationData(data, notification.event)) {
|
|
6902
|
+
return false;
|
|
6903
|
+
}
|
|
6904
|
+
const incidentData = data;
|
|
6905
|
+
const expectedCollection = notification.event === "paymentReconciliationRequired" ? "payment-sessions" : "payment-refund-attempts";
|
|
6906
|
+
const notificationSourceId = notification.event === "paymentReconciliationRequired" ? notification.paymentSessionId : notification.refundAttemptId;
|
|
6907
|
+
return sourceCollection === expectedCollection && typeof notification.paymentSessionId === "string" && notification.paymentSessionId === incidentData.paymentSessionId && typeof notificationSourceId === "string" && notificationSourceId === incidentData.source.id && matchesOptionalId(changeSourceId, incidentData.source.id);
|
|
6908
|
+
}
|
|
6644
6909
|
if (notification.event === "orderPaid" || notification.event === "orderCanceled" || notification.event === "orderDelivered") {
|
|
6645
6910
|
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);
|
|
6646
6911
|
}
|
|
@@ -6685,7 +6950,7 @@ function isWebhookOperation(event, operation2) {
|
|
|
6685
6950
|
return isValidWebhookEvent(event) && event.operation === operation2;
|
|
6686
6951
|
}
|
|
6687
6952
|
var CUSTOMER_PASSWORD_RESET_OPERATION = "password-reset";
|
|
6688
|
-
function
|
|
6953
|
+
function isRecord(value) {
|
|
6689
6954
|
return typeof value === "object" && value !== null;
|
|
6690
6955
|
}
|
|
6691
6956
|
function hasString(value, key) {
|
|
@@ -6695,7 +6960,7 @@ function hasStringOrNumber(value, key) {
|
|
|
6695
6960
|
return typeof value[key] === "string" || typeof value[key] === "number";
|
|
6696
6961
|
}
|
|
6697
6962
|
function isCustomerPasswordResetWebhookEvent(event) {
|
|
6698
|
-
if (event.collection !== "customers" || event.operation !== CUSTOMER_PASSWORD_RESET_OPERATION || !
|
|
6963
|
+
if (event.collection !== "customers" || event.operation !== CUSTOMER_PASSWORD_RESET_OPERATION || !isRecord(event.data)) {
|
|
6699
6964
|
return false;
|
|
6700
6965
|
}
|
|
6701
6966
|
return hasStringOrNumber(event.data, "customerId") && hasString(event.data, "email") && hasString(event.data, "name") && hasString(event.data, "resetPasswordToken") && hasString(event.data, "resetPasswordExpiresAt");
|
|
@@ -6709,80 +6974,8 @@ function createCustomerAuthWebhookHandler(handlers) {
|
|
|
6709
6974
|
await handlers.unhandled?.(event);
|
|
6710
6975
|
};
|
|
6711
6976
|
}
|
|
6712
|
-
async function verifySignature(payload, secret, signature, timestamp2, deliveryId) {
|
|
6713
|
-
const encoder = new TextEncoder();
|
|
6714
|
-
const key = await crypto.subtle.importKey(
|
|
6715
|
-
"raw",
|
|
6716
|
-
encoder.encode(secret),
|
|
6717
|
-
{ name: "HMAC", hash: "SHA-256" },
|
|
6718
|
-
false,
|
|
6719
|
-
["verify"]
|
|
6720
|
-
);
|
|
6721
|
-
if (signature.length % 2 !== 0 || !/^[0-9a-fA-F]*$/.test(signature)) {
|
|
6722
|
-
return false;
|
|
6723
|
-
}
|
|
6724
|
-
const sigBytes = new Uint8Array(
|
|
6725
|
-
(signature.match(/.{2}/g) ?? []).map((byte) => parseInt(byte, 16))
|
|
6726
|
-
);
|
|
6727
|
-
return crypto.subtle.verify(
|
|
6728
|
-
"HMAC",
|
|
6729
|
-
key,
|
|
6730
|
-
sigBytes,
|
|
6731
|
-
encoder.encode(`${timestamp2}.${deliveryId}.${payload}`)
|
|
6732
|
-
);
|
|
6733
|
-
}
|
|
6734
|
-
function timestampIsFresh(timestamp2, toleranceSeconds) {
|
|
6735
|
-
if (!/^\d+$/.test(timestamp2)) return false;
|
|
6736
|
-
const timestampMs = Number(timestamp2);
|
|
6737
|
-
if (!Number.isFinite(timestampMs)) return false;
|
|
6738
|
-
const skewMs = Math.abs(Date.now() - timestampMs);
|
|
6739
|
-
return skewMs <= toleranceSeconds * 1e3;
|
|
6740
|
-
}
|
|
6741
6977
|
async function handleWebhook(request, handler, options) {
|
|
6742
|
-
|
|
6743
|
-
const rawBody = await request.text();
|
|
6744
|
-
if (options?.secret) {
|
|
6745
|
-
const signature = request.headers.get("x-webhook-signature") || "";
|
|
6746
|
-
const timestamp2 = request.headers.get("x-webhook-timestamp") || "";
|
|
6747
|
-
const deliveryId = request.headers.get("x-webhook-delivery-id") || "";
|
|
6748
|
-
const toleranceSeconds = options.toleranceSeconds ?? 300;
|
|
6749
|
-
const valid = Boolean(timestamp2 && deliveryId) && timestampIsFresh(timestamp2, toleranceSeconds) && await verifySignature(
|
|
6750
|
-
rawBody,
|
|
6751
|
-
options.secret,
|
|
6752
|
-
signature,
|
|
6753
|
-
timestamp2,
|
|
6754
|
-
deliveryId
|
|
6755
|
-
);
|
|
6756
|
-
if (!valid) {
|
|
6757
|
-
return new Response(
|
|
6758
|
-
JSON.stringify({ error: "Invalid webhook signature" }),
|
|
6759
|
-
{ status: 401, headers: { "Content-Type": "application/json" } }
|
|
6760
|
-
);
|
|
6761
|
-
}
|
|
6762
|
-
} else {
|
|
6763
|
-
console.warn(
|
|
6764
|
-
"[@01.software/sdk] Webhook signature verification is disabled. Set { secret } in handleWebhook() options to enable HMAC-SHA256 verification."
|
|
6765
|
-
);
|
|
6766
|
-
}
|
|
6767
|
-
const body = JSON.parse(rawBody);
|
|
6768
|
-
if (!isValidWebhookEvent(body)) {
|
|
6769
|
-
return new Response(
|
|
6770
|
-
JSON.stringify({ error: "Invalid webhook event format" }),
|
|
6771
|
-
{ status: 400, headers: { "Content-Type": "application/json" } }
|
|
6772
|
-
);
|
|
6773
|
-
}
|
|
6774
|
-
await handler(body);
|
|
6775
|
-
return new Response(
|
|
6776
|
-
JSON.stringify({ success: true, message: "Webhook processed" }),
|
|
6777
|
-
{ status: 200, headers: { "Content-Type": "application/json" } }
|
|
6778
|
-
);
|
|
6779
|
-
} catch (error) {
|
|
6780
|
-
console.error("Webhook processing error:", error);
|
|
6781
|
-
return new Response(JSON.stringify({ error: "Internal server error" }), {
|
|
6782
|
-
status: 500,
|
|
6783
|
-
headers: { "Content-Type": "application/json" }
|
|
6784
|
-
});
|
|
6785
|
-
}
|
|
6978
|
+
return handleSignedWebhook(request, handler, options);
|
|
6786
6979
|
}
|
|
6787
6980
|
function createTypedWebhookHandler(collection, handler) {
|
|
6788
6981
|
return async (event) => {
|
|
@@ -6822,6 +7015,7 @@ var INTERNAL_COLLECTIONS = [
|
|
|
6822
7015
|
"payment-event-inbox",
|
|
6823
7016
|
"payment-refund-attempts",
|
|
6824
7017
|
"portone-payment-interactions",
|
|
7018
|
+
"commerce-payment-webhook-routes",
|
|
6825
7019
|
"commerce-notification-intents",
|
|
6826
7020
|
"commerce-idempotency-records",
|
|
6827
7021
|
"product-collection-items",
|
|
@@ -6862,7 +7056,6 @@ var COLLECTIONS = [
|
|
|
6862
7056
|
"brands",
|
|
6863
7057
|
"customer-profiles",
|
|
6864
7058
|
"customer-profile-stats",
|
|
6865
|
-
"discounts",
|
|
6866
7059
|
"shipping-policies",
|
|
6867
7060
|
"shipping-zones",
|
|
6868
7061
|
"documents",
|
|
@@ -6938,6 +7131,9 @@ var SERVER_ONLY_COLLECTIONS = [
|
|
|
6938
7131
|
"cart-items",
|
|
6939
7132
|
"checkouts",
|
|
6940
7133
|
"checkout-items",
|
|
7134
|
+
// Raw discount definitions require a server credential. Browser discount
|
|
7135
|
+
// validation is exposed through the shaped POST /api/discounts/validate path.
|
|
7136
|
+
"discounts",
|
|
6941
7137
|
"draft-orders",
|
|
6942
7138
|
"draft-order-items",
|
|
6943
7139
|
"posts",
|
|
@@ -7103,160 +7299,6 @@ var RealtimeConnection = class {
|
|
|
7103
7299
|
}
|
|
7104
7300
|
};
|
|
7105
7301
|
|
|
7106
|
-
// src/utils/product-media.ts
|
|
7107
|
-
function mediaPointerOptionValues(values) {
|
|
7108
|
-
return (values ?? []).filter((value) => value != null && value !== "").map((value) => ({
|
|
7109
|
-
swatch: {
|
|
7110
|
-
type: "media",
|
|
7111
|
-
mediaItemId: value
|
|
7112
|
-
}
|
|
7113
|
-
}));
|
|
7114
|
-
}
|
|
7115
|
-
function resolveProductMedia(input) {
|
|
7116
|
-
const resolved = resolveProductSelectionMedia({
|
|
7117
|
-
...input,
|
|
7118
|
-
selectedVariant: input.selectedVariant ?? (input.variantFeaturedMediaItemId ? { images: [input.variantFeaturedMediaItemId] } : null),
|
|
7119
|
-
selectedOptionValues: input.selectedOptionValues ?? mediaPointerOptionValues(input.selectedOptionValueMediaItemIds)
|
|
7120
|
-
});
|
|
7121
|
-
if (resolved.source !== "none") {
|
|
7122
|
-
return {
|
|
7123
|
-
...resolved,
|
|
7124
|
-
source: resolved.source === "variant_media_selected" ? "variant_featured" : resolved.source
|
|
7125
|
-
};
|
|
7126
|
-
}
|
|
7127
|
-
const display = resolveProductDisplayMedia({
|
|
7128
|
-
productMediaPool: input.productMediaPool
|
|
7129
|
-
});
|
|
7130
|
-
return {
|
|
7131
|
-
primaryImage: display.primaryImage,
|
|
7132
|
-
images: display.images,
|
|
7133
|
-
source: display.source
|
|
7134
|
-
};
|
|
7135
|
-
}
|
|
7136
|
-
|
|
7137
|
-
// src/utils/product-gallery.ts
|
|
7138
|
-
function mediaId(value) {
|
|
7139
|
-
if (typeof value === "string" || typeof value === "number") {
|
|
7140
|
-
return String(value);
|
|
7141
|
-
}
|
|
7142
|
-
if (typeof value === "object" && value !== null && "id" in value) {
|
|
7143
|
-
const id = value.id;
|
|
7144
|
-
if (typeof id === "string" || typeof id === "number") return String(id);
|
|
7145
|
-
}
|
|
7146
|
-
return null;
|
|
7147
|
-
}
|
|
7148
|
-
function relationshipIds(values) {
|
|
7149
|
-
if (!Array.isArray(values)) return [];
|
|
7150
|
-
return values.map((value) => mediaId(value)).filter((value) => Boolean(value));
|
|
7151
|
-
}
|
|
7152
|
-
function buildPoolById2(pool) {
|
|
7153
|
-
const poolById = /* @__PURE__ */ new Map();
|
|
7154
|
-
for (const item of pool) {
|
|
7155
|
-
const id = mediaId(item);
|
|
7156
|
-
if (id) poolById.set(id, item);
|
|
7157
|
-
}
|
|
7158
|
-
return poolById;
|
|
7159
|
-
}
|
|
7160
|
-
function mediaSetItemsInPool(mediaSet, poolById) {
|
|
7161
|
-
const seen = /* @__PURE__ */ new Set();
|
|
7162
|
-
const items = [];
|
|
7163
|
-
const primaryId = mediaId(mediaSet.primaryMediaItemId);
|
|
7164
|
-
if (primaryId) {
|
|
7165
|
-
const primary = poolById.get(primaryId);
|
|
7166
|
-
if (primary) {
|
|
7167
|
-
seen.add(primaryId);
|
|
7168
|
-
items.push(primary);
|
|
7169
|
-
}
|
|
7170
|
-
}
|
|
7171
|
-
for (const itemId of relationshipIds(mediaSet.items)) {
|
|
7172
|
-
if (seen.has(itemId)) continue;
|
|
7173
|
-
const item = poolById.get(itemId);
|
|
7174
|
-
if (!item) continue;
|
|
7175
|
-
seen.add(itemId);
|
|
7176
|
-
items.push(item);
|
|
7177
|
-
}
|
|
7178
|
-
return items;
|
|
7179
|
-
}
|
|
7180
|
-
function resolveLegacyMediaSet(input) {
|
|
7181
|
-
if (!Array.isArray(input.mediaSets)) return null;
|
|
7182
|
-
const pool = input.productMediaPool ?? input.pool ?? [];
|
|
7183
|
-
const poolById = buildPoolById2(pool);
|
|
7184
|
-
const selectedVariantId = mediaId(input.selectedVariantId);
|
|
7185
|
-
if (selectedVariantId) {
|
|
7186
|
-
const exactSet = input.mediaSets.find(
|
|
7187
|
-
(set) => set.matchType === "exact-variant" && relationshipIds(set.variantIds).includes(selectedVariantId)
|
|
7188
|
-
);
|
|
7189
|
-
if (exactSet) {
|
|
7190
|
-
const images = mediaSetItemsInPool(exactSet, poolById);
|
|
7191
|
-
if (images.length > 0) {
|
|
7192
|
-
return {
|
|
7193
|
-
primaryImage: images[0] ?? null,
|
|
7194
|
-
images,
|
|
7195
|
-
source: "exact_variant_set"
|
|
7196
|
-
};
|
|
7197
|
-
}
|
|
7198
|
-
}
|
|
7199
|
-
}
|
|
7200
|
-
const selectedOptionValueIds = new Set(
|
|
7201
|
-
relationshipIds(input.selectedOptionValueIds)
|
|
7202
|
-
);
|
|
7203
|
-
const optionSetMatches = input.mediaSets.filter((set) => set.matchType === "option-values").map((set) => {
|
|
7204
|
-
const optionValueIds = relationshipIds(set.optionValueIds);
|
|
7205
|
-
if (optionValueIds.length === 0) return null;
|
|
7206
|
-
if (!optionValueIds.every((id) => selectedOptionValueIds.has(id))) {
|
|
7207
|
-
return null;
|
|
7208
|
-
}
|
|
7209
|
-
const images = mediaSetItemsInPool(set, poolById);
|
|
7210
|
-
if (images.length === 0) return null;
|
|
7211
|
-
return { optionValueCount: optionValueIds.length, images };
|
|
7212
|
-
}).filter(
|
|
7213
|
-
(match) => Boolean(match)
|
|
7214
|
-
).sort((a, b) => b.optionValueCount - a.optionValueCount);
|
|
7215
|
-
if (optionSetMatches.length > 0) {
|
|
7216
|
-
const images = optionSetMatches[0].images;
|
|
7217
|
-
return {
|
|
7218
|
-
primaryImage: images[0] ?? null,
|
|
7219
|
-
images,
|
|
7220
|
-
source: "option_value_set"
|
|
7221
|
-
};
|
|
7222
|
-
}
|
|
7223
|
-
const defaultSet = input.mediaSets.find((set) => set.matchType === "default");
|
|
7224
|
-
if (defaultSet) {
|
|
7225
|
-
const images = mediaSetItemsInPool(defaultSet, poolById);
|
|
7226
|
-
if (images.length > 0) {
|
|
7227
|
-
return {
|
|
7228
|
-
primaryImage: images[0] ?? null,
|
|
7229
|
-
images,
|
|
7230
|
-
source: "default_set"
|
|
7231
|
-
};
|
|
7232
|
-
}
|
|
7233
|
-
}
|
|
7234
|
-
return {
|
|
7235
|
-
primaryImage: null,
|
|
7236
|
-
images: [],
|
|
7237
|
-
source: "none"
|
|
7238
|
-
};
|
|
7239
|
-
}
|
|
7240
|
-
function resolveProductGallery(input) {
|
|
7241
|
-
const selectedVariantId = mediaId(input.selectedVariantId);
|
|
7242
|
-
const selectedOptionValueIds = relationshipIds(input.selectedOptionValueIds);
|
|
7243
|
-
const selection = resolveProductSelectionMedia({
|
|
7244
|
-
...input,
|
|
7245
|
-
productMediaPool: input.productMediaPool ?? input.pool ?? null,
|
|
7246
|
-
selectedVariant: input.selectedVariant ?? (selectedVariantId ? { id: selectedVariantId } : null),
|
|
7247
|
-
selectedOptionValues: input.selectedOptionValues ?? selectedOptionValueIds.map((id) => ({ id }))
|
|
7248
|
-
});
|
|
7249
|
-
if (selection.source !== "none") {
|
|
7250
|
-
return selection;
|
|
7251
|
-
}
|
|
7252
|
-
const legacyResolved = resolveLegacyMediaSet(input);
|
|
7253
|
-
if (legacyResolved && legacyResolved.source !== "none") return legacyResolved;
|
|
7254
|
-
return resolveProductDisplayMedia({
|
|
7255
|
-
productMediaPool: input.productMediaPool ?? input.pool ?? null,
|
|
7256
|
-
featuredImage: input.featuredImage
|
|
7257
|
-
});
|
|
7258
|
-
}
|
|
7259
|
-
|
|
7260
7302
|
// src/utils/image.ts
|
|
7261
7303
|
var IMAGE_SIZES = [200, 400, 800, 1200, 1600];
|
|
7262
7304
|
function imageSizeCandidates(sizes) {
|
|
@@ -7388,7 +7430,7 @@ function createAnalytics(config) {
|
|
|
7388
7430
|
}, destroy() {
|
|
7389
7431
|
} };
|
|
7390
7432
|
}
|
|
7391
|
-
const
|
|
7433
|
+
const endpoint = config.endpoint ?? `${resolveApiUrl()}/api/analytics/collect`;
|
|
7392
7434
|
const respectDnt = config.respectDnt !== false;
|
|
7393
7435
|
function isDntActive() {
|
|
7394
7436
|
if (!respectDnt) return false;
|
|
@@ -7429,10 +7471,10 @@ function createAnalytics(config) {
|
|
|
7429
7471
|
try {
|
|
7430
7472
|
if (typeof navigator.sendBeacon === "function") {
|
|
7431
7473
|
const blob = new Blob([body], { type: "text/plain" });
|
|
7432
|
-
const sent = navigator.sendBeacon(
|
|
7474
|
+
const sent = navigator.sendBeacon(endpoint, blob);
|
|
7433
7475
|
if (sent) return;
|
|
7434
7476
|
}
|
|
7435
|
-
fetch(
|
|
7477
|
+
fetch(endpoint, {
|
|
7436
7478
|
method: "POST",
|
|
7437
7479
|
keepalive: true,
|
|
7438
7480
|
headers: { "Content-Type": "application/json" },
|
|
@@ -7648,6 +7690,7 @@ export {
|
|
|
7648
7690
|
getImageSrcSet,
|
|
7649
7691
|
getImageUrl,
|
|
7650
7692
|
getProductSelectionImages,
|
|
7693
|
+
getSDKErrorReason,
|
|
7651
7694
|
getSelectedValueByOptionId,
|
|
7652
7695
|
getVariantAvailableForSale,
|
|
7653
7696
|
getVariantAvailableStock,
|
|
@@ -7688,8 +7731,6 @@ export {
|
|
|
7688
7731
|
projectProductToListingShape,
|
|
7689
7732
|
resolveFeaturedImagePointer,
|
|
7690
7733
|
resolveProductDisplayMedia,
|
|
7691
|
-
resolveProductGallery,
|
|
7692
|
-
resolveProductMedia,
|
|
7693
7734
|
resolveProductSelection,
|
|
7694
7735
|
resolveProductSelectionFromMatrix,
|
|
7695
7736
|
resolveProductSelectionMedia,
|