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