@sixtyninecommerce/client 0.24.0 → 0.26.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 +21 -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/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 +92 -0
- package/dist/commerce/products.js.map +1 -1
- package/dist/commerce/queries.d.ts +113 -27
- package/dist/commerce/queries.d.ts.map +1 -1
- package/dist/commerce/queries.js +188 -2
- 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/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 +48 -2
- package/dist/errors.js.map +1 -1
- package/dist/events/envelope.d.ts +60 -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 +14 -1
- 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 +7 -0
- 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 +1163 -0
- 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,32 +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
|
+
*/
|
|
968
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
|
+
*/
|
|
969
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
|
+
*/
|
|
970
1524
|
sort?: {
|
|
971
1525
|
name?: 'ASC' | 'DESC';
|
|
972
1526
|
createdAt?: 'ASC' | 'DESC';
|
|
973
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
|
+
*/
|
|
974
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
|
+
*/
|
|
975
1541
|
enabled?: boolean;
|
|
976
1542
|
}
|
|
1543
|
+
/** Options for `getProductsInCollection` — the search-backed collection listing. */
|
|
977
1544
|
export interface CollectionProductListOptions {
|
|
978
1545
|
take?: number;
|
|
979
1546
|
skip?: number;
|
|
1547
|
+
/** The search backend sorts by `name` or `price` (unlike the products list, which cannot sort by price). */
|
|
980
1548
|
sort?: {
|
|
981
1549
|
name?: 'ASC' | 'DESC';
|
|
982
1550
|
price?: 'ASC' | 'DESC';
|
|
983
1551
|
};
|
|
984
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
|
+
*/
|
|
985
1562
|
export interface CollectionProductSummary {
|
|
986
1563
|
id: string;
|
|
987
1564
|
name: string;
|
|
988
1565
|
slug: string;
|
|
989
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
|
+
*/
|
|
990
1571
|
featuredAsset: Asset | null;
|
|
1572
|
+
/** Exactly one synthesised variant per row (search groups by product). */
|
|
991
1573
|
variants: [CollectionProductVariant];
|
|
992
1574
|
}
|
|
1575
|
+
/** The single synthesised variant on a `CollectionProductSummary`. */
|
|
993
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
|
+
*/
|
|
994
1581
|
id: string;
|
|
995
1582
|
name: string;
|
|
996
1583
|
price: number;
|
|
@@ -1014,15 +1601,35 @@ export interface FavoriteVariant {
|
|
|
1014
1601
|
priceWithTax: number;
|
|
1015
1602
|
currencyCode: string;
|
|
1016
1603
|
stockLevel: string;
|
|
1604
|
+
/** ATP numbers — `null` when the channel does not expose operational stock. */
|
|
1017
1605
|
stockOnHand: number | null;
|
|
1018
1606
|
stockAllocated: number | null;
|
|
1019
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
|
+
*/
|
|
1020
1614
|
incomingStock: number | null;
|
|
1021
1615
|
projectedSaleable: number | null;
|
|
1022
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;
|
|
1023
1629
|
priceListName: string | null;
|
|
1024
1630
|
retailPrice: number | null;
|
|
1025
1631
|
retailPriceWithTax: number | null;
|
|
1632
|
+
/** Tax rate applied to this price in the active channel/zone, e.g. `{ value: 21 }` for 21% VAT. */
|
|
1026
1633
|
taxRateApplied: {
|
|
1027
1634
|
value: number;
|
|
1028
1635
|
} | null;
|
|
@@ -1081,6 +1688,7 @@ export interface PaginatedList<T> {
|
|
|
1081
1688
|
export interface ResolvedContent {
|
|
1082
1689
|
data?: Record<string, unknown>;
|
|
1083
1690
|
item?: Record<string, unknown>;
|
|
1691
|
+
/** Resolved field values keyed by field slug (locale-filtered). */
|
|
1084
1692
|
values?: Record<string, unknown>;
|
|
1085
1693
|
collection?: {
|
|
1086
1694
|
id: string;
|
|
@@ -1096,6 +1704,10 @@ export interface ResolvedContent {
|
|
|
1096
1704
|
path: string;
|
|
1097
1705
|
}>;
|
|
1098
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
|
+
*/
|
|
1099
1711
|
metadata?: Record<string, unknown> | null;
|
|
1100
1712
|
}
|
|
1101
1713
|
export interface SitemapEntry {
|
|
@@ -1104,7 +1716,9 @@ export interface SitemapEntry {
|
|
|
1104
1716
|
title: string | null;
|
|
1105
1717
|
collection_slug: string | null;
|
|
1106
1718
|
updated_at: string;
|
|
1719
|
+
/** Present only for collection landing pages (basePath routes). */
|
|
1107
1720
|
type?: 'collection_page';
|
|
1721
|
+
/** Present only when the request specified a language_code. */
|
|
1108
1722
|
language_code?: string;
|
|
1109
1723
|
}
|
|
1110
1724
|
export interface ContentItemSummary {
|
|
@@ -1116,6 +1730,11 @@ export interface ContentItemSummary {
|
|
|
1116
1730
|
collection_title_field_slug: string | null;
|
|
1117
1731
|
title: string | null;
|
|
1118
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
|
+
*/
|
|
1119
1738
|
export interface ContentSearchQuery {
|
|
1120
1739
|
q?: string;
|
|
1121
1740
|
collectionId?: string;
|
|
@@ -1123,9 +1742,15 @@ export interface ContentSearchQuery {
|
|
|
1123
1742
|
parentId?: string;
|
|
1124
1743
|
limit?: number;
|
|
1125
1744
|
offset?: number;
|
|
1745
|
+
/** Meilisearch sort spec, e.g. `'updated_at:desc'`. */
|
|
1126
1746
|
sort?: string;
|
|
1127
1747
|
languageCode?: string;
|
|
1128
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
|
+
*/
|
|
1129
1754
|
export interface ContentSearchHit {
|
|
1130
1755
|
id: string;
|
|
1131
1756
|
channel_id: string;
|
|
@@ -1167,6 +1792,7 @@ export interface CollectionPageValues {
|
|
|
1167
1792
|
fields: CollectionFieldDefinition[];
|
|
1168
1793
|
values: Record<string, unknown>;
|
|
1169
1794
|
}
|
|
1795
|
+
/** A CMS collection (content type) as returned by `GET /collections`. */
|
|
1170
1796
|
export interface CmsCollection {
|
|
1171
1797
|
id: string;
|
|
1172
1798
|
name: string;
|
|
@@ -1182,6 +1808,11 @@ export interface CmsCollection {
|
|
|
1182
1808
|
export interface CmsCollectionDetail extends CmsCollection {
|
|
1183
1809
|
fields: CollectionFieldDefinition[];
|
|
1184
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
|
+
*/
|
|
1185
1816
|
export interface CmsCollectionItem {
|
|
1186
1817
|
id: string;
|
|
1187
1818
|
collectionId: string;
|
|
@@ -1192,7 +1823,9 @@ export interface CmsCollectionItem {
|
|
|
1192
1823
|
createdAt: string;
|
|
1193
1824
|
updatedAt: string;
|
|
1194
1825
|
values: Record<string, unknown>;
|
|
1826
|
+
/** Per-language slug overrides. Present on single-item reads. */
|
|
1195
1827
|
slug_translations?: Record<string, string>;
|
|
1828
|
+
/** Forward-compat: additional entity fields the CMS may add. */
|
|
1196
1829
|
[key: string]: unknown;
|
|
1197
1830
|
}
|
|
1198
1831
|
export interface CmsCollectionItemList {
|
|
@@ -1200,8 +1833,10 @@ export interface CmsCollectionItemList {
|
|
|
1200
1833
|
total: number;
|
|
1201
1834
|
}
|
|
1202
1835
|
export interface CollectionItemsQuery {
|
|
1836
|
+
/** Filter by parent item; pass `'root'` for top-level items. */
|
|
1203
1837
|
parentId?: string;
|
|
1204
1838
|
slug?: string;
|
|
1839
|
+
/** Full-text search within the collection (Meilisearch-assisted). */
|
|
1205
1840
|
search?: string;
|
|
1206
1841
|
sort?: string;
|
|
1207
1842
|
languageCode?: string;
|
|
@@ -1222,10 +1857,19 @@ export interface FormField {
|
|
|
1222
1857
|
label: string;
|
|
1223
1858
|
type: string;
|
|
1224
1859
|
required: boolean;
|
|
1860
|
+
/** Presentational config (e.g. select option labels). */
|
|
1225
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
|
+
*/
|
|
1226
1869
|
validation: Record<string, unknown>;
|
|
1227
1870
|
position: number;
|
|
1228
1871
|
}
|
|
1872
|
+
/** A form-level translation as emitted by the public projection. */
|
|
1229
1873
|
export interface FormTranslation {
|
|
1230
1874
|
languageCode: string;
|
|
1231
1875
|
title: string;
|
|
@@ -1237,8 +1881,11 @@ export interface FormDefinition {
|
|
|
1237
1881
|
id: string;
|
|
1238
1882
|
name: string;
|
|
1239
1883
|
slug: string;
|
|
1884
|
+
/** Where the storefront should send the visitor after a successful submit. */
|
|
1240
1885
|
redirectUrlOnSuccess: string | null;
|
|
1886
|
+
/** True when the form has internal-notification recipients configured (addresses are never exposed). */
|
|
1241
1887
|
hasNotifications: boolean;
|
|
1888
|
+
/** True when a visitor confirmation email will be sent on submit. */
|
|
1242
1889
|
sendsConfirmation: boolean;
|
|
1243
1890
|
fields: FormField[];
|
|
1244
1891
|
translations: FormTranslation[];
|
|
@@ -1246,6 +1893,12 @@ export interface FormDefinition {
|
|
|
1246
1893
|
submitMethod: string;
|
|
1247
1894
|
submitHeaders: Record<string, string>;
|
|
1248
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
|
+
*/
|
|
1249
1902
|
export interface FormSummary {
|
|
1250
1903
|
id: string;
|
|
1251
1904
|
name: string;
|
|
@@ -1259,8 +1912,11 @@ export interface FormSummary {
|
|
|
1259
1912
|
export interface FormListOptions {
|
|
1260
1913
|
limit?: number;
|
|
1261
1914
|
offset?: number;
|
|
1915
|
+
/** Case-insensitive match against the form name. */
|
|
1262
1916
|
search?: string;
|
|
1917
|
+
/** Sort field; prefix with `-` for descending (name, created_at, updated_at). */
|
|
1263
1918
|
sort?: string;
|
|
1919
|
+
/** Locale for the projected field labels. Defaults to the client language. */
|
|
1264
1920
|
locale?: string;
|
|
1265
1921
|
}
|
|
1266
1922
|
export interface FormListResult {
|
|
@@ -1269,40 +1925,66 @@ export interface FormListResult {
|
|
|
1269
1925
|
total: number;
|
|
1270
1926
|
};
|
|
1271
1927
|
}
|
|
1928
|
+
/** One constraint key a field type honors (see {@link FormFieldTypeDescriptor}). */
|
|
1272
1929
|
export interface FormFieldTypeConstraint {
|
|
1273
1930
|
key: string;
|
|
1274
1931
|
valueType: 'integer' | 'number' | 'string' | 'string[]';
|
|
1275
1932
|
description: string;
|
|
1276
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
|
+
*/
|
|
1277
1939
|
export interface FormFieldTypeDescriptor {
|
|
1278
1940
|
type: string;
|
|
1279
1941
|
label: string;
|
|
1280
1942
|
description: string;
|
|
1943
|
+
/** Shape of the value a submission sends for this field. */
|
|
1281
1944
|
valueType: string;
|
|
1945
|
+
/** Constraint keys honored on submit; resolved from `validation` first, then `config`. */
|
|
1282
1946
|
constraints: FormFieldTypeConstraint[];
|
|
1283
1947
|
notes?: string;
|
|
1284
1948
|
}
|
|
1949
|
+
/** The slug shape one authoring surface enforces (form slug or field slug). */
|
|
1285
1950
|
export interface FormSlugRule {
|
|
1951
|
+
/** Source of the regex the CMS validates against. */
|
|
1286
1952
|
pattern: string;
|
|
1287
1953
|
maxLength: number;
|
|
1288
1954
|
description: string;
|
|
1289
1955
|
validExamples: string[];
|
|
1290
1956
|
invalidExamples: string[];
|
|
1291
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
|
+
*/
|
|
1292
1963
|
export interface FormSlugRules {
|
|
1293
1964
|
form: FormSlugRule;
|
|
1294
1965
|
field: FormSlugRule;
|
|
1295
1966
|
}
|
|
1967
|
+
/** Everything GET /forms/field-types carries: the field types plus the slug rules. */
|
|
1296
1968
|
export interface FormFieldTypeRegistry {
|
|
1297
1969
|
fieldTypes: FormFieldTypeDescriptor[];
|
|
1298
1970
|
slugRules: FormSlugRules;
|
|
1299
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
|
+
*/
|
|
1300
1979
|
export type FormSubmissionResult = {
|
|
1301
1980
|
success: true;
|
|
1981
|
+
/** Stored submission id. */
|
|
1302
1982
|
id: string;
|
|
1983
|
+
/** ISO-8601 creation timestamp. */
|
|
1303
1984
|
createdAt: string;
|
|
1304
1985
|
} | {
|
|
1305
1986
|
success: false;
|
|
1987
|
+
/** Per-field validation errors, in the CMS's field order. */
|
|
1306
1988
|
errors: Array<{
|
|
1307
1989
|
field: string;
|
|
1308
1990
|
code?: string;
|
|
@@ -1343,8 +2025,21 @@ export interface RouteEntry {
|
|
|
1343
2025
|
slug?: string;
|
|
1344
2026
|
updated_at?: string;
|
|
1345
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
|
+
*/
|
|
1346
2035
|
canonical?: boolean;
|
|
1347
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
|
+
*/
|
|
1348
2043
|
export interface ResolvedRoute extends RouteEntry {
|
|
1349
2044
|
readonly cacheTags: readonly string[];
|
|
1350
2045
|
}
|
|
@@ -1372,6 +2067,7 @@ export interface ConvertedAmount {
|
|
|
1372
2067
|
rate: string;
|
|
1373
2068
|
rateDate: string;
|
|
1374
2069
|
}
|
|
2070
|
+
/** One entry of a `convertToMultiple()` result. */
|
|
1375
2071
|
export interface BulkConversionResult {
|
|
1376
2072
|
currency: string;
|
|
1377
2073
|
amount: string;
|
|
@@ -1384,6 +2080,7 @@ export interface PriceDisplay {
|
|
|
1384
2080
|
retailPrice: number | null;
|
|
1385
2081
|
retailPriceWithTax: number | null;
|
|
1386
2082
|
priceListName: string | null;
|
|
2083
|
+
/** Tax rate percentage applied to this price (e.g. `21`), or null if unknown. */
|
|
1387
2084
|
taxRate: number | null;
|
|
1388
2085
|
hasDiscount: boolean;
|
|
1389
2086
|
discountPercentage: number | null;
|
|
@@ -1393,33 +2090,68 @@ export interface TierTableEntry {
|
|
|
1393
2090
|
minQuantity: number;
|
|
1394
2091
|
price: number;
|
|
1395
2092
|
priceWithTax: number;
|
|
2093
|
+
/** Tax rate percentage applied to this tier's price (e.g. `21`), or null if unknown. */
|
|
1396
2094
|
taxRate: number | null;
|
|
1397
2095
|
discountLabel: string | null;
|
|
1398
2096
|
savingsPercentage: number | null;
|
|
1399
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
|
+
*/
|
|
1400
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
|
+
*/
|
|
1401
2110
|
export type TaxDisplayDefault = 'channel' | 'gross' | 'net';
|
|
2111
|
+
/**
|
|
2112
|
+
* B2B override (`Channel.customFields.taxDisplayB2b`). `inherit` leaves trade
|
|
2113
|
+
* accounts on the channel default.
|
|
2114
|
+
*/
|
|
1402
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
|
+
*/
|
|
1403
2121
|
export interface TaxDisplayPolicy {
|
|
1404
2122
|
default: TaxDisplayDefault;
|
|
1405
2123
|
b2b: TaxDisplayB2bMode;
|
|
2124
|
+
/** Upper-case ISO-3166 alpha-2 codes. Empty = the country rule is off. */
|
|
1406
2125
|
countries: readonly string[];
|
|
1407
2126
|
}
|
|
2127
|
+
/** The per-shopper facts `resolveTaxDisplayMode` judges. */
|
|
1408
2128
|
export interface TaxDisplayInputs {
|
|
2129
|
+
/** Member of one of the channel's configured B2B customer groups (`Customer.isB2B`). */
|
|
1409
2130
|
isB2B: boolean;
|
|
2131
|
+
/** The request carries `x-order-scope: trade` — the dealer storefront. */
|
|
1410
2132
|
isTrade: boolean;
|
|
2133
|
+
/** The shopper's country: active order shipping address, else their default one. */
|
|
1411
2134
|
countryCode: string | null;
|
|
2135
|
+
/** `Channel.pricesIncludeTax` — the STORAGE mode, not a display decision. */
|
|
1412
2136
|
pricesIncludeTax: boolean;
|
|
1413
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
|
+
*/
|
|
1414
2142
|
export interface ResolvedTaxDisplay {
|
|
1415
2143
|
stamp: string;
|
|
1416
2144
|
mode: TaxDisplayMode;
|
|
1417
2145
|
}
|
|
1418
2146
|
export interface DisplayPrice {
|
|
2147
|
+
/** The amount to show, in minor units, for the requested mode. */
|
|
1419
2148
|
amount: number;
|
|
2149
|
+
/** The strikethrough/retail amount for the requested mode, or null. */
|
|
1420
2150
|
retailAmount: number | null;
|
|
1421
2151
|
currencyCode: string;
|
|
2152
|
+
/** True when `amount` includes tax (i.e. mode was `gross`). */
|
|
1422
2153
|
isGross: boolean;
|
|
2154
|
+
/** True when a higher retail amount exists for the same mode. */
|
|
1423
2155
|
hasDiscount: boolean;
|
|
1424
2156
|
}
|
|
1425
2157
|
export interface VariantPriceData {
|
|
@@ -1470,6 +2202,11 @@ export interface PropertyConfig {
|
|
|
1470
2202
|
maxLength?: number;
|
|
1471
2203
|
allowedCollectionIds?: string[];
|
|
1472
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
|
+
*/
|
|
1473
2210
|
productFilter?: {
|
|
1474
2211
|
filters?: Array<{
|
|
1475
2212
|
property_slug: string;
|
|
@@ -1506,6 +2243,18 @@ export interface ProductPropertyGroupValues {
|
|
|
1506
2243
|
group: PropertyGroup;
|
|
1507
2244
|
values: PropertyValue[];
|
|
1508
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
|
+
*/
|
|
1509
2258
|
export type ProductPropertyRecord = Record<string, unknown>;
|
|
1510
2259
|
export type PresetName = 'xxs' | 'xs' | 's' | 'm' | 'l' | 'xl';
|
|
1511
2260
|
export interface ResponsiveImageData {
|
|
@@ -1632,6 +2381,13 @@ export interface SubscriptionUpcomingPayment {
|
|
|
1632
2381
|
dueAt: string | null;
|
|
1633
2382
|
amount: number;
|
|
1634
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
|
+
*/
|
|
1635
2391
|
state: string;
|
|
1636
2392
|
nextRetryAt: string | null;
|
|
1637
2393
|
checkoutUrl: string | null;
|
|
@@ -1639,9 +2395,19 @@ export interface SubscriptionUpcomingPayment {
|
|
|
1639
2395
|
export interface SubscriptionPurchasePreview {
|
|
1640
2396
|
planId: string;
|
|
1641
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
|
+
*/
|
|
1642
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
|
+
*/
|
|
1643
2407
|
pricesIncludeTax: boolean;
|
|
2408
|
+
/** `amount` without tax. */
|
|
1644
2409
|
netAmount: number;
|
|
2410
|
+
/** The tax in `amount` for the customer's tax zone. */
|
|
1645
2411
|
taxAmount: number;
|
|
1646
2412
|
currencyCode: string;
|
|
1647
2413
|
firstPaymentAt: string;
|
|
@@ -1662,7 +2428,12 @@ export interface SubscriptionPurchaseInput {
|
|
|
1662
2428
|
provider?: 'mollie' | 'stripe';
|
|
1663
2429
|
mandateId?: string;
|
|
1664
2430
|
returnUrl: string;
|
|
2431
|
+
/** Persist this key for the purchase; reuse it when retrying the same request. */
|
|
1665
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
|
+
*/
|
|
1666
2437
|
expectedAmount?: number;
|
|
1667
2438
|
}
|
|
1668
2439
|
export interface SubscriptionPaymentActionInput {
|
|
@@ -1727,6 +2498,7 @@ export interface CustomerSubscription {
|
|
|
1727
2498
|
cancelAtPeriodEnd: boolean;
|
|
1728
2499
|
createdAt: string;
|
|
1729
2500
|
}
|
|
2501
|
+
/** Customer-safe subscription plan for the storefront catalogue. */
|
|
1730
2502
|
export interface SubscriptionPlanPublic {
|
|
1731
2503
|
firstChargeTiming: SubscriptionFirstChargeTiming;
|
|
1732
2504
|
customerChangeCutoffHours: number;
|
|
@@ -1734,6 +2506,11 @@ export interface SubscriptionPlanPublic {
|
|
|
1734
2506
|
name: string;
|
|
1735
2507
|
description: string | null;
|
|
1736
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
|
+
*/
|
|
1737
2514
|
price: number;
|
|
1738
2515
|
billingInterval: string;
|
|
1739
2516
|
billingIntervalCount: number;
|
|
@@ -1741,17 +2518,21 @@ export interface SubscriptionPlanPublic {
|
|
|
1741
2518
|
minCycles: number | null;
|
|
1742
2519
|
maxCycles: number | null;
|
|
1743
2520
|
}
|
|
2521
|
+
/** Customer-safe view of a stored payment mandate. */
|
|
1744
2522
|
export interface MyPaymentMandate {
|
|
1745
2523
|
id: string;
|
|
1746
2524
|
provider: string;
|
|
1747
2525
|
mandateMethod: string | null;
|
|
2526
|
+
/** 'pending' | 'valid' | 'invalid' | 'revoked' */
|
|
1748
2527
|
mandateStatus: string;
|
|
1749
2528
|
isDefault: boolean;
|
|
1750
2529
|
createdAt: string;
|
|
1751
2530
|
}
|
|
1752
2531
|
export interface SetupPaymentMandateResult {
|
|
1753
2532
|
mandate: MyPaymentMandate;
|
|
2533
|
+
/** Mollie checkout URL to redirect the customer to (null for Stripe). */
|
|
1754
2534
|
checkoutUrl: string | null;
|
|
2535
|
+
/** Stripe SetupIntent client secret (null for Mollie). */
|
|
1755
2536
|
clientSecret: string | null;
|
|
1756
2537
|
}
|
|
1757
2538
|
export type QuoteStatus = 'draft' | 'requested' | 'in_review' | 'approved' | 'declined' | 'expired' | 'converted_to_order' | 'cancelled';
|
|
@@ -1759,16 +2540,62 @@ export interface QuoteLine {
|
|
|
1759
2540
|
id: string;
|
|
1760
2541
|
productVariantId: string;
|
|
1761
2542
|
quantity: number;
|
|
2543
|
+
/** Minor units in the quote currency. Null until a sales rep prices the line. */
|
|
1762
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
|
+
*/
|
|
1763
2549
|
discountType: 'percentage' | 'fixed' | null;
|
|
2550
|
+
/** Discount magnitude (basis points for `percentage`, minor units for `fixed`). */
|
|
1764
2551
|
discountValue: number;
|
|
1765
2552
|
discountLabel: string | null;
|
|
1766
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
|
+
*/
|
|
1767
2563
|
productName?: string | null;
|
|
2564
|
+
/** Variant SKU at read time. `null` under the same conditions as `productName`. */
|
|
1768
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
|
+
*/
|
|
1769
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
|
+
*/
|
|
1770
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
|
+
*/
|
|
1771
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
|
+
*/
|
|
1772
2599
|
lineTotalWithTax?: number | null;
|
|
1773
2600
|
createdAt: string;
|
|
1774
2601
|
updatedAt: string;
|
|
@@ -1783,6 +2610,7 @@ export interface Quote {
|
|
|
1783
2610
|
expiresAt: string | null;
|
|
1784
2611
|
salesRepUserId: string | null;
|
|
1785
2612
|
customerNotes: string | null;
|
|
2613
|
+
/** Set once the quote has been accepted and converted to an Order. */
|
|
1786
2614
|
convertedOrderId: string | null;
|
|
1787
2615
|
lines: QuoteLine[];
|
|
1788
2616
|
createdAt: string;
|
|
@@ -1804,6 +2632,11 @@ export interface CreateQuoteRequestInput {
|
|
|
1804
2632
|
}>;
|
|
1805
2633
|
customerNotes?: string;
|
|
1806
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
|
+
*/
|
|
1807
2640
|
export type CustomerReturnState = 'requested' | 'approved' | 'rejected' | 'cancelled' | 'items_received' | 'settlement_pending' | 'settlement_failed' | 'settled';
|
|
1808
2641
|
export type CustomerReturnSettlementMethod = 'refund' | 'store_credit';
|
|
1809
2642
|
export type CustomerReturnReasonCode = 'damaged' | 'defective' | 'wrong_item' | 'not_as_described' | 'arrived_late' | 'no_longer_needed' | 'order_error' | 'other';
|
|
@@ -1814,26 +2647,40 @@ export interface CustomerReturnLine {
|
|
|
1814
2647
|
productVariantName: string;
|
|
1815
2648
|
productVariantSku: string;
|
|
1816
2649
|
requestedQty: number;
|
|
2650
|
+
/** Null until the merchant approves; 0 means the line was declined. */
|
|
1817
2651
|
approvedQty: number | null;
|
|
2652
|
+
/** Cumulative units received back by the merchant across all receipts. */
|
|
1818
2653
|
receivedQty: number;
|
|
1819
2654
|
restockQty: number;
|
|
1820
2655
|
writeOffQty: number;
|
|
1821
2656
|
reasonCode: CustomerReturnReasonCode;
|
|
1822
2657
|
reasonNote: string | null;
|
|
2658
|
+
/** Snapshot of the order line's prorated unit price incl. tax (minor units). */
|
|
1823
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
|
+
*/
|
|
1824
2665
|
unitPriceWithTaxUnrounded: number | null;
|
|
2666
|
+
/** Refund amount for this line (minor units); null until approved. */
|
|
1825
2667
|
refundAmount: number | null;
|
|
1826
2668
|
}
|
|
2669
|
+
/** A customer-facing return (RMA). All money fields are Int minor units. */
|
|
1827
2670
|
export interface CustomerReturn {
|
|
1828
2671
|
id: string;
|
|
2672
|
+
/** Human-facing RMA code, e.g. RMA-000042. */
|
|
1829
2673
|
code: string;
|
|
1830
2674
|
state: CustomerReturnState;
|
|
1831
2675
|
orderId: string;
|
|
1832
2676
|
orderCode: string;
|
|
1833
2677
|
currencyCode: string;
|
|
1834
2678
|
preferredSettlementMethod: CustomerReturnSettlementMethod | null;
|
|
2679
|
+
/** Settlement method actually used; null until settled. */
|
|
1835
2680
|
settlementMethod: CustomerReturnSettlementMethod | null;
|
|
2681
|
+
/** Shipping refunded on top of line refunds (minor units). */
|
|
1836
2682
|
shippingRefundAmount: number;
|
|
2683
|
+
/** Total actually settled (minor units); null until settled. */
|
|
1837
2684
|
settledAmount: number | null;
|
|
1838
2685
|
customerNote: string | null;
|
|
1839
2686
|
requestedAt: string;
|
|
@@ -1861,39 +2708,74 @@ export interface RequestReturnInput {
|
|
|
1861
2708
|
customerNote?: string;
|
|
1862
2709
|
preferredSettlementMethod?: CustomerReturnSettlementMethod;
|
|
1863
2710
|
}
|
|
2711
|
+
/** Per-order-line returnable quantities for the return-request flow. */
|
|
1864
2712
|
export interface ReturnableOrderLine {
|
|
1865
2713
|
orderLineId: string;
|
|
1866
2714
|
productVariantId: string;
|
|
1867
2715
|
productVariantName: string;
|
|
1868
2716
|
productVariantSku: string;
|
|
2717
|
+
/** Units shipped or delivered for this order line. */
|
|
1869
2718
|
fulfilledQty: number;
|
|
2719
|
+
/** fulfilledQty minus quantities tied up in active returns. */
|
|
1870
2720
|
returnableQty: number;
|
|
2721
|
+
/** The order line's prorated unit price incl. tax (minor units). */
|
|
1871
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
|
+
*/
|
|
1872
2728
|
unitPriceWithTaxUnrounded: number;
|
|
1873
2729
|
}
|
|
1874
2730
|
export interface CustomerReturnEligibility {
|
|
1875
2731
|
orderId: string;
|
|
1876
2732
|
eligible: boolean;
|
|
2733
|
+
/** Why the order is not eligible; null when eligible. */
|
|
1877
2734
|
reason: string | null;
|
|
1878
2735
|
returnWindowEndsAt: string | null;
|
|
2736
|
+
/** Only lines with fulfilled quantity appear here. */
|
|
1879
2737
|
lines: ReturnableOrderLine[];
|
|
1880
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
|
+
*/
|
|
1881
2745
|
export interface B2bCreditStatus {
|
|
1882
2746
|
customerId: string;
|
|
1883
2747
|
currencyCode: string;
|
|
2748
|
+
/** Outstanding invoiced-but-unpaid ledger balance. */
|
|
1884
2749
|
balance: number;
|
|
2750
|
+
/** Total value of placed B2B orders not yet invoiced. */
|
|
1885
2751
|
uninvoicedOrdersTotal: number;
|
|
2752
|
+
/** Total credit exposure (`balance + uninvoicedOrdersTotal`). */
|
|
1886
2753
|
exposure: number;
|
|
2754
|
+
/** Configured credit limit; `null` when no limit is set. */
|
|
1887
2755
|
creditLimit: number | null;
|
|
2756
|
+
/** Remaining headroom (`creditLimit - exposure`); `null` when no limit is set. */
|
|
1888
2757
|
available: number | null;
|
|
1889
2758
|
overdueInvoiceCount: number;
|
|
1890
2759
|
overLimit: boolean;
|
|
1891
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
|
+
*/
|
|
1892
2767
|
balanceSource: CreditBalanceSource;
|
|
1893
2768
|
}
|
|
2769
|
+
/** Where a {@link B2bCreditStatus.balanceSource} balance was sourced from. */
|
|
1894
2770
|
export type CreditBalanceSource = 'LOCAL_LEDGER' | 'ERP_LIVE' | 'ERP_UNLINKED';
|
|
2771
|
+
/** How reliably the source payment condition could be interpreted. */
|
|
1895
2772
|
export type PaymentTermsClassification = 'SINGLE_DUE_DATE' | 'COMPLEX' | 'UNRESOLVED' | 'UNASSIGNED' | 'CONFLICT';
|
|
2773
|
+
/** Assignment and freshness state for externally managed customer payment terms. */
|
|
1896
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
|
+
*/
|
|
1897
2779
|
export interface CustomerPaymentTerms {
|
|
1898
2780
|
customerId: string | null;
|
|
1899
2781
|
source: string;
|
|
@@ -1914,15 +2796,25 @@ export interface CustomerPaymentTerms {
|
|
|
1914
2796
|
syncedAt: string | null;
|
|
1915
2797
|
error: string | null;
|
|
1916
2798
|
}
|
|
2799
|
+
/** Payment terms frozen on an order at acceptance, including later remote confirmation metadata. */
|
|
1917
2800
|
export interface OrderPaymentTermsSnapshot extends Omit<CustomerPaymentTerms, 'customerId'> {
|
|
1918
2801
|
resolvedAt: string;
|
|
1919
2802
|
remoteConditionCode: string | null;
|
|
1920
2803
|
remoteConfirmedAt: string | null;
|
|
2804
|
+
/** True after the ERP confirms a different condition than the accepted snapshot. */
|
|
1921
2805
|
remoteMismatch: boolean;
|
|
1922
2806
|
}
|
|
2807
|
+
/** Assignment and freshness state for Exact-managed customer delivery terms. */
|
|
1923
2808
|
export type DeliveryTermsStatus = 'ASSIGNED' | 'UNASSIGNED' | 'UNRESOLVED' | 'STALE' | 'CONFLICT';
|
|
2809
|
+
/** Exact's account-level partial-delivery policy, exposed as operational guidance. */
|
|
1924
2810
|
export type DeliveryAdvice = 'PARTIAL_ALLOWED' | 'COMPLETE_ORDER' | 'PARTIAL_WITHOUT_BACKORDER' | 'UNKNOWN';
|
|
2811
|
+
/** Why the placed order uses its selected shipping method. */
|
|
1925
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
|
+
*/
|
|
1926
2818
|
export interface CustomerDeliveryTerms {
|
|
1927
2819
|
customerId: string | null;
|
|
1928
2820
|
source: string;
|
|
@@ -1935,18 +2827,22 @@ export interface CustomerDeliveryTerms {
|
|
|
1935
2827
|
preferredShippingMethodCode: string | null;
|
|
1936
2828
|
preferredShippingMethodName: string | null;
|
|
1937
2829
|
preferredShippingMethodAvailable: boolean;
|
|
2830
|
+
/** Active platform mappings that may be selected as deliberate overrides. */
|
|
1938
2831
|
eligibleShippingMethodIds: string[];
|
|
1939
2832
|
incotermStatus: DeliveryTermsStatus;
|
|
1940
2833
|
incotermCode: string | null;
|
|
1941
2834
|
incotermVersion: number | null;
|
|
1942
2835
|
incotermAddress: string | null;
|
|
1943
2836
|
incotermDescription: string | null;
|
|
2837
|
+
/** Exact dispatch lead time in days; this is not a promised arrival date. */
|
|
1944
2838
|
shippingLeadDays: number | null;
|
|
1945
2839
|
deliveryAdvice: DeliveryAdvice | null;
|
|
1946
2840
|
stale: boolean;
|
|
1947
2841
|
syncedAt: string | null;
|
|
2842
|
+
/** Customer-safe warning; raw synchronization errors remain Admin-only. */
|
|
1948
2843
|
warning: string | null;
|
|
1949
2844
|
}
|
|
2845
|
+
/** Delivery terms frozen on an order at acceptance, plus later Exact readback metadata. */
|
|
1950
2846
|
export interface OrderDeliveryTermsSnapshot {
|
|
1951
2847
|
source: string;
|
|
1952
2848
|
managedExternally: boolean;
|
|
@@ -1961,7 +2857,9 @@ export interface OrderDeliveryTermsSnapshot {
|
|
|
1961
2857
|
platformShippingMethodCode: string | null;
|
|
1962
2858
|
platformShippingMethodName: string | null;
|
|
1963
2859
|
platformShippingMethodDescription: string | null;
|
|
2860
|
+
/** Accepted platform shipping quote in order-currency minor units. */
|
|
1964
2861
|
platformShippingPrice: number | null;
|
|
2862
|
+
/** Accepted platform shipping quote including tax, in order-currency minor units. */
|
|
1965
2863
|
platformShippingPriceWithTax: number | null;
|
|
1966
2864
|
preferredShippingMethodId: string | null;
|
|
1967
2865
|
incotermStatus: DeliveryTermsStatus;
|
|
@@ -1982,6 +2880,7 @@ export interface OrderDeliveryTermsSnapshot {
|
|
|
1982
2880
|
remoteIncotermAddress: string | null;
|
|
1983
2881
|
remoteDeliveryDate: string | null;
|
|
1984
2882
|
remoteConfirmedAt: string | null;
|
|
2883
|
+
/** True after Exact confirms delivery fields that differ from the accepted snapshot. */
|
|
1985
2884
|
remoteMismatch: boolean;
|
|
1986
2885
|
}
|
|
1987
2886
|
export interface VatValidationResult {
|
|
@@ -2014,6 +2913,7 @@ export interface DropOffPoint {
|
|
|
2014
2913
|
availableDays: number[] | null;
|
|
2015
2914
|
cutOffTime: string | null;
|
|
2016
2915
|
carrierId: number | null;
|
|
2916
|
+
/** Distance from the postal code, in metres. */
|
|
2017
2917
|
distance: number | null;
|
|
2018
2918
|
}
|
|
2019
2919
|
export interface DeliveryOptionsInput {
|
|
@@ -2030,10 +2930,12 @@ export interface DeliveryTimeFrame {
|
|
|
2030
2930
|
start: string;
|
|
2031
2931
|
end: string;
|
|
2032
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. */
|
|
2033
2934
|
price: {
|
|
2034
2935
|
amount: number;
|
|
2035
2936
|
currency: string;
|
|
2036
2937
|
} | null;
|
|
2938
|
+
/** Carrier delivery type of this window (MyParcel: 1 morning, 2 evening, 3 standard, 4 pickup). */
|
|
2037
2939
|
deliveryType: number | null;
|
|
2038
2940
|
}
|
|
2039
2941
|
export interface DeliveryOption {
|
|
@@ -2045,14 +2947,21 @@ export interface PickupLocationAddress {
|
|
|
2045
2947
|
number: string;
|
|
2046
2948
|
postalCode: string;
|
|
2047
2949
|
city: string;
|
|
2950
|
+
/** ISO 3166-1 alpha-2 country code. */
|
|
2048
2951
|
countryCode: string;
|
|
2049
2952
|
region?: string;
|
|
2050
2953
|
}
|
|
2051
2954
|
export interface PickupLocationOpeningHours {
|
|
2955
|
+
/** 0 = Sunday ... 6 = Saturday. */
|
|
2052
2956
|
weekday: number;
|
|
2957
|
+
/** `HH:MM` (24-hour). */
|
|
2053
2958
|
open: string;
|
|
2054
2959
|
close: string;
|
|
2055
2960
|
}
|
|
2961
|
+
/**
|
|
2962
|
+
* Carrier-agnostic pickup location. Currently MyParcel-backed; future
|
|
2963
|
+
* providers (Sendcloud, Hendriks) implement the same shape.
|
|
2964
|
+
*/
|
|
2056
2965
|
export interface PickupLocation {
|
|
2057
2966
|
provider: string;
|
|
2058
2967
|
carrier: number;
|
|
@@ -2060,9 +2969,11 @@ export interface PickupLocation {
|
|
|
2060
2969
|
name: string;
|
|
2061
2970
|
address: PickupLocationAddress;
|
|
2062
2971
|
openingHours?: PickupLocationOpeningHours[];
|
|
2972
|
+
/** Carrier-specific extras. */
|
|
2063
2973
|
details?: Record<string, unknown>;
|
|
2064
2974
|
}
|
|
2065
2975
|
export interface PickupLocationSearchInput {
|
|
2976
|
+
/** ISO 3166-1 alpha-2 country code. */
|
|
2066
2977
|
countryCode: string;
|
|
2067
2978
|
postalCode: string;
|
|
2068
2979
|
carrierId: number;
|
|
@@ -2071,6 +2982,7 @@ export interface PickupLocationSearchInput {
|
|
|
2071
2982
|
number?: string;
|
|
2072
2983
|
latitude?: number;
|
|
2073
2984
|
longitude?: number;
|
|
2985
|
+
/** Search radius in metres. */
|
|
2074
2986
|
distance?: number;
|
|
2075
2987
|
}
|
|
2076
2988
|
export interface ShipmentTrackingHistoryEntry {
|
|
@@ -2092,17 +3004,24 @@ export interface CommerceModule {
|
|
|
2092
3004
|
getProductById(id: string, options?: RequestOptions): Promise<Product>;
|
|
2093
3005
|
getProducts(listOptions?: ProductListOptions, options?: RequestOptions): Promise<PaginatedList<ProductSummary>>;
|
|
2094
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
|
+
*/
|
|
2095
3012
|
getProductsInCollectionById(collectionId: string, listOptions?: CollectionProductListOptions, options?: RequestOptions): Promise<PaginatedList<CollectionProductSummary>>;
|
|
2096
3013
|
getFacets(options?: RequestOptions): Promise<Facet[]>;
|
|
2097
3014
|
searchProducts(input: SearchInput, options?: RequestOptions): Promise<SearchResult>;
|
|
2098
3015
|
getActiveOrder(): Promise<Order | null>;
|
|
2099
3016
|
addToCart(variantId: string, quantity: number): Promise<Order>;
|
|
3017
|
+
/** Add several variants in one call (e.g. favourite-box bundles). */
|
|
2100
3018
|
addItemsToCart(items: Array<{
|
|
2101
3019
|
productVariantId: string;
|
|
2102
3020
|
quantity: number;
|
|
2103
3021
|
}>): Promise<Order>;
|
|
2104
3022
|
updateCartLine(lineId: string, quantity: number): Promise<Order>;
|
|
2105
3023
|
removeFromCart(lineId: string): Promise<Order>;
|
|
3024
|
+
/** Remove every line from the active order, leaving an empty cart. */
|
|
2106
3025
|
clearCart(): Promise<Order>;
|
|
2107
3026
|
applyCouponCode(code: string): Promise<Order>;
|
|
2108
3027
|
removeCouponCode(code: string): Promise<Order>;
|
|
@@ -2110,18 +3029,42 @@ export interface CommerceModule {
|
|
|
2110
3029
|
setShippingAddress(input: AddressInput): Promise<Order>;
|
|
2111
3030
|
setBillingAddress(input: AddressInput): Promise<Order>;
|
|
2112
3031
|
getEligibleShippingMethods(): Promise<ShippingMethod[]>;
|
|
3032
|
+
/** Exact-aware delivery defaults for the signed-in customer, or null when unavailable. */
|
|
2113
3033
|
getDeliveryTerms(options?: RequestOptions): Promise<CustomerDeliveryTerms | null>;
|
|
2114
3034
|
setShippingMethod(ids: string[]): Promise<Order>;
|
|
3035
|
+
/** Apply the signed-in customer's currently eligible Exact default shipping method. */
|
|
2115
3036
|
applyPreferredShippingMethod(): Promise<Order>;
|
|
2116
3037
|
getEligiblePaymentMethods(): Promise<PaymentMethod[]>;
|
|
3038
|
+
/** Order minimums on the active channel — display/pre-validation; server enforces. */
|
|
2117
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
|
+
*/
|
|
2118
3048
|
setPaymentIntent(intent: OrderPaymentIntent): Promise<Order>;
|
|
2119
3049
|
transitionToArrangingPayment(): Promise<Order>;
|
|
2120
3050
|
addPayment(input: PaymentInput): Promise<Order>;
|
|
2121
3051
|
createStripePaymentIntent(options?: RequestOptions): Promise<StripePaymentIntentResult>;
|
|
2122
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
|
+
*/
|
|
2123
3060
|
getOrderedMolliePaymentMethods(paymentMethodCode: string, options?: RequestOptions): Promise<OrderedMollieMethod[]>;
|
|
2124
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
|
+
*/
|
|
2125
3068
|
syncMolliePaymentStatus(orderCode: string, options?: RequestOptions): Promise<MollieOrderStatusResult | null>;
|
|
2126
3069
|
login(email: string, password: string): Promise<LoginResult>;
|
|
2127
3070
|
register(input: RegisterInput): Promise<{
|
|
@@ -2129,11 +3072,25 @@ export interface CommerceModule {
|
|
|
2129
3072
|
}>;
|
|
2130
3073
|
logout(): Promise<void>;
|
|
2131
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
|
+
*/
|
|
2132
3080
|
getActiveCustomerPriceLists(options?: RequestOptions): Promise<CustomerPriceList[]>;
|
|
2133
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
|
+
*/
|
|
2134
3087
|
reorder(orderCode: string): Promise<ReorderResult>;
|
|
2135
3088
|
getCollections(listOptions?: CollectionListOptions, options?: RequestOptions): Promise<Collection[]>;
|
|
2136
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
|
+
*/
|
|
2137
3094
|
getCollectionById(id: string, options?: RequestOptions): Promise<CollectionDetail>;
|
|
2138
3095
|
updateCustomer(input: UpdateCustomerInput): Promise<Customer>;
|
|
2139
3096
|
updatePassword(currentPassword: string, newPassword: string): Promise<void>;
|
|
@@ -2163,11 +3120,18 @@ export interface CommerceModule {
|
|
|
2163
3120
|
deleteAddress(id: string): Promise<void>;
|
|
2164
3121
|
getAvailableCountries(): Promise<Country[]>;
|
|
2165
3122
|
getOrderByCode(code: string): Promise<Order>;
|
|
3123
|
+
/** Invoices for one of the signed-in customer's own orders. */
|
|
2166
3124
|
getMyOrderInvoices(orderCode: string): Promise<CustomerInvoice[]>;
|
|
3125
|
+
/** Download one of the signed-in customer's own invoices as a base64 PDF. */
|
|
2167
3126
|
getMyInvoicePdf(invoiceId: string): Promise<CustomerInvoicePdf>;
|
|
2168
3127
|
getActiveChannel(): Promise<ActiveChannel>;
|
|
2169
3128
|
getPropertyGroups(options?: RequestOptions): Promise<PropertyGroup[]>;
|
|
2170
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
|
+
*/
|
|
2171
3135
|
mapProductProperties(groups: ProductPropertyGroupValues[]): ProductPropertyRecord;
|
|
2172
3136
|
getMySavedLists(): Promise<SavedList[]>;
|
|
2173
3137
|
getMySavedList(id: string): Promise<SavedList | null>;
|
|
@@ -2222,30 +3186,91 @@ export interface CommerceModule {
|
|
|
2222
3186
|
replaceMySubscriptionMandate(id: string, input: SubscriptionPaymentActionInput & {
|
|
2223
3187
|
provider: 'mollie' | 'stripe';
|
|
2224
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
|
+
*/
|
|
2225
3193
|
recoverMySubscriptionPayment(id: string, input: SubscriptionPaymentActionInput): Promise<SubscriptionPurchaseResult>;
|
|
2226
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
|
+
*/
|
|
2227
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
|
+
*/
|
|
2228
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
|
+
*/
|
|
2229
3209
|
setupPaymentMandate(input: {
|
|
2230
3210
|
provider: string;
|
|
2231
3211
|
redirectUrl: string;
|
|
2232
3212
|
}): Promise<SetupPaymentMandateResult>;
|
|
3213
|
+
/**
|
|
3214
|
+
* Create a subscription for the active customer against an enabled plan
|
|
3215
|
+
* using one of their valid mandates.
|
|
3216
|
+
*/
|
|
2233
3217
|
createSubscription(planId: string, mandateId: string, requestKey?: string): Promise<CustomerSubscription>;
|
|
3218
|
+
/** Pause an active or trial subscription owned by the active customer. */
|
|
2234
3219
|
pauseMySubscription(id: string, reason?: string): Promise<CustomerSubscription>;
|
|
3220
|
+
/** Resume a paused subscription owned by the active customer. */
|
|
2235
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
|
+
*/
|
|
2236
3226
|
cancelMySubscription(id: string, options?: {
|
|
2237
3227
|
reason?: string;
|
|
2238
3228
|
immediate?: boolean;
|
|
2239
3229
|
}): Promise<CustomerSubscription>;
|
|
3230
|
+
/** Returns the active customer's quotes in the current channel. */
|
|
2240
3231
|
getMyQuotes(options?: QuoteListOptions): Promise<QuoteList>;
|
|
3232
|
+
/** Returns one of the active customer's quotes by id. */
|
|
2241
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
|
+
*/
|
|
2242
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
|
+
*/
|
|
2243
3244
|
acceptQuote(id: string): Promise<Order>;
|
|
3245
|
+
/** Cancels a quote owned by the active customer. */
|
|
2244
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
|
+
*/
|
|
2245
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
|
+
*/
|
|
2246
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
|
+
*/
|
|
2247
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
|
+
*/
|
|
2248
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
|
+
*/
|
|
2249
3274
|
getReturnableLinesForOrder(orderId: string): Promise<CustomerReturnEligibility>;
|
|
2250
3275
|
getMyVatValidationStatus(): Promise<VatValidationResult | null>;
|
|
2251
3276
|
setMyVatNumber(vatNumber: string): Promise<VatValidationResult>;
|
|
@@ -2253,22 +3278,52 @@ export interface CommerceModule {
|
|
|
2253
3278
|
getDropOffPoints(input: DropOffPointInput): Promise<DropOffPoint[]>;
|
|
2254
3279
|
getDeliveryOptions(input: DeliveryOptionsInput): Promise<DeliveryOption[]>;
|
|
2255
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
|
+
*/
|
|
2256
3285
|
findPickupLocations(input: PickupLocationSearchInput): Promise<PickupLocation[]>;
|
|
3286
|
+
/** Persist the customer's chosen pickup location on the active order. */
|
|
2257
3287
|
selectPickupLocation(location: PickupLocation): Promise<Order>;
|
|
3288
|
+
/** Read the pickup location stored on the active order, or `null`. */
|
|
2258
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
|
+
*/
|
|
2259
3299
|
getBranding(options?: RequestOptions): Promise<BrandingInfo>;
|
|
2260
3300
|
}
|
|
2261
3301
|
export interface ContentModule {
|
|
2262
3302
|
resolvePath(path: string, locale?: string, options?: RequestOptions): Promise<ResolvedContent>;
|
|
2263
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
|
+
*/
|
|
2264
3308
|
searchContent(query: ContentSearchQuery, options?: RequestOptions): Promise<ContentSearchResult>;
|
|
2265
3309
|
getAsset(id: string, options?: RequestOptions): Promise<CmsAsset>;
|
|
2266
3310
|
lookupAssets(ids: string[], options?: RequestOptions): Promise<CmsAsset[]>;
|
|
2267
3311
|
lookupVendureAssetDescriptions(vendureAssetIds: string[], options?: RequestOptions): Promise<Record<string, VendureAssetDescriptionTranslation[]>>;
|
|
3312
|
+
/** Discover the channel's forms (public projection). See {@link FormSummary}. */
|
|
2268
3313
|
listForms(options?: FormListOptions & RequestOptions): Promise<FormListResult>;
|
|
2269
3314
|
getForm(id: string, options?: RequestOptions): Promise<FormDefinition>;
|
|
2270
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
|
+
*/
|
|
2271
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
|
+
*/
|
|
2272
3327
|
getFormFieldTypeRegistry(options?: RequestOptions): Promise<FormFieldTypeRegistry>;
|
|
2273
3328
|
submitForm(id: string, values: Record<string, unknown>, options?: RequestOptions): Promise<FormSubmissionResult>;
|
|
2274
3329
|
getContentStrings(format?: 'list' | 'export', options?: RequestOptions): Promise<ContentStrings>;
|
|
@@ -2289,48 +3344,149 @@ export interface NavigationModule {
|
|
|
2289
3344
|
getRoutesByType(type: 'cms' | 'collection' | 'product', languageCode?: string, options?: RequestOptions): Promise<RouteEntry[]>;
|
|
2290
3345
|
}
|
|
2291
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
|
+
*/
|
|
2292
3354
|
readonly pricesIncludeTax: boolean;
|
|
2293
3355
|
formatPrice(amount: number, currencyCode?: string, locale?: string): string;
|
|
2294
3356
|
formatPriceRange(min: number, max: number, currencyCode?: string, locale?: string): string;
|
|
2295
3357
|
getTierForQuantity(tiers: PriceTier[], quantity: number): PriceTier | null;
|
|
2296
3358
|
computeTierTable(variant: VariantPriceData): TierTableEntry[];
|
|
2297
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
|
+
*/
|
|
2298
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
|
+
*/
|
|
2299
3386
|
getTaxDisplayMode(options?: {
|
|
2300
3387
|
refresh?: boolean;
|
|
2301
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
|
+
*/
|
|
2302
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
|
+
*/
|
|
2303
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
|
+
*/
|
|
2304
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
|
+
*/
|
|
2305
3412
|
validateOrderMinimums(order: {
|
|
2306
3413
|
totalWithTax: number;
|
|
2307
3414
|
currencyCode: string;
|
|
2308
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
|
+
*/
|
|
2309
3422
|
subTotal?: number;
|
|
2310
3423
|
total?: number;
|
|
2311
3424
|
}, constraints: {
|
|
2312
3425
|
minOrderAmountGross?: number | null;
|
|
2313
3426
|
minOrderAmountNet?: number | null;
|
|
2314
3427
|
minOrderQuantity?: number | null;
|
|
3428
|
+
/** @deprecated Use `minOrderAmountGross`. */
|
|
2315
3429
|
minOrderAmount?: number | null;
|
|
2316
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;
|
|
2317
3453
|
}
|
|
2318
3454
|
export interface MediaModule {
|
|
2319
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
|
+
*/
|
|
2320
3462
|
getFullUrl(asset: Asset): string;
|
|
2321
3463
|
getPresetUrl(asset: Asset, preset: PresetName, format?: 'original' | 'webp'): string;
|
|
2322
3464
|
getResponsiveImageData(asset: Asset, presets?: PresetName[]): ResponsiveImageData;
|
|
2323
3465
|
}
|
|
2324
3466
|
export interface CurrencyModule {
|
|
2325
3467
|
getExchangeRates(): Promise<ExchangeRate[]>;
|
|
3468
|
+
/** Current rate for a single base→target pair, or `null` when unknown. */
|
|
2326
3469
|
getExchangeRate(targetCurrency: string): Promise<ExchangeRate | null>;
|
|
2327
3470
|
convertCurrency(amount: string, fromCurrency: string, toCurrency: string): Promise<ConvertedAmount>;
|
|
3471
|
+
/** Convert from the base currency (EUR) to a target currency. */
|
|
2328
3472
|
convertFromBase(amount: string, targetCurrency: string): Promise<ConvertedAmount>;
|
|
3473
|
+
/** Convert from a source currency to the base currency (EUR). */
|
|
2329
3474
|
convertToBase(amount: string, sourceCurrency: string): Promise<ConvertedAmount>;
|
|
3475
|
+
/** Convert one amount into several currencies in a single roundtrip. */
|
|
2330
3476
|
convertToMultiple(amount: string, fromCurrency: string, toCurrencies: string[]): Promise<BulkConversionResult[]>;
|
|
2331
3477
|
}
|
|
2332
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
|
+
*/
|
|
2333
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
|
+
*/
|
|
2334
3490
|
getPaymentTerms(options?: RequestOptions): Promise<CustomerPaymentTerms | null>;
|
|
2335
3491
|
}
|
|
2336
3492
|
export interface StorefrontClient {
|
|
@@ -2343,13 +3499,20 @@ export interface StorefrontClient {
|
|
|
2343
3499
|
readonly currency: CurrencyModule;
|
|
2344
3500
|
readonly credit: CreditModule;
|
|
2345
3501
|
readonly seo: import('./seo/types.js').SeoModule;
|
|
3502
|
+
/** Platform-managed URL redirects for this channel. */
|
|
2346
3503
|
readonly redirects: import('./redirects/types.js').RedirectStore;
|
|
2347
3504
|
readonly maintenanceMode: boolean;
|
|
2348
3505
|
setLanguage(code: string): void;
|
|
2349
3506
|
getLanguage(): string;
|
|
2350
3507
|
setAuthToken(token: string): void;
|
|
2351
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
|
+
*/
|
|
2352
3514
|
setOrderScope(scope: OrderScope | null): void;
|
|
3515
|
+
/** The scope currently sent as `x-order-scope`, or `null` when none is set. */
|
|
2353
3516
|
getOrderScope(): OrderScope | null;
|
|
2354
3517
|
graphql<T = unknown>(query: string, variables?: Record<string, unknown>): Promise<T>;
|
|
2355
3518
|
}
|