@minipim/sdk 0.4.1 → 0.6.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 +37 -0
- package/dist/index.cjs +1 -3
- package/dist/index.d.cts +7 -3
- package/dist/index.d.ts +7 -3
- package/dist/index.js +1 -3
- package/dist/openapi.d.cts +945 -126
- package/dist/openapi.d.ts +945 -126
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -130,6 +130,43 @@ const all = await collectAll<Product>(pim, '/v1/products');
|
|
|
130
130
|
|
|
131
131
|
Endpoints that return a **plain array** instead of the envelope (`/v1/categories` without `?limit=`, `/v1/attributes`, `/v1/products/{id}/variants`) are handled too (v0.3.0+): the array is treated as the one-and-only page, so `collectAll` works uniformly across every list endpoint.
|
|
132
132
|
|
|
133
|
+
## Listing by category, and by price (v0.5.0+)
|
|
134
|
+
|
|
135
|
+
Two things storefronts almost always need, and previously had to do in memory.
|
|
136
|
+
|
|
137
|
+
**Category subtrees.** `categoryId` on its own is **self-only** — it matches products filed directly against that category. Catalogs commonly assign products to leaf categories, so a parent category can legitimately return an empty page. Add `includeDescendants` for the whole subtree:
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
// Everything anywhere under "Backdrops", in ONE paginated query.
|
|
141
|
+
const { data } = await pim.GET('/v1/products', {
|
|
142
|
+
query: { categoryId, includeDescendants: true, limit: 50 },
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Don't fetch `/v1/categories`, resolve descendants yourself and issue one request per id — this is a single round trip and it paginates as one result set.
|
|
147
|
+
|
|
148
|
+
**Sorting and filtering by price.** There is no `sortBy: 'price'`, because a catalog's price attribute code is its own data (`price`, `msrp`, `list_price`, …). Name it:
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
// Cheapest first
|
|
152
|
+
await pim.GET('/v1/products', {
|
|
153
|
+
query: { sortBy: 'attribute', sortAttribute: 'price', sortDir: 'asc' },
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// $10.00–$50.00 — money bounds are INTEGER CENTS
|
|
157
|
+
await pim.GET('/v1/products', {
|
|
158
|
+
query: { filterAttribute: 'price', filterMin: 1000, filterMax: 5000 },
|
|
159
|
+
});
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
- Works on `money`, `number` and `decimal` attributes. `measurement` is refused — its values carry a unit, so ordering raw amounts would rank 5 g above 2 kg.
|
|
163
|
+
- For `money`, bounds and ordering use `amount_cents`. **`filterMin: 1000` is $10.00.** No currency conversion — mixed-currency catalogs compare by number.
|
|
164
|
+
- The value read is the one at the **default scope** (no locale, no channel). Products with no value sort **last in both directions** and are excluded by either bound: no price, not a price of zero.
|
|
165
|
+
- An unknown code, or one of a non-orderable type, is a **422 naming the problem**. It never degrades to name ordering, so you can't get a plausible page that isn't sorted the way you asked.
|
|
166
|
+
- `sortAttribute` and `filterAttribute` are independent; set both for "cheapest first, within a budget".
|
|
167
|
+
|
|
168
|
+
Needs API **0.9.0+**. Check `GET /healthz`.
|
|
169
|
+
|
|
133
170
|
## Attribute helpers
|
|
134
171
|
|
|
135
172
|
Attribute values are `unknown` and keyed by `(locale, channel)`. List responses return the raw `{ code: [{ locale, channel, value }] }` shape (only product *detail* with `?locale=&channel=` returns a flat `resolvedAttributes`). The SDK ships the flatten + coercion helpers so you don't reimplement them:
|
package/dist/index.cjs
CHANGED
|
@@ -80,9 +80,7 @@ async function* paginate(client, path, opts = {}) {
|
|
|
80
80
|
params: { query: { ...opts.query ?? {}, limit: pageSize, offset } }
|
|
81
81
|
});
|
|
82
82
|
if (error || !data) {
|
|
83
|
-
throw new Error(
|
|
84
|
-
`paginate ${path} failed at offset ${offset} (HTTP ${response?.status})`
|
|
85
|
-
);
|
|
83
|
+
throw new Error(`paginate ${path} failed at offset ${offset} (HTTP ${response?.status})`);
|
|
86
84
|
}
|
|
87
85
|
if (Array.isArray(data)) {
|
|
88
86
|
for (const item of data) yield item;
|
package/dist/index.d.cts
CHANGED
|
@@ -77,9 +77,13 @@ type MinipimClient = Client<paths>;
|
|
|
77
77
|
declare function createMinipimClient(opts: CreateMinipimClientOptions): MinipimClient;
|
|
78
78
|
|
|
79
79
|
/**
|
|
80
|
-
* Generic pagination helper.
|
|
81
|
-
* `{ data, limit, offset
|
|
82
|
-
*
|
|
80
|
+
* Generic pagination helper. MiniPim list endpoints return
|
|
81
|
+
* `{ data, limit, offset }`, and **only `/v1/products` also returns
|
|
82
|
+
* `hasMore`** — so this walks the pages by trusting `hasMore` when it is
|
|
83
|
+
* present and falling back to a short-page check when it isn't. That is the
|
|
84
|
+
* whole reason to use this instead of a hand-rolled `while (hasMore)` loop,
|
|
85
|
+
* which reads exactly one page from every other endpoint and stops. Yields
|
|
86
|
+
* one item at a time.
|
|
83
87
|
*
|
|
84
88
|
* Typed loosely on purpose — openapi-fetch's per-path generics don't
|
|
85
89
|
* compose into a single reusable signature without a lot of conditional-
|
package/dist/index.d.ts
CHANGED
|
@@ -77,9 +77,13 @@ type MinipimClient = Client<paths>;
|
|
|
77
77
|
declare function createMinipimClient(opts: CreateMinipimClientOptions): MinipimClient;
|
|
78
78
|
|
|
79
79
|
/**
|
|
80
|
-
* Generic pagination helper.
|
|
81
|
-
* `{ data, limit, offset
|
|
82
|
-
*
|
|
80
|
+
* Generic pagination helper. MiniPim list endpoints return
|
|
81
|
+
* `{ data, limit, offset }`, and **only `/v1/products` also returns
|
|
82
|
+
* `hasMore`** — so this walks the pages by trusting `hasMore` when it is
|
|
83
|
+
* present and falling back to a short-page check when it isn't. That is the
|
|
84
|
+
* whole reason to use this instead of a hand-rolled `while (hasMore)` loop,
|
|
85
|
+
* which reads exactly one page from every other endpoint and stops. Yields
|
|
86
|
+
* one item at a time.
|
|
83
87
|
*
|
|
84
88
|
* Typed loosely on purpose — openapi-fetch's per-path generics don't
|
|
85
89
|
* compose into a single reusable signature without a lot of conditional-
|
package/dist/index.js
CHANGED
|
@@ -28,9 +28,7 @@ async function* paginate(client, path, opts = {}) {
|
|
|
28
28
|
params: { query: { ...opts.query ?? {}, limit: pageSize, offset } }
|
|
29
29
|
});
|
|
30
30
|
if (error || !data) {
|
|
31
|
-
throw new Error(
|
|
32
|
-
`paginate ${path} failed at offset ${offset} (HTTP ${response?.status})`
|
|
33
|
-
);
|
|
31
|
+
throw new Error(`paginate ${path} failed at offset ${offset} (HTTP ${response?.status})`);
|
|
34
32
|
}
|
|
35
33
|
if (Array.isArray(data)) {
|
|
36
34
|
for (const item of data) yield item;
|