@01.software/sdk 0.3.0 → 0.4.1

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 (58) hide show
  1. package/README.md +5 -2
  2. package/dist/auth.d.cts +1 -1
  3. package/dist/auth.d.ts +1 -1
  4. package/dist/const-BsO3aVX_.d.cts +19 -0
  5. package/dist/const-DZyvV9wU.d.ts +19 -0
  6. package/dist/index.cjs +285 -86
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.d.cts +114 -196
  9. package/dist/index.d.ts +114 -196
  10. package/dist/index.js +285 -86
  11. package/dist/index.js.map +1 -1
  12. package/dist/{payload-types-ggU6BNuH.d.cts → payload-types-BsjHfeAF.d.cts} +68 -7
  13. package/dist/{payload-types-ggU6BNuH.d.ts → payload-types-BsjHfeAF.d.ts} +68 -7
  14. package/dist/realtime-DupPIYx-.d.cts +33 -0
  15. package/dist/realtime-DupPIYx-.d.ts +33 -0
  16. package/dist/realtime.cjs +263 -0
  17. package/dist/realtime.cjs.map +1 -0
  18. package/dist/realtime.d.cts +38 -0
  19. package/dist/realtime.d.ts +38 -0
  20. package/dist/realtime.js +241 -0
  21. package/dist/realtime.js.map +1 -0
  22. package/dist/ui/code-block.cjs +3 -1
  23. package/dist/ui/code-block.cjs.map +1 -1
  24. package/dist/ui/code-block.js +4 -2
  25. package/dist/ui/code-block.js.map +1 -1
  26. package/dist/ui/flow.cjs +282 -39
  27. package/dist/ui/flow.cjs.map +1 -1
  28. package/dist/ui/flow.d.cts +104 -3
  29. package/dist/ui/flow.d.ts +104 -3
  30. package/dist/ui/flow.js +270 -24
  31. package/dist/ui/flow.js.map +1 -1
  32. package/dist/ui/form.d.cts +1 -1
  33. package/dist/ui/form.d.ts +1 -1
  34. package/dist/ui/rich-text.cjs +8 -1
  35. package/dist/ui/rich-text.cjs.map +1 -1
  36. package/dist/ui/rich-text.d.cts +20 -1
  37. package/dist/ui/rich-text.d.ts +20 -1
  38. package/dist/ui/rich-text.js +8 -1
  39. package/dist/ui/rich-text.js.map +1 -1
  40. package/dist/ui/video.cjs +219 -0
  41. package/dist/ui/video.cjs.map +1 -0
  42. package/dist/ui/video.d.cts +96 -0
  43. package/dist/ui/video.d.ts +96 -0
  44. package/dist/ui/video.js +191 -0
  45. package/dist/ui/video.js.map +1 -0
  46. package/dist/video-DbLL8yuc.d.cts +85 -0
  47. package/dist/video-DbLL8yuc.d.ts +85 -0
  48. package/dist/webhook-BBWl8O2f.d.ts +20 -0
  49. package/dist/webhook-CkL56e65.d.cts +20 -0
  50. package/dist/webhook.cjs +8 -8
  51. package/dist/webhook.cjs.map +1 -1
  52. package/dist/webhook.d.cts +3 -2
  53. package/dist/webhook.d.ts +3 -2
  54. package/dist/webhook.js +8 -8
  55. package/dist/webhook.js.map +1 -1
  56. package/package.json +30 -4
  57. package/dist/webhook-B54a-HGd.d.ts +0 -35
  58. package/dist/webhook-DInps2xX.d.cts +0 -35
package/README.md CHANGED
@@ -10,6 +10,7 @@ npm install @01.software/sdk
10
10
  pnpm add @01.software/sdk
11
11
  ```
12
12
 
13
+
13
14
  ## Features
14
15
 
15
16
  - Full TypeScript type inference
@@ -47,6 +48,7 @@ import { Image } from '@01.software/sdk/ui/image'
47
48
  import { FormRenderer } from '@01.software/sdk/ui/form'
48
49
  import { CodeBlock } from '@01.software/sdk/ui/code-block'
49
50
  import { FlowRenderer } from '@01.software/sdk/ui/flow'
51
+ import { VideoPlayer } from '@01.software/sdk/ui/video'
50
52
  ```
51
53
 
52
54
  ## Getting Started
@@ -79,11 +81,12 @@ const client = createServerClient({
79
81
 
80
82
  // Create order (server only)
81
83
  const order = await client.api.createOrder({
82
- paymentId: 'pay_123',
83
84
  orderNumber: generateOrderNumber(),
84
- email: 'user@example.com',
85
+ customerSnapshot: { email: 'user@example.com' },
86
+ shippingAddress: { recipientName: 'John', phone: '010-1234-5678', postalCode: '12345', address1: 'Seoul', address2: 'Apt 101' },
85
87
  orderProducts: [...],
86
88
  totalAmount: 10000,
89
+ paymentId: 'pay_123', // optional (omit for free orders)
87
90
  discountCode: 'WELCOME10', // optional
88
91
  })
89
92
 
package/dist/auth.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import './payload-types-ggU6BNuH.cjs';
1
+ import './payload-types-BsjHfeAF.cjs';
2
2
 
3
3
  interface JwtPayload {
4
4
  clientKey: string;
package/dist/auth.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import './payload-types-ggU6BNuH.js';
1
+ import './payload-types-BsjHfeAF.js';
2
2
 
3
3
  interface JwtPayload {
4
4
  clientKey: string;
@@ -0,0 +1,19 @@
1
+ import { C as Config } from './payload-types-BsjHfeAF.cjs';
2
+
3
+ /**
4
+ * Collection type derived from Payload Config.
5
+ * This ensures type safety and automatic synchronization with payload-types.ts
6
+ */
7
+ type Collection = keyof Config['collections'];
8
+ /**
9
+ * Array of all public collection names for runtime use (e.g., Zod enum validation).
10
+ * This is the single source of truth for which collections are publicly accessible via SDK.
11
+ */
12
+ declare const COLLECTIONS: readonly ["tenants", "tenant-metadata", "tenant-logos", "products", "product-variants", "product-options", "product-categories", "product-tags", "product-collections", "brands", "brand-logos", "orders", "order-products", "returns", "return-products", "exchanges", "exchange-products", "fulfillments", "fulfillment-items", "transactions", "customers", "customer-addresses", "customer-groups", "carts", "cart-items", "discounts", "shipping-policies", "documents", "document-categories", "document-types", "posts", "post-authors", "post-categories", "post-tags", "playlists", "playlist-categories", "playlist-tags", "musics", "galleries", "gallery-categories", "gallery-tags", "gallery-items", "flows", "flow-node-types", "flow-edge-types", "flow-categories", "flow-tags", "videos", "video-categories", "video-tags", "live-streams", "images", "forms", "form-submissions"];
13
+ /**
14
+ * Public collections available for SDK access.
15
+ * Derived from the COLLECTIONS array (single source of truth).
16
+ */
17
+ type PublicCollection = (typeof COLLECTIONS)[number];
18
+
19
+ export { type Collection as C, type PublicCollection as P, COLLECTIONS as a };
@@ -0,0 +1,19 @@
1
+ import { C as Config } from './payload-types-BsjHfeAF.js';
2
+
3
+ /**
4
+ * Collection type derived from Payload Config.
5
+ * This ensures type safety and automatic synchronization with payload-types.ts
6
+ */
7
+ type Collection = keyof Config['collections'];
8
+ /**
9
+ * Array of all public collection names for runtime use (e.g., Zod enum validation).
10
+ * This is the single source of truth for which collections are publicly accessible via SDK.
11
+ */
12
+ declare const COLLECTIONS: readonly ["tenants", "tenant-metadata", "tenant-logos", "products", "product-variants", "product-options", "product-categories", "product-tags", "product-collections", "brands", "brand-logos", "orders", "order-products", "returns", "return-products", "exchanges", "exchange-products", "fulfillments", "fulfillment-items", "transactions", "customers", "customer-addresses", "customer-groups", "carts", "cart-items", "discounts", "shipping-policies", "documents", "document-categories", "document-types", "posts", "post-authors", "post-categories", "post-tags", "playlists", "playlist-categories", "playlist-tags", "musics", "galleries", "gallery-categories", "gallery-tags", "gallery-items", "flows", "flow-node-types", "flow-edge-types", "flow-categories", "flow-tags", "videos", "video-categories", "video-tags", "live-streams", "images", "forms", "form-submissions"];
13
+ /**
14
+ * Public collections available for SDK access.
15
+ * Derived from the COLLECTIONS array (single source of truth).
16
+ */
17
+ type PublicCollection = (typeof COLLECTIONS)[number];
18
+
19
+ export { type Collection as C, type PublicCollection as P, COLLECTIONS as a };
package/dist/index.cjs CHANGED
@@ -87,6 +87,7 @@ __export(src_exports, {
87
87
  OrderApi: () => OrderApi,
88
88
  ProductApi: () => ProductApi,
89
89
  QueryHooks: () => QueryHooks,
90
+ RealtimeConnection: () => RealtimeConnection,
90
91
  SDKError: () => SDKError,
91
92
  ServerClient: () => ServerClient,
92
93
  ServiceUnavailableError: () => ServiceUnavailableError,
@@ -215,7 +216,7 @@ function parseApiKey(apiKey) {
215
216
  }
216
217
 
217
218
  // src/core/internal/errors/index.ts
218
- var SDKError = class _SDKError extends Error {
219
+ var SDKError = class extends Error {
219
220
  constructor(code, message, status, details, userMessage, suggestion) {
220
221
  super(message);
221
222
  this.name = "SDKError";
@@ -225,7 +226,7 @@ var SDKError = class _SDKError extends Error {
225
226
  this.userMessage = userMessage;
226
227
  this.suggestion = suggestion;
227
228
  if (Error.captureStackTrace) {
228
- Error.captureStackTrace(this, _SDKError);
229
+ Error.captureStackTrace(this, new.target);
229
230
  }
230
231
  }
231
232
  getUserMessage() {
@@ -341,9 +342,11 @@ var createUsageLimitError = (message, usage, details, userMessage, suggestion) =
341
342
 
342
343
  // src/core/client/types.ts
343
344
  function resolveApiUrl() {
344
- const envUrl = process.env.SOFTWARE_API_URL || process.env.NEXT_PUBLIC_SOFTWARE_API_URL;
345
- if (envUrl) {
346
- return envUrl.replace(/\/$/, "");
345
+ if (typeof process !== "undefined" && process.env) {
346
+ const envUrl = process.env.SOFTWARE_API_URL || process.env.NEXT_PUBLIC_SOFTWARE_API_URL;
347
+ if (envUrl) {
348
+ return envUrl.replace(/\/$/, "");
349
+ }
347
350
  }
348
351
  return "https://api.01.software";
349
352
  }
@@ -364,10 +367,50 @@ function debugLog(debug, type, message, data) {
364
367
  }
365
368
  function getErrorSuggestion(status) {
366
369
  if (status === 401) return "Please check your authentication credentials.";
370
+ if (status === 403) return "Access denied. Check your credentials or permissions.";
367
371
  if (status === 404) return "The requested resource was not found.";
372
+ if (status === 422) return "The request data failed validation.";
368
373
  if (status >= 500) return "A server error occurred. Please try again later.";
369
374
  return void 0;
370
375
  }
376
+ function parseErrorBody(response) {
377
+ return __async(this, null, function* () {
378
+ const fallback = {
379
+ errorMessage: `HTTP ${response.status}: ${response.statusText}`,
380
+ userMessage: `Request failed (status: ${response.status})`
381
+ };
382
+ try {
383
+ const body = yield response.json();
384
+ if (body.errors && Array.isArray(body.errors)) {
385
+ const details = body.errors.map(
386
+ (e) => e.field ? `${e.field}: ${e.message}` : e.message
387
+ ).filter(Boolean).join("; ");
388
+ if (details) {
389
+ return {
390
+ errorMessage: `HTTP ${response.status}: ${details}`,
391
+ userMessage: details,
392
+ errors: body.errors
393
+ };
394
+ }
395
+ }
396
+ if (typeof body.error === "string") {
397
+ return {
398
+ errorMessage: `HTTP ${response.status}: ${body.error}`,
399
+ userMessage: body.error
400
+ };
401
+ }
402
+ if (body.message) {
403
+ return {
404
+ errorMessage: `HTTP ${response.status}: ${body.message}`,
405
+ userMessage: body.message
406
+ };
407
+ }
408
+ return fallback;
409
+ } catch (e) {
410
+ return fallback;
411
+ }
412
+ });
413
+ }
371
414
  function delay(ms) {
372
415
  return __async(this, null, function* () {
373
416
  return new Promise((resolve) => setTimeout(resolve, ms));
@@ -423,7 +466,7 @@ function httpFetch(url, options) {
423
466
  const redactedHeaders = Object.fromEntries(headers.entries());
424
467
  if (redactedHeaders["authorization"]) {
425
468
  const token = redactedHeaders["authorization"];
426
- redactedHeaders["authorization"] = token.length > 15 ? `${token.slice(0, 15)}...****` : "****";
469
+ redactedHeaders["authorization"] = token.length > 20 ? `Bearer ...****${token.slice(-8)}` : "****";
427
470
  }
428
471
  debugLog(debug, "request", url, {
429
472
  method: requestInit.method || "GET",
@@ -476,19 +519,26 @@ function httpFetch(url, options) {
476
519
  }
477
520
  }
478
521
  if (NON_RETRYABLE_STATUSES.includes(response.status)) {
522
+ const parsed2 = yield parseErrorBody(response);
523
+ const details = __spreadValues({
524
+ url,
525
+ method: requestInit.method || "GET",
526
+ attempt: attempt + 1
527
+ }, parsed2.errors && { errors: parsed2.errors });
479
528
  throw createNetworkError(
480
- `HTTP ${response.status}: ${response.statusText}`,
529
+ parsed2.errorMessage,
481
530
  response.status,
482
- { url, method: requestInit.method || "GET", attempt: attempt + 1 },
483
- `Request failed (status: ${response.status})`,
531
+ details,
532
+ parsed2.userMessage,
484
533
  getErrorSuggestion(response.status)
485
534
  );
486
535
  }
536
+ const parsed = yield parseErrorBody(response);
487
537
  const error = createNetworkError(
488
- `HTTP ${response.status}: ${response.statusText}`,
538
+ parsed.errorMessage,
489
539
  response.status,
490
540
  { url, method: requestInit.method || "GET", attempt: attempt + 1 },
491
- `Request failed (status: ${response.status})`,
541
+ parsed.userMessage,
492
542
  getErrorSuggestion(response.status)
493
543
  );
494
544
  const method = (requestInit.method || "GET").toUpperCase();
@@ -562,6 +612,35 @@ function httpFetch(url, options) {
562
612
  });
563
613
  }
564
614
 
615
+ // src/core/api/parse-response.ts
616
+ function parseApiResponse(response, endpoint) {
617
+ return __async(this, null, function* () {
618
+ let data;
619
+ try {
620
+ data = yield response.json();
621
+ } catch (e) {
622
+ throw createApiError(
623
+ `Invalid JSON response from ${endpoint}`,
624
+ response.status,
625
+ void 0,
626
+ "Server returned an invalid response.",
627
+ "Check if the API endpoint is available."
628
+ );
629
+ }
630
+ if (data.error) {
631
+ const errorMessage = typeof data.error === "string" ? data.error : "Unknown API error";
632
+ throw createApiError(
633
+ errorMessage,
634
+ response.status,
635
+ data,
636
+ errorMessage,
637
+ "An error occurred while processing the request."
638
+ );
639
+ }
640
+ return data;
641
+ });
642
+ }
643
+
565
644
  // src/core/api/base-api.ts
566
645
  var BaseApi = class {
567
646
  constructor(apiName, options) {
@@ -575,38 +654,17 @@ var BaseApi = class {
575
654
  this.secretKey = options.secretKey;
576
655
  this.baseUrl = options.baseUrl;
577
656
  }
578
- request(endpoint, body) {
657
+ request(endpoint, body, options) {
579
658
  return __async(this, null, function* () {
580
- const response = yield httpFetch(endpoint, {
581
- method: "POST",
659
+ var _a;
660
+ const method = (_a = options == null ? void 0 : options.method) != null ? _a : "POST";
661
+ const response = yield httpFetch(endpoint, __spreadValues(__spreadValues({
662
+ method,
582
663
  clientKey: this.clientKey,
583
664
  secretKey: this.secretKey,
584
- baseUrl: this.baseUrl,
585
- body: JSON.stringify(body)
586
- });
587
- let data;
588
- try {
589
- data = yield response.json();
590
- } catch (e) {
591
- throw createApiError(
592
- `Invalid JSON response from ${endpoint}`,
593
- response.status,
594
- void 0,
595
- "Server returned an invalid response.",
596
- "Check if the API endpoint is available."
597
- );
598
- }
599
- if (data.error) {
600
- const errorMessage = typeof data.error === "string" ? data.error : "Unknown API error";
601
- throw createApiError(
602
- errorMessage,
603
- response.status,
604
- data,
605
- errorMessage,
606
- "An error occurred while processing the request."
607
- );
608
- }
609
- return data;
665
+ baseUrl: this.baseUrl
666
+ }, body !== void 0 && { body: JSON.stringify(body) }), (options == null ? void 0 : options.headers) && { headers: options.headers }));
667
+ return parseApiResponse(response, endpoint);
610
668
  });
611
669
  }
612
670
  };
@@ -696,29 +754,7 @@ var CartApi = class {
696
754
  customerToken: token != null ? token : void 0,
697
755
  baseUrl: this.baseUrl
698
756
  }, token && this.onUnauthorized && { onUnauthorized: this.onUnauthorized }), body !== void 0 && { body: JSON.stringify(body) }));
699
- let data;
700
- try {
701
- data = yield response.json();
702
- } catch (e) {
703
- throw createApiError(
704
- `Invalid JSON response from ${endpoint}`,
705
- response.status,
706
- void 0,
707
- "Server returned an invalid response.",
708
- "Check if the API endpoint is available."
709
- );
710
- }
711
- if (data.error) {
712
- const errorMessage = typeof data.error === "string" ? data.error : "Unknown API error";
713
- throw createApiError(
714
- errorMessage,
715
- response.status,
716
- data,
717
- errorMessage,
718
- "An error occurred while processing the request."
719
- );
720
- }
721
- return data;
757
+ return parseApiResponse(response, endpoint);
722
758
  });
723
759
  }
724
760
  getCart(cartId) {
@@ -1018,7 +1054,7 @@ var HttpClient = class {
1018
1054
  */
1019
1055
  parseFindResponse(response) {
1020
1056
  return __async(this, null, function* () {
1021
- var _a, _b;
1057
+ var _a, _b, _c, _d, _e, _f;
1022
1058
  const contentType = response.headers.get("content-type");
1023
1059
  try {
1024
1060
  this.assertJsonResponse(response);
@@ -1030,15 +1066,15 @@ var HttpClient = class {
1030
1066
  }
1031
1067
  return {
1032
1068
  docs: jsonData.docs,
1033
- totalDocs: jsonData.totalDocs || 0,
1069
+ totalDocs: (_a = jsonData.totalDocs) != null ? _a : 0,
1034
1070
  limit: jsonData.limit || 20,
1035
- totalPages: jsonData.totalPages || 0,
1071
+ totalPages: (_b = jsonData.totalPages) != null ? _b : 0,
1036
1072
  page: jsonData.page || 1,
1037
1073
  pagingCounter: jsonData.pagingCounter || 1,
1038
- hasPrevPage: jsonData.hasPrevPage || false,
1039
- hasNextPage: jsonData.hasNextPage || false,
1040
- prevPage: (_a = jsonData.prevPage) != null ? _a : null,
1041
- nextPage: (_b = jsonData.nextPage) != null ? _b : null
1074
+ hasPrevPage: (_c = jsonData.hasPrevPage) != null ? _c : false,
1075
+ hasNextPage: (_d = jsonData.hasNextPage) != null ? _d : false,
1076
+ prevPage: (_e = jsonData.prevPage) != null ? _e : null,
1077
+ nextPage: (_f = jsonData.nextPage) != null ? _f : null
1042
1078
  };
1043
1079
  } catch (error) {
1044
1080
  if (error instanceof SDKError) throw error;
@@ -1283,6 +1319,7 @@ var COLLECTIONS = [
1283
1319
  "document-categories",
1284
1320
  "document-types",
1285
1321
  "posts",
1322
+ "post-authors",
1286
1323
  "post-categories",
1287
1324
  "post-tags",
1288
1325
  "playlists",
@@ -1309,23 +1346,33 @@ var COLLECTIONS = [
1309
1346
 
1310
1347
  // src/core/customer/customer-auth.ts
1311
1348
  var DEFAULT_TIMEOUT2 = 15e3;
1349
+ function safeGetItem(key) {
1350
+ try {
1351
+ return localStorage.getItem(key);
1352
+ } catch (e) {
1353
+ return null;
1354
+ }
1355
+ }
1312
1356
  var CustomerAuth = class {
1313
1357
  constructor(clientKey, baseUrl, options) {
1314
1358
  this.refreshPromise = null;
1315
- var _a, _b, _c;
1359
+ var _a, _b;
1316
1360
  this.clientKey = clientKey;
1317
1361
  this.baseUrl = baseUrl;
1318
1362
  const persist = (_a = options == null ? void 0 : options.persist) != null ? _a : true;
1319
1363
  if (persist) {
1320
1364
  const key = typeof persist === "string" ? persist : "customer-token";
1321
1365
  const isBrowser = typeof window !== "undefined";
1322
- this.token = isBrowser ? (_b = localStorage.getItem(key)) != null ? _b : null : null;
1366
+ this.token = isBrowser ? safeGetItem(key) : null;
1323
1367
  this.onTokenChange = isBrowser ? (token) => {
1324
- if (token) localStorage.setItem(key, token);
1325
- else localStorage.removeItem(key);
1368
+ try {
1369
+ if (token) localStorage.setItem(key, token);
1370
+ else localStorage.removeItem(key);
1371
+ } catch (e) {
1372
+ }
1326
1373
  } : void 0;
1327
1374
  } else {
1328
- this.token = (_c = options == null ? void 0 : options.token) != null ? _c : null;
1375
+ this.token = (_b = options == null ? void 0 : options.token) != null ? _b : null;
1329
1376
  this.onTokenChange = options == null ? void 0 : options.onTokenChange;
1330
1377
  }
1331
1378
  }
@@ -2121,6 +2168,157 @@ function createServerClient(options) {
2121
2168
  return new ServerClient(options);
2122
2169
  }
2123
2170
 
2171
+ // src/core/query/realtime.ts
2172
+ var INITIAL_RECONNECT_DELAY = 1e3;
2173
+ var MAX_RECONNECT_DELAY = 3e4;
2174
+ var RECONNECT_BACKOFF_FACTOR = 2;
2175
+ var MAX_NO_TOKEN_RETRIES = 5;
2176
+ var RealtimeConnection = class {
2177
+ constructor(baseUrl, clientKey, getToken, collections) {
2178
+ this.baseUrl = baseUrl;
2179
+ this.clientKey = clientKey;
2180
+ this.getToken = getToken;
2181
+ this.collections = collections;
2182
+ this.abortController = null;
2183
+ this.reconnectAttempt = 0;
2184
+ this.noTokenAttempts = 0;
2185
+ this.reconnectTimer = null;
2186
+ this.listeners = /* @__PURE__ */ new Set();
2187
+ this._connected = false;
2188
+ }
2189
+ get connected() {
2190
+ return this._connected;
2191
+ }
2192
+ addListener(fn) {
2193
+ this.listeners.add(fn);
2194
+ return () => this.listeners.delete(fn);
2195
+ }
2196
+ connect() {
2197
+ if (this.abortController) return;
2198
+ this.abortController = new AbortController();
2199
+ this.startStream(this.abortController.signal);
2200
+ }
2201
+ disconnect() {
2202
+ this._connected = false;
2203
+ if (this.reconnectTimer) {
2204
+ clearTimeout(this.reconnectTimer);
2205
+ this.reconnectTimer = null;
2206
+ }
2207
+ if (this.abortController) {
2208
+ this.abortController.abort();
2209
+ this.abortController = null;
2210
+ }
2211
+ this.reconnectAttempt = 0;
2212
+ this.noTokenAttempts = 0;
2213
+ }
2214
+ startStream(signal) {
2215
+ return __async(this, null, function* () {
2216
+ var _a;
2217
+ const token = this.getToken();
2218
+ if (!token) {
2219
+ this.noTokenAttempts++;
2220
+ if (this.noTokenAttempts >= MAX_NO_TOKEN_RETRIES) {
2221
+ this._connected = false;
2222
+ this.abortController = null;
2223
+ return;
2224
+ }
2225
+ this.scheduleReconnect();
2226
+ return;
2227
+ }
2228
+ this.noTokenAttempts = 0;
2229
+ const params = ((_a = this.collections) == null ? void 0 : _a.length) ? `?collections=${this.collections.join(",")}` : "";
2230
+ const url = `${this.baseUrl}/api/events/stream${params}`;
2231
+ try {
2232
+ const response = yield fetch(url, {
2233
+ headers: {
2234
+ "X-Client-Key": this.clientKey,
2235
+ Authorization: `Bearer ${token}`
2236
+ },
2237
+ signal
2238
+ });
2239
+ if (!response.ok) {
2240
+ if (response.status === 401) {
2241
+ this.scheduleReconnect();
2242
+ return;
2243
+ }
2244
+ throw new Error(`SSE connection failed: ${response.status}`);
2245
+ }
2246
+ if (!response.body) {
2247
+ throw new Error("SSE response has no body");
2248
+ }
2249
+ this._connected = true;
2250
+ this.reconnectAttempt = 0;
2251
+ yield this.readStream(response.body, signal);
2252
+ } catch (e) {
2253
+ if (signal.aborted) return;
2254
+ this._connected = false;
2255
+ this.scheduleReconnect();
2256
+ }
2257
+ });
2258
+ }
2259
+ readStream(body, signal) {
2260
+ return __async(this, null, function* () {
2261
+ var _a;
2262
+ const reader = body.getReader();
2263
+ const decoder = new TextDecoder();
2264
+ let buffer = "";
2265
+ let currentEvent = "";
2266
+ let currentData = "";
2267
+ try {
2268
+ while (true) {
2269
+ const { done, value } = yield reader.read();
2270
+ if (done || signal.aborted) break;
2271
+ buffer += decoder.decode(value, { stream: true });
2272
+ const lines = buffer.split("\n");
2273
+ buffer = (_a = lines.pop()) != null ? _a : "";
2274
+ for (const line of lines) {
2275
+ if (line.startsWith("event: ")) {
2276
+ currentEvent = line.slice(7);
2277
+ } else if (line.startsWith("data: ")) {
2278
+ currentData += (currentData ? "\n" : "") + line.slice(6);
2279
+ } else if (line === "") {
2280
+ if (currentEvent === "collection:change" && currentData) {
2281
+ try {
2282
+ const event = JSON.parse(currentData);
2283
+ for (const listener of this.listeners) {
2284
+ try {
2285
+ listener(event);
2286
+ } catch (e) {
2287
+ }
2288
+ }
2289
+ } catch (e) {
2290
+ }
2291
+ }
2292
+ currentEvent = "";
2293
+ currentData = "";
2294
+ }
2295
+ }
2296
+ }
2297
+ } catch (e) {
2298
+ } finally {
2299
+ reader.releaseLock();
2300
+ this._connected = false;
2301
+ if (!signal.aborted) {
2302
+ this.scheduleReconnect();
2303
+ }
2304
+ }
2305
+ });
2306
+ }
2307
+ scheduleReconnect() {
2308
+ if (this.reconnectTimer) return;
2309
+ const delay2 = Math.min(
2310
+ INITIAL_RECONNECT_DELAY * Math.pow(RECONNECT_BACKOFF_FACTOR, this.reconnectAttempt),
2311
+ MAX_RECONNECT_DELAY
2312
+ );
2313
+ this.reconnectAttempt++;
2314
+ this.reconnectTimer = setTimeout(() => {
2315
+ this.reconnectTimer = null;
2316
+ this.abortController = new AbortController();
2317
+ this.startStream(this.abortController.signal);
2318
+ }, delay2);
2319
+ }
2320
+ };
2321
+
2124
2322
  // src/core/webhook/index.ts
2125
2323
  function isValidWebhookEvent(data) {
2126
2324
  if (typeof data !== "object" || data === null) return false;
@@ -2129,22 +2327,22 @@ function isValidWebhookEvent(data) {
2129
2327
  }
2130
2328
  function verifySignature(payload, secret, signature) {
2131
2329
  return __async(this, null, function* () {
2330
+ var _a;
2132
2331
  const encoder = new TextEncoder();
2133
2332
  const key = yield crypto.subtle.importKey(
2134
2333
  "raw",
2135
2334
  encoder.encode(secret),
2136
2335
  { name: "HMAC", hash: "SHA-256" },
2137
2336
  false,
2138
- ["sign"]
2337
+ ["verify"]
2139
2338
  );
2140
- const sig = yield crypto.subtle.sign("HMAC", key, encoder.encode(payload));
2141
- const expected = Array.from(new Uint8Array(sig)).map((b) => b.toString(16).padStart(2, "0")).join("");
2142
- let result = expected.length !== signature.length ? 1 : 0;
2143
- const len = Math.max(expected.length, signature.length);
2144
- for (let i = 0; i < len; i++) {
2145
- result |= (expected.charCodeAt(i) || 0) ^ (signature.charCodeAt(i) || 0);
2339
+ if (signature.length % 2 !== 0 || !/^[0-9a-fA-F]*$/.test(signature)) {
2340
+ return false;
2146
2341
  }
2147
- return result === 0;
2342
+ const sigBytes = new Uint8Array(
2343
+ ((_a = signature.match(/.{2}/g)) != null ? _a : []).map((byte) => parseInt(byte, 16))
2344
+ );
2345
+ return crypto.subtle.verify("HMAC", key, sigBytes, encoder.encode(payload));
2148
2346
  });
2149
2347
  }
2150
2348
  function handleWebhook(request, handler, options) {
@@ -2266,9 +2464,10 @@ function getImagePlaceholderStyle(image, options) {
2266
2464
  // src/utils/order/generateOrderNumber.ts
2267
2465
  var generateOrderNumber = () => {
2268
2466
  var _a;
2269
- const year = (/* @__PURE__ */ new Date()).getFullYear().toString().slice(-2);
2270
- const month = ((/* @__PURE__ */ new Date()).getMonth() + 1).toString().padStart(2, "0");
2271
- const day = (/* @__PURE__ */ new Date()).getDate().toString().padStart(2, "0");
2467
+ const now = /* @__PURE__ */ new Date();
2468
+ const year = now.getFullYear().toString().slice(-2);
2469
+ const month = (now.getMonth() + 1).toString().padStart(2, "0");
2470
+ const day = now.getDate().toString().padStart(2, "0");
2272
2471
  const array = new Uint32Array(1);
2273
2472
  globalThis.crypto.getRandomValues(array);
2274
2473
  const random = (((_a = array[0]) != null ? _a : 0) % 1e6).toString().padStart(6, "0");