@01.software/sdk 0.70.1 → 0.72.1

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 (70) hide show
  1. package/CHANGELOG.md +143 -0
  2. package/MIGRATION.md +28 -0
  3. package/README.md +253 -11
  4. package/dist/client.cjs +396 -26
  5. package/dist/client.cjs.map +1 -1
  6. package/dist/client.d.cts +7 -6
  7. package/dist/client.d.ts +7 -6
  8. package/dist/client.js +396 -26
  9. package/dist/client.js.map +1 -1
  10. package/dist/{collection-client-BHLStm1K.d.cts → collection-client-B3CnqMDQ.d.cts} +14 -18
  11. package/dist/{collection-client-B1FSJ24_.d.ts → collection-client-uOgS_1bC.d.ts} +14 -18
  12. package/dist/{const-ty8u0TDI.d.ts → const-BJBK7jBl.d.ts} +1 -1
  13. package/dist/{const-BfQfV-rr.d.cts → const-_ZfJjRQG.d.cts} +1 -1
  14. package/dist/embedded-admin/server.cjs +117 -2
  15. package/dist/embedded-admin/server.cjs.map +1 -1
  16. package/dist/embedded-admin/server.d.cts +30 -2
  17. package/dist/embedded-admin/server.d.ts +30 -2
  18. package/dist/embedded-admin/server.js +117 -2
  19. package/dist/embedded-admin/server.js.map +1 -1
  20. package/dist/embedded-admin.cjs +135 -7
  21. package/dist/embedded-admin.cjs.map +1 -1
  22. package/dist/embedded-admin.d.cts +35 -2
  23. package/dist/embedded-admin.d.ts +35 -2
  24. package/dist/embedded-admin.js +135 -7
  25. package/dist/embedded-admin.js.map +1 -1
  26. package/dist/errors.cjs +2 -0
  27. package/dist/errors.cjs.map +1 -1
  28. package/dist/errors.d.cts +3 -3
  29. package/dist/errors.d.ts +3 -3
  30. package/dist/errors.js +2 -0
  31. package/dist/errors.js.map +1 -1
  32. package/dist/{index-DnKgjPGM.d.ts → index-CBaP4q8r.d.ts} +3 -3
  33. package/dist/{index-CX6si6YC.d.cts → index-CI_LFWiG.d.cts} +3 -3
  34. package/dist/index.cjs +396 -26
  35. package/dist/index.cjs.map +1 -1
  36. package/dist/index.d.cts +24 -9
  37. package/dist/index.d.ts +24 -9
  38. package/dist/index.js +396 -26
  39. package/dist/index.js.map +1 -1
  40. package/dist/{payload-types-DTAaWKrp.d.cts → payload-types-BRg8Yary.d.cts} +262 -177
  41. package/dist/{payload-types-DTAaWKrp.d.ts → payload-types-BRg8Yary.d.ts} +262 -177
  42. package/dist/query.cjs +20 -0
  43. package/dist/query.cjs.map +1 -1
  44. package/dist/query.d.cts +5 -5
  45. package/dist/query.d.ts +5 -5
  46. package/dist/query.js +20 -0
  47. package/dist/query.js.map +1 -1
  48. package/dist/realtime.d.cts +2 -2
  49. package/dist/realtime.d.ts +2 -2
  50. package/dist/server.cjs +459 -46
  51. package/dist/server.cjs.map +1 -1
  52. package/dist/server.d.cts +10 -8
  53. package/dist/server.d.ts +10 -8
  54. package/dist/server.js +459 -46
  55. package/dist/server.js.map +1 -1
  56. package/dist/storefront-cache.cjs +2 -0
  57. package/dist/storefront-cache.cjs.map +1 -1
  58. package/dist/storefront-cache.js +2 -0
  59. package/dist/storefront-cache.js.map +1 -1
  60. package/dist/{types-DdlhpNVv.d.ts → types-Cmnxxvuv.d.ts} +238 -21
  61. package/dist/{types-Bzgf4mTo.d.cts → types-CnkJQUez.d.cts} +238 -21
  62. package/dist/{types-DX8Z44yQ.d.ts → types-DLjSqL0P.d.ts} +2 -2
  63. package/dist/{types-CpSiyJud.d.cts → types-FyklqLAk.d.cts} +2 -2
  64. package/dist/ui/form.d.cts +1 -1
  65. package/dist/ui/form.d.ts +1 -1
  66. package/dist/ui/video.d.cts +1 -1
  67. package/dist/ui/video.d.ts +1 -1
  68. package/dist/webhook.d.cts +5 -5
  69. package/dist/webhook.d.ts +5 -5
  70. package/package.json +2 -4
package/dist/server.js CHANGED
@@ -85,6 +85,7 @@ var COMMERCE_ERROR_CODES = [
85
85
  "cart_not_active",
86
86
  "cart_locked",
87
87
  "cart_empty",
88
+ "shipping_address_required",
88
89
  "cart_market_unavailable",
89
90
  "cart_market_mismatch",
90
91
  "checkout_not_open",
@@ -101,6 +102,7 @@ var COMMERCE_ERROR_CODES = [
101
102
  "price_changed",
102
103
  "pricing_fact_in_use",
103
104
  "insufficient_stock",
105
+ "credit_insufficient",
104
106
  "reservation_conflict",
105
107
  "stock_lock_unavailable",
106
108
  "variant_not_found",
@@ -564,6 +566,8 @@ async function parseErrorBody(response) {
564
566
  try {
565
567
  const body = await response.json();
566
568
  const reason = typeof body.reason === "string" ? body.reason : typeof body.code === "string" ? body.code : void 0;
569
+ const payloadErrorReason = Array.isArray(body.errors) ? readPayloadErrorReason(body.errors) : void 0;
570
+ const payloadReasonField = payloadErrorReason !== void 0 ? { payloadErrorReason } : {};
567
571
  if (body.errors && Array.isArray(body.errors)) {
568
572
  const fieldErrors = [];
569
573
  for (const e of body.errors) {
@@ -586,6 +590,7 @@ async function parseErrorBody(response) {
586
590
  errorMessage: `HTTP ${response.status}: ${details}`,
587
591
  userMessage: details,
588
592
  reason,
593
+ ...payloadReasonField,
589
594
  body,
590
595
  errors: fieldErrors.length > 0 ? fieldErrors : body.errors
591
596
  };
@@ -596,6 +601,7 @@ async function parseErrorBody(response) {
596
601
  errorMessage: `HTTP ${response.status}: ${body.error}`,
597
602
  userMessage: body.error,
598
603
  reason,
604
+ ...payloadReasonField,
599
605
  body
600
606
  };
601
607
  }
@@ -604,14 +610,23 @@ async function parseErrorBody(response) {
604
610
  errorMessage: `HTTP ${response.status}: ${body.message}`,
605
611
  userMessage: body.message,
606
612
  reason,
613
+ ...payloadReasonField,
607
614
  body
608
615
  };
609
616
  }
610
- return { ...fallback, reason, body };
617
+ return { ...fallback, reason, ...payloadReasonField, body };
611
618
  } catch {
612
619
  return fallback;
613
620
  }
614
621
  }
622
+ function readPayloadErrorReason(errors) {
623
+ const data = errors[0]?.data;
624
+ if (!data || typeof data !== "object") return void 0;
625
+ const { reason, code } = data;
626
+ if (typeof reason === "string") return reason;
627
+ if (typeof code === "string") return code;
628
+ return void 0;
629
+ }
615
630
  function getParsedErrorSuggestion(status, parsed) {
616
631
  if (status === 403 && parsed.reason === "origin_not_allowed") {
617
632
  return "Add the request origin to the tenant Browser API origins, then retry the browser request.";
@@ -657,7 +672,10 @@ function mapResponseToError(status, parsed, details, requestId, retryAfter, cano
657
672
  if (retryAfter !== void 0) {
658
673
  Object.assign(withRequestId, { retryAfter });
659
674
  }
660
- return canonicalCommerceError ? enhanceCommerceError(withRequestId, parsed.body, requestId) : enhanceNonCommerceError(withRequestId, parsed.reason);
675
+ return canonicalCommerceError ? enhanceCommerceError(withRequestId, parsed.body, requestId) : enhanceNonCommerceError(
676
+ withRequestId,
677
+ parsed.reason ?? parsed.payloadErrorReason
678
+ );
661
679
  };
662
680
  if (status === 400 || status === 422) {
663
681
  return finalize(
@@ -1076,6 +1094,7 @@ async function parseApiResponse(response, endpoint, options = {}) {
1076
1094
  // ../../internal/http-contracts/src/index.ts
1077
1095
  var operationBrand = /* @__PURE__ */ Symbol("sdk-http-operation");
1078
1096
  var PORTONE_STANDARD_ACTION_CAPABILITIES_MEDIA_TYPE = "application/vnd.01software.portone-action-capabilities.v1+json";
1097
+ var CUSTOMER_CREDIT_FUNDING_MEDIA_TYPE = "application/vnd.01software.credit-funding.v1+json";
1079
1098
  var operation = (collection, method, path, errorFamily) => Object.freeze({
1080
1099
  [operationBrand]: true,
1081
1100
  collection,
@@ -1239,6 +1258,11 @@ var portOneStandardActionCapabilityOperations = /* @__PURE__ */ new Set([
1239
1258
  ]);
1240
1259
  var MEMBERSHIP_ENDPOINT_OPERATIONS = {
1241
1260
  subscribe: operation(null, "post", "/memberships/subscribe"),
1261
+ endSubscribeIntent: operation(
1262
+ null,
1263
+ "post",
1264
+ "/memberships/subscribe-intent/end"
1265
+ ),
1242
1266
  billingCustody: operation(null, "post", "/memberships/billing-custody"),
1243
1267
  cancel: operation(null, "post", "/memberships/:id/cancel"),
1244
1268
  me: operation(null, "get", "/memberships/me"),
@@ -1284,6 +1308,19 @@ var BENEFIT_VOUCHER_ENDPOINT_OPERATIONS = {
1284
1308
  void: operation("customers", "post", "/benefit-vouchers/void"),
1285
1309
  listMine: operation("customers", "get", "/me/benefit-vouchers")
1286
1310
  };
1311
+ var CUSTOMER_CREDIT_ENDPOINT_OPERATIONS = {
1312
+ grant: strictCommerceOperation("customers", "post", "/credits/grant"),
1313
+ getGrant: strictCommerceOperation("customers", "post", "/credits/get-grant"),
1314
+ getAccount: strictCommerceOperation("customers", "post", "/credits/account"),
1315
+ revoke: strictCommerceOperation("customers", "post", "/credits/revoke"),
1316
+ mine: strictCommerceOperation("customers", "get", "/me/credits"),
1317
+ history: strictCommerceOperation("customers", "get", "/me/credits/history"),
1318
+ configure: strictCommerceOperation(
1319
+ "customers",
1320
+ "post",
1321
+ "/credits/configuration"
1322
+ )
1323
+ };
1287
1324
  var CUSTOMER_GROUP_ENDPOINT_OPERATIONS = {
1288
1325
  members: operation("customer-groups", "get", "/:id/members"),
1289
1326
  grant: operation("customer-groups", "post", "/:id/members/grant"),
@@ -1703,6 +1740,179 @@ var BenefitVouchersApi = class extends BaseApi {
1703
1740
  }
1704
1741
  };
1705
1742
 
1743
+ // src/core/api/customer-credit-types.ts
1744
+ function parseCustomerCreditAccount(value) {
1745
+ const data = object2(value, ["summary", "history"]);
1746
+ return {
1747
+ summary: parseMyCustomerCredits(data.summary),
1748
+ history: parseMyCustomerCreditHistory(data.history)
1749
+ };
1750
+ }
1751
+ function invalid() {
1752
+ throw createApiError("Invalid customer credit response", 502);
1753
+ }
1754
+ function object2(value, keys) {
1755
+ if (!value || typeof value !== "object" || Array.isArray(value) || Object.keys(value).length !== keys.length || keys.some((key) => !Object.prototype.hasOwnProperty.call(value, key)))
1756
+ invalid();
1757
+ return value;
1758
+ }
1759
+ function money(value) {
1760
+ return typeof value === "string" && /^(0|[1-9][0-9]*)$/.test(value);
1761
+ }
1762
+ function uuid2(value) {
1763
+ return typeof value === "string" && /^([0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i.test(
1764
+ value
1765
+ );
1766
+ }
1767
+ function time2(value) {
1768
+ if (typeof value !== "string") return false;
1769
+ const match = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d+)?Z$/.exec(value);
1770
+ if (!match) return false;
1771
+ const [, year, month, day, hour, minute, second = "0"] = match;
1772
+ const y = Number(year), m = Number(month), d = Number(day);
1773
+ const days = [
1774
+ 31,
1775
+ y % 4 === 0 && (y % 100 !== 0 || y % 400 === 0) ? 29 : 28,
1776
+ 31,
1777
+ 30,
1778
+ 31,
1779
+ 30,
1780
+ 31,
1781
+ 31,
1782
+ 30,
1783
+ 31,
1784
+ 30,
1785
+ 31
1786
+ ];
1787
+ return m >= 1 && m <= 12 && d >= 1 && d <= days[m - 1] && Number(hour) < 24 && Number(minute) < 60 && Number(second) < 60;
1788
+ }
1789
+ var states = ["available", "held", "spent", "expired", "revoked"];
1790
+ function balances(value) {
1791
+ const data = object2(value, states);
1792
+ if (states.some((key) => !money(data[key]))) invalid();
1793
+ }
1794
+ function page(value) {
1795
+ if (value.currency !== "KRW" || !time2(value.evaluatedAt) || !Number.isSafeInteger(value.page) || value.page < 1 || typeof value.hasNextPage !== "boolean")
1796
+ invalid();
1797
+ }
1798
+ function parseCustomerCreditGrant(value) {
1799
+ const data = object2(value, [
1800
+ "id",
1801
+ "customerId",
1802
+ "templateId",
1803
+ "templateVersion",
1804
+ "mode",
1805
+ "maximum",
1806
+ "amount",
1807
+ "currency",
1808
+ "validityDays",
1809
+ "grantedAt",
1810
+ "expiresAt",
1811
+ "sourceNamespace",
1812
+ "sourceRef"
1813
+ ]);
1814
+ if (!uuid2(data.id) || !uuid2(data.customerId) || !uuid2(data.templateId) || !Number.isSafeInteger(data.templateVersion) || data.templateVersion < 1 || !["fixed", "bounded"].includes(data.mode) || !money(data.maximum) || !money(data.amount) || data.currency !== "KRW" || !Number.isInteger(data.validityDays) || data.validityDays < 1 || data.validityDays > 1825 || !time2(data.grantedAt) || !time2(data.expiresAt) || typeof data.sourceNamespace !== "string" || !/^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,127}$/.test(data.sourceNamespace) || typeof data.sourceRef !== "string" || !data.sourceRef.length || data.sourceRef.length > 256 || // eslint-disable-next-line no-control-regex -- The public source identity explicitly forbids ASCII control characters.
1815
+ /[\u0000-\u001f\u007f]/.test(data.sourceRef))
1816
+ invalid();
1817
+ return value;
1818
+ }
1819
+ function parseRevokeCustomerCredit(value) {
1820
+ const data = object2(value, ["revoked", "pending", "spent"]);
1821
+ if (!money(data.revoked) || !money(data.pending) || !money(data.spent))
1822
+ invalid();
1823
+ return value;
1824
+ }
1825
+ function parseMyCustomerCredits(value) {
1826
+ const data = object2(value, [
1827
+ "currency",
1828
+ "evaluatedAt",
1829
+ "granted",
1830
+ "balances",
1831
+ "buckets",
1832
+ "page",
1833
+ "hasNextPage"
1834
+ ]);
1835
+ page(data);
1836
+ balances(data.balances);
1837
+ if (!money(data.granted) || !Array.isArray(data.buckets) || data.buckets.length > 50)
1838
+ invalid();
1839
+ for (const value2 of data.buckets) {
1840
+ const bucket = object2(value2, [
1841
+ "id",
1842
+ "grantId",
1843
+ "kind",
1844
+ "grantedAt",
1845
+ "expiresAt",
1846
+ "isRevoked",
1847
+ "balances"
1848
+ ]);
1849
+ if (!uuid2(bucket.id) || !uuid2(bucket.grantId) || !["original", "grace"].includes(bucket.kind) || !time2(bucket.grantedAt) || !time2(bucket.expiresAt) || typeof bucket.isRevoked !== "boolean")
1850
+ invalid();
1851
+ balances(bucket.balances);
1852
+ }
1853
+ return value;
1854
+ }
1855
+ function parseMyCustomerCreditHistory(value) {
1856
+ const data = object2(value, [
1857
+ "currency",
1858
+ "evaluatedAt",
1859
+ "entries",
1860
+ "page",
1861
+ "hasNextPage"
1862
+ ]);
1863
+ page(data);
1864
+ if (!Array.isArray(data.entries) || data.entries.length > 50) invalid();
1865
+ for (const value2 of data.entries) {
1866
+ const entry = object2(value2, [
1867
+ "id",
1868
+ "grantId",
1869
+ "kind",
1870
+ "amount",
1871
+ "fromState",
1872
+ "toState",
1873
+ "createdAt"
1874
+ ]);
1875
+ if (!uuid2(entry.id) || !uuid2(entry.grantId) || !money(entry.amount) || !time2(entry.createdAt) || ![
1876
+ "grant",
1877
+ "reserve",
1878
+ "consume",
1879
+ "release",
1880
+ "restore",
1881
+ "expire",
1882
+ "revoke"
1883
+ ].includes(entry.kind) || entry.fromState !== null && !states.includes(entry.fromState) || entry.toState !== null && !states.includes(entry.toState))
1884
+ invalid();
1885
+ }
1886
+ return value;
1887
+ }
1888
+
1889
+ // src/core/api/credits-api.ts
1890
+ var CreditsApi = class extends BaseApi {
1891
+ constructor(options) {
1892
+ super("CreditsApi", options);
1893
+ }
1894
+ async grant(input) {
1895
+ return parseCustomerCreditGrant(
1896
+ await this.requestEndpoint(CUSTOMER_CREDIT_ENDPOINT_OPERATIONS.grant, input)
1897
+ );
1898
+ }
1899
+ async getGrant(input) {
1900
+ return parseCustomerCreditGrant(
1901
+ await this.requestEndpoint(CUSTOMER_CREDIT_ENDPOINT_OPERATIONS.getGrant, input)
1902
+ );
1903
+ }
1904
+ async getAccount(input) {
1905
+ return parseCustomerCreditAccount(
1906
+ await this.requestEndpoint(CUSTOMER_CREDIT_ENDPOINT_OPERATIONS.getAccount, input)
1907
+ );
1908
+ }
1909
+ async revoke(input) {
1910
+ return parseRevokeCustomerCredit(
1911
+ await this.requestEndpoint(CUSTOMER_CREDIT_ENDPOINT_OPERATIONS.revoke, input)
1912
+ );
1913
+ }
1914
+ };
1915
+
1706
1916
  // src/core/collection/http-client.ts
1707
1917
  import { stringify } from "qs-esm";
1708
1918
  function validateWhere(where) {
@@ -1954,6 +2164,9 @@ function resolveMetaImage(ref) {
1954
2164
  }
1955
2165
 
1956
2166
  // src/core/collection/query-builder.ts
2167
+ function toWriteOptions(options) {
2168
+ return options?.locale === void 0 ? void 0 : { locale: options.locale };
2169
+ }
1957
2170
  var CollectionQueryBuilder = class {
1958
2171
  constructor(api, collection) {
1959
2172
  this.api = api;
@@ -1984,36 +2197,50 @@ var CollectionQueryBuilder = class {
1984
2197
  /**
1985
2198
  * Create a new document
1986
2199
  * POST /api/{collection}
2200
+ * Pass `locale` to write localized fields in a tenant-enabled locale.
1987
2201
  * @returns Payload CMS mutation response with doc and message
1988
2202
  */
1989
2203
  async create(data, options) {
1990
2204
  const endpoint = `/api/${String(this.collection)}`;
2205
+ const writeOptions = toWriteOptions(options);
1991
2206
  if (options?.file) {
1992
2207
  return this.api.requestCreateWithFile(
1993
2208
  endpoint,
1994
2209
  data,
1995
2210
  options.file,
1996
- options.filename
2211
+ options.filename,
2212
+ writeOptions
1997
2213
  );
1998
2214
  }
1999
- return this.api.requestCreate(endpoint, data);
2215
+ return this.api.requestCreate(
2216
+ endpoint,
2217
+ data,
2218
+ writeOptions
2219
+ );
2000
2220
  }
2001
2221
  /**
2002
2222
  * Update a document by ID
2003
2223
  * PATCH /api/{collection}/{id}
2224
+ * Pass `locale` to write localized fields in a tenant-enabled locale.
2004
2225
  * @returns Payload CMS mutation response with doc and message
2005
2226
  */
2006
2227
  async update(id, data, options) {
2007
2228
  const endpoint = `/api/${String(this.collection)}/${String(id)}`;
2229
+ const writeOptions = toWriteOptions(options);
2008
2230
  if (options?.file) {
2009
2231
  return this.api.requestUpdateWithFile(
2010
2232
  endpoint,
2011
2233
  data,
2012
2234
  options.file,
2013
- options.filename
2235
+ options.filename,
2236
+ writeOptions
2014
2237
  );
2015
2238
  }
2016
- return this.api.requestUpdate(endpoint, data);
2239
+ return this.api.requestUpdate(
2240
+ endpoint,
2241
+ data,
2242
+ writeOptions
2243
+ );
2017
2244
  }
2018
2245
  /**
2019
2246
  * Count documents
@@ -2057,10 +2284,11 @@ var CollectionQueryBuilder = class {
2057
2284
  * PATCH /api/{collection}
2058
2285
  * @returns Payload CMS find response with updated docs
2059
2286
  */
2060
- async updateMany(where, data) {
2287
+ async updateMany(where, data, options) {
2061
2288
  return this.api.requestUpdateMany(
2062
2289
  `/api/${String(this.collection)}`,
2063
- { where, data }
2290
+ { where, data },
2291
+ toWriteOptions(options)
2064
2292
  );
2065
2293
  }
2066
2294
  /**
@@ -2155,8 +2383,9 @@ var CollectionClient = class extends HttpClient {
2155
2383
  * Create document
2156
2384
  * POST /api/{collection}
2157
2385
  */
2158
- async requestCreate(endpoint, data) {
2159
- const response = await this.fetchWithTracking(endpoint, {
2386
+ async requestCreate(endpoint, data, options) {
2387
+ const url = this.buildUrl(endpoint, options);
2388
+ const response = await this.fetchWithTracking(url, {
2160
2389
  ...this.defaultOptions,
2161
2390
  method: "POST",
2162
2391
  body: data ? JSON.stringify(data) : void 0
@@ -2167,8 +2396,9 @@ var CollectionClient = class extends HttpClient {
2167
2396
  * Update document
2168
2397
  * PATCH /api/{collection}/{id}
2169
2398
  */
2170
- async requestUpdate(endpoint, data) {
2171
- const response = await this.fetchWithTracking(endpoint, {
2399
+ async requestUpdate(endpoint, data, options) {
2400
+ const url = this.buildUrl(endpoint, options);
2401
+ const response = await this.fetchWithTracking(url, {
2172
2402
  ...this.defaultOptions,
2173
2403
  method: "PATCH",
2174
2404
  body: data ? JSON.stringify(data) : void 0
@@ -2191,8 +2421,8 @@ var CollectionClient = class extends HttpClient {
2191
2421
  * Update multiple documents (bulk update)
2192
2422
  * PATCH /api/{collection}
2193
2423
  */
2194
- async requestUpdateMany(endpoint, data) {
2195
- const url = this.buildUrl(endpoint, { where: data.where });
2424
+ async requestUpdateMany(endpoint, data, options) {
2425
+ const url = this.buildUrl(endpoint, { where: data.where, ...options });
2196
2426
  const response = await this.fetchWithTracking(url, {
2197
2427
  ...this.defaultOptions,
2198
2428
  method: "PATCH",
@@ -2228,8 +2458,9 @@ var CollectionClient = class extends HttpClient {
2228
2458
  * Create document with file upload
2229
2459
  * POST /api/{collection} (multipart/form-data)
2230
2460
  */
2231
- async requestCreateWithFile(endpoint, data, file, filename) {
2232
- const response = await this.fetchWithTracking(endpoint, {
2461
+ async requestCreateWithFile(endpoint, data, file, filename, options) {
2462
+ const url = this.buildUrl(endpoint, options);
2463
+ const response = await this.fetchWithTracking(url, {
2233
2464
  ...this.defaultOptions,
2234
2465
  method: "POST",
2235
2466
  body: buildPayloadFormData(data, file, filename)
@@ -2240,8 +2471,9 @@ var CollectionClient = class extends HttpClient {
2240
2471
  * Update document with file upload
2241
2472
  * PATCH /api/{collection}/{id} (multipart/form-data)
2242
2473
  */
2243
- async requestUpdateWithFile(endpoint, data, file, filename) {
2244
- const response = await this.fetchWithTracking(endpoint, {
2474
+ async requestUpdateWithFile(endpoint, data, file, filename, options) {
2475
+ const url = this.buildUrl(endpoint, options);
2476
+ const response = await this.fetchWithTracking(url, {
2245
2477
  ...this.defaultOptions,
2246
2478
  method: "PATCH",
2247
2479
  body: buildPayloadFormData(data, file, filename)
@@ -2497,11 +2729,11 @@ var CommunityClient = class extends RawCustomerScopedApi {
2497
2729
  * - `rootComment`: comments belonging to a thread rooted at that comment.
2498
2730
  */
2499
2731
  listComments(params) {
2500
- const { postId, page, limit, rootComment, topLevelOnly, sort } = params;
2732
+ const { postId, page: page2, limit, rootComment, topLevelOnly, sort } = params;
2501
2733
  return this.execute(
2502
2734
  this.buildCommentsListQuery({
2503
2735
  postId,
2504
- page,
2736
+ page: page2,
2505
2737
  limit,
2506
2738
  rootComment,
2507
2739
  topLevelOnly,
@@ -2512,11 +2744,11 @@ var CommunityClient = class extends RawCustomerScopedApi {
2512
2744
  }
2513
2745
  /** Direct replies to a comment (`where[parent][equals]`). */
2514
2746
  listReplies(params) {
2515
- const { commentId, page, limit, sort } = params;
2747
+ const { commentId, page: page2, limit, sort } = params;
2516
2748
  return this.execute(
2517
2749
  this.buildCommentsListQuery({
2518
2750
  parentId: commentId,
2519
- page,
2751
+ page: page2,
2520
2752
  limit,
2521
2753
  sort
2522
2754
  }),
@@ -2700,7 +2932,18 @@ var ABANDONED_REASONS = ["expired", "customer", "operator"];
2700
2932
  function managedPaymentProviders(providers) {
2701
2933
  return providers;
2702
2934
  }
2703
- var PAYMENT_PROVIDERS = managedPaymentProviders(["toss", "portone"]);
2935
+ var PAYMENT_PROVIDERS = managedPaymentProviders([
2936
+ "toss",
2937
+ "portone",
2938
+ "stripe"
2939
+ ]);
2940
+ var CANCEL_RECOVERY_METHODS = {
2941
+ toss: "cancel()",
2942
+ portone: "cancelPortOne()",
2943
+ stripe: null
2944
+ };
2945
+ var STRIPE_RETURN_URL_RAW_CHARACTERS = /^[^\s\u0000-\u001F\u007F\\]+$/;
2946
+ var STRIPE_RETURN_URL_AUTHORITY = /^[A-Za-z][A-Za-z0-9+.-]*:\/\/[^/?#@]+(?:[/?#]|$)/;
2704
2947
  var PAYMENT_PROVIDER_STATUSES = [
2705
2948
  "requires_payment_method",
2706
2949
  "requires_action",
@@ -2761,11 +3004,8 @@ function fail(resource, path, expected) {
2761
3004
  invalidCanonicalResponse(resource, { path, expected });
2762
3005
  }
2763
3006
  function providerMismatch(resource, expected, actual, operation2) {
2764
- if (operation2 === "cancel") {
2765
- const method = {
2766
- toss: "cancel()",
2767
- portone: "cancelPortOne()"
2768
- }[actual];
3007
+ const method = CANCEL_RECOVERY_METHODS[actual];
3008
+ if (operation2 === "cancel" && method !== null) {
2769
3009
  throw createApiError(
2770
3010
  `Canonical ${resource} response provider mismatch: expected ${expected}, received ${actual}.`,
2771
3011
  502,
@@ -2794,6 +3034,17 @@ function exact(value, required, optional, resource, path) {
2794
3034
  const unexpected = Object.keys(value).find((key) => !allowed.has(key));
2795
3035
  if (unexpected) fail(resource, `${path}.${unexpected}`, "no unknown fields");
2796
3036
  }
3037
+ function responseExtensionKeys(value, keys, resource, path) {
3038
+ if (!keys.some((key) => Object.prototype.hasOwnProperty.call(value, key)))
3039
+ return [];
3040
+ enumValue(
3041
+ value.deliveryMethod,
3042
+ ["shipping", "pickup"],
3043
+ resource,
3044
+ `${path}.deliveryMethod`
3045
+ );
3046
+ return [...keys];
3047
+ }
2797
3048
  function string(value, resource, path) {
2798
3049
  if (typeof value !== "string" || value.length === 0) {
2799
3050
  fail(resource, path, "non-empty string");
@@ -3148,6 +3399,12 @@ function validatePublicCart(value, resource = "Cart") {
3148
3399
  exact(
3149
3400
  cart,
3150
3401
  [
3402
+ ...responseExtensionKeys(
3403
+ cart,
3404
+ ["deliveryMethod", "shippingMinor", "totalMinor"],
3405
+ resource,
3406
+ "$"
3407
+ ),
3151
3408
  "id",
3152
3409
  "status",
3153
3410
  "revision",
@@ -3218,6 +3475,13 @@ function validatePublicCart(value, resource = "Cart") {
3218
3475
  if (expectedSubtotal - BigInt(discount) < 0n || BigInt(estimatedTotal) !== expectedSubtotal - BigInt(discount)) {
3219
3476
  fail(resource, "$.estimatedTotalMinor", "subtotalMinor - discountMinor");
3220
3477
  }
3478
+ if ("deliveryMethod" in cart) {
3479
+ const shipping = safeMinor(cart.shippingMinor, resource, "$.shippingMinor");
3480
+ const total = safeMinor(cart.totalMinor, resource, "$.totalMinor");
3481
+ if (BigInt(total) !== BigInt(estimatedTotal) + BigInt(shipping)) {
3482
+ fail(resource, "$.totalMinor", "estimatedTotalMinor + shippingMinor");
3483
+ }
3484
+ }
3221
3485
  timestamp(cart.expiresAt, resource, "$.expiresAt");
3222
3486
  timestamp(cart.createdAt, resource, "$.createdAt");
3223
3487
  timestamp(cart.updatedAt, resource, "$.updatedAt");
@@ -3461,6 +3725,17 @@ function validateCheckoutCore(value, resource, list, server) {
3461
3725
  "$.status"
3462
3726
  );
3463
3727
  const keys = checkoutVariantKeys(status, checkout.placedVia);
3728
+ keys.required.push(
3729
+ ...responseExtensionKeys(
3730
+ checkout,
3731
+ ["deliveryMethod", "source"],
3732
+ resource,
3733
+ "$"
3734
+ )
3735
+ );
3736
+ if ("deliveryMethod" in checkout)
3737
+ enumValue(checkout.source, ["web", "in_person"], resource, "$.source");
3738
+ keys.optional.push("funding");
3464
3739
  if (list) {
3465
3740
  keys.required = keys.required.filter(
3466
3741
  (key) => !["items", "shippingAddress", "attributes"].includes(key)
@@ -3472,6 +3747,33 @@ function validateCheckoutCore(value, resource, list, server) {
3472
3747
  exact(checkout, keys.required, keys.optional, resource, "$");
3473
3748
  string(checkout.id, resource, "$.id");
3474
3749
  validateCheckoutAmounts(checkout.amounts, resource, "$.amounts");
3750
+ if (Object.prototype.hasOwnProperty.call(checkout, "funding")) {
3751
+ const funding = record(checkout.funding, resource, "$.funding");
3752
+ exact(
3753
+ funding,
3754
+ ["creditAmount", "providerPayableAmount"],
3755
+ [],
3756
+ resource,
3757
+ "$.funding"
3758
+ );
3759
+ const credit = safeMinor(
3760
+ funding.creditAmount,
3761
+ resource,
3762
+ "$.funding.creditAmount"
3763
+ );
3764
+ const provider = safeMinor(
3765
+ funding.providerPayableAmount,
3766
+ resource,
3767
+ "$.funding.providerPayableAmount"
3768
+ );
3769
+ const amounts = checkout.amounts;
3770
+ if (BigInt(credit) + BigInt(provider) !== BigInt(amounts.totalMinor) || credit > 0 && amounts.currency !== "KRW")
3771
+ fail(
3772
+ resource,
3773
+ "$.funding",
3774
+ "exact purchase total split; positive credits require KRW"
3775
+ );
3776
+ }
3475
3777
  if (!list) {
3476
3778
  const items = array(checkout.items, resource, "$.items");
3477
3779
  if (items.length === 0) fail(resource, "$.items", "non-empty array");
@@ -3630,10 +3932,10 @@ function validateCheckoutQueryResult(value) {
3630
3932
  return value;
3631
3933
  }
3632
3934
  function validateMoney(value, resource, path) {
3633
- const money = record(value, resource, path);
3634
- exact(money, ["amountMinor", "currency"], [], resource, path);
3635
- safeMinor(money.amountMinor, resource, `${path}.amountMinor`);
3636
- currency(money.currency, resource, `${path}.currency`);
3935
+ const money2 = record(value, resource, path);
3936
+ exact(money2, ["amountMinor", "currency"], [], resource, path);
3937
+ safeMinor(money2.amountMinor, resource, `${path}.amountMinor`);
3938
+ currency(money2.currency, resource, `${path}.currency`);
3637
3939
  }
3638
3940
  function validateCustomPaymentSession(value) {
3639
3941
  const resource = "custom PaymentSession";
@@ -3894,6 +4196,65 @@ function validateRequiredReconciliation(value, allowed, resource, path) {
3894
4196
  }
3895
4197
  function validateNextAction(value, provider, resource, path) {
3896
4198
  const action = record(value, resource, path);
4199
+ if (provider === "stripe") {
4200
+ exact(
4201
+ action,
4202
+ ["type", "clientSecret", "publishableKey", "returnUrl"],
4203
+ [],
4204
+ resource,
4205
+ path
4206
+ );
4207
+ if (action.type !== "stripe_payment_element")
4208
+ fail(resource, `${path}.type`, "stripe_payment_element");
4209
+ const clientSecret = boundedString(
4210
+ action.clientSecret,
4211
+ 255,
4212
+ resource,
4213
+ `${path}.clientSecret`
4214
+ );
4215
+ if (!/^pi_[A-Za-z0-9]+_secret_[A-Za-z0-9]+$/.test(clientSecret)) {
4216
+ fail(
4217
+ resource,
4218
+ `${path}.clientSecret`,
4219
+ "Stripe PaymentIntent client secret"
4220
+ );
4221
+ }
4222
+ const publishableKey = boundedString(
4223
+ action.publishableKey,
4224
+ 255,
4225
+ resource,
4226
+ `${path}.publishableKey`
4227
+ );
4228
+ if (!/^pk_(?:test|live)_[A-Za-z0-9]+$/.test(publishableKey)) {
4229
+ fail(resource, `${path}.publishableKey`, "Stripe publishable key");
4230
+ }
4231
+ const returnUrl = boundedString(
4232
+ action.returnUrl,
4233
+ 2048,
4234
+ resource,
4235
+ `${path}.returnUrl`
4236
+ );
4237
+ if (!STRIPE_RETURN_URL_RAW_CHARACTERS.test(returnUrl) || !STRIPE_RETURN_URL_AUTHORITY.test(returnUrl)) {
4238
+ fail(
4239
+ resource,
4240
+ `${path}.returnUrl`,
4241
+ "HTTPS or loopback URL without embedded credentials"
4242
+ );
4243
+ }
4244
+ try {
4245
+ const parsed = new URL(returnUrl);
4246
+ const loopback = parsed.protocol === "http:" && (parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1");
4247
+ if (!loopback && parsed.protocol !== "https:" || parsed.username || parsed.password)
4248
+ throw new Error("unsafe return URL");
4249
+ } catch {
4250
+ fail(
4251
+ resource,
4252
+ `${path}.returnUrl`,
4253
+ "HTTPS or loopback URL without embedded credentials"
4254
+ );
4255
+ }
4256
+ return;
4257
+ }
3897
4258
  if (provider === "portone") {
3898
4259
  if (action.type === "portone_sdk") {
3899
4260
  const hasCancelable = "cancelable" in action;
@@ -4269,7 +4630,7 @@ function validatePublicPaymentSession(value, expectedProvider, operation2) {
4269
4630
  );
4270
4631
  }
4271
4632
  if (expectedProvider !== void 0 && provider !== expectedProvider) {
4272
- if (operation2 === "cancel" && status !== "canceling" && status !== "canceled") {
4633
+ if (operation2 === "cancel" && CANCEL_RECOVERY_METHODS[provider] !== null && status !== "canceling" && status !== "canceled") {
4273
4634
  fail(
4274
4635
  resource,
4275
4636
  "$.providerStatus",
@@ -5810,8 +6171,9 @@ var CheckoutApi = class extends CustomerScopedApi {
5810
6171
  }
5811
6172
  post(endpoint, body, idempotencyKey) {
5812
6173
  return this.requestEndpoint(endpoint, body, {
5813
- ...idempotencyKey && {
5814
- headers: { "X-Idempotency-Key": idempotencyKey }
6174
+ headers: {
6175
+ Accept: CUSTOMER_CREDIT_FUNDING_MEDIA_TYPE,
6176
+ ...idempotencyKey && { "X-Idempotency-Key": idempotencyKey }
5815
6177
  }
5816
6178
  });
5817
6179
  }
@@ -5821,34 +6183,58 @@ var CheckoutApi = class extends CustomerScopedApi {
5821
6183
  async serverCheckout(result) {
5822
6184
  return validateServerCheckout(await result);
5823
6185
  }
5824
- async createResult(result) {
5825
- return validateCreateCheckoutResult(
6186
+ async createResult(result, creditAmount) {
6187
+ const parsed = validateCreateCheckoutResult(
5826
6188
  await result,
5827
6189
  false
5828
6190
  );
6191
+ this.assertRequestedCredit(parsed.checkout, creditAmount);
6192
+ return parsed;
5829
6193
  }
5830
- async createServerResult(result) {
5831
- return validateCreateCheckoutResult(
6194
+ async createServerResult(result, creditAmount) {
6195
+ const parsed = validateCreateCheckoutResult(
5832
6196
  await result,
5833
6197
  true
5834
6198
  );
6199
+ this.assertRequestedCredit(parsed.checkout, creditAmount);
6200
+ return parsed;
6201
+ }
6202
+ assertCreditInput(amount) {
6203
+ if (amount !== void 0 && (!Number.isSafeInteger(amount) || amount <= 0))
6204
+ throw createValidationError(
6205
+ "creditAmount must be a positive safe integer."
6206
+ );
6207
+ }
6208
+ assertRequestedCredit(checkout, requested) {
6209
+ if (requested !== void 0 && checkout.funding?.creditAmount !== requested)
6210
+ throw createApiError(
6211
+ "Credit funding was not confirmed by the server.",
6212
+ 502,
6213
+ { resource: "Checkout", path: "$.funding" },
6214
+ "The response does not confirm the requested credit funding.",
6215
+ "Retry the same create with the original idempotency key and credit amount, or retrieve the Checkout; never retry without credit."
6216
+ );
5835
6217
  }
5836
6218
  create(params) {
5837
6219
  const { idempotencyKey, ...body } = params;
5838
6220
  assertCommerceIdempotencyKey(idempotencyKey);
6221
+ this.assertCreditInput(body.creditAmount);
5839
6222
  return this.createResult(
5840
- this.post(COMMERCE_ENDPOINTS.checkouts.create, body, idempotencyKey)
6223
+ this.post(COMMERCE_ENDPOINTS.checkouts.create, body, idempotencyKey),
6224
+ body.creditAmount
5841
6225
  );
5842
6226
  }
5843
6227
  createServer(params) {
5844
6228
  const { idempotencyKey, ...body } = params;
5845
6229
  assertCommerceIdempotencyKey(idempotencyKey);
6230
+ this.assertCreditInput(body.creditAmount);
5846
6231
  return this.createServerResult(
5847
6232
  this.post(
5848
6233
  COMMERCE_ENDPOINTS.checkouts.server.create,
5849
6234
  body,
5850
6235
  idempotencyKey
5851
- )
6236
+ ),
6237
+ body.creditAmount
5852
6238
  );
5853
6239
  }
5854
6240
  retrieve(params) {
@@ -6495,7 +6881,16 @@ var MembershipApi = class extends BaseApi {
6495
6881
  * to activate the membership.
6496
6882
  *
6497
6883
  * `subscribeIntentKey` is used as the HTTP idempotency key so the call is
6498
- * safely retryable.
6884
+ * safely retryable. Trials are once per tenant/customer/plan; a prior recipient
6885
+ * gets the paid prepare response (409 conflict without writes if the delegated
6886
+ * connection is unavailable). Catalog trialDays is not customer eligibility.
6887
+ * Display firstCharge amount/currency/periodStart and obtain explicit customer
6888
+ * consent before PSP execution; refusal must never dispatch payment.
6889
+ * Completed trial replays keep their result. Existing payload/live duplicate
6890
+ * checks run first (another live Membership is 409 duplicate_subscription).
6891
+ * If an unfinished trial replay passes those checks after another intent
6892
+ * received the trial, it returns 409 idempotency_conflict without writes;
6893
+ * its original snapshot is never rewritten into a paid intent.
6499
6894
  */
6500
6895
  subscribe(params) {
6501
6896
  const { subscribeIntentKey, ...body } = params;
@@ -6505,6 +6900,21 @@ var MembershipApi = class extends BaseApi {
6505
6900
  idempotencyRequestOptions(subscribeIntentKey)
6506
6901
  );
6507
6902
  }
6903
+ /**
6904
+ * End an unprepared or terminal intent without changing membership evidence.
6905
+ * Use an opaque random, non-personal key of 1–512 visible ASCII characters;
6906
+ * other keys are rejected because headers and JSON can encode them differently.
6907
+ */
6908
+ async endSubscribeIntent(params) {
6909
+ const result = await this.requestEndpoint(
6910
+ MEMBERSHIP_ENDPOINT_OPERATIONS.endSubscribeIntent,
6911
+ params
6912
+ );
6913
+ if (!result || typeof result !== "object" || Array.isArray(result) || Object.keys(result).length !== 1 || !("status" in result) || result.status !== "ended" && result.status !== "existing") {
6914
+ throw new Error("Invalid membership intent termination response");
6915
+ }
6916
+ return { status: result.status };
6917
+ }
6508
6918
  /**
6509
6919
  * Cancel a membership by id.
6510
6920
  * By default this sets `cancelAtPeriodEnd`, keeps benefits until
@@ -6602,7 +7012,7 @@ function getExternalEffectClaimErrorReason(error) {
6602
7012
  const reason = getSDKErrorReason(error);
6603
7013
  return errorReasons.has(reason) ? reason : void 0;
6604
7014
  }
6605
- var states = /* @__PURE__ */ new Set([
7015
+ var states2 = /* @__PURE__ */ new Set([
6606
7016
  "pre_dispatch_claimed",
6607
7017
  "armed_unknown",
6608
7018
  "reported_effect",
@@ -6627,7 +7037,7 @@ function claimFromResponse(value) {
6627
7037
  const claim = value.claim;
6628
7038
  if (!claim || typeof claim !== "object") invalidResponse();
6629
7039
  const row = claim;
6630
- if (typeof row.id !== "string" || !states.has(row.state) || row.armedAt !== null && typeof row.armedAt !== "string" || row.firstReportOutcome !== null && row.firstReportOutcome !== "effect" && row.firstReportOutcome !== "no_effect" || row.reportAuthority !== "tenant_supplied_unverified" || typeof row.leaseGranted !== "boolean" || row.leaseToken !== null && typeof row.leaseToken !== "string" || !Number.isSafeInteger(row.leaseGeneration) || row.leaseGranted && row.leaseToken === null || !row.leaseGranted && row.leaseToken !== null)
7040
+ if (typeof row.id !== "string" || !states2.has(row.state) || row.armedAt !== null && typeof row.armedAt !== "string" || row.firstReportOutcome !== null && row.firstReportOutcome !== "effect" && row.firstReportOutcome !== "no_effect" || row.reportAuthority !== "tenant_supplied_unverified" || typeof row.leaseGranted !== "boolean" || row.leaseToken !== null && typeof row.leaseToken !== "string" || !Number.isSafeInteger(row.leaseGeneration) || row.leaseGranted && row.leaseToken === null || !row.leaseGranted && row.leaseToken !== null)
6631
7041
  invalidResponse();
6632
7042
  return {
6633
7043
  id: row.id,
@@ -6750,8 +7160,8 @@ var InstallationCredentialsApi = class extends BaseApi {
6750
7160
  function invalidResponse3() {
6751
7161
  throw createApiError("Invalid external-customer link response", 200);
6752
7162
  }
6753
- var uuid2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
6754
- var isUuid = (value) => typeof value === "string" && (uuid2.test(value) || value === "00000000-0000-0000-0000-000000000000" || value.toLowerCase() === "ffffffff-ffff-ffff-ffff-ffffffffffff");
7163
+ var uuid3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
7164
+ var isUuid = (value) => typeof value === "string" && (uuid3.test(value) || value === "00000000-0000-0000-0000-000000000000" || value.toLowerCase() === "ffffffff-ffff-ffff-ffff-ffffffffffff");
6755
7165
  var isIdentity = (value) => typeof value === "string" && value.length > 0 && value.length <= 256 && value === value.trim() && // eslint-disable-next-line no-control-regex -- Normalized identity forbids C0 controls.
6756
7166
  !/[\u0000-\u001f]/.test(value) && !/[\uD800-\uDFFF]/u.test(value);
6757
7167
  var isDateTime = (value) => {
@@ -6892,6 +7302,7 @@ var ServerClient = class _ServerClient {
6892
7302
  const membershipApi = new MembershipApi(serverOptions);
6893
7303
  this.memberships = {
6894
7304
  subscribe: membershipApi.subscribe.bind(membershipApi),
7305
+ endSubscribeIntent: membershipApi.endSubscribeIntent.bind(membershipApi),
6895
7306
  cancel: membershipApi.cancel.bind(membershipApi),
6896
7307
  billingCustody: membershipApi.billingCustody.bind(membershipApi)
6897
7308
  };
@@ -6899,6 +7310,7 @@ var ServerClient = class _ServerClient {
6899
7310
  this.externalEffectClaims = new ExternalEffectClaimsApi(serverOptions);
6900
7311
  this.installationCredentials = new InstallationCredentialsApi(serverOptions);
6901
7312
  this.benefitVouchers = new BenefitVouchersApi(serverOptions);
7313
+ this.credits = new CreditsApi(serverOptions);
6902
7314
  this.externalCustomerLinks = new ExternalCustomerLinksApi(serverOptions);
6903
7315
  const tenantIntrospectionApi = new TenantIntrospectionApi(serverOptions);
6904
7316
  this.tenant = {
@@ -6976,6 +7388,7 @@ export {
6976
7388
  BenefitVouchersApi,
6977
7389
  CollectionClient,
6978
7390
  CommunityClient,
7391
+ CreditsApi,
6979
7392
  CustomerGroupApi,
6980
7393
  EventsClient,
6981
7394
  ExternalCustomerLinksApi,