@01.software/sdk 0.17.0 → 0.19.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.
package/dist/index.js CHANGED
@@ -418,7 +418,7 @@ async function parseErrorBody(response) {
418
418
  };
419
419
  try {
420
420
  const body = await response.json();
421
- const reason = typeof body.reason === "string" ? body.reason : void 0;
421
+ const reason = typeof body.reason === "string" ? body.reason : typeof body.code === "string" ? body.code : void 0;
422
422
  if (body.errors && Array.isArray(body.errors)) {
423
423
  const fieldErrors = [];
424
424
  for (const e of body.errors) {
@@ -441,6 +441,7 @@ async function parseErrorBody(response) {
441
441
  errorMessage: `HTTP ${response.status}: ${details}`,
442
442
  userMessage: details,
443
443
  reason,
444
+ body,
444
445
  errors: fieldErrors.length > 0 ? fieldErrors : body.errors
445
446
  };
446
447
  }
@@ -449,17 +450,19 @@ async function parseErrorBody(response) {
449
450
  return {
450
451
  errorMessage: `HTTP ${response.status}: ${body.error}`,
451
452
  userMessage: body.error,
452
- reason
453
+ reason,
454
+ body
453
455
  };
454
456
  }
455
457
  if (body.message) {
456
458
  return {
457
459
  errorMessage: `HTTP ${response.status}: ${body.message}`,
458
460
  userMessage: body.message,
459
- reason
461
+ reason,
462
+ body
460
463
  };
461
464
  }
462
- return { ...fallback, reason };
465
+ return { ...fallback, reason, body };
463
466
  } catch {
464
467
  return fallback;
465
468
  }
@@ -476,7 +479,6 @@ async function httpFetch(url, options) {
476
479
  publishableKey,
477
480
  secretKey,
478
481
  customerToken,
479
- tenantId,
480
482
  timeout = DEFAULT_TIMEOUT,
481
483
  debug,
482
484
  retry,
@@ -506,9 +508,6 @@ async function httpFetch(url, options) {
506
508
  if (authToken) {
507
509
  headers.set("Authorization", `Bearer ${authToken}`);
508
510
  }
509
- if (tenantId) {
510
- headers.set("X-Tenant-Id", tenantId);
511
- }
512
511
  if (!headers.has("Content-Type") && requestInit.body && !(requestInit.body instanceof FormData)) {
513
512
  headers.set("Content-Type", "application/json");
514
513
  }
@@ -675,10 +674,9 @@ async function httpFetch(url, options) {
675
674
 
676
675
  // src/core/collection/http-client.ts
677
676
  var HttpClient = class {
678
- constructor(publishableKey, secretKey, getCustomerToken, onUnauthorized, onRequestId, tenantId) {
677
+ constructor(publishableKey, secretKey, getCustomerToken, onUnauthorized, onRequestId) {
679
678
  this.publishableKey = publishableKey;
680
679
  this.secretKey = secretKey;
681
- this.tenantId = tenantId;
682
680
  this.getCustomerToken = getCustomerToken;
683
681
  this.onUnauthorized = onUnauthorized;
684
682
  this.onRequestId = onRequestId;
@@ -688,9 +686,6 @@ var HttpClient = class {
688
686
  publishableKey: this.publishableKey,
689
687
  secretKey: this.secretKey
690
688
  };
691
- if (this.secretKey?.startsWith("pat01_") && this.tenantId) {
692
- opts.tenantId = this.tenantId;
693
- }
694
689
  const token = this.getCustomerToken?.();
695
690
  if (token) {
696
691
  opts.customerToken = token;
@@ -966,8 +961,6 @@ var INTERNAL_COLLECTIONS = [
966
961
  "track-assets",
967
962
  "audiences",
968
963
  "email-logs",
969
- "tenant-auth-settings",
970
- "tenant-community-settings",
971
964
  "api-usage",
972
965
  "tenant-analytics-daily",
973
966
  "analytics-event-schemas",
@@ -981,7 +974,8 @@ var INTERNAL_COLLECTIONS = [
981
974
  "webhook-deliveries",
982
975
  "audit-logs",
983
976
  "plans",
984
- "webhooks"
977
+ "webhooks",
978
+ "event-registrations"
985
979
  ];
986
980
  var COLLECTIONS = [
987
981
  "tenants",
@@ -1015,10 +1009,10 @@ var COLLECTIONS = [
1015
1009
  "documents",
1016
1010
  "document-categories",
1017
1011
  "document-types",
1018
- "posts",
1019
- "post-authors",
1020
- "post-categories",
1021
- "post-tags",
1012
+ "articles",
1013
+ "article-authors",
1014
+ "article-categories",
1015
+ "article-tags",
1022
1016
  "playlists",
1023
1017
  "playlist-categories",
1024
1018
  "playlist-tags",
@@ -1047,14 +1041,19 @@ var COLLECTIONS = [
1047
1041
  "forms",
1048
1042
  "form-submissions",
1049
1043
  // Community
1050
- "threads",
1044
+ "posts",
1051
1045
  "comments",
1052
1046
  "reactions",
1053
1047
  "reaction-types",
1054
1048
  "bookmarks",
1055
- "thread-categories",
1049
+ "post-categories",
1056
1050
  "reports",
1057
- "community-bans"
1051
+ "community-bans",
1052
+ // Events
1053
+ "event-calendars",
1054
+ "events",
1055
+ "event-occurrences",
1056
+ "event-tags"
1058
1057
  ];
1059
1058
 
1060
1059
  // src/core/api/parse-response.ts
@@ -1108,7 +1107,6 @@ var CommunityClient = class {
1108
1107
  constructor(options) {
1109
1108
  this.publishableKey = options.publishableKey ?? "";
1110
1109
  this.secretKey = options.secretKey;
1111
- this.tenantId = options.tenantId;
1112
1110
  this.customerToken = options.customerToken;
1113
1111
  this.onUnauthorized = options.onUnauthorized;
1114
1112
  this.onRequestId = options.onRequestId;
@@ -1120,13 +1118,11 @@ var CommunityClient = class {
1120
1118
  }
1121
1119
  async execute(endpoint, method, body) {
1122
1120
  const token = typeof this.customerToken === "function" ? this.customerToken() : this.customerToken;
1123
- const tenantId = this.secretKey?.startsWith("pat01_") && this.tenantId ? this.tenantId : void 0;
1124
1121
  try {
1125
1122
  const response = await httpFetch(endpoint, {
1126
1123
  method,
1127
1124
  publishableKey: this.publishableKey,
1128
1125
  secretKey: this.secretKey,
1129
- tenantId,
1130
1126
  customerToken: token ?? void 0,
1131
1127
  ...token && this.onUnauthorized && { onUnauthorized: this.onUnauthorized },
1132
1128
  ...body !== void 0 && { body: JSON.stringify(body) }
@@ -1139,49 +1135,48 @@ var CommunityClient = class {
1139
1135
  throw err;
1140
1136
  }
1141
1137
  }
1142
- // Threads
1143
- createThread(params) {
1144
- return this.execute("/api/threads", "POST", params);
1138
+ createPost(params) {
1139
+ return this.execute("/api/posts", "POST", params);
1145
1140
  }
1146
- getMyThreads(params) {
1141
+ getMyPosts(params) {
1147
1142
  return this.execute(
1148
- `/api/threads/my${this.buildQuery(params)}`,
1143
+ `/api/posts/my${this.buildQuery(params)}`,
1149
1144
  "GET"
1150
1145
  );
1151
1146
  }
1152
1147
  getTrending(params) {
1153
1148
  return this.execute(
1154
- `/api/threads/trending${this.buildQuery(params)}`,
1149
+ `/api/posts/trending${this.buildQuery(params)}`,
1155
1150
  "GET"
1156
1151
  );
1157
1152
  }
1158
1153
  incrementView(params) {
1159
1154
  return this.execute(
1160
- `/api/threads/${params.threadId}/view`,
1155
+ `/api/posts/${params.postId}/view`,
1161
1156
  "POST"
1162
1157
  );
1163
1158
  }
1164
- reportThread(params) {
1165
- const { threadId, ...body } = params;
1159
+ reportPost(params) {
1160
+ const { postId, ...body } = params;
1166
1161
  return this.execute(
1167
- `/api/threads/${threadId}/report`,
1162
+ `/api/posts/${postId}/report`,
1168
1163
  "POST",
1169
1164
  body
1170
1165
  );
1171
1166
  }
1172
1167
  // Comments
1173
1168
  createComment(params) {
1174
- const { threadId, parentId, body: commentBody } = params;
1175
- const body = { thread: threadId, body: commentBody };
1169
+ const { postId, parentId, body: commentBody } = params;
1170
+ const body = { post: postId, body: commentBody };
1176
1171
  if (parentId !== void 0) {
1177
1172
  body.parent = parentId;
1178
1173
  }
1179
1174
  return this.execute("/api/comments", "POST", body);
1180
1175
  }
1181
1176
  listComments(params) {
1182
- const { threadId, page, limit, rootComment } = params;
1177
+ const { postId, page, limit, rootComment } = params;
1183
1178
  const urlParams = new URLSearchParams();
1184
- urlParams.set("where[thread][equals]", threadId);
1179
+ urlParams.set("where[post][equals]", postId);
1185
1180
  urlParams.set("sort", "-createdAt");
1186
1181
  if (limit !== void 0) urlParams.set("limit", String(limit));
1187
1182
  if (page !== void 0) urlParams.set("page", String(page));
@@ -1215,16 +1210,16 @@ var CommunityClient = class {
1215
1210
  }
1216
1211
  // Reactions
1217
1212
  addReaction(params) {
1218
- const { threadId, type } = params;
1213
+ const { postId, type } = params;
1219
1214
  return this.execute("/api/reactions", "POST", {
1220
- thread: threadId,
1215
+ post: postId,
1221
1216
  type
1222
1217
  });
1223
1218
  }
1224
1219
  removeReaction(params) {
1225
- const { threadId, type } = params;
1220
+ const { postId, type } = params;
1226
1221
  return this.execute(
1227
- `/api/threads/${threadId}/react?type=${encodeURIComponent(type)}`,
1222
+ `/api/posts/${postId}/react?type=${encodeURIComponent(type)}`,
1228
1223
  "DELETE"
1229
1224
  );
1230
1225
  }
@@ -1244,7 +1239,7 @@ var CommunityClient = class {
1244
1239
  }
1245
1240
  getReactionSummary(params) {
1246
1241
  return this.execute(
1247
- `/api/threads/${params.threadId}/reactions`,
1242
+ `/api/posts/${params.postId}/reactions`,
1248
1243
  "GET"
1249
1244
  );
1250
1245
  }
@@ -1257,12 +1252,12 @@ var CommunityClient = class {
1257
1252
  // Bookmarks
1258
1253
  addBookmark(params) {
1259
1254
  return this.execute("/api/bookmarks", "POST", {
1260
- thread: params.threadId
1255
+ post: params.postId
1261
1256
  });
1262
1257
  }
1263
1258
  removeBookmark(params) {
1264
1259
  return this.execute(
1265
- `/api/threads/${params.threadId}/bookmark`,
1260
+ `/api/posts/${params.postId}/bookmark`,
1266
1261
  "DELETE"
1267
1262
  );
1268
1263
  }
@@ -1282,18 +1277,15 @@ var BaseApi = class {
1282
1277
  }
1283
1278
  this.publishableKey = options.publishableKey ?? "";
1284
1279
  this.secretKey = options.secretKey;
1285
- this.tenantId = options.tenantId;
1286
1280
  this.onRequestId = options.onRequestId;
1287
1281
  }
1288
1282
  async request(endpoint, body, options) {
1289
1283
  const method = options?.method ?? "POST";
1290
- const tenantId = this.secretKey.startsWith("pat01_") && this.tenantId ? this.tenantId : void 0;
1291
1284
  try {
1292
1285
  const response = await httpFetch(endpoint, {
1293
1286
  method,
1294
1287
  publishableKey: this.publishableKey,
1295
1288
  secretKey: this.secretKey,
1296
- tenantId,
1297
1289
  ...body !== void 0 && { body: JSON.stringify(body) },
1298
1290
  ...options?.headers && { headers: options.headers }
1299
1291
  });
@@ -1470,15 +1462,6 @@ var CustomerAuth = class {
1470
1462
  body: JSON.stringify({ currentPassword, newPassword })
1471
1463
  });
1472
1464
  }
1473
- /**
1474
- * Verify email using the verification token
1475
- */
1476
- async verifyEmail(token) {
1477
- await this.requestJson("/api/customers/verify-email", {
1478
- method: "POST",
1479
- body: JSON.stringify({ token })
1480
- });
1481
- }
1482
1465
  /**
1483
1466
  * Get the authenticated customer's orders with pagination and optional status filter
1484
1467
  */
@@ -1588,20 +1571,17 @@ var CartApi = class {
1588
1571
  }
1589
1572
  this.publishableKey = options.publishableKey ?? "";
1590
1573
  this.secretKey = options.secretKey;
1591
- this.tenantId = options.tenantId;
1592
1574
  this.customerToken = options.customerToken;
1593
1575
  this.onUnauthorized = options.onUnauthorized;
1594
1576
  this.onRequestId = options.onRequestId;
1595
1577
  }
1596
1578
  async execute(endpoint, method, body) {
1597
1579
  const token = typeof this.customerToken === "function" ? this.customerToken() : this.customerToken;
1598
- const tenantId = this.secretKey?.startsWith("pat01_") && this.tenantId ? this.tenantId : void 0;
1599
1580
  try {
1600
1581
  const response = await httpFetch(endpoint, {
1601
1582
  method,
1602
1583
  publishableKey: this.publishableKey,
1603
1584
  secretKey: this.secretKey,
1604
- tenantId,
1605
1585
  customerToken: token ?? void 0,
1606
1586
  ...token && this.onUnauthorized && { onUnauthorized: this.onUnauthorized },
1607
1587
  ...body !== void 0 && { body: JSON.stringify(body) }
@@ -1788,7 +1768,6 @@ var ServerCommerceClient = class {
1788
1768
  const serverOptions = {
1789
1769
  publishableKey: options.publishableKey,
1790
1770
  secretKey: options.secretKey,
1791
- tenantId: options.tenantId,
1792
1771
  onRequestId: options.onRequestId
1793
1772
  };
1794
1773
  const productApi = new ProductApi(serverOptions);
@@ -2216,14 +2195,6 @@ var CustomerHooks = class {
2216
2195
  options
2217
2196
  );
2218
2197
  }
2219
- useCustomerVerifyEmail(options) {
2220
- return createMutation(
2221
- (token) => this.ensureCustomerAuth().verifyEmail(token).then(() => {
2222
- }),
2223
- options,
2224
- this.invalidateMe
2225
- );
2226
- }
2227
2198
  useCustomerRefreshToken(options) {
2228
2199
  return createMutation(
2229
2200
  () => this.ensureCustomerAuth().refreshToken(),
@@ -2268,7 +2239,6 @@ var QueryHooks = class extends CollectionHooks {
2268
2239
  this.useCustomerLogout = (...args) => this._customer.useCustomerLogout(...args);
2269
2240
  this.useCustomerForgotPassword = (...args) => this._customer.useCustomerForgotPassword(...args);
2270
2241
  this.useCustomerResetPassword = (...args) => this._customer.useCustomerResetPassword(...args);
2271
- this.useCustomerVerifyEmail = (...args) => this._customer.useCustomerVerifyEmail(...args);
2272
2242
  this.useCustomerRefreshToken = (...args) => this._customer.useCustomerRefreshToken(...args);
2273
2243
  this.useCustomerUpdateProfile = (...args) => this._customer.useCustomerUpdateProfile(...args);
2274
2244
  this.useCustomerChangePassword = (...args) => this._customer.useCustomerChangePassword(...args);
@@ -2468,7 +2438,6 @@ var ServerClient = class {
2468
2438
  const serverOptions = {
2469
2439
  publishableKey: this.config.publishableKey,
2470
2440
  secretKey: this.config.secretKey,
2471
- tenantId: this.config.tenantId,
2472
2441
  onRequestId
2473
2442
  };
2474
2443
  this.commerce = new ServerCommerceClient(serverOptions);
@@ -2485,8 +2454,7 @@ var ServerClient = class {
2485
2454
  this.config.secretKey,
2486
2455
  void 0,
2487
2456
  void 0,
2488
- onRequestId,
2489
- this.config.tenantId
2457
+ onRequestId
2490
2458
  );
2491
2459
  this.queryClient = getQueryClient();
2492
2460
  this.query = new QueryHooks(this.queryClient, this.collections);
@@ -2652,9 +2620,34 @@ var RealtimeConnection = class {
2652
2620
  function isValidWebhookEvent(data) {
2653
2621
  if (typeof data !== "object" || data === null) return false;
2654
2622
  const obj = data;
2655
- return typeof obj.collection === "string" && (obj.operation === "create" || obj.operation === "update") && typeof obj.data === "object" && obj.data !== null;
2623
+ return typeof obj.collection === "string" && typeof obj.operation === "string" && obj.operation.length > 0 && typeof obj.data === "object" && obj.data !== null;
2624
+ }
2625
+ var CUSTOMER_PASSWORD_RESET_OPERATION = "password-reset";
2626
+ function isRecord(value) {
2627
+ return typeof value === "object" && value !== null;
2628
+ }
2629
+ function hasString(value, key) {
2630
+ return typeof value[key] === "string";
2631
+ }
2632
+ function hasStringOrNumber(value, key) {
2633
+ return typeof value[key] === "string" || typeof value[key] === "number";
2634
+ }
2635
+ function isCustomerPasswordResetWebhookEvent(event) {
2636
+ if (event.collection !== "customers" || event.operation !== CUSTOMER_PASSWORD_RESET_OPERATION || !isRecord(event.data)) {
2637
+ return false;
2638
+ }
2639
+ return hasStringOrNumber(event.data, "customerId") && hasString(event.data, "email") && hasString(event.data, "name") && hasString(event.data, "resetPasswordToken") && hasString(event.data, "resetPasswordExpiresAt");
2656
2640
  }
2657
- async function verifySignature(payload, secret, signature) {
2641
+ function createCustomerAuthWebhookHandler(handlers) {
2642
+ return async (event) => {
2643
+ if (isCustomerPasswordResetWebhookEvent(event) && handlers.passwordReset) {
2644
+ await handlers.passwordReset(event.data, event);
2645
+ return;
2646
+ }
2647
+ await handlers.unhandled?.(event);
2648
+ };
2649
+ }
2650
+ async function verifySignature(payload, secret, signature, timestamp, deliveryId) {
2658
2651
  const encoder = new TextEncoder();
2659
2652
  const key = await crypto.subtle.importKey(
2660
2653
  "raw",
@@ -2669,14 +2662,35 @@ async function verifySignature(payload, secret, signature) {
2669
2662
  const sigBytes = new Uint8Array(
2670
2663
  (signature.match(/.{2}/g) ?? []).map((byte) => parseInt(byte, 16))
2671
2664
  );
2672
- return crypto.subtle.verify("HMAC", key, sigBytes, encoder.encode(payload));
2665
+ return crypto.subtle.verify(
2666
+ "HMAC",
2667
+ key,
2668
+ sigBytes,
2669
+ encoder.encode(`${timestamp}.${deliveryId}.${payload}`)
2670
+ );
2671
+ }
2672
+ function timestampIsFresh(timestamp, toleranceSeconds) {
2673
+ if (!/^\d+$/.test(timestamp)) return false;
2674
+ const timestampMs = Number(timestamp);
2675
+ if (!Number.isFinite(timestampMs)) return false;
2676
+ const skewMs = Math.abs(Date.now() - timestampMs);
2677
+ return skewMs <= toleranceSeconds * 1e3;
2673
2678
  }
2674
2679
  async function handleWebhook(request, handler, options) {
2675
2680
  try {
2676
2681
  const rawBody = await request.text();
2677
2682
  if (options?.secret) {
2678
2683
  const signature = request.headers.get("x-webhook-signature") || "";
2679
- const valid = await verifySignature(rawBody, options.secret, signature);
2684
+ const timestamp = request.headers.get("x-webhook-timestamp") || "";
2685
+ const deliveryId = request.headers.get("x-webhook-delivery-id") || "";
2686
+ const toleranceSeconds = options.toleranceSeconds ?? 300;
2687
+ const valid = Boolean(timestamp && deliveryId) && timestampIsFresh(timestamp, toleranceSeconds) && await verifySignature(
2688
+ rawBody,
2689
+ options.secret,
2690
+ signature,
2691
+ timestamp,
2692
+ deliveryId
2693
+ );
2680
2694
  if (!valid) {
2681
2695
  return new Response(
2682
2696
  JSON.stringify({ error: "Invalid webhook signature" }),
@@ -3244,6 +3258,7 @@ export {
3244
3258
  AuthError,
3245
3259
  BaseApi,
3246
3260
  COLLECTIONS,
3261
+ CUSTOMER_PASSWORD_RESET_OPERATION,
3247
3262
  CartApi,
3248
3263
  Client,
3249
3264
  CollectionClient,
@@ -3285,6 +3300,7 @@ export {
3285
3300
  createAuthError,
3286
3301
  createClient,
3287
3302
  createConflictError,
3303
+ createCustomerAuthWebhookHandler,
3288
3304
  createNotFoundError,
3289
3305
  createPermissionError,
3290
3306
  createRateLimitError,
@@ -3311,6 +3327,7 @@ export {
3311
3327
  isAuthError,
3312
3328
  isConfigError,
3313
3329
  isConflictError,
3330
+ isCustomerPasswordResetWebhookEvent,
3314
3331
  isGoneError,
3315
3332
  isNetworkError,
3316
3333
  isNotFoundError,