@01.software/sdk 0.12.1 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +94 -57
  2. package/dist/{const-CRjjFJ3o.d.ts → const-DSTPrI77.d.ts} +1 -1
  3. package/dist/{const-CZOY2tsf.d.cts → const-DqcpKgSA.d.cts} +1 -1
  4. package/dist/index.cjs +794 -504
  5. package/dist/index.cjs.map +1 -1
  6. package/dist/index.d.cts +639 -439
  7. package/dist/index.d.ts +639 -439
  8. package/dist/index.js +794 -504
  9. package/dist/index.js.map +1 -1
  10. package/dist/{payload-types-D4IWd3ZB.d.cts → payload-types-DqX4iuTW.d.cts} +1 -1
  11. package/dist/{payload-types-D4IWd3ZB.d.ts → payload-types-DqX4iuTW.d.ts} +1 -1
  12. package/dist/realtime.cjs.map +1 -1
  13. package/dist/realtime.d.cts +2 -2
  14. package/dist/realtime.d.ts +2 -2
  15. package/dist/realtime.js.map +1 -1
  16. package/dist/{server-JR9TvKZ5.d.cts → server-DLdbWJVv.d.cts} +5 -3
  17. package/dist/{server-JR9TvKZ5.d.ts → server-DLdbWJVv.d.ts} +5 -3
  18. package/dist/ui/canvas/server.cjs +4 -4
  19. package/dist/ui/canvas/server.cjs.map +1 -1
  20. package/dist/ui/canvas/server.d.cts +1 -1
  21. package/dist/ui/canvas/server.d.ts +1 -1
  22. package/dist/ui/canvas/server.js +4 -4
  23. package/dist/ui/canvas/server.js.map +1 -1
  24. package/dist/ui/canvas.cjs +4 -4
  25. package/dist/ui/canvas.cjs.map +1 -1
  26. package/dist/ui/canvas.d.cts +2 -2
  27. package/dist/ui/canvas.d.ts +2 -2
  28. package/dist/ui/canvas.js +4 -4
  29. package/dist/ui/canvas.js.map +1 -1
  30. package/dist/ui/form.d.cts +1 -1
  31. package/dist/ui/form.d.ts +1 -1
  32. package/dist/ui/video.d.cts +1 -1
  33. package/dist/ui/video.d.ts +1 -1
  34. package/dist/{webhook-D_7bYIKj.d.ts → webhook-CX21PpBt.d.ts} +2 -2
  35. package/dist/{webhook-C1q3iC6W.d.cts → webhook-mXjcW86I.d.cts} +2 -2
  36. package/dist/webhook.d.cts +3 -3
  37. package/dist/webhook.d.ts +3 -3
  38. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -1,6 +1,206 @@
1
+ // src/utils/types.ts
2
+ var resolveRelation = (ref) => {
3
+ if (typeof ref === "string" || typeof ref === "number" || ref === null || ref === void 0)
4
+ return null;
5
+ return ref;
6
+ };
7
+
8
+ // src/core/metadata/index.ts
9
+ function extractSeo(doc) {
10
+ const seo = doc.seo ?? {};
11
+ const og = seo.openGraph ?? {};
12
+ return {
13
+ title: seo.title ?? doc.title ?? null,
14
+ description: seo.description ?? null,
15
+ noIndex: seo.noIndex ?? null,
16
+ canonical: seo.canonical ?? null,
17
+ openGraph: {
18
+ title: og.title ?? null,
19
+ description: og.description ?? null,
20
+ image: og.image ?? null
21
+ }
22
+ };
23
+ }
24
+ function generateMetadata(input, options) {
25
+ const title = input.title ?? void 0;
26
+ const description = input.description ?? void 0;
27
+ const ogTitle = input.openGraph?.title ?? title;
28
+ const ogDescription = input.openGraph?.description ?? description;
29
+ const image = resolveMetaImage(input.openGraph?.image);
30
+ return {
31
+ title,
32
+ description,
33
+ ...input.noIndex && { robots: { index: false, follow: false } },
34
+ ...input.canonical && { alternates: { canonical: input.canonical } },
35
+ openGraph: {
36
+ ...ogTitle && { title: ogTitle },
37
+ ...ogDescription && { description: ogDescription },
38
+ ...options?.siteName && { siteName: options.siteName },
39
+ ...image && { images: [image] }
40
+ },
41
+ twitter: {
42
+ card: image ? "summary_large_image" : "summary",
43
+ ...ogTitle && { title: ogTitle },
44
+ ...ogDescription && { description: ogDescription },
45
+ ...image && { images: [image.url] }
46
+ }
47
+ };
48
+ }
49
+ function resolveMetaImage(ref) {
50
+ const image = resolveRelation(ref);
51
+ if (!image) return null;
52
+ const sized = image.sizes?.["1536"];
53
+ const url = sized?.url || image.url;
54
+ if (!url) return null;
55
+ const width = sized?.url ? sized.width : image.width;
56
+ const height = sized?.url ? sized.height : image.height;
57
+ return {
58
+ url,
59
+ ...width && { width },
60
+ ...height && { height },
61
+ ...image.alt && { alt: image.alt }
62
+ };
63
+ }
64
+
65
+ // src/core/collection/query-builder.ts
66
+ var CollectionQueryBuilder = class {
67
+ constructor(api, collection) {
68
+ this.api = api;
69
+ this.collection = collection;
70
+ }
71
+ /**
72
+ * Find documents (list query)
73
+ * GET /api/{collection}
74
+ * @returns Payload CMS find response with docs array and pagination
75
+ */
76
+ async find(options) {
77
+ return this.api.requestFind(
78
+ `/api/${String(this.collection)}`,
79
+ options
80
+ );
81
+ }
82
+ /**
83
+ * Find document by ID
84
+ * GET /api/{collection}/{id}
85
+ * @returns Document object directly (no wrapper)
86
+ */
87
+ async findById(id, options) {
88
+ return this.api.requestFindById(
89
+ `/api/${String(this.collection)}/${String(id)}`,
90
+ options
91
+ );
92
+ }
93
+ /**
94
+ * Create a new document
95
+ * POST /api/{collection}
96
+ * @returns Payload CMS mutation response with doc and message
97
+ */
98
+ async create(data, options) {
99
+ const endpoint = `/api/${String(this.collection)}`;
100
+ if (options?.file) {
101
+ return this.api.requestCreateWithFile(
102
+ endpoint,
103
+ data,
104
+ options.file,
105
+ options.filename
106
+ );
107
+ }
108
+ return this.api.requestCreate(endpoint, data);
109
+ }
110
+ /**
111
+ * Update a document by ID
112
+ * PATCH /api/{collection}/{id}
113
+ * @returns Payload CMS mutation response with doc and message
114
+ */
115
+ async update(id, data, options) {
116
+ const endpoint = `/api/${String(this.collection)}/${String(id)}`;
117
+ if (options?.file) {
118
+ return this.api.requestUpdateWithFile(
119
+ endpoint,
120
+ data,
121
+ options.file,
122
+ options.filename
123
+ );
124
+ }
125
+ return this.api.requestUpdate(endpoint, data);
126
+ }
127
+ /**
128
+ * Count documents
129
+ * GET /api/{collection}/count
130
+ * @returns Count response with totalDocs
131
+ */
132
+ async count(options) {
133
+ return this.api.requestCount(
134
+ `/api/${String(this.collection)}/count`,
135
+ options
136
+ );
137
+ }
138
+ /**
139
+ * Find first matching document and return its Next.js Metadata.
140
+ * Applies depth: 1 (SEO image populate) and limit: 1 automatically.
141
+ * @returns Metadata or null if no document matches
142
+ */
143
+ async findMetadata(options, metadataOptions) {
144
+ const { docs } = await this.find({ ...options, limit: 1, depth: 1 });
145
+ const doc = docs[0];
146
+ if (!doc) return null;
147
+ return generateMetadata(
148
+ extractSeo(doc),
149
+ metadataOptions
150
+ );
151
+ }
152
+ /**
153
+ * Find document by ID and return its Next.js Metadata.
154
+ * Applies depth: 1 (SEO image populate) automatically.
155
+ * @returns Metadata (throws on 404)
156
+ */
157
+ async findMetadataById(id, metadataOptions) {
158
+ const doc = await this.findById(id, { depth: 1 });
159
+ return generateMetadata(
160
+ extractSeo(doc),
161
+ metadataOptions
162
+ );
163
+ }
164
+ /**
165
+ * Update multiple documents (bulk update)
166
+ * PATCH /api/{collection}
167
+ * @returns Payload CMS find response with updated docs
168
+ */
169
+ async updateMany(where, data) {
170
+ return this.api.requestUpdateMany(
171
+ `/api/${String(this.collection)}`,
172
+ { where, data }
173
+ );
174
+ }
175
+ /**
176
+ * Delete a document by ID
177
+ * DELETE /api/{collection}/{id}
178
+ * @returns Deleted document object directly (no wrapper)
179
+ */
180
+ async remove(id) {
181
+ return this.api.requestDelete(
182
+ `/api/${String(this.collection)}/${String(id)}`
183
+ );
184
+ }
185
+ /**
186
+ * Delete multiple documents (bulk delete)
187
+ * DELETE /api/{collection}
188
+ * @returns Payload CMS find response with deleted docs
189
+ */
190
+ async removeMany(where) {
191
+ return this.api.requestDeleteMany(
192
+ `/api/${String(this.collection)}`,
193
+ { where }
194
+ );
195
+ }
196
+ };
197
+
198
+ // src/core/collection/http-client.ts
199
+ import { stringify } from "qs-esm";
200
+
1
201
  // src/core/internal/errors/index.ts
2
202
  var SDKError = class extends Error {
3
- constructor(code, message, status, details, userMessage, suggestion) {
203
+ constructor(code, message, status, details, userMessage, suggestion, requestId) {
4
204
  super(message);
5
205
  this.name = "SDKError";
6
206
  this.code = code;
@@ -8,6 +208,7 @@ var SDKError = class extends Error {
8
208
  this.details = details;
9
209
  this.userMessage = userMessage;
10
210
  this.suggestion = suggestion;
211
+ this.requestId = requestId;
11
212
  if (Error.captureStackTrace) {
12
213
  Error.captureStackTrace(this, new.target);
13
214
  }
@@ -23,7 +224,8 @@ var SDKError = class extends Error {
23
224
  status: this.status,
24
225
  details: this.details,
25
226
  userMessage: this.userMessage,
26
- suggestion: this.suggestion
227
+ suggestion: this.suggestion,
228
+ ...this.requestId !== void 0 && { requestId: this.requestId }
27
229
  };
28
230
  }
29
231
  };
@@ -90,6 +292,37 @@ var UsageLimitError = class extends SDKError {
90
292
  };
91
293
  }
92
294
  };
295
+ var AuthError = class extends SDKError {
296
+ constructor(message, details, userMessage, suggestion, requestId) {
297
+ super("auth_error", message, 401, details, userMessage, suggestion, requestId);
298
+ this.name = "AuthError";
299
+ }
300
+ };
301
+ var PermissionError = class extends SDKError {
302
+ constructor(message, details, userMessage, suggestion, requestId) {
303
+ super("permission_error", message, 403, details, userMessage, suggestion, requestId);
304
+ this.name = "PermissionError";
305
+ }
306
+ };
307
+ var NotFoundError = class extends SDKError {
308
+ constructor(message, details, userMessage, suggestion, requestId) {
309
+ super("not_found", message, 404, details, userMessage, suggestion, requestId);
310
+ this.name = "NotFoundError";
311
+ }
312
+ };
313
+ var ConflictError = class extends SDKError {
314
+ constructor(message, details, userMessage, suggestion, requestId) {
315
+ super("conflict", message, 409, details, userMessage, suggestion, requestId);
316
+ this.name = "ConflictError";
317
+ }
318
+ };
319
+ var RateLimitError = class extends SDKError {
320
+ constructor(message, retryAfter, details, userMessage, suggestion, requestId) {
321
+ super("rate_limit_exceeded", message, 429, details, userMessage, suggestion, requestId);
322
+ this.name = "RateLimitError";
323
+ this.retryAfter = retryAfter;
324
+ }
325
+ };
93
326
  function isSDKError(error) {
94
327
  return error instanceof SDKError;
95
328
  }
@@ -117,11 +350,32 @@ function isServiceUnavailableError(error) {
117
350
  function isUsageLimitError(error) {
118
351
  return error instanceof UsageLimitError;
119
352
  }
353
+ function isAuthError(error) {
354
+ return error instanceof AuthError;
355
+ }
356
+ function isPermissionError(error) {
357
+ return error instanceof PermissionError;
358
+ }
359
+ function isNotFoundError(error) {
360
+ return error instanceof NotFoundError;
361
+ }
362
+ function isConflictError(error) {
363
+ return error instanceof ConflictError;
364
+ }
365
+ function isRateLimitError(error) {
366
+ return error instanceof RateLimitError;
367
+ }
120
368
  var createNetworkError = (message, status, details, userMessage, suggestion) => new NetworkError(message, status, details, userMessage, suggestion);
369
+ var createValidationError = (message, details, userMessage, suggestion) => new ValidationError(message, details, userMessage, suggestion);
121
370
  var createApiError = (message, status, details, userMessage, suggestion) => new ApiError(message, status, details, userMessage, suggestion);
122
371
  var createConfigError = (message, details, userMessage, suggestion) => new ConfigError(message, details, userMessage, suggestion);
123
372
  var createTimeoutError = (message, details, userMessage, suggestion) => new TimeoutError(message, details, userMessage, suggestion);
124
373
  var createUsageLimitError = (message, usage, details, userMessage, suggestion) => new UsageLimitError(message, usage, details, userMessage, suggestion);
374
+ var createAuthError = (message, details, userMessage, suggestion, requestId) => new AuthError(message, details, userMessage, suggestion, requestId);
375
+ var createPermissionError = (message, details, userMessage, suggestion, requestId) => new PermissionError(message, details, userMessage, suggestion, requestId);
376
+ var createNotFoundError = (message, details, userMessage, suggestion, requestId) => new NotFoundError(message, details, userMessage, suggestion, requestId);
377
+ var createConflictError = (message, details, userMessage, suggestion, requestId) => new ConflictError(message, details, userMessage, suggestion, requestId);
378
+ var createRateLimitError = (message, retryAfter, details, userMessage, suggestion, requestId) => new RateLimitError(message, retryAfter, details, userMessage, suggestion, requestId);
125
379
 
126
380
  // src/core/client/types.ts
127
381
  function resolveApiUrl() {
@@ -164,6 +418,7 @@ async function parseErrorBody(response) {
164
418
  };
165
419
  try {
166
420
  const body = await response.json();
421
+ const reason = typeof body.reason === "string" ? body.reason : void 0;
167
422
  if (body.errors && Array.isArray(body.errors)) {
168
423
  const fieldErrors = [];
169
424
  for (const e of body.errors) {
@@ -185,6 +440,7 @@ async function parseErrorBody(response) {
185
440
  return {
186
441
  errorMessage: `HTTP ${response.status}: ${details}`,
187
442
  userMessage: details,
443
+ reason,
188
444
  errors: fieldErrors.length > 0 ? fieldErrors : body.errors
189
445
  };
190
446
  }
@@ -192,16 +448,18 @@ async function parseErrorBody(response) {
192
448
  if (typeof body.error === "string") {
193
449
  return {
194
450
  errorMessage: `HTTP ${response.status}: ${body.error}`,
195
- userMessage: body.error
451
+ userMessage: body.error,
452
+ reason
196
453
  };
197
454
  }
198
455
  if (body.message) {
199
456
  return {
200
457
  errorMessage: `HTTP ${response.status}: ${body.message}`,
201
- userMessage: body.message
458
+ userMessage: body.message,
459
+ reason
202
460
  };
203
461
  }
204
- return fallback;
462
+ return { ...fallback, reason };
205
463
  } catch {
206
464
  return fallback;
207
465
  }
@@ -209,11 +467,16 @@ async function parseErrorBody(response) {
209
467
  async function delay(ms) {
210
468
  return new Promise((resolve) => setTimeout(resolve, ms));
211
469
  }
470
+ function attachRequestId(err, id) {
471
+ if (id) err.requestId = id;
472
+ return err;
473
+ }
212
474
  async function httpFetch(url, options) {
213
475
  const {
214
476
  publishableKey,
215
477
  secretKey,
216
478
  customerToken,
479
+ tenantId,
217
480
  timeout = DEFAULT_TIMEOUT,
218
481
  debug,
219
482
  retry,
@@ -243,6 +506,9 @@ async function httpFetch(url, options) {
243
506
  if (authToken) {
244
507
  headers.set("Authorization", `Bearer ${authToken}`);
245
508
  }
509
+ if (tenantId) {
510
+ headers.set("X-Tenant-Id", tenantId);
511
+ }
246
512
  if (!headers.has("Content-Type") && requestInit.body && !(requestInit.body instanceof FormData)) {
247
513
  headers.set("Content-Type", "application/json");
248
514
  }
@@ -264,6 +530,7 @@ async function httpFetch(url, options) {
264
530
  signal: controller.signal
265
531
  });
266
532
  clearTimeout(timeoutId);
533
+ const requestId = response.headers.get("x-request-id") ?? void 0;
267
534
  debugLog(debug, "response", url, {
268
535
  status: response.status,
269
536
  statusText: response.statusText,
@@ -283,15 +550,19 @@ async function httpFetch(url, options) {
283
550
  response.headers.get("X-Usage-Remaining") || "0",
284
551
  10
285
552
  );
286
- throw createUsageLimitError(
287
- `Monthly API usage limit exceeded (${current.toLocaleString()}/${limit.toLocaleString()})`,
288
- { limit, current, remaining },
289
- { url, method: requestInit.method || "GET", attempt: attempt + 1 },
290
- "Monthly API call limit exceeded. Please upgrade your plan.",
291
- "Upgrade your tenant plan to increase the monthly API call limit."
553
+ throw attachRequestId(
554
+ createUsageLimitError(
555
+ `Monthly API usage limit exceeded (${current.toLocaleString()}/${limit.toLocaleString()})`,
556
+ { limit, current, remaining },
557
+ { url, method: requestInit.method || "GET", attempt: attempt + 1 },
558
+ "Monthly API call limit exceeded. Please upgrade your plan.",
559
+ "Upgrade your tenant plan to increase the monthly API call limit."
560
+ ),
561
+ requestId
292
562
  );
293
563
  }
294
- if (response.status === 401 && onUnauthorized && customerToken && !hasRetried401) {
564
+ const parsed = await parseErrorBody(response);
565
+ if (response.status === 401 && onUnauthorized && customerToken && !hasRetried401 && parsed.reason === "token_expired") {
295
566
  hasRetried401 = true;
296
567
  try {
297
568
  const newToken = await onUnauthorized();
@@ -302,29 +573,32 @@ async function httpFetch(url, options) {
302
573
  } catch {
303
574
  }
304
575
  }
576
+ const details = {
577
+ url,
578
+ method: requestInit.method || "GET",
579
+ attempt: attempt + 1
580
+ };
305
581
  if (NON_RETRYABLE_STATUSES.includes(response.status)) {
306
- const parsed2 = await parseErrorBody(response);
307
- const details = {
308
- url,
309
- method: requestInit.method || "GET",
310
- attempt: attempt + 1,
311
- ...parsed2.errors && { errors: parsed2.errors }
312
- };
313
- throw createNetworkError(
314
- parsed2.errorMessage,
582
+ throw attachRequestId(
583
+ createNetworkError(
584
+ parsed.errorMessage,
585
+ response.status,
586
+ { ...details, ...parsed.errors && { errors: parsed.errors } },
587
+ parsed.userMessage,
588
+ getErrorSuggestion(response.status)
589
+ ),
590
+ requestId
591
+ );
592
+ }
593
+ const error = attachRequestId(
594
+ createNetworkError(
595
+ parsed.errorMessage,
315
596
  response.status,
316
597
  details,
317
- parsed2.userMessage,
598
+ parsed.userMessage,
318
599
  getErrorSuggestion(response.status)
319
- );
320
- }
321
- const parsed = await parseErrorBody(response);
322
- const error = createNetworkError(
323
- parsed.errorMessage,
324
- response.status,
325
- { url, method: requestInit.method || "GET", attempt: attempt + 1 },
326
- parsed.userMessage,
327
- getErrorSuggestion(response.status)
600
+ ),
601
+ requestId
328
602
  );
329
603
  const method = (requestInit.method || "GET").toUpperCase();
330
604
  if (attempt < retryConfig.maxRetries && SAFE_METHODS.includes(method) && retryConfig.retryableStatuses.includes(response.status)) {
@@ -372,417 +646,51 @@ async function httpFetch(url, options) {
372
646
  }
373
647
  if (error instanceof NetworkError || error instanceof TimeoutError) {
374
648
  if (isSafe && attempt < retryConfig.maxRetries && error.status && !NON_RETRYABLE_STATUSES.includes(error.status) && retryConfig.retryableStatuses.includes(error.status)) {
375
- lastError = error;
376
- await delay(retryConfig.retryDelay(attempt));
377
- continue;
378
- }
379
- throw error;
380
- }
381
- if (error instanceof SDKError) {
382
- throw error;
383
- }
384
- const unknownError = createNetworkError(
385
- error instanceof Error ? error.message : "An unknown network error occurred.",
386
- void 0,
387
- { url, originalError: error, attempt: attempt + 1 },
388
- "An unknown error occurred.",
389
- "Please try again later."
390
- );
391
- if (isSafe && attempt < retryConfig.maxRetries) {
392
- lastError = unknownError;
393
- await delay(retryConfig.retryDelay(attempt));
394
- continue;
395
- }
396
- throw unknownError;
397
- }
398
- }
399
- throw lastError ?? new NetworkError("Request failed after retries");
400
- }
401
-
402
- // src/core/api/parse-response.ts
403
- async function parseApiResponse(response, endpoint) {
404
- let data;
405
- try {
406
- data = await response.json();
407
- } catch {
408
- throw createApiError(
409
- `Invalid JSON response from ${endpoint}`,
410
- response.status,
411
- void 0,
412
- "Server returned an invalid response.",
413
- "Check if the API endpoint is available."
414
- );
415
- }
416
- if (data.error) {
417
- const errorMessage = typeof data.error === "string" ? data.error : "Unknown API error";
418
- throw createApiError(
419
- errorMessage,
420
- response.status,
421
- data,
422
- errorMessage,
423
- "An error occurred while processing the request."
424
- );
425
- }
426
- return data;
427
- }
428
-
429
- // src/core/api/base-api.ts
430
- var BaseApi = class {
431
- constructor(apiName, options) {
432
- if (!options.secretKey) {
433
- throw createConfigError(`secretKey is required for ${apiName}.`);
434
- }
435
- this.publishableKey = options.publishableKey ?? "";
436
- this.secretKey = options.secretKey;
437
- }
438
- async request(endpoint, body, options) {
439
- const method = options?.method ?? "POST";
440
- const response = await httpFetch(endpoint, {
441
- method,
442
- publishableKey: this.publishableKey,
443
- secretKey: this.secretKey,
444
- ...body !== void 0 && { body: JSON.stringify(body) },
445
- ...options?.headers && { headers: options.headers }
446
- });
447
- return parseApiResponse(response, endpoint);
448
- }
449
- };
450
-
451
- // src/core/api/order-api.ts
452
- var OrderApi = class extends BaseApi {
453
- constructor(options) {
454
- super("OrderApi", options);
455
- }
456
- createOrder(params) {
457
- return this.request("/api/orders/create", params);
458
- }
459
- updateOrder(params) {
460
- return this.request("/api/orders/update", params);
461
- }
462
- getOrder(params) {
463
- return this.request("/api/orders/get", params);
464
- }
465
- updateTransaction(params) {
466
- return this.request("/api/transactions/update", params);
467
- }
468
- checkout(params) {
469
- return this.request("/api/orders/checkout", params);
470
- }
471
- createFulfillment(params) {
472
- return this.request("/api/orders/create-fulfillment", params);
473
- }
474
- updateFulfillment(params) {
475
- return this.request("/api/orders/update-fulfillment", params);
476
- }
477
- returnWithRefund(params) {
478
- return this.request(
479
- "/api/returns/return-refund",
480
- params
481
- );
482
- }
483
- createReturn(params) {
484
- return this.request("/api/returns/create", params);
485
- }
486
- updateReturn(params) {
487
- return this.request("/api/returns/update", params);
488
- }
489
- validateDiscount(params) {
490
- return this.request(
491
- "/api/discounts/validate",
492
- params
493
- );
494
- }
495
- calculateShipping(params) {
496
- return this.request(
497
- "/api/shipping-policies/calculate",
498
- params
499
- );
500
- }
501
- };
502
-
503
- // src/core/api/cart-api.ts
504
- var CartApi = class {
505
- constructor(options) {
506
- if (!options.secretKey && !options.customerToken) {
507
- throw createConfigError(
508
- "Either secretKey or customerToken is required for CartApi."
509
- );
510
- }
511
- this.publishableKey = options.publishableKey ?? "";
512
- this.secretKey = options.secretKey;
513
- this.customerToken = options.customerToken;
514
- this.onUnauthorized = options.onUnauthorized;
515
- }
516
- async execute(endpoint, method, body) {
517
- const token = typeof this.customerToken === "function" ? this.customerToken() : this.customerToken;
518
- const response = await httpFetch(endpoint, {
519
- method,
520
- publishableKey: this.publishableKey,
521
- secretKey: this.secretKey,
522
- customerToken: token ?? void 0,
523
- ...token && this.onUnauthorized && { onUnauthorized: this.onUnauthorized },
524
- ...body !== void 0 && { body: JSON.stringify(body) }
525
- });
526
- return parseApiResponse(response, endpoint);
527
- }
528
- getCart(cartId) {
529
- return this.execute(`/api/carts/${cartId}`, "GET");
530
- }
531
- addItem(params) {
532
- return this.execute("/api/carts/add-item", "POST", params);
533
- }
534
- updateItem(params) {
535
- return this.execute("/api/carts/update-item", "POST", params);
536
- }
537
- removeItem(params) {
538
- return this.execute(
539
- "/api/carts/remove-item",
540
- "POST",
541
- params
542
- );
543
- }
544
- applyDiscount(params) {
545
- return this.execute("/api/carts/apply-discount", "POST", params);
546
- }
547
- removeDiscount(params) {
548
- return this.execute("/api/carts/remove-discount", "POST", params);
549
- }
550
- clearCart(params) {
551
- return this.execute(
552
- "/api/carts/clear",
553
- "POST",
554
- params
555
- );
556
- }
557
- };
558
-
559
- // src/core/api/product-api.ts
560
- var ProductApi = class extends BaseApi {
561
- constructor(options) {
562
- super("ProductApi", options);
563
- }
564
- stockCheck(params) {
565
- return this.request("/api/products/stock-check", params);
566
- }
567
- listingGroups(params) {
568
- return this.request(
569
- "/api/products/listing-groups",
570
- params
571
- );
572
- }
573
- };
574
-
575
- // src/utils/types.ts
576
- var resolveRelation = (ref) => {
577
- if (typeof ref === "string" || typeof ref === "number" || ref === null || ref === void 0)
578
- return null;
579
- return ref;
580
- };
581
-
582
- // src/core/metadata/index.ts
583
- function extractSeo(doc) {
584
- const seo = doc.seo ?? {};
585
- const og = seo.openGraph ?? {};
586
- return {
587
- title: seo.title ?? doc.title ?? null,
588
- description: seo.description ?? null,
589
- noIndex: seo.noIndex ?? null,
590
- canonical: seo.canonical ?? null,
591
- openGraph: {
592
- title: og.title ?? null,
593
- description: og.description ?? null,
594
- image: og.image ?? null
595
- }
596
- };
597
- }
598
- function generateMetadata(input, options) {
599
- const title = input.title ?? void 0;
600
- const description = input.description ?? void 0;
601
- const ogTitle = input.openGraph?.title ?? title;
602
- const ogDescription = input.openGraph?.description ?? description;
603
- const image = resolveMetaImage(input.openGraph?.image);
604
- return {
605
- title,
606
- description,
607
- ...input.noIndex && { robots: { index: false, follow: false } },
608
- ...input.canonical && { alternates: { canonical: input.canonical } },
609
- openGraph: {
610
- ...ogTitle && { title: ogTitle },
611
- ...ogDescription && { description: ogDescription },
612
- ...options?.siteName && { siteName: options.siteName },
613
- ...image && { images: [image] }
614
- },
615
- twitter: {
616
- card: image ? "summary_large_image" : "summary",
617
- ...ogTitle && { title: ogTitle },
618
- ...ogDescription && { description: ogDescription },
619
- ...image && { images: [image.url] }
620
- }
621
- };
622
- }
623
- function resolveMetaImage(ref) {
624
- const image = resolveRelation(ref);
625
- if (!image) return null;
626
- const sized = image.sizes?.["1536"];
627
- const url = sized?.url || image.url;
628
- if (!url) return null;
629
- const width = sized?.url ? sized.width : image.width;
630
- const height = sized?.url ? sized.height : image.height;
631
- return {
632
- url,
633
- ...width && { width },
634
- ...height && { height },
635
- ...image.alt && { alt: image.alt }
636
- };
637
- }
638
-
639
- // src/core/collection/query-builder.ts
640
- var CollectionQueryBuilder = class {
641
- constructor(api, collection) {
642
- this.api = api;
643
- this.collection = collection;
644
- }
645
- /**
646
- * Find documents (list query)
647
- * GET /api/{collection}
648
- * @returns Payload CMS find response with docs array and pagination
649
- */
650
- async find(options) {
651
- return this.api.requestFind(
652
- `/api/${String(this.collection)}`,
653
- options
654
- );
655
- }
656
- /**
657
- * Find document by ID
658
- * GET /api/{collection}/{id}
659
- * @returns Document object directly (no wrapper)
660
- */
661
- async findById(id, options) {
662
- return this.api.requestFindById(
663
- `/api/${String(this.collection)}/${String(id)}`,
664
- options
665
- );
666
- }
667
- /**
668
- * Create a new document
669
- * POST /api/{collection}
670
- * @returns Payload CMS mutation response with doc and message
671
- */
672
- async create(data, options) {
673
- const endpoint = `/api/${String(this.collection)}`;
674
- if (options?.file) {
675
- return this.api.requestCreateWithFile(
676
- endpoint,
677
- data,
678
- options.file,
679
- options.filename
680
- );
681
- }
682
- return this.api.requestCreate(endpoint, data);
683
- }
684
- /**
685
- * Update a document by ID
686
- * PATCH /api/{collection}/{id}
687
- * @returns Payload CMS mutation response with doc and message
688
- */
689
- async update(id, data, options) {
690
- const endpoint = `/api/${String(this.collection)}/${String(id)}`;
691
- if (options?.file) {
692
- return this.api.requestUpdateWithFile(
693
- endpoint,
694
- data,
695
- options.file,
696
- options.filename
697
- );
698
- }
699
- return this.api.requestUpdate(endpoint, data);
700
- }
701
- /**
702
- * Count documents
703
- * GET /api/{collection}/count
704
- * @returns Count response with totalDocs
705
- */
706
- async count(options) {
707
- return this.api.requestCount(
708
- `/api/${String(this.collection)}/count`,
709
- options
710
- );
711
- }
712
- /**
713
- * Find first matching document and return its Next.js Metadata.
714
- * Applies depth: 1 (SEO image populate) and limit: 1 automatically.
715
- * @returns Metadata or null if no document matches
716
- */
717
- async findMetadata(options, metadataOptions) {
718
- const { docs } = await this.find({ ...options, limit: 1, depth: 1 });
719
- const doc = docs[0];
720
- if (!doc) return null;
721
- return generateMetadata(
722
- extractSeo(doc),
723
- metadataOptions
724
- );
725
- }
726
- /**
727
- * Find document by ID and return its Next.js Metadata.
728
- * Applies depth: 1 (SEO image populate) automatically.
729
- * @returns Metadata (throws on 404)
730
- */
731
- async findMetadataById(id, metadataOptions) {
732
- const doc = await this.findById(id, { depth: 1 });
733
- return generateMetadata(
734
- extractSeo(doc),
735
- metadataOptions
736
- );
737
- }
738
- /**
739
- * Update multiple documents (bulk update)
740
- * PATCH /api/{collection}
741
- * @returns Payload CMS find response with updated docs
742
- */
743
- async updateMany(where, data) {
744
- return this.api.requestUpdateMany(
745
- `/api/${String(this.collection)}`,
746
- { where, data }
747
- );
748
- }
749
- /**
750
- * Delete a document by ID
751
- * DELETE /api/{collection}/{id}
752
- * @returns Deleted document object directly (no wrapper)
753
- */
754
- async remove(id) {
755
- return this.api.requestDelete(
756
- `/api/${String(this.collection)}/${String(id)}`
757
- );
758
- }
759
- /**
760
- * Delete multiple documents (bulk delete)
761
- * DELETE /api/{collection}
762
- * @returns Payload CMS find response with deleted docs
763
- */
764
- async removeMany(where) {
765
- return this.api.requestDeleteMany(
766
- `/api/${String(this.collection)}`,
767
- { where }
768
- );
649
+ lastError = error;
650
+ await delay(retryConfig.retryDelay(attempt));
651
+ continue;
652
+ }
653
+ throw error;
654
+ }
655
+ if (error instanceof SDKError) {
656
+ throw error;
657
+ }
658
+ const unknownError = createNetworkError(
659
+ error instanceof Error ? error.message : "An unknown network error occurred.",
660
+ void 0,
661
+ { url, originalError: error, attempt: attempt + 1 },
662
+ "An unknown error occurred.",
663
+ "Please try again later."
664
+ );
665
+ if (isSafe && attempt < retryConfig.maxRetries) {
666
+ lastError = unknownError;
667
+ await delay(retryConfig.retryDelay(attempt));
668
+ continue;
669
+ }
670
+ throw unknownError;
671
+ }
769
672
  }
770
- };
673
+ throw lastError ?? new NetworkError("Request failed after retries");
674
+ }
771
675
 
772
676
  // src/core/collection/http-client.ts
773
- import { stringify } from "qs-esm";
774
677
  var HttpClient = class {
775
- constructor(publishableKey, secretKey, getCustomerToken, onUnauthorized) {
678
+ constructor(publishableKey, secretKey, getCustomerToken, onUnauthorized, onRequestId, tenantId) {
776
679
  this.publishableKey = publishableKey;
777
680
  this.secretKey = secretKey;
681
+ this.tenantId = tenantId;
778
682
  this.getCustomerToken = getCustomerToken;
779
683
  this.onUnauthorized = onUnauthorized;
684
+ this.onRequestId = onRequestId;
780
685
  }
781
686
  get defaultOptions() {
782
687
  const opts = {
783
688
  publishableKey: this.publishableKey,
784
689
  secretKey: this.secretKey
785
690
  };
691
+ if (this.secretKey?.startsWith("pat01_") && this.tenantId) {
692
+ opts.tenantId = this.tenantId;
693
+ }
786
694
  const token = this.getCustomerToken?.();
787
695
  if (token) {
788
696
  opts.customerToken = token;
@@ -792,6 +700,17 @@ var HttpClient = class {
792
700
  }
793
701
  return opts;
794
702
  }
703
+ async fetchWithTracking(url, opts) {
704
+ try {
705
+ const response = await httpFetch(url, opts);
706
+ this.onRequestId?.(response.headers.get("x-request-id") ?? null);
707
+ return response;
708
+ } catch (err) {
709
+ const id = err instanceof SDKError ? err.requestId ?? null : null;
710
+ this.onRequestId?.(id);
711
+ throw err;
712
+ }
713
+ }
795
714
  buildUrl(endpoint, options) {
796
715
  if (!options) return endpoint;
797
716
  const queryString = stringify(options, { addQueryPrefix: true });
@@ -908,7 +827,7 @@ var CollectionClient = class extends HttpClient {
908
827
  */
909
828
  async requestFind(endpoint, options) {
910
829
  const url = this.buildUrl(endpoint, options);
911
- const response = await httpFetch(url, {
830
+ const response = await this.fetchWithTracking(url, {
912
831
  ...this.defaultOptions,
913
832
  method: "GET"
914
833
  });
@@ -919,7 +838,7 @@ var CollectionClient = class extends HttpClient {
919
838
  * POST /api/...custom-endpoint
920
839
  */
921
840
  async requestFindEndpoint(endpoint, data) {
922
- const response = await httpFetch(endpoint, {
841
+ const response = await this.fetchWithTracking(endpoint, {
923
842
  ...this.defaultOptions,
924
843
  method: "POST",
925
844
  body: data ? JSON.stringify(data) : void 0
@@ -932,7 +851,7 @@ var CollectionClient = class extends HttpClient {
932
851
  */
933
852
  async requestFindById(endpoint, options) {
934
853
  const url = this.buildUrl(endpoint, options);
935
- const response = await httpFetch(url, {
854
+ const response = await this.fetchWithTracking(url, {
936
855
  ...this.defaultOptions,
937
856
  method: "GET"
938
857
  });
@@ -943,7 +862,7 @@ var CollectionClient = class extends HttpClient {
943
862
  * POST /api/{collection}
944
863
  */
945
864
  async requestCreate(endpoint, data) {
946
- const response = await httpFetch(endpoint, {
865
+ const response = await this.fetchWithTracking(endpoint, {
947
866
  ...this.defaultOptions,
948
867
  method: "POST",
949
868
  body: data ? JSON.stringify(data) : void 0
@@ -955,7 +874,7 @@ var CollectionClient = class extends HttpClient {
955
874
  * PATCH /api/{collection}/{id}
956
875
  */
957
876
  async requestUpdate(endpoint, data) {
958
- const response = await httpFetch(endpoint, {
877
+ const response = await this.fetchWithTracking(endpoint, {
959
878
  ...this.defaultOptions,
960
879
  method: "PATCH",
961
880
  body: data ? JSON.stringify(data) : void 0
@@ -968,7 +887,7 @@ var CollectionClient = class extends HttpClient {
968
887
  */
969
888
  async requestCount(endpoint, options) {
970
889
  const url = this.buildUrl(endpoint, options);
971
- const response = await httpFetch(url, {
890
+ const response = await this.fetchWithTracking(url, {
972
891
  ...this.defaultOptions,
973
892
  method: "GET"
974
893
  });
@@ -979,7 +898,7 @@ var CollectionClient = class extends HttpClient {
979
898
  * PATCH /api/{collection}
980
899
  */
981
900
  async requestUpdateMany(endpoint, data) {
982
- const response = await httpFetch(endpoint, {
901
+ const response = await this.fetchWithTracking(endpoint, {
983
902
  ...this.defaultOptions,
984
903
  method: "PATCH",
985
904
  body: JSON.stringify(data)
@@ -991,7 +910,7 @@ var CollectionClient = class extends HttpClient {
991
910
  * DELETE /api/{collection}/{id}
992
911
  */
993
912
  async requestDelete(endpoint) {
994
- const response = await httpFetch(endpoint, {
913
+ const response = await this.fetchWithTracking(endpoint, {
995
914
  ...this.defaultOptions,
996
915
  method: "DELETE"
997
916
  });
@@ -1002,7 +921,7 @@ var CollectionClient = class extends HttpClient {
1002
921
  * DELETE /api/{collection}
1003
922
  */
1004
923
  async requestDeleteMany(endpoint, data) {
1005
- const response = await httpFetch(endpoint, {
924
+ const response = await this.fetchWithTracking(endpoint, {
1006
925
  ...this.defaultOptions,
1007
926
  method: "DELETE",
1008
927
  body: JSON.stringify(data)
@@ -1014,7 +933,7 @@ var CollectionClient = class extends HttpClient {
1014
933
  * POST /api/{collection} (multipart/form-data)
1015
934
  */
1016
935
  async requestCreateWithFile(endpoint, data, file, filename) {
1017
- const response = await httpFetch(endpoint, {
936
+ const response = await this.fetchWithTracking(endpoint, {
1018
937
  ...this.defaultOptions,
1019
938
  method: "POST",
1020
939
  body: buildPayloadFormData(data, file, filename)
@@ -1026,7 +945,7 @@ var CollectionClient = class extends HttpClient {
1026
945
  * PATCH /api/{collection}/{id} (multipart/form-data)
1027
946
  */
1028
947
  async requestUpdateWithFile(endpoint, data, file, filename) {
1029
- const response = await httpFetch(endpoint, {
948
+ const response = await this.fetchWithTracking(endpoint, {
1030
949
  ...this.defaultOptions,
1031
950
  method: "PATCH",
1032
951
  body: buildPayloadFormData(data, file, filename)
@@ -1106,49 +1025,101 @@ var COLLECTIONS = [
1106
1025
  "community-bans"
1107
1026
  ];
1108
1027
 
1028
+ // src/core/api/parse-response.ts
1029
+ async function parseApiResponse(response, endpoint) {
1030
+ let data;
1031
+ try {
1032
+ data = await response.json();
1033
+ } catch {
1034
+ throw createApiError(
1035
+ `Invalid JSON response from ${endpoint}`,
1036
+ response.status,
1037
+ void 0,
1038
+ "Server returned an invalid response.",
1039
+ "Check if the API endpoint is available."
1040
+ );
1041
+ }
1042
+ if (data.error) {
1043
+ const errorMessage = typeof data.error === "string" ? data.error : "Unknown API error";
1044
+ const reason = typeof data.reason === "string" ? data.reason : void 0;
1045
+ const requestId = response.headers.get("x-request-id") ?? void 0;
1046
+ const retryAfterRaw = response.headers.get("Retry-After");
1047
+ const retryAfter = retryAfterRaw ? parseInt(retryAfterRaw, 10) || void 0 : void 0;
1048
+ if (reason === "validation_failed") {
1049
+ throw attachRequestId(createValidationError(errorMessage, data, errorMessage), requestId);
1050
+ }
1051
+ if (reason === "token_expired" || reason === "token_invalid" || reason === "key_invalid" || reason === "key_revoked") {
1052
+ throw attachRequestId(createAuthError(errorMessage, data, errorMessage), requestId);
1053
+ }
1054
+ if (reason === "forbidden") {
1055
+ throw attachRequestId(createPermissionError(errorMessage, data, errorMessage), requestId);
1056
+ }
1057
+ if (reason === "rate_limit_exceeded") {
1058
+ throw attachRequestId(createRateLimitError(errorMessage, retryAfter, data, errorMessage), requestId);
1059
+ }
1060
+ if (reason === "not_found") {
1061
+ throw attachRequestId(createNotFoundError(errorMessage, data, errorMessage), requestId);
1062
+ }
1063
+ if (reason === "conflict") {
1064
+ throw attachRequestId(createConflictError(errorMessage, data, errorMessage), requestId);
1065
+ }
1066
+ throw attachRequestId(
1067
+ createApiError(errorMessage, response.status, data, errorMessage, "An error occurred while processing the request."),
1068
+ requestId
1069
+ );
1070
+ }
1071
+ return data;
1072
+ }
1073
+
1109
1074
  // src/core/community/community-client.ts
1110
1075
  var CommunityClient = class {
1111
1076
  constructor(options) {
1112
1077
  this.publishableKey = options.publishableKey ?? "";
1113
1078
  this.secretKey = options.secretKey;
1079
+ this.tenantId = options.tenantId;
1114
1080
  this.customerToken = options.customerToken;
1115
1081
  this.onUnauthorized = options.onUnauthorized;
1082
+ this.onRequestId = options.onRequestId;
1083
+ }
1084
+ buildQuery(params) {
1085
+ if (!params) return "";
1086
+ const entries = Object.entries(params).filter((e) => e[1] !== void 0).map(([k, v]) => [k, String(v)]);
1087
+ return entries.length ? `?${new URLSearchParams(entries).toString()}` : "";
1116
1088
  }
1117
1089
  async execute(endpoint, method, body) {
1118
1090
  const token = typeof this.customerToken === "function" ? this.customerToken() : this.customerToken;
1119
- const response = await httpFetch(endpoint, {
1120
- method,
1121
- publishableKey: this.publishableKey,
1122
- secretKey: this.secretKey,
1123
- customerToken: token ?? void 0,
1124
- ...token && this.onUnauthorized && { onUnauthorized: this.onUnauthorized },
1125
- ...body !== void 0 && { body: JSON.stringify(body) }
1126
- });
1127
- return parseApiResponse(response, endpoint);
1091
+ const tenantId = this.secretKey?.startsWith("pat01_") && this.tenantId ? this.tenantId : void 0;
1092
+ try {
1093
+ const response = await httpFetch(endpoint, {
1094
+ method,
1095
+ publishableKey: this.publishableKey,
1096
+ secretKey: this.secretKey,
1097
+ tenantId,
1098
+ customerToken: token ?? void 0,
1099
+ ...token && this.onUnauthorized && { onUnauthorized: this.onUnauthorized },
1100
+ ...body !== void 0 && { body: JSON.stringify(body) }
1101
+ });
1102
+ this.onRequestId?.(response.headers.get("x-request-id") ?? null);
1103
+ return parseApiResponse(response, endpoint);
1104
+ } catch (err) {
1105
+ const id = err instanceof SDKError ? err.requestId ?? null : null;
1106
+ this.onRequestId?.(id);
1107
+ throw err;
1108
+ }
1128
1109
  }
1129
1110
  // Threads
1130
1111
  createThread(params) {
1131
1112
  return this.execute("/api/threads", "POST", params);
1132
1113
  }
1133
1114
  getMyThreads(params) {
1134
- const query = params ? `?${new URLSearchParams(
1135
- Object.fromEntries(
1136
- Object.entries(params).map(([k, v]) => [k, String(v)])
1137
- )
1138
- ).toString()}` : "";
1139
1115
  return this.execute(
1140
- `/api/threads/my${query}`,
1116
+ `/api/threads/my${this.buildQuery(params)}`,
1141
1117
  "GET"
1142
1118
  );
1143
1119
  }
1144
1120
  getTrending(params) {
1145
- const query = params ? `?${new URLSearchParams(
1146
- Object.fromEntries(
1147
- Object.entries(params).map(([k, v]) => [k, String(v)])
1148
- )
1149
- ).toString()}` : "";
1150
1121
  return this.execute(
1151
- `/api/threads/trending${query}`,
1122
+ `/api/threads/trending${this.buildQuery(params)}`,
1152
1123
  "GET"
1153
1124
  );
1154
1125
  }
@@ -1264,26 +1235,56 @@ var CommunityClient = class {
1264
1235
  );
1265
1236
  }
1266
1237
  getMyBookmarks(params) {
1267
- const query = params ? `?${new URLSearchParams(
1268
- Object.fromEntries(
1269
- Object.entries(params).map(([k, v]) => [k, String(v)])
1270
- )
1271
- ).toString()}` : "";
1272
1238
  return this.execute(
1273
- `/api/bookmarks/my${query}`,
1239
+ `/api/bookmarks/my${this.buildQuery(params)}`,
1274
1240
  "GET"
1275
1241
  );
1276
1242
  }
1277
- // Moderation
1243
+ };
1244
+
1245
+ // src/core/api/base-api.ts
1246
+ var BaseApi = class {
1247
+ constructor(apiName, options) {
1248
+ if (!options.secretKey) {
1249
+ throw createConfigError(`secretKey is required for ${apiName}.`);
1250
+ }
1251
+ this.publishableKey = options.publishableKey ?? "";
1252
+ this.secretKey = options.secretKey;
1253
+ this.tenantId = options.tenantId;
1254
+ this.onRequestId = options.onRequestId;
1255
+ }
1256
+ async request(endpoint, body, options) {
1257
+ const method = options?.method ?? "POST";
1258
+ const tenantId = this.secretKey.startsWith("pat01_") && this.tenantId ? this.tenantId : void 0;
1259
+ try {
1260
+ const response = await httpFetch(endpoint, {
1261
+ method,
1262
+ publishableKey: this.publishableKey,
1263
+ secretKey: this.secretKey,
1264
+ tenantId,
1265
+ ...body !== void 0 && { body: JSON.stringify(body) },
1266
+ ...options?.headers && { headers: options.headers }
1267
+ });
1268
+ this.onRequestId?.(response.headers.get("x-request-id") ?? null);
1269
+ return parseApiResponse(response, endpoint);
1270
+ } catch (err) {
1271
+ const id = err instanceof SDKError ? err.requestId ?? null : null;
1272
+ this.onRequestId?.(id);
1273
+ throw err;
1274
+ }
1275
+ }
1276
+ };
1277
+
1278
+ // src/core/community/moderation-api.ts
1279
+ var ModerationApi = class extends BaseApi {
1280
+ constructor(options) {
1281
+ super("ModerationApi", options);
1282
+ }
1278
1283
  banCustomer(params) {
1279
- return this.execute("/api/community-bans/ban", "POST", params);
1284
+ return this.request("/api/community-bans/ban", params);
1280
1285
  }
1281
1286
  unbanCustomer(params) {
1282
- return this.execute(
1283
- "/api/community-bans/unban",
1284
- "DELETE",
1285
- params
1286
- );
1287
+ return this.request("/api/community-bans/unban", params);
1287
1288
  }
1288
1289
  };
1289
1290
 
@@ -1538,6 +1539,265 @@ var CustomerAuth = class {
1538
1539
  }
1539
1540
  };
1540
1541
 
1542
+ // src/core/customer/customer-namespace.ts
1543
+ var CustomerNamespace = class {
1544
+ constructor(publishableKey, options) {
1545
+ this.auth = new CustomerAuth(publishableKey, options);
1546
+ }
1547
+ };
1548
+
1549
+ // src/core/api/cart-api.ts
1550
+ var CartApi = class {
1551
+ constructor(options) {
1552
+ if (!options.secretKey && !options.customerToken) {
1553
+ throw createConfigError(
1554
+ "Either secretKey or customerToken is required for CartApi."
1555
+ );
1556
+ }
1557
+ this.publishableKey = options.publishableKey ?? "";
1558
+ this.secretKey = options.secretKey;
1559
+ this.tenantId = options.tenantId;
1560
+ this.customerToken = options.customerToken;
1561
+ this.onUnauthorized = options.onUnauthorized;
1562
+ this.onRequestId = options.onRequestId;
1563
+ }
1564
+ async execute(endpoint, method, body) {
1565
+ const token = typeof this.customerToken === "function" ? this.customerToken() : this.customerToken;
1566
+ const tenantId = this.secretKey?.startsWith("pat01_") && this.tenantId ? this.tenantId : void 0;
1567
+ try {
1568
+ const response = await httpFetch(endpoint, {
1569
+ method,
1570
+ publishableKey: this.publishableKey,
1571
+ secretKey: this.secretKey,
1572
+ tenantId,
1573
+ customerToken: token ?? void 0,
1574
+ ...token && this.onUnauthorized && { onUnauthorized: this.onUnauthorized },
1575
+ ...body !== void 0 && { body: JSON.stringify(body) }
1576
+ });
1577
+ this.onRequestId?.(response.headers.get("x-request-id") ?? null);
1578
+ return parseApiResponse(response, endpoint);
1579
+ } catch (err) {
1580
+ const id = err instanceof SDKError ? err.requestId ?? null : null;
1581
+ this.onRequestId?.(id);
1582
+ throw err;
1583
+ }
1584
+ }
1585
+ getCart(cartId) {
1586
+ return this.execute(`/api/carts/${cartId}`, "GET");
1587
+ }
1588
+ addItem(params) {
1589
+ return this.execute("/api/carts/add-item", "POST", params);
1590
+ }
1591
+ updateItem(params) {
1592
+ return this.execute("/api/carts/update-item", "POST", params);
1593
+ }
1594
+ removeItem(params) {
1595
+ return this.execute(
1596
+ "/api/carts/remove-item",
1597
+ "POST",
1598
+ params
1599
+ );
1600
+ }
1601
+ applyDiscount(params) {
1602
+ return this.execute("/api/carts/apply-discount", "POST", params);
1603
+ }
1604
+ removeDiscount(params) {
1605
+ return this.execute("/api/carts/remove-discount", "POST", params);
1606
+ }
1607
+ clearCart(params) {
1608
+ return this.execute(
1609
+ "/api/carts/clear",
1610
+ "POST",
1611
+ params
1612
+ );
1613
+ }
1614
+ };
1615
+
1616
+ // src/core/commerce/commerce-client.ts
1617
+ var CommerceClient = class {
1618
+ constructor(options) {
1619
+ const cartApi = new CartApi({
1620
+ publishableKey: options.publishableKey,
1621
+ customerToken: options.customerToken,
1622
+ onUnauthorized: options.onUnauthorized,
1623
+ onRequestId: options.onRequestId
1624
+ });
1625
+ const execute = async (endpoint, body) => {
1626
+ const token = options.customerToken();
1627
+ try {
1628
+ const response = await httpFetch(endpoint, {
1629
+ method: "POST",
1630
+ publishableKey: options.publishableKey,
1631
+ customerToken: token ?? void 0,
1632
+ ...token && options.onUnauthorized && { onUnauthorized: options.onUnauthorized },
1633
+ body: JSON.stringify(body)
1634
+ });
1635
+ options.onRequestId?.(response.headers.get("x-request-id") ?? null);
1636
+ return parseApiResponse(response, endpoint);
1637
+ } catch (err) {
1638
+ const id = err instanceof SDKError ? err.requestId ?? null : null;
1639
+ options.onRequestId?.(id);
1640
+ throw err;
1641
+ }
1642
+ };
1643
+ this.product = {
1644
+ stockCheck: (params) => execute("/api/products/stock-check", params),
1645
+ listingGroups: (params) => execute("/api/products/listing-groups", params)
1646
+ };
1647
+ this.cart = {
1648
+ get: cartApi.getCart.bind(cartApi),
1649
+ addItem: cartApi.addItem.bind(cartApi),
1650
+ updateItem: cartApi.updateItem.bind(cartApi),
1651
+ removeItem: cartApi.removeItem.bind(cartApi),
1652
+ applyDiscount: cartApi.applyDiscount.bind(cartApi),
1653
+ removeDiscount: cartApi.removeDiscount.bind(cartApi),
1654
+ clear: cartApi.clearCart.bind(cartApi)
1655
+ };
1656
+ this.orders = {
1657
+ checkout: (params) => execute("/api/orders/checkout", params),
1658
+ listMine: (params) => options.customerAuth.getMyOrders(params)
1659
+ };
1660
+ this.discounts = {
1661
+ validate: (params) => execute("/api/discounts/validate", params)
1662
+ };
1663
+ this.shipping = {
1664
+ calculate: (params) => execute("/api/shipping-policies/calculate", params)
1665
+ };
1666
+ }
1667
+ };
1668
+
1669
+ // src/core/api/product-api.ts
1670
+ var ProductApi = class extends BaseApi {
1671
+ constructor(options) {
1672
+ super("ProductApi", options);
1673
+ }
1674
+ /**
1675
+ * Check point-in-time stock availability for one or more product variants.
1676
+ * Results reflect available stock at the moment of the call and are not guaranteed
1677
+ * to remain available by the time an order is placed.
1678
+ */
1679
+ stockCheck(params) {
1680
+ return this.request("/api/products/stock-check", params);
1681
+ }
1682
+ listingGroups(params) {
1683
+ return this.request(
1684
+ "/api/products/listing-groups",
1685
+ params
1686
+ );
1687
+ }
1688
+ };
1689
+
1690
+ // src/core/api/discount-api.ts
1691
+ var DiscountApi = class extends BaseApi {
1692
+ constructor(options) {
1693
+ super("DiscountApi", options);
1694
+ }
1695
+ validate(params) {
1696
+ return this.request("/api/discounts/validate", params);
1697
+ }
1698
+ };
1699
+
1700
+ // src/core/api/shipping-api.ts
1701
+ var ShippingApi = class extends BaseApi {
1702
+ constructor(options) {
1703
+ super("ShippingApi", options);
1704
+ }
1705
+ calculate(params) {
1706
+ return this.request("/api/shipping-policies/calculate", params);
1707
+ }
1708
+ };
1709
+
1710
+ // src/core/api/order-api.ts
1711
+ var OrderApi = class extends BaseApi {
1712
+ constructor(options) {
1713
+ super("OrderApi", options);
1714
+ }
1715
+ createOrder(params) {
1716
+ return this.request("/api/orders/create", params);
1717
+ }
1718
+ updateOrder(params) {
1719
+ return this.request("/api/orders/update", params);
1720
+ }
1721
+ updateTransaction(params) {
1722
+ return this.request("/api/transactions/update", params);
1723
+ }
1724
+ checkout(params) {
1725
+ return this.request("/api/orders/checkout", params);
1726
+ }
1727
+ createFulfillment(params) {
1728
+ return this.request("/api/orders/create-fulfillment", params);
1729
+ }
1730
+ updateFulfillment(params) {
1731
+ return this.request("/api/orders/update-fulfillment", params);
1732
+ }
1733
+ bulkImportFulfillments(params) {
1734
+ return this.request(
1735
+ "/api/orders/bulk-import-fulfillments",
1736
+ params
1737
+ );
1738
+ }
1739
+ returnWithRefund(params) {
1740
+ return this.request(
1741
+ "/api/returns/return-refund",
1742
+ params
1743
+ );
1744
+ }
1745
+ createReturn(params) {
1746
+ return this.request("/api/returns/create", params);
1747
+ }
1748
+ updateReturn(params) {
1749
+ return this.request("/api/returns/update", params);
1750
+ }
1751
+ };
1752
+
1753
+ // src/core/commerce/server-commerce-client.ts
1754
+ var ServerCommerceClient = class {
1755
+ constructor(options) {
1756
+ const serverOptions = {
1757
+ publishableKey: options.publishableKey,
1758
+ secretKey: options.secretKey,
1759
+ tenantId: options.tenantId,
1760
+ onRequestId: options.onRequestId
1761
+ };
1762
+ const productApi = new ProductApi(serverOptions);
1763
+ const cartApi = new CartApi(serverOptions);
1764
+ const discountApi = new DiscountApi(serverOptions);
1765
+ const shippingApi = new ShippingApi(serverOptions);
1766
+ const orderApi = new OrderApi(serverOptions);
1767
+ this.product = {
1768
+ stockCheck: productApi.stockCheck.bind(productApi),
1769
+ listingGroups: productApi.listingGroups.bind(productApi)
1770
+ };
1771
+ this.cart = {
1772
+ get: cartApi.getCart.bind(cartApi),
1773
+ addItem: cartApi.addItem.bind(cartApi),
1774
+ updateItem: cartApi.updateItem.bind(cartApi),
1775
+ removeItem: cartApi.removeItem.bind(cartApi),
1776
+ applyDiscount: cartApi.applyDiscount.bind(cartApi),
1777
+ removeDiscount: cartApi.removeDiscount.bind(cartApi),
1778
+ clear: cartApi.clearCart.bind(cartApi)
1779
+ };
1780
+ this.orders = {
1781
+ checkout: orderApi.checkout.bind(orderApi),
1782
+ create: orderApi.createOrder.bind(orderApi),
1783
+ update: orderApi.updateOrder.bind(orderApi),
1784
+ updateTransaction: orderApi.updateTransaction.bind(orderApi),
1785
+ createFulfillment: orderApi.createFulfillment.bind(orderApi),
1786
+ updateFulfillment: orderApi.updateFulfillment.bind(orderApi),
1787
+ bulkImportFulfillments: orderApi.bulkImportFulfillments.bind(orderApi),
1788
+ createReturn: orderApi.createReturn.bind(orderApi),
1789
+ updateReturn: orderApi.updateReturn.bind(orderApi),
1790
+ returnWithRefund: orderApi.returnWithRefund.bind(orderApi)
1791
+ };
1792
+ this.discounts = {
1793
+ validate: discountApi.validate.bind(discountApi)
1794
+ };
1795
+ this.shipping = {
1796
+ calculate: shippingApi.calculate.bind(shippingApi)
1797
+ };
1798
+ }
1799
+ };
1800
+
1541
1801
  // src/core/query/get-query-client.ts
1542
1802
  import {
1543
1803
  isServer,
@@ -2083,6 +2343,7 @@ var QueryHooks = class extends CollectionHooks {
2083
2343
  // src/core/client/client.ts
2084
2344
  var Client = class {
2085
2345
  constructor(options) {
2346
+ this.lastRequestId = null;
2086
2347
  const publishableKey = options.publishableKey;
2087
2348
  if (!publishableKey) {
2088
2349
  throw createConfigError("publishableKey is required.");
@@ -2094,43 +2355,47 @@ var Client = class {
2094
2355
  };
2095
2356
  this.state = { metadata };
2096
2357
  this.queryClient = getQueryClient();
2097
- this.customer = new CustomerAuth(
2358
+ this.customer = new CustomerNamespace(
2098
2359
  this.config.publishableKey,
2099
2360
  options.customer
2100
2361
  );
2101
2362
  const onUnauthorized = async () => {
2102
2363
  try {
2103
- const result = await this.customer.refreshToken();
2364
+ const result = await this.customer.auth.refreshToken();
2104
2365
  return result.token ?? null;
2105
2366
  } catch {
2106
2367
  return null;
2107
2368
  }
2108
2369
  };
2109
- this.cart = new CartApi({
2370
+ const onRequestId = (id) => {
2371
+ this.lastRequestId = id;
2372
+ };
2373
+ this.commerce = new CommerceClient({
2110
2374
  publishableKey: this.config.publishableKey,
2111
- customerToken: () => this.customer.getToken(),
2112
- onUnauthorized
2375
+ customerToken: () => this.customer.auth.getToken(),
2376
+ onUnauthorized,
2377
+ onRequestId,
2378
+ customerAuth: this.customer.auth
2113
2379
  });
2114
2380
  this.community = new CommunityClient({
2115
2381
  publishableKey: this.config.publishableKey,
2116
- customerToken: () => this.customer.getToken(),
2117
- onUnauthorized
2382
+ customerToken: () => this.customer.auth.getToken(),
2383
+ onUnauthorized,
2384
+ onRequestId
2118
2385
  });
2119
2386
  this.collections = new CollectionClient(
2120
2387
  this.config.publishableKey,
2121
2388
  void 0,
2122
- () => this.customer.getToken(),
2123
- onUnauthorized
2389
+ () => this.customer.auth.getToken(),
2390
+ onUnauthorized,
2391
+ onRequestId
2124
2392
  );
2125
2393
  this.query = new QueryHooks(
2126
2394
  this.queryClient,
2127
2395
  this.collections,
2128
- this.customer
2396
+ this.customer.auth
2129
2397
  );
2130
2398
  }
2131
- from(collection) {
2132
- return this.collections.from(collection);
2133
- }
2134
2399
  getState() {
2135
2400
  return { ...this.state };
2136
2401
  }
@@ -2145,6 +2410,7 @@ function createClient(options) {
2145
2410
  // src/core/client/client.server.ts
2146
2411
  var ServerClient = class {
2147
2412
  constructor(options) {
2413
+ this.lastRequestId = null;
2148
2414
  if (typeof window !== "undefined") {
2149
2415
  throw createConfigError(
2150
2416
  "ServerClient must not be used in a browser environment. This risks exposing your secretKey in client bundles. Use createClient() for browser code instead."
@@ -2164,32 +2430,35 @@ var ServerClient = class {
2164
2430
  userAgent: "Node.js"
2165
2431
  };
2166
2432
  this.state = { metadata };
2167
- this.api = new OrderApi({
2168
- publishableKey: this.config.publishableKey,
2169
- secretKey: this.config.secretKey
2170
- });
2171
- this.cart = new CartApi({
2172
- publishableKey: this.config.publishableKey,
2173
- secretKey: this.config.secretKey
2174
- });
2175
- this.community = new CommunityClient({
2176
- publishableKey: this.config.publishableKey,
2177
- secretKey: this.config.secretKey
2178
- });
2179
- this.product = new ProductApi({
2433
+ const onRequestId = (id) => {
2434
+ this.lastRequestId = id;
2435
+ };
2436
+ const serverOptions = {
2180
2437
  publishableKey: this.config.publishableKey,
2181
- secretKey: this.config.secretKey
2438
+ secretKey: this.config.secretKey,
2439
+ tenantId: this.config.tenantId,
2440
+ onRequestId
2441
+ };
2442
+ this.commerce = new ServerCommerceClient(serverOptions);
2443
+ const communityClient = new CommunityClient(serverOptions);
2444
+ const moderationApi = new ModerationApi(serverOptions);
2445
+ this.community = Object.assign(communityClient, {
2446
+ moderation: {
2447
+ banCustomer: moderationApi.banCustomer.bind(moderationApi),
2448
+ unbanCustomer: moderationApi.unbanCustomer.bind(moderationApi)
2449
+ }
2182
2450
  });
2183
2451
  this.collections = new CollectionClient(
2184
2452
  this.config.publishableKey,
2185
- this.config.secretKey
2453
+ this.config.secretKey,
2454
+ void 0,
2455
+ void 0,
2456
+ onRequestId,
2457
+ this.config.tenantId
2186
2458
  );
2187
2459
  this.queryClient = getQueryClient();
2188
2460
  this.query = new QueryHooks(this.queryClient, this.collections);
2189
2461
  }
2190
- from(collection) {
2191
- return this.collections.from(collection);
2192
- }
2193
2462
  getState() {
2194
2463
  return { ...this.state };
2195
2464
  }
@@ -2768,6 +3037,7 @@ function getVideoMp4Url(playbackId, resolution = "high") {
2768
3037
  }
2769
3038
  export {
2770
3039
  ApiError,
3040
+ AuthError,
2771
3041
  BaseApi,
2772
3042
  COLLECTIONS,
2773
3043
  CartApi,
@@ -2775,20 +3045,30 @@ export {
2775
3045
  CollectionClient,
2776
3046
  CollectionHooks,
2777
3047
  CollectionQueryBuilder,
3048
+ CommerceClient,
2778
3049
  CommunityClient,
2779
3050
  ConfigError,
3051
+ ConflictError,
2780
3052
  CustomerAuth,
2781
3053
  CustomerHooks,
3054
+ CustomerNamespace,
3055
+ DiscountApi,
2782
3056
  GoneError,
2783
3057
  IMAGE_SIZES,
3058
+ ModerationApi,
2784
3059
  NetworkError,
3060
+ NotFoundError,
2785
3061
  OrderApi,
3062
+ PermissionError,
2786
3063
  ProductApi,
2787
3064
  QueryHooks,
3065
+ RateLimitError,
2788
3066
  RealtimeConnection,
2789
3067
  SDKError,
2790
3068
  ServerClient,
3069
+ ServerCommerceClient,
2791
3070
  ServiceUnavailableError,
3071
+ ShippingApi,
2792
3072
  TimeoutError,
2793
3073
  UsageLimitError,
2794
3074
  ValidationError,
@@ -2796,7 +3076,12 @@ export {
2796
3076
  buildProductListingProjection,
2797
3077
  buildProductOptionMatrix,
2798
3078
  collectionKeys,
3079
+ createAuthError,
2799
3080
  createClient,
3081
+ createConflictError,
3082
+ createNotFoundError,
3083
+ createPermissionError,
3084
+ createRateLimitError,
2800
3085
  createServerClient,
2801
3086
  createTypedWebhookHandler,
2802
3087
  customerKeys,
@@ -2817,9 +3102,14 @@ export {
2817
3102
  getVideoThumbnail,
2818
3103
  handleWebhook,
2819
3104
  isApiError,
3105
+ isAuthError,
2820
3106
  isConfigError,
3107
+ isConflictError,
2821
3108
  isGoneError,
2822
3109
  isNetworkError,
3110
+ isNotFoundError,
3111
+ isPermissionError,
3112
+ isRateLimitError,
2823
3113
  isSDKError,
2824
3114
  isServiceUnavailableError,
2825
3115
  isTimeoutError,