@01.software/sdk 0.18.0 → 0.20.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;
@@ -1014,10 +1009,10 @@ var COLLECTIONS = [
1014
1009
  "documents",
1015
1010
  "document-categories",
1016
1011
  "document-types",
1017
- "posts",
1018
- "post-authors",
1019
- "post-categories",
1020
- "post-tags",
1012
+ "articles",
1013
+ "article-authors",
1014
+ "article-categories",
1015
+ "article-tags",
1021
1016
  "playlists",
1022
1017
  "playlist-categories",
1023
1018
  "playlist-tags",
@@ -1046,17 +1041,18 @@ var COLLECTIONS = [
1046
1041
  "forms",
1047
1042
  "form-submissions",
1048
1043
  // Community
1049
- "threads",
1044
+ "posts",
1050
1045
  "comments",
1051
1046
  "reactions",
1052
1047
  "reaction-types",
1053
1048
  "bookmarks",
1054
- "thread-categories",
1049
+ "post-categories",
1055
1050
  "reports",
1056
1051
  "community-bans",
1057
1052
  // Events
1058
1053
  "event-calendars",
1059
1054
  "events",
1055
+ "event-categories",
1060
1056
  "event-occurrences",
1061
1057
  "event-tags"
1062
1058
  ];
@@ -1112,7 +1108,6 @@ var CommunityClient = class {
1112
1108
  constructor(options) {
1113
1109
  this.publishableKey = options.publishableKey ?? "";
1114
1110
  this.secretKey = options.secretKey;
1115
- this.tenantId = options.tenantId;
1116
1111
  this.customerToken = options.customerToken;
1117
1112
  this.onUnauthorized = options.onUnauthorized;
1118
1113
  this.onRequestId = options.onRequestId;
@@ -1124,13 +1119,11 @@ var CommunityClient = class {
1124
1119
  }
1125
1120
  async execute(endpoint, method, body) {
1126
1121
  const token = typeof this.customerToken === "function" ? this.customerToken() : this.customerToken;
1127
- const tenantId = this.secretKey?.startsWith("pat01_") && this.tenantId ? this.tenantId : void 0;
1128
1122
  try {
1129
1123
  const response = await httpFetch(endpoint, {
1130
1124
  method,
1131
1125
  publishableKey: this.publishableKey,
1132
1126
  secretKey: this.secretKey,
1133
- tenantId,
1134
1127
  customerToken: token ?? void 0,
1135
1128
  ...token && this.onUnauthorized && { onUnauthorized: this.onUnauthorized },
1136
1129
  ...body !== void 0 && { body: JSON.stringify(body) }
@@ -1143,49 +1136,48 @@ var CommunityClient = class {
1143
1136
  throw err;
1144
1137
  }
1145
1138
  }
1146
- // Threads
1147
- createThread(params) {
1148
- return this.execute("/api/threads", "POST", params);
1139
+ createPost(params) {
1140
+ return this.execute("/api/posts", "POST", params);
1149
1141
  }
1150
- getMyThreads(params) {
1142
+ getMyPosts(params) {
1151
1143
  return this.execute(
1152
- `/api/threads/my${this.buildQuery(params)}`,
1144
+ `/api/posts/my${this.buildQuery(params)}`,
1153
1145
  "GET"
1154
1146
  );
1155
1147
  }
1156
1148
  getTrending(params) {
1157
1149
  return this.execute(
1158
- `/api/threads/trending${this.buildQuery(params)}`,
1150
+ `/api/posts/trending${this.buildQuery(params)}`,
1159
1151
  "GET"
1160
1152
  );
1161
1153
  }
1162
1154
  incrementView(params) {
1163
1155
  return this.execute(
1164
- `/api/threads/${params.threadId}/view`,
1156
+ `/api/posts/${params.postId}/view`,
1165
1157
  "POST"
1166
1158
  );
1167
1159
  }
1168
- reportThread(params) {
1169
- const { threadId, ...body } = params;
1160
+ reportPost(params) {
1161
+ const { postId, ...body } = params;
1170
1162
  return this.execute(
1171
- `/api/threads/${threadId}/report`,
1163
+ `/api/posts/${postId}/report`,
1172
1164
  "POST",
1173
1165
  body
1174
1166
  );
1175
1167
  }
1176
1168
  // Comments
1177
1169
  createComment(params) {
1178
- const { threadId, parentId, body: commentBody } = params;
1179
- const body = { thread: threadId, body: commentBody };
1170
+ const { postId, parentId, body: commentBody } = params;
1171
+ const body = { post: postId, body: commentBody };
1180
1172
  if (parentId !== void 0) {
1181
1173
  body.parent = parentId;
1182
1174
  }
1183
1175
  return this.execute("/api/comments", "POST", body);
1184
1176
  }
1185
1177
  listComments(params) {
1186
- const { threadId, page, limit, rootComment } = params;
1178
+ const { postId, page, limit, rootComment } = params;
1187
1179
  const urlParams = new URLSearchParams();
1188
- urlParams.set("where[thread][equals]", threadId);
1180
+ urlParams.set("where[post][equals]", postId);
1189
1181
  urlParams.set("sort", "-createdAt");
1190
1182
  if (limit !== void 0) urlParams.set("limit", String(limit));
1191
1183
  if (page !== void 0) urlParams.set("page", String(page));
@@ -1219,16 +1211,16 @@ var CommunityClient = class {
1219
1211
  }
1220
1212
  // Reactions
1221
1213
  addReaction(params) {
1222
- const { threadId, type } = params;
1214
+ const { postId, type } = params;
1223
1215
  return this.execute("/api/reactions", "POST", {
1224
- thread: threadId,
1216
+ post: postId,
1225
1217
  type
1226
1218
  });
1227
1219
  }
1228
1220
  removeReaction(params) {
1229
- const { threadId, type } = params;
1221
+ const { postId, type } = params;
1230
1222
  return this.execute(
1231
- `/api/threads/${threadId}/react?type=${encodeURIComponent(type)}`,
1223
+ `/api/posts/${postId}/react?type=${encodeURIComponent(type)}`,
1232
1224
  "DELETE"
1233
1225
  );
1234
1226
  }
@@ -1248,7 +1240,7 @@ var CommunityClient = class {
1248
1240
  }
1249
1241
  getReactionSummary(params) {
1250
1242
  return this.execute(
1251
- `/api/threads/${params.threadId}/reactions`,
1243
+ `/api/posts/${params.postId}/reactions`,
1252
1244
  "GET"
1253
1245
  );
1254
1246
  }
@@ -1261,12 +1253,12 @@ var CommunityClient = class {
1261
1253
  // Bookmarks
1262
1254
  addBookmark(params) {
1263
1255
  return this.execute("/api/bookmarks", "POST", {
1264
- thread: params.threadId
1256
+ post: params.postId
1265
1257
  });
1266
1258
  }
1267
1259
  removeBookmark(params) {
1268
1260
  return this.execute(
1269
- `/api/threads/${params.threadId}/bookmark`,
1261
+ `/api/posts/${params.postId}/bookmark`,
1270
1262
  "DELETE"
1271
1263
  );
1272
1264
  }
@@ -1286,18 +1278,15 @@ var BaseApi = class {
1286
1278
  }
1287
1279
  this.publishableKey = options.publishableKey ?? "";
1288
1280
  this.secretKey = options.secretKey;
1289
- this.tenantId = options.tenantId;
1290
1281
  this.onRequestId = options.onRequestId;
1291
1282
  }
1292
1283
  async request(endpoint, body, options) {
1293
1284
  const method = options?.method ?? "POST";
1294
- const tenantId = this.secretKey.startsWith("pat01_") && this.tenantId ? this.tenantId : void 0;
1295
1285
  try {
1296
1286
  const response = await httpFetch(endpoint, {
1297
1287
  method,
1298
1288
  publishableKey: this.publishableKey,
1299
1289
  secretKey: this.secretKey,
1300
- tenantId,
1301
1290
  ...body !== void 0 && { body: JSON.stringify(body) },
1302
1291
  ...options?.headers && { headers: options.headers }
1303
1292
  });
@@ -1583,20 +1572,17 @@ var CartApi = class {
1583
1572
  }
1584
1573
  this.publishableKey = options.publishableKey ?? "";
1585
1574
  this.secretKey = options.secretKey;
1586
- this.tenantId = options.tenantId;
1587
1575
  this.customerToken = options.customerToken;
1588
1576
  this.onUnauthorized = options.onUnauthorized;
1589
1577
  this.onRequestId = options.onRequestId;
1590
1578
  }
1591
1579
  async execute(endpoint, method, body) {
1592
1580
  const token = typeof this.customerToken === "function" ? this.customerToken() : this.customerToken;
1593
- const tenantId = this.secretKey?.startsWith("pat01_") && this.tenantId ? this.tenantId : void 0;
1594
1581
  try {
1595
1582
  const response = await httpFetch(endpoint, {
1596
1583
  method,
1597
1584
  publishableKey: this.publishableKey,
1598
1585
  secretKey: this.secretKey,
1599
- tenantId,
1600
1586
  customerToken: token ?? void 0,
1601
1587
  ...token && this.onUnauthorized && { onUnauthorized: this.onUnauthorized },
1602
1588
  ...body !== void 0 && { body: JSON.stringify(body) }
@@ -1783,7 +1769,6 @@ var ServerCommerceClient = class {
1783
1769
  const serverOptions = {
1784
1770
  publishableKey: options.publishableKey,
1785
1771
  secretKey: options.secretKey,
1786
- tenantId: options.tenantId,
1787
1772
  onRequestId: options.onRequestId
1788
1773
  };
1789
1774
  const productApi = new ProductApi(serverOptions);
@@ -2454,7 +2439,6 @@ var ServerClient = class {
2454
2439
  const serverOptions = {
2455
2440
  publishableKey: this.config.publishableKey,
2456
2441
  secretKey: this.config.secretKey,
2457
- tenantId: this.config.tenantId,
2458
2442
  onRequestId
2459
2443
  };
2460
2444
  this.commerce = new ServerCommerceClient(serverOptions);
@@ -2471,8 +2455,7 @@ var ServerClient = class {
2471
2455
  this.config.secretKey,
2472
2456
  void 0,
2473
2457
  void 0,
2474
- onRequestId,
2475
- this.config.tenantId
2458
+ onRequestId
2476
2459
  );
2477
2460
  this.queryClient = getQueryClient();
2478
2461
  this.query = new QueryHooks(this.queryClient, this.collections);
@@ -2665,7 +2648,7 @@ function createCustomerAuthWebhookHandler(handlers) {
2665
2648
  await handlers.unhandled?.(event);
2666
2649
  };
2667
2650
  }
2668
- async function verifySignature(payload, secret, signature) {
2651
+ async function verifySignature(payload, secret, signature, timestamp, deliveryId) {
2669
2652
  const encoder = new TextEncoder();
2670
2653
  const key = await crypto.subtle.importKey(
2671
2654
  "raw",
@@ -2680,14 +2663,35 @@ async function verifySignature(payload, secret, signature) {
2680
2663
  const sigBytes = new Uint8Array(
2681
2664
  (signature.match(/.{2}/g) ?? []).map((byte) => parseInt(byte, 16))
2682
2665
  );
2683
- return crypto.subtle.verify("HMAC", key, sigBytes, encoder.encode(payload));
2666
+ return crypto.subtle.verify(
2667
+ "HMAC",
2668
+ key,
2669
+ sigBytes,
2670
+ encoder.encode(`${timestamp}.${deliveryId}.${payload}`)
2671
+ );
2672
+ }
2673
+ function timestampIsFresh(timestamp, toleranceSeconds) {
2674
+ if (!/^\d+$/.test(timestamp)) return false;
2675
+ const timestampMs = Number(timestamp);
2676
+ if (!Number.isFinite(timestampMs)) return false;
2677
+ const skewMs = Math.abs(Date.now() - timestampMs);
2678
+ return skewMs <= toleranceSeconds * 1e3;
2684
2679
  }
2685
2680
  async function handleWebhook(request, handler, options) {
2686
2681
  try {
2687
2682
  const rawBody = await request.text();
2688
2683
  if (options?.secret) {
2689
2684
  const signature = request.headers.get("x-webhook-signature") || "";
2690
- const valid = await verifySignature(rawBody, options.secret, signature);
2685
+ const timestamp = request.headers.get("x-webhook-timestamp") || "";
2686
+ const deliveryId = request.headers.get("x-webhook-delivery-id") || "";
2687
+ const toleranceSeconds = options.toleranceSeconds ?? 300;
2688
+ const valid = Boolean(timestamp && deliveryId) && timestampIsFresh(timestamp, toleranceSeconds) && await verifySignature(
2689
+ rawBody,
2690
+ options.secret,
2691
+ signature,
2692
+ timestamp,
2693
+ deliveryId
2694
+ );
2691
2695
  if (!valid) {
2692
2696
  return new Response(
2693
2697
  JSON.stringify({ error: "Invalid webhook signature" }),