@01.software/sdk 0.36.0 → 0.38.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 (82) hide show
  1. package/README.md +142 -55
  2. package/dist/analytics/react.cjs +33 -9
  3. package/dist/analytics/react.cjs.map +1 -1
  4. package/dist/analytics/react.d.cts +1 -1
  5. package/dist/analytics/react.d.ts +1 -1
  6. package/dist/analytics/react.js +33 -9
  7. package/dist/analytics/react.js.map +1 -1
  8. package/dist/analytics.cjs +30 -8
  9. package/dist/analytics.cjs.map +1 -1
  10. package/dist/analytics.d.cts +6 -0
  11. package/dist/analytics.d.ts +6 -0
  12. package/dist/analytics.js +30 -8
  13. package/dist/analytics.js.map +1 -1
  14. package/dist/client.cjs +150 -207
  15. package/dist/client.cjs.map +1 -1
  16. package/dist/client.d.cts +6 -6
  17. package/dist/client.d.ts +6 -6
  18. package/dist/client.js +150 -207
  19. package/dist/client.js.map +1 -1
  20. package/dist/{collection-client-Cv0D2w1Q.d.cts → collection-client-B0J9wMNE.d.cts} +5 -5
  21. package/dist/{collection-client-Bq5Zd7p7.d.ts → collection-client-BroIWHY1.d.ts} +5 -5
  22. package/dist/const-6XHz_jej.d.ts +32 -0
  23. package/dist/const-B5KT72c7.d.cts +32 -0
  24. package/dist/{image-BDz2-AaO.d.cts → image-BDjHp03R.d.cts} +13 -9
  25. package/dist/{image-BDz2-AaO.d.ts → image-BDjHp03R.d.ts} +13 -9
  26. package/dist/{index-DTSXUYkr.d.ts → index-BOLQxveo.d.cts} +9 -6
  27. package/dist/{index-BHDKJ6B3.d.cts → index-CSwR2HSg.d.ts} +9 -6
  28. package/dist/index.cjs +256 -244
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.d.cts +12 -11
  31. package/dist/index.d.ts +12 -11
  32. package/dist/index.js +256 -244
  33. package/dist/index.js.map +1 -1
  34. package/dist/metadata.cjs +5 -3
  35. package/dist/metadata.cjs.map +1 -1
  36. package/dist/metadata.js +5 -3
  37. package/dist/metadata.js.map +1 -1
  38. package/dist/{payload-types-BCui2Oml.d.cts → payload-types-m3jjhxk9.d.cts} +669 -184
  39. package/dist/{payload-types-BCui2Oml.d.ts → payload-types-m3jjhxk9.d.ts} +669 -184
  40. package/dist/query.cjs +3 -1033
  41. package/dist/query.cjs.map +1 -1
  42. package/dist/query.d.cts +13 -13
  43. package/dist/query.d.ts +13 -13
  44. package/dist/query.js +3 -1033
  45. package/dist/query.js.map +1 -1
  46. package/dist/realtime.d.cts +2 -2
  47. package/dist/realtime.d.ts +2 -2
  48. package/dist/server.cjs +121 -85
  49. package/dist/server.cjs.map +1 -1
  50. package/dist/server.d.cts +7 -7
  51. package/dist/server.d.ts +7 -7
  52. package/dist/server.js +121 -85
  53. package/dist/server.js.map +1 -1
  54. package/dist/{types-Dib-zdK6.d.cts → types-CIGscmus.d.cts} +1471 -1100
  55. package/dist/{types-3qV6sY7T.d.ts → types-Cmrd1ezc.d.ts} +1 -15
  56. package/dist/{types-CEzLf3PX.d.cts → types-D0ubzQw0.d.cts} +1 -15
  57. package/dist/{types-DK9EnLwJ.d.ts → types-D2xYdz4P.d.ts} +1471 -1100
  58. package/dist/ui/canvas.cjs +15 -5
  59. package/dist/ui/canvas.cjs.map +1 -1
  60. package/dist/ui/canvas.d.cts +1 -1
  61. package/dist/ui/canvas.d.ts +1 -1
  62. package/dist/ui/canvas.js +15 -5
  63. package/dist/ui/canvas.js.map +1 -1
  64. package/dist/ui/form.d.cts +1 -1
  65. package/dist/ui/form.d.ts +1 -1
  66. package/dist/ui/image.cjs +15 -5
  67. package/dist/ui/image.cjs.map +1 -1
  68. package/dist/ui/image.d.cts +1 -1
  69. package/dist/ui/image.d.ts +1 -1
  70. package/dist/ui/image.js +15 -5
  71. package/dist/ui/image.js.map +1 -1
  72. package/dist/ui/video.d.cts +1 -1
  73. package/dist/ui/video.d.ts +1 -1
  74. package/dist/webhook.cjs +5 -1
  75. package/dist/webhook.cjs.map +1 -1
  76. package/dist/webhook.d.cts +4 -4
  77. package/dist/webhook.d.ts +4 -4
  78. package/dist/webhook.js +5 -1
  79. package/dist/webhook.js.map +1 -1
  80. package/package.json +3 -3
  81. package/dist/const-BDUKFP9w.d.ts +0 -32
  82. package/dist/const-DVcM7Ac_.d.cts +0 -32
package/dist/query.js CHANGED
@@ -377,115 +377,13 @@ var SDKError = class extends Error {
377
377
  };
378
378
  }
379
379
  };
380
- var NetworkError = class extends SDKError {
381
- constructor(message, status, details, userMessage, suggestion) {
382
- super("NETWORK_ERROR", message, status, details, userMessage, suggestion);
383
- this.name = "NetworkError";
384
- }
385
- };
386
- var ValidationError = class extends SDKError {
387
- constructor(message, details, userMessage, suggestion, status = 400) {
388
- super("VALIDATION_ERROR", message, status, details, userMessage, suggestion);
389
- this.name = "ValidationError";
390
- }
391
- };
392
- var ApiError = class extends SDKError {
393
- constructor(message, status, details, userMessage, suggestion, requestId) {
394
- super(
395
- "API_ERROR",
396
- message,
397
- status,
398
- details,
399
- userMessage,
400
- suggestion,
401
- requestId
402
- );
403
- this.name = "ApiError";
404
- }
405
- };
406
380
  var ConfigError = class extends SDKError {
407
381
  constructor(message, details, userMessage, suggestion) {
408
382
  super("CONFIG_ERROR", message, void 0, details, userMessage, suggestion);
409
383
  this.name = "ConfigError";
410
384
  }
411
385
  };
412
- var TimeoutError = class extends SDKError {
413
- constructor(message = "Request timed out.", details, userMessage, suggestion) {
414
- super("TIMEOUT_ERROR", message, 408, details, userMessage, suggestion);
415
- this.name = "TimeoutError";
416
- }
417
- };
418
- var UsageLimitError = class extends SDKError {
419
- constructor(message, usage, details, userMessage, suggestion) {
420
- super("USAGE_LIMIT_ERROR", message, 429, details, userMessage, suggestion);
421
- this.name = "UsageLimitError";
422
- this.usage = usage;
423
- }
424
- toJSON() {
425
- return {
426
- ...super.toJSON(),
427
- usage: this.usage
428
- };
429
- }
430
- };
431
- var AuthError = class extends SDKError {
432
- constructor(message, details, userMessage, suggestion, requestId) {
433
- super(
434
- "auth_error",
435
- message,
436
- 401,
437
- details,
438
- userMessage,
439
- suggestion,
440
- requestId
441
- );
442
- this.name = "AuthError";
443
- }
444
- };
445
- var PermissionError = class extends SDKError {
446
- constructor(message, details, userMessage, suggestion, requestId) {
447
- super(
448
- "permission_error",
449
- message,
450
- 403,
451
- details,
452
- userMessage,
453
- suggestion,
454
- requestId
455
- );
456
- this.name = "PermissionError";
457
- }
458
- };
459
- var NotFoundError = class extends SDKError {
460
- constructor(message, details, userMessage, suggestion, requestId) {
461
- super(
462
- "not_found",
463
- message,
464
- 404,
465
- details,
466
- userMessage,
467
- suggestion,
468
- requestId
469
- );
470
- this.name = "NotFoundError";
471
- }
472
- };
473
- var ConflictError = class extends SDKError {
474
- constructor(message, details, userMessage, suggestion, requestId) {
475
- super("conflict", message, 409, details, userMessage, suggestion, requestId);
476
- this.name = "ConflictError";
477
- }
478
- };
479
- var createNetworkError = (message, status, details, userMessage, suggestion) => new NetworkError(message, status, details, userMessage, suggestion);
480
- var createValidationError = (message, details, userMessage, suggestion, status) => new ValidationError(message, details, userMessage, suggestion, status);
481
- var createApiError = (message, status, details, userMessage, suggestion, requestId) => new ApiError(message, status, details, userMessage, suggestion, requestId);
482
386
  var createConfigError = (message, details, userMessage, suggestion) => new ConfigError(message, details, userMessage, suggestion);
483
- var createTimeoutError = (message, details, userMessage, suggestion) => new TimeoutError(message, details, userMessage, suggestion);
484
- var createUsageLimitError = (message, usage, details, userMessage, suggestion) => new UsageLimitError(message, usage, details, userMessage, suggestion);
485
- var createAuthError = (message, details, userMessage, suggestion, requestId) => new AuthError(message, details, userMessage, suggestion, requestId);
486
- var createPermissionError = (message, details, userMessage, suggestion, requestId) => new PermissionError(message, details, userMessage, suggestion, requestId);
487
- var createNotFoundError = (message, details, userMessage, suggestion, requestId) => new NotFoundError(message, details, userMessage, suggestion, requestId);
488
- var createConflictError = (message, details, userMessage, suggestion, requestId) => new ConflictError(message, details, userMessage, suggestion, requestId);
489
387
 
490
388
  // src/core/query/customer-hooks.ts
491
389
  function createMutation(mutationFn, callbacks, onSuccessExtra) {
@@ -983,7 +881,7 @@ var RealtimeConnection = class {
983
881
  }
984
882
  scheduleReconnect() {
985
883
  if (this.reconnectTimer) return;
986
- const delay2 = Math.min(
884
+ const delay = Math.min(
987
885
  INITIAL_RECONNECT_DELAY * Math.pow(RECONNECT_BACKOFF_FACTOR, this.reconnectAttempt),
988
886
  MAX_RECONNECT_DELAY
989
887
  );
@@ -992,916 +890,7 @@ var RealtimeConnection = class {
992
890
  this.reconnectTimer = null;
993
891
  this.abortController = new AbortController();
994
892
  this.startStream(this.abortController.signal);
995
- }, delay2);
996
- }
997
- };
998
-
999
- // src/utils/types.ts
1000
- var resolveRelation = (ref) => {
1001
- if (typeof ref === "string" || typeof ref === "number" || ref === null || ref === void 0)
1002
- return null;
1003
- return ref;
1004
- };
1005
-
1006
- // src/core/metadata/index.ts
1007
- function extractSeo(doc) {
1008
- const seo = doc.seo ?? {};
1009
- const og = seo.openGraph ?? {};
1010
- return {
1011
- title: seo.title ?? doc.title ?? null,
1012
- description: seo.description ?? null,
1013
- noIndex: seo.noIndex ?? null,
1014
- canonical: seo.canonical ?? null,
1015
- openGraph: {
1016
- title: og.title ?? null,
1017
- description: og.description ?? null,
1018
- image: og.image ?? null
1019
- }
1020
- };
1021
- }
1022
- function generateMetadata(input, options) {
1023
- const title = input.title ?? void 0;
1024
- const description = input.description ?? void 0;
1025
- const ogTitle = input.openGraph?.title ?? title;
1026
- const ogDescription = input.openGraph?.description ?? description;
1027
- const image = resolveMetaImage(input.openGraph?.image);
1028
- return {
1029
- title,
1030
- description,
1031
- ...input.noIndex && { robots: { index: false, follow: false } },
1032
- ...input.canonical && { alternates: { canonical: input.canonical } },
1033
- openGraph: {
1034
- ...ogTitle && { title: ogTitle },
1035
- ...ogDescription && { description: ogDescription },
1036
- ...options?.siteName && { siteName: options.siteName },
1037
- ...image && { images: [image] }
1038
- },
1039
- twitter: {
1040
- card: image ? "summary_large_image" : "summary",
1041
- ...ogTitle && { title: ogTitle },
1042
- ...ogDescription && { description: ogDescription },
1043
- ...image && { images: [image.url] }
1044
- }
1045
- };
1046
- }
1047
- function resolveMetaImage(ref) {
1048
- const image = resolveRelation(ref);
1049
- if (!image) return null;
1050
- const sized = image.sizes?.["1536"];
1051
- const url = sized?.url || image.url;
1052
- if (!url) return null;
1053
- const width = sized?.url ? sized.width : image.width;
1054
- const height = sized?.url ? sized.height : image.height;
1055
- return {
1056
- url,
1057
- ...width && { width },
1058
- ...height && { height },
1059
- ...image.alt && { alt: image.alt }
1060
- };
1061
- }
1062
-
1063
- // src/core/collection/query-builder.ts
1064
- var CollectionQueryBuilder = class {
1065
- constructor(api, collection) {
1066
- this.api = api;
1067
- this.collection = collection;
1068
- }
1069
- /**
1070
- * Find documents (list query)
1071
- * GET /api/{collection}
1072
- * @returns Payload CMS find response with docs array and pagination
1073
- */
1074
- async find(options) {
1075
- return this.api.requestFind(
1076
- `/api/${String(this.collection)}`,
1077
- options
1078
- );
1079
- }
1080
- /**
1081
- * Find document by ID
1082
- * GET /api/{collection}/{id}
1083
- * @returns Document object directly (no wrapper)
1084
- */
1085
- async findById(id, options) {
1086
- return this.api.requestFindById(
1087
- `/api/${String(this.collection)}/${String(id)}`,
1088
- options
1089
- );
1090
- }
1091
- /**
1092
- * Create a new document
1093
- * POST /api/{collection}
1094
- * @returns Payload CMS mutation response with doc and message
1095
- */
1096
- async create(data, options) {
1097
- const endpoint = `/api/${String(this.collection)}`;
1098
- if (options?.file) {
1099
- return this.api.requestCreateWithFile(
1100
- endpoint,
1101
- data,
1102
- options.file,
1103
- options.filename
1104
- );
1105
- }
1106
- return this.api.requestCreate(endpoint, data);
1107
- }
1108
- /**
1109
- * Update a document by ID
1110
- * PATCH /api/{collection}/{id}
1111
- * @returns Payload CMS mutation response with doc and message
1112
- */
1113
- async update(id, data, options) {
1114
- const endpoint = `/api/${String(this.collection)}/${String(id)}`;
1115
- if (options?.file) {
1116
- return this.api.requestUpdateWithFile(
1117
- endpoint,
1118
- data,
1119
- options.file,
1120
- options.filename
1121
- );
1122
- }
1123
- return this.api.requestUpdate(endpoint, data);
1124
- }
1125
- /**
1126
- * Count documents
1127
- * GET /api/{collection}/count
1128
- * @returns Count response with totalDocs
1129
- */
1130
- async count(options) {
1131
- return this.api.requestCount(
1132
- `/api/${String(this.collection)}/count`,
1133
- options
1134
- );
1135
- }
1136
- /**
1137
- * Find first matching document and return its Next.js Metadata.
1138
- * Applies depth: 1 (SEO image populate) and limit: 1 automatically.
1139
- * @returns Metadata or null if no document matches
1140
- */
1141
- async findMetadata(options, metadataOptions) {
1142
- const { docs } = await this.find({ ...options, limit: 1, depth: 1 });
1143
- const doc = docs[0];
1144
- if (!doc) return null;
1145
- return generateMetadata(
1146
- extractSeo(doc),
1147
- metadataOptions
1148
- );
1149
- }
1150
- /**
1151
- * Find document by ID and return its Next.js Metadata.
1152
- * Applies depth: 1 (SEO image populate) automatically.
1153
- * @returns Metadata (throws on 404)
1154
- */
1155
- async findMetadataById(id, metadataOptions) {
1156
- const doc = await this.findById(id, { depth: 1 });
1157
- return generateMetadata(
1158
- extractSeo(doc),
1159
- metadataOptions
1160
- );
1161
- }
1162
- /**
1163
- * Update multiple documents (bulk update)
1164
- * PATCH /api/{collection}
1165
- * @returns Payload CMS find response with updated docs
1166
- */
1167
- async updateMany(where, data) {
1168
- return this.api.requestUpdateMany(
1169
- `/api/${String(this.collection)}`,
1170
- { where, data }
1171
- );
1172
- }
1173
- /**
1174
- * Delete a document by ID
1175
- * DELETE /api/{collection}/{id}
1176
- * @returns Deleted document object directly (no wrapper)
1177
- */
1178
- async remove(id) {
1179
- return this.api.requestDelete(
1180
- `/api/${String(this.collection)}/${String(id)}`
1181
- );
1182
- }
1183
- /**
1184
- * Delete multiple documents (bulk delete)
1185
- * DELETE /api/{collection}
1186
- * @returns Payload CMS find response with deleted docs
1187
- */
1188
- async removeMany(where) {
1189
- return this.api.requestDeleteMany(
1190
- `/api/${String(this.collection)}`,
1191
- { where }
1192
- );
1193
- }
1194
- };
1195
-
1196
- // src/core/collection/http-client.ts
1197
- import { stringify } from "qs-esm";
1198
-
1199
- // src/core/internal/utils/credentials.ts
1200
- function requirePublishableKeyForSecret(apiName, publishableKey, secretKey) {
1201
- if (secretKey && !publishableKey) {
1202
- throw createConfigError(
1203
- `publishableKey is required for ${apiName} when secretKey is used. It is sent as X-Publishable-Key for tenant routing, rate limiting, and quota enforcement.`
1204
- );
1205
- }
1206
- return publishableKey ?? "";
1207
- }
1208
-
1209
- // src/core/client/types.ts
1210
- function resolveApiUrl(apiUrl) {
1211
- if (apiUrl) {
1212
- return apiUrl.replace(/\/$/, "");
1213
- }
1214
- if (typeof process !== "undefined" && process.env) {
1215
- const envUrl = process.env.SOFTWARE_API_URL || process.env.NEXT_PUBLIC_SOFTWARE_API_URL;
1216
- if (envUrl) {
1217
- return envUrl.replace(/\/$/, "");
1218
- }
1219
- }
1220
- return "https://api.01.software";
1221
- }
1222
-
1223
- // src/core/internal/utils/http.ts
1224
- var DEFAULT_TIMEOUT = 3e4;
1225
- var STOREFRONT_BROWSER_TIMEOUT = 15e3;
1226
- var DEFAULT_RETRYABLE_STATUSES = [408, 429, 500, 502, 503, 504];
1227
- var NON_RETRYABLE_STATUSES = [400, 401, 403, 404, 409, 422];
1228
- var SAFE_METHODS = ["GET", "HEAD", "OPTIONS"];
1229
- var DEFAULT_MAX_RETRIES = 3;
1230
- var STOREFRONT_BROWSER_MAX_RETRIES = 1;
1231
- function debugLog(debug, type, message, data) {
1232
- if (!debug) return;
1233
- const shouldLog = debug === true || type === "request" && debug.logRequests || type === "response" && debug.logResponses || type === "error" && debug.logErrors;
1234
- if (shouldLog) {
1235
- console.group(`[SDK ${type.toUpperCase()}] ${message}`);
1236
- if (data) console.log(data);
1237
- console.groupEnd();
1238
- }
1239
- }
1240
- function redactSensitiveHeader(value) {
1241
- const prefix = value.toLowerCase().startsWith("bearer ") ? "Bearer " : "";
1242
- return value.length > 20 ? `${prefix}...****${value.slice(-8)}` : "****";
1243
- }
1244
- function redactSensitiveHeaders(headers) {
1245
- const redacted = Object.fromEntries(headers.entries());
1246
- if (redacted.authorization) {
1247
- redacted.authorization = redactSensitiveHeader(redacted.authorization);
1248
- }
1249
- if (redacted["x-preview-token"]) {
1250
- redacted["x-preview-token"] = redactSensitiveHeader(
1251
- redacted["x-preview-token"]
1252
- );
1253
- }
1254
- return redacted;
1255
- }
1256
- function getErrorSuggestion(status) {
1257
- if (status === 400)
1258
- return "The request data failed validation. Check field values and types.";
1259
- if (status === 401) return "Please check your authentication credentials.";
1260
- if (status === 403)
1261
- return "Access denied. Check your credentials or permissions.";
1262
- if (status === 404) return "The requested resource was not found.";
1263
- if (status === 422) return "The request data failed validation.";
1264
- if (status >= 500) return "A server error occurred. Please try again later.";
1265
- return void 0;
1266
- }
1267
- function isUsageLimitExceededResponse(response) {
1268
- if (response.status !== 429) return false;
1269
- const limit = parseInt(response.headers.get("X-Usage-Limit") || "", 10);
1270
- const current = parseInt(response.headers.get("X-Usage-Current") || "", 10);
1271
- if (!Number.isFinite(limit) || !Number.isFinite(current)) return false;
1272
- return response.headers.get("X-Usage-Exceeded") === "true" || current > limit;
1273
- }
1274
- async function parseErrorBody(response) {
1275
- const fallback = {
1276
- errorMessage: `HTTP ${response.status}: ${response.statusText}`,
1277
- userMessage: `Request failed (status: ${response.status})`
1278
- };
1279
- try {
1280
- const body = await response.json();
1281
- const reason = typeof body.reason === "string" ? body.reason : typeof body.code === "string" ? body.code : void 0;
1282
- if (body.errors && Array.isArray(body.errors)) {
1283
- const fieldErrors = [];
1284
- for (const e of body.errors) {
1285
- if (e.data?.errors && Array.isArray(e.data.errors) && e.data.errors.length > 0) {
1286
- for (const fe of e.data.errors) {
1287
- fieldErrors.push({
1288
- field: fe.path || fe.field,
1289
- message: fe.message
1290
- });
1291
- }
1292
- } else if (e.field || e.message) {
1293
- fieldErrors.push({ field: e.field, message: e.message });
1294
- }
1295
- }
1296
- const details = (fieldErrors.length > 0 ? fieldErrors : body.errors).map(
1297
- (e) => e.field ? `${e.field}: ${e.message}` : e.message
1298
- ).filter(Boolean).join("; ");
1299
- if (details) {
1300
- return {
1301
- errorMessage: `HTTP ${response.status}: ${details}`,
1302
- userMessage: details,
1303
- reason,
1304
- body,
1305
- errors: fieldErrors.length > 0 ? fieldErrors : body.errors
1306
- };
1307
- }
1308
- }
1309
- if (typeof body.error === "string") {
1310
- return {
1311
- errorMessage: `HTTP ${response.status}: ${body.error}`,
1312
- userMessage: body.error,
1313
- reason,
1314
- body
1315
- };
1316
- }
1317
- if (body.message) {
1318
- return {
1319
- errorMessage: `HTTP ${response.status}: ${body.message}`,
1320
- userMessage: body.message,
1321
- reason,
1322
- body
1323
- };
1324
- }
1325
- return { ...fallback, reason, body };
1326
- } catch {
1327
- return fallback;
1328
- }
1329
- }
1330
- function getParsedErrorSuggestion(status, parsed) {
1331
- if (status === 403 && parsed.reason === "origin_not_allowed") {
1332
- return "Add the request origin to the tenant Browser API origins, then retry the browser request.";
1333
- }
1334
- return getErrorSuggestion(status);
1335
- }
1336
- async function delay(ms) {
1337
- return new Promise((resolve) => setTimeout(resolve, ms));
1338
- }
1339
- function attachRequestId(err, id) {
1340
- if (id) err.requestId = id;
1341
- return err;
1342
- }
1343
- function createHttpStatusError(status, parsed, details, requestId) {
1344
- const errorDetails = {
1345
- ...details,
1346
- ...parsed.errors && { errors: parsed.errors },
1347
- ...parsed.body && { body: parsed.body }
1348
- };
1349
- const suggestion = getParsedErrorSuggestion(status, parsed);
1350
- if (status === 400 || status === 422) {
1351
- return attachRequestId(
1352
- createValidationError(
1353
- parsed.errorMessage,
1354
- errorDetails,
1355
- parsed.userMessage,
1356
- suggestion,
1357
- status
1358
- ),
1359
- requestId
1360
- );
1361
- }
1362
- if (status === 401) {
1363
- return attachRequestId(
1364
- createAuthError(
1365
- parsed.errorMessage,
1366
- errorDetails,
1367
- parsed.userMessage,
1368
- suggestion
1369
- ),
1370
- requestId
1371
- );
1372
- }
1373
- if (status === 403) {
1374
- return attachRequestId(
1375
- createPermissionError(
1376
- parsed.errorMessage,
1377
- errorDetails,
1378
- parsed.userMessage,
1379
- suggestion
1380
- ),
1381
- requestId
1382
- );
1383
- }
1384
- if (status === 404) {
1385
- return attachRequestId(
1386
- createNotFoundError(
1387
- parsed.errorMessage,
1388
- errorDetails,
1389
- parsed.userMessage,
1390
- suggestion
1391
- ),
1392
- requestId
1393
- );
1394
- }
1395
- if (status === 409) {
1396
- return attachRequestId(
1397
- createConflictError(
1398
- parsed.errorMessage,
1399
- errorDetails,
1400
- parsed.userMessage,
1401
- suggestion
1402
- ),
1403
- requestId
1404
- );
1405
- }
1406
- return attachRequestId(
1407
- createNetworkError(
1408
- parsed.errorMessage,
1409
- status,
1410
- errorDetails,
1411
- parsed.userMessage,
1412
- suggestion
1413
- ),
1414
- requestId
1415
- );
1416
- }
1417
- async function httpFetch(url, options) {
1418
- const {
1419
- apiUrl,
1420
- publishableKey,
1421
- secretKey,
1422
- customerToken,
1423
- timeout: timeoutOption = DEFAULT_TIMEOUT,
1424
- debug,
1425
- retry,
1426
- onUnauthorized,
1427
- ...requestInit
1428
- } = options || {};
1429
- const baseUrl = resolveApiUrl(apiUrl);
1430
- const method = (requestInit.method || "GET").toUpperCase();
1431
- const isPublishableKeyBrowserGet = typeof window !== "undefined" && !secretKey && !customerToken && Boolean(publishableKey) && SAFE_METHODS.includes(method);
1432
- const timeout = timeoutOption === DEFAULT_TIMEOUT && isPublishableKeyBrowserGet ? STOREFRONT_BROWSER_TIMEOUT : timeoutOption;
1433
- const retryConfig = {
1434
- maxRetries: retry?.maxRetries ?? (isPublishableKeyBrowserGet ? STOREFRONT_BROWSER_MAX_RETRIES : DEFAULT_MAX_RETRIES),
1435
- retryableStatuses: retry?.retryableStatuses ?? DEFAULT_RETRYABLE_STATUSES,
1436
- retryDelay: retry?.retryDelay ?? ((attempt) => Math.min(1e3 * 2 ** attempt, 1e4))
1437
- };
1438
- let authToken;
1439
- if (secretKey) {
1440
- authToken = secretKey;
1441
- } else if (customerToken) {
1442
- authToken = customerToken;
1443
- }
1444
- let lastError;
1445
- let hasRetried401 = false;
1446
- for (let attempt = 0; attempt <= retryConfig.maxRetries; attempt++) {
1447
- try {
1448
- const headers = new Headers(requestInit.headers);
1449
- if (publishableKey) {
1450
- headers.set("X-Publishable-Key", publishableKey);
1451
- }
1452
- if (authToken) {
1453
- headers.set("Authorization", `Bearer ${authToken}`);
1454
- }
1455
- if (!headers.has("Content-Type") && requestInit.body && !(requestInit.body instanceof FormData)) {
1456
- headers.set("Content-Type", "application/json");
1457
- }
1458
- const redactedHeaders = redactSensitiveHeaders(headers);
1459
- debugLog(debug, "request", url, {
1460
- method: requestInit.method || "GET",
1461
- headers: redactedHeaders,
1462
- attempt: attempt + 1
1463
- });
1464
- const controller = new AbortController();
1465
- const timeoutId = setTimeout(() => controller.abort(), timeout);
1466
- const response = await fetch(`${baseUrl}${url}`, {
1467
- ...requestInit,
1468
- headers,
1469
- signal: controller.signal
1470
- });
1471
- clearTimeout(timeoutId);
1472
- const requestId = response.headers.get("x-request-id") ?? void 0;
1473
- debugLog(debug, "response", url, {
1474
- status: response.status,
1475
- statusText: response.statusText,
1476
- headers: redactSensitiveHeaders(response.headers)
1477
- });
1478
- if (!response.ok) {
1479
- if (isUsageLimitExceededResponse(response)) {
1480
- const limit = parseInt(
1481
- response.headers.get("X-Usage-Limit") || "0",
1482
- 10
1483
- );
1484
- const current = parseInt(
1485
- response.headers.get("X-Usage-Current") || "0",
1486
- 10
1487
- );
1488
- const remaining = parseInt(
1489
- response.headers.get("X-Usage-Remaining") || "0",
1490
- 10
1491
- );
1492
- throw attachRequestId(
1493
- createUsageLimitError(
1494
- `Monthly API usage limit exceeded (${current.toLocaleString()}/${limit.toLocaleString()})`,
1495
- { limit, current, remaining },
1496
- {
1497
- url,
1498
- method: requestInit.method || "GET",
1499
- attempt: attempt + 1
1500
- },
1501
- "Monthly API call limit exceeded. Please upgrade your plan.",
1502
- "Upgrade your tenant plan to increase the monthly API call limit."
1503
- ),
1504
- requestId
1505
- );
1506
- }
1507
- const parsed = await parseErrorBody(response);
1508
- if (response.status === 401 && onUnauthorized && customerToken && !hasRetried401 && parsed.reason === "token_expired") {
1509
- hasRetried401 = true;
1510
- try {
1511
- const newToken = await onUnauthorized();
1512
- if (newToken) {
1513
- authToken = newToken;
1514
- continue;
1515
- }
1516
- } catch {
1517
- }
1518
- }
1519
- const details = {
1520
- url,
1521
- method: requestInit.method || "GET",
1522
- attempt: attempt + 1
1523
- };
1524
- if (NON_RETRYABLE_STATUSES.includes(response.status)) {
1525
- throw createHttpStatusError(
1526
- response.status,
1527
- parsed,
1528
- details,
1529
- requestId
1530
- );
1531
- }
1532
- const error = attachRequestId(
1533
- createNetworkError(
1534
- parsed.errorMessage,
1535
- response.status,
1536
- details,
1537
- parsed.userMessage,
1538
- getErrorSuggestion(response.status)
1539
- ),
1540
- requestId
1541
- );
1542
- const method2 = (requestInit.method || "GET").toUpperCase();
1543
- if (attempt < retryConfig.maxRetries && SAFE_METHODS.includes(method2) && retryConfig.retryableStatuses.includes(response.status)) {
1544
- lastError = error;
1545
- const retryDelay = retryConfig.retryDelay(attempt);
1546
- debugLog(debug, "error", `Retrying in ${retryDelay}ms...`, error);
1547
- await delay(retryDelay);
1548
- continue;
1549
- }
1550
- throw error;
1551
- }
1552
- return response;
1553
- } catch (error) {
1554
- debugLog(debug, "error", url, error);
1555
- const method2 = (requestInit.method || "GET").toUpperCase();
1556
- const isSafe = SAFE_METHODS.includes(method2);
1557
- if (error instanceof Error && error.name === "AbortError") {
1558
- const timeoutError = createTimeoutError(
1559
- `Request timed out after ${timeout}ms.`,
1560
- { url, timeout, attempt: attempt + 1 },
1561
- "The request timed out.",
1562
- "Please check your network connection or try again later."
1563
- );
1564
- if (isSafe && attempt < retryConfig.maxRetries) {
1565
- lastError = timeoutError;
1566
- await delay(retryConfig.retryDelay(attempt));
1567
- continue;
1568
- }
1569
- throw timeoutError;
1570
- }
1571
- if (error instanceof TypeError) {
1572
- const networkError = createNetworkError(
1573
- "Network connection failed.",
1574
- void 0,
1575
- { url, originalError: error.message, attempt: attempt + 1 },
1576
- "Network connection failed.",
1577
- "Please check your internet connection and try again."
1578
- );
1579
- if (isSafe && attempt < retryConfig.maxRetries) {
1580
- lastError = networkError;
1581
- await delay(retryConfig.retryDelay(attempt));
1582
- continue;
1583
- }
1584
- throw networkError;
1585
- }
1586
- if (error instanceof NetworkError || error instanceof TimeoutError) {
1587
- if (isSafe && attempt < retryConfig.maxRetries && error.status && !NON_RETRYABLE_STATUSES.includes(error.status) && retryConfig.retryableStatuses.includes(error.status)) {
1588
- lastError = error;
1589
- await delay(retryConfig.retryDelay(attempt));
1590
- continue;
1591
- }
1592
- throw error;
1593
- }
1594
- if (error instanceof SDKError) {
1595
- throw error;
1596
- }
1597
- const unknownError = createNetworkError(
1598
- error instanceof Error ? error.message : "An unknown network error occurred.",
1599
- void 0,
1600
- { url, originalError: error, attempt: attempt + 1 },
1601
- "An unknown error occurred.",
1602
- "Please try again later."
1603
- );
1604
- if (isSafe && attempt < retryConfig.maxRetries) {
1605
- lastError = unknownError;
1606
- await delay(retryConfig.retryDelay(attempt));
1607
- continue;
1608
- }
1609
- throw unknownError;
1610
- }
1611
- }
1612
- throw lastError ?? new NetworkError("Request failed after retries");
1613
- }
1614
-
1615
- // src/core/collection/http-client.ts
1616
- var HttpClient = class {
1617
- constructor(publishableKey, secretKey, getCustomerToken, onUnauthorized, onRequestId, apiUrl) {
1618
- this.publishableKey = requirePublishableKeyForSecret(
1619
- "CollectionClient",
1620
- publishableKey,
1621
- secretKey
1622
- );
1623
- this.secretKey = secretKey;
1624
- this.getCustomerToken = getCustomerToken;
1625
- this.onUnauthorized = onUnauthorized;
1626
- this.onRequestId = onRequestId;
1627
- this.apiUrl = apiUrl;
1628
- }
1629
- get defaultOptions() {
1630
- const opts = {
1631
- apiUrl: this.apiUrl,
1632
- publishableKey: this.publishableKey,
1633
- secretKey: this.secretKey
1634
- };
1635
- const token = this.getCustomerToken?.();
1636
- if (token) {
1637
- opts.customerToken = token;
1638
- if (this.onUnauthorized) {
1639
- opts.onUnauthorized = this.onUnauthorized;
1640
- }
1641
- }
1642
- return opts;
1643
- }
1644
- async fetchWithTracking(url, opts) {
1645
- try {
1646
- const response = await httpFetch(url, opts);
1647
- this.onRequestId?.(response.headers.get("x-request-id") ?? null);
1648
- return response;
1649
- } catch (err) {
1650
- const id = err instanceof SDKError ? err.requestId ?? null : null;
1651
- this.onRequestId?.(id);
1652
- throw err;
1653
- }
1654
- }
1655
- buildUrl(endpoint, options) {
1656
- if (!options) return endpoint;
1657
- const queryString = stringify(options, { addQueryPrefix: true });
1658
- return queryString ? `${endpoint}${queryString}` : endpoint;
1659
- }
1660
- assertJsonResponse(response) {
1661
- const contentType = response.headers.get("content-type");
1662
- if (!contentType?.includes("application/json")) {
1663
- throw createApiError("Response is not in JSON format.", response.status, {
1664
- contentType
1665
- });
1666
- }
1667
- }
1668
- /**
1669
- * Parse Payload CMS find response (list query)
1670
- * Returns native Payload response structure
1671
- */
1672
- async parseFindResponse(response) {
1673
- const contentType = response.headers.get("content-type");
1674
- try {
1675
- this.assertJsonResponse(response);
1676
- const jsonData = await response.json();
1677
- if (jsonData.docs === void 0) {
1678
- throw createApiError("Invalid find response.", response.status, {
1679
- jsonData
1680
- });
1681
- }
1682
- return {
1683
- docs: jsonData.docs,
1684
- totalDocs: jsonData.totalDocs ?? 0,
1685
- limit: jsonData.limit || 20,
1686
- totalPages: jsonData.totalPages ?? 0,
1687
- page: jsonData.page || 1,
1688
- pagingCounter: jsonData.pagingCounter || 1,
1689
- hasPrevPage: jsonData.hasPrevPage ?? false,
1690
- hasNextPage: jsonData.hasNextPage ?? false,
1691
- prevPage: jsonData.prevPage ?? null,
1692
- nextPage: jsonData.nextPage ?? null
1693
- };
1694
- } catch (error) {
1695
- if (error instanceof SDKError) throw error;
1696
- throw createApiError("Failed to parse response.", response.status, {
1697
- contentType,
1698
- error: error instanceof Error ? error.message : error
1699
- });
1700
- }
1701
- }
1702
- /**
1703
- * Parse Payload CMS mutation response (create/update)
1704
- * Returns native Payload response structure
1705
- */
1706
- async parseMutationResponse(response) {
1707
- const contentType = response.headers.get("content-type");
1708
- try {
1709
- this.assertJsonResponse(response);
1710
- const jsonData = await response.json();
1711
- if (jsonData.doc === void 0) {
1712
- throw createApiError("Invalid mutation response.", response.status, {
1713
- jsonData
1714
- });
1715
- }
1716
- return {
1717
- message: jsonData.message || "",
1718
- doc: jsonData.doc,
1719
- errors: jsonData.errors
1720
- };
1721
- } catch (error) {
1722
- if (error instanceof SDKError) throw error;
1723
- throw createApiError("Failed to parse response.", response.status, {
1724
- contentType,
1725
- error: error instanceof Error ? error.message : error
1726
- });
1727
- }
1728
- }
1729
- /**
1730
- * Parse Payload CMS document response (findById/delete)
1731
- * Returns document directly without wrapper
1732
- */
1733
- async parseDocumentResponse(response) {
1734
- const contentType = response.headers.get("content-type");
1735
- try {
1736
- this.assertJsonResponse(response);
1737
- const jsonData = await response.json();
1738
- return jsonData;
1739
- } catch (error) {
1740
- if (error instanceof SDKError) throw error;
1741
- throw createApiError("Failed to parse response.", response.status, {
1742
- contentType,
1743
- error: error instanceof Error ? error.message : error
1744
- });
1745
- }
1746
- }
1747
- };
1748
-
1749
- // src/core/collection/collection-client.ts
1750
- function buildPayloadFormData(data, file, filename) {
1751
- const formData = new FormData();
1752
- formData.append("file", file, filename);
1753
- if (data != null) {
1754
- formData.append("_payload", JSON.stringify(data));
1755
- }
1756
- return formData;
1757
- }
1758
- var CollectionClient = class extends HttpClient {
1759
- from(collection) {
1760
- return new CollectionQueryBuilder(this, collection);
1761
- }
1762
- // ============================================================================
1763
- // Payload-native methods
1764
- // ============================================================================
1765
- /**
1766
- * Find documents (list query)
1767
- * GET /api/{collection}
1768
- */
1769
- async requestFind(endpoint, options) {
1770
- const url = this.buildUrl(endpoint, options);
1771
- const response = await this.fetchWithTracking(url, {
1772
- ...this.defaultOptions,
1773
- method: "GET"
1774
- });
1775
- return this.parseFindResponse(response);
1776
- }
1777
- /**
1778
- * Find-like response from a custom endpoint
1779
- * POST /api/...custom-endpoint
1780
- */
1781
- async requestFindEndpoint(endpoint, data) {
1782
- const response = await this.fetchWithTracking(endpoint, {
1783
- ...this.defaultOptions,
1784
- method: "POST",
1785
- body: data ? JSON.stringify(data) : void 0
1786
- });
1787
- return this.parseFindResponse(response);
1788
- }
1789
- /**
1790
- * Find-like response from a cacheable GET custom endpoint.
1791
- */
1792
- async requestFindEndpointGet(endpoint) {
1793
- const response = await this.fetchWithTracking(endpoint, {
1794
- ...this.defaultOptions,
1795
- method: "GET"
1796
- });
1797
- return this.parseFindResponse(response);
1798
- }
1799
- /**
1800
- * Find document by ID
1801
- * GET /api/{collection}/{id}
1802
- */
1803
- async requestFindById(endpoint, options) {
1804
- const url = this.buildUrl(endpoint, options);
1805
- const response = await this.fetchWithTracking(url, {
1806
- ...this.defaultOptions,
1807
- method: "GET"
1808
- });
1809
- return this.parseDocumentResponse(response);
1810
- }
1811
- /**
1812
- * Create document
1813
- * POST /api/{collection}
1814
- */
1815
- async requestCreate(endpoint, data) {
1816
- const response = await this.fetchWithTracking(endpoint, {
1817
- ...this.defaultOptions,
1818
- method: "POST",
1819
- body: data ? JSON.stringify(data) : void 0
1820
- });
1821
- return this.parseMutationResponse(response);
1822
- }
1823
- /**
1824
- * Update document
1825
- * PATCH /api/{collection}/{id}
1826
- */
1827
- async requestUpdate(endpoint, data) {
1828
- const response = await this.fetchWithTracking(endpoint, {
1829
- ...this.defaultOptions,
1830
- method: "PATCH",
1831
- body: data ? JSON.stringify(data) : void 0
1832
- });
1833
- return this.parseMutationResponse(response);
1834
- }
1835
- /**
1836
- * Count documents
1837
- * GET /api/{collection}/count
1838
- */
1839
- async requestCount(endpoint, options) {
1840
- const url = this.buildUrl(endpoint, options);
1841
- const response = await this.fetchWithTracking(url, {
1842
- ...this.defaultOptions,
1843
- method: "GET"
1844
- });
1845
- return this.parseDocumentResponse(response);
1846
- }
1847
- /**
1848
- * Update multiple documents (bulk update)
1849
- * PATCH /api/{collection}
1850
- */
1851
- async requestUpdateMany(endpoint, data) {
1852
- const response = await this.fetchWithTracking(endpoint, {
1853
- ...this.defaultOptions,
1854
- method: "PATCH",
1855
- body: JSON.stringify(data)
1856
- });
1857
- return this.parseFindResponse(response);
1858
- }
1859
- /**
1860
- * Delete document
1861
- * DELETE /api/{collection}/{id}
1862
- */
1863
- async requestDelete(endpoint) {
1864
- const response = await this.fetchWithTracking(endpoint, {
1865
- ...this.defaultOptions,
1866
- method: "DELETE"
1867
- });
1868
- return this.parseDocumentResponse(response);
1869
- }
1870
- /**
1871
- * Delete multiple documents (bulk delete)
1872
- * DELETE /api/{collection}
1873
- */
1874
- async requestDeleteMany(endpoint, data) {
1875
- const response = await this.fetchWithTracking(endpoint, {
1876
- ...this.defaultOptions,
1877
- method: "DELETE",
1878
- body: JSON.stringify(data)
1879
- });
1880
- return this.parseFindResponse(response);
1881
- }
1882
- /**
1883
- * Create document with file upload
1884
- * POST /api/{collection} (multipart/form-data)
1885
- */
1886
- async requestCreateWithFile(endpoint, data, file, filename) {
1887
- const response = await this.fetchWithTracking(endpoint, {
1888
- ...this.defaultOptions,
1889
- method: "POST",
1890
- body: buildPayloadFormData(data, file, filename)
1891
- });
1892
- return this.parseMutationResponse(response);
1893
- }
1894
- /**
1895
- * Update document with file upload
1896
- * PATCH /api/{collection}/{id} (multipart/form-data)
1897
- */
1898
- async requestUpdateWithFile(endpoint, data, file, filename) {
1899
- const response = await this.fetchWithTracking(endpoint, {
1900
- ...this.defaultOptions,
1901
- method: "PATCH",
1902
- body: buildPayloadFormData(data, file, filename)
1903
- });
1904
- return this.parseMutationResponse(response);
893
+ }, delay);
1905
894
  }
1906
895
  };
1907
896
 
@@ -1944,28 +933,9 @@ function createReadOnlyQueryHooksFacade(hooks) {
1944
933
  };
1945
934
  }
1946
935
  function createQueryHooks(client, queryClient = getQueryClient()) {
1947
- const config = client.getConfig();
1948
- const onUnauthorized = async () => {
1949
- try {
1950
- const result = await client.customer.auth.refreshToken();
1951
- return result.token ?? null;
1952
- } catch {
1953
- return null;
1954
- }
1955
- };
1956
- const collectionClient = new CollectionClient(
1957
- config.publishableKey,
1958
- void 0,
1959
- () => client.customer.auth.getToken(),
1960
- onUnauthorized,
1961
- (id) => {
1962
- client.lastRequestId = id;
1963
- },
1964
- config.apiUrl
1965
- );
1966
936
  const hooks = new QueryHooks(
1967
937
  queryClient,
1968
- collectionClient,
938
+ client.collections,
1969
939
  client.customer.auth,
1970
940
  client.commerce
1971
941
  );