@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.
Files changed (30) hide show
  1. package/CHANGELOG.md +466 -0
  2. package/dist/core/cart/cart-client.d.ts +10 -1
  3. package/dist/core/cart/cart-client.d.ts.map +1 -1
  4. package/dist/core/cart/cart-client.js +17 -1
  5. package/dist/core/cart/cart-recovery.d.ts +63 -0
  6. package/dist/core/cart/cart-recovery.d.ts.map +1 -1
  7. package/dist/core/cart/cart-recovery.js +91 -8
  8. package/dist/core/cart/types.d.ts +1 -1
  9. package/dist/core/cart/types.d.ts.map +1 -1
  10. package/dist/core/generated/operation-types.d.ts +198 -32
  11. package/dist/core/generated/operation-types.d.ts.map +1 -1
  12. package/dist/core/operations/cart.d.ts +7 -0
  13. package/dist/core/operations/cart.d.ts.map +1 -1
  14. package/dist/core/operations/cart.js +52 -0
  15. package/dist/react/components/PaymentInstrumentSection.d.ts +56 -0
  16. package/dist/react/components/PaymentInstrumentSection.d.ts.map +1 -0
  17. package/dist/react/components/PaymentInstrumentSection.js +89 -0
  18. package/dist/react/components/PaymentInstrumentTile.d.ts +56 -0
  19. package/dist/react/components/PaymentInstrumentTile.d.ts.map +1 -0
  20. package/dist/react/components/PaymentInstrumentTile.js +40 -0
  21. package/dist/react/components/index.d.ts +2 -0
  22. package/dist/react/components/index.d.ts.map +1 -1
  23. package/dist/react/components/index.js +2 -0
  24. package/dist/react/helpers/browser-data.d.ts +89 -0
  25. package/dist/react/helpers/browser-data.d.ts.map +1 -0
  26. package/dist/react/helpers/browser-data.js +84 -0
  27. package/dist/react/index.d.ts +2 -1
  28. package/dist/react/index.d.ts.map +1 -1
  29. package/dist/react/index.js +3 -1
  30. 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 listeners = new Set();
185
- function emit(event) {
186
- for (const listener of listeners) {
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: emit,
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
- emit({
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
- listeners.add(listener);
233
- return () => listeners.delete(listener);
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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"}