@sdg.la/wishlist-stack-sdk 0.14.0 → 0.16.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 +117 -15
- package/dist/index.cjs +17 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +43 -6
- package/dist/index.d.ts +43 -6
- package/dist/index.js +17 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,6 +11,8 @@ TypeScript/JavaScript SDK for the Wishlist Stack API.
|
|
|
11
11
|
- [Requirements](#requirements)
|
|
12
12
|
- [Installation](#installation)
|
|
13
13
|
- [Quick Start](#quick-start)
|
|
14
|
+
- [Choose a transport](#choose-a-transport)
|
|
15
|
+
- [Upgrading the default origin](#upgrading-the-default-origin)
|
|
14
16
|
- [Usage](#usage)
|
|
15
17
|
- [Server / Node.js / Workers](#server--nodejs--workers)
|
|
16
18
|
- [Browser](#browser)
|
|
@@ -37,6 +39,7 @@ TypeScript/JavaScript SDK for the Wishlist Stack API.
|
|
|
37
39
|
- **Built-in error handling** — Structured `WishlistStackApiError` with status codes, `Retry-After` / rate-limit headers, and API error messages
|
|
38
40
|
- **Pagination support** — List endpoints support `page` and `pageSize` (max **25**); helpers fetch all pages when needed
|
|
39
41
|
- **Batch helpers** — `lists.addItemsBatched` chunks adds to the max of 25 items per request
|
|
42
|
+
- **Fast membership checks** — `lists.containsVariants` checks up to 100 variants without hydrating a list
|
|
40
43
|
- **Sort support** — Collection endpoints accept `sortBy` (`position` | `createdAt` | `updatedAt`) and `sortDirection` (`asc` | `desc`)
|
|
41
44
|
|
|
42
45
|
## Requirements
|
|
@@ -68,7 +71,7 @@ const client = createWishlistStackClient({
|
|
|
68
71
|
customerAccessToken: 'customer-access-token', // required for authenticated endpoints
|
|
69
72
|
// optional:
|
|
70
73
|
// defaultTimeoutMs: 10_000,
|
|
71
|
-
// retryOnRateLimit: true, //
|
|
74
|
+
// retryOnRateLimit: true, // safe reads retry once on HTTP 429
|
|
72
75
|
});
|
|
73
76
|
|
|
74
77
|
// Fetch all groups
|
|
@@ -78,14 +81,64 @@ const { groups } = await client.groups.getAll();
|
|
|
78
81
|
const { lists } = await client.lists.getAll();
|
|
79
82
|
```
|
|
80
83
|
|
|
84
|
+
## Choose a transport
|
|
85
|
+
|
|
86
|
+
For **Shopify Online Store themes**, we recommend the installed, same-origin app
|
|
87
|
+
proxy. Use its configured prefix (normally `/apps/wishlist-stack`) as `baseUrl`.
|
|
88
|
+
Do not append `/api`; the SDK adds each endpoint path. Keep same-origin cookies
|
|
89
|
+
so Shopify can sign the logged-in shopper identity. A customer access token is
|
|
90
|
+
not required for private calls made through that signed proxy; a shopper must
|
|
91
|
+
still be signed in. Public shared reads also work for signed-out visitors.
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
const client = createWishlistStackClient({
|
|
95
|
+
apiKey: 'YOUR_MERCHANT_API_KEY',
|
|
96
|
+
baseUrl: '/apps/wishlist-stack',
|
|
97
|
+
fetch: (input, init) => window.fetch(input, {
|
|
98
|
+
...init,
|
|
99
|
+
credentials: 'same-origin',
|
|
100
|
+
}),
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const firstPage = await client.lists.getById('list-id', {page: 1, pageSize: 20});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
For **headless storefronts and server integrations**, use
|
|
107
|
+
`https://app.wishliststack.com` and the documented merchant key/customer token
|
|
108
|
+
authentication. Do not assume an Online Store app proxy exists on a headless
|
|
109
|
+
hostname. Direct and proxy transports expose the same `/api/*` methods and
|
|
110
|
+
payloads; authentication is specific to each transport.
|
|
111
|
+
|
|
112
|
+
Prefer explicit 20-item pages for storefront rendering and follow pagination
|
|
113
|
+
metadata. Existing page sizes up to **25**, including the SDK's default, remain
|
|
114
|
+
supported. Use all-page helpers only when the operation needs every item.
|
|
115
|
+
|
|
116
|
+
## Upgrading the default origin
|
|
117
|
+
|
|
118
|
+
Starting with **0.16.0**, omitting `baseUrl` uses
|
|
119
|
+
`https://app.wishliststack.com`. Earlier package versions keep their original
|
|
120
|
+
default. An explicitly configured `baseUrl` is always preserved, including an
|
|
121
|
+
existing compatibility hostname or a same-origin proxy path.
|
|
122
|
+
|
|
123
|
+
Before upgrading a direct browser integration that uses the default, allow
|
|
124
|
+
`https://app.wishliststack.com` in CSP `connect-src`. Keep the previous origin
|
|
125
|
+
allowed while older bundles are still cached. Alternatively, keep your current
|
|
126
|
+
explicit `baseUrl` during a staged upgrade. This release does not change method
|
|
127
|
+
names, authentication headers, payloads or pagination limits, and does not
|
|
128
|
+
automatically switch an existing integration to the proxy.
|
|
129
|
+
|
|
81
130
|
### Pagination, batching, and add responses
|
|
82
131
|
|
|
83
|
-
The API paginates list detail
|
|
132
|
+
The API paginates list detail when `pageSize` is supplied (max **25**) and
|
|
133
|
+
always includes an add **delta** (`{ listId, addedItems, addedCount }`). Backend
|
|
134
|
+
compatibility mode may additionally return the full list from add and returns
|
|
135
|
+
all list items when `pageSize` is omitted; the SDK ignores those additive fields.
|
|
84
136
|
|
|
85
137
|
| Concern | Guidance |
|
|
86
138
|
|---------|----------|
|
|
87
139
|
| List detail | Prefer `page` / `pageSize` ≤ 25, or `lists.getByIdAllItems` for every item |
|
|
88
140
|
| Adding many items | Use `lists.addItemsBatched` (chunks of ≤ 25) |
|
|
141
|
+
| Checking membership | Use `lists.containsVariants` for up to 100 variant IDs |
|
|
89
142
|
| Add response | `{ listId, addedItems, addedCount }` |
|
|
90
143
|
| Create + items | Do not send `variantIds` on create; create the list, then `addItems` |
|
|
91
144
|
| `quantity` on add | Supported **1–999** |
|
|
@@ -125,7 +178,7 @@ import { createWishlistStackClient } from '@sdg.la/wishlist-stack-sdk';
|
|
|
125
178
|
|
|
126
179
|
const client = createWishlistStackClient({
|
|
127
180
|
apiKey: 'YOUR_API_KEY',
|
|
128
|
-
baseUrl: 'https://
|
|
181
|
+
baseUrl: 'https://app.wishliststack.com', // optional direct API default
|
|
129
182
|
customerAccessToken: '...optional...',
|
|
130
183
|
});
|
|
131
184
|
|
|
@@ -140,10 +193,11 @@ You can load the SDK in plain HTML without a bundler by using a `<script type="m
|
|
|
140
193
|
|
|
141
194
|
```html
|
|
142
195
|
<script type="module">
|
|
143
|
-
import { createWishlistStackClient } from "https://cdn.jsdelivr.net/npm/@sdg.la/wishlist-stack-sdk@0.
|
|
196
|
+
import { createWishlistStackClient } from "https://cdn.jsdelivr.net/npm/@sdg.la/wishlist-stack-sdk@0.15.0/+esm";
|
|
144
197
|
|
|
145
198
|
window.wishlistClient = createWishlistStackClient({
|
|
146
199
|
apiKey: "YOUR_MERCHANT_API_KEY",
|
|
200
|
+
baseUrl: "https://app.wishliststack.com", // explicit for this pinned version
|
|
147
201
|
customerAccessToken: "...",
|
|
148
202
|
});
|
|
149
203
|
|
|
@@ -159,7 +213,11 @@ Pin the version in the CDN URL (as shown above) so updates do not break your int
|
|
|
159
213
|
|
|
160
214
|
### Shopify Liquid authentication
|
|
161
215
|
|
|
162
|
-
|
|
216
|
+
Direct authenticated SDK calls require a customer access token. The recommended
|
|
217
|
+
same-origin app proxy uses Shopify's signed shopper identity instead (see
|
|
218
|
+
[Choose a transport](#choose-a-transport)). If a Liquid integration intentionally
|
|
219
|
+
uses the direct API, obtain a token through Shopify's Customer Account API OAuth
|
|
220
|
+
flow in the browser.
|
|
163
221
|
|
|
164
222
|
See [AUTH_EXAMPLE.md](./AUTH_EXAMPLE.md) for an example-only reference implementation adapted from Shopify's docs.
|
|
165
223
|
|
|
@@ -213,7 +271,7 @@ Groups endpoints may return **503** with message `Groups API disabled for this m
|
|
|
213
271
|
|
|
214
272
|
## Pagination
|
|
215
273
|
|
|
216
|
-
Endpoints that return lists support pagination via query parameters. Keep `pageSize` in **1–25** (use `clampPageSize()`). Prefer `lists.getByIdAllItems()` when you need every item.
|
|
274
|
+
Endpoints that return lists support pagination via query parameters. Keep `pageSize` in **1–25** (use `clampPageSize()`). Prefer `lists.getByIdAllItems()` when you need every item; it always supplies `pageSize`, so it behaves consistently in strict and compatibility backend modes.
|
|
217
275
|
|
|
218
276
|
```ts
|
|
219
277
|
import { clampPageSize } from '@sdg.la/wishlist-stack-sdk';
|
|
@@ -237,7 +295,7 @@ await client.lists.getById('list-id', {
|
|
|
237
295
|
await client.lists.getByIdAllItems('list-id', { pageSize: 25 });
|
|
238
296
|
```
|
|
239
297
|
|
|
240
|
-
**
|
|
298
|
+
**Collection pagination response:**
|
|
241
299
|
|
|
242
300
|
```ts
|
|
243
301
|
{
|
|
@@ -248,6 +306,9 @@ await client.lists.getByIdAllItems('list-id', { pageSize: 25 });
|
|
|
248
306
|
}
|
|
249
307
|
```
|
|
250
308
|
|
|
309
|
+
List detail uses `ListDetailPagination`, which exposes `totalItems`, the
|
|
310
|
+
`totalCount` compatibility alias, and next/previous-page flags.
|
|
311
|
+
|
|
251
312
|
## Sorting
|
|
252
313
|
|
|
253
314
|
Collection endpoints accept optional sort parameters. Defaults match historical behavior (`sortBy=position`, `sortDirection=asc`). Sorting applies only to the primary collection returned by the endpoint.
|
|
@@ -270,7 +331,7 @@ await client.shared.getSharedList('list-id', { sortBy: 'createdAt', sortDirectio
|
|
|
270
331
|
|
|
271
332
|
### Groups
|
|
272
333
|
|
|
273
|
-
> [View full Groups API reference](https://
|
|
334
|
+
> [View full Groups API reference](https://app.wishliststack.com/docs#/groups)
|
|
274
335
|
|
|
275
336
|
---
|
|
276
337
|
|
|
@@ -663,7 +724,7 @@ await client.groups.unshare('group-id');
|
|
|
663
724
|
|
|
664
725
|
### Lists
|
|
665
726
|
|
|
666
|
-
> [View full Lists API reference](https://
|
|
727
|
+
> [View full Lists API reference](https://app.wishliststack.com/docs#/lists)
|
|
667
728
|
|
|
668
729
|
---
|
|
669
730
|
|
|
@@ -722,13 +783,13 @@ const { lists, pagination } = await client.lists.getAll({ page: 1, pageSize: 10,
|
|
|
722
783
|
|
|
723
784
|
#### `lists.getById(listId, query?)`
|
|
724
785
|
|
|
725
|
-
Fetch a single list by ID. Items are hydrated with Shopify product data
|
|
786
|
+
Fetch a single list by ID. Items are hydrated with Shopify product data. Pass pagination options for consistent paging across strict and compatibility backend modes (max `pageSize` **25**).
|
|
726
787
|
|
|
727
788
|
- **Endpoint:** `GET /api/lists/{listId}`
|
|
728
789
|
- **Parameters:**
|
|
729
790
|
- `listId` — `string`
|
|
730
791
|
- `query?` — `{ page?: number; pageSize?: number; sortBy?: 'position' | 'createdAt' | 'updatedAt'; sortDirection?: 'asc' | 'desc' }`
|
|
731
|
-
- **Returns:** `Promise<GetListResponse>` (`ListDetail & { pagination:
|
|
792
|
+
- **Returns:** `Promise<GetListResponse>` (`ListDetail & { pagination: ListDetailPagination }`)
|
|
732
793
|
|
|
733
794
|
```ts
|
|
734
795
|
const list = await client.lists.getById('list-id', { page: 1, pageSize: 25, sortBy: 'updatedAt', sortDirection: 'desc' });
|
|
@@ -807,12 +868,33 @@ const full = await client.lists.getByIdAllItems('list-id', { pageSize: 25 });
|
|
|
807
868
|
|
|
808
869
|
---
|
|
809
870
|
|
|
871
|
+
#### `lists.containsVariants(listId, body)`
|
|
872
|
+
|
|
873
|
+
Check whether up to **100** Shopify product variants are present without product hydration or paging through the list. Numeric IDs and ProductVariant GIDs are accepted; response keys preserve the supplied IDs. `matches` contains lightweight item records for property-aware duplicate and move flows.
|
|
874
|
+
|
|
875
|
+
- **Endpoint:** `POST /api/lists/{listId}/contains`
|
|
876
|
+
- **Parameters:** `body` — `{ variantIds: string[] }`
|
|
877
|
+
- **Returns:** `Promise<ContainsVariantsResponse>`
|
|
878
|
+
|
|
879
|
+
```ts
|
|
880
|
+
const { present, matches } = await client.lists.containsVariants('list-id', {
|
|
881
|
+
variantIds: ['46932429275374', 'gid://shopify/ProductVariant/46932429275375'],
|
|
882
|
+
});
|
|
883
|
+
|
|
884
|
+
if (present['46932429275374']) {
|
|
885
|
+
const existingItems = matches['46932429275374'];
|
|
886
|
+
// Each match includes id, quantity, position, note, and properties.
|
|
887
|
+
}
|
|
888
|
+
```
|
|
889
|
+
|
|
890
|
+
---
|
|
891
|
+
|
|
810
892
|
#### `lists.create(body)`
|
|
811
893
|
|
|
812
894
|
Create a new list, optionally assigned to a group. Do **not** send `variantIds` on create (the API rejects them). Create the list, then call `addItems` / `addItemsBatched`.
|
|
813
895
|
|
|
814
896
|
- **Endpoint:** `POST /api/lists`
|
|
815
|
-
- **Parameters:** `body` — `{ name
|
|
897
|
+
- **Parameters:** `body` — `{ name: string; description?: string; groupId?: string }`
|
|
816
898
|
- **Returns:** `Promise<CreateListResponse>`
|
|
817
899
|
|
|
818
900
|
```ts
|
|
@@ -951,8 +1033,8 @@ Add one or more items to a list. Prefer `lists.addItemsBatched` when sending mor
|
|
|
951
1033
|
|
|
952
1034
|
```ts
|
|
953
1035
|
type AddItemsToListBody = {
|
|
954
|
-
items
|
|
955
|
-
variantId
|
|
1036
|
+
items: Array<{
|
|
1037
|
+
variantId: string;
|
|
956
1038
|
/** Quantity 1–999. */
|
|
957
1039
|
quantity?: number;
|
|
958
1040
|
note?: string;
|
|
@@ -1180,7 +1262,7 @@ await client.lists.unshare('list-id');
|
|
|
1180
1262
|
|
|
1181
1263
|
Public read-only endpoints for accessing shared lists and groups. These require only the merchant `apiKey` — no customer access token needed.
|
|
1182
1264
|
|
|
1183
|
-
> [View full Shared API reference](https://
|
|
1265
|
+
> [View full Shared API reference](https://app.wishliststack.com/docs#/shared)
|
|
1184
1266
|
|
|
1185
1267
|
---
|
|
1186
1268
|
|
|
@@ -1259,6 +1341,8 @@ import type {
|
|
|
1259
1341
|
AddItemsToListBody,
|
|
1260
1342
|
AddItemsToListResponse,
|
|
1261
1343
|
AddItemsToListDeltaResponse,
|
|
1344
|
+
ContainsVariantsBody,
|
|
1345
|
+
ContainsVariantsResponse,
|
|
1262
1346
|
UpdateListItemBody,
|
|
1263
1347
|
ReorderListItemsBody,
|
|
1264
1348
|
ReorderListItemsResponse,
|
|
@@ -1279,6 +1363,7 @@ import type {
|
|
|
1279
1363
|
|
|
1280
1364
|
// Common
|
|
1281
1365
|
Pagination,
|
|
1366
|
+
ListDetailPagination,
|
|
1282
1367
|
PaginationParams,
|
|
1283
1368
|
OkResponse,
|
|
1284
1369
|
Image,
|
|
@@ -1304,6 +1389,23 @@ type Pagination = {
|
|
|
1304
1389
|
|
|
1305
1390
|
</details>
|
|
1306
1391
|
|
|
1392
|
+
<details>
|
|
1393
|
+
<summary><code>ListDetailPagination</code></summary>
|
|
1394
|
+
|
|
1395
|
+
```ts
|
|
1396
|
+
type ListDetailPagination = {
|
|
1397
|
+
page: number;
|
|
1398
|
+
pageSize: number;
|
|
1399
|
+
totalItems: number;
|
|
1400
|
+
totalCount: number; // compatibility alias for totalItems
|
|
1401
|
+
totalPages: number;
|
|
1402
|
+
hasNextPage: boolean;
|
|
1403
|
+
hasPreviousPage: boolean;
|
|
1404
|
+
};
|
|
1405
|
+
```
|
|
1406
|
+
|
|
1407
|
+
</details>
|
|
1408
|
+
|
|
1307
1409
|
<details>
|
|
1308
1410
|
<summary><code>GroupSummary</code></summary>
|
|
1309
1411
|
|
package/dist/index.cjs
CHANGED
|
@@ -6,7 +6,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
6
6
|
|
|
7
7
|
// src/constants.ts
|
|
8
8
|
var MAX_PAGINATION_SIZE = 25;
|
|
9
|
-
var BASE_URL = "https://
|
|
9
|
+
var BASE_URL = "https://app.wishliststack.com";
|
|
10
10
|
|
|
11
11
|
// src/client/query.ts
|
|
12
12
|
function toQueryString(query) {
|
|
@@ -166,7 +166,8 @@ function createRequest(ctx) {
|
|
|
166
166
|
}
|
|
167
167
|
};
|
|
168
168
|
let res = await doFetch();
|
|
169
|
-
|
|
169
|
+
const retryable = args.method === "GET" || args.retryable === true;
|
|
170
|
+
if (!res.ok && res.status === 429 && ctx.retryOnRateLimit && retryable) {
|
|
170
171
|
const retryAfter = res.headers.get("retry-after") ?? void 0;
|
|
171
172
|
await sleep(jitterDelayMs(parseRetryAfterMs(retryAfter)));
|
|
172
173
|
res = await doFetch();
|
|
@@ -313,12 +314,26 @@ function createListsResource(request) {
|
|
|
313
314
|
* when sending more than 25 items.
|
|
314
315
|
*/
|
|
315
316
|
addItems,
|
|
317
|
+
/**
|
|
318
|
+
* Check whether up to 100 variants are present without hydrating or
|
|
319
|
+
* paging through the list. Response keys preserve the supplied IDs.
|
|
320
|
+
*/
|
|
321
|
+
containsVariants: (listId, body) => request({
|
|
322
|
+
method: "POST",
|
|
323
|
+
path: `/api/lists/${encodeURIComponent(listId)}/contains`,
|
|
324
|
+
auth: "authenticated",
|
|
325
|
+
body,
|
|
326
|
+
retryable: true
|
|
327
|
+
}),
|
|
316
328
|
/**
|
|
317
329
|
* Add items in sequential batches of ≤25 (API hard max).
|
|
318
330
|
* Merges `{ addedItems, addedCount }` across batches.
|
|
319
331
|
*/
|
|
320
332
|
addItemsBatched: async (listId, body, opts) => {
|
|
321
333
|
const items = body.items ?? [];
|
|
334
|
+
if (items.length === 0) {
|
|
335
|
+
throw new Error("lists.addItemsBatched requires at least one item");
|
|
336
|
+
}
|
|
322
337
|
const batchSize = opts?.batchSize ?? MAX_PAGINATION_SIZE;
|
|
323
338
|
const chunks = chunkItems(items, batchSize);
|
|
324
339
|
const merged = {
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.ts","../src/client/query.ts","../src/client/errors.ts","../src/client/request.ts","../src/helpers/pagination.ts","../src/resources/lists/index.ts","../src/resources/groups/index.ts","../src/resources/shared/index.ts","../src/client/createWishlistStackClient.ts","../src/WishlistStackClient.ts","../src/types/pagination.ts","../src/types/query-options.ts","../src/types/guards.ts"],"names":["isRecord"],"mappings":"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","file":"index.cjs","sourcesContent":["export const MAX_PAGINATION_SIZE = 25 as const;\nexport const BASE_URL = \"https://wishlist.devteam.run\" as const;\n\n","export type QueryValue =\n | string\n | number\n | boolean\n | null\n | undefined\n | Array<string | number | boolean | null | undefined>;\n\nexport type Query = Record<string, QueryValue>;\n\nexport function toQueryString(query?: Query): string {\n if (!query) return \"\";\n\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined || value === null) continue;\n if (Array.isArray(value)) {\n for (const v of value) {\n if (v === undefined || v === null) continue;\n params.append(key, String(v));\n }\n continue;\n }\n params.set(key, String(value));\n }\n\n const qs = params.toString();\n return qs ? `?${qs}` : \"\";\n}\n\n","export type WishlistStackApiErrorDetails<TBody = unknown> = {\n status: number;\n url: string;\n method: string;\n requestId?: string;\n body?: TBody;\n /** Value of the `Retry-After` response header when present (seconds or HTTP-date). */\n retryAfter?: string;\n /** Selected rate-limit response headers when present. */\n rateLimit?: {\n limit?: string;\n remaining?: string;\n reset?: string;\n };\n};\n\ntype ApiErrorItemLike = { message?: unknown; field?: unknown };\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isApiErrorItemLike(value: unknown): value is ApiErrorItemLike {\n return isRecord(value) && \"message\" in value;\n}\n\nfunction extractApiErrors(body: unknown): Array<{ message: string; field?: string }> | undefined {\n if (!isRecord(body)) return undefined;\n const errors = body.errors;\n if (!Array.isArray(errors)) return undefined;\n const out: Array<{ message: string; field?: string }> = [];\n for (const e of errors) {\n if (!isApiErrorItemLike(e)) continue;\n const msg = typeof e.message === \"string\" ? e.message : undefined;\n if (!msg) continue;\n const field = typeof (e as any).field === \"string\" ? (e as any).field : undefined;\n out.push(field ? { message: msg, field } : { message: msg });\n }\n return out.length ? out : undefined;\n}\n\nexport class WishlistStackApiError<TBody = unknown> extends Error {\n readonly name = \"WishlistStackApiError\";\n readonly status: number;\n readonly url: string;\n readonly method: string;\n readonly requestId?: string;\n readonly body?: TBody;\n readonly retryAfter?: string;\n readonly rateLimit?: WishlistStackApiErrorDetails[\"rateLimit\"];\n\n constructor(message: string, details: WishlistStackApiErrorDetails<TBody>) {\n super(message);\n this.status = details.status;\n this.url = details.url;\n this.method = details.method;\n this.requestId = details.requestId;\n this.body = details.body;\n this.retryAfter = details.retryAfter;\n this.rateLimit = details.rateLimit;\n }\n\n /**\n * Best-effort extraction of API error items from the response body.\n * Useful for UI/logging without needing to know the exact response shape.\n */\n get apiErrors(): Array<{ message: string; field?: string }> | undefined {\n return extractApiErrors(this.body);\n }\n\n /**\n * Convenience: extracted error messages (if present).\n */\n get apiErrorMessages(): string[] | undefined {\n const errs = this.apiErrors;\n return errs?.map((e) => e.message);\n }\n}\n\n/**\n * Bundler-safe type guard (prefer this over `instanceof WishlistStackApiError`).\n */\nexport function isWishlistStackApiError(value: unknown): value is WishlistStackApiError<unknown> {\n if (!isRecord(value)) return false;\n return (\n (value as any).name === \"WishlistStackApiError\" &&\n typeof (value as any).status === \"number\" &&\n typeof (value as any).url === \"string\" &&\n typeof (value as any).method === \"string\"\n );\n}\n","import { toQueryString, type Query } from \"./query\";\nimport { WishlistStackApiError } from \"./errors\";\nimport type { ApiErrorResponse } from \"../types/common\";\n\nexport type FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;\n\nexport type AuthMode = \"authenticated\" | \"merchant\";\n\nexport type RequestContext = {\n baseUrl: string;\n apiKey: string;\n customerAccessToken?: string;\n fetch: FetchLike;\n /** Applied when a call does not pass `timeoutMs`. */\n defaultTimeoutMs?: number;\n /** When true, retry a single time on HTTP 429 with jittered delay. */\n retryOnRateLimit?: boolean;\n};\n\nexport type RequestArgs<TBody> = {\n method: \"GET\" | \"POST\" | \"PATCH\" | \"DELETE\";\n path: string;\n auth: AuthMode;\n query?: Query;\n body?: TBody;\n headers?: Record<string, string>;\n signal?: AbortSignal;\n timeoutMs?: number;\n};\n\nasync function safeParseJson(res: Response): Promise<unknown | undefined> {\n const contentType = res.headers.get(\"content-type\") ?? \"\";\n if (!contentType.toLowerCase().includes(\"application/json\")) return undefined;\n try {\n return await res.json();\n } catch {\n return undefined;\n }\n}\n\nfunction pickRequestId(res: Response): string | undefined {\n return (\n res.headers.get(\"fly-request-id\") ??\n res.headers.get(\"x-request-id\") ??\n res.headers.get(\"x-nf-request-id\") ??\n res.headers.get(\"x-netlify-request-id\") ??\n undefined\n );\n}\n\nfunction pickRateLimit(res: Response): { limit?: string; remaining?: string; reset?: string } | undefined {\n const limit = res.headers.get(\"x-ratelimit-limit\") ?? undefined;\n const remaining = res.headers.get(\"x-ratelimit-remaining\") ?? undefined;\n const reset = res.headers.get(\"x-ratelimit-reset\") ?? undefined;\n if (!limit && !remaining && !reset) return undefined;\n return { limit, remaining, reset };\n}\n\nfunction errorMessageFor(status: number, path: string): string {\n if (status === 503 && path.includes(\"/api/groups\")) {\n return \"Groups API disabled for this merchant\";\n }\n return `Wishlist Stack API request failed (${status})`;\n}\n\nfunction parseRetryAfterMs(retryAfter: string | undefined): number {\n if (!retryAfter) return 0;\n const asSeconds = Number(retryAfter);\n if (Number.isFinite(asSeconds) && asSeconds >= 0) {\n return Math.min(asSeconds * 1000, 30_000);\n }\n const asDate = Date.parse(retryAfter);\n if (!Number.isNaN(asDate)) {\n return Math.min(Math.max(0, asDate - Date.now()), 30_000);\n }\n return 0;\n}\n\nfunction jitterDelayMs(baseMs: number): number {\n const base = Math.max(100, baseMs || 500);\n const jitter = Math.floor(Math.random() * 250);\n return Math.min(base + jitter, 30_000);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function createRequest(ctx: RequestContext) {\n return async function request<TResponse = unknown, TBody = unknown>(\n args: RequestArgs<TBody>,\n ): Promise<TResponse> {\n const url = `${ctx.baseUrl}${args.path}${toQueryString(args.query)}`;\n\n const headers: Record<string, string> = {\n \"X-Wishlist-Stack-Api-Key\": ctx.apiKey,\n ...(args.headers ?? {}),\n };\n\n if (args.auth === \"authenticated\") {\n const token = ctx.customerAccessToken;\n // If token is missing, still perform the request and let the API return the appropriate\n // error response (which we will surface as a WishlistStackApiError based on the HTTP response).\n if (token) headers[\"X-Shopify-Customer-Access-Token\"] = token;\n }\n\n let body: BodyInit | undefined;\n if (args.body !== undefined) {\n // Only JSON bodies are supported for this SDK.\n headers[\"content-type\"] ??= \"application/json\";\n body = JSON.stringify(args.body);\n }\n\n const timeoutMs = args.timeoutMs ?? ctx.defaultTimeoutMs;\n\n const doFetch = async (): Promise<Response> => {\n const controller = timeoutMs ? new AbortController() : undefined;\n const timeout =\n timeoutMs && controller\n ? setTimeout(() => controller.abort(), timeoutMs)\n : undefined;\n\n const signal = args.signal\n ? args.signal\n : controller\n ? controller.signal\n : undefined;\n\n try {\n return await ctx.fetch(url, {\n method: args.method,\n headers,\n body,\n signal,\n });\n } finally {\n if (timeout) clearTimeout(timeout);\n }\n };\n\n let res = await doFetch();\n\n if (!res.ok && res.status === 429 && ctx.retryOnRateLimit) {\n const retryAfter = res.headers.get(\"retry-after\") ?? undefined;\n await sleep(jitterDelayMs(parseRetryAfterMs(retryAfter)));\n res = await doFetch();\n }\n\n if (!res.ok) {\n const errBody = (await safeParseJson(res)) as ApiErrorResponse | unknown;\n const retryAfter = res.headers.get(\"retry-after\") ?? undefined;\n throw new WishlistStackApiError<ApiErrorResponse | unknown>(errorMessageFor(res.status, args.path), {\n status: res.status,\n url,\n method: args.method,\n requestId: pickRequestId(res),\n body: errBody,\n retryAfter,\n rateLimit: pickRateLimit(res),\n });\n }\n\n if (res.status === 204) return undefined as TResponse;\n\n const parsed = await safeParseJson(res);\n // If server didn't return JSON, return the raw text as unknown.\n if (parsed === undefined) {\n const text = await res.text().catch(() => \"\");\n return text as unknown as TResponse;\n }\n\n return parsed as TResponse;\n };\n}\n","import { MAX_PAGINATION_SIZE } from \"../constants\";\n\n/**\n * Clamp a page size to the API-allowed range (1–25) so requests\n * do not send invalid `pageSize` values.\n */\nexport function clampPageSize(n: number): number {\n if (!Number.isFinite(n)) return MAX_PAGINATION_SIZE;\n return Math.min(MAX_PAGINATION_SIZE, Math.max(1, Math.trunc(n)));\n}\n\n/**\n * Clamp a 1-based page index to at least 1.\n */\nexport function clampPage(n: number): number {\n if (!Number.isFinite(n)) return 1;\n return Math.max(1, Math.trunc(n));\n}\n","import type { RequestArgs } from \"../../client/request\";\nimport { MAX_PAGINATION_SIZE } from \"../../constants\";\nimport { clampPage, clampPageSize } from \"../../helpers/pagination\";\nimport type { PaginatedQuery } from \"../../types/query-options\";\nimport type {\n AddItemsToListBody,\n CreateListBody,\n DuplicateListBody,\n ReorderListItemsBody,\n UpdateListBody,\n UpdateListItemBody,\n} from \"../../types/requests/lists\";\nimport type {\n AddItemsToListResponse,\n CreateListResponse,\n DuplicateListResponse,\n GetListResponse,\n GetListsResponse,\n HydratedWishlistItem,\n MarkListSharedResponse,\n RemoveItemFromListResponse,\n RemoveListResponse,\n ReorderListItemsResponse,\n RevokeListSharedResponse,\n UpdateListDetailsResponse,\n UpdateListItemResponse,\n} from \"../../types/responses/lists\";\nimport type { Pagination } from \"../../types/responses/common\";\n\ntype RequestFn = <TResponse = unknown, TBody = unknown>(\n args: RequestArgs<TBody>,\n) => Promise<TResponse>;\n\nexport type GetListsQuery = PaginatedQuery;\nexport type GetListQuery = Omit<PaginatedQuery, \"query\">;\n\nexport type AddItemsBatchedOptions = {\n /** Max items per POST (API hard max is 25). */\n batchSize?: number;\n};\n\nexport type GetByIdAllItemsOptions = {\n pageSize?: number;\n sortBy?: GetListQuery[\"sortBy\"];\n sortDirection?: GetListQuery[\"sortDirection\"];\n};\n\nfunction chunkItems<T>(items: T[], batchSize: number): T[][] {\n const size = Math.max(1, Math.min(MAX_PAGINATION_SIZE, Math.trunc(batchSize) || MAX_PAGINATION_SIZE));\n const chunks: T[][] = [];\n for (let i = 0; i < items.length; i += size) {\n chunks.push(items.slice(i, i + size));\n }\n return chunks.length ? chunks : [[]];\n}\n\nexport function createListsResource(request: RequestFn) {\n const getById = (listId: string, query?: GetListQuery) =>\n request<GetListResponse>({\n method: \"GET\",\n path: `/api/lists/${encodeURIComponent(listId)}`,\n auth: \"authenticated\",\n query,\n });\n\n const addItems = (listId: string, body: AddItemsToListBody) =>\n request<AddItemsToListResponse, AddItemsToListBody>({\n method: \"POST\",\n path: `/api/lists/${encodeURIComponent(listId)}/add`,\n auth: \"authenticated\",\n body,\n });\n\n return {\n /** Returns all lists for the authenticated customer under the current merchant. */\n getAll: (query?: GetListsQuery) =>\n request<GetListsResponse>({\n method: \"GET\",\n path: \"/api/lists\",\n auth: \"authenticated\",\n query,\n }),\n\n /** Fetch list details by id. */\n getById,\n\n /**\n * Fetch every item on a list by walking pages (list detail is paginated;\n * max pageSize 25).\n */\n getByIdAllItems: async (listId: string, opts?: GetByIdAllItemsOptions): Promise<GetListResponse> => {\n const pageSize = clampPageSize(opts?.pageSize ?? MAX_PAGINATION_SIZE);\n const sortBy = opts?.sortBy;\n const sortDirection = opts?.sortDirection;\n\n const first = await getById(listId, {\n page: 1,\n pageSize,\n ...(sortBy ? { sortBy } : {}),\n ...(sortDirection ? { sortDirection } : {}),\n });\n\n const totalPages = first.pagination.totalPages;\n const allItems: HydratedWishlistItem[] = [...(first.items ?? [])];\n\n for (let page = 2; page <= totalPages; page++) {\n const next = await getById(listId, {\n page: clampPage(page),\n pageSize,\n ...(sortBy ? { sortBy } : {}),\n ...(sortDirection ? { sortDirection } : {}),\n });\n allItems.push(...(next.items ?? []));\n }\n\n const pagination: Pagination = {\n ...first.pagination,\n page: 1,\n pageSize,\n };\n\n return {\n ...first,\n items: allItems,\n pagination,\n };\n },\n\n /**\n * Create a new list. Do not send `variantIds` — add items via `addItems`\n * or `addItemsBatched` after create.\n */\n create: (body: CreateListBody) =>\n request<CreateListResponse, CreateListBody>({\n method: \"POST\",\n path: \"/api/lists\",\n auth: \"authenticated\",\n body,\n }),\n\n /** Update list name/description. */\n update: (listId: string, body: UpdateListBody) =>\n request<UpdateListDetailsResponse, UpdateListBody>({\n method: \"PATCH\",\n path: `/api/lists/${encodeURIComponent(listId)}`,\n auth: \"authenticated\",\n body,\n }),\n\n /** Remove a list. */\n remove: (listId: string) =>\n request<RemoveListResponse>({\n method: \"DELETE\",\n path: `/api/lists/${encodeURIComponent(listId)}`,\n auth: \"authenticated\",\n }),\n\n /**\n * Duplicate a list (including all items) in a single call.\n * By default the copy stays in the same group as the source. Pass `groupId`\n * to place it in another group, or `groupId: null` to leave it ungrouped.\n * The copy is named `Copy of {original name}` and is not shared.\n */\n duplicate: (listId: string, body?: DuplicateListBody) =>\n request<DuplicateListResponse, DuplicateListBody>({\n method: \"POST\",\n path: `/api/lists/${encodeURIComponent(listId)}/duplicate`,\n auth: \"authenticated\",\n body,\n }),\n\n /**\n * Add one or more items to a list.\n * Returns `{ listId, addedItems, addedCount }`. Prefer `addItemsBatched`\n * when sending more than 25 items.\n */\n addItems,\n\n /**\n * Add items in sequential batches of ≤25 (API hard max).\n * Merges `{ addedItems, addedCount }` across batches.\n */\n addItemsBatched: async (\n listId: string,\n body: AddItemsToListBody,\n opts?: AddItemsBatchedOptions,\n ): Promise<AddItemsToListResponse> => {\n const items = body.items ?? [];\n const batchSize = opts?.batchSize ?? MAX_PAGINATION_SIZE;\n const chunks = chunkItems(items, batchSize);\n\n const merged: AddItemsToListResponse = {\n listId,\n addedItems: [],\n addedCount: 0,\n };\n\n for (const chunk of chunks) {\n const res = await addItems(listId, { items: chunk });\n merged.listId = res.listId;\n merged.addedItems.push(...res.addedItems);\n merged.addedCount += res.addedCount;\n }\n\n return merged;\n },\n\n /** Update an item on a list. */\n updateItem: (listId: string, itemId: string, body: UpdateListItemBody) =>\n request<UpdateListItemResponse, UpdateListItemBody>({\n method: \"PATCH\",\n path: `/api/lists/${encodeURIComponent(listId)}/items/${encodeURIComponent(itemId)}`,\n auth: \"authenticated\",\n body,\n }),\n\n /** Remove an item from a list. */\n removeItem: (listId: string, itemId: string) =>\n request<RemoveItemFromListResponse>({\n method: \"DELETE\",\n path: `/api/lists/${encodeURIComponent(listId)}/items/${encodeURIComponent(itemId)}`,\n auth: \"authenticated\",\n }),\n\n /** Reorder all items in a list. */\n reorderItems: (listId: string, body: ReorderListItemsBody) =>\n request<ReorderListItemsResponse, ReorderListItemsBody>({\n method: \"POST\",\n path: `/api/lists/${encodeURIComponent(listId)}/reorder`,\n auth: \"authenticated\",\n body,\n }),\n\n /** Mark list as shared (public read-only). */\n share: (listId: string) =>\n request<MarkListSharedResponse>({\n method: \"POST\",\n path: `/api/lists/${encodeURIComponent(listId)}/share`,\n auth: \"authenticated\",\n }),\n\n /** Revoke list sharing. */\n unshare: (listId: string) =>\n request<RevokeListSharedResponse>({\n method: \"DELETE\",\n path: `/api/lists/${encodeURIComponent(listId)}/share`,\n auth: \"authenticated\",\n }),\n\n /**\n * Legacy endpoint kept in the OpenAPI spec (`/api/wishlists/{id}/add`).\n * Prefer `addItems(listId, body)` unless your server only supports the legacy route.\n */\n addItemsLegacy: (id: string, body: AddItemsToListBody) =>\n request<AddItemsToListResponse, AddItemsToListBody>({\n method: \"POST\",\n path: `/api/wishlists/${encodeURIComponent(id)}/add`,\n auth: \"authenticated\",\n body,\n }),\n };\n}\n","import type { RequestArgs } from \"../../client/request\";\nimport type { CreateGroupBody, ReorderGroupsBody, UpdateGroupBody } from \"../../types/requests/groups\";\nimport type { PaginatedQuery } from \"../../types/query-options\";\nimport type {\n CreateGroupResponse,\n DuplicateGroupResponse,\n GetGroupResponse,\n GetGroupsResponse,\n MarkGroupSharedResponse,\n RemoveGroupResponse,\n ReorderGroupsResponse,\n RevokeGroupSharedResponse,\n UpdateGroupDetailsResponse,\n} from \"../../types/responses/groups\";\n\ntype RequestFn = <TResponse = unknown, TBody = unknown>(\n args: RequestArgs<TBody>,\n) => Promise<TResponse>;\n\nexport type GetGroupsQuery = PaginatedQuery<{\n /**\n * When truthy (`true`, `1`, or `\"1\"`), each group includes embedded `lists`\n * with hydrated items (`includeLists=1`).\n *\n * Expect at most **10 lists × 25 items** per group. For full data use\n * `groups.getById` plus `lists.getById` / `lists.getByIdAllItems`. Groups\n * endpoints may return **503** until the Groups API is enabled for the merchant.\n */\n includeLists?: boolean | 1 | \"1\";\n}>;\nexport type GetGroupQuery = PaginatedQuery;\n\nfunction normalizeGetGroupsQuery(query?: GetGroupsQuery): GetGroupsQuery | undefined {\n if (!query) return undefined;\n const { includeLists, ...rest } = query;\n if (includeLists) {\n return { ...rest, includeLists: 1 };\n }\n return Object.keys(rest).length > 0 ? rest : undefined;\n}\n\nexport function createGroupsResource(request: RequestFn) {\n return {\n /**\n * Fetch groups for the authenticated customer.\n * May return **503** when the Groups API is disabled for this merchant.\n */\n getAll: (query?: GetGroupsQuery) =>\n request<GetGroupsResponse>({\n method: \"GET\",\n path: \"/api/groups\",\n auth: \"authenticated\",\n query: normalizeGetGroupsQuery(query),\n }),\n\n /**\n * Fetch group details by id.\n * May return **503** when the Groups API is disabled for this merchant.\n */\n getById: (groupId: string, query?: GetGroupQuery) =>\n request<GetGroupResponse>({\n method: \"GET\",\n path: `/api/groups/${encodeURIComponent(groupId)}`,\n auth: \"authenticated\",\n query,\n }),\n\n /** Create a new group. */\n create: (body: CreateGroupBody) =>\n request<CreateGroupResponse, CreateGroupBody>({\n method: \"POST\",\n path: \"/api/groups\",\n auth: \"authenticated\",\n body,\n }),\n\n /** Update group name/description. */\n update: (groupId: string, body: UpdateGroupBody) =>\n request<UpdateGroupDetailsResponse, UpdateGroupBody>({\n method: \"PATCH\",\n path: `/api/groups/${encodeURIComponent(groupId)}`,\n auth: \"authenticated\",\n body,\n }),\n\n /** Remove a group. */\n remove: (groupId: string) =>\n request<RemoveGroupResponse>({\n method: \"DELETE\",\n path: `/api/groups/${encodeURIComponent(groupId)}`,\n auth: \"authenticated\",\n }),\n\n /**\n * Duplicate a group (including all lists and items) in a single call.\n * The copy is named `Copy of {original name}` and is not shared.\n */\n duplicate: (groupId: string) =>\n request<DuplicateGroupResponse>({\n method: \"POST\",\n path: `/api/groups/${encodeURIComponent(groupId)}/duplicate`,\n auth: \"authenticated\",\n }),\n\n /**\n * Reorder the customer's groups (`POST /api/groups/reorder`).\n * Body must include `groupIds` in the desired order — not list IDs, and\n * not a per-group path.\n */\n reorder: (body: ReorderGroupsBody) =>\n request<ReorderGroupsResponse, ReorderGroupsBody>({\n method: \"POST\",\n path: \"/api/groups/reorder\",\n auth: \"authenticated\",\n body,\n }),\n\n /** Mark group as shared (public read-only). */\n share: (groupId: string) =>\n request<MarkGroupSharedResponse>({\n method: \"POST\",\n path: `/api/groups/${encodeURIComponent(groupId)}/share`,\n auth: \"authenticated\",\n }),\n\n /** Revoke group sharing. */\n unshare: (groupId: string) =>\n request<RevokeGroupSharedResponse>({\n method: \"DELETE\",\n path: `/api/groups/${encodeURIComponent(groupId)}/share`,\n auth: \"authenticated\",\n }),\n };\n}\n","import type { RequestArgs } from \"../../client/request\";\nimport type { PaginatedQuery } from \"../../types/query-options\";\nimport type { GetSharedGroupResponse, GetSharedListResponse } from \"../../types/responses/shared\";\n\ntype RequestFn = <TResponse = unknown, TBody = unknown>(\n args: RequestArgs<TBody>,\n) => Promise<TResponse>;\n\nexport type GetSharedListQuery = Omit<PaginatedQuery, \"query\">;\nexport type GetSharedGroupQuery = PaginatedQuery;\n\nexport function createSharedResource(request: RequestFn) {\n return {\n /** Public read-only view of a shared list. Requires only merchant apiKey. */\n getSharedList: (listId: string, query?: GetSharedListQuery) =>\n request<GetSharedListResponse>({\n method: \"GET\",\n path: `/api/shared/list/${encodeURIComponent(listId)}`,\n auth: \"merchant\",\n query,\n }),\n\n /** Public read-only view of a shared group. Requires only merchant apiKey. */\n getSharedGroup: (groupId: string, query?: GetSharedGroupQuery) =>\n request<GetSharedGroupResponse>({\n method: \"GET\",\n path: `/api/shared/group/${encodeURIComponent(groupId)}`,\n auth: \"merchant\",\n query,\n }),\n };\n}\n\n","import { BASE_URL } from \"../constants\";\nimport { createRequest, type FetchLike } from \"./request\";\nimport { createListsResource } from \"../resources/lists\";\nimport { createGroupsResource } from \"../resources/groups\";\nimport { createSharedResource } from \"../resources/shared\";\n\nexport type CreateWishlistStackClientOptions = {\n baseUrl?: string;\n apiKey: string;\n customerAccessToken?: string;\n fetch?: FetchLike;\n /** Default request timeout in ms when a call does not pass `timeoutMs`. */\n defaultTimeoutMs?: number;\n /** When true, retry once on HTTP 429 with jittered backoff (default: false). */\n retryOnRateLimit?: boolean;\n};\n\nexport type WishlistStackClient = {\n lists: ReturnType<typeof createListsResource>;\n groups: ReturnType<typeof createGroupsResource>;\n shared: ReturnType<typeof createSharedResource>;\n};\n\nexport function createWishlistStackClient(opts: CreateWishlistStackClientOptions): WishlistStackClient {\n if (!opts.apiKey) {\n throw new Error(\n \"merchant api key is required. Pass it to createWishlistStackClient({ apiKey })\",\n );\n }\n\n // Cloudflare Workers (and some other runtimes) can throw \"Illegal invocation\" if you\n // capture `globalThis.fetch` and call it later without the correct `this` binding.\n // So: default to a wrapper that calls `globalThis.fetch(...)` directly.\n const fetchImpl: FetchLike | undefined =\n opts.fetch ??\n (typeof globalThis.fetch === \"function\"\n ? ((input, init) => globalThis.fetch(input, init)) // keep correct invocation context\n : undefined);\n\n if (!fetchImpl) {\n throw new Error(\n \"No fetch implementation found. Provide one via createWishlistStackClient({ fetch }) or use Node 18+ / modern browsers.\",\n );\n }\n\n const request = createRequest({\n baseUrl: opts.baseUrl ?? BASE_URL,\n apiKey: opts.apiKey,\n customerAccessToken: opts.customerAccessToken,\n fetch: fetchImpl,\n defaultTimeoutMs: opts.defaultTimeoutMs,\n retryOnRateLimit: opts.retryOnRateLimit,\n });\n\n return {\n lists: createListsResource(request),\n groups: createGroupsResource(request),\n shared: createSharedResource(request),\n };\n}\n","import { createWishlistStackClient, type CreateWishlistStackClientOptions, type WishlistStackClient as IWishlistStackClient } from \"./client/createWishlistStackClient\";\n\n/**\n * Class wrapper around `createWishlistStackClient()` for users who prefer `new`.\n * Exposes `lists`, `groups`, and `shared` resources.\n */\nexport class WishlistStackClient implements IWishlistStackClient {\n readonly lists: IWishlistStackClient[\"lists\"];\n readonly groups: IWishlistStackClient[\"groups\"];\n readonly shared: IWishlistStackClient[\"shared\"];\n\n constructor(opts: CreateWishlistStackClientOptions) {\n const client = createWishlistStackClient(opts);\n this.lists = client.lists;\n this.groups = client.groups;\n this.shared = client.shared;\n }\n\n /** Back-compat alias: `client.groups.getAll()` */\n getGroups() {\n return this.groups.getAll();\n }\n\n /** Back-compat alias: `client.groups.getById(groupId)` */\n getGroupById(groupId: string) {\n return this.groups.getById(groupId);\n }\n\n /** Back-compat alias: `client.lists.getAll()` */\n getLists() {\n return this.lists.getAll();\n }\n}\n","import { MAX_PAGINATION_SIZE } from \"../constants\";\n\nexport type PaginationParams = {\n page?: number;\n pageSize?: number;\n query?: string;\n};\n\nexport const DEFAULT_PAGE = 1 as const;\nexport const DEFAULT_PAGE_SIZE = MAX_PAGINATION_SIZE;\n\n","import type { Query } from \"../client/query\";\nimport type { PaginationParams } from \"./pagination\";\n\nexport const SORT_FIELDS = [\"position\", \"createdAt\", \"updatedAt\"] as const;\nexport const SORT_DIRECTIONS = [\"asc\", \"desc\"] as const;\n\nexport type SortField = (typeof SORT_FIELDS)[number];\nexport type SortDirection = (typeof SORT_DIRECTIONS)[number];\n\n/**\n * Collection sort options for multi-resource GET endpoints.\n * Defaults on the API are `sortBy=position` and `sortDirection=asc`.\n */\nexport type SortParams = {\n sortBy?: SortField;\n sortDirection?: SortDirection;\n};\n\n/**\n * Shared query option building blocks for list/group endpoints.\n *\n * Keep this extendable: as we add filters/sorts, we can add additional helpers/types here\n * and reuse them across endpoints without duplicating logic.\n */\nexport type PaginatedQuery<TExtra extends Query = Query> = PaginationParams & SortParams & TExtra;\n\n/**\n * Merge a base query with pagination parameters.\n * (Useful when an endpoint also gains filter/sort params over time.)\n */\nexport function withPagination<TExtra extends Query>(\n query?: TExtra,\n pagination?: PaginationParams,\n): PaginatedQuery<TExtra> | undefined {\n if (!query && !pagination) return undefined;\n return { ...(query ?? {}), ...(pagination ?? {}) } as PaginatedQuery<TExtra>;\n}\n\n/**\n * Merge a base query with sort parameters.\n */\nexport function withSort<TExtra extends Query>(\n query?: TExtra,\n sort?: SortParams,\n): (TExtra & SortParams) | undefined {\n if (!query && !sort) return undefined;\n return { ...(query ?? {}), ...(sort ?? {}) } as TExtra & SortParams;\n}\n\n","import type { AddItemsToListResponse } from \"./responses/lists\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\n/**\n * True when the value matches the add-items response shape\n * (`{ listId, addedItems, addedCount }`).\n */\nexport function isAddItemsDeltaResponse(\n value: AddItemsToListResponse | unknown,\n): value is AddItemsToListResponse {\n if (!isRecord(value)) return false;\n return (\n typeof value.listId === \"string\" &&\n Array.isArray(value.addedItems) &&\n typeof value.addedCount === \"number\"\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/client/query.ts","../src/client/errors.ts","../src/client/request.ts","../src/helpers/pagination.ts","../src/resources/lists/index.ts","../src/resources/groups/index.ts","../src/resources/shared/index.ts","../src/client/createWishlistStackClient.ts","../src/WishlistStackClient.ts","../src/types/pagination.ts","../src/types/query-options.ts","../src/types/guards.ts"],"names":["isRecord"],"mappings":"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","file":"index.cjs","sourcesContent":["export const MAX_PAGINATION_SIZE = 25 as const;\nexport const BASE_URL = \"https://app.wishliststack.com\" as const;\n\n","export type QueryValue =\n | string\n | number\n | boolean\n | null\n | undefined\n | Array<string | number | boolean | null | undefined>;\n\nexport type Query = Record<string, QueryValue>;\n\nexport function toQueryString(query?: Query): string {\n if (!query) return \"\";\n\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined || value === null) continue;\n if (Array.isArray(value)) {\n for (const v of value) {\n if (v === undefined || v === null) continue;\n params.append(key, String(v));\n }\n continue;\n }\n params.set(key, String(value));\n }\n\n const qs = params.toString();\n return qs ? `?${qs}` : \"\";\n}\n\n","export type WishlistStackApiErrorDetails<TBody = unknown> = {\n status: number;\n url: string;\n method: string;\n requestId?: string;\n body?: TBody;\n /** Value of the `Retry-After` response header when present (seconds or HTTP-date). */\n retryAfter?: string;\n /** Selected rate-limit response headers when present. */\n rateLimit?: {\n limit?: string;\n remaining?: string;\n reset?: string;\n };\n};\n\ntype ApiErrorItemLike = { message?: unknown; field?: unknown };\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isApiErrorItemLike(value: unknown): value is ApiErrorItemLike {\n return isRecord(value) && \"message\" in value;\n}\n\nfunction extractApiErrors(body: unknown): Array<{ message: string; field?: string }> | undefined {\n if (!isRecord(body)) return undefined;\n const errors = body.errors;\n if (!Array.isArray(errors)) return undefined;\n const out: Array<{ message: string; field?: string }> = [];\n for (const e of errors) {\n if (!isApiErrorItemLike(e)) continue;\n const msg = typeof e.message === \"string\" ? e.message : undefined;\n if (!msg) continue;\n const field = typeof (e as any).field === \"string\" ? (e as any).field : undefined;\n out.push(field ? { message: msg, field } : { message: msg });\n }\n return out.length ? out : undefined;\n}\n\nexport class WishlistStackApiError<TBody = unknown> extends Error {\n readonly name = \"WishlistStackApiError\";\n readonly status: number;\n readonly url: string;\n readonly method: string;\n readonly requestId?: string;\n readonly body?: TBody;\n readonly retryAfter?: string;\n readonly rateLimit?: WishlistStackApiErrorDetails[\"rateLimit\"];\n\n constructor(message: string, details: WishlistStackApiErrorDetails<TBody>) {\n super(message);\n this.status = details.status;\n this.url = details.url;\n this.method = details.method;\n this.requestId = details.requestId;\n this.body = details.body;\n this.retryAfter = details.retryAfter;\n this.rateLimit = details.rateLimit;\n }\n\n /**\n * Best-effort extraction of API error items from the response body.\n * Useful for UI/logging without needing to know the exact response shape.\n */\n get apiErrors(): Array<{ message: string; field?: string }> | undefined {\n return extractApiErrors(this.body);\n }\n\n /**\n * Convenience: extracted error messages (if present).\n */\n get apiErrorMessages(): string[] | undefined {\n const errs = this.apiErrors;\n return errs?.map((e) => e.message);\n }\n}\n\n/**\n * Bundler-safe type guard (prefer this over `instanceof WishlistStackApiError`).\n */\nexport function isWishlistStackApiError(value: unknown): value is WishlistStackApiError<unknown> {\n if (!isRecord(value)) return false;\n return (\n (value as any).name === \"WishlistStackApiError\" &&\n typeof (value as any).status === \"number\" &&\n typeof (value as any).url === \"string\" &&\n typeof (value as any).method === \"string\"\n );\n}\n","import { toQueryString, type Query } from \"./query\";\nimport { WishlistStackApiError } from \"./errors\";\nimport type { ApiErrorResponse } from \"../types/common\";\n\nexport type FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;\n\nexport type AuthMode = \"authenticated\" | \"merchant\";\n\nexport type RequestContext = {\n baseUrl: string;\n apiKey: string;\n customerAccessToken?: string;\n fetch: FetchLike;\n /** Applied when a call does not pass `timeoutMs`. */\n defaultTimeoutMs?: number;\n /** When true, retry safe GET requests once on HTTP 429 with jittered delay. */\n retryOnRateLimit?: boolean;\n};\n\nexport type RequestArgs<TBody> = {\n method: \"GET\" | \"POST\" | \"PATCH\" | \"DELETE\";\n path: string;\n auth: AuthMode;\n query?: Query;\n body?: TBody;\n headers?: Record<string, string>;\n signal?: AbortSignal;\n timeoutMs?: number;\n /** Marks a non-GET operation as safe to retry once on HTTP 429. */\n retryable?: boolean;\n};\n\nasync function safeParseJson(res: Response): Promise<unknown | undefined> {\n const contentType = res.headers.get(\"content-type\") ?? \"\";\n if (!contentType.toLowerCase().includes(\"application/json\")) return undefined;\n try {\n return await res.json();\n } catch {\n return undefined;\n }\n}\n\nfunction pickRequestId(res: Response): string | undefined {\n return (\n res.headers.get(\"fly-request-id\") ??\n res.headers.get(\"x-request-id\") ??\n res.headers.get(\"x-nf-request-id\") ??\n res.headers.get(\"x-netlify-request-id\") ??\n undefined\n );\n}\n\nfunction pickRateLimit(res: Response): { limit?: string; remaining?: string; reset?: string } | undefined {\n const limit = res.headers.get(\"x-ratelimit-limit\") ?? undefined;\n const remaining = res.headers.get(\"x-ratelimit-remaining\") ?? undefined;\n const reset = res.headers.get(\"x-ratelimit-reset\") ?? undefined;\n if (!limit && !remaining && !reset) return undefined;\n return { limit, remaining, reset };\n}\n\nfunction errorMessageFor(status: number, path: string): string {\n if (status === 503 && path.includes(\"/api/groups\")) {\n return \"Groups API disabled for this merchant\";\n }\n return `Wishlist Stack API request failed (${status})`;\n}\n\nfunction parseRetryAfterMs(retryAfter: string | undefined): number {\n if (!retryAfter) return 0;\n const asSeconds = Number(retryAfter);\n if (Number.isFinite(asSeconds) && asSeconds >= 0) {\n return Math.min(asSeconds * 1000, 30_000);\n }\n const asDate = Date.parse(retryAfter);\n if (!Number.isNaN(asDate)) {\n return Math.min(Math.max(0, asDate - Date.now()), 30_000);\n }\n return 0;\n}\n\nfunction jitterDelayMs(baseMs: number): number {\n const base = Math.max(100, baseMs || 500);\n const jitter = Math.floor(Math.random() * 250);\n return Math.min(base + jitter, 30_000);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function createRequest(ctx: RequestContext) {\n return async function request<TResponse = unknown, TBody = unknown>(\n args: RequestArgs<TBody>,\n ): Promise<TResponse> {\n const url = `${ctx.baseUrl}${args.path}${toQueryString(args.query)}`;\n\n const headers: Record<string, string> = {\n \"X-Wishlist-Stack-Api-Key\": ctx.apiKey,\n ...(args.headers ?? {}),\n };\n\n if (args.auth === \"authenticated\") {\n const token = ctx.customerAccessToken;\n // If token is missing, still perform the request and let the API return the appropriate\n // error response (which we will surface as a WishlistStackApiError based on the HTTP response).\n if (token) headers[\"X-Shopify-Customer-Access-Token\"] = token;\n }\n\n let body: BodyInit | undefined;\n if (args.body !== undefined) {\n // Only JSON bodies are supported for this SDK.\n headers[\"content-type\"] ??= \"application/json\";\n body = JSON.stringify(args.body);\n }\n\n const timeoutMs = args.timeoutMs ?? ctx.defaultTimeoutMs;\n\n const doFetch = async (): Promise<Response> => {\n const controller = timeoutMs ? new AbortController() : undefined;\n const timeout =\n timeoutMs && controller\n ? setTimeout(() => controller.abort(), timeoutMs)\n : undefined;\n\n const signal = args.signal\n ? args.signal\n : controller\n ? controller.signal\n : undefined;\n\n try {\n return await ctx.fetch(url, {\n method: args.method,\n headers,\n body,\n signal,\n });\n } finally {\n if (timeout) clearTimeout(timeout);\n }\n };\n\n let res = await doFetch();\n\n const retryable = args.method === \"GET\" || args.retryable === true;\n if (!res.ok && res.status === 429 && ctx.retryOnRateLimit && retryable) {\n const retryAfter = res.headers.get(\"retry-after\") ?? undefined;\n await sleep(jitterDelayMs(parseRetryAfterMs(retryAfter)));\n res = await doFetch();\n }\n\n if (!res.ok) {\n const errBody = (await safeParseJson(res)) as ApiErrorResponse | unknown;\n const retryAfter = res.headers.get(\"retry-after\") ?? undefined;\n throw new WishlistStackApiError<ApiErrorResponse | unknown>(errorMessageFor(res.status, args.path), {\n status: res.status,\n url,\n method: args.method,\n requestId: pickRequestId(res),\n body: errBody,\n retryAfter,\n rateLimit: pickRateLimit(res),\n });\n }\n\n if (res.status === 204) return undefined as TResponse;\n\n const parsed = await safeParseJson(res);\n // If server didn't return JSON, return the raw text as unknown.\n if (parsed === undefined) {\n const text = await res.text().catch(() => \"\");\n return text as unknown as TResponse;\n }\n\n return parsed as TResponse;\n };\n}\n","import { MAX_PAGINATION_SIZE } from \"../constants\";\n\n/**\n * Clamp a page size to the API-allowed range (1–25) so requests\n * do not send invalid `pageSize` values.\n */\nexport function clampPageSize(n: number): number {\n if (!Number.isFinite(n)) return MAX_PAGINATION_SIZE;\n return Math.min(MAX_PAGINATION_SIZE, Math.max(1, Math.trunc(n)));\n}\n\n/**\n * Clamp a 1-based page index to at least 1.\n */\nexport function clampPage(n: number): number {\n if (!Number.isFinite(n)) return 1;\n return Math.max(1, Math.trunc(n));\n}\n","import type { RequestArgs } from \"../../client/request\";\nimport { MAX_PAGINATION_SIZE } from \"../../constants\";\nimport { clampPage, clampPageSize } from \"../../helpers/pagination\";\nimport type { PaginatedQuery } from \"../../types/query-options\";\nimport type {\n AddItemsToListBody,\n ContainsVariantsBody,\n CreateListBody,\n DuplicateListBody,\n ReorderListItemsBody,\n UpdateListBody,\n UpdateListItemBody,\n} from \"../../types/requests/lists\";\nimport type {\n AddItemsToListResponse,\n ContainsVariantsResponse,\n CreateListResponse,\n DuplicateListResponse,\n GetListResponse,\n GetListsResponse,\n HydratedWishlistItem,\n MarkListSharedResponse,\n RemoveItemFromListResponse,\n RemoveListResponse,\n ReorderListItemsResponse,\n RevokeListSharedResponse,\n UpdateListDetailsResponse,\n UpdateListItemResponse,\n} from \"../../types/responses/lists\";\nimport type { ListDetailPagination } from \"../../types/responses/common\";\n\ntype RequestFn = <TResponse = unknown, TBody = unknown>(\n args: RequestArgs<TBody>,\n) => Promise<TResponse>;\n\nexport type GetListsQuery = PaginatedQuery;\nexport type GetListQuery = Omit<PaginatedQuery, \"query\">;\n\nexport type AddItemsBatchedOptions = {\n /** Max items per POST (API hard max is 25). */\n batchSize?: number;\n};\n\nexport type GetByIdAllItemsOptions = {\n pageSize?: number;\n sortBy?: GetListQuery[\"sortBy\"];\n sortDirection?: GetListQuery[\"sortDirection\"];\n};\n\nfunction chunkItems<T>(items: T[], batchSize: number): T[][] {\n const size = Math.max(1, Math.min(MAX_PAGINATION_SIZE, Math.trunc(batchSize) || MAX_PAGINATION_SIZE));\n const chunks: T[][] = [];\n for (let i = 0; i < items.length; i += size) {\n chunks.push(items.slice(i, i + size));\n }\n return chunks.length ? chunks : [[]];\n}\n\nexport function createListsResource(request: RequestFn) {\n const getById = (listId: string, query?: GetListQuery) =>\n request<GetListResponse>({\n method: \"GET\",\n path: `/api/lists/${encodeURIComponent(listId)}`,\n auth: \"authenticated\",\n query,\n });\n\n const addItems = (listId: string, body: AddItemsToListBody) =>\n request<AddItemsToListResponse, AddItemsToListBody>({\n method: \"POST\",\n path: `/api/lists/${encodeURIComponent(listId)}/add`,\n auth: \"authenticated\",\n body,\n });\n\n return {\n /** Returns all lists for the authenticated customer under the current merchant. */\n getAll: (query?: GetListsQuery) =>\n request<GetListsResponse>({\n method: \"GET\",\n path: \"/api/lists\",\n auth: \"authenticated\",\n query,\n }),\n\n /** Fetch list details by id. */\n getById,\n\n /**\n * Fetch every item on a list by walking pages (list detail is paginated;\n * max pageSize 25).\n */\n getByIdAllItems: async (listId: string, opts?: GetByIdAllItemsOptions): Promise<GetListResponse> => {\n const pageSize = clampPageSize(opts?.pageSize ?? MAX_PAGINATION_SIZE);\n const sortBy = opts?.sortBy;\n const sortDirection = opts?.sortDirection;\n\n const first = await getById(listId, {\n page: 1,\n pageSize,\n ...(sortBy ? { sortBy } : {}),\n ...(sortDirection ? { sortDirection } : {}),\n });\n\n const totalPages = first.pagination.totalPages;\n const allItems: HydratedWishlistItem[] = [...(first.items ?? [])];\n\n for (let page = 2; page <= totalPages; page++) {\n const next = await getById(listId, {\n page: clampPage(page),\n pageSize,\n ...(sortBy ? { sortBy } : {}),\n ...(sortDirection ? { sortDirection } : {}),\n });\n allItems.push(...(next.items ?? []));\n }\n\n const pagination: ListDetailPagination = {\n ...first.pagination,\n page: 1,\n pageSize,\n };\n\n return {\n ...first,\n items: allItems,\n pagination,\n };\n },\n\n /**\n * Create a new list. Do not send `variantIds` — add items via `addItems`\n * or `addItemsBatched` after create.\n */\n create: (body: CreateListBody) =>\n request<CreateListResponse, CreateListBody>({\n method: \"POST\",\n path: \"/api/lists\",\n auth: \"authenticated\",\n body,\n }),\n\n /** Update list name/description. */\n update: (listId: string, body: UpdateListBody) =>\n request<UpdateListDetailsResponse, UpdateListBody>({\n method: \"PATCH\",\n path: `/api/lists/${encodeURIComponent(listId)}`,\n auth: \"authenticated\",\n body,\n }),\n\n /** Remove a list. */\n remove: (listId: string) =>\n request<RemoveListResponse>({\n method: \"DELETE\",\n path: `/api/lists/${encodeURIComponent(listId)}`,\n auth: \"authenticated\",\n }),\n\n /**\n * Duplicate a list (including all items) in a single call.\n * By default the copy stays in the same group as the source. Pass `groupId`\n * to place it in another group, or `groupId: null` to leave it ungrouped.\n * The copy is named `Copy of {original name}` and is not shared.\n */\n duplicate: (listId: string, body?: DuplicateListBody) =>\n request<DuplicateListResponse, DuplicateListBody>({\n method: \"POST\",\n path: `/api/lists/${encodeURIComponent(listId)}/duplicate`,\n auth: \"authenticated\",\n body,\n }),\n\n /**\n * Add one or more items to a list.\n * Returns `{ listId, addedItems, addedCount }`. Prefer `addItemsBatched`\n * when sending more than 25 items.\n */\n addItems,\n\n /**\n * Check whether up to 100 variants are present without hydrating or\n * paging through the list. Response keys preserve the supplied IDs.\n */\n containsVariants: (listId: string, body: ContainsVariantsBody) =>\n request<ContainsVariantsResponse, ContainsVariantsBody>({\n method: \"POST\",\n path: `/api/lists/${encodeURIComponent(listId)}/contains`,\n auth: \"authenticated\",\n body,\n retryable: true,\n }),\n\n /**\n * Add items in sequential batches of ≤25 (API hard max).\n * Merges `{ addedItems, addedCount }` across batches.\n */\n addItemsBatched: async (\n listId: string,\n body: AddItemsToListBody,\n opts?: AddItemsBatchedOptions,\n ): Promise<AddItemsToListResponse> => {\n const items = body.items ?? [];\n if (items.length === 0) {\n throw new Error(\"lists.addItemsBatched requires at least one item\");\n }\n const batchSize = opts?.batchSize ?? MAX_PAGINATION_SIZE;\n const chunks = chunkItems(items, batchSize);\n\n const merged: AddItemsToListResponse = {\n listId,\n addedItems: [],\n addedCount: 0,\n };\n\n for (const chunk of chunks) {\n const res = await addItems(listId, { items: chunk });\n merged.listId = res.listId;\n merged.addedItems.push(...res.addedItems);\n merged.addedCount += res.addedCount;\n }\n\n return merged;\n },\n\n /** Update an item on a list. */\n updateItem: (listId: string, itemId: string, body: UpdateListItemBody) =>\n request<UpdateListItemResponse, UpdateListItemBody>({\n method: \"PATCH\",\n path: `/api/lists/${encodeURIComponent(listId)}/items/${encodeURIComponent(itemId)}`,\n auth: \"authenticated\",\n body,\n }),\n\n /** Remove an item from a list. */\n removeItem: (listId: string, itemId: string) =>\n request<RemoveItemFromListResponse>({\n method: \"DELETE\",\n path: `/api/lists/${encodeURIComponent(listId)}/items/${encodeURIComponent(itemId)}`,\n auth: \"authenticated\",\n }),\n\n /** Reorder all items in a list. */\n reorderItems: (listId: string, body: ReorderListItemsBody) =>\n request<ReorderListItemsResponse, ReorderListItemsBody>({\n method: \"POST\",\n path: `/api/lists/${encodeURIComponent(listId)}/reorder`,\n auth: \"authenticated\",\n body,\n }),\n\n /** Mark list as shared (public read-only). */\n share: (listId: string) =>\n request<MarkListSharedResponse>({\n method: \"POST\",\n path: `/api/lists/${encodeURIComponent(listId)}/share`,\n auth: \"authenticated\",\n }),\n\n /** Revoke list sharing. */\n unshare: (listId: string) =>\n request<RevokeListSharedResponse>({\n method: \"DELETE\",\n path: `/api/lists/${encodeURIComponent(listId)}/share`,\n auth: \"authenticated\",\n }),\n\n /**\n * Legacy endpoint kept in the OpenAPI spec (`/api/wishlists/{id}/add`).\n * Prefer `addItems(listId, body)` unless your server only supports the legacy route.\n */\n addItemsLegacy: (id: string, body: AddItemsToListBody) =>\n request<AddItemsToListResponse, AddItemsToListBody>({\n method: \"POST\",\n path: `/api/wishlists/${encodeURIComponent(id)}/add`,\n auth: \"authenticated\",\n body,\n }),\n };\n}\n","import type { RequestArgs } from \"../../client/request\";\nimport type { CreateGroupBody, ReorderGroupsBody, UpdateGroupBody } from \"../../types/requests/groups\";\nimport type { PaginatedQuery } from \"../../types/query-options\";\nimport type {\n CreateGroupResponse,\n DuplicateGroupResponse,\n GetGroupResponse,\n GetGroupsResponse,\n MarkGroupSharedResponse,\n RemoveGroupResponse,\n ReorderGroupsResponse,\n RevokeGroupSharedResponse,\n UpdateGroupDetailsResponse,\n} from \"../../types/responses/groups\";\n\ntype RequestFn = <TResponse = unknown, TBody = unknown>(\n args: RequestArgs<TBody>,\n) => Promise<TResponse>;\n\nexport type GetGroupsQuery = PaginatedQuery<{\n /**\n * When truthy (`true`, `1`, or `\"1\"`), each group includes embedded `lists`\n * with hydrated items (`includeLists=1`).\n *\n * Expect at most **10 lists × 25 items** per group. For full data use\n * `groups.getById` plus `lists.getById` / `lists.getByIdAllItems`. Groups\n * endpoints may return **503** until the Groups API is enabled for the merchant.\n */\n includeLists?: boolean | 1 | \"1\";\n}>;\nexport type GetGroupQuery = PaginatedQuery;\n\nfunction normalizeGetGroupsQuery(query?: GetGroupsQuery): GetGroupsQuery | undefined {\n if (!query) return undefined;\n const { includeLists, ...rest } = query;\n if (includeLists) {\n return { ...rest, includeLists: 1 };\n }\n return Object.keys(rest).length > 0 ? rest : undefined;\n}\n\nexport function createGroupsResource(request: RequestFn) {\n return {\n /**\n * Fetch groups for the authenticated customer.\n * May return **503** when the Groups API is disabled for this merchant.\n */\n getAll: (query?: GetGroupsQuery) =>\n request<GetGroupsResponse>({\n method: \"GET\",\n path: \"/api/groups\",\n auth: \"authenticated\",\n query: normalizeGetGroupsQuery(query),\n }),\n\n /**\n * Fetch group details by id.\n * May return **503** when the Groups API is disabled for this merchant.\n */\n getById: (groupId: string, query?: GetGroupQuery) =>\n request<GetGroupResponse>({\n method: \"GET\",\n path: `/api/groups/${encodeURIComponent(groupId)}`,\n auth: \"authenticated\",\n query,\n }),\n\n /** Create a new group. */\n create: (body: CreateGroupBody) =>\n request<CreateGroupResponse, CreateGroupBody>({\n method: \"POST\",\n path: \"/api/groups\",\n auth: \"authenticated\",\n body,\n }),\n\n /** Update group name/description. */\n update: (groupId: string, body: UpdateGroupBody) =>\n request<UpdateGroupDetailsResponse, UpdateGroupBody>({\n method: \"PATCH\",\n path: `/api/groups/${encodeURIComponent(groupId)}`,\n auth: \"authenticated\",\n body,\n }),\n\n /** Remove a group. */\n remove: (groupId: string) =>\n request<RemoveGroupResponse>({\n method: \"DELETE\",\n path: `/api/groups/${encodeURIComponent(groupId)}`,\n auth: \"authenticated\",\n }),\n\n /**\n * Duplicate a group (including all lists and items) in a single call.\n * The copy is named `Copy of {original name}` and is not shared.\n */\n duplicate: (groupId: string) =>\n request<DuplicateGroupResponse>({\n method: \"POST\",\n path: `/api/groups/${encodeURIComponent(groupId)}/duplicate`,\n auth: \"authenticated\",\n }),\n\n /**\n * Reorder the customer's groups (`POST /api/groups/reorder`).\n * Body must include `groupIds` in the desired order — not list IDs, and\n * not a per-group path.\n */\n reorder: (body: ReorderGroupsBody) =>\n request<ReorderGroupsResponse, ReorderGroupsBody>({\n method: \"POST\",\n path: \"/api/groups/reorder\",\n auth: \"authenticated\",\n body,\n }),\n\n /** Mark group as shared (public read-only). */\n share: (groupId: string) =>\n request<MarkGroupSharedResponse>({\n method: \"POST\",\n path: `/api/groups/${encodeURIComponent(groupId)}/share`,\n auth: \"authenticated\",\n }),\n\n /** Revoke group sharing. */\n unshare: (groupId: string) =>\n request<RevokeGroupSharedResponse>({\n method: \"DELETE\",\n path: `/api/groups/${encodeURIComponent(groupId)}/share`,\n auth: \"authenticated\",\n }),\n };\n}\n","import type { RequestArgs } from \"../../client/request\";\nimport type { PaginatedQuery } from \"../../types/query-options\";\nimport type { GetSharedGroupResponse, GetSharedListResponse } from \"../../types/responses/shared\";\n\ntype RequestFn = <TResponse = unknown, TBody = unknown>(\n args: RequestArgs<TBody>,\n) => Promise<TResponse>;\n\nexport type GetSharedListQuery = Omit<PaginatedQuery, \"query\">;\nexport type GetSharedGroupQuery = PaginatedQuery;\n\nexport function createSharedResource(request: RequestFn) {\n return {\n /** Public read-only view of a shared list. Requires only merchant apiKey. */\n getSharedList: (listId: string, query?: GetSharedListQuery) =>\n request<GetSharedListResponse>({\n method: \"GET\",\n path: `/api/shared/list/${encodeURIComponent(listId)}`,\n auth: \"merchant\",\n query,\n }),\n\n /** Public read-only view of a shared group. Requires only merchant apiKey. */\n getSharedGroup: (groupId: string, query?: GetSharedGroupQuery) =>\n request<GetSharedGroupResponse>({\n method: \"GET\",\n path: `/api/shared/group/${encodeURIComponent(groupId)}`,\n auth: \"merchant\",\n query,\n }),\n };\n}\n\n","import { BASE_URL } from \"../constants\";\nimport { createRequest, type FetchLike } from \"./request\";\nimport { createListsResource } from \"../resources/lists\";\nimport { createGroupsResource } from \"../resources/groups\";\nimport { createSharedResource } from \"../resources/shared\";\n\nexport type CreateWishlistStackClientOptions = {\n baseUrl?: string;\n apiKey: string;\n customerAccessToken?: string;\n fetch?: FetchLike;\n /** Default request timeout in ms when a call does not pass `timeoutMs`. */\n defaultTimeoutMs?: number;\n /** When true, retry safe reads once on HTTP 429 (default: false). */\n retryOnRateLimit?: boolean;\n};\n\nexport type WishlistStackClient = {\n lists: ReturnType<typeof createListsResource>;\n groups: ReturnType<typeof createGroupsResource>;\n shared: ReturnType<typeof createSharedResource>;\n};\n\nexport function createWishlistStackClient(opts: CreateWishlistStackClientOptions): WishlistStackClient {\n if (!opts.apiKey) {\n throw new Error(\n \"merchant api key is required. Pass it to createWishlistStackClient({ apiKey })\",\n );\n }\n\n // Cloudflare Workers (and some other runtimes) can throw \"Illegal invocation\" if you\n // capture `globalThis.fetch` and call it later without the correct `this` binding.\n // So: default to a wrapper that calls `globalThis.fetch(...)` directly.\n const fetchImpl: FetchLike | undefined =\n opts.fetch ??\n (typeof globalThis.fetch === \"function\"\n ? ((input, init) => globalThis.fetch(input, init)) // keep correct invocation context\n : undefined);\n\n if (!fetchImpl) {\n throw new Error(\n \"No fetch implementation found. Provide one via createWishlistStackClient({ fetch }) or use Node 18+ / modern browsers.\",\n );\n }\n\n const request = createRequest({\n baseUrl: opts.baseUrl ?? BASE_URL,\n apiKey: opts.apiKey,\n customerAccessToken: opts.customerAccessToken,\n fetch: fetchImpl,\n defaultTimeoutMs: opts.defaultTimeoutMs,\n retryOnRateLimit: opts.retryOnRateLimit,\n });\n\n return {\n lists: createListsResource(request),\n groups: createGroupsResource(request),\n shared: createSharedResource(request),\n };\n}\n","import { createWishlistStackClient, type CreateWishlistStackClientOptions, type WishlistStackClient as IWishlistStackClient } from \"./client/createWishlistStackClient\";\n\n/**\n * Class wrapper around `createWishlistStackClient()` for users who prefer `new`.\n * Exposes `lists`, `groups`, and `shared` resources.\n */\nexport class WishlistStackClient implements IWishlistStackClient {\n readonly lists: IWishlistStackClient[\"lists\"];\n readonly groups: IWishlistStackClient[\"groups\"];\n readonly shared: IWishlistStackClient[\"shared\"];\n\n constructor(opts: CreateWishlistStackClientOptions) {\n const client = createWishlistStackClient(opts);\n this.lists = client.lists;\n this.groups = client.groups;\n this.shared = client.shared;\n }\n\n /** Back-compat alias: `client.groups.getAll()` */\n getGroups() {\n return this.groups.getAll();\n }\n\n /** Back-compat alias: `client.groups.getById(groupId)` */\n getGroupById(groupId: string) {\n return this.groups.getById(groupId);\n }\n\n /** Back-compat alias: `client.lists.getAll()` */\n getLists() {\n return this.lists.getAll();\n }\n}\n","import { MAX_PAGINATION_SIZE } from \"../constants\";\n\nexport type PaginationParams = {\n page?: number;\n pageSize?: number;\n query?: string;\n};\n\nexport const DEFAULT_PAGE = 1 as const;\nexport const DEFAULT_PAGE_SIZE = MAX_PAGINATION_SIZE;\n\n","import type { Query } from \"../client/query\";\nimport type { PaginationParams } from \"./pagination\";\n\nexport const SORT_FIELDS = [\"position\", \"createdAt\", \"updatedAt\"] as const;\nexport const SORT_DIRECTIONS = [\"asc\", \"desc\"] as const;\n\nexport type SortField = (typeof SORT_FIELDS)[number];\nexport type SortDirection = (typeof SORT_DIRECTIONS)[number];\n\n/**\n * Collection sort options for multi-resource GET endpoints.\n * Defaults on the API are `sortBy=position` and `sortDirection=asc`.\n */\nexport type SortParams = {\n sortBy?: SortField;\n sortDirection?: SortDirection;\n};\n\n/**\n * Shared query option building blocks for list/group endpoints.\n *\n * Keep this extendable: as we add filters/sorts, we can add additional helpers/types here\n * and reuse them across endpoints without duplicating logic.\n */\nexport type PaginatedQuery<TExtra extends Query = Query> = PaginationParams & SortParams & TExtra;\n\n/**\n * Merge a base query with pagination parameters.\n * (Useful when an endpoint also gains filter/sort params over time.)\n */\nexport function withPagination<TExtra extends Query>(\n query?: TExtra,\n pagination?: PaginationParams,\n): PaginatedQuery<TExtra> | undefined {\n if (!query && !pagination) return undefined;\n return { ...(query ?? {}), ...(pagination ?? {}) } as PaginatedQuery<TExtra>;\n}\n\n/**\n * Merge a base query with sort parameters.\n */\nexport function withSort<TExtra extends Query>(\n query?: TExtra,\n sort?: SortParams,\n): (TExtra & SortParams) | undefined {\n if (!query && !sort) return undefined;\n return { ...(query ?? {}), ...(sort ?? {}) } as TExtra & SortParams;\n}\n\n","import type { AddItemsToListResponse } from \"./responses/lists\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\n/**\n * True when the value matches the add-items response shape\n * (`{ listId, addedItems, addedCount }`).\n */\nexport function isAddItemsDeltaResponse(\n value: AddItemsToListResponse | unknown,\n): value is AddItemsToListResponse {\n if (!isRecord(value)) return false;\n return (\n typeof value.listId === \"string\" &&\n Array.isArray(value.addedItems) &&\n typeof value.addedCount === \"number\"\n );\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -12,6 +12,8 @@ type RequestArgs<TBody> = {
|
|
|
12
12
|
headers?: Record<string, string>;
|
|
13
13
|
signal?: AbortSignal;
|
|
14
14
|
timeoutMs?: number;
|
|
15
|
+
/** Marks a non-GET operation as safe to retry once on HTTP 429. */
|
|
16
|
+
retryable?: boolean;
|
|
15
17
|
};
|
|
16
18
|
|
|
17
19
|
type PaginationParams = {
|
|
@@ -56,7 +58,7 @@ declare function withSort<TExtra extends Query>(query?: TExtra, sort?: SortParam
|
|
|
56
58
|
* Create the list, then call `lists.addItems` or `lists.addItemsBatched`.
|
|
57
59
|
*/
|
|
58
60
|
type CreateListBody = {
|
|
59
|
-
name
|
|
61
|
+
name: string;
|
|
60
62
|
description?: string;
|
|
61
63
|
groupId?: string;
|
|
62
64
|
};
|
|
@@ -66,14 +68,18 @@ type UpdateListBody = {
|
|
|
66
68
|
groupId?: string;
|
|
67
69
|
};
|
|
68
70
|
type AddItemsToListBody = {
|
|
69
|
-
items
|
|
70
|
-
variantId
|
|
71
|
+
items: Array<{
|
|
72
|
+
variantId: string;
|
|
71
73
|
/** Quantity for the item (1–999). */
|
|
72
74
|
quantity?: number;
|
|
73
75
|
note?: string;
|
|
74
76
|
properties?: Record<string, unknown> | null;
|
|
75
77
|
}>;
|
|
76
78
|
};
|
|
79
|
+
/** Check membership for 1–100 Shopify product variant IDs. */
|
|
80
|
+
type ContainsVariantsBody = {
|
|
81
|
+
variantIds: string[];
|
|
82
|
+
};
|
|
77
83
|
type UpdateListItemBody = {
|
|
78
84
|
variantId?: string;
|
|
79
85
|
quantity?: number;
|
|
@@ -101,6 +107,17 @@ type Pagination = {
|
|
|
101
107
|
totalCount: number;
|
|
102
108
|
totalPages: number;
|
|
103
109
|
};
|
|
110
|
+
/** Pagination metadata returned by list-detail endpoints. */
|
|
111
|
+
type ListDetailPagination = {
|
|
112
|
+
page: number;
|
|
113
|
+
pageSize: number;
|
|
114
|
+
totalItems: number;
|
|
115
|
+
/** Compatibility alias for `totalItems`. */
|
|
116
|
+
totalCount: number;
|
|
117
|
+
totalPages: number;
|
|
118
|
+
hasNextPage: boolean;
|
|
119
|
+
hasPreviousPage: boolean;
|
|
120
|
+
};
|
|
104
121
|
type Image = {
|
|
105
122
|
altText?: string | null;
|
|
106
123
|
url: string;
|
|
@@ -181,7 +198,7 @@ type GetListsResponse = {
|
|
|
181
198
|
};
|
|
182
199
|
/** GET `/api/lists/:listId` — items are paginated (max pageSize 25). */
|
|
183
200
|
type GetListResponse = ListDetail & {
|
|
184
|
-
pagination:
|
|
201
|
+
pagination: ListDetailPagination;
|
|
185
202
|
};
|
|
186
203
|
type ListMutationResponse = Omit<ListSummary, "featuredProducts">;
|
|
187
204
|
type CreateListResponse = ListMutationResponse;
|
|
@@ -194,6 +211,20 @@ type AddItemsToListResponse = {
|
|
|
194
211
|
addedItems: HydratedWishlistItem[];
|
|
195
212
|
addedCount: number;
|
|
196
213
|
};
|
|
214
|
+
/** POST `/api/lists/:listId/contains` */
|
|
215
|
+
type VariantMembershipMatch = {
|
|
216
|
+
id: string;
|
|
217
|
+
variantId: string;
|
|
218
|
+
quantity: number;
|
|
219
|
+
position: number;
|
|
220
|
+
note: string | null;
|
|
221
|
+
properties: Record<string, unknown> | null;
|
|
222
|
+
};
|
|
223
|
+
type ContainsVariantsResponse = {
|
|
224
|
+
listId: string;
|
|
225
|
+
present: Record<string, boolean>;
|
|
226
|
+
matches: Record<string, VariantMembershipMatch[]>;
|
|
227
|
+
};
|
|
197
228
|
/** @deprecated Use `AddItemsToListResponse`. */
|
|
198
229
|
type AddItemsToListDeltaResponse = AddItemsToListResponse;
|
|
199
230
|
type UpdateListItemResponse = unknown;
|
|
@@ -251,6 +282,11 @@ declare function createListsResource(request: RequestFn$2): {
|
|
|
251
282
|
* when sending more than 25 items.
|
|
252
283
|
*/
|
|
253
284
|
addItems: (listId: string, body: AddItemsToListBody) => Promise<AddItemsToListResponse>;
|
|
285
|
+
/**
|
|
286
|
+
* Check whether up to 100 variants are present without hydrating or
|
|
287
|
+
* paging through the list. Response keys preserve the supplied IDs.
|
|
288
|
+
*/
|
|
289
|
+
containsVariants: (listId: string, body: ContainsVariantsBody) => Promise<ContainsVariantsResponse>;
|
|
254
290
|
/**
|
|
255
291
|
* Add items in sequential batches of ≤25 (API hard max).
|
|
256
292
|
* Merges `{ addedItems, addedCount }` across batches.
|
|
@@ -442,7 +478,7 @@ type CreateWishlistStackClientOptions = {
|
|
|
442
478
|
fetch?: FetchLike;
|
|
443
479
|
/** Default request timeout in ms when a call does not pass `timeoutMs`. */
|
|
444
480
|
defaultTimeoutMs?: number;
|
|
445
|
-
/** When true, retry once on HTTP 429
|
|
481
|
+
/** When true, retry safe reads once on HTTP 429 (default: false). */
|
|
446
482
|
retryOnRateLimit?: boolean;
|
|
447
483
|
};
|
|
448
484
|
type WishlistStackClient$1 = {
|
|
@@ -540,4 +576,5 @@ declare function clampPageSize(n: number): number;
|
|
|
540
576
|
*/
|
|
541
577
|
declare function clampPage(n: number): number;
|
|
542
578
|
|
|
543
|
-
export {
|
|
579
|
+
export { DEFAULT_PAGE, DEFAULT_PAGE_SIZE, SORT_DIRECTIONS, SORT_FIELDS, WishlistStackApiError, WishlistStackClient as WishlistStackSDK, clampPage, clampPageSize, createWishlistStackClient, isAddItemsDeltaResponse, isWishlistStackApiError, withPagination, withSort };
|
|
580
|
+
export type { AddItemsToListBody, AddItemsToListDeltaResponse, AddItemsToListResponse, ApiErrorItem, ApiErrorResponse, ContainsVariantsBody, ContainsVariantsResponse, CreateGroupBody, CreateGroupResponse, CreateListBody, CreateListResponse, CreateWishlistStackClientOptions, DuplicateGroupResponse, DuplicateListBody, DuplicateListResponse, FeaturedItem, GetGroupResponse, GetGroupsResponse, GetListResponse, GetListsResponse, GetSharedGroupResponse, GetSharedListResponse, GroupDetail, GroupDetailList, GroupMutationResponse, GroupSummary, GroupSummaryList, HydratedProduct, HydratedVariant, HydratedWishlistItem, Id, Image, ListDetail, ListDetailPagination, ListMutationResponse, ListSummary, MarkGroupSharedResponse, MarkListSharedResponse, Metafield, Money, OkResponse, PaginatedQuery, Pagination, PaginationParams, RemoveGroupResponse, RemoveItemFromListResponse, RemoveListResponse, ReorderGroupBody, ReorderGroupResponse, ReorderGroupsBody, ReorderGroupsResponse, ReorderListItemsBody, ReorderListItemsResponse, RevokeGroupSharedResponse, RevokeListSharedResponse, SelectedOption, SortDirection, SortField, SortParams, UpdateGroupBody, UpdateGroupDetailsResponse, UpdateListBody, UpdateListDetailsResponse, UpdateListItemBody, UpdateListItemResponse, VariantMembershipMatch, WishlistStackClient$1 as WishlistStackClient };
|
package/dist/index.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ type RequestArgs<TBody> = {
|
|
|
12
12
|
headers?: Record<string, string>;
|
|
13
13
|
signal?: AbortSignal;
|
|
14
14
|
timeoutMs?: number;
|
|
15
|
+
/** Marks a non-GET operation as safe to retry once on HTTP 429. */
|
|
16
|
+
retryable?: boolean;
|
|
15
17
|
};
|
|
16
18
|
|
|
17
19
|
type PaginationParams = {
|
|
@@ -56,7 +58,7 @@ declare function withSort<TExtra extends Query>(query?: TExtra, sort?: SortParam
|
|
|
56
58
|
* Create the list, then call `lists.addItems` or `lists.addItemsBatched`.
|
|
57
59
|
*/
|
|
58
60
|
type CreateListBody = {
|
|
59
|
-
name
|
|
61
|
+
name: string;
|
|
60
62
|
description?: string;
|
|
61
63
|
groupId?: string;
|
|
62
64
|
};
|
|
@@ -66,14 +68,18 @@ type UpdateListBody = {
|
|
|
66
68
|
groupId?: string;
|
|
67
69
|
};
|
|
68
70
|
type AddItemsToListBody = {
|
|
69
|
-
items
|
|
70
|
-
variantId
|
|
71
|
+
items: Array<{
|
|
72
|
+
variantId: string;
|
|
71
73
|
/** Quantity for the item (1–999). */
|
|
72
74
|
quantity?: number;
|
|
73
75
|
note?: string;
|
|
74
76
|
properties?: Record<string, unknown> | null;
|
|
75
77
|
}>;
|
|
76
78
|
};
|
|
79
|
+
/** Check membership for 1–100 Shopify product variant IDs. */
|
|
80
|
+
type ContainsVariantsBody = {
|
|
81
|
+
variantIds: string[];
|
|
82
|
+
};
|
|
77
83
|
type UpdateListItemBody = {
|
|
78
84
|
variantId?: string;
|
|
79
85
|
quantity?: number;
|
|
@@ -101,6 +107,17 @@ type Pagination = {
|
|
|
101
107
|
totalCount: number;
|
|
102
108
|
totalPages: number;
|
|
103
109
|
};
|
|
110
|
+
/** Pagination metadata returned by list-detail endpoints. */
|
|
111
|
+
type ListDetailPagination = {
|
|
112
|
+
page: number;
|
|
113
|
+
pageSize: number;
|
|
114
|
+
totalItems: number;
|
|
115
|
+
/** Compatibility alias for `totalItems`. */
|
|
116
|
+
totalCount: number;
|
|
117
|
+
totalPages: number;
|
|
118
|
+
hasNextPage: boolean;
|
|
119
|
+
hasPreviousPage: boolean;
|
|
120
|
+
};
|
|
104
121
|
type Image = {
|
|
105
122
|
altText?: string | null;
|
|
106
123
|
url: string;
|
|
@@ -181,7 +198,7 @@ type GetListsResponse = {
|
|
|
181
198
|
};
|
|
182
199
|
/** GET `/api/lists/:listId` — items are paginated (max pageSize 25). */
|
|
183
200
|
type GetListResponse = ListDetail & {
|
|
184
|
-
pagination:
|
|
201
|
+
pagination: ListDetailPagination;
|
|
185
202
|
};
|
|
186
203
|
type ListMutationResponse = Omit<ListSummary, "featuredProducts">;
|
|
187
204
|
type CreateListResponse = ListMutationResponse;
|
|
@@ -194,6 +211,20 @@ type AddItemsToListResponse = {
|
|
|
194
211
|
addedItems: HydratedWishlistItem[];
|
|
195
212
|
addedCount: number;
|
|
196
213
|
};
|
|
214
|
+
/** POST `/api/lists/:listId/contains` */
|
|
215
|
+
type VariantMembershipMatch = {
|
|
216
|
+
id: string;
|
|
217
|
+
variantId: string;
|
|
218
|
+
quantity: number;
|
|
219
|
+
position: number;
|
|
220
|
+
note: string | null;
|
|
221
|
+
properties: Record<string, unknown> | null;
|
|
222
|
+
};
|
|
223
|
+
type ContainsVariantsResponse = {
|
|
224
|
+
listId: string;
|
|
225
|
+
present: Record<string, boolean>;
|
|
226
|
+
matches: Record<string, VariantMembershipMatch[]>;
|
|
227
|
+
};
|
|
197
228
|
/** @deprecated Use `AddItemsToListResponse`. */
|
|
198
229
|
type AddItemsToListDeltaResponse = AddItemsToListResponse;
|
|
199
230
|
type UpdateListItemResponse = unknown;
|
|
@@ -251,6 +282,11 @@ declare function createListsResource(request: RequestFn$2): {
|
|
|
251
282
|
* when sending more than 25 items.
|
|
252
283
|
*/
|
|
253
284
|
addItems: (listId: string, body: AddItemsToListBody) => Promise<AddItemsToListResponse>;
|
|
285
|
+
/**
|
|
286
|
+
* Check whether up to 100 variants are present without hydrating or
|
|
287
|
+
* paging through the list. Response keys preserve the supplied IDs.
|
|
288
|
+
*/
|
|
289
|
+
containsVariants: (listId: string, body: ContainsVariantsBody) => Promise<ContainsVariantsResponse>;
|
|
254
290
|
/**
|
|
255
291
|
* Add items in sequential batches of ≤25 (API hard max).
|
|
256
292
|
* Merges `{ addedItems, addedCount }` across batches.
|
|
@@ -442,7 +478,7 @@ type CreateWishlistStackClientOptions = {
|
|
|
442
478
|
fetch?: FetchLike;
|
|
443
479
|
/** Default request timeout in ms when a call does not pass `timeoutMs`. */
|
|
444
480
|
defaultTimeoutMs?: number;
|
|
445
|
-
/** When true, retry once on HTTP 429
|
|
481
|
+
/** When true, retry safe reads once on HTTP 429 (default: false). */
|
|
446
482
|
retryOnRateLimit?: boolean;
|
|
447
483
|
};
|
|
448
484
|
type WishlistStackClient$1 = {
|
|
@@ -540,4 +576,5 @@ declare function clampPageSize(n: number): number;
|
|
|
540
576
|
*/
|
|
541
577
|
declare function clampPage(n: number): number;
|
|
542
578
|
|
|
543
|
-
export {
|
|
579
|
+
export { DEFAULT_PAGE, DEFAULT_PAGE_SIZE, SORT_DIRECTIONS, SORT_FIELDS, WishlistStackApiError, WishlistStackClient as WishlistStackSDK, clampPage, clampPageSize, createWishlistStackClient, isAddItemsDeltaResponse, isWishlistStackApiError, withPagination, withSort };
|
|
580
|
+
export type { AddItemsToListBody, AddItemsToListDeltaResponse, AddItemsToListResponse, ApiErrorItem, ApiErrorResponse, ContainsVariantsBody, ContainsVariantsResponse, CreateGroupBody, CreateGroupResponse, CreateListBody, CreateListResponse, CreateWishlistStackClientOptions, DuplicateGroupResponse, DuplicateListBody, DuplicateListResponse, FeaturedItem, GetGroupResponse, GetGroupsResponse, GetListResponse, GetListsResponse, GetSharedGroupResponse, GetSharedListResponse, GroupDetail, GroupDetailList, GroupMutationResponse, GroupSummary, GroupSummaryList, HydratedProduct, HydratedVariant, HydratedWishlistItem, Id, Image, ListDetail, ListDetailPagination, ListMutationResponse, ListSummary, MarkGroupSharedResponse, MarkListSharedResponse, Metafield, Money, OkResponse, PaginatedQuery, Pagination, PaginationParams, RemoveGroupResponse, RemoveItemFromListResponse, RemoveListResponse, ReorderGroupBody, ReorderGroupResponse, ReorderGroupsBody, ReorderGroupsResponse, ReorderListItemsBody, ReorderListItemsResponse, RevokeGroupSharedResponse, RevokeListSharedResponse, SelectedOption, SortDirection, SortField, SortParams, UpdateGroupBody, UpdateGroupDetailsResponse, UpdateListBody, UpdateListDetailsResponse, UpdateListItemBody, UpdateListItemResponse, VariantMembershipMatch, WishlistStackClient$1 as WishlistStackClient };
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
4
4
|
|
|
5
5
|
// src/constants.ts
|
|
6
6
|
var MAX_PAGINATION_SIZE = 25;
|
|
7
|
-
var BASE_URL = "https://
|
|
7
|
+
var BASE_URL = "https://app.wishliststack.com";
|
|
8
8
|
|
|
9
9
|
// src/client/query.ts
|
|
10
10
|
function toQueryString(query) {
|
|
@@ -164,7 +164,8 @@ function createRequest(ctx) {
|
|
|
164
164
|
}
|
|
165
165
|
};
|
|
166
166
|
let res = await doFetch();
|
|
167
|
-
|
|
167
|
+
const retryable = args.method === "GET" || args.retryable === true;
|
|
168
|
+
if (!res.ok && res.status === 429 && ctx.retryOnRateLimit && retryable) {
|
|
168
169
|
const retryAfter = res.headers.get("retry-after") ?? void 0;
|
|
169
170
|
await sleep(jitterDelayMs(parseRetryAfterMs(retryAfter)));
|
|
170
171
|
res = await doFetch();
|
|
@@ -311,12 +312,26 @@ function createListsResource(request) {
|
|
|
311
312
|
* when sending more than 25 items.
|
|
312
313
|
*/
|
|
313
314
|
addItems,
|
|
315
|
+
/**
|
|
316
|
+
* Check whether up to 100 variants are present without hydrating or
|
|
317
|
+
* paging through the list. Response keys preserve the supplied IDs.
|
|
318
|
+
*/
|
|
319
|
+
containsVariants: (listId, body) => request({
|
|
320
|
+
method: "POST",
|
|
321
|
+
path: `/api/lists/${encodeURIComponent(listId)}/contains`,
|
|
322
|
+
auth: "authenticated",
|
|
323
|
+
body,
|
|
324
|
+
retryable: true
|
|
325
|
+
}),
|
|
314
326
|
/**
|
|
315
327
|
* Add items in sequential batches of ≤25 (API hard max).
|
|
316
328
|
* Merges `{ addedItems, addedCount }` across batches.
|
|
317
329
|
*/
|
|
318
330
|
addItemsBatched: async (listId, body, opts) => {
|
|
319
331
|
const items = body.items ?? [];
|
|
332
|
+
if (items.length === 0) {
|
|
333
|
+
throw new Error("lists.addItemsBatched requires at least one item");
|
|
334
|
+
}
|
|
320
335
|
const batchSize = opts?.batchSize ?? MAX_PAGINATION_SIZE;
|
|
321
336
|
const chunks = chunkItems(items, batchSize);
|
|
322
337
|
const merged = {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.ts","../src/client/query.ts","../src/client/errors.ts","../src/client/request.ts","../src/helpers/pagination.ts","../src/resources/lists/index.ts","../src/resources/groups/index.ts","../src/resources/shared/index.ts","../src/client/createWishlistStackClient.ts","../src/WishlistStackClient.ts","../src/types/pagination.ts","../src/types/query-options.ts","../src/types/guards.ts"],"names":["isRecord"],"mappings":"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","file":"index.js","sourcesContent":["export const MAX_PAGINATION_SIZE = 25 as const;\nexport const BASE_URL = \"https://wishlist.devteam.run\" as const;\n\n","export type QueryValue =\n | string\n | number\n | boolean\n | null\n | undefined\n | Array<string | number | boolean | null | undefined>;\n\nexport type Query = Record<string, QueryValue>;\n\nexport function toQueryString(query?: Query): string {\n if (!query) return \"\";\n\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined || value === null) continue;\n if (Array.isArray(value)) {\n for (const v of value) {\n if (v === undefined || v === null) continue;\n params.append(key, String(v));\n }\n continue;\n }\n params.set(key, String(value));\n }\n\n const qs = params.toString();\n return qs ? `?${qs}` : \"\";\n}\n\n","export type WishlistStackApiErrorDetails<TBody = unknown> = {\n status: number;\n url: string;\n method: string;\n requestId?: string;\n body?: TBody;\n /** Value of the `Retry-After` response header when present (seconds or HTTP-date). */\n retryAfter?: string;\n /** Selected rate-limit response headers when present. */\n rateLimit?: {\n limit?: string;\n remaining?: string;\n reset?: string;\n };\n};\n\ntype ApiErrorItemLike = { message?: unknown; field?: unknown };\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isApiErrorItemLike(value: unknown): value is ApiErrorItemLike {\n return isRecord(value) && \"message\" in value;\n}\n\nfunction extractApiErrors(body: unknown): Array<{ message: string; field?: string }> | undefined {\n if (!isRecord(body)) return undefined;\n const errors = body.errors;\n if (!Array.isArray(errors)) return undefined;\n const out: Array<{ message: string; field?: string }> = [];\n for (const e of errors) {\n if (!isApiErrorItemLike(e)) continue;\n const msg = typeof e.message === \"string\" ? e.message : undefined;\n if (!msg) continue;\n const field = typeof (e as any).field === \"string\" ? (e as any).field : undefined;\n out.push(field ? { message: msg, field } : { message: msg });\n }\n return out.length ? out : undefined;\n}\n\nexport class WishlistStackApiError<TBody = unknown> extends Error {\n readonly name = \"WishlistStackApiError\";\n readonly status: number;\n readonly url: string;\n readonly method: string;\n readonly requestId?: string;\n readonly body?: TBody;\n readonly retryAfter?: string;\n readonly rateLimit?: WishlistStackApiErrorDetails[\"rateLimit\"];\n\n constructor(message: string, details: WishlistStackApiErrorDetails<TBody>) {\n super(message);\n this.status = details.status;\n this.url = details.url;\n this.method = details.method;\n this.requestId = details.requestId;\n this.body = details.body;\n this.retryAfter = details.retryAfter;\n this.rateLimit = details.rateLimit;\n }\n\n /**\n * Best-effort extraction of API error items from the response body.\n * Useful for UI/logging without needing to know the exact response shape.\n */\n get apiErrors(): Array<{ message: string; field?: string }> | undefined {\n return extractApiErrors(this.body);\n }\n\n /**\n * Convenience: extracted error messages (if present).\n */\n get apiErrorMessages(): string[] | undefined {\n const errs = this.apiErrors;\n return errs?.map((e) => e.message);\n }\n}\n\n/**\n * Bundler-safe type guard (prefer this over `instanceof WishlistStackApiError`).\n */\nexport function isWishlistStackApiError(value: unknown): value is WishlistStackApiError<unknown> {\n if (!isRecord(value)) return false;\n return (\n (value as any).name === \"WishlistStackApiError\" &&\n typeof (value as any).status === \"number\" &&\n typeof (value as any).url === \"string\" &&\n typeof (value as any).method === \"string\"\n );\n}\n","import { toQueryString, type Query } from \"./query\";\nimport { WishlistStackApiError } from \"./errors\";\nimport type { ApiErrorResponse } from \"../types/common\";\n\nexport type FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;\n\nexport type AuthMode = \"authenticated\" | \"merchant\";\n\nexport type RequestContext = {\n baseUrl: string;\n apiKey: string;\n customerAccessToken?: string;\n fetch: FetchLike;\n /** Applied when a call does not pass `timeoutMs`. */\n defaultTimeoutMs?: number;\n /** When true, retry a single time on HTTP 429 with jittered delay. */\n retryOnRateLimit?: boolean;\n};\n\nexport type RequestArgs<TBody> = {\n method: \"GET\" | \"POST\" | \"PATCH\" | \"DELETE\";\n path: string;\n auth: AuthMode;\n query?: Query;\n body?: TBody;\n headers?: Record<string, string>;\n signal?: AbortSignal;\n timeoutMs?: number;\n};\n\nasync function safeParseJson(res: Response): Promise<unknown | undefined> {\n const contentType = res.headers.get(\"content-type\") ?? \"\";\n if (!contentType.toLowerCase().includes(\"application/json\")) return undefined;\n try {\n return await res.json();\n } catch {\n return undefined;\n }\n}\n\nfunction pickRequestId(res: Response): string | undefined {\n return (\n res.headers.get(\"fly-request-id\") ??\n res.headers.get(\"x-request-id\") ??\n res.headers.get(\"x-nf-request-id\") ??\n res.headers.get(\"x-netlify-request-id\") ??\n undefined\n );\n}\n\nfunction pickRateLimit(res: Response): { limit?: string; remaining?: string; reset?: string } | undefined {\n const limit = res.headers.get(\"x-ratelimit-limit\") ?? undefined;\n const remaining = res.headers.get(\"x-ratelimit-remaining\") ?? undefined;\n const reset = res.headers.get(\"x-ratelimit-reset\") ?? undefined;\n if (!limit && !remaining && !reset) return undefined;\n return { limit, remaining, reset };\n}\n\nfunction errorMessageFor(status: number, path: string): string {\n if (status === 503 && path.includes(\"/api/groups\")) {\n return \"Groups API disabled for this merchant\";\n }\n return `Wishlist Stack API request failed (${status})`;\n}\n\nfunction parseRetryAfterMs(retryAfter: string | undefined): number {\n if (!retryAfter) return 0;\n const asSeconds = Number(retryAfter);\n if (Number.isFinite(asSeconds) && asSeconds >= 0) {\n return Math.min(asSeconds * 1000, 30_000);\n }\n const asDate = Date.parse(retryAfter);\n if (!Number.isNaN(asDate)) {\n return Math.min(Math.max(0, asDate - Date.now()), 30_000);\n }\n return 0;\n}\n\nfunction jitterDelayMs(baseMs: number): number {\n const base = Math.max(100, baseMs || 500);\n const jitter = Math.floor(Math.random() * 250);\n return Math.min(base + jitter, 30_000);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function createRequest(ctx: RequestContext) {\n return async function request<TResponse = unknown, TBody = unknown>(\n args: RequestArgs<TBody>,\n ): Promise<TResponse> {\n const url = `${ctx.baseUrl}${args.path}${toQueryString(args.query)}`;\n\n const headers: Record<string, string> = {\n \"X-Wishlist-Stack-Api-Key\": ctx.apiKey,\n ...(args.headers ?? {}),\n };\n\n if (args.auth === \"authenticated\") {\n const token = ctx.customerAccessToken;\n // If token is missing, still perform the request and let the API return the appropriate\n // error response (which we will surface as a WishlistStackApiError based on the HTTP response).\n if (token) headers[\"X-Shopify-Customer-Access-Token\"] = token;\n }\n\n let body: BodyInit | undefined;\n if (args.body !== undefined) {\n // Only JSON bodies are supported for this SDK.\n headers[\"content-type\"] ??= \"application/json\";\n body = JSON.stringify(args.body);\n }\n\n const timeoutMs = args.timeoutMs ?? ctx.defaultTimeoutMs;\n\n const doFetch = async (): Promise<Response> => {\n const controller = timeoutMs ? new AbortController() : undefined;\n const timeout =\n timeoutMs && controller\n ? setTimeout(() => controller.abort(), timeoutMs)\n : undefined;\n\n const signal = args.signal\n ? args.signal\n : controller\n ? controller.signal\n : undefined;\n\n try {\n return await ctx.fetch(url, {\n method: args.method,\n headers,\n body,\n signal,\n });\n } finally {\n if (timeout) clearTimeout(timeout);\n }\n };\n\n let res = await doFetch();\n\n if (!res.ok && res.status === 429 && ctx.retryOnRateLimit) {\n const retryAfter = res.headers.get(\"retry-after\") ?? undefined;\n await sleep(jitterDelayMs(parseRetryAfterMs(retryAfter)));\n res = await doFetch();\n }\n\n if (!res.ok) {\n const errBody = (await safeParseJson(res)) as ApiErrorResponse | unknown;\n const retryAfter = res.headers.get(\"retry-after\") ?? undefined;\n throw new WishlistStackApiError<ApiErrorResponse | unknown>(errorMessageFor(res.status, args.path), {\n status: res.status,\n url,\n method: args.method,\n requestId: pickRequestId(res),\n body: errBody,\n retryAfter,\n rateLimit: pickRateLimit(res),\n });\n }\n\n if (res.status === 204) return undefined as TResponse;\n\n const parsed = await safeParseJson(res);\n // If server didn't return JSON, return the raw text as unknown.\n if (parsed === undefined) {\n const text = await res.text().catch(() => \"\");\n return text as unknown as TResponse;\n }\n\n return parsed as TResponse;\n };\n}\n","import { MAX_PAGINATION_SIZE } from \"../constants\";\n\n/**\n * Clamp a page size to the API-allowed range (1–25) so requests\n * do not send invalid `pageSize` values.\n */\nexport function clampPageSize(n: number): number {\n if (!Number.isFinite(n)) return MAX_PAGINATION_SIZE;\n return Math.min(MAX_PAGINATION_SIZE, Math.max(1, Math.trunc(n)));\n}\n\n/**\n * Clamp a 1-based page index to at least 1.\n */\nexport function clampPage(n: number): number {\n if (!Number.isFinite(n)) return 1;\n return Math.max(1, Math.trunc(n));\n}\n","import type { RequestArgs } from \"../../client/request\";\nimport { MAX_PAGINATION_SIZE } from \"../../constants\";\nimport { clampPage, clampPageSize } from \"../../helpers/pagination\";\nimport type { PaginatedQuery } from \"../../types/query-options\";\nimport type {\n AddItemsToListBody,\n CreateListBody,\n DuplicateListBody,\n ReorderListItemsBody,\n UpdateListBody,\n UpdateListItemBody,\n} from \"../../types/requests/lists\";\nimport type {\n AddItemsToListResponse,\n CreateListResponse,\n DuplicateListResponse,\n GetListResponse,\n GetListsResponse,\n HydratedWishlistItem,\n MarkListSharedResponse,\n RemoveItemFromListResponse,\n RemoveListResponse,\n ReorderListItemsResponse,\n RevokeListSharedResponse,\n UpdateListDetailsResponse,\n UpdateListItemResponse,\n} from \"../../types/responses/lists\";\nimport type { Pagination } from \"../../types/responses/common\";\n\ntype RequestFn = <TResponse = unknown, TBody = unknown>(\n args: RequestArgs<TBody>,\n) => Promise<TResponse>;\n\nexport type GetListsQuery = PaginatedQuery;\nexport type GetListQuery = Omit<PaginatedQuery, \"query\">;\n\nexport type AddItemsBatchedOptions = {\n /** Max items per POST (API hard max is 25). */\n batchSize?: number;\n};\n\nexport type GetByIdAllItemsOptions = {\n pageSize?: number;\n sortBy?: GetListQuery[\"sortBy\"];\n sortDirection?: GetListQuery[\"sortDirection\"];\n};\n\nfunction chunkItems<T>(items: T[], batchSize: number): T[][] {\n const size = Math.max(1, Math.min(MAX_PAGINATION_SIZE, Math.trunc(batchSize) || MAX_PAGINATION_SIZE));\n const chunks: T[][] = [];\n for (let i = 0; i < items.length; i += size) {\n chunks.push(items.slice(i, i + size));\n }\n return chunks.length ? chunks : [[]];\n}\n\nexport function createListsResource(request: RequestFn) {\n const getById = (listId: string, query?: GetListQuery) =>\n request<GetListResponse>({\n method: \"GET\",\n path: `/api/lists/${encodeURIComponent(listId)}`,\n auth: \"authenticated\",\n query,\n });\n\n const addItems = (listId: string, body: AddItemsToListBody) =>\n request<AddItemsToListResponse, AddItemsToListBody>({\n method: \"POST\",\n path: `/api/lists/${encodeURIComponent(listId)}/add`,\n auth: \"authenticated\",\n body,\n });\n\n return {\n /** Returns all lists for the authenticated customer under the current merchant. */\n getAll: (query?: GetListsQuery) =>\n request<GetListsResponse>({\n method: \"GET\",\n path: \"/api/lists\",\n auth: \"authenticated\",\n query,\n }),\n\n /** Fetch list details by id. */\n getById,\n\n /**\n * Fetch every item on a list by walking pages (list detail is paginated;\n * max pageSize 25).\n */\n getByIdAllItems: async (listId: string, opts?: GetByIdAllItemsOptions): Promise<GetListResponse> => {\n const pageSize = clampPageSize(opts?.pageSize ?? MAX_PAGINATION_SIZE);\n const sortBy = opts?.sortBy;\n const sortDirection = opts?.sortDirection;\n\n const first = await getById(listId, {\n page: 1,\n pageSize,\n ...(sortBy ? { sortBy } : {}),\n ...(sortDirection ? { sortDirection } : {}),\n });\n\n const totalPages = first.pagination.totalPages;\n const allItems: HydratedWishlistItem[] = [...(first.items ?? [])];\n\n for (let page = 2; page <= totalPages; page++) {\n const next = await getById(listId, {\n page: clampPage(page),\n pageSize,\n ...(sortBy ? { sortBy } : {}),\n ...(sortDirection ? { sortDirection } : {}),\n });\n allItems.push(...(next.items ?? []));\n }\n\n const pagination: Pagination = {\n ...first.pagination,\n page: 1,\n pageSize,\n };\n\n return {\n ...first,\n items: allItems,\n pagination,\n };\n },\n\n /**\n * Create a new list. Do not send `variantIds` — add items via `addItems`\n * or `addItemsBatched` after create.\n */\n create: (body: CreateListBody) =>\n request<CreateListResponse, CreateListBody>({\n method: \"POST\",\n path: \"/api/lists\",\n auth: \"authenticated\",\n body,\n }),\n\n /** Update list name/description. */\n update: (listId: string, body: UpdateListBody) =>\n request<UpdateListDetailsResponse, UpdateListBody>({\n method: \"PATCH\",\n path: `/api/lists/${encodeURIComponent(listId)}`,\n auth: \"authenticated\",\n body,\n }),\n\n /** Remove a list. */\n remove: (listId: string) =>\n request<RemoveListResponse>({\n method: \"DELETE\",\n path: `/api/lists/${encodeURIComponent(listId)}`,\n auth: \"authenticated\",\n }),\n\n /**\n * Duplicate a list (including all items) in a single call.\n * By default the copy stays in the same group as the source. Pass `groupId`\n * to place it in another group, or `groupId: null` to leave it ungrouped.\n * The copy is named `Copy of {original name}` and is not shared.\n */\n duplicate: (listId: string, body?: DuplicateListBody) =>\n request<DuplicateListResponse, DuplicateListBody>({\n method: \"POST\",\n path: `/api/lists/${encodeURIComponent(listId)}/duplicate`,\n auth: \"authenticated\",\n body,\n }),\n\n /**\n * Add one or more items to a list.\n * Returns `{ listId, addedItems, addedCount }`. Prefer `addItemsBatched`\n * when sending more than 25 items.\n */\n addItems,\n\n /**\n * Add items in sequential batches of ≤25 (API hard max).\n * Merges `{ addedItems, addedCount }` across batches.\n */\n addItemsBatched: async (\n listId: string,\n body: AddItemsToListBody,\n opts?: AddItemsBatchedOptions,\n ): Promise<AddItemsToListResponse> => {\n const items = body.items ?? [];\n const batchSize = opts?.batchSize ?? MAX_PAGINATION_SIZE;\n const chunks = chunkItems(items, batchSize);\n\n const merged: AddItemsToListResponse = {\n listId,\n addedItems: [],\n addedCount: 0,\n };\n\n for (const chunk of chunks) {\n const res = await addItems(listId, { items: chunk });\n merged.listId = res.listId;\n merged.addedItems.push(...res.addedItems);\n merged.addedCount += res.addedCount;\n }\n\n return merged;\n },\n\n /** Update an item on a list. */\n updateItem: (listId: string, itemId: string, body: UpdateListItemBody) =>\n request<UpdateListItemResponse, UpdateListItemBody>({\n method: \"PATCH\",\n path: `/api/lists/${encodeURIComponent(listId)}/items/${encodeURIComponent(itemId)}`,\n auth: \"authenticated\",\n body,\n }),\n\n /** Remove an item from a list. */\n removeItem: (listId: string, itemId: string) =>\n request<RemoveItemFromListResponse>({\n method: \"DELETE\",\n path: `/api/lists/${encodeURIComponent(listId)}/items/${encodeURIComponent(itemId)}`,\n auth: \"authenticated\",\n }),\n\n /** Reorder all items in a list. */\n reorderItems: (listId: string, body: ReorderListItemsBody) =>\n request<ReorderListItemsResponse, ReorderListItemsBody>({\n method: \"POST\",\n path: `/api/lists/${encodeURIComponent(listId)}/reorder`,\n auth: \"authenticated\",\n body,\n }),\n\n /** Mark list as shared (public read-only). */\n share: (listId: string) =>\n request<MarkListSharedResponse>({\n method: \"POST\",\n path: `/api/lists/${encodeURIComponent(listId)}/share`,\n auth: \"authenticated\",\n }),\n\n /** Revoke list sharing. */\n unshare: (listId: string) =>\n request<RevokeListSharedResponse>({\n method: \"DELETE\",\n path: `/api/lists/${encodeURIComponent(listId)}/share`,\n auth: \"authenticated\",\n }),\n\n /**\n * Legacy endpoint kept in the OpenAPI spec (`/api/wishlists/{id}/add`).\n * Prefer `addItems(listId, body)` unless your server only supports the legacy route.\n */\n addItemsLegacy: (id: string, body: AddItemsToListBody) =>\n request<AddItemsToListResponse, AddItemsToListBody>({\n method: \"POST\",\n path: `/api/wishlists/${encodeURIComponent(id)}/add`,\n auth: \"authenticated\",\n body,\n }),\n };\n}\n","import type { RequestArgs } from \"../../client/request\";\nimport type { CreateGroupBody, ReorderGroupsBody, UpdateGroupBody } from \"../../types/requests/groups\";\nimport type { PaginatedQuery } from \"../../types/query-options\";\nimport type {\n CreateGroupResponse,\n DuplicateGroupResponse,\n GetGroupResponse,\n GetGroupsResponse,\n MarkGroupSharedResponse,\n RemoveGroupResponse,\n ReorderGroupsResponse,\n RevokeGroupSharedResponse,\n UpdateGroupDetailsResponse,\n} from \"../../types/responses/groups\";\n\ntype RequestFn = <TResponse = unknown, TBody = unknown>(\n args: RequestArgs<TBody>,\n) => Promise<TResponse>;\n\nexport type GetGroupsQuery = PaginatedQuery<{\n /**\n * When truthy (`true`, `1`, or `\"1\"`), each group includes embedded `lists`\n * with hydrated items (`includeLists=1`).\n *\n * Expect at most **10 lists × 25 items** per group. For full data use\n * `groups.getById` plus `lists.getById` / `lists.getByIdAllItems`. Groups\n * endpoints may return **503** until the Groups API is enabled for the merchant.\n */\n includeLists?: boolean | 1 | \"1\";\n}>;\nexport type GetGroupQuery = PaginatedQuery;\n\nfunction normalizeGetGroupsQuery(query?: GetGroupsQuery): GetGroupsQuery | undefined {\n if (!query) return undefined;\n const { includeLists, ...rest } = query;\n if (includeLists) {\n return { ...rest, includeLists: 1 };\n }\n return Object.keys(rest).length > 0 ? rest : undefined;\n}\n\nexport function createGroupsResource(request: RequestFn) {\n return {\n /**\n * Fetch groups for the authenticated customer.\n * May return **503** when the Groups API is disabled for this merchant.\n */\n getAll: (query?: GetGroupsQuery) =>\n request<GetGroupsResponse>({\n method: \"GET\",\n path: \"/api/groups\",\n auth: \"authenticated\",\n query: normalizeGetGroupsQuery(query),\n }),\n\n /**\n * Fetch group details by id.\n * May return **503** when the Groups API is disabled for this merchant.\n */\n getById: (groupId: string, query?: GetGroupQuery) =>\n request<GetGroupResponse>({\n method: \"GET\",\n path: `/api/groups/${encodeURIComponent(groupId)}`,\n auth: \"authenticated\",\n query,\n }),\n\n /** Create a new group. */\n create: (body: CreateGroupBody) =>\n request<CreateGroupResponse, CreateGroupBody>({\n method: \"POST\",\n path: \"/api/groups\",\n auth: \"authenticated\",\n body,\n }),\n\n /** Update group name/description. */\n update: (groupId: string, body: UpdateGroupBody) =>\n request<UpdateGroupDetailsResponse, UpdateGroupBody>({\n method: \"PATCH\",\n path: `/api/groups/${encodeURIComponent(groupId)}`,\n auth: \"authenticated\",\n body,\n }),\n\n /** Remove a group. */\n remove: (groupId: string) =>\n request<RemoveGroupResponse>({\n method: \"DELETE\",\n path: `/api/groups/${encodeURIComponent(groupId)}`,\n auth: \"authenticated\",\n }),\n\n /**\n * Duplicate a group (including all lists and items) in a single call.\n * The copy is named `Copy of {original name}` and is not shared.\n */\n duplicate: (groupId: string) =>\n request<DuplicateGroupResponse>({\n method: \"POST\",\n path: `/api/groups/${encodeURIComponent(groupId)}/duplicate`,\n auth: \"authenticated\",\n }),\n\n /**\n * Reorder the customer's groups (`POST /api/groups/reorder`).\n * Body must include `groupIds` in the desired order — not list IDs, and\n * not a per-group path.\n */\n reorder: (body: ReorderGroupsBody) =>\n request<ReorderGroupsResponse, ReorderGroupsBody>({\n method: \"POST\",\n path: \"/api/groups/reorder\",\n auth: \"authenticated\",\n body,\n }),\n\n /** Mark group as shared (public read-only). */\n share: (groupId: string) =>\n request<MarkGroupSharedResponse>({\n method: \"POST\",\n path: `/api/groups/${encodeURIComponent(groupId)}/share`,\n auth: \"authenticated\",\n }),\n\n /** Revoke group sharing. */\n unshare: (groupId: string) =>\n request<RevokeGroupSharedResponse>({\n method: \"DELETE\",\n path: `/api/groups/${encodeURIComponent(groupId)}/share`,\n auth: \"authenticated\",\n }),\n };\n}\n","import type { RequestArgs } from \"../../client/request\";\nimport type { PaginatedQuery } from \"../../types/query-options\";\nimport type { GetSharedGroupResponse, GetSharedListResponse } from \"../../types/responses/shared\";\n\ntype RequestFn = <TResponse = unknown, TBody = unknown>(\n args: RequestArgs<TBody>,\n) => Promise<TResponse>;\n\nexport type GetSharedListQuery = Omit<PaginatedQuery, \"query\">;\nexport type GetSharedGroupQuery = PaginatedQuery;\n\nexport function createSharedResource(request: RequestFn) {\n return {\n /** Public read-only view of a shared list. Requires only merchant apiKey. */\n getSharedList: (listId: string, query?: GetSharedListQuery) =>\n request<GetSharedListResponse>({\n method: \"GET\",\n path: `/api/shared/list/${encodeURIComponent(listId)}`,\n auth: \"merchant\",\n query,\n }),\n\n /** Public read-only view of a shared group. Requires only merchant apiKey. */\n getSharedGroup: (groupId: string, query?: GetSharedGroupQuery) =>\n request<GetSharedGroupResponse>({\n method: \"GET\",\n path: `/api/shared/group/${encodeURIComponent(groupId)}`,\n auth: \"merchant\",\n query,\n }),\n };\n}\n\n","import { BASE_URL } from \"../constants\";\nimport { createRequest, type FetchLike } from \"./request\";\nimport { createListsResource } from \"../resources/lists\";\nimport { createGroupsResource } from \"../resources/groups\";\nimport { createSharedResource } from \"../resources/shared\";\n\nexport type CreateWishlistStackClientOptions = {\n baseUrl?: string;\n apiKey: string;\n customerAccessToken?: string;\n fetch?: FetchLike;\n /** Default request timeout in ms when a call does not pass `timeoutMs`. */\n defaultTimeoutMs?: number;\n /** When true, retry once on HTTP 429 with jittered backoff (default: false). */\n retryOnRateLimit?: boolean;\n};\n\nexport type WishlistStackClient = {\n lists: ReturnType<typeof createListsResource>;\n groups: ReturnType<typeof createGroupsResource>;\n shared: ReturnType<typeof createSharedResource>;\n};\n\nexport function createWishlistStackClient(opts: CreateWishlistStackClientOptions): WishlistStackClient {\n if (!opts.apiKey) {\n throw new Error(\n \"merchant api key is required. Pass it to createWishlistStackClient({ apiKey })\",\n );\n }\n\n // Cloudflare Workers (and some other runtimes) can throw \"Illegal invocation\" if you\n // capture `globalThis.fetch` and call it later without the correct `this` binding.\n // So: default to a wrapper that calls `globalThis.fetch(...)` directly.\n const fetchImpl: FetchLike | undefined =\n opts.fetch ??\n (typeof globalThis.fetch === \"function\"\n ? ((input, init) => globalThis.fetch(input, init)) // keep correct invocation context\n : undefined);\n\n if (!fetchImpl) {\n throw new Error(\n \"No fetch implementation found. Provide one via createWishlistStackClient({ fetch }) or use Node 18+ / modern browsers.\",\n );\n }\n\n const request = createRequest({\n baseUrl: opts.baseUrl ?? BASE_URL,\n apiKey: opts.apiKey,\n customerAccessToken: opts.customerAccessToken,\n fetch: fetchImpl,\n defaultTimeoutMs: opts.defaultTimeoutMs,\n retryOnRateLimit: opts.retryOnRateLimit,\n });\n\n return {\n lists: createListsResource(request),\n groups: createGroupsResource(request),\n shared: createSharedResource(request),\n };\n}\n","import { createWishlistStackClient, type CreateWishlistStackClientOptions, type WishlistStackClient as IWishlistStackClient } from \"./client/createWishlistStackClient\";\n\n/**\n * Class wrapper around `createWishlistStackClient()` for users who prefer `new`.\n * Exposes `lists`, `groups`, and `shared` resources.\n */\nexport class WishlistStackClient implements IWishlistStackClient {\n readonly lists: IWishlistStackClient[\"lists\"];\n readonly groups: IWishlistStackClient[\"groups\"];\n readonly shared: IWishlistStackClient[\"shared\"];\n\n constructor(opts: CreateWishlistStackClientOptions) {\n const client = createWishlistStackClient(opts);\n this.lists = client.lists;\n this.groups = client.groups;\n this.shared = client.shared;\n }\n\n /** Back-compat alias: `client.groups.getAll()` */\n getGroups() {\n return this.groups.getAll();\n }\n\n /** Back-compat alias: `client.groups.getById(groupId)` */\n getGroupById(groupId: string) {\n return this.groups.getById(groupId);\n }\n\n /** Back-compat alias: `client.lists.getAll()` */\n getLists() {\n return this.lists.getAll();\n }\n}\n","import { MAX_PAGINATION_SIZE } from \"../constants\";\n\nexport type PaginationParams = {\n page?: number;\n pageSize?: number;\n query?: string;\n};\n\nexport const DEFAULT_PAGE = 1 as const;\nexport const DEFAULT_PAGE_SIZE = MAX_PAGINATION_SIZE;\n\n","import type { Query } from \"../client/query\";\nimport type { PaginationParams } from \"./pagination\";\n\nexport const SORT_FIELDS = [\"position\", \"createdAt\", \"updatedAt\"] as const;\nexport const SORT_DIRECTIONS = [\"asc\", \"desc\"] as const;\n\nexport type SortField = (typeof SORT_FIELDS)[number];\nexport type SortDirection = (typeof SORT_DIRECTIONS)[number];\n\n/**\n * Collection sort options for multi-resource GET endpoints.\n * Defaults on the API are `sortBy=position` and `sortDirection=asc`.\n */\nexport type SortParams = {\n sortBy?: SortField;\n sortDirection?: SortDirection;\n};\n\n/**\n * Shared query option building blocks for list/group endpoints.\n *\n * Keep this extendable: as we add filters/sorts, we can add additional helpers/types here\n * and reuse them across endpoints without duplicating logic.\n */\nexport type PaginatedQuery<TExtra extends Query = Query> = PaginationParams & SortParams & TExtra;\n\n/**\n * Merge a base query with pagination parameters.\n * (Useful when an endpoint also gains filter/sort params over time.)\n */\nexport function withPagination<TExtra extends Query>(\n query?: TExtra,\n pagination?: PaginationParams,\n): PaginatedQuery<TExtra> | undefined {\n if (!query && !pagination) return undefined;\n return { ...(query ?? {}), ...(pagination ?? {}) } as PaginatedQuery<TExtra>;\n}\n\n/**\n * Merge a base query with sort parameters.\n */\nexport function withSort<TExtra extends Query>(\n query?: TExtra,\n sort?: SortParams,\n): (TExtra & SortParams) | undefined {\n if (!query && !sort) return undefined;\n return { ...(query ?? {}), ...(sort ?? {}) } as TExtra & SortParams;\n}\n\n","import type { AddItemsToListResponse } from \"./responses/lists\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\n/**\n * True when the value matches the add-items response shape\n * (`{ listId, addedItems, addedCount }`).\n */\nexport function isAddItemsDeltaResponse(\n value: AddItemsToListResponse | unknown,\n): value is AddItemsToListResponse {\n if (!isRecord(value)) return false;\n return (\n typeof value.listId === \"string\" &&\n Array.isArray(value.addedItems) &&\n typeof value.addedCount === \"number\"\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/client/query.ts","../src/client/errors.ts","../src/client/request.ts","../src/helpers/pagination.ts","../src/resources/lists/index.ts","../src/resources/groups/index.ts","../src/resources/shared/index.ts","../src/client/createWishlistStackClient.ts","../src/WishlistStackClient.ts","../src/types/pagination.ts","../src/types/query-options.ts","../src/types/guards.ts"],"names":["isRecord"],"mappings":"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","file":"index.js","sourcesContent":["export const MAX_PAGINATION_SIZE = 25 as const;\nexport const BASE_URL = \"https://app.wishliststack.com\" as const;\n\n","export type QueryValue =\n | string\n | number\n | boolean\n | null\n | undefined\n | Array<string | number | boolean | null | undefined>;\n\nexport type Query = Record<string, QueryValue>;\n\nexport function toQueryString(query?: Query): string {\n if (!query) return \"\";\n\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined || value === null) continue;\n if (Array.isArray(value)) {\n for (const v of value) {\n if (v === undefined || v === null) continue;\n params.append(key, String(v));\n }\n continue;\n }\n params.set(key, String(value));\n }\n\n const qs = params.toString();\n return qs ? `?${qs}` : \"\";\n}\n\n","export type WishlistStackApiErrorDetails<TBody = unknown> = {\n status: number;\n url: string;\n method: string;\n requestId?: string;\n body?: TBody;\n /** Value of the `Retry-After` response header when present (seconds or HTTP-date). */\n retryAfter?: string;\n /** Selected rate-limit response headers when present. */\n rateLimit?: {\n limit?: string;\n remaining?: string;\n reset?: string;\n };\n};\n\ntype ApiErrorItemLike = { message?: unknown; field?: unknown };\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isApiErrorItemLike(value: unknown): value is ApiErrorItemLike {\n return isRecord(value) && \"message\" in value;\n}\n\nfunction extractApiErrors(body: unknown): Array<{ message: string; field?: string }> | undefined {\n if (!isRecord(body)) return undefined;\n const errors = body.errors;\n if (!Array.isArray(errors)) return undefined;\n const out: Array<{ message: string; field?: string }> = [];\n for (const e of errors) {\n if (!isApiErrorItemLike(e)) continue;\n const msg = typeof e.message === \"string\" ? e.message : undefined;\n if (!msg) continue;\n const field = typeof (e as any).field === \"string\" ? (e as any).field : undefined;\n out.push(field ? { message: msg, field } : { message: msg });\n }\n return out.length ? out : undefined;\n}\n\nexport class WishlistStackApiError<TBody = unknown> extends Error {\n readonly name = \"WishlistStackApiError\";\n readonly status: number;\n readonly url: string;\n readonly method: string;\n readonly requestId?: string;\n readonly body?: TBody;\n readonly retryAfter?: string;\n readonly rateLimit?: WishlistStackApiErrorDetails[\"rateLimit\"];\n\n constructor(message: string, details: WishlistStackApiErrorDetails<TBody>) {\n super(message);\n this.status = details.status;\n this.url = details.url;\n this.method = details.method;\n this.requestId = details.requestId;\n this.body = details.body;\n this.retryAfter = details.retryAfter;\n this.rateLimit = details.rateLimit;\n }\n\n /**\n * Best-effort extraction of API error items from the response body.\n * Useful for UI/logging without needing to know the exact response shape.\n */\n get apiErrors(): Array<{ message: string; field?: string }> | undefined {\n return extractApiErrors(this.body);\n }\n\n /**\n * Convenience: extracted error messages (if present).\n */\n get apiErrorMessages(): string[] | undefined {\n const errs = this.apiErrors;\n return errs?.map((e) => e.message);\n }\n}\n\n/**\n * Bundler-safe type guard (prefer this over `instanceof WishlistStackApiError`).\n */\nexport function isWishlistStackApiError(value: unknown): value is WishlistStackApiError<unknown> {\n if (!isRecord(value)) return false;\n return (\n (value as any).name === \"WishlistStackApiError\" &&\n typeof (value as any).status === \"number\" &&\n typeof (value as any).url === \"string\" &&\n typeof (value as any).method === \"string\"\n );\n}\n","import { toQueryString, type Query } from \"./query\";\nimport { WishlistStackApiError } from \"./errors\";\nimport type { ApiErrorResponse } from \"../types/common\";\n\nexport type FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;\n\nexport type AuthMode = \"authenticated\" | \"merchant\";\n\nexport type RequestContext = {\n baseUrl: string;\n apiKey: string;\n customerAccessToken?: string;\n fetch: FetchLike;\n /** Applied when a call does not pass `timeoutMs`. */\n defaultTimeoutMs?: number;\n /** When true, retry safe GET requests once on HTTP 429 with jittered delay. */\n retryOnRateLimit?: boolean;\n};\n\nexport type RequestArgs<TBody> = {\n method: \"GET\" | \"POST\" | \"PATCH\" | \"DELETE\";\n path: string;\n auth: AuthMode;\n query?: Query;\n body?: TBody;\n headers?: Record<string, string>;\n signal?: AbortSignal;\n timeoutMs?: number;\n /** Marks a non-GET operation as safe to retry once on HTTP 429. */\n retryable?: boolean;\n};\n\nasync function safeParseJson(res: Response): Promise<unknown | undefined> {\n const contentType = res.headers.get(\"content-type\") ?? \"\";\n if (!contentType.toLowerCase().includes(\"application/json\")) return undefined;\n try {\n return await res.json();\n } catch {\n return undefined;\n }\n}\n\nfunction pickRequestId(res: Response): string | undefined {\n return (\n res.headers.get(\"fly-request-id\") ??\n res.headers.get(\"x-request-id\") ??\n res.headers.get(\"x-nf-request-id\") ??\n res.headers.get(\"x-netlify-request-id\") ??\n undefined\n );\n}\n\nfunction pickRateLimit(res: Response): { limit?: string; remaining?: string; reset?: string } | undefined {\n const limit = res.headers.get(\"x-ratelimit-limit\") ?? undefined;\n const remaining = res.headers.get(\"x-ratelimit-remaining\") ?? undefined;\n const reset = res.headers.get(\"x-ratelimit-reset\") ?? undefined;\n if (!limit && !remaining && !reset) return undefined;\n return { limit, remaining, reset };\n}\n\nfunction errorMessageFor(status: number, path: string): string {\n if (status === 503 && path.includes(\"/api/groups\")) {\n return \"Groups API disabled for this merchant\";\n }\n return `Wishlist Stack API request failed (${status})`;\n}\n\nfunction parseRetryAfterMs(retryAfter: string | undefined): number {\n if (!retryAfter) return 0;\n const asSeconds = Number(retryAfter);\n if (Number.isFinite(asSeconds) && asSeconds >= 0) {\n return Math.min(asSeconds * 1000, 30_000);\n }\n const asDate = Date.parse(retryAfter);\n if (!Number.isNaN(asDate)) {\n return Math.min(Math.max(0, asDate - Date.now()), 30_000);\n }\n return 0;\n}\n\nfunction jitterDelayMs(baseMs: number): number {\n const base = Math.max(100, baseMs || 500);\n const jitter = Math.floor(Math.random() * 250);\n return Math.min(base + jitter, 30_000);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function createRequest(ctx: RequestContext) {\n return async function request<TResponse = unknown, TBody = unknown>(\n args: RequestArgs<TBody>,\n ): Promise<TResponse> {\n const url = `${ctx.baseUrl}${args.path}${toQueryString(args.query)}`;\n\n const headers: Record<string, string> = {\n \"X-Wishlist-Stack-Api-Key\": ctx.apiKey,\n ...(args.headers ?? {}),\n };\n\n if (args.auth === \"authenticated\") {\n const token = ctx.customerAccessToken;\n // If token is missing, still perform the request and let the API return the appropriate\n // error response (which we will surface as a WishlistStackApiError based on the HTTP response).\n if (token) headers[\"X-Shopify-Customer-Access-Token\"] = token;\n }\n\n let body: BodyInit | undefined;\n if (args.body !== undefined) {\n // Only JSON bodies are supported for this SDK.\n headers[\"content-type\"] ??= \"application/json\";\n body = JSON.stringify(args.body);\n }\n\n const timeoutMs = args.timeoutMs ?? ctx.defaultTimeoutMs;\n\n const doFetch = async (): Promise<Response> => {\n const controller = timeoutMs ? new AbortController() : undefined;\n const timeout =\n timeoutMs && controller\n ? setTimeout(() => controller.abort(), timeoutMs)\n : undefined;\n\n const signal = args.signal\n ? args.signal\n : controller\n ? controller.signal\n : undefined;\n\n try {\n return await ctx.fetch(url, {\n method: args.method,\n headers,\n body,\n signal,\n });\n } finally {\n if (timeout) clearTimeout(timeout);\n }\n };\n\n let res = await doFetch();\n\n const retryable = args.method === \"GET\" || args.retryable === true;\n if (!res.ok && res.status === 429 && ctx.retryOnRateLimit && retryable) {\n const retryAfter = res.headers.get(\"retry-after\") ?? undefined;\n await sleep(jitterDelayMs(parseRetryAfterMs(retryAfter)));\n res = await doFetch();\n }\n\n if (!res.ok) {\n const errBody = (await safeParseJson(res)) as ApiErrorResponse | unknown;\n const retryAfter = res.headers.get(\"retry-after\") ?? undefined;\n throw new WishlistStackApiError<ApiErrorResponse | unknown>(errorMessageFor(res.status, args.path), {\n status: res.status,\n url,\n method: args.method,\n requestId: pickRequestId(res),\n body: errBody,\n retryAfter,\n rateLimit: pickRateLimit(res),\n });\n }\n\n if (res.status === 204) return undefined as TResponse;\n\n const parsed = await safeParseJson(res);\n // If server didn't return JSON, return the raw text as unknown.\n if (parsed === undefined) {\n const text = await res.text().catch(() => \"\");\n return text as unknown as TResponse;\n }\n\n return parsed as TResponse;\n };\n}\n","import { MAX_PAGINATION_SIZE } from \"../constants\";\n\n/**\n * Clamp a page size to the API-allowed range (1–25) so requests\n * do not send invalid `pageSize` values.\n */\nexport function clampPageSize(n: number): number {\n if (!Number.isFinite(n)) return MAX_PAGINATION_SIZE;\n return Math.min(MAX_PAGINATION_SIZE, Math.max(1, Math.trunc(n)));\n}\n\n/**\n * Clamp a 1-based page index to at least 1.\n */\nexport function clampPage(n: number): number {\n if (!Number.isFinite(n)) return 1;\n return Math.max(1, Math.trunc(n));\n}\n","import type { RequestArgs } from \"../../client/request\";\nimport { MAX_PAGINATION_SIZE } from \"../../constants\";\nimport { clampPage, clampPageSize } from \"../../helpers/pagination\";\nimport type { PaginatedQuery } from \"../../types/query-options\";\nimport type {\n AddItemsToListBody,\n ContainsVariantsBody,\n CreateListBody,\n DuplicateListBody,\n ReorderListItemsBody,\n UpdateListBody,\n UpdateListItemBody,\n} from \"../../types/requests/lists\";\nimport type {\n AddItemsToListResponse,\n ContainsVariantsResponse,\n CreateListResponse,\n DuplicateListResponse,\n GetListResponse,\n GetListsResponse,\n HydratedWishlistItem,\n MarkListSharedResponse,\n RemoveItemFromListResponse,\n RemoveListResponse,\n ReorderListItemsResponse,\n RevokeListSharedResponse,\n UpdateListDetailsResponse,\n UpdateListItemResponse,\n} from \"../../types/responses/lists\";\nimport type { ListDetailPagination } from \"../../types/responses/common\";\n\ntype RequestFn = <TResponse = unknown, TBody = unknown>(\n args: RequestArgs<TBody>,\n) => Promise<TResponse>;\n\nexport type GetListsQuery = PaginatedQuery;\nexport type GetListQuery = Omit<PaginatedQuery, \"query\">;\n\nexport type AddItemsBatchedOptions = {\n /** Max items per POST (API hard max is 25). */\n batchSize?: number;\n};\n\nexport type GetByIdAllItemsOptions = {\n pageSize?: number;\n sortBy?: GetListQuery[\"sortBy\"];\n sortDirection?: GetListQuery[\"sortDirection\"];\n};\n\nfunction chunkItems<T>(items: T[], batchSize: number): T[][] {\n const size = Math.max(1, Math.min(MAX_PAGINATION_SIZE, Math.trunc(batchSize) || MAX_PAGINATION_SIZE));\n const chunks: T[][] = [];\n for (let i = 0; i < items.length; i += size) {\n chunks.push(items.slice(i, i + size));\n }\n return chunks.length ? chunks : [[]];\n}\n\nexport function createListsResource(request: RequestFn) {\n const getById = (listId: string, query?: GetListQuery) =>\n request<GetListResponse>({\n method: \"GET\",\n path: `/api/lists/${encodeURIComponent(listId)}`,\n auth: \"authenticated\",\n query,\n });\n\n const addItems = (listId: string, body: AddItemsToListBody) =>\n request<AddItemsToListResponse, AddItemsToListBody>({\n method: \"POST\",\n path: `/api/lists/${encodeURIComponent(listId)}/add`,\n auth: \"authenticated\",\n body,\n });\n\n return {\n /** Returns all lists for the authenticated customer under the current merchant. */\n getAll: (query?: GetListsQuery) =>\n request<GetListsResponse>({\n method: \"GET\",\n path: \"/api/lists\",\n auth: \"authenticated\",\n query,\n }),\n\n /** Fetch list details by id. */\n getById,\n\n /**\n * Fetch every item on a list by walking pages (list detail is paginated;\n * max pageSize 25).\n */\n getByIdAllItems: async (listId: string, opts?: GetByIdAllItemsOptions): Promise<GetListResponse> => {\n const pageSize = clampPageSize(opts?.pageSize ?? MAX_PAGINATION_SIZE);\n const sortBy = opts?.sortBy;\n const sortDirection = opts?.sortDirection;\n\n const first = await getById(listId, {\n page: 1,\n pageSize,\n ...(sortBy ? { sortBy } : {}),\n ...(sortDirection ? { sortDirection } : {}),\n });\n\n const totalPages = first.pagination.totalPages;\n const allItems: HydratedWishlistItem[] = [...(first.items ?? [])];\n\n for (let page = 2; page <= totalPages; page++) {\n const next = await getById(listId, {\n page: clampPage(page),\n pageSize,\n ...(sortBy ? { sortBy } : {}),\n ...(sortDirection ? { sortDirection } : {}),\n });\n allItems.push(...(next.items ?? []));\n }\n\n const pagination: ListDetailPagination = {\n ...first.pagination,\n page: 1,\n pageSize,\n };\n\n return {\n ...first,\n items: allItems,\n pagination,\n };\n },\n\n /**\n * Create a new list. Do not send `variantIds` — add items via `addItems`\n * or `addItemsBatched` after create.\n */\n create: (body: CreateListBody) =>\n request<CreateListResponse, CreateListBody>({\n method: \"POST\",\n path: \"/api/lists\",\n auth: \"authenticated\",\n body,\n }),\n\n /** Update list name/description. */\n update: (listId: string, body: UpdateListBody) =>\n request<UpdateListDetailsResponse, UpdateListBody>({\n method: \"PATCH\",\n path: `/api/lists/${encodeURIComponent(listId)}`,\n auth: \"authenticated\",\n body,\n }),\n\n /** Remove a list. */\n remove: (listId: string) =>\n request<RemoveListResponse>({\n method: \"DELETE\",\n path: `/api/lists/${encodeURIComponent(listId)}`,\n auth: \"authenticated\",\n }),\n\n /**\n * Duplicate a list (including all items) in a single call.\n * By default the copy stays in the same group as the source. Pass `groupId`\n * to place it in another group, or `groupId: null` to leave it ungrouped.\n * The copy is named `Copy of {original name}` and is not shared.\n */\n duplicate: (listId: string, body?: DuplicateListBody) =>\n request<DuplicateListResponse, DuplicateListBody>({\n method: \"POST\",\n path: `/api/lists/${encodeURIComponent(listId)}/duplicate`,\n auth: \"authenticated\",\n body,\n }),\n\n /**\n * Add one or more items to a list.\n * Returns `{ listId, addedItems, addedCount }`. Prefer `addItemsBatched`\n * when sending more than 25 items.\n */\n addItems,\n\n /**\n * Check whether up to 100 variants are present without hydrating or\n * paging through the list. Response keys preserve the supplied IDs.\n */\n containsVariants: (listId: string, body: ContainsVariantsBody) =>\n request<ContainsVariantsResponse, ContainsVariantsBody>({\n method: \"POST\",\n path: `/api/lists/${encodeURIComponent(listId)}/contains`,\n auth: \"authenticated\",\n body,\n retryable: true,\n }),\n\n /**\n * Add items in sequential batches of ≤25 (API hard max).\n * Merges `{ addedItems, addedCount }` across batches.\n */\n addItemsBatched: async (\n listId: string,\n body: AddItemsToListBody,\n opts?: AddItemsBatchedOptions,\n ): Promise<AddItemsToListResponse> => {\n const items = body.items ?? [];\n if (items.length === 0) {\n throw new Error(\"lists.addItemsBatched requires at least one item\");\n }\n const batchSize = opts?.batchSize ?? MAX_PAGINATION_SIZE;\n const chunks = chunkItems(items, batchSize);\n\n const merged: AddItemsToListResponse = {\n listId,\n addedItems: [],\n addedCount: 0,\n };\n\n for (const chunk of chunks) {\n const res = await addItems(listId, { items: chunk });\n merged.listId = res.listId;\n merged.addedItems.push(...res.addedItems);\n merged.addedCount += res.addedCount;\n }\n\n return merged;\n },\n\n /** Update an item on a list. */\n updateItem: (listId: string, itemId: string, body: UpdateListItemBody) =>\n request<UpdateListItemResponse, UpdateListItemBody>({\n method: \"PATCH\",\n path: `/api/lists/${encodeURIComponent(listId)}/items/${encodeURIComponent(itemId)}`,\n auth: \"authenticated\",\n body,\n }),\n\n /** Remove an item from a list. */\n removeItem: (listId: string, itemId: string) =>\n request<RemoveItemFromListResponse>({\n method: \"DELETE\",\n path: `/api/lists/${encodeURIComponent(listId)}/items/${encodeURIComponent(itemId)}`,\n auth: \"authenticated\",\n }),\n\n /** Reorder all items in a list. */\n reorderItems: (listId: string, body: ReorderListItemsBody) =>\n request<ReorderListItemsResponse, ReorderListItemsBody>({\n method: \"POST\",\n path: `/api/lists/${encodeURIComponent(listId)}/reorder`,\n auth: \"authenticated\",\n body,\n }),\n\n /** Mark list as shared (public read-only). */\n share: (listId: string) =>\n request<MarkListSharedResponse>({\n method: \"POST\",\n path: `/api/lists/${encodeURIComponent(listId)}/share`,\n auth: \"authenticated\",\n }),\n\n /** Revoke list sharing. */\n unshare: (listId: string) =>\n request<RevokeListSharedResponse>({\n method: \"DELETE\",\n path: `/api/lists/${encodeURIComponent(listId)}/share`,\n auth: \"authenticated\",\n }),\n\n /**\n * Legacy endpoint kept in the OpenAPI spec (`/api/wishlists/{id}/add`).\n * Prefer `addItems(listId, body)` unless your server only supports the legacy route.\n */\n addItemsLegacy: (id: string, body: AddItemsToListBody) =>\n request<AddItemsToListResponse, AddItemsToListBody>({\n method: \"POST\",\n path: `/api/wishlists/${encodeURIComponent(id)}/add`,\n auth: \"authenticated\",\n body,\n }),\n };\n}\n","import type { RequestArgs } from \"../../client/request\";\nimport type { CreateGroupBody, ReorderGroupsBody, UpdateGroupBody } from \"../../types/requests/groups\";\nimport type { PaginatedQuery } from \"../../types/query-options\";\nimport type {\n CreateGroupResponse,\n DuplicateGroupResponse,\n GetGroupResponse,\n GetGroupsResponse,\n MarkGroupSharedResponse,\n RemoveGroupResponse,\n ReorderGroupsResponse,\n RevokeGroupSharedResponse,\n UpdateGroupDetailsResponse,\n} from \"../../types/responses/groups\";\n\ntype RequestFn = <TResponse = unknown, TBody = unknown>(\n args: RequestArgs<TBody>,\n) => Promise<TResponse>;\n\nexport type GetGroupsQuery = PaginatedQuery<{\n /**\n * When truthy (`true`, `1`, or `\"1\"`), each group includes embedded `lists`\n * with hydrated items (`includeLists=1`).\n *\n * Expect at most **10 lists × 25 items** per group. For full data use\n * `groups.getById` plus `lists.getById` / `lists.getByIdAllItems`. Groups\n * endpoints may return **503** until the Groups API is enabled for the merchant.\n */\n includeLists?: boolean | 1 | \"1\";\n}>;\nexport type GetGroupQuery = PaginatedQuery;\n\nfunction normalizeGetGroupsQuery(query?: GetGroupsQuery): GetGroupsQuery | undefined {\n if (!query) return undefined;\n const { includeLists, ...rest } = query;\n if (includeLists) {\n return { ...rest, includeLists: 1 };\n }\n return Object.keys(rest).length > 0 ? rest : undefined;\n}\n\nexport function createGroupsResource(request: RequestFn) {\n return {\n /**\n * Fetch groups for the authenticated customer.\n * May return **503** when the Groups API is disabled for this merchant.\n */\n getAll: (query?: GetGroupsQuery) =>\n request<GetGroupsResponse>({\n method: \"GET\",\n path: \"/api/groups\",\n auth: \"authenticated\",\n query: normalizeGetGroupsQuery(query),\n }),\n\n /**\n * Fetch group details by id.\n * May return **503** when the Groups API is disabled for this merchant.\n */\n getById: (groupId: string, query?: GetGroupQuery) =>\n request<GetGroupResponse>({\n method: \"GET\",\n path: `/api/groups/${encodeURIComponent(groupId)}`,\n auth: \"authenticated\",\n query,\n }),\n\n /** Create a new group. */\n create: (body: CreateGroupBody) =>\n request<CreateGroupResponse, CreateGroupBody>({\n method: \"POST\",\n path: \"/api/groups\",\n auth: \"authenticated\",\n body,\n }),\n\n /** Update group name/description. */\n update: (groupId: string, body: UpdateGroupBody) =>\n request<UpdateGroupDetailsResponse, UpdateGroupBody>({\n method: \"PATCH\",\n path: `/api/groups/${encodeURIComponent(groupId)}`,\n auth: \"authenticated\",\n body,\n }),\n\n /** Remove a group. */\n remove: (groupId: string) =>\n request<RemoveGroupResponse>({\n method: \"DELETE\",\n path: `/api/groups/${encodeURIComponent(groupId)}`,\n auth: \"authenticated\",\n }),\n\n /**\n * Duplicate a group (including all lists and items) in a single call.\n * The copy is named `Copy of {original name}` and is not shared.\n */\n duplicate: (groupId: string) =>\n request<DuplicateGroupResponse>({\n method: \"POST\",\n path: `/api/groups/${encodeURIComponent(groupId)}/duplicate`,\n auth: \"authenticated\",\n }),\n\n /**\n * Reorder the customer's groups (`POST /api/groups/reorder`).\n * Body must include `groupIds` in the desired order — not list IDs, and\n * not a per-group path.\n */\n reorder: (body: ReorderGroupsBody) =>\n request<ReorderGroupsResponse, ReorderGroupsBody>({\n method: \"POST\",\n path: \"/api/groups/reorder\",\n auth: \"authenticated\",\n body,\n }),\n\n /** Mark group as shared (public read-only). */\n share: (groupId: string) =>\n request<MarkGroupSharedResponse>({\n method: \"POST\",\n path: `/api/groups/${encodeURIComponent(groupId)}/share`,\n auth: \"authenticated\",\n }),\n\n /** Revoke group sharing. */\n unshare: (groupId: string) =>\n request<RevokeGroupSharedResponse>({\n method: \"DELETE\",\n path: `/api/groups/${encodeURIComponent(groupId)}/share`,\n auth: \"authenticated\",\n }),\n };\n}\n","import type { RequestArgs } from \"../../client/request\";\nimport type { PaginatedQuery } from \"../../types/query-options\";\nimport type { GetSharedGroupResponse, GetSharedListResponse } from \"../../types/responses/shared\";\n\ntype RequestFn = <TResponse = unknown, TBody = unknown>(\n args: RequestArgs<TBody>,\n) => Promise<TResponse>;\n\nexport type GetSharedListQuery = Omit<PaginatedQuery, \"query\">;\nexport type GetSharedGroupQuery = PaginatedQuery;\n\nexport function createSharedResource(request: RequestFn) {\n return {\n /** Public read-only view of a shared list. Requires only merchant apiKey. */\n getSharedList: (listId: string, query?: GetSharedListQuery) =>\n request<GetSharedListResponse>({\n method: \"GET\",\n path: `/api/shared/list/${encodeURIComponent(listId)}`,\n auth: \"merchant\",\n query,\n }),\n\n /** Public read-only view of a shared group. Requires only merchant apiKey. */\n getSharedGroup: (groupId: string, query?: GetSharedGroupQuery) =>\n request<GetSharedGroupResponse>({\n method: \"GET\",\n path: `/api/shared/group/${encodeURIComponent(groupId)}`,\n auth: \"merchant\",\n query,\n }),\n };\n}\n\n","import { BASE_URL } from \"../constants\";\nimport { createRequest, type FetchLike } from \"./request\";\nimport { createListsResource } from \"../resources/lists\";\nimport { createGroupsResource } from \"../resources/groups\";\nimport { createSharedResource } from \"../resources/shared\";\n\nexport type CreateWishlistStackClientOptions = {\n baseUrl?: string;\n apiKey: string;\n customerAccessToken?: string;\n fetch?: FetchLike;\n /** Default request timeout in ms when a call does not pass `timeoutMs`. */\n defaultTimeoutMs?: number;\n /** When true, retry safe reads once on HTTP 429 (default: false). */\n retryOnRateLimit?: boolean;\n};\n\nexport type WishlistStackClient = {\n lists: ReturnType<typeof createListsResource>;\n groups: ReturnType<typeof createGroupsResource>;\n shared: ReturnType<typeof createSharedResource>;\n};\n\nexport function createWishlistStackClient(opts: CreateWishlistStackClientOptions): WishlistStackClient {\n if (!opts.apiKey) {\n throw new Error(\n \"merchant api key is required. Pass it to createWishlistStackClient({ apiKey })\",\n );\n }\n\n // Cloudflare Workers (and some other runtimes) can throw \"Illegal invocation\" if you\n // capture `globalThis.fetch` and call it later without the correct `this` binding.\n // So: default to a wrapper that calls `globalThis.fetch(...)` directly.\n const fetchImpl: FetchLike | undefined =\n opts.fetch ??\n (typeof globalThis.fetch === \"function\"\n ? ((input, init) => globalThis.fetch(input, init)) // keep correct invocation context\n : undefined);\n\n if (!fetchImpl) {\n throw new Error(\n \"No fetch implementation found. Provide one via createWishlistStackClient({ fetch }) or use Node 18+ / modern browsers.\",\n );\n }\n\n const request = createRequest({\n baseUrl: opts.baseUrl ?? BASE_URL,\n apiKey: opts.apiKey,\n customerAccessToken: opts.customerAccessToken,\n fetch: fetchImpl,\n defaultTimeoutMs: opts.defaultTimeoutMs,\n retryOnRateLimit: opts.retryOnRateLimit,\n });\n\n return {\n lists: createListsResource(request),\n groups: createGroupsResource(request),\n shared: createSharedResource(request),\n };\n}\n","import { createWishlistStackClient, type CreateWishlistStackClientOptions, type WishlistStackClient as IWishlistStackClient } from \"./client/createWishlistStackClient\";\n\n/**\n * Class wrapper around `createWishlistStackClient()` for users who prefer `new`.\n * Exposes `lists`, `groups`, and `shared` resources.\n */\nexport class WishlistStackClient implements IWishlistStackClient {\n readonly lists: IWishlistStackClient[\"lists\"];\n readonly groups: IWishlistStackClient[\"groups\"];\n readonly shared: IWishlistStackClient[\"shared\"];\n\n constructor(opts: CreateWishlistStackClientOptions) {\n const client = createWishlistStackClient(opts);\n this.lists = client.lists;\n this.groups = client.groups;\n this.shared = client.shared;\n }\n\n /** Back-compat alias: `client.groups.getAll()` */\n getGroups() {\n return this.groups.getAll();\n }\n\n /** Back-compat alias: `client.groups.getById(groupId)` */\n getGroupById(groupId: string) {\n return this.groups.getById(groupId);\n }\n\n /** Back-compat alias: `client.lists.getAll()` */\n getLists() {\n return this.lists.getAll();\n }\n}\n","import { MAX_PAGINATION_SIZE } from \"../constants\";\n\nexport type PaginationParams = {\n page?: number;\n pageSize?: number;\n query?: string;\n};\n\nexport const DEFAULT_PAGE = 1 as const;\nexport const DEFAULT_PAGE_SIZE = MAX_PAGINATION_SIZE;\n\n","import type { Query } from \"../client/query\";\nimport type { PaginationParams } from \"./pagination\";\n\nexport const SORT_FIELDS = [\"position\", \"createdAt\", \"updatedAt\"] as const;\nexport const SORT_DIRECTIONS = [\"asc\", \"desc\"] as const;\n\nexport type SortField = (typeof SORT_FIELDS)[number];\nexport type SortDirection = (typeof SORT_DIRECTIONS)[number];\n\n/**\n * Collection sort options for multi-resource GET endpoints.\n * Defaults on the API are `sortBy=position` and `sortDirection=asc`.\n */\nexport type SortParams = {\n sortBy?: SortField;\n sortDirection?: SortDirection;\n};\n\n/**\n * Shared query option building blocks for list/group endpoints.\n *\n * Keep this extendable: as we add filters/sorts, we can add additional helpers/types here\n * and reuse them across endpoints without duplicating logic.\n */\nexport type PaginatedQuery<TExtra extends Query = Query> = PaginationParams & SortParams & TExtra;\n\n/**\n * Merge a base query with pagination parameters.\n * (Useful when an endpoint also gains filter/sort params over time.)\n */\nexport function withPagination<TExtra extends Query>(\n query?: TExtra,\n pagination?: PaginationParams,\n): PaginatedQuery<TExtra> | undefined {\n if (!query && !pagination) return undefined;\n return { ...(query ?? {}), ...(pagination ?? {}) } as PaginatedQuery<TExtra>;\n}\n\n/**\n * Merge a base query with sort parameters.\n */\nexport function withSort<TExtra extends Query>(\n query?: TExtra,\n sort?: SortParams,\n): (TExtra & SortParams) | undefined {\n if (!query && !sort) return undefined;\n return { ...(query ?? {}), ...(sort ?? {}) } as TExtra & SortParams;\n}\n\n","import type { AddItemsToListResponse } from \"./responses/lists\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\n/**\n * True when the value matches the add-items response shape\n * (`{ listId, addedItems, addedCount }`).\n */\nexport function isAddItemsDeltaResponse(\n value: AddItemsToListResponse | unknown,\n): value is AddItemsToListResponse {\n if (!isRecord(value)) return false;\n return (\n typeof value.listId === \"string\" &&\n Array.isArray(value.addedItems) &&\n typeof value.addedCount === \"number\"\n );\n}\n"]}
|