@asteby/storefront 0.5.0 → 0.6.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.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { GeoPoint } from './geo.js';
2
2
  export { OpenStatus, OpeningHours } from './geo.js';
3
- import { $ as ProductSort, a7 as Shop, Z as ProductConnection, W as Product, q as Connection, p as Collection, G as LocationListParams, L as Location, O as NearestLocation, ab as StockLevel, i as CartLineInput, C as Cart, k as CartLineUpdateInput, d as CartBuyerInput, a as AddressInput, w as DeliveryOptions, U as PaymentMethods, D as DeliveryInput, m as CheckoutInput, o as CheckoutResult, s as CustomerIdentifier, u as CustomerSessionInput, t as CustomerSession, r as Customer, P as Order, a2 as ReturnRequestInput, a1 as ReturnRequest, y as InvoiceRequest, z as InvoiceResult, A as Address, ae as Theme, R as Page, M as Menu, b as Article, ad as StorefrontErrorCode, K as Money } from './types-BmC-RDo8.js';
4
- export { c as CartBuyer, e as CartCost, f as CartDelivery, g as CartDiscountCode, h as CartLine, j as CartLineMerchandise, l as CheckoutInfo, n as CheckoutPayment, v as DeliveryMethod, F as Facet, x as FacetValue, I as Image, B as LocationContacts, E as LocationKind, H as LocationPickup, J as MenuItem, N as MoneyRange, Q as OrderLine, S as PageInfo, T as PaymentMethod, V as PickupOption, X as ProductAttributeValue, Y as ProductCategory, _ as ProductOption, a0 as ProductVariant, a3 as SEO, a4 as Section, a5 as SelectedOption, a6 as ShippingRate, a8 as ShopBranch, a9 as ShopContact, aa as ShopPolicies, ac as StorefrontErrorBody, af as UnavailableRateProvider } from './types-BmC-RDo8.js';
3
+ import { am as ProductSort, aB as Shop, ak as ProductConnection, ah as Product, x as Connection, w as Collection, S as LocationListParams, P as Location, Y as NearestLocation, aF as StockLevel, at as RestockSubscriptionInput, au as RestockSubscriptionResult, l as CartLineInput, C as Cart, o as CartLineUpdateInput, f as CartBuyerInput, a as AddressInput, H as DeliveryOptions, a9 as PaymentMethods, F as DeliveryInput, as as RecommendationPlacement, r as CartRecommendations, t as CheckoutInput, v as CheckoutResult, ar as PromotionsList, a6 as PaymentConfig, ae as PaymentSubmitInput, a2 as PaymentAttemptResult, z as CustomerIdentifier, D as CustomerSessionInput, B as CustomerSession, y as Customer, Z as Order, aw as ReturnRequestInput, av as ReturnRequest, N as InvoiceRequest, O as InvoiceResult, A as Address, aI as Theme, $ as Page, U as Menu, b as Article, aH as StorefrontErrorCode, M as InsufficientStockLine, W as Money, d as AvailabilityStatus, n as CartLineProblem, c as Availability, an as ProductVariant, E as DeclineCode, af as PaymentVoucher, aa as PaymentNextStep, p as CartPromotions, ap as PromotionReward } from './types-iGGZ9EiC.js';
4
+ export { e as CartBuyer, g as CartCost, h as CartDelivery, i as CartDiscountCode, j as CartDiscountLine, k as CartLine, m as CartLineMerchandise, q as CartRecommendation, s as CheckoutInfo, u as CheckoutPayment, G as DeliveryMethod, I as Facet, J as FacetValue, K as Image, L as InsufficientStockDetails, Q as LocationContacts, R as LocationKind, T as LocationPickup, V as MenuItem, X as MoneyRange, _ as OrderLine, a0 as PageInfo, a1 as PaymentAction, a3 as PaymentAttemptStatus, a4 as PaymentClient, a5 as PaymentClientCsp, a7 as PaymentFlow, a8 as PaymentMethod, ab as PaymentOption, ac as PaymentOptionKey, ad as PaymentPoint, ag as PickupOption, ai as ProductAttributeValue, aj as ProductCategory, al as ProductOption, ao as PromotionAnnouncement, aq as PromotionTier, ax as SEO, ay as Section, az as SelectedOption, aA as ShippingRate, aC as ShopBranch, aD as ShopContact, aE as ShopPolicies, aG as StorefrontErrorBody, aJ as UnavailableRateProvider } from './types-iGGZ9EiC.js';
5
5
 
6
6
  type QueryValue = string | number | boolean | null | undefined;
7
7
  type QueryParams = Record<string, QueryValue | QueryValue[]>;
@@ -193,6 +193,13 @@ declare function createStorefrontClient(config: StorefrontClientOptions): {
193
193
  nodes: StockLevel[];
194
194
  }>;
195
195
  };
196
+ restock: {
197
+ /**
198
+ * "Notify me when it is back". Idempotent per contact + SKU; always answers `202 pending`.
199
+ * Only offered when `availability.notify_available` is true. Needs `customer:write`.
200
+ */
201
+ subscribe: (input: RestockSubscriptionInput, options?: WriteOptions) => Promise<RestockSubscriptionResult>;
202
+ };
196
203
  carts: {
197
204
  create: (input?: {
198
205
  lines?: CartLineInput[];
@@ -210,10 +217,34 @@ declare function createStorefrontClient(config: StorefrontClientOptions): {
210
217
  /** Payment providers active for the cart's market; send the chosen `key` as `payment_method`. */
211
218
  paymentMethods: (id: string, options?: RequestOptions) => Promise<PaymentMethods>;
212
219
  setDelivery: (id: string, delivery: DeliveryInput, options?: WriteOptions) => Promise<Cart>;
220
+ /** Order note (up to 1000 characters). `null` or empty clears it. */
221
+ setNote: (id: string, note: string | null, options?: WriteOptions) => Promise<Cart>;
222
+ /**
223
+ * Cross-sell suggestions: only sellable variants, with `unlocks` when adding one reaches the next
224
+ * discount tier. `first` 1-8 (default 4). `private, no-store`; ask on demand, not on every render.
225
+ */
226
+ recommendations: (id: string, params?: {
227
+ first?: number;
228
+ placement?: RecommendationPlacement;
229
+ }, options?: RequestOptions) => Promise<CartRecommendations>;
213
230
  /** Reserves stock and creates the order. Sends `Idempotency-Key` (auto-generated if omitted). */
214
231
  checkout: (id: string, input: CheckoutInput, options?: WriteOptions) => Promise<CheckoutResult>;
215
232
  };
233
+ promotions: {
234
+ /** Public promotions and the entry pop-up announcement for the request's market (cacheable). */
235
+ list: (options?: RequestOptions) => Promise<PromotionsList>;
236
+ };
216
237
  checkouts: {
238
+ /** What to mount for an embedded checkout (public key, options, amount) and whether it can still be paid. Never cache. */
239
+ paymentConfig: (id: string, options?: RequestOptions) => Promise<PaymentConfig | null>;
240
+ /**
241
+ * Pays a checkout in the page. The browser brings only what the provider SDK returned (`provider_data`);
242
+ * the amount is the server's. `idempotencyKey` is REQUIRED (use `paymentIdempotencyKey(checkoutId, attempt)`):
243
+ * repeating a call with the same key never charges twice. Needs a server token (`checkout:write`).
244
+ */
245
+ pay: (id: string, input: PaymentSubmitInput, options: WriteOptions & {
246
+ idempotencyKey: string;
247
+ }) => Promise<PaymentAttemptResult>;
217
248
  /**
218
249
  * Reads a placed checkout (same shape as the `carts.checkout` result). `order.number` is `null` until OPS
219
250
  * has created the order (a few hundred ms after checkout); poll once or twice and, if it is still `null`,
@@ -260,6 +291,8 @@ type StorefrontErrorInit = {
260
291
  code: StorefrontErrorCode;
261
292
  message: string;
262
293
  field?: string;
294
+ /** Raw `error.details` from the body (untrusted shape). */
295
+ details?: unknown;
263
296
  /** Request URL that failed (without credentials). */
264
297
  url?: string;
265
298
  cause?: unknown;
@@ -273,8 +306,15 @@ declare class StorefrontError extends Error {
273
306
  readonly status: number;
274
307
  readonly code: StorefrontErrorCode;
275
308
  readonly field: string | undefined;
309
+ readonly details: unknown;
276
310
  readonly url: string | undefined;
277
311
  constructor(init: StorefrontErrorInit);
312
+ /**
313
+ * Affected lines of a `409 insufficient_stock` (empty for any other error or a
314
+ * server older than contract 1.1). The cart is untouched: show the lines and
315
+ * let the buyer adjust or remove them.
316
+ */
317
+ get stockLines(): InsufficientStockLine[];
278
318
  toJSON(): {
279
319
  name: string;
280
320
  status: number;
@@ -308,4 +348,229 @@ declare function toMoney(value: number, currencyCode: string): Money;
308
348
  */
309
349
  declare function isTokenPublishable(token: string | null | undefined): boolean;
310
350
 
311
- export { Address, AddressInput, Article, type ArticleListParams, CLIENT_IP_HEADER, Cart, CartBuyerInput, CartLineInput, CartLineUpdateInput, CheckoutInput, CheckoutResult, Collection, type CollectionListParams, Connection, Customer, CustomerIdentifier, CustomerSession, CustomerSessionInput, DeliveryInput, DeliveryOptions, type FetchLike, type FormatMoneyOptions, GeoPoint, InvoiceRequest, InvoiceResult, Location, LocationListParams, Menu, Money, NearestLocation, Order, Page, type PaginationParams, PaymentMethods, type PreviewOptions, Product, ProductConnection, type ProductListParams, ProductSort, type QueryParams, type QueryValue, type RequestOptions, ReturnRequest, ReturnRequestInput, Shop, StockLevel, type StorefrontClient, type StorefrontClientOptions, StorefrontError, StorefrontErrorCode, type StorefrontErrorInit, type StorefrontRequestContext, type StorefrontResponseContext, Theme, type WriteOptions, appendParams, createStorefrontClient, formatMoney, generateIdempotencyKey, isStorefrontError, isTokenPublishable, normalizeClientIp, parseMoney, parseProductFilters, productListQuery, toMoney };
351
+ /**
352
+ * Availability presentation: the single source of the texts and states a
353
+ * storefront shows for stock. Pure functions, no DOM: safe in loaders, SSR and
354
+ * edge runtimes.
355
+ *
356
+ * The server decides the state (`Availability.status`, already filtered by the
357
+ * shop's `show_stock`); this module only turns it into labels. Shops may
358
+ * override texts by key (`messages`) but never the logic. Numbers shown here
359
+ * ("Quedan 3") come from `availability.quantity`, which the server sends only
360
+ * when the shop allows it and past its own threshold: there is no threshold in
361
+ * this code.
362
+ */
363
+
364
+ type AvailabilityTone = 'success' | 'warning' | 'danger' | 'info';
365
+ type AvailabilityLocale = 'es' | 'en';
366
+ /** Text keys, overridable per shop. `{n}` and `{date}` are replaced. */
367
+ type AvailabilityMessageKey = 'status.in_stock' | 'status.low_stock' | 'status.low_stock_n' | 'status.out_of_stock' | 'status.backorder' | 'status.preorder' | 'sub.backorder_eta' | 'sub.preorder_date' | 'cta.add' | 'cta.out_of_stock' | 'cta.backorder' | 'cta.preorder' | 'sr.in_stock' | 'sr.low_stock' | 'sr.low_stock_n' | 'sr.out_of_stock' | 'sr.backorder' | 'sr.preorder' | 'option.sold_out' | 'option.backorder' | 'option.preorder' | 'max_per_order' | 'notify.title' | 'notify.email' | 'notify.phone' | 'notify.consent' | 'notify.submit' | 'notify.done' | 'notify.error' | 'problem.out_of_stock' | 'problem.insufficient_stock' | 'problem.insufficient_stock_n' | 'problem.adjust' | 'problem.remove' | 'conflict.title' | 'conflict.body' | 'conflict.dismiss';
368
+ type AvailabilityMessages = Record<AvailabilityMessageKey, string>;
369
+ /** `es-MX` -> `es`, `en-US` -> `en`; anything else falls back to Spanish. */
370
+ declare function availabilityLocale(locale: string | null | undefined): AvailabilityLocale;
371
+ /** Catalog for a locale with the shop's per-key overrides applied. */
372
+ declare function availabilityMessages(locale: string | null | undefined, overrides?: Partial<AvailabilityMessages> | null): AvailabilityMessages;
373
+ /** Replaces `{name}` placeholders. */
374
+ declare function formatAvailabilityMessage(template: string, values?: Record<string, string | number>): string;
375
+ type ResolveAvailabilityOptions = {
376
+ /**
377
+ * Polyfill only: shop-level "low stock" threshold to derive `low_stock` from
378
+ * `quantity_available` on servers older than contract 1.1. Without it the
379
+ * polyfill never reports `low_stock`. Ignored when the server sends `availability`.
380
+ */
381
+ lowStockThreshold?: number | null;
382
+ };
383
+ type AvailabilitySource = Pick<Product | ProductVariant, 'available_for_sale'> & {
384
+ availability?: Availability | null;
385
+ quantity_available?: number | null;
386
+ };
387
+ /**
388
+ * The `Availability` of a variant or product. Uses the server's `availability`
389
+ * when present; otherwise derives `in_stock | low_stock | out_of_stock` from
390
+ * `available_for_sale` / `quantity_available` so storefronts can migrate before
391
+ * the backend does. A malformed `availability` falls back to the polyfill.
392
+ */
393
+ declare function resolveAvailability(source: AvailabilitySource, options?: ResolveAvailabilityOptions): Availability;
394
+ type AvailabilityView = {
395
+ status: AvailabilityStatus;
396
+ tone: AvailabilityTone;
397
+ /** Short badge text: "Agotado", "Quedan 3", "Bajo pedido"... Never empty. */
398
+ label: string;
399
+ /** ETA / release date text, or `null`. */
400
+ sublabel: string | null;
401
+ /** Primary button text. */
402
+ ctaLabel: string;
403
+ /** The primary button may be pressed (backorder/preorder are purchasable). */
404
+ ctaEnabled: boolean;
405
+ /** Offer the "Notify me when it is back" form. */
406
+ showNotify: boolean;
407
+ /** Full sentence for screen readers. */
408
+ srText: string;
409
+ /** Units to cap the quantity picker at, or `null`. */
410
+ maxPerOrder: number | null;
411
+ /** Show a badge on listing cards (everything but plain `in_stock`: do not clutter). */
412
+ showOnCard: boolean;
413
+ };
414
+ type AvailabilityViewOptions = {
415
+ messages?: Partial<AvailabilityMessages> | null;
416
+ };
417
+ /**
418
+ * Texts and flags for one availability. `availability` accepts anything with an
419
+ * unknown `status` (a future server): it is treated as `out_of_stock`.
420
+ */
421
+ declare function availabilityView(availability: Availability, locale: string | null | undefined, options?: AvailabilityViewOptions): AvailabilityView;
422
+ type CartLineProblemView = {
423
+ code: CartLineProblem['code'];
424
+ /** "Ya no hay existencias" / "Solo puedes llevar 2". */
425
+ message: string;
426
+ /** Quantity to adjust the line to, or `null` (remove only). */
427
+ adjustTo: number | null;
428
+ adjustLabel: string | null;
429
+ removeLabel: string;
430
+ };
431
+ /** Texts and actions for a cart line problem. Offers "Adjust to N" only when `max_quantity` is a positive number different from the line quantity (a refused change leaves the cart at its old quantity). */
432
+ declare function cartLineProblemView(problem: CartLineProblem | InsufficientStockLine, locale: string | null | undefined, options?: AvailabilityViewOptions & {
433
+ lineQuantity?: number;
434
+ }): CartLineProblemView;
435
+ /** schema.org `ItemAvailability` URL for a status (unknown -> `OutOfStock`). */
436
+ declare function schemaAvailability(status: AvailabilityStatus | string): string;
437
+ /** Best state among variants for a product summary (when the server sends none). */
438
+ declare function productAvailability(product: Pick<Product, 'variants' | 'available_for_sale' | 'availability'>, options?: ResolveAvailabilityOptions): Availability;
439
+
440
+ /**
441
+ * Embedded payment presentation: the single source of the texts and states a
442
+ * storefront shows around an in-page payment. Pure functions, no DOM: safe in
443
+ * loaders, SSR and edge runtimes.
444
+ *
445
+ * Rules this module encodes (DISENO-PAGO-INTEGRADO-BRICKS):
446
+ * - The server decides the outcome and the amount. Nothing here computes or
447
+ * compares money; `expected_total` is the server's own number echoed back.
448
+ * - A rejection is explained with an actionable text built from the neutral
449
+ * `decline_code`. A raw provider code is never shown.
450
+ * - Vouchers and redirects only trust https URLs.
451
+ */
452
+
453
+ type PaymentLocale = AvailabilityLocale;
454
+ type PaymentMessageKey = `decline.${DeclineCode}` | 'state.loading' | 'state.processing' | 'state.approved' | 'state.in_review' | 'state.voucher' | 'state.challenge' | 'state.expired' | 'state.cancelled' | 'state.redirect' | 'state.fallback' | 'error.network' | 'error.card_data' | 'error.price_mismatch' | 'error.payment_in_progress' | 'error.expired' | 'error.too_many_attempts' | 'error.generic' | 'action.retry' | 'action.try_again' | 'action.pay' | 'action.cancel' | 'voucher.title' | 'voucher.point' | 'voucher.reference' | 'voucher.amount' | 'voucher.expires' | 'voucher.clabe' | 'voucher.barcode' | 'voucher.open' | 'voucher.email' | 'form.label' | 'challenge.title';
455
+ type PaymentMessages = Record<PaymentMessageKey, string>;
456
+ /** Catalog for a locale (`es-MX` -> es, `en-US` -> en) with the shop's per-key overrides applied. */
457
+ declare function paymentMessages(locale: string | null | undefined, overrides?: Partial<PaymentMessages> | null): PaymentMessages;
458
+ /** i18n key of a decline code; unknown or missing codes map to `declined` (never a raw provider code). */
459
+ declare function declineMessageKey(code: string | null | undefined): `decline.${DeclineCode}`;
460
+ /** Actionable text for a decline code. */
461
+ declare function declineMessage(code: string | null | undefined, locale?: string | null, overrides?: Partial<PaymentMessages> | null): string;
462
+ /** The value only if it is an absolute `https:` URL without credentials; `null` otherwise. */
463
+ declare function safeHttpsUrl(value: unknown): string | null;
464
+ /** What the UI should do with an attempt result. */
465
+ type PaymentOutcomeKind = 'approved' | 'in_review' | 'voucher' | 'challenge' | 'redirect' | 'rejected' | 'expired' | 'cancelled';
466
+ /** A voucher ready to render: https-only link and the amount as `Money` (or `null` when the server sent none). */
467
+ type PaymentOutcomeVoucher = Omit<PaymentVoucher, 'amount' | 'voucher_url' | 'currency'> & {
468
+ voucher_url: string | null;
469
+ amount: Money | null;
470
+ };
471
+ type PaymentOutcome = {
472
+ kind: PaymentOutcomeKind;
473
+ /** Text for the buyer (no codes). */
474
+ message: string;
475
+ decline_code: DeclineCode | null;
476
+ /** `true` when the buyer can try again with the checkout still open. */
477
+ retryable: boolean;
478
+ /** https-only. */
479
+ redirect_url: string | null;
480
+ challenge: {
481
+ url: string | null;
482
+ creq: string | null;
483
+ } | null;
484
+ voucher: PaymentOutcomeVoucher | null;
485
+ attempts_left: number | null;
486
+ /** What to do next (server value, or derived from the decline code): fix the card, use another, rebuild the cart... */
487
+ next_step: PaymentNextStep | null;
488
+ };
489
+ /**
490
+ * Classifies an attempt result. Unknown statuses are treated as `in_review`
491
+ * (never as approved, never as a reason to charge again).
492
+ */
493
+ declare function paymentOutcome(result: PaymentAttemptResult, locale?: string | null, overrides?: Partial<PaymentMessages> | null): PaymentOutcome;
494
+ /** Failures of `POST /payment` the form maps to a specific text and next step. */
495
+ type PaymentErrorKind = 'network' | 'price_mismatch' | 'payment_in_progress' | 'expired' | 'too_many_attempts' | 'generic';
496
+ type PaymentErrorView = {
497
+ kind: PaymentErrorKind;
498
+ message: string;
499
+ retrySameAttempt: boolean;
500
+ canRetry: boolean;
501
+ };
502
+ /**
503
+ * Maps a transport error (a `StorefrontError` or anything with `status`/`code`)
504
+ * to a view. Network failures and 502/503/504 are safe to retry with the same
505
+ * idempotency key; 409/422/429 are answers, not outages.
506
+ */
507
+ declare function paymentErrorView(err: unknown, locale?: string | null, overrides?: Partial<PaymentMessages> | null): PaymentErrorView;
508
+ /** `Vence el 5 de noviembre de 2026, 18:00` style text for a voucher deadline; `null` when absent or invalid. */
509
+ declare function formatVoucherExpiry(expiresAt: string | null | undefined, locale?: string | null, overrides?: Partial<PaymentMessages> | null): string | null;
510
+ /** Builds an idempotency key for a payment attempt: the same attempt always yields the same key. */
511
+ declare function paymentIdempotencyKey(checkoutId: string, attempt: string): string;
512
+
513
+ /**
514
+ * Promotion presentation: turns `Cart.promotions` (computed by OPS) into the
515
+ * labels and bar states a storefront shows. Pure functions, no DOM.
516
+ *
517
+ * The shop never computes a discount here: `remaining`, `percent`, `reached`
518
+ * and `percent_of_max` are the server's. The only arithmetic is clamping a
519
+ * server percentage into 0-100 for `aria-valuenow`.
520
+ */
521
+
522
+ type PromotionLocale = AvailabilityLocale;
523
+ type PromotionMessageKey = 'discount.next' | 'discount.next_upgrade' | 'discount.applied' | 'discount.max' | 'discount.suppressed' | 'discount.unlocks' | 'discount.remaining' | 'shipping.progress' | 'shipping.reached' | 'shipping.always' | 'reward.free_shipping' | 'bar.discount' | 'bar.shipping' | 'popup.close' | 'popup.valid_until' | 'popup.limited_time' | 'popup.discount_tier' | 'popup.free_shipping_min' | 'popup.free_shipping_always' | 'upsell.title' | 'upsell.subtitle' | 'upsell.next_level' | 'upsell.you_miss' | 'upsell.unlocks_reward' | 'upsell.total_saved' | 'upsell.current_benefit' | 'upsell.status' | 'upsell.status_pending' | 'upsell.status_active' | 'upsell.next_reward' | 'upsell.suggestions' | 'upsell.add' | 'upsell.adding' | 'upsell.flavor' | 'upsell.unlocks_badge' | 'upsell.unlocked' | 'upsell.best' | 'upsell.skip' | 'upsell.continue' | 'upsell.footer' | 'upsell.sold_out' | 'upsell.error' | 'note.label' | 'note.placeholder' | 'note.save' | 'note.saving' | 'note.saved' | 'note.error' | 'note.counter';
524
+ type PromotionMessages = Record<PromotionMessageKey, string>;
525
+ /** Catalog for a locale with the shop's per-key overrides applied. */
526
+ declare function promotionMessages(locale: string | null | undefined, overrides?: Partial<PromotionMessages> | null): PromotionMessages;
527
+ /** Order-note limit enforced by the server (`validateNote`). */
528
+ declare const NOTE_MAX_LENGTH = 1000;
529
+ /** Trims and caps a note; empty becomes `null` (the server clears the note). */
530
+ declare function normalizeNote(note: string | null | undefined): string | null;
531
+ /** `5 %` / `7.5 %` (es) or `5%` (en) / `$250` / `Envío gratis`. The values are the server's. */
532
+ declare function rewardLabel(reward: PromotionReward, locale?: string | null, overrides?: Partial<PromotionMessages> | null): string;
533
+ /** Display clamp for a server percentage (`aria-valuenow`). Not a calculation. */
534
+ declare function clampPercent(value: unknown): number;
535
+ type DiscountBarState = 'next' | 'upgrade' | 'max' | 'suppressed';
536
+ type DiscountBarView = {
537
+ state: DiscountBarState;
538
+ /** Server progress 0-100. */
539
+ percent: number;
540
+ text: string;
541
+ /** `aria-valuetext`. */
542
+ valueText: string;
543
+ remaining: Money | null;
544
+ /** Reward of the next tier (or the applied one at max). */
545
+ rewardText: string | null;
546
+ appliedText: string | null;
547
+ nextText: string | null;
548
+ tiers: {
549
+ id: string;
550
+ label: string;
551
+ threshold: string;
552
+ reached: boolean;
553
+ position: number;
554
+ }[];
555
+ };
556
+ type ShippingBarState = 'progress' | 'reached' | 'always';
557
+ type ShippingBarView = {
558
+ state: ShippingBarState;
559
+ percent: number;
560
+ text: string;
561
+ valueText: string;
562
+ remaining: Money | null;
563
+ /** `false` for `always`: there is nothing to fill. */
564
+ showBar: boolean;
565
+ };
566
+ type PromoProgressView = {
567
+ discount: DiscountBarView | null;
568
+ shipping: ShippingBarView | null;
569
+ };
570
+ /**
571
+ * Bars of the cart and the pre-payment modal. Both read the same `Cart.promotions`,
572
+ * so they can never disagree. `null`/absent promotions give `{ discount: null, shipping: null }`.
573
+ */
574
+ declare function promoProgressView(promotions: CartPromotions | null | undefined, locale?: string | null, overrides?: Partial<PromotionMessages> | null): PromoProgressView;
575
+
576
+ export { Address, AddressInput, Article, type ArticleListParams, Availability, type AvailabilityLocale, type AvailabilityMessageKey, type AvailabilityMessages, AvailabilityStatus, type AvailabilityTone, type AvailabilityView, type AvailabilityViewOptions, CLIENT_IP_HEADER, Cart, CartBuyerInput, CartLineInput, CartLineProblem, type CartLineProblemView, CartLineUpdateInput, CartPromotions, CartRecommendations, CheckoutInput, CheckoutResult, Collection, type CollectionListParams, Connection, Customer, CustomerIdentifier, CustomerSession, CustomerSessionInput, DeclineCode, DeliveryInput, DeliveryOptions, type DiscountBarState, type DiscountBarView, type FetchLike, type FormatMoneyOptions, GeoPoint, InsufficientStockLine, InvoiceRequest, InvoiceResult, Location, LocationListParams, 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, 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, type WriteOptions, appendParams, availabilityLocale, availabilityMessages, availabilityView, cartLineProblemView, clampPercent, createStorefrontClient, declineMessage, declineMessageKey, formatAvailabilityMessage, formatMoney, formatVoucherExpiry, generateIdempotencyKey, isStorefrontError, isTokenPublishable, normalizeClientIp, normalizeNote, parseMoney, parseProductFilters, paymentErrorView, paymentIdempotencyKey, paymentMessages, paymentOutcome, productAvailability, productListQuery, promoProgressView, promotionMessages, resolveAvailability, rewardLabel, safeHttpsUrl, schemaAvailability, toMoney };