@asteby/storefront 0.16.1 → 0.18.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/README.md CHANGED
@@ -408,6 +408,30 @@ a rule that produces a `discard_fields` field. `qr_canonical` (top level) is a t
408
408
  (`fiscal_regime`, `invoice_use`). A text that does not match yields `missing` (required fields); only a spec that cannot
409
409
  run throws `IdentityRulesError`.
410
410
 
411
+ ## Buyer items: «My items» / «My garage» (Storefront API 1.9)
412
+
413
+ A **subject** is something the buyer shops for: a vehicle, a printer, a phone, a pet, a size. WHICH kinds a store has is data the organization publishes (`content.subjectKinds()`); the SDK names none. A store that declares none (`customer.capabilities().subjects` absent, `subjectKinds()` empty) has no such section: show nothing.
414
+
415
+ ```ts
416
+ const kinds = await sf.content.subjectKinds() // [] when the store declares none (or the server is older)
417
+ const me = sf.withCustomerToken(token)
418
+ const item = await me.customer.subjects.create({ kind: 'vehicle', attributes: { make: 'nissan', model: 'np300', year: 2012, engine: '2.5', plate: 'ABC-123' } })
419
+ item.label // 'Nissan NP300 Frontier 2012 2.5 L' (built by the server from the catalog and the PUBLIC values)
420
+ item.fit_key // 'nissan/np300/2012/2.5' (the `fit:<key>` tag of the products; '' if it does not resolve completely)
421
+ item.attributes.plate // '••23' (a `private` field is returned masked, always)
422
+
423
+ // Only the parts that fit: its own tag plus the universal one.
424
+ await sf.products.list({ tags_any: fitTagsAny(item.fit_key) }) // ?tags_any=fit:nissan/np300/2012/2.5,fit:universal
425
+ ```
426
+
427
+ - `customer.subjects.list({ kind? })`, `create`, `update(id, patch)` (attributes merge; `null` clears a field; a private value sent back as its mask is kept), `delete(id)`. Errors: `422` with `field: 'attributes.<field>'` (never the value), `409` repeated or past the limit, `429` too many saves, `404` for an item that is not the buyer's.
428
+ - **Privacy**: a `private` field (a licence plate) is stored for the buyer and never enters the label, the key, a filter, a cache key, a cookie or an order. Never prefill it from the server (it only comes masked, `isMasked`), never log it, never put it in a URL.
429
+ - Pure helpers (`@asteby/storefront`), no UI: `subjectOptions(kind, field, values)` (the cascade), `reconcileSubjectValues`, `resolveSubject(kind, values)` (the same validation as the server, so the form answers without a round trip; the server stays the authority), `fitTagsAny`, `fitTag`, `isMasked`.
430
+ - `splitSubjectTree(tree, maxBytes?)`: a catalog larger than one page (a page is one 64 KiB write with the draft and the published copy, ~28 KB of tree) is published as several `subject_catalog` pages, split by its first level; the kind names them all (`catalog_ref: ["page:x-1", "page:x-2"]`) and the server joins them.
431
+ - Catalog: the levels of the tree follow the kind's `catalog` fields that are not years; an option may declare `from`/`to`/`ranges` (model years) and a `year` field must satisfy every option on the chosen path. A year chosen before an engine narrows the engines; an engine never narrows the year.
432
+ - `products.list({ tags_any })`: at most 5 tags of 120 characters, comma-separated on the wire (a tag with a comma is refused by the client); a hard filter, so facets count inside it.
433
+ - Mock: `createMockStorefront({ subjectKinds: MOCK_SUBJECT_KINDS })` serves the kinds and the whole CRUD with the same rules (default: none, like a store that declares nothing).
434
+
411
435
  ## Buyer account: orders, shipments, invoices (Storefront API 1.8)
412
436
 
413
437
  `customer.order(id)` carries `progress` (unified timeline), `next_action`, `shipments[]` (events, carrier, `https`
@@ -375,6 +375,10 @@ type DeliveryOptions = {
375
375
  /** `true` when some provider failed: `rates` holds only what arrived. */
376
376
  partial?: boolean;
377
377
  unavailable?: UnavailableRateProvider[];
378
+ /** The shop's own fixed price: no carrier was asked (addon setting `shipping_quote_mode`). */
379
+ fixed?: boolean;
380
+ /** Every shipping rate costs 0 (free-shipping minimum reached): nothing to choose, show "Free shipping" and go on. */
381
+ free?: boolean;
378
382
  };
379
383
  /** One way to pay (`GET /storefront/carts/:id/payment-methods`). `key` is sent as `payment_method` at checkout. */
380
384
  type PaymentMethod = {
@@ -494,6 +498,10 @@ type Customer = {
494
498
  /** Saved fiscal data; `null`/absent when none. */
495
499
  fiscal?: FiscalIdentity | null;
496
500
  created_at: string;
501
+ /** Preferred language, one of the store's (contract 1.9). Absent on older servers. */
502
+ locale?: string | null;
503
+ /** Notification preferences (contract 1.9). Absent on older servers. */
504
+ preferences?: CustomerPreferences;
497
505
  };
498
506
  type CustomerIdentifier = {
499
507
  email: string;
@@ -531,6 +539,22 @@ type CustomerCapabilities = {
531
539
  fiscal_profiles?: {
532
540
  max: number;
533
541
  };
542
+ /**
543
+ * The kinds of saved item the store declares («My items»; contract 1.9). Absent when the store declares none (or on
544
+ * older servers): there is no such section, show nothing.
545
+ */
546
+ subjects?: {
547
+ kinds: string[];
548
+ share_with_workshop?: boolean;
549
+ };
550
+ /** Channels the notification preferences can use (connector installed). Absent on older servers: no preferences section. */
551
+ notifications?: {
552
+ channels: string[];
553
+ };
554
+ /** The buyer can download their data (`customer.exportData`). Absent on older servers. */
555
+ data_export?: boolean;
556
+ /** The buyer can delete their account (`customer.deleteAccount`). Absent on older servers. */
557
+ account_delete?: boolean;
534
558
  };
535
559
  /** `GET {gateway}/_token`: what the token in use is and what it can do. Needs no scope. */
536
560
  type TokenIntrospection = {
@@ -1379,12 +1403,101 @@ type FiscalProfileInput = Partial<FiscalIdentityInput> & {
1379
1403
  label?: string;
1380
1404
  is_default?: boolean;
1381
1405
  };
1406
+ /**
1407
+ * A subject is something the buyer shops for: a vehicle, a printer, a phone, a pet, a size. WHICH kinds exist is
1408
+ * data the organization publishes (`content.subjectKinds()`); nothing in the SDK or the contract names one. A store
1409
+ * with no kinds has no such section.
1410
+ */
1411
+ type SubjectFieldType = 'text' | 'year' | 'select';
1412
+ type SubjectField = {
1413
+ key: string;
1414
+ label: string;
1415
+ type: SubjectFieldType;
1416
+ /** `catalog`: the value is an option of the kind's catalog (a `year` is checked against the options' years). Default `free`. */
1417
+ source?: 'catalog' | 'free';
1418
+ /** The field whose choice narrows this one (the cascade order). */
1419
+ depends_on?: string | null;
1420
+ required?: boolean;
1421
+ /**
1422
+ * Stored for the buyer and NEVER part of the label, the compatibility key, a filter, a cache key, a cookie or an
1423
+ * order (a licence plate). The server returns it only masked (`••34`): never prefill it, never log it.
1424
+ */
1425
+ private?: boolean;
1426
+ max?: number;
1427
+ };
1428
+ /**
1429
+ * One option of a catalog level (make, model, engine…). `from`/`to`/`ranges` bound the model years it covers: a
1430
+ * `year` field must satisfy every option on the chosen path that declares them.
1431
+ */
1432
+ type SubjectCatalogNode = {
1433
+ label: string;
1434
+ from?: number;
1435
+ to?: number;
1436
+ ranges?: [number, number][];
1437
+ children?: Record<string, SubjectCatalogNode>;
1438
+ };
1439
+ /** The cascade of options of a kind: levels follow the kind's `catalog` fields that are not years. */
1440
+ type SubjectCatalog = {
1441
+ version?: string | null;
1442
+ tree: Record<string, SubjectCatalogNode>;
1443
+ };
1444
+ type SubjectKind = {
1445
+ key: string;
1446
+ /** Singular («Vehicle»). */
1447
+ label: string;
1448
+ /** The section's name («My garage»). */
1449
+ label_plural: string;
1450
+ max_per_account: number;
1451
+ fields: SubjectField[];
1452
+ /** Template of the compatibility key with the fields in braces (public ones only). */
1453
+ fit_key_template: string;
1454
+ /** The checkout may ask «which one is this order for?». */
1455
+ attach_to_order?: boolean;
1456
+ /** `null` for kinds with free fields only. */
1457
+ catalog?: SubjectCatalog | null;
1458
+ };
1459
+ /** A saved item. `attributes` holds the public values; private ones come masked (`••34`). */
1460
+ type Subject = {
1461
+ id: string;
1462
+ kind: string;
1463
+ /** Public label built by the server from the catalog and the public values. */
1464
+ label: string;
1465
+ nickname?: string | null;
1466
+ /** Compatibility key (the `fit:<key>` tag of the products); `''` when the item does not resolve completely. */
1467
+ fit_key: string;
1468
+ attributes: Record<string, unknown>;
1469
+ /** The active item of its kind. */
1470
+ is_default: boolean;
1471
+ last_used_at?: string | null;
1472
+ created_at: string;
1473
+ };
1474
+ type SubjectInput = {
1475
+ kind: string;
1476
+ attributes: Record<string, unknown>;
1477
+ nickname?: string | null;
1478
+ is_default?: boolean;
1479
+ };
1480
+ /** Merged over the stored item: `null` clears a field; a private value sent back as its mask is kept. */
1481
+ type SubjectPatch = {
1482
+ attributes?: Record<string, unknown>;
1483
+ nickname?: string | null;
1484
+ is_default?: boolean;
1485
+ };
1486
+ /** The item an order is for (kinds with `attach_to_order`). */
1487
+ type SubjectRef = {
1488
+ kind: string;
1489
+ id: string;
1490
+ };
1382
1491
  /** `PATCH /customer`. `fiscal: null` deletes the saved fiscal data (ARCO). */
1383
1492
  type CustomerUpdateInput = {
1384
1493
  first_name?: string | null;
1385
1494
  last_name?: string | null;
1386
1495
  phone?: string | null;
1387
1496
  fiscal?: FiscalIdentityInput | null;
1497
+ /** One of the store's languages (`400` with `field: 'locale'` otherwise); `null` clears it. */
1498
+ locale?: string | null;
1499
+ /** Merged by event and channel; `null` restores the defaults. `400` for an event that cannot be turned off. */
1500
+ preferences?: CustomerPreferences | null;
1388
1501
  };
1389
1502
  /** Post-processing: the value must match `pattern`; `group` of it replaces the value. */
1390
1503
  type IdentityCapture = {
@@ -1448,4 +1561,131 @@ type IdentityRulesV1 = {
1448
1561
  fields: IdentityFieldRule[];
1449
1562
  };
1450
1563
 
1451
- export type { IdentityCapture as $, Address as A, CustomerCapabilities as B, Cart as C, CustomerIdentifier as D, CustomerPasswordLoginInput as E, CustomerRegisterInput as F, CustomerRegisterResult as G, CustomerResetPasswordInput as H, CustomerSession as I, CustomerSessionInput as J, CustomerSetPasswordInput as K, CustomerUpdateInput as L, CustomerVerifyRegistrationInput as M, DeclineCode as N, DeliveryInput as O, DeliveryMethod as P, DeliveryOptions as Q, Facet as R, FacetValue as S, FiscalDocumentEvidence as T, FiscalDocumentSource as U, FiscalIdentity as V, FiscalIdentityInput as W, FiscalProfile as X, FiscalProfileInput as Y, FiscalVerification as Z, GeoHint as _, AddressInput as a, ProductOption as a$, IdentityDocumentSpec as a0, IdentityFieldRule as a1, IdentityRulesV1 as a2, IdentityStrategy as a3, Image as a4, InsufficientStockDetails as a5, InsufficientStockLine as a6, InvoiceAction as a7, InvoiceDoc as a8, InvoiceFile as a9, OrderStepKey as aA, OrderStepState as aB, Page as aC, PageInfo as aD, PaymentAction as aE, PaymentAttemptResult as aF, PaymentAttemptStatus as aG, PaymentClient as aH, PaymentClientCsp as aI, PaymentConfig as aJ, PaymentFlow as aK, PaymentInfo as aL, PaymentMethod as aM, PaymentMethods as aN, PaymentNextStep as aO, PaymentOption as aP, PaymentOptionKey as aQ, PaymentPoint as aR, PaymentSubmitInput as aS, PaymentVoucher as aT, PendingPayment as aU, PendingPaymentVoucher as aV, PickupOption as aW, Product as aX, ProductAttributeValue as aY, ProductCategory as aZ, ProductConnection as a_, InvoiceFileKind as aa, InvoiceRequest as ab, InvoiceResult as ac, InvoiceStage as ad, InvoiceSummary as ae, InvoicingCapabilities as af, Location as ag, LocationContacts as ah, LocationKind as ai, LocationListParams as aj, LocationPickup as ak, Menu as al, MenuItem as am, Money as an, MoneyRange as ao, NearestLocation as ap, NextAction as aq, NextActionKind as ar, Order as as, OrderLine as at, OrderPickup as au, OrderProblem as av, OrderProgress as aw, OrderProgressStep as ax, OrderSection as ay, OrderStage as az, Article as b, ProductSort as b0, ProductVariant as b1, PromotionAnnouncement as b2, PromotionReward as b3, PromotionTier as b4, PromotionsList as b5, RecommendationPlacement as b6, Refund as b7, Region as b8, RegionFiscalEntry as b9, UnavailableRateProvider as bA, RegionFiscalId as ba, RegionPaymentMethod as bb, RegionPostalCode as bc, RestockSubscriptionInput as bd, RestockSubscriptionResult as be, ReturnRequest as bf, ReturnRequestInput as bg, SEO as bh, Section as bi, SelectedOption as bj, Shipment as bk, ShipmentEvent as bl, ShipmentKind as bm, ShipmentMap as bn, ShipmentStatus as bo, ShipmentsSummary as bp, ShippingRate as bq, Shop as br, ShopBranch as bs, ShopContact as bt, ShopPolicies as bu, StockLevel as bv, StorefrontErrorBody as bw, StorefrontErrorCode as bx, Theme as by, TokenIntrospection as bz, Availability as c, AvailabilityStatus as d, CartBuyer as e, CartBuyerInput as f, CartCost as g, CartDelivery as h, CartDiscountCode as i, CartDiscountLine as j, CartInvoice as k, CartLine as l, CartLineInput as m, CartLineMerchandise as n, CartLineProblem as o, CartLineUpdateInput as p, CartPromotions as q, CartRecommendation as r, CartRecommendations as s, CheckoutInfo as t, CheckoutInput as u, CheckoutPayment as v, CheckoutResult as w, Collection as x, Connection as y, Customer as z };
1564
+ type StorefrontErrorInit = {
1565
+ status: number;
1566
+ code: StorefrontErrorCode;
1567
+ message: string;
1568
+ field?: string;
1569
+ /** Raw `error.details` from the body (untrusted shape). */
1570
+ details?: unknown;
1571
+ /** Request URL that failed (without credentials). */
1572
+ url?: string;
1573
+ cause?: unknown;
1574
+ /** Scopes named by the gateway on a `403 insufficient_scope`. */
1575
+ requiredScopes?: string[];
1576
+ /** `error.retryable` as OPS declared it (payment failures). `undefined` = OPS did not say. */
1577
+ retryable?: boolean;
1578
+ /** `error.retry_after` in seconds. */
1579
+ retryAfter?: number;
1580
+ /** `error.checkout_id`: the checkout a refused cart write can resume. */
1581
+ checkoutId?: string;
1582
+ /** `error.cost` of a `price_mismatch` (the cart's current cost; untrusted shape). */
1583
+ cost?: unknown;
1584
+ /** `error.message_en`. */
1585
+ messageEn?: string;
1586
+ };
1587
+ /**
1588
+ * Error thrown by the client for any non-2xx response, network failure,
1589
+ * timeout or abort. `status` is `0` when no HTTP response was received.
1590
+ */
1591
+ declare class StorefrontError extends Error {
1592
+ readonly name = "StorefrontError";
1593
+ readonly status: number;
1594
+ readonly code: StorefrontErrorCode;
1595
+ readonly field: string | undefined;
1596
+ readonly details: unknown;
1597
+ readonly url: string | undefined;
1598
+ /** Scopes a `403 insufficient_scope` says the route needs (empty for any other error). */
1599
+ readonly requiredScopes: string[];
1600
+ /** `true`: repeating the request (same idempotency key) can succeed. `false`: not until someone fixes something. `undefined`: OPS did not say. */
1601
+ readonly retryable: boolean | undefined;
1602
+ /** Seconds OPS asks to wait before retrying. */
1603
+ readonly retryAfter: number | undefined;
1604
+ /** Checkout that a refused cart write can resume. */
1605
+ readonly checkoutId: string | undefined;
1606
+ /** Current cart cost sent with a `price_mismatch` (untrusted shape). */
1607
+ readonly cost: unknown;
1608
+ /** English version of `message`, when OPS sent one. */
1609
+ readonly messageEn: string | undefined;
1610
+ constructor(init: StorefrontErrorInit);
1611
+ /**
1612
+ * Affected lines of a `409 insufficient_stock` (empty for any other error or a
1613
+ * server older than contract 1.1). The cart is untouched: show the lines and
1614
+ * let the buyer adjust or remove them.
1615
+ */
1616
+ get stockLines(): InsufficientStockLine[];
1617
+ toJSON(): {
1618
+ checkoutId?: string | undefined;
1619
+ retryAfter?: number | undefined;
1620
+ retryable?: boolean | undefined;
1621
+ requiredScopes?: string[] | undefined;
1622
+ name: string;
1623
+ status: number;
1624
+ code: StorefrontErrorCode;
1625
+ message: string;
1626
+ field: string | undefined;
1627
+ };
1628
+ }
1629
+ declare function isStorefrontError(err: unknown): err is StorefrontError;
1630
+
1631
+ /**
1632
+ * Account settings of the buyer (contract 1.9): active sessions, recent re-authentication, language and
1633
+ * notification preferences, data export and account deletion. Types and small pure helpers; the calls live on
1634
+ * `client.customer`.
1635
+ */
1636
+ /** Notification preferences: event → channel → on. Only optional events can be configured (never the order confirmation or the invoice). */
1637
+ type CustomerPreferences = {
1638
+ notifications?: Record<string, Record<string, boolean>>;
1639
+ };
1640
+ /** One session of the buyer for a «Devices» list. The server never sends an address or a token. */
1641
+ type CustomerSessionInfo = {
1642
+ id: string;
1643
+ /** `true` for the session that made the request. */
1644
+ current: boolean;
1645
+ /** A summary such as «Chrome · Windows». Never a full user agent. */
1646
+ device_label: string;
1647
+ login_method: 'email' | 'phone' | 'password' | (string & {});
1648
+ last_used_at?: string | null;
1649
+ created_at: string;
1650
+ };
1651
+ /** What proves the buyer is who they say: the password, or a sign-in code requested with `customer.requestOtp`. Exactly one. */
1652
+ type ReauthInput = {
1653
+ password: string;
1654
+ otp_code?: never;
1655
+ } | {
1656
+ otp_code: string;
1657
+ password?: never;
1658
+ };
1659
+ type ReauthResult = {
1660
+ reauth_at: string;
1661
+ /** How long the confirmation lasts (seconds). It applies to the session that made the call, nowhere else. */
1662
+ valid_for_seconds?: number;
1663
+ };
1664
+ /** The buyer's data as a JSON file, in memory. `content_base64` is the file; serve it as a download and do not keep it. */
1665
+ type DataExportFile = {
1666
+ filename: string;
1667
+ content_type: string;
1668
+ content_base64: string;
1669
+ };
1670
+ /** `DELETE /customer`. `confirm` is the text your interface asked the buyer to type. */
1671
+ type AccountDeleteInput = {
1672
+ confirm: string;
1673
+ };
1674
+ /**
1675
+ * `true` when a call was refused because the buyer must confirm their password or a code first
1676
+ * (`403` with code `reauth_required`): show your confirmation step, call `customer.reauth`, and repeat the call.
1677
+ */
1678
+ declare function isReauthRequired(error: unknown): error is StorefrontError;
1679
+ /**
1680
+ * `true` when deleting the account was refused because an order is on its way or a payment is still pending
1681
+ * (`409`; `field` says which: `orders` or `pending_payments`).
1682
+ */
1683
+ declare function isAccountDeleteBlocked(error: unknown): error is StorefrontError & {
1684
+ field: 'orders' | 'pending_payments';
1685
+ };
1686
+ /** Decodes `content_base64` of a data export. Throws `TypeError` when it is not valid base64. */
1687
+ declare function dataExportBytes(file: Pick<DataExportFile, 'content_base64'>): Uint8Array;
1688
+ /** A download filename that is safe in a `Content-Disposition` header: no path, quotes, control characters or spaces. */
1689
+ declare function safeExportFilename(name: unknown, fallback?: string): string;
1690
+
1691
+ export { type FiscalProfile as $, type AccountDeleteInput as A, type Customer as B, type Cart as C, type CustomerCapabilities as D, type CustomerIdentifier as E, type CustomerPasswordLoginInput as F, type CustomerPreferences as G, type CustomerRegisterInput as H, type CustomerRegisterResult as I, type CustomerResetPasswordInput as J, type CustomerSession as K, type CustomerSessionInfo as L, type CustomerSessionInput as M, type CustomerSetPasswordInput as N, type CustomerUpdateInput as O, type CustomerVerifyRegistrationInput as P, type DataExportFile as Q, type DeclineCode as R, type DeliveryInput as S, type DeliveryMethod as T, type DeliveryOptions as U, type Facet as V, type FacetValue as W, type FiscalDocumentEvidence as X, type FiscalDocumentSource as Y, type FiscalIdentity as Z, type FiscalIdentityInput as _, type Address as a, type Product as a$, type FiscalProfileInput as a0, type FiscalVerification as a1, type GeoHint as a2, type IdentityCapture as a3, type IdentityDocumentSpec as a4, type IdentityFieldRule as a5, type IdentityRulesV1 as a6, type IdentityStrategy as a7, type Image as a8, type InsufficientStockDetails as a9, type OrderProgress as aA, type OrderProgressStep as aB, type OrderSection as aC, type OrderStage as aD, type OrderStepKey as aE, type OrderStepState as aF, type Page as aG, type PageInfo as aH, type PaymentAction as aI, type PaymentAttemptResult as aJ, type PaymentAttemptStatus as aK, type PaymentClient as aL, type PaymentClientCsp as aM, type PaymentConfig as aN, type PaymentFlow as aO, type PaymentInfo as aP, type PaymentMethod as aQ, type PaymentMethods as aR, type PaymentNextStep as aS, type PaymentOption as aT, type PaymentOptionKey as aU, type PaymentPoint as aV, type PaymentSubmitInput as aW, type PaymentVoucher as aX, type PendingPayment as aY, type PendingPaymentVoucher as aZ, type PickupOption as a_, type InsufficientStockLine as aa, type InvoiceAction as ab, type InvoiceDoc as ac, type InvoiceFile as ad, type InvoiceFileKind as ae, type InvoiceRequest as af, type InvoiceResult as ag, type InvoiceStage as ah, type InvoiceSummary as ai, type InvoicingCapabilities as aj, type Location as ak, type LocationContacts as al, type LocationKind as am, type LocationListParams as an, type LocationPickup as ao, type Menu as ap, type MenuItem as aq, type Money as ar, type MoneyRange as as, type NearestLocation as at, type NextAction as au, type NextActionKind as av, type Order as aw, type OrderLine as ax, type OrderPickup as ay, type OrderProblem as az, type AddressInput as b, type ProductAttributeValue as b0, type ProductCategory as b1, type ProductConnection as b2, type ProductOption as b3, type ProductSort as b4, type ProductVariant as b5, type PromotionAnnouncement as b6, type PromotionReward as b7, type PromotionTier as b8, type PromotionsList as b9, type ShopPolicies as bA, type StockLevel as bB, StorefrontError as bC, type StorefrontErrorBody as bD, type StorefrontErrorCode as bE, type StorefrontErrorInit as bF, type Subject as bG, type SubjectCatalog as bH, type SubjectCatalogNode as bI, type SubjectField as bJ, type SubjectFieldType as bK, type SubjectInput as bL, type SubjectKind as bM, type SubjectPatch as bN, type SubjectRef as bO, type Theme as bP, type TokenIntrospection as bQ, type UnavailableRateProvider as bR, dataExportBytes as bS, isAccountDeleteBlocked as bT, isReauthRequired as bU, isStorefrontError as bV, safeExportFilename as bW, type ReauthInput as ba, type ReauthResult as bb, type RecommendationPlacement as bc, type Refund as bd, type Region as be, type RegionFiscalEntry as bf, type RegionFiscalId as bg, type RegionPaymentMethod as bh, type RegionPostalCode as bi, type RestockSubscriptionInput as bj, type RestockSubscriptionResult as bk, type ReturnRequest as bl, type ReturnRequestInput as bm, type SEO as bn, type Section as bo, type SelectedOption as bp, type Shipment as bq, type ShipmentEvent as br, type ShipmentKind as bs, type ShipmentMap as bt, type ShipmentStatus as bu, type ShipmentsSummary as bv, type ShippingRate as bw, type Shop as bx, type ShopBranch as by, type ShopContact as bz, type Article as c, type Availability as d, type AvailabilityStatus as e, type CartBuyer as f, type CartBuyerInput as g, type CartCost as h, type CartDelivery as i, type CartDiscountCode as j, type CartDiscountLine as k, type CartInvoice as l, type CartLine as m, type CartLineInput as n, type CartLineMerchandise as o, type CartLineProblem as p, type CartLineUpdateInput as q, type CartPromotions as r, type CartRecommendation as s, type CartRecommendations as t, type CheckoutInfo as u, type CheckoutInput as v, type CheckoutPayment as w, type CheckoutResult as x, type Collection as y, type Connection as z };
@@ -375,6 +375,10 @@ type DeliveryOptions = {
375
375
  /** `true` when some provider failed: `rates` holds only what arrived. */
376
376
  partial?: boolean;
377
377
  unavailable?: UnavailableRateProvider[];
378
+ /** The shop's own fixed price: no carrier was asked (addon setting `shipping_quote_mode`). */
379
+ fixed?: boolean;
380
+ /** Every shipping rate costs 0 (free-shipping minimum reached): nothing to choose, show "Free shipping" and go on. */
381
+ free?: boolean;
378
382
  };
379
383
  /** One way to pay (`GET /storefront/carts/:id/payment-methods`). `key` is sent as `payment_method` at checkout. */
380
384
  type PaymentMethod = {
@@ -494,6 +498,10 @@ type Customer = {
494
498
  /** Saved fiscal data; `null`/absent when none. */
495
499
  fiscal?: FiscalIdentity | null;
496
500
  created_at: string;
501
+ /** Preferred language, one of the store's (contract 1.9). Absent on older servers. */
502
+ locale?: string | null;
503
+ /** Notification preferences (contract 1.9). Absent on older servers. */
504
+ preferences?: CustomerPreferences;
497
505
  };
498
506
  type CustomerIdentifier = {
499
507
  email: string;
@@ -531,6 +539,22 @@ type CustomerCapabilities = {
531
539
  fiscal_profiles?: {
532
540
  max: number;
533
541
  };
542
+ /**
543
+ * The kinds of saved item the store declares («My items»; contract 1.9). Absent when the store declares none (or on
544
+ * older servers): there is no such section, show nothing.
545
+ */
546
+ subjects?: {
547
+ kinds: string[];
548
+ share_with_workshop?: boolean;
549
+ };
550
+ /** Channels the notification preferences can use (connector installed). Absent on older servers: no preferences section. */
551
+ notifications?: {
552
+ channels: string[];
553
+ };
554
+ /** The buyer can download their data (`customer.exportData`). Absent on older servers. */
555
+ data_export?: boolean;
556
+ /** The buyer can delete their account (`customer.deleteAccount`). Absent on older servers. */
557
+ account_delete?: boolean;
534
558
  };
535
559
  /** `GET {gateway}/_token`: what the token in use is and what it can do. Needs no scope. */
536
560
  type TokenIntrospection = {
@@ -1379,12 +1403,101 @@ type FiscalProfileInput = Partial<FiscalIdentityInput> & {
1379
1403
  label?: string;
1380
1404
  is_default?: boolean;
1381
1405
  };
1406
+ /**
1407
+ * A subject is something the buyer shops for: a vehicle, a printer, a phone, a pet, a size. WHICH kinds exist is
1408
+ * data the organization publishes (`content.subjectKinds()`); nothing in the SDK or the contract names one. A store
1409
+ * with no kinds has no such section.
1410
+ */
1411
+ type SubjectFieldType = 'text' | 'year' | 'select';
1412
+ type SubjectField = {
1413
+ key: string;
1414
+ label: string;
1415
+ type: SubjectFieldType;
1416
+ /** `catalog`: the value is an option of the kind's catalog (a `year` is checked against the options' years). Default `free`. */
1417
+ source?: 'catalog' | 'free';
1418
+ /** The field whose choice narrows this one (the cascade order). */
1419
+ depends_on?: string | null;
1420
+ required?: boolean;
1421
+ /**
1422
+ * Stored for the buyer and NEVER part of the label, the compatibility key, a filter, a cache key, a cookie or an
1423
+ * order (a licence plate). The server returns it only masked (`••34`): never prefill it, never log it.
1424
+ */
1425
+ private?: boolean;
1426
+ max?: number;
1427
+ };
1428
+ /**
1429
+ * One option of a catalog level (make, model, engine…). `from`/`to`/`ranges` bound the model years it covers: a
1430
+ * `year` field must satisfy every option on the chosen path that declares them.
1431
+ */
1432
+ type SubjectCatalogNode = {
1433
+ label: string;
1434
+ from?: number;
1435
+ to?: number;
1436
+ ranges?: [number, number][];
1437
+ children?: Record<string, SubjectCatalogNode>;
1438
+ };
1439
+ /** The cascade of options of a kind: levels follow the kind's `catalog` fields that are not years. */
1440
+ type SubjectCatalog = {
1441
+ version?: string | null;
1442
+ tree: Record<string, SubjectCatalogNode>;
1443
+ };
1444
+ type SubjectKind = {
1445
+ key: string;
1446
+ /** Singular («Vehicle»). */
1447
+ label: string;
1448
+ /** The section's name («My garage»). */
1449
+ label_plural: string;
1450
+ max_per_account: number;
1451
+ fields: SubjectField[];
1452
+ /** Template of the compatibility key with the fields in braces (public ones only). */
1453
+ fit_key_template: string;
1454
+ /** The checkout may ask «which one is this order for?». */
1455
+ attach_to_order?: boolean;
1456
+ /** `null` for kinds with free fields only. */
1457
+ catalog?: SubjectCatalog | null;
1458
+ };
1459
+ /** A saved item. `attributes` holds the public values; private ones come masked (`••34`). */
1460
+ type Subject = {
1461
+ id: string;
1462
+ kind: string;
1463
+ /** Public label built by the server from the catalog and the public values. */
1464
+ label: string;
1465
+ nickname?: string | null;
1466
+ /** Compatibility key (the `fit:<key>` tag of the products); `''` when the item does not resolve completely. */
1467
+ fit_key: string;
1468
+ attributes: Record<string, unknown>;
1469
+ /** The active item of its kind. */
1470
+ is_default: boolean;
1471
+ last_used_at?: string | null;
1472
+ created_at: string;
1473
+ };
1474
+ type SubjectInput = {
1475
+ kind: string;
1476
+ attributes: Record<string, unknown>;
1477
+ nickname?: string | null;
1478
+ is_default?: boolean;
1479
+ };
1480
+ /** Merged over the stored item: `null` clears a field; a private value sent back as its mask is kept. */
1481
+ type SubjectPatch = {
1482
+ attributes?: Record<string, unknown>;
1483
+ nickname?: string | null;
1484
+ is_default?: boolean;
1485
+ };
1486
+ /** The item an order is for (kinds with `attach_to_order`). */
1487
+ type SubjectRef = {
1488
+ kind: string;
1489
+ id: string;
1490
+ };
1382
1491
  /** `PATCH /customer`. `fiscal: null` deletes the saved fiscal data (ARCO). */
1383
1492
  type CustomerUpdateInput = {
1384
1493
  first_name?: string | null;
1385
1494
  last_name?: string | null;
1386
1495
  phone?: string | null;
1387
1496
  fiscal?: FiscalIdentityInput | null;
1497
+ /** One of the store's languages (`400` with `field: 'locale'` otherwise); `null` clears it. */
1498
+ locale?: string | null;
1499
+ /** Merged by event and channel; `null` restores the defaults. `400` for an event that cannot be turned off. */
1500
+ preferences?: CustomerPreferences | null;
1388
1501
  };
1389
1502
  /** Post-processing: the value must match `pattern`; `group` of it replaces the value. */
1390
1503
  type IdentityCapture = {
@@ -1448,4 +1561,131 @@ type IdentityRulesV1 = {
1448
1561
  fields: IdentityFieldRule[];
1449
1562
  };
1450
1563
 
1451
- export type { IdentityCapture as $, Address as A, CustomerCapabilities as B, Cart as C, CustomerIdentifier as D, CustomerPasswordLoginInput as E, CustomerRegisterInput as F, CustomerRegisterResult as G, CustomerResetPasswordInput as H, CustomerSession as I, CustomerSessionInput as J, CustomerSetPasswordInput as K, CustomerUpdateInput as L, CustomerVerifyRegistrationInput as M, DeclineCode as N, DeliveryInput as O, DeliveryMethod as P, DeliveryOptions as Q, Facet as R, FacetValue as S, FiscalDocumentEvidence as T, FiscalDocumentSource as U, FiscalIdentity as V, FiscalIdentityInput as W, FiscalProfile as X, FiscalProfileInput as Y, FiscalVerification as Z, GeoHint as _, AddressInput as a, ProductOption as a$, IdentityDocumentSpec as a0, IdentityFieldRule as a1, IdentityRulesV1 as a2, IdentityStrategy as a3, Image as a4, InsufficientStockDetails as a5, InsufficientStockLine as a6, InvoiceAction as a7, InvoiceDoc as a8, InvoiceFile as a9, OrderStepKey as aA, OrderStepState as aB, Page as aC, PageInfo as aD, PaymentAction as aE, PaymentAttemptResult as aF, PaymentAttemptStatus as aG, PaymentClient as aH, PaymentClientCsp as aI, PaymentConfig as aJ, PaymentFlow as aK, PaymentInfo as aL, PaymentMethod as aM, PaymentMethods as aN, PaymentNextStep as aO, PaymentOption as aP, PaymentOptionKey as aQ, PaymentPoint as aR, PaymentSubmitInput as aS, PaymentVoucher as aT, PendingPayment as aU, PendingPaymentVoucher as aV, PickupOption as aW, Product as aX, ProductAttributeValue as aY, ProductCategory as aZ, ProductConnection as a_, InvoiceFileKind as aa, InvoiceRequest as ab, InvoiceResult as ac, InvoiceStage as ad, InvoiceSummary as ae, InvoicingCapabilities as af, Location as ag, LocationContacts as ah, LocationKind as ai, LocationListParams as aj, LocationPickup as ak, Menu as al, MenuItem as am, Money as an, MoneyRange as ao, NearestLocation as ap, NextAction as aq, NextActionKind as ar, Order as as, OrderLine as at, OrderPickup as au, OrderProblem as av, OrderProgress as aw, OrderProgressStep as ax, OrderSection as ay, OrderStage as az, Article as b, ProductSort as b0, ProductVariant as b1, PromotionAnnouncement as b2, PromotionReward as b3, PromotionTier as b4, PromotionsList as b5, RecommendationPlacement as b6, Refund as b7, Region as b8, RegionFiscalEntry as b9, UnavailableRateProvider as bA, RegionFiscalId as ba, RegionPaymentMethod as bb, RegionPostalCode as bc, RestockSubscriptionInput as bd, RestockSubscriptionResult as be, ReturnRequest as bf, ReturnRequestInput as bg, SEO as bh, Section as bi, SelectedOption as bj, Shipment as bk, ShipmentEvent as bl, ShipmentKind as bm, ShipmentMap as bn, ShipmentStatus as bo, ShipmentsSummary as bp, ShippingRate as bq, Shop as br, ShopBranch as bs, ShopContact as bt, ShopPolicies as bu, StockLevel as bv, StorefrontErrorBody as bw, StorefrontErrorCode as bx, Theme as by, TokenIntrospection as bz, Availability as c, AvailabilityStatus as d, CartBuyer as e, CartBuyerInput as f, CartCost as g, CartDelivery as h, CartDiscountCode as i, CartDiscountLine as j, CartInvoice as k, CartLine as l, CartLineInput as m, CartLineMerchandise as n, CartLineProblem as o, CartLineUpdateInput as p, CartPromotions as q, CartRecommendation as r, CartRecommendations as s, CheckoutInfo as t, CheckoutInput as u, CheckoutPayment as v, CheckoutResult as w, Collection as x, Connection as y, Customer as z };
1564
+ type StorefrontErrorInit = {
1565
+ status: number;
1566
+ code: StorefrontErrorCode;
1567
+ message: string;
1568
+ field?: string;
1569
+ /** Raw `error.details` from the body (untrusted shape). */
1570
+ details?: unknown;
1571
+ /** Request URL that failed (without credentials). */
1572
+ url?: string;
1573
+ cause?: unknown;
1574
+ /** Scopes named by the gateway on a `403 insufficient_scope`. */
1575
+ requiredScopes?: string[];
1576
+ /** `error.retryable` as OPS declared it (payment failures). `undefined` = OPS did not say. */
1577
+ retryable?: boolean;
1578
+ /** `error.retry_after` in seconds. */
1579
+ retryAfter?: number;
1580
+ /** `error.checkout_id`: the checkout a refused cart write can resume. */
1581
+ checkoutId?: string;
1582
+ /** `error.cost` of a `price_mismatch` (the cart's current cost; untrusted shape). */
1583
+ cost?: unknown;
1584
+ /** `error.message_en`. */
1585
+ messageEn?: string;
1586
+ };
1587
+ /**
1588
+ * Error thrown by the client for any non-2xx response, network failure,
1589
+ * timeout or abort. `status` is `0` when no HTTP response was received.
1590
+ */
1591
+ declare class StorefrontError extends Error {
1592
+ readonly name = "StorefrontError";
1593
+ readonly status: number;
1594
+ readonly code: StorefrontErrorCode;
1595
+ readonly field: string | undefined;
1596
+ readonly details: unknown;
1597
+ readonly url: string | undefined;
1598
+ /** Scopes a `403 insufficient_scope` says the route needs (empty for any other error). */
1599
+ readonly requiredScopes: string[];
1600
+ /** `true`: repeating the request (same idempotency key) can succeed. `false`: not until someone fixes something. `undefined`: OPS did not say. */
1601
+ readonly retryable: boolean | undefined;
1602
+ /** Seconds OPS asks to wait before retrying. */
1603
+ readonly retryAfter: number | undefined;
1604
+ /** Checkout that a refused cart write can resume. */
1605
+ readonly checkoutId: string | undefined;
1606
+ /** Current cart cost sent with a `price_mismatch` (untrusted shape). */
1607
+ readonly cost: unknown;
1608
+ /** English version of `message`, when OPS sent one. */
1609
+ readonly messageEn: string | undefined;
1610
+ constructor(init: StorefrontErrorInit);
1611
+ /**
1612
+ * Affected lines of a `409 insufficient_stock` (empty for any other error or a
1613
+ * server older than contract 1.1). The cart is untouched: show the lines and
1614
+ * let the buyer adjust or remove them.
1615
+ */
1616
+ get stockLines(): InsufficientStockLine[];
1617
+ toJSON(): {
1618
+ checkoutId?: string | undefined;
1619
+ retryAfter?: number | undefined;
1620
+ retryable?: boolean | undefined;
1621
+ requiredScopes?: string[] | undefined;
1622
+ name: string;
1623
+ status: number;
1624
+ code: StorefrontErrorCode;
1625
+ message: string;
1626
+ field: string | undefined;
1627
+ };
1628
+ }
1629
+ declare function isStorefrontError(err: unknown): err is StorefrontError;
1630
+
1631
+ /**
1632
+ * Account settings of the buyer (contract 1.9): active sessions, recent re-authentication, language and
1633
+ * notification preferences, data export and account deletion. Types and small pure helpers; the calls live on
1634
+ * `client.customer`.
1635
+ */
1636
+ /** Notification preferences: event → channel → on. Only optional events can be configured (never the order confirmation or the invoice). */
1637
+ type CustomerPreferences = {
1638
+ notifications?: Record<string, Record<string, boolean>>;
1639
+ };
1640
+ /** One session of the buyer for a «Devices» list. The server never sends an address or a token. */
1641
+ type CustomerSessionInfo = {
1642
+ id: string;
1643
+ /** `true` for the session that made the request. */
1644
+ current: boolean;
1645
+ /** A summary such as «Chrome · Windows». Never a full user agent. */
1646
+ device_label: string;
1647
+ login_method: 'email' | 'phone' | 'password' | (string & {});
1648
+ last_used_at?: string | null;
1649
+ created_at: string;
1650
+ };
1651
+ /** What proves the buyer is who they say: the password, or a sign-in code requested with `customer.requestOtp`. Exactly one. */
1652
+ type ReauthInput = {
1653
+ password: string;
1654
+ otp_code?: never;
1655
+ } | {
1656
+ otp_code: string;
1657
+ password?: never;
1658
+ };
1659
+ type ReauthResult = {
1660
+ reauth_at: string;
1661
+ /** How long the confirmation lasts (seconds). It applies to the session that made the call, nowhere else. */
1662
+ valid_for_seconds?: number;
1663
+ };
1664
+ /** The buyer's data as a JSON file, in memory. `content_base64` is the file; serve it as a download and do not keep it. */
1665
+ type DataExportFile = {
1666
+ filename: string;
1667
+ content_type: string;
1668
+ content_base64: string;
1669
+ };
1670
+ /** `DELETE /customer`. `confirm` is the text your interface asked the buyer to type. */
1671
+ type AccountDeleteInput = {
1672
+ confirm: string;
1673
+ };
1674
+ /**
1675
+ * `true` when a call was refused because the buyer must confirm their password or a code first
1676
+ * (`403` with code `reauth_required`): show your confirmation step, call `customer.reauth`, and repeat the call.
1677
+ */
1678
+ declare function isReauthRequired(error: unknown): error is StorefrontError;
1679
+ /**
1680
+ * `true` when deleting the account was refused because an order is on its way or a payment is still pending
1681
+ * (`409`; `field` says which: `orders` or `pending_payments`).
1682
+ */
1683
+ declare function isAccountDeleteBlocked(error: unknown): error is StorefrontError & {
1684
+ field: 'orders' | 'pending_payments';
1685
+ };
1686
+ /** Decodes `content_base64` of a data export. Throws `TypeError` when it is not valid base64. */
1687
+ declare function dataExportBytes(file: Pick<DataExportFile, 'content_base64'>): Uint8Array;
1688
+ /** A download filename that is safe in a `Content-Disposition` header: no path, quotes, control characters or spaces. */
1689
+ declare function safeExportFilename(name: unknown, fallback?: string): string;
1690
+
1691
+ export { type FiscalProfile as $, type AccountDeleteInput as A, type Customer as B, type Cart as C, type CustomerCapabilities as D, type CustomerIdentifier as E, type CustomerPasswordLoginInput as F, type CustomerPreferences as G, type CustomerRegisterInput as H, type CustomerRegisterResult as I, type CustomerResetPasswordInput as J, type CustomerSession as K, type CustomerSessionInfo as L, type CustomerSessionInput as M, type CustomerSetPasswordInput as N, type CustomerUpdateInput as O, type CustomerVerifyRegistrationInput as P, type DataExportFile as Q, type DeclineCode as R, type DeliveryInput as S, type DeliveryMethod as T, type DeliveryOptions as U, type Facet as V, type FacetValue as W, type FiscalDocumentEvidence as X, type FiscalDocumentSource as Y, type FiscalIdentity as Z, type FiscalIdentityInput as _, type Address as a, type Product as a$, type FiscalProfileInput as a0, type FiscalVerification as a1, type GeoHint as a2, type IdentityCapture as a3, type IdentityDocumentSpec as a4, type IdentityFieldRule as a5, type IdentityRulesV1 as a6, type IdentityStrategy as a7, type Image as a8, type InsufficientStockDetails as a9, type OrderProgress as aA, type OrderProgressStep as aB, type OrderSection as aC, type OrderStage as aD, type OrderStepKey as aE, type OrderStepState as aF, type Page as aG, type PageInfo as aH, type PaymentAction as aI, type PaymentAttemptResult as aJ, type PaymentAttemptStatus as aK, type PaymentClient as aL, type PaymentClientCsp as aM, type PaymentConfig as aN, type PaymentFlow as aO, type PaymentInfo as aP, type PaymentMethod as aQ, type PaymentMethods as aR, type PaymentNextStep as aS, type PaymentOption as aT, type PaymentOptionKey as aU, type PaymentPoint as aV, type PaymentSubmitInput as aW, type PaymentVoucher as aX, type PendingPayment as aY, type PendingPaymentVoucher as aZ, type PickupOption as a_, type InsufficientStockLine as aa, type InvoiceAction as ab, type InvoiceDoc as ac, type InvoiceFile as ad, type InvoiceFileKind as ae, type InvoiceRequest as af, type InvoiceResult as ag, type InvoiceStage as ah, type InvoiceSummary as ai, type InvoicingCapabilities as aj, type Location as ak, type LocationContacts as al, type LocationKind as am, type LocationListParams as an, type LocationPickup as ao, type Menu as ap, type MenuItem as aq, type Money as ar, type MoneyRange as as, type NearestLocation as at, type NextAction as au, type NextActionKind as av, type Order as aw, type OrderLine as ax, type OrderPickup as ay, type OrderProblem as az, type AddressInput as b, type ProductAttributeValue as b0, type ProductCategory as b1, type ProductConnection as b2, type ProductOption as b3, type ProductSort as b4, type ProductVariant as b5, type PromotionAnnouncement as b6, type PromotionReward as b7, type PromotionTier as b8, type PromotionsList as b9, type ShopPolicies as bA, type StockLevel as bB, StorefrontError as bC, type StorefrontErrorBody as bD, type StorefrontErrorCode as bE, type StorefrontErrorInit as bF, type Subject as bG, type SubjectCatalog as bH, type SubjectCatalogNode as bI, type SubjectField as bJ, type SubjectFieldType as bK, type SubjectInput as bL, type SubjectKind as bM, type SubjectPatch as bN, type SubjectRef as bO, type Theme as bP, type TokenIntrospection as bQ, type UnavailableRateProvider as bR, dataExportBytes as bS, isAccountDeleteBlocked as bT, isReauthRequired as bU, isStorefrontError as bV, safeExportFilename as bW, type ReauthInput as ba, type ReauthResult as bb, type RecommendationPlacement as bc, type Refund as bd, type Region as be, type RegionFiscalEntry as bf, type RegionFiscalId as bg, type RegionPaymentMethod as bh, type RegionPostalCode as bi, type RestockSubscriptionInput as bj, type RestockSubscriptionResult as bk, type ReturnRequest as bl, type ReturnRequestInput as bm, type SEO as bn, type Section as bo, type SelectedOption as bp, type Shipment as bq, type ShipmentEvent as br, type ShipmentKind as bs, type ShipmentMap as bt, type ShipmentStatus as bu, type ShipmentsSummary as bv, type ShippingRate as bw, type Shop as bx, type ShopBranch as by, type ShopContact as bz, type Article as c, type Availability as d, type AvailabilityStatus as e, type CartBuyer as f, type CartBuyerInput as g, type CartCost as h, type CartDelivery as i, type CartDiscountCode as j, type CartDiscountLine as k, type CartInvoice as l, type CartLine as m, type CartLineInput as n, type CartLineMerchandise as o, type CartLineProblem as p, type CartLineUpdateInput as q, type CartPromotions as r, type CartRecommendation as s, type CartRecommendations as t, type CheckoutInfo as u, type CheckoutInput as v, type CheckoutPayment as w, type CheckoutResult as x, type Collection as y, type Connection as z };