@asstio-dev/storefront 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -75,6 +75,60 @@ for (const file of product?.files ?? []) console.log(file.filename, fileUrl(site
75
75
  // A variant with hasOwnImages: false inherits: variant.hasOwnImages ? variant.images : product.images
76
76
  ```
77
77
 
78
+ `videoSources` returns `[]` for anything that is not a video, while `mediaUrl`/`pictureSources`/`fileUrl`/`posterUrl`
79
+ throw `MediaUrlError` when the descriptor cannot produce that URL — branch on `kind` before calling.
80
+
81
+ ### Product content
82
+
83
+ `description` is **already sanitized** on the server: render `description.html` as-is — do not sanitize, escape or
84
+ re-parse it — and use `description.text` wherever you need plain text (a meta description, a snippet, an
85
+ `aria-label`). `shortDescription` is plain text. `brand.facet` is set when the brand shares a facet's source, so it
86
+ can link straight to a filtered listing; when it is `null`, render `brand.label` as plain text and never guess a
87
+ filter.
88
+
89
+ `attributes[]` arrives ordered and labelled for display. Branch on `type` (`text` | `html` | `number` | `bool` |
90
+ `list`): a list fills `values`, everything else fills `value`, and `html` fills `html` too — sanitized exactly like
91
+ `description.html`.
92
+
93
+ ```ts
94
+ if (product.description) render(product.description.html); // as-is: sanitized server-side
95
+ for (const a of product.attributes) {
96
+ if (a.type === "html") render(a.html!); // sanitized like description.html
97
+ else if (a.values) render(a.values.join(", ")); // type: "list"
98
+ else render(a.value!); // text | number | bool
99
+ }
100
+ ```
101
+
102
+ `facetKey` and `valueKeys` turn an attribute's values into filter links — `filter[facetKey]=valueKeys[i]`, aligned
103
+ index-for-index with `values` (or carrying the single `value`'s key). `valueKeys` is absent entirely when any one
104
+ value has no key of its own: a list is either fully linkable or not linkable at all.
105
+
106
+ `related[]` holds groups of cards already resolved for this market, and `bundle.components[]` the cards a bundle is
107
+ made of; both leave out anything that no longer exists or is not sold here.
108
+
109
+ ### Search-as-you-type and search-in-facet
110
+
111
+ `/v1/search/suggest` answers three short lists for what the shopper has typed so far: up to 5 product cards
112
+ (matched on the product name), 5 categories (each with the `path` to show above it) and 10 values from the facets
113
+ whose panel is searchable. `q` is required and 1–100 characters — blank, missing or longer is a 400
114
+ (`INVALID_QUERY`), not a truncation the way a listing's `q` is.
115
+
116
+ `/v1/products/facets/{key}` is the search box inside one facet panel: the facet's values with the counts they have
117
+ in the same `filter[…]` context the listing is showing, so a count is what selecting that value would leave. Send
118
+ the panel's own filters with it, and omit `q` for the values as they are.
119
+
120
+ ```ts
121
+ const { data: suggestions } = await storefront.GET("/v1/search/suggest", { params: { query: { q: typed } } });
122
+ const { data: brands } = await storefront.GET("/v1/products/facets/{key}", {
123
+ params: { path: { key: "varumarke" }, query: { q: typed, filter: filterQuery({ kon: ["dam"] }) } },
124
+ });
125
+ ```
126
+
127
+ The endpoint reads the facet's **1000 most common values** and matches `q` against those — label contains,
128
+ case-insensitively, or key prefix — returning at most 50. A facet with more distinct values than that is searched
129
+ over its top 1000; no regular expression ever reaches the search index. `key` has to be a `list` or `swatch` facet:
130
+ an unknown key is `FACET_NOT_FOUND` (404), and a range or toggle facet is `FACET_NOT_SEARCHABLE` (400).
131
+
78
132
  ## Headers
79
133
 
80
134
  Every call the client makes carries these; you never set them by hand.
@@ -115,7 +169,8 @@ Every operation documents `400`, `401`, `403`, `404`, `429` and `503`; the entit
115
169
  Codes you will meet: `SITE_KEY_MISSING`, `SITE_KEY_INVALID`, `SITE_INACTIVE`, `SECRET_KEY_FROM_BROWSER`,
116
170
  `SITE_REGISTRY_WARMING`, `MARKET_UNKNOWN`, `RATE_LIMITED` (with `retryAfterSeconds`, plus a `Retry-After`
117
171
  header), `PRODUCT_NOT_FOUND`, `COLLECTION_NOT_FOUND`, `INVALID_PAGE`, `INVALID_SINCE`, `INVALID_TYPE`,
118
- `INDEX_UNAVAILABLE` (retry — a preview index is being rebuilt), `NOT_FOUND`.
172
+ `INDEX_UNAVAILABLE` (retry — a preview index is being rebuilt), `NOT_FOUND`, `INVALID_QUERY`,
173
+ `FACET_NOT_FOUND`, `FACET_NOT_SEARCHABLE`.
119
174
 
120
175
  `SITE_REGISTRY_WARMING` and `INDEX_UNAVAILABLE` are retries, not bugs in your call.
121
176
 
@@ -140,6 +195,9 @@ form the API reads. `filterQuery()` is a thin helper that joins multi-select val
140
195
  `/v1/sitemap` takes `type` (`product` | `collection`), `since` (ISO-8601, inclusive), `page` and `pageSize`
141
196
  (max 1000, default 500).
142
197
 
198
+ `/v1/search/suggest` takes `q` only, and `/v1/products/facets/{key}` takes `q` plus the same `filter` object as a
199
+ listing — both are described under [Search-as-you-type and search-in-facet](#search-as-you-type-and-search-in-facet).
200
+
143
201
  ## Caching
144
202
 
145
203
  Read responses carry an `ETag` and `Vary: X-Site-Key, X-Market, Accept-Language` — the answer depends on
package/dist/schema.d.ts CHANGED
@@ -153,6 +153,23 @@ export interface paths {
153
153
  patch?: never;
154
154
  trace?: never;
155
155
  };
156
+ "/v1/products/facets/{key}": {
157
+ parameters: {
158
+ query?: never;
159
+ header?: never;
160
+ path?: never;
161
+ cookie?: never;
162
+ };
163
+ /** Search within a facet: values whose label matches q, counted in this request's filter[...] context (spelled as on /products). Free text and collections are not applied. */
164
+ get: operations["SearchFacetValues"];
165
+ put?: never;
166
+ post?: never;
167
+ delete?: never;
168
+ options?: never;
169
+ head?: never;
170
+ patch?: never;
171
+ trace?: never;
172
+ };
156
173
  "/v1/products/{slugOrId}": {
157
174
  parameters: {
158
175
  query?: never;
@@ -187,6 +204,23 @@ export interface paths {
187
204
  patch?: never;
188
205
  trace?: never;
189
206
  };
207
+ "/v1/search/suggest": {
208
+ parameters: {
209
+ query?: never;
210
+ header?: never;
211
+ path?: never;
212
+ cookie?: never;
213
+ };
214
+ /** Search-as-you-type: products by name prefix, categories and facet values whose label starts with q. Market, assortment and language as /products. */
215
+ get: operations["Suggest"];
216
+ put?: never;
217
+ post?: never;
218
+ delete?: never;
219
+ options?: never;
220
+ head?: never;
221
+ patch?: never;
222
+ trace?: never;
223
+ };
190
224
  "/v1/site": {
191
225
  parameters: {
192
226
  query?: never;
@@ -235,6 +269,27 @@ export interface components {
235
269
  label: string;
236
270
  value: string;
237
271
  };
272
+ AttributeDto: {
273
+ facetKey: null | string;
274
+ html: null | string;
275
+ key: string;
276
+ label: string;
277
+ type: string;
278
+ value: null | string;
279
+ valueKeys: string[] | null;
280
+ values: string[] | null;
281
+ };
282
+ BrandDto: {
283
+ facet: null | components["schemas"]["FacetLinkDto"];
284
+ label: string;
285
+ };
286
+ BundleComponentDto: {
287
+ product: components["schemas"]["ProductCardDto"];
288
+ quantity: string;
289
+ };
290
+ BundleDto: {
291
+ components: components["schemas"]["BundleComponentDto"][];
292
+ };
238
293
  CartDto: {
239
294
  currency: string;
240
295
  grandTotalInc: string;
@@ -251,10 +306,22 @@ export interface components {
251
306
  id: string;
252
307
  image: null | components["schemas"]["MediaDescriptorDto"];
253
308
  price: components["schemas"]["PriceDto"];
254
- productId: string;
309
+ product: components["schemas"]["CartLineProductDto"];
255
310
  /** Format: int32 */
256
311
  quantity: number | string;
257
312
  sku: string;
313
+ variant: components["schemas"]["CartLineVariantDto"];
314
+ };
315
+ CartLineProductDto: {
316
+ id: string;
317
+ name: string;
318
+ slug: string;
319
+ };
320
+ CartLineVariantDto: {
321
+ id: string;
322
+ selectedOptions: {
323
+ [key: string]: string;
324
+ };
258
325
  };
259
326
  CategoryNodeDto: {
260
327
  children: components["schemas"]["CategoryNodeDto"][];
@@ -298,6 +365,10 @@ export interface components {
298
365
  slug: string;
299
366
  url: string;
300
367
  };
368
+ DescriptionDto: {
369
+ html: string;
370
+ text: string;
371
+ };
301
372
  FacetDto: {
302
373
  key: string;
303
374
  label: string;
@@ -308,6 +379,10 @@ export interface components {
308
379
  type: string;
309
380
  values: components["schemas"]["FacetValueDto"][];
310
381
  };
382
+ FacetLinkDto: {
383
+ key: string;
384
+ valueKey: string;
385
+ };
311
386
  FacetValueDto: {
312
387
  children: components["schemas"]["FacetValueDto"][] | null;
313
388
  /** Format: int64 */
@@ -318,6 +393,10 @@ export interface components {
318
393
  selected: boolean;
319
394
  swatch: null | components["schemas"]["SwatchDto"];
320
395
  };
396
+ FacetValuesResponse: {
397
+ facet: string;
398
+ values: components["schemas"]["FacetValueDto"][];
399
+ };
321
400
  ListingResponse: {
322
401
  appliedFilters: components["schemas"]["AppliedFilterDto"][];
323
402
  facets: components["schemas"]["FacetDto"][];
@@ -414,6 +493,7 @@ export interface components {
414
493
  vatRate: string;
415
494
  };
416
495
  ProductCardDto: {
496
+ brand: null | components["schemas"]["BrandDto"];
417
497
  collections: string[];
418
498
  id: string;
419
499
  image: null | components["schemas"]["MediaDescriptorDto"];
@@ -421,6 +501,7 @@ export interface components {
421
501
  name: string;
422
502
  price: null | components["schemas"]["PriceDto"];
423
503
  priceVaries: boolean;
504
+ shortDescription: null | string;
424
505
  sku: string;
425
506
  slug: string;
426
507
  /** Format: date-time */
@@ -431,8 +512,12 @@ export interface components {
431
512
  alternateUrls: {
432
513
  [key: string]: string;
433
514
  };
515
+ attributes: components["schemas"]["AttributeDto"][];
516
+ brand: null | components["schemas"]["BrandDto"];
517
+ bundle: null | components["schemas"]["BundleDto"];
434
518
  categories: components["schemas"]["CategoryRefDto"][];
435
519
  collections: components["schemas"]["CollectionRefDto"][];
520
+ description: null | components["schemas"]["DescriptionDto"];
436
521
  files: components["schemas"]["MediaDescriptorDto"][];
437
522
  id: string;
438
523
  image: null | components["schemas"]["MediaDescriptorDto"];
@@ -441,7 +526,9 @@ export interface components {
441
526
  name: string;
442
527
  options: components["schemas"]["OptionDto"][];
443
528
  redirectTo: null | string;
529
+ related: components["schemas"]["RelatedGroupDto"][];
444
530
  seo: components["schemas"]["SeoDto"];
531
+ shortDescription: null | string;
445
532
  sku: string;
446
533
  slug: string;
447
534
  /** Format: date-time */
@@ -457,12 +544,18 @@ export interface components {
457
544
  min: string;
458
545
  mode: string;
459
546
  selected: null | components["schemas"]["RangeSelectionDto"];
547
+ step: null | string;
460
548
  unit: null | string;
461
549
  };
462
550
  RangeSelectionDto: {
463
551
  max: null | string;
464
552
  min: null | string;
465
553
  };
554
+ RelatedGroupDto: {
555
+ key: string;
556
+ label: string;
557
+ products: components["schemas"]["ProductCardDto"][];
558
+ };
466
559
  SeoDto: {
467
560
  description: null | string;
468
561
  title: string;
@@ -532,6 +625,22 @@ export interface components {
532
625
  /** @description Link to this code's documentation. */
533
626
  type?: string;
534
627
  };
628
+ SuggestCategoryDto: {
629
+ id: string;
630
+ name: string;
631
+ path: string[];
632
+ };
633
+ SuggestFacetValueDto: {
634
+ facet: string;
635
+ key: string;
636
+ label: string;
637
+ };
638
+ SuggestResponse: {
639
+ categories: components["schemas"]["SuggestCategoryDto"][];
640
+ facetValues: components["schemas"]["SuggestFacetValueDto"][];
641
+ products: components["schemas"]["ProductCardDto"][];
642
+ query: string;
643
+ };
535
644
  SwatchDto: {
536
645
  color: null | string;
537
646
  image: null | components["schemas"]["MediaDescriptorDto"];
@@ -1630,6 +1739,96 @@ export interface operations {
1630
1739
  };
1631
1740
  };
1632
1741
  };
1742
+ SearchFacetValues: {
1743
+ parameters: {
1744
+ query?: {
1745
+ /** @description Narrows to the values whose label contains q (case-insensitively) or whose key starts with it. Omit for the facet's values as they are. Matched against the 1000 most common values of the facet, in this API — at most 50 are returned. Present but blank is a 400 (INVALID_QUERY). */
1746
+ q?: string;
1747
+ /** @description The filter context the values are counted in, sent as filter[key]=value exactly as on /products: a count is what selecting that value would leave. This facet's own selection does not narrow it (the counts are disjunctive), and a key this site has no facet for is dropped silently. */
1748
+ filter?: {
1749
+ [key: string]: string;
1750
+ };
1751
+ };
1752
+ header: {
1753
+ /** @description Publishable, preview or secret site key. Required on every request; secret keys are server-side only. */
1754
+ "X-Site-Key": string;
1755
+ /** @description Market code (e.g. "se"). Omit for the site's default market. */
1756
+ "X-Market"?: string;
1757
+ /** @description BCP-47 language tag. Omit to use the market's language. */
1758
+ "Accept-Language"?: string;
1759
+ };
1760
+ path: {
1761
+ key: string;
1762
+ };
1763
+ cookie?: never;
1764
+ };
1765
+ requestBody?: never;
1766
+ responses: {
1767
+ /** @description OK */
1768
+ 200: {
1769
+ headers: {
1770
+ [name: string]: unknown;
1771
+ };
1772
+ content: {
1773
+ "application/json": components["schemas"]["FacetValuesResponse"];
1774
+ };
1775
+ };
1776
+ /** @description problem+json. MARKET_UNKNOWN (no such market on this site), INVALID_PAGE, or INVALID_QUERY (q present but blank, or longer than 100 characters), or FACET_NOT_SEARCHABLE (the facet exists but has no list of values to search in: a range, a toggle or a tree). */
1777
+ 400: {
1778
+ headers: {
1779
+ [name: string]: unknown;
1780
+ };
1781
+ content: {
1782
+ "application/problem+json": components["schemas"]["StorefrontProblem"];
1783
+ };
1784
+ };
1785
+ /** @description problem+json. SITE_KEY_MISSING or SITE_KEY_INVALID. */
1786
+ 401: {
1787
+ headers: {
1788
+ [name: string]: unknown;
1789
+ };
1790
+ content: {
1791
+ "application/problem+json": components["schemas"]["StorefrontProblem"];
1792
+ };
1793
+ };
1794
+ /** @description problem+json. SECRET_KEY_FROM_BROWSER: a secret key was sent from a browser. */
1795
+ 403: {
1796
+ headers: {
1797
+ [name: string]: unknown;
1798
+ };
1799
+ content: {
1800
+ "application/problem+json": components["schemas"]["StorefrontProblem"];
1801
+ };
1802
+ };
1803
+ /** @description problem+json. FACET_NOT_FOUND, or SITE_INACTIVE when the site itself is not live. */
1804
+ 404: {
1805
+ headers: {
1806
+ [name: string]: unknown;
1807
+ };
1808
+ content: {
1809
+ "application/problem+json": components["schemas"]["StorefrontProblem"];
1810
+ };
1811
+ };
1812
+ /** @description problem+json. RATE_LIMITED; retryAfterSeconds and the Retry-After header say how long to wait. */
1813
+ 429: {
1814
+ headers: {
1815
+ [name: string]: unknown;
1816
+ };
1817
+ content: {
1818
+ "application/problem+json": components["schemas"]["StorefrontProblem"];
1819
+ };
1820
+ };
1821
+ /** @description problem+json. SITE_REGISTRY_WARMING or INDEX_UNAVAILABLE — retry, the request was not wrong. */
1822
+ 503: {
1823
+ headers: {
1824
+ [name: string]: unknown;
1825
+ };
1826
+ content: {
1827
+ "application/problem+json": components["schemas"]["StorefrontProblem"];
1828
+ };
1829
+ };
1830
+ };
1831
+ };
1633
1832
  GetProduct: {
1634
1833
  parameters: {
1635
1834
  query?: never;
@@ -1805,6 +2004,90 @@ export interface operations {
1805
2004
  };
1806
2005
  };
1807
2006
  };
2007
+ Suggest: {
2008
+ parameters: {
2009
+ query: {
2010
+ /** @description What the shopper has typed so far, 1–100 characters. Blank, missing or longer is a 400 (INVALID_QUERY) — unlike a listing's q, which is truncated. */
2011
+ q: string;
2012
+ };
2013
+ header: {
2014
+ /** @description Publishable, preview or secret site key. Required on every request; secret keys are server-side only. */
2015
+ "X-Site-Key": string;
2016
+ /** @description Market code (e.g. "se"). Omit for the site's default market. */
2017
+ "X-Market"?: string;
2018
+ /** @description BCP-47 language tag. Omit to use the market's language. */
2019
+ "Accept-Language"?: string;
2020
+ };
2021
+ path?: never;
2022
+ cookie?: never;
2023
+ };
2024
+ requestBody?: never;
2025
+ responses: {
2026
+ /** @description OK */
2027
+ 200: {
2028
+ headers: {
2029
+ [name: string]: unknown;
2030
+ };
2031
+ content: {
2032
+ "application/json": components["schemas"]["SuggestResponse"];
2033
+ };
2034
+ };
2035
+ /** @description problem+json. MARKET_UNKNOWN (no such market on this site), INVALID_PAGE, or INVALID_QUERY (q missing, blank or longer than 100 characters). */
2036
+ 400: {
2037
+ headers: {
2038
+ [name: string]: unknown;
2039
+ };
2040
+ content: {
2041
+ "application/problem+json": components["schemas"]["StorefrontProblem"];
2042
+ };
2043
+ };
2044
+ /** @description problem+json. SITE_KEY_MISSING or SITE_KEY_INVALID. */
2045
+ 401: {
2046
+ headers: {
2047
+ [name: string]: unknown;
2048
+ };
2049
+ content: {
2050
+ "application/problem+json": components["schemas"]["StorefrontProblem"];
2051
+ };
2052
+ };
2053
+ /** @description problem+json. SECRET_KEY_FROM_BROWSER: a secret key was sent from a browser. */
2054
+ 403: {
2055
+ headers: {
2056
+ [name: string]: unknown;
2057
+ };
2058
+ content: {
2059
+ "application/problem+json": components["schemas"]["StorefrontProblem"];
2060
+ };
2061
+ };
2062
+ /** @description problem+json. SITE_INACTIVE, or NOT_FOUND for an unrouted path. */
2063
+ 404: {
2064
+ headers: {
2065
+ [name: string]: unknown;
2066
+ };
2067
+ content: {
2068
+ "application/problem+json": components["schemas"]["StorefrontProblem"];
2069
+ };
2070
+ };
2071
+ /** @description problem+json. RATE_LIMITED; retryAfterSeconds and the Retry-After header say how long to wait. */
2072
+ 429: {
2073
+ headers: {
2074
+ [name: string]: unknown;
2075
+ };
2076
+ content: {
2077
+ "application/problem+json": components["schemas"]["StorefrontProblem"];
2078
+ };
2079
+ };
2080
+ /** @description problem+json. SITE_REGISTRY_WARMING or INDEX_UNAVAILABLE — retry, the request was not wrong. */
2081
+ 503: {
2082
+ headers: {
2083
+ [name: string]: unknown;
2084
+ };
2085
+ content: {
2086
+ "application/problem+json": components["schemas"]["StorefrontProblem"];
2087
+ };
2088
+ };
2089
+ };
2090
+ };
1808
2091
  GetSite: {
1809
2092
  parameters: {
1810
2093
  query?: never;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asstio-dev/storefront",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "Typed client for the Asstio Storefront API (generated from OpenAPI).",
5
5
  "repository": {
6
6
  "type": "git",
package/src/schema.d.ts CHANGED
@@ -153,6 +153,23 @@ export interface paths {
153
153
  patch?: never;
154
154
  trace?: never;
155
155
  };
156
+ "/v1/products/facets/{key}": {
157
+ parameters: {
158
+ query?: never;
159
+ header?: never;
160
+ path?: never;
161
+ cookie?: never;
162
+ };
163
+ /** Search within a facet: values whose label matches q, counted in this request's filter[...] context (spelled as on /products). Free text and collections are not applied. */
164
+ get: operations["SearchFacetValues"];
165
+ put?: never;
166
+ post?: never;
167
+ delete?: never;
168
+ options?: never;
169
+ head?: never;
170
+ patch?: never;
171
+ trace?: never;
172
+ };
156
173
  "/v1/products/{slugOrId}": {
157
174
  parameters: {
158
175
  query?: never;
@@ -187,6 +204,23 @@ export interface paths {
187
204
  patch?: never;
188
205
  trace?: never;
189
206
  };
207
+ "/v1/search/suggest": {
208
+ parameters: {
209
+ query?: never;
210
+ header?: never;
211
+ path?: never;
212
+ cookie?: never;
213
+ };
214
+ /** Search-as-you-type: products by name prefix, categories and facet values whose label starts with q. Market, assortment and language as /products. */
215
+ get: operations["Suggest"];
216
+ put?: never;
217
+ post?: never;
218
+ delete?: never;
219
+ options?: never;
220
+ head?: never;
221
+ patch?: never;
222
+ trace?: never;
223
+ };
190
224
  "/v1/site": {
191
225
  parameters: {
192
226
  query?: never;
@@ -235,6 +269,27 @@ export interface components {
235
269
  label: string;
236
270
  value: string;
237
271
  };
272
+ AttributeDto: {
273
+ facetKey: null | string;
274
+ html: null | string;
275
+ key: string;
276
+ label: string;
277
+ type: string;
278
+ value: null | string;
279
+ valueKeys: string[] | null;
280
+ values: string[] | null;
281
+ };
282
+ BrandDto: {
283
+ facet: null | components["schemas"]["FacetLinkDto"];
284
+ label: string;
285
+ };
286
+ BundleComponentDto: {
287
+ product: components["schemas"]["ProductCardDto"];
288
+ quantity: string;
289
+ };
290
+ BundleDto: {
291
+ components: components["schemas"]["BundleComponentDto"][];
292
+ };
238
293
  CartDto: {
239
294
  currency: string;
240
295
  grandTotalInc: string;
@@ -251,10 +306,22 @@ export interface components {
251
306
  id: string;
252
307
  image: null | components["schemas"]["MediaDescriptorDto"];
253
308
  price: components["schemas"]["PriceDto"];
254
- productId: string;
309
+ product: components["schemas"]["CartLineProductDto"];
255
310
  /** Format: int32 */
256
311
  quantity: number | string;
257
312
  sku: string;
313
+ variant: components["schemas"]["CartLineVariantDto"];
314
+ };
315
+ CartLineProductDto: {
316
+ id: string;
317
+ name: string;
318
+ slug: string;
319
+ };
320
+ CartLineVariantDto: {
321
+ id: string;
322
+ selectedOptions: {
323
+ [key: string]: string;
324
+ };
258
325
  };
259
326
  CategoryNodeDto: {
260
327
  children: components["schemas"]["CategoryNodeDto"][];
@@ -298,6 +365,10 @@ export interface components {
298
365
  slug: string;
299
366
  url: string;
300
367
  };
368
+ DescriptionDto: {
369
+ html: string;
370
+ text: string;
371
+ };
301
372
  FacetDto: {
302
373
  key: string;
303
374
  label: string;
@@ -308,6 +379,10 @@ export interface components {
308
379
  type: string;
309
380
  values: components["schemas"]["FacetValueDto"][];
310
381
  };
382
+ FacetLinkDto: {
383
+ key: string;
384
+ valueKey: string;
385
+ };
311
386
  FacetValueDto: {
312
387
  children: components["schemas"]["FacetValueDto"][] | null;
313
388
  /** Format: int64 */
@@ -318,6 +393,10 @@ export interface components {
318
393
  selected: boolean;
319
394
  swatch: null | components["schemas"]["SwatchDto"];
320
395
  };
396
+ FacetValuesResponse: {
397
+ facet: string;
398
+ values: components["schemas"]["FacetValueDto"][];
399
+ };
321
400
  ListingResponse: {
322
401
  appliedFilters: components["schemas"]["AppliedFilterDto"][];
323
402
  facets: components["schemas"]["FacetDto"][];
@@ -414,6 +493,7 @@ export interface components {
414
493
  vatRate: string;
415
494
  };
416
495
  ProductCardDto: {
496
+ brand: null | components["schemas"]["BrandDto"];
417
497
  collections: string[];
418
498
  id: string;
419
499
  image: null | components["schemas"]["MediaDescriptorDto"];
@@ -421,6 +501,7 @@ export interface components {
421
501
  name: string;
422
502
  price: null | components["schemas"]["PriceDto"];
423
503
  priceVaries: boolean;
504
+ shortDescription: null | string;
424
505
  sku: string;
425
506
  slug: string;
426
507
  /** Format: date-time */
@@ -431,8 +512,12 @@ export interface components {
431
512
  alternateUrls: {
432
513
  [key: string]: string;
433
514
  };
515
+ attributes: components["schemas"]["AttributeDto"][];
516
+ brand: null | components["schemas"]["BrandDto"];
517
+ bundle: null | components["schemas"]["BundleDto"];
434
518
  categories: components["schemas"]["CategoryRefDto"][];
435
519
  collections: components["schemas"]["CollectionRefDto"][];
520
+ description: null | components["schemas"]["DescriptionDto"];
436
521
  files: components["schemas"]["MediaDescriptorDto"][];
437
522
  id: string;
438
523
  image: null | components["schemas"]["MediaDescriptorDto"];
@@ -441,7 +526,9 @@ export interface components {
441
526
  name: string;
442
527
  options: components["schemas"]["OptionDto"][];
443
528
  redirectTo: null | string;
529
+ related: components["schemas"]["RelatedGroupDto"][];
444
530
  seo: components["schemas"]["SeoDto"];
531
+ shortDescription: null | string;
445
532
  sku: string;
446
533
  slug: string;
447
534
  /** Format: date-time */
@@ -457,12 +544,18 @@ export interface components {
457
544
  min: string;
458
545
  mode: string;
459
546
  selected: null | components["schemas"]["RangeSelectionDto"];
547
+ step: null | string;
460
548
  unit: null | string;
461
549
  };
462
550
  RangeSelectionDto: {
463
551
  max: null | string;
464
552
  min: null | string;
465
553
  };
554
+ RelatedGroupDto: {
555
+ key: string;
556
+ label: string;
557
+ products: components["schemas"]["ProductCardDto"][];
558
+ };
466
559
  SeoDto: {
467
560
  description: null | string;
468
561
  title: string;
@@ -532,6 +625,22 @@ export interface components {
532
625
  /** @description Link to this code's documentation. */
533
626
  type?: string;
534
627
  };
628
+ SuggestCategoryDto: {
629
+ id: string;
630
+ name: string;
631
+ path: string[];
632
+ };
633
+ SuggestFacetValueDto: {
634
+ facet: string;
635
+ key: string;
636
+ label: string;
637
+ };
638
+ SuggestResponse: {
639
+ categories: components["schemas"]["SuggestCategoryDto"][];
640
+ facetValues: components["schemas"]["SuggestFacetValueDto"][];
641
+ products: components["schemas"]["ProductCardDto"][];
642
+ query: string;
643
+ };
535
644
  SwatchDto: {
536
645
  color: null | string;
537
646
  image: null | components["schemas"]["MediaDescriptorDto"];
@@ -1630,6 +1739,96 @@ export interface operations {
1630
1739
  };
1631
1740
  };
1632
1741
  };
1742
+ SearchFacetValues: {
1743
+ parameters: {
1744
+ query?: {
1745
+ /** @description Narrows to the values whose label contains q (case-insensitively) or whose key starts with it. Omit for the facet's values as they are. Matched against the 1000 most common values of the facet, in this API — at most 50 are returned. Present but blank is a 400 (INVALID_QUERY). */
1746
+ q?: string;
1747
+ /** @description The filter context the values are counted in, sent as filter[key]=value exactly as on /products: a count is what selecting that value would leave. This facet's own selection does not narrow it (the counts are disjunctive), and a key this site has no facet for is dropped silently. */
1748
+ filter?: {
1749
+ [key: string]: string;
1750
+ };
1751
+ };
1752
+ header: {
1753
+ /** @description Publishable, preview or secret site key. Required on every request; secret keys are server-side only. */
1754
+ "X-Site-Key": string;
1755
+ /** @description Market code (e.g. "se"). Omit for the site's default market. */
1756
+ "X-Market"?: string;
1757
+ /** @description BCP-47 language tag. Omit to use the market's language. */
1758
+ "Accept-Language"?: string;
1759
+ };
1760
+ path: {
1761
+ key: string;
1762
+ };
1763
+ cookie?: never;
1764
+ };
1765
+ requestBody?: never;
1766
+ responses: {
1767
+ /** @description OK */
1768
+ 200: {
1769
+ headers: {
1770
+ [name: string]: unknown;
1771
+ };
1772
+ content: {
1773
+ "application/json": components["schemas"]["FacetValuesResponse"];
1774
+ };
1775
+ };
1776
+ /** @description problem+json. MARKET_UNKNOWN (no such market on this site), INVALID_PAGE, or INVALID_QUERY (q present but blank, or longer than 100 characters), or FACET_NOT_SEARCHABLE (the facet exists but has no list of values to search in: a range, a toggle or a tree). */
1777
+ 400: {
1778
+ headers: {
1779
+ [name: string]: unknown;
1780
+ };
1781
+ content: {
1782
+ "application/problem+json": components["schemas"]["StorefrontProblem"];
1783
+ };
1784
+ };
1785
+ /** @description problem+json. SITE_KEY_MISSING or SITE_KEY_INVALID. */
1786
+ 401: {
1787
+ headers: {
1788
+ [name: string]: unknown;
1789
+ };
1790
+ content: {
1791
+ "application/problem+json": components["schemas"]["StorefrontProblem"];
1792
+ };
1793
+ };
1794
+ /** @description problem+json. SECRET_KEY_FROM_BROWSER: a secret key was sent from a browser. */
1795
+ 403: {
1796
+ headers: {
1797
+ [name: string]: unknown;
1798
+ };
1799
+ content: {
1800
+ "application/problem+json": components["schemas"]["StorefrontProblem"];
1801
+ };
1802
+ };
1803
+ /** @description problem+json. FACET_NOT_FOUND, or SITE_INACTIVE when the site itself is not live. */
1804
+ 404: {
1805
+ headers: {
1806
+ [name: string]: unknown;
1807
+ };
1808
+ content: {
1809
+ "application/problem+json": components["schemas"]["StorefrontProblem"];
1810
+ };
1811
+ };
1812
+ /** @description problem+json. RATE_LIMITED; retryAfterSeconds and the Retry-After header say how long to wait. */
1813
+ 429: {
1814
+ headers: {
1815
+ [name: string]: unknown;
1816
+ };
1817
+ content: {
1818
+ "application/problem+json": components["schemas"]["StorefrontProblem"];
1819
+ };
1820
+ };
1821
+ /** @description problem+json. SITE_REGISTRY_WARMING or INDEX_UNAVAILABLE — retry, the request was not wrong. */
1822
+ 503: {
1823
+ headers: {
1824
+ [name: string]: unknown;
1825
+ };
1826
+ content: {
1827
+ "application/problem+json": components["schemas"]["StorefrontProblem"];
1828
+ };
1829
+ };
1830
+ };
1831
+ };
1633
1832
  GetProduct: {
1634
1833
  parameters: {
1635
1834
  query?: never;
@@ -1805,6 +2004,90 @@ export interface operations {
1805
2004
  };
1806
2005
  };
1807
2006
  };
2007
+ Suggest: {
2008
+ parameters: {
2009
+ query: {
2010
+ /** @description What the shopper has typed so far, 1–100 characters. Blank, missing or longer is a 400 (INVALID_QUERY) — unlike a listing's q, which is truncated. */
2011
+ q: string;
2012
+ };
2013
+ header: {
2014
+ /** @description Publishable, preview or secret site key. Required on every request; secret keys are server-side only. */
2015
+ "X-Site-Key": string;
2016
+ /** @description Market code (e.g. "se"). Omit for the site's default market. */
2017
+ "X-Market"?: string;
2018
+ /** @description BCP-47 language tag. Omit to use the market's language. */
2019
+ "Accept-Language"?: string;
2020
+ };
2021
+ path?: never;
2022
+ cookie?: never;
2023
+ };
2024
+ requestBody?: never;
2025
+ responses: {
2026
+ /** @description OK */
2027
+ 200: {
2028
+ headers: {
2029
+ [name: string]: unknown;
2030
+ };
2031
+ content: {
2032
+ "application/json": components["schemas"]["SuggestResponse"];
2033
+ };
2034
+ };
2035
+ /** @description problem+json. MARKET_UNKNOWN (no such market on this site), INVALID_PAGE, or INVALID_QUERY (q missing, blank or longer than 100 characters). */
2036
+ 400: {
2037
+ headers: {
2038
+ [name: string]: unknown;
2039
+ };
2040
+ content: {
2041
+ "application/problem+json": components["schemas"]["StorefrontProblem"];
2042
+ };
2043
+ };
2044
+ /** @description problem+json. SITE_KEY_MISSING or SITE_KEY_INVALID. */
2045
+ 401: {
2046
+ headers: {
2047
+ [name: string]: unknown;
2048
+ };
2049
+ content: {
2050
+ "application/problem+json": components["schemas"]["StorefrontProblem"];
2051
+ };
2052
+ };
2053
+ /** @description problem+json. SECRET_KEY_FROM_BROWSER: a secret key was sent from a browser. */
2054
+ 403: {
2055
+ headers: {
2056
+ [name: string]: unknown;
2057
+ };
2058
+ content: {
2059
+ "application/problem+json": components["schemas"]["StorefrontProblem"];
2060
+ };
2061
+ };
2062
+ /** @description problem+json. SITE_INACTIVE, or NOT_FOUND for an unrouted path. */
2063
+ 404: {
2064
+ headers: {
2065
+ [name: string]: unknown;
2066
+ };
2067
+ content: {
2068
+ "application/problem+json": components["schemas"]["StorefrontProblem"];
2069
+ };
2070
+ };
2071
+ /** @description problem+json. RATE_LIMITED; retryAfterSeconds and the Retry-After header say how long to wait. */
2072
+ 429: {
2073
+ headers: {
2074
+ [name: string]: unknown;
2075
+ };
2076
+ content: {
2077
+ "application/problem+json": components["schemas"]["StorefrontProblem"];
2078
+ };
2079
+ };
2080
+ /** @description problem+json. SITE_REGISTRY_WARMING or INDEX_UNAVAILABLE — retry, the request was not wrong. */
2081
+ 503: {
2082
+ headers: {
2083
+ [name: string]: unknown;
2084
+ };
2085
+ content: {
2086
+ "application/problem+json": components["schemas"]["StorefrontProblem"];
2087
+ };
2088
+ };
2089
+ };
2090
+ };
1808
2091
  GetSite: {
1809
2092
  parameters: {
1810
2093
  query?: never;