@doswiftly/storefront-sdk 13.1.0 → 15.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,241 @@
1
1
  # Changelog
2
2
 
3
+ ## 15.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 94c2603: Storefront SDK now covers the full checkout flow end-to-end through typed methods — no more dropping to raw GraphQL for shipping discovery, payment listing, guest order lookup, cart attributes, or saved-address pickers.
8
+
9
+ **New `CartClient` methods**
10
+ - `getAvailableShippingMethods(cartId, address)` — cart-aware shipping discovery. Resolves with `null` when the cart does not exist or has expired (symmetric with `get(cartId)`), otherwise with `AvailableShippingMethodsPayload`: `methods[]` (each carrying `deliveryType` — `HOME`, `PICKUP_POINT`, `LOCKER` — so the storefront picks the pickup / locker UI without inferring from the method name), `freeShippingProgress` (best progress across methods, for the picker banner), and `userErrors[]` populated for business conditions like `DIGITAL_ONLY_NO_SHIPPING` (cart with no shippable lines) or `NO_SHIPPING_METHODS` (unsupported address). Branch on `result.userErrors[0].code`; the `message` is localized per the request's `Accept-Language`.
11
+ - `getAvailablePaymentMethods()` — shop-level list of active payment methods. Returns `AvailablePaymentMethods`: `methods[]` (sorted by merchant position) and `defaultMethod` (merchant-flagged pre-selection). Prefer `result.defaultMethod ?? result.methods.find(m => m.isDefault)` — the merchant may override the default independently of per-method flags.
12
+ - `getOrderByToken(token, email?)` — guest order lookup by opaque access token (returned in `complete().order.accessToken`). Optional `email` adds defense in depth; mismatch returns the same `null` shape as an invalid token. Rate-limited server-side (5 req / min per IP + shop).
13
+ - `updateAttributes(cartId, attributes)` — replace-all of the cart's custom `{ key, value }` pairs (delivery instructions, gift-wrap flags, B2B PO numbers). Pass an empty array to clear.
14
+
15
+ **New `AuthClient` method**
16
+ - `getAddresses()` — saved address book of the authenticated customer (shipping + billing). Resolves with the address list when authenticated, with `null` when no auth context reached the server (symmetric with `getCustomer()`). Each entry carries B2B fields (`taxId`, `vatNumber`) and the `isDefault` flag, so the same list serves both shipping and billing pickers.
17
+
18
+ **Schema additions (operations package)**
19
+ - `MailingAddress` now exposes `taxId`, `vatNumber`, and `pickupPoint`. The new `PickupPoint` type (`provider`, `pointId`, `name?`, `address?`) is returned on shipping addresses delivered to a parcel locker / collection point.
20
+ - `AvailableShippingMethod` gains the declarative `deliveryType` enum.
21
+ - `CartAppliedGiftCard` now exposes `id` — the stable handle to pass to `cartRemoveGiftCard` (no need to keep the raw gift card code on the client).
22
+ - New `CustomerAddresses` query — `customer.addresses(first: 50)` connection returning the address book, normalized to a node list by the SDK wrapper.
23
+
24
+ **SDK fragment changes**
25
+
26
+ The SDK's `MailingAddress` fragment now selects `taxId`, `vatNumber`, and `pickupPoint`. Existing types that include a mailing address (`Cart.shippingAddress`, `Cart.billingAddress`, `Order.shippingAddress`, `Customer.defaultAddress`) get these fields automatically. The `AvailableShippingMethod` fragment selects `deliveryType`. The `CartAppliedGiftCard` fragment selects `id`.
27
+
28
+ **New React hook — server-driven checkout**
29
+ - `useCart(cartId, options?)` — sister of `useCartManager`, bound to an explicit `cartId` instead of the `cart-id` cookie. Use it for SSR-rendered checkout, deep-link order recovery, and admin "view this cart" UIs where the cart id is known up front and the cookie is irrelevant. Returns the loaded cart plus the same mutation surface as the cookie-based hook (`addItems`, `updateItems`, `removeItems`, `updateBuyerIdentity`, `setShippingAddress`, `updateDiscountCodes`, `updateNote`, `updateAttributes` — each resolves with `{ cart, warnings }` so low-stock and partial-availability hints flow through), reactive `isLoading` / `error` / `operation` state, and a `refetch()` callback. `autoFetch: false` + `initialCart` lets you skip the hydration round-trip when the server already resolved the cart.
30
+
31
+ **Field-level descriptions visible in your IDE**
32
+
33
+ Hovering on any cart / order / customer / payment / shipping field in your editor now shows a precise English description of what the field carries — when to use it, what its values mean, what is null vs zero, which enum values are relevant. The descriptions were rewritten across every type selected by the SDK so the storefront-developer audience does not need to look anywhere else for the contract. Codegen is configured (`preResolveTypes: false`) to propagate those descriptions through every generated fragment / query type, so the same hover works on the typed shape your codegen produces.
34
+
35
+ These additions are backward-compatible — existing calls keep their current signatures and return the same fields (plus the new ones). The mailing-address fragment expansion is purely additive.
36
+
37
+ ## 15.0.0
38
+
39
+ ### Major Changes
40
+
41
+ - a11f9e4: GraphQL types are now generated from the storefront schema instead of being hand-written. Every exported cart, order, customer, and payment type is derived directly from the schema, so they can no longer drift out of sync with the API.
42
+
43
+ **Breaking** — the previous hand-written types were inaccurate, and correcting them changes some shapes:
44
+ - `Customer.orderCount` is now `string` (was `number`).
45
+ - `CartLineEdge` and `CartLineConnection.edges` were removed — the cart query never returned edges.
46
+ - Fields previously typed as `string` are now precise string-literal union types: `Order.status`, `Order.paymentStatus`, `Order.fulfillmentStatus`, `PaymentSession.status`, `CartLine.productType`, `Money.currencyCode`, `CartWarning.code`, and the `AttributeSelection` mode fields. Reading these values still works; assigning arbitrary strings into them no longer compiles.
47
+
48
+ **Fixed** — types that were missing fields or had the wrong nullability:
49
+ - `Order` now includes `accessToken`.
50
+ - `Cart` and `CartLine` now include `requiresShipping`.
51
+ - `Customer.displayName`, `Customer.emailMarketing`, and `Customer.totalSpent` are now correctly non-nullable.
52
+ - The duplicated `MailingAddress` definition is collapsed into one.
53
+
54
+ **New** — the schema enum types used by the public types are now exported: `CurrencyCode`, `CountryCode`, `LanguageCode`, `ProductTypeEnum`, `WeightUnit`, `CartWarningCode`, `StorefrontOrderStatus`, `OrderPaymentStatus`, `OrderFulfillmentStatus`, `EmailMarketingState`, `MarketingOptInLevel`, and the attribute enums.
55
+
56
+ These are type-only changes — no runtime behaviour changed.
57
+
58
+ ## 14.0.0
59
+
60
+ ### Major Changes
61
+
62
+ - 1fda2ab: **BREAKING**: URL identifier unification (`slug` → `handle`) + type renames for naming consistency.
63
+
64
+ ### What changed
65
+
66
+ URL-friendly identifiers across the storefront GraphQL API now consistently use `handle` (previously a mix of `slug` and `handle`). Canonical product brand entity renamed from `BrandSummary` to `Brand`. Shop branding type `Brand` renamed to `ShopBrand` to free the `Brand` name for the product entity.
67
+
68
+ ### Field renames (GraphQL response)
69
+
70
+ | Type | Old | New |
71
+ | ---------------------------- | ------ | -------- |
72
+ | `Category` | `slug` | `handle` |
73
+ | `BlogPost` | `slug` | `handle` |
74
+ | `BlogCategory` | `slug` | `handle` |
75
+ | `BlogTag` | `slug` | `handle` |
76
+ | `LoyaltyReward` | `slug` | `handle` |
77
+ | `BrandFilter` (input) | `slug` | `handle` |
78
+ | `BrandFilterValue` | `slug` | `handle` |
79
+ | `ProductAttributeDefinition` | `slug` | `handle` |
80
+ | `CategoryFilterOption` | `slug` | `handle` |
81
+
82
+ ### Type renames
83
+ - `BrandSummary` → `Brand` (canonical product brand entity, e.g. Funko, Nike). Update `__typename` checks and fragment spreads.
84
+ - `Brand` (shop branding) → `ShopBrand` (tenant-scoped shop metadata: logo, slogan, colors).
85
+
86
+ ### Query args renamed
87
+
88
+ ```graphql
89
+ # Old
90
+ query { category(slug: "figurki") { id name } }
91
+ query { blogPost(slug: "post-handle") { title } }
92
+ query BlogPosts($categorySlug: String, $tagSlug: String) {
93
+ blogPosts(categorySlug: $categorySlug, tagSlug: $tagSlug) { ... }
94
+ }
95
+
96
+ # New
97
+ query { category(handle: "figurki") { id name } }
98
+ query { blogPost(handle: "post-handle") { title } }
99
+ query BlogPosts($categoryHandle: String, $tagHandle: String) {
100
+ blogPosts(categoryHandle: $categoryHandle, tagHandle: $tagHandle) { ... }
101
+ }
102
+ ```
103
+
104
+ ### Brand filter input
105
+
106
+ ```graphql
107
+ # Old
108
+ products(filters: [{ brand: { slug: "funko" } }]) { ... }
109
+
110
+ # New
111
+ products(filters: [{ brand: { handle: "funko" } }]) { ... }
112
+ ```
113
+
114
+ ### MenuItem resource union
115
+
116
+ ```graphql
117
+ # Old
118
+ fragment MenuItem on MenuItem {
119
+ resource {
120
+ __typename
121
+ ... on Category {
122
+ id
123
+ slug
124
+ name
125
+ }
126
+ ... on BrandSummary {
127
+ id
128
+ slug
129
+ name
130
+ logo
131
+ }
132
+ }
133
+ }
134
+
135
+ # New
136
+ fragment MenuItem on MenuItem {
137
+ resource {
138
+ __typename
139
+ ... on Category {
140
+ id
141
+ handle
142
+ name
143
+ }
144
+ ... on Brand {
145
+ id
146
+ handle
147
+ name
148
+ logo
149
+ }
150
+ }
151
+ }
152
+ ```
153
+
154
+ ### Migration steps
155
+ 1. Update to `@doswiftly/storefront-operations@^14.0.0` + `@doswiftly/storefront-sdk@^14.0.0`.
156
+ 2. Run your codegen — TypeScript will surface every call site that needs update.
157
+ 3. Find/replace in storefront code:
158
+ - `.slug` → `.handle` on response fields listed above.
159
+ - `__typename === 'BrandSummary'` → `__typename === 'Brand'`.
160
+ - `{ brand: { slug } }` filter input → `{ brand: { handle } }`.
161
+ - `categorySlug`/`tagSlug` query args → `categoryHandle`/`tagHandle`.
162
+ 4. Update GraphQL fragments selecting renamed fields.
163
+ 5. Re-run codegen, fix any remaining TypeScript errors.
164
+
165
+ ### Why
166
+
167
+ A single naming convention (`handle`) across all URL identifiers removes ambiguity and matches common e-commerce GraphQL convention. The `BrandSummary` suffix was misleading — no full `Brand` ObjectType existed, so the suffix suggested a missing parent type. Shop branding `Brand` blocked the cleaner name for the product entity.
168
+
169
+ Full migration guide with code examples: <https://docs.doswiftly.pl/storefront-developer/migration-14.0>
170
+
171
+ Naming conventions reference: <https://docs.doswiftly.pl/storefront-developer/api/naming-conventions>
172
+
173
+ ### Minor Changes
174
+
175
+ - 507d487: Storefront GraphQL: nowy `attributeOptionsSearch(input)` query — paginated + searchable lista opcji atrybutu (Relay Connection).
176
+
177
+ Use case: storefront UI z dużymi filtrami atrybutów (np. 800+ licencji, materiałów, rozmiarów, kolorów) — dropdown z autocomplete i paginacją bez zassania całej listy. `productFilters.attributes[].filterValues[]` zostaje jako quick browse facets (top N), `attributeOptionsSearch` służy do drill-into specific filter card z searchem.
178
+
179
+ Dla **marek/producentów** preferuj dedykowane API `productFilters.brands[]` (Brand jest pełnoprawną encją z logo i productCount) — `attributeOptionsSearch(handle: "marka")` jest legacy fallback dla katalogów bez kanonicznej Brand entity.
180
+
181
+ **Input** (`AttributeOptionsSearchInput`):
182
+ - `handle: String!` — slug atrybutu (np. `"marka"`)
183
+ - `contextInput: AvailableFiltersInput` — produktowy kontekst (kategoria/kolekcja/search/currentFilters) z exclude-self semantyką
184
+ - `first: Int` (1–100, default 50)
185
+ - `after: String` — opaque cursor
186
+ - `search: String` — case-insensitive ILIKE (max 100 znaków)
187
+ - `sort: AttributeOptionsSearchSort` — `COUNT_DESC` (default, most popular first) lub `LABEL_ASC` (alfabetycznie z polskim collation)
188
+
189
+ **Output** (`AttributeFilterValueConnection`): `edges { cursor node }`, `nodes` (shortcut), `pageInfo`, `totalCount`. Wspiera atrybuty `SELECT`/`CHECKBOX`/`RADIO`/`COLOR` (z bazy `attribute_options`) oraz `TEXT`/`TEXTAREA` (z aggregated unique values).
190
+
191
+ **Migration**: brak breaking changes — `productFilters` zachowuje obecny shape. Jeśli budujesz "Pokaż wszystkie marki" UI, przenoś logikę na nowy query żeby uniknąć over-fetching.
192
+
193
+ - 6f8d873: `CartWarningCode` enum gains a fourth value, `SHIPPING_METHOD_AUTO_CLEARED`.
194
+
195
+ Cart line mutations (`cartAddLines`, `cartUpdateLines`, `cartRemoveLines`) now reconcile the selected shipping method against cart contents on every call. When a mutation leaves the cart with no items that require physical delivery (digital-only or empty) but a shipping method is still set, the method is cleared automatically and the mutation response surfaces a `CartWarning { code: "SHIPPING_METHOD_AUTO_CLEARED", target: "selectedShippingMethod", message: "…" }`.
196
+
197
+ This closes the gap where a mixed cart that lost its last physical line via the storefront UI would persist a stale shipping method and fail later at checkout submit with `FORBIDDEN_SHIPPING_METHOD`. There is no escape hatch needed on the storefront — the mutation accepts non-null `shippingMethodId` only, so the backend takes responsibility for the transition.
198
+
199
+ **Storefront impact**: none required. Reads of `cart.selectedShippingMethod` already returned `null` once cleared. Apps that already consume the `warnings[]` array (Apps that follow the standard `userErrors[]` + `warnings[]` payload shape) will surface the auto-clear toast for free. Apps that ignore `warnings[]` continue to work — the mutation still succeeds and the cart is left in a consistent state.
200
+
201
+ **Locale**: `message` is translated server-side (`Accept-Language`) — for example, `pl` returns "Wybrana metoda wysyłki została usunięta, ponieważ koszyk nie wymaga już dostawy.", `en` returns "The selected shipping method was removed because the cart no longer requires delivery."
202
+
203
+ The warning fires only on the line mutation that triggers the transition, never on subsequent reads or unrelated mutations. Decrementing a physical line quantity from `3` to `1`, removing one physical line while another remains, or adding digital lines to a mixed cart all leave the shipping method untouched.
204
+
205
+ - 1fda2ab: Storefront navigation menus: typed `resource` field eksponowany w `MenuItem` fragment + nowy typ linku `BRAND`.
206
+
207
+ **Co nowego**:
208
+ - `MenuItem.resource: MenuItemResource` — typed union (`Category` / `Collection` / `ShopPage` / `Product` / `BrandSummary`) wystawiony w `MenuItem` fragment na wszystkich 3 poziomach zagnieżdżenia. Każdy member zwraca `slug` (Category/Product/BrandSummary) lub `handle` (Collection/ShopPage) gotowy do budowy własnego URL.
209
+ - `MenuItemType.BRAND` — nowy typ linku menu dla marek producentów. `BrandSummary` w `resource` union (`id`, `name`, `slug`, `logo`).
210
+ - `MenuItem.url` dla `BRAND` resolve'uje się serwerowo jako `/brands/<slug>` — spójnie z istniejącą konwencją `/categories|/collections|/pages|/products/<slug>`.
211
+
212
+ **Dwa sposoby renderingu link target**:
213
+ 1. **Standard route convention** — użyj `item.url` jak dotąd. Działa jeśli storefront ma routy `/categories/[slug]`, `/collections/[handle]`, `/pages/[handle]`, `/products/[handle]`, `/brands/[slug]`.
214
+ 2. **Custom routing** (Next.js single-segment, Remix, itd.) — odczytaj `item.resource.__typename` + per-type `slug`/`handle`:
215
+
216
+ ```ts
217
+ function buildHref(item: MenuItem): string {
218
+ if (!item.resource) return item.url ?? "#";
219
+ switch (item.resource.__typename) {
220
+ case "Category":
221
+ return `/${item.resource.slug}`;
222
+ case "Collection":
223
+ return `/${item.resource.handle}`;
224
+ case "ShopPage":
225
+ return `/${item.resource.handle}`;
226
+ case "Product":
227
+ return `/p/${item.resource.handle}`;
228
+ case "BrandSummary":
229
+ return `/marka/${item.resource.slug}`;
230
+ }
231
+ return item.url ?? "#";
232
+ }
233
+ ```
234
+
235
+ **Performance**: wszystkie resource lookupy są batchowane per request — zero N+1 nawet w głębokich menu.
236
+
237
+ **Migration**: brak breaking changes. Kod używający tylko `item.url` działa bez zmian. `resource` jest opt-in dopóki nie zaczniesz go selekcjonować w custom fragmencie.
238
+
3
239
  ## 13.1.0
4
240
 
5
241
  ### Minor Changes
@@ -16,7 +16,7 @@
16
16
  * ```
17
17
  */
18
18
  import type { StorefrontClient } from '../client/types';
19
- import type { AuthResult, Customer, CustomerCreateInput } from './types';
19
+ import type { AuthResult, Customer, CustomerCreateInput, MailingAddress } from './types';
20
20
  export declare class AuthClient {
21
21
  private readonly client;
22
22
  constructor(client: StorefrontClient);
@@ -48,5 +48,17 @@ export declare class AuthClient {
48
48
  * via SDK auth middleware (`setAuthToken`).
49
49
  */
50
50
  getCustomer(): Promise<Customer | null>;
51
+ /**
52
+ * Saved address book of the authenticated customer (shipping + billing).
53
+ * Each entry carries B2B fields (`taxId`, `vatNumber`) and the `isDefault`
54
+ * flag, so the same list serves both pickers on checkout.
55
+ *
56
+ * Resolves with `null` when the request reaches the server without an auth
57
+ * context — symmetric with `getCustomer()` which also returns `null` for
58
+ * the unauthenticated case. Storefront UIs typically already gate access
59
+ * to address-pickers behind their own auth-state (`useAuth`), so `null`
60
+ * here means "no session reached the server" rather than "no addresses".
61
+ */
62
+ getAddresses(): Promise<MailingAddress[] | null>;
51
63
  }
52
64
  //# sourceMappingURL=auth-client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth-client.d.ts","sourceRoot":"","sources":["../../../src/core/auth/auth-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAUzE,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,gBAAgB;IAErD;;;OAGG;IACG,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAiBjE;;;;;OAKG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAa7B;;;OAGG;IACG,YAAY,IAAI,OAAO,CAAC,UAAU,CAAC;IAiBzC;;;OAGG;IACG,QAAQ,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC;IAmB/D;;;;OAIG;IACG,WAAW,IAAI,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;CAO9C"}
1
+ {"version":3,"file":"auth-client.d.ts","sourceRoot":"","sources":["../../../src/core/auth/auth-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAWzF,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,gBAAgB;IAErD;;;OAGG;IACG,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAiBjE;;;;;OAKG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAa7B;;;OAGG;IACG,YAAY,IAAI,OAAO,CAAC,UAAU,CAAC;IAiBzC;;;OAGG;IACG,QAAQ,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC;IAmB/D;;;;OAIG;IACG,WAAW,IAAI,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAQ7C;;;;;;;;;;OAUG;IACG,YAAY,IAAI,OAAO,CAAC,cAAc,EAAE,GAAG,IAAI,CAAC;CAMvD"}
@@ -16,7 +16,7 @@
16
16
  * ```
17
17
  */
18
18
  import { assertNoUserErrors } from '../helpers/assert-no-user-errors';
19
- import { CUSTOMER_LOGIN, CUSTOMER_LOGOUT, CUSTOMER_REFRESH_TOKEN, CUSTOMER_SIGNUP, CUSTOMER_QUERY, } from '../operations/auth';
19
+ import { CUSTOMER_LOGIN, CUSTOMER_LOGOUT, CUSTOMER_REFRESH_TOKEN, CUSTOMER_SIGNUP, CUSTOMER_QUERY, CUSTOMER_ADDRESSES_QUERY, } from '../operations/auth';
20
20
  export class AuthClient {
21
21
  client;
22
22
  constructor(client) {
@@ -85,4 +85,19 @@ export class AuthClient {
85
85
  const data = await this.client.query(CUSTOMER_QUERY);
86
86
  return data.customer;
87
87
  }
88
+ /**
89
+ * Saved address book of the authenticated customer (shipping + billing).
90
+ * Each entry carries B2B fields (`taxId`, `vatNumber`) and the `isDefault`
91
+ * flag, so the same list serves both pickers on checkout.
92
+ *
93
+ * Resolves with `null` when the request reaches the server without an auth
94
+ * context — symmetric with `getCustomer()` which also returns `null` for
95
+ * the unauthenticated case. Storefront UIs typically already gate access
96
+ * to address-pickers behind their own auth-state (`useAuth`), so `null`
97
+ * here means "no session reached the server" rather than "no addresses".
98
+ */
99
+ async getAddresses() {
100
+ const data = await this.client.query(CUSTOMER_ADDRESSES_QUERY);
101
+ return data.customer?.addresses.nodes ?? null;
102
+ }
88
103
  }
@@ -1,60 +1,26 @@
1
1
  /**
2
- * Auth types — manual (no codegen).
2
+ * Auth types — derived from the generated GraphQL operation types.
3
+ *
4
+ * Output types alias the generated `*Fragment` types; the input type and enums
5
+ * re-export the generated schema types. SSOT chain: backend storefront-graphql
6
+ * schema → `core/operations/*.ts` → `src/core/generated/operation-types.ts`
7
+ * (regenerate with `pnpm codegen`).
8
+ */
9
+ import type { CustomerFieldsFragment, CustomerAccessTokenFieldsFragment, MailingAddressFragment } from '../generated/operation-types';
10
+ /** Authenticated customer profile. */
11
+ export type Customer = CustomerFieldsFragment;
12
+ /** Access token pair issued by login / signup / refresh. */
13
+ export type CustomerAccessToken = CustomerAccessTokenFieldsFragment;
14
+ /** Shipping/billing address shape (shared with the cart surface). */
15
+ export type MailingAddress = MailingAddressFragment;
16
+ export type { CustomerCreateInput, EmailMarketingState, MarketingOptInLevel, } from '../generated/operation-types';
17
+ /**
18
+ * Result of a login / signup call — the SDK's composite shape pairing the
19
+ * issued access token with the (optional) customer profile.
3
20
  */
4
- export interface CustomerAccessToken {
5
- accessToken: string;
6
- expiresAt: string;
7
- }
8
- export interface Customer {
9
- id: string;
10
- email: string;
11
- firstName: string | null;
12
- lastName: string | null;
13
- displayName: string | null;
14
- phone: string | null;
15
- isEmailVerified: boolean;
16
- emailMarketing: string | null;
17
- defaultAddress: MailingAddress | null;
18
- orderCount: number;
19
- totalSpent: {
20
- amount: string;
21
- currencyCode: string;
22
- } | null;
23
- createdAt: string;
24
- updatedAt: string;
25
- }
26
- export interface MailingAddress {
27
- id: string;
28
- streetLine1: string | null;
29
- streetLine2: string | null;
30
- city: string | null;
31
- company: string | null;
32
- country: string | null;
33
- countryCode: string | null;
34
- firstName: string | null;
35
- lastName: string | null;
36
- /** Computed full name (`firstName + " " + lastName`). */
37
- name: string | null;
38
- phone: string | null;
39
- state: string | null;
40
- stateCode: string | null;
41
- postalCode: string | null;
42
- isDefault: boolean;
43
- }
44
21
  export interface AuthResult {
45
22
  accessToken: string;
46
23
  expiresAt: string;
47
24
  customer?: Customer;
48
25
  }
49
- export interface CustomerCreateInput {
50
- email: string;
51
- password: string;
52
- firstName?: string;
53
- lastName?: string;
54
- phone?: string;
55
- /** Opt-in to email marketing. `true` → SUBSCRIBED (lub PENDING gdy CONFIRMED_OPT_IN). */
56
- acceptsMarketing?: boolean;
57
- /** Marketing opt-in level — `'SINGLE_OPT_IN'` (default) lub `'CONFIRMED_OPT_IN'` (double opt-in via email). */
58
- marketingOptInLevel?: 'SINGLE_OPT_IN' | 'CONFIRMED_OPT_IN';
59
- }
60
26
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/auth/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,cAAc,EAAE,cAAc,GAAG,IAAI,CAAC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC5D,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,yDAAyD;IACzD,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yFAAyF;IACzF,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,+GAA+G;IAC/G,mBAAmB,CAAC,EAAE,eAAe,GAAG,kBAAkB,CAAC;CAC5D"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/auth/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EACV,sBAAsB,EACtB,iCAAiC,EACjC,sBAAsB,EACvB,MAAM,8BAA8B,CAAC;AAEtC,sCAAsC;AACtC,MAAM,MAAM,QAAQ,GAAG,sBAAsB,CAAC;AAE9C,4DAA4D;AAC5D,MAAM,MAAM,mBAAmB,GAAG,iCAAiC,CAAC;AAEpE,qEAAqE;AACrE,MAAM,MAAM,cAAc,GAAG,sBAAsB,CAAC;AAEpD,YAAY,EACV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,8BAA8B,CAAC;AAEtC;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB"}
@@ -1,4 +1 @@
1
- /**
2
- * Auth types — manual (no codegen).
3
- */
4
1
  export {};
@@ -22,7 +22,7 @@
22
22
  * ```
23
23
  */
24
24
  import type { StorefrontClient } from '../client/types';
25
- import type { Cart, CartCreateInput, CartLineInput, CartLineUpdateInput, CartBuyerIdentityInput, CartSetShippingAddressInput, CartSetBillingAddressInput, CartSelectShippingMethodInput, CartSelectPaymentMethodInput, CartApplyGiftCardInput, CartRemoveGiftCardInput, CartUpdateGiftCardRecipientInput, CartCompleteInput, CartWarning, Order, DiscountValidationResult, PaymentSession, PaymentCreateInput } from './types';
25
+ import type { Cart, CartCreateInput, CartLineInput, CartLineUpdateInput, CartBuyerIdentityInput, CartAttributeInput, CartSetShippingAddressInput, CartSetBillingAddressInput, CartSelectShippingMethodInput, CartSelectPaymentMethodInput, CartApplyGiftCardInput, CartRemoveGiftCardInput, CartUpdateGiftCardRecipientInput, CartCompleteInput, CartWarning, Order, DiscountValidationResult, PaymentSession, PaymentCreateInput, AvailableShippingMethodsPayload, AvailablePaymentMethods, ShippingAddressInput } from './types';
26
26
  /**
27
27
  * Standard mutation return shape — `cart` is non-null on success (userErrors
28
28
  * cause assertNoUserErrors to throw), `warnings` may be empty.
@@ -51,6 +51,47 @@ export declare class CartClient {
51
51
  * Returns null if cart doesn't exist or has expired.
52
52
  */
53
53
  get(cartId: string): Promise<Cart | null>;
54
+ /**
55
+ * Cart-aware list of shipping methods available for the given destination.
56
+ * Resolves with `null` when the cart does not exist or has expired —
57
+ * symmetric with `CartClient.get(cartId)`. Otherwise resolves with
58
+ * `AvailableShippingMethodsPayload`:
59
+ *
60
+ * - `methods[]` — methods available for this cart at the destination, each
61
+ * carrying `deliveryType` (`HOME` / `PICKUP_POINT` / `LOCKER`).
62
+ * - `freeShippingProgress` — best free-shipping progress across all
63
+ * returned methods (use for a single banner above the picker).
64
+ * - `userErrors[]` — populated by the backend for business conditions
65
+ * (e.g. `DIGITAL_ONLY_NO_SHIPPING` for a cart with no shippable lines,
66
+ * `NO_SHIPPING_METHODS` for an unsupported address). Branch on
67
+ * `userErrors[0].code`; the `message` is localized per the request's
68
+ * `Accept-Language` header.
69
+ */
70
+ getAvailableShippingMethods(cartId: string, address: ShippingAddressInput): Promise<AvailableShippingMethodsPayload | null>;
71
+ /**
72
+ * Shop-level list of active payment methods. Returns the raw payload from
73
+ * the backend:
74
+ *
75
+ * - `methods[]` — sorted by the merchant's display position.
76
+ * - `defaultMethod` — the merchant-flagged pre-selection (may be null when
77
+ * none is configured). Prefer this over scanning `methods.find(isDefault)`
78
+ * — the merchant may override the default independently of per-method
79
+ * flags.
80
+ */
81
+ getAvailablePaymentMethods(): Promise<AvailablePaymentMethods>;
82
+ /**
83
+ * Fetch a guest order by its opaque access token (returned in
84
+ * `complete().order.accessToken`). Use on the post-checkout confirmation
85
+ * page when the buyer is not signed in.
86
+ *
87
+ * Optional `email` is matched case-insensitively against the order's buyer
88
+ * email as defense in depth — on mismatch the call returns `null` with the
89
+ * same shape as an invalid token (attackers cannot distinguish the two).
90
+ *
91
+ * Backend rate-limits this query (5 requests / minute per IP + shop) and
92
+ * responses are uncached.
93
+ */
94
+ getOrderByToken(token: string, email?: string): Promise<Order | null>;
54
95
  /**
55
96
  * Create a new cart, optionally with initial lines.
56
97
  */
@@ -76,6 +117,14 @@ export declare class CartClient {
76
117
  * Update cart note / gift message.
77
118
  */
78
119
  updateNote(cartId: string, note: string): Promise<CartMutationOutcome>;
120
+ /**
121
+ * Replace the cart's custom `{ key, value }` attribute pairs — free-form
122
+ * metadata visible to the merchant (delivery instructions, gift-wrap flags,
123
+ * B2B PO numbers). Semantics is REPLACE-ALL (not merge): pass the full set
124
+ * each call, an empty array clears all attributes. Backend rejects oversized
125
+ * sets with `CART_ATTRIBUTES_LIMIT_EXCEEDED` (max 250 pairs, 255-char keys).
126
+ */
127
+ updateAttributes(cartId: string, attributes: CartAttributeInput[]): Promise<CartMutationOutcome>;
79
128
  /**
80
129
  * Update buyer identity (email, phone, country, customer link, languageCode).
81
130
  */
@@ -1 +1 @@
1
- {"version":3,"file":"cart-client.d.ts","sourceRoot":"","sources":["../../../src/core/cart/cart-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EACV,IAAI,EACJ,eAAe,EACf,aAAa,EACb,mBAAmB,EACnB,sBAAsB,EACtB,2BAA2B,EAC3B,0BAA0B,EAC1B,6BAA6B,EAC7B,4BAA4B,EAC5B,sBAAsB,EACtB,uBAAuB,EACvB,gCAAgC,EAChC,iBAAiB,EACjB,WAAW,EACX,KAAK,EACL,wBAAwB,EACxB,cAAc,EACd,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAoDjB;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,gBAAgB;IAErD;;;OAGG;IACG,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAQ/C;;OAEG;IACG,MAAM,CAAC,KAAK,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,mBAAmB,CAAC;IASnE;;OAEG;IACG,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,mBAAmB,CAAC;IASpF;;OAEG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,EAAE,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAS7F;;OAEG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,mBAAmB,CAAC;IASlF;;;OAGG;IACG,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAShG;;OAEG;IACG,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAS5E;;OAEG;IACG,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,sBAAsB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAa9G;;;OAGG;IACG,kBAAkB,CAAC,KAAK,EAAE,2BAA2B,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAS1F;;;OAGG;IACG,iBAAiB,CAAC,KAAK,EAAE,0BAA0B,GAAG,OAAO,CAAC,mBAAmB,CAAC;IASxF;;;OAGG;IACG,oBAAoB,CAAC,KAAK,EAAE,6BAA6B,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAS9F;;;OAGG;IACG,mBAAmB,CAAC,KAAK,EAAE,4BAA4B,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAS5F;;;OAGG;IACG,aAAa,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAShF;;;OAGG;IACG,cAAc,CAAC,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IASlF;;;;OAIG;IACG,uBAAuB,CAAC,KAAK,EAAE,gCAAgC,GAAG,OAAO,CAAC,mBAAmB,CAAC;IASpG;;;;;;;;;;;;OAYG;IACG,QAAQ,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAYtE;;;;;;;;;;;;;;;;OAgBG;IACG,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,cAAc,CAAC;IASvE;;;;;;;;OAQG;IACG,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,CAAC;CAOpG"}
1
+ {"version":3,"file":"cart-client.d.ts","sourceRoot":"","sources":["../../../src/core/cart/cart-client.ts"],"names":[],"mappings":"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"}
@@ -22,7 +22,7 @@
22
22
  * ```
23
23
  */
24
24
  import { assertNoUserErrors } from '../helpers/assert-no-user-errors';
25
- import { CART_QUERY, CART_CREATE, CART_ADD_LINES, CART_UPDATE_LINES, CART_REMOVE_LINES, CART_DISCOUNT_CODES_UPDATE, CART_UPDATE_NOTE, CART_UPDATE_BUYER_IDENTITY, CART_SET_SHIPPING_ADDRESS, CART_SET_BILLING_ADDRESS, CART_SELECT_SHIPPING_METHOD, CART_SELECT_PAYMENT_METHOD, CART_APPLY_GIFT_CARD, CART_REMOVE_GIFT_CARD, CART_UPDATE_GIFT_CARD_RECIPIENT, CART_COMPLETE, CART_VALIDATE_DISCOUNT_CODE, PAYMENT_CREATE, } from '../operations/cart';
25
+ import { CART_QUERY, ORDER_BY_TOKEN_QUERY, CART_AVAILABLE_SHIPPING_METHODS_QUERY, AVAILABLE_PAYMENT_METHODS_QUERY, CART_CREATE, CART_ADD_LINES, CART_UPDATE_LINES, CART_REMOVE_LINES, CART_DISCOUNT_CODES_UPDATE, CART_UPDATE_NOTE, CART_UPDATE_ATTRIBUTES, CART_UPDATE_BUYER_IDENTITY, CART_SET_SHIPPING_ADDRESS, CART_SET_BILLING_ADDRESS, CART_SELECT_SHIPPING_METHOD, CART_SELECT_PAYMENT_METHOD, CART_APPLY_GIFT_CARD, CART_REMOVE_GIFT_CARD, CART_UPDATE_GIFT_CARD_RECIPIENT, CART_COMPLETE, CART_VALIDATE_DISCOUNT_CODE, PAYMENT_CREATE, } from '../operations/cart';
26
26
  export class CartClient {
27
27
  client;
28
28
  constructor(client) {
@@ -36,6 +36,56 @@ export class CartClient {
36
36
  const data = await this.client.query(CART_QUERY, { id: cartId });
37
37
  return data.cart;
38
38
  }
39
+ /**
40
+ * Cart-aware list of shipping methods available for the given destination.
41
+ * Resolves with `null` when the cart does not exist or has expired —
42
+ * symmetric with `CartClient.get(cartId)`. Otherwise resolves with
43
+ * `AvailableShippingMethodsPayload`:
44
+ *
45
+ * - `methods[]` — methods available for this cart at the destination, each
46
+ * carrying `deliveryType` (`HOME` / `PICKUP_POINT` / `LOCKER`).
47
+ * - `freeShippingProgress` — best free-shipping progress across all
48
+ * returned methods (use for a single banner above the picker).
49
+ * - `userErrors[]` — populated by the backend for business conditions
50
+ * (e.g. `DIGITAL_ONLY_NO_SHIPPING` for a cart with no shippable lines,
51
+ * `NO_SHIPPING_METHODS` for an unsupported address). Branch on
52
+ * `userErrors[0].code`; the `message` is localized per the request's
53
+ * `Accept-Language` header.
54
+ */
55
+ async getAvailableShippingMethods(cartId, address) {
56
+ const data = await this.client.query(CART_AVAILABLE_SHIPPING_METHODS_QUERY, { cartId, address });
57
+ return data.cart?.availableShippingMethods ?? null;
58
+ }
59
+ /**
60
+ * Shop-level list of active payment methods. Returns the raw payload from
61
+ * the backend:
62
+ *
63
+ * - `methods[]` — sorted by the merchant's display position.
64
+ * - `defaultMethod` — the merchant-flagged pre-selection (may be null when
65
+ * none is configured). Prefer this over scanning `methods.find(isDefault)`
66
+ * — the merchant may override the default independently of per-method
67
+ * flags.
68
+ */
69
+ async getAvailablePaymentMethods() {
70
+ const data = await this.client.query(AVAILABLE_PAYMENT_METHODS_QUERY);
71
+ return data.availablePaymentMethods;
72
+ }
73
+ /**
74
+ * Fetch a guest order by its opaque access token (returned in
75
+ * `complete().order.accessToken`). Use on the post-checkout confirmation
76
+ * page when the buyer is not signed in.
77
+ *
78
+ * Optional `email` is matched case-insensitively against the order's buyer
79
+ * email as defense in depth — on mismatch the call returns `null` with the
80
+ * same shape as an invalid token (attackers cannot distinguish the two).
81
+ *
82
+ * Backend rate-limits this query (5 requests / minute per IP + shop) and
83
+ * responses are uncached.
84
+ */
85
+ async getOrderByToken(token, email) {
86
+ const data = await this.client.query(ORDER_BY_TOKEN_QUERY, { token, email });
87
+ return data.orderByToken;
88
+ }
39
89
  /**
40
90
  * Create a new cart, optionally with initial lines.
41
91
  */
@@ -85,6 +135,18 @@ export class CartClient {
85
135
  assertNoUserErrors(data.cartUpdateNote);
86
136
  return { cart: data.cartUpdateNote.cart, warnings: data.cartUpdateNote.warnings ?? [] };
87
137
  }
138
+ /**
139
+ * Replace the cart's custom `{ key, value }` attribute pairs — free-form
140
+ * metadata visible to the merchant (delivery instructions, gift-wrap flags,
141
+ * B2B PO numbers). Semantics is REPLACE-ALL (not merge): pass the full set
142
+ * each call, an empty array clears all attributes. Backend rejects oversized
143
+ * sets with `CART_ATTRIBUTES_LIMIT_EXCEEDED` (max 250 pairs, 255-char keys).
144
+ */
145
+ async updateAttributes(cartId, attributes) {
146
+ const data = await this.client.mutate(CART_UPDATE_ATTRIBUTES, { id: cartId, attributes });
147
+ assertNoUserErrors(data.cartUpdateAttributes);
148
+ return { cart: data.cartUpdateAttributes.cart, warnings: data.cartUpdateAttributes.warnings ?? [] };
149
+ }
88
150
  /**
89
151
  * Update buyer identity (email, phone, country, customer link, languageCode).
90
152
  */