@01.software/sdk 0.33.0 → 0.35.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 (76) hide show
  1. package/README.md +214 -22
  2. package/dist/analytics/react.cjs.map +1 -1
  3. package/dist/analytics/react.js.map +1 -1
  4. package/dist/analytics.cjs.map +1 -1
  5. package/dist/analytics.js.map +1 -1
  6. package/dist/client.cjs +342 -27
  7. package/dist/client.cjs.map +1 -1
  8. package/dist/client.d.cts +7 -6
  9. package/dist/client.d.ts +7 -6
  10. package/dist/client.js +342 -27
  11. package/dist/client.js.map +1 -1
  12. package/dist/{collection-client-De6eKW1J.d.cts → collection-client-CR2B8c1v.d.cts} +7 -3
  13. package/dist/{collection-client-B6SlhzIP.d.ts → collection-client-DkREjhQ9.d.ts} +7 -3
  14. package/dist/{const-sPR2IkCe.d.cts → const-BTvdrXtY.d.cts} +4 -4
  15. package/dist/{const-DwmSDeWq.d.ts → const-CdqCauHQ.d.ts} +4 -4
  16. package/dist/errors.cjs +300 -0
  17. package/dist/errors.cjs.map +1 -0
  18. package/dist/{index-BGEhoDUs.d.cts → errors.d.cts} +13 -1
  19. package/dist/{index-BGEhoDUs.d.ts → errors.d.ts} +13 -1
  20. package/dist/errors.js +277 -0
  21. package/dist/errors.js.map +1 -0
  22. package/dist/index-CjA3U6X3.d.cts +186 -0
  23. package/dist/index-DK8_NXkh.d.ts +186 -0
  24. package/dist/index.cjs +1402 -177
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.cts +75 -10
  27. package/dist/index.d.ts +75 -10
  28. package/dist/index.js +1402 -177
  29. package/dist/index.js.map +1 -1
  30. package/dist/{payload-types-dkeQyrDC.d.cts → payload-types-C7tb7Xbs.d.cts} +208 -52
  31. package/dist/{payload-types-dkeQyrDC.d.ts → payload-types-C7tb7Xbs.d.ts} +208 -52
  32. package/dist/query.cjs +195 -36
  33. package/dist/query.cjs.map +1 -1
  34. package/dist/query.d.cts +45 -18
  35. package/dist/query.d.ts +45 -18
  36. package/dist/query.js +195 -36
  37. package/dist/query.js.map +1 -1
  38. package/dist/realtime.cjs.map +1 -1
  39. package/dist/realtime.d.cts +2 -2
  40. package/dist/realtime.d.ts +2 -2
  41. package/dist/realtime.js.map +1 -1
  42. package/dist/{server-CrsPyqEc.d.cts → server-nXOezi4b.d.cts} +22 -6
  43. package/dist/{server-CrsPyqEc.d.ts → server-nXOezi4b.d.ts} +22 -6
  44. package/dist/server.cjs +440 -33
  45. package/dist/server.cjs.map +1 -1
  46. package/dist/server.d.cts +11 -179
  47. package/dist/server.d.ts +11 -179
  48. package/dist/server.js +440 -33
  49. package/dist/server.js.map +1 -1
  50. package/dist/{types-Cel_4L9t.d.ts → types-1ylMrCuW.d.ts} +1 -1
  51. package/dist/{types-B3YT092I.d.cts → types-Bx558PU6.d.cts} +1 -1
  52. package/dist/{types-BHh0YLmq.d.ts → types-Byo_Rty4.d.ts} +705 -69
  53. package/dist/{types-BZKxss8Y.d.cts → types-DDhtZI6E.d.cts} +705 -69
  54. package/dist/ui/canvas/server.cjs +231 -38
  55. package/dist/ui/canvas/server.cjs.map +1 -1
  56. package/dist/ui/canvas/server.d.cts +1 -1
  57. package/dist/ui/canvas/server.d.ts +1 -1
  58. package/dist/ui/canvas/server.js +221 -38
  59. package/dist/ui/canvas/server.js.map +1 -1
  60. package/dist/ui/canvas.cjs +320 -257
  61. package/dist/ui/canvas.cjs.map +1 -1
  62. package/dist/ui/canvas.d.cts +5 -19
  63. package/dist/ui/canvas.d.ts +5 -19
  64. package/dist/ui/canvas.js +323 -260
  65. package/dist/ui/canvas.js.map +1 -1
  66. package/dist/ui/form.d.cts +1 -1
  67. package/dist/ui/form.d.ts +1 -1
  68. package/dist/ui/video.d.cts +1 -1
  69. package/dist/ui/video.d.ts +1 -1
  70. package/dist/webhook.cjs +2 -1
  71. package/dist/webhook.cjs.map +1 -1
  72. package/dist/webhook.d.cts +20 -179
  73. package/dist/webhook.d.ts +20 -179
  74. package/dist/webhook.js +2 -1
  75. package/dist/webhook.js.map +1 -1
  76. package/package.json +12 -3
package/dist/server.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // src/core/collection/http-client.ts
2
2
  import { stringify } from "qs-esm";
3
3
 
4
- // src/core/internal/errors/index.ts
4
+ // src/core/errors.ts
5
5
  var SDKError = class extends Error {
6
6
  constructor(code, message, status, details, userMessage, suggestion, requestId) {
7
7
  super(message);
@@ -191,9 +191,12 @@ function resolveApiUrl(apiUrl) {
191
191
 
192
192
  // src/core/internal/utils/http.ts
193
193
  var DEFAULT_TIMEOUT = 3e4;
194
+ var STOREFRONT_BROWSER_TIMEOUT = 15e3;
194
195
  var DEFAULT_RETRYABLE_STATUSES = [408, 429, 500, 502, 503, 504];
195
196
  var NON_RETRYABLE_STATUSES = [400, 401, 403, 404, 409, 422];
196
197
  var SAFE_METHODS = ["GET", "HEAD", "OPTIONS"];
198
+ var DEFAULT_MAX_RETRIES = 3;
199
+ var STOREFRONT_BROWSER_MAX_RETRIES = 1;
197
200
  function debugLog(debug, type, message, data) {
198
201
  if (!debug) return;
199
202
  const shouldLog = debug === true || type === "request" && debug.logRequests || type === "response" && debug.logResponses || type === "error" && debug.logErrors;
@@ -386,15 +389,18 @@ async function httpFetch(url, options) {
386
389
  publishableKey,
387
390
  secretKey,
388
391
  customerToken,
389
- timeout = DEFAULT_TIMEOUT,
392
+ timeout: timeoutOption = DEFAULT_TIMEOUT,
390
393
  debug,
391
394
  retry,
392
395
  onUnauthorized,
393
396
  ...requestInit
394
397
  } = options || {};
395
398
  const baseUrl = resolveApiUrl(apiUrl);
399
+ const method = (requestInit.method || "GET").toUpperCase();
400
+ const isPublishableKeyBrowserGet = typeof window !== "undefined" && !secretKey && !customerToken && Boolean(publishableKey) && SAFE_METHODS.includes(method);
401
+ const timeout = timeoutOption === DEFAULT_TIMEOUT && isPublishableKeyBrowserGet ? STOREFRONT_BROWSER_TIMEOUT : timeoutOption;
396
402
  const retryConfig = {
397
- maxRetries: retry?.maxRetries ?? 3,
403
+ maxRetries: retry?.maxRetries ?? (isPublishableKeyBrowserGet ? STOREFRONT_BROWSER_MAX_RETRIES : DEFAULT_MAX_RETRIES),
398
404
  retryableStatuses: retry?.retryableStatuses ?? DEFAULT_RETRYABLE_STATUSES,
399
405
  retryDelay: retry?.retryDelay ?? ((attempt) => Math.min(1e3 * 2 ** attempt, 1e4))
400
406
  };
@@ -502,8 +508,8 @@ async function httpFetch(url, options) {
502
508
  ),
503
509
  requestId
504
510
  );
505
- const method = (requestInit.method || "GET").toUpperCase();
506
- if (attempt < retryConfig.maxRetries && SAFE_METHODS.includes(method) && retryConfig.retryableStatuses.includes(response.status)) {
511
+ const method2 = (requestInit.method || "GET").toUpperCase();
512
+ if (attempt < retryConfig.maxRetries && SAFE_METHODS.includes(method2) && retryConfig.retryableStatuses.includes(response.status)) {
507
513
  lastError = error;
508
514
  const retryDelay = retryConfig.retryDelay(attempt);
509
515
  debugLog(debug, "error", `Retrying in ${retryDelay}ms...`, error);
@@ -515,8 +521,8 @@ async function httpFetch(url, options) {
515
521
  return response;
516
522
  } catch (error) {
517
523
  debugLog(debug, "error", url, error);
518
- const method = (requestInit.method || "GET").toUpperCase();
519
- const isSafe = SAFE_METHODS.includes(method);
524
+ const method2 = (requestInit.method || "GET").toUpperCase();
525
+ const isSafe = SAFE_METHODS.includes(method2);
520
526
  if (error instanceof Error && error.name === "AbortError") {
521
527
  const timeoutError = createTimeoutError(
522
528
  `Request timed out after ${timeout}ms.`,
@@ -575,6 +581,35 @@ async function httpFetch(url, options) {
575
581
  throw lastError ?? new NetworkError("Request failed after retries");
576
582
  }
577
583
 
584
+ // src/core/internal/utils/query-string.ts
585
+ function productDetailQuery(params) {
586
+ const search = new URLSearchParams();
587
+ if ("slug" in params) {
588
+ search.set("slug", params.slug);
589
+ } else {
590
+ search.set("id", params.id);
591
+ }
592
+ return `/api/products/detail?${search}`;
593
+ }
594
+ function productDetailCatalogQuery(params) {
595
+ const search = new URLSearchParams();
596
+ if ("slug" in params) {
597
+ search.set("slug", params.slug);
598
+ } else {
599
+ search.set("id", params.id);
600
+ }
601
+ return `/api/products/detail/catalog?${search}`;
602
+ }
603
+ function listingGroupsQuery(params) {
604
+ return `/api/products/listing-groups?ids=${params.productIds.map(encodeURIComponent).join(",")}`;
605
+ }
606
+ function listingGroupsCatalogQuery(params) {
607
+ return `/api/products/listing-groups/catalog?ids=${params.productIds.map(encodeURIComponent).join(",")}`;
608
+ }
609
+ function stockSnapshotQuery(params) {
610
+ return `/api/products/stock?variantIds=${params.variantIds.map(encodeURIComponent).join(",")}`;
611
+ }
612
+
578
613
  // src/core/collection/http-client.ts
579
614
  var HttpClient = class {
580
615
  constructor(publishableKey, secretKey, getCustomerToken, onUnauthorized, onRequestId, apiUrl) {
@@ -948,6 +983,16 @@ var CollectionClient = class extends HttpClient {
948
983
  });
949
984
  return this.parseFindResponse(response);
950
985
  }
986
+ /**
987
+ * Find-like response from a cacheable GET custom endpoint.
988
+ */
989
+ async requestFindEndpointGet(endpoint) {
990
+ const response = await this.fetchWithTracking(endpoint, {
991
+ ...this.defaultOptions,
992
+ method: "GET"
993
+ });
994
+ return this.parseFindResponse(response);
995
+ }
951
996
  /**
952
997
  * Find document by ID
953
998
  * GET /api/{collection}/{id}
@@ -1109,6 +1154,8 @@ async function parseApiResponse(response, endpoint) {
1109
1154
  }
1110
1155
 
1111
1156
  // src/core/community/community-client.ts
1157
+ var DEFAULT_POST_LIST_SORT = "-lastActivityAt";
1158
+ var DEFAULT_COMMENT_LIST_SORT = "-createdAt";
1112
1159
  var CommunityClient = class {
1113
1160
  constructor(options) {
1114
1161
  this.publishableKey = requirePublishableKeyForSecret(
@@ -1127,6 +1174,40 @@ var CommunityClient = class {
1127
1174
  const entries = Object.entries(params).filter((e) => e[1] !== void 0).map(([k, v]) => [k, String(v)]);
1128
1175
  return entries.length ? `?${new URLSearchParams(entries).toString()}` : "";
1129
1176
  }
1177
+ buildPostsListQuery(params) {
1178
+ const urlParams = new URLSearchParams();
1179
+ const sort = params?.sort ?? DEFAULT_POST_LIST_SORT;
1180
+ urlParams.set("sort", sort);
1181
+ if (params?.limit !== void 0) urlParams.set("limit", String(params.limit));
1182
+ if (params?.page !== void 0) urlParams.set("page", String(params.page));
1183
+ if (params?.categoryId !== void 0) {
1184
+ urlParams.set("where[categories][in]", params.categoryId);
1185
+ }
1186
+ if (params?.tagId !== void 0) {
1187
+ urlParams.set("where[tags][in]", params.tagId);
1188
+ }
1189
+ return `/api/posts?${urlParams.toString()}`;
1190
+ }
1191
+ buildCommentsListQuery(params) {
1192
+ const urlParams = new URLSearchParams();
1193
+ const sort = params.sort ?? DEFAULT_COMMENT_LIST_SORT;
1194
+ urlParams.set("sort", sort);
1195
+ if (params.postId !== void 0) {
1196
+ urlParams.set("where[post][equals]", params.postId);
1197
+ }
1198
+ if (params.parentId !== void 0) {
1199
+ urlParams.set("where[parent][equals]", params.parentId);
1200
+ }
1201
+ if (params.rootComment !== void 0) {
1202
+ urlParams.set("where[rootComment][equals]", params.rootComment);
1203
+ }
1204
+ if (params.topLevelOnly) {
1205
+ urlParams.set("where[parent][exists]", "false");
1206
+ }
1207
+ if (params.limit !== void 0) urlParams.set("limit", String(params.limit));
1208
+ if (params.page !== void 0) urlParams.set("page", String(params.page));
1209
+ return `/api/comments?${urlParams.toString()}`;
1210
+ }
1130
1211
  async execute(endpoint, method, body) {
1131
1212
  const token = typeof this.customerToken === "function" ? this.customerToken() : this.customerToken;
1132
1213
  try {
@@ -1150,6 +1231,28 @@ var CommunityClient = class {
1150
1231
  createPost(params) {
1151
1232
  return this.execute("/api/posts", "POST", params);
1152
1233
  }
1234
+ /**
1235
+ * Public post feed. Server applies the same visibility contract as
1236
+ * `communityPostRead` (published + visible + moderation-safe).
1237
+ */
1238
+ listPosts(params) {
1239
+ return this.execute(
1240
+ this.buildPostsListQuery(params),
1241
+ "GET"
1242
+ );
1243
+ }
1244
+ listPostCategories(params) {
1245
+ return this.execute(
1246
+ `/api/post-categories${this.buildQuery(params)}`,
1247
+ "GET"
1248
+ );
1249
+ }
1250
+ listPostTags(params) {
1251
+ return this.execute(
1252
+ `/api/post-tags${this.buildQuery(params)}`,
1253
+ "GET"
1254
+ );
1255
+ }
1153
1256
  getMyPosts(params) {
1154
1257
  return this.execute(
1155
1258
  `/api/posts/my${this.buildQuery(params)}`,
@@ -1185,16 +1288,37 @@ var CommunityClient = class {
1185
1288
  }
1186
1289
  return this.execute("/api/comments", "POST", body);
1187
1290
  }
1291
+ /**
1292
+ * List comments for a post.
1293
+ *
1294
+ * - Default: all visible comments on the post (any depth).
1295
+ * - `topLevelOnly: true`: only root comments (`parent` unset).
1296
+ * - `rootComment`: comments belonging to a thread rooted at that comment.
1297
+ */
1188
1298
  listComments(params) {
1189
- const { postId, page, limit, rootComment } = params;
1190
- const urlParams = new URLSearchParams();
1191
- urlParams.set("where[post][equals]", postId);
1192
- urlParams.set("sort", "-createdAt");
1193
- if (limit !== void 0) urlParams.set("limit", String(limit));
1194
- if (page !== void 0) urlParams.set("page", String(page));
1195
- if (rootComment !== void 0) urlParams.set("where[rootComment][equals]", rootComment);
1299
+ const { postId, page, limit, rootComment, topLevelOnly, sort } = params;
1300
+ return this.execute(
1301
+ this.buildCommentsListQuery({
1302
+ postId,
1303
+ page,
1304
+ limit,
1305
+ rootComment,
1306
+ topLevelOnly,
1307
+ sort
1308
+ }),
1309
+ "GET"
1310
+ );
1311
+ }
1312
+ /** Direct replies to a comment (`where[parent][equals]`). */
1313
+ listReplies(params) {
1314
+ const { commentId, page, limit, sort } = params;
1196
1315
  return this.execute(
1197
- `/api/comments?${urlParams.toString()}`,
1316
+ this.buildCommentsListQuery({
1317
+ parentId: commentId,
1318
+ page,
1319
+ limit,
1320
+ sort
1321
+ }),
1198
1322
  "GET"
1199
1323
  );
1200
1324
  }
@@ -1222,10 +1346,18 @@ var CommunityClient = class {
1222
1346
  }
1223
1347
  // Reactions
1224
1348
  addReaction(params) {
1225
- const { postId, type } = params;
1349
+ const { postId, typeSlug, type } = params;
1350
+ const reactionType = typeSlug ?? type;
1351
+ if (!reactionType) {
1352
+ throw new SDKError(
1353
+ "validation_failed",
1354
+ "addReaction requires typeSlug (or deprecated type)",
1355
+ 400
1356
+ );
1357
+ }
1226
1358
  return this.execute("/api/reactions", "POST", {
1227
1359
  post: postId,
1228
- type
1360
+ type: reactionType
1229
1361
  });
1230
1362
  }
1231
1363
  removeReaction(params) {
@@ -1236,10 +1368,18 @@ var CommunityClient = class {
1236
1368
  );
1237
1369
  }
1238
1370
  addCommentReaction(params) {
1239
- const { commentId, type } = params;
1371
+ const { commentId, typeSlug, type } = params;
1372
+ const reactionType = typeSlug ?? type;
1373
+ if (!reactionType) {
1374
+ throw new SDKError(
1375
+ "validation_failed",
1376
+ "addCommentReaction requires typeSlug (or deprecated type)",
1377
+ 400
1378
+ );
1379
+ }
1240
1380
  return this.execute("/api/reactions", "POST", {
1241
1381
  comment: commentId,
1242
- type
1382
+ type: reactionType
1243
1383
  });
1244
1384
  }
1245
1385
  removeCommentReaction(params) {
@@ -1255,6 +1395,12 @@ var CommunityClient = class {
1255
1395
  "GET"
1256
1396
  );
1257
1397
  }
1398
+ getCommentReactionSummary(params) {
1399
+ return this.execute(
1400
+ `/api/comments/${params.commentId}/reactions`,
1401
+ "GET"
1402
+ );
1403
+ }
1258
1404
  getReactionTypes() {
1259
1405
  return this.execute(
1260
1406
  "/api/reaction-types?limit=100",
@@ -1279,6 +1425,25 @@ var CommunityClient = class {
1279
1425
  "GET"
1280
1426
  );
1281
1427
  }
1428
+ // Profiles
1429
+ listProfileLists(params) {
1430
+ return this.execute(
1431
+ `/api/customer-profile-lists${this.buildQuery(params)}`,
1432
+ "GET"
1433
+ );
1434
+ }
1435
+ async getProfileList(params) {
1436
+ const query = "slug" in params ? `?where[slug][equals]=${encodeURIComponent(params.slug)}&limit=1` : `?where[id][equals]=${encodeURIComponent(params.id)}&limit=1`;
1437
+ const res = await this.execute(`/api/customer-profile-lists${query}`, "GET");
1438
+ return res.docs[0] ?? null;
1439
+ }
1440
+ updatePublicProfile(body) {
1441
+ return this.execute(
1442
+ "/api/customers/me/profile",
1443
+ "PATCH",
1444
+ body
1445
+ );
1446
+ }
1282
1447
  };
1283
1448
 
1284
1449
  // src/core/api/base-api.ts
@@ -1323,10 +1488,18 @@ var ModerationApi = class extends BaseApi {
1323
1488
  super("ModerationApi", options);
1324
1489
  }
1325
1490
  banCustomer(params) {
1326
- return this.request("/api/community-bans/ban", params);
1491
+ return this.request(
1492
+ "/api/community-bans/ban-bearer",
1493
+ params,
1494
+ { method: "POST" }
1495
+ );
1327
1496
  }
1328
1497
  unbanCustomer(params) {
1329
- return this.request("/api/community-bans/unban", params);
1498
+ return this.request(
1499
+ "/api/community-bans/unban-bearer",
1500
+ params,
1501
+ { method: "POST" }
1502
+ );
1330
1503
  }
1331
1504
  };
1332
1505
 
@@ -1423,6 +1596,37 @@ function productDetailResultFromError(error) {
1423
1596
  if (!reason) return void 0;
1424
1597
  return { found: false, reason };
1425
1598
  }
1599
+ function rejectLegacyOptionValueSwatchColor(value) {
1600
+ if (Object.prototype.hasOwnProperty.call(
1601
+ value,
1602
+ "swatchColor"
1603
+ )) {
1604
+ throw new TypeError(
1605
+ 'Product upsert option values no longer accept legacy flat "swatchColor"; use nested "swatch" instead.'
1606
+ );
1607
+ }
1608
+ }
1609
+ function normalizeProductUpsertOptionValue(value) {
1610
+ rejectLegacyOptionValueSwatchColor(value);
1611
+ return value;
1612
+ }
1613
+ function normalizeProductUpsertParams(params) {
1614
+ const options = params.options ?? [];
1615
+ const variants = params.variants ?? [];
1616
+ if (!options.length) {
1617
+ return { ...params, options, variants };
1618
+ }
1619
+ return {
1620
+ ...params,
1621
+ options: options.map((option) => ({
1622
+ ...option,
1623
+ values: option.values.map(
1624
+ (value) => normalizeProductUpsertOptionValue(value)
1625
+ )
1626
+ })),
1627
+ variants
1628
+ };
1629
+ }
1426
1630
  var ProductApi = class extends BaseApi {
1427
1631
  constructor(options) {
1428
1632
  super("ProductApi", options);
@@ -1435,10 +1639,25 @@ var ProductApi = class extends BaseApi {
1435
1639
  stockCheck(params) {
1436
1640
  return this.request("/api/products/stock-check", params);
1437
1641
  }
1642
+ stockSnapshot(params) {
1643
+ return this.request(
1644
+ stockSnapshotQuery(params),
1645
+ void 0,
1646
+ { method: "GET" }
1647
+ );
1648
+ }
1438
1649
  listingGroups(params) {
1439
1650
  return this.request(
1440
- "/api/products/listing-groups",
1441
- params
1651
+ listingGroupsQuery(params),
1652
+ void 0,
1653
+ { method: "GET" }
1654
+ );
1655
+ }
1656
+ listingGroupsCatalog(params) {
1657
+ return this.request(
1658
+ listingGroupsCatalogQuery(params),
1659
+ void 0,
1660
+ { method: "GET" }
1442
1661
  );
1443
1662
  }
1444
1663
  /**
@@ -1454,8 +1673,9 @@ var ProductApi = class extends BaseApi {
1454
1673
  async detail(params) {
1455
1674
  try {
1456
1675
  const product = await this.request(
1457
- "/api/products/detail",
1458
- params
1676
+ productDetailQuery(params),
1677
+ void 0,
1678
+ { method: "GET" }
1459
1679
  );
1460
1680
  return { found: true, product };
1461
1681
  } catch (err) {
@@ -1464,6 +1684,20 @@ var ProductApi = class extends BaseApi {
1464
1684
  throw err;
1465
1685
  }
1466
1686
  }
1687
+ async detailCatalog(params) {
1688
+ try {
1689
+ const product = await this.request(
1690
+ productDetailCatalogQuery(params),
1691
+ void 0,
1692
+ { method: "GET" }
1693
+ );
1694
+ return { found: true, product };
1695
+ } catch (err) {
1696
+ const notFoundResult = productDetailResultFromError(err);
1697
+ if (notFoundResult?.found === false) return notFoundResult;
1698
+ throw err;
1699
+ }
1700
+ }
1467
1701
  /**
1468
1702
  * Atomically create or update a product together with its options,
1469
1703
  * option-values, and variants in a single transaction. Mirrors Shopify's
@@ -1471,7 +1705,10 @@ var ProductApi = class extends BaseApi {
1471
1705
  * `product-upsert` tool.
1472
1706
  */
1473
1707
  upsert(params) {
1474
- return this.request("/api/products/upsert", params);
1708
+ return this.request(
1709
+ "/api/products/upsert",
1710
+ normalizeProductUpsertParams(params)
1711
+ );
1475
1712
  }
1476
1713
  };
1477
1714
 
@@ -1496,12 +1733,24 @@ var ShippingApi = class extends BaseApi {
1496
1733
  };
1497
1734
 
1498
1735
  // src/core/api/order-api.ts
1736
+ function idempotencyRequestOptions(idempotencyKey) {
1737
+ return idempotencyKey ? { headers: { "X-Idempotency-Key": idempotencyKey } } : void 0;
1738
+ }
1739
+ function splitIdempotencyKey(params) {
1740
+ const { idempotencyKey, ...body } = params;
1741
+ return { body, idempotencyKey };
1742
+ }
1499
1743
  var OrderApi = class extends BaseApi {
1500
1744
  constructor(options) {
1501
1745
  super("OrderApi", options);
1502
1746
  }
1503
1747
  createOrder(params) {
1504
- return this.request("/api/orders/create", params);
1748
+ const { body, idempotencyKey } = splitIdempotencyKey(params);
1749
+ return this.request(
1750
+ "/api/orders/create",
1751
+ body,
1752
+ idempotencyRequestOptions(idempotencyKey)
1753
+ );
1505
1754
  }
1506
1755
  updateOrder(params) {
1507
1756
  return this.request("/api/orders/update", params);
@@ -1510,17 +1759,42 @@ var OrderApi = class extends BaseApi {
1510
1759
  return this.request("/api/transactions/update", params);
1511
1760
  }
1512
1761
  confirmPayment(params) {
1762
+ const { body, idempotencyKey } = splitIdempotencyKey(params);
1763
+ const headerKey = idempotencyKey ?? params.providerEventId;
1513
1764
  return this.request(
1514
1765
  "/api/orders/confirm-payment",
1515
- params,
1516
- params.providerEventId ? { headers: { "X-Idempotency-Key": params.providerEventId } } : void 0
1766
+ body,
1767
+ idempotencyRequestOptions(headerKey)
1768
+ );
1769
+ }
1770
+ cancelOrder(params) {
1771
+ const { idempotencyKey } = params;
1772
+ const body = {
1773
+ orderNumber: params.orderNumber,
1774
+ reasonCode: params.reasonCode,
1775
+ reasonDetail: params.reasonDetail
1776
+ };
1777
+ return this.request(
1778
+ "/api/orders/cancel",
1779
+ body,
1780
+ idempotencyKey ? { headers: { "X-Idempotency-Key": idempotencyKey } } : void 0
1517
1781
  );
1518
1782
  }
1519
1783
  checkout(params) {
1520
- return this.request("/api/orders/checkout", params);
1784
+ const { body, idempotencyKey } = splitIdempotencyKey(params);
1785
+ return this.request(
1786
+ "/api/orders/checkout",
1787
+ body,
1788
+ idempotencyRequestOptions(idempotencyKey)
1789
+ );
1521
1790
  }
1522
1791
  createFulfillment(params) {
1523
- return this.request("/api/orders/create-fulfillment", params);
1792
+ const { body, idempotencyKey } = splitIdempotencyKey(params);
1793
+ return this.request(
1794
+ "/api/orders/create-fulfillment",
1795
+ body,
1796
+ idempotencyRequestOptions(idempotencyKey)
1797
+ );
1524
1798
  }
1525
1799
  updateFulfillment(params) {
1526
1800
  return this.request("/api/orders/update-fulfillment", params);
@@ -1532,13 +1806,20 @@ var OrderApi = class extends BaseApi {
1532
1806
  );
1533
1807
  }
1534
1808
  returnWithRefund(params) {
1809
+ const { body, idempotencyKey } = splitIdempotencyKey(params);
1535
1810
  return this.request(
1536
1811
  "/api/returns/return-refund",
1537
- params
1812
+ body,
1813
+ idempotencyRequestOptions(idempotencyKey)
1538
1814
  );
1539
1815
  }
1540
1816
  createReturn(params) {
1541
- return this.request("/api/returns/create", params);
1817
+ const { body, idempotencyKey } = splitIdempotencyKey(params);
1818
+ return this.request(
1819
+ "/api/returns/create",
1820
+ body,
1821
+ idempotencyRequestOptions(idempotencyKey)
1822
+ );
1542
1823
  }
1543
1824
  updateReturn(params) {
1544
1825
  return this.request("/api/returns/update", params);
@@ -1640,6 +1921,7 @@ var ServerCommerceClient = class {
1640
1921
  update: orderApi.updateOrder.bind(orderApi),
1641
1922
  updateTransaction: orderApi.updateTransaction.bind(orderApi),
1642
1923
  confirmPayment: orderApi.confirmPayment.bind(orderApi),
1924
+ cancelOrder: orderApi.cancelOrder.bind(orderApi),
1643
1925
  createFulfillment: orderApi.createFulfillment.bind(orderApi),
1644
1926
  updateFulfillment: orderApi.updateFulfillment.bind(orderApi),
1645
1927
  bulkImportFulfillments: orderApi.bulkImportFulfillments.bind(orderApi),
@@ -1656,6 +1938,113 @@ var ServerCommerceClient = class {
1656
1938
  }
1657
1939
  };
1658
1940
 
1941
+ // src/core/events/events-client.ts
1942
+ var EventsClient = class {
1943
+ constructor(options) {
1944
+ const secretKey = options.secretKey;
1945
+ this.publishableKey = requirePublishableKeyForSecret(
1946
+ "EventsClient",
1947
+ options.publishableKey,
1948
+ secretKey
1949
+ );
1950
+ this.apiUrl = options.apiUrl;
1951
+ this.customerToken = options.customerToken;
1952
+ this.onUnauthorized = options.onUnauthorized;
1953
+ this.onRequestId = options.onRequestId;
1954
+ }
1955
+ getRange(params) {
1956
+ return this.execute(
1957
+ buildRangeEndpoint(params),
1958
+ "GET",
1959
+ void 0,
1960
+ { useCustomerAuth: false }
1961
+ );
1962
+ }
1963
+ register(params) {
1964
+ return this.execute(
1965
+ "/api/event-registrations/register",
1966
+ "POST",
1967
+ buildRegistrationRequestBody(params),
1968
+ { useCustomerAuth: true }
1969
+ );
1970
+ }
1971
+ getGuestRegistration(token) {
1972
+ return this.execute(
1973
+ "/api/event-registrations/guest/lookup",
1974
+ "POST",
1975
+ { token },
1976
+ { useCustomerAuth: false }
1977
+ );
1978
+ }
1979
+ cancelGuestRegistration(token, params = {}) {
1980
+ return this.execute(
1981
+ "/api/event-registrations/guest/cancel",
1982
+ "POST",
1983
+ buildGuestCancelRequestBody(token, params),
1984
+ { useCustomerAuth: false }
1985
+ );
1986
+ }
1987
+ async execute(endpoint, method, body, options = {}) {
1988
+ const useCustomerAuth = options.useCustomerAuth === true;
1989
+ const token = useCustomerAuth ? typeof this.customerToken === "function" ? this.customerToken() : this.customerToken : void 0;
1990
+ try {
1991
+ const response = await httpFetch(endpoint, {
1992
+ method,
1993
+ apiUrl: this.apiUrl,
1994
+ publishableKey: this.publishableKey,
1995
+ ...useCustomerAuth && token ? { customerToken: token } : {},
1996
+ ...useCustomerAuth && token && this.onUnauthorized && { onUnauthorized: this.onUnauthorized },
1997
+ ...body !== void 0 && { body: JSON.stringify(body) }
1998
+ });
1999
+ this.onRequestId?.(response.headers.get("x-request-id") ?? null);
2000
+ return parseApiResponse(response, endpoint);
2001
+ } catch (err) {
2002
+ const id = err instanceof SDKError ? err.requestId ?? null : null;
2003
+ this.onRequestId?.(id);
2004
+ throw err;
2005
+ }
2006
+ }
2007
+ };
2008
+ function buildRegistrationRequestBody(params) {
2009
+ return {
2010
+ event: params.event,
2011
+ occurrence: params.occurrence,
2012
+ ...params.quantity !== void 0 && { quantity: params.quantity },
2013
+ ...params.attendee !== void 0 && { attendee: params.attendee },
2014
+ ...params.answers !== void 0 && { answers: params.answers }
2015
+ };
2016
+ }
2017
+ function buildGuestCancelRequestBody(token, params) {
2018
+ return {
2019
+ token,
2020
+ ...params.reason !== void 0 && { reason: params.reason }
2021
+ };
2022
+ }
2023
+ function buildRangeEndpoint(params) {
2024
+ const urlParams = new URLSearchParams();
2025
+ urlParams.set("start", formatDateParam(params.start));
2026
+ urlParams.set("end", formatDateParam(params.end));
2027
+ if (params.limit !== void 0) urlParams.set("limit", String(params.limit));
2028
+ if (params.page !== void 0) urlParams.set("page", String(params.page));
2029
+ appendValues(urlParams, "calendar", params.calendar);
2030
+ appendValues(urlParams, "calendarSlug", params.calendarSlug);
2031
+ appendValues(urlParams, "category", params.category);
2032
+ appendValues(urlParams, "categorySlug", params.categorySlug);
2033
+ appendValues(urlParams, "tag", params.tag);
2034
+ appendValues(urlParams, "tagSlug", params.tagSlug);
2035
+ return `/api/event-occurrences/range?${urlParams.toString()}`;
2036
+ }
2037
+ function formatDateParam(value) {
2038
+ return value instanceof Date ? value.toISOString() : value;
2039
+ }
2040
+ function appendValues(params, key, value) {
2041
+ if (value === void 0) return;
2042
+ const values = Array.isArray(value) ? value : [value];
2043
+ for (const entry of values) {
2044
+ if (entry) params.append(key, entry);
2045
+ }
2046
+ }
2047
+
1659
2048
  // src/core/api/tenant-introspection-api.ts
1660
2049
  var TenantIntrospectionApi = class extends BaseApi {
1661
2050
  constructor(options) {
@@ -1742,6 +2131,23 @@ var ServerClient = class {
1742
2131
  this.config.apiUrl
1743
2132
  );
1744
2133
  }
2134
+ get events() {
2135
+ if (!this._events) {
2136
+ if (!this.config.publishableKey) {
2137
+ throw createConfigError(
2138
+ "publishableKey is required for server.events. It is sent as X-Publishable-Key for rate limiting and quota enforcement. Get it from Console > Settings > API Keys."
2139
+ );
2140
+ }
2141
+ this._events = new EventsClient({
2142
+ publishableKey: this.config.publishableKey,
2143
+ apiUrl: this.config.apiUrl,
2144
+ onRequestId: (id) => {
2145
+ this.lastRequestId = id;
2146
+ }
2147
+ });
2148
+ }
2149
+ return this._events;
2150
+ }
1745
2151
  getState() {
1746
2152
  return { ...this.state };
1747
2153
  }
@@ -1756,6 +2162,7 @@ function createServerClient(options) {
1756
2162
  export {
1757
2163
  CollectionClient,
1758
2164
  CommunityClient,
2165
+ EventsClient,
1759
2166
  ModerationApi,
1760
2167
  ServerClient,
1761
2168
  ServerCollectionClient,