@usethrottle/catalog 1.3.0 → 1.4.1
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/CHANGELOG.md +22 -0
- package/README.md +105 -9
- package/dist/admin.cjs +16 -16
- package/dist/admin.d.cts +14 -2
- package/dist/admin.d.ts +14 -2
- package/dist/admin.js +1 -1
- package/dist/{catalog-error-BOaSKgY3.d.cts → catalog-error-bG1XHquN.d.cts} +1 -1
- package/dist/{catalog-error-CSoPS0-d.d.ts → catalog-error-c3BVgU6k.d.ts} +1 -1
- package/dist/{chunk-2YQNMBDI.cjs → chunk-2ODFFMZ4.cjs} +274 -38
- package/dist/chunk-5AJS3CX5.cjs +192 -0
- package/dist/{chunk-CADIHOIR.js → chunk-6K7H7HBD.js} +89 -2
- package/dist/chunk-P3ABGAF5.js +192 -0
- package/dist/{chunk-3DLH56OX.js → chunk-STNQNHNZ.js} +258 -22
- package/dist/{chunk-GU63WFXI.cjs → chunk-VOOX3WJY.cjs} +102 -15
- package/dist/{client-6j1Iz-iJ.d.cts → client-CGGlbacq.d.cts} +1 -1
- package/dist/{client-B3mL2-xJ.d.ts → client-CNsVr2lR.d.ts} +1 -1
- package/dist/{contract-types-BRyonOYH.d.cts → contract-types-BJMeJSTz.d.cts} +269 -2
- package/dist/{contract-types-BRyonOYH.d.ts → contract-types-BJMeJSTz.d.ts} +269 -2
- package/dist/index.cjs +12 -2
- package/dist/index.d.cts +53 -7
- package/dist/index.d.ts +53 -7
- package/dist/index.js +11 -1
- package/dist/next.cjs +180 -0
- package/dist/next.d.cts +60 -0
- package/dist/next.d.ts +60 -0
- package/dist/next.js +180 -0
- package/dist/react-extras.cjs +27 -9
- package/dist/react-extras.d.cts +6 -4
- package/dist/react-extras.d.ts +6 -4
- package/dist/react-extras.js +20 -2
- package/dist/react.cjs +18 -14
- package/dist/react.d.cts +22 -5
- package/dist/react.d.ts +22 -5
- package/dist/react.js +6 -2
- package/dist/server.cjs +58 -66
- package/dist/server.d.cts +57 -10
- package/dist/server.d.ts +57 -10
- package/dist/server.js +52 -60
- package/dist/{types-D0PywKnN.d.cts → types-BtBxMbM5.d.cts} +40 -3
- package/dist/{types-BfveENg1.d.ts → types-dKvIfrVH.d.ts} +40 -3
- package/dist/url.d.cts +1 -1
- package/dist/url.d.ts +1 -1
- package/dist/{use-query-UWf6Pi5g.d.cts → use-query-C2rfTJd4.d.cts} +1 -1
- package/dist/{use-query-CR7r5tam.d.ts → use-query-DeCj1hXt.d.ts} +1 -1
- package/package.json +16 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# @usethrottle/catalog
|
|
2
2
|
|
|
3
|
+
## 1.4.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- c3f11bd: Throttle Builder preparation. The SDK exports the answer types of two new public storefront routes, `StorefrontLookupAnswer` (`GET /v1/storefront/lookup`: the current handle and title of catalog ids, public items only) and `StorefrontLatestReviewsAnswer` (`GET /v1/storefront/reviews`: the latest approved reviews across public products, each with its product). `settings.product.sections[].pageHandle` of `/config` can now be the slug of a Throttle Builder page (the product page `shipping` section's new `builderPageHandle`); its type is unchanged.
|
|
8
|
+
- a3baea5: Money range aligned with `@usethrottle/money` 1.1 so stores install one copy.
|
|
9
|
+
|
|
10
|
+
## 1.4.0
|
|
11
|
+
|
|
12
|
+
### Minor Changes
|
|
13
|
+
|
|
14
|
+
- c9636d7: Dynamic storefront. Everything is additive except the cache defaults below.
|
|
15
|
+
|
|
16
|
+
- `client.settings()` returns the store's theme, navigation, home page, strings and route patterns with `settingsVersion` and `generation`. `t(settings, key, vars)`, `resolveMenuTarget(settings, target)`, `DEFAULT_STRINGS` and `fontStylesheetHref` read them.
|
|
17
|
+
- `client.pages.list()` and `client.pages.get(handle)` read the store's content pages.
|
|
18
|
+
- `createServerCatalogClient({ cachePolicy })` sets how long each kind of read is cached (`'until-changed'`, `'no-store'` or a duration such as `'90s'`), with `DEFAULT_CACHE_POLICY`, `cacheKindForPath` and `policyToNext` exported from `/server`. Every read is tagged by family (`throttle-catalog:config`, `:pages`, `:data`) as well as by route and handle, and `scopesToTags(scopes)` turns the scopes of a change notice into the tags to clear.
|
|
19
|
+
- New entry `@usethrottle/catalog/next` for the Next.js App Router (`next` 14 or later, an optional peer): `createRevalidateHandler` verifies the signed `storefront.changed` webhook and revalidates the matching tags; the helpers `previewMiddleware` and `getPreviewToken` carry a dashboard preview token in an HTTP-only cookie; `noteMinGeneration` makes the next `/config` read at least that fresh.
|
|
20
|
+
- `previewToken` client option and a per-call `minGeneration` on settings and pages reads.
|
|
21
|
+
- React: `useStorefrontSettings` and `useGenerationWatch` (`/react`), `usePages` and `usePage` (`/react/extras`).
|
|
22
|
+
|
|
23
|
+
Behaviour changes: the default `revalidate` of `/config`, settings, pages and product reads is now 3600 seconds (it was 60), cleared sooner by tag revalidation; lists, filters, related products, reviews and search keep 60 seconds. Set `cachePolicy` to restore the old numbers. `x-storefront-preview` is a reserved header: the SDK sets it from `previewToken`.
|
|
24
|
+
|
|
3
25
|
## 1.3.0
|
|
4
26
|
|
|
5
27
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -36,14 +36,15 @@ Prices are integers in the minor units of their currency; format them with `form
|
|
|
36
36
|
|
|
37
37
|
## Entries
|
|
38
38
|
|
|
39
|
-
| Import | What it holds
|
|
40
|
-
| ----------------------------------- |
|
|
41
|
-
| `@usethrottle/catalog` | `createCatalogClient`, the error classes and `isCatalogError`, the answer types, and the `@usethrottle/money` helpers (`money`, `formatMoney`, …). No DOM and no Node-only API.
|
|
42
|
-
| `@usethrottle/catalog/react` | `CatalogProvider`, the read hooks, `useCart`, `useSubmitReview` and `useCustomerKey` (marked `"use client"`).
|
|
43
|
-
| `@usethrottle/catalog/react/extras` | `useTags`, `useCollections` and `useReviewEligibility` (marked `"use client"`). They share `CatalogProvider` and the cache with `/react`: import the provider from `/react` and these three from here.
|
|
44
|
-
| `@usethrottle/catalog/server` | `createServerCatalogClient`, `catalogTags`, `syncCatalogGeneration` and the paging helpers (`listAllProductHandles`, `staticProductParams`, `listAllCollectionHandles`, `listAllCategoryHandles`: it asks for `CATEGORY_TREE_MAX_DEPTH` levels, 10, so a sitemap lists the whole tree).
|
|
45
|
-
| `@usethrottle/catalog/
|
|
46
|
-
| `@usethrottle/catalog/
|
|
39
|
+
| Import | What it holds |
|
|
40
|
+
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
41
|
+
| `@usethrottle/catalog` | `createCatalogClient`, the error classes and `isCatalogError`, the answer types, and the `@usethrottle/money` helpers (`money`, `formatMoney`, …). No DOM and no Node-only API. |
|
|
42
|
+
| `@usethrottle/catalog/react` | `CatalogProvider`, the read hooks, `useCart`, `useSubmitReview` and `useCustomerKey` (marked `"use client"`). |
|
|
43
|
+
| `@usethrottle/catalog/react/extras` | `useTags`, `useCollections` and `useReviewEligibility` (marked `"use client"`). They share `CatalogProvider` and the cache with `/react`: import the provider from `/react` and these three from here. |
|
|
44
|
+
| `@usethrottle/catalog/server` | `createServerCatalogClient`, `catalogTags`, `syncCatalogGeneration` and the paging helpers (`listAllProductHandles`, `staticProductParams`, `listAllCollectionHandles`, `listAllCategoryHandles`: it asks for `CATEGORY_TREE_MAX_DEPTH` levels, 10, so a sitemap lists the whole tree). |
|
|
45
|
+
| `@usethrottle/catalog/next` | **Server only.** `createRevalidateHandler` (the change-notice webhook), `previewMiddleware`, `getPreviewToken` and `noteMinGeneration` for the Next.js App Router. `next` (14 or later) is an optional peer. See [Revalidation webhook](#revalidation-webhook) and [Preview mode](#preview-mode). |
|
|
46
|
+
| `@usethrottle/catalog/url` | `parseShopQuery`, `serializeShopQuery`, `toProductsQuery`, `parseRange` and `formatRange`. Standalone: none of the client or React code (the ESM and CommonJS builds each load one tiny shared helper file). |
|
|
47
|
+
| `@usethrottle/catalog/admin` | **Experimental, server only.** `createCatalogAdmin` and `verifyCatalogWebhook` for the catalog push API (sync jobs, single batches, runs, products, stock), and the push request and answer types. See [Admin](#admin-server-only-experimental). |
|
|
47
48
|
|
|
48
49
|
Everything `/react` exports is a client reference in a server component, `SDK_VERSION` and `catalogQueryKey` included: in server code import `SDK_VERSION` from the root or `/server`, and call `catalogQueryKey` only in client code.
|
|
49
50
|
|
|
@@ -312,7 +313,7 @@ function ReviewButton({ handle }: { handle: string }) {
|
|
|
312
313
|
|
|
313
314
|
## Next.js
|
|
314
315
|
|
|
315
|
-
On the server, use a **server** key and `createServerCatalogClient`. Every catalog read's `fetch` carries `next: { revalidate, tags }` (60 seconds
|
|
316
|
+
On the server, use a **server** key and `createServerCatalogClient`. Every catalog read's `fetch` carries `next: { revalidate, tags }` (an hour for settings, pages and products, cleared sooner by tags; 60 seconds for lists, filters, related products, reviews and search: see [Cache policy](#cache-policy)); carts, Throttle calls and any request with a customer token are `cache: 'no-store'`. Next.js itself is never imported.
|
|
316
317
|
|
|
317
318
|
```ts
|
|
318
319
|
// lib/catalog.ts
|
|
@@ -349,6 +350,101 @@ export async function GET() {
|
|
|
349
350
|
|
|
350
351
|
`staticProductParams(catalog)` feeds `generateStaticParams`, and `listAllProductHandles(catalog)` (an async iterable) feeds a sitemap. In the browser, use a browser key and the React provider.
|
|
351
352
|
|
|
353
|
+
## Storefront settings
|
|
354
|
+
|
|
355
|
+
The store's theme, navigation, home page, strings and route patterns are edited in the dashboard and read with `client.settings()`. It is `/config` cut to `{ settings, settingsVersion, generation }`.
|
|
356
|
+
|
|
357
|
+
```ts
|
|
358
|
+
import { t, resolveMenuTarget } from '@usethrottle/catalog';
|
|
359
|
+
import { catalog } from '@/lib/catalog'; // createServerCatalogClient(...)
|
|
360
|
+
|
|
361
|
+
const { settings } = await catalog.settings();
|
|
362
|
+
t(settings, 'cart.checkout'); // "Checkout", in the locale of the read; falls back to English
|
|
363
|
+
settings.navigation.header.map((item) => ({
|
|
364
|
+
label: item.label,
|
|
365
|
+
href: resolveMenuTarget(settings, item.target), // null when it points at nothing
|
|
366
|
+
}));
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
In React, `useStorefrontSettings()` (from `/react`) returns the same answer, and `useGenerationWatch({ onChange })` polls the generation (every 60 seconds by default, only while the tab is visible) and refreshes the cached reads when it moves. Settings and pages calls take `minGeneration`, the generation a change notice named: a read above what the edge holds is answered fresh.
|
|
370
|
+
|
|
371
|
+
## Pages
|
|
372
|
+
|
|
373
|
+
Pages are the store's own content pages (shipping, about, ...). `catalog.pages.list()` returns `{ pages: [{ handle, title, position }] }` and `catalog.pages.get(handle)` returns `{ handle, title, bodyHtml, seo }`. In React, `usePages()` and `usePage(handle)` come from `/react/extras`.
|
|
374
|
+
|
|
375
|
+
```ts
|
|
376
|
+
const { bodyHtml, seo } = await catalog.pages.get('shipping');
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
`bodyHtml` is HTML: render it only where you trust the store's editors, or sanitize it first.
|
|
380
|
+
|
|
381
|
+
## Cache policy
|
|
382
|
+
|
|
383
|
+
`createServerCatalogClient({ cachePolicy })` sets how long each kind of read is cached. Kinds: `settings`, `navigation`, `pages`, `listings`, `facets`, `product`, `related`, `reviews` and `search`. A policy is `'until-changed'` (an hour's safety TTL, cleared sooner by cache tags), `'no-store'`, or a duration such as `'90s'` or `'5m'`. The defaults are `'until-changed'` for `settings`, `navigation`, `pages` and `product`, and `'60s'` for the rest. Customer-token, cart and preview requests are always `no-store`.
|
|
384
|
+
|
|
385
|
+
```ts
|
|
386
|
+
export const catalog = createServerCatalogClient({
|
|
387
|
+
publishableKey: process.env.CATALOG_SERVER_KEY ?? '',
|
|
388
|
+
cachePolicy: { product: '5m', search: 'no-store' },
|
|
389
|
+
});
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
Every read carries its tags: `throttle-catalog`, a family tag (`throttle-catalog:config`, `:pages` or `:data`), the route's own and, for one handle, `throttle-catalog:<route>:<handle>`. `scopesToTags(scopes)` turns the scopes of a change notice into the tags to clear.
|
|
393
|
+
|
|
394
|
+
## Revalidation webhook
|
|
395
|
+
|
|
396
|
+
Instead of polling, point a catalog webhook at a route handler. The catalog sends `storefront.changed` with the changed scopes; the handler checks the `x-catalog-signature` header, clears the matching tags and makes the next `/config` read fresh. Several secrets can be passed while one is being rotated.
|
|
397
|
+
|
|
398
|
+
```ts
|
|
399
|
+
// app/api/throttle/revalidate/route.ts
|
|
400
|
+
import { createRevalidateHandler } from '@usethrottle/catalog/next';
|
|
401
|
+
|
|
402
|
+
export const POST = createRevalidateHandler({
|
|
403
|
+
secret: process.env.THROTTLE_WEBHOOK_SECRET,
|
|
404
|
+
});
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
It answers `200 { revalidated: [...tags] }`, `401` for a missing, wrong or older-than-5-minutes signature, `400` for a body that is not a change notice, `413` for a body over 64 KB and `500` when no secret is set. The secret is read on each request, so an unset variable at build time does not fail `next build`. The route expires the tags immediately (`revalidateTag(tag, { expire: 0 })`), so the next request after a change is rendered fresh rather than stale. Each notice also raises a generation floor: the server client's next `/config` read (and so `settings()`) asks for at least that generation until an answer reaches it. The floor applies to every client of the process unless you name it. With one store that needs nothing. On a server with several stores, a handler without `floorKey` raises the floor for every store, so the other stores' reads skip the cache (`no-store`) until it clears: always pass each store's publishable key. With several stores in one app, give each handler the publishable key of its store's server client (or a `floorKey` set on both), so one store's notice never touches another's reads. If the variable is unset, `floorKey: process.env.X` is `undefined` and falls back to the shared floor.
|
|
408
|
+
|
|
409
|
+
```ts
|
|
410
|
+
export const POST = createRevalidateHandler({
|
|
411
|
+
secret: process.env.STORE_A_WEBHOOK_SECRET,
|
|
412
|
+
floorKey: process.env.STORE_A_KEY, // the publishableKey of store A's createServerCatalogClient
|
|
413
|
+
});
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
Pass `revalidateTag` to use your own function instead of the one from `next/cache`.
|
|
417
|
+
|
|
418
|
+
## Preview mode
|
|
419
|
+
|
|
420
|
+
The dashboard's preview opens your storefront with `?throttle_preview=<token>`. The middleware moves the token into an HTTP-only cookie (`SameSite=None; Secure`, one hour, so it works inside the preview iframe) and redirects to the same URL without it. Pass the token to the server client and settings and pages answer the draft, uncached.
|
|
421
|
+
|
|
422
|
+
```ts
|
|
423
|
+
// middleware.ts
|
|
424
|
+
import { previewMiddleware } from '@usethrottle/catalog/next';
|
|
425
|
+
|
|
426
|
+
export function middleware(req: Request) {
|
|
427
|
+
return previewMiddleware(req) ?? undefined;
|
|
428
|
+
}
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
```ts
|
|
432
|
+
// lib/catalog.ts
|
|
433
|
+
import { createServerCatalogClient } from '@usethrottle/catalog/server';
|
|
434
|
+
import { getPreviewToken } from '@usethrottle/catalog/next';
|
|
435
|
+
|
|
436
|
+
export async function getCatalog() {
|
|
437
|
+
return createServerCatalogClient({
|
|
438
|
+
publishableKey: process.env.CATALOG_SERVER_KEY ?? '',
|
|
439
|
+
previewToken: await getPreviewToken(),
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
Safari may drop `Secure` cookies on `http://localhost`: develop the preview over https, or use Chrome. With `exactOptionalPropertyTypes` on, pass `previewToken` only when there is one (`...(token ? { previewToken: token } : {})`), since `getPreviewToken()` can return `undefined`.
|
|
445
|
+
|
|
446
|
+
`x-storefront-preview` is a reserved header: the SDK sets it from `previewToken`, and a `headers` option may not.
|
|
447
|
+
|
|
352
448
|
## URL helpers
|
|
353
449
|
|
|
354
450
|
`@usethrottle/catalog/url` keeps a shop page's selection in its URL, with one canonical string per selection and every parameter it does not know kept in order:
|
package/dist/admin.cjs
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
var
|
|
13
|
+
var _chunk2ODFFMZ4cjs = require('./chunk-2ODFFMZ4.cjs');
|
|
14
14
|
require('./chunk-ETV4XYOV.cjs');
|
|
15
15
|
|
|
16
16
|
// src/generated/push-types.ts
|
|
@@ -45,7 +45,7 @@ var MAX_IDEMPOTENCY_KEY = 200;
|
|
|
45
45
|
var HEADER_SAFE = /^[\x21-\x7e]+$/u;
|
|
46
46
|
var MAX_RETRY_AFTER_S = 86400;
|
|
47
47
|
function invalidRequest(message) {
|
|
48
|
-
return new (0,
|
|
48
|
+
return new (0, _chunk2ODFFMZ4cjs.CatalogError)({
|
|
49
49
|
code: "INVALID_REQUEST",
|
|
50
50
|
message,
|
|
51
51
|
statusCode: 0,
|
|
@@ -54,7 +54,7 @@ function invalidRequest(message) {
|
|
|
54
54
|
});
|
|
55
55
|
}
|
|
56
56
|
function clientError(code, message) {
|
|
57
|
-
return new (0,
|
|
57
|
+
return new (0, _chunk2ODFFMZ4cjs.CatalogError)({
|
|
58
58
|
code,
|
|
59
59
|
message,
|
|
60
60
|
statusCode: 0,
|
|
@@ -126,13 +126,13 @@ function toError(status, headers, text) {
|
|
|
126
126
|
requestId
|
|
127
127
|
};
|
|
128
128
|
if (status === 429) {
|
|
129
|
-
return new (0,
|
|
129
|
+
return new (0, _chunk2ODFFMZ4cjs.RateLimitedError)({
|
|
130
130
|
...init,
|
|
131
131
|
retryable: true,
|
|
132
|
-
retryAfterSeconds: retryAfter !== null && retryAfter >= 1 ? retryAfter :
|
|
132
|
+
retryAfterSeconds: retryAfter !== null && retryAfter >= 1 ? retryAfter : _chunk2ODFFMZ4cjs.RATE_LIMIT_DEFAULT_RETRY_S
|
|
133
133
|
});
|
|
134
134
|
}
|
|
135
|
-
return new (0,
|
|
135
|
+
return new (0, _chunk2ODFFMZ4cjs.CatalogError)(init);
|
|
136
136
|
}
|
|
137
137
|
function guarded(work, callerSignal, timeoutMs) {
|
|
138
138
|
if (_optionalChain([callerSignal, 'optionalAccess', _8 => _8.aborted])) return Promise.reject(callerSignal.reason);
|
|
@@ -151,7 +151,7 @@ function guarded(work, callerSignal, timeoutMs) {
|
|
|
151
151
|
const timer = setTimeout(() => {
|
|
152
152
|
finish();
|
|
153
153
|
controller.abort();
|
|
154
|
-
reject(new (0,
|
|
154
|
+
reject(new (0, _chunk2ODFFMZ4cjs.TimeoutError)({ timeoutMs }));
|
|
155
155
|
}, timeoutMs);
|
|
156
156
|
_optionalChain([callerSignal, 'optionalAccess', _12 => _12.addEventListener, 'call', _13 => _13("abort", onAbort, { once: true })]);
|
|
157
157
|
work(controller.signal).then(
|
|
@@ -194,7 +194,7 @@ function createHttp(key, baseUrl, fetchFn, timeoutMs) {
|
|
|
194
194
|
signal
|
|
195
195
|
});
|
|
196
196
|
} catch (cause) {
|
|
197
|
-
throw new (0,
|
|
197
|
+
throw new (0, _chunk2ODFFMZ4cjs.NetworkError)({ cause });
|
|
198
198
|
}
|
|
199
199
|
try {
|
|
200
200
|
return {
|
|
@@ -203,14 +203,14 @@ function createHttp(key, baseUrl, fetchFn, timeoutMs) {
|
|
|
203
203
|
text: await response.text()
|
|
204
204
|
};
|
|
205
205
|
} catch (cause) {
|
|
206
|
-
throw new (0,
|
|
206
|
+
throw new (0, _chunk2ODFFMZ4cjs.NetworkError)({ cause });
|
|
207
207
|
}
|
|
208
208
|
},
|
|
209
209
|
spec.signal,
|
|
210
210
|
timeoutMs
|
|
211
211
|
);
|
|
212
212
|
} catch (error) {
|
|
213
|
-
if (error instanceof
|
|
213
|
+
if (error instanceof _chunk2ODFFMZ4cjs.NetworkError && attempt < attempts) continue;
|
|
214
214
|
throw error;
|
|
215
215
|
}
|
|
216
216
|
}
|
|
@@ -223,7 +223,7 @@ function createHttp(key, baseUrl, fetchFn, timeoutMs) {
|
|
|
223
223
|
throw toError(answer.status, answer.headers, answer.text);
|
|
224
224
|
const parsed = parseJson(answer.text);
|
|
225
225
|
if (parsed === void 0)
|
|
226
|
-
throw new (0,
|
|
226
|
+
throw new (0, _chunk2ODFFMZ4cjs.CatalogError)({
|
|
227
227
|
code: "INVALID_RESPONSE",
|
|
228
228
|
message: "The server answered with a body that is not JSON.",
|
|
229
229
|
statusCode: answer.status,
|
|
@@ -278,7 +278,7 @@ function refQuery(ref) {
|
|
|
278
278
|
return [[field, value]];
|
|
279
279
|
}
|
|
280
280
|
function unreadable() {
|
|
281
|
-
return new (0,
|
|
281
|
+
return new (0, _chunk2ODFFMZ4cjs.CatalogError)({
|
|
282
282
|
code: "INVALID_RESPONSE",
|
|
283
283
|
message: "The server answered with an unexpected shape.",
|
|
284
284
|
statusCode: 200,
|
|
@@ -367,7 +367,7 @@ async function pollUntil(read, done, options = {}) {
|
|
|
367
367
|
const value = await read(options.signal);
|
|
368
368
|
if (done(value)) return value;
|
|
369
369
|
const remaining = deadline - Date.now();
|
|
370
|
-
if (remaining <= 0) throw new (0,
|
|
370
|
+
if (remaining <= 0) throw new (0, _chunk2ODFFMZ4cjs.TimeoutError)({ timeoutMs });
|
|
371
371
|
await sleep(Math.min(intervalMs, remaining), options.signal);
|
|
372
372
|
}
|
|
373
373
|
}
|
|
@@ -452,7 +452,7 @@ function createJobs(http) {
|
|
|
452
452
|
await handle.send(rows, { idempotencyKey });
|
|
453
453
|
return;
|
|
454
454
|
} catch (error) {
|
|
455
|
-
if (!(error instanceof
|
|
455
|
+
if (!(error instanceof _chunk2ODFFMZ4cjs.RateLimitedError) || retry >= QUEUE_RETRIES)
|
|
456
456
|
throw error;
|
|
457
457
|
await sleep(error.retryAfterSeconds * 1e3, signal);
|
|
458
458
|
}
|
|
@@ -589,7 +589,7 @@ function assertServer() {
|
|
|
589
589
|
function createCatalogAdmin(options) {
|
|
590
590
|
assertServer();
|
|
591
591
|
const key = checkKey(options.key);
|
|
592
|
-
const baseUrl = (_nullishCoalesce(options.baseUrl, () => (
|
|
592
|
+
const baseUrl = (_nullishCoalesce(options.baseUrl, () => ( _chunk2ODFFMZ4cjs.DEFAULT_BASE_URL))).replace(/\/+$/u, "");
|
|
593
593
|
if (!/^https?:\/\/[^\s/]+/iu.test(baseUrl))
|
|
594
594
|
throw invalidRequest("baseUrl must be an absolute http or https URL.");
|
|
595
595
|
const http = createHttp(
|
|
@@ -678,4 +678,4 @@ async function verifyCatalogWebhook(input) {
|
|
|
678
678
|
|
|
679
679
|
|
|
680
680
|
|
|
681
|
-
exports.CartLineError =
|
|
681
|
+
exports.CartLineError = _chunk2ODFFMZ4cjs.CartLineError; exports.CatalogError = _chunk2ODFFMZ4cjs.CatalogError; exports.CustomerTokenInvalidError = _chunk2ODFFMZ4cjs.CustomerTokenInvalidError; exports.FeatureUnavailableError = _chunk2ODFFMZ4cjs.FeatureUnavailableError; exports.NetworkError = _chunk2ODFFMZ4cjs.NetworkError; exports.OriginNotAllowedError = _chunk2ODFFMZ4cjs.OriginNotAllowedError; exports.RateLimitedError = _chunk2ODFFMZ4cjs.RateLimitedError; exports.TimeoutError = _chunk2ODFFMZ4cjs.TimeoutError; exports.createCatalogAdmin = createCatalogAdmin; exports.isCatalogError = _chunk2ODFFMZ4cjs.isCatalogError; exports.verifyCatalogWebhook = verifyCatalogWebhook;
|
package/dist/admin.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { C as CartLineError, a as CartLineProblem, b as CatalogError, c as CatalogErrorCode, d as CatalogErrorInit, e as CatalogErrorIssue, f as CatalogErrorSource, g as ClientErrorCode, h as CustomerTokenInvalidError, F as FeatureUnavailableError, N as NetworkError, O as OriginNotAllowedError, R as RateLimitedError, T as TimeoutError, i as isCatalogError } from './catalog-error-
|
|
2
|
-
import './contract-types-
|
|
1
|
+
export { C as CartLineError, a as CartLineProblem, b as CatalogError, c as CatalogErrorCode, d as CatalogErrorInit, e as CatalogErrorIssue, f as CatalogErrorSource, g as ClientErrorCode, h as CustomerTokenInvalidError, F as FeatureUnavailableError, N as NetworkError, O as OriginNotAllowedError, R as RateLimitedError, T as TimeoutError, i as isCatalogError } from './catalog-error-bG1XHquN.cjs';
|
|
2
|
+
import './contract-types-BJMeJSTz.cjs';
|
|
3
3
|
import '@usethrottle/money';
|
|
4
4
|
|
|
5
5
|
type JobBatchAnswer = {
|
|
@@ -85,6 +85,16 @@ type PushJob = {
|
|
|
85
85
|
updated?: number | undefined;
|
|
86
86
|
unchanged?: number | undefined;
|
|
87
87
|
reportExpiresAt?: string | null | undefined;
|
|
88
|
+
failureMessage?: string | null | undefined;
|
|
89
|
+
progressUpdatedAt?: string | undefined;
|
|
90
|
+
attempts?: number | undefined;
|
|
91
|
+
lastAttempt?: {
|
|
92
|
+
attempt: number;
|
|
93
|
+
at: string;
|
|
94
|
+
result: 'success' | 'retryable_failure' | 'terminal_failure';
|
|
95
|
+
code: string;
|
|
96
|
+
} | null | undefined;
|
|
97
|
+
nextAttemptAt?: string | null | undefined;
|
|
88
98
|
batches?: {
|
|
89
99
|
batchId: string;
|
|
90
100
|
sequence: number;
|
|
@@ -139,6 +149,8 @@ type PushProduct = {
|
|
|
139
149
|
held: boolean;
|
|
140
150
|
apiArchived: boolean;
|
|
141
151
|
purgeAfter: string | null;
|
|
152
|
+
createdAt: string;
|
|
153
|
+
updatedAt: string;
|
|
142
154
|
vendorId: string | null;
|
|
143
155
|
attributes: {
|
|
144
156
|
[key: string]: JsonValue;
|
package/dist/admin.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { C as CartLineError, a as CartLineProblem, b as CatalogError, c as CatalogErrorCode, d as CatalogErrorInit, e as CatalogErrorIssue, f as CatalogErrorSource, g as ClientErrorCode, h as CustomerTokenInvalidError, F as FeatureUnavailableError, N as NetworkError, O as OriginNotAllowedError, R as RateLimitedError, T as TimeoutError, i as isCatalogError } from './catalog-error-
|
|
2
|
-
import './contract-types-
|
|
1
|
+
export { C as CartLineError, a as CartLineProblem, b as CatalogError, c as CatalogErrorCode, d as CatalogErrorInit, e as CatalogErrorIssue, f as CatalogErrorSource, g as ClientErrorCode, h as CustomerTokenInvalidError, F as FeatureUnavailableError, N as NetworkError, O as OriginNotAllowedError, R as RateLimitedError, T as TimeoutError, i as isCatalogError } from './catalog-error-c3BVgU6k.js';
|
|
2
|
+
import './contract-types-BJMeJSTz.js';
|
|
3
3
|
import '@usethrottle/money';
|
|
4
4
|
|
|
5
5
|
type JobBatchAnswer = {
|
|
@@ -85,6 +85,16 @@ type PushJob = {
|
|
|
85
85
|
updated?: number | undefined;
|
|
86
86
|
unchanged?: number | undefined;
|
|
87
87
|
reportExpiresAt?: string | null | undefined;
|
|
88
|
+
failureMessage?: string | null | undefined;
|
|
89
|
+
progressUpdatedAt?: string | undefined;
|
|
90
|
+
attempts?: number | undefined;
|
|
91
|
+
lastAttempt?: {
|
|
92
|
+
attempt: number;
|
|
93
|
+
at: string;
|
|
94
|
+
result: 'success' | 'retryable_failure' | 'terminal_failure';
|
|
95
|
+
code: string;
|
|
96
|
+
} | null | undefined;
|
|
97
|
+
nextAttemptAt?: string | null | undefined;
|
|
88
98
|
batches?: {
|
|
89
99
|
batchId: string;
|
|
90
100
|
sequence: number;
|
|
@@ -139,6 +149,8 @@ type PushProduct = {
|
|
|
139
149
|
held: boolean;
|
|
140
150
|
apiArchived: boolean;
|
|
141
151
|
purgeAfter: string | null;
|
|
152
|
+
createdAt: string;
|
|
153
|
+
updatedAt: string;
|
|
142
154
|
vendorId: string | null;
|
|
143
155
|
attributes: {
|
|
144
156
|
[key: string]: JsonValue;
|
package/dist/admin.js
CHANGED