@asteby/storefront 0.11.1 → 0.12.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/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { GeoPoint } from './geo.cjs';
2
2
  export { OpenStatus, OpeningHours } from './geo.cjs';
3
- import { aJ as ProductSort, b8 as TokenIntrospection, b0 as Shop, aQ as Region, aH as ProductConnection, aE as Product, y as Connection, x as Collection, ad as LocationListParams, aa as Location, aj as NearestLocation, b4 as StockLevel, aU as RestockSubscriptionInput, aV as RestockSubscriptionResult, m as CartLineInput, C as Cart, p as CartLineUpdateInput, f as CartBuyerInput, a as AddressInput, Q as DeliveryOptions, aw as PaymentMethods, O as DeliveryInput, a5 as InvoiceRequest, aP as RecommendationPlacement, s as CartRecommendations, u as CheckoutInput, w as CheckoutResult, aO as PromotionsList, at as PaymentConfig, aB as PaymentSubmitInput, ap as PaymentAttemptResult, D as CustomerIdentifier, J as CustomerSessionInput, I as CustomerSession, B as CustomerCapabilities, F as CustomerRegisterInput, G as CustomerRegisterResult, M as CustomerVerifyRegistrationInput, E as CustomerPasswordLoginInput, K as CustomerSetPasswordInput, H as CustomerResetPasswordInput, z as Customer, L as CustomerUpdateInput, ak as Order, aX as ReturnRequestInput, aW as ReturnRequest, a6 as InvoiceResult, A as Address, b7 as Theme, am as Page, af as Menu, b as Article, b6 as StorefrontErrorCode, a3 as InsufficientStockLine, ah as Money, d as AvailabilityStatus, o as CartLineProblem, c as Availability, aK as ProductVariant, N as DeclineCode, aC as PaymentVoucher, ax as PaymentNextStep, q as CartPromotions, aM as PromotionReward, P as DeliveryMethod, b9 as UnavailableRateProvider } from './types-bsdlAumU.cjs';
4
- export { e as CartBuyer, g as CartCost, h as CartDelivery, i as CartDiscountCode, j as CartDiscountLine, k as CartInvoice, l as CartLine, n as CartLineMerchandise, r as CartRecommendation, t as CheckoutInfo, v as CheckoutPayment, R as Facet, S as FacetValue, T as FiscalDocumentEvidence, U as FiscalDocumentSource, V as FiscalIdentity, W as FiscalIdentityInput, X as FiscalVerification, Y as IdentityCapture, Z as IdentityDocumentSpec, _ as IdentityFieldRule, $ as IdentityRulesV1, a0 as IdentityStrategy, a1 as Image, a2 as InsufficientStockDetails, a4 as InvoiceAction, a7 as InvoiceStage, a8 as InvoiceSummary, a9 as InvoicingCapabilities, ab as LocationContacts, ac as LocationKind, ae as LocationPickup, ag as MenuItem, ai as MoneyRange, al as OrderLine, an as PageInfo, ao as PaymentAction, aq as PaymentAttemptStatus, ar as PaymentClient, as as PaymentClientCsp, au as PaymentFlow, av as PaymentMethod, ay as PaymentOption, az as PaymentOptionKey, aA as PaymentPoint, aD as PickupOption, aF as ProductAttributeValue, aG as ProductCategory, aI as ProductOption, aL as PromotionAnnouncement, aN as PromotionTier, aR as RegionFiscalEntry, aS as RegionFiscalId, aT as RegionPaymentMethod, aY as SEO, aZ as Section, a_ as SelectedOption, a$ as ShippingRate, b1 as ShopBranch, b2 as ShopContact, b3 as ShopPolicies, b5 as StorefrontErrorBody } from './types-bsdlAumU.cjs';
3
+ import { aJ as ProductSort, b8 as TokenIntrospection, b0 as Shop, aQ as Region, aH as ProductConnection, aE as Product, y as Connection, x as Collection, ad as LocationListParams, aa as Location, aj as NearestLocation, b4 as StockLevel, aU as RestockSubscriptionInput, aV as RestockSubscriptionResult, m as CartLineInput, C as Cart, p as CartLineUpdateInput, f as CartBuyerInput, a as AddressInput, Q as DeliveryOptions, aw as PaymentMethods, O as DeliveryInput, a5 as InvoiceRequest, aP as RecommendationPlacement, s as CartRecommendations, u as CheckoutInput, w as CheckoutResult, aO as PromotionsList, at as PaymentConfig, aB as PaymentSubmitInput, ap as PaymentAttemptResult, D as CustomerIdentifier, J as CustomerSessionInput, I as CustomerSession, B as CustomerCapabilities, F as CustomerRegisterInput, G as CustomerRegisterResult, M as CustomerVerifyRegistrationInput, E as CustomerPasswordLoginInput, K as CustomerSetPasswordInput, H as CustomerResetPasswordInput, z as Customer, L as CustomerUpdateInput, ak as Order, aX as ReturnRequestInput, aW as ReturnRequest, a6 as InvoiceResult, A as Address, b7 as Theme, am as Page, af as Menu, b as Article, b6 as StorefrontErrorCode, a3 as InsufficientStockLine, ah as Money, d as AvailabilityStatus, o as CartLineProblem, c as Availability, aK as ProductVariant, N as DeclineCode, aC as PaymentVoucher, ax as PaymentNextStep, q as CartPromotions, aM as PromotionReward, P as DeliveryMethod, b9 as UnavailableRateProvider } from './types-BQ3S6VjF.cjs';
4
+ export { e as CartBuyer, g as CartCost, h as CartDelivery, i as CartDiscountCode, j as CartDiscountLine, k as CartInvoice, l as CartLine, n as CartLineMerchandise, r as CartRecommendation, t as CheckoutInfo, v as CheckoutPayment, R as Facet, S as FacetValue, T as FiscalDocumentEvidence, U as FiscalDocumentSource, V as FiscalIdentity, W as FiscalIdentityInput, X as FiscalVerification, Y as IdentityCapture, Z as IdentityDocumentSpec, _ as IdentityFieldRule, $ as IdentityRulesV1, a0 as IdentityStrategy, a1 as Image, a2 as InsufficientStockDetails, a4 as InvoiceAction, a7 as InvoiceStage, a8 as InvoiceSummary, a9 as InvoicingCapabilities, ab as LocationContacts, ac as LocationKind, ae as LocationPickup, ag as MenuItem, ai as MoneyRange, al as OrderLine, an as PageInfo, ao as PaymentAction, aq as PaymentAttemptStatus, ar as PaymentClient, as as PaymentClientCsp, au as PaymentFlow, av as PaymentMethod, ay as PaymentOption, az as PaymentOptionKey, aA as PaymentPoint, aD as PickupOption, aF as ProductAttributeValue, aG as ProductCategory, aI as ProductOption, aL as PromotionAnnouncement, aN as PromotionTier, aR as RegionFiscalEntry, aS as RegionFiscalId, aT as RegionPaymentMethod, aY as SEO, aZ as Section, a_ as SelectedOption, a$ as ShippingRate, b1 as ShopBranch, b2 as ShopContact, b3 as ShopPolicies, b5 as StorefrontErrorBody } from './types-BQ3S6VjF.cjs';
5
5
 
6
6
  type QueryValue = string | number | boolean | null | undefined;
7
7
  type QueryParams = Record<string, QueryValue | QueryValue[]>;
@@ -353,6 +353,16 @@ type StorefrontErrorInit = {
353
353
  cause?: unknown;
354
354
  /** Scopes named by the gateway on a `403 insufficient_scope`. */
355
355
  requiredScopes?: string[];
356
+ /** `error.retryable` as OPS declared it (payment failures). `undefined` = OPS did not say. */
357
+ retryable?: boolean;
358
+ /** `error.retry_after` in seconds. */
359
+ retryAfter?: number;
360
+ /** `error.checkout_id`: the checkout a refused cart write can resume. */
361
+ checkoutId?: string;
362
+ /** `error.cost` of a `price_mismatch` (the cart's current cost; untrusted shape). */
363
+ cost?: unknown;
364
+ /** `error.message_en`. */
365
+ messageEn?: string;
356
366
  };
357
367
  /**
358
368
  * Error thrown by the client for any non-2xx response, network failure,
@@ -367,6 +377,16 @@ declare class StorefrontError extends Error {
367
377
  readonly url: string | undefined;
368
378
  /** Scopes a `403 insufficient_scope` says the route needs (empty for any other error). */
369
379
  readonly requiredScopes: string[];
380
+ /** `true`: repeating the request (same idempotency key) can succeed. `false`: not until someone fixes something. `undefined`: OPS did not say. */
381
+ readonly retryable: boolean | undefined;
382
+ /** Seconds OPS asks to wait before retrying. */
383
+ readonly retryAfter: number | undefined;
384
+ /** Checkout that a refused cart write can resume. */
385
+ readonly checkoutId: string | undefined;
386
+ /** Current cart cost sent with a `price_mismatch` (untrusted shape). */
387
+ readonly cost: unknown;
388
+ /** English version of `message`, when OPS sent one. */
389
+ readonly messageEn: string | undefined;
370
390
  constructor(init: StorefrontErrorInit);
371
391
  /**
372
392
  * Affected lines of a `409 insufficient_stock` (empty for any other error or a
@@ -375,6 +395,9 @@ declare class StorefrontError extends Error {
375
395
  */
376
396
  get stockLines(): InsufficientStockLine[];
377
397
  toJSON(): {
398
+ checkoutId?: string | undefined;
399
+ retryAfter?: number | undefined;
400
+ retryable?: boolean | undefined;
378
401
  requiredScopes?: string[] | undefined;
379
402
  name: string;
380
403
  status: number;
@@ -385,6 +408,52 @@ declare class StorefrontError extends Error {
385
408
  }
386
409
  declare function isStorefrontError(err: unknown): err is StorefrontError;
387
410
 
411
+ /**
412
+ * Classification of the failures of a card payment (`POST pay` / `GET status`). No texts, no DOM, no server APIs: the
413
+ * shop's server uses it to answer with `kind` and `retryable`, and the browser transport uses it to decide whether to
414
+ * repeat, ask for the status or give up.
415
+ *
416
+ * Rule that never changes: an INDETERMINATE result (`transient`, `in_progress`) is never charged again with another
417
+ * idempotency key; it is repeated with the SAME key or its status is read.
418
+ */
419
+ type PaymentErrorClassKind =
420
+ /** OPS or the provider did not answer (5xx, timeout, network). The charge may or may not have happened. */
421
+ 'transient'
422
+ /** A payment is already in progress for this order (409): read the status, do not charge again. */
423
+ | 'in_progress'
424
+ /** Too many attempts (429). */
425
+ | 'rate_limited'
426
+ /** Credentials or configuration of the merchant with the provider: not the buyer's fault. */
427
+ | 'merchant_config'
428
+ /** The provider refused the charge at API level (`payment_provider_rejected`): definitive, nothing was charged. */
429
+ | 'provider_declined'
430
+ /** The cart already became an order and OPS will not open a new attempt (`422 invalid_state`). */
431
+ | 'stale_checkout' | 'expired' | 'price_mismatch' | 'store_closed' | 'validation' | 'other';
432
+ type PaymentErrorClass = {
433
+ kind: PaymentErrorClassKind;
434
+ retryable: boolean;
435
+ };
436
+ type PaymentErrorLike = {
437
+ status?: number | null;
438
+ code?: string | null;
439
+ field?: string | null;
440
+ /** `error.retryable` as OPS declared it (`StorefrontError.retryable`). */
441
+ retryable?: boolean | null;
442
+ /** `error.checkout_id` (`StorefrontError.checkoutId`). */
443
+ checkoutId?: string | null;
444
+ /** Raw `error.details`; a `retryable` inside is honoured too (older bodies). */
445
+ details?: unknown;
446
+ };
447
+ /** Did OPS expressly say the failure must NOT be repeated (`retryable: false`, on the error or inside `details`)? */
448
+ declare function opsSaysNotRetryable(err: PaymentErrorLike): boolean;
449
+ /** Field the shop's server sets when IT refuses a payment row that is not offered (so it is not read as a stale checkout). */
450
+ declare const PAYMENT_CHOICE_REFUSED_FIELD = "payment_choice";
451
+ /**
452
+ * What a payment failure means and whether repeating it can help. What OPS declares (`retryable`, stable codes) wins
453
+ * over the HTTP status: a 502 with a stable code is an answer, not "no response".
454
+ */
455
+ declare function classifyPaymentError(err: PaymentErrorLike): PaymentErrorClass;
456
+
388
457
  /** `sk_…a91f`: the prefix and the last four characters, never enough to use the token. */
389
458
  declare function maskToken(token: string | null | undefined): string;
390
459
  type DiagnoseOptions = {
@@ -748,4 +817,4 @@ type DeliveryNotices = {
748
817
  /** Splits `delivery.unavailable` into the `missing_weight` notice and the generic one. */
749
818
  declare function deliveryNotices(delivery: Pick<DeliveryOptions, 'unavailable' | 'partial'> | null | undefined): DeliveryNotices;
750
819
 
751
- export { Address, AddressInput, Article, type ArticleListParams, Availability, type AvailabilityLocale, type AvailabilityMessageKey, type AvailabilityMessages, AvailabilityStatus, type AvailabilityTone, type AvailabilityView, type AvailabilityViewOptions, CLIENT_IP_HEADER, COUNTRY_HEADERS, Cart, CartBuyerInput, CartLineInput, CartLineProblem, type CartLineProblemView, CartLineUpdateInput, CartPromotions, CartRecommendations, CheckoutInput, CheckoutResult, Collection, type CollectionListParams, Connection, Customer, CustomerCapabilities, CustomerIdentifier, CustomerPasswordLoginInput, CustomerRegisterInput, CustomerRegisterResult, CustomerResetPasswordInput, CustomerSession, CustomerSessionInput, CustomerSetPasswordInput, CustomerUpdateInput, CustomerVerifyRegistrationInput, DeclineCode, type DeliveryChoice, type DeliveryChoiceKind, DeliveryInput, DeliveryMethod, type DeliveryNotices, DeliveryOptions, type DiagnoseOptions, type DiscountBarState, type DiscountBarView, type FetchLike, type FormatMoneyOptions, GeoPoint, InsufficientStockLine, InvoiceRequest, InvoiceResult, Location, LocationListParams, MISSING_WEIGHT, type MarketInfo, type MarketSuggestion, Menu, Money, NOTE_MAX_LENGTH, NearestLocation, Order, Page, type PaginationParams, PaymentAttemptResult, PaymentConfig, type PaymentErrorKind, type PaymentErrorView, type PaymentLocale, type PaymentMessageKey, type PaymentMessages, PaymentMethods, PaymentNextStep, type PaymentOutcome, type PaymentOutcomeKind, PaymentSubmitInput, PaymentVoucher, type PreviewOptions, Product, ProductConnection, type ProductListParams, ProductSort, ProductVariant, type PromoProgressView, type PromotionLocale, type PromotionMessageKey, type PromotionMessages, PromotionReward, PromotionsList, type QueryParams, type QueryValue, RecommendationPlacement, Region, type RequestOptions, type ResolveAvailabilityOptions, RestockSubscriptionInput, RestockSubscriptionResult, ReturnRequest, ReturnRequestInput, type ShippingBarState, type ShippingBarView, Shop, StockLevel, type StorefrontClient, type StorefrontClientOptions, StorefrontError, StorefrontErrorCode, type StorefrontErrorInit, type StorefrontRequestContext, type StorefrontResponseContext, Theme, TokenIntrospection, UnavailableRateProvider, type WriteOptions, appendParams, availabilityLocale, availabilityMessages, availabilityView, cartLineProblemView, clampPercent, createStorefrontClient, declineMessage, declineMessageKey, deliveryInput, deliveryNotices, diagnose, formatAvailabilityMessage, formatMoney, formatVoucherExpiry, generateIdempotencyKey, hreflangLinks, isStorefrontError, isTokenPublishable, maskToken, negotiateLocale, normalizeClientIp, normalizeNote, parseDelivery, parseMoney, parseProductFilters, paymentErrorView, paymentIdempotencyKey, paymentMessages, paymentOutcome, preferredLanguages, productAvailability, productListQuery, promoProgressView, promotionMessages, repairPath, resolveAvailability, rewardLabel, safeHttpsUrl, schemaAvailability, storefrontDomainHeader, suggestMarket, toMoney, visitorCountry };
820
+ export { Address, AddressInput, Article, type ArticleListParams, Availability, type AvailabilityLocale, type AvailabilityMessageKey, type AvailabilityMessages, AvailabilityStatus, type AvailabilityTone, type AvailabilityView, type AvailabilityViewOptions, CLIENT_IP_HEADER, COUNTRY_HEADERS, Cart, CartBuyerInput, CartLineInput, CartLineProblem, type CartLineProblemView, CartLineUpdateInput, CartPromotions, CartRecommendations, CheckoutInput, CheckoutResult, Collection, type CollectionListParams, Connection, Customer, CustomerCapabilities, CustomerIdentifier, CustomerPasswordLoginInput, CustomerRegisterInput, CustomerRegisterResult, CustomerResetPasswordInput, CustomerSession, CustomerSessionInput, CustomerSetPasswordInput, CustomerUpdateInput, CustomerVerifyRegistrationInput, DeclineCode, type DeliveryChoice, type DeliveryChoiceKind, DeliveryInput, DeliveryMethod, type DeliveryNotices, DeliveryOptions, type DiagnoseOptions, type DiscountBarState, type DiscountBarView, type FetchLike, type FormatMoneyOptions, GeoPoint, InsufficientStockLine, InvoiceRequest, InvoiceResult, Location, LocationListParams, MISSING_WEIGHT, type MarketInfo, type MarketSuggestion, Menu, Money, NOTE_MAX_LENGTH, NearestLocation, Order, PAYMENT_CHOICE_REFUSED_FIELD, Page, type PaginationParams, PaymentAttemptResult, PaymentConfig, type PaymentErrorClass, type PaymentErrorClassKind, type PaymentErrorKind, type PaymentErrorLike, type PaymentErrorView, type PaymentLocale, type PaymentMessageKey, type PaymentMessages, PaymentMethods, PaymentNextStep, type PaymentOutcome, type PaymentOutcomeKind, PaymentSubmitInput, PaymentVoucher, type PreviewOptions, Product, ProductConnection, type ProductListParams, ProductSort, ProductVariant, type PromoProgressView, type PromotionLocale, type PromotionMessageKey, type PromotionMessages, PromotionReward, PromotionsList, type QueryParams, type QueryValue, RecommendationPlacement, Region, type RequestOptions, type ResolveAvailabilityOptions, RestockSubscriptionInput, RestockSubscriptionResult, ReturnRequest, ReturnRequestInput, type ShippingBarState, type ShippingBarView, Shop, StockLevel, type StorefrontClient, type StorefrontClientOptions, StorefrontError, StorefrontErrorCode, type StorefrontErrorInit, type StorefrontRequestContext, type StorefrontResponseContext, Theme, TokenIntrospection, UnavailableRateProvider, type WriteOptions, appendParams, availabilityLocale, availabilityMessages, availabilityView, cartLineProblemView, clampPercent, classifyPaymentError, createStorefrontClient, declineMessage, declineMessageKey, deliveryInput, deliveryNotices, diagnose, formatAvailabilityMessage, formatMoney, formatVoucherExpiry, generateIdempotencyKey, hreflangLinks, isStorefrontError, isTokenPublishable, maskToken, negotiateLocale, normalizeClientIp, normalizeNote, opsSaysNotRetryable, parseDelivery, parseMoney, parseProductFilters, paymentErrorView, paymentIdempotencyKey, paymentMessages, paymentOutcome, preferredLanguages, productAvailability, productListQuery, promoProgressView, promotionMessages, repairPath, resolveAvailability, rewardLabel, safeHttpsUrl, schemaAvailability, storefrontDomainHeader, suggestMarket, toMoney, visitorCountry };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { GeoPoint } from './geo.js';
2
2
  export { OpenStatus, OpeningHours } from './geo.js';
3
- import { aJ as ProductSort, b8 as TokenIntrospection, b0 as Shop, aQ as Region, aH as ProductConnection, aE as Product, y as Connection, x as Collection, ad as LocationListParams, aa as Location, aj as NearestLocation, b4 as StockLevel, aU as RestockSubscriptionInput, aV as RestockSubscriptionResult, m as CartLineInput, C as Cart, p as CartLineUpdateInput, f as CartBuyerInput, a as AddressInput, Q as DeliveryOptions, aw as PaymentMethods, O as DeliveryInput, a5 as InvoiceRequest, aP as RecommendationPlacement, s as CartRecommendations, u as CheckoutInput, w as CheckoutResult, aO as PromotionsList, at as PaymentConfig, aB as PaymentSubmitInput, ap as PaymentAttemptResult, D as CustomerIdentifier, J as CustomerSessionInput, I as CustomerSession, B as CustomerCapabilities, F as CustomerRegisterInput, G as CustomerRegisterResult, M as CustomerVerifyRegistrationInput, E as CustomerPasswordLoginInput, K as CustomerSetPasswordInput, H as CustomerResetPasswordInput, z as Customer, L as CustomerUpdateInput, ak as Order, aX as ReturnRequestInput, aW as ReturnRequest, a6 as InvoiceResult, A as Address, b7 as Theme, am as Page, af as Menu, b as Article, b6 as StorefrontErrorCode, a3 as InsufficientStockLine, ah as Money, d as AvailabilityStatus, o as CartLineProblem, c as Availability, aK as ProductVariant, N as DeclineCode, aC as PaymentVoucher, ax as PaymentNextStep, q as CartPromotions, aM as PromotionReward, P as DeliveryMethod, b9 as UnavailableRateProvider } from './types-B1E3GySa.js';
4
- export { e as CartBuyer, g as CartCost, h as CartDelivery, i as CartDiscountCode, j as CartDiscountLine, k as CartInvoice, l as CartLine, n as CartLineMerchandise, r as CartRecommendation, t as CheckoutInfo, v as CheckoutPayment, R as Facet, S as FacetValue, T as FiscalDocumentEvidence, U as FiscalDocumentSource, V as FiscalIdentity, W as FiscalIdentityInput, X as FiscalVerification, Y as IdentityCapture, Z as IdentityDocumentSpec, _ as IdentityFieldRule, $ as IdentityRulesV1, a0 as IdentityStrategy, a1 as Image, a2 as InsufficientStockDetails, a4 as InvoiceAction, a7 as InvoiceStage, a8 as InvoiceSummary, a9 as InvoicingCapabilities, ab as LocationContacts, ac as LocationKind, ae as LocationPickup, ag as MenuItem, ai as MoneyRange, al as OrderLine, an as PageInfo, ao as PaymentAction, aq as PaymentAttemptStatus, ar as PaymentClient, as as PaymentClientCsp, au as PaymentFlow, av as PaymentMethod, ay as PaymentOption, az as PaymentOptionKey, aA as PaymentPoint, aD as PickupOption, aF as ProductAttributeValue, aG as ProductCategory, aI as ProductOption, aL as PromotionAnnouncement, aN as PromotionTier, aR as RegionFiscalEntry, aS as RegionFiscalId, aT as RegionPaymentMethod, aY as SEO, aZ as Section, a_ as SelectedOption, a$ as ShippingRate, b1 as ShopBranch, b2 as ShopContact, b3 as ShopPolicies, b5 as StorefrontErrorBody } from './types-B1E3GySa.js';
3
+ import { aJ as ProductSort, b8 as TokenIntrospection, b0 as Shop, aQ as Region, aH as ProductConnection, aE as Product, y as Connection, x as Collection, ad as LocationListParams, aa as Location, aj as NearestLocation, b4 as StockLevel, aU as RestockSubscriptionInput, aV as RestockSubscriptionResult, m as CartLineInput, C as Cart, p as CartLineUpdateInput, f as CartBuyerInput, a as AddressInput, Q as DeliveryOptions, aw as PaymentMethods, O as DeliveryInput, a5 as InvoiceRequest, aP as RecommendationPlacement, s as CartRecommendations, u as CheckoutInput, w as CheckoutResult, aO as PromotionsList, at as PaymentConfig, aB as PaymentSubmitInput, ap as PaymentAttemptResult, D as CustomerIdentifier, J as CustomerSessionInput, I as CustomerSession, B as CustomerCapabilities, F as CustomerRegisterInput, G as CustomerRegisterResult, M as CustomerVerifyRegistrationInput, E as CustomerPasswordLoginInput, K as CustomerSetPasswordInput, H as CustomerResetPasswordInput, z as Customer, L as CustomerUpdateInput, ak as Order, aX as ReturnRequestInput, aW as ReturnRequest, a6 as InvoiceResult, A as Address, b7 as Theme, am as Page, af as Menu, b as Article, b6 as StorefrontErrorCode, a3 as InsufficientStockLine, ah as Money, d as AvailabilityStatus, o as CartLineProblem, c as Availability, aK as ProductVariant, N as DeclineCode, aC as PaymentVoucher, ax as PaymentNextStep, q as CartPromotions, aM as PromotionReward, P as DeliveryMethod, b9 as UnavailableRateProvider } from './types-C_rsJRCl.js';
4
+ export { e as CartBuyer, g as CartCost, h as CartDelivery, i as CartDiscountCode, j as CartDiscountLine, k as CartInvoice, l as CartLine, n as CartLineMerchandise, r as CartRecommendation, t as CheckoutInfo, v as CheckoutPayment, R as Facet, S as FacetValue, T as FiscalDocumentEvidence, U as FiscalDocumentSource, V as FiscalIdentity, W as FiscalIdentityInput, X as FiscalVerification, Y as IdentityCapture, Z as IdentityDocumentSpec, _ as IdentityFieldRule, $ as IdentityRulesV1, a0 as IdentityStrategy, a1 as Image, a2 as InsufficientStockDetails, a4 as InvoiceAction, a7 as InvoiceStage, a8 as InvoiceSummary, a9 as InvoicingCapabilities, ab as LocationContacts, ac as LocationKind, ae as LocationPickup, ag as MenuItem, ai as MoneyRange, al as OrderLine, an as PageInfo, ao as PaymentAction, aq as PaymentAttemptStatus, ar as PaymentClient, as as PaymentClientCsp, au as PaymentFlow, av as PaymentMethod, ay as PaymentOption, az as PaymentOptionKey, aA as PaymentPoint, aD as PickupOption, aF as ProductAttributeValue, aG as ProductCategory, aI as ProductOption, aL as PromotionAnnouncement, aN as PromotionTier, aR as RegionFiscalEntry, aS as RegionFiscalId, aT as RegionPaymentMethod, aY as SEO, aZ as Section, a_ as SelectedOption, a$ as ShippingRate, b1 as ShopBranch, b2 as ShopContact, b3 as ShopPolicies, b5 as StorefrontErrorBody } from './types-C_rsJRCl.js';
5
5
 
6
6
  type QueryValue = string | number | boolean | null | undefined;
7
7
  type QueryParams = Record<string, QueryValue | QueryValue[]>;
@@ -353,6 +353,16 @@ type StorefrontErrorInit = {
353
353
  cause?: unknown;
354
354
  /** Scopes named by the gateway on a `403 insufficient_scope`. */
355
355
  requiredScopes?: string[];
356
+ /** `error.retryable` as OPS declared it (payment failures). `undefined` = OPS did not say. */
357
+ retryable?: boolean;
358
+ /** `error.retry_after` in seconds. */
359
+ retryAfter?: number;
360
+ /** `error.checkout_id`: the checkout a refused cart write can resume. */
361
+ checkoutId?: string;
362
+ /** `error.cost` of a `price_mismatch` (the cart's current cost; untrusted shape). */
363
+ cost?: unknown;
364
+ /** `error.message_en`. */
365
+ messageEn?: string;
356
366
  };
357
367
  /**
358
368
  * Error thrown by the client for any non-2xx response, network failure,
@@ -367,6 +377,16 @@ declare class StorefrontError extends Error {
367
377
  readonly url: string | undefined;
368
378
  /** Scopes a `403 insufficient_scope` says the route needs (empty for any other error). */
369
379
  readonly requiredScopes: string[];
380
+ /** `true`: repeating the request (same idempotency key) can succeed. `false`: not until someone fixes something. `undefined`: OPS did not say. */
381
+ readonly retryable: boolean | undefined;
382
+ /** Seconds OPS asks to wait before retrying. */
383
+ readonly retryAfter: number | undefined;
384
+ /** Checkout that a refused cart write can resume. */
385
+ readonly checkoutId: string | undefined;
386
+ /** Current cart cost sent with a `price_mismatch` (untrusted shape). */
387
+ readonly cost: unknown;
388
+ /** English version of `message`, when OPS sent one. */
389
+ readonly messageEn: string | undefined;
370
390
  constructor(init: StorefrontErrorInit);
371
391
  /**
372
392
  * Affected lines of a `409 insufficient_stock` (empty for any other error or a
@@ -375,6 +395,9 @@ declare class StorefrontError extends Error {
375
395
  */
376
396
  get stockLines(): InsufficientStockLine[];
377
397
  toJSON(): {
398
+ checkoutId?: string | undefined;
399
+ retryAfter?: number | undefined;
400
+ retryable?: boolean | undefined;
378
401
  requiredScopes?: string[] | undefined;
379
402
  name: string;
380
403
  status: number;
@@ -385,6 +408,52 @@ declare class StorefrontError extends Error {
385
408
  }
386
409
  declare function isStorefrontError(err: unknown): err is StorefrontError;
387
410
 
411
+ /**
412
+ * Classification of the failures of a card payment (`POST pay` / `GET status`). No texts, no DOM, no server APIs: the
413
+ * shop's server uses it to answer with `kind` and `retryable`, and the browser transport uses it to decide whether to
414
+ * repeat, ask for the status or give up.
415
+ *
416
+ * Rule that never changes: an INDETERMINATE result (`transient`, `in_progress`) is never charged again with another
417
+ * idempotency key; it is repeated with the SAME key or its status is read.
418
+ */
419
+ type PaymentErrorClassKind =
420
+ /** OPS or the provider did not answer (5xx, timeout, network). The charge may or may not have happened. */
421
+ 'transient'
422
+ /** A payment is already in progress for this order (409): read the status, do not charge again. */
423
+ | 'in_progress'
424
+ /** Too many attempts (429). */
425
+ | 'rate_limited'
426
+ /** Credentials or configuration of the merchant with the provider: not the buyer's fault. */
427
+ | 'merchant_config'
428
+ /** The provider refused the charge at API level (`payment_provider_rejected`): definitive, nothing was charged. */
429
+ | 'provider_declined'
430
+ /** The cart already became an order and OPS will not open a new attempt (`422 invalid_state`). */
431
+ | 'stale_checkout' | 'expired' | 'price_mismatch' | 'store_closed' | 'validation' | 'other';
432
+ type PaymentErrorClass = {
433
+ kind: PaymentErrorClassKind;
434
+ retryable: boolean;
435
+ };
436
+ type PaymentErrorLike = {
437
+ status?: number | null;
438
+ code?: string | null;
439
+ field?: string | null;
440
+ /** `error.retryable` as OPS declared it (`StorefrontError.retryable`). */
441
+ retryable?: boolean | null;
442
+ /** `error.checkout_id` (`StorefrontError.checkoutId`). */
443
+ checkoutId?: string | null;
444
+ /** Raw `error.details`; a `retryable` inside is honoured too (older bodies). */
445
+ details?: unknown;
446
+ };
447
+ /** Did OPS expressly say the failure must NOT be repeated (`retryable: false`, on the error or inside `details`)? */
448
+ declare function opsSaysNotRetryable(err: PaymentErrorLike): boolean;
449
+ /** Field the shop's server sets when IT refuses a payment row that is not offered (so it is not read as a stale checkout). */
450
+ declare const PAYMENT_CHOICE_REFUSED_FIELD = "payment_choice";
451
+ /**
452
+ * What a payment failure means and whether repeating it can help. What OPS declares (`retryable`, stable codes) wins
453
+ * over the HTTP status: a 502 with a stable code is an answer, not "no response".
454
+ */
455
+ declare function classifyPaymentError(err: PaymentErrorLike): PaymentErrorClass;
456
+
388
457
  /** `sk_…a91f`: the prefix and the last four characters, never enough to use the token. */
389
458
  declare function maskToken(token: string | null | undefined): string;
390
459
  type DiagnoseOptions = {
@@ -748,4 +817,4 @@ type DeliveryNotices = {
748
817
  /** Splits `delivery.unavailable` into the `missing_weight` notice and the generic one. */
749
818
  declare function deliveryNotices(delivery: Pick<DeliveryOptions, 'unavailable' | 'partial'> | null | undefined): DeliveryNotices;
750
819
 
751
- export { Address, AddressInput, Article, type ArticleListParams, Availability, type AvailabilityLocale, type AvailabilityMessageKey, type AvailabilityMessages, AvailabilityStatus, type AvailabilityTone, type AvailabilityView, type AvailabilityViewOptions, CLIENT_IP_HEADER, COUNTRY_HEADERS, Cart, CartBuyerInput, CartLineInput, CartLineProblem, type CartLineProblemView, CartLineUpdateInput, CartPromotions, CartRecommendations, CheckoutInput, CheckoutResult, Collection, type CollectionListParams, Connection, Customer, CustomerCapabilities, CustomerIdentifier, CustomerPasswordLoginInput, CustomerRegisterInput, CustomerRegisterResult, CustomerResetPasswordInput, CustomerSession, CustomerSessionInput, CustomerSetPasswordInput, CustomerUpdateInput, CustomerVerifyRegistrationInput, DeclineCode, type DeliveryChoice, type DeliveryChoiceKind, DeliveryInput, DeliveryMethod, type DeliveryNotices, DeliveryOptions, type DiagnoseOptions, type DiscountBarState, type DiscountBarView, type FetchLike, type FormatMoneyOptions, GeoPoint, InsufficientStockLine, InvoiceRequest, InvoiceResult, Location, LocationListParams, MISSING_WEIGHT, type MarketInfo, type MarketSuggestion, Menu, Money, NOTE_MAX_LENGTH, NearestLocation, Order, Page, type PaginationParams, PaymentAttemptResult, PaymentConfig, type PaymentErrorKind, type PaymentErrorView, type PaymentLocale, type PaymentMessageKey, type PaymentMessages, PaymentMethods, PaymentNextStep, type PaymentOutcome, type PaymentOutcomeKind, PaymentSubmitInput, PaymentVoucher, type PreviewOptions, Product, ProductConnection, type ProductListParams, ProductSort, ProductVariant, type PromoProgressView, type PromotionLocale, type PromotionMessageKey, type PromotionMessages, PromotionReward, PromotionsList, type QueryParams, type QueryValue, RecommendationPlacement, Region, type RequestOptions, type ResolveAvailabilityOptions, RestockSubscriptionInput, RestockSubscriptionResult, ReturnRequest, ReturnRequestInput, type ShippingBarState, type ShippingBarView, Shop, StockLevel, type StorefrontClient, type StorefrontClientOptions, StorefrontError, StorefrontErrorCode, type StorefrontErrorInit, type StorefrontRequestContext, type StorefrontResponseContext, Theme, TokenIntrospection, UnavailableRateProvider, type WriteOptions, appendParams, availabilityLocale, availabilityMessages, availabilityView, cartLineProblemView, clampPercent, createStorefrontClient, declineMessage, declineMessageKey, deliveryInput, deliveryNotices, diagnose, formatAvailabilityMessage, formatMoney, formatVoucherExpiry, generateIdempotencyKey, hreflangLinks, isStorefrontError, isTokenPublishable, maskToken, negotiateLocale, normalizeClientIp, normalizeNote, parseDelivery, parseMoney, parseProductFilters, paymentErrorView, paymentIdempotencyKey, paymentMessages, paymentOutcome, preferredLanguages, productAvailability, productListQuery, promoProgressView, promotionMessages, repairPath, resolveAvailability, rewardLabel, safeHttpsUrl, schemaAvailability, storefrontDomainHeader, suggestMarket, toMoney, visitorCountry };
820
+ export { Address, AddressInput, Article, type ArticleListParams, Availability, type AvailabilityLocale, type AvailabilityMessageKey, type AvailabilityMessages, AvailabilityStatus, type AvailabilityTone, type AvailabilityView, type AvailabilityViewOptions, CLIENT_IP_HEADER, COUNTRY_HEADERS, Cart, CartBuyerInput, CartLineInput, CartLineProblem, type CartLineProblemView, CartLineUpdateInput, CartPromotions, CartRecommendations, CheckoutInput, CheckoutResult, Collection, type CollectionListParams, Connection, Customer, CustomerCapabilities, CustomerIdentifier, CustomerPasswordLoginInput, CustomerRegisterInput, CustomerRegisterResult, CustomerResetPasswordInput, CustomerSession, CustomerSessionInput, CustomerSetPasswordInput, CustomerUpdateInput, CustomerVerifyRegistrationInput, DeclineCode, type DeliveryChoice, type DeliveryChoiceKind, DeliveryInput, DeliveryMethod, type DeliveryNotices, DeliveryOptions, type DiagnoseOptions, type DiscountBarState, type DiscountBarView, type FetchLike, type FormatMoneyOptions, GeoPoint, InsufficientStockLine, InvoiceRequest, InvoiceResult, Location, LocationListParams, MISSING_WEIGHT, type MarketInfo, type MarketSuggestion, Menu, Money, NOTE_MAX_LENGTH, NearestLocation, Order, PAYMENT_CHOICE_REFUSED_FIELD, Page, type PaginationParams, PaymentAttemptResult, PaymentConfig, type PaymentErrorClass, type PaymentErrorClassKind, type PaymentErrorKind, type PaymentErrorLike, type PaymentErrorView, type PaymentLocale, type PaymentMessageKey, type PaymentMessages, PaymentMethods, PaymentNextStep, type PaymentOutcome, type PaymentOutcomeKind, PaymentSubmitInput, PaymentVoucher, type PreviewOptions, Product, ProductConnection, type ProductListParams, ProductSort, ProductVariant, type PromoProgressView, type PromotionLocale, type PromotionMessageKey, type PromotionMessages, PromotionReward, PromotionsList, type QueryParams, type QueryValue, RecommendationPlacement, Region, type RequestOptions, type ResolveAvailabilityOptions, RestockSubscriptionInput, RestockSubscriptionResult, ReturnRequest, ReturnRequestInput, type ShippingBarState, type ShippingBarView, Shop, StockLevel, type StorefrontClient, type StorefrontClientOptions, StorefrontError, StorefrontErrorCode, type StorefrontErrorInit, type StorefrontRequestContext, type StorefrontResponseContext, Theme, TokenIntrospection, UnavailableRateProvider, type WriteOptions, appendParams, availabilityLocale, availabilityMessages, availabilityView, cartLineProblemView, clampPercent, classifyPaymentError, createStorefrontClient, declineMessage, declineMessageKey, deliveryInput, deliveryNotices, diagnose, formatAvailabilityMessage, formatMoney, formatVoucherExpiry, generateIdempotencyKey, hreflangLinks, isStorefrontError, isTokenPublishable, maskToken, negotiateLocale, normalizeClientIp, normalizeNote, opsSaysNotRetryable, parseDelivery, parseMoney, parseProductFilters, paymentErrorView, paymentIdempotencyKey, paymentMessages, paymentOutcome, preferredLanguages, productAvailability, productListQuery, promoProgressView, promotionMessages, repairPath, resolveAvailability, rewardLabel, safeHttpsUrl, schemaAvailability, storefrontDomainHeader, suggestMarket, toMoney, visitorCountry };
package/dist/index.js CHANGED
@@ -12,6 +12,16 @@ var StorefrontError = class extends Error {
12
12
  url;
13
13
  /** Scopes a `403 insufficient_scope` says the route needs (empty for any other error). */
14
14
  requiredScopes;
15
+ /** `true`: repeating the request (same idempotency key) can succeed. `false`: not until someone fixes something. `undefined`: OPS did not say. */
16
+ retryable;
17
+ /** Seconds OPS asks to wait before retrying. */
18
+ retryAfter;
19
+ /** Checkout that a refused cart write can resume. */
20
+ checkoutId;
21
+ /** Current cart cost sent with a `price_mismatch` (untrusted shape). */
22
+ cost;
23
+ /** English version of `message`, when OPS sent one. */
24
+ messageEn;
15
25
  constructor(init) {
16
26
  super(init.message, init.cause === void 0 ? void 0 : { cause: init.cause });
17
27
  this.status = init.status;
@@ -20,6 +30,11 @@ var StorefrontError = class extends Error {
20
30
  this.details = init.details;
21
31
  this.url = init.url;
22
32
  this.requiredScopes = init.requiredScopes ?? [];
33
+ this.retryable = init.retryable;
34
+ this.retryAfter = init.retryAfter;
35
+ this.checkoutId = init.checkoutId;
36
+ this.cost = init.cost;
37
+ this.messageEn = init.messageEn;
23
38
  }
24
39
  /**
25
40
  * Affected lines of a `409 insufficient_stock` (empty for any other error or a
@@ -38,7 +53,10 @@ var StorefrontError = class extends Error {
38
53
  code: this.code,
39
54
  message: this.message,
40
55
  field: this.field,
41
- ...this.requiredScopes.length ? { requiredScopes: this.requiredScopes } : {}
56
+ ...this.requiredScopes.length ? { requiredScopes: this.requiredScopes } : {},
57
+ ...this.retryable !== void 0 ? { retryable: this.retryable } : {},
58
+ ...this.retryAfter !== void 0 ? { retryAfter: this.retryAfter } : {},
59
+ ...this.checkoutId ? { checkoutId: this.checkoutId } : {}
42
60
  };
43
61
  }
44
62
  };
@@ -199,6 +217,11 @@ async function readError(res, url) {
199
217
  message: e?.message ?? `Storefront API responded ${res.status}${res.statusText ? " " + res.statusText : ""}`,
200
218
  ...e?.field ? { field: e.field } : {},
201
219
  ...e?.details !== void 0 ? { details: e.details } : {},
220
+ ...typeof e?.retryable === "boolean" ? { retryable: e.retryable } : {},
221
+ ...typeof e?.retry_after === "number" && e.retry_after > 0 ? { retryAfter: e.retry_after } : {},
222
+ ...typeof e?.checkout_id === "string" && e.checkout_id ? { checkoutId: e.checkout_id } : {},
223
+ ...e?.cost !== void 0 ? { cost: e.cost } : {},
224
+ ...typeof e?.message_en === "string" && e.message_en ? { messageEn: e.message_en } : {},
202
225
  url
203
226
  });
204
227
  }
@@ -480,6 +503,35 @@ function storefrontDomainHeader(domain, market) {
480
503
  return code && /^[a-z0-9_-]{1,32}$/.test(code) ? `${host}#${code}` : host;
481
504
  }
482
505
 
506
+ // src/payment-errors.ts
507
+ function opsSaysNotRetryable(err) {
508
+ if (err.retryable === false) return true;
509
+ const d = err.details;
510
+ return typeof d === "object" && d !== null && d.retryable === false;
511
+ }
512
+ var PAYMENT_CHOICE_REFUSED_FIELD = "payment_choice";
513
+ var MERCHANT_CONFIG_CODE = /credential|not_configured|unconfigured|invalid_access|access_token|provider_config|merchant|invalid_public_key|unauthorized/i;
514
+ function classifyPaymentError(err) {
515
+ const status = typeof err.status === "number" ? err.status : 0;
516
+ const code = typeof err.code === "string" ? err.code : "";
517
+ if (code === "store_not_ready") return { kind: "store_closed", retryable: false };
518
+ if (code === "price_mismatch" || status === 422 && err.field === "expected_total") return { kind: "price_mismatch", retryable: false };
519
+ if (status === 409 && (code === "payment_in_progress" || err.field === "payment_in_progress")) return { kind: "in_progress", retryable: true };
520
+ if (status === 409 && code === "expired") return { kind: "expired", retryable: false };
521
+ if (status === 429 || code === "too_many_attempts" || code === "rate_limited") return { kind: "rate_limited", retryable: true };
522
+ if (status === 422 && code === "invalid_state") {
523
+ if (err.field === PAYMENT_CHOICE_REFUSED_FIELD) return { kind: "other", retryable: false };
524
+ return { kind: "stale_checkout", retryable: false };
525
+ }
526
+ if (code === "payment_provider_misconfigured") return { kind: "merchant_config", retryable: false };
527
+ if (code === "payment_provider_rejected") return { kind: "provider_declined", retryable: false };
528
+ if (MERCHANT_CONFIG_CODE.test(code) || status === 401 || status === 403) return { kind: "merchant_config", retryable: false };
529
+ if (status >= 500 && opsSaysNotRetryable(err)) return { kind: "other", retryable: false };
530
+ if (status === 0 || status >= 500 || code === "network" || code === "timeout" || code === "unavailable") return { kind: "transient", retryable: true };
531
+ if (status === 400 || code === "validation") return { kind: "validation", retryable: false };
532
+ return { kind: "other", retryable: false };
533
+ }
534
+
483
535
  // src/diagnose.ts
484
536
  function maskToken(token) {
485
537
  if (!token) return "(sin token)";
@@ -725,7 +777,9 @@ function paymentErrorView(err, locale, overrides) {
725
777
  if (status === 429 || code === "too_many_attempts") {
726
778
  return { kind: "too_many_attempts", message: m["error.too_many_attempts"], retrySameAttempt: false, canRetry: false };
727
779
  }
728
- if (status === 0 || status === 502 || status === 503 || status === 504 || code === "network" || code === "timeout") {
780
+ const declared = e.retryable;
781
+ if (status >= 500 && declared === false) return { kind: "generic", message: m["error.generic"], retrySameAttempt: false, canRetry: true };
782
+ if (status === 0 || status === 502 || status === 503 || status === 504 || code === "network" || code === "timeout" || status >= 500) {
729
783
  return { kind: "network", message: m["error.network"], retrySameAttempt: true, canRetry: true };
730
784
  }
731
785
  return { kind: "generic", message: m["error.generic"], retrySameAttempt: false, canRetry: true };
@@ -1024,6 +1078,6 @@ function deliveryNotices(delivery) {
1024
1078
  };
1025
1079
  }
1026
1080
 
1027
- export { CLIENT_IP_HEADER, COUNTRY_HEADERS, MISSING_WEIGHT, NOTE_MAX_LENGTH, StorefrontError, appendParams, clampPercent, createStorefrontClient, declineMessage, declineMessageKey, deliveryInput, deliveryNotices, diagnose, formatMoney, formatVoucherExpiry, generateIdempotencyKey, hreflangLinks, isStorefrontError, isTokenPublishable, maskToken, negotiateLocale, normalizeClientIp, normalizeNote, parseDelivery, parseMoney, parseProductFilters, paymentErrorView, paymentIdempotencyKey, paymentMessages, paymentOutcome, preferredLanguages, productListQuery, promoProgressView, promotionMessages, repairPath, rewardLabel, safeHttpsUrl, storefrontDomainHeader, suggestMarket, toMoney, visitorCountry };
1081
+ export { CLIENT_IP_HEADER, COUNTRY_HEADERS, MISSING_WEIGHT, NOTE_MAX_LENGTH, PAYMENT_CHOICE_REFUSED_FIELD, StorefrontError, appendParams, clampPercent, classifyPaymentError, createStorefrontClient, declineMessage, declineMessageKey, deliveryInput, deliveryNotices, diagnose, formatMoney, formatVoucherExpiry, generateIdempotencyKey, hreflangLinks, isStorefrontError, isTokenPublishable, maskToken, negotiateLocale, normalizeClientIp, normalizeNote, opsSaysNotRetryable, parseDelivery, parseMoney, parseProductFilters, paymentErrorView, paymentIdempotencyKey, paymentMessages, paymentOutcome, preferredLanguages, productListQuery, promoProgressView, promotionMessages, repairPath, rewardLabel, safeHttpsUrl, storefrontDomainHeader, suggestMarket, toMoney, visitorCountry };
1028
1082
  //# sourceMappingURL=index.js.map
1029
1083
  //# sourceMappingURL=index.js.map