@01.software/sdk 0.5.4 → 0.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth.cjs +22 -46
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.js +22 -47
- package/dist/auth.js.map +1 -1
- package/dist/index.cjs +922 -1069
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +922 -1072
- package/dist/index.js.map +1 -1
- package/dist/realtime.cjs +75 -101
- package/dist/realtime.cjs.map +1 -1
- package/dist/realtime.js +75 -102
- package/dist/realtime.js.map +1 -1
- package/dist/ui/code-block.cjs +13 -35
- package/dist/ui/code-block.cjs.map +1 -1
- package/dist/ui/code-block.js +13 -35
- package/dist/ui/code-block.js.map +1 -1
- package/dist/ui/flow/server.cjs +26 -68
- package/dist/ui/flow/server.cjs.map +1 -1
- package/dist/ui/flow/server.js +26 -71
- package/dist/ui/flow/server.js.map +1 -1
- package/dist/ui/flow.cjs +176 -232
- package/dist/ui/flow.cjs.map +1 -1
- package/dist/ui/flow.js +176 -234
- package/dist/ui/flow.js.map +1 -1
- package/dist/ui/form.cjs +40 -84
- package/dist/ui/form.cjs.map +1 -1
- package/dist/ui/form.js +40 -86
- package/dist/ui/form.js.map +1 -1
- package/dist/ui/image.cjs +27 -40
- package/dist/ui/image.cjs.map +1 -1
- package/dist/ui/image.js +27 -42
- package/dist/ui/image.js.map +1 -1
- package/dist/ui/rich-text.cjs +33 -67
- package/dist/ui/rich-text.cjs.map +1 -1
- package/dist/ui/rich-text.js +33 -69
- package/dist/ui/rich-text.js.map +1 -1
- package/dist/ui/video.cjs +32 -50
- package/dist/ui/video.cjs.map +1 -1
- package/dist/ui/video.js +32 -52
- package/dist/ui/video.js.map +1 -1
- package/dist/webhook.cjs +48 -73
- package/dist/webhook.cjs.map +1 -1
- package/dist/webhook.js +48 -74
- package/dist/webhook.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -1,38 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
|
-
var __defProps = Object.defineProperties;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
6
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
8
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
10
|
-
var __pow = Math.pow;
|
|
11
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
12
|
-
var __spreadValues = (a, b) => {
|
|
13
|
-
for (var prop in b || (b = {}))
|
|
14
|
-
if (__hasOwnProp.call(b, prop))
|
|
15
|
-
__defNormalProp(a, prop, b[prop]);
|
|
16
|
-
if (__getOwnPropSymbols)
|
|
17
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
18
|
-
if (__propIsEnum.call(b, prop))
|
|
19
|
-
__defNormalProp(a, prop, b[prop]);
|
|
20
|
-
}
|
|
21
|
-
return a;
|
|
22
|
-
};
|
|
23
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
24
|
-
var __objRest = (source, exclude) => {
|
|
25
|
-
var target = {};
|
|
26
|
-
for (var prop in source)
|
|
27
|
-
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
28
|
-
target[prop] = source[prop];
|
|
29
|
-
if (source != null && __getOwnPropSymbols)
|
|
30
|
-
for (var prop of __getOwnPropSymbols(source)) {
|
|
31
|
-
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
32
|
-
target[prop] = source[prop];
|
|
33
|
-
}
|
|
34
|
-
return target;
|
|
35
|
-
};
|
|
36
6
|
var __export = (target, all) => {
|
|
37
7
|
for (var name in all)
|
|
38
8
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -46,26 +16,6 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
46
16
|
return to;
|
|
47
17
|
};
|
|
48
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
49
|
-
var __async = (__this, __arguments, generator) => {
|
|
50
|
-
return new Promise((resolve, reject) => {
|
|
51
|
-
var fulfilled = (value) => {
|
|
52
|
-
try {
|
|
53
|
-
step(generator.next(value));
|
|
54
|
-
} catch (e) {
|
|
55
|
-
reject(e);
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
var rejected = (value) => {
|
|
59
|
-
try {
|
|
60
|
-
step(generator.throw(value));
|
|
61
|
-
} catch (e) {
|
|
62
|
-
reject(e);
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
66
|
-
step((generator = generator.apply(__this, __arguments)).next());
|
|
67
|
-
});
|
|
68
|
-
};
|
|
69
19
|
|
|
70
20
|
// src/index.ts
|
|
71
21
|
var src_exports = {};
|
|
@@ -134,33 +84,29 @@ module.exports = __toCommonJS(src_exports);
|
|
|
134
84
|
|
|
135
85
|
// src/core/internal/utils/jwt.ts
|
|
136
86
|
var import_jose = require("jose");
|
|
137
|
-
function createServerToken(clientKey, secretKey, expiresIn = "1h") {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
return new import_jose.SignJWT({ clientKey }).setProtectedHeader({ alg: "HS256" }).setIssuedAt().setExpirationTime(expiresIn).sign(secret);
|
|
144
|
-
});
|
|
87
|
+
async function createServerToken(clientKey, secretKey, expiresIn = "1h") {
|
|
88
|
+
if (!clientKey || !secretKey) {
|
|
89
|
+
throw new Error("clientKey and secretKey are required.");
|
|
90
|
+
}
|
|
91
|
+
const secret = new TextEncoder().encode(secretKey);
|
|
92
|
+
return new import_jose.SignJWT({ clientKey }).setProtectedHeader({ alg: "HS256" }).setIssuedAt().setExpirationTime(expiresIn).sign(secret);
|
|
145
93
|
}
|
|
146
|
-
function verifyServerToken(token, secretKey) {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
algorithms: ["HS256"]
|
|
154
|
-
});
|
|
155
|
-
if (!payload.clientKey || typeof payload.clientKey !== "string") {
|
|
156
|
-
throw new Error("Invalid token payload: clientKey is missing");
|
|
157
|
-
}
|
|
158
|
-
return {
|
|
159
|
-
clientKey: payload.clientKey,
|
|
160
|
-
iat: payload.iat,
|
|
161
|
-
exp: payload.exp
|
|
162
|
-
};
|
|
94
|
+
async function verifyServerToken(token, secretKey) {
|
|
95
|
+
if (!token || !secretKey) {
|
|
96
|
+
throw new Error("token and secretKey are required.");
|
|
97
|
+
}
|
|
98
|
+
const secret = new TextEncoder().encode(secretKey);
|
|
99
|
+
const { payload } = await (0, import_jose.jwtVerify)(token, secret, {
|
|
100
|
+
algorithms: ["HS256"]
|
|
163
101
|
});
|
|
102
|
+
if (!payload.clientKey || typeof payload.clientKey !== "string") {
|
|
103
|
+
throw new Error("Invalid token payload: clientKey is missing");
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
clientKey: payload.clientKey,
|
|
107
|
+
iat: payload.iat,
|
|
108
|
+
exp: payload.exp
|
|
109
|
+
};
|
|
164
110
|
}
|
|
165
111
|
function decodeServerToken(token) {
|
|
166
112
|
if (!token) {
|
|
@@ -208,7 +154,7 @@ function parseApiKey(apiKey) {
|
|
|
208
154
|
throw new Error("Invalid format: empty clientKey or secretKey");
|
|
209
155
|
}
|
|
210
156
|
return { clientKey, secretKey };
|
|
211
|
-
} catch
|
|
157
|
+
} catch {
|
|
212
158
|
throw new Error(
|
|
213
159
|
'Invalid API key. Expected Base64 encoded "clientKey:secretKey"'
|
|
214
160
|
);
|
|
@@ -301,9 +247,10 @@ var UsageLimitError = class extends SDKError {
|
|
|
301
247
|
this.usage = usage;
|
|
302
248
|
}
|
|
303
249
|
toJSON() {
|
|
304
|
-
return
|
|
250
|
+
return {
|
|
251
|
+
...super.toJSON(),
|
|
305
252
|
usage: this.usage
|
|
306
|
-
}
|
|
253
|
+
};
|
|
307
254
|
}
|
|
308
255
|
};
|
|
309
256
|
function isSDKError(error) {
|
|
@@ -374,286 +321,270 @@ function getErrorSuggestion(status) {
|
|
|
374
321
|
if (status >= 500) return "A server error occurred. Please try again later.";
|
|
375
322
|
return void 0;
|
|
376
323
|
}
|
|
377
|
-
function parseErrorBody(response) {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
const
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
message: fe.message
|
|
394
|
-
});
|
|
395
|
-
}
|
|
396
|
-
} else if (e.field || e.message) {
|
|
397
|
-
fieldErrors.push({ field: e.field, message: e.message });
|
|
324
|
+
async function parseErrorBody(response) {
|
|
325
|
+
const fallback = {
|
|
326
|
+
errorMessage: `HTTP ${response.status}: ${response.statusText}`,
|
|
327
|
+
userMessage: `Request failed (status: ${response.status})`
|
|
328
|
+
};
|
|
329
|
+
try {
|
|
330
|
+
const body = await response.json();
|
|
331
|
+
if (body.errors && Array.isArray(body.errors)) {
|
|
332
|
+
const fieldErrors = [];
|
|
333
|
+
for (const e of body.errors) {
|
|
334
|
+
if (e.data?.errors && Array.isArray(e.data.errors) && e.data.errors.length > 0) {
|
|
335
|
+
for (const fe of e.data.errors) {
|
|
336
|
+
fieldErrors.push({
|
|
337
|
+
field: fe.path || fe.field,
|
|
338
|
+
message: fe.message
|
|
339
|
+
});
|
|
398
340
|
}
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
(e) => e.field ? `${e.field}: ${e.message}` : e.message
|
|
402
|
-
).filter(Boolean).join("; ");
|
|
403
|
-
if (details) {
|
|
404
|
-
return {
|
|
405
|
-
errorMessage: `HTTP ${response.status}: ${details}`,
|
|
406
|
-
userMessage: details,
|
|
407
|
-
errors: fieldErrors.length > 0 ? fieldErrors : body.errors
|
|
408
|
-
};
|
|
341
|
+
} else if (e.field || e.message) {
|
|
342
|
+
fieldErrors.push({ field: e.field, message: e.message });
|
|
409
343
|
}
|
|
410
344
|
}
|
|
411
|
-
|
|
345
|
+
const details = (fieldErrors.length > 0 ? fieldErrors : body.errors).map(
|
|
346
|
+
(e) => e.field ? `${e.field}: ${e.message}` : e.message
|
|
347
|
+
).filter(Boolean).join("; ");
|
|
348
|
+
if (details) {
|
|
412
349
|
return {
|
|
413
|
-
errorMessage: `HTTP ${response.status}: ${
|
|
414
|
-
userMessage:
|
|
350
|
+
errorMessage: `HTTP ${response.status}: ${details}`,
|
|
351
|
+
userMessage: details,
|
|
352
|
+
errors: fieldErrors.length > 0 ? fieldErrors : body.errors
|
|
415
353
|
};
|
|
416
354
|
}
|
|
417
|
-
if (body.message) {
|
|
418
|
-
return {
|
|
419
|
-
errorMessage: `HTTP ${response.status}: ${body.message}`,
|
|
420
|
-
userMessage: body.message
|
|
421
|
-
};
|
|
422
|
-
}
|
|
423
|
-
return fallback;
|
|
424
|
-
} catch (e) {
|
|
425
|
-
return fallback;
|
|
426
355
|
}
|
|
427
|
-
|
|
356
|
+
if (typeof body.error === "string") {
|
|
357
|
+
return {
|
|
358
|
+
errorMessage: `HTTP ${response.status}: ${body.error}`,
|
|
359
|
+
userMessage: body.error
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
if (body.message) {
|
|
363
|
+
return {
|
|
364
|
+
errorMessage: `HTTP ${response.status}: ${body.message}`,
|
|
365
|
+
userMessage: body.message
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
return fallback;
|
|
369
|
+
} catch {
|
|
370
|
+
return fallback;
|
|
371
|
+
}
|
|
428
372
|
}
|
|
429
|
-
function delay(ms) {
|
|
430
|
-
return
|
|
431
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
432
|
-
});
|
|
373
|
+
async function delay(ms) {
|
|
374
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
433
375
|
}
|
|
434
|
-
function httpFetch(url, options) {
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
authToken
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
376
|
+
async function httpFetch(url, options) {
|
|
377
|
+
const {
|
|
378
|
+
clientKey,
|
|
379
|
+
secretKey,
|
|
380
|
+
customerToken,
|
|
381
|
+
timeout = DEFAULT_TIMEOUT,
|
|
382
|
+
baseUrl = resolveApiUrl(),
|
|
383
|
+
debug,
|
|
384
|
+
retry,
|
|
385
|
+
onUnauthorized,
|
|
386
|
+
...requestInit
|
|
387
|
+
} = options || {};
|
|
388
|
+
const retryConfig = {
|
|
389
|
+
maxRetries: retry?.maxRetries ?? 3,
|
|
390
|
+
retryableStatuses: retry?.retryableStatuses ?? DEFAULT_RETRYABLE_STATUSES,
|
|
391
|
+
retryDelay: retry?.retryDelay ?? ((attempt) => Math.min(1e3 * 2 ** attempt, 1e4))
|
|
392
|
+
};
|
|
393
|
+
let authToken;
|
|
394
|
+
if (secretKey && clientKey) {
|
|
395
|
+
authToken = await createServerToken(clientKey, secretKey);
|
|
396
|
+
} else if (customerToken) {
|
|
397
|
+
authToken = customerToken;
|
|
398
|
+
}
|
|
399
|
+
let lastError;
|
|
400
|
+
let hasRetried401 = false;
|
|
401
|
+
for (let attempt = 0; attempt <= retryConfig.maxRetries; attempt++) {
|
|
402
|
+
try {
|
|
403
|
+
const headers = new Headers(requestInit.headers);
|
|
404
|
+
if (clientKey) {
|
|
405
|
+
headers.set("X-Client-Key", clientKey);
|
|
406
|
+
}
|
|
407
|
+
if (authToken) {
|
|
408
|
+
headers.set("Authorization", `Bearer ${authToken}`);
|
|
409
|
+
}
|
|
410
|
+
if (!headers.has("Content-Type") && requestInit.body && !(requestInit.body instanceof FormData)) {
|
|
411
|
+
headers.set("Content-Type", "application/json");
|
|
412
|
+
}
|
|
413
|
+
const redactedHeaders = Object.fromEntries(headers.entries());
|
|
414
|
+
if (redactedHeaders["authorization"]) {
|
|
415
|
+
const token = redactedHeaders["authorization"];
|
|
416
|
+
redactedHeaders["authorization"] = token.length > 20 ? `Bearer ...****${token.slice(-8)}` : "****";
|
|
417
|
+
}
|
|
418
|
+
debugLog(debug, "request", url, {
|
|
419
|
+
method: requestInit.method || "GET",
|
|
420
|
+
headers: redactedHeaders,
|
|
421
|
+
attempt: attempt + 1
|
|
422
|
+
});
|
|
423
|
+
const controller = new AbortController();
|
|
424
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
425
|
+
const response = await fetch(`${baseUrl}${url}`, {
|
|
426
|
+
...requestInit,
|
|
427
|
+
headers,
|
|
428
|
+
signal: controller.signal
|
|
429
|
+
});
|
|
430
|
+
clearTimeout(timeoutId);
|
|
431
|
+
debugLog(debug, "response", url, {
|
|
432
|
+
status: response.status,
|
|
433
|
+
statusText: response.statusText,
|
|
434
|
+
headers: Object.fromEntries(response.headers.entries())
|
|
435
|
+
});
|
|
436
|
+
if (!response.ok) {
|
|
437
|
+
if (response.status === 429 && response.headers.get("X-Usage-Limit")) {
|
|
438
|
+
const limit = parseInt(
|
|
439
|
+
response.headers.get("X-Usage-Limit") || "0",
|
|
440
|
+
10
|
|
441
|
+
);
|
|
442
|
+
const current = parseInt(
|
|
443
|
+
response.headers.get("X-Usage-Current") || "0",
|
|
444
|
+
10
|
|
445
|
+
);
|
|
446
|
+
const remaining = parseInt(
|
|
447
|
+
response.headers.get("X-Usage-Remaining") || "0",
|
|
448
|
+
10
|
|
449
|
+
);
|
|
450
|
+
throw createUsageLimitError(
|
|
451
|
+
`Monthly API usage limit exceeded (${current.toLocaleString()}/${limit.toLocaleString()})`,
|
|
452
|
+
{ limit, current, remaining },
|
|
453
|
+
{ url, method: requestInit.method || "GET", attempt: attempt + 1 },
|
|
454
|
+
"Monthly API call limit exceeded. Please upgrade your plan.",
|
|
455
|
+
"Upgrade your tenant plan to increase the monthly API call limit."
|
|
456
|
+
);
|
|
485
457
|
}
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
const response = yield fetch(`${baseUrl}${url}`, __spreadProps(__spreadValues({}, requestInit), {
|
|
494
|
-
headers,
|
|
495
|
-
signal: controller.signal
|
|
496
|
-
}));
|
|
497
|
-
clearTimeout(timeoutId);
|
|
498
|
-
debugLog(debug, "response", url, {
|
|
499
|
-
status: response.status,
|
|
500
|
-
statusText: response.statusText,
|
|
501
|
-
headers: Object.fromEntries(response.headers.entries())
|
|
502
|
-
});
|
|
503
|
-
if (!response.ok) {
|
|
504
|
-
if (response.status === 429 && response.headers.get("X-Usage-Limit")) {
|
|
505
|
-
const limit = parseInt(
|
|
506
|
-
response.headers.get("X-Usage-Limit") || "0",
|
|
507
|
-
10
|
|
508
|
-
);
|
|
509
|
-
const current = parseInt(
|
|
510
|
-
response.headers.get("X-Usage-Current") || "0",
|
|
511
|
-
10
|
|
512
|
-
);
|
|
513
|
-
const remaining = parseInt(
|
|
514
|
-
response.headers.get("X-Usage-Remaining") || "0",
|
|
515
|
-
10
|
|
516
|
-
);
|
|
517
|
-
throw createUsageLimitError(
|
|
518
|
-
`Monthly API usage limit exceeded (${current.toLocaleString()}/${limit.toLocaleString()})`,
|
|
519
|
-
{ limit, current, remaining },
|
|
520
|
-
{ url, method: requestInit.method || "GET", attempt: attempt + 1 },
|
|
521
|
-
"Monthly API call limit exceeded. Please upgrade your plan.",
|
|
522
|
-
"Upgrade your tenant plan to increase the monthly API call limit."
|
|
523
|
-
);
|
|
524
|
-
}
|
|
525
|
-
if (response.status === 401 && onUnauthorized && customerToken && !hasRetried401) {
|
|
526
|
-
hasRetried401 = true;
|
|
527
|
-
try {
|
|
528
|
-
const newToken = yield onUnauthorized();
|
|
529
|
-
if (newToken) {
|
|
530
|
-
authToken = newToken;
|
|
531
|
-
continue;
|
|
532
|
-
}
|
|
533
|
-
} catch (e) {
|
|
458
|
+
if (response.status === 401 && onUnauthorized && customerToken && !hasRetried401) {
|
|
459
|
+
hasRetried401 = true;
|
|
460
|
+
try {
|
|
461
|
+
const newToken = await onUnauthorized();
|
|
462
|
+
if (newToken) {
|
|
463
|
+
authToken = newToken;
|
|
464
|
+
continue;
|
|
534
465
|
}
|
|
466
|
+
} catch {
|
|
535
467
|
}
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
parsed2.userMessage,
|
|
548
|
-
getErrorSuggestion(response.status)
|
|
549
|
-
);
|
|
550
|
-
}
|
|
551
|
-
const parsed = yield parseErrorBody(response);
|
|
552
|
-
const error = createNetworkError(
|
|
553
|
-
parsed.errorMessage,
|
|
468
|
+
}
|
|
469
|
+
if (NON_RETRYABLE_STATUSES.includes(response.status)) {
|
|
470
|
+
const parsed2 = await parseErrorBody(response);
|
|
471
|
+
const details = {
|
|
472
|
+
url,
|
|
473
|
+
method: requestInit.method || "GET",
|
|
474
|
+
attempt: attempt + 1,
|
|
475
|
+
...parsed2.errors && { errors: parsed2.errors }
|
|
476
|
+
};
|
|
477
|
+
throw createNetworkError(
|
|
478
|
+
parsed2.errorMessage,
|
|
554
479
|
response.status,
|
|
555
|
-
|
|
556
|
-
|
|
480
|
+
details,
|
|
481
|
+
parsed2.userMessage,
|
|
557
482
|
getErrorSuggestion(response.status)
|
|
558
483
|
);
|
|
559
|
-
const method = (requestInit.method || "GET").toUpperCase();
|
|
560
|
-
if (attempt < retryConfig.maxRetries && SAFE_METHODS.includes(method) && retryConfig.retryableStatuses.includes(response.status)) {
|
|
561
|
-
lastError = error;
|
|
562
|
-
const retryDelay = retryConfig.retryDelay(attempt);
|
|
563
|
-
debugLog(debug, "error", `Retrying in ${retryDelay}ms...`, error);
|
|
564
|
-
yield delay(retryDelay);
|
|
565
|
-
continue;
|
|
566
|
-
}
|
|
567
|
-
throw error;
|
|
568
484
|
}
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
485
|
+
const parsed = await parseErrorBody(response);
|
|
486
|
+
const error = createNetworkError(
|
|
487
|
+
parsed.errorMessage,
|
|
488
|
+
response.status,
|
|
489
|
+
{ url, method: requestInit.method || "GET", attempt: attempt + 1 },
|
|
490
|
+
parsed.userMessage,
|
|
491
|
+
getErrorSuggestion(response.status)
|
|
492
|
+
);
|
|
572
493
|
const method = (requestInit.method || "GET").toUpperCase();
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
const
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
"Please check your network connection or try again later."
|
|
580
|
-
);
|
|
581
|
-
if (isSafe && attempt < retryConfig.maxRetries) {
|
|
582
|
-
lastError = timeoutError;
|
|
583
|
-
yield delay(retryConfig.retryDelay(attempt));
|
|
584
|
-
continue;
|
|
585
|
-
}
|
|
586
|
-
throw timeoutError;
|
|
587
|
-
}
|
|
588
|
-
if (error instanceof TypeError) {
|
|
589
|
-
const networkError = createNetworkError(
|
|
590
|
-
"Network connection failed.",
|
|
591
|
-
void 0,
|
|
592
|
-
{ url, originalError: error.message, attempt: attempt + 1 },
|
|
593
|
-
"Network connection failed.",
|
|
594
|
-
"Please check your internet connection and try again."
|
|
595
|
-
);
|
|
596
|
-
if (isSafe && attempt < retryConfig.maxRetries) {
|
|
597
|
-
lastError = networkError;
|
|
598
|
-
yield delay(retryConfig.retryDelay(attempt));
|
|
599
|
-
continue;
|
|
600
|
-
}
|
|
601
|
-
throw networkError;
|
|
494
|
+
if (attempt < retryConfig.maxRetries && SAFE_METHODS.includes(method) && retryConfig.retryableStatuses.includes(response.status)) {
|
|
495
|
+
lastError = error;
|
|
496
|
+
const retryDelay = retryConfig.retryDelay(attempt);
|
|
497
|
+
debugLog(debug, "error", `Retrying in ${retryDelay}ms...`, error);
|
|
498
|
+
await delay(retryDelay);
|
|
499
|
+
continue;
|
|
602
500
|
}
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
501
|
+
throw error;
|
|
502
|
+
}
|
|
503
|
+
return response;
|
|
504
|
+
} catch (error) {
|
|
505
|
+
debugLog(debug, "error", url, error);
|
|
506
|
+
const method = (requestInit.method || "GET").toUpperCase();
|
|
507
|
+
const isSafe = SAFE_METHODS.includes(method);
|
|
508
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
509
|
+
const timeoutError = createTimeoutError(
|
|
510
|
+
`Request timed out after ${timeout}ms.`,
|
|
511
|
+
{ url, timeout, attempt: attempt + 1 },
|
|
512
|
+
"The request timed out.",
|
|
513
|
+
"Please check your network connection or try again later."
|
|
514
|
+
);
|
|
515
|
+
if (isSafe && attempt < retryConfig.maxRetries) {
|
|
516
|
+
lastError = timeoutError;
|
|
517
|
+
await delay(retryConfig.retryDelay(attempt));
|
|
518
|
+
continue;
|
|
610
519
|
}
|
|
611
|
-
|
|
612
|
-
|
|
520
|
+
throw timeoutError;
|
|
521
|
+
}
|
|
522
|
+
if (error instanceof TypeError) {
|
|
523
|
+
const networkError = createNetworkError(
|
|
524
|
+
"Network connection failed.",
|
|
613
525
|
void 0,
|
|
614
|
-
{ url, originalError: error, attempt: attempt + 1 },
|
|
615
|
-
"
|
|
616
|
-
"Please try again
|
|
526
|
+
{ url, originalError: error.message, attempt: attempt + 1 },
|
|
527
|
+
"Network connection failed.",
|
|
528
|
+
"Please check your internet connection and try again."
|
|
617
529
|
);
|
|
618
530
|
if (isSafe && attempt < retryConfig.maxRetries) {
|
|
619
|
-
lastError =
|
|
620
|
-
|
|
531
|
+
lastError = networkError;
|
|
532
|
+
await delay(retryConfig.retryDelay(attempt));
|
|
621
533
|
continue;
|
|
622
534
|
}
|
|
623
|
-
throw
|
|
535
|
+
throw networkError;
|
|
624
536
|
}
|
|
537
|
+
if (error instanceof NetworkError || error instanceof TimeoutError) {
|
|
538
|
+
if (isSafe && attempt < retryConfig.maxRetries && error.status && !NON_RETRYABLE_STATUSES.includes(error.status) && retryConfig.retryableStatuses.includes(error.status)) {
|
|
539
|
+
lastError = error;
|
|
540
|
+
await delay(retryConfig.retryDelay(attempt));
|
|
541
|
+
continue;
|
|
542
|
+
}
|
|
543
|
+
throw error;
|
|
544
|
+
}
|
|
545
|
+
const unknownError = createNetworkError(
|
|
546
|
+
error instanceof Error ? error.message : "An unknown network error occurred.",
|
|
547
|
+
void 0,
|
|
548
|
+
{ url, originalError: error, attempt: attempt + 1 },
|
|
549
|
+
"An unknown error occurred.",
|
|
550
|
+
"Please try again later."
|
|
551
|
+
);
|
|
552
|
+
if (isSafe && attempt < retryConfig.maxRetries) {
|
|
553
|
+
lastError = unknownError;
|
|
554
|
+
await delay(retryConfig.retryDelay(attempt));
|
|
555
|
+
continue;
|
|
556
|
+
}
|
|
557
|
+
throw unknownError;
|
|
625
558
|
}
|
|
626
|
-
|
|
627
|
-
|
|
559
|
+
}
|
|
560
|
+
throw lastError ?? new NetworkError("Request failed after retries");
|
|
628
561
|
}
|
|
629
562
|
|
|
630
563
|
// src/core/api/parse-response.ts
|
|
631
|
-
function parseApiResponse(response, endpoint) {
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
return data;
|
|
656
|
-
});
|
|
564
|
+
async function parseApiResponse(response, endpoint) {
|
|
565
|
+
let data;
|
|
566
|
+
try {
|
|
567
|
+
data = await response.json();
|
|
568
|
+
} catch {
|
|
569
|
+
throw createApiError(
|
|
570
|
+
`Invalid JSON response from ${endpoint}`,
|
|
571
|
+
response.status,
|
|
572
|
+
void 0,
|
|
573
|
+
"Server returned an invalid response.",
|
|
574
|
+
"Check if the API endpoint is available."
|
|
575
|
+
);
|
|
576
|
+
}
|
|
577
|
+
if (data.error) {
|
|
578
|
+
const errorMessage = typeof data.error === "string" ? data.error : "Unknown API error";
|
|
579
|
+
throw createApiError(
|
|
580
|
+
errorMessage,
|
|
581
|
+
response.status,
|
|
582
|
+
data,
|
|
583
|
+
errorMessage,
|
|
584
|
+
"An error occurred while processing the request."
|
|
585
|
+
);
|
|
586
|
+
}
|
|
587
|
+
return data;
|
|
657
588
|
}
|
|
658
589
|
|
|
659
590
|
// src/core/api/base-api.ts
|
|
@@ -669,18 +600,17 @@ var BaseApi = class {
|
|
|
669
600
|
this.secretKey = options.secretKey;
|
|
670
601
|
this.baseUrl = options.baseUrl;
|
|
671
602
|
}
|
|
672
|
-
request(endpoint, body, options) {
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
}, body !== void 0 && { body: JSON.stringify(body) }), (options == null ? void 0 : options.headers) && { headers: options.headers }));
|
|
682
|
-
return parseApiResponse(response, endpoint);
|
|
603
|
+
async request(endpoint, body, options) {
|
|
604
|
+
const method = options?.method ?? "POST";
|
|
605
|
+
const response = await httpFetch(endpoint, {
|
|
606
|
+
method,
|
|
607
|
+
clientKey: this.clientKey,
|
|
608
|
+
secretKey: this.secretKey,
|
|
609
|
+
baseUrl: this.baseUrl,
|
|
610
|
+
...body !== void 0 && { body: JSON.stringify(body) },
|
|
611
|
+
...options?.headers && { headers: options.headers }
|
|
683
612
|
});
|
|
613
|
+
return parseApiResponse(response, endpoint);
|
|
684
614
|
}
|
|
685
615
|
};
|
|
686
616
|
|
|
@@ -759,18 +689,18 @@ var CartApi = class {
|
|
|
759
689
|
this.baseUrl = options.baseUrl;
|
|
760
690
|
this.onUnauthorized = options.onUnauthorized;
|
|
761
691
|
}
|
|
762
|
-
execute(endpoint, method, body) {
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
return parseApiResponse(response, endpoint);
|
|
692
|
+
async execute(endpoint, method, body) {
|
|
693
|
+
const token = typeof this.customerToken === "function" ? this.customerToken() : this.customerToken;
|
|
694
|
+
const response = await httpFetch(endpoint, {
|
|
695
|
+
method,
|
|
696
|
+
clientKey: this.clientKey,
|
|
697
|
+
secretKey: this.secretKey,
|
|
698
|
+
customerToken: token ?? void 0,
|
|
699
|
+
baseUrl: this.baseUrl,
|
|
700
|
+
...token && this.onUnauthorized && { onUnauthorized: this.onUnauthorized },
|
|
701
|
+
...body !== void 0 && { body: JSON.stringify(body) }
|
|
773
702
|
});
|
|
703
|
+
return parseApiResponse(response, endpoint);
|
|
774
704
|
}
|
|
775
705
|
getCart(cartId) {
|
|
776
706
|
return this.execute(`/api/carts/${cartId}`, "GET");
|
|
@@ -822,50 +752,59 @@ var resolveRelation = (ref) => {
|
|
|
822
752
|
|
|
823
753
|
// src/core/metadata/index.ts
|
|
824
754
|
function extractSeo(doc) {
|
|
825
|
-
|
|
826
|
-
const
|
|
827
|
-
const og = (_b = seo.openGraph) != null ? _b : {};
|
|
755
|
+
const seo = doc.seo ?? {};
|
|
756
|
+
const og = seo.openGraph ?? {};
|
|
828
757
|
return {
|
|
829
|
-
title:
|
|
830
|
-
description:
|
|
831
|
-
noIndex:
|
|
832
|
-
canonical:
|
|
758
|
+
title: seo.title ?? doc.title ?? null,
|
|
759
|
+
description: seo.description ?? null,
|
|
760
|
+
noIndex: seo.noIndex ?? null,
|
|
761
|
+
canonical: seo.canonical ?? null,
|
|
833
762
|
openGraph: {
|
|
834
|
-
title:
|
|
835
|
-
description:
|
|
836
|
-
image:
|
|
763
|
+
title: og.title ?? null,
|
|
764
|
+
description: og.description ?? null,
|
|
765
|
+
image: og.image ?? null
|
|
837
766
|
}
|
|
838
767
|
};
|
|
839
768
|
}
|
|
840
769
|
function generateMetadata(input, options) {
|
|
841
|
-
|
|
842
|
-
const
|
|
843
|
-
const
|
|
844
|
-
const
|
|
845
|
-
const
|
|
846
|
-
|
|
847
|
-
return __spreadProps(__spreadValues(__spreadValues({
|
|
770
|
+
const title = input.title ?? void 0;
|
|
771
|
+
const description = input.description ?? void 0;
|
|
772
|
+
const ogTitle = input.openGraph?.title ?? title;
|
|
773
|
+
const ogDescription = input.openGraph?.description ?? description;
|
|
774
|
+
const image = resolveMetaImage(input.openGraph?.image);
|
|
775
|
+
return {
|
|
848
776
|
title,
|
|
849
|
-
description
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
777
|
+
description,
|
|
778
|
+
...input.noIndex && { robots: { index: false, follow: false } },
|
|
779
|
+
...input.canonical && { alternates: { canonical: input.canonical } },
|
|
780
|
+
openGraph: {
|
|
781
|
+
...ogTitle && { title: ogTitle },
|
|
782
|
+
...ogDescription && { description: ogDescription },
|
|
783
|
+
...options?.siteName && { siteName: options.siteName },
|
|
784
|
+
...image && { images: [image] }
|
|
785
|
+
},
|
|
786
|
+
twitter: {
|
|
787
|
+
card: image ? "summary_large_image" : "summary",
|
|
788
|
+
...ogTitle && { title: ogTitle },
|
|
789
|
+
...ogDescription && { description: ogDescription },
|
|
790
|
+
...image && { images: [image.url] }
|
|
791
|
+
}
|
|
792
|
+
};
|
|
856
793
|
}
|
|
857
794
|
function resolveMetaImage(ref) {
|
|
858
|
-
var _a;
|
|
859
795
|
const image = resolveRelation(ref);
|
|
860
796
|
if (!image) return null;
|
|
861
|
-
const sized =
|
|
862
|
-
const url =
|
|
797
|
+
const sized = image.sizes?.["1536"];
|
|
798
|
+
const url = sized?.url || image.url;
|
|
863
799
|
if (!url) return null;
|
|
864
|
-
const width =
|
|
865
|
-
const height =
|
|
866
|
-
return
|
|
867
|
-
url
|
|
868
|
-
|
|
800
|
+
const width = sized?.url ? sized.width : image.width;
|
|
801
|
+
const height = sized?.url ? sized.height : image.height;
|
|
802
|
+
return {
|
|
803
|
+
url,
|
|
804
|
+
...width && { width },
|
|
805
|
+
...height && { height },
|
|
806
|
+
...image.alt && { alt: image.alt }
|
|
807
|
+
};
|
|
869
808
|
}
|
|
870
809
|
|
|
871
810
|
// src/core/collection/query-builder.ts
|
|
@@ -879,145 +818,125 @@ var CollectionQueryBuilder = class {
|
|
|
879
818
|
* GET /api/{collection}
|
|
880
819
|
* @returns Payload CMS find response with docs array and pagination
|
|
881
820
|
*/
|
|
882
|
-
find(options) {
|
|
883
|
-
return
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
);
|
|
888
|
-
});
|
|
821
|
+
async find(options) {
|
|
822
|
+
return this.api.requestFind(
|
|
823
|
+
`/api/${String(this.collection)}`,
|
|
824
|
+
options
|
|
825
|
+
);
|
|
889
826
|
}
|
|
890
827
|
/**
|
|
891
828
|
* Find document by ID
|
|
892
829
|
* GET /api/{collection}/{id}
|
|
893
830
|
* @returns Document object directly (no wrapper)
|
|
894
831
|
*/
|
|
895
|
-
findById(id, options) {
|
|
896
|
-
return
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
);
|
|
901
|
-
});
|
|
832
|
+
async findById(id, options) {
|
|
833
|
+
return this.api.requestFindById(
|
|
834
|
+
`/api/${String(this.collection)}/${String(id)}`,
|
|
835
|
+
options
|
|
836
|
+
);
|
|
902
837
|
}
|
|
903
838
|
/**
|
|
904
839
|
* Create a new document
|
|
905
840
|
* POST /api/{collection}
|
|
906
841
|
* @returns Payload CMS mutation response with doc and message
|
|
907
842
|
*/
|
|
908
|
-
create(data, options) {
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
return this.api.requestCreate(endpoint, data);
|
|
920
|
-
});
|
|
843
|
+
async create(data, options) {
|
|
844
|
+
const endpoint = `/api/${String(this.collection)}`;
|
|
845
|
+
if (options?.file) {
|
|
846
|
+
return this.api.requestCreateWithFile(
|
|
847
|
+
endpoint,
|
|
848
|
+
data,
|
|
849
|
+
options.file,
|
|
850
|
+
options.filename
|
|
851
|
+
);
|
|
852
|
+
}
|
|
853
|
+
return this.api.requestCreate(endpoint, data);
|
|
921
854
|
}
|
|
922
855
|
/**
|
|
923
856
|
* Update a document by ID
|
|
924
857
|
* PATCH /api/{collection}/{id}
|
|
925
858
|
* @returns Payload CMS mutation response with doc and message
|
|
926
859
|
*/
|
|
927
|
-
update(id, data, options) {
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
return this.api.requestUpdate(endpoint, data);
|
|
939
|
-
});
|
|
860
|
+
async update(id, data, options) {
|
|
861
|
+
const endpoint = `/api/${String(this.collection)}/${String(id)}`;
|
|
862
|
+
if (options?.file) {
|
|
863
|
+
return this.api.requestUpdateWithFile(
|
|
864
|
+
endpoint,
|
|
865
|
+
data,
|
|
866
|
+
options.file,
|
|
867
|
+
options.filename
|
|
868
|
+
);
|
|
869
|
+
}
|
|
870
|
+
return this.api.requestUpdate(endpoint, data);
|
|
940
871
|
}
|
|
941
872
|
/**
|
|
942
873
|
* Count documents
|
|
943
874
|
* GET /api/{collection}/count
|
|
944
875
|
* @returns Count response with totalDocs
|
|
945
876
|
*/
|
|
946
|
-
count(options) {
|
|
947
|
-
return
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
);
|
|
952
|
-
});
|
|
877
|
+
async count(options) {
|
|
878
|
+
return this.api.requestCount(
|
|
879
|
+
`/api/${String(this.collection)}/count`,
|
|
880
|
+
options
|
|
881
|
+
);
|
|
953
882
|
}
|
|
954
883
|
/**
|
|
955
884
|
* Find first matching document and return its Next.js Metadata.
|
|
956
885
|
* Applies depth: 1 (image populate) and limit: 1 automatically.
|
|
957
886
|
* @returns Metadata or null if no document matches
|
|
958
887
|
*/
|
|
959
|
-
findMetadata(options, metadataOptions) {
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
);
|
|
968
|
-
});
|
|
888
|
+
async findMetadata(options, metadataOptions) {
|
|
889
|
+
const { docs } = await this.find({ ...options, limit: 1, depth: 1 });
|
|
890
|
+
const doc = docs[0];
|
|
891
|
+
if (!doc) return null;
|
|
892
|
+
return generateMetadata(
|
|
893
|
+
extractSeo(doc),
|
|
894
|
+
metadataOptions
|
|
895
|
+
);
|
|
969
896
|
}
|
|
970
897
|
/**
|
|
971
898
|
* Find document by ID and return its Next.js Metadata.
|
|
972
899
|
* Applies depth: 1 (image populate) automatically.
|
|
973
900
|
* @returns Metadata (throws on 404)
|
|
974
901
|
*/
|
|
975
|
-
findMetadataById(id, metadataOptions) {
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
);
|
|
982
|
-
});
|
|
902
|
+
async findMetadataById(id, metadataOptions) {
|
|
903
|
+
const doc = await this.findById(id, { depth: 1 });
|
|
904
|
+
return generateMetadata(
|
|
905
|
+
extractSeo(doc),
|
|
906
|
+
metadataOptions
|
|
907
|
+
);
|
|
983
908
|
}
|
|
984
909
|
/**
|
|
985
910
|
* Update multiple documents (bulk update)
|
|
986
911
|
* PATCH /api/{collection}
|
|
987
912
|
* @returns Payload CMS find response with updated docs
|
|
988
913
|
*/
|
|
989
|
-
updateMany(where, data) {
|
|
990
|
-
return
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
);
|
|
995
|
-
});
|
|
914
|
+
async updateMany(where, data) {
|
|
915
|
+
return this.api.requestUpdateMany(
|
|
916
|
+
`/api/${String(this.collection)}`,
|
|
917
|
+
{ where, data }
|
|
918
|
+
);
|
|
996
919
|
}
|
|
997
920
|
/**
|
|
998
921
|
* Delete a document by ID
|
|
999
922
|
* DELETE /api/{collection}/{id}
|
|
1000
923
|
* @returns Deleted document object directly (no wrapper)
|
|
1001
924
|
*/
|
|
1002
|
-
remove(id) {
|
|
1003
|
-
return
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
);
|
|
1007
|
-
});
|
|
925
|
+
async remove(id) {
|
|
926
|
+
return this.api.requestDelete(
|
|
927
|
+
`/api/${String(this.collection)}/${String(id)}`
|
|
928
|
+
);
|
|
1008
929
|
}
|
|
1009
930
|
/**
|
|
1010
931
|
* Delete multiple documents (bulk delete)
|
|
1011
932
|
* DELETE /api/{collection}
|
|
1012
933
|
* @returns Payload CMS find response with deleted docs
|
|
1013
934
|
*/
|
|
1014
|
-
removeMany(where) {
|
|
1015
|
-
return
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
);
|
|
1020
|
-
});
|
|
935
|
+
async removeMany(where) {
|
|
936
|
+
return this.api.requestDeleteMany(
|
|
937
|
+
`/api/${String(this.collection)}`,
|
|
938
|
+
{ where }
|
|
939
|
+
);
|
|
1021
940
|
}
|
|
1022
941
|
};
|
|
1023
942
|
|
|
@@ -1035,13 +954,12 @@ var HttpClient = class {
|
|
|
1035
954
|
this.onUnauthorized = onUnauthorized;
|
|
1036
955
|
}
|
|
1037
956
|
get defaultOptions() {
|
|
1038
|
-
var _a;
|
|
1039
957
|
const opts = {
|
|
1040
958
|
clientKey: this.clientKey,
|
|
1041
959
|
secretKey: this.secretKey,
|
|
1042
960
|
baseUrl: this.baseUrl
|
|
1043
961
|
};
|
|
1044
|
-
const token =
|
|
962
|
+
const token = this.getCustomerToken?.();
|
|
1045
963
|
if (token) {
|
|
1046
964
|
opts.customerToken = token;
|
|
1047
965
|
if (this.onUnauthorized) {
|
|
@@ -1057,7 +975,7 @@ var HttpClient = class {
|
|
|
1057
975
|
}
|
|
1058
976
|
assertJsonResponse(response) {
|
|
1059
977
|
const contentType = response.headers.get("content-type");
|
|
1060
|
-
if (!
|
|
978
|
+
if (!contentType?.includes("application/json")) {
|
|
1061
979
|
throw createApiError("Response is not in JSON format.", response.status, {
|
|
1062
980
|
contentType
|
|
1063
981
|
});
|
|
@@ -1067,87 +985,80 @@ var HttpClient = class {
|
|
|
1067
985
|
* Parse Payload CMS find response (list query)
|
|
1068
986
|
* Returns native Payload response structure
|
|
1069
987
|
*/
|
|
1070
|
-
parseFindResponse(response) {
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
throw createApiError("Invalid find response.", response.status, {
|
|
1079
|
-
jsonData
|
|
1080
|
-
});
|
|
1081
|
-
}
|
|
1082
|
-
return {
|
|
1083
|
-
docs: jsonData.docs,
|
|
1084
|
-
totalDocs: (_a = jsonData.totalDocs) != null ? _a : 0,
|
|
1085
|
-
limit: jsonData.limit || 20,
|
|
1086
|
-
totalPages: (_b = jsonData.totalPages) != null ? _b : 0,
|
|
1087
|
-
page: jsonData.page || 1,
|
|
1088
|
-
pagingCounter: jsonData.pagingCounter || 1,
|
|
1089
|
-
hasPrevPage: (_c = jsonData.hasPrevPage) != null ? _c : false,
|
|
1090
|
-
hasNextPage: (_d = jsonData.hasNextPage) != null ? _d : false,
|
|
1091
|
-
prevPage: (_e = jsonData.prevPage) != null ? _e : null,
|
|
1092
|
-
nextPage: (_f = jsonData.nextPage) != null ? _f : null
|
|
1093
|
-
};
|
|
1094
|
-
} catch (error) {
|
|
1095
|
-
if (error instanceof SDKError) throw error;
|
|
1096
|
-
throw createApiError("Failed to parse response.", response.status, {
|
|
1097
|
-
contentType,
|
|
1098
|
-
error: error instanceof Error ? error.message : error
|
|
988
|
+
async parseFindResponse(response) {
|
|
989
|
+
const contentType = response.headers.get("content-type");
|
|
990
|
+
try {
|
|
991
|
+
this.assertJsonResponse(response);
|
|
992
|
+
const jsonData = await response.json();
|
|
993
|
+
if (jsonData.docs === void 0) {
|
|
994
|
+
throw createApiError("Invalid find response.", response.status, {
|
|
995
|
+
jsonData
|
|
1099
996
|
});
|
|
1100
997
|
}
|
|
1101
|
-
|
|
998
|
+
return {
|
|
999
|
+
docs: jsonData.docs,
|
|
1000
|
+
totalDocs: jsonData.totalDocs ?? 0,
|
|
1001
|
+
limit: jsonData.limit || 20,
|
|
1002
|
+
totalPages: jsonData.totalPages ?? 0,
|
|
1003
|
+
page: jsonData.page || 1,
|
|
1004
|
+
pagingCounter: jsonData.pagingCounter || 1,
|
|
1005
|
+
hasPrevPage: jsonData.hasPrevPage ?? false,
|
|
1006
|
+
hasNextPage: jsonData.hasNextPage ?? false,
|
|
1007
|
+
prevPage: jsonData.prevPage ?? null,
|
|
1008
|
+
nextPage: jsonData.nextPage ?? null
|
|
1009
|
+
};
|
|
1010
|
+
} catch (error) {
|
|
1011
|
+
if (error instanceof SDKError) throw error;
|
|
1012
|
+
throw createApiError("Failed to parse response.", response.status, {
|
|
1013
|
+
contentType,
|
|
1014
|
+
error: error instanceof Error ? error.message : error
|
|
1015
|
+
});
|
|
1016
|
+
}
|
|
1102
1017
|
}
|
|
1103
1018
|
/**
|
|
1104
1019
|
* Parse Payload CMS mutation response (create/update)
|
|
1105
1020
|
* Returns native Payload response structure
|
|
1106
1021
|
*/
|
|
1107
|
-
parseMutationResponse(response) {
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
jsonData
|
|
1116
|
-
});
|
|
1117
|
-
}
|
|
1118
|
-
return {
|
|
1119
|
-
message: jsonData.message || "",
|
|
1120
|
-
doc: jsonData.doc,
|
|
1121
|
-
errors: jsonData.errors
|
|
1122
|
-
};
|
|
1123
|
-
} catch (error) {
|
|
1124
|
-
if (error instanceof SDKError) throw error;
|
|
1125
|
-
throw createApiError("Failed to parse response.", response.status, {
|
|
1126
|
-
contentType,
|
|
1127
|
-
error: error instanceof Error ? error.message : error
|
|
1022
|
+
async parseMutationResponse(response) {
|
|
1023
|
+
const contentType = response.headers.get("content-type");
|
|
1024
|
+
try {
|
|
1025
|
+
this.assertJsonResponse(response);
|
|
1026
|
+
const jsonData = await response.json();
|
|
1027
|
+
if (jsonData.doc === void 0) {
|
|
1028
|
+
throw createApiError("Invalid mutation response.", response.status, {
|
|
1029
|
+
jsonData
|
|
1128
1030
|
});
|
|
1129
1031
|
}
|
|
1130
|
-
|
|
1032
|
+
return {
|
|
1033
|
+
message: jsonData.message || "",
|
|
1034
|
+
doc: jsonData.doc,
|
|
1035
|
+
errors: jsonData.errors
|
|
1036
|
+
};
|
|
1037
|
+
} catch (error) {
|
|
1038
|
+
if (error instanceof SDKError) throw error;
|
|
1039
|
+
throw createApiError("Failed to parse response.", response.status, {
|
|
1040
|
+
contentType,
|
|
1041
|
+
error: error instanceof Error ? error.message : error
|
|
1042
|
+
});
|
|
1043
|
+
}
|
|
1131
1044
|
}
|
|
1132
1045
|
/**
|
|
1133
1046
|
* Parse Payload CMS document response (findById/delete)
|
|
1134
1047
|
* Returns document directly without wrapper
|
|
1135
1048
|
*/
|
|
1136
|
-
parseDocumentResponse(response) {
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
}
|
|
1150
|
-
});
|
|
1049
|
+
async parseDocumentResponse(response) {
|
|
1050
|
+
const contentType = response.headers.get("content-type");
|
|
1051
|
+
try {
|
|
1052
|
+
this.assertJsonResponse(response);
|
|
1053
|
+
const jsonData = await response.json();
|
|
1054
|
+
return jsonData;
|
|
1055
|
+
} catch (error) {
|
|
1056
|
+
if (error instanceof SDKError) throw error;
|
|
1057
|
+
throw createApiError("Failed to parse response.", response.status, {
|
|
1058
|
+
contentType,
|
|
1059
|
+
error: error instanceof Error ? error.message : error
|
|
1060
|
+
});
|
|
1061
|
+
}
|
|
1151
1062
|
}
|
|
1152
1063
|
};
|
|
1153
1064
|
|
|
@@ -1174,130 +1085,120 @@ var CollectionClient = class extends HttpClient {
|
|
|
1174
1085
|
* Find documents (list query)
|
|
1175
1086
|
* GET /api/{collection}
|
|
1176
1087
|
*/
|
|
1177
|
-
requestFind(endpoint, options) {
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
}));
|
|
1183
|
-
return this.parseFindResponse(response);
|
|
1088
|
+
async requestFind(endpoint, options) {
|
|
1089
|
+
const url = this.buildUrl(endpoint, options);
|
|
1090
|
+
const response = await httpFetch(url, {
|
|
1091
|
+
...this.defaultOptions,
|
|
1092
|
+
method: "GET"
|
|
1184
1093
|
});
|
|
1094
|
+
return this.parseFindResponse(response);
|
|
1185
1095
|
}
|
|
1186
1096
|
/**
|
|
1187
1097
|
* Find document by ID
|
|
1188
1098
|
* GET /api/{collection}/{id}
|
|
1189
1099
|
*/
|
|
1190
|
-
requestFindById(endpoint, options) {
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
}));
|
|
1196
|
-
return this.parseDocumentResponse(response);
|
|
1100
|
+
async requestFindById(endpoint, options) {
|
|
1101
|
+
const url = this.buildUrl(endpoint, options);
|
|
1102
|
+
const response = await httpFetch(url, {
|
|
1103
|
+
...this.defaultOptions,
|
|
1104
|
+
method: "GET"
|
|
1197
1105
|
});
|
|
1106
|
+
return this.parseDocumentResponse(response);
|
|
1198
1107
|
}
|
|
1199
1108
|
/**
|
|
1200
1109
|
* Create document
|
|
1201
1110
|
* POST /api/{collection}
|
|
1202
1111
|
*/
|
|
1203
|
-
requestCreate(endpoint, data) {
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
}));
|
|
1209
|
-
return this.parseMutationResponse(response);
|
|
1112
|
+
async requestCreate(endpoint, data) {
|
|
1113
|
+
const response = await httpFetch(endpoint, {
|
|
1114
|
+
...this.defaultOptions,
|
|
1115
|
+
method: "POST",
|
|
1116
|
+
body: data ? JSON.stringify(data) : void 0
|
|
1210
1117
|
});
|
|
1118
|
+
return this.parseMutationResponse(response);
|
|
1211
1119
|
}
|
|
1212
1120
|
/**
|
|
1213
1121
|
* Update document
|
|
1214
1122
|
* PATCH /api/{collection}/{id}
|
|
1215
1123
|
*/
|
|
1216
|
-
requestUpdate(endpoint, data) {
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
}));
|
|
1222
|
-
return this.parseMutationResponse(response);
|
|
1124
|
+
async requestUpdate(endpoint, data) {
|
|
1125
|
+
const response = await httpFetch(endpoint, {
|
|
1126
|
+
...this.defaultOptions,
|
|
1127
|
+
method: "PATCH",
|
|
1128
|
+
body: data ? JSON.stringify(data) : void 0
|
|
1223
1129
|
});
|
|
1130
|
+
return this.parseMutationResponse(response);
|
|
1224
1131
|
}
|
|
1225
1132
|
/**
|
|
1226
1133
|
* Count documents
|
|
1227
1134
|
* GET /api/{collection}/count
|
|
1228
1135
|
*/
|
|
1229
|
-
requestCount(endpoint, options) {
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
}));
|
|
1235
|
-
return this.parseDocumentResponse(response);
|
|
1136
|
+
async requestCount(endpoint, options) {
|
|
1137
|
+
const url = this.buildUrl(endpoint, options);
|
|
1138
|
+
const response = await httpFetch(url, {
|
|
1139
|
+
...this.defaultOptions,
|
|
1140
|
+
method: "GET"
|
|
1236
1141
|
});
|
|
1142
|
+
return this.parseDocumentResponse(response);
|
|
1237
1143
|
}
|
|
1238
1144
|
/**
|
|
1239
1145
|
* Update multiple documents (bulk update)
|
|
1240
1146
|
* PATCH /api/{collection}
|
|
1241
1147
|
*/
|
|
1242
|
-
requestUpdateMany(endpoint, data) {
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
}));
|
|
1248
|
-
return this.parseFindResponse(response);
|
|
1148
|
+
async requestUpdateMany(endpoint, data) {
|
|
1149
|
+
const response = await httpFetch(endpoint, {
|
|
1150
|
+
...this.defaultOptions,
|
|
1151
|
+
method: "PATCH",
|
|
1152
|
+
body: JSON.stringify(data)
|
|
1249
1153
|
});
|
|
1154
|
+
return this.parseFindResponse(response);
|
|
1250
1155
|
}
|
|
1251
1156
|
/**
|
|
1252
1157
|
* Delete document
|
|
1253
1158
|
* DELETE /api/{collection}/{id}
|
|
1254
1159
|
*/
|
|
1255
|
-
requestDelete(endpoint) {
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
}));
|
|
1260
|
-
return this.parseDocumentResponse(response);
|
|
1160
|
+
async requestDelete(endpoint) {
|
|
1161
|
+
const response = await httpFetch(endpoint, {
|
|
1162
|
+
...this.defaultOptions,
|
|
1163
|
+
method: "DELETE"
|
|
1261
1164
|
});
|
|
1165
|
+
return this.parseDocumentResponse(response);
|
|
1262
1166
|
}
|
|
1263
1167
|
/**
|
|
1264
1168
|
* Delete multiple documents (bulk delete)
|
|
1265
1169
|
* DELETE /api/{collection}
|
|
1266
1170
|
*/
|
|
1267
|
-
requestDeleteMany(endpoint, data) {
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
}));
|
|
1273
|
-
return this.parseFindResponse(response);
|
|
1171
|
+
async requestDeleteMany(endpoint, data) {
|
|
1172
|
+
const response = await httpFetch(endpoint, {
|
|
1173
|
+
...this.defaultOptions,
|
|
1174
|
+
method: "DELETE",
|
|
1175
|
+
body: JSON.stringify(data)
|
|
1274
1176
|
});
|
|
1177
|
+
return this.parseFindResponse(response);
|
|
1275
1178
|
}
|
|
1276
1179
|
/**
|
|
1277
1180
|
* Create document with file upload
|
|
1278
1181
|
* POST /api/{collection} (multipart/form-data)
|
|
1279
1182
|
*/
|
|
1280
|
-
requestCreateWithFile(endpoint, data, file, filename) {
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
}));
|
|
1286
|
-
return this.parseMutationResponse(response);
|
|
1183
|
+
async requestCreateWithFile(endpoint, data, file, filename) {
|
|
1184
|
+
const response = await httpFetch(endpoint, {
|
|
1185
|
+
...this.defaultOptions,
|
|
1186
|
+
method: "POST",
|
|
1187
|
+
body: buildPayloadFormData(data, file, filename)
|
|
1287
1188
|
});
|
|
1189
|
+
return this.parseMutationResponse(response);
|
|
1288
1190
|
}
|
|
1289
1191
|
/**
|
|
1290
1192
|
* Update document with file upload
|
|
1291
1193
|
* PATCH /api/{collection}/{id} (multipart/form-data)
|
|
1292
1194
|
*/
|
|
1293
|
-
requestUpdateWithFile(endpoint, data, file, filename) {
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
}));
|
|
1299
|
-
return this.parseMutationResponse(response);
|
|
1195
|
+
async requestUpdateWithFile(endpoint, data, file, filename) {
|
|
1196
|
+
const response = await httpFetch(endpoint, {
|
|
1197
|
+
...this.defaultOptions,
|
|
1198
|
+
method: "PATCH",
|
|
1199
|
+
body: buildPayloadFormData(data, file, filename)
|
|
1300
1200
|
});
|
|
1201
|
+
return this.parseMutationResponse(response);
|
|
1301
1202
|
}
|
|
1302
1203
|
};
|
|
1303
1204
|
|
|
@@ -1366,17 +1267,16 @@ var DEFAULT_TIMEOUT2 = 15e3;
|
|
|
1366
1267
|
function safeGetItem(key) {
|
|
1367
1268
|
try {
|
|
1368
1269
|
return localStorage.getItem(key);
|
|
1369
|
-
} catch
|
|
1270
|
+
} catch {
|
|
1370
1271
|
return null;
|
|
1371
1272
|
}
|
|
1372
1273
|
}
|
|
1373
1274
|
var CustomerAuth = class {
|
|
1374
1275
|
constructor(clientKey, baseUrl, options) {
|
|
1375
1276
|
this.refreshPromise = null;
|
|
1376
|
-
var _a, _b;
|
|
1377
1277
|
this.clientKey = clientKey;
|
|
1378
1278
|
this.baseUrl = baseUrl;
|
|
1379
|
-
const persist =
|
|
1279
|
+
const persist = options?.persist ?? true;
|
|
1380
1280
|
if (persist) {
|
|
1381
1281
|
const key = typeof persist === "string" ? persist : "customer-token";
|
|
1382
1282
|
const isBrowser = typeof window !== "undefined";
|
|
@@ -1385,68 +1285,60 @@ var CustomerAuth = class {
|
|
|
1385
1285
|
try {
|
|
1386
1286
|
if (token) localStorage.setItem(key, token);
|
|
1387
1287
|
else localStorage.removeItem(key);
|
|
1388
|
-
} catch
|
|
1288
|
+
} catch {
|
|
1389
1289
|
}
|
|
1390
1290
|
} : void 0;
|
|
1391
1291
|
} else {
|
|
1392
|
-
this.token =
|
|
1393
|
-
this.onTokenChange = options
|
|
1292
|
+
this.token = options?.token ?? null;
|
|
1293
|
+
this.onTokenChange = options?.onTokenChange;
|
|
1394
1294
|
}
|
|
1395
1295
|
}
|
|
1396
1296
|
/**
|
|
1397
1297
|
* Register a new customer account
|
|
1398
1298
|
*/
|
|
1399
|
-
register(data) {
|
|
1400
|
-
return
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
body: JSON.stringify(data)
|
|
1404
|
-
});
|
|
1299
|
+
async register(data) {
|
|
1300
|
+
return this.requestJson("/api/customers/register", {
|
|
1301
|
+
method: "POST",
|
|
1302
|
+
body: JSON.stringify(data)
|
|
1405
1303
|
});
|
|
1406
1304
|
}
|
|
1407
1305
|
/**
|
|
1408
1306
|
* Login with email and password. Stores the token internally.
|
|
1409
1307
|
*/
|
|
1410
|
-
login(data) {
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
return result;
|
|
1421
|
-
});
|
|
1308
|
+
async login(data) {
|
|
1309
|
+
const result = await this.requestJson(
|
|
1310
|
+
"/api/customers/login",
|
|
1311
|
+
{
|
|
1312
|
+
method: "POST",
|
|
1313
|
+
body: JSON.stringify(data)
|
|
1314
|
+
}
|
|
1315
|
+
);
|
|
1316
|
+
this.setToken(result.token);
|
|
1317
|
+
return result;
|
|
1422
1318
|
}
|
|
1423
1319
|
/**
|
|
1424
1320
|
* Refresh the current token. Requires a valid (non-expired) token.
|
|
1425
1321
|
*/
|
|
1426
|
-
refreshToken() {
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
}
|
|
1436
|
-
});
|
|
1322
|
+
async refreshToken() {
|
|
1323
|
+
if (!this.token) throw new ApiError("Not authenticated", 401);
|
|
1324
|
+
if (this.refreshPromise) return this.refreshPromise;
|
|
1325
|
+
this.refreshPromise = this._doRefreshToken();
|
|
1326
|
+
try {
|
|
1327
|
+
return await this.refreshPromise;
|
|
1328
|
+
} finally {
|
|
1329
|
+
this.refreshPromise = null;
|
|
1330
|
+
}
|
|
1437
1331
|
}
|
|
1438
|
-
_doRefreshToken() {
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
return result;
|
|
1449
|
-
});
|
|
1332
|
+
async _doRefreshToken() {
|
|
1333
|
+
const result = await this.requestJson(
|
|
1334
|
+
"/api/customers/refresh",
|
|
1335
|
+
{
|
|
1336
|
+
method: "POST",
|
|
1337
|
+
headers: { Authorization: `Bearer ${this.token}` }
|
|
1338
|
+
}
|
|
1339
|
+
);
|
|
1340
|
+
this.setToken(result.token);
|
|
1341
|
+
return result;
|
|
1450
1342
|
}
|
|
1451
1343
|
/**
|
|
1452
1344
|
* Clear the stored token
|
|
@@ -1457,106 +1349,91 @@ var CustomerAuth = class {
|
|
|
1457
1349
|
/**
|
|
1458
1350
|
* Get the current authenticated customer's profile
|
|
1459
1351
|
*/
|
|
1460
|
-
me() {
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
"
|
|
1467
|
-
{
|
|
1468
|
-
method: "GET",
|
|
1469
|
-
headers: { Authorization: `Bearer ${this.token}` }
|
|
1470
|
-
}
|
|
1471
|
-
);
|
|
1472
|
-
return (_a = data.customer) != null ? _a : null;
|
|
1473
|
-
} catch (error) {
|
|
1474
|
-
if (error instanceof ApiError && error.status === 401) {
|
|
1475
|
-
this.setToken(null);
|
|
1476
|
-
return null;
|
|
1352
|
+
async me() {
|
|
1353
|
+
if (!this.token) return null;
|
|
1354
|
+
try {
|
|
1355
|
+
const data = await this.requestJson(
|
|
1356
|
+
"/api/customers/me",
|
|
1357
|
+
{
|
|
1358
|
+
method: "GET",
|
|
1359
|
+
headers: { Authorization: `Bearer ${this.token}` }
|
|
1477
1360
|
}
|
|
1478
|
-
|
|
1361
|
+
);
|
|
1362
|
+
return data.customer ?? null;
|
|
1363
|
+
} catch (error) {
|
|
1364
|
+
if (error instanceof ApiError && error.status === 401) {
|
|
1365
|
+
this.setToken(null);
|
|
1366
|
+
return null;
|
|
1479
1367
|
}
|
|
1480
|
-
|
|
1368
|
+
throw error;
|
|
1369
|
+
}
|
|
1481
1370
|
}
|
|
1482
1371
|
/**
|
|
1483
1372
|
* Request a password reset email
|
|
1484
1373
|
*/
|
|
1485
|
-
forgotPassword(email) {
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
body: JSON.stringify({ email })
|
|
1490
|
-
});
|
|
1374
|
+
async forgotPassword(email) {
|
|
1375
|
+
await this.requestJson("/api/customers/forgot-password", {
|
|
1376
|
+
method: "POST",
|
|
1377
|
+
body: JSON.stringify({ email })
|
|
1491
1378
|
});
|
|
1492
1379
|
}
|
|
1493
1380
|
/**
|
|
1494
1381
|
* Reset password using a token from the reset email
|
|
1495
1382
|
*/
|
|
1496
|
-
resetPassword(token, password) {
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
body: JSON.stringify({ token, password })
|
|
1501
|
-
});
|
|
1383
|
+
async resetPassword(token, password) {
|
|
1384
|
+
await this.requestJson("/api/customers/reset-password", {
|
|
1385
|
+
method: "POST",
|
|
1386
|
+
body: JSON.stringify({ token, password })
|
|
1502
1387
|
});
|
|
1503
1388
|
}
|
|
1504
1389
|
/**
|
|
1505
1390
|
* Update the authenticated customer's profile (name, phone, marketingConsent)
|
|
1506
1391
|
*/
|
|
1507
|
-
updateProfile(data) {
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
return result.customer;
|
|
1519
|
-
});
|
|
1392
|
+
async updateProfile(data) {
|
|
1393
|
+
if (!this.token) throw new ApiError("Not authenticated", 401);
|
|
1394
|
+
const result = await this.requestJson(
|
|
1395
|
+
"/api/customers/me",
|
|
1396
|
+
{
|
|
1397
|
+
method: "PATCH",
|
|
1398
|
+
headers: { Authorization: `Bearer ${this.token}` },
|
|
1399
|
+
body: JSON.stringify(data)
|
|
1400
|
+
}
|
|
1401
|
+
);
|
|
1402
|
+
return result.customer;
|
|
1520
1403
|
}
|
|
1521
1404
|
/**
|
|
1522
1405
|
* Change the password of the currently authenticated customer
|
|
1523
1406
|
*/
|
|
1524
|
-
changePassword(currentPassword, newPassword) {
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
body: JSON.stringify({ currentPassword, newPassword })
|
|
1531
|
-
});
|
|
1407
|
+
async changePassword(currentPassword, newPassword) {
|
|
1408
|
+
if (!this.token) throw new ApiError("Not authenticated", 401);
|
|
1409
|
+
await this.requestJson("/api/customers/change-password", {
|
|
1410
|
+
method: "POST",
|
|
1411
|
+
headers: { Authorization: `Bearer ${this.token}` },
|
|
1412
|
+
body: JSON.stringify({ currentPassword, newPassword })
|
|
1532
1413
|
});
|
|
1533
1414
|
}
|
|
1534
1415
|
/**
|
|
1535
1416
|
* Verify email using the verification token
|
|
1536
1417
|
*/
|
|
1537
|
-
verifyEmail(token) {
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
body: JSON.stringify({ token })
|
|
1542
|
-
});
|
|
1418
|
+
async verifyEmail(token) {
|
|
1419
|
+
await this.requestJson("/api/customers/verify-email", {
|
|
1420
|
+
method: "POST",
|
|
1421
|
+
body: JSON.stringify({ token })
|
|
1543
1422
|
});
|
|
1544
1423
|
}
|
|
1545
1424
|
/**
|
|
1546
1425
|
* Get the authenticated customer's orders with pagination and optional status filter
|
|
1547
1426
|
*/
|
|
1548
|
-
getMyOrders(options) {
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
headers: { Authorization: `Bearer ${this.token}` }
|
|
1559
|
-
});
|
|
1427
|
+
async getMyOrders(options) {
|
|
1428
|
+
if (!this.token) throw new ApiError("Not authenticated", 401);
|
|
1429
|
+
const params = new URLSearchParams();
|
|
1430
|
+
if (options?.page) params.set("page", String(options.page));
|
|
1431
|
+
if (options?.limit) params.set("limit", String(options.limit));
|
|
1432
|
+
if (options?.status) params.set("status", options.status);
|
|
1433
|
+
const qs = params.toString();
|
|
1434
|
+
return this.requestJson(`/api/customers/me/orders${qs ? `?${qs}` : ""}`, {
|
|
1435
|
+
method: "GET",
|
|
1436
|
+
headers: { Authorization: `Bearer ${this.token}` }
|
|
1560
1437
|
});
|
|
1561
1438
|
}
|
|
1562
1439
|
/**
|
|
@@ -1569,9 +1446,8 @@ var CustomerAuth = class {
|
|
|
1569
1446
|
* Set the token manually (e.g. from SSR)
|
|
1570
1447
|
*/
|
|
1571
1448
|
setToken(token) {
|
|
1572
|
-
var _a;
|
|
1573
1449
|
this.token = token;
|
|
1574
|
-
|
|
1450
|
+
this.onTokenChange?.(token);
|
|
1575
1451
|
}
|
|
1576
1452
|
/**
|
|
1577
1453
|
* Check if the customer is currently authenticated
|
|
@@ -1583,58 +1459,57 @@ var CustomerAuth = class {
|
|
|
1583
1459
|
* Internal: make a request with timeout and error handling.
|
|
1584
1460
|
* Auth endpoints don't retry — failures are final.
|
|
1585
1461
|
*/
|
|
1586
|
-
requestJson(path, init) {
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
clearTimeout(timeoutId);
|
|
1603
|
-
if (error instanceof Error && error.name === "AbortError") {
|
|
1604
|
-
throw new TimeoutError(`Request timed out after ${DEFAULT_TIMEOUT2}ms`, {
|
|
1605
|
-
url: path,
|
|
1606
|
-
timeout: DEFAULT_TIMEOUT2
|
|
1607
|
-
});
|
|
1608
|
-
}
|
|
1609
|
-
throw new NetworkError(
|
|
1610
|
-
error instanceof Error ? error.message : "Network request failed",
|
|
1611
|
-
void 0,
|
|
1612
|
-
{ url: path },
|
|
1613
|
-
"Network connection failed.",
|
|
1614
|
-
"Please check your internet connection and try again."
|
|
1615
|
-
);
|
|
1616
|
-
}
|
|
1462
|
+
async requestJson(path, init) {
|
|
1463
|
+
const headers = new Headers(init.headers);
|
|
1464
|
+
headers.set("X-Client-Key", this.clientKey);
|
|
1465
|
+
if (!headers.has("Content-Type") && init.body) {
|
|
1466
|
+
headers.set("Content-Type", "application/json");
|
|
1467
|
+
}
|
|
1468
|
+
const controller = new AbortController();
|
|
1469
|
+
const timeoutId = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT2);
|
|
1470
|
+
let res;
|
|
1471
|
+
try {
|
|
1472
|
+
res = await fetch(`${this.baseUrl}${path}`, {
|
|
1473
|
+
...init,
|
|
1474
|
+
headers,
|
|
1475
|
+
signal: controller.signal
|
|
1476
|
+
});
|
|
1477
|
+
} catch (error) {
|
|
1617
1478
|
clearTimeout(timeoutId);
|
|
1618
|
-
if (
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
body.details,
|
|
1624
|
-
body.error
|
|
1625
|
-
);
|
|
1626
|
-
}
|
|
1627
|
-
try {
|
|
1628
|
-
return yield res.json();
|
|
1629
|
-
} catch (e) {
|
|
1630
|
-
throw new ApiError(
|
|
1631
|
-
"Invalid JSON response from server",
|
|
1632
|
-
res.status,
|
|
1633
|
-
void 0,
|
|
1634
|
-
"INVALID_RESPONSE"
|
|
1635
|
-
);
|
|
1479
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
1480
|
+
throw new TimeoutError(`Request timed out after ${DEFAULT_TIMEOUT2}ms`, {
|
|
1481
|
+
url: path,
|
|
1482
|
+
timeout: DEFAULT_TIMEOUT2
|
|
1483
|
+
});
|
|
1636
1484
|
}
|
|
1637
|
-
|
|
1485
|
+
throw new NetworkError(
|
|
1486
|
+
error instanceof Error ? error.message : "Network request failed",
|
|
1487
|
+
void 0,
|
|
1488
|
+
{ url: path },
|
|
1489
|
+
"Network connection failed.",
|
|
1490
|
+
"Please check your internet connection and try again."
|
|
1491
|
+
);
|
|
1492
|
+
}
|
|
1493
|
+
clearTimeout(timeoutId);
|
|
1494
|
+
if (!res.ok) {
|
|
1495
|
+
const body = await res.json().catch(() => ({}));
|
|
1496
|
+
throw new ApiError(
|
|
1497
|
+
body.error || `HTTP ${res.status}`,
|
|
1498
|
+
res.status,
|
|
1499
|
+
body.details,
|
|
1500
|
+
body.error
|
|
1501
|
+
);
|
|
1502
|
+
}
|
|
1503
|
+
try {
|
|
1504
|
+
return await res.json();
|
|
1505
|
+
} catch {
|
|
1506
|
+
throw new ApiError(
|
|
1507
|
+
"Invalid JSON response from server",
|
|
1508
|
+
res.status,
|
|
1509
|
+
void 0,
|
|
1510
|
+
"INVALID_RESPONSE"
|
|
1511
|
+
);
|
|
1512
|
+
}
|
|
1638
1513
|
}
|
|
1639
1514
|
};
|
|
1640
1515
|
|
|
@@ -1698,48 +1573,56 @@ var CollectionHooks = class {
|
|
|
1698
1573
|
// ===== useQuery =====
|
|
1699
1574
|
useQuery(params, options) {
|
|
1700
1575
|
const { collection, options: queryOptions } = params;
|
|
1701
|
-
const
|
|
1702
|
-
return (0, import_react_query2.useQuery)(
|
|
1576
|
+
const { placeholderData, ...restOptions } = options ?? {};
|
|
1577
|
+
return (0, import_react_query2.useQuery)({
|
|
1703
1578
|
queryKey: collectionKeys(collection).list(queryOptions),
|
|
1704
|
-
queryFn: () =>
|
|
1705
|
-
return
|
|
1706
|
-
}
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1579
|
+
queryFn: async () => {
|
|
1580
|
+
return await this.collectionClient.from(collection).find(queryOptions);
|
|
1581
|
+
},
|
|
1582
|
+
...restOptions,
|
|
1583
|
+
// NonFunctionGuard<T> incompatible with generic union types — safe cast
|
|
1584
|
+
...placeholderData !== void 0 && {
|
|
1585
|
+
placeholderData
|
|
1586
|
+
}
|
|
1587
|
+
});
|
|
1710
1588
|
}
|
|
1711
1589
|
// ===== useSuspenseQuery =====
|
|
1712
1590
|
useSuspenseQuery(params, options) {
|
|
1713
1591
|
const { collection, options: queryOptions } = params;
|
|
1714
|
-
return (0, import_react_query2.useSuspenseQuery)(
|
|
1592
|
+
return (0, import_react_query2.useSuspenseQuery)({
|
|
1715
1593
|
queryKey: collectionKeys(collection).list(queryOptions),
|
|
1716
|
-
queryFn: () =>
|
|
1717
|
-
return
|
|
1718
|
-
}
|
|
1719
|
-
|
|
1594
|
+
queryFn: async () => {
|
|
1595
|
+
return await this.collectionClient.from(collection).find(queryOptions);
|
|
1596
|
+
},
|
|
1597
|
+
...options
|
|
1598
|
+
});
|
|
1720
1599
|
}
|
|
1721
1600
|
// ===== useQueryById =====
|
|
1722
1601
|
useQueryById(params, options) {
|
|
1723
1602
|
const { collection, id, options: queryOptions } = params;
|
|
1724
|
-
const
|
|
1725
|
-
return (0, import_react_query2.useQuery)(
|
|
1603
|
+
const { placeholderData, ...restOptions } = options ?? {};
|
|
1604
|
+
return (0, import_react_query2.useQuery)({
|
|
1726
1605
|
queryKey: collectionKeys(collection).detail(id, queryOptions),
|
|
1727
|
-
queryFn: () =>
|
|
1728
|
-
return
|
|
1729
|
-
}
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1606
|
+
queryFn: async () => {
|
|
1607
|
+
return await this.collectionClient.from(collection).findById(id, queryOptions);
|
|
1608
|
+
},
|
|
1609
|
+
...restOptions,
|
|
1610
|
+
// NonFunctionGuard<T> incompatible with generic union types — safe cast
|
|
1611
|
+
...placeholderData !== void 0 && {
|
|
1612
|
+
placeholderData
|
|
1613
|
+
}
|
|
1614
|
+
});
|
|
1733
1615
|
}
|
|
1734
1616
|
// ===== useSuspenseQueryById =====
|
|
1735
1617
|
useSuspenseQueryById(params, options) {
|
|
1736
1618
|
const { collection, id, options: queryOptions } = params;
|
|
1737
|
-
return (0, import_react_query2.useSuspenseQuery)(
|
|
1619
|
+
return (0, import_react_query2.useSuspenseQuery)({
|
|
1738
1620
|
queryKey: collectionKeys(collection).detail(id, queryOptions),
|
|
1739
|
-
queryFn: () =>
|
|
1740
|
-
return
|
|
1741
|
-
}
|
|
1742
|
-
|
|
1621
|
+
queryFn: async () => {
|
|
1622
|
+
return await this.collectionClient.from(collection).findById(id, queryOptions);
|
|
1623
|
+
},
|
|
1624
|
+
...options
|
|
1625
|
+
});
|
|
1743
1626
|
}
|
|
1744
1627
|
// ===== useInfiniteQuery =====
|
|
1745
1628
|
useInfiniteQuery(params, options) {
|
|
@@ -1748,17 +1631,18 @@ var CollectionHooks = class {
|
|
|
1748
1631
|
options: queryOptions,
|
|
1749
1632
|
pageSize = DEFAULT_PAGE_SIZE
|
|
1750
1633
|
} = params;
|
|
1751
|
-
return (0, import_react_query2.useInfiniteQuery)(
|
|
1634
|
+
return (0, import_react_query2.useInfiniteQuery)({
|
|
1752
1635
|
queryKey: collectionKeys(collection).infinite(queryOptions),
|
|
1753
|
-
queryFn:
|
|
1754
|
-
const response =
|
|
1636
|
+
queryFn: async ({ pageParam }) => {
|
|
1637
|
+
const response = await this.collectionClient.from(collection).find({ ...queryOptions, page: pageParam, limit: pageSize });
|
|
1755
1638
|
return response;
|
|
1756
|
-
}
|
|
1639
|
+
},
|
|
1757
1640
|
initialPageParam: 1,
|
|
1758
1641
|
getNextPageParam: (lastPage) => {
|
|
1759
1642
|
return lastPage.hasNextPage ? lastPage.nextPage : void 0;
|
|
1760
|
-
}
|
|
1761
|
-
|
|
1643
|
+
},
|
|
1644
|
+
...options
|
|
1645
|
+
});
|
|
1762
1646
|
}
|
|
1763
1647
|
// ===== useSuspenseInfiniteQuery =====
|
|
1764
1648
|
useSuspenseInfiniteQuery(params, options) {
|
|
@@ -1767,123 +1651,116 @@ var CollectionHooks = class {
|
|
|
1767
1651
|
options: queryOptions,
|
|
1768
1652
|
pageSize = DEFAULT_PAGE_SIZE
|
|
1769
1653
|
} = params;
|
|
1770
|
-
return (0, import_react_query2.useSuspenseInfiniteQuery)(
|
|
1654
|
+
return (0, import_react_query2.useSuspenseInfiniteQuery)({
|
|
1771
1655
|
queryKey: collectionKeys(collection).infinite(queryOptions),
|
|
1772
|
-
queryFn:
|
|
1773
|
-
const response =
|
|
1656
|
+
queryFn: async ({ pageParam }) => {
|
|
1657
|
+
const response = await this.collectionClient.from(collection).find({ ...queryOptions, page: pageParam, limit: pageSize });
|
|
1774
1658
|
return response;
|
|
1775
|
-
}
|
|
1659
|
+
},
|
|
1776
1660
|
initialPageParam: 1,
|
|
1777
1661
|
getNextPageParam: (lastPage) => {
|
|
1778
1662
|
return lastPage.hasNextPage ? lastPage.nextPage : void 0;
|
|
1779
|
-
}
|
|
1780
|
-
|
|
1663
|
+
},
|
|
1664
|
+
...options
|
|
1665
|
+
});
|
|
1781
1666
|
}
|
|
1782
1667
|
// ===== prefetchQuery =====
|
|
1783
|
-
prefetchQuery(params, options) {
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
}, options));
|
|
1668
|
+
async prefetchQuery(params, options) {
|
|
1669
|
+
const { collection, options: queryOptions } = params;
|
|
1670
|
+
return this.queryClient.prefetchQuery({
|
|
1671
|
+
queryKey: collectionKeys(collection).list(queryOptions),
|
|
1672
|
+
queryFn: async () => {
|
|
1673
|
+
return await this.collectionClient.from(collection).find(queryOptions);
|
|
1674
|
+
},
|
|
1675
|
+
...options
|
|
1792
1676
|
});
|
|
1793
1677
|
}
|
|
1794
1678
|
// ===== prefetchQueryById =====
|
|
1795
|
-
prefetchQueryById(params, options) {
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
}, options));
|
|
1679
|
+
async prefetchQueryById(params, options) {
|
|
1680
|
+
const { collection, id, options: queryOptions } = params;
|
|
1681
|
+
return this.queryClient.prefetchQuery({
|
|
1682
|
+
queryKey: collectionKeys(collection).detail(id, queryOptions),
|
|
1683
|
+
queryFn: async () => {
|
|
1684
|
+
return await this.collectionClient.from(collection).findById(id, queryOptions);
|
|
1685
|
+
},
|
|
1686
|
+
...options
|
|
1804
1687
|
});
|
|
1805
1688
|
}
|
|
1806
1689
|
// ===== prefetchInfiniteQuery =====
|
|
1807
|
-
prefetchInfiniteQuery(params, options) {
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
pages: (_a = options == null ? void 0 : options.pages) != null ? _a : 1,
|
|
1826
|
-
staleTime: options == null ? void 0 : options.staleTime
|
|
1827
|
-
});
|
|
1690
|
+
async prefetchInfiniteQuery(params, options) {
|
|
1691
|
+
const {
|
|
1692
|
+
collection,
|
|
1693
|
+
options: queryOptions,
|
|
1694
|
+
pageSize = DEFAULT_PAGE_SIZE
|
|
1695
|
+
} = params;
|
|
1696
|
+
return this.queryClient.prefetchInfiniteQuery({
|
|
1697
|
+
queryKey: collectionKeys(collection).infinite(queryOptions),
|
|
1698
|
+
queryFn: async ({ pageParam }) => {
|
|
1699
|
+
const response = await this.collectionClient.from(collection).find({ ...queryOptions, page: pageParam, limit: pageSize });
|
|
1700
|
+
return response;
|
|
1701
|
+
},
|
|
1702
|
+
initialPageParam: 1,
|
|
1703
|
+
getNextPageParam: (lastPage) => {
|
|
1704
|
+
return lastPage.hasNextPage ? lastPage.nextPage : void 0;
|
|
1705
|
+
},
|
|
1706
|
+
pages: options?.pages ?? 1,
|
|
1707
|
+
staleTime: options?.staleTime
|
|
1828
1708
|
});
|
|
1829
1709
|
}
|
|
1830
1710
|
// ===== Mutation Hooks =====
|
|
1831
1711
|
useCreate(params, options) {
|
|
1832
1712
|
const { collection } = params;
|
|
1833
1713
|
return (0, import_react_query2.useMutation)({
|
|
1834
|
-
mutationFn: (variables) =>
|
|
1835
|
-
return
|
|
1714
|
+
mutationFn: async (variables) => {
|
|
1715
|
+
return await this.collectionClient.from(collection).create(
|
|
1836
1716
|
variables.data,
|
|
1837
1717
|
variables.file ? { file: variables.file, filename: variables.filename } : void 0
|
|
1838
1718
|
);
|
|
1839
|
-
}
|
|
1719
|
+
},
|
|
1840
1720
|
onSuccess: (data) => {
|
|
1841
|
-
var _a;
|
|
1842
1721
|
this.queryClient.invalidateQueries({
|
|
1843
1722
|
queryKey: collectionKeys(collection).all
|
|
1844
1723
|
});
|
|
1845
|
-
|
|
1724
|
+
options?.onSuccess?.(data);
|
|
1846
1725
|
},
|
|
1847
|
-
onError: options
|
|
1848
|
-
onSettled: options
|
|
1726
|
+
onError: options?.onError,
|
|
1727
|
+
onSettled: options?.onSettled
|
|
1849
1728
|
});
|
|
1850
1729
|
}
|
|
1851
1730
|
useUpdate(params, options) {
|
|
1852
1731
|
const { collection } = params;
|
|
1853
1732
|
return (0, import_react_query2.useMutation)({
|
|
1854
|
-
mutationFn: (variables) =>
|
|
1855
|
-
return
|
|
1733
|
+
mutationFn: async (variables) => {
|
|
1734
|
+
return await this.collectionClient.from(collection).update(
|
|
1856
1735
|
variables.id,
|
|
1857
1736
|
variables.data,
|
|
1858
1737
|
variables.file ? { file: variables.file, filename: variables.filename } : void 0
|
|
1859
1738
|
);
|
|
1860
|
-
}
|
|
1739
|
+
},
|
|
1861
1740
|
onSuccess: (data) => {
|
|
1862
|
-
var _a;
|
|
1863
1741
|
this.queryClient.invalidateQueries({
|
|
1864
1742
|
queryKey: collectionKeys(collection).all
|
|
1865
1743
|
});
|
|
1866
|
-
|
|
1744
|
+
options?.onSuccess?.(data);
|
|
1867
1745
|
},
|
|
1868
|
-
onError: options
|
|
1869
|
-
onSettled: options
|
|
1746
|
+
onError: options?.onError,
|
|
1747
|
+
onSettled: options?.onSettled
|
|
1870
1748
|
});
|
|
1871
1749
|
}
|
|
1872
1750
|
useRemove(params, options) {
|
|
1873
1751
|
const { collection } = params;
|
|
1874
1752
|
return (0, import_react_query2.useMutation)({
|
|
1875
|
-
mutationFn: (id) =>
|
|
1876
|
-
return
|
|
1877
|
-
}
|
|
1753
|
+
mutationFn: async (id) => {
|
|
1754
|
+
return await this.collectionClient.from(collection).remove(id);
|
|
1755
|
+
},
|
|
1878
1756
|
onSuccess: (data) => {
|
|
1879
|
-
var _a;
|
|
1880
1757
|
this.queryClient.invalidateQueries({
|
|
1881
1758
|
queryKey: collectionKeys(collection).all
|
|
1882
1759
|
});
|
|
1883
|
-
|
|
1760
|
+
options?.onSuccess?.(data);
|
|
1884
1761
|
},
|
|
1885
|
-
onError: options
|
|
1886
|
-
onSettled: options
|
|
1762
|
+
onError: options?.onError,
|
|
1763
|
+
onSettled: options?.onSettled
|
|
1887
1764
|
});
|
|
1888
1765
|
}
|
|
1889
1766
|
// ===== Cache Utilities =====
|
|
@@ -1922,12 +1799,11 @@ function createMutation(mutationFn, callbacks, onSuccessExtra) {
|
|
|
1922
1799
|
return (0, import_react_query3.useMutation)({
|
|
1923
1800
|
mutationFn,
|
|
1924
1801
|
onSuccess: (data) => {
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
(_a = callbacks == null ? void 0 : callbacks.onSuccess) == null ? void 0 : _a.call(callbacks, data);
|
|
1802
|
+
onSuccessExtra?.(data);
|
|
1803
|
+
callbacks?.onSuccess?.(data);
|
|
1928
1804
|
},
|
|
1929
|
-
onError: callbacks
|
|
1930
|
-
onSettled: callbacks
|
|
1805
|
+
onError: callbacks?.onError,
|
|
1806
|
+
onSettled: callbacks?.onSettled
|
|
1931
1807
|
});
|
|
1932
1808
|
}
|
|
1933
1809
|
var CustomerHooks = class {
|
|
@@ -1948,15 +1824,14 @@ var CustomerHooks = class {
|
|
|
1948
1824
|
}
|
|
1949
1825
|
// ===== useCustomerMe =====
|
|
1950
1826
|
useCustomerMe(options) {
|
|
1951
|
-
|
|
1952
|
-
return (0, import_react_query3.useQuery)(__spreadProps(__spreadValues({
|
|
1827
|
+
return (0, import_react_query3.useQuery)({
|
|
1953
1828
|
queryKey: customerKeys.me(),
|
|
1954
|
-
queryFn: () =>
|
|
1955
|
-
return
|
|
1956
|
-
}
|
|
1957
|
-
|
|
1958
|
-
enabled: (
|
|
1959
|
-
})
|
|
1829
|
+
queryFn: async () => {
|
|
1830
|
+
return await this.ensureCustomerAuth().me();
|
|
1831
|
+
},
|
|
1832
|
+
...options,
|
|
1833
|
+
enabled: (options?.enabled ?? true) && !!this.customerAuth?.isAuthenticated()
|
|
1834
|
+
});
|
|
1960
1835
|
}
|
|
1961
1836
|
// ===== Mutations =====
|
|
1962
1837
|
useCustomerLogin(options) {
|
|
@@ -1974,16 +1849,15 @@ var CustomerHooks = class {
|
|
|
1974
1849
|
}
|
|
1975
1850
|
useCustomerLogout(options) {
|
|
1976
1851
|
return (0, import_react_query3.useMutation)({
|
|
1977
|
-
mutationFn: () =>
|
|
1852
|
+
mutationFn: async () => {
|
|
1978
1853
|
this.ensureCustomerAuth().logout();
|
|
1979
|
-
}
|
|
1854
|
+
},
|
|
1980
1855
|
onSuccess: () => {
|
|
1981
|
-
var _a;
|
|
1982
1856
|
this.queryClient.removeQueries({ queryKey: customerKeys.all });
|
|
1983
|
-
|
|
1857
|
+
options?.onSuccess?.();
|
|
1984
1858
|
},
|
|
1985
|
-
onError: options
|
|
1986
|
-
onSettled: options
|
|
1859
|
+
onError: options?.onError,
|
|
1860
|
+
onSettled: options?.onSettled
|
|
1987
1861
|
});
|
|
1988
1862
|
}
|
|
1989
1863
|
useCustomerForgotPassword(options) {
|
|
@@ -2067,15 +1941,14 @@ var QueryHooks = class extends CollectionHooks {
|
|
|
2067
1941
|
// src/core/client/client.ts
|
|
2068
1942
|
var Client = class {
|
|
2069
1943
|
constructor(options) {
|
|
2070
|
-
var _a;
|
|
2071
1944
|
if (!options.clientKey) {
|
|
2072
1945
|
throw createConfigError("clientKey is required.");
|
|
2073
1946
|
}
|
|
2074
|
-
this.config =
|
|
1947
|
+
this.config = { ...options };
|
|
2075
1948
|
this.baseUrl = resolveApiUrl();
|
|
2076
1949
|
const metadata = {
|
|
2077
1950
|
timestamp: Date.now(),
|
|
2078
|
-
userAgent: typeof window !== "undefined" ?
|
|
1951
|
+
userAgent: typeof window !== "undefined" ? window.navigator?.userAgent : "Node.js"
|
|
2079
1952
|
};
|
|
2080
1953
|
this.state = { metadata };
|
|
2081
1954
|
this.queryClient = getQueryClient();
|
|
@@ -2084,15 +1957,14 @@ var Client = class {
|
|
|
2084
1957
|
this.baseUrl,
|
|
2085
1958
|
options.customer
|
|
2086
1959
|
);
|
|
2087
|
-
const onUnauthorized = () =>
|
|
2088
|
-
var _a2;
|
|
1960
|
+
const onUnauthorized = async () => {
|
|
2089
1961
|
try {
|
|
2090
|
-
const result =
|
|
2091
|
-
return
|
|
2092
|
-
} catch
|
|
1962
|
+
const result = await this.customer.refreshToken();
|
|
1963
|
+
return result.token ?? null;
|
|
1964
|
+
} catch {
|
|
2093
1965
|
return null;
|
|
2094
1966
|
}
|
|
2095
|
-
}
|
|
1967
|
+
};
|
|
2096
1968
|
this.cart = new CartApi({
|
|
2097
1969
|
clientKey: this.config.clientKey,
|
|
2098
1970
|
customerToken: () => this.customer.getToken(),
|
|
@@ -2116,10 +1988,10 @@ var Client = class {
|
|
|
2116
1988
|
return this.collections.from(collection);
|
|
2117
1989
|
}
|
|
2118
1990
|
getState() {
|
|
2119
|
-
return
|
|
1991
|
+
return { ...this.state };
|
|
2120
1992
|
}
|
|
2121
1993
|
getConfig() {
|
|
2122
|
-
return
|
|
1994
|
+
return { ...this.config };
|
|
2123
1995
|
}
|
|
2124
1996
|
};
|
|
2125
1997
|
function createClient(options) {
|
|
@@ -2140,7 +2012,7 @@ var ServerClient = class {
|
|
|
2140
2012
|
if (!options.secretKey) {
|
|
2141
2013
|
throw createConfigError("secretKey is required.");
|
|
2142
2014
|
}
|
|
2143
|
-
this.config =
|
|
2015
|
+
this.config = { ...options };
|
|
2144
2016
|
this.baseUrl = resolveApiUrl();
|
|
2145
2017
|
const metadata = {
|
|
2146
2018
|
timestamp: Date.now(),
|
|
@@ -2174,10 +2046,10 @@ var ServerClient = class {
|
|
|
2174
2046
|
return this.collections.from(collection);
|
|
2175
2047
|
}
|
|
2176
2048
|
getState() {
|
|
2177
|
-
return
|
|
2049
|
+
return { ...this.state };
|
|
2178
2050
|
}
|
|
2179
2051
|
getConfig() {
|
|
2180
|
-
const
|
|
2052
|
+
const { secretKey: _, ...safeConfig } = this.config;
|
|
2181
2053
|
return safeConfig;
|
|
2182
2054
|
}
|
|
2183
2055
|
};
|
|
@@ -2228,98 +2100,92 @@ var RealtimeConnection = class {
|
|
|
2228
2100
|
this.reconnectAttempt = 0;
|
|
2229
2101
|
this.noTokenAttempts = 0;
|
|
2230
2102
|
}
|
|
2231
|
-
startStream(signal) {
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
if (
|
|
2236
|
-
this.
|
|
2237
|
-
|
|
2238
|
-
this._connected = false;
|
|
2239
|
-
this.abortController = null;
|
|
2240
|
-
return;
|
|
2241
|
-
}
|
|
2242
|
-
this.scheduleReconnect();
|
|
2103
|
+
async startStream(signal) {
|
|
2104
|
+
const token = this.getToken();
|
|
2105
|
+
if (!token) {
|
|
2106
|
+
this.noTokenAttempts++;
|
|
2107
|
+
if (this.noTokenAttempts >= MAX_NO_TOKEN_RETRIES) {
|
|
2108
|
+
this._connected = false;
|
|
2109
|
+
this.abortController = null;
|
|
2243
2110
|
return;
|
|
2244
2111
|
}
|
|
2245
|
-
this.
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
if (!response.body) {
|
|
2264
|
-
throw new Error("SSE response has no body");
|
|
2112
|
+
this.scheduleReconnect();
|
|
2113
|
+
return;
|
|
2114
|
+
}
|
|
2115
|
+
this.noTokenAttempts = 0;
|
|
2116
|
+
const params = this.collections?.length ? `?collections=${this.collections.join(",")}` : "";
|
|
2117
|
+
const url = `${this.baseUrl}/api/events/stream${params}`;
|
|
2118
|
+
try {
|
|
2119
|
+
const response = await fetch(url, {
|
|
2120
|
+
headers: {
|
|
2121
|
+
"X-Client-Key": this.clientKey,
|
|
2122
|
+
Authorization: `Bearer ${token}`
|
|
2123
|
+
},
|
|
2124
|
+
signal
|
|
2125
|
+
});
|
|
2126
|
+
if (!response.ok) {
|
|
2127
|
+
if (response.status === 401) {
|
|
2128
|
+
this.scheduleReconnect();
|
|
2129
|
+
return;
|
|
2265
2130
|
}
|
|
2266
|
-
|
|
2267
|
-
this.reconnectAttempt = 0;
|
|
2268
|
-
yield this.readStream(response.body, signal);
|
|
2269
|
-
} catch (e) {
|
|
2270
|
-
if (signal.aborted) return;
|
|
2271
|
-
this._connected = false;
|
|
2272
|
-
this.scheduleReconnect();
|
|
2131
|
+
throw new Error(`SSE connection failed: ${response.status}`);
|
|
2273
2132
|
}
|
|
2274
|
-
|
|
2133
|
+
if (!response.body) {
|
|
2134
|
+
throw new Error("SSE response has no body");
|
|
2135
|
+
}
|
|
2136
|
+
this._connected = true;
|
|
2137
|
+
this.reconnectAttempt = 0;
|
|
2138
|
+
await this.readStream(response.body, signal);
|
|
2139
|
+
} catch {
|
|
2140
|
+
if (signal.aborted) return;
|
|
2141
|
+
this._connected = false;
|
|
2142
|
+
this.scheduleReconnect();
|
|
2143
|
+
}
|
|
2275
2144
|
}
|
|
2276
|
-
readStream(body, signal) {
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
listener(event);
|
|
2303
|
-
} catch (e) {
|
|
2304
|
-
}
|
|
2145
|
+
async readStream(body, signal) {
|
|
2146
|
+
const reader = body.getReader();
|
|
2147
|
+
const decoder = new TextDecoder();
|
|
2148
|
+
let buffer = "";
|
|
2149
|
+
let currentEvent = "";
|
|
2150
|
+
let currentData = "";
|
|
2151
|
+
try {
|
|
2152
|
+
while (true) {
|
|
2153
|
+
const { done, value } = await reader.read();
|
|
2154
|
+
if (done || signal.aborted) break;
|
|
2155
|
+
buffer += decoder.decode(value, { stream: true });
|
|
2156
|
+
const lines = buffer.split("\n");
|
|
2157
|
+
buffer = lines.pop() ?? "";
|
|
2158
|
+
for (const line of lines) {
|
|
2159
|
+
if (line.startsWith("event: ")) {
|
|
2160
|
+
currentEvent = line.slice(7);
|
|
2161
|
+
} else if (line.startsWith("data: ")) {
|
|
2162
|
+
currentData += (currentData ? "\n" : "") + line.slice(6);
|
|
2163
|
+
} else if (line === "") {
|
|
2164
|
+
if (currentEvent === "collection:change" && currentData) {
|
|
2165
|
+
try {
|
|
2166
|
+
const event = JSON.parse(currentData);
|
|
2167
|
+
for (const listener of this.listeners) {
|
|
2168
|
+
try {
|
|
2169
|
+
listener(event);
|
|
2170
|
+
} catch {
|
|
2305
2171
|
}
|
|
2306
|
-
} catch (e) {
|
|
2307
2172
|
}
|
|
2173
|
+
} catch {
|
|
2308
2174
|
}
|
|
2309
|
-
currentEvent = "";
|
|
2310
|
-
currentData = "";
|
|
2311
2175
|
}
|
|
2176
|
+
currentEvent = "";
|
|
2177
|
+
currentData = "";
|
|
2312
2178
|
}
|
|
2313
2179
|
}
|
|
2314
|
-
} catch (e) {
|
|
2315
|
-
} finally {
|
|
2316
|
-
reader.releaseLock();
|
|
2317
|
-
this._connected = false;
|
|
2318
|
-
if (!signal.aborted) {
|
|
2319
|
-
this.scheduleReconnect();
|
|
2320
|
-
}
|
|
2321
2180
|
}
|
|
2322
|
-
}
|
|
2181
|
+
} catch {
|
|
2182
|
+
} finally {
|
|
2183
|
+
reader.releaseLock();
|
|
2184
|
+
this._connected = false;
|
|
2185
|
+
if (!signal.aborted) {
|
|
2186
|
+
this.scheduleReconnect();
|
|
2187
|
+
}
|
|
2188
|
+
}
|
|
2323
2189
|
}
|
|
2324
2190
|
scheduleReconnect() {
|
|
2325
2191
|
if (this.reconnectTimer) return;
|
|
@@ -2342,91 +2208,85 @@ function isValidWebhookEvent(data) {
|
|
|
2342
2208
|
const obj = data;
|
|
2343
2209
|
return typeof obj.collection === "string" && (obj.operation === "create" || obj.operation === "update") && typeof obj.data === "object" && obj.data !== null;
|
|
2344
2210
|
}
|
|
2345
|
-
function verifySignature(payload, secret, signature) {
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
}
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
);
|
|
2362
|
-
return crypto.subtle.verify("HMAC", key, sigBytes, encoder.encode(payload));
|
|
2363
|
-
});
|
|
2211
|
+
async function verifySignature(payload, secret, signature) {
|
|
2212
|
+
const encoder = new TextEncoder();
|
|
2213
|
+
const key = await crypto.subtle.importKey(
|
|
2214
|
+
"raw",
|
|
2215
|
+
encoder.encode(secret),
|
|
2216
|
+
{ name: "HMAC", hash: "SHA-256" },
|
|
2217
|
+
false,
|
|
2218
|
+
["verify"]
|
|
2219
|
+
);
|
|
2220
|
+
if (signature.length % 2 !== 0 || !/^[0-9a-fA-F]*$/.test(signature)) {
|
|
2221
|
+
return false;
|
|
2222
|
+
}
|
|
2223
|
+
const sigBytes = new Uint8Array(
|
|
2224
|
+
(signature.match(/.{2}/g) ?? []).map((byte) => parseInt(byte, 16))
|
|
2225
|
+
);
|
|
2226
|
+
return crypto.subtle.verify("HMAC", key, sigBytes, encoder.encode(payload));
|
|
2364
2227
|
}
|
|
2365
|
-
function handleWebhook(request, handler, options) {
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
if (!valid) {
|
|
2373
|
-
return new Response(
|
|
2374
|
-
JSON.stringify({ error: "Invalid webhook signature" }),
|
|
2375
|
-
{ status: 401, headers: { "Content-Type": "application/json" } }
|
|
2376
|
-
);
|
|
2377
|
-
}
|
|
2378
|
-
} else {
|
|
2379
|
-
console.warn(
|
|
2380
|
-
"[@01.software/sdk] Webhook signature verification is disabled. Set { secret } in handleWebhook() options to enable HMAC-SHA256 verification."
|
|
2381
|
-
);
|
|
2382
|
-
}
|
|
2383
|
-
const body = JSON.parse(rawBody);
|
|
2384
|
-
if (!isValidWebhookEvent(body)) {
|
|
2228
|
+
async function handleWebhook(request, handler, options) {
|
|
2229
|
+
try {
|
|
2230
|
+
const rawBody = await request.text();
|
|
2231
|
+
if (options?.secret) {
|
|
2232
|
+
const signature = request.headers.get("x-webhook-signature") || "";
|
|
2233
|
+
const valid = await verifySignature(rawBody, options.secret, signature);
|
|
2234
|
+
if (!valid) {
|
|
2385
2235
|
return new Response(
|
|
2386
|
-
JSON.stringify({ error: "Invalid webhook
|
|
2387
|
-
{ status:
|
|
2236
|
+
JSON.stringify({ error: "Invalid webhook signature" }),
|
|
2237
|
+
{ status: 401, headers: { "Content-Type": "application/json" } }
|
|
2388
2238
|
);
|
|
2389
2239
|
}
|
|
2390
|
-
|
|
2240
|
+
} else {
|
|
2241
|
+
console.warn(
|
|
2242
|
+
"[@01.software/sdk] Webhook signature verification is disabled. Set { secret } in handleWebhook() options to enable HMAC-SHA256 verification."
|
|
2243
|
+
);
|
|
2244
|
+
}
|
|
2245
|
+
const body = JSON.parse(rawBody);
|
|
2246
|
+
if (!isValidWebhookEvent(body)) {
|
|
2391
2247
|
return new Response(
|
|
2392
|
-
JSON.stringify({
|
|
2393
|
-
{ status:
|
|
2248
|
+
JSON.stringify({ error: "Invalid webhook event format" }),
|
|
2249
|
+
{ status: 400, headers: { "Content-Type": "application/json" } }
|
|
2394
2250
|
);
|
|
2395
|
-
} catch (error) {
|
|
2396
|
-
console.error("Webhook processing error:", error);
|
|
2397
|
-
return new Response(JSON.stringify({ error: "Internal server error" }), {
|
|
2398
|
-
status: 500,
|
|
2399
|
-
headers: { "Content-Type": "application/json" }
|
|
2400
|
-
});
|
|
2401
2251
|
}
|
|
2402
|
-
|
|
2252
|
+
await handler(body);
|
|
2253
|
+
return new Response(
|
|
2254
|
+
JSON.stringify({ success: true, message: "Webhook processed" }),
|
|
2255
|
+
{ status: 200, headers: { "Content-Type": "application/json" } }
|
|
2256
|
+
);
|
|
2257
|
+
} catch (error) {
|
|
2258
|
+
console.error("Webhook processing error:", error);
|
|
2259
|
+
return new Response(JSON.stringify({ error: "Internal server error" }), {
|
|
2260
|
+
status: 500,
|
|
2261
|
+
headers: { "Content-Type": "application/json" }
|
|
2262
|
+
});
|
|
2263
|
+
}
|
|
2403
2264
|
}
|
|
2404
2265
|
function createTypedWebhookHandler(collection, handler) {
|
|
2405
|
-
return (event) =>
|
|
2266
|
+
return async (event) => {
|
|
2406
2267
|
if (event.collection !== collection) {
|
|
2407
2268
|
throw new Error(
|
|
2408
2269
|
`Expected collection "${collection}", got "${event.collection}"`
|
|
2409
2270
|
);
|
|
2410
2271
|
}
|
|
2411
2272
|
return handler(event);
|
|
2412
|
-
}
|
|
2273
|
+
};
|
|
2413
2274
|
}
|
|
2414
2275
|
|
|
2415
2276
|
// src/utils/image.ts
|
|
2416
2277
|
var IMAGE_SIZES = [384, 768, 1536];
|
|
2417
2278
|
function getImageUrl(image, displayWidth, dpr = 1) {
|
|
2418
|
-
var _a;
|
|
2419
2279
|
const target = displayWidth * dpr;
|
|
2420
2280
|
const sizes = image.sizes;
|
|
2421
2281
|
if (sizes) {
|
|
2422
2282
|
for (const size of IMAGE_SIZES) {
|
|
2423
2283
|
if (size >= target) {
|
|
2424
2284
|
const entry = sizes[String(size)];
|
|
2425
|
-
if (entry
|
|
2285
|
+
if (entry?.url) return entry.url;
|
|
2426
2286
|
}
|
|
2427
2287
|
}
|
|
2428
2288
|
}
|
|
2429
|
-
return
|
|
2289
|
+
return image.url ?? "";
|
|
2430
2290
|
}
|
|
2431
2291
|
function getImageSrcSet(image) {
|
|
2432
2292
|
const parts = [];
|
|
@@ -2434,7 +2294,7 @@ function getImageSrcSet(image) {
|
|
|
2434
2294
|
if (sizes) {
|
|
2435
2295
|
for (const size of IMAGE_SIZES) {
|
|
2436
2296
|
const entry = sizes[String(size)];
|
|
2437
|
-
if (
|
|
2297
|
+
if (entry?.url && entry.width) {
|
|
2438
2298
|
parts.push(`${entry.url} ${entry.width}w`);
|
|
2439
2299
|
}
|
|
2440
2300
|
}
|
|
@@ -2445,19 +2305,16 @@ function getImageSrcSet(image) {
|
|
|
2445
2305
|
return parts.join(", ");
|
|
2446
2306
|
}
|
|
2447
2307
|
function getImageLqip(image) {
|
|
2448
|
-
|
|
2449
|
-
return (_a = image.lqip) != null ? _a : void 0;
|
|
2308
|
+
return image.lqip ?? void 0;
|
|
2450
2309
|
}
|
|
2451
2310
|
function getImagePalette(image) {
|
|
2452
|
-
|
|
2453
|
-
return (_a = image.palette) != null ? _a : void 0;
|
|
2311
|
+
return image.palette ?? void 0;
|
|
2454
2312
|
}
|
|
2455
2313
|
function getImagePlaceholderStyle(image, options) {
|
|
2456
|
-
|
|
2457
|
-
const
|
|
2458
|
-
const paletteColor = (_b = options == null ? void 0 : options.paletteColor) != null ? _b : "muted";
|
|
2314
|
+
const type = options?.type ?? "blur";
|
|
2315
|
+
const paletteColor = options?.paletteColor ?? "muted";
|
|
2459
2316
|
if (type === "none") return {};
|
|
2460
|
-
const color =
|
|
2317
|
+
const color = image.palette?.[paletteColor];
|
|
2461
2318
|
if (type === "blur") {
|
|
2462
2319
|
const lqip = image.lqip;
|
|
2463
2320
|
if (lqip) {
|
|
@@ -2480,22 +2337,20 @@ function getImagePlaceholderStyle(image, options) {
|
|
|
2480
2337
|
|
|
2481
2338
|
// src/utils/order/generateOrderNumber.ts
|
|
2482
2339
|
var generateOrderNumber = () => {
|
|
2483
|
-
var _a;
|
|
2484
2340
|
const now = /* @__PURE__ */ new Date();
|
|
2485
2341
|
const year = now.getFullYear().toString().slice(-2);
|
|
2486
2342
|
const month = (now.getMonth() + 1).toString().padStart(2, "0");
|
|
2487
2343
|
const day = now.getDate().toString().padStart(2, "0");
|
|
2488
2344
|
const array = new Uint32Array(1);
|
|
2489
2345
|
globalThis.crypto.getRandomValues(array);
|
|
2490
|
-
const random = ((
|
|
2346
|
+
const random = ((array[0] ?? 0) % 1e6).toString().padStart(6, "0");
|
|
2491
2347
|
return `${year}${month}${day}${random}`;
|
|
2492
2348
|
};
|
|
2493
2349
|
|
|
2494
2350
|
// src/utils/order/formatOrderName.ts
|
|
2495
2351
|
var formatOrderName = (items) => {
|
|
2496
|
-
var _a, _b;
|
|
2497
2352
|
if (items.length === 0) return "";
|
|
2498
|
-
const firstTitle =
|
|
2353
|
+
const firstTitle = resolveRelation(items[0]?.product)?.title || "";
|
|
2499
2354
|
return items.length === 1 ? firstTitle : `${firstTitle} \uC678 ${items.length - 1}\uAC74`;
|
|
2500
2355
|
};
|
|
2501
2356
|
|
|
@@ -2503,24 +2358,22 @@ var formatOrderName = (items) => {
|
|
|
2503
2358
|
var MUX_IMAGE_BASE = "https://image.mux.com";
|
|
2504
2359
|
var MUX_STREAM_BASE = "https://stream.mux.com";
|
|
2505
2360
|
function getVideoThumbnail(playbackId, options) {
|
|
2506
|
-
var _a;
|
|
2507
2361
|
const params = new URLSearchParams();
|
|
2508
|
-
params.set("width", String(
|
|
2509
|
-
if (options
|
|
2510
|
-
if (
|
|
2511
|
-
if (options
|
|
2512
|
-
if (options
|
|
2513
|
-
if (options
|
|
2514
|
-
if (options
|
|
2362
|
+
params.set("width", String(options?.width ?? 640));
|
|
2363
|
+
if (options?.height) params.set("height", String(options.height));
|
|
2364
|
+
if (options?.time != null) params.set("time", String(options.time));
|
|
2365
|
+
if (options?.fitMode) params.set("fit_mode", options.fitMode);
|
|
2366
|
+
if (options?.flipH) params.set("flip_h", "true");
|
|
2367
|
+
if (options?.flipV) params.set("flip_v", "true");
|
|
2368
|
+
if (options?.rotate) params.set("rotate", String(options.rotate));
|
|
2515
2369
|
return `${MUX_IMAGE_BASE}/${playbackId}/thumbnail.jpg?${params}`;
|
|
2516
2370
|
}
|
|
2517
2371
|
function getVideoGif(playbackId, options) {
|
|
2518
|
-
var _a;
|
|
2519
2372
|
const params = new URLSearchParams();
|
|
2520
|
-
params.set("width", String(
|
|
2521
|
-
if (
|
|
2522
|
-
if (
|
|
2523
|
-
if (options
|
|
2373
|
+
params.set("width", String(options?.width ?? 320));
|
|
2374
|
+
if (options?.start != null) params.set("start", String(options.start));
|
|
2375
|
+
if (options?.end != null) params.set("end", String(options.end));
|
|
2376
|
+
if (options?.fps) params.set("fps", String(options.fps));
|
|
2524
2377
|
return `${MUX_IMAGE_BASE}/${playbackId}/animated.gif?${params}`;
|
|
2525
2378
|
}
|
|
2526
2379
|
function getVideoStoryboard(playbackId) {
|