@minipim/sdk 0.6.0 → 0.8.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
@@ -126,7 +126,11 @@ for await (const p of paginate<Product>(pim, '/v1/products', { query: { status:
126
126
  const all = await collectAll<Product>(pim, '/v1/products');
127
127
  ```
128
128
 
129
- `paginate` manages `limit`/`offset`, honors the server's `hasMore`, and defaults to the 200-row max page size (override with `pageSize`). Pass `withTotal: true` in `query` if you need `total` — it adds one `COUNT(*)`, so leave it off on hot reads.
129
+ `paginate` manages `limit`/`offset`, honors the server's `hasMore`, and defaults to the 200-row max page size (override with `pageSize`).
130
+
131
+ `withTotal: true` is supported by **`/v1/products` only** — it adds one `COUNT(*)`, so leave it off on hot reads. Other list endpoints never return `total`, and as of v0.7.0 their types say so rather than declaring a field that was always `undefined`.
132
+
133
+ Against API **0.14.0 and newer, `hasMore` is present and exact on every list endpoint** — the server reads one row past the page, so a final page that happens to be exactly full reports `false` instead of sending you after an empty one. Older deployments omitted `hasMore` everywhere except `/v1/products`; `paginate` keeps a short-page fallback for those, which is the whole reason not to hand-roll the loop.
130
134
 
131
135
  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
136
 
@@ -167,6 +171,72 @@ await pim.GET('/v1/products', {
167
171
 
168
172
  Needs API **0.9.0+**. Check `GET /healthz`.
169
173
 
174
+ ## Tags
175
+
176
+ Tags are **canonicalized on write**, so what you read back is not verbatim what you sent:
177
+
178
+ ```ts
179
+ await pim.POST('/v1/content', { body: { /* … */ tags: ['Buying Guide', 'buying guide', 'FAQ!'] } });
180
+ // stored, and returned as: ['buying-guide', 'faq']
181
+ ```
182
+
183
+ Each tag is lower-cased, stripped of diacritics, has runs of non-alphanumerics collapsed to `-`, is trimmed of leading/trailing `-`, and is truncated to **60 characters**. Empties are dropped and duplicates removed (first occurrence wins), so **the array you get back can be shorter than the one you sent**. Note that the schema's `maxLength` is 80: two tags differing only past character 60 collapse into one.
184
+
185
+ This is deliberate — it is what makes `Featured`, `featured` and `FEATURED` one tag rather than three. Filters are canonicalized identically, so you never have to pre-slugify one:
186
+
187
+ ```ts
188
+ await pim.GET('/v1/content', { params: { query: { tag: 'Buying Guide' } } }); // matches buying-guide
189
+ ```
190
+
191
+ `tag` is repeatable and ANDs: `{ tag: ['guide', 'seo'] }` returns only pages carrying both. `GET /v1/products/tags` and `GET /v1/content/tags` list the vocabulary actually in use, with counts — two **separate** vocabularies, since an editorial tag and a merchandising tag rarely mean the same thing.
192
+
193
+ Documented in the field descriptions from API **0.14.1+**, and in these types from v0.7.0.
194
+
195
+ ## Ordering a content archive (API 0.19.0+)
196
+
197
+ `GET /v1/content` defaults to `updatedAt` descending — the order things were last *edited*, which is rarely the order an archive should read in. Sort by `publishedAt`, which imports preserve from the source system:
198
+
199
+ ```ts
200
+ const { data } = await pim.GET('/v1/content', {
201
+ params: { query: { sortBy: 'publishedAt', sortDir: 'desc', limit: 20 } },
202
+ });
203
+ ```
204
+
205
+ Pages with no `publishedAt` sort **last in both directions** — an undated page is unscheduled, not newest. `sortBy` also accepts `updatedAt`, `createdAt` and `title`.
206
+
207
+ `categoryId` behaves exactly like it does on products: **self-only** unless you add `includeDescendants: true`. Content gets filed against leaf categories too, so filtering by a parent section returns an empty page without it.
208
+
209
+ ## Uploading files
210
+
211
+ `POST /v1/media` is `multipart/form-data`, not JSON. The file field is named `file`; everything else is optional and lets you attach the upload in the same request:
212
+
213
+ ```ts
214
+ const form = new FormData();
215
+ form.append('file', blob, 'sell-sheet.pdf');
216
+ form.append('entityType', 'product'); // 'product' | 'variant' | 'content_page'
217
+ form.append('entityId', productId);
218
+ form.append('role', 'technical'); // hero | gallery | thumbnail | technical | lifestyle | swatch
219
+ form.append('altText', JSON.stringify({ en_US: 'Sell sheet' })); // a JSON *string*, not an object
220
+ ```
221
+
222
+ `altText` is parsed as JSON, so passing a real object rather than a string stores no alt text. Send `JSON.stringify(...)`.
223
+
224
+ That case no longer fails silently. From API **0.21.0** a malformed `altText` still lets the upload succeed — it never fails the request — but the response says what it ignored:
225
+
226
+ ```ts
227
+ const { data } = await pim.POST('/v1/media', { body: form as never });
228
+ if (data?.warnings?.length) console.warn(data.warnings);
229
+ // ["altText was not valid JSON and no alt text was stored; expected an object keyed by locale, …"]
230
+ ```
231
+
232
+ `warnings` is absent when there is nothing to report, so a clean upload's response is unchanged.
233
+
234
+ **You do not have to get the content type right.** From API **0.21.0** the leading bytes are sniffed whenever you send `application/octet-stream` or no type at all — so a PNG whose filename lost its extension uploads as a PNG. If a specific declared type contradicts the bytes, the bytes win. SVG, CSV, plain text and the Office formats have no distinguishing magic bytes and still need an explicit type.
235
+
236
+ `role` and `position` are validated: an unrecognised value is a 422 listing the accepted ones in `details.accepted`, not a 500.
237
+
238
+ Requires API **0.14.0+** to appear in the spec at all — before that this endpoint published no request body, so generated clients had nothing for it.
239
+
170
240
  ## Attribute helpers
171
241
 
172
242
  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.d.cts CHANGED
@@ -78,12 +78,17 @@ declare function createMinipimClient(opts: CreateMinipimClientOptions): MinipimC
78
78
 
79
79
  /**
80
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.
81
+ * `{ data, limit, offset, hasMore }`, where `hasMore` is always present and
82
+ * exactthe server fetches one row past the page to decide it, so a final
83
+ * page that is exactly full reports `false` instead of sending you after an
84
+ * empty one. Yields one item at a time.
85
+ *
86
+ * `hasMore` stays OPTIONAL in the type below, and the short-page fallback
87
+ * stays, deliberately: this client talks to whatever version the deployment is
88
+ * running, and API ≤ 0.13.0 omitted the field everywhere except
89
+ * `/v1/products`. Keeping the fallback means an older instance paginates
90
+ * correctly rather than reading one page and stopping — which is exactly the
91
+ * bug a hand-rolled `while (hasMore)` loop hit against those versions.
87
92
  *
88
93
  * Typed loosely on purpose — openapi-fetch's per-path generics don't
89
94
  * compose into a single reusable signature without a lot of conditional-
package/dist/index.d.ts CHANGED
@@ -78,12 +78,17 @@ declare function createMinipimClient(opts: CreateMinipimClientOptions): MinipimC
78
78
 
79
79
  /**
80
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.
81
+ * `{ data, limit, offset, hasMore }`, where `hasMore` is always present and
82
+ * exactthe server fetches one row past the page to decide it, so a final
83
+ * page that is exactly full reports `false` instead of sending you after an
84
+ * empty one. Yields one item at a time.
85
+ *
86
+ * `hasMore` stays OPTIONAL in the type below, and the short-page fallback
87
+ * stays, deliberately: this client talks to whatever version the deployment is
88
+ * running, and API ≤ 0.13.0 omitted the field everywhere except
89
+ * `/v1/products`. Keeping the fallback means an older instance paginates
90
+ * correctly rather than reading one page and stopping — which is exactly the
91
+ * bug a hand-rolled `while (hasMore)` loop hit against those versions.
87
92
  *
88
93
  * Typed loosely on purpose — openapi-fetch's per-path generics don't
89
94
  * compose into a single reusable signature without a lot of conditional-
@@ -914,11 +914,6 @@ interface paths {
914
914
  content: {
915
915
  "application/json": {
916
916
  code?: string;
917
- /**
918
- * @default product
919
- * @enum {string}
920
- */
921
- entityKind?: "product" | "content";
922
917
  label?: {
923
918
  [key: string]: string;
924
919
  };
@@ -1575,6 +1570,7 @@ interface paths {
1575
1570
  categoryId?: string;
1576
1571
  includeDescendants?: boolean | ("true" | "false" | "1" | "0");
1577
1572
  brand?: string;
1573
+ /** @description Repeatable — `?tag=a&tag=b` matches records carrying ALL listed tags. Values are canonicalized exactly as writes are, so `?tag=Buying%20Guide` matches the stored `buying-guide`; you never have to pre-slugify a filter. Backed by the GIN index on `tags`. */
1578
1574
  tag?: string | string[];
1579
1575
  connectorId?: string;
1580
1576
  updatedSince?: string;
@@ -1621,6 +1617,7 @@ interface paths {
1621
1617
  attributes: (string | number | boolean | ("null" | null)) | unknown[] | {
1622
1618
  [key: string]: unknown;
1623
1619
  };
1620
+ /** @description Tags in canonical form. These are normalized on write (lower-cased, slugified, deduplicated, truncated), so this array will not necessarily match what was submitted — see the `tags` field on the create/update request body for the exact rules. Filter with `?tag=` using either form. */
1624
1621
  tags: string[];
1625
1622
  /** Format: uuid */
1626
1623
  createdBy: string | null;
@@ -1631,7 +1628,7 @@ interface paths {
1631
1628
  }[];
1632
1629
  limit: number;
1633
1630
  offset: number;
1634
- hasMore?: boolean;
1631
+ hasMore: boolean;
1635
1632
  total?: number;
1636
1633
  };
1637
1634
  };
@@ -1670,7 +1667,10 @@ interface paths {
1670
1667
  value?: unknown;
1671
1668
  }[];
1672
1669
  };
1673
- /** @default [] */
1670
+ /**
1671
+ * @description Free-form tags, canonicalized on write and echoed back in canonical form — the response will NOT match your input verbatim. Each tag is lower-cased, stripped of diacritics, has every run of non-alphanumerics replaced with `-`, is trimmed of leading/trailing `-`, and is then truncated to 60 characters. So `"Buying Guide"` is stored and filtered as `buying-guide`. Tags that normalize to nothing (`""`, `"!!"`) are dropped, and duplicates are removed keeping first-occurrence order, so the array you get back may be SHORTER than the one you sent. Note the asymmetry with `maxLength`: an item may be up to 80 characters on input but is truncated to 60 once canonicalized, which can collapse two long tags into one.
1672
+ * @default []
1673
+ */
1674
1674
  tags?: string[];
1675
1675
  };
1676
1676
  };
@@ -1700,6 +1700,7 @@ interface paths {
1700
1700
  attributes: (string | number | boolean | ("null" | null)) | unknown[] | {
1701
1701
  [key: string]: unknown;
1702
1702
  };
1703
+ /** @description Tags in canonical form. These are normalized on write (lower-cased, slugified, deduplicated, truncated), so this array will not necessarily match what was submitted — see the `tags` field on the create/update request body for the exact rules. Filter with `?tag=` using either form. */
1703
1704
  tags: string[];
1704
1705
  /** Format: uuid */
1705
1706
  createdBy: string | null;
@@ -1766,6 +1767,7 @@ interface paths {
1766
1767
  categoryId?: string;
1767
1768
  includeDescendants?: boolean | ("true" | "false" | "1" | "0");
1768
1769
  brand?: string;
1770
+ /** @description Repeatable — `?tag=a&tag=b` matches records carrying ALL listed tags. Values are canonicalized exactly as writes are, so `?tag=Buying%20Guide` matches the stored `buying-guide`; you never have to pre-slugify a filter. Backed by the GIN index on `tags`. */
1769
1771
  tag?: string | string[];
1770
1772
  connectorId?: string;
1771
1773
  updatedSince?: string;
@@ -1985,6 +1987,7 @@ interface paths {
1985
1987
  attributes: (string | number | boolean | ("null" | null)) | unknown[] | {
1986
1988
  [key: string]: unknown;
1987
1989
  };
1990
+ /** @description Tags in canonical form. These are normalized on write (lower-cased, slugified, deduplicated, truncated), so this array will not necessarily match what was submitted — see the `tags` field on the create/update request body for the exact rules. Filter with `?tag=` using either form. */
1988
1991
  tags: string[];
1989
1992
  /** Format: uuid */
1990
1993
  createdBy: string | null;
@@ -2108,6 +2111,7 @@ interface paths {
2108
2111
  value?: unknown;
2109
2112
  }[];
2110
2113
  };
2114
+ /** @description Replaces the full tag list when present. Free-form tags, canonicalized on write and echoed back in canonical form — the response will NOT match your input verbatim. Each tag is lower-cased, stripped of diacritics, has every run of non-alphanumerics replaced with `-`, is trimmed of leading/trailing `-`, and is then truncated to 60 characters. So `"Buying Guide"` is stored and filtered as `buying-guide`. Tags that normalize to nothing (`""`, `"!!"`) are dropped, and duplicates are removed keeping first-occurrence order, so the array you get back may be SHORTER than the one you sent. Note the asymmetry with `maxLength`: an item may be up to 80 characters on input but is truncated to 60 once canonicalized, which can collapse two long tags into one. */
2111
2115
  tags?: string[];
2112
2116
  };
2113
2117
  };
@@ -2137,6 +2141,7 @@ interface paths {
2137
2141
  attributes: (string | number | boolean | ("null" | null)) | unknown[] | {
2138
2142
  [key: string]: unknown;
2139
2143
  };
2144
+ /** @description Tags in canonical form. These are normalized on write (lower-cased, slugified, deduplicated, truncated), so this array will not necessarily match what was submitted — see the `tags` field on the create/update request body for the exact rules. Filter with `?tag=` using either form. */
2140
2145
  tags: string[];
2141
2146
  /** Format: uuid */
2142
2147
  createdBy: string | null;
@@ -2304,6 +2309,7 @@ interface paths {
2304
2309
  attributes: (string | number | boolean | ("null" | null)) | unknown[] | {
2305
2310
  [key: string]: unknown;
2306
2311
  };
2312
+ /** @description Tags in canonical form. These are normalized on write (lower-cased, slugified, deduplicated, truncated), so this array will not necessarily match what was submitted — see the `tags` field on the create/update request body for the exact rules. Filter with `?tag=` using either form. */
2307
2313
  tags: string[];
2308
2314
  /** Format: uuid */
2309
2315
  createdBy: string | null;
@@ -2710,6 +2716,7 @@ interface paths {
2710
2716
  productIds: string[];
2711
2717
  /** @enum {string} */
2712
2718
  mode: "add" | "remove" | "replace";
2719
+ /** @description Free-form tags, canonicalized on write and echoed back in canonical form — the response will NOT match your input verbatim. Each tag is lower-cased, stripped of diacritics, has every run of non-alphanumerics replaced with `-`, is trimmed of leading/trailing `-`, and is then truncated to 60 characters. So `"Buying Guide"` is stored and filtered as `buying-guide`. Tags that normalize to nothing (`""`, `"!!"`) are dropped, and duplicates are removed keeping first-occurrence order, so the array you get back may be SHORTER than the one you sent. Note the asymmetry with `maxLength`: an item may be up to 80 characters on input but is truncated to 60 once canonicalized, which can collapse two long tags into one. */
2713
2720
  tags: string[];
2714
2721
  };
2715
2722
  };
@@ -3514,6 +3521,16 @@ interface paths {
3514
3521
  /**
3515
3522
  * List content pages
3516
3523
  * @description Filters and pagination mirror `GET /v1/products`. `tag` is repeatable and matches pages carrying ALL listed tags.
3524
+ *
3525
+ * Ordering defaults to `updatedAt` descending. For a blog archive sort by `publishedAt`, which imports preserve from the source system:
3526
+ *
3527
+ * ```
3528
+ * curl 'https://api.minipim.com/v1/content?sortBy=publishedAt&sortDir=desc&limit=20'
3529
+ * ```
3530
+ *
3531
+ * Pages with no `publishedAt` sort LAST in both directions — an undated page is unscheduled, not newest.
3532
+ *
3533
+ * `categoryId` is SELF-ONLY. Content is filed against leaf categories, so filtering by a parent returns an empty page unless you add `includeDescendants=true` to match the whole subtree.
3517
3534
  */
3518
3535
  get: {
3519
3536
  parameters: {
@@ -3522,9 +3539,13 @@ interface paths {
3522
3539
  q?: string;
3523
3540
  familyId?: string;
3524
3541
  categoryId?: string;
3542
+ includeDescendants?: boolean | ("true" | "false" | "1" | "0");
3525
3543
  channelId?: string;
3544
+ /** @description Repeatable — `?tag=a&tag=b` matches records carrying ALL listed tags. Values are canonicalized exactly as writes are, so `?tag=Buying%20Guide` matches the stored `buying-guide`; you never have to pre-slugify a filter. */
3526
3545
  tag?: string | string[];
3527
3546
  updatedSince?: string;
3547
+ sortBy?: "publishedAt" | "updatedAt" | "createdAt" | "title";
3548
+ sortDir?: "asc" | "desc";
3528
3549
  limit?: number;
3529
3550
  offset?: number;
3530
3551
  };
@@ -3563,6 +3584,7 @@ interface paths {
3563
3584
  attributes: (string | number | boolean | ("null" | null)) | unknown[] | {
3564
3585
  [key: string]: unknown;
3565
3586
  };
3587
+ /** @description Tags in canonical form. These are normalized on write (lower-cased, slugified, deduplicated, truncated), so this array will not necessarily match what was submitted — see the `tags` field on the create/update request body for the exact rules. Filter with `?tag=` using either form. */
3566
3588
  tags: string[];
3567
3589
  /** Format: uuid */
3568
3590
  createdBy: string | null;
@@ -3571,8 +3593,7 @@ interface paths {
3571
3593
  }[];
3572
3594
  limit: number;
3573
3595
  offset: number;
3574
- hasMore?: boolean;
3575
- total?: number;
3596
+ hasMore: boolean;
3576
3597
  };
3577
3598
  };
3578
3599
  };
@@ -3629,7 +3650,10 @@ interface paths {
3629
3650
  value?: unknown;
3630
3651
  }[];
3631
3652
  };
3632
- /** @default [] */
3653
+ /**
3654
+ * @description Free-form tags, canonicalized on write and echoed back in canonical form — the response will NOT match your input verbatim. Each tag is lower-cased, stripped of diacritics, has every run of non-alphanumerics replaced with `-`, is trimmed of leading/trailing `-`, and is then truncated to 60 characters. So `"Buying Guide"` is stored and filtered as `buying-guide`. Tags that normalize to nothing (`""`, `"!!"`) are dropped, and duplicates are removed keeping first-occurrence order, so the array you get back may be SHORTER than the one you sent. Note the asymmetry with `maxLength`: an item may be up to 80 characters on input but is truncated to 60 once canonicalized, which can collapse two long tags into one.
3655
+ * @default []
3656
+ */
3633
3657
  tags?: string[];
3634
3658
  };
3635
3659
  };
@@ -3663,6 +3687,7 @@ interface paths {
3663
3687
  attributes: (string | number | boolean | ("null" | null)) | unknown[] | {
3664
3688
  [key: string]: unknown;
3665
3689
  };
3690
+ /** @description Tags in canonical form. These are normalized on write (lower-cased, slugified, deduplicated, truncated), so this array will not necessarily match what was submitted — see the `tags` field on the create/update request body for the exact rules. Filter with `?tag=` using either form. */
3666
3691
  tags: string[];
3667
3692
  /** Format: uuid */
3668
3693
  createdBy: string | null;
@@ -3739,6 +3764,63 @@ interface paths {
3739
3764
  patch?: never;
3740
3765
  trace?: never;
3741
3766
  };
3767
+ "/v1/content/tags": {
3768
+ parameters: {
3769
+ query?: never;
3770
+ header?: never;
3771
+ path?: never;
3772
+ cookie?: never;
3773
+ };
3774
+ /**
3775
+ * List all content-page tags in use, with counts
3776
+ * @description Every distinct tag currently on at least one content page, ordered by usage. Powers tag autocomplete in the editor, which is what keeps a vocabulary from drifting into `guide` / `guides` / `Guides`. Filter pages by tag with `GET /v1/content?tag=<tag>` (repeatable; multiple tags AND together).
3777
+ */
3778
+ get: {
3779
+ parameters: {
3780
+ query?: never;
3781
+ header?: never;
3782
+ path?: never;
3783
+ cookie?: never;
3784
+ };
3785
+ requestBody?: never;
3786
+ responses: {
3787
+ /** @description Default Response */
3788
+ 200: {
3789
+ headers: {
3790
+ [name: string]: unknown;
3791
+ };
3792
+ content: {
3793
+ "application/json": {
3794
+ value: string;
3795
+ count: number;
3796
+ }[];
3797
+ };
3798
+ };
3799
+ /** @description Default Response */
3800
+ 403: {
3801
+ headers: {
3802
+ [name: string]: unknown;
3803
+ };
3804
+ content: {
3805
+ "application/json": {
3806
+ error: {
3807
+ code: string;
3808
+ message: string;
3809
+ details?: unknown;
3810
+ };
3811
+ };
3812
+ };
3813
+ };
3814
+ };
3815
+ };
3816
+ put?: never;
3817
+ post?: never;
3818
+ delete?: never;
3819
+ options?: never;
3820
+ head?: never;
3821
+ patch?: never;
3822
+ trace?: never;
3823
+ };
3742
3824
  "/v1/content/{id}": {
3743
3825
  parameters: {
3744
3826
  query?: never;
@@ -3786,6 +3868,7 @@ interface paths {
3786
3868
  attributes: (string | number | boolean | ("null" | null)) | unknown[] | {
3787
3869
  [key: string]: unknown;
3788
3870
  };
3871
+ /** @description Tags in canonical form. These are normalized on write (lower-cased, slugified, deduplicated, truncated), so this array will not necessarily match what was submitted — see the `tags` field on the create/update request body for the exact rules. Filter with `?tag=` using either form. */
3789
3872
  tags: string[];
3790
3873
  /** Format: uuid */
3791
3874
  createdBy: string | null;
@@ -3918,6 +4001,7 @@ interface paths {
3918
4001
  value?: unknown;
3919
4002
  }[];
3920
4003
  };
4004
+ /** @description Replaces the full tag list when present. Free-form tags, canonicalized on write and echoed back in canonical form — the response will NOT match your input verbatim. Each tag is lower-cased, stripped of diacritics, has every run of non-alphanumerics replaced with `-`, is trimmed of leading/trailing `-`, and is then truncated to 60 characters. So `"Buying Guide"` is stored and filtered as `buying-guide`. Tags that normalize to nothing (`""`, `"!!"`) are dropped, and duplicates are removed keeping first-occurrence order, so the array you get back may be SHORTER than the one you sent. Note the asymmetry with `maxLength`: an item may be up to 80 characters on input but is truncated to 60 once canonicalized, which can collapse two long tags into one. */
3921
4005
  tags?: string[];
3922
4006
  };
3923
4007
  };
@@ -3951,6 +4035,7 @@ interface paths {
3951
4035
  attributes: (string | number | boolean | ("null" | null)) | unknown[] | {
3952
4036
  [key: string]: unknown;
3953
4037
  };
4038
+ /** @description Tags in canonical form. These are normalized on write (lower-cased, slugified, deduplicated, truncated), so this array will not necessarily match what was submitted — see the `tags` field on the create/update request body for the exact rules. Filter with `?tag=` using either form. */
3954
4039
  tags: string[];
3955
4040
  /** Format: uuid */
3956
4041
  createdBy: string | null;
@@ -5913,7 +5998,44 @@ interface paths {
5913
5998
  path?: never;
5914
5999
  cookie?: never;
5915
6000
  };
5916
- requestBody?: never;
6001
+ requestBody: {
6002
+ content: {
6003
+ "multipart/form-data": {
6004
+ /**
6005
+ * Format: binary
6006
+ * @description The file to upload. Images, video, PDF, Office documents and glTF are accepted; the 422 response lists every allowed type in `details.allowed`. You do NOT have to get the content type right: when you send `application/octet-stream` (or no type at all), the leading bytes are sniffed and the detected type is used — so a PNG whose filename lost its extension uploads fine. SVG, CSV, plain text and Office formats have no distinguishing magic bytes and still need an explicit type. If a specific declared type contradicts the bytes, the bytes win.
6007
+ */
6008
+ file: string;
6009
+ /**
6010
+ * @description Attach the upload in the same transaction. Requires `entityId`; supplying only one of the pair uploads the file WITHOUT associating it. A value outside the enum is a 422, not a silent miss.
6011
+ * @enum {string}
6012
+ */
6013
+ entityType?: "product" | "variant" | "content_page";
6014
+ /**
6015
+ * Format: uuid
6016
+ * @description The id of the entity named by `entityType`.
6017
+ */
6018
+ entityId?: string;
6019
+ /**
6020
+ * @description Association role. Ignored unless `entityType`+`entityId` are present. A value outside this enum is rejected with a 422 that lists the accepted values in `details.accepted`.
6021
+ * @default gallery
6022
+ * @enum {string}
6023
+ */
6024
+ role?: "hero" | "gallery" | "thumbnail" | "technical" | "lifestyle" | "swatch";
6025
+ /**
6026
+ * @description Sort position within the entity’s gallery. Must be a non-negative integer; anything else is a 422.
6027
+ * @default 0
6028
+ */
6029
+ position?: number;
6030
+ /**
6031
+ * @description A JSON OBJECT keyed by locale, sent as a STRING — e.g. `{"en_US":"Blue widget on white"}`. Unparseable JSON, or JSON that is not an object of locale → string, does NOT fail the upload: the file is stored, no alt text is saved, and the 201 response carries a `warnings` entry saying so. Check `warnings` if you send alt text programmatically. Omit the field entirely if you have none.
6032
+ *
6033
+ * (0.20.0 briefly made this a 422; 0.21.0 restored the original behaviour and added `warnings` instead, so the problem is reported without breaking callers.)
6034
+ */
6035
+ altText?: string;
6036
+ };
6037
+ };
6038
+ };
5917
6039
  responses: {
5918
6040
  /** @description Default Response */
5919
6041
  201: {
@@ -5966,6 +6088,8 @@ interface paths {
5966
6088
  channelId: string | null;
5967
6089
  };
5968
6090
  url: string;
6091
+ /** @description Non-fatal problems with this upload — currently only malformed `altText`. The upload succeeded; something you sent was ignored. Absent when there is nothing to report. */
6092
+ warnings?: string[];
5969
6093
  };
5970
6094
  };
5971
6095
  };
@@ -5985,6 +6109,36 @@ interface paths {
5985
6109
  };
5986
6110
  };
5987
6111
  /** @description Default Response */
6112
+ 413: {
6113
+ headers: {
6114
+ [name: string]: unknown;
6115
+ };
6116
+ content: {
6117
+ "application/json": {
6118
+ error: {
6119
+ code: string;
6120
+ message: string;
6121
+ details?: unknown;
6122
+ };
6123
+ };
6124
+ };
6125
+ };
6126
+ /** @description Default Response */
6127
+ 422: {
6128
+ headers: {
6129
+ [name: string]: unknown;
6130
+ };
6131
+ content: {
6132
+ "application/json": {
6133
+ error: {
6134
+ code: string;
6135
+ message: string;
6136
+ details?: unknown;
6137
+ };
6138
+ };
6139
+ };
6140
+ };
6141
+ /** @description Default Response */
5988
6142
  503: {
5989
6143
  headers: {
5990
6144
  [name: string]: unknown;
@@ -7471,7 +7625,7 @@ interface paths {
7471
7625
  availability: "oss" | "hosted";
7472
7626
  capabilities: {
7473
7627
  /** @enum {string} */
7474
- entity: "product" | "variant" | "media" | "category";
7628
+ entity: "product" | "variant" | "media" | "category" | "content_page";
7475
7629
  /** @enum {string} */
7476
7630
  direction: "push" | "pull" | "bidirectional";
7477
7631
  }[];
@@ -8934,11 +9088,12 @@ interface paths {
8934
9088
  }) | null;
8935
9089
  /** Format: date-time */
8936
9090
  createdAt: string;
9091
+ /** @description Display name for the actor: the user’s name or email for `user` rows, the connector’s name for `connector` rows, null when the actor is unattributed (`system`) or no longer resolvable. */
9092
+ actorLabel: string | null;
8937
9093
  }[];
8938
9094
  limit: number;
8939
9095
  offset: number;
8940
- hasMore?: boolean;
8941
- total?: number;
9096
+ hasMore: boolean;
8942
9097
  };
8943
9098
  };
8944
9099
  };
package/dist/openapi.d.ts CHANGED
@@ -914,11 +914,6 @@ interface paths {
914
914
  content: {
915
915
  "application/json": {
916
916
  code?: string;
917
- /**
918
- * @default product
919
- * @enum {string}
920
- */
921
- entityKind?: "product" | "content";
922
917
  label?: {
923
918
  [key: string]: string;
924
919
  };
@@ -1575,6 +1570,7 @@ interface paths {
1575
1570
  categoryId?: string;
1576
1571
  includeDescendants?: boolean | ("true" | "false" | "1" | "0");
1577
1572
  brand?: string;
1573
+ /** @description Repeatable — `?tag=a&tag=b` matches records carrying ALL listed tags. Values are canonicalized exactly as writes are, so `?tag=Buying%20Guide` matches the stored `buying-guide`; you never have to pre-slugify a filter. Backed by the GIN index on `tags`. */
1578
1574
  tag?: string | string[];
1579
1575
  connectorId?: string;
1580
1576
  updatedSince?: string;
@@ -1621,6 +1617,7 @@ interface paths {
1621
1617
  attributes: (string | number | boolean | ("null" | null)) | unknown[] | {
1622
1618
  [key: string]: unknown;
1623
1619
  };
1620
+ /** @description Tags in canonical form. These are normalized on write (lower-cased, slugified, deduplicated, truncated), so this array will not necessarily match what was submitted — see the `tags` field on the create/update request body for the exact rules. Filter with `?tag=` using either form. */
1624
1621
  tags: string[];
1625
1622
  /** Format: uuid */
1626
1623
  createdBy: string | null;
@@ -1631,7 +1628,7 @@ interface paths {
1631
1628
  }[];
1632
1629
  limit: number;
1633
1630
  offset: number;
1634
- hasMore?: boolean;
1631
+ hasMore: boolean;
1635
1632
  total?: number;
1636
1633
  };
1637
1634
  };
@@ -1670,7 +1667,10 @@ interface paths {
1670
1667
  value?: unknown;
1671
1668
  }[];
1672
1669
  };
1673
- /** @default [] */
1670
+ /**
1671
+ * @description Free-form tags, canonicalized on write and echoed back in canonical form — the response will NOT match your input verbatim. Each tag is lower-cased, stripped of diacritics, has every run of non-alphanumerics replaced with `-`, is trimmed of leading/trailing `-`, and is then truncated to 60 characters. So `"Buying Guide"` is stored and filtered as `buying-guide`. Tags that normalize to nothing (`""`, `"!!"`) are dropped, and duplicates are removed keeping first-occurrence order, so the array you get back may be SHORTER than the one you sent. Note the asymmetry with `maxLength`: an item may be up to 80 characters on input but is truncated to 60 once canonicalized, which can collapse two long tags into one.
1672
+ * @default []
1673
+ */
1674
1674
  tags?: string[];
1675
1675
  };
1676
1676
  };
@@ -1700,6 +1700,7 @@ interface paths {
1700
1700
  attributes: (string | number | boolean | ("null" | null)) | unknown[] | {
1701
1701
  [key: string]: unknown;
1702
1702
  };
1703
+ /** @description Tags in canonical form. These are normalized on write (lower-cased, slugified, deduplicated, truncated), so this array will not necessarily match what was submitted — see the `tags` field on the create/update request body for the exact rules. Filter with `?tag=` using either form. */
1703
1704
  tags: string[];
1704
1705
  /** Format: uuid */
1705
1706
  createdBy: string | null;
@@ -1766,6 +1767,7 @@ interface paths {
1766
1767
  categoryId?: string;
1767
1768
  includeDescendants?: boolean | ("true" | "false" | "1" | "0");
1768
1769
  brand?: string;
1770
+ /** @description Repeatable — `?tag=a&tag=b` matches records carrying ALL listed tags. Values are canonicalized exactly as writes are, so `?tag=Buying%20Guide` matches the stored `buying-guide`; you never have to pre-slugify a filter. Backed by the GIN index on `tags`. */
1769
1771
  tag?: string | string[];
1770
1772
  connectorId?: string;
1771
1773
  updatedSince?: string;
@@ -1985,6 +1987,7 @@ interface paths {
1985
1987
  attributes: (string | number | boolean | ("null" | null)) | unknown[] | {
1986
1988
  [key: string]: unknown;
1987
1989
  };
1990
+ /** @description Tags in canonical form. These are normalized on write (lower-cased, slugified, deduplicated, truncated), so this array will not necessarily match what was submitted — see the `tags` field on the create/update request body for the exact rules. Filter with `?tag=` using either form. */
1988
1991
  tags: string[];
1989
1992
  /** Format: uuid */
1990
1993
  createdBy: string | null;
@@ -2108,6 +2111,7 @@ interface paths {
2108
2111
  value?: unknown;
2109
2112
  }[];
2110
2113
  };
2114
+ /** @description Replaces the full tag list when present. Free-form tags, canonicalized on write and echoed back in canonical form — the response will NOT match your input verbatim. Each tag is lower-cased, stripped of diacritics, has every run of non-alphanumerics replaced with `-`, is trimmed of leading/trailing `-`, and is then truncated to 60 characters. So `"Buying Guide"` is stored and filtered as `buying-guide`. Tags that normalize to nothing (`""`, `"!!"`) are dropped, and duplicates are removed keeping first-occurrence order, so the array you get back may be SHORTER than the one you sent. Note the asymmetry with `maxLength`: an item may be up to 80 characters on input but is truncated to 60 once canonicalized, which can collapse two long tags into one. */
2111
2115
  tags?: string[];
2112
2116
  };
2113
2117
  };
@@ -2137,6 +2141,7 @@ interface paths {
2137
2141
  attributes: (string | number | boolean | ("null" | null)) | unknown[] | {
2138
2142
  [key: string]: unknown;
2139
2143
  };
2144
+ /** @description Tags in canonical form. These are normalized on write (lower-cased, slugified, deduplicated, truncated), so this array will not necessarily match what was submitted — see the `tags` field on the create/update request body for the exact rules. Filter with `?tag=` using either form. */
2140
2145
  tags: string[];
2141
2146
  /** Format: uuid */
2142
2147
  createdBy: string | null;
@@ -2304,6 +2309,7 @@ interface paths {
2304
2309
  attributes: (string | number | boolean | ("null" | null)) | unknown[] | {
2305
2310
  [key: string]: unknown;
2306
2311
  };
2312
+ /** @description Tags in canonical form. These are normalized on write (lower-cased, slugified, deduplicated, truncated), so this array will not necessarily match what was submitted — see the `tags` field on the create/update request body for the exact rules. Filter with `?tag=` using either form. */
2307
2313
  tags: string[];
2308
2314
  /** Format: uuid */
2309
2315
  createdBy: string | null;
@@ -2710,6 +2716,7 @@ interface paths {
2710
2716
  productIds: string[];
2711
2717
  /** @enum {string} */
2712
2718
  mode: "add" | "remove" | "replace";
2719
+ /** @description Free-form tags, canonicalized on write and echoed back in canonical form — the response will NOT match your input verbatim. Each tag is lower-cased, stripped of diacritics, has every run of non-alphanumerics replaced with `-`, is trimmed of leading/trailing `-`, and is then truncated to 60 characters. So `"Buying Guide"` is stored and filtered as `buying-guide`. Tags that normalize to nothing (`""`, `"!!"`) are dropped, and duplicates are removed keeping first-occurrence order, so the array you get back may be SHORTER than the one you sent. Note the asymmetry with `maxLength`: an item may be up to 80 characters on input but is truncated to 60 once canonicalized, which can collapse two long tags into one. */
2713
2720
  tags: string[];
2714
2721
  };
2715
2722
  };
@@ -3514,6 +3521,16 @@ interface paths {
3514
3521
  /**
3515
3522
  * List content pages
3516
3523
  * @description Filters and pagination mirror `GET /v1/products`. `tag` is repeatable and matches pages carrying ALL listed tags.
3524
+ *
3525
+ * Ordering defaults to `updatedAt` descending. For a blog archive sort by `publishedAt`, which imports preserve from the source system:
3526
+ *
3527
+ * ```
3528
+ * curl 'https://api.minipim.com/v1/content?sortBy=publishedAt&sortDir=desc&limit=20'
3529
+ * ```
3530
+ *
3531
+ * Pages with no `publishedAt` sort LAST in both directions — an undated page is unscheduled, not newest.
3532
+ *
3533
+ * `categoryId` is SELF-ONLY. Content is filed against leaf categories, so filtering by a parent returns an empty page unless you add `includeDescendants=true` to match the whole subtree.
3517
3534
  */
3518
3535
  get: {
3519
3536
  parameters: {
@@ -3522,9 +3539,13 @@ interface paths {
3522
3539
  q?: string;
3523
3540
  familyId?: string;
3524
3541
  categoryId?: string;
3542
+ includeDescendants?: boolean | ("true" | "false" | "1" | "0");
3525
3543
  channelId?: string;
3544
+ /** @description Repeatable — `?tag=a&tag=b` matches records carrying ALL listed tags. Values are canonicalized exactly as writes are, so `?tag=Buying%20Guide` matches the stored `buying-guide`; you never have to pre-slugify a filter. */
3526
3545
  tag?: string | string[];
3527
3546
  updatedSince?: string;
3547
+ sortBy?: "publishedAt" | "updatedAt" | "createdAt" | "title";
3548
+ sortDir?: "asc" | "desc";
3528
3549
  limit?: number;
3529
3550
  offset?: number;
3530
3551
  };
@@ -3563,6 +3584,7 @@ interface paths {
3563
3584
  attributes: (string | number | boolean | ("null" | null)) | unknown[] | {
3564
3585
  [key: string]: unknown;
3565
3586
  };
3587
+ /** @description Tags in canonical form. These are normalized on write (lower-cased, slugified, deduplicated, truncated), so this array will not necessarily match what was submitted — see the `tags` field on the create/update request body for the exact rules. Filter with `?tag=` using either form. */
3566
3588
  tags: string[];
3567
3589
  /** Format: uuid */
3568
3590
  createdBy: string | null;
@@ -3571,8 +3593,7 @@ interface paths {
3571
3593
  }[];
3572
3594
  limit: number;
3573
3595
  offset: number;
3574
- hasMore?: boolean;
3575
- total?: number;
3596
+ hasMore: boolean;
3576
3597
  };
3577
3598
  };
3578
3599
  };
@@ -3629,7 +3650,10 @@ interface paths {
3629
3650
  value?: unknown;
3630
3651
  }[];
3631
3652
  };
3632
- /** @default [] */
3653
+ /**
3654
+ * @description Free-form tags, canonicalized on write and echoed back in canonical form — the response will NOT match your input verbatim. Each tag is lower-cased, stripped of diacritics, has every run of non-alphanumerics replaced with `-`, is trimmed of leading/trailing `-`, and is then truncated to 60 characters. So `"Buying Guide"` is stored and filtered as `buying-guide`. Tags that normalize to nothing (`""`, `"!!"`) are dropped, and duplicates are removed keeping first-occurrence order, so the array you get back may be SHORTER than the one you sent. Note the asymmetry with `maxLength`: an item may be up to 80 characters on input but is truncated to 60 once canonicalized, which can collapse two long tags into one.
3655
+ * @default []
3656
+ */
3633
3657
  tags?: string[];
3634
3658
  };
3635
3659
  };
@@ -3663,6 +3687,7 @@ interface paths {
3663
3687
  attributes: (string | number | boolean | ("null" | null)) | unknown[] | {
3664
3688
  [key: string]: unknown;
3665
3689
  };
3690
+ /** @description Tags in canonical form. These are normalized on write (lower-cased, slugified, deduplicated, truncated), so this array will not necessarily match what was submitted — see the `tags` field on the create/update request body for the exact rules. Filter with `?tag=` using either form. */
3666
3691
  tags: string[];
3667
3692
  /** Format: uuid */
3668
3693
  createdBy: string | null;
@@ -3739,6 +3764,63 @@ interface paths {
3739
3764
  patch?: never;
3740
3765
  trace?: never;
3741
3766
  };
3767
+ "/v1/content/tags": {
3768
+ parameters: {
3769
+ query?: never;
3770
+ header?: never;
3771
+ path?: never;
3772
+ cookie?: never;
3773
+ };
3774
+ /**
3775
+ * List all content-page tags in use, with counts
3776
+ * @description Every distinct tag currently on at least one content page, ordered by usage. Powers tag autocomplete in the editor, which is what keeps a vocabulary from drifting into `guide` / `guides` / `Guides`. Filter pages by tag with `GET /v1/content?tag=<tag>` (repeatable; multiple tags AND together).
3777
+ */
3778
+ get: {
3779
+ parameters: {
3780
+ query?: never;
3781
+ header?: never;
3782
+ path?: never;
3783
+ cookie?: never;
3784
+ };
3785
+ requestBody?: never;
3786
+ responses: {
3787
+ /** @description Default Response */
3788
+ 200: {
3789
+ headers: {
3790
+ [name: string]: unknown;
3791
+ };
3792
+ content: {
3793
+ "application/json": {
3794
+ value: string;
3795
+ count: number;
3796
+ }[];
3797
+ };
3798
+ };
3799
+ /** @description Default Response */
3800
+ 403: {
3801
+ headers: {
3802
+ [name: string]: unknown;
3803
+ };
3804
+ content: {
3805
+ "application/json": {
3806
+ error: {
3807
+ code: string;
3808
+ message: string;
3809
+ details?: unknown;
3810
+ };
3811
+ };
3812
+ };
3813
+ };
3814
+ };
3815
+ };
3816
+ put?: never;
3817
+ post?: never;
3818
+ delete?: never;
3819
+ options?: never;
3820
+ head?: never;
3821
+ patch?: never;
3822
+ trace?: never;
3823
+ };
3742
3824
  "/v1/content/{id}": {
3743
3825
  parameters: {
3744
3826
  query?: never;
@@ -3786,6 +3868,7 @@ interface paths {
3786
3868
  attributes: (string | number | boolean | ("null" | null)) | unknown[] | {
3787
3869
  [key: string]: unknown;
3788
3870
  };
3871
+ /** @description Tags in canonical form. These are normalized on write (lower-cased, slugified, deduplicated, truncated), so this array will not necessarily match what was submitted — see the `tags` field on the create/update request body for the exact rules. Filter with `?tag=` using either form. */
3789
3872
  tags: string[];
3790
3873
  /** Format: uuid */
3791
3874
  createdBy: string | null;
@@ -3918,6 +4001,7 @@ interface paths {
3918
4001
  value?: unknown;
3919
4002
  }[];
3920
4003
  };
4004
+ /** @description Replaces the full tag list when present. Free-form tags, canonicalized on write and echoed back in canonical form — the response will NOT match your input verbatim. Each tag is lower-cased, stripped of diacritics, has every run of non-alphanumerics replaced with `-`, is trimmed of leading/trailing `-`, and is then truncated to 60 characters. So `"Buying Guide"` is stored and filtered as `buying-guide`. Tags that normalize to nothing (`""`, `"!!"`) are dropped, and duplicates are removed keeping first-occurrence order, so the array you get back may be SHORTER than the one you sent. Note the asymmetry with `maxLength`: an item may be up to 80 characters on input but is truncated to 60 once canonicalized, which can collapse two long tags into one. */
3921
4005
  tags?: string[];
3922
4006
  };
3923
4007
  };
@@ -3951,6 +4035,7 @@ interface paths {
3951
4035
  attributes: (string | number | boolean | ("null" | null)) | unknown[] | {
3952
4036
  [key: string]: unknown;
3953
4037
  };
4038
+ /** @description Tags in canonical form. These are normalized on write (lower-cased, slugified, deduplicated, truncated), so this array will not necessarily match what was submitted — see the `tags` field on the create/update request body for the exact rules. Filter with `?tag=` using either form. */
3954
4039
  tags: string[];
3955
4040
  /** Format: uuid */
3956
4041
  createdBy: string | null;
@@ -5913,7 +5998,44 @@ interface paths {
5913
5998
  path?: never;
5914
5999
  cookie?: never;
5915
6000
  };
5916
- requestBody?: never;
6001
+ requestBody: {
6002
+ content: {
6003
+ "multipart/form-data": {
6004
+ /**
6005
+ * Format: binary
6006
+ * @description The file to upload. Images, video, PDF, Office documents and glTF are accepted; the 422 response lists every allowed type in `details.allowed`. You do NOT have to get the content type right: when you send `application/octet-stream` (or no type at all), the leading bytes are sniffed and the detected type is used — so a PNG whose filename lost its extension uploads fine. SVG, CSV, plain text and Office formats have no distinguishing magic bytes and still need an explicit type. If a specific declared type contradicts the bytes, the bytes win.
6007
+ */
6008
+ file: string;
6009
+ /**
6010
+ * @description Attach the upload in the same transaction. Requires `entityId`; supplying only one of the pair uploads the file WITHOUT associating it. A value outside the enum is a 422, not a silent miss.
6011
+ * @enum {string}
6012
+ */
6013
+ entityType?: "product" | "variant" | "content_page";
6014
+ /**
6015
+ * Format: uuid
6016
+ * @description The id of the entity named by `entityType`.
6017
+ */
6018
+ entityId?: string;
6019
+ /**
6020
+ * @description Association role. Ignored unless `entityType`+`entityId` are present. A value outside this enum is rejected with a 422 that lists the accepted values in `details.accepted`.
6021
+ * @default gallery
6022
+ * @enum {string}
6023
+ */
6024
+ role?: "hero" | "gallery" | "thumbnail" | "technical" | "lifestyle" | "swatch";
6025
+ /**
6026
+ * @description Sort position within the entity’s gallery. Must be a non-negative integer; anything else is a 422.
6027
+ * @default 0
6028
+ */
6029
+ position?: number;
6030
+ /**
6031
+ * @description A JSON OBJECT keyed by locale, sent as a STRING — e.g. `{"en_US":"Blue widget on white"}`. Unparseable JSON, or JSON that is not an object of locale → string, does NOT fail the upload: the file is stored, no alt text is saved, and the 201 response carries a `warnings` entry saying so. Check `warnings` if you send alt text programmatically. Omit the field entirely if you have none.
6032
+ *
6033
+ * (0.20.0 briefly made this a 422; 0.21.0 restored the original behaviour and added `warnings` instead, so the problem is reported without breaking callers.)
6034
+ */
6035
+ altText?: string;
6036
+ };
6037
+ };
6038
+ };
5917
6039
  responses: {
5918
6040
  /** @description Default Response */
5919
6041
  201: {
@@ -5966,6 +6088,8 @@ interface paths {
5966
6088
  channelId: string | null;
5967
6089
  };
5968
6090
  url: string;
6091
+ /** @description Non-fatal problems with this upload — currently only malformed `altText`. The upload succeeded; something you sent was ignored. Absent when there is nothing to report. */
6092
+ warnings?: string[];
5969
6093
  };
5970
6094
  };
5971
6095
  };
@@ -5985,6 +6109,36 @@ interface paths {
5985
6109
  };
5986
6110
  };
5987
6111
  /** @description Default Response */
6112
+ 413: {
6113
+ headers: {
6114
+ [name: string]: unknown;
6115
+ };
6116
+ content: {
6117
+ "application/json": {
6118
+ error: {
6119
+ code: string;
6120
+ message: string;
6121
+ details?: unknown;
6122
+ };
6123
+ };
6124
+ };
6125
+ };
6126
+ /** @description Default Response */
6127
+ 422: {
6128
+ headers: {
6129
+ [name: string]: unknown;
6130
+ };
6131
+ content: {
6132
+ "application/json": {
6133
+ error: {
6134
+ code: string;
6135
+ message: string;
6136
+ details?: unknown;
6137
+ };
6138
+ };
6139
+ };
6140
+ };
6141
+ /** @description Default Response */
5988
6142
  503: {
5989
6143
  headers: {
5990
6144
  [name: string]: unknown;
@@ -7471,7 +7625,7 @@ interface paths {
7471
7625
  availability: "oss" | "hosted";
7472
7626
  capabilities: {
7473
7627
  /** @enum {string} */
7474
- entity: "product" | "variant" | "media" | "category";
7628
+ entity: "product" | "variant" | "media" | "category" | "content_page";
7475
7629
  /** @enum {string} */
7476
7630
  direction: "push" | "pull" | "bidirectional";
7477
7631
  }[];
@@ -8934,11 +9088,12 @@ interface paths {
8934
9088
  }) | null;
8935
9089
  /** Format: date-time */
8936
9090
  createdAt: string;
9091
+ /** @description Display name for the actor: the user’s name or email for `user` rows, the connector’s name for `connector` rows, null when the actor is unattributed (`system`) or no longer resolvable. */
9092
+ actorLabel: string | null;
8937
9093
  }[];
8938
9094
  limit: number;
8939
9095
  offset: number;
8940
- hasMore?: boolean;
8941
- total?: number;
9096
+ hasMore: boolean;
8942
9097
  };
8943
9098
  };
8944
9099
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@minipim/sdk",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "description": "Typed TypeScript client for the MiniPim API.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/Epic-Design-Labs/minipim",