@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.
- package/CHANGELOG.md +143 -0
- package/MIGRATION.md +28 -0
- package/README.md +253 -11
- package/dist/client.cjs +396 -26
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +7 -6
- package/dist/client.d.ts +7 -6
- package/dist/client.js +396 -26
- package/dist/client.js.map +1 -1
- package/dist/{collection-client-BHLStm1K.d.cts → collection-client-B3CnqMDQ.d.cts} +14 -18
- package/dist/{collection-client-B1FSJ24_.d.ts → collection-client-uOgS_1bC.d.ts} +14 -18
- package/dist/{const-ty8u0TDI.d.ts → const-BJBK7jBl.d.ts} +1 -1
- package/dist/{const-BfQfV-rr.d.cts → const-_ZfJjRQG.d.cts} +1 -1
- package/dist/embedded-admin/server.cjs +117 -2
- package/dist/embedded-admin/server.cjs.map +1 -1
- package/dist/embedded-admin/server.d.cts +30 -2
- package/dist/embedded-admin/server.d.ts +30 -2
- package/dist/embedded-admin/server.js +117 -2
- package/dist/embedded-admin/server.js.map +1 -1
- package/dist/embedded-admin.cjs +135 -7
- package/dist/embedded-admin.cjs.map +1 -1
- package/dist/embedded-admin.d.cts +35 -2
- package/dist/embedded-admin.d.ts +35 -2
- package/dist/embedded-admin.js +135 -7
- package/dist/embedded-admin.js.map +1 -1
- package/dist/errors.cjs +2 -0
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.cts +3 -3
- package/dist/errors.d.ts +3 -3
- package/dist/errors.js +2 -0
- package/dist/errors.js.map +1 -1
- package/dist/{index-DnKgjPGM.d.ts → index-CBaP4q8r.d.ts} +3 -3
- package/dist/{index-CX6si6YC.d.cts → index-CI_LFWiG.d.cts} +3 -3
- package/dist/index.cjs +396 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +24 -9
- package/dist/index.d.ts +24 -9
- package/dist/index.js +396 -26
- package/dist/index.js.map +1 -1
- package/dist/{payload-types-DTAaWKrp.d.cts → payload-types-BRg8Yary.d.cts} +262 -177
- package/dist/{payload-types-DTAaWKrp.d.ts → payload-types-BRg8Yary.d.ts} +262 -177
- package/dist/query.cjs +20 -0
- package/dist/query.cjs.map +1 -1
- package/dist/query.d.cts +5 -5
- package/dist/query.d.ts +5 -5
- package/dist/query.js +20 -0
- package/dist/query.js.map +1 -1
- package/dist/realtime.d.cts +2 -2
- package/dist/realtime.d.ts +2 -2
- package/dist/server.cjs +459 -46
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +10 -8
- package/dist/server.d.ts +10 -8
- package/dist/server.js +459 -46
- package/dist/server.js.map +1 -1
- package/dist/storefront-cache.cjs +2 -0
- package/dist/storefront-cache.cjs.map +1 -1
- package/dist/storefront-cache.js +2 -0
- package/dist/storefront-cache.js.map +1 -1
- package/dist/{types-DdlhpNVv.d.ts → types-Cmnxxvuv.d.ts} +238 -21
- package/dist/{types-Bzgf4mTo.d.cts → types-CnkJQUez.d.cts} +238 -21
- package/dist/{types-DX8Z44yQ.d.ts → types-DLjSqL0P.d.ts} +2 -2
- package/dist/{types-CpSiyJud.d.cts → types-FyklqLAk.d.cts} +2 -2
- package/dist/ui/form.d.cts +1 -1
- package/dist/ui/form.d.ts +1 -1
- package/dist/ui/video.d.cts +1 -1
- package/dist/ui/video.d.ts +1 -1
- package/dist/webhook.d.cts +5 -5
- package/dist/webhook.d.ts +5 -5
- 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(
|
|
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(
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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([
|
|
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
|
-
|
|
2765
|
-
|
|
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
|
|
3634
|
-
exact(
|
|
3635
|
-
safeMinor(
|
|
3636
|
-
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
|
-
|
|
5814
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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" || !
|
|
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
|
|
6754
|
-
var isUuid = (value) => typeof value === "string" && (
|
|
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,
|