@sixtyninecommerce/client 0.23.1 → 0.25.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 +25 -0
- package/dist/admin/forms.js +19 -0
- package/dist/admin/forms.js.map +1 -1
- package/dist/admin/http.d.ts +9 -0
- package/dist/admin/http.d.ts.map +1 -1
- package/dist/admin/http.js +3 -0
- package/dist/admin/http.js.map +1 -1
- package/dist/admin/index.d.ts +63 -0
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +67 -0
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/redirects.d.ts +6 -0
- package/dist/admin/redirects.d.ts.map +1 -1
- package/dist/admin/redirects.js +12 -0
- package/dist/admin/redirects.js.map +1 -1
- package/dist/admin/types.d.ts +63 -0
- package/dist/admin/types.d.ts.map +1 -1
- package/dist/cache-tags.d.ts +19 -0
- package/dist/cache-tags.d.ts.map +1 -1
- package/dist/cache-tags.js +19 -0
- package/dist/cache-tags.js.map +1 -1
- package/dist/client.d.ts +17 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +17 -0
- package/dist/client.js.map +1 -1
- package/dist/commerce/age-verification.js +3 -3
- package/dist/commerce/age-verification.js.map +1 -1
- package/dist/commerce/branding.js +7 -0
- package/dist/commerce/branding.js.map +1 -1
- package/dist/commerce/cart.js +25 -0
- package/dist/commerce/cart.js.map +1 -1
- package/dist/commerce/checkout.d.ts +68 -0
- package/dist/commerce/checkout.d.ts.map +1 -1
- package/dist/commerce/checkout.js +83 -0
- package/dist/commerce/checkout.js.map +1 -1
- package/dist/commerce/customer.d.ts +58 -0
- package/dist/commerce/customer.d.ts.map +1 -1
- package/dist/commerce/customer.js +65 -0
- package/dist/commerce/customer.js.map +1 -1
- package/dist/commerce/index.d.ts +17 -1
- package/dist/commerce/index.d.ts.map +1 -1
- package/dist/commerce/pickup-location-parser.d.ts +18 -0
- package/dist/commerce/pickup-location-parser.d.ts.map +1 -1
- package/dist/commerce/pickup-location-parser.js +28 -0
- package/dist/commerce/pickup-location-parser.js.map +1 -1
- package/dist/commerce/placement-error.d.ts +52 -0
- package/dist/commerce/placement-error.d.ts.map +1 -1
- package/dist/commerce/placement-error.js +87 -0
- package/dist/commerce/placement-error.js.map +1 -1
- package/dist/commerce/products.d.ts +48 -0
- package/dist/commerce/products.d.ts.map +1 -1
- package/dist/commerce/products.js +95 -2
- package/dist/commerce/products.js.map +1 -1
- package/dist/commerce/queries.d.ts +114 -27
- package/dist/commerce/queries.d.ts.map +1 -1
- package/dist/commerce/queries.js +219 -1
- package/dist/commerce/queries.js.map +1 -1
- package/dist/commerce/quotes.js +33 -0
- package/dist/commerce/quotes.js.map +1 -1
- package/dist/commerce/saved-lists.d.ts +7 -7
- package/dist/commerce/saved-lists.d.ts.map +1 -1
- package/dist/commerce/saved-lists.js +1 -1
- package/dist/commerce/search.js +3 -0
- package/dist/commerce/search.js.map +1 -1
- package/dist/commerce/shipping.js +3 -3
- package/dist/commerce/shipping.js.map +1 -1
- package/dist/commerce/stock-notifications.d.ts +11 -0
- package/dist/commerce/stock-notifications.d.ts.map +1 -1
- package/dist/commerce/stock-notifications.js +11 -0
- package/dist/commerce/stock-notifications.js.map +1 -1
- package/dist/commerce/subscriptions.d.ts +32 -8
- package/dist/commerce/subscriptions.d.ts.map +1 -1
- package/dist/commerce/subscriptions.js +90 -2
- package/dist/commerce/subscriptions.js.map +1 -1
- package/dist/commerce/vat-validation.js +4 -4
- package/dist/commerce/vat-validation.js.map +1 -1
- package/dist/constants.d.ts +31 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +32 -0
- package/dist/constants.js.map +1 -1
- package/dist/content/asset-urls.d.ts +50 -0
- package/dist/content/asset-urls.d.ts.map +1 -1
- package/dist/content/asset-urls.js +92 -0
- package/dist/content/asset-urls.js.map +1 -1
- package/dist/content/assets.d.ts +15 -0
- package/dist/content/assets.d.ts.map +1 -1
- package/dist/content/assets.js +15 -0
- package/dist/content/assets.js.map +1 -1
- package/dist/content/collection-pages.d.ts +5 -0
- package/dist/content/collection-pages.d.ts.map +1 -1
- package/dist/content/collection-pages.js +8 -0
- package/dist/content/collection-pages.js.map +1 -1
- package/dist/content/collections.d.ts +14 -0
- package/dist/content/collections.d.ts.map +1 -1
- package/dist/content/collections.js +16 -0
- package/dist/content/collections.js.map +1 -1
- package/dist/content/filtered-products.d.ts +18 -0
- package/dist/content/filtered-products.d.ts.map +1 -1
- package/dist/content/filtered-products.js +16 -0
- package/dist/content/filtered-products.js.map +1 -1
- package/dist/content/form-field-types.d.ts +6 -0
- package/dist/content/form-field-types.d.ts.map +1 -1
- package/dist/content/form-field-types.js +12 -0
- package/dist/content/form-field-types.js.map +1 -1
- package/dist/content/forms.d.ts +16 -0
- package/dist/content/forms.d.ts.map +1 -1
- package/dist/content/forms.js +23 -0
- package/dist/content/forms.js.map +1 -1
- package/dist/content/items.d.ts +26 -0
- package/dist/content/items.d.ts.map +1 -1
- package/dist/content/items.js +33 -0
- package/dist/content/items.js.map +1 -1
- package/dist/content/resolve.js +6 -0
- package/dist/content/resolve.js.map +1 -1
- package/dist/content/sitemap.d.ts +5 -0
- package/dist/content/sitemap.d.ts.map +1 -1
- package/dist/content/sitemap.js +5 -0
- package/dist/content/sitemap.js.map +1 -1
- package/dist/core/context.js +6 -0
- package/dist/core/context.js.map +1 -1
- package/dist/core/headers.js +2 -0
- package/dist/core/headers.js.map +1 -1
- package/dist/core/http.d.ts +8 -0
- package/dist/core/http.d.ts.map +1 -1
- package/dist/core/http.js +89 -1
- package/dist/core/http.js.map +1 -1
- package/dist/credit/credit-status.js +2 -2
- package/dist/credit/credit-status.js.map +1 -1
- package/dist/credit/payment-terms.js +2 -2
- package/dist/credit/payment-terms.js.map +1 -1
- package/dist/currency/exchange.d.ts +11 -0
- package/dist/currency/exchange.d.ts.map +1 -1
- package/dist/currency/exchange.js +11 -0
- package/dist/currency/exchange.js.map +1 -1
- package/dist/errors.d.ts +50 -2
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +50 -3
- package/dist/errors.js.map +1 -1
- package/dist/events/envelope.d.ts +36 -0
- package/dist/events/envelope.d.ts.map +1 -1
- package/dist/events/envelope.js +12 -0
- package/dist/events/envelope.js.map +1 -1
- package/dist/events/index.d.ts +13 -0
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +13 -0
- package/dist/events/index.js.map +1 -1
- package/dist/events/payloads.d.ts +19 -0
- package/dist/events/payloads.d.ts.map +1 -1
- package/dist/events/payloads.js +12 -0
- package/dist/events/payloads.js.map +1 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/media/index.js +2 -0
- package/dist/media/index.js.map +1 -1
- package/dist/media/urls.d.ts +52 -0
- package/dist/media/urls.d.ts.map +1 -1
- package/dist/media/urls.js +38 -0
- package/dist/media/urls.js.map +1 -1
- package/dist/media/video.d.ts +16 -0
- package/dist/media/video.d.ts.map +1 -1
- package/dist/media/video.js +16 -0
- package/dist/media/video.js.map +1 -1
- package/dist/next/artifact-handler.d.ts +22 -0
- package/dist/next/artifact-handler.d.ts.map +1 -1
- package/dist/next/artifact-handler.js +22 -0
- package/dist/next/artifact-handler.js.map +1 -1
- package/dist/next/event-revalidate-handler.d.ts +67 -0
- package/dist/next/event-revalidate-handler.d.ts.map +1 -1
- package/dist/next/event-revalidate-handler.js +48 -0
- package/dist/next/event-revalidate-handler.js.map +1 -1
- package/dist/next/index.d.ts +6 -0
- package/dist/next/index.d.ts.map +1 -1
- package/dist/next/index.js +6 -0
- package/dist/next/index.js.map +1 -1
- package/dist/next/json-ld.d.ts +9 -0
- package/dist/next/json-ld.d.ts.map +1 -1
- package/dist/next/json-ld.js +9 -0
- package/dist/next/json-ld.js.map +1 -1
- package/dist/next/metadata.d.ts +18 -0
- package/dist/next/metadata.d.ts.map +1 -1
- package/dist/next/metadata.js +21 -0
- package/dist/next/metadata.js.map +1 -1
- package/dist/next/redirect-middleware.d.ts +39 -0
- package/dist/next/redirect-middleware.d.ts.map +1 -1
- package/dist/next/redirect-middleware.js +32 -0
- package/dist/next/redirect-middleware.js.map +1 -1
- package/dist/next/revalidate-handler.d.ts +30 -0
- package/dist/next/revalidate-handler.d.ts.map +1 -1
- package/dist/next/revalidate-handler.js +22 -0
- package/dist/next/revalidate-handler.js.map +1 -1
- package/dist/order-scope.d.ts +27 -0
- package/dist/order-scope.d.ts.map +1 -1
- package/dist/order-scope.js +29 -0
- package/dist/order-scope.js.map +1 -1
- package/dist/pricing/format.d.ts +17 -0
- package/dist/pricing/format.d.ts.map +1 -1
- package/dist/pricing/format.js +19 -0
- package/dist/pricing/format.js.map +1 -1
- package/dist/pricing/index.d.ts +8 -1
- package/dist/pricing/index.d.ts.map +1 -1
- package/dist/pricing/index.js +18 -2
- package/dist/pricing/index.js.map +1 -1
- package/dist/pricing/tax-display.d.ts +77 -0
- package/dist/pricing/tax-display.d.ts.map +1 -1
- package/dist/pricing/tax-display.js +85 -0
- package/dist/pricing/tax-display.js.map +1 -1
- package/dist/pricing/tiers.d.ts +9 -0
- package/dist/pricing/tiers.d.ts.map +1 -1
- package/dist/pricing/tiers.js +9 -0
- package/dist/pricing/tiers.js.map +1 -1
- package/dist/pricing/validation.d.ts +56 -1
- package/dist/pricing/validation.d.ts.map +1 -1
- package/dist/pricing/validation.js +61 -0
- package/dist/pricing/validation.js.map +1 -1
- package/dist/redirects/index.d.ts +1 -0
- package/dist/redirects/index.d.ts.map +1 -1
- package/dist/redirects/index.js +1 -0
- package/dist/redirects/index.js.map +1 -1
- package/dist/redirects/store.d.ts +20 -0
- package/dist/redirects/store.d.ts.map +1 -1
- package/dist/redirects/store.js +57 -0
- package/dist/redirects/store.js.map +1 -1
- package/dist/redirects/types.d.ts +24 -0
- package/dist/redirects/types.d.ts.map +1 -1
- package/dist/redirects/types.js +1 -0
- package/dist/redirects/types.js.map +1 -1
- package/dist/revalidation/event-plan.d.ts +48 -0
- package/dist/revalidation/event-plan.d.ts.map +1 -1
- package/dist/revalidation/event-plan.js +61 -0
- package/dist/revalidation/event-plan.js.map +1 -1
- package/dist/revalidation/event-verify.d.ts +25 -0
- package/dist/revalidation/event-verify.d.ts.map +1 -1
- package/dist/revalidation/event-verify.js +27 -0
- package/dist/revalidation/event-verify.js.map +1 -1
- package/dist/revalidation/types.d.ts +20 -0
- package/dist/revalidation/types.d.ts.map +1 -1
- package/dist/revalidation/types.js +10 -0
- package/dist/revalidation/types.js.map +1 -1
- package/dist/revalidation/url-context.d.ts +25 -0
- package/dist/revalidation/url-context.d.ts.map +1 -1
- package/dist/revalidation/url-context.js +17 -0
- package/dist/revalidation/url-context.js.map +1 -1
- package/dist/revalidation/verify.d.ts +8 -0
- package/dist/revalidation/verify.d.ts.map +1 -1
- package/dist/revalidation/verify.js +8 -0
- package/dist/revalidation/verify.js.map +1 -1
- package/dist/seo/ai.d.ts +17 -0
- package/dist/seo/ai.d.ts.map +1 -1
- package/dist/seo/ai.js +12 -0
- package/dist/seo/ai.js.map +1 -1
- package/dist/seo/alternates.js +13 -0
- package/dist/seo/alternates.js.map +1 -1
- package/dist/seo/artifacts.d.ts +13 -0
- package/dist/seo/artifacts.d.ts.map +1 -1
- package/dist/seo/artifacts.js +19 -0
- package/dist/seo/artifacts.js.map +1 -1
- package/dist/seo/canonical.d.ts +15 -0
- package/dist/seo/canonical.d.ts.map +1 -1
- package/dist/seo/canonical.js +24 -0
- package/dist/seo/canonical.js.map +1 -1
- package/dist/seo/index.js +6 -0
- package/dist/seo/index.js.map +1 -1
- package/dist/seo/json-ld.d.ts +13 -0
- package/dist/seo/json-ld.d.ts.map +1 -1
- package/dist/seo/json-ld.js +32 -0
- package/dist/seo/json-ld.js.map +1 -1
- package/dist/seo/locale-tag.d.ts +31 -0
- package/dist/seo/locale-tag.d.ts.map +1 -1
- package/dist/seo/locale-tag.js +31 -0
- package/dist/seo/locale-tag.js.map +1 -1
- package/dist/seo/meta-tags.d.ts +29 -0
- package/dist/seo/meta-tags.d.ts.map +1 -1
- package/dist/seo/meta-tags.js +28 -0
- package/dist/seo/meta-tags.js.map +1 -1
- package/dist/seo/metadata-parser.d.ts +24 -0
- package/dist/seo/metadata-parser.d.ts.map +1 -1
- package/dist/seo/metadata-parser.js +38 -0
- package/dist/seo/metadata-parser.js.map +1 -1
- package/dist/seo/metadata-types.d.ts +16 -0
- package/dist/seo/metadata-types.d.ts.map +1 -1
- package/dist/seo/product-path.d.ts +96 -0
- package/dist/seo/product-path.d.ts.map +1 -1
- package/dist/seo/product-path.js +96 -0
- package/dist/seo/product-path.js.map +1 -1
- package/dist/seo/robots.d.ts +17 -0
- package/dist/seo/robots.d.ts.map +1 -1
- package/dist/seo/robots.js +12 -0
- package/dist/seo/robots.js.map +1 -1
- package/dist/seo/types.d.ts +39 -0
- package/dist/seo/types.d.ts.map +1 -1
- package/dist/seo/url-builder.d.ts +31 -0
- package/dist/seo/url-builder.d.ts.map +1 -1
- package/dist/seo/url-builder.js +36 -0
- package/dist/seo/url-builder.js.map +1 -1
- package/dist/types.d.ts +1283 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/types.d.ts
CHANGED
|
@@ -1,15 +1,44 @@
|
|
|
1
|
+
/** Retry configuration for transient GET failures. */
|
|
1
2
|
export interface RetryConfig {
|
|
3
|
+
/** Maximum number of attempts including the first request. Default: 2. */
|
|
2
4
|
attempts?: number;
|
|
5
|
+
/** Base delay in ms for exponential backoff. Default: 200. */
|
|
3
6
|
baseDelayMs?: number;
|
|
4
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* Per-call request controls. Pass to read methods (catalog, content,
|
|
10
|
+
* navigation) to cancel in-flight requests — useful for SSR and
|
|
11
|
+
* search-as-you-type.
|
|
12
|
+
*/
|
|
5
13
|
export interface RequestOptions {
|
|
6
14
|
signal?: AbortSignal;
|
|
15
|
+
/**
|
|
16
|
+
* Extra cache tags for this request, added to the SDK's own — e.g.
|
|
17
|
+
* `getProduct(slug, { cacheTags: [productCacheTag(route.id)] })` when the id
|
|
18
|
+
* is already known from the route manifest. Applied to commerce (Vendure)
|
|
19
|
+
* requests only; see {@link StorefrontClientConfig.cacheTags}.
|
|
20
|
+
*/
|
|
7
21
|
cacheTags?: readonly string[];
|
|
8
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Decides the cache tags a commerce request carries. Receives the SDK's
|
|
25
|
+
* defaults (plus any per-request `cacheTags`) and the SDK method name
|
|
26
|
+
* (`getProduct`, `getProductById`, `searchProducts`, …); returns what to send.
|
|
27
|
+
*/
|
|
9
28
|
export type CacheTagResolver = (tags: readonly string[], request: {
|
|
10
29
|
readonly operation: string;
|
|
11
30
|
}) => readonly string[];
|
|
31
|
+
/**
|
|
32
|
+
* Which storefront a cart/order belongs to.
|
|
33
|
+
*
|
|
34
|
+
* A tenant can run a consumer shop and a trade (B2B/dealer) shop off ONE
|
|
35
|
+
* channel. Without a scope both storefronts share a single active order per
|
|
36
|
+
* customer, because Vendure's fallback lookup is "the one active order for this
|
|
37
|
+
* customer in this channel" — separate cookies do not change that. Setting a
|
|
38
|
+
* scope keeps the two carts apart.
|
|
39
|
+
*/
|
|
12
40
|
export type OrderScope = 'CONSUMER' | 'TRADE';
|
|
41
|
+
/** Configuration for creating a storefront client. */
|
|
13
42
|
export interface StorefrontClientConfig {
|
|
14
43
|
storeCode: string;
|
|
15
44
|
cdnUrl: string;
|
|
@@ -18,18 +47,96 @@ export interface StorefrontClientConfig {
|
|
|
18
47
|
pluginsUrl?: string;
|
|
19
48
|
defaultLanguageCode?: string;
|
|
20
49
|
fetch?: typeof globalThis.fetch;
|
|
50
|
+
/** Called when an auth token is received from Vendure (e.g. after login). Use to persist the token. */
|
|
21
51
|
onAuthToken?: (token: string) => void;
|
|
52
|
+
/**
|
|
53
|
+
* Called when the SDK detects the stored session is genuinely dead. Fires on
|
|
54
|
+
* an UNAUTHORIZED error, and on a FORBIDDEN error only when a follow-up
|
|
55
|
+
* `activeCustomer` probe confirms there is no active session — Vendure's Shop
|
|
56
|
+
* API returns FORBIDDEN for both an expired session and a real authorization
|
|
57
|
+
* denial, so the probe is what tells them apart. Use to prompt re-login or
|
|
58
|
+
* clear local user state. A FORBIDDEN with a still-valid session is an
|
|
59
|
+
* authorization denial, NOT an expiry: `onAuthExpired` does not fire and the
|
|
60
|
+
* caller receives a StorefrontError with `errorCode: 'FORBIDDEN'` /
|
|
61
|
+
* `statusCode: 403` to handle.
|
|
62
|
+
*/
|
|
22
63
|
onAuthExpired?: () => void;
|
|
64
|
+
/**
|
|
65
|
+
* Called after `logout()` clears the stored auth token — the inverse of
|
|
66
|
+
* `onAuthToken`. Use to drop the persisted token from storage/cookies. NOT
|
|
67
|
+
* fired on session expiry (that is `onAuthExpired`).
|
|
68
|
+
*/
|
|
23
69
|
onAuthCleared?: () => void;
|
|
70
|
+
/**
|
|
71
|
+
* Retry config for transient GET failures (network errors and 502/503/504).
|
|
72
|
+
* Defaults to `{ attempts: 2, baseDelayMs: 200 }`. Set `attempts: 1` to
|
|
73
|
+
* disable retries entirely. Mutations are never retried.
|
|
74
|
+
*/
|
|
24
75
|
retry?: RetryConfig;
|
|
76
|
+
/**
|
|
77
|
+
* Which storefront this client speaks for — `'CONSUMER'` or `'TRADE'`. Sent
|
|
78
|
+
* as the `x-order-scope` header on every Vendure Shop API request, which is
|
|
79
|
+
* what keeps a dealer's consumer basket and trade order separate on a single
|
|
80
|
+
* channel.
|
|
81
|
+
*
|
|
82
|
+
* Leave it unset for a single-storefront tenant: the engine then behaves
|
|
83
|
+
* exactly as stock Vendure does. Unset is NOT the same as `'CONSUMER'` — a
|
|
84
|
+
* client that omits the header never has an existing trade cart reclassified.
|
|
85
|
+
*
|
|
86
|
+
* A `'TRADE'` cart requires a logged-in customer; the engine rejects an
|
|
87
|
+
* anonymous trade order with `error.trade-order-requires-authentication`.
|
|
88
|
+
*
|
|
89
|
+
* Per client, not per request — run two clients (or call `setOrderScope`) if
|
|
90
|
+
* one process serves both storefronts.
|
|
91
|
+
*/
|
|
25
92
|
orderScope?: OrderScope;
|
|
93
|
+
/**
|
|
94
|
+
* Cache tags on product and collection reads, for Next.js `revalidateTag` —
|
|
95
|
+
* the tags `createEventRevalidateHandler` purges. The SDK adds
|
|
96
|
+
* `next: { tags }` to the fetch init (Next reads it; other fetch
|
|
97
|
+
* implementations ignore unknown init keys) and sets no cache policy:
|
|
98
|
+
* whether a request is cached stays your app's decision.
|
|
99
|
+
*
|
|
100
|
+
* - `true` (default): tags derived from each call's inputs — `product:<id>`
|
|
101
|
+
* for `getProductById` and `getProductProperties`, `collection:<id>` for
|
|
102
|
+
* `getCollectionById`, `getProductsInCollectionById` and `searchProducts`
|
|
103
|
+
* with `collectionId`/`collectionIds`.
|
|
104
|
+
* - `false`: no `next` key on any request.
|
|
105
|
+
* - a {@link CacheTagResolver}: decides per request.
|
|
106
|
+
*
|
|
107
|
+
* Load pages by the id `findRoute` resolves and they are tagged. Raw slug
|
|
108
|
+
* reads (`getProduct(slug)`, `getCollection(slug)`,
|
|
109
|
+
* `getProductsInCollection(slug)`) stay untagged — the id is not known until
|
|
110
|
+
* the response arrives; pass `route.cacheTags` per request to tag one.
|
|
111
|
+
*/
|
|
26
112
|
cacheTags?: boolean | CacheTagResolver;
|
|
27
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Storefront-visible Channel custom fields. Enumerates fields the SDK or its
|
|
116
|
+
* consumers read directly. Unknown fields are still accessible via the index
|
|
117
|
+
* signature, so adding a new field on the backend doesn't require an SDK
|
|
118
|
+
* release for storefronts to consume it.
|
|
119
|
+
*/
|
|
28
120
|
export interface ChannelCustomFields {
|
|
121
|
+
/** SDK consumes this to gate the entire client into read-only mode. */
|
|
29
122
|
maintenanceMode?: boolean;
|
|
123
|
+
/** Custom CDN domain for asset URLs (set per-channel via cdn-domain plugin). */
|
|
30
124
|
cdnDomain?: string | null;
|
|
125
|
+
/**
|
|
126
|
+
* Absolute URL of the storefront for this channel (e.g. `https://store.example.com`).
|
|
127
|
+
* Required by the SEO module to emit canonical URLs and hreflang tags.
|
|
128
|
+
*/
|
|
31
129
|
storefrontUrl?: string;
|
|
130
|
+
/**
|
|
131
|
+
* URL strategy the storefront uses to encode the active language. Drives
|
|
132
|
+
* canonical/alternate URL generation in the SEO module.
|
|
133
|
+
*/
|
|
32
134
|
urlLocaleStrategy?: 'path-prefix' | 'subdomain' | 'none';
|
|
135
|
+
/**
|
|
136
|
+
* When `true`, the URL still includes a locale prefix even for the channel's
|
|
137
|
+
* default language. When `false` (default), the default language URL has no
|
|
138
|
+
* prefix.
|
|
139
|
+
*/
|
|
33
140
|
urlLocalePrefixDefault?: boolean;
|
|
34
141
|
businessName?: string | null;
|
|
35
142
|
businessDescription?: string | null;
|
|
@@ -50,19 +157,50 @@ export interface ChannelCustomFields {
|
|
|
50
157
|
postalCode?: string | null;
|
|
51
158
|
province?: string | null;
|
|
52
159
|
country?: string | null;
|
|
160
|
+
/** JSON-encoded social URLs map. Keys: facebook, instagram, twitter, linkedin, youtube, tiktok. */
|
|
53
161
|
socialLinks?: string | null;
|
|
54
162
|
commercePathPrefix?: string | null;
|
|
163
|
+
/** JSON-encoded `{ [languageCode]: pathPrefix }` per-locale overrides. */
|
|
55
164
|
commercePathPrefixTranslations?: string | null;
|
|
165
|
+
/** Segment canonical product URLs sit under. Unset/empty means `products`. */
|
|
56
166
|
productPathSegment?: string | null;
|
|
167
|
+
/** Channel default Twitter / X handle (without @). Used by `metaTagsFor()` for `twitter:site`. */
|
|
57
168
|
twitterHandle?: string | null;
|
|
169
|
+
/** Vendure Asset ID used as the fallback OpenGraph image when a product does not provide one. */
|
|
58
170
|
defaultOgImageId?: string | null;
|
|
171
|
+
/** When true, the storefront serves `/llms.txt` advertising AI-friendly endpoints. */
|
|
59
172
|
llmsTxtEnabled?: boolean;
|
|
173
|
+
/**
|
|
174
|
+
* When true, B2B customers can submit quote requests on this channel.
|
|
175
|
+
* Storefronts should gate quote UI (request-quote buttons, "My quotes"
|
|
176
|
+
* account section) on this flag instead of probing `createQuoteRequest`.
|
|
177
|
+
*/
|
|
60
178
|
quotesEnabled?: boolean;
|
|
179
|
+
/**
|
|
180
|
+
* When true, customers can request order returns on this channel.
|
|
181
|
+
* Storefronts should gate return UI ("Request return" buttons, "My
|
|
182
|
+
* returns" account section) on this flag instead of probing
|
|
183
|
+
* `requestReturn`.
|
|
184
|
+
*/
|
|
61
185
|
returnsEnabled?: boolean;
|
|
186
|
+
/** Days after delivery/shipment during which a return may be requested. */
|
|
62
187
|
returnWindowDays?: number;
|
|
188
|
+
/**
|
|
189
|
+
* Channel-wide display default: `channel` (follow `pricesIncludeTax`),
|
|
190
|
+
* `gross` or `net`. Raw storage value — read it with `parseTaxDisplayPolicy`
|
|
191
|
+
* and render from `pricing.getTaxDisplayMode()`, which resolves the whole
|
|
192
|
+
* policy server-side for the actual shopper.
|
|
193
|
+
*/
|
|
63
194
|
taxDisplayDefault?: string | null;
|
|
195
|
+
/** B2B override: `inherit`, `gross` or `net`. See {@link taxDisplayDefault}. */
|
|
64
196
|
taxDisplayB2b?: string | null;
|
|
197
|
+
/**
|
|
198
|
+
* JSON array of ISO-3166 alpha-2 codes, e.g. `["US"]`. A shopper whose
|
|
199
|
+
* country is listed always sees prices excl. tax AND is taxed by their own
|
|
200
|
+
* country's tax zone. Empty/unset = the rule is off.
|
|
201
|
+
*/
|
|
65
202
|
taxExclusiveCountries?: string | null;
|
|
203
|
+
/** Forward-compat: any additional storefront-visible custom fields. */
|
|
66
204
|
[key: string]: unknown;
|
|
67
205
|
}
|
|
68
206
|
export interface BrandingAssetRef {
|
|
@@ -77,6 +215,7 @@ export interface BrandingFontResource {
|
|
|
77
215
|
kind: 'google' | 'self_hosted';
|
|
78
216
|
family: string;
|
|
79
217
|
weights: number[];
|
|
218
|
+
/** Resolved Asset references for self-hosted fonts. Empty for Google Fonts. */
|
|
80
219
|
files: BrandingAssetRef[];
|
|
81
220
|
}
|
|
82
221
|
export interface BrandingSocialLinks {
|
|
@@ -120,6 +259,11 @@ export interface BrandingLegal {
|
|
|
120
259
|
}
|
|
121
260
|
export interface BrandingStorefrontConfig {
|
|
122
261
|
url: string | null;
|
|
262
|
+
/**
|
|
263
|
+
* Resolved CDN base URL. When the channel sets `cdnDomain`, this is
|
|
264
|
+
* `https://{cdnDomain}`; otherwise it falls back to the global CDN URL the
|
|
265
|
+
* client was constructed with.
|
|
266
|
+
*/
|
|
123
267
|
cdnUrl: string;
|
|
124
268
|
urlLocaleStrategy: 'path-prefix' | 'subdomain' | 'none';
|
|
125
269
|
urlLocalePrefixDefault: boolean;
|
|
@@ -139,15 +283,23 @@ export interface BrandingInfo {
|
|
|
139
283
|
social: BrandingSocialLinks;
|
|
140
284
|
storefront: BrandingStorefrontConfig;
|
|
141
285
|
}
|
|
286
|
+
/** Channel info resolved from CMS at initialization. */
|
|
142
287
|
export interface ChannelInfo {
|
|
143
288
|
id: string;
|
|
144
289
|
code: string;
|
|
145
290
|
token: string;
|
|
146
291
|
defaultLanguageCode: string;
|
|
147
292
|
defaultCurrencyCode: string;
|
|
293
|
+
/**
|
|
294
|
+
* The channel's tax-display storage mode. When `true`, `price`/`*Price`
|
|
295
|
+
* fields already include tax; when `false`, they are net and the gross
|
|
296
|
+
* figure lives in the matching `priceWithTax`/`*PriceWithTax` field. Drives
|
|
297
|
+
* net-vs-gross display decisions (e.g. a B2B/B2C BTW toggle).
|
|
298
|
+
*/
|
|
148
299
|
pricesIncludeTax: boolean;
|
|
149
300
|
customFields: ChannelCustomFields;
|
|
150
301
|
}
|
|
302
|
+
/** Shared context used by all modules. */
|
|
151
303
|
export interface StoreContext {
|
|
152
304
|
channel: ChannelInfo;
|
|
153
305
|
cdnUrl: string;
|
|
@@ -157,9 +309,21 @@ export interface StoreContext {
|
|
|
157
309
|
pluginsUrl: string;
|
|
158
310
|
languageCode: string;
|
|
159
311
|
currencyCode: string;
|
|
312
|
+
/** Channel tax-display storage mode — see {@link ChannelInfo.pricesIncludeTax}. */
|
|
160
313
|
pricesIncludeTax: boolean;
|
|
161
314
|
authToken: string | null;
|
|
315
|
+
/**
|
|
316
|
+
* Active order scope, emitted as the `x-order-scope` header. `null`/absent
|
|
317
|
+
* means "send no header" — legacy, unscoped behaviour. See
|
|
318
|
+
* {@link StorefrontClientConfig.orderScope}.
|
|
319
|
+
*/
|
|
162
320
|
orderScope?: OrderScope | null;
|
|
321
|
+
/**
|
|
322
|
+
* Last resolved tax display mode, cached against the identity it was resolved
|
|
323
|
+
* for (see `identityStamp`). Owned by `pricing.getTaxDisplayMode()`; cleared
|
|
324
|
+
* by `setShippingAddress` because moving the order's country can flip the
|
|
325
|
+
* mode without changing the identity. Treat as internal.
|
|
326
|
+
*/
|
|
163
327
|
taxDisplay?: ResolvedTaxDisplay | null;
|
|
164
328
|
fetch: typeof globalThis.fetch;
|
|
165
329
|
onAuthToken?: (token: string) => void;
|
|
@@ -169,6 +333,7 @@ export interface StoreContext {
|
|
|
169
333
|
attempts: number;
|
|
170
334
|
baseDelayMs: number;
|
|
171
335
|
};
|
|
336
|
+
/** See {@link StorefrontClientConfig.cacheTags}. Absent means `true`. */
|
|
172
337
|
cacheTags?: boolean | CacheTagResolver;
|
|
173
338
|
}
|
|
174
339
|
export interface GraphQLResponse<T = unknown> {
|
|
@@ -202,7 +367,9 @@ export interface AssetPresets {
|
|
|
202
367
|
export interface Asset {
|
|
203
368
|
source: string;
|
|
204
369
|
name?: string;
|
|
370
|
+
/** Intrinsic pixel width of the source image. Absent when not selected. */
|
|
205
371
|
width?: number | null;
|
|
372
|
+
/** Intrinsic pixel height of the source image. Absent when not selected. */
|
|
206
373
|
height?: number | null;
|
|
207
374
|
customFields?: {
|
|
208
375
|
altText?: string;
|
|
@@ -214,6 +381,7 @@ export interface CmsAssetTranslation {
|
|
|
214
381
|
language_code: string;
|
|
215
382
|
alt_text: string | null;
|
|
216
383
|
}
|
|
384
|
+
/** Public-safe CMS asset returned by /assets/lookup, /public-assets/:id. */
|
|
217
385
|
export interface CmsAsset {
|
|
218
386
|
id: string;
|
|
219
387
|
filename: string;
|
|
@@ -265,15 +433,52 @@ export interface ProductVariant {
|
|
|
265
433
|
priceWithTax: number;
|
|
266
434
|
currencyCode: string;
|
|
267
435
|
stockLevel: string;
|
|
436
|
+
/**
|
|
437
|
+
* Physical on-hand stock across the channel's locations. `null` when the
|
|
438
|
+
* channel does not expose operational stock numbers (the default) — fall
|
|
439
|
+
* back to the `stockLevel` string.
|
|
440
|
+
*/
|
|
268
441
|
stockOnHand: number | null;
|
|
442
|
+
/** Stock reserved by open orders. `null` when the channel does not expose it. */
|
|
269
443
|
stockAllocated: number | null;
|
|
444
|
+
/**
|
|
445
|
+
* Units a customer can actually order right now (available-to-promise).
|
|
446
|
+
* `null` when the channel does not expose operational stock numbers.
|
|
447
|
+
*/
|
|
270
448
|
saleable: number | null;
|
|
449
|
+
/**
|
|
450
|
+
* Units already on order from suppliers (e.g. open Exact purchase orders).
|
|
451
|
+
* `null` unless the channel exposes stock AND the signed-in customer's group
|
|
452
|
+
* may see incoming stock — anonymous visitors always get `null`.
|
|
453
|
+
*/
|
|
271
454
|
incomingStock: number | null;
|
|
455
|
+
/** Forward-looking `max(0, saleable) + incomingStock`. Same gate as `incomingStock`. */
|
|
272
456
|
projectedSaleable: number | null;
|
|
457
|
+
/**
|
|
458
|
+
* Earliest FUTURE expected warehouse arrival, ISO 8601. Never a past date.
|
|
459
|
+
* `null` under the same gate as `incomingStock`, and ALSO when no open line
|
|
460
|
+
* has a future date — so `incomingStock > 0` with `nextExpectedArrival: null`
|
|
461
|
+
* is normal (on order, but every date is overdue or missing). Show a dateless
|
|
462
|
+
* "restock on order" hint then. This is a warehouse-arrival estimate, never a
|
|
463
|
+
* delivery promise.
|
|
464
|
+
*/
|
|
273
465
|
nextExpectedArrival: string | null;
|
|
466
|
+
/**
|
|
467
|
+
* Units BEYOND `saleable` the signed-in customer may order on backorder right
|
|
468
|
+
* now. The quantity ceiling is `max(0, saleable) + backorderAllowance` (see
|
|
469
|
+
* `maxOrderableQuantity` in `@sixtyninecommerce/client/pricing`). `null` when
|
|
470
|
+
* the question does not apply — anonymous, group may not backorder, or the
|
|
471
|
+
* channel hides stock — treat exactly like today; `0` = denied; a large
|
|
472
|
+
* value (2,000,000,000) is the "unlimited" sentinel. A snapshot: the server
|
|
473
|
+
* re-checks on add-to-cart and at placement and refuses with the usual
|
|
474
|
+
* `InsufficientStockError` / `INSUFFICIENT_STOCK`, whose `quantityAvailable`
|
|
475
|
+
* then already includes the allowance.
|
|
476
|
+
*/
|
|
477
|
+
backorderAllowance: number | null;
|
|
274
478
|
priceListName: string | null;
|
|
275
479
|
retailPrice: number | null;
|
|
276
480
|
retailPriceWithTax: number | null;
|
|
481
|
+
/** Tax rate applied to this price in the active channel/zone, e.g. `{ value: 21 }` for 21% VAT. */
|
|
277
482
|
taxRateApplied: {
|
|
278
483
|
value: number;
|
|
279
484
|
} | null;
|
|
@@ -303,6 +508,14 @@ export interface CollectionRef {
|
|
|
303
508
|
name: string;
|
|
304
509
|
slug: string;
|
|
305
510
|
position?: number;
|
|
511
|
+
/**
|
|
512
|
+
* The parent's `slug` is load-bearing, not decoration: a top-level collection
|
|
513
|
+
* is parented to the `__root_collection__` SENTINEL (Vendure resolves `parent`
|
|
514
|
+
* to null only when the real parent is PRIVATE), so the slug is what
|
|
515
|
+
* distinguishes "this is a root" from "this is nested". The SDK's own product
|
|
516
|
+
* queries select it. A caller writing its own query and omitting it gets the
|
|
517
|
+
* flat product path for every canonical — see `isUserFacingRoot`.
|
|
518
|
+
*/
|
|
306
519
|
parent?: {
|
|
307
520
|
id: string;
|
|
308
521
|
slug?: string;
|
|
@@ -342,6 +555,7 @@ export interface PublicProductDocument {
|
|
|
342
555
|
fileMimeType: string;
|
|
343
556
|
fileSize: number;
|
|
344
557
|
fileName: string;
|
|
558
|
+
/** When true, the URL is presigned and short-lived. Don't cache it. */
|
|
345
559
|
requiresAuth: boolean;
|
|
346
560
|
}
|
|
347
561
|
export interface Product {
|
|
@@ -357,6 +571,11 @@ export interface Product {
|
|
|
357
571
|
collections: CollectionRef[];
|
|
358
572
|
translations?: ProductTranslation[];
|
|
359
573
|
documents?: PublicProductDocument[];
|
|
574
|
+
/**
|
|
575
|
+
* Per-product SEO/social/AI metadata. Resolved server-side for the active
|
|
576
|
+
* language and validated client-side at the SDK boundary. `null` when no
|
|
577
|
+
* metadata has been authored for this product on the current channel.
|
|
578
|
+
*/
|
|
360
579
|
metadata?: import('./seo/metadata-types.js').ProductMetadata | null;
|
|
361
580
|
}
|
|
362
581
|
export interface RecommendedProductGroup {
|
|
@@ -369,6 +588,7 @@ export interface ProductSummary {
|
|
|
369
588
|
name: string;
|
|
370
589
|
slug: string;
|
|
371
590
|
description?: string;
|
|
591
|
+
/** Whether the product is enabled on the channel. Selected by `LIST_PRODUCTS`. */
|
|
372
592
|
enabled?: boolean;
|
|
373
593
|
featuredAsset: Asset | null;
|
|
374
594
|
variants: Array<{
|
|
@@ -379,12 +599,21 @@ export interface ProductSummary {
|
|
|
379
599
|
priceWithTax: number;
|
|
380
600
|
currencyCode: string;
|
|
381
601
|
stockLevel: string;
|
|
602
|
+
/** ATP numbers — `null` when the channel does not expose operational stock. */
|
|
382
603
|
stockOnHand?: number | null;
|
|
383
604
|
stockAllocated?: number | null;
|
|
384
605
|
saleable?: number | null;
|
|
606
|
+
/**
|
|
607
|
+
* Incoming-stock numbers — additionally `null` unless the signed-in customer's
|
|
608
|
+
* group may see incoming stock. `nextExpectedArrival` is the earliest FUTURE
|
|
609
|
+
* arrival (ISO 8601, never past) and is `null` when every open line is overdue,
|
|
610
|
+
* even while `incomingStock > 0`.
|
|
611
|
+
*/
|
|
385
612
|
incomingStock?: number | null;
|
|
386
613
|
projectedSaleable?: number | null;
|
|
387
614
|
nextExpectedArrival?: string | null;
|
|
615
|
+
/** Units beyond `saleable` this buyer may backorder; `null` = not applicable. */
|
|
616
|
+
backorderAllowance?: number | null;
|
|
388
617
|
availabilityByLocation?: VariantLocationAvailability[];
|
|
389
618
|
priceListName?: string | null;
|
|
390
619
|
retailPrice?: number | null;
|
|
@@ -417,6 +646,7 @@ export interface Breadcrumb {
|
|
|
417
646
|
name: string;
|
|
418
647
|
slug: string;
|
|
419
648
|
}
|
|
649
|
+
/** Per-language translation of a collection, including SEO custom fields. */
|
|
420
650
|
export interface CollectionTranslation {
|
|
421
651
|
languageCode: string;
|
|
422
652
|
name?: string;
|
|
@@ -430,6 +660,7 @@ export interface CollectionTranslation {
|
|
|
430
660
|
socialImageAlt?: string | null;
|
|
431
661
|
} | null;
|
|
432
662
|
}
|
|
663
|
+
/** Collection-scoped custom fields: routing directives + SEO scalars. */
|
|
433
664
|
export interface CollectionCustomFields {
|
|
434
665
|
isRoutable?: boolean | null;
|
|
435
666
|
isCanonical?: boolean | null;
|
|
@@ -462,12 +693,21 @@ export interface CollectionDetail extends Collection {
|
|
|
462
693
|
priceWithTax: number;
|
|
463
694
|
currencyCode: string;
|
|
464
695
|
stockLevel: string;
|
|
696
|
+
/** ATP numbers — `null` when the channel does not expose operational stock. */
|
|
465
697
|
stockOnHand: number | null;
|
|
466
698
|
stockAllocated: number | null;
|
|
467
699
|
saleable: number | null;
|
|
700
|
+
/**
|
|
701
|
+
* Incoming-stock numbers — additionally `null` unless the signed-in customer's
|
|
702
|
+
* group may see incoming stock. `nextExpectedArrival` is the earliest FUTURE
|
|
703
|
+
* arrival (ISO 8601, never past) and is `null` when every open line is overdue,
|
|
704
|
+
* even while `incomingStock > 0`.
|
|
705
|
+
*/
|
|
468
706
|
incomingStock: number | null;
|
|
469
707
|
projectedSaleable: number | null;
|
|
470
708
|
nextExpectedArrival: string | null;
|
|
709
|
+
/** Units beyond `saleable` this buyer may backorder; `null` = not applicable. */
|
|
710
|
+
backorderAllowance: number | null;
|
|
471
711
|
priceListName: string | null;
|
|
472
712
|
retailPrice: number | null;
|
|
473
713
|
retailPriceWithTax: number | null;
|
|
@@ -485,29 +725,75 @@ export interface CollectionDetail extends Collection {
|
|
|
485
725
|
totalItems: number;
|
|
486
726
|
};
|
|
487
727
|
}
|
|
728
|
+
/**
|
|
729
|
+
* Stable, append-only vocabulary for why an order could not be placed — or why
|
|
730
|
+
* a payment was refused before it was taken.
|
|
731
|
+
*
|
|
732
|
+
* Branch on this instead of keyword-matching `transitionError` /
|
|
733
|
+
* `paymentErrorMessage`: that prose is operator English, is re-worded per
|
|
734
|
+
* merchant, and is translated. This list is a deliberate copy of the
|
|
735
|
+
* platform's (`@sixtynine-digital/commerce-shared/placement-rejection`) so the
|
|
736
|
+
* published client stays zero-dependency; a spec asserts the two match.
|
|
737
|
+
*
|
|
738
|
+
* Treat an unrecognised value defensively — always give your `switch` a
|
|
739
|
+
* `default:` branch and fall back to `MutationError.message`. Codes are added
|
|
740
|
+
* over time, and the SDK deliberately passes a code it does not know through
|
|
741
|
+
* unchanged rather than rewriting it to `UNKNOWN`.
|
|
742
|
+
*/
|
|
488
743
|
export type PlacementRejectionCode = 'ORDER_EMPTY' | 'CUSTOMER_REQUIRED' | 'SHIPPING_METHOD_REQUIRED' | 'INSUFFICIENT_STOCK' | 'ORDER_MINIMUM_AMOUNT_NOT_MET' | 'ORDER_MINIMUM_QUANTITY_NOT_MET' | 'FULFILLMENT_MINIMUM_NOT_MET' | 'LINE_MINIMUM_QUANTITY_NOT_MET' | 'LINE_SALES_UNIT_NOT_MET' | 'SHIPPING_ADDRESS_INCOMPLETE' | 'SHIPPING_COUNTRY_NOT_SERVED' | 'AGE_VERIFICATION_REQUIRED' | 'AGE_REQUIREMENT_NOT_MET' | 'DELIVERY_TERMS_UNAVAILABLE' | 'PAYMENT_TERMS_UNAVAILABLE' | 'PAYMENT_INTENT_MISMATCH' | 'PLACEMENT_BLOCKED' | 'UNKNOWN';
|
|
744
|
+
/**
|
|
745
|
+
* An order line implicated in a rejection — the line below its minimum
|
|
746
|
+
* quantity, the line that ran short of stock.
|
|
747
|
+
*
|
|
748
|
+
* The engine caps a rejection at 20 lines (`PlacementRejection.linesTruncated`
|
|
749
|
+
* says when it did). Every field except the variant id is nullable, so render
|
|
750
|
+
* defensively; `productName`/`productVariantName` are already translated.
|
|
751
|
+
*/
|
|
489
752
|
export interface PlacementRejectionLine {
|
|
490
753
|
orderLineId?: string | null;
|
|
491
754
|
productVariantId: string;
|
|
492
755
|
sku?: string | null;
|
|
493
756
|
productVariantName?: string | null;
|
|
494
757
|
productName?: string | null;
|
|
758
|
+
/** What was asked for, before any correction the engine applied. */
|
|
495
759
|
quantityRequested?: number | null;
|
|
496
760
|
quantityAvailable?: number | null;
|
|
497
761
|
}
|
|
762
|
+
/**
|
|
763
|
+
* Field-level detail, e.g. which part of the shipping address is unusable.
|
|
764
|
+
*
|
|
765
|
+
* Deliberately NOT `FieldError` (the CMS form-validation shape): `field` is
|
|
766
|
+
* nullable here, because a detail may be about the order as a whole.
|
|
767
|
+
*/
|
|
498
768
|
export interface PlacementRejectionDetail {
|
|
499
769
|
field?: string | null;
|
|
500
770
|
code?: string | null;
|
|
501
771
|
message: string;
|
|
502
772
|
}
|
|
773
|
+
/**
|
|
774
|
+
* The structured, customer-safe half of a placement rejection.
|
|
775
|
+
*
|
|
776
|
+
* `customerMessage` is plain shopper English and safe to render as-is; the
|
|
777
|
+
* operator prose stays on the error's own reason field for merchant-facing
|
|
778
|
+
* surfaces. The metadata fields are populated per code (e.g. `requiredAmount` +
|
|
779
|
+
* `amountBasis` for a minimum-amount rejection) and are null otherwise.
|
|
780
|
+
*/
|
|
503
781
|
export interface PlacementRejection {
|
|
782
|
+
/**
|
|
783
|
+
* Widened past the union on purpose: the SDK passes a code it does not know
|
|
784
|
+
* through unchanged, so an exhaustive `switch` must still have a `default:`.
|
|
785
|
+
*/
|
|
504
786
|
code: PlacementRejectionCode | (string & {});
|
|
787
|
+
/** Shopper-safe sentence. Null when the veto site supplied none. */
|
|
505
788
|
customerMessage?: string | null;
|
|
506
789
|
lines?: PlacementRejectionLine[] | null;
|
|
507
790
|
details?: PlacementRejectionDetail[] | null;
|
|
791
|
+
/** True when `lines` was capped and does not list every affected line. */
|
|
508
792
|
linesTruncated: boolean;
|
|
793
|
+
/** Minor units, in `currencyCode`. */
|
|
509
794
|
requiredAmount?: number | null;
|
|
510
795
|
currencyCode?: string | null;
|
|
796
|
+
/** `net` or `gross` — which basis `requiredAmount` is expressed in. */
|
|
511
797
|
amountBasis?: string | null;
|
|
512
798
|
requiredQuantity?: number | null;
|
|
513
799
|
priceListName?: string | null;
|
|
@@ -516,16 +802,21 @@ export interface PlacementRejection {
|
|
|
516
802
|
}
|
|
517
803
|
export type AdjustmentType = 'PROMOTION' | 'DISTRIBUTED_ORDER_PROMOTION' | 'OTHER';
|
|
518
804
|
export interface Discount {
|
|
805
|
+
/** Identifier of the source (e.g. promotion code or shipping method id). */
|
|
519
806
|
adjustmentSource: string;
|
|
520
807
|
type: AdjustmentType | string;
|
|
521
808
|
description: string;
|
|
809
|
+
/** Pre-tax discount amount in minor units. Negative values reduce the price. */
|
|
522
810
|
amount: number;
|
|
523
811
|
amountWithTax: number;
|
|
524
812
|
}
|
|
525
813
|
export interface OrderTaxSummary {
|
|
526
814
|
description: string;
|
|
815
|
+
/** Tax rate as a percentage (e.g. 21 for 21%). */
|
|
527
816
|
taxRate: number;
|
|
817
|
+
/** Net total to which this tax rate applies, in minor units. */
|
|
528
818
|
taxBase: number;
|
|
819
|
+
/** Tax total at this rate, in minor units. */
|
|
529
820
|
taxTotal: number;
|
|
530
821
|
}
|
|
531
822
|
export interface OrderPromotion {
|
|
@@ -537,18 +828,41 @@ export interface OrderPromotion {
|
|
|
537
828
|
export interface OrderLine {
|
|
538
829
|
id: string;
|
|
539
830
|
quantity: number;
|
|
831
|
+
/**
|
|
832
|
+
* Units of this line physical stock did NOT cover when the order was placed
|
|
833
|
+
* (the part the merchant ships later). Stamped at placement, never
|
|
834
|
+
* decremented as the line ships — the fulfilments record what arrived.
|
|
835
|
+
*
|
|
836
|
+
* Selected by the PLACED-order reads alone (`getOrderByCode`,
|
|
837
|
+
* `getCustomerOrders`), so it is `undefined` from the cart reads and
|
|
838
|
+
* mutations: a cart line has no stamp to carry, and selecting it in the
|
|
839
|
+
* shared fragment would couple every cart call to an engine that has the
|
|
840
|
+
* field.
|
|
841
|
+
*/
|
|
842
|
+
backorderedQuantity?: number;
|
|
540
843
|
unitPrice: number;
|
|
541
844
|
unitPriceWithTax: number;
|
|
845
|
+
/** Tax rate applied to this line as a percentage (e.g. 21 for 21%). */
|
|
542
846
|
taxRate: number;
|
|
543
847
|
linePrice: number;
|
|
544
848
|
linePriceWithTax: number;
|
|
849
|
+
/** Line price after item-level discounts, excluding tax. */
|
|
545
850
|
discountedLinePrice: number;
|
|
546
851
|
discountedLinePriceWithTax: number;
|
|
852
|
+
/** Discounts applied to this line (item-level promotions). */
|
|
547
853
|
discounts: Discount[];
|
|
548
854
|
productVariant: {
|
|
549
855
|
id: string;
|
|
550
856
|
name: string;
|
|
551
857
|
sku: string;
|
|
858
|
+
/**
|
|
859
|
+
* Units the channel will sell right now, `null` when it hides stock. Here
|
|
860
|
+
* so a cart can show how much of a line is on backorder BEFORE placement,
|
|
861
|
+
* when `backorderedQuantity` is still 0 — through
|
|
862
|
+
* `pricing.backorderedQuantityForCart(variant, quantity)`, which yields no
|
|
863
|
+
* hint at all when this is `null` (never read `null` as 0).
|
|
864
|
+
*/
|
|
865
|
+
saleable: number | null;
|
|
552
866
|
product: {
|
|
553
867
|
id: string;
|
|
554
868
|
name: string;
|
|
@@ -579,22 +893,42 @@ export interface FulfillmentLine {
|
|
|
579
893
|
orderLineId: string;
|
|
580
894
|
quantity: number;
|
|
581
895
|
}
|
|
896
|
+
/**
|
|
897
|
+
* A shipment created for (part of) an order. `trackingCode` is the carrier
|
|
898
|
+
* barcode — feed it to `commerce.trackShipment(trackingCode, postalCode)`
|
|
899
|
+
* for live tracking history.
|
|
900
|
+
*/
|
|
582
901
|
export interface Fulfillment {
|
|
583
902
|
id: string;
|
|
903
|
+
/** Fulfillment FSM state, e.g. Pending, Shipped, Delivered, Cancelled. */
|
|
584
904
|
state: string;
|
|
905
|
+
/** Human-readable fulfillment/shipping method description. */
|
|
585
906
|
method: string;
|
|
586
907
|
trackingCode: string | null;
|
|
587
908
|
createdAt: string;
|
|
588
909
|
updatedAt: string;
|
|
589
910
|
lines: FulfillmentLine[];
|
|
590
911
|
}
|
|
912
|
+
/**
|
|
913
|
+
* A payment recorded against an order. `method` is the payment-method *code*
|
|
914
|
+
* (e.g. `manual-payment`, `mollie-payment`) — drives storefront invoice-vs-PSP
|
|
915
|
+
* routing. `transactionId` is the PSP receipt; null for manual/offline methods.
|
|
916
|
+
*/
|
|
591
917
|
export interface OrderPayment {
|
|
592
918
|
id: string;
|
|
919
|
+
/** Payment-method code, e.g. `mollie-payment` or `manual-payment`. */
|
|
593
920
|
method: string;
|
|
921
|
+
/** Amount captured by this payment, in minor units. */
|
|
594
922
|
amount: number;
|
|
923
|
+
/** Payment FSM state, e.g. Authorized, Settled, Declined, Cancelled. */
|
|
595
924
|
state: string;
|
|
925
|
+
/** PSP transaction reference; null for manual/offline payments. */
|
|
596
926
|
transactionId: string | null;
|
|
597
927
|
}
|
|
928
|
+
/**
|
|
929
|
+
* A shipping charge applied to an order. The selected method's name/code feeds
|
|
930
|
+
* order-detail rendering; `priceWithTax` is the charged amount in minor units.
|
|
931
|
+
*/
|
|
598
932
|
export interface ShippingLine {
|
|
599
933
|
shippingMethod: {
|
|
600
934
|
id: string;
|
|
@@ -608,7 +942,9 @@ export interface Order {
|
|
|
608
942
|
code: string;
|
|
609
943
|
state: string;
|
|
610
944
|
active: boolean;
|
|
945
|
+
/** When the order (cart) was created — ISO-8601 instant. */
|
|
611
946
|
createdAt: string;
|
|
947
|
+
/** When the order left the cart state (was placed) — ISO-8601 instant; null while still an active cart. */
|
|
612
948
|
orderPlacedAt: string | null;
|
|
613
949
|
totalQuantity: number;
|
|
614
950
|
subTotal: number;
|
|
@@ -619,10 +955,15 @@ export interface Order {
|
|
|
619
955
|
totalWithTax: number;
|
|
620
956
|
currencyCode: string;
|
|
621
957
|
lines: OrderLine[];
|
|
958
|
+
/** Order-level discounts (e.g. order-total promotions, free shipping). */
|
|
622
959
|
discounts: Discount[];
|
|
960
|
+
/** Tax breakdown grouped by tax rate. */
|
|
623
961
|
taxSummary: OrderTaxSummary[];
|
|
962
|
+
/** Promotions applied to this order. */
|
|
624
963
|
promotions: OrderPromotion[];
|
|
964
|
+
/** Shipping charges on the order (selected method + charged price). */
|
|
625
965
|
shippingLines: ShippingLine[];
|
|
966
|
+
/** Payments recorded against the order (method code, state, PSP receipt). */
|
|
626
967
|
payments: OrderPayment[];
|
|
627
968
|
shippingAddress?: OrderAddress;
|
|
628
969
|
billingAddress?: OrderAddress;
|
|
@@ -633,30 +974,102 @@ export interface Order {
|
|
|
633
974
|
emailAddress: string;
|
|
634
975
|
};
|
|
635
976
|
couponCodes: string[];
|
|
977
|
+
/**
|
|
978
|
+
* Shipments for this order. Only selected on placed-order reads
|
|
979
|
+
* (`getOrderByCode`, customer order history) — absent on cart operations.
|
|
980
|
+
*/
|
|
636
981
|
fulfillments?: Fulfillment[] | null;
|
|
982
|
+
/**
|
|
983
|
+
* Tracking pushed by an external fulfilment system, oldest delivery first.
|
|
984
|
+
* Prefer this over `fulfillments[].trackingCode` for display: one fulfilment can
|
|
985
|
+
* cover several parcels, which a single tracking code cannot express.
|
|
986
|
+
*/
|
|
637
987
|
externalShipments?: ExternalShipment[] | null;
|
|
988
|
+
/** Immutable source-aware payment condition captured when this order was accepted. */
|
|
638
989
|
paymentTerms?: OrderPaymentTermsSnapshot | null;
|
|
990
|
+
/** Immutable Exact-aware delivery terms captured when this order was accepted. */
|
|
639
991
|
deliveryTerms?: OrderDeliveryTermsSnapshot | null;
|
|
992
|
+
/**
|
|
993
|
+
* Order-level custom fields.
|
|
994
|
+
*
|
|
995
|
+
* Only populated on the order returned by
|
|
996
|
+
* {@link CommerceModule.setPaymentIntent | commerce.setPaymentIntent} —
|
|
997
|
+
* ordinary cart and order reads do not select it, so that a client release
|
|
998
|
+
* cannot break every cart operation against an engine that predates a field.
|
|
999
|
+
* Keep the buyer's chosen intent in your own state; that call's response is
|
|
1000
|
+
* where to read it back.
|
|
1001
|
+
*/
|
|
640
1002
|
customFields?: OrderCustomFields | null;
|
|
641
1003
|
}
|
|
1004
|
+
/**
|
|
1005
|
+
* How the buyer said they would settle this order.
|
|
1006
|
+
*
|
|
1007
|
+
* `pay_now` = paid immediately (iDEAL, card, …), which is what a pay-now
|
|
1008
|
+
* discount promotion looks for; `on_account` = pay later on the net terms the
|
|
1009
|
+
* account carries. Written only by
|
|
1010
|
+
* {@link CommerceModule.setPaymentIntent | commerce.setPaymentIntent}, which
|
|
1011
|
+
* re-prices the order in the same call.
|
|
1012
|
+
*/
|
|
642
1013
|
export type OrderPaymentIntentValue = 'pay_now' | 'on_account';
|
|
1014
|
+
/** The Shop API enum accepted by `commerce.setPaymentIntent`. */
|
|
643
1015
|
export type OrderPaymentIntent = 'PAY_NOW' | 'PAY_ON_ACCOUNT';
|
|
644
1016
|
export interface OrderCustomFields {
|
|
1017
|
+
/**
|
|
1018
|
+
* The buyer's stated payment intent, or `null` when they never stated one.
|
|
1019
|
+
* Read-only: the only write path is `commerce.setPaymentIntent`.
|
|
1020
|
+
*/
|
|
645
1021
|
paymentIntent?: OrderPaymentIntentValue | null;
|
|
646
1022
|
}
|
|
1023
|
+
/**
|
|
1024
|
+
* One parcel, pallet or pickup instruction pushed by the external fulfilment
|
|
1025
|
+
* system.
|
|
1026
|
+
*
|
|
1027
|
+
* `reference` is overloaded by design, because the sending systems overload it:
|
|
1028
|
+
* a parcel carrier sends a tracking URL, a pallet carrier sends a URL *or* a
|
|
1029
|
+
* plain reference, and ex-works sends free-text pickup instructions. Branch on
|
|
1030
|
+
* {@link ExternalShipment.isLink} — derived server-side — to decide between an
|
|
1031
|
+
* anchor and a text block. Never put a non-link reference in an `href`.
|
|
1032
|
+
*/
|
|
647
1033
|
export interface ExternalShipment {
|
|
1034
|
+
/** Carrier name as the sender reports it, e.g. `PostNL`, `Pallet`, `Ex works`. */
|
|
648
1035
|
carrier: string;
|
|
1036
|
+
/** A tracking URL, a carrier reference, or pickup instructions. */
|
|
649
1037
|
reference: string;
|
|
1038
|
+
/** True when `reference` is an http(s) URL safe to render as a link. */
|
|
650
1039
|
isLink: boolean;
|
|
1040
|
+
/** ISO-8601 dispatch timestamp, or null if the sender omitted it. */
|
|
651
1041
|
shippedAt: string | null;
|
|
1042
|
+
/** Which delivery of the order this parcel belongs to. */
|
|
652
1043
|
deliveryNumber: string;
|
|
653
1044
|
}
|
|
1045
|
+
/**
|
|
1046
|
+
* Order minimums in effect on the active channel (inline order-constraints
|
|
1047
|
+
* plugin). Display/pre-validation only — checkout enforces server-side.
|
|
1048
|
+
*/
|
|
654
1049
|
export interface ActiveChannelOrderConstraints {
|
|
1050
|
+
/**
|
|
1051
|
+
* Minimum vs the GROSS order total, minor units. Null when unset. This is the
|
|
1052
|
+
* channel-wide minimum raised by any price-list minimum applying to the
|
|
1053
|
+
* signed-in customer, so it varies per visitor.
|
|
1054
|
+
*/
|
|
655
1055
|
minOrderAmountGross: number | null;
|
|
1056
|
+
/**
|
|
1057
|
+
* Minimum vs the NET (tax-exclusive) total, minor units, when a price list
|
|
1058
|
+
* applying to this customer states its minimum ex tax. Independent of
|
|
1059
|
+
* `minOrderAmountGross` — both bind, and neither can be derived from the
|
|
1060
|
+
* other without a tax rate. Null when no net-basis minimum applies.
|
|
1061
|
+
*/
|
|
656
1062
|
minOrderAmountNet: number | null;
|
|
1063
|
+
/** Minimum total item count, from an applicable price list. Null when unset. */
|
|
657
1064
|
minOrderQuantity: number | null;
|
|
1065
|
+
/** Default fulfillment profile minimum vs the NET subtotal, minor units. Null when unset. */
|
|
658
1066
|
fulfillmentMinOrderNet: number | null;
|
|
659
1067
|
currencyCode: string;
|
|
1068
|
+
/**
|
|
1069
|
+
* True when the signed-in customer's group is exempt from the CHANNEL-wide
|
|
1070
|
+
* minimum. A price-list minimum still applies, so `minOrderAmountGross` may
|
|
1071
|
+
* be non-null while this is true.
|
|
1072
|
+
*/
|
|
660
1073
|
customerIsExempt: boolean;
|
|
661
1074
|
}
|
|
662
1075
|
export interface ShippingMethod {
|
|
@@ -666,7 +1079,9 @@ export interface ShippingMethod {
|
|
|
666
1079
|
price: number;
|
|
667
1080
|
priceWithTax: number;
|
|
668
1081
|
metadata?: Record<string, unknown>;
|
|
1082
|
+
/** True when this is the signed-in customer's eligible Exact default. */
|
|
669
1083
|
isPreferred: boolean;
|
|
1084
|
+
/** False when the current externally governed customer cannot select this mapping. */
|
|
670
1085
|
isDeliveryTermsEligible: boolean;
|
|
671
1086
|
}
|
|
672
1087
|
export interface PaymentMethod {
|
|
@@ -688,13 +1103,33 @@ export interface Customer {
|
|
|
688
1103
|
items: OrderSummary[];
|
|
689
1104
|
totalItems: number;
|
|
690
1105
|
};
|
|
1106
|
+
/**
|
|
1107
|
+
* Customer groups the customer belongs to in the active channel. Drives
|
|
1108
|
+
* B2B-only UI (navigation, VAT-mode default, order gating) — pricing is
|
|
1109
|
+
* already applied server-side, so groups are for presentation only.
|
|
1110
|
+
*/
|
|
691
1111
|
groups?: CustomerGroup[];
|
|
1112
|
+
/**
|
|
1113
|
+
* Whether this customer is a trade (B2B) account — i.e. belongs to one of the
|
|
1114
|
+
* channel's configured B2B customer groups. The authoritative signal to gate
|
|
1115
|
+
* B2B UI on, so a storefront never hard-codes a group name. Optional because
|
|
1116
|
+
* a Vendure predating the field simply omits it.
|
|
1117
|
+
*
|
|
1118
|
+
* Presentation only: pricing, the tax display mode and access to quotes /
|
|
1119
|
+
* credit / contract pricing are all resolved server-side regardless.
|
|
1120
|
+
*/
|
|
692
1121
|
isB2B?: boolean;
|
|
693
1122
|
}
|
|
1123
|
+
/** A customer group, as exposed to the storefront (identity only). */
|
|
694
1124
|
export interface CustomerGroup {
|
|
695
1125
|
id: string;
|
|
696
1126
|
name: string;
|
|
697
1127
|
}
|
|
1128
|
+
/**
|
|
1129
|
+
* A price list applying to the active customer. Identity only — prices are
|
|
1130
|
+
* applied server-side; storefronts use this to label which lists (contract /
|
|
1131
|
+
* tier) the signed-in customer is on.
|
|
1132
|
+
*/
|
|
698
1133
|
export interface CustomerPriceList {
|
|
699
1134
|
id: string;
|
|
700
1135
|
name: string;
|
|
@@ -719,6 +1154,7 @@ export interface OrderSummary {
|
|
|
719
1154
|
id: string;
|
|
720
1155
|
code: string;
|
|
721
1156
|
state: string;
|
|
1157
|
+
/** Net (excl. tax) order total, in minor units. */
|
|
722
1158
|
total: number;
|
|
723
1159
|
totalWithTax: number;
|
|
724
1160
|
currencyCode: string;
|
|
@@ -726,6 +1162,12 @@ export interface OrderSummary {
|
|
|
726
1162
|
lines: Array<{
|
|
727
1163
|
id: string;
|
|
728
1164
|
quantity: number;
|
|
1165
|
+
/**
|
|
1166
|
+
* Units stock did not cover at placement (backorder); 0 otherwise.
|
|
1167
|
+
* Selected by `getCustomerOrders`; `undefined` from `getCurrentCustomer`.
|
|
1168
|
+
*/
|
|
1169
|
+
backorderedQuantity?: number;
|
|
1170
|
+
/** Line total incl. tax, in minor units. */
|
|
729
1171
|
linePriceWithTax: number;
|
|
730
1172
|
productVariant: {
|
|
731
1173
|
id: string;
|
|
@@ -745,24 +1187,32 @@ export interface OrderSummary {
|
|
|
745
1187
|
};
|
|
746
1188
|
}>;
|
|
747
1189
|
fulfillments?: Fulfillment[] | null;
|
|
1190
|
+
/** Tracking pushed by an external fulfilment system. See {@link ExternalShipment}. */
|
|
748
1191
|
externalShipments?: ExternalShipment[] | null;
|
|
1192
|
+
/** Immutable source-aware payment condition captured when this order was accepted. */
|
|
749
1193
|
paymentTerms?: OrderPaymentTermsSnapshot | null;
|
|
1194
|
+
/** Immutable delivery terms captured when this order was accepted. */
|
|
750
1195
|
deliveryTerms?: OrderDeliveryTermsSnapshot | null;
|
|
751
1196
|
}
|
|
1197
|
+
/** An invoice issued for one of the signed-in customer's orders. */
|
|
752
1198
|
export interface CustomerInvoice {
|
|
753
1199
|
id: string;
|
|
754
1200
|
invoiceNumber: string;
|
|
1201
|
+
/** Issue date (ISO-8601 date). */
|
|
755
1202
|
invoicedOn: string;
|
|
1203
|
+
/** Minor units. */
|
|
756
1204
|
totalWithTax: number;
|
|
757
1205
|
currencyCode: string;
|
|
758
1206
|
languageCode: string;
|
|
759
1207
|
createdAt: string;
|
|
760
1208
|
}
|
|
1209
|
+
/** Base64-encoded invoice PDF download. */
|
|
761
1210
|
export interface CustomerInvoicePdf {
|
|
762
1211
|
base64: string;
|
|
763
1212
|
filename: string;
|
|
764
1213
|
invoiceNumber: string;
|
|
765
1214
|
}
|
|
1215
|
+
/** A line that could not be re-added during a `reorder()` call. */
|
|
766
1216
|
export interface ReorderSkipped {
|
|
767
1217
|
variantId: string;
|
|
768
1218
|
quantity: number;
|
|
@@ -774,6 +1224,20 @@ export interface ReorderResult {
|
|
|
774
1224
|
addedLines: number;
|
|
775
1225
|
skipped: ReorderSkipped[];
|
|
776
1226
|
}
|
|
1227
|
+
/**
|
|
1228
|
+
* Outcome of {@link CommerceModule.login}. A discriminated union so the
|
|
1229
|
+
* storefront can distinguish a genuine bad password from a migrated/imported
|
|
1230
|
+
* account that needs to set a new password.
|
|
1231
|
+
*
|
|
1232
|
+
* - `success`: signed in; `id`/`identifier` are the current user.
|
|
1233
|
+
* - `password_reset_required`: an imported account with no migrated password.
|
|
1234
|
+
* The platform has already emailed a reset link — prompt the user to check
|
|
1235
|
+
* their inbox, do NOT report invalid credentials.
|
|
1236
|
+
* - `account_not_verified`: the account exists but has not been verified yet.
|
|
1237
|
+
*
|
|
1238
|
+
* Genuine invalid credentials still throw a `MutationError` and never produce a
|
|
1239
|
+
* result here.
|
|
1240
|
+
*/
|
|
777
1241
|
export type LoginResult = {
|
|
778
1242
|
status: 'success';
|
|
779
1243
|
id: string;
|
|
@@ -825,13 +1289,30 @@ export interface MolliePaymentMethod {
|
|
|
825
1289
|
size2x: string;
|
|
826
1290
|
svg: string;
|
|
827
1291
|
};
|
|
1292
|
+
/**
|
|
1293
|
+
* Mollie's availability status for this method on the order (e.g.
|
|
1294
|
+
* `"activated"`, `"pending-boarding"`). `null` when Mollie omits it.
|
|
1295
|
+
*/
|
|
828
1296
|
status: string | null;
|
|
829
1297
|
}
|
|
1298
|
+
/**
|
|
1299
|
+
* A storefront-visible Mollie payment method, ordered per the channel's saved
|
|
1300
|
+
* configuration with hidden methods removed. Returned by
|
|
1301
|
+
* `commerce.getOrderedMolliePaymentMethods`. Decoupled from
|
|
1302
|
+
* {@link MolliePaymentMethod}: this is the curated, channel-ordered shape from
|
|
1303
|
+
* the platform's `payment-config` plugin, not the raw community plugin type.
|
|
1304
|
+
*/
|
|
830
1305
|
export interface OrderedMollieMethod {
|
|
831
1306
|
id: string;
|
|
1307
|
+
/** Mollie method id (e.g. `"ideal"`); pass as `molliePaymentMethodCode`. */
|
|
832
1308
|
code: string;
|
|
833
1309
|
description: string | null;
|
|
1310
|
+
/** Mollie's icon URL (SVG preferred, 2x PNG fallback); null when omitted. */
|
|
834
1311
|
imageUrl: string | null;
|
|
1312
|
+
/**
|
|
1313
|
+
* Mollie's availability status for this method (e.g. `"activated"`). `null`
|
|
1314
|
+
* when Mollie omits it.
|
|
1315
|
+
*/
|
|
835
1316
|
status: string | null;
|
|
836
1317
|
}
|
|
837
1318
|
export interface CreateMolliePaymentIntentInput {
|
|
@@ -840,11 +1321,21 @@ export interface CreateMolliePaymentIntentInput {
|
|
|
840
1321
|
molliePaymentMethodCode?: string;
|
|
841
1322
|
locale?: string;
|
|
842
1323
|
immediateCapture?: boolean;
|
|
1324
|
+
/**
|
|
1325
|
+
* Create the intent for a specific order rather than the session's active
|
|
1326
|
+
* order — required when topping up an order in `ArrangingAdditionalPayment`,
|
|
1327
|
+
* or when driving checkout for a non-active order.
|
|
1328
|
+
*/
|
|
843
1329
|
orderId?: string;
|
|
844
1330
|
}
|
|
845
1331
|
export interface MolliePaymentIntentResult {
|
|
846
1332
|
url: string;
|
|
847
1333
|
}
|
|
1334
|
+
/**
|
|
1335
|
+
* Minimal order shape returned by `syncMolliePaymentStatus`. Use the `state`
|
|
1336
|
+
* to confirm the order settled (e.g. `PaymentSettled`) after a delayed/missing
|
|
1337
|
+
* Mollie webhook. `null` when no order matches the code.
|
|
1338
|
+
*/
|
|
848
1339
|
export interface MollieOrderStatusResult {
|
|
849
1340
|
id: string;
|
|
850
1341
|
code: string;
|
|
@@ -899,7 +1390,14 @@ export interface SearchInput {
|
|
|
899
1390
|
term: string;
|
|
900
1391
|
collectionSlug?: string;
|
|
901
1392
|
collectionId?: string;
|
|
1393
|
+
/**
|
|
1394
|
+
* Filter to products belonging to ALL of these collections (AND). Combine with
|
|
1395
|
+
* `collectionSlugs` to intersect categories across collection groups. A slug
|
|
1396
|
+
* that doesn't resolve in the active channel yields an empty result rather than
|
|
1397
|
+
* widening the search.
|
|
1398
|
+
*/
|
|
902
1399
|
collectionSlugs?: string[];
|
|
1400
|
+
/** Filter to products belonging to ALL of these collection ids (AND). */
|
|
903
1401
|
collectionIds?: string[];
|
|
904
1402
|
facetValueIds?: string[];
|
|
905
1403
|
facetValueFilters?: FacetValueFilterInput[];
|
|
@@ -912,6 +1410,11 @@ export interface SearchInput {
|
|
|
912
1410
|
}
|
|
913
1411
|
export interface SearchResultItem {
|
|
914
1412
|
productId: string;
|
|
1413
|
+
/**
|
|
1414
|
+
* Orderable variant id for this search row — pass THIS (never `productId`) to
|
|
1415
|
+
* `addToCart`. Under `groupByProduct` it is a representative variant; for the
|
|
1416
|
+
* exact variant on multi-variant products, load `getProduct(slug)`.
|
|
1417
|
+
*/
|
|
915
1418
|
productVariantId: string;
|
|
916
1419
|
productName: string;
|
|
917
1420
|
slug: string;
|
|
@@ -935,6 +1438,7 @@ export interface SearchResultItem {
|
|
|
935
1438
|
};
|
|
936
1439
|
} | null;
|
|
937
1440
|
collectionIds: string[];
|
|
1441
|
+
/** Aggregate availability across all stock locations (Meilisearch plugin). */
|
|
938
1442
|
inStock: boolean;
|
|
939
1443
|
}
|
|
940
1444
|
export interface SearchFacetValue {
|
|
@@ -955,9 +1459,16 @@ export interface SearchResult {
|
|
|
955
1459
|
totalItems: number;
|
|
956
1460
|
facetValues: SearchFacetValue[];
|
|
957
1461
|
}
|
|
1462
|
+
/** `eq` boolean operator mirroring Vendure's `BooleanOperators` input. */
|
|
958
1463
|
export interface BooleanOperators {
|
|
959
1464
|
eq?: boolean;
|
|
960
1465
|
}
|
|
1466
|
+
/**
|
|
1467
|
+
* Subset of Vendure's `ProductFilterParameter` the SDK types explicitly.
|
|
1468
|
+
* `enabled` is the field `getProducts` defaults on; the index signature keeps
|
|
1469
|
+
* the parameter open to the other server-side filter fields without the SDK
|
|
1470
|
+
* having to enumerate them all.
|
|
1471
|
+
*/
|
|
961
1472
|
export interface ProductFilterParameter {
|
|
962
1473
|
enabled?: BooleanOperators;
|
|
963
1474
|
[field: string]: unknown;
|
|
@@ -965,31 +1476,108 @@ export interface ProductFilterParameter {
|
|
|
965
1476
|
export interface ProductListOptions {
|
|
966
1477
|
take?: number;
|
|
967
1478
|
skip?: number;
|
|
1479
|
+
/**
|
|
1480
|
+
* How much of each product to fetch. Defaults to `'full'` — the existing
|
|
1481
|
+
* selection, unchanged for every current caller.
|
|
1482
|
+
*
|
|
1483
|
+
* `'card'` asks only for what a grid tile renders. It drops the per-VARIANT
|
|
1484
|
+
* stock reads a tile never shows — `availabilityByLocation`, `stockOnHand`,
|
|
1485
|
+
* `stockAllocated`, `incomingStock`, `projectedSaleable`,
|
|
1486
|
+
* `nextExpectedArrival` — and the product `description`, including the
|
|
1487
|
+
* per-language copy inside `translations`. The variant fields are resolved by
|
|
1488
|
+
* per-variant field resolvers server-side (`availabilityByLocation` issues one
|
|
1489
|
+
* stock query PER VARIANT), so the saving is backend work and SQL statements,
|
|
1490
|
+
* not just bytes.
|
|
1491
|
+
*
|
|
1492
|
+
* **The collection tree and the translated slugs are kept**, so card rows can
|
|
1493
|
+
* still feed `seo.canonicalFor`/`alternatesFor`: `collections` keeps
|
|
1494
|
+
* `parent`, `position`, `translations` and `customFields { isRoutable
|
|
1495
|
+
* isCanonical }`, and the product keeps `translations { languageCode name
|
|
1496
|
+
* slug }`. Also kept: `enabled` and `saleable` (storefronts gate orderability
|
|
1497
|
+
* on `saleable == null || saleable > 0`), `sku`, `stockLevel`,
|
|
1498
|
+
* `priceListName`, `retailPrice`/`retailPriceWithTax`, `priceTiers`, variant
|
|
1499
|
+
* `customFields` (purchase constraints) and `facetValues`. These cost bytes,
|
|
1500
|
+
* not queries.
|
|
1501
|
+
*
|
|
1502
|
+
* Ignored on the deprecated `{ collectionSlug }` path, which reroutes to the
|
|
1503
|
+
* search backend and returns its own already-flat row shape regardless.
|
|
1504
|
+
*
|
|
1505
|
+
* Both shapes are typed `ProductSummary`; the omitted members are optional on
|
|
1506
|
+
* that type, so a card row is a valid — just sparser — `ProductSummary`. Read
|
|
1507
|
+
* a dropped field and you get `undefined`, not a stale value.
|
|
1508
|
+
*/
|
|
1509
|
+
detail?: 'card' | 'full';
|
|
1510
|
+
/**
|
|
1511
|
+
* @deprecated Use `getProductsInCollection(slug, options)` instead. This
|
|
1512
|
+
* option silently reroutes the call through the search backend, whose rows
|
|
1513
|
+
* are flatter than the products list (single synthesised variant, no `sku`,
|
|
1514
|
+
* `facetValues`, or `collections`) — the named method makes that shape
|
|
1515
|
+
* explicit. The option keeps working for now.
|
|
1516
|
+
*/
|
|
968
1517
|
collectionSlug?: string;
|
|
1518
|
+
/**
|
|
1519
|
+
* Vendure's `products` query cannot sort by price — `ProductSortParameter`
|
|
1520
|
+
* has no such field (price lives on variants). For price-sorted listings use
|
|
1521
|
+
* `getProductsInCollection` or `searchProducts`, both of which sort by price
|
|
1522
|
+
* server-side.
|
|
1523
|
+
*/
|
|
969
1524
|
sort?: {
|
|
970
1525
|
name?: 'ASC' | 'DESC';
|
|
971
1526
|
createdAt?: 'ASC' | 'DESC';
|
|
972
1527
|
};
|
|
1528
|
+
/**
|
|
1529
|
+
* Vendure `ProductFilterParameter`. When omitted, `getProducts` defaults to
|
|
1530
|
+
* `{ enabled: { eq: true } }` so disabled products never leak into an
|
|
1531
|
+
* unfiltered listing. An explicit `filter` REPLACES the default — but note
|
|
1532
|
+
* the Shop API additionally forces `enabled: { eq: true }` server-side, so
|
|
1533
|
+
* no filter can surface disabled products.
|
|
1534
|
+
*/
|
|
973
1535
|
filter?: ProductFilterParameter;
|
|
1536
|
+
/**
|
|
1537
|
+
* @deprecated The Shop API forces `enabled: { eq: true }` server-side, so
|
|
1538
|
+
* `enabled: false` cannot surface disabled products; the shorthand is
|
|
1539
|
+
* meaningless. Disabled products are only reachable through the Admin API.
|
|
1540
|
+
*/
|
|
974
1541
|
enabled?: boolean;
|
|
975
1542
|
}
|
|
1543
|
+
/** Options for `getProductsInCollection` — the search-backed collection listing. */
|
|
976
1544
|
export interface CollectionProductListOptions {
|
|
977
1545
|
take?: number;
|
|
978
1546
|
skip?: number;
|
|
1547
|
+
/** The search backend sorts by `name` or `price` (unlike the products list, which cannot sort by price). */
|
|
979
1548
|
sort?: {
|
|
980
1549
|
name?: 'ASC' | 'DESC';
|
|
981
1550
|
price?: 'ASC' | 'DESC';
|
|
982
1551
|
};
|
|
983
1552
|
}
|
|
1553
|
+
/**
|
|
1554
|
+
* A product card row from the search backend, as returned by
|
|
1555
|
+
* `getProductsInCollection`. Honest projection of a search hit: exactly one
|
|
1556
|
+
* synthesised variant, and none of the fields the search index does not carry
|
|
1557
|
+
* (`sku`, `facetValues`, `collections`). Structurally a subset of
|
|
1558
|
+
* `ProductSummary`, so card components consuming `{ featuredAsset,
|
|
1559
|
+
* variants[0] }` work with either. Load `getProduct(slug)` for the full
|
|
1560
|
+
* variant/asset tree.
|
|
1561
|
+
*/
|
|
984
1562
|
export interface CollectionProductSummary {
|
|
985
1563
|
id: string;
|
|
986
1564
|
name: string;
|
|
987
1565
|
slug: string;
|
|
988
1566
|
description: string;
|
|
1567
|
+
/**
|
|
1568
|
+
* Synthesised from the search row's single preview URL — every preset
|
|
1569
|
+
* points at the same image and `source` is empty.
|
|
1570
|
+
*/
|
|
989
1571
|
featuredAsset: Asset | null;
|
|
1572
|
+
/** Exactly one synthesised variant per row (search groups by product). */
|
|
990
1573
|
variants: [CollectionProductVariant];
|
|
991
1574
|
}
|
|
1575
|
+
/** The single synthesised variant on a `CollectionProductSummary`. */
|
|
992
1576
|
export interface CollectionProductVariant {
|
|
1577
|
+
/**
|
|
1578
|
+
* Orderable variant id — pass THIS (never the product id) to `addToCart`.
|
|
1579
|
+
* A representative variant for multi-variant products.
|
|
1580
|
+
*/
|
|
993
1581
|
id: string;
|
|
994
1582
|
name: string;
|
|
995
1583
|
price: number;
|
|
@@ -1013,15 +1601,35 @@ export interface FavoriteVariant {
|
|
|
1013
1601
|
priceWithTax: number;
|
|
1014
1602
|
currencyCode: string;
|
|
1015
1603
|
stockLevel: string;
|
|
1604
|
+
/** ATP numbers — `null` when the channel does not expose operational stock. */
|
|
1016
1605
|
stockOnHand: number | null;
|
|
1017
1606
|
stockAllocated: number | null;
|
|
1018
1607
|
saleable: number | null;
|
|
1608
|
+
/**
|
|
1609
|
+
* Incoming-stock numbers — additionally `null` unless the signed-in customer's
|
|
1610
|
+
* group may see incoming stock. `nextExpectedArrival` is the earliest FUTURE
|
|
1611
|
+
* arrival (ISO 8601, never past) and is `null` when every open line is overdue,
|
|
1612
|
+
* even while `incomingStock > 0`.
|
|
1613
|
+
*/
|
|
1019
1614
|
incomingStock: number | null;
|
|
1020
1615
|
projectedSaleable: number | null;
|
|
1021
1616
|
nextExpectedArrival: string | null;
|
|
1617
|
+
/**
|
|
1618
|
+
* Units BEYOND `saleable` the signed-in customer may order on backorder right
|
|
1619
|
+
* now. The quantity ceiling is `max(0, saleable) + backorderAllowance` (see
|
|
1620
|
+
* `maxOrderableQuantity` in `@sixtyninecommerce/client/pricing`). `null` when
|
|
1621
|
+
* the question does not apply — anonymous, group may not backorder, or the
|
|
1622
|
+
* channel hides stock — treat exactly like today; `0` = denied; a large
|
|
1623
|
+
* value (2,000,000,000) is the "unlimited" sentinel. A snapshot: the server
|
|
1624
|
+
* re-checks on add-to-cart and at placement and refuses with the usual
|
|
1625
|
+
* `InsufficientStockError` / `INSUFFICIENT_STOCK`, whose `quantityAvailable`
|
|
1626
|
+
* then already includes the allowance.
|
|
1627
|
+
*/
|
|
1628
|
+
backorderAllowance: number | null;
|
|
1022
1629
|
priceListName: string | null;
|
|
1023
1630
|
retailPrice: number | null;
|
|
1024
1631
|
retailPriceWithTax: number | null;
|
|
1632
|
+
/** Tax rate applied to this price in the active channel/zone, e.g. `{ value: 21 }` for 21% VAT. */
|
|
1025
1633
|
taxRateApplied: {
|
|
1026
1634
|
value: number;
|
|
1027
1635
|
} | null;
|
|
@@ -1080,6 +1688,7 @@ export interface PaginatedList<T> {
|
|
|
1080
1688
|
export interface ResolvedContent {
|
|
1081
1689
|
data?: Record<string, unknown>;
|
|
1082
1690
|
item?: Record<string, unknown>;
|
|
1691
|
+
/** Resolved field values keyed by field slug (locale-filtered). */
|
|
1083
1692
|
values?: Record<string, unknown>;
|
|
1084
1693
|
collection?: {
|
|
1085
1694
|
id: string;
|
|
@@ -1095,6 +1704,10 @@ export interface ResolvedContent {
|
|
|
1095
1704
|
path: string;
|
|
1096
1705
|
}>;
|
|
1097
1706
|
slug_translations?: Record<string, string>;
|
|
1707
|
+
/**
|
|
1708
|
+
* Derived SEO metadata block (from the standard SEO field group). `null` when
|
|
1709
|
+
* the item/page carries no SEO fields. Feed to `parseCmsItemMetadata`.
|
|
1710
|
+
*/
|
|
1098
1711
|
metadata?: Record<string, unknown> | null;
|
|
1099
1712
|
}
|
|
1100
1713
|
export interface SitemapEntry {
|
|
@@ -1103,7 +1716,9 @@ export interface SitemapEntry {
|
|
|
1103
1716
|
title: string | null;
|
|
1104
1717
|
collection_slug: string | null;
|
|
1105
1718
|
updated_at: string;
|
|
1719
|
+
/** Present only for collection landing pages (basePath routes). */
|
|
1106
1720
|
type?: 'collection_page';
|
|
1721
|
+
/** Present only when the request specified a language_code. */
|
|
1107
1722
|
language_code?: string;
|
|
1108
1723
|
}
|
|
1109
1724
|
export interface ContentItemSummary {
|
|
@@ -1115,6 +1730,11 @@ export interface ContentItemSummary {
|
|
|
1115
1730
|
collection_title_field_slug: string | null;
|
|
1116
1731
|
title: string | null;
|
|
1117
1732
|
}
|
|
1733
|
+
/**
|
|
1734
|
+
* Channel-wide CMS search query. All fields optional — supplying only `q`
|
|
1735
|
+
* searches across every collection in the store. Use `collectionId` or
|
|
1736
|
+
* `collectionSlug` to scope results.
|
|
1737
|
+
*/
|
|
1118
1738
|
export interface ContentSearchQuery {
|
|
1119
1739
|
q?: string;
|
|
1120
1740
|
collectionId?: string;
|
|
@@ -1122,9 +1742,15 @@ export interface ContentSearchQuery {
|
|
|
1122
1742
|
parentId?: string;
|
|
1123
1743
|
limit?: number;
|
|
1124
1744
|
offset?: number;
|
|
1745
|
+
/** Meilisearch sort spec, e.g. `'updated_at:desc'`. */
|
|
1125
1746
|
sort?: string;
|
|
1126
1747
|
languageCode?: string;
|
|
1127
1748
|
}
|
|
1749
|
+
/**
|
|
1750
|
+
* A single CMS content item search hit. Field values are flattened on the
|
|
1751
|
+
* document with locale-suffixed keys (`title_en`, `title_nl`, ...) — index
|
|
1752
|
+
* with `[fieldSlug]` or `[fieldSlug + '_' + languageCode]` as needed.
|
|
1753
|
+
*/
|
|
1128
1754
|
export interface ContentSearchHit {
|
|
1129
1755
|
id: string;
|
|
1130
1756
|
channel_id: string;
|
|
@@ -1166,6 +1792,7 @@ export interface CollectionPageValues {
|
|
|
1166
1792
|
fields: CollectionFieldDefinition[];
|
|
1167
1793
|
values: Record<string, unknown>;
|
|
1168
1794
|
}
|
|
1795
|
+
/** A CMS collection (content type) as returned by `GET /collections`. */
|
|
1169
1796
|
export interface CmsCollection {
|
|
1170
1797
|
id: string;
|
|
1171
1798
|
name: string;
|
|
@@ -1181,6 +1808,11 @@ export interface CmsCollection {
|
|
|
1181
1808
|
export interface CmsCollectionDetail extends CmsCollection {
|
|
1182
1809
|
fields: CollectionFieldDefinition[];
|
|
1183
1810
|
}
|
|
1811
|
+
/**
|
|
1812
|
+
* A collection item from the direct CMS item endpoints. `values` holds the
|
|
1813
|
+
* item's field values keyed by field slug, locale-merged when a
|
|
1814
|
+
* `languageCode` was requested. Public callers only ever see published items.
|
|
1815
|
+
*/
|
|
1184
1816
|
export interface CmsCollectionItem {
|
|
1185
1817
|
id: string;
|
|
1186
1818
|
collectionId: string;
|
|
@@ -1191,7 +1823,9 @@ export interface CmsCollectionItem {
|
|
|
1191
1823
|
createdAt: string;
|
|
1192
1824
|
updatedAt: string;
|
|
1193
1825
|
values: Record<string, unknown>;
|
|
1826
|
+
/** Per-language slug overrides. Present on single-item reads. */
|
|
1194
1827
|
slug_translations?: Record<string, string>;
|
|
1828
|
+
/** Forward-compat: additional entity fields the CMS may add. */
|
|
1195
1829
|
[key: string]: unknown;
|
|
1196
1830
|
}
|
|
1197
1831
|
export interface CmsCollectionItemList {
|
|
@@ -1199,8 +1833,10 @@ export interface CmsCollectionItemList {
|
|
|
1199
1833
|
total: number;
|
|
1200
1834
|
}
|
|
1201
1835
|
export interface CollectionItemsQuery {
|
|
1836
|
+
/** Filter by parent item; pass `'root'` for top-level items. */
|
|
1202
1837
|
parentId?: string;
|
|
1203
1838
|
slug?: string;
|
|
1839
|
+
/** Full-text search within the collection (Meilisearch-assisted). */
|
|
1204
1840
|
search?: string;
|
|
1205
1841
|
sort?: string;
|
|
1206
1842
|
languageCode?: string;
|
|
@@ -1221,10 +1857,19 @@ export interface FormField {
|
|
|
1221
1857
|
label: string;
|
|
1222
1858
|
type: string;
|
|
1223
1859
|
required: boolean;
|
|
1860
|
+
/** Presentational config (e.g. select option labels). */
|
|
1224
1861
|
config: Record<string, unknown>;
|
|
1862
|
+
/**
|
|
1863
|
+
* Effective per-field validation constraints the server enforces on submit
|
|
1864
|
+
* (min/max length, numeric range, options, pattern), resolved from the
|
|
1865
|
+
* field's `validation` first and `config` as a fallback. Contains only
|
|
1866
|
+
* recognized constraint keys. Mirror it to validate client-side. See
|
|
1867
|
+
* {@link FormFieldTypeDescriptor} / `content.getFormFieldTypes()`.
|
|
1868
|
+
*/
|
|
1225
1869
|
validation: Record<string, unknown>;
|
|
1226
1870
|
position: number;
|
|
1227
1871
|
}
|
|
1872
|
+
/** A form-level translation as emitted by the public projection. */
|
|
1228
1873
|
export interface FormTranslation {
|
|
1229
1874
|
languageCode: string;
|
|
1230
1875
|
title: string;
|
|
@@ -1236,8 +1881,11 @@ export interface FormDefinition {
|
|
|
1236
1881
|
id: string;
|
|
1237
1882
|
name: string;
|
|
1238
1883
|
slug: string;
|
|
1884
|
+
/** Where the storefront should send the visitor after a successful submit. */
|
|
1239
1885
|
redirectUrlOnSuccess: string | null;
|
|
1886
|
+
/** True when the form has internal-notification recipients configured (addresses are never exposed). */
|
|
1240
1887
|
hasNotifications: boolean;
|
|
1888
|
+
/** True when a visitor confirmation email will be sent on submit. */
|
|
1241
1889
|
sendsConfirmation: boolean;
|
|
1242
1890
|
fields: FormField[];
|
|
1243
1891
|
translations: FormTranslation[];
|
|
@@ -1245,6 +1893,12 @@ export interface FormDefinition {
|
|
|
1245
1893
|
submitMethod: string;
|
|
1246
1894
|
submitHeaders: Record<string, string>;
|
|
1247
1895
|
}
|
|
1896
|
+
/**
|
|
1897
|
+
* A form as returned by `content.listForms()`. Mirrors the public projection.
|
|
1898
|
+
* NOTE: list responses populate id/name/slug/redirect + the email booleans;
|
|
1899
|
+
* `fields` and `translations` arrive EMPTY in list context — fetch a single
|
|
1900
|
+
* form via `getForm`/`getFormBySlug` to load them.
|
|
1901
|
+
*/
|
|
1248
1902
|
export interface FormSummary {
|
|
1249
1903
|
id: string;
|
|
1250
1904
|
name: string;
|
|
@@ -1258,8 +1912,11 @@ export interface FormSummary {
|
|
|
1258
1912
|
export interface FormListOptions {
|
|
1259
1913
|
limit?: number;
|
|
1260
1914
|
offset?: number;
|
|
1915
|
+
/** Case-insensitive match against the form name. */
|
|
1261
1916
|
search?: string;
|
|
1917
|
+
/** Sort field; prefix with `-` for descending (name, created_at, updated_at). */
|
|
1262
1918
|
sort?: string;
|
|
1919
|
+
/** Locale for the projected field labels. Defaults to the client language. */
|
|
1263
1920
|
locale?: string;
|
|
1264
1921
|
}
|
|
1265
1922
|
export interface FormListResult {
|
|
@@ -1268,40 +1925,66 @@ export interface FormListResult {
|
|
|
1268
1925
|
total: number;
|
|
1269
1926
|
};
|
|
1270
1927
|
}
|
|
1928
|
+
/** One constraint key a field type honors (see {@link FormFieldTypeDescriptor}). */
|
|
1271
1929
|
export interface FormFieldTypeConstraint {
|
|
1272
1930
|
key: string;
|
|
1273
1931
|
valueType: 'integer' | 'number' | 'string' | 'string[]';
|
|
1274
1932
|
description: string;
|
|
1275
1933
|
}
|
|
1934
|
+
/**
|
|
1935
|
+
* Describes a form field type and the config/validation constraints it honors.
|
|
1936
|
+
* The SDK ships a static mirror as {@link FORM_FIELD_TYPES}; the same data is
|
|
1937
|
+
* served live by `content.getFormFieldTypes()` (GET /forms/field-types).
|
|
1938
|
+
*/
|
|
1276
1939
|
export interface FormFieldTypeDescriptor {
|
|
1277
1940
|
type: string;
|
|
1278
1941
|
label: string;
|
|
1279
1942
|
description: string;
|
|
1943
|
+
/** Shape of the value a submission sends for this field. */
|
|
1280
1944
|
valueType: string;
|
|
1945
|
+
/** Constraint keys honored on submit; resolved from `validation` first, then `config`. */
|
|
1281
1946
|
constraints: FormFieldTypeConstraint[];
|
|
1282
1947
|
notes?: string;
|
|
1283
1948
|
}
|
|
1949
|
+
/** The slug shape one authoring surface enforces (form slug or field slug). */
|
|
1284
1950
|
export interface FormSlugRule {
|
|
1951
|
+
/** Source of the regex the CMS validates against. */
|
|
1285
1952
|
pattern: string;
|
|
1286
1953
|
maxLength: number;
|
|
1287
1954
|
description: string;
|
|
1288
1955
|
validExamples: string[];
|
|
1289
1956
|
invalidExamples: string[];
|
|
1290
1957
|
}
|
|
1958
|
+
/**
|
|
1959
|
+
* Slug rules for form authoring: form slugs are HYPHEN-separated, field slugs
|
|
1960
|
+
* are UNDERSCORE-separated. Shipped statically as {@link FORM_SLUG_RULES} and
|
|
1961
|
+
* served live in the field-types registry response.
|
|
1962
|
+
*/
|
|
1291
1963
|
export interface FormSlugRules {
|
|
1292
1964
|
form: FormSlugRule;
|
|
1293
1965
|
field: FormSlugRule;
|
|
1294
1966
|
}
|
|
1967
|
+
/** Everything GET /forms/field-types carries: the field types plus the slug rules. */
|
|
1295
1968
|
export interface FormFieldTypeRegistry {
|
|
1296
1969
|
fieldTypes: FormFieldTypeDescriptor[];
|
|
1297
1970
|
slugRules: FormSlugRules;
|
|
1298
1971
|
}
|
|
1972
|
+
/**
|
|
1973
|
+
* Result of `submitForm` — discriminate on `success`. Field-validation
|
|
1974
|
+
* failures RESOLVE with `success: false` + per-field errors (render them
|
|
1975
|
+
* inline next to the fields); rate limits (429, carries
|
|
1976
|
+
* `retryAfterSeconds`), transport failures, and server errors still throw
|
|
1977
|
+
* `StorefrontError`.
|
|
1978
|
+
*/
|
|
1299
1979
|
export type FormSubmissionResult = {
|
|
1300
1980
|
success: true;
|
|
1981
|
+
/** Stored submission id. */
|
|
1301
1982
|
id: string;
|
|
1983
|
+
/** ISO-8601 creation timestamp. */
|
|
1302
1984
|
createdAt: string;
|
|
1303
1985
|
} | {
|
|
1304
1986
|
success: false;
|
|
1987
|
+
/** Per-field validation errors, in the CMS's field order. */
|
|
1305
1988
|
errors: Array<{
|
|
1306
1989
|
field: string;
|
|
1307
1990
|
code?: string;
|
|
@@ -1342,8 +2025,21 @@ export interface RouteEntry {
|
|
|
1342
2025
|
slug?: string;
|
|
1343
2026
|
updated_at?: string;
|
|
1344
2027
|
source?: string;
|
|
2028
|
+
/**
|
|
2029
|
+
* Only set on `product` routes. A product listed under multiple collections
|
|
2030
|
+
* emits one route per collection; exactly one — the canonical URL home — is
|
|
2031
|
+
* `true`, the rest `false`. Filter to `canonical !== false` to get the
|
|
2032
|
+
* deduplicated (one-per-product) URL set. `undefined` on `cms`/`collection`
|
|
2033
|
+
* routes, which are already one-per-entity.
|
|
2034
|
+
*/
|
|
1345
2035
|
canonical?: boolean;
|
|
1346
2036
|
}
|
|
2037
|
+
/**
|
|
2038
|
+
* A manifest entry as `findRoute` returns it, plus the cache tags the page's
|
|
2039
|
+
* reads should carry — `product:<id>` / `collection:<id>`, none for CMS pages.
|
|
2040
|
+
* Load the page by `id` (`getProductById`, `getCollectionById`,
|
|
2041
|
+
* `getProductsInCollectionById`) and those tags are already on its reads.
|
|
2042
|
+
*/
|
|
1347
2043
|
export interface ResolvedRoute extends RouteEntry {
|
|
1348
2044
|
readonly cacheTags: readonly string[];
|
|
1349
2045
|
}
|
|
@@ -1371,6 +2067,7 @@ export interface ConvertedAmount {
|
|
|
1371
2067
|
rate: string;
|
|
1372
2068
|
rateDate: string;
|
|
1373
2069
|
}
|
|
2070
|
+
/** One entry of a `convertToMultiple()` result. */
|
|
1374
2071
|
export interface BulkConversionResult {
|
|
1375
2072
|
currency: string;
|
|
1376
2073
|
amount: string;
|
|
@@ -1383,6 +2080,7 @@ export interface PriceDisplay {
|
|
|
1383
2080
|
retailPrice: number | null;
|
|
1384
2081
|
retailPriceWithTax: number | null;
|
|
1385
2082
|
priceListName: string | null;
|
|
2083
|
+
/** Tax rate percentage applied to this price (e.g. `21`), or null if unknown. */
|
|
1386
2084
|
taxRate: number | null;
|
|
1387
2085
|
hasDiscount: boolean;
|
|
1388
2086
|
discountPercentage: number | null;
|
|
@@ -1392,33 +2090,68 @@ export interface TierTableEntry {
|
|
|
1392
2090
|
minQuantity: number;
|
|
1393
2091
|
price: number;
|
|
1394
2092
|
priceWithTax: number;
|
|
2093
|
+
/** Tax rate percentage applied to this tier's price (e.g. `21`), or null if unknown. */
|
|
1395
2094
|
taxRate: number | null;
|
|
1396
2095
|
discountLabel: string | null;
|
|
1397
2096
|
savingsPercentage: number | null;
|
|
1398
2097
|
}
|
|
2098
|
+
/**
|
|
2099
|
+
* Which tax figure to display. `gross` = tax-inclusive (BTW "incl."),
|
|
2100
|
+
* `net` = tax-exclusive (BTW "excl."). The platform always returns both the
|
|
2101
|
+
* net (`price`) and gross (`priceWithTax`) figures, so switching modes never
|
|
2102
|
+
* recomputes tax — it just picks the server-authoritative field.
|
|
2103
|
+
*/
|
|
1399
2104
|
export type TaxDisplayMode = 'gross' | 'net';
|
|
2105
|
+
/**
|
|
2106
|
+
* Channel-wide display default (`Channel.customFields.taxDisplayDefault`).
|
|
2107
|
+
* `channel` means "follow `pricesIncludeTax`", which is what every storefront
|
|
2108
|
+
* did before the policy existed.
|
|
2109
|
+
*/
|
|
1400
2110
|
export type TaxDisplayDefault = 'channel' | 'gross' | 'net';
|
|
2111
|
+
/**
|
|
2112
|
+
* B2B override (`Channel.customFields.taxDisplayB2b`). `inherit` leaves trade
|
|
2113
|
+
* accounts on the channel default.
|
|
2114
|
+
*/
|
|
1401
2115
|
export type TaxDisplayB2bMode = 'inherit' | 'gross' | 'net';
|
|
2116
|
+
/**
|
|
2117
|
+
* The channel's price-display policy, as parsed from `activeChannel.customFields`
|
|
2118
|
+
* by `parseTaxDisplayPolicy`. Feed it to `resolveTaxDisplayMode` to preview a
|
|
2119
|
+
* mode offline; the authority is `getTaxDisplayMode()`.
|
|
2120
|
+
*/
|
|
1402
2121
|
export interface TaxDisplayPolicy {
|
|
1403
2122
|
default: TaxDisplayDefault;
|
|
1404
2123
|
b2b: TaxDisplayB2bMode;
|
|
2124
|
+
/** Upper-case ISO-3166 alpha-2 codes. Empty = the country rule is off. */
|
|
1405
2125
|
countries: readonly string[];
|
|
1406
2126
|
}
|
|
2127
|
+
/** The per-shopper facts `resolveTaxDisplayMode` judges. */
|
|
1407
2128
|
export interface TaxDisplayInputs {
|
|
2129
|
+
/** Member of one of the channel's configured B2B customer groups (`Customer.isB2B`). */
|
|
1408
2130
|
isB2B: boolean;
|
|
2131
|
+
/** The request carries `x-order-scope: trade` — the dealer storefront. */
|
|
1409
2132
|
isTrade: boolean;
|
|
2133
|
+
/** The shopper's country: active order shipping address, else their default one. */
|
|
1410
2134
|
countryCode: string | null;
|
|
2135
|
+
/** `Channel.pricesIncludeTax` — the STORAGE mode, not a display decision. */
|
|
1411
2136
|
pricesIncludeTax: boolean;
|
|
1412
2137
|
}
|
|
2138
|
+
/**
|
|
2139
|
+
* A resolved mode cached against the identity it was resolved for. Stored on
|
|
2140
|
+
* {@link StoreContext.taxDisplay}; `stamp` is `identityStamp(ctx)`.
|
|
2141
|
+
*/
|
|
1413
2142
|
export interface ResolvedTaxDisplay {
|
|
1414
2143
|
stamp: string;
|
|
1415
2144
|
mode: TaxDisplayMode;
|
|
1416
2145
|
}
|
|
1417
2146
|
export interface DisplayPrice {
|
|
2147
|
+
/** The amount to show, in minor units, for the requested mode. */
|
|
1418
2148
|
amount: number;
|
|
2149
|
+
/** The strikethrough/retail amount for the requested mode, or null. */
|
|
1419
2150
|
retailAmount: number | null;
|
|
1420
2151
|
currencyCode: string;
|
|
2152
|
+
/** True when `amount` includes tax (i.e. mode was `gross`). */
|
|
1421
2153
|
isGross: boolean;
|
|
2154
|
+
/** True when a higher retail amount exists for the same mode. */
|
|
1422
2155
|
hasDiscount: boolean;
|
|
1423
2156
|
}
|
|
1424
2157
|
export interface VariantPriceData {
|
|
@@ -1469,6 +2202,11 @@ export interface PropertyConfig {
|
|
|
1469
2202
|
maxLength?: number;
|
|
1470
2203
|
allowedCollectionIds?: string[];
|
|
1471
2204
|
filterableFieldSlugs?: string[];
|
|
2205
|
+
/**
|
|
2206
|
+
* For `product` field type: strict filter applied in the admin UI to
|
|
2207
|
+
* narrow the picker. Storefront callers can ignore this — the selected
|
|
2208
|
+
* product IDs are already stored in `PropertyValue.value` (as `string[]`).
|
|
2209
|
+
*/
|
|
1472
2210
|
productFilter?: {
|
|
1473
2211
|
filters?: Array<{
|
|
1474
2212
|
property_slug: string;
|
|
@@ -1505,6 +2243,18 @@ export interface ProductPropertyGroupValues {
|
|
|
1505
2243
|
group: PropertyGroup;
|
|
1506
2244
|
values: PropertyValue[];
|
|
1507
2245
|
}
|
|
2246
|
+
/**
|
|
2247
|
+
* A product's property values flattened to a `slug → value` record (the shape
|
|
2248
|
+
* a product-detail view actually renders). Produced by
|
|
2249
|
+
* `commerce.mapProductProperties(...)`.
|
|
2250
|
+
*
|
|
2251
|
+
* Values keep their stored JSON type: `string` (string/text/enum fields),
|
|
2252
|
+
* `boolean`, `number`, or `string[]` (multi_enum / product-reference fields).
|
|
2253
|
+
*
|
|
2254
|
+
* CAVEAT — `content_item` fields (e.g. `producer_winehouse`) store a **CMS
|
|
2255
|
+
* content-item id string**, NOT a human-readable name. To display the producer,
|
|
2256
|
+
* resolve that id against the CMS content API; do not render it verbatim.
|
|
2257
|
+
*/
|
|
1508
2258
|
export type ProductPropertyRecord = Record<string, unknown>;
|
|
1509
2259
|
export type PresetName = 'xxs' | 'xs' | 's' | 'm' | 'l' | 'xl';
|
|
1510
2260
|
export interface ResponsiveImageData {
|
|
@@ -1613,8 +2363,129 @@ export interface ReviewMediaUploadResult {
|
|
|
1613
2363
|
preview: string;
|
|
1614
2364
|
mimeType: string;
|
|
1615
2365
|
}
|
|
1616
|
-
export type CustomerSubscriptionStatus = 'TRIAL' | 'ACTIVE' | 'PAUSED' | 'PAST_DUE' | 'CANCELLED' | 'EXPIRED' | 'COMPLETED';
|
|
2366
|
+
export type CustomerSubscriptionStatus = 'incomplete' | 'trial' | 'active' | 'paused' | 'past_due' | 'cancelled' | 'expired' | 'completed' | 'INCOMPLETE' | 'TRIAL' | 'ACTIVE' | 'PAUSED' | 'PAST_DUE' | 'CANCELLED' | 'EXPIRED' | 'COMPLETED';
|
|
2367
|
+
export type SubscriptionFirstChargeTiming = 'immediate' | 'after_interval';
|
|
2368
|
+
export type SubscriptionLifecycleAction = 'pause' | 'resume' | 'skip' | 'reschedule' | 'cancel' | 'undoCancellation';
|
|
2369
|
+
export interface SubscriptionProduct {
|
|
2370
|
+
variantId: string;
|
|
2371
|
+
quantity: number;
|
|
2372
|
+
name: string;
|
|
2373
|
+
sku: string;
|
|
2374
|
+
}
|
|
2375
|
+
export interface SubscriptionAllowedAction {
|
|
2376
|
+
action: string;
|
|
2377
|
+
allowed: boolean;
|
|
2378
|
+
reason: string | null;
|
|
2379
|
+
}
|
|
2380
|
+
export interface SubscriptionUpcomingPayment {
|
|
2381
|
+
dueAt: string | null;
|
|
2382
|
+
amount: number;
|
|
2383
|
+
currencyCode: string;
|
|
2384
|
+
/**
|
|
2385
|
+
* The outstanding cycle's payment state (`ready`, `processing`, `pending`,
|
|
2386
|
+
* `action_required`, `unknown`, `failed`, or `charged_back` — a paid cycle the
|
|
2387
|
+
* bank reversed), else a live checkout's state, else `scheduled`, `paused` or
|
|
2388
|
+
* `none`. `failed` and `charged_back` are recovered with
|
|
2389
|
+
* `recoverMySubscriptionPayment`.
|
|
2390
|
+
*/
|
|
2391
|
+
state: string;
|
|
2392
|
+
nextRetryAt: string | null;
|
|
2393
|
+
checkoutUrl: string | null;
|
|
2394
|
+
}
|
|
2395
|
+
export interface SubscriptionPurchasePreview {
|
|
2396
|
+
planId: string;
|
|
2397
|
+
planName: string;
|
|
2398
|
+
/**
|
|
2399
|
+
* What the customer is charged per cycle, in minor units: products, shipping and
|
|
2400
|
+
* the tax of their zone included. Pass it back as `expectedAmount` when starting.
|
|
2401
|
+
*/
|
|
2402
|
+
amount: number;
|
|
2403
|
+
/**
|
|
2404
|
+
* Whether plan prices on this channel include tax. When false the plan price is
|
|
2405
|
+
* net and `amount` adds the customer's VAT (none under reverse charge).
|
|
2406
|
+
*/
|
|
2407
|
+
pricesIncludeTax: boolean;
|
|
2408
|
+
/** `amount` without tax. */
|
|
2409
|
+
netAmount: number;
|
|
2410
|
+
/** The tax in `amount` for the customer's tax zone. */
|
|
2411
|
+
taxAmount: number;
|
|
2412
|
+
currencyCode: string;
|
|
2413
|
+
firstPaymentAt: string;
|
|
2414
|
+
firstChargeTiming: SubscriptionFirstChargeTiming;
|
|
2415
|
+
billingInterval: string;
|
|
2416
|
+
billingIntervalCount: number;
|
|
2417
|
+
trialDays: number;
|
|
2418
|
+
trialEndsAt: string | null;
|
|
2419
|
+
minCycles: number | null;
|
|
2420
|
+
maxCycles: number | null;
|
|
2421
|
+
customerChangeCutoffHours: number;
|
|
2422
|
+
cutoffAt: string | null;
|
|
2423
|
+
mandateVerificationAmount: number;
|
|
2424
|
+
products: SubscriptionProduct[];
|
|
2425
|
+
}
|
|
2426
|
+
export interface SubscriptionPurchaseInput {
|
|
2427
|
+
planId: string;
|
|
2428
|
+
provider?: 'mollie' | 'stripe';
|
|
2429
|
+
mandateId?: string;
|
|
2430
|
+
returnUrl: string;
|
|
2431
|
+
/** Persist this key for the purchase; reuse it when retrying the same request. */
|
|
2432
|
+
requestKey: string;
|
|
2433
|
+
/**
|
|
2434
|
+
* The previewed `amount`. When given, the purchase is rejected — before any
|
|
2435
|
+
* payment starts — if the price changed since the preview; preview again.
|
|
2436
|
+
*/
|
|
2437
|
+
expectedAmount?: number;
|
|
2438
|
+
}
|
|
2439
|
+
export interface SubscriptionPaymentActionInput {
|
|
2440
|
+
requestKey: string;
|
|
2441
|
+
returnUrl: string;
|
|
2442
|
+
provider?: 'mollie' | 'stripe';
|
|
2443
|
+
}
|
|
2444
|
+
export interface SubscriptionLifecycleCommand {
|
|
2445
|
+
action: SubscriptionLifecycleAction;
|
|
2446
|
+
requestKey: string;
|
|
2447
|
+
date?: string;
|
|
2448
|
+
reason?: string;
|
|
2449
|
+
}
|
|
2450
|
+
export interface SubscriptionChangePreview {
|
|
2451
|
+
allowed: boolean;
|
|
2452
|
+
reason: string | null;
|
|
2453
|
+
nextRenewalAt: string | null;
|
|
2454
|
+
cancellationEffectiveAt: string | null;
|
|
2455
|
+
committedPayment: boolean;
|
|
2456
|
+
remainingPaidCycles: number;
|
|
2457
|
+
}
|
|
2458
|
+
export interface SubscriptionPurchaseResult {
|
|
2459
|
+
id: string;
|
|
2460
|
+
subscriptionId: string;
|
|
2461
|
+
state: string;
|
|
2462
|
+
checkoutUrl: string | null;
|
|
2463
|
+
expiresAt: string | null;
|
|
2464
|
+
currentStatus: string | null;
|
|
2465
|
+
paymentActionRequired: boolean;
|
|
2466
|
+
nextRenewalAt: string | null;
|
|
2467
|
+
}
|
|
1617
2468
|
export interface CustomerSubscription {
|
|
2469
|
+
billingIntervalCount: number;
|
|
2470
|
+
trialEndsAt: string | null;
|
|
2471
|
+
minCycles: number | null;
|
|
2472
|
+
maxCycles: number | null;
|
|
2473
|
+
paidCycleCount: number;
|
|
2474
|
+
firstChargeTiming: SubscriptionFirstChargeTiming;
|
|
2475
|
+
customerChangeCutoffHours: number;
|
|
2476
|
+
cutoffAt: string | null;
|
|
2477
|
+
cancellationRequested: boolean;
|
|
2478
|
+
cancellationEffectiveAt: string | null;
|
|
2479
|
+
earliestCancellationAt: string | null;
|
|
2480
|
+
remainingPaidCycles: number;
|
|
2481
|
+
committedPayment: boolean;
|
|
2482
|
+
resumeAt: string | null;
|
|
2483
|
+
retainedResumeAt: string | null;
|
|
2484
|
+
earliestResumeAt: string;
|
|
2485
|
+
allowedActions: SubscriptionAllowedAction[];
|
|
2486
|
+
products: SubscriptionProduct[];
|
|
2487
|
+
paymentActionRequired: boolean;
|
|
2488
|
+
upcomingPayment: SubscriptionUpcomingPayment;
|
|
1618
2489
|
id: string;
|
|
1619
2490
|
planName: string;
|
|
1620
2491
|
currencyCode: string;
|
|
@@ -1627,11 +2498,19 @@ export interface CustomerSubscription {
|
|
|
1627
2498
|
cancelAtPeriodEnd: boolean;
|
|
1628
2499
|
createdAt: string;
|
|
1629
2500
|
}
|
|
2501
|
+
/** Customer-safe subscription plan for the storefront catalogue. */
|
|
1630
2502
|
export interface SubscriptionPlanPublic {
|
|
2503
|
+
firstChargeTiming: SubscriptionFirstChargeTiming;
|
|
2504
|
+
customerChangeCutoffHours: number;
|
|
1631
2505
|
id: string;
|
|
1632
2506
|
name: string;
|
|
1633
2507
|
description: string | null;
|
|
1634
2508
|
currencyCode: string;
|
|
2509
|
+
/**
|
|
2510
|
+
* Price per cycle in minor units, shipping included, on the channel's price
|
|
2511
|
+
* basis: gross when the channel's prices include tax, otherwise net. Use
|
|
2512
|
+
* `previewSubscriptionPurchase` for the amount a customer is charged.
|
|
2513
|
+
*/
|
|
1635
2514
|
price: number;
|
|
1636
2515
|
billingInterval: string;
|
|
1637
2516
|
billingIntervalCount: number;
|
|
@@ -1639,17 +2518,21 @@ export interface SubscriptionPlanPublic {
|
|
|
1639
2518
|
minCycles: number | null;
|
|
1640
2519
|
maxCycles: number | null;
|
|
1641
2520
|
}
|
|
2521
|
+
/** Customer-safe view of a stored payment mandate. */
|
|
1642
2522
|
export interface MyPaymentMandate {
|
|
1643
2523
|
id: string;
|
|
1644
2524
|
provider: string;
|
|
1645
2525
|
mandateMethod: string | null;
|
|
2526
|
+
/** 'pending' | 'valid' | 'invalid' | 'revoked' */
|
|
1646
2527
|
mandateStatus: string;
|
|
1647
2528
|
isDefault: boolean;
|
|
1648
2529
|
createdAt: string;
|
|
1649
2530
|
}
|
|
1650
2531
|
export interface SetupPaymentMandateResult {
|
|
1651
2532
|
mandate: MyPaymentMandate;
|
|
2533
|
+
/** Mollie checkout URL to redirect the customer to (null for Stripe). */
|
|
1652
2534
|
checkoutUrl: string | null;
|
|
2535
|
+
/** Stripe SetupIntent client secret (null for Mollie). */
|
|
1653
2536
|
clientSecret: string | null;
|
|
1654
2537
|
}
|
|
1655
2538
|
export type QuoteStatus = 'draft' | 'requested' | 'in_review' | 'approved' | 'declined' | 'expired' | 'converted_to_order' | 'cancelled';
|
|
@@ -1657,16 +2540,62 @@ export interface QuoteLine {
|
|
|
1657
2540
|
id: string;
|
|
1658
2541
|
productVariantId: string;
|
|
1659
2542
|
quantity: number;
|
|
2543
|
+
/** Minor units in the quote currency. Null until a sales rep prices the line. */
|
|
1660
2544
|
unitPrice: number | null;
|
|
2545
|
+
/**
|
|
2546
|
+
* Line-level discount the rep applied. `percentage` is basis points
|
|
2547
|
+
* (10000 = 100%); `fixed` is whole-line minor units. Null when no discount.
|
|
2548
|
+
*/
|
|
1661
2549
|
discountType: 'percentage' | 'fixed' | null;
|
|
2550
|
+
/** Discount magnitude (basis points for `percentage`, minor units for `fixed`). */
|
|
1662
2551
|
discountValue: number;
|
|
1663
2552
|
discountLabel: string | null;
|
|
1664
2553
|
position: number;
|
|
2554
|
+
/**
|
|
2555
|
+
* Variant display name at read time, in the request's language. `null` when
|
|
2556
|
+
* the variant has been deleted or left the channel — render a placeholder
|
|
2557
|
+
* rather than scanning the catalogue for it.
|
|
2558
|
+
*
|
|
2559
|
+
* Optional, like the five fields below: they are `undefined` against a
|
|
2560
|
+
* Vendure that predates them, which the client detects once and then stops
|
|
2561
|
+
* asking for (see `createQuotesMethods`).
|
|
2562
|
+
*/
|
|
1665
2563
|
productName?: string | null;
|
|
2564
|
+
/** Variant SKU at read time. `null` under the same conditions as `productName`. */
|
|
1666
2565
|
sku?: string | null;
|
|
2566
|
+
/**
|
|
2567
|
+
* Effective tax rate for this line as a PERCENT — 21 for 21%, and fractional
|
|
2568
|
+
* where the statutory rate is (13.5 in IE, 8.1 in CH). It is the variant's
|
|
2569
|
+
* own applied TaxRate, the rate the converted order is charged at; never
|
|
2570
|
+
* assume a national rate. `null` when the variant is unavailable.
|
|
2571
|
+
*/
|
|
1667
2572
|
taxRate?: number | null;
|
|
2573
|
+
/**
|
|
2574
|
+
* Per-unit GROSS (incl. tax) price in minor units, with the whole-line
|
|
2575
|
+
* discount already amortised across the units. `null` when the variant is
|
|
2576
|
+
* unavailable, and while the line is still unpriced (`unitPrice` is `null`,
|
|
2577
|
+
* i.e. a draft or requested quote) — render a placeholder, never `0`.
|
|
2578
|
+
*
|
|
2579
|
+
* Derived from `lineTotalWithTax / quantity`, so it is the quote's own
|
|
2580
|
+
* agreed per-unit figure: `unitPriceWithTax × quantity` reconciles with the
|
|
2581
|
+
* line total exactly, and may differ from the variant's catalogue gross
|
|
2582
|
+
* unit price by a rounding unit.
|
|
2583
|
+
*/
|
|
1668
2584
|
unitPriceWithTax?: number | null;
|
|
2585
|
+
/**
|
|
2586
|
+
* NET (excl. tax) line total in minor units, after discount. `null` when the
|
|
2587
|
+
* variant is unavailable or the line is still unpriced.
|
|
2588
|
+
*/
|
|
1669
2589
|
lineTotal?: number | null;
|
|
2590
|
+
/**
|
|
2591
|
+
* GROSS (incl. tax) line total in minor units, after discount — what this
|
|
2592
|
+
* line adds to the payable total. `null` when the variant is unavailable or
|
|
2593
|
+
* the line is still unpriced.
|
|
2594
|
+
*
|
|
2595
|
+
* This is the quote's OWN line maths. The order `acceptQuote` creates
|
|
2596
|
+
* re-prices per unit, so an order total can differ from the sum of these by
|
|
2597
|
+
* a minor unit per line when the discount does not divide evenly.
|
|
2598
|
+
*/
|
|
1670
2599
|
lineTotalWithTax?: number | null;
|
|
1671
2600
|
createdAt: string;
|
|
1672
2601
|
updatedAt: string;
|
|
@@ -1681,6 +2610,7 @@ export interface Quote {
|
|
|
1681
2610
|
expiresAt: string | null;
|
|
1682
2611
|
salesRepUserId: string | null;
|
|
1683
2612
|
customerNotes: string | null;
|
|
2613
|
+
/** Set once the quote has been accepted and converted to an Order. */
|
|
1684
2614
|
convertedOrderId: string | null;
|
|
1685
2615
|
lines: QuoteLine[];
|
|
1686
2616
|
createdAt: string;
|
|
@@ -1702,6 +2632,11 @@ export interface CreateQuoteRequestInput {
|
|
|
1702
2632
|
}>;
|
|
1703
2633
|
customerNotes?: string;
|
|
1704
2634
|
}
|
|
2635
|
+
/**
|
|
2636
|
+
* Lifecycle state of a return, derived from its status log. Customers can
|
|
2637
|
+
* only cancel while still `requested`; everything after that is merchant- or
|
|
2638
|
+
* system-driven.
|
|
2639
|
+
*/
|
|
1705
2640
|
export type CustomerReturnState = 'requested' | 'approved' | 'rejected' | 'cancelled' | 'items_received' | 'settlement_pending' | 'settlement_failed' | 'settled';
|
|
1706
2641
|
export type CustomerReturnSettlementMethod = 'refund' | 'store_credit';
|
|
1707
2642
|
export type CustomerReturnReasonCode = 'damaged' | 'defective' | 'wrong_item' | 'not_as_described' | 'arrived_late' | 'no_longer_needed' | 'order_error' | 'other';
|
|
@@ -1712,26 +2647,40 @@ export interface CustomerReturnLine {
|
|
|
1712
2647
|
productVariantName: string;
|
|
1713
2648
|
productVariantSku: string;
|
|
1714
2649
|
requestedQty: number;
|
|
2650
|
+
/** Null until the merchant approves; 0 means the line was declined. */
|
|
1715
2651
|
approvedQty: number | null;
|
|
2652
|
+
/** Cumulative units received back by the merchant across all receipts. */
|
|
1716
2653
|
receivedQty: number;
|
|
1717
2654
|
restockQty: number;
|
|
1718
2655
|
writeOffQty: number;
|
|
1719
2656
|
reasonCode: CustomerReturnReasonCode;
|
|
1720
2657
|
reasonNote: string | null;
|
|
2658
|
+
/** Snapshot of the order line's prorated unit price incl. tax (minor units). */
|
|
1721
2659
|
unitPriceWithTax: number;
|
|
2660
|
+
/**
|
|
2661
|
+
* The same snapshot before per-unit rounding; null for returns requested
|
|
2662
|
+
* before the field existed. Multiply by a quantity and round ONCE to get
|
|
2663
|
+
* that quantity's share, exactly as the order line totals itself.
|
|
2664
|
+
*/
|
|
1722
2665
|
unitPriceWithTaxUnrounded: number | null;
|
|
2666
|
+
/** Refund amount for this line (minor units); null until approved. */
|
|
1723
2667
|
refundAmount: number | null;
|
|
1724
2668
|
}
|
|
2669
|
+
/** A customer-facing return (RMA). All money fields are Int minor units. */
|
|
1725
2670
|
export interface CustomerReturn {
|
|
1726
2671
|
id: string;
|
|
2672
|
+
/** Human-facing RMA code, e.g. RMA-000042. */
|
|
1727
2673
|
code: string;
|
|
1728
2674
|
state: CustomerReturnState;
|
|
1729
2675
|
orderId: string;
|
|
1730
2676
|
orderCode: string;
|
|
1731
2677
|
currencyCode: string;
|
|
1732
2678
|
preferredSettlementMethod: CustomerReturnSettlementMethod | null;
|
|
2679
|
+
/** Settlement method actually used; null until settled. */
|
|
1733
2680
|
settlementMethod: CustomerReturnSettlementMethod | null;
|
|
2681
|
+
/** Shipping refunded on top of line refunds (minor units). */
|
|
1734
2682
|
shippingRefundAmount: number;
|
|
2683
|
+
/** Total actually settled (minor units); null until settled. */
|
|
1735
2684
|
settledAmount: number | null;
|
|
1736
2685
|
customerNote: string | null;
|
|
1737
2686
|
requestedAt: string;
|
|
@@ -1759,39 +2708,74 @@ export interface RequestReturnInput {
|
|
|
1759
2708
|
customerNote?: string;
|
|
1760
2709
|
preferredSettlementMethod?: CustomerReturnSettlementMethod;
|
|
1761
2710
|
}
|
|
2711
|
+
/** Per-order-line returnable quantities for the return-request flow. */
|
|
1762
2712
|
export interface ReturnableOrderLine {
|
|
1763
2713
|
orderLineId: string;
|
|
1764
2714
|
productVariantId: string;
|
|
1765
2715
|
productVariantName: string;
|
|
1766
2716
|
productVariantSku: string;
|
|
2717
|
+
/** Units shipped or delivered for this order line. */
|
|
1767
2718
|
fulfilledQty: number;
|
|
2719
|
+
/** fulfilledQty minus quantities tied up in active returns. */
|
|
1768
2720
|
returnableQty: number;
|
|
2721
|
+
/** The order line's prorated unit price incl. tax (minor units). */
|
|
1769
2722
|
unitPriceWithTax: number;
|
|
2723
|
+
/**
|
|
2724
|
+
* The same price before per-unit rounding. Multiply by a quantity and round
|
|
2725
|
+
* ONCE to preview that quantity's refund, exactly as the order line totals
|
|
2726
|
+
* itself.
|
|
2727
|
+
*/
|
|
1770
2728
|
unitPriceWithTaxUnrounded: number;
|
|
1771
2729
|
}
|
|
1772
2730
|
export interface CustomerReturnEligibility {
|
|
1773
2731
|
orderId: string;
|
|
1774
2732
|
eligible: boolean;
|
|
2733
|
+
/** Why the order is not eligible; null when eligible. */
|
|
1775
2734
|
reason: string | null;
|
|
1776
2735
|
returnWindowEndsAt: string | null;
|
|
2736
|
+
/** Only lines with fulfilled quantity appear here. */
|
|
1777
2737
|
lines: ReturnableOrderLine[];
|
|
1778
2738
|
}
|
|
2739
|
+
/**
|
|
2740
|
+
* The authenticated customer's B2B accounts-receivable credit status in the
|
|
2741
|
+
* current channel. All money fields are in minor units of `currencyCode`.
|
|
2742
|
+
* Returned by `client.credit.getCreditStatus()`; `null` when the customer is
|
|
2743
|
+
* not signed in, has no credit account, or the channel has B2B credit disabled.
|
|
2744
|
+
*/
|
|
1779
2745
|
export interface B2bCreditStatus {
|
|
1780
2746
|
customerId: string;
|
|
1781
2747
|
currencyCode: string;
|
|
2748
|
+
/** Outstanding invoiced-but-unpaid ledger balance. */
|
|
1782
2749
|
balance: number;
|
|
2750
|
+
/** Total value of placed B2B orders not yet invoiced. */
|
|
1783
2751
|
uninvoicedOrdersTotal: number;
|
|
2752
|
+
/** Total credit exposure (`balance + uninvoicedOrdersTotal`). */
|
|
1784
2753
|
exposure: number;
|
|
2754
|
+
/** Configured credit limit; `null` when no limit is set. */
|
|
1785
2755
|
creditLimit: number | null;
|
|
2756
|
+
/** Remaining headroom (`creditLimit - exposure`); `null` when no limit is set. */
|
|
1786
2757
|
available: number | null;
|
|
1787
2758
|
overdueInvoiceCount: number;
|
|
1788
2759
|
overLimit: boolean;
|
|
1789
2760
|
hasOverdue: boolean;
|
|
2761
|
+
/**
|
|
2762
|
+
* Where `balance` was sourced from. `LOCAL_LEDGER` = computed from the local
|
|
2763
|
+
* AR subledger; `ERP_LIVE` = read live from the ERP; `ERP_UNLINKED` = the
|
|
2764
|
+
* channel is ERP-driven but this customer isn't linked yet (treat the balance
|
|
2765
|
+
* as unavailable rather than zero, and surface a "not linked" notice).
|
|
2766
|
+
*/
|
|
1790
2767
|
balanceSource: CreditBalanceSource;
|
|
1791
2768
|
}
|
|
2769
|
+
/** Where a {@link B2bCreditStatus.balanceSource} balance was sourced from. */
|
|
1792
2770
|
export type CreditBalanceSource = 'LOCAL_LEDGER' | 'ERP_LIVE' | 'ERP_UNLINKED';
|
|
2771
|
+
/** How reliably the source payment condition could be interpreted. */
|
|
1793
2772
|
export type PaymentTermsClassification = 'SINGLE_DUE_DATE' | 'COMPLEX' | 'UNRESOLVED' | 'UNASSIGNED' | 'CONFLICT';
|
|
2773
|
+
/** Assignment and freshness state for externally managed customer payment terms. */
|
|
1794
2774
|
export type PaymentTermsStatus = 'ASSIGNED' | 'UNASSIGNED' | 'UNRESOLVED' | 'STALE' | 'CONFLICT';
|
|
2775
|
+
/**
|
|
2776
|
+
* Source-aware payment terms for the authenticated customer. Exact-backed terms preserve the
|
|
2777
|
+
* original condition code and complex-rule fields rather than reducing every condition to days.
|
|
2778
|
+
*/
|
|
1795
2779
|
export interface CustomerPaymentTerms {
|
|
1796
2780
|
customerId: string | null;
|
|
1797
2781
|
source: string;
|
|
@@ -1812,15 +2796,25 @@ export interface CustomerPaymentTerms {
|
|
|
1812
2796
|
syncedAt: string | null;
|
|
1813
2797
|
error: string | null;
|
|
1814
2798
|
}
|
|
2799
|
+
/** Payment terms frozen on an order at acceptance, including later remote confirmation metadata. */
|
|
1815
2800
|
export interface OrderPaymentTermsSnapshot extends Omit<CustomerPaymentTerms, 'customerId'> {
|
|
1816
2801
|
resolvedAt: string;
|
|
1817
2802
|
remoteConditionCode: string | null;
|
|
1818
2803
|
remoteConfirmedAt: string | null;
|
|
2804
|
+
/** True after the ERP confirms a different condition than the accepted snapshot. */
|
|
1819
2805
|
remoteMismatch: boolean;
|
|
1820
2806
|
}
|
|
2807
|
+
/** Assignment and freshness state for Exact-managed customer delivery terms. */
|
|
1821
2808
|
export type DeliveryTermsStatus = 'ASSIGNED' | 'UNASSIGNED' | 'UNRESOLVED' | 'STALE' | 'CONFLICT';
|
|
2809
|
+
/** Exact's account-level partial-delivery policy, exposed as operational guidance. */
|
|
1822
2810
|
export type DeliveryAdvice = 'PARTIAL_ALLOWED' | 'COMPLETE_ORDER' | 'PARTIAL_WITHOUT_BACKORDER' | 'UNKNOWN';
|
|
2811
|
+
/** Why the placed order uses its selected shipping method. */
|
|
1823
2812
|
export type DeliverySelectionSource = 'CUSTOMER_DEFAULT' | 'EXPLICIT_OVERRIDE' | 'IMPORTED' | 'UNKNOWN';
|
|
2813
|
+
/**
|
|
2814
|
+
* Exact-aware delivery terms for the authenticated customer in the current channel.
|
|
2815
|
+
* The preferred method is a default, not an eligibility restriction; checkout pricing
|
|
2816
|
+
* still comes from the platform's shipping calculator.
|
|
2817
|
+
*/
|
|
1824
2818
|
export interface CustomerDeliveryTerms {
|
|
1825
2819
|
customerId: string | null;
|
|
1826
2820
|
source: string;
|
|
@@ -1833,18 +2827,22 @@ export interface CustomerDeliveryTerms {
|
|
|
1833
2827
|
preferredShippingMethodCode: string | null;
|
|
1834
2828
|
preferredShippingMethodName: string | null;
|
|
1835
2829
|
preferredShippingMethodAvailable: boolean;
|
|
2830
|
+
/** Active platform mappings that may be selected as deliberate overrides. */
|
|
1836
2831
|
eligibleShippingMethodIds: string[];
|
|
1837
2832
|
incotermStatus: DeliveryTermsStatus;
|
|
1838
2833
|
incotermCode: string | null;
|
|
1839
2834
|
incotermVersion: number | null;
|
|
1840
2835
|
incotermAddress: string | null;
|
|
1841
2836
|
incotermDescription: string | null;
|
|
2837
|
+
/** Exact dispatch lead time in days; this is not a promised arrival date. */
|
|
1842
2838
|
shippingLeadDays: number | null;
|
|
1843
2839
|
deliveryAdvice: DeliveryAdvice | null;
|
|
1844
2840
|
stale: boolean;
|
|
1845
2841
|
syncedAt: string | null;
|
|
2842
|
+
/** Customer-safe warning; raw synchronization errors remain Admin-only. */
|
|
1846
2843
|
warning: string | null;
|
|
1847
2844
|
}
|
|
2845
|
+
/** Delivery terms frozen on an order at acceptance, plus later Exact readback metadata. */
|
|
1848
2846
|
export interface OrderDeliveryTermsSnapshot {
|
|
1849
2847
|
source: string;
|
|
1850
2848
|
managedExternally: boolean;
|
|
@@ -1859,7 +2857,9 @@ export interface OrderDeliveryTermsSnapshot {
|
|
|
1859
2857
|
platformShippingMethodCode: string | null;
|
|
1860
2858
|
platformShippingMethodName: string | null;
|
|
1861
2859
|
platformShippingMethodDescription: string | null;
|
|
2860
|
+
/** Accepted platform shipping quote in order-currency minor units. */
|
|
1862
2861
|
platformShippingPrice: number | null;
|
|
2862
|
+
/** Accepted platform shipping quote including tax, in order-currency minor units. */
|
|
1863
2863
|
platformShippingPriceWithTax: number | null;
|
|
1864
2864
|
preferredShippingMethodId: string | null;
|
|
1865
2865
|
incotermStatus: DeliveryTermsStatus;
|
|
@@ -1880,6 +2880,7 @@ export interface OrderDeliveryTermsSnapshot {
|
|
|
1880
2880
|
remoteIncotermAddress: string | null;
|
|
1881
2881
|
remoteDeliveryDate: string | null;
|
|
1882
2882
|
remoteConfirmedAt: string | null;
|
|
2883
|
+
/** True after Exact confirms delivery fields that differ from the accepted snapshot. */
|
|
1883
2884
|
remoteMismatch: boolean;
|
|
1884
2885
|
}
|
|
1885
2886
|
export interface VatValidationResult {
|
|
@@ -1912,6 +2913,7 @@ export interface DropOffPoint {
|
|
|
1912
2913
|
availableDays: number[] | null;
|
|
1913
2914
|
cutOffTime: string | null;
|
|
1914
2915
|
carrierId: number | null;
|
|
2916
|
+
/** Distance from the postal code, in metres. */
|
|
1915
2917
|
distance: number | null;
|
|
1916
2918
|
}
|
|
1917
2919
|
export interface DeliveryOptionsInput {
|
|
@@ -1928,10 +2930,12 @@ export interface DeliveryTimeFrame {
|
|
|
1928
2930
|
start: string;
|
|
1929
2931
|
end: string;
|
|
1930
2932
|
priceComment: string | null;
|
|
2933
|
+
/** Base rate for this window in minor units (cents); null when the carrier omits it. Surcharges finalize after shipment creation. */
|
|
1931
2934
|
price: {
|
|
1932
2935
|
amount: number;
|
|
1933
2936
|
currency: string;
|
|
1934
2937
|
} | null;
|
|
2938
|
+
/** Carrier delivery type of this window (MyParcel: 1 morning, 2 evening, 3 standard, 4 pickup). */
|
|
1935
2939
|
deliveryType: number | null;
|
|
1936
2940
|
}
|
|
1937
2941
|
export interface DeliveryOption {
|
|
@@ -1943,14 +2947,21 @@ export interface PickupLocationAddress {
|
|
|
1943
2947
|
number: string;
|
|
1944
2948
|
postalCode: string;
|
|
1945
2949
|
city: string;
|
|
2950
|
+
/** ISO 3166-1 alpha-2 country code. */
|
|
1946
2951
|
countryCode: string;
|
|
1947
2952
|
region?: string;
|
|
1948
2953
|
}
|
|
1949
2954
|
export interface PickupLocationOpeningHours {
|
|
2955
|
+
/** 0 = Sunday ... 6 = Saturday. */
|
|
1950
2956
|
weekday: number;
|
|
2957
|
+
/** `HH:MM` (24-hour). */
|
|
1951
2958
|
open: string;
|
|
1952
2959
|
close: string;
|
|
1953
2960
|
}
|
|
2961
|
+
/**
|
|
2962
|
+
* Carrier-agnostic pickup location. Currently MyParcel-backed; future
|
|
2963
|
+
* providers (Sendcloud, Hendriks) implement the same shape.
|
|
2964
|
+
*/
|
|
1954
2965
|
export interface PickupLocation {
|
|
1955
2966
|
provider: string;
|
|
1956
2967
|
carrier: number;
|
|
@@ -1958,9 +2969,11 @@ export interface PickupLocation {
|
|
|
1958
2969
|
name: string;
|
|
1959
2970
|
address: PickupLocationAddress;
|
|
1960
2971
|
openingHours?: PickupLocationOpeningHours[];
|
|
2972
|
+
/** Carrier-specific extras. */
|
|
1961
2973
|
details?: Record<string, unknown>;
|
|
1962
2974
|
}
|
|
1963
2975
|
export interface PickupLocationSearchInput {
|
|
2976
|
+
/** ISO 3166-1 alpha-2 country code. */
|
|
1964
2977
|
countryCode: string;
|
|
1965
2978
|
postalCode: string;
|
|
1966
2979
|
carrierId: number;
|
|
@@ -1969,6 +2982,7 @@ export interface PickupLocationSearchInput {
|
|
|
1969
2982
|
number?: string;
|
|
1970
2983
|
latitude?: number;
|
|
1971
2984
|
longitude?: number;
|
|
2985
|
+
/** Search radius in metres. */
|
|
1972
2986
|
distance?: number;
|
|
1973
2987
|
}
|
|
1974
2988
|
export interface ShipmentTrackingHistoryEntry {
|
|
@@ -1990,17 +3004,24 @@ export interface CommerceModule {
|
|
|
1990
3004
|
getProductById(id: string, options?: RequestOptions): Promise<Product>;
|
|
1991
3005
|
getProducts(listOptions?: ProductListOptions, options?: RequestOptions): Promise<PaginatedList<ProductSummary>>;
|
|
1992
3006
|
getProductsInCollection(collectionSlug: string, listOptions?: CollectionProductListOptions, options?: RequestOptions): Promise<PaginatedList<CollectionProductSummary>>;
|
|
3007
|
+
/**
|
|
3008
|
+
* `getProductsInCollection` by collection id — typically `route.id` from the
|
|
3009
|
+
* routes manifest. Tagged `collection:<id>`, which the slug variant cannot be,
|
|
3010
|
+
* so `collection.membership_changed` purges the listing.
|
|
3011
|
+
*/
|
|
1993
3012
|
getProductsInCollectionById(collectionId: string, listOptions?: CollectionProductListOptions, options?: RequestOptions): Promise<PaginatedList<CollectionProductSummary>>;
|
|
1994
3013
|
getFacets(options?: RequestOptions): Promise<Facet[]>;
|
|
1995
3014
|
searchProducts(input: SearchInput, options?: RequestOptions): Promise<SearchResult>;
|
|
1996
3015
|
getActiveOrder(): Promise<Order | null>;
|
|
1997
3016
|
addToCart(variantId: string, quantity: number): Promise<Order>;
|
|
3017
|
+
/** Add several variants in one call (e.g. favourite-box bundles). */
|
|
1998
3018
|
addItemsToCart(items: Array<{
|
|
1999
3019
|
productVariantId: string;
|
|
2000
3020
|
quantity: number;
|
|
2001
3021
|
}>): Promise<Order>;
|
|
2002
3022
|
updateCartLine(lineId: string, quantity: number): Promise<Order>;
|
|
2003
3023
|
removeFromCart(lineId: string): Promise<Order>;
|
|
3024
|
+
/** Remove every line from the active order, leaving an empty cart. */
|
|
2004
3025
|
clearCart(): Promise<Order>;
|
|
2005
3026
|
applyCouponCode(code: string): Promise<Order>;
|
|
2006
3027
|
removeCouponCode(code: string): Promise<Order>;
|
|
@@ -2008,18 +3029,42 @@ export interface CommerceModule {
|
|
|
2008
3029
|
setShippingAddress(input: AddressInput): Promise<Order>;
|
|
2009
3030
|
setBillingAddress(input: AddressInput): Promise<Order>;
|
|
2010
3031
|
getEligibleShippingMethods(): Promise<ShippingMethod[]>;
|
|
3032
|
+
/** Exact-aware delivery defaults for the signed-in customer, or null when unavailable. */
|
|
2011
3033
|
getDeliveryTerms(options?: RequestOptions): Promise<CustomerDeliveryTerms | null>;
|
|
2012
3034
|
setShippingMethod(ids: string[]): Promise<Order>;
|
|
3035
|
+
/** Apply the signed-in customer's currently eligible Exact default shipping method. */
|
|
2013
3036
|
applyPreferredShippingMethod(): Promise<Order>;
|
|
2014
3037
|
getEligiblePaymentMethods(): Promise<PaymentMethod[]>;
|
|
3038
|
+
/** Order minimums on the active channel — display/pre-validation; server enforces. */
|
|
2015
3039
|
getOrderConstraints(): Promise<ActiveChannelOrderConstraints>;
|
|
3040
|
+
/**
|
|
3041
|
+
* Record how the buyer intends to settle this order and return the
|
|
3042
|
+
* **re-priced** order — a pay-now discount promotion only applies once the
|
|
3043
|
+
* engine knows the intent, and a payment method is not chosen until
|
|
3044
|
+
* {@link CommerceModule.addPayment}, long after the totals the buyer is
|
|
3045
|
+
* looking at were computed. Call it whenever the buyer picks or changes a
|
|
3046
|
+
* payment method, before {@link CommerceModule.transitionToArrangingPayment}.
|
|
3047
|
+
*/
|
|
2016
3048
|
setPaymentIntent(intent: OrderPaymentIntent): Promise<Order>;
|
|
2017
3049
|
transitionToArrangingPayment(): Promise<Order>;
|
|
2018
3050
|
addPayment(input: PaymentInput): Promise<Order>;
|
|
2019
3051
|
createStripePaymentIntent(options?: RequestOptions): Promise<StripePaymentIntentResult>;
|
|
2020
3052
|
getMolliePaymentMethods(input: MolliePaymentMethodsInput, options?: RequestOptions): Promise<MolliePaymentMethod[]>;
|
|
3053
|
+
/**
|
|
3054
|
+
* Mollie payment methods for the given PaymentMethod, ordered per the
|
|
3055
|
+
* channel's saved configuration and with hidden methods removed. Use this
|
|
3056
|
+
* (rather than `getMolliePaymentMethods`) when the storefront should respect
|
|
3057
|
+
* the merchant's curated order + visibility. Returns `[]` when no Mollie API
|
|
3058
|
+
* key is configured for the channel or Mollie is unreachable.
|
|
3059
|
+
*/
|
|
2021
3060
|
getOrderedMolliePaymentMethods(paymentMethodCode: string, options?: RequestOptions): Promise<OrderedMollieMethod[]>;
|
|
2022
3061
|
createMolliePaymentIntent(input: CreateMolliePaymentIntentInput, options?: RequestOptions): Promise<MolliePaymentIntentResult>;
|
|
3062
|
+
/**
|
|
3063
|
+
* Force-fetch the Mollie payment status and reconcile the order state.
|
|
3064
|
+
* Use as a fallback when the Mollie webhook is delayed or did not arrive
|
|
3065
|
+
* (e.g. local/staging without a public tunnel). Returns `null` when no
|
|
3066
|
+
* order matches `orderCode`.
|
|
3067
|
+
*/
|
|
2023
3068
|
syncMolliePaymentStatus(orderCode: string, options?: RequestOptions): Promise<MollieOrderStatusResult | null>;
|
|
2024
3069
|
login(email: string, password: string): Promise<LoginResult>;
|
|
2025
3070
|
register(input: RegisterInput): Promise<{
|
|
@@ -2027,11 +3072,25 @@ export interface CommerceModule {
|
|
|
2027
3072
|
}>;
|
|
2028
3073
|
logout(): Promise<void>;
|
|
2029
3074
|
getCurrentCustomer(): Promise<Customer | null>;
|
|
3075
|
+
/**
|
|
3076
|
+
* Price lists currently applying to the signed-in customer (identity only,
|
|
3077
|
+
* sorted by resolution priority). Empty for anonymous visitors with no
|
|
3078
|
+
* channel-wide lists.
|
|
3079
|
+
*/
|
|
2030
3080
|
getActiveCustomerPriceLists(options?: RequestOptions): Promise<CustomerPriceList[]>;
|
|
2031
3081
|
getCustomerOrders(options?: OrderListOptions): Promise<PaginatedList<OrderSummary>>;
|
|
3082
|
+
/**
|
|
3083
|
+
* Add every line of a previous order to the active cart. Returns the new
|
|
3084
|
+
* active order plus a list of lines that could not be added (e.g. variant
|
|
3085
|
+
* removed, out of stock).
|
|
3086
|
+
*/
|
|
2032
3087
|
reorder(orderCode: string): Promise<ReorderResult>;
|
|
2033
3088
|
getCollections(listOptions?: CollectionListOptions, options?: RequestOptions): Promise<Collection[]>;
|
|
2034
3089
|
getCollection(slug: string, options?: RequestOptions): Promise<CollectionDetail>;
|
|
3090
|
+
/**
|
|
3091
|
+
* A collection by id — typically `route.id` from the routes manifest. Tagged
|
|
3092
|
+
* `collection:<id>`; throws a `NOT_FOUND` StorefrontError (404) when absent.
|
|
3093
|
+
*/
|
|
2035
3094
|
getCollectionById(id: string, options?: RequestOptions): Promise<CollectionDetail>;
|
|
2036
3095
|
updateCustomer(input: UpdateCustomerInput): Promise<Customer>;
|
|
2037
3096
|
updatePassword(currentPassword: string, newPassword: string): Promise<void>;
|
|
@@ -2061,11 +3120,18 @@ export interface CommerceModule {
|
|
|
2061
3120
|
deleteAddress(id: string): Promise<void>;
|
|
2062
3121
|
getAvailableCountries(): Promise<Country[]>;
|
|
2063
3122
|
getOrderByCode(code: string): Promise<Order>;
|
|
3123
|
+
/** Invoices for one of the signed-in customer's own orders. */
|
|
2064
3124
|
getMyOrderInvoices(orderCode: string): Promise<CustomerInvoice[]>;
|
|
3125
|
+
/** Download one of the signed-in customer's own invoices as a base64 PDF. */
|
|
2065
3126
|
getMyInvoicePdf(invoiceId: string): Promise<CustomerInvoicePdf>;
|
|
2066
3127
|
getActiveChannel(): Promise<ActiveChannel>;
|
|
2067
3128
|
getPropertyGroups(options?: RequestOptions): Promise<PropertyGroup[]>;
|
|
2068
3129
|
getProductProperties(productId: string, options?: RequestOptions): Promise<ProductPropertyGroupValues[]>;
|
|
3130
|
+
/**
|
|
3131
|
+
* Flatten `getProductProperties(...)` output into a `slug → value` record for
|
|
3132
|
+
* the product-detail view. Pure helper — see `ProductPropertyRecord` for the
|
|
3133
|
+
* `content_item` (producer) caveat.
|
|
3134
|
+
*/
|
|
2069
3135
|
mapProductProperties(groups: ProductPropertyGroupValues[]): ProductPropertyRecord;
|
|
2070
3136
|
getMySavedLists(): Promise<SavedList[]>;
|
|
2071
3137
|
getMySavedList(id: string): Promise<SavedList | null>;
|
|
@@ -2105,29 +3171,106 @@ export interface CommerceModule {
|
|
|
2105
3171
|
voteReview(reviewId: string, isHelpful: boolean): Promise<boolean>;
|
|
2106
3172
|
reportReview(reviewId: string, reason: string): Promise<boolean>;
|
|
2107
3173
|
uploadReviewMedia(files: File[]): Promise<ReviewMediaUploadResult[]>;
|
|
3174
|
+
getMySubscription(id: string): Promise<CustomerSubscription | null>;
|
|
3175
|
+
previewSubscriptionPurchase(planId: string, options?: {
|
|
3176
|
+
provider?: 'mollie' | 'stripe';
|
|
3177
|
+
mandateId?: string;
|
|
3178
|
+
}): Promise<SubscriptionPurchasePreview>;
|
|
3179
|
+
startSubscriptionPurchase(input: SubscriptionPurchaseInput): Promise<SubscriptionPurchaseResult>;
|
|
3180
|
+
getSubscriptionPurchaseStatus(id: string): Promise<SubscriptionPurchaseResult>;
|
|
3181
|
+
previewMySubscriptionChange(id: string, input: SubscriptionLifecycleCommand): Promise<SubscriptionChangePreview>;
|
|
3182
|
+
manageMySubscription(id: string, input: SubscriptionLifecycleCommand): Promise<CustomerSubscription>;
|
|
3183
|
+
skipMySubscription(id: string, requestKey: string): Promise<CustomerSubscription>;
|
|
3184
|
+
rescheduleMySubscription(id: string, date: string, requestKey: string): Promise<CustomerSubscription>;
|
|
3185
|
+
undoMySubscriptionCancellation(id: string, requestKey: string): Promise<CustomerSubscription>;
|
|
3186
|
+
replaceMySubscriptionMandate(id: string, input: SubscriptionPaymentActionInput & {
|
|
3187
|
+
provider: 'mollie' | 'stripe';
|
|
3188
|
+
}): Promise<SubscriptionPurchaseResult>;
|
|
3189
|
+
/**
|
|
3190
|
+
* A hosted link that pays the outstanding failed or charged-back cycle again,
|
|
3191
|
+
* without another delivery. Reuse `upcomingPayment.checkoutUrl` while it is live.
|
|
3192
|
+
*/
|
|
3193
|
+
recoverMySubscriptionPayment(id: string, input: SubscriptionPaymentActionInput): Promise<SubscriptionPurchaseResult>;
|
|
2108
3194
|
getMySubscriptions(): Promise<CustomerSubscription[]>;
|
|
3195
|
+
/**
|
|
3196
|
+
* Plans available to subscribe to in the current channel. Public —
|
|
3197
|
+
* works for anonymous visitors. Only enabled plans are returned.
|
|
3198
|
+
*/
|
|
2109
3199
|
getSubscriptionPlans(): Promise<SubscriptionPlanPublic[]>;
|
|
3200
|
+
/**
|
|
3201
|
+
* The active customer's valid or still-pending payment mandates. Poll this
|
|
3202
|
+
* after `setupPaymentMandate` until the mandate flips to `valid`.
|
|
3203
|
+
*/
|
|
2110
3204
|
getMyPaymentMandates(): Promise<MyPaymentMandate[]>;
|
|
3205
|
+
/**
|
|
3206
|
+
* Begin establishing a payment mandate. Returns a `checkoutUrl` (Mollie) or
|
|
3207
|
+
* `clientSecret` (Stripe) for the frontend to complete the setup.
|
|
3208
|
+
*/
|
|
2111
3209
|
setupPaymentMandate(input: {
|
|
2112
3210
|
provider: string;
|
|
2113
3211
|
redirectUrl: string;
|
|
2114
3212
|
}): Promise<SetupPaymentMandateResult>;
|
|
2115
|
-
|
|
3213
|
+
/**
|
|
3214
|
+
* Create a subscription for the active customer against an enabled plan
|
|
3215
|
+
* using one of their valid mandates.
|
|
3216
|
+
*/
|
|
3217
|
+
createSubscription(planId: string, mandateId: string, requestKey?: string): Promise<CustomerSubscription>;
|
|
3218
|
+
/** Pause an active or trial subscription owned by the active customer. */
|
|
2116
3219
|
pauseMySubscription(id: string, reason?: string): Promise<CustomerSubscription>;
|
|
3220
|
+
/** Resume a paused subscription owned by the active customer. */
|
|
2117
3221
|
resumeMySubscription(id: string): Promise<CustomerSubscription>;
|
|
3222
|
+
/**
|
|
3223
|
+
* Cancel a subscription owned by the active customer. Defaults to
|
|
3224
|
+
* the earliest eligible cancellation date; minimum paid-cycle commitments still apply.
|
|
3225
|
+
*/
|
|
2118
3226
|
cancelMySubscription(id: string, options?: {
|
|
2119
3227
|
reason?: string;
|
|
2120
3228
|
immediate?: boolean;
|
|
2121
3229
|
}): Promise<CustomerSubscription>;
|
|
3230
|
+
/** Returns the active customer's quotes in the current channel. */
|
|
2122
3231
|
getMyQuotes(options?: QuoteListOptions): Promise<QuoteList>;
|
|
3232
|
+
/** Returns one of the active customer's quotes by id. */
|
|
2123
3233
|
getMyQuote(id: string): Promise<Quote | null>;
|
|
3234
|
+
/**
|
|
3235
|
+
* Submits a new quote request. Lines are unpriced — a sales rep
|
|
3236
|
+
* prices them later. Requires the customer to belong to a configured
|
|
3237
|
+
* B2B customer group.
|
|
3238
|
+
*/
|
|
2124
3239
|
createQuoteRequest(input: CreateQuoteRequestInput): Promise<Quote>;
|
|
3240
|
+
/**
|
|
3241
|
+
* Accepts a priced+approved quote, producing a real `Order` in
|
|
3242
|
+
* `ArrangingPayment` with the quoted unit prices applied.
|
|
3243
|
+
*/
|
|
2125
3244
|
acceptQuote(id: string): Promise<Order>;
|
|
3245
|
+
/** Cancels a quote owned by the active customer. */
|
|
2126
3246
|
cancelMyQuote(id: string, reason?: string): Promise<Quote>;
|
|
3247
|
+
/**
|
|
3248
|
+
* Returns the active customer's returns (RMAs) in the current channel,
|
|
3249
|
+
* newest first. Requires an authenticated customer session.
|
|
3250
|
+
*/
|
|
2127
3251
|
getMyReturns(options?: CustomerReturnListOptions): Promise<CustomerReturnList>;
|
|
3252
|
+
/**
|
|
3253
|
+
* Returns one of the active customer's returns by id, or `null` when it
|
|
3254
|
+
* does not exist or belongs to another customer.
|
|
3255
|
+
*/
|
|
2128
3256
|
getMyReturn(id: string): Promise<CustomerReturn | null>;
|
|
3257
|
+
/**
|
|
3258
|
+
* Requests a return (RMA) for fulfilled lines of one of the active
|
|
3259
|
+
* customer's orders. Only allowed when the channel has returns enabled and
|
|
3260
|
+
* the order is inside the return window; quantities are capped at each
|
|
3261
|
+
* line's returnable quantity (see `getReturnableLinesForOrder`).
|
|
3262
|
+
*/
|
|
2129
3263
|
requestReturn(input: RequestReturnInput): Promise<CustomerReturn>;
|
|
3264
|
+
/**
|
|
3265
|
+
* Cancels a return owned by the active customer. Only possible while the
|
|
3266
|
+
* return is still in the `requested` state.
|
|
3267
|
+
*/
|
|
2130
3268
|
cancelMyReturn(id: string): Promise<CustomerReturn>;
|
|
3269
|
+
/**
|
|
3270
|
+
* Per-line returnable quantities and the return window for one of the
|
|
3271
|
+
* active customer's orders — drives the return-request UI. Lines only
|
|
3272
|
+
* appear once they have shipped/delivered quantity.
|
|
3273
|
+
*/
|
|
2131
3274
|
getReturnableLinesForOrder(orderId: string): Promise<CustomerReturnEligibility>;
|
|
2132
3275
|
getMyVatValidationStatus(): Promise<VatValidationResult | null>;
|
|
2133
3276
|
setMyVatNumber(vatNumber: string): Promise<VatValidationResult>;
|
|
@@ -2135,22 +3278,52 @@ export interface CommerceModule {
|
|
|
2135
3278
|
getDropOffPoints(input: DropOffPointInput): Promise<DropOffPoint[]>;
|
|
2136
3279
|
getDeliveryOptions(input: DeliveryOptionsInput): Promise<DeliveryOption[]>;
|
|
2137
3280
|
trackShipment(barcode: string, postalCode: string): Promise<ShipmentTrackingInfo | null>;
|
|
3281
|
+
/**
|
|
3282
|
+
* Carrier-agnostic pickup-location search. Currently MyParcel-backed;
|
|
3283
|
+
* future providers (Sendcloud, Hendriks) implement the same shape.
|
|
3284
|
+
*/
|
|
2138
3285
|
findPickupLocations(input: PickupLocationSearchInput): Promise<PickupLocation[]>;
|
|
3286
|
+
/** Persist the customer's chosen pickup location on the active order. */
|
|
2139
3287
|
selectPickupLocation(location: PickupLocation): Promise<Order>;
|
|
3288
|
+
/** Read the pickup location stored on the active order, or `null`. */
|
|
2140
3289
|
getActivePickupLocation(): Promise<PickupLocation | null>;
|
|
3290
|
+
/**
|
|
3291
|
+
* Returns the channel's public branding info: identity (logos, name),
|
|
3292
|
+
* theme (primary color), fonts (Google + self-hosted), contact, legal,
|
|
3293
|
+
* social links, and storefront routing config. Asset URLs are resolved
|
|
3294
|
+
* against the channel's CDN domain (or global cdnUrl fallback).
|
|
3295
|
+
*
|
|
3296
|
+
* Used by the `@sixtyninecommerce/create-storefront` CLI for fail-fast scaffolding
|
|
3297
|
+
* validation and at storefront runtime for footer/header/SEO rendering.
|
|
3298
|
+
*/
|
|
2141
3299
|
getBranding(options?: RequestOptions): Promise<BrandingInfo>;
|
|
2142
3300
|
}
|
|
2143
3301
|
export interface ContentModule {
|
|
2144
3302
|
resolvePath(path: string, locale?: string, options?: RequestOptions): Promise<ResolvedContent>;
|
|
2145
3303
|
getContent(queryOptions: ContentQueryOptions, options?: RequestOptions): Promise<Record<string, unknown>>;
|
|
3304
|
+
/**
|
|
3305
|
+
* Typed channel-wide CMS content search. Pass `collectionId`/`collectionSlug`
|
|
3306
|
+
* to scope, or omit both to search across every collection.
|
|
3307
|
+
*/
|
|
2146
3308
|
searchContent(query: ContentSearchQuery, options?: RequestOptions): Promise<ContentSearchResult>;
|
|
2147
3309
|
getAsset(id: string, options?: RequestOptions): Promise<CmsAsset>;
|
|
2148
3310
|
lookupAssets(ids: string[], options?: RequestOptions): Promise<CmsAsset[]>;
|
|
2149
3311
|
lookupVendureAssetDescriptions(vendureAssetIds: string[], options?: RequestOptions): Promise<Record<string, VendureAssetDescriptionTranslation[]>>;
|
|
3312
|
+
/** Discover the channel's forms (public projection). See {@link FormSummary}. */
|
|
2150
3313
|
listForms(options?: FormListOptions & RequestOptions): Promise<FormListResult>;
|
|
2151
3314
|
getForm(id: string, options?: RequestOptions): Promise<FormDefinition>;
|
|
2152
3315
|
getFormBySlug(slug: string, options?: RequestOptions): Promise<FormDefinition>;
|
|
3316
|
+
/**
|
|
3317
|
+
* The field-type registry (GET /forms/field-types) — every legal field type
|
|
3318
|
+
* and its config/validation schema. Prefer the static {@link FORM_FIELD_TYPES}
|
|
3319
|
+
* constant when a round-trip isn't warranted.
|
|
3320
|
+
*/
|
|
2153
3321
|
getFormFieldTypes(options?: RequestOptions): Promise<FormFieldTypeDescriptor[]>;
|
|
3322
|
+
/**
|
|
3323
|
+
* The same request as {@link ContentModule.getFormFieldTypes}, but keeping the
|
|
3324
|
+
* slug rules the response carries alongside the field types — use it when
|
|
3325
|
+
* authoring forms, so the hyphen/underscore split is known before the write.
|
|
3326
|
+
*/
|
|
2154
3327
|
getFormFieldTypeRegistry(options?: RequestOptions): Promise<FormFieldTypeRegistry>;
|
|
2155
3328
|
submitForm(id: string, values: Record<string, unknown>, options?: RequestOptions): Promise<FormSubmissionResult>;
|
|
2156
3329
|
getContentStrings(format?: 'list' | 'export', options?: RequestOptions): Promise<ContentStrings>;
|
|
@@ -2171,48 +3344,149 @@ export interface NavigationModule {
|
|
|
2171
3344
|
getRoutesByType(type: 'cms' | 'collection' | 'product', languageCode?: string, options?: RequestOptions): Promise<RouteEntry[]>;
|
|
2172
3345
|
}
|
|
2173
3346
|
export interface PricingModule {
|
|
3347
|
+
/**
|
|
3348
|
+
* The channel's tax-display STORAGE mode (mirrors
|
|
3349
|
+
* {@link ChannelInfo.pricesIncludeTax}) — which of `price`/`priceWithTax` the
|
|
3350
|
+
* merchant typed in. It is NOT the display decision: use
|
|
3351
|
+
* {@link PricingModule.getTaxDisplayMode} for that. This stays the last-resort
|
|
3352
|
+
* fallback when the mode cannot be resolved.
|
|
3353
|
+
*/
|
|
2174
3354
|
readonly pricesIncludeTax: boolean;
|
|
2175
3355
|
formatPrice(amount: number, currencyCode?: string, locale?: string): string;
|
|
2176
3356
|
formatPriceRange(min: number, max: number, currencyCode?: string, locale?: string): string;
|
|
2177
3357
|
getTierForQuantity(tiers: PriceTier[], quantity: number): PriceTier | null;
|
|
2178
3358
|
computeTierTable(variant: VariantPriceData): TierTableEntry[];
|
|
2179
3359
|
getPriceDisplay(variant: VariantPriceData): PriceDisplay;
|
|
3360
|
+
/**
|
|
3361
|
+
* Pick the net-or-gross figure to display for a variant. Never recomputes
|
|
3362
|
+
* tax — selects the server-authoritative `price`/`priceWithTax` (and the
|
|
3363
|
+
* matching retail field) for the requested mode.
|
|
3364
|
+
*
|
|
3365
|
+
* Omit `mode` to use {@link PricingModule.currentTaxDisplayMode}, i.e. the
|
|
3366
|
+
* mode `getTaxDisplayMode()` last resolved for this shopper. Pass one only to
|
|
3367
|
+
* override — a side-by-side incl./excl. table, or a toggle the shopper drove.
|
|
3368
|
+
*/
|
|
2180
3369
|
selectDisplayPrice(variant: VariantPriceData, mode?: TaxDisplayMode): DisplayPrice;
|
|
3370
|
+
/**
|
|
3371
|
+
* The mode this shopper should see prices in, resolved by the server from the
|
|
3372
|
+
* channel's policy (country list → B2B/trade → channel default →
|
|
3373
|
+
* `pricesIncludeTax`). Call it once per request/session and let
|
|
3374
|
+
* `selectDisplayPrice(variant)` default to it.
|
|
3375
|
+
*
|
|
3376
|
+
* Never throws and never blocks a render: an unreachable or older engine
|
|
3377
|
+
* falls back to the channel storage mode (`pricesIncludeTax ? 'gross' :
|
|
3378
|
+
* 'net'`), which is exactly the pre-policy behaviour. Only a real answer is
|
|
3379
|
+
* cached, so a transient failure does not pin the mode for the session.
|
|
3380
|
+
*
|
|
3381
|
+
* The result is cached per identity (auth token + order scope) and is
|
|
3382
|
+
* re-resolved automatically after a sign-in/out, a `setOrderScope`, or a
|
|
3383
|
+
* `setShippingAddress` — moving the order's country can flip the mode. Pass
|
|
3384
|
+
* `{ refresh: true }` to force a round-trip.
|
|
3385
|
+
*/
|
|
2181
3386
|
getTaxDisplayMode(options?: {
|
|
2182
3387
|
refresh?: boolean;
|
|
2183
3388
|
}): Promise<TaxDisplayMode>;
|
|
3389
|
+
/**
|
|
3390
|
+
* The last mode {@link PricingModule.getTaxDisplayMode} resolved for the
|
|
3391
|
+
* current identity, without a round-trip — the channel storage mode when
|
|
3392
|
+
* nothing has been resolved yet. Synchronous, for render paths.
|
|
3393
|
+
*/
|
|
2184
3394
|
currentTaxDisplayMode(): TaxDisplayMode;
|
|
3395
|
+
/**
|
|
3396
|
+
* Preview the mode for a hypothetical shopper, offline. Mirrors the engine's
|
|
3397
|
+
* precedence rule for a "who sees what" table or an SSR guess before the
|
|
3398
|
+
* first round-trip — `getTaxDisplayMode()` remains the authority, because
|
|
3399
|
+
* only the server knows the shopper's resolved country.
|
|
3400
|
+
*/
|
|
2185
3401
|
resolveTaxDisplayMode(policy: TaxDisplayPolicy, inputs: TaxDisplayInputs): TaxDisplayMode;
|
|
3402
|
+
/**
|
|
3403
|
+
* Read the channel's display policy off `activeChannel.customFields`.
|
|
3404
|
+
* Lenient — an unreadable value degrades to the pre-policy default.
|
|
3405
|
+
*/
|
|
2186
3406
|
parseTaxDisplayPolicy(fields: unknown): TaxDisplayPolicy;
|
|
3407
|
+
/**
|
|
3408
|
+
* Pre-validate the cart against the channel's order minimums. Pass the object
|
|
3409
|
+
* from `getOrderConstraints()` straight through. The server enforces at the
|
|
3410
|
+
* `ArrangingPayment` transition regardless.
|
|
3411
|
+
*/
|
|
2187
3412
|
validateOrderMinimums(order: {
|
|
2188
3413
|
totalWithTax: number;
|
|
2189
3414
|
currencyCode: string;
|
|
2190
3415
|
totalQuantity?: number;
|
|
3416
|
+
/**
|
|
3417
|
+
* Net (tax-exclusive) total, minor units — required for the
|
|
3418
|
+
* `minOrderAmountNet` check. `subTotal` is preferred over `total` because
|
|
3419
|
+
* the server compares line totals, which exclude shipping. Without one of
|
|
3420
|
+
* them the net check is skipped.
|
|
3421
|
+
*/
|
|
2191
3422
|
subTotal?: number;
|
|
2192
3423
|
total?: number;
|
|
2193
3424
|
}, constraints: {
|
|
2194
3425
|
minOrderAmountGross?: number | null;
|
|
2195
3426
|
minOrderAmountNet?: number | null;
|
|
2196
3427
|
minOrderQuantity?: number | null;
|
|
3428
|
+
/** @deprecated Use `minOrderAmountGross`. */
|
|
2197
3429
|
minOrderAmount?: number | null;
|
|
2198
3430
|
}): OrderValidationResult;
|
|
3431
|
+
/**
|
|
3432
|
+
* The quantity ceiling for a variant: `max(0, saleable) + backorderAllowance`.
|
|
3433
|
+
* `null` when the channel hides stock — no ceiling to show, let the server
|
|
3434
|
+
* decide, exactly as before backorders. Clamp quantity steppers to it.
|
|
3435
|
+
*/
|
|
3436
|
+
maxOrderableQuantity(variant: OrderableStockInput): number | null;
|
|
3437
|
+
/**
|
|
3438
|
+
* Whether a variant is orderable only on backorder: nothing saleable, but an
|
|
3439
|
+
* allowance. The signal to label "Backorder" instead of "Out of stock".
|
|
3440
|
+
*/
|
|
3441
|
+
isBackorderOnly(variant: OrderableStockInput): boolean;
|
|
3442
|
+
/**
|
|
3443
|
+
* Units of a cart line stock will not cover — the "N on backorder" hint
|
|
3444
|
+
* before placement, as the server will stamp it. `null` when the channel
|
|
3445
|
+
* hides stock or stock covers the line: show nothing.
|
|
3446
|
+
*/
|
|
3447
|
+
backorderedQuantityForCart(variant: Pick<OrderableStockInput, 'saleable'>, quantity: number): number | null;
|
|
3448
|
+
}
|
|
3449
|
+
/** The two fields the quantity ceiling reads; satisfied by every SDK variant shape. */
|
|
3450
|
+
export interface OrderableStockInput {
|
|
3451
|
+
saleable?: number | null;
|
|
3452
|
+
backorderAllowance?: number | null;
|
|
2199
3453
|
}
|
|
2200
3454
|
export interface MediaModule {
|
|
2201
3455
|
assetUrl(path: string): string;
|
|
3456
|
+
/**
|
|
3457
|
+
* Absolute full-resolution URL for an asset's original `source`. Use for the
|
|
3458
|
+
* gallery main/lightbox image — `Asset.source` arrives as a CDN-relative
|
|
3459
|
+
* storage key and must never be rendered directly. Returns `''` for an asset
|
|
3460
|
+
* with an empty `source`.
|
|
3461
|
+
*/
|
|
2202
3462
|
getFullUrl(asset: Asset): string;
|
|
2203
3463
|
getPresetUrl(asset: Asset, preset: PresetName, format?: 'original' | 'webp'): string;
|
|
2204
3464
|
getResponsiveImageData(asset: Asset, presets?: PresetName[]): ResponsiveImageData;
|
|
2205
3465
|
}
|
|
2206
3466
|
export interface CurrencyModule {
|
|
2207
3467
|
getExchangeRates(): Promise<ExchangeRate[]>;
|
|
3468
|
+
/** Current rate for a single base→target pair, or `null` when unknown. */
|
|
2208
3469
|
getExchangeRate(targetCurrency: string): Promise<ExchangeRate | null>;
|
|
2209
3470
|
convertCurrency(amount: string, fromCurrency: string, toCurrency: string): Promise<ConvertedAmount>;
|
|
3471
|
+
/** Convert from the base currency (EUR) to a target currency. */
|
|
2210
3472
|
convertFromBase(amount: string, targetCurrency: string): Promise<ConvertedAmount>;
|
|
3473
|
+
/** Convert from a source currency to the base currency (EUR). */
|
|
2211
3474
|
convertToBase(amount: string, sourceCurrency: string): Promise<ConvertedAmount>;
|
|
3475
|
+
/** Convert one amount into several currencies in a single roundtrip. */
|
|
2212
3476
|
convertToMultiple(amount: string, fromCurrency: string, toCurrencies: string[]): Promise<BulkConversionResult[]>;
|
|
2213
3477
|
}
|
|
2214
3478
|
export interface CreditModule {
|
|
3479
|
+
/**
|
|
3480
|
+
* Returns the signed-in customer's B2B credit status in the current
|
|
3481
|
+
* channel, or `null` when not signed in, no credit account exists, or the
|
|
3482
|
+
* channel has B2B credit disabled. Soft-enforcement only — display the
|
|
3483
|
+
* `overLimit` / `hasOverdue` flags as warnings; the SDK never blocks checkout.
|
|
3484
|
+
*/
|
|
2215
3485
|
getCreditStatus(options?: RequestOptions): Promise<B2bCreditStatus | null>;
|
|
3486
|
+
/**
|
|
3487
|
+
* Returns the signed-in customer's source-aware payment terms (including local B2B terms), or
|
|
3488
|
+
* `null` when the customer is not signed in or has no payment-terms account in this channel.
|
|
3489
|
+
*/
|
|
2216
3490
|
getPaymentTerms(options?: RequestOptions): Promise<CustomerPaymentTerms | null>;
|
|
2217
3491
|
}
|
|
2218
3492
|
export interface StorefrontClient {
|
|
@@ -2225,13 +3499,20 @@ export interface StorefrontClient {
|
|
|
2225
3499
|
readonly currency: CurrencyModule;
|
|
2226
3500
|
readonly credit: CreditModule;
|
|
2227
3501
|
readonly seo: import('./seo/types.js').SeoModule;
|
|
3502
|
+
/** Platform-managed URL redirects for this channel. */
|
|
2228
3503
|
readonly redirects: import('./redirects/types.js').RedirectStore;
|
|
2229
3504
|
readonly maintenanceMode: boolean;
|
|
2230
3505
|
setLanguage(code: string): void;
|
|
2231
3506
|
getLanguage(): string;
|
|
2232
3507
|
setAuthToken(token: string): void;
|
|
2233
3508
|
clearAuthToken(): void;
|
|
3509
|
+
/**
|
|
3510
|
+
* Change which storefront this client speaks for. Takes effect on the next
|
|
3511
|
+
* request. Pass `null` to stop sending the header entirely (legacy,
|
|
3512
|
+
* unscoped behaviour) — which is not the same as `'CONSUMER'`.
|
|
3513
|
+
*/
|
|
2234
3514
|
setOrderScope(scope: OrderScope | null): void;
|
|
3515
|
+
/** The scope currently sent as `x-order-scope`, or `null` when none is set. */
|
|
2235
3516
|
getOrderScope(): OrderScope | null;
|
|
2236
3517
|
graphql<T = unknown>(query: string, variables?: Record<string, unknown>): Promise<T>;
|
|
2237
3518
|
}
|