@01.software/sdk 0.1.0-dev.260210.4ecca43 → 0.1.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.
package/dist/index.cjs CHANGED
@@ -78,20 +78,21 @@ var __async = (__this, __arguments, generator) => {
78
78
  };
79
79
 
80
80
  // src/index.ts
81
- var index_exports = {};
82
- __export(index_exports, {
83
- ApiClient: () => ApiClient,
81
+ var src_exports = {};
82
+ __export(src_exports, {
84
83
  ApiError: () => ApiError,
85
84
  BrowserClient: () => BrowserClient,
86
85
  COLLECTIONS: () => COLLECTIONS,
86
+ CollectionClient: () => CollectionClient,
87
87
  CollectionQueryBuilder: () => CollectionQueryBuilder,
88
- CollectionsApi: () => CollectionsApi,
89
88
  ConfigError: () => ConfigError,
90
89
  NetworkError: () => NetworkError,
90
+ OrderApi: () => OrderApi,
91
+ QueryHooks: () => QueryHooks,
91
92
  RichTextContent: () => RichTextContent,
92
93
  ServerClient: () => ServerClient,
93
94
  TimeoutError: () => TimeoutError,
94
- UnifiedQueryClient: () => UnifiedQueryClient,
95
+ UsageLimitError: () => UsageLimitError,
95
96
  ValidationError: () => ValidationError,
96
97
  collectionKeys: () => collectionKeys,
97
98
  createApiKey: () => createApiKey,
@@ -109,13 +110,15 @@ __export(index_exports, {
109
110
  isNetworkError: () => isNetworkError,
110
111
  isSDKError: () => isSDKError,
111
112
  isTimeoutError: () => isTimeoutError,
113
+ isUsageLimitError: () => isUsageLimitError,
112
114
  isValidWebhookEvent: () => isValidWebhookEvent,
113
115
  isValidationError: () => isValidationError,
114
116
  objectFor: () => objectFor,
115
117
  parseApiKey: () => parseApiKey,
118
+ resolveRelation: () => resolveRelation,
116
119
  verifyServerToken: () => verifyServerToken
117
120
  });
118
- module.exports = __toCommonJS(index_exports);
121
+ module.exports = __toCommonJS(src_exports);
119
122
 
120
123
  // src/core/collection/query-builder.ts
121
124
  var CollectionQueryBuilder = class {
@@ -228,7 +231,7 @@ var CollectionQueryBuilder = class {
228
231
  }
229
232
  };
230
233
 
231
- // src/core/collection/base.ts
234
+ // src/core/collection/http-client.ts
232
235
  var import_qs_esm = require("qs-esm");
233
236
 
234
237
  // src/core/internal/errors/index.ts
@@ -285,11 +288,23 @@ var ConfigError = class extends SDKError {
285
288
  }
286
289
  };
287
290
  var TimeoutError = class extends SDKError {
288
- constructor(message = "\uC694\uCCAD\uC774 \uC2DC\uAC04 \uCD08\uACFC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.", details, userMessage, suggestion) {
291
+ constructor(message = "Request timed out.", details, userMessage, suggestion) {
289
292
  super("TIMEOUT_ERROR", message, 408, details, userMessage, suggestion);
290
293
  this.name = "TimeoutError";
291
294
  }
292
295
  };
296
+ var UsageLimitError = class extends SDKError {
297
+ constructor(message, usage, details, userMessage, suggestion) {
298
+ super("USAGE_LIMIT_ERROR", message, 429, details, userMessage, suggestion);
299
+ this.name = "UsageLimitError";
300
+ this.usage = usage;
301
+ }
302
+ toJSON() {
303
+ return __spreadProps(__spreadValues({}, super.toJSON()), {
304
+ usage: this.usage
305
+ });
306
+ }
307
+ };
293
308
  function isSDKError(error) {
294
309
  return error instanceof SDKError;
295
310
  }
@@ -308,15 +323,20 @@ function isConfigError(error) {
308
323
  function isTimeoutError(error) {
309
324
  return error instanceof TimeoutError;
310
325
  }
326
+ function isUsageLimitError(error) {
327
+ return error instanceof UsageLimitError;
328
+ }
311
329
  var createNetworkError = (message, status, details, userMessage, suggestion) => new NetworkError(message, status, details, userMessage, suggestion);
312
330
  var createValidationError = (message, details, userMessage, suggestion) => new ValidationError(message, details, userMessage, suggestion);
313
331
  var createApiError = (message, status, details, userMessage, suggestion) => new ApiError(message, status, details, userMessage, suggestion);
332
+ var createTimeoutError = (message, details, userMessage, suggestion) => new TimeoutError(message, details, userMessage, suggestion);
333
+ var createUsageLimitError = (message, usage, details, userMessage, suggestion) => new UsageLimitError(message, usage, details, userMessage, suggestion);
314
334
 
315
- // src/core/collection/base.ts
316
- var BaseApiClient = class {
335
+ // src/core/collection/http-client.ts
336
+ var HttpClient = class {
317
337
  constructor(clientKey, secretKey, baseUrl) {
318
338
  if (!clientKey) {
319
- throw createValidationError("clientKey\uB294 \uD544\uC218\uC785\uB2C8\uB2E4.");
339
+ throw createValidationError("clientKey is required.");
320
340
  }
321
341
  this.clientKey = clientKey;
322
342
  this.secretKey = secretKey;
@@ -328,6 +348,12 @@ var BaseApiClient = class {
328
348
  const queryString = (0, import_qs_esm.stringify)(options, { addQueryPrefix: true });
329
349
  return queryString ? `${endpoint}${queryString}` : endpoint;
330
350
  }
351
+ assertJsonResponse(response) {
352
+ const contentType = response.headers.get("content-type");
353
+ if (!(contentType == null ? void 0 : contentType.includes("application/json"))) {
354
+ throw createApiError("Response is not in JSON format.", response.status, { contentType });
355
+ }
356
+ }
331
357
  /**
332
358
  * Parse Payload CMS find response (list query)
333
359
  * Returns native Payload response structure
@@ -337,12 +363,10 @@ var BaseApiClient = class {
337
363
  var _a, _b;
338
364
  const contentType = response.headers.get("content-type");
339
365
  try {
340
- if (!(contentType == null ? void 0 : contentType.includes("application/json"))) {
341
- throw createApiError("\uC751\uB2F5\uC774 JSON \uD615\uC2DD\uC774 \uC544\uB2D9\uB2C8\uB2E4.", response.status, { contentType });
342
- }
366
+ this.assertJsonResponse(response);
343
367
  const jsonData = yield response.json();
344
368
  if (jsonData.docs === void 0) {
345
- throw createApiError("\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 find \uC751\uB2F5\uC785\uB2C8\uB2E4.", response.status, { jsonData });
369
+ throw createApiError("Invalid find response.", response.status, { jsonData });
346
370
  }
347
371
  return {
348
372
  docs: jsonData.docs,
@@ -357,7 +381,7 @@ var BaseApiClient = class {
357
381
  nextPage: (_b = jsonData.nextPage) != null ? _b : null
358
382
  };
359
383
  } catch (error) {
360
- throw createApiError("\uC751\uB2F5 \uD30C\uC2F1\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.", response.status, {
384
+ throw createApiError("Failed to parse response.", response.status, {
361
385
  contentType,
362
386
  error: error instanceof Error ? error.message : error
363
387
  });
@@ -372,12 +396,10 @@ var BaseApiClient = class {
372
396
  return __async(this, null, function* () {
373
397
  const contentType = response.headers.get("content-type");
374
398
  try {
375
- if (!(contentType == null ? void 0 : contentType.includes("application/json"))) {
376
- throw createApiError("\uC751\uB2F5\uC774 JSON \uD615\uC2DD\uC774 \uC544\uB2D9\uB2C8\uB2E4.", response.status, { contentType });
377
- }
399
+ this.assertJsonResponse(response);
378
400
  const jsonData = yield response.json();
379
401
  if (jsonData.doc === void 0) {
380
- throw createApiError("\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 mutation \uC751\uB2F5\uC785\uB2C8\uB2E4.", response.status, { jsonData });
402
+ throw createApiError("Invalid mutation response.", response.status, { jsonData });
381
403
  }
382
404
  return {
383
405
  message: jsonData.message || "",
@@ -385,7 +407,7 @@ var BaseApiClient = class {
385
407
  errors: jsonData.errors
386
408
  };
387
409
  } catch (error) {
388
- throw createApiError("\uC751\uB2F5 \uD30C\uC2F1\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.", response.status, {
410
+ throw createApiError("Failed to parse response.", response.status, {
389
411
  contentType,
390
412
  error: error instanceof Error ? error.message : error
391
413
  });
@@ -400,13 +422,11 @@ var BaseApiClient = class {
400
422
  return __async(this, null, function* () {
401
423
  const contentType = response.headers.get("content-type");
402
424
  try {
403
- if (!(contentType == null ? void 0 : contentType.includes("application/json"))) {
404
- throw createApiError("\uC751\uB2F5\uC774 JSON \uD615\uC2DD\uC774 \uC544\uB2D9\uB2C8\uB2E4.", response.status, { contentType });
405
- }
425
+ this.assertJsonResponse(response);
406
426
  const jsonData = yield response.json();
407
427
  return jsonData;
408
428
  } catch (error) {
409
- throw createApiError("\uC751\uB2F5 \uD30C\uC2F1\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.", response.status, {
429
+ throw createApiError("Failed to parse response.", response.status, {
410
430
  contentType,
411
431
  error: error instanceof Error ? error.message : error
412
432
  });
@@ -442,10 +462,11 @@ function resolveApiUrl(config) {
442
462
  // src/core/internal/utils/index.ts
443
463
  var DEFAULT_TIMEOUT = 3e4;
444
464
  var DEFAULT_RETRYABLE_STATUSES = [408, 429, 500, 502, 503, 504];
465
+ var NON_RETRYABLE_STATUSES = [401, 403, 404, 422];
445
466
  function createServerToken(clientKey, secretKey, expiresIn = "1h") {
446
467
  return __async(this, null, function* () {
447
468
  if (!clientKey || !secretKey) {
448
- throw new Error("clientKey\uC640 secretKey\uB294 \uD544\uC218\uC785\uB2C8\uB2E4.");
469
+ throw new Error("clientKey and secretKey are required.");
449
470
  }
450
471
  const secret = new TextEncoder().encode(secretKey);
451
472
  return new import_jose.SignJWT({ clientKey }).setProtectedHeader({ alg: "HS256" }).setIssuedAt().setExpirationTime(expiresIn).sign(secret);
@@ -454,7 +475,7 @@ function createServerToken(clientKey, secretKey, expiresIn = "1h") {
454
475
  function verifyServerToken(token, secretKey) {
455
476
  return __async(this, null, function* () {
456
477
  if (!token || !secretKey) {
457
- throw new Error("token\uACFC secretKey\uB294 \uD544\uC218\uC785\uB2C8\uB2E4.");
478
+ throw new Error("token and secretKey are required.");
458
479
  }
459
480
  const secret = new TextEncoder().encode(secretKey);
460
481
  const { payload } = yield (0, import_jose.jwtVerify)(token, secret, {
@@ -472,7 +493,7 @@ function verifyServerToken(token, secretKey) {
472
493
  }
473
494
  function decodeServerToken(token) {
474
495
  if (!token) {
475
- throw new Error("token\uC740 \uD544\uC218\uC785\uB2C8\uB2E4.");
496
+ throw new Error("token is required.");
476
497
  }
477
498
  const payload = (0, import_jose.decodeJwt)(token);
478
499
  if (!payload.clientKey || typeof payload.clientKey !== "string") {
@@ -486,7 +507,7 @@ function decodeServerToken(token) {
486
507
  }
487
508
  function createApiKey(clientKey, secretKey) {
488
509
  if (!clientKey || !secretKey) {
489
- throw new Error("clientKey\uC640 secretKey\uB294 \uD544\uC218\uC785\uB2C8\uB2E4.");
510
+ throw new Error("clientKey and secretKey are required.");
490
511
  }
491
512
  if (typeof Buffer !== "undefined") {
492
513
  return Buffer.from(`${clientKey}:${secretKey}`).toString("base64");
@@ -495,7 +516,7 @@ function createApiKey(clientKey, secretKey) {
495
516
  }
496
517
  function parseApiKey(apiKey) {
497
518
  if (!apiKey) {
498
- throw new Error("apiKey\uB294 \uD544\uC218\uC785\uB2C8\uB2E4.");
519
+ throw new Error("apiKey is required.");
499
520
  }
500
521
  try {
501
522
  let decoded;
@@ -506,12 +527,12 @@ function parseApiKey(apiKey) {
506
527
  }
507
528
  const colonIndex = decoded.indexOf(":");
508
529
  if (colonIndex === -1) {
509
- throw new Error("Invalid format");
530
+ throw new Error("Invalid format: missing colon separator");
510
531
  }
511
532
  const clientKey = decoded.substring(0, colonIndex);
512
533
  const secretKey = decoded.substring(colonIndex + 1);
513
534
  if (!clientKey || !secretKey) {
514
- throw new Error("Invalid format");
535
+ throw new Error("Invalid format: empty clientKey or secretKey");
515
536
  }
516
537
  return { clientKey, secretKey };
517
538
  } catch (e) {
@@ -528,10 +549,10 @@ function debugLog(debug, type, message, data) {
528
549
  }
529
550
  }
530
551
  function getErrorSuggestion(status) {
531
- if (status === 401) return "\uC778\uC99D \uC815\uBCF4\uB97C \uD655\uC778\uD574\uC8FC\uC138\uC694.";
532
- if (status === 404) return "\uC694\uCCAD\uD55C \uB9AC\uC18C\uC2A4\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.";
552
+ if (status === 401) return "Please check your authentication credentials.";
553
+ if (status === 404) return "The requested resource was not found.";
533
554
  if (status >= 500)
534
- return "\uC11C\uBC84 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4. \uC7A0\uC2DC \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694.";
555
+ return "A server error occurred. Please try again later.";
535
556
  return void 0;
536
557
  }
537
558
  function delay(ms) {
@@ -562,6 +583,10 @@ function _fetch(url, options) {
562
583
  retryableStatuses: (_c = retry == null ? void 0 : retry.retryableStatuses) != null ? _c : DEFAULT_RETRYABLE_STATUSES,
563
584
  retryDelay: (_d = retry == null ? void 0 : retry.retryDelay) != null ? _d : ((attempt) => Math.min(1e3 * __pow(2, attempt), 1e4))
564
585
  };
586
+ let authToken;
587
+ if (secretKey && clientKey) {
588
+ authToken = yield createServerToken(clientKey, secretKey);
589
+ }
565
590
  let lastError;
566
591
  for (let attempt = 0; attempt <= retryConfig.maxRetries; attempt++) {
567
592
  try {
@@ -569,9 +594,8 @@ function _fetch(url, options) {
569
594
  if (clientKey) {
570
595
  headers.set("X-Client-Key", clientKey);
571
596
  }
572
- if (secretKey && clientKey) {
573
- const token = yield createServerToken(clientKey, secretKey);
574
- headers.set("Authorization", `Bearer ${token}`);
597
+ if (authToken) {
598
+ headers.set("Authorization", `Bearer ${authToken}`);
575
599
  }
576
600
  if (!headers.has("Content-Type") && requestInit.body) {
577
601
  headers.set("Content-Type", "application/json");
@@ -594,17 +618,38 @@ function _fetch(url, options) {
594
618
  headers: Object.fromEntries(response.headers.entries())
595
619
  });
596
620
  if (!response.ok) {
621
+ if (response.status === 429 && response.headers.get("X-Usage-Limit")) {
622
+ const limit = parseInt(response.headers.get("X-Usage-Limit") || "0", 10);
623
+ const current = parseInt(response.headers.get("X-Usage-Current") || "0", 10);
624
+ const remaining = parseInt(response.headers.get("X-Usage-Remaining") || "0", 10);
625
+ throw createUsageLimitError(
626
+ `Monthly API usage limit exceeded (${current.toLocaleString()}/${limit.toLocaleString()})`,
627
+ { limit, current, remaining },
628
+ { url, method: requestInit.method || "GET", attempt: attempt + 1 },
629
+ "Monthly API call limit exceeded. Please upgrade your plan.",
630
+ "Upgrade your tenant plan to increase the monthly API call limit."
631
+ );
632
+ }
633
+ if (NON_RETRYABLE_STATUSES.includes(response.status)) {
634
+ throw createNetworkError(
635
+ `HTTP ${response.status}: ${response.statusText}`,
636
+ response.status,
637
+ { url, method: requestInit.method || "GET", attempt: attempt + 1 },
638
+ `Request failed (status: ${response.status})`,
639
+ getErrorSuggestion(response.status)
640
+ );
641
+ }
597
642
  const error = createNetworkError(
598
643
  `HTTP ${response.status}: ${response.statusText}`,
599
644
  response.status,
600
645
  { url, method: requestInit.method || "GET", attempt: attempt + 1 },
601
- `\uC694\uCCAD\uC774 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4 (\uC0C1\uD0DC \uCF54\uB4DC: ${response.status})`,
646
+ `Request failed (status: ${response.status})`,
602
647
  getErrorSuggestion(response.status)
603
648
  );
604
649
  if (attempt < retryConfig.maxRetries && retryConfig.retryableStatuses.includes(response.status)) {
605
650
  lastError = error;
606
651
  const retryDelay = retryConfig.retryDelay(attempt);
607
- debugLog(debug, "error", `\uC7AC\uC2DC\uB3C4 \uB300\uAE30 \uC911... (${retryDelay}ms)`, error);
652
+ debugLog(debug, "error", `Retrying in ${retryDelay}ms...`, error);
608
653
  yield delay(retryDelay);
609
654
  continue;
610
655
  }
@@ -614,11 +659,11 @@ function _fetch(url, options) {
614
659
  } catch (error) {
615
660
  debugLog(debug, "error", url, error);
616
661
  if (error instanceof Error && error.name === "AbortError") {
617
- const timeoutError = new TimeoutError(
618
- `\uC694\uCCAD\uC774 ${timeout}ms \uD6C4 \uD0C0\uC784\uC544\uC6C3\uB418\uC5C8\uC2B5\uB2C8\uB2E4.`,
662
+ const timeoutError = createTimeoutError(
663
+ `Request timed out after ${timeout}ms.`,
619
664
  { url, timeout, attempt: attempt + 1 },
620
- "\uC694\uCCAD \uC2DC\uAC04\uC774 \uCD08\uACFC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.",
621
- "\uB124\uD2B8\uC6CC\uD06C \uC5F0\uACB0\uC744 \uD655\uC778\uD558\uAC70\uB098 \uC7A0\uC2DC \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694."
665
+ "The request timed out.",
666
+ "Please check your network connection or try again later."
622
667
  );
623
668
  if (attempt < retryConfig.maxRetries) {
624
669
  lastError = timeoutError;
@@ -629,11 +674,11 @@ function _fetch(url, options) {
629
674
  }
630
675
  if (error instanceof TypeError) {
631
676
  const networkError = createNetworkError(
632
- "\uB124\uD2B8\uC6CC\uD06C \uC5F0\uACB0\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.",
677
+ "Network connection failed.",
633
678
  void 0,
634
679
  { url, originalError: error.message, attempt: attempt + 1 },
635
- "\uB124\uD2B8\uC6CC\uD06C \uC5F0\uACB0\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.",
636
- "\uC778\uD130\uB137 \uC5F0\uACB0\uC744 \uD655\uC778\uD558\uACE0 \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694."
680
+ "Network connection failed.",
681
+ "Please check your internet connection and try again."
637
682
  );
638
683
  if (attempt < retryConfig.maxRetries) {
639
684
  lastError = networkError;
@@ -643,7 +688,7 @@ function _fetch(url, options) {
643
688
  throw networkError;
644
689
  }
645
690
  if (error instanceof NetworkError || error instanceof TimeoutError) {
646
- if (attempt < retryConfig.maxRetries && error.status && retryConfig.retryableStatuses.includes(error.status)) {
691
+ if (attempt < retryConfig.maxRetries && error.status && !NON_RETRYABLE_STATUSES.includes(error.status) && retryConfig.retryableStatuses.includes(error.status)) {
647
692
  lastError = error;
648
693
  yield delay(retryConfig.retryDelay(attempt));
649
694
  continue;
@@ -651,11 +696,11 @@ function _fetch(url, options) {
651
696
  throw error;
652
697
  }
653
698
  const unknownError = createNetworkError(
654
- error instanceof Error ? error.message : "\uC54C \uC218 \uC5C6\uB294 \uB124\uD2B8\uC6CC\uD06C \uC5D0\uB7EC\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.",
699
+ error instanceof Error ? error.message : "An unknown network error occurred.",
655
700
  void 0,
656
701
  { url, originalError: error, attempt: attempt + 1 },
657
- "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.",
658
- "\uC7A0\uC2DC \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694."
702
+ "An unknown error occurred.",
703
+ "Please try again later."
659
704
  );
660
705
  if (attempt < retryConfig.maxRetries) {
661
706
  lastError = unknownError;
@@ -669,8 +714,8 @@ function _fetch(url, options) {
669
714
  });
670
715
  }
671
716
 
672
- // src/core/collection/collections-api.ts
673
- var CollectionsApi = class extends BaseApiClient {
717
+ // src/core/collection/collection-client.ts
718
+ var CollectionClient = class extends HttpClient {
674
719
  constructor(clientKey, secretKey, baseUrl) {
675
720
  super(clientKey, secretKey, baseUrl);
676
721
  }
@@ -678,7 +723,7 @@ var CollectionsApi = class extends BaseApiClient {
678
723
  return new CollectionQueryBuilder(this, collection);
679
724
  }
680
725
  // ============================================================================
681
- // New Payload-native methods
726
+ // Payload-native methods
682
727
  // ============================================================================
683
728
  /**
684
729
  * Find documents (list query)
@@ -842,7 +887,7 @@ function getQueryClient() {
842
887
  return browserQueryClient;
843
888
  }
844
889
 
845
- // src/core/query/UnifiedQuery.ts
890
+ // src/core/query/query-hooks.ts
846
891
  var import_react_query2 = require("@tanstack/react-query");
847
892
  function collectionKeys(collection) {
848
893
  return {
@@ -856,10 +901,10 @@ function collectionKeys(collection) {
856
901
  };
857
902
  }
858
903
  var DEFAULT_PAGE_SIZE = 20;
859
- var UnifiedQueryClient = class {
860
- constructor(queryClient, options) {
904
+ var QueryHooks = class {
905
+ constructor(queryClient, collectionClient) {
861
906
  this.queryClient = queryClient;
862
- this.collectionsApi = new CollectionsApi((options == null ? void 0 : options.clientKey) || "", void 0, options == null ? void 0 : options.baseUrl);
907
+ this.collectionClient = collectionClient;
863
908
  }
864
909
  // ===== useQuery =====
865
910
  useQuery(params, options) {
@@ -868,7 +913,7 @@ var UnifiedQueryClient = class {
868
913
  queryKey: collectionKeys(collection).list(queryOptions),
869
914
  queryFn: () => __async(this, null, function* () {
870
915
  var _a;
871
- const response = yield this.collectionsApi.from(collection).find(queryOptions);
916
+ const response = yield this.collectionClient.from(collection).find(queryOptions);
872
917
  return (_a = response.docs) != null ? _a : [];
873
918
  })
874
919
  }, options));
@@ -880,7 +925,7 @@ var UnifiedQueryClient = class {
880
925
  queryKey: collectionKeys(collection).list(queryOptions),
881
926
  queryFn: () => __async(this, null, function* () {
882
927
  var _a;
883
- const response = yield this.collectionsApi.from(collection).find(queryOptions);
928
+ const response = yield this.collectionClient.from(collection).find(queryOptions);
884
929
  return (_a = response.docs) != null ? _a : [];
885
930
  })
886
931
  }, options));
@@ -891,7 +936,7 @@ var UnifiedQueryClient = class {
891
936
  return (0, import_react_query2.useQuery)(__spreadValues({
892
937
  queryKey: collectionKeys(collection).detail(id, queryOptions),
893
938
  queryFn: () => __async(this, null, function* () {
894
- return yield this.collectionsApi.from(collection).findById(id, queryOptions);
939
+ return yield this.collectionClient.from(collection).findById(id, queryOptions);
895
940
  })
896
941
  }, options));
897
942
  }
@@ -901,7 +946,7 @@ var UnifiedQueryClient = class {
901
946
  return (0, import_react_query2.useSuspenseQuery)(__spreadValues({
902
947
  queryKey: collectionKeys(collection).detail(id, queryOptions),
903
948
  queryFn: () => __async(this, null, function* () {
904
- return yield this.collectionsApi.from(collection).findById(id, queryOptions);
949
+ return yield this.collectionClient.from(collection).findById(id, queryOptions);
905
950
  })
906
951
  }, options));
907
952
  }
@@ -911,7 +956,7 @@ var UnifiedQueryClient = class {
911
956
  return (0, import_react_query2.useInfiniteQuery)(__spreadValues({
912
957
  queryKey: collectionKeys(collection).infinite(queryOptions),
913
958
  queryFn: (_0) => __async(this, [_0], function* ({ pageParam }) {
914
- const response = yield this.collectionsApi.from(collection).find(__spreadProps(__spreadValues({}, queryOptions), { page: pageParam, limit: pageSize }));
959
+ const response = yield this.collectionClient.from(collection).find(__spreadProps(__spreadValues({}, queryOptions), { page: pageParam, limit: pageSize }));
915
960
  return response;
916
961
  }),
917
962
  initialPageParam: 1,
@@ -926,7 +971,7 @@ var UnifiedQueryClient = class {
926
971
  return (0, import_react_query2.useSuspenseInfiniteQuery)(__spreadValues({
927
972
  queryKey: collectionKeys(collection).infinite(queryOptions),
928
973
  queryFn: (_0) => __async(this, [_0], function* ({ pageParam }) {
929
- const response = yield this.collectionsApi.from(collection).find(__spreadProps(__spreadValues({}, queryOptions), { page: pageParam, limit: pageSize }));
974
+ const response = yield this.collectionClient.from(collection).find(__spreadProps(__spreadValues({}, queryOptions), { page: pageParam, limit: pageSize }));
930
975
  return response;
931
976
  }),
932
977
  initialPageParam: 1,
@@ -943,7 +988,7 @@ var UnifiedQueryClient = class {
943
988
  queryKey: collectionKeys(collection).list(queryOptions),
944
989
  queryFn: () => __async(this, null, function* () {
945
990
  var _a;
946
- const response = yield this.collectionsApi.from(collection).find(queryOptions);
991
+ const response = yield this.collectionClient.from(collection).find(queryOptions);
947
992
  return (_a = response.docs) != null ? _a : [];
948
993
  })
949
994
  }, options));
@@ -956,7 +1001,7 @@ var UnifiedQueryClient = class {
956
1001
  return this.queryClient.prefetchQuery(__spreadValues({
957
1002
  queryKey: collectionKeys(collection).detail(id, queryOptions),
958
1003
  queryFn: () => __async(this, null, function* () {
959
- return yield this.collectionsApi.from(collection).findById(id, queryOptions);
1004
+ return yield this.collectionClient.from(collection).findById(id, queryOptions);
960
1005
  })
961
1006
  }, options));
962
1007
  });
@@ -969,7 +1014,7 @@ var UnifiedQueryClient = class {
969
1014
  return this.queryClient.prefetchInfiniteQuery({
970
1015
  queryKey: collectionKeys(collection).infinite(queryOptions),
971
1016
  queryFn: (_0) => __async(this, [_0], function* ({ pageParam }) {
972
- const response = yield this.collectionsApi.from(collection).find(__spreadProps(__spreadValues({}, queryOptions), { page: pageParam, limit: pageSize }));
1017
+ const response = yield this.collectionClient.from(collection).find(__spreadProps(__spreadValues({}, queryOptions), { page: pageParam, limit: pageSize }));
973
1018
  return response;
974
1019
  }),
975
1020
  initialPageParam: 1,
@@ -981,6 +1026,52 @@ var UnifiedQueryClient = class {
981
1026
  });
982
1027
  });
983
1028
  }
1029
+ // ===== Mutation Hooks =====
1030
+ useCreate(params, options) {
1031
+ const { collection } = params;
1032
+ return (0, import_react_query2.useMutation)({
1033
+ mutationFn: (data) => __async(this, null, function* () {
1034
+ return yield this.collectionClient.from(collection).create(data);
1035
+ }),
1036
+ onSuccess: (data) => {
1037
+ var _a;
1038
+ this.queryClient.invalidateQueries({ queryKey: collectionKeys(collection).lists() });
1039
+ (_a = options == null ? void 0 : options.onSuccess) == null ? void 0 : _a.call(options, data);
1040
+ },
1041
+ onError: options == null ? void 0 : options.onError,
1042
+ onSettled: options == null ? void 0 : options.onSettled
1043
+ });
1044
+ }
1045
+ useUpdate(params, options) {
1046
+ const { collection } = params;
1047
+ return (0, import_react_query2.useMutation)({
1048
+ mutationFn: (variables) => __async(this, null, function* () {
1049
+ return yield this.collectionClient.from(collection).update(variables.id, variables.data);
1050
+ }),
1051
+ onSuccess: (data) => {
1052
+ var _a;
1053
+ this.queryClient.invalidateQueries({ queryKey: collectionKeys(collection).all });
1054
+ (_a = options == null ? void 0 : options.onSuccess) == null ? void 0 : _a.call(options, data);
1055
+ },
1056
+ onError: options == null ? void 0 : options.onError,
1057
+ onSettled: options == null ? void 0 : options.onSettled
1058
+ });
1059
+ }
1060
+ useRemove(params, options) {
1061
+ const { collection } = params;
1062
+ return (0, import_react_query2.useMutation)({
1063
+ mutationFn: (id) => __async(this, null, function* () {
1064
+ return yield this.collectionClient.from(collection).remove(id);
1065
+ }),
1066
+ onSuccess: (data) => {
1067
+ var _a;
1068
+ this.queryClient.invalidateQueries({ queryKey: collectionKeys(collection).all });
1069
+ (_a = options == null ? void 0 : options.onSuccess) == null ? void 0 : _a.call(options, data);
1070
+ },
1071
+ onError: options == null ? void 0 : options.onError,
1072
+ onSettled: options == null ? void 0 : options.onSettled
1073
+ });
1074
+ }
984
1075
  // ===== Cache Utilities =====
985
1076
  invalidateQueries(collection, type) {
986
1077
  const queryKey = type ? [collection, type] : [collection];
@@ -1022,11 +1113,8 @@ var BrowserClient = class {
1022
1113
  };
1023
1114
  this.state = { metadata };
1024
1115
  this.queryClient = getQueryClient();
1025
- this.query = new UnifiedQueryClient(this.queryClient, {
1026
- clientKey: this.config.clientKey,
1027
- baseUrl: this.baseUrl
1028
- });
1029
- this.collections = new CollectionsApi(this.config.clientKey, void 0, this.baseUrl);
1116
+ this.collections = new CollectionClient(this.config.clientKey, void 0, this.baseUrl);
1117
+ this.query = new QueryHooks(this.queryClient, this.collections);
1030
1118
  }
1031
1119
  from(collection) {
1032
1120
  return this.collections.from(collection);
@@ -1039,8 +1127,8 @@ function createBrowserClient(options) {
1039
1127
  return new BrowserClient(options);
1040
1128
  }
1041
1129
 
1042
- // src/core/api/api-client.ts
1043
- var ApiClient = class {
1130
+ // src/core/api/order-api.ts
1131
+ var OrderApi = class {
1044
1132
  constructor(options) {
1045
1133
  if (!options.clientKey) {
1046
1134
  throw new Error("clientKey is required.");
@@ -1068,7 +1156,7 @@ var ApiClient = class {
1068
1156
  response.status,
1069
1157
  data,
1070
1158
  data.error,
1071
- "\uC694\uCCAD \uCC98\uB9AC \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4."
1159
+ "An error occurred while processing the request."
1072
1160
  );
1073
1161
  }
1074
1162
  return data;
@@ -1102,16 +1190,18 @@ var ServerClient = class {
1102
1190
  userAgent: typeof window !== "undefined" ? (_a = window.navigator) == null ? void 0 : _a.userAgent : "Node.js"
1103
1191
  };
1104
1192
  this.state = { metadata };
1105
- this.api = new ApiClient({
1193
+ this.api = new OrderApi({
1106
1194
  clientKey: this.config.clientKey,
1107
1195
  secretKey: this.config.secretKey,
1108
1196
  baseUrl: this.baseUrl
1109
1197
  });
1110
- this.collections = new CollectionsApi(
1198
+ this.collections = new CollectionClient(
1111
1199
  this.config.clientKey,
1112
1200
  this.config.secretKey,
1113
1201
  this.baseUrl
1114
1202
  );
1203
+ this.queryClient = getQueryClient();
1204
+ this.query = new QueryHooks(this.queryClient, this.collections);
1115
1205
  }
1116
1206
  from(collection) {
1117
1207
  return this.collections.from(collection);
@@ -1134,10 +1224,36 @@ function isValidWebhookEvent(data) {
1134
1224
  const obj = data;
1135
1225
  return typeof obj.collection === "string" && (obj.operation === "create" || obj.operation === "update") && typeof obj.data === "object" && obj.data !== null;
1136
1226
  }
1137
- function handleWebhook(request, handler) {
1227
+ function verifySignature(payload, secret, signature) {
1228
+ return __async(this, null, function* () {
1229
+ const encoder = new TextEncoder();
1230
+ const key = yield crypto.subtle.importKey(
1231
+ "raw",
1232
+ encoder.encode(secret),
1233
+ { name: "HMAC", hash: "SHA-256" },
1234
+ false,
1235
+ ["sign"]
1236
+ );
1237
+ const sig = yield crypto.subtle.sign("HMAC", key, encoder.encode(payload));
1238
+ const expected = Array.from(new Uint8Array(sig)).map((b) => b.toString(16).padStart(2, "0")).join("");
1239
+ return expected === signature;
1240
+ });
1241
+ }
1242
+ function handleWebhook(request, handler, options) {
1138
1243
  return __async(this, null, function* () {
1139
1244
  try {
1140
- const body = yield request.json();
1245
+ const rawBody = yield request.text();
1246
+ if (options == null ? void 0 : options.secret) {
1247
+ const signature = request.headers.get("x-webhook-signature") || "";
1248
+ const valid = yield verifySignature(rawBody, options.secret, signature);
1249
+ if (!valid) {
1250
+ return new Response(
1251
+ JSON.stringify({ error: "Invalid webhook signature" }),
1252
+ { status: 401, headers: { "Content-Type": "application/json" } }
1253
+ );
1254
+ }
1255
+ }
1256
+ const body = JSON.parse(rawBody);
1141
1257
  if (!isValidWebhookEvent(body)) {
1142
1258
  return new Response(
1143
1259
  JSON.stringify({ error: "Invalid webhook event format" }),
@@ -1173,25 +1289,25 @@ function createTypedWebhookHandler(collection, handler) {
1173
1289
  // src/utils/order/generateOrderNumber.ts
1174
1290
  var generateOrderNumber = () => {
1175
1291
  const year = (/* @__PURE__ */ new Date()).getFullYear().toString().slice(-2);
1176
- const month = (/* @__PURE__ */ new Date()).getMonth().toString().padStart(2, "0");
1292
+ const month = ((/* @__PURE__ */ new Date()).getMonth() + 1).toString().padStart(2, "0");
1177
1293
  const day = (/* @__PURE__ */ new Date()).getDate().toString().padStart(2, "0");
1178
1294
  const random = Math.floor(Math.random() * 1e6).toString().padStart(6, "0");
1179
1295
  return `${year}${month}${day}${random}`;
1180
1296
  };
1181
1297
 
1182
1298
  // src/utils/types.ts
1183
- var objectFor = (data) => {
1184
- if (typeof data === "number") {
1185
- return null;
1186
- }
1187
- return data;
1299
+ var resolveRelation = (ref) => {
1300
+ if (typeof ref === "number" || ref === null || ref === void 0) return null;
1301
+ return ref;
1188
1302
  };
1303
+ var objectFor = resolveRelation;
1189
1304
 
1190
1305
  // src/utils/order/formatOrderName.ts
1191
1306
  var formatOrderName = (options) => {
1192
- var _a, _b, _c, _d;
1193
- const optionLength = options.length;
1194
- return optionLength === 1 ? ((_b = objectFor((_a = options == null ? void 0 : options[0]) == null ? void 0 : _a.product)) == null ? void 0 : _b.title) || "" : `${(_d = objectFor((_c = options.at(0)) == null ? void 0 : _c.product)) == null ? void 0 : _d.title} \uC678 ${optionLength - 1}\uAC74`;
1307
+ var _a, _b;
1308
+ if (options.length === 0) return "";
1309
+ const firstTitle = ((_b = resolveRelation((_a = options[0]) == null ? void 0 : _a.product)) == null ? void 0 : _b.title) || "";
1310
+ return options.length === 1 ? firstTitle : `${firstTitle} \uC678 ${options.length - 1}\uAC74`;
1195
1311
  };
1196
1312
 
1197
1313
  // src/components/RichTextContent/index.tsx