@01.software/sdk 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +93 -7
- package/dist/{auth-DNaV-5wt.d.ts → auth-Cl6xQinU.d.cts} +12 -1
- package/dist/{auth-DMvniYSs.d.cts → auth-u5YEtV1J.d.ts} +12 -1
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.d.cts +2 -2
- package/dist/auth.d.ts +2 -2
- package/dist/auth.js.map +1 -1
- package/dist/index.cjs +817 -296
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +342 -46
- package/dist/index.d.ts +342 -46
- package/dist/index.js +817 -296
- package/dist/index.js.map +1 -1
- package/dist/metadata.cjs +70 -0
- package/dist/metadata.cjs.map +1 -0
- package/dist/metadata.d.cts +18 -0
- package/dist/metadata.d.ts +18 -0
- package/dist/metadata.js +50 -0
- package/dist/metadata.js.map +1 -0
- package/dist/{payload-types-BAZCcssT.d.cts → payload-types-9ZTBbiqb.d.cts} +864 -11
- package/dist/{payload-types-BAZCcssT.d.ts → payload-types-9ZTBbiqb.d.ts} +864 -11
- package/dist/{webhook-DdNkaI-f.d.cts → webhook-Cdv7bup2.d.cts} +2 -2
- package/dist/{webhook-CYJ0OPds.d.ts → webhook-c_A4J8UH.d.ts} +2 -2
- package/dist/webhook.cjs +6 -4
- package/dist/webhook.cjs.map +1 -1
- package/dist/webhook.d.cts +2 -2
- package/dist/webhook.d.ts +2 -2
- package/dist/webhook.js +6 -4
- package/dist/webhook.js.map +1 -1
- package/package.json +11 -1
package/dist/index.js
CHANGED
|
@@ -51,119 +51,8 @@ var __async = (__this, __arguments, generator) => {
|
|
|
51
51
|
});
|
|
52
52
|
};
|
|
53
53
|
|
|
54
|
-
// src/core/
|
|
55
|
-
|
|
56
|
-
constructor(api, collection) {
|
|
57
|
-
this.api = api;
|
|
58
|
-
this.collection = collection;
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Find documents (list query)
|
|
62
|
-
* GET /api/{collection}
|
|
63
|
-
* @returns Payload CMS find response with docs array and pagination
|
|
64
|
-
*/
|
|
65
|
-
find(options) {
|
|
66
|
-
return __async(this, null, function* () {
|
|
67
|
-
return this.api.requestFind(
|
|
68
|
-
`/api/${String(this.collection)}`,
|
|
69
|
-
options
|
|
70
|
-
);
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Find document by ID
|
|
75
|
-
* GET /api/{collection}/{id}
|
|
76
|
-
* @returns Document object directly (no wrapper)
|
|
77
|
-
*/
|
|
78
|
-
findById(id, options) {
|
|
79
|
-
return __async(this, null, function* () {
|
|
80
|
-
return this.api.requestFindById(
|
|
81
|
-
`/api/${String(this.collection)}/${String(id)}`,
|
|
82
|
-
options
|
|
83
|
-
);
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Create a new document
|
|
88
|
-
* POST /api/{collection}
|
|
89
|
-
* @returns Payload CMS mutation response with doc and message
|
|
90
|
-
*/
|
|
91
|
-
create(data) {
|
|
92
|
-
return __async(this, null, function* () {
|
|
93
|
-
return this.api.requestCreate(
|
|
94
|
-
`/api/${String(this.collection)}`,
|
|
95
|
-
data
|
|
96
|
-
);
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Update a document by ID
|
|
101
|
-
* PATCH /api/{collection}/{id}
|
|
102
|
-
* @returns Payload CMS mutation response with doc and message
|
|
103
|
-
*/
|
|
104
|
-
update(id, data) {
|
|
105
|
-
return __async(this, null, function* () {
|
|
106
|
-
return this.api.requestUpdate(
|
|
107
|
-
`/api/${String(this.collection)}/${String(id)}`,
|
|
108
|
-
data
|
|
109
|
-
);
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Count documents
|
|
114
|
-
* GET /api/{collection}/count
|
|
115
|
-
* @returns Count response with totalDocs
|
|
116
|
-
*/
|
|
117
|
-
count(options) {
|
|
118
|
-
return __async(this, null, function* () {
|
|
119
|
-
return this.api.requestCount(
|
|
120
|
-
`/api/${String(this.collection)}/count`,
|
|
121
|
-
options
|
|
122
|
-
);
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Update multiple documents (bulk update)
|
|
127
|
-
* PATCH /api/{collection}
|
|
128
|
-
* @returns Payload CMS find response with updated docs
|
|
129
|
-
*/
|
|
130
|
-
updateMany(where, data) {
|
|
131
|
-
return __async(this, null, function* () {
|
|
132
|
-
return this.api.requestUpdateMany(
|
|
133
|
-
`/api/${String(this.collection)}`,
|
|
134
|
-
{ where, data }
|
|
135
|
-
);
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Delete a document by ID
|
|
140
|
-
* DELETE /api/{collection}/{id}
|
|
141
|
-
* @returns Deleted document object directly (no wrapper)
|
|
142
|
-
*/
|
|
143
|
-
remove(id) {
|
|
144
|
-
return __async(this, null, function* () {
|
|
145
|
-
return this.api.requestDelete(
|
|
146
|
-
`/api/${String(this.collection)}/${String(id)}`
|
|
147
|
-
);
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Delete multiple documents (bulk delete)
|
|
152
|
-
* DELETE /api/{collection}
|
|
153
|
-
* @returns Payload CMS find response with deleted docs
|
|
154
|
-
*/
|
|
155
|
-
removeMany(where) {
|
|
156
|
-
return __async(this, null, function* () {
|
|
157
|
-
return this.api.requestDeleteMany(
|
|
158
|
-
`/api/${String(this.collection)}`,
|
|
159
|
-
{ where }
|
|
160
|
-
);
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
// src/core/collection/http-client.ts
|
|
166
|
-
import { stringify } from "qs-esm";
|
|
54
|
+
// src/core/internal/utils/index.ts
|
|
55
|
+
import { SignJWT, jwtVerify, decodeJwt } from "jose";
|
|
167
56
|
|
|
168
57
|
// src/core/internal/errors/index.ts
|
|
169
58
|
var SDKError = class _SDKError extends Error {
|
|
@@ -264,112 +153,6 @@ var createConfigError = (message, details, userMessage, suggestion) => new Confi
|
|
|
264
153
|
var createTimeoutError = (message, details, userMessage, suggestion) => new TimeoutError(message, details, userMessage, suggestion);
|
|
265
154
|
var createUsageLimitError = (message, usage, details, userMessage, suggestion) => new UsageLimitError(message, usage, details, userMessage, suggestion);
|
|
266
155
|
|
|
267
|
-
// src/core/collection/http-client.ts
|
|
268
|
-
var HttpClient = class {
|
|
269
|
-
constructor(clientKey, secretKey, baseUrl) {
|
|
270
|
-
if (!clientKey) {
|
|
271
|
-
throw createValidationError("clientKey is required.");
|
|
272
|
-
}
|
|
273
|
-
this.clientKey = clientKey;
|
|
274
|
-
this.secretKey = secretKey;
|
|
275
|
-
this.baseUrl = baseUrl;
|
|
276
|
-
this.defaultOptions = { clientKey, secretKey, baseUrl };
|
|
277
|
-
}
|
|
278
|
-
buildUrl(endpoint, options) {
|
|
279
|
-
if (!options) return endpoint;
|
|
280
|
-
const queryString = stringify(options, { addQueryPrefix: true });
|
|
281
|
-
return queryString ? `${endpoint}${queryString}` : endpoint;
|
|
282
|
-
}
|
|
283
|
-
assertJsonResponse(response) {
|
|
284
|
-
const contentType = response.headers.get("content-type");
|
|
285
|
-
if (!(contentType == null ? void 0 : contentType.includes("application/json"))) {
|
|
286
|
-
throw createApiError("Response is not in JSON format.", response.status, { contentType });
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
/**
|
|
290
|
-
* Parse Payload CMS find response (list query)
|
|
291
|
-
* Returns native Payload response structure
|
|
292
|
-
*/
|
|
293
|
-
parseFindResponse(response) {
|
|
294
|
-
return __async(this, null, function* () {
|
|
295
|
-
var _a, _b;
|
|
296
|
-
const contentType = response.headers.get("content-type");
|
|
297
|
-
try {
|
|
298
|
-
this.assertJsonResponse(response);
|
|
299
|
-
const jsonData = yield response.json();
|
|
300
|
-
if (jsonData.docs === void 0) {
|
|
301
|
-
throw createApiError("Invalid find response.", response.status, { jsonData });
|
|
302
|
-
}
|
|
303
|
-
return {
|
|
304
|
-
docs: jsonData.docs,
|
|
305
|
-
totalDocs: jsonData.totalDocs || 0,
|
|
306
|
-
limit: jsonData.limit || 20,
|
|
307
|
-
totalPages: jsonData.totalPages || 0,
|
|
308
|
-
page: jsonData.page || 1,
|
|
309
|
-
pagingCounter: jsonData.pagingCounter || 1,
|
|
310
|
-
hasPrevPage: jsonData.hasPrevPage || false,
|
|
311
|
-
hasNextPage: jsonData.hasNextPage || false,
|
|
312
|
-
prevPage: (_a = jsonData.prevPage) != null ? _a : null,
|
|
313
|
-
nextPage: (_b = jsonData.nextPage) != null ? _b : null
|
|
314
|
-
};
|
|
315
|
-
} catch (error) {
|
|
316
|
-
throw createApiError("Failed to parse response.", response.status, {
|
|
317
|
-
contentType,
|
|
318
|
-
error: error instanceof Error ? error.message : error
|
|
319
|
-
});
|
|
320
|
-
}
|
|
321
|
-
});
|
|
322
|
-
}
|
|
323
|
-
/**
|
|
324
|
-
* Parse Payload CMS mutation response (create/update)
|
|
325
|
-
* Returns native Payload response structure
|
|
326
|
-
*/
|
|
327
|
-
parseMutationResponse(response) {
|
|
328
|
-
return __async(this, null, function* () {
|
|
329
|
-
const contentType = response.headers.get("content-type");
|
|
330
|
-
try {
|
|
331
|
-
this.assertJsonResponse(response);
|
|
332
|
-
const jsonData = yield response.json();
|
|
333
|
-
if (jsonData.doc === void 0) {
|
|
334
|
-
throw createApiError("Invalid mutation response.", response.status, { jsonData });
|
|
335
|
-
}
|
|
336
|
-
return {
|
|
337
|
-
message: jsonData.message || "",
|
|
338
|
-
doc: jsonData.doc,
|
|
339
|
-
errors: jsonData.errors
|
|
340
|
-
};
|
|
341
|
-
} catch (error) {
|
|
342
|
-
throw createApiError("Failed to parse response.", response.status, {
|
|
343
|
-
contentType,
|
|
344
|
-
error: error instanceof Error ? error.message : error
|
|
345
|
-
});
|
|
346
|
-
}
|
|
347
|
-
});
|
|
348
|
-
}
|
|
349
|
-
/**
|
|
350
|
-
* Parse Payload CMS document response (findById/delete)
|
|
351
|
-
* Returns document directly without wrapper
|
|
352
|
-
*/
|
|
353
|
-
parseDocumentResponse(response) {
|
|
354
|
-
return __async(this, null, function* () {
|
|
355
|
-
const contentType = response.headers.get("content-type");
|
|
356
|
-
try {
|
|
357
|
-
this.assertJsonResponse(response);
|
|
358
|
-
const jsonData = yield response.json();
|
|
359
|
-
return jsonData;
|
|
360
|
-
} catch (error) {
|
|
361
|
-
throw createApiError("Failed to parse response.", response.status, {
|
|
362
|
-
contentType,
|
|
363
|
-
error: error instanceof Error ? error.message : error
|
|
364
|
-
});
|
|
365
|
-
}
|
|
366
|
-
});
|
|
367
|
-
}
|
|
368
|
-
};
|
|
369
|
-
|
|
370
|
-
// src/core/internal/utils/index.ts
|
|
371
|
-
import { SignJWT, jwtVerify, decodeJwt } from "jose";
|
|
372
|
-
|
|
373
156
|
// src/core/client/types.ts
|
|
374
157
|
var API_URLS = {
|
|
375
158
|
local: "http://localhost:3000",
|
|
@@ -395,6 +178,7 @@ function resolveApiUrl(config) {
|
|
|
395
178
|
var DEFAULT_TIMEOUT = 3e4;
|
|
396
179
|
var DEFAULT_RETRYABLE_STATUSES = [408, 429, 500, 502, 503, 504];
|
|
397
180
|
var NON_RETRYABLE_STATUSES = [401, 403, 404, 422];
|
|
181
|
+
var SAFE_METHODS = ["GET", "HEAD", "OPTIONS"];
|
|
398
182
|
function createServerToken(clientKey, secretKey, expiresIn = "1h") {
|
|
399
183
|
return __async(this, null, function* () {
|
|
400
184
|
if (!clientKey || !secretKey) {
|
|
@@ -498,6 +282,7 @@ function _fetch(url, options) {
|
|
|
498
282
|
const _a = options || {}, {
|
|
499
283
|
clientKey,
|
|
500
284
|
secretKey,
|
|
285
|
+
customerToken,
|
|
501
286
|
timeout = DEFAULT_TIMEOUT,
|
|
502
287
|
baseUrl = API_URLS.production,
|
|
503
288
|
debug,
|
|
@@ -505,6 +290,7 @@ function _fetch(url, options) {
|
|
|
505
290
|
} = _a, requestInit = __objRest(_a, [
|
|
506
291
|
"clientKey",
|
|
507
292
|
"secretKey",
|
|
293
|
+
"customerToken",
|
|
508
294
|
"timeout",
|
|
509
295
|
"baseUrl",
|
|
510
296
|
"debug",
|
|
@@ -518,6 +304,8 @@ function _fetch(url, options) {
|
|
|
518
304
|
let authToken;
|
|
519
305
|
if (secretKey && clientKey) {
|
|
520
306
|
authToken = yield createServerToken(clientKey, secretKey);
|
|
307
|
+
} else if (customerToken) {
|
|
308
|
+
authToken = customerToken;
|
|
521
309
|
}
|
|
522
310
|
let lastError;
|
|
523
311
|
for (let attempt = 0; attempt <= retryConfig.maxRetries; attempt++) {
|
|
@@ -532,9 +320,14 @@ function _fetch(url, options) {
|
|
|
532
320
|
if (!headers.has("Content-Type") && requestInit.body) {
|
|
533
321
|
headers.set("Content-Type", "application/json");
|
|
534
322
|
}
|
|
323
|
+
const redactedHeaders = Object.fromEntries(headers.entries());
|
|
324
|
+
if (redactedHeaders["authorization"]) {
|
|
325
|
+
const token = redactedHeaders["authorization"];
|
|
326
|
+
redactedHeaders["authorization"] = token.length > 15 ? `${token.slice(0, 15)}...****` : "****";
|
|
327
|
+
}
|
|
535
328
|
debugLog(debug, "request", url, {
|
|
536
329
|
method: requestInit.method || "GET",
|
|
537
|
-
headers:
|
|
330
|
+
headers: redactedHeaders,
|
|
538
331
|
attempt: attempt + 1
|
|
539
332
|
});
|
|
540
333
|
const controller = new AbortController();
|
|
@@ -578,7 +371,8 @@ function _fetch(url, options) {
|
|
|
578
371
|
`Request failed (status: ${response.status})`,
|
|
579
372
|
getErrorSuggestion(response.status)
|
|
580
373
|
);
|
|
581
|
-
|
|
374
|
+
const method = (requestInit.method || "GET").toUpperCase();
|
|
375
|
+
if (attempt < retryConfig.maxRetries && SAFE_METHODS.includes(method) && retryConfig.retryableStatuses.includes(response.status)) {
|
|
582
376
|
lastError = error;
|
|
583
377
|
const retryDelay = retryConfig.retryDelay(attempt);
|
|
584
378
|
debugLog(debug, "error", `Retrying in ${retryDelay}ms...`, error);
|
|
@@ -590,6 +384,8 @@ function _fetch(url, options) {
|
|
|
590
384
|
return response;
|
|
591
385
|
} catch (error) {
|
|
592
386
|
debugLog(debug, "error", url, error);
|
|
387
|
+
const method = (requestInit.method || "GET").toUpperCase();
|
|
388
|
+
const isSafe = SAFE_METHODS.includes(method);
|
|
593
389
|
if (error instanceof Error && error.name === "AbortError") {
|
|
594
390
|
const timeoutError = createTimeoutError(
|
|
595
391
|
`Request timed out after ${timeout}ms.`,
|
|
@@ -597,7 +393,7 @@ function _fetch(url, options) {
|
|
|
597
393
|
"The request timed out.",
|
|
598
394
|
"Please check your network connection or try again later."
|
|
599
395
|
);
|
|
600
|
-
if (attempt < retryConfig.maxRetries) {
|
|
396
|
+
if (isSafe && attempt < retryConfig.maxRetries) {
|
|
601
397
|
lastError = timeoutError;
|
|
602
398
|
yield delay(retryConfig.retryDelay(attempt));
|
|
603
399
|
continue;
|
|
@@ -612,7 +408,7 @@ function _fetch(url, options) {
|
|
|
612
408
|
"Network connection failed.",
|
|
613
409
|
"Please check your internet connection and try again."
|
|
614
410
|
);
|
|
615
|
-
if (attempt < retryConfig.maxRetries) {
|
|
411
|
+
if (isSafe && attempt < retryConfig.maxRetries) {
|
|
616
412
|
lastError = networkError;
|
|
617
413
|
yield delay(retryConfig.retryDelay(attempt));
|
|
618
414
|
continue;
|
|
@@ -620,7 +416,7 @@ function _fetch(url, options) {
|
|
|
620
416
|
throw networkError;
|
|
621
417
|
}
|
|
622
418
|
if (error instanceof NetworkError || error instanceof TimeoutError) {
|
|
623
|
-
if (attempt < retryConfig.maxRetries && error.status && !NON_RETRYABLE_STATUSES.includes(error.status) && retryConfig.retryableStatuses.includes(error.status)) {
|
|
419
|
+
if (isSafe && attempt < retryConfig.maxRetries && error.status && !NON_RETRYABLE_STATUSES.includes(error.status) && retryConfig.retryableStatuses.includes(error.status)) {
|
|
624
420
|
lastError = error;
|
|
625
421
|
yield delay(retryConfig.retryDelay(attempt));
|
|
626
422
|
continue;
|
|
@@ -634,7 +430,7 @@ function _fetch(url, options) {
|
|
|
634
430
|
"An unknown error occurred.",
|
|
635
431
|
"Please try again later."
|
|
636
432
|
);
|
|
637
|
-
if (attempt < retryConfig.maxRetries) {
|
|
433
|
+
if (isSafe && attempt < retryConfig.maxRetries) {
|
|
638
434
|
lastError = unknownError;
|
|
639
435
|
yield delay(retryConfig.retryDelay(attempt));
|
|
640
436
|
continue;
|
|
@@ -642,14 +438,427 @@ function _fetch(url, options) {
|
|
|
642
438
|
throw unknownError;
|
|
643
439
|
}
|
|
644
440
|
}
|
|
645
|
-
throw lastError;
|
|
441
|
+
throw lastError != null ? lastError : new NetworkError("Request failed after retries");
|
|
646
442
|
});
|
|
647
443
|
}
|
|
648
444
|
|
|
445
|
+
// src/core/api/order-api.ts
|
|
446
|
+
var OrderApi = class {
|
|
447
|
+
constructor(options) {
|
|
448
|
+
if (!options.clientKey) {
|
|
449
|
+
throw createConfigError("clientKey is required for OrderApi.");
|
|
450
|
+
}
|
|
451
|
+
if (!options.secretKey) {
|
|
452
|
+
throw createConfigError("secretKey is required for OrderApi.");
|
|
453
|
+
}
|
|
454
|
+
this.clientKey = options.clientKey;
|
|
455
|
+
this.secretKey = options.secretKey;
|
|
456
|
+
this.baseUrl = options.baseUrl;
|
|
457
|
+
}
|
|
458
|
+
request(endpoint, body) {
|
|
459
|
+
return __async(this, null, function* () {
|
|
460
|
+
const response = yield _fetch(endpoint, {
|
|
461
|
+
method: "POST",
|
|
462
|
+
clientKey: this.clientKey,
|
|
463
|
+
secretKey: this.secretKey,
|
|
464
|
+
baseUrl: this.baseUrl,
|
|
465
|
+
body: JSON.stringify(body)
|
|
466
|
+
});
|
|
467
|
+
let data;
|
|
468
|
+
try {
|
|
469
|
+
data = yield response.json();
|
|
470
|
+
} catch (e) {
|
|
471
|
+
throw createApiError(
|
|
472
|
+
`Invalid JSON response from ${endpoint}`,
|
|
473
|
+
response.status,
|
|
474
|
+
void 0,
|
|
475
|
+
"Server returned an invalid response.",
|
|
476
|
+
"Check if the API endpoint is available."
|
|
477
|
+
);
|
|
478
|
+
}
|
|
479
|
+
if (data.error) {
|
|
480
|
+
const errorMessage = typeof data.error === "string" ? data.error : "Unknown API error";
|
|
481
|
+
throw createApiError(
|
|
482
|
+
errorMessage,
|
|
483
|
+
response.status,
|
|
484
|
+
data,
|
|
485
|
+
errorMessage,
|
|
486
|
+
"An error occurred while processing the request."
|
|
487
|
+
);
|
|
488
|
+
}
|
|
489
|
+
return data;
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
createOrder(params) {
|
|
493
|
+
return this.request("/api/orders/create", params);
|
|
494
|
+
}
|
|
495
|
+
updateOrder(params) {
|
|
496
|
+
return this.request("/api/orders/update", params);
|
|
497
|
+
}
|
|
498
|
+
getOrder(params) {
|
|
499
|
+
return this.request("/api/orders/get", params);
|
|
500
|
+
}
|
|
501
|
+
updateTransaction(params) {
|
|
502
|
+
return this.request("/api/transactions/update", params);
|
|
503
|
+
}
|
|
504
|
+
checkout(params) {
|
|
505
|
+
return this.request("/api/orders/checkout", params);
|
|
506
|
+
}
|
|
507
|
+
createFulfillment(params) {
|
|
508
|
+
return this.request("/api/orders/create-fulfillment", params);
|
|
509
|
+
}
|
|
510
|
+
returnWithRefund(params) {
|
|
511
|
+
return this.request("/api/returns/return-refund", params);
|
|
512
|
+
}
|
|
513
|
+
createReturn(params) {
|
|
514
|
+
return this.request("/api/returns/create", params);
|
|
515
|
+
}
|
|
516
|
+
updateReturn(params) {
|
|
517
|
+
return this.request("/api/returns/update", params);
|
|
518
|
+
}
|
|
519
|
+
};
|
|
520
|
+
|
|
521
|
+
// src/core/api/cart-api.ts
|
|
522
|
+
var CartApi = class {
|
|
523
|
+
constructor(options) {
|
|
524
|
+
if (!options.clientKey) {
|
|
525
|
+
throw createConfigError("clientKey is required for CartApi.");
|
|
526
|
+
}
|
|
527
|
+
if (!options.secretKey && !options.customerToken) {
|
|
528
|
+
throw createConfigError("Either secretKey or customerToken is required for CartApi.");
|
|
529
|
+
}
|
|
530
|
+
this.clientKey = options.clientKey;
|
|
531
|
+
this.secretKey = options.secretKey;
|
|
532
|
+
this.customerToken = options.customerToken;
|
|
533
|
+
this.baseUrl = options.baseUrl;
|
|
534
|
+
}
|
|
535
|
+
request(endpoint, body) {
|
|
536
|
+
return __async(this, null, function* () {
|
|
537
|
+
const token = typeof this.customerToken === "function" ? this.customerToken() : this.customerToken;
|
|
538
|
+
const response = yield _fetch(endpoint, {
|
|
539
|
+
method: "POST",
|
|
540
|
+
clientKey: this.clientKey,
|
|
541
|
+
secretKey: this.secretKey,
|
|
542
|
+
customerToken: token != null ? token : void 0,
|
|
543
|
+
baseUrl: this.baseUrl,
|
|
544
|
+
body: JSON.stringify(body)
|
|
545
|
+
});
|
|
546
|
+
let data;
|
|
547
|
+
try {
|
|
548
|
+
data = yield response.json();
|
|
549
|
+
} catch (e) {
|
|
550
|
+
throw createApiError(
|
|
551
|
+
`Invalid JSON response from ${endpoint}`,
|
|
552
|
+
response.status,
|
|
553
|
+
void 0,
|
|
554
|
+
"Server returned an invalid response.",
|
|
555
|
+
"Check if the API endpoint is available."
|
|
556
|
+
);
|
|
557
|
+
}
|
|
558
|
+
if (data.error) {
|
|
559
|
+
const errorMessage = typeof data.error === "string" ? data.error : "Unknown API error";
|
|
560
|
+
throw createApiError(
|
|
561
|
+
errorMessage,
|
|
562
|
+
response.status,
|
|
563
|
+
data,
|
|
564
|
+
errorMessage,
|
|
565
|
+
"An error occurred while processing the request."
|
|
566
|
+
);
|
|
567
|
+
}
|
|
568
|
+
return data;
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
addItem(params) {
|
|
572
|
+
return this.request("/api/carts/add-item", params);
|
|
573
|
+
}
|
|
574
|
+
updateItem(params) {
|
|
575
|
+
return this.request("/api/carts/update-item", params);
|
|
576
|
+
}
|
|
577
|
+
removeItem(params) {
|
|
578
|
+
return this.request("/api/carts/remove-item", params);
|
|
579
|
+
}
|
|
580
|
+
};
|
|
581
|
+
|
|
582
|
+
// src/core/api/product-api.ts
|
|
583
|
+
var ProductApi = class {
|
|
584
|
+
constructor(options) {
|
|
585
|
+
if (!options.clientKey) {
|
|
586
|
+
throw createConfigError("clientKey is required for ProductApi.");
|
|
587
|
+
}
|
|
588
|
+
if (!options.secretKey) {
|
|
589
|
+
throw createConfigError("secretKey is required for ProductApi.");
|
|
590
|
+
}
|
|
591
|
+
this.clientKey = options.clientKey;
|
|
592
|
+
this.secretKey = options.secretKey;
|
|
593
|
+
this.baseUrl = options.baseUrl;
|
|
594
|
+
}
|
|
595
|
+
request(endpoint, body) {
|
|
596
|
+
return __async(this, null, function* () {
|
|
597
|
+
const response = yield _fetch(endpoint, {
|
|
598
|
+
method: "POST",
|
|
599
|
+
clientKey: this.clientKey,
|
|
600
|
+
secretKey: this.secretKey,
|
|
601
|
+
baseUrl: this.baseUrl,
|
|
602
|
+
body: JSON.stringify(body)
|
|
603
|
+
});
|
|
604
|
+
let data;
|
|
605
|
+
try {
|
|
606
|
+
data = yield response.json();
|
|
607
|
+
} catch (e) {
|
|
608
|
+
throw createApiError(
|
|
609
|
+
`Invalid JSON response from ${endpoint}`,
|
|
610
|
+
response.status,
|
|
611
|
+
void 0,
|
|
612
|
+
"Server returned an invalid response.",
|
|
613
|
+
"Check if the API endpoint is available."
|
|
614
|
+
);
|
|
615
|
+
}
|
|
616
|
+
if (data.error) {
|
|
617
|
+
const errorMessage = typeof data.error === "string" ? data.error : "Unknown API error";
|
|
618
|
+
throw createApiError(
|
|
619
|
+
errorMessage,
|
|
620
|
+
response.status,
|
|
621
|
+
data,
|
|
622
|
+
errorMessage,
|
|
623
|
+
"An error occurred while processing the request."
|
|
624
|
+
);
|
|
625
|
+
}
|
|
626
|
+
return data;
|
|
627
|
+
});
|
|
628
|
+
}
|
|
629
|
+
stockCheck(params) {
|
|
630
|
+
return this.request("/api/products/stock-check", params);
|
|
631
|
+
}
|
|
632
|
+
};
|
|
633
|
+
|
|
634
|
+
// src/core/collection/query-builder.ts
|
|
635
|
+
var CollectionQueryBuilder = class {
|
|
636
|
+
constructor(api, collection) {
|
|
637
|
+
this.api = api;
|
|
638
|
+
this.collection = collection;
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Find documents (list query)
|
|
642
|
+
* GET /api/{collection}
|
|
643
|
+
* @returns Payload CMS find response with docs array and pagination
|
|
644
|
+
*/
|
|
645
|
+
find(options) {
|
|
646
|
+
return __async(this, null, function* () {
|
|
647
|
+
return this.api.requestFind(
|
|
648
|
+
`/api/${String(this.collection)}`,
|
|
649
|
+
options
|
|
650
|
+
);
|
|
651
|
+
});
|
|
652
|
+
}
|
|
653
|
+
/**
|
|
654
|
+
* Find document by ID
|
|
655
|
+
* GET /api/{collection}/{id}
|
|
656
|
+
* @returns Document object directly (no wrapper)
|
|
657
|
+
*/
|
|
658
|
+
findById(id, options) {
|
|
659
|
+
return __async(this, null, function* () {
|
|
660
|
+
return this.api.requestFindById(
|
|
661
|
+
`/api/${String(this.collection)}/${String(id)}`,
|
|
662
|
+
options
|
|
663
|
+
);
|
|
664
|
+
});
|
|
665
|
+
}
|
|
666
|
+
/**
|
|
667
|
+
* Create a new document
|
|
668
|
+
* POST /api/{collection}
|
|
669
|
+
* @returns Payload CMS mutation response with doc and message
|
|
670
|
+
*/
|
|
671
|
+
create(data) {
|
|
672
|
+
return __async(this, null, function* () {
|
|
673
|
+
return this.api.requestCreate(
|
|
674
|
+
`/api/${String(this.collection)}`,
|
|
675
|
+
data
|
|
676
|
+
);
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
/**
|
|
680
|
+
* Update a document by ID
|
|
681
|
+
* PATCH /api/{collection}/{id}
|
|
682
|
+
* @returns Payload CMS mutation response with doc and message
|
|
683
|
+
*/
|
|
684
|
+
update(id, data) {
|
|
685
|
+
return __async(this, null, function* () {
|
|
686
|
+
return this.api.requestUpdate(
|
|
687
|
+
`/api/${String(this.collection)}/${String(id)}`,
|
|
688
|
+
data
|
|
689
|
+
);
|
|
690
|
+
});
|
|
691
|
+
}
|
|
692
|
+
/**
|
|
693
|
+
* Count documents
|
|
694
|
+
* GET /api/{collection}/count
|
|
695
|
+
* @returns Count response with totalDocs
|
|
696
|
+
*/
|
|
697
|
+
count(options) {
|
|
698
|
+
return __async(this, null, function* () {
|
|
699
|
+
return this.api.requestCount(
|
|
700
|
+
`/api/${String(this.collection)}/count`,
|
|
701
|
+
options
|
|
702
|
+
);
|
|
703
|
+
});
|
|
704
|
+
}
|
|
705
|
+
/**
|
|
706
|
+
* Update multiple documents (bulk update)
|
|
707
|
+
* PATCH /api/{collection}
|
|
708
|
+
* @returns Payload CMS find response with updated docs
|
|
709
|
+
*/
|
|
710
|
+
updateMany(where, data) {
|
|
711
|
+
return __async(this, null, function* () {
|
|
712
|
+
return this.api.requestUpdateMany(
|
|
713
|
+
`/api/${String(this.collection)}`,
|
|
714
|
+
{ where, data }
|
|
715
|
+
);
|
|
716
|
+
});
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Delete a document by ID
|
|
720
|
+
* DELETE /api/{collection}/{id}
|
|
721
|
+
* @returns Deleted document object directly (no wrapper)
|
|
722
|
+
*/
|
|
723
|
+
remove(id) {
|
|
724
|
+
return __async(this, null, function* () {
|
|
725
|
+
return this.api.requestDelete(
|
|
726
|
+
`/api/${String(this.collection)}/${String(id)}`
|
|
727
|
+
);
|
|
728
|
+
});
|
|
729
|
+
}
|
|
730
|
+
/**
|
|
731
|
+
* Delete multiple documents (bulk delete)
|
|
732
|
+
* DELETE /api/{collection}
|
|
733
|
+
* @returns Payload CMS find response with deleted docs
|
|
734
|
+
*/
|
|
735
|
+
removeMany(where) {
|
|
736
|
+
return __async(this, null, function* () {
|
|
737
|
+
return this.api.requestDeleteMany(
|
|
738
|
+
`/api/${String(this.collection)}`,
|
|
739
|
+
{ where }
|
|
740
|
+
);
|
|
741
|
+
});
|
|
742
|
+
}
|
|
743
|
+
};
|
|
744
|
+
|
|
745
|
+
// src/core/collection/http-client.ts
|
|
746
|
+
import { stringify } from "qs-esm";
|
|
747
|
+
var HttpClient = class {
|
|
748
|
+
constructor(clientKey, secretKey, baseUrl, getCustomerToken) {
|
|
749
|
+
if (!clientKey) {
|
|
750
|
+
throw createValidationError("clientKey is required.");
|
|
751
|
+
}
|
|
752
|
+
this.clientKey = clientKey;
|
|
753
|
+
this.secretKey = secretKey;
|
|
754
|
+
this.baseUrl = baseUrl;
|
|
755
|
+
this.getCustomerToken = getCustomerToken;
|
|
756
|
+
}
|
|
757
|
+
get defaultOptions() {
|
|
758
|
+
var _a;
|
|
759
|
+
const opts = { clientKey: this.clientKey, secretKey: this.secretKey, baseUrl: this.baseUrl };
|
|
760
|
+
const token = (_a = this.getCustomerToken) == null ? void 0 : _a.call(this);
|
|
761
|
+
if (token) {
|
|
762
|
+
opts.customerToken = token;
|
|
763
|
+
}
|
|
764
|
+
return opts;
|
|
765
|
+
}
|
|
766
|
+
buildUrl(endpoint, options) {
|
|
767
|
+
if (!options) return endpoint;
|
|
768
|
+
const queryString = stringify(options, { addQueryPrefix: true });
|
|
769
|
+
return queryString ? `${endpoint}${queryString}` : endpoint;
|
|
770
|
+
}
|
|
771
|
+
assertJsonResponse(response) {
|
|
772
|
+
const contentType = response.headers.get("content-type");
|
|
773
|
+
if (!(contentType == null ? void 0 : contentType.includes("application/json"))) {
|
|
774
|
+
throw createApiError("Response is not in JSON format.", response.status, { contentType });
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
/**
|
|
778
|
+
* Parse Payload CMS find response (list query)
|
|
779
|
+
* Returns native Payload response structure
|
|
780
|
+
*/
|
|
781
|
+
parseFindResponse(response) {
|
|
782
|
+
return __async(this, null, function* () {
|
|
783
|
+
var _a, _b;
|
|
784
|
+
const contentType = response.headers.get("content-type");
|
|
785
|
+
try {
|
|
786
|
+
this.assertJsonResponse(response);
|
|
787
|
+
const jsonData = yield response.json();
|
|
788
|
+
if (jsonData.docs === void 0) {
|
|
789
|
+
throw createApiError("Invalid find response.", response.status, { jsonData });
|
|
790
|
+
}
|
|
791
|
+
return {
|
|
792
|
+
docs: jsonData.docs,
|
|
793
|
+
totalDocs: jsonData.totalDocs || 0,
|
|
794
|
+
limit: jsonData.limit || 20,
|
|
795
|
+
totalPages: jsonData.totalPages || 0,
|
|
796
|
+
page: jsonData.page || 1,
|
|
797
|
+
pagingCounter: jsonData.pagingCounter || 1,
|
|
798
|
+
hasPrevPage: jsonData.hasPrevPage || false,
|
|
799
|
+
hasNextPage: jsonData.hasNextPage || false,
|
|
800
|
+
prevPage: (_a = jsonData.prevPage) != null ? _a : null,
|
|
801
|
+
nextPage: (_b = jsonData.nextPage) != null ? _b : null
|
|
802
|
+
};
|
|
803
|
+
} catch (error) {
|
|
804
|
+
throw createApiError("Failed to parse response.", response.status, {
|
|
805
|
+
contentType,
|
|
806
|
+
error: error instanceof Error ? error.message : error
|
|
807
|
+
});
|
|
808
|
+
}
|
|
809
|
+
});
|
|
810
|
+
}
|
|
811
|
+
/**
|
|
812
|
+
* Parse Payload CMS mutation response (create/update)
|
|
813
|
+
* Returns native Payload response structure
|
|
814
|
+
*/
|
|
815
|
+
parseMutationResponse(response) {
|
|
816
|
+
return __async(this, null, function* () {
|
|
817
|
+
const contentType = response.headers.get("content-type");
|
|
818
|
+
try {
|
|
819
|
+
this.assertJsonResponse(response);
|
|
820
|
+
const jsonData = yield response.json();
|
|
821
|
+
if (jsonData.doc === void 0) {
|
|
822
|
+
throw createApiError("Invalid mutation response.", response.status, { jsonData });
|
|
823
|
+
}
|
|
824
|
+
return {
|
|
825
|
+
message: jsonData.message || "",
|
|
826
|
+
doc: jsonData.doc,
|
|
827
|
+
errors: jsonData.errors
|
|
828
|
+
};
|
|
829
|
+
} catch (error) {
|
|
830
|
+
throw createApiError("Failed to parse response.", response.status, {
|
|
831
|
+
contentType,
|
|
832
|
+
error: error instanceof Error ? error.message : error
|
|
833
|
+
});
|
|
834
|
+
}
|
|
835
|
+
});
|
|
836
|
+
}
|
|
837
|
+
/**
|
|
838
|
+
* Parse Payload CMS document response (findById/delete)
|
|
839
|
+
* Returns document directly without wrapper
|
|
840
|
+
*/
|
|
841
|
+
parseDocumentResponse(response) {
|
|
842
|
+
return __async(this, null, function* () {
|
|
843
|
+
const contentType = response.headers.get("content-type");
|
|
844
|
+
try {
|
|
845
|
+
this.assertJsonResponse(response);
|
|
846
|
+
const jsonData = yield response.json();
|
|
847
|
+
return jsonData;
|
|
848
|
+
} catch (error) {
|
|
849
|
+
throw createApiError("Failed to parse response.", response.status, {
|
|
850
|
+
contentType,
|
|
851
|
+
error: error instanceof Error ? error.message : error
|
|
852
|
+
});
|
|
853
|
+
}
|
|
854
|
+
});
|
|
855
|
+
}
|
|
856
|
+
};
|
|
857
|
+
|
|
649
858
|
// src/core/collection/collection-client.ts
|
|
650
859
|
var CollectionClient = class extends HttpClient {
|
|
651
|
-
constructor(clientKey, secretKey, baseUrl) {
|
|
652
|
-
super(clientKey, secretKey, baseUrl);
|
|
860
|
+
constructor(clientKey, secretKey, baseUrl, getCustomerToken) {
|
|
861
|
+
super(clientKey, secretKey, baseUrl, getCustomerToken);
|
|
653
862
|
}
|
|
654
863
|
from(collection) {
|
|
655
864
|
return new CollectionQueryBuilder(this, collection);
|
|
@@ -774,7 +983,19 @@ var COLLECTIONS = [
|
|
|
774
983
|
"order-products",
|
|
775
984
|
"returns",
|
|
776
985
|
"return-products",
|
|
986
|
+
"exchanges",
|
|
987
|
+
"exchange-products",
|
|
988
|
+
"fulfillments",
|
|
989
|
+
"fulfillment-items",
|
|
777
990
|
"transactions",
|
|
991
|
+
"customers",
|
|
992
|
+
"customer-addresses",
|
|
993
|
+
"customer-groups",
|
|
994
|
+
"customer-group-images",
|
|
995
|
+
"carts",
|
|
996
|
+
"cart-items",
|
|
997
|
+
"discounts",
|
|
998
|
+
"shipping-policies",
|
|
778
999
|
"documents",
|
|
779
1000
|
"document-categories",
|
|
780
1001
|
"document-images",
|
|
@@ -792,12 +1013,205 @@ var COLLECTIONS = [
|
|
|
792
1013
|
"media"
|
|
793
1014
|
];
|
|
794
1015
|
|
|
1016
|
+
// src/core/customer/customer-auth.ts
|
|
1017
|
+
var DEFAULT_TIMEOUT2 = 15e3;
|
|
1018
|
+
var CustomerAuth = class {
|
|
1019
|
+
constructor(clientKey, baseUrl, options) {
|
|
1020
|
+
var _a;
|
|
1021
|
+
this.clientKey = clientKey;
|
|
1022
|
+
this.baseUrl = baseUrl;
|
|
1023
|
+
this.token = (_a = options == null ? void 0 : options.token) != null ? _a : null;
|
|
1024
|
+
this.onTokenChange = options == null ? void 0 : options.onTokenChange;
|
|
1025
|
+
}
|
|
1026
|
+
/**
|
|
1027
|
+
* Register a new customer account
|
|
1028
|
+
*/
|
|
1029
|
+
register(data) {
|
|
1030
|
+
return __async(this, null, function* () {
|
|
1031
|
+
return this.requestJson("/api/customers/register", {
|
|
1032
|
+
method: "POST",
|
|
1033
|
+
body: JSON.stringify(data)
|
|
1034
|
+
});
|
|
1035
|
+
});
|
|
1036
|
+
}
|
|
1037
|
+
/**
|
|
1038
|
+
* Login with email and password. Stores the token internally.
|
|
1039
|
+
*/
|
|
1040
|
+
login(data) {
|
|
1041
|
+
return __async(this, null, function* () {
|
|
1042
|
+
const result = yield this.requestJson("/api/customers/login", {
|
|
1043
|
+
method: "POST",
|
|
1044
|
+
body: JSON.stringify(data)
|
|
1045
|
+
});
|
|
1046
|
+
this.setToken(result.token);
|
|
1047
|
+
return result;
|
|
1048
|
+
});
|
|
1049
|
+
}
|
|
1050
|
+
/**
|
|
1051
|
+
* Refresh the current token. Requires a valid (non-expired) token.
|
|
1052
|
+
*/
|
|
1053
|
+
refreshToken() {
|
|
1054
|
+
return __async(this, null, function* () {
|
|
1055
|
+
if (!this.token) throw new ApiError("Not authenticated", 401);
|
|
1056
|
+
const result = yield this.requestJson("/api/customers/refresh", {
|
|
1057
|
+
method: "POST",
|
|
1058
|
+
headers: { Authorization: `Bearer ${this.token}` }
|
|
1059
|
+
});
|
|
1060
|
+
this.setToken(result.token);
|
|
1061
|
+
return result;
|
|
1062
|
+
});
|
|
1063
|
+
}
|
|
1064
|
+
/**
|
|
1065
|
+
* Clear the stored token
|
|
1066
|
+
*/
|
|
1067
|
+
logout() {
|
|
1068
|
+
this.setToken(null);
|
|
1069
|
+
}
|
|
1070
|
+
/**
|
|
1071
|
+
* Get the current authenticated customer's profile
|
|
1072
|
+
*/
|
|
1073
|
+
me() {
|
|
1074
|
+
return __async(this, null, function* () {
|
|
1075
|
+
var _a;
|
|
1076
|
+
if (!this.token) return null;
|
|
1077
|
+
try {
|
|
1078
|
+
const data = yield this.requestJson("/api/customers/me", {
|
|
1079
|
+
method: "GET",
|
|
1080
|
+
headers: { Authorization: `Bearer ${this.token}` }
|
|
1081
|
+
});
|
|
1082
|
+
return (_a = data.customer) != null ? _a : null;
|
|
1083
|
+
} catch (error) {
|
|
1084
|
+
if (error instanceof ApiError && error.status === 401) {
|
|
1085
|
+
this.setToken(null);
|
|
1086
|
+
return null;
|
|
1087
|
+
}
|
|
1088
|
+
throw error;
|
|
1089
|
+
}
|
|
1090
|
+
});
|
|
1091
|
+
}
|
|
1092
|
+
/**
|
|
1093
|
+
* Request a password reset email
|
|
1094
|
+
*/
|
|
1095
|
+
forgotPassword(email) {
|
|
1096
|
+
return __async(this, null, function* () {
|
|
1097
|
+
yield this.requestJson("/api/customers/forgot-password", {
|
|
1098
|
+
method: "POST",
|
|
1099
|
+
body: JSON.stringify({ email })
|
|
1100
|
+
});
|
|
1101
|
+
});
|
|
1102
|
+
}
|
|
1103
|
+
/**
|
|
1104
|
+
* Reset password using a token from the reset email
|
|
1105
|
+
*/
|
|
1106
|
+
resetPassword(token, password) {
|
|
1107
|
+
return __async(this, null, function* () {
|
|
1108
|
+
yield this.requestJson("/api/customers/reset-password", {
|
|
1109
|
+
method: "POST",
|
|
1110
|
+
body: JSON.stringify({ token, password })
|
|
1111
|
+
});
|
|
1112
|
+
});
|
|
1113
|
+
}
|
|
1114
|
+
/**
|
|
1115
|
+
* Change the password of the currently authenticated customer
|
|
1116
|
+
*/
|
|
1117
|
+
changePassword(currentPassword, newPassword) {
|
|
1118
|
+
return __async(this, null, function* () {
|
|
1119
|
+
if (!this.token) throw new ApiError("Not authenticated", 401);
|
|
1120
|
+
yield this.requestJson("/api/customers/change-password", {
|
|
1121
|
+
method: "POST",
|
|
1122
|
+
headers: { Authorization: `Bearer ${this.token}` },
|
|
1123
|
+
body: JSON.stringify({ currentPassword, newPassword })
|
|
1124
|
+
});
|
|
1125
|
+
});
|
|
1126
|
+
}
|
|
1127
|
+
/**
|
|
1128
|
+
* Verify email using the verification token
|
|
1129
|
+
*/
|
|
1130
|
+
verifyEmail(token) {
|
|
1131
|
+
return __async(this, null, function* () {
|
|
1132
|
+
yield this.requestJson("/api/customers/verify-email", {
|
|
1133
|
+
method: "POST",
|
|
1134
|
+
body: JSON.stringify({ token })
|
|
1135
|
+
});
|
|
1136
|
+
});
|
|
1137
|
+
}
|
|
1138
|
+
/**
|
|
1139
|
+
* Get the current token (or null if not authenticated)
|
|
1140
|
+
*/
|
|
1141
|
+
getToken() {
|
|
1142
|
+
return this.token;
|
|
1143
|
+
}
|
|
1144
|
+
/**
|
|
1145
|
+
* Set the token manually (e.g. from SSR)
|
|
1146
|
+
*/
|
|
1147
|
+
setToken(token) {
|
|
1148
|
+
var _a;
|
|
1149
|
+
this.token = token;
|
|
1150
|
+
(_a = this.onTokenChange) == null ? void 0 : _a.call(this, token);
|
|
1151
|
+
}
|
|
1152
|
+
/**
|
|
1153
|
+
* Check if the customer is currently authenticated
|
|
1154
|
+
*/
|
|
1155
|
+
isAuthenticated() {
|
|
1156
|
+
return this.token !== null;
|
|
1157
|
+
}
|
|
1158
|
+
/**
|
|
1159
|
+
* Internal: make a request with timeout and error handling.
|
|
1160
|
+
* Auth endpoints don't retry — failures are final.
|
|
1161
|
+
*/
|
|
1162
|
+
requestJson(path, init) {
|
|
1163
|
+
return __async(this, null, function* () {
|
|
1164
|
+
const headers = new Headers(init.headers);
|
|
1165
|
+
headers.set("X-Client-Key", this.clientKey);
|
|
1166
|
+
if (!headers.has("Content-Type") && init.body) {
|
|
1167
|
+
headers.set("Content-Type", "application/json");
|
|
1168
|
+
}
|
|
1169
|
+
const controller = new AbortController();
|
|
1170
|
+
const timeoutId = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT2);
|
|
1171
|
+
let res;
|
|
1172
|
+
try {
|
|
1173
|
+
res = yield fetch(`${this.baseUrl}${path}`, __spreadProps(__spreadValues({}, init), {
|
|
1174
|
+
headers,
|
|
1175
|
+
signal: controller.signal
|
|
1176
|
+
}));
|
|
1177
|
+
} catch (error) {
|
|
1178
|
+
clearTimeout(timeoutId);
|
|
1179
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
1180
|
+
throw new TimeoutError(
|
|
1181
|
+
`Request timed out after ${DEFAULT_TIMEOUT2}ms`,
|
|
1182
|
+
{ url: path, timeout: DEFAULT_TIMEOUT2 }
|
|
1183
|
+
);
|
|
1184
|
+
}
|
|
1185
|
+
throw new NetworkError(
|
|
1186
|
+
error instanceof Error ? error.message : "Network request failed",
|
|
1187
|
+
void 0,
|
|
1188
|
+
{ url: path },
|
|
1189
|
+
"Network connection failed.",
|
|
1190
|
+
"Please check your internet connection and try again."
|
|
1191
|
+
);
|
|
1192
|
+
}
|
|
1193
|
+
clearTimeout(timeoutId);
|
|
1194
|
+
if (!res.ok) {
|
|
1195
|
+
const body = yield res.json().catch(() => ({}));
|
|
1196
|
+
throw new ApiError(
|
|
1197
|
+
body.error || `HTTP ${res.status}`,
|
|
1198
|
+
res.status,
|
|
1199
|
+
body.details,
|
|
1200
|
+
body.error
|
|
1201
|
+
);
|
|
1202
|
+
}
|
|
1203
|
+
return res.json();
|
|
1204
|
+
});
|
|
1205
|
+
}
|
|
1206
|
+
};
|
|
1207
|
+
|
|
795
1208
|
// src/core/query/get-query-client.ts
|
|
796
1209
|
import { isServer, QueryClient, defaultShouldDehydrateQuery } from "@tanstack/react-query";
|
|
797
1210
|
function makeQueryClient() {
|
|
798
1211
|
return new QueryClient({
|
|
799
1212
|
defaultOptions: {
|
|
800
1213
|
queries: {
|
|
1214
|
+
// SSR/RSC: server-fetched data doesn't auto-refetch; use refetch()/invalidate() to refresh
|
|
801
1215
|
staleTime: Number.POSITIVE_INFINITY,
|
|
802
1216
|
refetchOnWindowFocus: false
|
|
803
1217
|
},
|
|
@@ -838,11 +1252,24 @@ function collectionKeys(collection) {
|
|
|
838
1252
|
infinite: (options) => [collection, "infinite", options]
|
|
839
1253
|
};
|
|
840
1254
|
}
|
|
1255
|
+
var customerKeys = {
|
|
1256
|
+
all: ["customer"],
|
|
1257
|
+
me: () => ["customer", "me"]
|
|
1258
|
+
};
|
|
841
1259
|
var DEFAULT_PAGE_SIZE = 20;
|
|
842
1260
|
var QueryHooks = class {
|
|
843
|
-
constructor(queryClient, collectionClient) {
|
|
1261
|
+
constructor(queryClient, collectionClient, customerAuth) {
|
|
844
1262
|
this.queryClient = queryClient;
|
|
845
1263
|
this.collectionClient = collectionClient;
|
|
1264
|
+
this.customerAuth = customerAuth;
|
|
1265
|
+
}
|
|
1266
|
+
ensureCustomerAuth() {
|
|
1267
|
+
if (!this.customerAuth) {
|
|
1268
|
+
throw createConfigError(
|
|
1269
|
+
"Customer hooks require BrowserClient. Use createBrowserClient() instead of createServerClient()."
|
|
1270
|
+
);
|
|
1271
|
+
}
|
|
1272
|
+
return this.customerAuth;
|
|
846
1273
|
}
|
|
847
1274
|
// ===== useQuery =====
|
|
848
1275
|
useQuery(params, options) {
|
|
@@ -1034,6 +1461,124 @@ var QueryHooks = class {
|
|
|
1034
1461
|
);
|
|
1035
1462
|
}
|
|
1036
1463
|
}
|
|
1464
|
+
// ===== Customer Query Hooks =====
|
|
1465
|
+
useCustomerMe(options) {
|
|
1466
|
+
var _a, _b;
|
|
1467
|
+
return useQueryOriginal(__spreadProps(__spreadValues({
|
|
1468
|
+
queryKey: customerKeys.me(),
|
|
1469
|
+
queryFn: () => __async(this, null, function* () {
|
|
1470
|
+
return yield this.ensureCustomerAuth().me();
|
|
1471
|
+
})
|
|
1472
|
+
}, options), {
|
|
1473
|
+
enabled: ((_a = options == null ? void 0 : options.enabled) != null ? _a : true) && !!((_b = this.customerAuth) == null ? void 0 : _b.isAuthenticated())
|
|
1474
|
+
}));
|
|
1475
|
+
}
|
|
1476
|
+
useCustomerLogin(options) {
|
|
1477
|
+
return useMutationOriginal({
|
|
1478
|
+
mutationFn: (data) => __async(this, null, function* () {
|
|
1479
|
+
return yield this.ensureCustomerAuth().login(data);
|
|
1480
|
+
}),
|
|
1481
|
+
onSuccess: (data) => {
|
|
1482
|
+
var _a;
|
|
1483
|
+
this.queryClient.invalidateQueries({ queryKey: customerKeys.me() });
|
|
1484
|
+
(_a = options == null ? void 0 : options.onSuccess) == null ? void 0 : _a.call(options, data);
|
|
1485
|
+
},
|
|
1486
|
+
onError: options == null ? void 0 : options.onError,
|
|
1487
|
+
onSettled: options == null ? void 0 : options.onSettled
|
|
1488
|
+
});
|
|
1489
|
+
}
|
|
1490
|
+
useCustomerRegister(options) {
|
|
1491
|
+
return useMutationOriginal({
|
|
1492
|
+
mutationFn: (data) => __async(this, null, function* () {
|
|
1493
|
+
return yield this.ensureCustomerAuth().register(data);
|
|
1494
|
+
}),
|
|
1495
|
+
onSuccess: options == null ? void 0 : options.onSuccess,
|
|
1496
|
+
onError: options == null ? void 0 : options.onError,
|
|
1497
|
+
onSettled: options == null ? void 0 : options.onSettled
|
|
1498
|
+
});
|
|
1499
|
+
}
|
|
1500
|
+
useCustomerLogout(options) {
|
|
1501
|
+
return useMutationOriginal({
|
|
1502
|
+
mutationFn: () => __async(this, null, function* () {
|
|
1503
|
+
this.ensureCustomerAuth().logout();
|
|
1504
|
+
}),
|
|
1505
|
+
onSuccess: () => {
|
|
1506
|
+
var _a;
|
|
1507
|
+
this.queryClient.removeQueries({ queryKey: customerKeys.all });
|
|
1508
|
+
(_a = options == null ? void 0 : options.onSuccess) == null ? void 0 : _a.call(options);
|
|
1509
|
+
},
|
|
1510
|
+
onError: options == null ? void 0 : options.onError,
|
|
1511
|
+
onSettled: options == null ? void 0 : options.onSettled
|
|
1512
|
+
});
|
|
1513
|
+
}
|
|
1514
|
+
useCustomerForgotPassword(options) {
|
|
1515
|
+
return useMutationOriginal({
|
|
1516
|
+
mutationFn: (email) => __async(this, null, function* () {
|
|
1517
|
+
yield this.ensureCustomerAuth().forgotPassword(email);
|
|
1518
|
+
}),
|
|
1519
|
+
onSuccess: options == null ? void 0 : options.onSuccess,
|
|
1520
|
+
onError: options == null ? void 0 : options.onError,
|
|
1521
|
+
onSettled: options == null ? void 0 : options.onSettled
|
|
1522
|
+
});
|
|
1523
|
+
}
|
|
1524
|
+
useCustomerResetPassword(options) {
|
|
1525
|
+
return useMutationOriginal({
|
|
1526
|
+
mutationFn: (data) => __async(this, null, function* () {
|
|
1527
|
+
yield this.ensureCustomerAuth().resetPassword(data.token, data.password);
|
|
1528
|
+
}),
|
|
1529
|
+
onSuccess: options == null ? void 0 : options.onSuccess,
|
|
1530
|
+
onError: options == null ? void 0 : options.onError,
|
|
1531
|
+
onSettled: options == null ? void 0 : options.onSettled
|
|
1532
|
+
});
|
|
1533
|
+
}
|
|
1534
|
+
useCustomerVerifyEmail(options) {
|
|
1535
|
+
return useMutationOriginal({
|
|
1536
|
+
mutationFn: (token) => __async(this, null, function* () {
|
|
1537
|
+
yield this.ensureCustomerAuth().verifyEmail(token);
|
|
1538
|
+
}),
|
|
1539
|
+
onSuccess: () => {
|
|
1540
|
+
var _a;
|
|
1541
|
+
this.queryClient.invalidateQueries({ queryKey: customerKeys.me() });
|
|
1542
|
+
(_a = options == null ? void 0 : options.onSuccess) == null ? void 0 : _a.call(options);
|
|
1543
|
+
},
|
|
1544
|
+
onError: options == null ? void 0 : options.onError,
|
|
1545
|
+
onSettled: options == null ? void 0 : options.onSettled
|
|
1546
|
+
});
|
|
1547
|
+
}
|
|
1548
|
+
useCustomerRefreshToken(options) {
|
|
1549
|
+
return useMutationOriginal({
|
|
1550
|
+
mutationFn: () => __async(this, null, function* () {
|
|
1551
|
+
return yield this.ensureCustomerAuth().refreshToken();
|
|
1552
|
+
}),
|
|
1553
|
+
onSuccess: (data) => {
|
|
1554
|
+
var _a;
|
|
1555
|
+
this.queryClient.invalidateQueries({ queryKey: customerKeys.me() });
|
|
1556
|
+
(_a = options == null ? void 0 : options.onSuccess) == null ? void 0 : _a.call(options, data);
|
|
1557
|
+
},
|
|
1558
|
+
onError: options == null ? void 0 : options.onError,
|
|
1559
|
+
onSettled: options == null ? void 0 : options.onSettled
|
|
1560
|
+
});
|
|
1561
|
+
}
|
|
1562
|
+
useCustomerChangePassword(options) {
|
|
1563
|
+
return useMutationOriginal({
|
|
1564
|
+
mutationFn: (data) => __async(this, null, function* () {
|
|
1565
|
+
yield this.ensureCustomerAuth().changePassword(data.currentPassword, data.newPassword);
|
|
1566
|
+
}),
|
|
1567
|
+
onSuccess: options == null ? void 0 : options.onSuccess,
|
|
1568
|
+
onError: options == null ? void 0 : options.onError,
|
|
1569
|
+
onSettled: options == null ? void 0 : options.onSettled
|
|
1570
|
+
});
|
|
1571
|
+
}
|
|
1572
|
+
// ===== Customer Cache Utilities =====
|
|
1573
|
+
invalidateCustomerQueries() {
|
|
1574
|
+
return this.queryClient.invalidateQueries({ queryKey: customerKeys.all });
|
|
1575
|
+
}
|
|
1576
|
+
getCustomerData() {
|
|
1577
|
+
return this.queryClient.getQueryData(customerKeys.me());
|
|
1578
|
+
}
|
|
1579
|
+
setCustomerData(data) {
|
|
1580
|
+
this.queryClient.setQueryData(customerKeys.me(), data);
|
|
1581
|
+
}
|
|
1037
1582
|
};
|
|
1038
1583
|
|
|
1039
1584
|
// src/core/client/client.ts
|
|
@@ -1051,8 +1596,19 @@ var BrowserClient = class {
|
|
|
1051
1596
|
};
|
|
1052
1597
|
this.state = { metadata };
|
|
1053
1598
|
this.queryClient = getQueryClient();
|
|
1054
|
-
this.
|
|
1055
|
-
this.
|
|
1599
|
+
this.customer = new CustomerAuth(this.config.clientKey, this.baseUrl, options.customer);
|
|
1600
|
+
this.cart = new CartApi({
|
|
1601
|
+
clientKey: this.config.clientKey,
|
|
1602
|
+
customerToken: () => this.customer.getToken(),
|
|
1603
|
+
baseUrl: this.baseUrl
|
|
1604
|
+
});
|
|
1605
|
+
this.collections = new CollectionClient(
|
|
1606
|
+
this.config.clientKey,
|
|
1607
|
+
void 0,
|
|
1608
|
+
this.baseUrl,
|
|
1609
|
+
() => this.customer.getToken()
|
|
1610
|
+
);
|
|
1611
|
+
this.query = new QueryHooks(this.queryClient, this.collections, this.customer);
|
|
1056
1612
|
}
|
|
1057
1613
|
from(collection) {
|
|
1058
1614
|
return this.collections.from(collection);
|
|
@@ -1065,68 +1621,14 @@ function createBrowserClient(options) {
|
|
|
1065
1621
|
return new BrowserClient(options);
|
|
1066
1622
|
}
|
|
1067
1623
|
|
|
1068
|
-
// src/core/api/order-api.ts
|
|
1069
|
-
var OrderApi = class {
|
|
1070
|
-
constructor(options) {
|
|
1071
|
-
if (!options.clientKey) {
|
|
1072
|
-
throw createConfigError("clientKey is required for OrderApi.");
|
|
1073
|
-
}
|
|
1074
|
-
if (!options.secretKey) {
|
|
1075
|
-
throw createConfigError("secretKey is required for OrderApi.");
|
|
1076
|
-
}
|
|
1077
|
-
this.clientKey = options.clientKey;
|
|
1078
|
-
this.secretKey = options.secretKey;
|
|
1079
|
-
this.baseUrl = options.baseUrl;
|
|
1080
|
-
}
|
|
1081
|
-
request(endpoint, body) {
|
|
1082
|
-
return __async(this, null, function* () {
|
|
1083
|
-
const response = yield _fetch(endpoint, {
|
|
1084
|
-
method: "POST",
|
|
1085
|
-
clientKey: this.clientKey,
|
|
1086
|
-
secretKey: this.secretKey,
|
|
1087
|
-
baseUrl: this.baseUrl,
|
|
1088
|
-
body: JSON.stringify(body)
|
|
1089
|
-
});
|
|
1090
|
-
let data;
|
|
1091
|
-
try {
|
|
1092
|
-
data = yield response.json();
|
|
1093
|
-
} catch (e) {
|
|
1094
|
-
throw createApiError(
|
|
1095
|
-
`Invalid JSON response from ${endpoint}`,
|
|
1096
|
-
response.status,
|
|
1097
|
-
void 0,
|
|
1098
|
-
"Server returned an invalid response.",
|
|
1099
|
-
"Check if the API endpoint is available."
|
|
1100
|
-
);
|
|
1101
|
-
}
|
|
1102
|
-
if (data.error) {
|
|
1103
|
-
const errorMessage = typeof data.error === "string" ? data.error : "Unknown API error";
|
|
1104
|
-
throw createApiError(
|
|
1105
|
-
errorMessage,
|
|
1106
|
-
response.status,
|
|
1107
|
-
data,
|
|
1108
|
-
errorMessage,
|
|
1109
|
-
"An error occurred while processing the request."
|
|
1110
|
-
);
|
|
1111
|
-
}
|
|
1112
|
-
return data;
|
|
1113
|
-
});
|
|
1114
|
-
}
|
|
1115
|
-
createOrder(params) {
|
|
1116
|
-
return this.request("/api/orders/create", params);
|
|
1117
|
-
}
|
|
1118
|
-
updateOrder(params) {
|
|
1119
|
-
return this.request("/api/orders/update", params);
|
|
1120
|
-
}
|
|
1121
|
-
updateTransaction(params) {
|
|
1122
|
-
return this.request("/api/transactions/update", params);
|
|
1123
|
-
}
|
|
1124
|
-
};
|
|
1125
|
-
|
|
1126
1624
|
// src/core/client/client.server.ts
|
|
1127
1625
|
var ServerClient = class {
|
|
1128
1626
|
constructor(options) {
|
|
1129
|
-
|
|
1627
|
+
if (typeof window !== "undefined") {
|
|
1628
|
+
throw createConfigError(
|
|
1629
|
+
"ServerClient must not be used in a browser environment. This risks exposing your secretKey in client bundles. Use createBrowserClient() for browser code instead."
|
|
1630
|
+
);
|
|
1631
|
+
}
|
|
1130
1632
|
if (!options.clientKey) {
|
|
1131
1633
|
throw createConfigError("clientKey is required.");
|
|
1132
1634
|
}
|
|
@@ -1137,7 +1639,7 @@ var ServerClient = class {
|
|
|
1137
1639
|
this.baseUrl = resolveApiUrl(options);
|
|
1138
1640
|
const metadata = {
|
|
1139
1641
|
timestamp: Date.now(),
|
|
1140
|
-
userAgent:
|
|
1642
|
+
userAgent: "Node.js"
|
|
1141
1643
|
};
|
|
1142
1644
|
this.state = { metadata };
|
|
1143
1645
|
this.api = new OrderApi({
|
|
@@ -1145,6 +1647,16 @@ var ServerClient = class {
|
|
|
1145
1647
|
secretKey: this.config.secretKey,
|
|
1146
1648
|
baseUrl: this.baseUrl
|
|
1147
1649
|
});
|
|
1650
|
+
this.cart = new CartApi({
|
|
1651
|
+
clientKey: this.config.clientKey,
|
|
1652
|
+
secretKey: this.config.secretKey,
|
|
1653
|
+
baseUrl: this.baseUrl
|
|
1654
|
+
});
|
|
1655
|
+
this.product = new ProductApi({
|
|
1656
|
+
clientKey: this.config.clientKey,
|
|
1657
|
+
secretKey: this.config.secretKey,
|
|
1658
|
+
baseUrl: this.baseUrl
|
|
1659
|
+
});
|
|
1148
1660
|
this.collections = new CollectionClient(
|
|
1149
1661
|
this.config.clientKey,
|
|
1150
1662
|
this.config.secretKey,
|
|
@@ -1198,6 +1710,11 @@ function handleWebhook(request, handler, options) {
|
|
|
1198
1710
|
return __async(this, null, function* () {
|
|
1199
1711
|
try {
|
|
1200
1712
|
const rawBody = yield request.text();
|
|
1713
|
+
if (!(options == null ? void 0 : options.secret)) {
|
|
1714
|
+
console.warn(
|
|
1715
|
+
"[@01.software/sdk] Webhook signature verification is skipped because no secret was provided. Pass { secret } to handleWebhook() to enable signature verification."
|
|
1716
|
+
);
|
|
1717
|
+
}
|
|
1201
1718
|
if (options == null ? void 0 : options.secret) {
|
|
1202
1719
|
const signature = request.headers.get("x-webhook-signature") || "";
|
|
1203
1720
|
const valid = yield verifySignature(rawBody, options.secret, signature);
|
|
@@ -1223,10 +1740,7 @@ function handleWebhook(request, handler, options) {
|
|
|
1223
1740
|
} catch (error) {
|
|
1224
1741
|
console.error("Webhook processing error:", error);
|
|
1225
1742
|
return new Response(
|
|
1226
|
-
JSON.stringify({
|
|
1227
|
-
error: "Internal server error",
|
|
1228
|
-
message: error instanceof Error ? error.message : "Unknown error"
|
|
1229
|
-
}),
|
|
1743
|
+
JSON.stringify({ error: "Internal server error" }),
|
|
1230
1744
|
{ status: 500, headers: { "Content-Type": "application/json" } }
|
|
1231
1745
|
);
|
|
1232
1746
|
}
|
|
@@ -1243,10 +1757,13 @@ function createTypedWebhookHandler(collection, handler) {
|
|
|
1243
1757
|
|
|
1244
1758
|
// src/utils/order/generateOrderNumber.ts
|
|
1245
1759
|
var generateOrderNumber = () => {
|
|
1760
|
+
var _a;
|
|
1246
1761
|
const year = (/* @__PURE__ */ new Date()).getFullYear().toString().slice(-2);
|
|
1247
1762
|
const month = ((/* @__PURE__ */ new Date()).getMonth() + 1).toString().padStart(2, "0");
|
|
1248
1763
|
const day = (/* @__PURE__ */ new Date()).getDate().toString().padStart(2, "0");
|
|
1249
|
-
const
|
|
1764
|
+
const array = new Uint32Array(1);
|
|
1765
|
+
globalThis.crypto.getRandomValues(array);
|
|
1766
|
+
const random = (((_a = array[0]) != null ? _a : 0) % 1e6).toString().padStart(6, "0");
|
|
1250
1767
|
return `${year}${month}${day}${random}`;
|
|
1251
1768
|
};
|
|
1252
1769
|
|
|
@@ -1295,11 +1812,14 @@ export {
|
|
|
1295
1812
|
ApiError,
|
|
1296
1813
|
BrowserClient,
|
|
1297
1814
|
COLLECTIONS,
|
|
1815
|
+
CartApi,
|
|
1298
1816
|
CollectionClient,
|
|
1299
1817
|
CollectionQueryBuilder,
|
|
1300
1818
|
ConfigError,
|
|
1819
|
+
CustomerAuth,
|
|
1301
1820
|
NetworkError,
|
|
1302
1821
|
OrderApi,
|
|
1822
|
+
ProductApi,
|
|
1303
1823
|
QueryHooks,
|
|
1304
1824
|
RichTextContent,
|
|
1305
1825
|
ServerClient,
|
|
@@ -1312,6 +1832,7 @@ export {
|
|
|
1312
1832
|
createServerClient,
|
|
1313
1833
|
createServerToken,
|
|
1314
1834
|
createTypedWebhookHandler,
|
|
1835
|
+
customerKeys,
|
|
1315
1836
|
decodeServerToken,
|
|
1316
1837
|
formatOrderName,
|
|
1317
1838
|
generateOrderNumber,
|