@doswiftly/storefront-sdk 16.0.0 → 17.0.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 +466 -0
- package/dist/core/cart/cart-client.d.ts +10 -1
- package/dist/core/cart/cart-client.d.ts.map +1 -1
- package/dist/core/cart/cart-client.js +17 -1
- package/dist/core/cart/cart-recovery.d.ts +63 -0
- package/dist/core/cart/cart-recovery.d.ts.map +1 -1
- package/dist/core/cart/cart-recovery.js +91 -8
- package/dist/core/cart/types.d.ts +1 -1
- package/dist/core/cart/types.d.ts.map +1 -1
- package/dist/core/generated/operation-types.d.ts +198 -32
- package/dist/core/generated/operation-types.d.ts.map +1 -1
- package/dist/core/operations/cart.d.ts +7 -0
- package/dist/core/operations/cart.d.ts.map +1 -1
- package/dist/core/operations/cart.js +52 -0
- package/dist/react/components/PaymentInstrumentSection.d.ts +56 -0
- package/dist/react/components/PaymentInstrumentSection.d.ts.map +1 -0
- package/dist/react/components/PaymentInstrumentSection.js +89 -0
- package/dist/react/components/PaymentInstrumentTile.d.ts +56 -0
- package/dist/react/components/PaymentInstrumentTile.d.ts.map +1 -0
- package/dist/react/components/PaymentInstrumentTile.js +40 -0
- package/dist/react/components/index.d.ts +2 -0
- package/dist/react/components/index.d.ts.map +1 -1
- package/dist/react/components/index.js +2 -0
- package/dist/react/helpers/browser-data.d.ts +89 -0
- package/dist/react/helpers/browser-data.d.ts.map +1 -0
- package/dist/react/helpers/browser-data.js +84 -0
- package/dist/react/index.d.ts +2 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +3 -1
- package/package.json +1 -1
|
@@ -65,6 +65,53 @@ export function isCartRecoverableError(err) {
|
|
|
65
65
|
return false;
|
|
66
66
|
return err.userErrors.some((ue) => typeof ue.code === 'string' && RECOVERABLE_CODE_SET.has(ue.code));
|
|
67
67
|
}
|
|
68
|
+
// ---------------------------------------------------------------------------
|
|
69
|
+
// Session error codes — auth-recoverable, distinct from cart-resource recovery
|
|
70
|
+
// ---------------------------------------------------------------------------
|
|
71
|
+
/**
|
|
72
|
+
* Cart error codes that signal a missing or invalid auth context on a
|
|
73
|
+
* customer-owned cart — distinct from cart-resource recovery
|
|
74
|
+
* (`CART_RECOVERABLE_ERROR_CODES`).
|
|
75
|
+
*
|
|
76
|
+
* - `CART_UNAUTHENTICATED` — anonymous request OR present-but-invalid token
|
|
77
|
+
* (expired JWT, malformed). The cart resource is intact and reachable
|
|
78
|
+
* again after re-auth.
|
|
79
|
+
*
|
|
80
|
+
* Storefronts SHOULD preserve the `cart-id` cookie when handling these
|
|
81
|
+
* codes and prompt sign-in — the same cart resumes after a successful login.
|
|
82
|
+
*/
|
|
83
|
+
export const CART_SESSION_ERROR_CODES = ['CART_UNAUTHENTICATED'];
|
|
84
|
+
const SESSION_CODE_SET = new Set(CART_SESSION_ERROR_CODES);
|
|
85
|
+
/**
|
|
86
|
+
* Type-safe predicate for "this error means the session is gone, but the
|
|
87
|
+
* cart resource is intact". Distinct from `isCartRecoverableError`
|
|
88
|
+
* (cart-resource recovery) — `isCartSessionError` matches auth-recoverable
|
|
89
|
+
* codes that should trigger re-auth flow, NOT cart cookie cleanup.
|
|
90
|
+
*
|
|
91
|
+
* Inspects `err.userErrors[].code` (structured field) — never matches against
|
|
92
|
+
* `err.message` (locale-dependent, non-stable).
|
|
93
|
+
*/
|
|
94
|
+
export function isCartSessionError(err) {
|
|
95
|
+
if (!(err instanceof StorefrontError))
|
|
96
|
+
return false;
|
|
97
|
+
if (err.userErrors.length === 0)
|
|
98
|
+
return false;
|
|
99
|
+
return err.userErrors.some((ue) => typeof ue.code === 'string' && SESSION_CODE_SET.has(ue.code));
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Thrown when a cart operation fails with a session error
|
|
103
|
+
* (`CART_UNAUTHENTICATED`). Distinct from `CartRecoveryNotPossibleError`
|
|
104
|
+
* (cart-resource issue) — storefronts should redirect to a sign-in flow
|
|
105
|
+
* and retry the operation after re-auth.
|
|
106
|
+
*/
|
|
107
|
+
export class CartSessionRequiredError extends Error {
|
|
108
|
+
cause;
|
|
109
|
+
constructor(cause, message) {
|
|
110
|
+
super(message ?? 'Session required — please sign in to continue', { cause });
|
|
111
|
+
this.name = 'CartSessionRequiredError';
|
|
112
|
+
this.cause = cause;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
68
115
|
/**
|
|
69
116
|
* Thrown when an operation hits a recoverable cart error but recovery is not
|
|
70
117
|
* possible (no `recreateAndRun`, or recovery itself failed). UI should clear
|
|
@@ -109,7 +156,7 @@ async function acquireCartId(coord, factory) {
|
|
|
109
156
|
* consumers can wire this directly without the runner factory.
|
|
110
157
|
*/
|
|
111
158
|
export async function executeWithCartRecovery(opts) {
|
|
112
|
-
const { cartClient, cookieStore, operation, ensureCart, cookieMaxAge, onExpired } = opts;
|
|
159
|
+
const { cartClient, cookieStore, operation, ensureCart, cookieMaxAge, onExpired, onSessionExpired } = opts;
|
|
113
160
|
const coord = opts.recoveryCoordinator ?? createCoordinator();
|
|
114
161
|
const opName = operation.name ?? 'unknown';
|
|
115
162
|
// Phase 0 — ensure cart exists (cookie may be empty on first interaction).
|
|
@@ -126,6 +173,17 @@ export async function executeWithCartRecovery(opts) {
|
|
|
126
173
|
return await operation.run(cartId);
|
|
127
174
|
}
|
|
128
175
|
catch (err) {
|
|
176
|
+
// Session loss — cart resource intact, re-auth needed. Preserve cookie
|
|
177
|
+
// so the same cart resumes after a successful login.
|
|
178
|
+
if (isCartSessionError(err)) {
|
|
179
|
+
const sessionEvent = {
|
|
180
|
+
oldCartId: cartId,
|
|
181
|
+
operation: opName,
|
|
182
|
+
cause: err,
|
|
183
|
+
};
|
|
184
|
+
onSessionExpired?.(sessionEvent);
|
|
185
|
+
throw new CartSessionRequiredError(err);
|
|
186
|
+
}
|
|
129
187
|
if (!isCartRecoverableError(err))
|
|
130
188
|
throw err;
|
|
131
189
|
const oldCartId = cartId;
|
|
@@ -181,9 +239,20 @@ export async function executeWithCartRecovery(opts) {
|
|
|
181
239
|
export function createCartRecoveryRunner(options) {
|
|
182
240
|
const { cartClient, cookieStore, ensureCart, cookieMaxAge } = options;
|
|
183
241
|
const coordinator = createCoordinator();
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
|
|
242
|
+
const expiredListeners = new Set();
|
|
243
|
+
const sessionListeners = new Set();
|
|
244
|
+
function emitExpired(event) {
|
|
245
|
+
for (const listener of expiredListeners) {
|
|
246
|
+
try {
|
|
247
|
+
listener(event);
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
// Listeners must not break recovery flow — swallow listener exceptions.
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
function emitSessionExpired(event) {
|
|
255
|
+
for (const listener of sessionListeners) {
|
|
187
256
|
try {
|
|
188
257
|
listener(event);
|
|
189
258
|
}
|
|
@@ -203,7 +272,8 @@ export function createCartRecoveryRunner(options) {
|
|
|
203
272
|
ensureCart,
|
|
204
273
|
cookieMaxAge,
|
|
205
274
|
recoveryCoordinator: coordinator,
|
|
206
|
-
onExpired:
|
|
275
|
+
onExpired: emitExpired,
|
|
276
|
+
onSessionExpired: emitSessionExpired,
|
|
207
277
|
};
|
|
208
278
|
return executeWithCartRecovery(internalOpts);
|
|
209
279
|
},
|
|
@@ -215,9 +285,18 @@ export function createCartRecoveryRunner(options) {
|
|
|
215
285
|
return await cartClient.get(cartId);
|
|
216
286
|
}
|
|
217
287
|
catch (err) {
|
|
288
|
+
if (isCartSessionError(err)) {
|
|
289
|
+
// Cart resource intact — re-auth required. Preserve cookie.
|
|
290
|
+
emitSessionExpired({
|
|
291
|
+
oldCartId: cartId,
|
|
292
|
+
operation: 'getCart',
|
|
293
|
+
cause: err,
|
|
294
|
+
});
|
|
295
|
+
throw new CartSessionRequiredError(err);
|
|
296
|
+
}
|
|
218
297
|
if (isCartRecoverableError(err)) {
|
|
219
298
|
cookieStore.clear();
|
|
220
|
-
|
|
299
|
+
emitExpired({
|
|
221
300
|
reason: 'state-dependent',
|
|
222
301
|
oldCartId: cartId,
|
|
223
302
|
operation: 'getCart',
|
|
@@ -229,8 +308,12 @@ export function createCartRecoveryRunner(options) {
|
|
|
229
308
|
}
|
|
230
309
|
},
|
|
231
310
|
onExpired(listener) {
|
|
232
|
-
|
|
233
|
-
return () =>
|
|
311
|
+
expiredListeners.add(listener);
|
|
312
|
+
return () => expiredListeners.delete(listener);
|
|
313
|
+
},
|
|
314
|
+
onSessionExpired(listener) {
|
|
315
|
+
sessionListeners.add(listener);
|
|
316
|
+
return () => sessionListeners.delete(listener);
|
|
234
317
|
},
|
|
235
318
|
};
|
|
236
319
|
}
|
|
@@ -93,7 +93,7 @@ export type PaymentSession = PaymentSessionFragment;
|
|
|
93
93
|
export type DiscountValidationResult = CartValidateDiscountCodeQuery['cartValidateDiscountCode'];
|
|
94
94
|
export type DiscountInfo = NonNullable<DiscountValidationResult['discount']>;
|
|
95
95
|
export type DiscountValidationError = NonNullable<DiscountValidationResult['error']>;
|
|
96
|
-
export type { CartCreateInput, CartLineInput, CartLineUpdateInput, CartBuyerIdentityInput, CartAddressInput, CartAttributeInput, CartCompleteInput, CartApplyGiftCardInput, CartRemoveGiftCardInput, CartSelectPaymentMethodInput, CartSelectShippingMethodInput, CartSetBillingAddressInput, CartSetShippingAddressInput, CartUpdateGiftCardRecipientInput, PaymentCreateInput, ShippingAddressInput, PickupPointInput, DeliveryType, DeliveryEstimate, ShippingCarrier, FreeShippingProgress, PickupPoint, AttributeSelectionInput as CartAttributeSelectionInput, PaymentMethodType, PaymentInitiationFlow, DiscountApplicationType, DiscountErrorCode, CurrencyCode, CountryCode, LanguageCode, ProductTypeEnum, WeightUnit, CartWarningCode, AttributeType, AttributeFillingMode, AttributeBillingMode, AttributeOptionSurchargeType, StorefrontOrderStatus, OrderPaymentStatus, OrderFulfillmentStatus, } from '../generated/operation-types';
|
|
96
|
+
export type { CartCreateInput, CartLineInput, CartLineUpdateInput, CartBuyerIdentityInput, CartAddressInput, CartAttributeInput, CartCompleteInput, CartApplyGiftCardInput, CartRemoveGiftCardInput, CartSelectPaymentMethodInput, CartClearPaymentSelectionInput, CartSelectShippingMethodInput, CartSetBillingAddressInput, CartSetShippingAddressInput, CartUpdateGiftCardRecipientInput, PaymentCreateInput, ShippingAddressInput, PickupPointInput, DeliveryType, DeliveryEstimate, ShippingCarrier, FreeShippingProgress, PickupPoint, AttributeSelectionInput as CartAttributeSelectionInput, PaymentMethodType, PaymentInitiationFlow, DiscountApplicationType, DiscountErrorCode, CurrencyCode, CountryCode, LanguageCode, ProductTypeEnum, WeightUnit, CartWarningCode, AttributeType, AttributeFillingMode, AttributeBillingMode, AttributeOptionSurchargeType, StorefrontOrderStatus, OrderPaymentStatus, OrderFulfillmentStatus, } from '../generated/operation-types';
|
|
97
97
|
/**
|
|
98
98
|
* Machine-readable error code surfaced when `createPayment` fails. The call
|
|
99
99
|
* throws a `StorefrontError` on `userErrors` — read `.userErrors[0].code` off
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/cart/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/cart/types.ts"],"names":[],"mappings":"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"}
|