@sonic-commerce/storefront-types 0.26.1 → 0.27.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
@@ -74,6 +74,31 @@ and so on — alongside the raw `paths`, `components` and `operations` that
74
74
  import type { Cart, CartTotals, AddCartItemBody } from "@sonic-commerce/storefront-types";
75
75
  ```
76
76
 
77
+ ### Option filters
78
+
79
+ `opt.<option>` keys are named after the store's options, so they are not in the
80
+ typed query parameters. Spread them in — TypeScript does not check spread
81
+ properties against the parameter list:
82
+
83
+ ```ts
84
+ import type { ProductFilters } from "@sonic-commerce/storefront-types";
85
+
86
+ const options = { "opt.size": "m,l", "opt.colour": "red" };
87
+
88
+ const { data: filters } = await api.GET("/products/filters", {
89
+ params: { query: { ...options, "price[lte]": 18500 } },
90
+ });
91
+ const sidebar: ProductFilters | undefined = filters?.data;
92
+
93
+ const { data: page } = await api.GET("/products", {
94
+ params: { query: { ...options, "price[lte]": 18500, sort: "price" } },
95
+ });
96
+ ```
97
+
98
+ Take keys from `ProductFilters` (`option.key`, `value.key`) rather than
99
+ building them from labels. Counts are over the current result and `null` above
100
+ 5,000 matching products; see the API guide for the rules.
101
+
77
102
  ### One openapi-fetch quirk
78
103
 
79
104
  `openapi-fetch` (0.17.0, checked) drops properties typed as exactly `null` from
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  // Generated by scripts/build.mjs from app/openapi/public-api.json — do not edit.
2
- // Spec version 0.26.1, 54 named schemas.
2
+ // Spec version 0.27.0, 58 named schemas.
3
3
 
4
4
  export type { paths, components, operations } from "./schema";
5
5
  import type { components } from "./schema";
@@ -36,8 +36,12 @@ export type PaymentMethod = components["schemas"]["PaymentMethod"];
36
36
  export type Product = components["schemas"]["Product"];
37
37
  export type ProductCategory = components["schemas"]["ProductCategory"];
38
38
  export type ProductCollection = components["schemas"]["ProductCollection"];
39
+ export type ProductFilterOption = components["schemas"]["ProductFilterOption"];
40
+ export type ProductFilterValue = components["schemas"]["ProductFilterValue"];
41
+ export type ProductFilters = components["schemas"]["ProductFilters"];
39
42
  export type ProductListItem = components["schemas"]["ProductListItem"];
40
43
  export type ProductOption = components["schemas"]["ProductOption"];
44
+ export type ProductPriceBand = components["schemas"]["ProductPriceBand"];
41
45
  export type ProductVariant = components["schemas"]["ProductVariant"];
42
46
  export type Region = components["schemas"]["Region"];
43
47
  export type RegionSummary = components["schemas"]["RegionSummary"];
package/dist/schema.d.ts CHANGED
@@ -13,7 +13,7 @@ export interface paths {
13
13
  };
14
14
  /**
15
15
  * List products
16
- * @description Filter, sort, search and expand. `price` sorts and filters resolve against the store's default currency, in minor units.
16
+ * @description Filter, sort, search and expand. Prices are in minor units, in `currency` or the store's default. A `price[...]` filter matches a product when one variant is priced in range — every bound against that one price, and on the same variant as any `opt.` filter. `sort=price` orders by the product's lowest price; products with no price in the currency come last in both directions.
17
17
  */
18
18
  get: {
19
19
  parameters: {
@@ -115,6 +115,110 @@ export interface paths {
115
115
  patch?: never;
116
116
  trace?: never;
117
117
  };
118
+ "/products/filters": {
119
+ parameters: {
120
+ query?: never;
121
+ header?: never;
122
+ path?: never;
123
+ cookie?: never;
124
+ };
125
+ /**
126
+ * Filters for a product listing
127
+ * @description What a filter sidebar shows for the listing the same query returns. Send the listing's filters, `q`, `currency` and `opt.` keys. Counts are taken over the current result: with `opt.size=m`, the other sizes count 0, and every value of a chosen option is listed so it can be widened. The price block ignores the price filter itself so the range can be widened too; its bands are round steps to snap a slider to. Above 5,000 matching products nothing is counted: `counted` is `false`, every count is `null`, and the option lists are store-wide.
128
+ */
129
+ get: {
130
+ parameters: {
131
+ query?: {
132
+ /** @description 1-based page number. */
133
+ page?: number;
134
+ /** @description Rows per page. Values above 100 are rejected, not clamped. */
135
+ limit?: number;
136
+ /** @description Free-text search term. */
137
+ q?: string;
138
+ /** @description ISO 4217 code to price against, e.g. `CAD`. Must be one the store supports. Defaults to the store's default currency. */
139
+ currency?: string;
140
+ /** @description Filter by category_id. A comma-separated list matches any value; the literal `null` matches rows where category_id is unset. */
141
+ category_id?: string;
142
+ /** @description Filter where category_id is not equal to the given value. */
143
+ "category_id[ne]"?: string;
144
+ /** @description Filter by collection_id. A comma-separated list matches any value; the literal `null` matches rows where collection_id is unset. */
145
+ collection_id?: string;
146
+ /** @description Filter where collection_id is not equal to the given value. */
147
+ "collection_id[ne]"?: string;
148
+ /** @description Filter by handle. A comma-separated list matches any value; the literal `null` matches rows where handle is unset. */
149
+ handle?: string;
150
+ /** @description Filter where handle is not equal to the given value. */
151
+ "handle[ne]"?: string;
152
+ /** @description Filter where handle is case-insensitive substring match the given value. */
153
+ "handle[like]"?: string;
154
+ /** @description Filter by tag. A comma-separated list matches any value; the literal `null` matches rows where tag is unset. */
155
+ tag?: string;
156
+ /** @description Filter where tag is not equal to the given value. */
157
+ "tag[ne]"?: string;
158
+ /** @description Filter by type. A comma-separated list matches any value; the literal `null` matches rows where type is unset. */
159
+ type?: string;
160
+ /** @description Filter where type is not equal to the given value. */
161
+ "type[ne]"?: string;
162
+ /** @description Filter by price. A comma-separated list matches any value; the literal `null` matches rows where price is unset. */
163
+ price?: string;
164
+ /** @description Filter where price is not equal to the given value. */
165
+ "price[ne]"?: number;
166
+ /** @description Filter where price is greater than the given value. */
167
+ "price[gt]"?: number;
168
+ /** @description Filter where price is greater than or equal to the given value. */
169
+ "price[gte]"?: number;
170
+ /** @description Filter where price is less than the given value. */
171
+ "price[lt]"?: number;
172
+ /** @description Filter where price is less than or equal to the given value. */
173
+ "price[lte]"?: number;
174
+ /** @description Filter by in_stock. A comma-separated list matches any value; the literal `null` matches rows where in_stock is unset. */
175
+ in_stock?: string;
176
+ };
177
+ header?: never;
178
+ path?: never;
179
+ cookie?: never;
180
+ };
181
+ requestBody?: never;
182
+ responses: {
183
+ /** @description Success */
184
+ 200: {
185
+ headers: {
186
+ [name: string]: unknown;
187
+ };
188
+ content: {
189
+ "application/json": {
190
+ data: components["schemas"]["ProductFilters"];
191
+ };
192
+ };
193
+ };
194
+ /** @description Invalid request — unknown parameter or bad value. */
195
+ 400: {
196
+ headers: {
197
+ [name: string]: unknown;
198
+ };
199
+ content: {
200
+ "application/json": components["schemas"]["Error"];
201
+ };
202
+ };
203
+ /** @description Rate limit exceeded. */
204
+ 429: {
205
+ headers: {
206
+ [name: string]: unknown;
207
+ };
208
+ content: {
209
+ "application/json": components["schemas"]["Error"];
210
+ };
211
+ };
212
+ };
213
+ };
214
+ put?: never;
215
+ post?: never;
216
+ delete?: never;
217
+ options?: never;
218
+ head?: never;
219
+ patch?: never;
220
+ trace?: never;
221
+ };
118
222
  "/products/search": {
119
223
  parameters: {
120
224
  query?: never;
@@ -3607,6 +3711,35 @@ export interface components {
3607
3711
  image: string | null;
3608
3712
  };
3609
3713
  };
3714
+ ProductFilters: {
3715
+ total: number;
3716
+ counted: boolean;
3717
+ options: components["schemas"]["ProductFilterOption"][];
3718
+ price: {
3719
+ currency_code: string;
3720
+ min: number;
3721
+ max: number;
3722
+ bands: components["schemas"]["ProductPriceBand"][];
3723
+ } | null;
3724
+ in_stock: {
3725
+ count: number | null;
3726
+ };
3727
+ };
3728
+ ProductFilterOption: {
3729
+ key: string;
3730
+ title: string;
3731
+ values: components["schemas"]["ProductFilterValue"][];
3732
+ };
3733
+ ProductFilterValue: {
3734
+ key: string;
3735
+ value: string;
3736
+ count: number | null;
3737
+ };
3738
+ ProductPriceBand: {
3739
+ gte: number;
3740
+ lt: number;
3741
+ count: number | null;
3742
+ };
3610
3743
  Category: {
3611
3744
  id: string;
3612
3745
  name?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sonic-commerce/storefront-types",
3
- "version": "0.26.1",
3
+ "version": "0.27.0",
4
4
  "description": "TypeScript types for the Sonic Commerce storefront API (/v1).",
5
5
  "keywords": ["sonic-commerce", "openapi", "types", "storefront"],
6
6
  "license": "UNLICENSED",