@01.software/sdk 0.48.0 → 0.49.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.
- package/CHANGELOG.md +27 -0
- package/README.md +64 -7
- package/dist/client.cjs +189 -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 +189 -26
- package/dist/client.js.map +1 -1
- package/dist/{collection-client-D3ExJU-7.d.ts → collection-client-DnDt6EQz.d.ts} +4 -4
- package/dist/{collection-client-CBup9yOx.d.cts → collection-client-XfGLPuTf.d.cts} +4 -4
- package/dist/{const-BXEi1Kix.d.cts → const-CBba4lDo.d.cts} +1 -1
- package/dist/{const-k9gHylYa.d.ts → const-DCNV5Kq7.d.ts} +1 -1
- package/dist/errors.cjs +63 -15
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.cts +10 -1
- package/dist/errors.d.ts +10 -1
- package/dist/errors.js +63 -15
- package/dist/errors.js.map +1 -1
- package/dist/{index-BCM9CTL7.d.cts → index-CbKyoEzy.d.cts} +3 -3
- package/dist/{index-CHGGkcLj.d.ts → index-DUuIqUS8.d.ts} +3 -3
- package/dist/index.cjs +152 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -8
- package/dist/index.d.ts +8 -8
- package/dist/index.js +152 -48
- package/dist/index.js.map +1 -1
- package/dist/{payload-types-B6AZQcB7.d.cts → payload-types-MKbx5MuJ.d.cts} +133 -3
- package/dist/{payload-types-B6AZQcB7.d.ts → payload-types-MKbx5MuJ.d.ts} +133 -3
- package/dist/query.cjs +21 -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 +21 -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 +189 -26
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +8 -7
- package/dist/server.d.ts +8 -7
- package/dist/server.js +189 -26
- package/dist/server.js.map +1 -1
- package/dist/storefront-cache.cjs +21 -0
- package/dist/storefront-cache.cjs.map +1 -1
- package/dist/storefront-cache.js +21 -0
- package/dist/storefront-cache.js.map +1 -1
- package/dist/{types-DbA5V3mt.d.ts → types-1UeOk1Uy.d.cts} +31 -6
- package/dist/{types-8us-_C-Q.d.cts → types-BKr_2avj.d.cts} +2 -2
- package/dist/{types-CM2je9Kw.d.cts → types-Du4s5anw.d.ts} +31 -6
- package/dist/{types-ByD2zii1.d.ts → types-L_nh-ED7.d.ts} +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 +4 -4
- package/dist/webhook.d.ts +4 -4
- package/package.json +5 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# @01.software/sdk
|
|
2
2
|
|
|
3
|
+
## 0.49.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- aef44ec: Fix SDK error guards across independently bundled entrypoints and expose the guards from the client and server entries.
|
|
8
|
+
- 86f74d3: Expose immutable membership subscribe-admission snapshot fields in the generated SDK types.
|
|
9
|
+
- edc790e: BREAKING (0.x minor): Checkout `paymentState.activePaymentSession.provider` can
|
|
10
|
+
now be `portone`. Consumers using `@01.software/sdk` 0.45.0, 0.46.0, or 0.46.1
|
|
11
|
+
must upgrade to the 0.49.0 release produced by this minor changeset, or later,
|
|
12
|
+
before the server exposes managed PortOne sessions; otherwise
|
|
13
|
+
`checkouts.retrieve` and `checkouts.query` throw during strict response
|
|
14
|
+
validation. SDK 0.48.0's runtime decoder already accepts `portone`, but its
|
|
15
|
+
published TypeScript `CheckoutPaymentSessionRef` remains `provider: 'toss'`, so
|
|
16
|
+
0.48.0 is not the fully compatible public-contract floor. `checkouts.create` is
|
|
17
|
+
not part of this break because the current producer does not return an active
|
|
18
|
+
PortOne session reference.
|
|
19
|
+
|
|
20
|
+
Keep custom bridge recovery on the server-only exact lookup.
|
|
21
|
+
|
|
22
|
+
- fa71a21: Add a fail-closed PortOne Standard V2 Toss Payments CARD browser action with a required redirect, PG-safe payment identity, and durable single-slot retry semantics.
|
|
23
|
+
- 5ea6348: Expose non-commerce API reasons through `SDKError.apiReason` and the family-aware `getSDKErrorReason` accessor while preserving strict commerce error typing.
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- cb2a742: Clarify that idempotent commerce mutation response fields do not provide exactly-once side-effect semantics.
|
|
28
|
+
- 15c1024: Synchronize generated Payload types for the internal payment-kernel result and owner-commit records without exposing those collections through a public SDK collection bucket.
|
|
29
|
+
|
|
3
30
|
## 0.48.0
|
|
4
31
|
|
|
5
32
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ pnpm add @01.software/sdk
|
|
|
29
29
|
import { createClient } from '@01.software/sdk'
|
|
30
30
|
|
|
31
31
|
// Server-only entry - keep Secret Key code out of browser-facing imports
|
|
32
|
-
import { createServerClient } from '@01.software/sdk/server'
|
|
32
|
+
import { createServerClient, isCommerceSDKError } from '@01.software/sdk/server'
|
|
33
33
|
|
|
34
34
|
// Webhook only - webhook handlers
|
|
35
35
|
import {
|
|
@@ -61,8 +61,8 @@ entry.
|
|
|
61
61
|
| Import | Feature(s) | Install when used |
|
|
62
62
|
| ----------------------------------- | ------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- |
|
|
63
63
|
| `@01.software/sdk` | browser-safe `createClient`, commerce helpers, collection helpers, types | none |
|
|
64
|
-
| `@01.software/sdk/client` | browser-safe `createClient` entry
|
|
65
|
-
| `@01.software/sdk/server` | `createServerClient`, server-only
|
|
64
|
+
| `@01.software/sdk/client` | browser-safe `createClient` entry and SDK error guards | none |
|
|
65
|
+
| `@01.software/sdk/server` | `createServerClient`, server-only APIs, and SDK error guards | none; keep `secretKey` code on the server |
|
|
66
66
|
| `@01.software/sdk/errors` | SDK error classes and guards | none |
|
|
67
67
|
| `@01.software/sdk/analytics` | browser analytics client and typed event helpers | none |
|
|
68
68
|
| `@01.software/sdk/metadata` | SEO metadata extraction and generation helpers | none |
|
|
@@ -92,6 +92,9 @@ Migration quick reference:
|
|
|
92
92
|
- `createClient` remains available from `@01.software/sdk` and
|
|
93
93
|
`@01.software/sdk/client`.
|
|
94
94
|
- `createServerClient` must be imported from `@01.software/sdk/server`.
|
|
95
|
+
- Error guards are available from the same `@01.software/sdk/client` or
|
|
96
|
+
`@01.software/sdk/server` entry as the client that throws; the root and
|
|
97
|
+
`@01.software/sdk/errors` guards also classify errors across entries.
|
|
95
98
|
- React Query hooks and cache helpers must be imported from
|
|
96
99
|
`@01.software/sdk/query`.
|
|
97
100
|
- Product storefront cache resource helpers must be imported from
|
|
@@ -1325,10 +1328,8 @@ Treat a replayed Cart result as an operation receipt: never replace a newer
|
|
|
1325
1328
|
cached Cart with a lower `revision`; retrieve when response ordering is unclear.
|
|
1326
1329
|
|
|
1327
1330
|
```typescript
|
|
1328
|
-
import {
|
|
1329
|
-
|
|
1330
|
-
isCommerceSDKError,
|
|
1331
|
-
} from '@01.software/sdk'
|
|
1331
|
+
import { createCommerceIdempotencyKey } from '@01.software/sdk'
|
|
1332
|
+
import { isCommerceSDKError } from '@01.software/sdk/errors'
|
|
1332
1333
|
|
|
1333
1334
|
const checkoutIdempotencyKey = createCommerceIdempotencyKey()
|
|
1334
1335
|
const { checkout, checkoutToken } = await client.commerce.checkouts.create({
|
|
@@ -1369,6 +1370,24 @@ if (
|
|
|
1369
1370
|
window.location.assign(portOneSession.nextAction.checkoutUrl)
|
|
1370
1371
|
}
|
|
1371
1372
|
|
|
1373
|
+
// Standard V2 is a distinct Browser SDK capability, not a Hosted fallback.
|
|
1374
|
+
// Do not treat the SDK result or mobile redirect as payment finality.
|
|
1375
|
+
const standardPortOneSession =
|
|
1376
|
+
await client.commerce.paymentSessions.createPortOne({
|
|
1377
|
+
checkoutToken,
|
|
1378
|
+
provider: 'portone',
|
|
1379
|
+
providerOptions: { profile: 'standard_v2', paymentMethod: 'CARD' },
|
|
1380
|
+
idempotencyKey: createCommerceIdempotencyKey(),
|
|
1381
|
+
})
|
|
1382
|
+
if (
|
|
1383
|
+
standardPortOneSession.presentationStatus === 'actionable' &&
|
|
1384
|
+
standardPortOneSession.nextAction.type === 'portone_sdk'
|
|
1385
|
+
) {
|
|
1386
|
+
// PortOne V2 requires its currency constant (`CURRENCY_KRW`), not ISO `KRW`.
|
|
1387
|
+
// await PortOne.requestPayment(standardPortOneSession.nextAction)
|
|
1388
|
+
// Always retrieve the session afterwards; Console lookup/webhook is authoritative.
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1372
1391
|
// Browser recovery requires the parent capability.
|
|
1373
1392
|
await client.commerce.paymentSessions.retrieve({
|
|
1374
1393
|
paymentSessionId: paymentSession.id,
|
|
@@ -1424,6 +1443,12 @@ authoritative API response or signed webhook, then report the exact captured
|
|
|
1424
1443
|
identity and Money. The create response is intentionally limited to
|
|
1425
1444
|
`{ id, provider, providerSessionId, money }`.
|
|
1426
1445
|
|
|
1446
|
+
Custom bridge sessions intentionally remain `null` in
|
|
1447
|
+
`checkout.paymentState.activePaymentSession`: Checkout exposes only managed
|
|
1448
|
+
adapters from its closed provider vocabulary. Persist the `providerSessionId`
|
|
1449
|
+
returned by `custom.create` and use `custom.retrieve` with that identity as the
|
|
1450
|
+
supported custom-lane settlement recovery path.
|
|
1451
|
+
|
|
1427
1452
|
```typescript
|
|
1428
1453
|
const customSession = await server.commerce.paymentSessions.custom.create({
|
|
1429
1454
|
provider: 'my-provider',
|
|
@@ -1491,6 +1516,38 @@ Canonical commerce error envelopes become `CommerceSDKError`. Branch on its
|
|
|
1491
1516
|
stable `reason`, inspect `retryable`, and log `requestId`; a newer server reason
|
|
1492
1517
|
is preserved as `reason: 'unknown_commerce_error'` plus `rawReason`.
|
|
1493
1518
|
|
|
1519
|
+
Non-commerce endpoints preserve their open-ended machine reason separately as
|
|
1520
|
+
`SDKError.apiReason`. Use `getSDKErrorReason(error)` when shared error handling
|
|
1521
|
+
must read either family: it returns the canonical commerce reason, the verbatim
|
|
1522
|
+
unknown commerce `rawReason`, or the non-commerce `apiReason`. Existing
|
|
1523
|
+
`details` payloads remain available for compatibility, but consumers no longer
|
|
1524
|
+
need to normalize `details.reason` and `details.body.reason` themselves.
|
|
1525
|
+
|
|
1526
|
+
#### Idempotent mutation results are not exactly-once receipts
|
|
1527
|
+
|
|
1528
|
+
No commerce mutation response field is a safe exactly-once gate for a
|
|
1529
|
+
non-idempotent side effect such as an operational alert, outbound webhook, or
|
|
1530
|
+
ledger entry. Use a consumer-owned durable claim keyed by the side effect's
|
|
1531
|
+
stable logical identity. The public webhook guide's
|
|
1532
|
+
[`processOnce`](https://docs.01.software/developers/webhooks) pattern uses a
|
|
1533
|
+
database unique key, queue idempotency store, or provider-safe send ledger.
|
|
1534
|
+
|
|
1535
|
+
`custom.confirm` returns `alreadyConfirmed: true` when the session was already
|
|
1536
|
+
confirmed at observation time. It does not attribute the transition to the
|
|
1537
|
+
current call. The field is absent from the initial successful confirmation, so
|
|
1538
|
+
code that only interprets the response shape must test
|
|
1539
|
+
`'alreadyConfirmed' in result`, not `result.alreadyConfirmed === false`. That
|
|
1540
|
+
presence check is still not a side-effect gate: when the initial commit succeeds
|
|
1541
|
+
but its response is lost, a retry returns `alreadyConfirmed: true` and would
|
|
1542
|
+
otherwise silently miss the transition.
|
|
1543
|
+
|
|
1544
|
+
Likewise, the `orders.cancelOrder` fields `cancelCommitted` and
|
|
1545
|
+
`alreadyCanceled` are domain effect dispositions, not transport replay markers.
|
|
1546
|
+
A same-key retry replays the cached initial 2xx body byte-for-byte and can
|
|
1547
|
+
therefore return the original `cancelCommitted: true` again. Neither field says
|
|
1548
|
+
whether the response was replayed or whether an external side effect has already
|
|
1549
|
+
run.
|
|
1550
|
+
|
|
1494
1551
|
### Commerce Orders (post-placement operations)
|
|
1495
1552
|
|
|
1496
1553
|
Provider-paid `orders.create`, `orders.confirmPayment`, and ordinary
|
package/dist/client.cjs
CHANGED
|
@@ -22,7 +22,22 @@ var client_exports = {};
|
|
|
22
22
|
__export(client_exports, {
|
|
23
23
|
Client: () => Client,
|
|
24
24
|
ContentClient: () => ContentClient,
|
|
25
|
-
createClient: () => createClient
|
|
25
|
+
createClient: () => createClient,
|
|
26
|
+
isApiError: () => isApiError,
|
|
27
|
+
isAuthError: () => isAuthError,
|
|
28
|
+
isCommerceSDKError: () => isCommerceSDKError,
|
|
29
|
+
isConfigError: () => isConfigError,
|
|
30
|
+
isConflictError: () => isConflictError,
|
|
31
|
+
isGoneError: () => isGoneError,
|
|
32
|
+
isNetworkError: () => isNetworkError,
|
|
33
|
+
isNotFoundError: () => isNotFoundError,
|
|
34
|
+
isPermissionError: () => isPermissionError,
|
|
35
|
+
isRateLimitError: () => isRateLimitError,
|
|
36
|
+
isSDKError: () => isSDKError,
|
|
37
|
+
isServiceUnavailableError: () => isServiceUnavailableError,
|
|
38
|
+
isTimeoutError: () => isTimeoutError,
|
|
39
|
+
isUsageLimitError: () => isUsageLimitError,
|
|
40
|
+
isValidationError: () => isValidationError
|
|
26
41
|
});
|
|
27
42
|
module.exports = __toCommonJS(client_exports);
|
|
28
43
|
|
|
@@ -30,6 +45,24 @@ module.exports = __toCommonJS(client_exports);
|
|
|
30
45
|
var import_qs_esm = require("qs-esm");
|
|
31
46
|
|
|
32
47
|
// src/core/errors.ts
|
|
48
|
+
var SDK_ERROR_BRAND = /* @__PURE__ */ Symbol.for("@01.software/sdk/SDKError");
|
|
49
|
+
var SDK_ERROR_TYPE_BRAND = /* @__PURE__ */ Symbol.for("@01.software/sdk/SDKError.type");
|
|
50
|
+
function defineSDKErrorBrand(error) {
|
|
51
|
+
Object.defineProperty(error, SDK_ERROR_BRAND, {
|
|
52
|
+
value: true,
|
|
53
|
+
enumerable: false,
|
|
54
|
+
configurable: false,
|
|
55
|
+
writable: false
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
function defineSDKErrorType(error, type) {
|
|
59
|
+
Object.defineProperty(error, SDK_ERROR_TYPE_BRAND, {
|
|
60
|
+
value: type,
|
|
61
|
+
enumerable: false,
|
|
62
|
+
configurable: false,
|
|
63
|
+
writable: false
|
|
64
|
+
});
|
|
65
|
+
}
|
|
33
66
|
var SDKError = class extends Error {
|
|
34
67
|
constructor(code, message, status, details, userMessage, suggestion, requestId) {
|
|
35
68
|
super(message);
|
|
@@ -40,6 +73,7 @@ var SDKError = class extends Error {
|
|
|
40
73
|
this.userMessage = userMessage;
|
|
41
74
|
this.suggestion = suggestion;
|
|
42
75
|
this.requestId = requestId;
|
|
76
|
+
defineSDKErrorBrand(this);
|
|
43
77
|
if (Error.captureStackTrace) {
|
|
44
78
|
Error.captureStackTrace(this, new.target);
|
|
45
79
|
}
|
|
@@ -60,6 +94,7 @@ var SDKError = class extends Error {
|
|
|
60
94
|
...this.kind !== void 0 && { kind: this.kind },
|
|
61
95
|
...this.reason !== void 0 && { reason: this.reason },
|
|
62
96
|
...this.rawReason !== void 0 && { rawReason: this.rawReason },
|
|
97
|
+
...this.apiReason !== void 0 && { apiReason: this.apiReason },
|
|
63
98
|
...this.retryable !== void 0 && { retryable: this.retryable },
|
|
64
99
|
...this.retryAfter !== void 0 && { retryAfter: this.retryAfter }
|
|
65
100
|
};
|
|
@@ -233,8 +268,16 @@ function enhanceCommerceError(error, body, headerRequestId) {
|
|
|
233
268
|
});
|
|
234
269
|
return error;
|
|
235
270
|
}
|
|
271
|
+
function enhanceNonCommerceError(error, reason) {
|
|
272
|
+
if (typeof reason === "string") Object.assign(error, { apiReason: reason });
|
|
273
|
+
return error;
|
|
274
|
+
}
|
|
275
|
+
function getSDKErrorReason(error) {
|
|
276
|
+
if (error.kind !== "commerce") return error.apiReason;
|
|
277
|
+
return error.reason === "unknown_commerce_error" ? error.rawReason : error.reason;
|
|
278
|
+
}
|
|
236
279
|
function isCommerceSDKError(error) {
|
|
237
|
-
if (!(error
|
|
280
|
+
if (!isSDKError(error) || error.kind !== "commerce") return false;
|
|
238
281
|
if (typeof error.requestId !== "string" || typeof error.retryable !== "boolean" || error.retryAfter !== void 0 && (!Number.isSafeInteger(error.retryAfter) || error.retryAfter < 0) || typeof error.reason !== "string") {
|
|
239
282
|
return false;
|
|
240
283
|
}
|
|
@@ -244,12 +287,14 @@ var NetworkError = class extends SDKError {
|
|
|
244
287
|
constructor(message, status, details, userMessage, suggestion) {
|
|
245
288
|
super("NETWORK_ERROR", message, status, details, userMessage, suggestion);
|
|
246
289
|
this.name = "NetworkError";
|
|
290
|
+
defineSDKErrorType(this, "NetworkError");
|
|
247
291
|
}
|
|
248
292
|
};
|
|
249
293
|
var ValidationError = class extends SDKError {
|
|
250
294
|
constructor(message, details, userMessage, suggestion, status = 400) {
|
|
251
295
|
super("VALIDATION_ERROR", message, status, details, userMessage, suggestion);
|
|
252
296
|
this.name = "ValidationError";
|
|
297
|
+
defineSDKErrorType(this, "ValidationError");
|
|
253
298
|
}
|
|
254
299
|
};
|
|
255
300
|
var ApiError = class extends SDKError {
|
|
@@ -264,24 +309,28 @@ var ApiError = class extends SDKError {
|
|
|
264
309
|
requestId
|
|
265
310
|
);
|
|
266
311
|
this.name = "ApiError";
|
|
312
|
+
defineSDKErrorType(this, "ApiError");
|
|
267
313
|
}
|
|
268
314
|
};
|
|
269
315
|
var ConfigError = class extends SDKError {
|
|
270
316
|
constructor(message, details, userMessage, suggestion) {
|
|
271
317
|
super("CONFIG_ERROR", message, void 0, details, userMessage, suggestion);
|
|
272
318
|
this.name = "ConfigError";
|
|
319
|
+
defineSDKErrorType(this, "ConfigError");
|
|
273
320
|
}
|
|
274
321
|
};
|
|
275
322
|
var TimeoutError = class extends SDKError {
|
|
276
323
|
constructor(message = "Request timed out.", details, userMessage, suggestion) {
|
|
277
324
|
super("TIMEOUT_ERROR", message, 408, details, userMessage, suggestion);
|
|
278
325
|
this.name = "TimeoutError";
|
|
326
|
+
defineSDKErrorType(this, "TimeoutError");
|
|
279
327
|
}
|
|
280
328
|
};
|
|
281
329
|
var GoneError = class extends SDKError {
|
|
282
330
|
constructor(message = "The requested resource is no longer available.", details, userMessage, suggestion) {
|
|
283
331
|
super("GONE_ERROR", message, 410, details, userMessage, suggestion);
|
|
284
332
|
this.name = "GoneError";
|
|
333
|
+
defineSDKErrorType(this, "GoneError");
|
|
285
334
|
}
|
|
286
335
|
};
|
|
287
336
|
var ServiceUnavailableError = class extends SDKError {
|
|
@@ -296,6 +345,7 @@ var ServiceUnavailableError = class extends SDKError {
|
|
|
296
345
|
);
|
|
297
346
|
this.name = "ServiceUnavailableError";
|
|
298
347
|
this.retryAfter = retryAfter;
|
|
348
|
+
defineSDKErrorType(this, "ServiceUnavailableError");
|
|
299
349
|
}
|
|
300
350
|
};
|
|
301
351
|
var UsageLimitError = class extends SDKError {
|
|
@@ -303,6 +353,7 @@ var UsageLimitError = class extends SDKError {
|
|
|
303
353
|
super("USAGE_LIMIT_ERROR", message, 429, details, userMessage, suggestion);
|
|
304
354
|
this.name = "UsageLimitError";
|
|
305
355
|
this.usage = usage;
|
|
356
|
+
defineSDKErrorType(this, "UsageLimitError");
|
|
306
357
|
}
|
|
307
358
|
toJSON() {
|
|
308
359
|
return {
|
|
@@ -323,6 +374,7 @@ var AuthError = class extends SDKError {
|
|
|
323
374
|
requestId
|
|
324
375
|
);
|
|
325
376
|
this.name = "AuthError";
|
|
377
|
+
defineSDKErrorType(this, "AuthError");
|
|
326
378
|
}
|
|
327
379
|
};
|
|
328
380
|
var PermissionError = class extends SDKError {
|
|
@@ -337,6 +389,7 @@ var PermissionError = class extends SDKError {
|
|
|
337
389
|
requestId
|
|
338
390
|
);
|
|
339
391
|
this.name = "PermissionError";
|
|
392
|
+
defineSDKErrorType(this, "PermissionError");
|
|
340
393
|
}
|
|
341
394
|
};
|
|
342
395
|
var NotFoundError = class extends SDKError {
|
|
@@ -351,12 +404,14 @@ var NotFoundError = class extends SDKError {
|
|
|
351
404
|
requestId
|
|
352
405
|
);
|
|
353
406
|
this.name = "NotFoundError";
|
|
407
|
+
defineSDKErrorType(this, "NotFoundError");
|
|
354
408
|
}
|
|
355
409
|
};
|
|
356
410
|
var ConflictError = class extends SDKError {
|
|
357
411
|
constructor(message, details, userMessage, suggestion, requestId) {
|
|
358
412
|
super("conflict", message, 409, details, userMessage, suggestion, requestId);
|
|
359
413
|
this.name = "ConflictError";
|
|
414
|
+
defineSDKErrorType(this, "ConflictError");
|
|
360
415
|
}
|
|
361
416
|
};
|
|
362
417
|
var RateLimitError = class extends SDKError {
|
|
@@ -372,8 +427,64 @@ var RateLimitError = class extends SDKError {
|
|
|
372
427
|
);
|
|
373
428
|
this.name = "RateLimitError";
|
|
374
429
|
this.retryAfter = retryAfter;
|
|
430
|
+
defineSDKErrorType(this, "RateLimitError");
|
|
375
431
|
}
|
|
376
432
|
};
|
|
433
|
+
function hasBrandedSDKErrorShape(error) {
|
|
434
|
+
if (error === null || typeof error !== "object") return false;
|
|
435
|
+
const candidate = error;
|
|
436
|
+
return candidate[SDK_ERROR_BRAND] === true && typeof candidate.name === "string" && typeof candidate.code === "string" && typeof candidate.message === "string" && (candidate.status === void 0 || typeof candidate.status === "number") && (candidate.userMessage === void 0 || typeof candidate.userMessage === "string") && (candidate.suggestion === void 0 || typeof candidate.suggestion === "string") && (candidate.requestId === void 0 || typeof candidate.requestId === "string") && (candidate.kind === void 0 || candidate.kind === "commerce") && (candidate.reason === void 0 || typeof candidate.reason === "string") && (candidate.rawReason === void 0 || typeof candidate.rawReason === "string") && (candidate.apiReason === void 0 || typeof candidate.apiReason === "string") && (candidate.retryable === void 0 || typeof candidate.retryable === "boolean") && (candidate.retryAfter === void 0 || typeof candidate.retryAfter === "number") && typeof candidate.getUserMessage === "function" && typeof candidate.toJSON === "function";
|
|
437
|
+
}
|
|
438
|
+
function hasSDKErrorType(error, type) {
|
|
439
|
+
return hasBrandedSDKErrorShape(error) && error[SDK_ERROR_TYPE_BRAND] === type;
|
|
440
|
+
}
|
|
441
|
+
function isSDKError(error) {
|
|
442
|
+
return error instanceof SDKError || hasBrandedSDKErrorShape(error);
|
|
443
|
+
}
|
|
444
|
+
function isNetworkError(error) {
|
|
445
|
+
return error instanceof NetworkError || hasSDKErrorType(error, "NetworkError");
|
|
446
|
+
}
|
|
447
|
+
function isValidationError(error) {
|
|
448
|
+
if (error instanceof ValidationError || hasSDKErrorType(error, "ValidationError")) {
|
|
449
|
+
return true;
|
|
450
|
+
}
|
|
451
|
+
if (error == null || typeof error !== "object") return false;
|
|
452
|
+
const candidate = error;
|
|
453
|
+
return candidate.name === "ValidationError" && candidate.code === "VALIDATION_ERROR" && typeof candidate.message === "string" && typeof candidate.getUserMessage === "function" && typeof candidate.toJSON === "function";
|
|
454
|
+
}
|
|
455
|
+
function isApiError(error) {
|
|
456
|
+
return error instanceof ApiError || hasSDKErrorType(error, "ApiError");
|
|
457
|
+
}
|
|
458
|
+
function isConfigError(error) {
|
|
459
|
+
return error instanceof ConfigError || hasSDKErrorType(error, "ConfigError");
|
|
460
|
+
}
|
|
461
|
+
function isTimeoutError(error) {
|
|
462
|
+
return error instanceof TimeoutError || hasSDKErrorType(error, "TimeoutError");
|
|
463
|
+
}
|
|
464
|
+
function isGoneError(error) {
|
|
465
|
+
return error instanceof GoneError || hasSDKErrorType(error, "GoneError");
|
|
466
|
+
}
|
|
467
|
+
function isServiceUnavailableError(error) {
|
|
468
|
+
return error instanceof ServiceUnavailableError || hasSDKErrorType(error, "ServiceUnavailableError");
|
|
469
|
+
}
|
|
470
|
+
function isUsageLimitError(error) {
|
|
471
|
+
return error instanceof UsageLimitError || hasSDKErrorType(error, "UsageLimitError");
|
|
472
|
+
}
|
|
473
|
+
function isAuthError(error) {
|
|
474
|
+
return error instanceof AuthError || hasSDKErrorType(error, "AuthError");
|
|
475
|
+
}
|
|
476
|
+
function isPermissionError(error) {
|
|
477
|
+
return error instanceof PermissionError || hasSDKErrorType(error, "PermissionError");
|
|
478
|
+
}
|
|
479
|
+
function isNotFoundError(error) {
|
|
480
|
+
return error instanceof NotFoundError || hasSDKErrorType(error, "NotFoundError");
|
|
481
|
+
}
|
|
482
|
+
function isConflictError(error) {
|
|
483
|
+
return error instanceof ConflictError || hasSDKErrorType(error, "ConflictError");
|
|
484
|
+
}
|
|
485
|
+
function isRateLimitError(error) {
|
|
486
|
+
return error instanceof RateLimitError || hasSDKErrorType(error, "RateLimitError");
|
|
487
|
+
}
|
|
377
488
|
var createNetworkError = (message, status, details, userMessage, suggestion) => new NetworkError(message, status, details, userMessage, suggestion);
|
|
378
489
|
var createValidationError = (message, details, userMessage, suggestion, status) => new ValidationError(message, details, userMessage, suggestion, status);
|
|
379
490
|
var createApiError = (message, status, details, userMessage, suggestion, requestId) => new ApiError(message, status, details, userMessage, suggestion, requestId);
|
|
@@ -583,7 +694,7 @@ function mapResponseToError(status, parsed, details, requestId, retryAfter, erro
|
|
|
583
694
|
if (retryAfter !== void 0) {
|
|
584
695
|
Object.assign(withRequestId, { retryAfter });
|
|
585
696
|
}
|
|
586
|
-
return errorFamily === "commerce" ? enhanceCommerceError(withRequestId, parsed.body, requestId) : withRequestId;
|
|
697
|
+
return errorFamily === "commerce" ? enhanceCommerceError(withRequestId, parsed.body, requestId) : enhanceNonCommerceError(withRequestId, parsed.reason);
|
|
587
698
|
};
|
|
588
699
|
if (status === 400 || status === 422) {
|
|
589
700
|
return finalize(
|
|
@@ -770,7 +881,7 @@ async function httpFetch(url, options) {
|
|
|
770
881
|
),
|
|
771
882
|
requestId
|
|
772
883
|
);
|
|
773
|
-
throw errorFamily === "commerce" ? enhanceCommerceError(usageError, parsed.body, requestId) : usageError;
|
|
884
|
+
throw errorFamily === "commerce" ? enhanceCommerceError(usageError, parsed.body, requestId) : enhanceNonCommerceError(usageError, parsed.reason);
|
|
774
885
|
}
|
|
775
886
|
if (response.status === 401 && onUnauthorized && customerToken && !hasRetried401 && (commerceEnvelope?.reason ?? parsed.reason) === "token_expired") {
|
|
776
887
|
hasRetried401 = true;
|
|
@@ -1217,7 +1328,7 @@ async function parseApiResponse(response, endpoint2, options = {}) {
|
|
|
1217
1328
|
}
|
|
1218
1329
|
const withRequestId = attachRequestId(error, requestId);
|
|
1219
1330
|
if (retryAfter !== void 0) Object.assign(withRequestId, { retryAfter });
|
|
1220
|
-
throw options.errorFamily === "commerce" ? enhanceCommerceError(withRequestId, data, requestId) : withRequestId;
|
|
1331
|
+
throw options.errorFamily === "commerce" ? enhanceCommerceError(withRequestId, data, requestId) : enhanceNonCommerceError(withRequestId, reason);
|
|
1221
1332
|
}
|
|
1222
1333
|
return data;
|
|
1223
1334
|
}
|
|
@@ -1641,13 +1752,7 @@ function unwrapPayloadDoc(value) {
|
|
|
1641
1752
|
return value;
|
|
1642
1753
|
}
|
|
1643
1754
|
function hasCanonicalNotFoundReason(error) {
|
|
1644
|
-
|
|
1645
|
-
if (typeof details !== "object" || details === null) return false;
|
|
1646
|
-
if ("reason" in details && details.reason === "not_found") return true;
|
|
1647
|
-
if (!("body" in details) || typeof details.body !== "object" || details.body === null) {
|
|
1648
|
-
return false;
|
|
1649
|
-
}
|
|
1650
|
-
return "reason" in details.body && details.body.reason === "not_found";
|
|
1755
|
+
return getSDKErrorReason(error) === "not_found";
|
|
1651
1756
|
}
|
|
1652
1757
|
var CommunityClient = class extends RawCustomerScopedApi {
|
|
1653
1758
|
constructor(options) {
|
|
@@ -3253,9 +3358,77 @@ function validateRequiredReconciliation(value, allowed, resource, path) {
|
|
|
3253
3358
|
function validateNextAction(value, provider, resource, path) {
|
|
3254
3359
|
const action = record(value, resource, path);
|
|
3255
3360
|
if (provider === "portone") {
|
|
3361
|
+
if (action.type === "portone_sdk") {
|
|
3362
|
+
exact(
|
|
3363
|
+
action,
|
|
3364
|
+
[
|
|
3365
|
+
"type",
|
|
3366
|
+
"version",
|
|
3367
|
+
"storeId",
|
|
3368
|
+
"channelKey",
|
|
3369
|
+
"paymentId",
|
|
3370
|
+
"orderName",
|
|
3371
|
+
"totalAmount",
|
|
3372
|
+
"currency",
|
|
3373
|
+
"payMethod",
|
|
3374
|
+
"redirectUrl"
|
|
3375
|
+
],
|
|
3376
|
+
[],
|
|
3377
|
+
resource,
|
|
3378
|
+
path
|
|
3379
|
+
);
|
|
3380
|
+
if (action.version !== "v2") fail(resource, `${path}.version`, "v2");
|
|
3381
|
+
for (const key of ["storeId", "channelKey"]) {
|
|
3382
|
+
boundedString(action[key], 255, resource, `${path}.${key}`);
|
|
3383
|
+
}
|
|
3384
|
+
const paymentId = boundedString(
|
|
3385
|
+
action.paymentId,
|
|
3386
|
+
40,
|
|
3387
|
+
resource,
|
|
3388
|
+
`${path}.paymentId`
|
|
3389
|
+
);
|
|
3390
|
+
if (!/^[A-Za-z0-9]{6,40}$/.test(paymentId)) {
|
|
3391
|
+
fail(
|
|
3392
|
+
resource,
|
|
3393
|
+
`${path}.paymentId`,
|
|
3394
|
+
"6-40 ASCII alphanumeric characters"
|
|
3395
|
+
);
|
|
3396
|
+
}
|
|
3397
|
+
boundedString(
|
|
3398
|
+
action.orderName,
|
|
3399
|
+
MAX_COMMERCE_SHORT_TEXT_LENGTH,
|
|
3400
|
+
resource,
|
|
3401
|
+
`${path}.orderName`
|
|
3402
|
+
);
|
|
3403
|
+
positiveInteger(action.totalAmount, resource, `${path}.totalAmount`);
|
|
3404
|
+
if (action.currency !== "CURRENCY_KRW") {
|
|
3405
|
+
fail(resource, `${path}.currency`, "CURRENCY_KRW");
|
|
3406
|
+
}
|
|
3407
|
+
if (action.payMethod !== "CARD")
|
|
3408
|
+
fail(resource, `${path}.payMethod`, "CARD");
|
|
3409
|
+
const redirectUrl = boundedString(
|
|
3410
|
+
action.redirectUrl,
|
|
3411
|
+
2048,
|
|
3412
|
+
resource,
|
|
3413
|
+
`${path}.redirectUrl`
|
|
3414
|
+
);
|
|
3415
|
+
try {
|
|
3416
|
+
const parsed = new URL(redirectUrl);
|
|
3417
|
+
const loopback = parsed.protocol === "http:" && (parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1");
|
|
3418
|
+
if (!loopback && parsed.protocol !== "https:" || parsed.username || parsed.password)
|
|
3419
|
+
throw new Error("unsafe redirect URL");
|
|
3420
|
+
} catch {
|
|
3421
|
+
fail(
|
|
3422
|
+
resource,
|
|
3423
|
+
`${path}.redirectUrl`,
|
|
3424
|
+
"HTTPS or loopback URL without embedded credentials"
|
|
3425
|
+
);
|
|
3426
|
+
}
|
|
3427
|
+
return;
|
|
3428
|
+
}
|
|
3256
3429
|
exact(action, ["type", "checkoutUrl"], [], resource, path);
|
|
3257
3430
|
if (action.type !== "portone_checkout") {
|
|
3258
|
-
fail(resource, `${path}.type`, "portone_checkout");
|
|
3431
|
+
fail(resource, `${path}.type`, "portone_checkout | portone_sdk");
|
|
3259
3432
|
}
|
|
3260
3433
|
const checkoutUrl = boundedString(
|
|
3261
3434
|
action.checkoutUrl,
|
|
@@ -5218,21 +5391,11 @@ var PRODUCT_DETAIL_UNAVAILABLE_REASONS = /* @__PURE__ */ new Set([
|
|
|
5218
5391
|
"not_published",
|
|
5219
5392
|
"feature_disabled"
|
|
5220
5393
|
]);
|
|
5221
|
-
function isRecord(value) {
|
|
5222
|
-
return typeof value === "object" && value !== null;
|
|
5223
|
-
}
|
|
5224
|
-
function readProductDetailUnavailableReason(value) {
|
|
5225
|
-
if (!isRecord(value)) return void 0;
|
|
5226
|
-
const directReason = value.reason ?? value.code;
|
|
5227
|
-
if (typeof directReason === "string" && PRODUCT_DETAIL_UNAVAILABLE_REASONS.has(directReason)) {
|
|
5228
|
-
return directReason;
|
|
5229
|
-
}
|
|
5230
|
-
return readProductDetailUnavailableReason(value.body);
|
|
5231
|
-
}
|
|
5232
5394
|
function productDetailResultFromError(error) {
|
|
5233
5395
|
if (!(error instanceof SDKError) || error.status !== 404) return void 0;
|
|
5234
|
-
const reason =
|
|
5235
|
-
if (!reason
|
|
5396
|
+
const reason = getSDKErrorReason(error);
|
|
5397
|
+
if (!reason || !PRODUCT_DETAIL_UNAVAILABLE_REASONS.has(reason))
|
|
5398
|
+
return void 0;
|
|
5236
5399
|
return { found: false, reason };
|
|
5237
5400
|
}
|
|
5238
5401
|
var MARKET_PRICE_QUERY_UNSUPPORTED_MESSAGE = "Market listing pages do not support base price filters or price sorts.";
|