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