@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.js CHANGED
@@ -1,6 +1,3 @@
1
- // src/core/collection/http-client.ts
2
- import { stringify } from "qs-esm";
3
-
4
1
  // src/core/errors.ts
5
2
  var SDK_ERROR_BRAND = /* @__PURE__ */ Symbol.for("@01.software/sdk/SDKError");
6
3
  var SDK_ERROR_TYPE_BRAND = /* @__PURE__ */ Symbol.for("@01.software/sdk/SDKError.type");
@@ -114,6 +111,7 @@ var COMMERCE_ERROR_CODES = [
114
111
  "admission_metadata_invalid",
115
112
  "admission_metadata_required",
116
113
  "capacity_exceeded",
114
+ "admission_required",
117
115
  "occurrence_lock_unavailable",
118
116
  "occurrence_not_open",
119
117
  "admission_type_capacity_exceeded",
@@ -132,6 +130,8 @@ var COMMERCE_ERROR_CODES = [
132
130
  "variant_inactive",
133
131
  "variant_product_mismatch",
134
132
  "product_not_public",
133
+ "product_not_eligible",
134
+ "purchase_limit_exceeded",
135
135
  "market_not_found",
136
136
  "market_shipping_currency_unsupported",
137
137
  "missing_market_rate",
@@ -1004,288 +1004,6 @@ function stockSnapshotSearchParams(params) {
1004
1004
  return `variantIds=${params.variantIds.map(encodeURIComponent).join(",")}`;
1005
1005
  }
1006
1006
 
1007
- // src/core/collection/http-client.ts
1008
- function validateWhere(where) {
1009
- if (where === void 0) return false;
1010
- let hasNull = false;
1011
- function visit(value, depth, key) {
1012
- if (depth > 10) {
1013
- throw createValidationError(
1014
- "Collection where must not exceed nesting depth 10."
1015
- );
1016
- }
1017
- if (value === null && (key === "equals" || key === "not_equals")) {
1018
- hasNull = true;
1019
- return;
1020
- }
1021
- if (value == null) {
1022
- throw createValidationError(
1023
- "Collection where must not contain null or undefined values."
1024
- );
1025
- }
1026
- if (Array.isArray(value)) {
1027
- if (value.length === 0) {
1028
- throw createValidationError(
1029
- "Collection where must not contain empty arrays, including and/or."
1030
- );
1031
- }
1032
- if (value.length > 1e3) {
1033
- throw createValidationError(
1034
- "Collection where arrays must not contain more than 1000 elements."
1035
- );
1036
- }
1037
- for (const item of value) visit(item, depth + 1);
1038
- } else if (typeof value === "object" && !(value instanceof Date)) {
1039
- const values = Object.entries(value);
1040
- if (values.length === 0) {
1041
- throw createValidationError(
1042
- "Collection where must not contain empty condition objects."
1043
- );
1044
- }
1045
- for (const [key2, item] of values) visit(item, depth + 1, key2);
1046
- }
1047
- }
1048
- visit(where, 0);
1049
- return hasNull;
1050
- }
1051
- var HttpClient = class {
1052
- constructor(publishableKey, secretKey, getCustomerToken, onUnauthorized, onRequestId, apiUrl) {
1053
- this.publishableKey = requirePublishableKeyForSecret(
1054
- "CollectionClient",
1055
- publishableKey,
1056
- secretKey
1057
- );
1058
- this.secretKey = secretKey;
1059
- this.getCustomerToken = getCustomerToken;
1060
- this.onUnauthorized = onUnauthorized;
1061
- this.onRequestId = onRequestId;
1062
- this.apiUrl = apiUrl;
1063
- }
1064
- get defaultOptions() {
1065
- const opts = {
1066
- apiUrl: this.apiUrl,
1067
- publishableKey: this.publishableKey,
1068
- secretKey: this.secretKey
1069
- };
1070
- const token = this.getCustomerToken?.();
1071
- if (token) {
1072
- opts.customerToken = token;
1073
- if (this.onUnauthorized) {
1074
- opts.onUnauthorized = this.onUnauthorized;
1075
- }
1076
- }
1077
- return opts;
1078
- }
1079
- async fetchWithTracking(url, opts) {
1080
- try {
1081
- const response = await httpFetch(url, opts);
1082
- this.onRequestId?.(response.headers.get("x-request-id") ?? null);
1083
- return response;
1084
- } catch (err) {
1085
- const id = err instanceof SDKError ? err.requestId ?? null : null;
1086
- this.onRequestId?.(id);
1087
- throw err;
1088
- }
1089
- }
1090
- buildUrl(endpoint, options) {
1091
- if (!options) return endpoint;
1092
- const { fallbackLocale, ...rest } = options;
1093
- const queryOptions = fallbackLocale === void 0 ? rest : {
1094
- ...rest,
1095
- "fallback-locale": fallbackLocale === false ? "none" : fallbackLocale
1096
- };
1097
- const encodedOptions = validateWhere(queryOptions.where) ? { ...queryOptions, where: JSON.stringify(queryOptions.where) } : queryOptions;
1098
- const queryString = stringify(encodedOptions, { addQueryPrefix: true });
1099
- return queryString ? `${endpoint}${queryString}` : endpoint;
1100
- }
1101
- assertJsonResponse(response) {
1102
- const contentType = response.headers.get("content-type");
1103
- if (!contentType?.includes("application/json")) {
1104
- throw createApiError("Response is not in JSON format.", response.status, {
1105
- contentType
1106
- });
1107
- }
1108
- }
1109
- /**
1110
- * Parse Payload CMS find response (list query)
1111
- * Returns native Payload response structure
1112
- */
1113
- async parseFindResponse(response) {
1114
- const contentType = response.headers.get("content-type");
1115
- try {
1116
- this.assertJsonResponse(response);
1117
- const jsonData = await response.json();
1118
- if (jsonData.docs === void 0) {
1119
- throw createApiError("Invalid find response.", response.status, {
1120
- jsonData
1121
- });
1122
- }
1123
- return {
1124
- docs: jsonData.docs,
1125
- totalDocs: jsonData.totalDocs ?? 0,
1126
- limit: jsonData.limit || 20,
1127
- totalPages: jsonData.totalPages ?? 0,
1128
- page: jsonData.page || 1,
1129
- pagingCounter: jsonData.pagingCounter || 1,
1130
- hasPrevPage: jsonData.hasPrevPage ?? false,
1131
- hasNextPage: jsonData.hasNextPage ?? false,
1132
- prevPage: jsonData.prevPage ?? null,
1133
- nextPage: jsonData.nextPage ?? null
1134
- };
1135
- } catch (error) {
1136
- if (error instanceof SDKError) throw error;
1137
- throw createApiError("Failed to parse response.", response.status, {
1138
- contentType,
1139
- error: error instanceof Error ? error.message : error
1140
- });
1141
- }
1142
- }
1143
- /**
1144
- * Parse Payload CMS mutation response (create/update)
1145
- * Returns native Payload response structure
1146
- */
1147
- async parseMutationResponse(response) {
1148
- const contentType = response.headers.get("content-type");
1149
- try {
1150
- this.assertJsonResponse(response);
1151
- const jsonData = await response.json();
1152
- if (jsonData.doc === void 0) {
1153
- throw createApiError("Invalid mutation response.", response.status, {
1154
- jsonData
1155
- });
1156
- }
1157
- return {
1158
- message: jsonData.message || "",
1159
- doc: jsonData.doc,
1160
- errors: jsonData.errors
1161
- };
1162
- } catch (error) {
1163
- if (error instanceof SDKError) throw error;
1164
- throw createApiError("Failed to parse response.", response.status, {
1165
- contentType,
1166
- error: error instanceof Error ? error.message : error
1167
- });
1168
- }
1169
- }
1170
- /**
1171
- * Parse Payload CMS document response (findById/delete)
1172
- * Returns document directly without wrapper
1173
- */
1174
- async parseDocumentResponse(response) {
1175
- const contentType = response.headers.get("content-type");
1176
- try {
1177
- this.assertJsonResponse(response);
1178
- const jsonData = await response.json();
1179
- return jsonData;
1180
- } catch (error) {
1181
- if (error instanceof SDKError) throw error;
1182
- throw createApiError("Failed to parse response.", response.status, {
1183
- contentType,
1184
- error: error instanceof Error ? error.message : error
1185
- });
1186
- }
1187
- }
1188
- };
1189
-
1190
- // src/utils/types.ts
1191
- function resolveRelation(ref) {
1192
- if (typeof ref === "string" || typeof ref === "number" || ref === null || ref === void 0)
1193
- return null;
1194
- return ref;
1195
- }
1196
-
1197
- // src/core/collection/query-builder.ts
1198
- var PUBLIC_READ_DEPTH_ERROR = "Publishable collection reads require depth: 0. Use a shaped commerce endpoint or server client for populated data.";
1199
- var PUBLIC_READ_JOINS_ERROR = "Publishable collection reads require joins: false. Use a shaped commerce endpoint or server client for joined data.";
1200
- var PUBLIC_READ_POPULATE_ERROR = "Publishable collection reads do not support populate. Use a shaped commerce endpoint or server client for populated data.";
1201
- function withDefaultPublicReadOptions(options) {
1202
- const rawOptions = options;
1203
- if (rawOptions?.depth !== void 0 && rawOptions.depth !== 0) {
1204
- throw createValidationError(PUBLIC_READ_DEPTH_ERROR);
1205
- }
1206
- if (rawOptions?.joins !== void 0 && rawOptions.joins !== false) {
1207
- throw createValidationError(PUBLIC_READ_JOINS_ERROR);
1208
- }
1209
- if (rawOptions?.populate !== void 0) {
1210
- throw createValidationError(PUBLIC_READ_POPULATE_ERROR);
1211
- }
1212
- return {
1213
- ...options,
1214
- depth: options?.depth ?? 0,
1215
- joins: options?.joins ?? false
1216
- };
1217
- }
1218
- var ReadOnlyCollectionQueryBuilder = class {
1219
- constructor(api, collection) {
1220
- this.api = api;
1221
- this.collection = collection;
1222
- }
1223
- async find(options) {
1224
- return this.api.requestFind(
1225
- `/api/${String(this.collection)}`,
1226
- withDefaultPublicReadOptions(options)
1227
- );
1228
- }
1229
- async findById(id, options) {
1230
- return this.api.requestFindById(
1231
- `/api/${String(this.collection)}/${String(id)}`,
1232
- withDefaultPublicReadOptions(options)
1233
- );
1234
- }
1235
- async count(options) {
1236
- return this.api.requestCount(
1237
- `/api/${String(this.collection)}/count`,
1238
- withDefaultPublicReadOptions(options)
1239
- );
1240
- }
1241
- };
1242
-
1243
- // src/core/collection/collection-client.ts
1244
- var ReadOnlyCollectionClient = class extends HttpClient {
1245
- from(collection) {
1246
- return new ReadOnlyCollectionQueryBuilder(this, collection);
1247
- }
1248
- async requestFind(endpoint, options) {
1249
- const url = this.buildUrl(endpoint, options);
1250
- const response = await this.fetchWithTracking(url, {
1251
- ...this.defaultOptions,
1252
- method: "GET"
1253
- });
1254
- return this.parseFindResponse(response);
1255
- }
1256
- async requestFindEndpoint(endpoint, data) {
1257
- const response = await this.fetchWithTracking(endpoint, {
1258
- ...this.defaultOptions,
1259
- method: "POST",
1260
- body: data ? JSON.stringify(data) : void 0
1261
- });
1262
- return this.parseFindResponse(response);
1263
- }
1264
- async requestFindEndpointGet(endpoint) {
1265
- const response = await this.fetchWithTracking(endpoint, {
1266
- ...this.defaultOptions,
1267
- method: "GET"
1268
- });
1269
- return this.parseFindResponse(response);
1270
- }
1271
- async requestFindById(endpoint, options) {
1272
- const url = this.buildUrl(endpoint, options);
1273
- const response = await this.fetchWithTracking(url, {
1274
- ...this.defaultOptions,
1275
- method: "GET"
1276
- });
1277
- return this.parseDocumentResponse(response);
1278
- }
1279
- async requestCount(endpoint, options) {
1280
- const url = this.buildUrl(endpoint, options);
1281
- const response = await this.fetchWithTracking(url, {
1282
- ...this.defaultOptions,
1283
- method: "GET"
1284
- });
1285
- return this.parseDocumentResponse(response);
1286
- }
1287
- };
1288
-
1289
1007
  // src/core/api/parse-response.ts
1290
1008
  async function parseApiResponse(response, endpoint, options = {}) {
1291
1009
  if (response.status === 204 || response.headers.get("content-length") === "0") {
@@ -1547,6 +1265,14 @@ var EXTERNAL_CUSTOMER_LINK_ENDPOINT_OPERATIONS = {
1547
1265
  "/external-links/clear-previous-state"
1548
1266
  )
1549
1267
  };
1268
+ var BENEFIT_VOUCHER_ENDPOINT_OPERATIONS = {
1269
+ issue: operation("customers", "post", "/benefit-vouchers/issue"),
1270
+ get: operation("customers", "post", "/benefit-vouchers/get"),
1271
+ list: operation("customers", "post", "/benefit-vouchers/list"),
1272
+ redeem: operation("customers", "post", "/benefit-vouchers/redeem"),
1273
+ void: operation("customers", "post", "/benefit-vouchers/void"),
1274
+ listMine: operation("customers", "get", "/me/benefit-vouchers")
1275
+ };
1550
1276
  var CUSTOMER_GROUP_ENDPOINT_OPERATIONS = {
1551
1277
  members: operation("customer-groups", "get", "/:id/members"),
1552
1278
  grant: operation("customer-groups", "post", "/:id/members/grant"),
@@ -1788,58 +1514,425 @@ var CustomerScopedTransport = class {
1788
1514
  options.publishableKey,
1789
1515
  options.secretKey
1790
1516
  );
1791
- this.secretKey = options.secretKey;
1792
- this.apiUrl = options.apiUrl;
1793
- this.customerToken = options.customerToken;
1794
- this.onUnauthorized = options.onUnauthorized;
1795
- this.onRequestId = options.onRequestId;
1517
+ this.secretKey = options.secretKey;
1518
+ this.apiUrl = options.apiUrl;
1519
+ this.customerToken = options.customerToken;
1520
+ this.onUnauthorized = options.onUnauthorized;
1521
+ this.onRequestId = options.onRequestId;
1522
+ }
1523
+ async request(endpoint, options) {
1524
+ const token = typeof this.customerToken === "function" ? this.customerToken() : this.customerToken;
1525
+ try {
1526
+ const response = await httpFetch(endpoint, {
1527
+ method: options.method,
1528
+ apiUrl: this.apiUrl,
1529
+ publishableKey: this.publishableKey,
1530
+ secretKey: this.secretKey,
1531
+ customerToken: token ?? void 0,
1532
+ ...token && this.onUnauthorized && { onUnauthorized: this.onUnauthorized },
1533
+ ...options.body !== void 0 && {
1534
+ body: JSON.stringify(options.body)
1535
+ },
1536
+ ...options.headers && { headers: options.headers },
1537
+ ...options.errorFamily && { errorFamily: options.errorFamily }
1538
+ });
1539
+ this.onRequestId?.(response.headers.get("x-request-id") ?? null);
1540
+ return parseApiResponse(response, endpoint, {
1541
+ errorFamily: options.errorFamily
1542
+ });
1543
+ } catch (err) {
1544
+ const id = err instanceof SDKError ? err.requestId ?? null : null;
1545
+ this.onRequestId?.(id);
1546
+ throw err;
1547
+ }
1548
+ }
1549
+ };
1550
+ var CustomerScopedApi = class {
1551
+ constructor(apiName, options) {
1552
+ this.transport = new CustomerScopedTransport(apiName, options);
1553
+ }
1554
+ requestEndpoint(endpoint, body, options) {
1555
+ return this.transport.request(resolveOperationPath(endpoint, options), {
1556
+ method: resolveOperationMethod(endpoint),
1557
+ body,
1558
+ headers: options?.headers,
1559
+ errorFamily: resolveOperationErrorFamily(endpoint)
1560
+ });
1561
+ }
1562
+ };
1563
+ var RawCustomerScopedApi = class {
1564
+ constructor(apiName, options) {
1565
+ this.transport = new CustomerScopedTransport(apiName, options);
1566
+ }
1567
+ request(endpoint, options) {
1568
+ return this.transport.request(endpoint, options);
1569
+ }
1570
+ };
1571
+
1572
+ // src/core/api/benefit-voucher-types.ts
1573
+ var BENEFIT_VOUCHER_VOID_REASONS = [
1574
+ "issued_in_error",
1575
+ "benefit_revoked",
1576
+ "customer_request",
1577
+ "other"
1578
+ ];
1579
+ function invalidBenefitVoucherResponse() {
1580
+ throw createApiError("Invalid benefit voucher response", 200);
1581
+ }
1582
+ function object(value, keys) {
1583
+ if (!value || typeof value !== "object" || Array.isArray(value) || Object.keys(value).length !== keys.length || keys.some((key) => !(key in value)))
1584
+ invalidBenefitVoucherResponse();
1585
+ return value;
1586
+ }
1587
+ 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(
1588
+ v
1589
+ ) || v === "00000000-0000-0000-0000-000000000000" || v.toLowerCase() === "ffffffff-ffff-ffff-ffff-ffffffffffff");
1590
+ 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;
1591
+ var actor = (v) => typeof v === "string" && /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(v);
1592
+ function parseBenefitVoucher(value, mine = false) {
1593
+ const v = object(value, [
1594
+ "id",
1595
+ "name",
1596
+ "description",
1597
+ "state",
1598
+ "issuedAt",
1599
+ "expiresAt",
1600
+ ...mine ? ["closedAt"] : ["customerId", "definitionId", "source", "closed"]
1601
+ ]);
1602
+ 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))
1603
+ invalidBenefitVoucherResponse();
1604
+ if (mine) {
1605
+ if (v.closedAt !== null && !time(v.closedAt))
1606
+ invalidBenefitVoucherResponse();
1607
+ } else {
1608
+ if (!uuid(v.customerId) || !uuid(v.definitionId))
1609
+ invalidBenefitVoucherResponse();
1610
+ const source = object(v.source, ["namespace", "ref"]);
1611
+ 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)
1612
+ invalidBenefitVoucherResponse();
1613
+ if (v.closed !== null) {
1614
+ const closed = object(v.closed, [
1615
+ "at",
1616
+ "channel",
1617
+ "actor",
1618
+ "actorRef",
1619
+ "voidReason"
1620
+ ]);
1621
+ const principal = object(closed.actor, ["type", "id"]);
1622
+ 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))
1623
+ invalidBenefitVoucherResponse();
1624
+ }
1625
+ }
1626
+ return value;
1627
+ }
1628
+ function parseBenefitVoucherList(value, mine = false) {
1629
+ const v = object(value, ["vouchers", "nextCursor", "evaluatedAt"]);
1630
+ 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))
1631
+ invalidBenefitVoucherResponse();
1632
+ for (const row of v.vouchers) {
1633
+ if (mine) parseBenefitVoucher(row, true);
1634
+ else parseBenefitVoucher(row);
1635
+ }
1636
+ return value;
1637
+ }
1638
+
1639
+ // src/core/api/customer-benefit-vouchers-api.ts
1640
+ var CustomerBenefitVouchersApi = class extends CustomerScopedApi {
1641
+ async listMine(params = {}) {
1642
+ const query = new URLSearchParams();
1643
+ for (const [key, value] of Object.entries(params))
1644
+ if (value !== void 0) query.set(key, String(value));
1645
+ return parseBenefitVoucherList(
1646
+ await this.requestEndpoint(
1647
+ BENEFIT_VOUCHER_ENDPOINT_OPERATIONS.listMine,
1648
+ void 0,
1649
+ { query }
1650
+ ),
1651
+ true
1652
+ );
1653
+ }
1654
+ };
1655
+
1656
+ // src/core/collection/http-client.ts
1657
+ import { stringify } from "qs-esm";
1658
+ function validateWhere(where) {
1659
+ if (where === void 0) return false;
1660
+ let hasNull = false;
1661
+ function visit(value, depth, key) {
1662
+ if (depth > 10) {
1663
+ throw createValidationError(
1664
+ "Collection where must not exceed nesting depth 10."
1665
+ );
1666
+ }
1667
+ if (value === null && (key === "equals" || key === "not_equals")) {
1668
+ hasNull = true;
1669
+ return;
1670
+ }
1671
+ if (value == null) {
1672
+ throw createValidationError(
1673
+ "Collection where must not contain null or undefined values."
1674
+ );
1675
+ }
1676
+ if (Array.isArray(value)) {
1677
+ if (value.length === 0) {
1678
+ throw createValidationError(
1679
+ "Collection where must not contain empty arrays, including and/or."
1680
+ );
1681
+ }
1682
+ if (value.length > 1e3) {
1683
+ throw createValidationError(
1684
+ "Collection where arrays must not contain more than 1000 elements."
1685
+ );
1686
+ }
1687
+ for (const item of value) visit(item, depth + 1);
1688
+ } else if (typeof value === "object" && !(value instanceof Date)) {
1689
+ const values = Object.entries(value);
1690
+ if (values.length === 0) {
1691
+ throw createValidationError(
1692
+ "Collection where must not contain empty condition objects."
1693
+ );
1694
+ }
1695
+ for (const [key2, item] of values) visit(item, depth + 1, key2);
1696
+ }
1697
+ }
1698
+ visit(where, 0);
1699
+ return hasNull;
1700
+ }
1701
+ var HttpClient = class {
1702
+ constructor(publishableKey, secretKey, getCustomerToken, onUnauthorized, onRequestId, apiUrl) {
1703
+ this.publishableKey = requirePublishableKeyForSecret(
1704
+ "CollectionClient",
1705
+ publishableKey,
1706
+ secretKey
1707
+ );
1708
+ this.secretKey = secretKey;
1709
+ this.getCustomerToken = getCustomerToken;
1710
+ this.onUnauthorized = onUnauthorized;
1711
+ this.onRequestId = onRequestId;
1712
+ this.apiUrl = apiUrl;
1796
1713
  }
1797
- async request(endpoint, options) {
1798
- const token = typeof this.customerToken === "function" ? this.customerToken() : this.customerToken;
1714
+ get defaultOptions() {
1715
+ const opts = {
1716
+ apiUrl: this.apiUrl,
1717
+ publishableKey: this.publishableKey,
1718
+ secretKey: this.secretKey
1719
+ };
1720
+ const token = this.getCustomerToken?.();
1721
+ if (token) {
1722
+ opts.customerToken = token;
1723
+ if (this.onUnauthorized) {
1724
+ opts.onUnauthorized = this.onUnauthorized;
1725
+ }
1726
+ }
1727
+ return opts;
1728
+ }
1729
+ async fetchWithTracking(url, opts) {
1799
1730
  try {
1800
- const response = await httpFetch(endpoint, {
1801
- method: options.method,
1802
- apiUrl: this.apiUrl,
1803
- publishableKey: this.publishableKey,
1804
- secretKey: this.secretKey,
1805
- customerToken: token ?? void 0,
1806
- ...token && this.onUnauthorized && { onUnauthorized: this.onUnauthorized },
1807
- ...options.body !== void 0 && {
1808
- body: JSON.stringify(options.body)
1809
- },
1810
- ...options.headers && { headers: options.headers },
1811
- ...options.errorFamily && { errorFamily: options.errorFamily }
1812
- });
1731
+ const response = await httpFetch(url, opts);
1813
1732
  this.onRequestId?.(response.headers.get("x-request-id") ?? null);
1814
- return parseApiResponse(response, endpoint, {
1815
- errorFamily: options.errorFamily
1816
- });
1733
+ return response;
1817
1734
  } catch (err) {
1818
1735
  const id = err instanceof SDKError ? err.requestId ?? null : null;
1819
1736
  this.onRequestId?.(id);
1820
1737
  throw err;
1821
1738
  }
1822
1739
  }
1740
+ buildUrl(endpoint, options) {
1741
+ if (!options) return endpoint;
1742
+ const { fallbackLocale, ...rest } = options;
1743
+ const queryOptions = fallbackLocale === void 0 ? rest : {
1744
+ ...rest,
1745
+ "fallback-locale": fallbackLocale === false ? "none" : fallbackLocale
1746
+ };
1747
+ const encodedOptions = validateWhere(queryOptions.where) ? { ...queryOptions, where: JSON.stringify(queryOptions.where) } : queryOptions;
1748
+ const queryString = stringify(encodedOptions, { addQueryPrefix: true });
1749
+ return queryString ? `${endpoint}${queryString}` : endpoint;
1750
+ }
1751
+ assertJsonResponse(response) {
1752
+ const contentType = response.headers.get("content-type");
1753
+ if (!contentType?.includes("application/json")) {
1754
+ throw createApiError("Response is not in JSON format.", response.status, {
1755
+ contentType
1756
+ });
1757
+ }
1758
+ }
1759
+ /**
1760
+ * Parse Payload CMS find response (list query)
1761
+ * Returns native Payload response structure
1762
+ */
1763
+ async parseFindResponse(response) {
1764
+ const contentType = response.headers.get("content-type");
1765
+ try {
1766
+ this.assertJsonResponse(response);
1767
+ const jsonData = await response.json();
1768
+ if (jsonData.docs === void 0) {
1769
+ throw createApiError("Invalid find response.", response.status, {
1770
+ jsonData
1771
+ });
1772
+ }
1773
+ return {
1774
+ docs: jsonData.docs,
1775
+ totalDocs: jsonData.totalDocs ?? 0,
1776
+ limit: jsonData.limit || 20,
1777
+ totalPages: jsonData.totalPages ?? 0,
1778
+ page: jsonData.page || 1,
1779
+ pagingCounter: jsonData.pagingCounter || 1,
1780
+ hasPrevPage: jsonData.hasPrevPage ?? false,
1781
+ hasNextPage: jsonData.hasNextPage ?? false,
1782
+ prevPage: jsonData.prevPage ?? null,
1783
+ nextPage: jsonData.nextPage ?? null
1784
+ };
1785
+ } catch (error) {
1786
+ if (error instanceof SDKError) throw error;
1787
+ throw createApiError("Failed to parse response.", response.status, {
1788
+ contentType,
1789
+ error: error instanceof Error ? error.message : error
1790
+ });
1791
+ }
1792
+ }
1793
+ /**
1794
+ * Parse Payload CMS mutation response (create/update)
1795
+ * Returns native Payload response structure
1796
+ */
1797
+ async parseMutationResponse(response) {
1798
+ const contentType = response.headers.get("content-type");
1799
+ try {
1800
+ this.assertJsonResponse(response);
1801
+ const jsonData = await response.json();
1802
+ if (jsonData.doc === void 0) {
1803
+ throw createApiError("Invalid mutation response.", response.status, {
1804
+ jsonData
1805
+ });
1806
+ }
1807
+ return {
1808
+ message: jsonData.message || "",
1809
+ doc: jsonData.doc,
1810
+ errors: jsonData.errors
1811
+ };
1812
+ } catch (error) {
1813
+ if (error instanceof SDKError) throw error;
1814
+ throw createApiError("Failed to parse response.", response.status, {
1815
+ contentType,
1816
+ error: error instanceof Error ? error.message : error
1817
+ });
1818
+ }
1819
+ }
1820
+ /**
1821
+ * Parse Payload CMS document response (findById/delete)
1822
+ * Returns document directly without wrapper
1823
+ */
1824
+ async parseDocumentResponse(response) {
1825
+ const contentType = response.headers.get("content-type");
1826
+ try {
1827
+ this.assertJsonResponse(response);
1828
+ const jsonData = await response.json();
1829
+ return jsonData;
1830
+ } catch (error) {
1831
+ if (error instanceof SDKError) throw error;
1832
+ throw createApiError("Failed to parse response.", response.status, {
1833
+ contentType,
1834
+ error: error instanceof Error ? error.message : error
1835
+ });
1836
+ }
1837
+ }
1823
1838
  };
1824
- var CustomerScopedApi = class {
1825
- constructor(apiName, options) {
1826
- this.transport = new CustomerScopedTransport(apiName, options);
1839
+
1840
+ // src/utils/types.ts
1841
+ function resolveRelation(ref) {
1842
+ if (typeof ref === "string" || typeof ref === "number" || ref === null || ref === void 0)
1843
+ return null;
1844
+ return ref;
1845
+ }
1846
+
1847
+ // src/core/collection/query-builder.ts
1848
+ var PUBLIC_READ_DEPTH_ERROR = "Publishable collection reads require depth: 0. Use a shaped commerce endpoint or server client for populated data.";
1849
+ var PUBLIC_READ_JOINS_ERROR = "Publishable collection reads require joins: false. Use a shaped commerce endpoint or server client for joined data.";
1850
+ var PUBLIC_READ_POPULATE_ERROR = "Publishable collection reads do not support populate. Use a shaped commerce endpoint or server client for populated data.";
1851
+ function withDefaultPublicReadOptions(options) {
1852
+ const rawOptions = options;
1853
+ if (rawOptions?.depth !== void 0 && rawOptions.depth !== 0) {
1854
+ throw createValidationError(PUBLIC_READ_DEPTH_ERROR);
1827
1855
  }
1828
- requestEndpoint(endpoint, body, options) {
1829
- return this.transport.request(resolveOperationPath(endpoint, options), {
1830
- method: resolveOperationMethod(endpoint),
1831
- body,
1832
- headers: options?.headers,
1833
- errorFamily: resolveOperationErrorFamily(endpoint)
1834
- });
1856
+ if (rawOptions?.joins !== void 0 && rawOptions.joins !== false) {
1857
+ throw createValidationError(PUBLIC_READ_JOINS_ERROR);
1858
+ }
1859
+ if (rawOptions?.populate !== void 0) {
1860
+ throw createValidationError(PUBLIC_READ_POPULATE_ERROR);
1861
+ }
1862
+ return {
1863
+ ...options,
1864
+ depth: options?.depth ?? 0,
1865
+ joins: options?.joins ?? false
1866
+ };
1867
+ }
1868
+ var ReadOnlyCollectionQueryBuilder = class {
1869
+ constructor(api, collection) {
1870
+ this.api = api;
1871
+ this.collection = collection;
1872
+ }
1873
+ async find(options) {
1874
+ return this.api.requestFind(
1875
+ `/api/${String(this.collection)}`,
1876
+ withDefaultPublicReadOptions(options)
1877
+ );
1878
+ }
1879
+ async findById(id, options) {
1880
+ return this.api.requestFindById(
1881
+ `/api/${String(this.collection)}/${String(id)}`,
1882
+ withDefaultPublicReadOptions(options)
1883
+ );
1884
+ }
1885
+ async count(options) {
1886
+ return this.api.requestCount(
1887
+ `/api/${String(this.collection)}/count`,
1888
+ withDefaultPublicReadOptions(options)
1889
+ );
1835
1890
  }
1836
1891
  };
1837
- var RawCustomerScopedApi = class {
1838
- constructor(apiName, options) {
1839
- this.transport = new CustomerScopedTransport(apiName, options);
1892
+
1893
+ // src/core/collection/collection-client.ts
1894
+ var ReadOnlyCollectionClient = class extends HttpClient {
1895
+ from(collection) {
1896
+ return new ReadOnlyCollectionQueryBuilder(this, collection);
1840
1897
  }
1841
- request(endpoint, options) {
1842
- return this.transport.request(endpoint, options);
1898
+ async requestFind(endpoint, options) {
1899
+ const url = this.buildUrl(endpoint, options);
1900
+ const response = await this.fetchWithTracking(url, {
1901
+ ...this.defaultOptions,
1902
+ method: "GET"
1903
+ });
1904
+ return this.parseFindResponse(response);
1905
+ }
1906
+ async requestFindEndpoint(endpoint, data) {
1907
+ const response = await this.fetchWithTracking(endpoint, {
1908
+ ...this.defaultOptions,
1909
+ method: "POST",
1910
+ body: data ? JSON.stringify(data) : void 0
1911
+ });
1912
+ return this.parseFindResponse(response);
1913
+ }
1914
+ async requestFindEndpointGet(endpoint) {
1915
+ const response = await this.fetchWithTracking(endpoint, {
1916
+ ...this.defaultOptions,
1917
+ method: "GET"
1918
+ });
1919
+ return this.parseFindResponse(response);
1920
+ }
1921
+ async requestFindById(endpoint, options) {
1922
+ const url = this.buildUrl(endpoint, options);
1923
+ const response = await this.fetchWithTracking(url, {
1924
+ ...this.defaultOptions,
1925
+ method: "GET"
1926
+ });
1927
+ return this.parseDocumentResponse(response);
1928
+ }
1929
+ async requestCount(endpoint, options) {
1930
+ const url = this.buildUrl(endpoint, options);
1931
+ const response = await this.fetchWithTracking(url, {
1932
+ ...this.defaultOptions,
1933
+ method: "GET"
1934
+ });
1935
+ return this.parseDocumentResponse(response);
1843
1936
  }
1844
1937
  };
1845
1938
 
@@ -7170,6 +7263,16 @@ var Client = class _Client {
7170
7263
  this.markets = new MarketDiscovery(
7171
7264
  (options2) => this.collections.from("markets").find(options2)
7172
7265
  );
7266
+ this.benefitVouchers = new CustomerBenefitVouchersApi(
7267
+ "CustomerBenefitVouchersApi",
7268
+ {
7269
+ publishableKey: this.config.publishableKey,
7270
+ apiUrl: this.config.apiUrl,
7271
+ customerToken: () => this.customer.auth.getToken(),
7272
+ onUnauthorized,
7273
+ onRequestId
7274
+ }
7275
+ );
7173
7276
  const membershipApi = new BrowserMembershipApi("MembershipApi", {
7174
7277
  publishableKey: this.config.publishableKey,
7175
7278
  apiUrl: this.config.apiUrl,
@@ -7549,6 +7652,7 @@ function createTypedWebhookHandler(collection, handler) {
7549
7652
 
7550
7653
  // src/core/collection/const.ts
7551
7654
  var INTERNAL_COLLECTIONS = [
7655
+ "benefit-voucher-definitions",
7552
7656
  "users",
7553
7657
  "payload-kv",
7554
7658
  "payload-locked-documents",