@01.software/sdk 0.67.0 → 0.69.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 (69) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +124 -6
  3. package/dist/client.cjs +422 -319
  4. package/dist/client.cjs.map +1 -1
  5. package/dist/client.d.cts +11 -6
  6. package/dist/client.d.ts +11 -6
  7. package/dist/client.js +422 -319
  8. package/dist/client.js.map +1 -1
  9. package/dist/{collection-client-D4HEOoO_.d.ts → collection-client-C2VGBnCC.d.ts} +4 -4
  10. package/dist/{collection-client-jrNFGbrO.d.cts → collection-client-DvWkDxSM.d.cts} +4 -4
  11. package/dist/{const-CCQ3MdLE.d.cts → const-AtPEgg__.d.cts} +2 -2
  12. package/dist/{const-BU79hCFB.d.ts → const-DR96Chal.d.ts} +2 -2
  13. package/dist/embedded-admin/server.cjs +19 -1
  14. package/dist/embedded-admin/server.cjs.map +1 -1
  15. package/dist/embedded-admin/server.d.cts +4 -2
  16. package/dist/embedded-admin/server.d.ts +4 -2
  17. package/dist/embedded-admin/server.js +19 -1
  18. package/dist/embedded-admin/server.js.map +1 -1
  19. package/dist/embedded-admin.cjs +22 -0
  20. package/dist/embedded-admin.cjs.map +1 -1
  21. package/dist/embedded-admin.d.cts +7 -1
  22. package/dist/embedded-admin.d.ts +7 -1
  23. package/dist/embedded-admin.js +22 -0
  24. package/dist/embedded-admin.js.map +1 -1
  25. package/dist/errors.cjs +3 -0
  26. package/dist/errors.cjs.map +1 -1
  27. package/dist/errors.d.cts +3 -3
  28. package/dist/errors.d.ts +3 -3
  29. package/dist/errors.js +3 -0
  30. package/dist/errors.js.map +1 -1
  31. package/dist/{index-DiyhsVHd.d.cts → index-Ce11c_Oh.d.cts} +3 -3
  32. package/dist/{index-CwKxWHIa.d.ts → index-D8fmTrZk.d.ts} +3 -3
  33. package/dist/index.cjs +427 -323
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.d.cts +7 -7
  36. package/dist/index.d.ts +7 -7
  37. package/dist/index.js +427 -323
  38. package/dist/index.js.map +1 -1
  39. package/dist/{payload-types-jdsUXunB.d.cts → payload-types-rhnw3rR8.d.cts} +48 -1
  40. package/dist/{payload-types-jdsUXunB.d.ts → payload-types-rhnw3rR8.d.ts} +48 -1
  41. package/dist/query.cjs +11 -0
  42. package/dist/query.cjs.map +1 -1
  43. package/dist/query.d.cts +5 -5
  44. package/dist/query.d.ts +5 -5
  45. package/dist/query.js +11 -0
  46. package/dist/query.js.map +1 -1
  47. package/dist/realtime.d.cts +2 -2
  48. package/dist/realtime.d.ts +2 -2
  49. package/dist/server.cjs +1186 -1071
  50. package/dist/server.cjs.map +1 -1
  51. package/dist/server.d.cts +9 -8
  52. package/dist/server.d.ts +9 -8
  53. package/dist/server.js +1186 -1071
  54. package/dist/server.js.map +1 -1
  55. package/dist/storefront-cache.cjs +3 -0
  56. package/dist/storefront-cache.cjs.map +1 -1
  57. package/dist/storefront-cache.js +3 -0
  58. package/dist/storefront-cache.js.map +1 -1
  59. package/dist/{types-CvdBV3ri.d.cts → types-B99utaKU.d.cts} +147 -40
  60. package/dist/{types-BPwXAFZ7.d.cts → types-BR0D4AaW.d.cts} +2 -2
  61. package/dist/{types-BusejG-v.d.ts → types-CHK8VIPa.d.ts} +2 -2
  62. package/dist/{types-I2k6Laad.d.ts → types-L0xmn_iT.d.ts} +147 -40
  63. package/dist/ui/form.d.cts +1 -1
  64. package/dist/ui/form.d.ts +1 -1
  65. package/dist/ui/video.d.cts +1 -1
  66. package/dist/ui/video.d.ts +1 -1
  67. package/dist/webhook.d.cts +5 -5
  68. package/dist/webhook.d.ts +5 -5
  69. package/package.json +2 -2
package/dist/index.cjs CHANGED
@@ -141,9 +141,6 @@ __export(src_exports, {
141
141
  });
142
142
  module.exports = __toCommonJS(src_exports);
143
143
 
144
- // src/core/collection/http-client.ts
145
- var import_qs_esm = require("qs-esm");
146
-
147
144
  // src/core/errors.ts
148
145
  var SDK_ERROR_BRAND = /* @__PURE__ */ Symbol.for("@01.software/sdk/SDKError");
149
146
  var SDK_ERROR_TYPE_BRAND = /* @__PURE__ */ Symbol.for("@01.software/sdk/SDKError.type");
@@ -257,6 +254,7 @@ var COMMERCE_ERROR_CODES = [
257
254
  "admission_metadata_invalid",
258
255
  "admission_metadata_required",
259
256
  "capacity_exceeded",
257
+ "admission_required",
260
258
  "occurrence_lock_unavailable",
261
259
  "occurrence_not_open",
262
260
  "admission_type_capacity_exceeded",
@@ -275,6 +273,8 @@ var COMMERCE_ERROR_CODES = [
275
273
  "variant_inactive",
276
274
  "variant_product_mismatch",
277
275
  "product_not_public",
276
+ "product_not_eligible",
277
+ "purchase_limit_exceeded",
278
278
  "market_not_found",
279
279
  "market_shipping_currency_unsupported",
280
280
  "missing_market_rate",
@@ -1147,288 +1147,6 @@ function stockSnapshotSearchParams(params) {
1147
1147
  return `variantIds=${params.variantIds.map(encodeURIComponent).join(",")}`;
1148
1148
  }
1149
1149
 
1150
- // src/core/collection/http-client.ts
1151
- function validateWhere(where) {
1152
- if (where === void 0) return false;
1153
- let hasNull = false;
1154
- function visit(value, depth, key) {
1155
- if (depth > 10) {
1156
- throw createValidationError(
1157
- "Collection where must not exceed nesting depth 10."
1158
- );
1159
- }
1160
- if (value === null && (key === "equals" || key === "not_equals")) {
1161
- hasNull = true;
1162
- return;
1163
- }
1164
- if (value == null) {
1165
- throw createValidationError(
1166
- "Collection where must not contain null or undefined values."
1167
- );
1168
- }
1169
- if (Array.isArray(value)) {
1170
- if (value.length === 0) {
1171
- throw createValidationError(
1172
- "Collection where must not contain empty arrays, including and/or."
1173
- );
1174
- }
1175
- if (value.length > 1e3) {
1176
- throw createValidationError(
1177
- "Collection where arrays must not contain more than 1000 elements."
1178
- );
1179
- }
1180
- for (const item of value) visit(item, depth + 1);
1181
- } else if (typeof value === "object" && !(value instanceof Date)) {
1182
- const values = Object.entries(value);
1183
- if (values.length === 0) {
1184
- throw createValidationError(
1185
- "Collection where must not contain empty condition objects."
1186
- );
1187
- }
1188
- for (const [key2, item] of values) visit(item, depth + 1, key2);
1189
- }
1190
- }
1191
- visit(where, 0);
1192
- return hasNull;
1193
- }
1194
- var HttpClient = class {
1195
- constructor(publishableKey, secretKey, getCustomerToken, onUnauthorized, onRequestId, apiUrl) {
1196
- this.publishableKey = requirePublishableKeyForSecret(
1197
- "CollectionClient",
1198
- publishableKey,
1199
- secretKey
1200
- );
1201
- this.secretKey = secretKey;
1202
- this.getCustomerToken = getCustomerToken;
1203
- this.onUnauthorized = onUnauthorized;
1204
- this.onRequestId = onRequestId;
1205
- this.apiUrl = apiUrl;
1206
- }
1207
- get defaultOptions() {
1208
- const opts = {
1209
- apiUrl: this.apiUrl,
1210
- publishableKey: this.publishableKey,
1211
- secretKey: this.secretKey
1212
- };
1213
- const token = this.getCustomerToken?.();
1214
- if (token) {
1215
- opts.customerToken = token;
1216
- if (this.onUnauthorized) {
1217
- opts.onUnauthorized = this.onUnauthorized;
1218
- }
1219
- }
1220
- return opts;
1221
- }
1222
- async fetchWithTracking(url, opts) {
1223
- try {
1224
- const response = await httpFetch(url, opts);
1225
- this.onRequestId?.(response.headers.get("x-request-id") ?? null);
1226
- return response;
1227
- } catch (err) {
1228
- const id = err instanceof SDKError ? err.requestId ?? null : null;
1229
- this.onRequestId?.(id);
1230
- throw err;
1231
- }
1232
- }
1233
- buildUrl(endpoint, options) {
1234
- if (!options) return endpoint;
1235
- const { fallbackLocale, ...rest } = options;
1236
- const queryOptions = fallbackLocale === void 0 ? rest : {
1237
- ...rest,
1238
- "fallback-locale": fallbackLocale === false ? "none" : fallbackLocale
1239
- };
1240
- const encodedOptions = validateWhere(queryOptions.where) ? { ...queryOptions, where: JSON.stringify(queryOptions.where) } : queryOptions;
1241
- const queryString = (0, import_qs_esm.stringify)(encodedOptions, { addQueryPrefix: true });
1242
- return queryString ? `${endpoint}${queryString}` : endpoint;
1243
- }
1244
- assertJsonResponse(response) {
1245
- const contentType = response.headers.get("content-type");
1246
- if (!contentType?.includes("application/json")) {
1247
- throw createApiError("Response is not in JSON format.", response.status, {
1248
- contentType
1249
- });
1250
- }
1251
- }
1252
- /**
1253
- * Parse Payload CMS find response (list query)
1254
- * Returns native Payload response structure
1255
- */
1256
- async parseFindResponse(response) {
1257
- const contentType = response.headers.get("content-type");
1258
- try {
1259
- this.assertJsonResponse(response);
1260
- const jsonData = await response.json();
1261
- if (jsonData.docs === void 0) {
1262
- throw createApiError("Invalid find response.", response.status, {
1263
- jsonData
1264
- });
1265
- }
1266
- return {
1267
- docs: jsonData.docs,
1268
- totalDocs: jsonData.totalDocs ?? 0,
1269
- limit: jsonData.limit || 20,
1270
- totalPages: jsonData.totalPages ?? 0,
1271
- page: jsonData.page || 1,
1272
- pagingCounter: jsonData.pagingCounter || 1,
1273
- hasPrevPage: jsonData.hasPrevPage ?? false,
1274
- hasNextPage: jsonData.hasNextPage ?? false,
1275
- prevPage: jsonData.prevPage ?? null,
1276
- nextPage: jsonData.nextPage ?? null
1277
- };
1278
- } catch (error) {
1279
- if (error instanceof SDKError) throw error;
1280
- throw createApiError("Failed to parse response.", response.status, {
1281
- contentType,
1282
- error: error instanceof Error ? error.message : error
1283
- });
1284
- }
1285
- }
1286
- /**
1287
- * Parse Payload CMS mutation response (create/update)
1288
- * Returns native Payload response structure
1289
- */
1290
- async parseMutationResponse(response) {
1291
- const contentType = response.headers.get("content-type");
1292
- try {
1293
- this.assertJsonResponse(response);
1294
- const jsonData = await response.json();
1295
- if (jsonData.doc === void 0) {
1296
- throw createApiError("Invalid mutation response.", response.status, {
1297
- jsonData
1298
- });
1299
- }
1300
- return {
1301
- message: jsonData.message || "",
1302
- doc: jsonData.doc,
1303
- errors: jsonData.errors
1304
- };
1305
- } catch (error) {
1306
- if (error instanceof SDKError) throw error;
1307
- throw createApiError("Failed to parse response.", response.status, {
1308
- contentType,
1309
- error: error instanceof Error ? error.message : error
1310
- });
1311
- }
1312
- }
1313
- /**
1314
- * Parse Payload CMS document response (findById/delete)
1315
- * Returns document directly without wrapper
1316
- */
1317
- async parseDocumentResponse(response) {
1318
- const contentType = response.headers.get("content-type");
1319
- try {
1320
- this.assertJsonResponse(response);
1321
- const jsonData = await response.json();
1322
- return jsonData;
1323
- } catch (error) {
1324
- if (error instanceof SDKError) throw error;
1325
- throw createApiError("Failed to parse response.", response.status, {
1326
- contentType,
1327
- error: error instanceof Error ? error.message : error
1328
- });
1329
- }
1330
- }
1331
- };
1332
-
1333
- // src/utils/types.ts
1334
- function resolveRelation(ref) {
1335
- if (typeof ref === "string" || typeof ref === "number" || ref === null || ref === void 0)
1336
- return null;
1337
- return ref;
1338
- }
1339
-
1340
- // src/core/collection/query-builder.ts
1341
- var PUBLIC_READ_DEPTH_ERROR = "Publishable collection reads require depth: 0. Use a shaped commerce endpoint or server client for populated data.";
1342
- var PUBLIC_READ_JOINS_ERROR = "Publishable collection reads require joins: false. Use a shaped commerce endpoint or server client for joined data.";
1343
- var PUBLIC_READ_POPULATE_ERROR = "Publishable collection reads do not support populate. Use a shaped commerce endpoint or server client for populated data.";
1344
- function withDefaultPublicReadOptions(options) {
1345
- const rawOptions = options;
1346
- if (rawOptions?.depth !== void 0 && rawOptions.depth !== 0) {
1347
- throw createValidationError(PUBLIC_READ_DEPTH_ERROR);
1348
- }
1349
- if (rawOptions?.joins !== void 0 && rawOptions.joins !== false) {
1350
- throw createValidationError(PUBLIC_READ_JOINS_ERROR);
1351
- }
1352
- if (rawOptions?.populate !== void 0) {
1353
- throw createValidationError(PUBLIC_READ_POPULATE_ERROR);
1354
- }
1355
- return {
1356
- ...options,
1357
- depth: options?.depth ?? 0,
1358
- joins: options?.joins ?? false
1359
- };
1360
- }
1361
- var ReadOnlyCollectionQueryBuilder = class {
1362
- constructor(api, collection) {
1363
- this.api = api;
1364
- this.collection = collection;
1365
- }
1366
- async find(options) {
1367
- return this.api.requestFind(
1368
- `/api/${String(this.collection)}`,
1369
- withDefaultPublicReadOptions(options)
1370
- );
1371
- }
1372
- async findById(id, options) {
1373
- return this.api.requestFindById(
1374
- `/api/${String(this.collection)}/${String(id)}`,
1375
- withDefaultPublicReadOptions(options)
1376
- );
1377
- }
1378
- async count(options) {
1379
- return this.api.requestCount(
1380
- `/api/${String(this.collection)}/count`,
1381
- withDefaultPublicReadOptions(options)
1382
- );
1383
- }
1384
- };
1385
-
1386
- // src/core/collection/collection-client.ts
1387
- var ReadOnlyCollectionClient = class extends HttpClient {
1388
- from(collection) {
1389
- return new ReadOnlyCollectionQueryBuilder(this, collection);
1390
- }
1391
- async requestFind(endpoint, options) {
1392
- const url = this.buildUrl(endpoint, options);
1393
- const response = await this.fetchWithTracking(url, {
1394
- ...this.defaultOptions,
1395
- method: "GET"
1396
- });
1397
- return this.parseFindResponse(response);
1398
- }
1399
- async requestFindEndpoint(endpoint, data) {
1400
- const response = await this.fetchWithTracking(endpoint, {
1401
- ...this.defaultOptions,
1402
- method: "POST",
1403
- body: data ? JSON.stringify(data) : void 0
1404
- });
1405
- return this.parseFindResponse(response);
1406
- }
1407
- async requestFindEndpointGet(endpoint) {
1408
- const response = await this.fetchWithTracking(endpoint, {
1409
- ...this.defaultOptions,
1410
- method: "GET"
1411
- });
1412
- return this.parseFindResponse(response);
1413
- }
1414
- async requestFindById(endpoint, options) {
1415
- const url = this.buildUrl(endpoint, options);
1416
- const response = await this.fetchWithTracking(url, {
1417
- ...this.defaultOptions,
1418
- method: "GET"
1419
- });
1420
- return this.parseDocumentResponse(response);
1421
- }
1422
- async requestCount(endpoint, options) {
1423
- const url = this.buildUrl(endpoint, options);
1424
- const response = await this.fetchWithTracking(url, {
1425
- ...this.defaultOptions,
1426
- method: "GET"
1427
- });
1428
- return this.parseDocumentResponse(response);
1429
- }
1430
- };
1431
-
1432
1150
  // src/core/api/parse-response.ts
1433
1151
  async function parseApiResponse(response, endpoint, options = {}) {
1434
1152
  if (response.status === 204 || response.headers.get("content-length") === "0") {
@@ -1690,6 +1408,14 @@ var EXTERNAL_CUSTOMER_LINK_ENDPOINT_OPERATIONS = {
1690
1408
  "/external-links/clear-previous-state"
1691
1409
  )
1692
1410
  };
1411
+ var BENEFIT_VOUCHER_ENDPOINT_OPERATIONS = {
1412
+ issue: operation("customers", "post", "/benefit-vouchers/issue"),
1413
+ get: operation("customers", "post", "/benefit-vouchers/get"),
1414
+ list: operation("customers", "post", "/benefit-vouchers/list"),
1415
+ redeem: operation("customers", "post", "/benefit-vouchers/redeem"),
1416
+ void: operation("customers", "post", "/benefit-vouchers/void"),
1417
+ listMine: operation("customers", "get", "/me/benefit-vouchers")
1418
+ };
1693
1419
  var CUSTOMER_GROUP_ENDPOINT_OPERATIONS = {
1694
1420
  members: operation("customer-groups", "get", "/:id/members"),
1695
1421
  grant: operation("customer-groups", "post", "/:id/members/grant"),
@@ -1931,58 +1657,425 @@ var CustomerScopedTransport = class {
1931
1657
  options.publishableKey,
1932
1658
  options.secretKey
1933
1659
  );
1934
- this.secretKey = options.secretKey;
1935
- this.apiUrl = options.apiUrl;
1936
- this.customerToken = options.customerToken;
1937
- this.onUnauthorized = options.onUnauthorized;
1938
- this.onRequestId = options.onRequestId;
1660
+ this.secretKey = options.secretKey;
1661
+ this.apiUrl = options.apiUrl;
1662
+ this.customerToken = options.customerToken;
1663
+ this.onUnauthorized = options.onUnauthorized;
1664
+ this.onRequestId = options.onRequestId;
1665
+ }
1666
+ async request(endpoint, options) {
1667
+ const token = typeof this.customerToken === "function" ? this.customerToken() : this.customerToken;
1668
+ try {
1669
+ const response = await httpFetch(endpoint, {
1670
+ method: options.method,
1671
+ apiUrl: this.apiUrl,
1672
+ publishableKey: this.publishableKey,
1673
+ secretKey: this.secretKey,
1674
+ customerToken: token ?? void 0,
1675
+ ...token && this.onUnauthorized && { onUnauthorized: this.onUnauthorized },
1676
+ ...options.body !== void 0 && {
1677
+ body: JSON.stringify(options.body)
1678
+ },
1679
+ ...options.headers && { headers: options.headers },
1680
+ ...options.errorFamily && { errorFamily: options.errorFamily }
1681
+ });
1682
+ this.onRequestId?.(response.headers.get("x-request-id") ?? null);
1683
+ return parseApiResponse(response, endpoint, {
1684
+ errorFamily: options.errorFamily
1685
+ });
1686
+ } catch (err) {
1687
+ const id = err instanceof SDKError ? err.requestId ?? null : null;
1688
+ this.onRequestId?.(id);
1689
+ throw err;
1690
+ }
1691
+ }
1692
+ };
1693
+ var CustomerScopedApi = class {
1694
+ constructor(apiName, options) {
1695
+ this.transport = new CustomerScopedTransport(apiName, options);
1696
+ }
1697
+ requestEndpoint(endpoint, body, options) {
1698
+ return this.transport.request(resolveOperationPath(endpoint, options), {
1699
+ method: resolveOperationMethod(endpoint),
1700
+ body,
1701
+ headers: options?.headers,
1702
+ errorFamily: resolveOperationErrorFamily(endpoint)
1703
+ });
1704
+ }
1705
+ };
1706
+ var RawCustomerScopedApi = class {
1707
+ constructor(apiName, options) {
1708
+ this.transport = new CustomerScopedTransport(apiName, options);
1709
+ }
1710
+ request(endpoint, options) {
1711
+ return this.transport.request(endpoint, options);
1712
+ }
1713
+ };
1714
+
1715
+ // src/core/api/benefit-voucher-types.ts
1716
+ var BENEFIT_VOUCHER_VOID_REASONS = [
1717
+ "issued_in_error",
1718
+ "benefit_revoked",
1719
+ "customer_request",
1720
+ "other"
1721
+ ];
1722
+ function invalidBenefitVoucherResponse() {
1723
+ throw createApiError("Invalid benefit voucher response", 200);
1724
+ }
1725
+ function object(value, keys) {
1726
+ if (!value || typeof value !== "object" || Array.isArray(value) || Object.keys(value).length !== keys.length || keys.some((key) => !(key in value)))
1727
+ invalidBenefitVoucherResponse();
1728
+ return value;
1729
+ }
1730
+ var uuid = (v) => typeof v === "string" && (/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(
1731
+ v
1732
+ ) || v === "00000000-0000-0000-0000-000000000000" || v.toLowerCase() === "ffffffff-ffff-ffff-ffff-ffffffffffff");
1733
+ var time = (v) => typeof v === "string" && /^\d{4}-\d{2}-\d{2}T/.test(v) && Number.isFinite(Date.parse(v)) && new Date(Date.parse(v)).toISOString() === v;
1734
+ var actor = (v) => typeof v === "string" && /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(v);
1735
+ function parseBenefitVoucher(value, mine = false) {
1736
+ const v = object(value, [
1737
+ "id",
1738
+ "name",
1739
+ "description",
1740
+ "state",
1741
+ "issuedAt",
1742
+ "expiresAt",
1743
+ ...mine ? ["closedAt"] : ["customerId", "definitionId", "source", "closed"]
1744
+ ]);
1745
+ if (!uuid(v.id) || typeof v.name !== "string" || !v.name.length || v.name.length > 120 || v.description !== null && (typeof v.description !== "string" || v.description.length > 1e3) || !["issued", "redeemed", "expired", "voided"].includes(v.state) || !time(v.issuedAt) || !time(v.expiresAt))
1746
+ invalidBenefitVoucherResponse();
1747
+ if (mine) {
1748
+ if (v.closedAt !== null && !time(v.closedAt))
1749
+ invalidBenefitVoucherResponse();
1750
+ } else {
1751
+ if (!uuid(v.customerId) || !uuid(v.definitionId))
1752
+ invalidBenefitVoucherResponse();
1753
+ const source = object(v.source, ["namespace", "ref"]);
1754
+ if (typeof source.namespace !== "string" || !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(source.namespace) || typeof source.ref !== "string" || !source.ref.length || source.ref.length > 256)
1755
+ invalidBenefitVoucherResponse();
1756
+ if (v.closed !== null) {
1757
+ const closed = object(v.closed, [
1758
+ "at",
1759
+ "channel",
1760
+ "actor",
1761
+ "actorRef",
1762
+ "voidReason"
1763
+ ]);
1764
+ const principal = object(closed.actor, ["type", "id"]);
1765
+ if (!time(closed.at) || !uuid(principal.id) || !["server", "console"].includes(closed.channel) || !["server_credential", "operator"].includes(principal.type) || closed.actorRef !== null && !actor(closed.actorRef) || closed.voidReason !== null && !BENEFIT_VOUCHER_VOID_REASONS.includes(closed.voidReason))
1766
+ invalidBenefitVoucherResponse();
1767
+ }
1768
+ }
1769
+ return value;
1770
+ }
1771
+ function parseBenefitVoucherList(value, mine = false) {
1772
+ const v = object(value, ["vouchers", "nextCursor", "evaluatedAt"]);
1773
+ if (!Array.isArray(v.vouchers) || v.vouchers.length > 100 || !time(v.evaluatedAt) || v.nextCursor !== null && (typeof v.nextCursor !== "string" || !v.nextCursor.length || v.nextCursor.length > 2048))
1774
+ invalidBenefitVoucherResponse();
1775
+ for (const row of v.vouchers) {
1776
+ if (mine) parseBenefitVoucher(row, true);
1777
+ else parseBenefitVoucher(row);
1778
+ }
1779
+ return value;
1780
+ }
1781
+
1782
+ // src/core/api/customer-benefit-vouchers-api.ts
1783
+ var CustomerBenefitVouchersApi = class extends CustomerScopedApi {
1784
+ async listMine(params = {}) {
1785
+ const query = new URLSearchParams();
1786
+ for (const [key, value] of Object.entries(params))
1787
+ if (value !== void 0) query.set(key, String(value));
1788
+ return parseBenefitVoucherList(
1789
+ await this.requestEndpoint(
1790
+ BENEFIT_VOUCHER_ENDPOINT_OPERATIONS.listMine,
1791
+ void 0,
1792
+ { query }
1793
+ ),
1794
+ true
1795
+ );
1796
+ }
1797
+ };
1798
+
1799
+ // src/core/collection/http-client.ts
1800
+ var import_qs_esm = require("qs-esm");
1801
+ function validateWhere(where) {
1802
+ if (where === void 0) return false;
1803
+ let hasNull = false;
1804
+ function visit(value, depth, key) {
1805
+ if (depth > 10) {
1806
+ throw createValidationError(
1807
+ "Collection where must not exceed nesting depth 10."
1808
+ );
1809
+ }
1810
+ if (value === null && (key === "equals" || key === "not_equals")) {
1811
+ hasNull = true;
1812
+ return;
1813
+ }
1814
+ if (value == null) {
1815
+ throw createValidationError(
1816
+ "Collection where must not contain null or undefined values."
1817
+ );
1818
+ }
1819
+ if (Array.isArray(value)) {
1820
+ if (value.length === 0) {
1821
+ throw createValidationError(
1822
+ "Collection where must not contain empty arrays, including and/or."
1823
+ );
1824
+ }
1825
+ if (value.length > 1e3) {
1826
+ throw createValidationError(
1827
+ "Collection where arrays must not contain more than 1000 elements."
1828
+ );
1829
+ }
1830
+ for (const item of value) visit(item, depth + 1);
1831
+ } else if (typeof value === "object" && !(value instanceof Date)) {
1832
+ const values = Object.entries(value);
1833
+ if (values.length === 0) {
1834
+ throw createValidationError(
1835
+ "Collection where must not contain empty condition objects."
1836
+ );
1837
+ }
1838
+ for (const [key2, item] of values) visit(item, depth + 1, key2);
1839
+ }
1840
+ }
1841
+ visit(where, 0);
1842
+ return hasNull;
1843
+ }
1844
+ var HttpClient = class {
1845
+ constructor(publishableKey, secretKey, getCustomerToken, onUnauthorized, onRequestId, apiUrl) {
1846
+ this.publishableKey = requirePublishableKeyForSecret(
1847
+ "CollectionClient",
1848
+ publishableKey,
1849
+ secretKey
1850
+ );
1851
+ this.secretKey = secretKey;
1852
+ this.getCustomerToken = getCustomerToken;
1853
+ this.onUnauthorized = onUnauthorized;
1854
+ this.onRequestId = onRequestId;
1855
+ this.apiUrl = apiUrl;
1939
1856
  }
1940
- async request(endpoint, options) {
1941
- const token = typeof this.customerToken === "function" ? this.customerToken() : this.customerToken;
1857
+ get defaultOptions() {
1858
+ const opts = {
1859
+ apiUrl: this.apiUrl,
1860
+ publishableKey: this.publishableKey,
1861
+ secretKey: this.secretKey
1862
+ };
1863
+ const token = this.getCustomerToken?.();
1864
+ if (token) {
1865
+ opts.customerToken = token;
1866
+ if (this.onUnauthorized) {
1867
+ opts.onUnauthorized = this.onUnauthorized;
1868
+ }
1869
+ }
1870
+ return opts;
1871
+ }
1872
+ async fetchWithTracking(url, opts) {
1942
1873
  try {
1943
- const response = await httpFetch(endpoint, {
1944
- method: options.method,
1945
- apiUrl: this.apiUrl,
1946
- publishableKey: this.publishableKey,
1947
- secretKey: this.secretKey,
1948
- customerToken: token ?? void 0,
1949
- ...token && this.onUnauthorized && { onUnauthorized: this.onUnauthorized },
1950
- ...options.body !== void 0 && {
1951
- body: JSON.stringify(options.body)
1952
- },
1953
- ...options.headers && { headers: options.headers },
1954
- ...options.errorFamily && { errorFamily: options.errorFamily }
1955
- });
1874
+ const response = await httpFetch(url, opts);
1956
1875
  this.onRequestId?.(response.headers.get("x-request-id") ?? null);
1957
- return parseApiResponse(response, endpoint, {
1958
- errorFamily: options.errorFamily
1959
- });
1876
+ return response;
1960
1877
  } catch (err) {
1961
1878
  const id = err instanceof SDKError ? err.requestId ?? null : null;
1962
1879
  this.onRequestId?.(id);
1963
1880
  throw err;
1964
1881
  }
1965
1882
  }
1883
+ buildUrl(endpoint, options) {
1884
+ if (!options) return endpoint;
1885
+ const { fallbackLocale, ...rest } = options;
1886
+ const queryOptions = fallbackLocale === void 0 ? rest : {
1887
+ ...rest,
1888
+ "fallback-locale": fallbackLocale === false ? "none" : fallbackLocale
1889
+ };
1890
+ const encodedOptions = validateWhere(queryOptions.where) ? { ...queryOptions, where: JSON.stringify(queryOptions.where) } : queryOptions;
1891
+ const queryString = (0, import_qs_esm.stringify)(encodedOptions, { addQueryPrefix: true });
1892
+ return queryString ? `${endpoint}${queryString}` : endpoint;
1893
+ }
1894
+ assertJsonResponse(response) {
1895
+ const contentType = response.headers.get("content-type");
1896
+ if (!contentType?.includes("application/json")) {
1897
+ throw createApiError("Response is not in JSON format.", response.status, {
1898
+ contentType
1899
+ });
1900
+ }
1901
+ }
1902
+ /**
1903
+ * Parse Payload CMS find response (list query)
1904
+ * Returns native Payload response structure
1905
+ */
1906
+ async parseFindResponse(response) {
1907
+ const contentType = response.headers.get("content-type");
1908
+ try {
1909
+ this.assertJsonResponse(response);
1910
+ const jsonData = await response.json();
1911
+ if (jsonData.docs === void 0) {
1912
+ throw createApiError("Invalid find response.", response.status, {
1913
+ jsonData
1914
+ });
1915
+ }
1916
+ return {
1917
+ docs: jsonData.docs,
1918
+ totalDocs: jsonData.totalDocs ?? 0,
1919
+ limit: jsonData.limit || 20,
1920
+ totalPages: jsonData.totalPages ?? 0,
1921
+ page: jsonData.page || 1,
1922
+ pagingCounter: jsonData.pagingCounter || 1,
1923
+ hasPrevPage: jsonData.hasPrevPage ?? false,
1924
+ hasNextPage: jsonData.hasNextPage ?? false,
1925
+ prevPage: jsonData.prevPage ?? null,
1926
+ nextPage: jsonData.nextPage ?? null
1927
+ };
1928
+ } catch (error) {
1929
+ if (error instanceof SDKError) throw error;
1930
+ throw createApiError("Failed to parse response.", response.status, {
1931
+ contentType,
1932
+ error: error instanceof Error ? error.message : error
1933
+ });
1934
+ }
1935
+ }
1936
+ /**
1937
+ * Parse Payload CMS mutation response (create/update)
1938
+ * Returns native Payload response structure
1939
+ */
1940
+ async parseMutationResponse(response) {
1941
+ const contentType = response.headers.get("content-type");
1942
+ try {
1943
+ this.assertJsonResponse(response);
1944
+ const jsonData = await response.json();
1945
+ if (jsonData.doc === void 0) {
1946
+ throw createApiError("Invalid mutation response.", response.status, {
1947
+ jsonData
1948
+ });
1949
+ }
1950
+ return {
1951
+ message: jsonData.message || "",
1952
+ doc: jsonData.doc,
1953
+ errors: jsonData.errors
1954
+ };
1955
+ } catch (error) {
1956
+ if (error instanceof SDKError) throw error;
1957
+ throw createApiError("Failed to parse response.", response.status, {
1958
+ contentType,
1959
+ error: error instanceof Error ? error.message : error
1960
+ });
1961
+ }
1962
+ }
1963
+ /**
1964
+ * Parse Payload CMS document response (findById/delete)
1965
+ * Returns document directly without wrapper
1966
+ */
1967
+ async parseDocumentResponse(response) {
1968
+ const contentType = response.headers.get("content-type");
1969
+ try {
1970
+ this.assertJsonResponse(response);
1971
+ const jsonData = await response.json();
1972
+ return jsonData;
1973
+ } catch (error) {
1974
+ if (error instanceof SDKError) throw error;
1975
+ throw createApiError("Failed to parse response.", response.status, {
1976
+ contentType,
1977
+ error: error instanceof Error ? error.message : error
1978
+ });
1979
+ }
1980
+ }
1966
1981
  };
1967
- var CustomerScopedApi = class {
1968
- constructor(apiName, options) {
1969
- this.transport = new CustomerScopedTransport(apiName, options);
1982
+
1983
+ // src/utils/types.ts
1984
+ function resolveRelation(ref) {
1985
+ if (typeof ref === "string" || typeof ref === "number" || ref === null || ref === void 0)
1986
+ return null;
1987
+ return ref;
1988
+ }
1989
+
1990
+ // src/core/collection/query-builder.ts
1991
+ var PUBLIC_READ_DEPTH_ERROR = "Publishable collection reads require depth: 0. Use a shaped commerce endpoint or server client for populated data.";
1992
+ var PUBLIC_READ_JOINS_ERROR = "Publishable collection reads require joins: false. Use a shaped commerce endpoint or server client for joined data.";
1993
+ var PUBLIC_READ_POPULATE_ERROR = "Publishable collection reads do not support populate. Use a shaped commerce endpoint or server client for populated data.";
1994
+ function withDefaultPublicReadOptions(options) {
1995
+ const rawOptions = options;
1996
+ if (rawOptions?.depth !== void 0 && rawOptions.depth !== 0) {
1997
+ throw createValidationError(PUBLIC_READ_DEPTH_ERROR);
1970
1998
  }
1971
- requestEndpoint(endpoint, body, options) {
1972
- return this.transport.request(resolveOperationPath(endpoint, options), {
1973
- method: resolveOperationMethod(endpoint),
1974
- body,
1975
- headers: options?.headers,
1976
- errorFamily: resolveOperationErrorFamily(endpoint)
1977
- });
1999
+ if (rawOptions?.joins !== void 0 && rawOptions.joins !== false) {
2000
+ throw createValidationError(PUBLIC_READ_JOINS_ERROR);
2001
+ }
2002
+ if (rawOptions?.populate !== void 0) {
2003
+ throw createValidationError(PUBLIC_READ_POPULATE_ERROR);
2004
+ }
2005
+ return {
2006
+ ...options,
2007
+ depth: options?.depth ?? 0,
2008
+ joins: options?.joins ?? false
2009
+ };
2010
+ }
2011
+ var ReadOnlyCollectionQueryBuilder = class {
2012
+ constructor(api, collection) {
2013
+ this.api = api;
2014
+ this.collection = collection;
2015
+ }
2016
+ async find(options) {
2017
+ return this.api.requestFind(
2018
+ `/api/${String(this.collection)}`,
2019
+ withDefaultPublicReadOptions(options)
2020
+ );
2021
+ }
2022
+ async findById(id, options) {
2023
+ return this.api.requestFindById(
2024
+ `/api/${String(this.collection)}/${String(id)}`,
2025
+ withDefaultPublicReadOptions(options)
2026
+ );
2027
+ }
2028
+ async count(options) {
2029
+ return this.api.requestCount(
2030
+ `/api/${String(this.collection)}/count`,
2031
+ withDefaultPublicReadOptions(options)
2032
+ );
1978
2033
  }
1979
2034
  };
1980
- var RawCustomerScopedApi = class {
1981
- constructor(apiName, options) {
1982
- this.transport = new CustomerScopedTransport(apiName, options);
2035
+
2036
+ // src/core/collection/collection-client.ts
2037
+ var ReadOnlyCollectionClient = class extends HttpClient {
2038
+ from(collection) {
2039
+ return new ReadOnlyCollectionQueryBuilder(this, collection);
1983
2040
  }
1984
- request(endpoint, options) {
1985
- return this.transport.request(endpoint, options);
2041
+ async requestFind(endpoint, options) {
2042
+ const url = this.buildUrl(endpoint, options);
2043
+ const response = await this.fetchWithTracking(url, {
2044
+ ...this.defaultOptions,
2045
+ method: "GET"
2046
+ });
2047
+ return this.parseFindResponse(response);
2048
+ }
2049
+ async requestFindEndpoint(endpoint, data) {
2050
+ const response = await this.fetchWithTracking(endpoint, {
2051
+ ...this.defaultOptions,
2052
+ method: "POST",
2053
+ body: data ? JSON.stringify(data) : void 0
2054
+ });
2055
+ return this.parseFindResponse(response);
2056
+ }
2057
+ async requestFindEndpointGet(endpoint) {
2058
+ const response = await this.fetchWithTracking(endpoint, {
2059
+ ...this.defaultOptions,
2060
+ method: "GET"
2061
+ });
2062
+ return this.parseFindResponse(response);
2063
+ }
2064
+ async requestFindById(endpoint, options) {
2065
+ const url = this.buildUrl(endpoint, options);
2066
+ const response = await this.fetchWithTracking(url, {
2067
+ ...this.defaultOptions,
2068
+ method: "GET"
2069
+ });
2070
+ return this.parseDocumentResponse(response);
2071
+ }
2072
+ async requestCount(endpoint, options) {
2073
+ const url = this.buildUrl(endpoint, options);
2074
+ const response = await this.fetchWithTracking(url, {
2075
+ ...this.defaultOptions,
2076
+ method: "GET"
2077
+ });
2078
+ return this.parseDocumentResponse(response);
1986
2079
  }
1987
2080
  };
1988
2081
 
@@ -7313,6 +7406,16 @@ var Client = class _Client {
7313
7406
  this.markets = new MarketDiscovery(
7314
7407
  (options2) => this.collections.from("markets").find(options2)
7315
7408
  );
7409
+ this.benefitVouchers = new CustomerBenefitVouchersApi(
7410
+ "CustomerBenefitVouchersApi",
7411
+ {
7412
+ publishableKey: this.config.publishableKey,
7413
+ apiUrl: this.config.apiUrl,
7414
+ customerToken: () => this.customer.auth.getToken(),
7415
+ onUnauthorized,
7416
+ onRequestId
7417
+ }
7418
+ );
7316
7419
  const membershipApi = new BrowserMembershipApi("MembershipApi", {
7317
7420
  publishableKey: this.config.publishableKey,
7318
7421
  apiUrl: this.config.apiUrl,
@@ -7692,6 +7795,7 @@ function createTypedWebhookHandler(collection, handler) {
7692
7795
 
7693
7796
  // src/core/collection/const.ts
7694
7797
  var INTERNAL_COLLECTIONS = [
7798
+ "benefit-voucher-definitions",
7695
7799
  "users",
7696
7800
  "payload-kv",
7697
7801
  "payload-locked-documents",