@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.
Files changed (45) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +105 -9
  3. package/dist/admin.cjs +16 -16
  4. package/dist/admin.d.cts +14 -2
  5. package/dist/admin.d.ts +14 -2
  6. package/dist/admin.js +1 -1
  7. package/dist/{catalog-error-BOaSKgY3.d.cts → catalog-error-bG1XHquN.d.cts} +1 -1
  8. package/dist/{catalog-error-CSoPS0-d.d.ts → catalog-error-c3BVgU6k.d.ts} +1 -1
  9. package/dist/{chunk-2YQNMBDI.cjs → chunk-2ODFFMZ4.cjs} +274 -38
  10. package/dist/chunk-5AJS3CX5.cjs +192 -0
  11. package/dist/{chunk-CADIHOIR.js → chunk-6K7H7HBD.js} +89 -2
  12. package/dist/chunk-P3ABGAF5.js +192 -0
  13. package/dist/{chunk-3DLH56OX.js → chunk-STNQNHNZ.js} +258 -22
  14. package/dist/{chunk-GU63WFXI.cjs → chunk-VOOX3WJY.cjs} +102 -15
  15. package/dist/{client-6j1Iz-iJ.d.cts → client-CGGlbacq.d.cts} +1 -1
  16. package/dist/{client-B3mL2-xJ.d.ts → client-CNsVr2lR.d.ts} +1 -1
  17. package/dist/{contract-types-BRyonOYH.d.cts → contract-types-BJMeJSTz.d.cts} +269 -2
  18. package/dist/{contract-types-BRyonOYH.d.ts → contract-types-BJMeJSTz.d.ts} +269 -2
  19. package/dist/index.cjs +12 -2
  20. package/dist/index.d.cts +53 -7
  21. package/dist/index.d.ts +53 -7
  22. package/dist/index.js +11 -1
  23. package/dist/next.cjs +180 -0
  24. package/dist/next.d.cts +60 -0
  25. package/dist/next.d.ts +60 -0
  26. package/dist/next.js +180 -0
  27. package/dist/react-extras.cjs +27 -9
  28. package/dist/react-extras.d.cts +6 -4
  29. package/dist/react-extras.d.ts +6 -4
  30. package/dist/react-extras.js +20 -2
  31. package/dist/react.cjs +18 -14
  32. package/dist/react.d.cts +22 -5
  33. package/dist/react.d.ts +22 -5
  34. package/dist/react.js +6 -2
  35. package/dist/server.cjs +58 -66
  36. package/dist/server.d.cts +57 -10
  37. package/dist/server.d.ts +57 -10
  38. package/dist/server.js +52 -60
  39. package/dist/{types-D0PywKnN.d.cts → types-BtBxMbM5.d.cts} +40 -3
  40. package/dist/{types-BfveENg1.d.ts → types-dKvIfrVH.d.ts} +40 -3
  41. package/dist/url.d.cts +1 -1
  42. package/dist/url.d.ts +1 -1
  43. package/dist/{use-query-UWf6Pi5g.d.cts → use-query-C2rfTJd4.d.cts} +1 -1
  44. package/dist/{use-query-CR7r5tam.d.ts → use-query-DeCj1hXt.d.ts} +1 -1
  45. 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/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). |
46
- | `@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). |
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 by default); carts, Throttle calls and any request with a customer token are `cache: 'no-store'`. Next.js itself is never imported.
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 _chunk2YQNMBDIcjs = require('./chunk-2YQNMBDI.cjs');
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, _chunk2YQNMBDIcjs.CatalogError)({
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, _chunk2YQNMBDIcjs.CatalogError)({
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, _chunk2YQNMBDIcjs.RateLimitedError)({
129
+ return new (0, _chunk2ODFFMZ4cjs.RateLimitedError)({
130
130
  ...init,
131
131
  retryable: true,
132
- retryAfterSeconds: retryAfter !== null && retryAfter >= 1 ? retryAfter : _chunk2YQNMBDIcjs.RATE_LIMIT_DEFAULT_RETRY_S
132
+ retryAfterSeconds: retryAfter !== null && retryAfter >= 1 ? retryAfter : _chunk2ODFFMZ4cjs.RATE_LIMIT_DEFAULT_RETRY_S
133
133
  });
134
134
  }
135
- return new (0, _chunk2YQNMBDIcjs.CatalogError)(init);
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, _chunk2YQNMBDIcjs.TimeoutError)({ timeoutMs }));
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, _chunk2YQNMBDIcjs.NetworkError)({ cause });
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, _chunk2YQNMBDIcjs.NetworkError)({ cause });
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 _chunk2YQNMBDIcjs.NetworkError && attempt < attempts) continue;
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, _chunk2YQNMBDIcjs.CatalogError)({
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, _chunk2YQNMBDIcjs.CatalogError)({
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, _chunk2YQNMBDIcjs.TimeoutError)({ timeoutMs });
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 _chunk2YQNMBDIcjs.RateLimitedError) || retry >= QUEUE_RETRIES)
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, () => ( _chunk2YQNMBDIcjs.DEFAULT_BASE_URL))).replace(/\/+$/u, "");
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 = _chunk2YQNMBDIcjs.CartLineError; exports.CatalogError = _chunk2YQNMBDIcjs.CatalogError; exports.CustomerTokenInvalidError = _chunk2YQNMBDIcjs.CustomerTokenInvalidError; exports.FeatureUnavailableError = _chunk2YQNMBDIcjs.FeatureUnavailableError; exports.NetworkError = _chunk2YQNMBDIcjs.NetworkError; exports.OriginNotAllowedError = _chunk2YQNMBDIcjs.OriginNotAllowedError; exports.RateLimitedError = _chunk2YQNMBDIcjs.RateLimitedError; exports.TimeoutError = _chunk2YQNMBDIcjs.TimeoutError; exports.createCatalogAdmin = createCatalogAdmin; exports.isCatalogError = _chunk2YQNMBDIcjs.isCatalogError; exports.verifyCatalogWebhook = verifyCatalogWebhook;
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-BOaSKgY3.cjs';
2
- import './contract-types-BRyonOYH.cjs';
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-CSoPS0-d.js';
2
- import './contract-types-BRyonOYH.js';
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
@@ -10,7 +10,7 @@ import {
10
10
  RateLimitedError,
11
11
  TimeoutError,
12
12
  isCatalogError
13
- } from "./chunk-3DLH56OX.js";
13
+ } from "./chunk-STNQNHNZ.js";
14
14
  import "./chunk-PKBMQBKP.js";
15
15
 
16
16
  // src/generated/push-types.ts
@@ -1,4 +1,4 @@
1
- import { i as CatalogContractErrorCode } from './contract-types-BRyonOYH.cjs';
1
+ import { k as CatalogContractErrorCode } from './contract-types-BJMeJSTz.cjs';
2
2
 
3
3
  /**
4
4
  * Shared error type for every Throttle SDK.
@@ -1,4 +1,4 @@
1
- import { i as CatalogContractErrorCode } from './contract-types-BRyonOYH.js';
1
+ import { k as CatalogContractErrorCode } from './contract-types-BJMeJSTz.js';
2
2
 
3
3
  /**
4
4
  * Shared error type for every Throttle SDK.