@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/dist/index.d.cts CHANGED
@@ -1,12 +1,58 @@
1
- import { S as StorefrontCategoryNode, b as StorefrontListAnswer, c as StorefrontListProduct, d as ReviewEligibilityAnswer, e as StorefrontProductAnswer } from './contract-types-BRyonOYH.cjs';
2
- export { C as CartCheckAnswer, f as CartCheckRequest, g as CartCreateAnswer, h as CartCreateRequest, i as CatalogContractErrorCode, R as ReviewSubmitAnswer, a as ReviewSubmitInput, j as StorefrontCategoriesAnswer, k as StorefrontCategoryAnswer, l as StorefrontCollectionAnswer, m as StorefrontCollectionsAnswer, n as StorefrontConfigAnswer, o as StorefrontFilterValuesAnswer, p as StorefrontRelatedAnswer, q as StorefrontReviewsAnswer, r as StorefrontSuggestAnswer, s as StorefrontTagsAnswer } from './contract-types-BRyonOYH.cjs';
1
+ import { S as StorefrontSettings, b as StorefrontMenuItem, c as StorefrontCategoryNode, d as StorefrontListAnswer, e as StorefrontListProduct, f as ReviewEligibilityAnswer, g as StorefrontProductAnswer } from './contract-types-BJMeJSTz.cjs';
2
+ export { C as CartCheckAnswer, h as CartCheckRequest, i as CartCreateAnswer, j as CartCreateRequest, k as CatalogContractErrorCode, R as ReviewSubmitAnswer, a as ReviewSubmitInput, l as StorefrontCategoriesAnswer, m as StorefrontCategoryAnswer, n as StorefrontCollectionAnswer, o as StorefrontCollectionsAnswer, p as StorefrontConfigAnswer, q as StorefrontFilterDefinition, r as StorefrontFilterValuesAnswer, s as StorefrontLatestReviewsAnswer, t as StorefrontLookupAnswer, u as StorefrontPageAnswer, v as StorefrontPagesAnswer, w as StorefrontRelatedAnswer, x as StorefrontReviewsAnswer, y as StorefrontSuggestAnswer, z as StorefrontTagsAnswer } from './contract-types-BJMeJSTz.cjs';
3
3
  export { S as SDK_VERSION } from './version-ev3p03v2.cjs';
4
4
  import * as money from '@usethrottle/money';
5
5
  export { money };
6
6
  export { CURRENCIES, CurrencyCode, MoneyValue, UnknownCurrencyError, currencySymbol, formatMoney, isKnownCurrency, minorUnitsOf, moneyValue, parseMoney, toDecimalString, toMinor } from '@usethrottle/money';
7
- export { C as CatalogClient, c as createCatalogClient } from './client-6j1Iz-iJ.cjs';
8
- export { c as CallOptions, d as CartAbsorb, e as CartCheckout, f as CartCheckoutInput, g as CartSession, h as CartSessionBranding, i as CartSessionDetail, j as CartSessionSnapshot, b as CartWarning, k as CartsNamespace, l as CatalogClientOptions, m as CatalogHttpCache, n as CatalogHttpCacheEntry, o as CatalogNamespaces, p as CategoriesNamespace, a as CategoryTreeDepth, q as CollectionsNamespace, C as CustomerCartSource, r as CustomerTokenSource, F as FieldsOption, s as FiltersNamespace, N as NextFetchOptions, O as OpenCartRef, t as ProductsNamespace, P as ProductsQuery, R as Redirect, u as ReviewsNamespace, S as SessionCallOptions, v as StorefrontSort, w as TagsNamespace, T as ThrottleCart, x as ThrottleLine } from './types-D0PywKnN.cjs';
9
- 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, j as ThrottleCartCode, T as TimeoutError, i as isCatalogError } from './catalog-error-BOaSKgY3.cjs';
7
+ export { C as CatalogClient, c as createCatalogClient } from './client-CGGlbacq.cjs';
8
+ export { c as CallOptions, d as CartAbsorb, e as CartCheckout, f as CartCheckoutInput, g as CartSession, h as CartSessionBranding, i as CartSessionDetail, j as CartSessionSnapshot, b as CartWarning, k as CartsNamespace, l as CatalogClientOptions, m as CatalogHttpCache, n as CatalogHttpCacheEntry, o as CatalogNamespaces, p as CategoriesNamespace, a as CategoryTreeDepth, q as CollectionsNamespace, C as CustomerCartSource, r as CustomerTokenSource, F as FieldsOption, s as FiltersNamespace, N as NextFetchOptions, O as OpenCartRef, t as PagesNamespace, u as ProductsNamespace, P as ProductsQuery, R as Redirect, v as ReviewsNamespace, S as SessionCallOptions, w as SettingsCallOptions, x as SettingsNamespace, y as StorefrontSettingsResult, z as StorefrontSort, A as TagsNamespace, T as ThrottleCart, B as ThrottleLine } from './types-BtBxMbM5.cjs';
9
+ 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, j as ThrottleCartCode, T as TimeoutError, i as isCatalogError } from './catalog-error-bG1XHquN.cjs';
10
+
11
+ /** The settings document as `/config` answers it: text resolved, targets as handles. */
12
+ type ResolvedStorefrontSettings = StorefrontSettings;
13
+ /** Where a menu item, announcement or hero button points. */
14
+ type ResolvedMenuTarget = StorefrontMenuItem['target'];
15
+ /** A key of `settings.strings`. */
16
+ type StringKey = keyof StorefrontSettings['strings'];
17
+ /**
18
+ * The English text of every storefront string: what `t` falls back to. Kept
19
+ * in step with the contract's defaults, which the Worker resolves first.
20
+ */
21
+ declare const DEFAULT_STRINGS: Readonly<Record<StringKey, string>>;
22
+ /**
23
+ * One string of the store, in the locale the settings were read for, with
24
+ * `{name}` placeholders filled from `vars` (a name without a value stays as
25
+ * written). A missing or empty string falls back to the English default.
26
+ */
27
+ declare function t(settings: {
28
+ strings?: Partial<Record<StringKey, string>>;
29
+ } | null | undefined, key: StringKey, vars?: Record<string, string | number>): string;
30
+ /**
31
+ * The URL a menu target points to, from the store's route patterns
32
+ * (`settings.routes`); `null` when the target has nothing to point at (no
33
+ * handle, or a link that is not http(s) or a site path).
34
+ */
35
+ declare function resolveMenuTarget(settings: Pick<ResolvedStorefrontSettings, 'routes'>, target: ResolvedMenuTarget): string | null;
36
+ /** The style options `@usethrottle/auth` components take (the part this maps to). */
37
+ type ThrottleAppearance = {
38
+ theme?: 'light' | 'dark' | 'auto';
39
+ variables?: Partial<Record<'colorPrimary' | 'colorPrimaryForeground' | 'colorBackground' | 'colorSurface' | 'colorForeground' | 'colorMuted' | 'colorMutedForeground' | 'colorBorder' | 'colorBorderControl' | 'colorDanger' | 'colorSuccess' | 'colorWarning' | 'fontFamily' | 'borderRadius', string>>;
40
+ };
41
+ type Fonts = StorefrontSettings['theme']['fonts'];
42
+ /**
43
+ * One Google Fonts `css2` URL for the theme's fonts: each Google family once,
44
+ * with the weights the storefront uses (400 to 700, as far as the family has
45
+ * them) and `display=swap`. `null` when every font is a system stack.
46
+ */
47
+ declare function fontStylesheetHref(theme: {
48
+ fonts: Fonts;
49
+ }): string | null;
50
+ /**
51
+ * The appearance for `@usethrottle/auth` components under the store's theme:
52
+ * the `scheme` palette (its accent and sale colours have no auth variable),
53
+ * `fonts.body` as `fontFamily` and `radius` as `borderRadius`.
54
+ */
55
+ declare function toAuthAppearance(theme: Pick<StorefrontSettings['theme'], 'light' | 'dark' | 'fonts' | 'radius'>, scheme: 'light' | 'dark'): ThrottleAppearance;
10
56
 
11
57
  /** The answer of `reviews.eligibility`. */
12
58
  type ReviewEligibility = ReviewEligibilityAnswer;
@@ -19,5 +65,5 @@ type Filter = NonNullable<StorefrontListAnswer['filters']>[number];
19
65
  /** One node of the category tree. */
20
66
  type CategoryNode = StorefrontCategoryNode;
21
67
 
22
- export { ReviewEligibilityAnswer, StorefrontCategoryNode, StorefrontListAnswer, StorefrontListProduct, StorefrontProductAnswer };
23
- export type { CategoryNode, Filter, ListProduct, ReviewEligibility, StorefrontProduct };
68
+ export { DEFAULT_STRINGS, ReviewEligibilityAnswer, StorefrontCategoryNode, StorefrontListAnswer, StorefrontListProduct, StorefrontMenuItem, StorefrontProductAnswer, StorefrontSettings, fontStylesheetHref, resolveMenuTarget, t, toAuthAppearance };
69
+ export type { CategoryNode, Filter, ListProduct, ResolvedMenuTarget, ResolvedStorefrontSettings, ReviewEligibility, StorefrontProduct, StringKey, ThrottleAppearance };
package/dist/index.d.ts CHANGED
@@ -1,12 +1,58 @@
1
- import { S as StorefrontCategoryNode, b as StorefrontListAnswer, c as StorefrontListProduct, d as ReviewEligibilityAnswer, e as StorefrontProductAnswer } from './contract-types-BRyonOYH.js';
2
- export { C as CartCheckAnswer, f as CartCheckRequest, g as CartCreateAnswer, h as CartCreateRequest, i as CatalogContractErrorCode, R as ReviewSubmitAnswer, a as ReviewSubmitInput, j as StorefrontCategoriesAnswer, k as StorefrontCategoryAnswer, l as StorefrontCollectionAnswer, m as StorefrontCollectionsAnswer, n as StorefrontConfigAnswer, o as StorefrontFilterValuesAnswer, p as StorefrontRelatedAnswer, q as StorefrontReviewsAnswer, r as StorefrontSuggestAnswer, s as StorefrontTagsAnswer } from './contract-types-BRyonOYH.js';
1
+ import { S as StorefrontSettings, b as StorefrontMenuItem, c as StorefrontCategoryNode, d as StorefrontListAnswer, e as StorefrontListProduct, f as ReviewEligibilityAnswer, g as StorefrontProductAnswer } from './contract-types-BJMeJSTz.js';
2
+ export { C as CartCheckAnswer, h as CartCheckRequest, i as CartCreateAnswer, j as CartCreateRequest, k as CatalogContractErrorCode, R as ReviewSubmitAnswer, a as ReviewSubmitInput, l as StorefrontCategoriesAnswer, m as StorefrontCategoryAnswer, n as StorefrontCollectionAnswer, o as StorefrontCollectionsAnswer, p as StorefrontConfigAnswer, q as StorefrontFilterDefinition, r as StorefrontFilterValuesAnswer, s as StorefrontLatestReviewsAnswer, t as StorefrontLookupAnswer, u as StorefrontPageAnswer, v as StorefrontPagesAnswer, w as StorefrontRelatedAnswer, x as StorefrontReviewsAnswer, y as StorefrontSuggestAnswer, z as StorefrontTagsAnswer } from './contract-types-BJMeJSTz.js';
3
3
  export { S as SDK_VERSION } from './version-ev3p03v2.js';
4
4
  import * as money from '@usethrottle/money';
5
5
  export { money };
6
6
  export { CURRENCIES, CurrencyCode, MoneyValue, UnknownCurrencyError, currencySymbol, formatMoney, isKnownCurrency, minorUnitsOf, moneyValue, parseMoney, toDecimalString, toMinor } from '@usethrottle/money';
7
- export { C as CatalogClient, c as createCatalogClient } from './client-B3mL2-xJ.js';
8
- export { c as CallOptions, d as CartAbsorb, e as CartCheckout, f as CartCheckoutInput, g as CartSession, h as CartSessionBranding, i as CartSessionDetail, j as CartSessionSnapshot, b as CartWarning, k as CartsNamespace, l as CatalogClientOptions, m as CatalogHttpCache, n as CatalogHttpCacheEntry, o as CatalogNamespaces, p as CategoriesNamespace, a as CategoryTreeDepth, q as CollectionsNamespace, C as CustomerCartSource, r as CustomerTokenSource, F as FieldsOption, s as FiltersNamespace, N as NextFetchOptions, O as OpenCartRef, t as ProductsNamespace, P as ProductsQuery, R as Redirect, u as ReviewsNamespace, S as SessionCallOptions, v as StorefrontSort, w as TagsNamespace, T as ThrottleCart, x as ThrottleLine } from './types-BfveENg1.js';
9
- 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, j as ThrottleCartCode, T as TimeoutError, i as isCatalogError } from './catalog-error-CSoPS0-d.js';
7
+ export { C as CatalogClient, c as createCatalogClient } from './client-CNsVr2lR.js';
8
+ export { c as CallOptions, d as CartAbsorb, e as CartCheckout, f as CartCheckoutInput, g as CartSession, h as CartSessionBranding, i as CartSessionDetail, j as CartSessionSnapshot, b as CartWarning, k as CartsNamespace, l as CatalogClientOptions, m as CatalogHttpCache, n as CatalogHttpCacheEntry, o as CatalogNamespaces, p as CategoriesNamespace, a as CategoryTreeDepth, q as CollectionsNamespace, C as CustomerCartSource, r as CustomerTokenSource, F as FieldsOption, s as FiltersNamespace, N as NextFetchOptions, O as OpenCartRef, t as PagesNamespace, u as ProductsNamespace, P as ProductsQuery, R as Redirect, v as ReviewsNamespace, S as SessionCallOptions, w as SettingsCallOptions, x as SettingsNamespace, y as StorefrontSettingsResult, z as StorefrontSort, A as TagsNamespace, T as ThrottleCart, B as ThrottleLine } from './types-dKvIfrVH.js';
9
+ 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, j as ThrottleCartCode, T as TimeoutError, i as isCatalogError } from './catalog-error-c3BVgU6k.js';
10
+
11
+ /** The settings document as `/config` answers it: text resolved, targets as handles. */
12
+ type ResolvedStorefrontSettings = StorefrontSettings;
13
+ /** Where a menu item, announcement or hero button points. */
14
+ type ResolvedMenuTarget = StorefrontMenuItem['target'];
15
+ /** A key of `settings.strings`. */
16
+ type StringKey = keyof StorefrontSettings['strings'];
17
+ /**
18
+ * The English text of every storefront string: what `t` falls back to. Kept
19
+ * in step with the contract's defaults, which the Worker resolves first.
20
+ */
21
+ declare const DEFAULT_STRINGS: Readonly<Record<StringKey, string>>;
22
+ /**
23
+ * One string of the store, in the locale the settings were read for, with
24
+ * `{name}` placeholders filled from `vars` (a name without a value stays as
25
+ * written). A missing or empty string falls back to the English default.
26
+ */
27
+ declare function t(settings: {
28
+ strings?: Partial<Record<StringKey, string>>;
29
+ } | null | undefined, key: StringKey, vars?: Record<string, string | number>): string;
30
+ /**
31
+ * The URL a menu target points to, from the store's route patterns
32
+ * (`settings.routes`); `null` when the target has nothing to point at (no
33
+ * handle, or a link that is not http(s) or a site path).
34
+ */
35
+ declare function resolveMenuTarget(settings: Pick<ResolvedStorefrontSettings, 'routes'>, target: ResolvedMenuTarget): string | null;
36
+ /** The style options `@usethrottle/auth` components take (the part this maps to). */
37
+ type ThrottleAppearance = {
38
+ theme?: 'light' | 'dark' | 'auto';
39
+ variables?: Partial<Record<'colorPrimary' | 'colorPrimaryForeground' | 'colorBackground' | 'colorSurface' | 'colorForeground' | 'colorMuted' | 'colorMutedForeground' | 'colorBorder' | 'colorBorderControl' | 'colorDanger' | 'colorSuccess' | 'colorWarning' | 'fontFamily' | 'borderRadius', string>>;
40
+ };
41
+ type Fonts = StorefrontSettings['theme']['fonts'];
42
+ /**
43
+ * One Google Fonts `css2` URL for the theme's fonts: each Google family once,
44
+ * with the weights the storefront uses (400 to 700, as far as the family has
45
+ * them) and `display=swap`. `null` when every font is a system stack.
46
+ */
47
+ declare function fontStylesheetHref(theme: {
48
+ fonts: Fonts;
49
+ }): string | null;
50
+ /**
51
+ * The appearance for `@usethrottle/auth` components under the store's theme:
52
+ * the `scheme` palette (its accent and sale colours have no auth variable),
53
+ * `fonts.body` as `fontFamily` and `radius` as `borderRadius`.
54
+ */
55
+ declare function toAuthAppearance(theme: Pick<StorefrontSettings['theme'], 'light' | 'dark' | 'fonts' | 'radius'>, scheme: 'light' | 'dark'): ThrottleAppearance;
10
56
 
11
57
  /** The answer of `reviews.eligibility`. */
12
58
  type ReviewEligibility = ReviewEligibilityAnswer;
@@ -19,5 +65,5 @@ type Filter = NonNullable<StorefrontListAnswer['filters']>[number];
19
65
  /** One node of the category tree. */
20
66
  type CategoryNode = StorefrontCategoryNode;
21
67
 
22
- export { ReviewEligibilityAnswer, StorefrontCategoryNode, StorefrontListAnswer, StorefrontListProduct, StorefrontProductAnswer };
23
- export type { CategoryNode, Filter, ListProduct, ReviewEligibility, StorefrontProduct };
68
+ export { DEFAULT_STRINGS, ReviewEligibilityAnswer, StorefrontCategoryNode, StorefrontListAnswer, StorefrontListProduct, StorefrontMenuItem, StorefrontProductAnswer, StorefrontSettings, fontStylesheetHref, resolveMenuTarget, t, toAuthAppearance };
69
+ export type { CategoryNode, Filter, ListProduct, ResolvedMenuTarget, ResolvedStorefrontSettings, ReviewEligibility, StorefrontProduct, StringKey, ThrottleAppearance };
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@ import {
3
3
  CartLineError,
4
4
  CatalogError,
5
5
  CustomerTokenInvalidError,
6
+ DEFAULT_STRINGS,
6
7
  FeatureUnavailableError,
7
8
  NetworkError,
8
9
  OriginNotAllowedError,
@@ -12,6 +13,7 @@ import {
12
13
  UnknownCurrencyError,
13
14
  createCatalogClient,
14
15
  currencySymbol,
16
+ fontStylesheetHref,
15
17
  formatMoney,
16
18
  isCatalogError,
17
19
  isKnownCurrency,
@@ -19,15 +21,19 @@ import {
19
21
  money,
20
22
  moneyValue,
21
23
  parseMoney,
24
+ resolveMenuTarget,
25
+ t,
26
+ toAuthAppearance,
22
27
  toDecimalString,
23
28
  toMinor
24
- } from "./chunk-3DLH56OX.js";
29
+ } from "./chunk-STNQNHNZ.js";
25
30
  import "./chunk-PKBMQBKP.js";
26
31
  export {
27
32
  CURRENCIES,
28
33
  CartLineError,
29
34
  CatalogError,
30
35
  CustomerTokenInvalidError,
36
+ DEFAULT_STRINGS,
31
37
  FeatureUnavailableError,
32
38
  NetworkError,
33
39
  OriginNotAllowedError,
@@ -37,6 +43,7 @@ export {
37
43
  UnknownCurrencyError,
38
44
  createCatalogClient,
39
45
  currencySymbol,
46
+ fontStylesheetHref,
40
47
  formatMoney,
41
48
  isCatalogError,
42
49
  isKnownCurrency,
@@ -44,6 +51,9 @@ export {
44
51
  money,
45
52
  moneyValue,
46
53
  parseMoney,
54
+ resolveMenuTarget,
55
+ t,
56
+ toAuthAppearance,
47
57
  toDecimalString,
48
58
  toMinor
49
59
  };
package/dist/next.cjs ADDED
@@ -0,0 +1,180 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } async function _asyncNullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return await rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
+
3
+
4
+ var _chunk5AJS3CX5cjs = require('./chunk-5AJS3CX5.cjs');
5
+
6
+
7
+
8
+ var _chunk2ODFFMZ4cjs = require('./chunk-2ODFFMZ4.cjs');
9
+ require('./chunk-ETV4XYOV.cjs');
10
+
11
+ // src/next/verify.ts
12
+ var HEX_SHA256 = /^[0-9a-fA-F]{64}$/u;
13
+ var TOLERANCE_SECONDS = 300;
14
+ var MAX_V1 = 8;
15
+ var MAX_HEADER_BYTES = 1024;
16
+ var encoder = new TextEncoder();
17
+ async function hmac(secret, payload) {
18
+ const key = await crypto.subtle.importKey(
19
+ "raw",
20
+ encoder.encode(secret),
21
+ { name: "HMAC", hash: "SHA-256" },
22
+ false,
23
+ ["sign"]
24
+ );
25
+ return new Uint8Array(
26
+ await crypto.subtle.sign("HMAC", key, encoder.encode(payload))
27
+ );
28
+ }
29
+ function fromHex(hex) {
30
+ return Uint8Array.from(
31
+ { length: hex.length / 2 },
32
+ (_, i) => Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16)
33
+ );
34
+ }
35
+ function constantTimeEqual(left, right) {
36
+ const length = Math.max(left.length, right.length);
37
+ let difference = left.length ^ right.length;
38
+ for (let i = 0; i < length; i += 1)
39
+ difference |= (_nullishCoalesce(left[i], () => ( 0))) ^ (_nullishCoalesce(right[i], () => ( 0)));
40
+ return difference === 0;
41
+ }
42
+ async function verifyCatalogWebhook(input) {
43
+ try {
44
+ const { secret, rawBody, signature } = input;
45
+ const now = Math.floor(Date.now() / 1e3);
46
+ if (secret.length === 0 || rawBody.length === 0 || signature.length === 0 || encoder.encode(signature).byteLength > MAX_HEADER_BYTES)
47
+ return false;
48
+ const parts = signature.split(",").map((part) => part.split("="));
49
+ if (parts.some((part) => part.length !== 2)) return false;
50
+ const timestamps = parts.filter(([k]) => k === "t").map(([, v]) => _nullishCoalesce(v, () => ( "")));
51
+ const digests = parts.filter(([k]) => k === "v1").map(([, v]) => _nullishCoalesce(v, () => ( "")));
52
+ if (parts.some(([k]) => k !== "t" && k !== "v1") || timestamps.length !== 1 || digests.length === 0 || digests.length > MAX_V1 || digests.some((d) => !HEX_SHA256.test(d)))
53
+ return false;
54
+ const timestampText = _nullishCoalesce(timestamps[0], () => ( ""));
55
+ if (!/^(?:0|[1-9][0-9]*)$/u.test(timestampText)) return false;
56
+ const timestamp = Number(timestampText);
57
+ if (!Number.isSafeInteger(timestamp) || Math.abs(now - timestamp) > TOLERANCE_SECONDS)
58
+ return false;
59
+ const expected = await hmac(secret, `${timestampText}.${rawBody}`);
60
+ let matched = false;
61
+ for (const digest of digests)
62
+ matched = constantTimeEqual(expected, fromHex(digest)) || matched;
63
+ return matched;
64
+ } catch (e) {
65
+ return false;
66
+ }
67
+ }
68
+
69
+ // src/next/revalidate.ts
70
+ var SIGNATURE_HEADER = "x-catalog-signature";
71
+ var MAX_BODY_BYTES = 64 * 1024;
72
+ async function readCapped(req) {
73
+ const declared = Number(req.headers.get("content-length"));
74
+ if (Number.isFinite(declared) && declared > MAX_BODY_BYTES) return null;
75
+ if (req.body === null) return "";
76
+ const reader = req.body.getReader();
77
+ const decoder = new TextDecoder();
78
+ let text = "";
79
+ let size = 0;
80
+ for (; ; ) {
81
+ const { done, value } = await reader.read();
82
+ if (done) return text + decoder.decode();
83
+ size += value.byteLength;
84
+ if (size > MAX_BODY_BYTES) {
85
+ await reader.cancel();
86
+ return null;
87
+ }
88
+ text += decoder.decode(value, { stream: true });
89
+ }
90
+ }
91
+ var json = (status, body) => new Response(JSON.stringify(body), {
92
+ status,
93
+ headers: {
94
+ "content-type": "application/json",
95
+ "cache-control": "no-store"
96
+ }
97
+ });
98
+ function parseNotice(rawBody) {
99
+ let value;
100
+ try {
101
+ value = JSON.parse(rawBody);
102
+ } catch (e2) {
103
+ return null;
104
+ }
105
+ if (typeof value !== "object" || value === null) return null;
106
+ const event = value;
107
+ const { generation, scopes } = event;
108
+ if (event.type !== "storefront.changed" || typeof generation !== "number" || !Number.isSafeInteger(generation) || generation < 0 || !Array.isArray(scopes) || scopes.length === 0 || !scopes.every(
109
+ (scope) => typeof scope === "string" && scope.length > 0 && scope.length <= _chunk2ODFFMZ4cjs.TAG_MAX_CHARS
110
+ ) || event.test !== void 0 && typeof event.test !== "boolean")
111
+ return null;
112
+ return {
113
+ generation,
114
+ scopes,
115
+ test: event.test === true
116
+ };
117
+ }
118
+ async function defaultRevalidateTag() {
119
+ const { revalidateTag } = await Promise.resolve().then(() => _interopRequireWildcard(require("next/cache")));
120
+ return (tag) => revalidateTag(tag, { expire: 0 });
121
+ }
122
+ function createRevalidateHandler(options) {
123
+ return async (req) => {
124
+ const list = typeof options.secret === "string" || options.secret === void 0 ? [options.secret] : options.secret;
125
+ const secrets = list.filter(
126
+ (secret) => typeof secret === "string" && secret !== ""
127
+ );
128
+ if (secrets.length === 0)
129
+ return json(500, {
130
+ error: "createRevalidateHandler has no signing secret: set the webhook secret (for example THROTTLE_WEBHOOK_SECRET) in this environment."
131
+ });
132
+ const rawBody = await readCapped(req);
133
+ if (rawBody === null) return json(413, { error: "body too large" });
134
+ const signature = _nullishCoalesce(req.headers.get(SIGNATURE_HEADER), () => ( ""));
135
+ let verified = false;
136
+ for (const secret of secrets)
137
+ verified = await verifyCatalogWebhook({ rawBody, signature, secret }) || verified;
138
+ if (!verified) return json(401, { error: "invalid signature" });
139
+ const notice = parseNotice(rawBody);
140
+ if (notice === null) return json(400, { error: "invalid body" });
141
+ if (notice.test) return json(200, { revalidated: [] });
142
+ const tags = _chunk5AJS3CX5cjs.scopesToTags.call(void 0, notice.scopes);
143
+ const revalidate = await _asyncNullishCoalesce(options.revalidateTag, async () => ( await defaultRevalidateTag()));
144
+ for (const tag of tags) revalidate(tag);
145
+ _chunk5AJS3CX5cjs.noteMinGeneration.call(void 0, notice.generation, options.floorKey);
146
+ return json(200, { revalidated: tags });
147
+ };
148
+ }
149
+
150
+ // src/next/preview.ts
151
+ var PREVIEW_COOKIE = "throttle_preview";
152
+ var PREVIEW_PARAM = "throttle_preview";
153
+ var PREVIEW_MAX_AGE_S = 3600;
154
+ function previewMiddleware(req) {
155
+ const url = new URL(req.url);
156
+ const token = url.searchParams.get(PREVIEW_PARAM);
157
+ if (token === null || token === "") return null;
158
+ url.searchParams.delete(PREVIEW_PARAM);
159
+ return new Response(null, {
160
+ status: 307,
161
+ headers: {
162
+ location: url.toString(),
163
+ "set-cookie": `${PREVIEW_COOKIE}=${encodeURIComponent(token)}; Max-Age=${PREVIEW_MAX_AGE_S}; Path=/; HttpOnly; Secure; SameSite=None`,
164
+ "cache-control": "no-store"
165
+ }
166
+ });
167
+ }
168
+ async function getPreviewToken() {
169
+ const { cookies } = await Promise.resolve().then(() => _interopRequireWildcard(require("next/headers")));
170
+ const store = await cookies();
171
+ const value = _optionalChain([store, 'access', _2 => _2.get, 'call', _3 => _3(PREVIEW_COOKIE), 'optionalAccess', _4 => _4.value]);
172
+ return value === void 0 || value === "" ? void 0 : value;
173
+ }
174
+
175
+
176
+
177
+
178
+
179
+
180
+ exports.SDK_VERSION = _chunk2ODFFMZ4cjs.SDK_VERSION; exports.createRevalidateHandler = createRevalidateHandler; exports.getPreviewToken = getPreviewToken; exports.noteMinGeneration = _chunk5AJS3CX5cjs.noteMinGeneration; exports.previewMiddleware = previewMiddleware;
@@ -0,0 +1,60 @@
1
+ export { S as SDK_VERSION } from './version-ev3p03v2.cjs';
2
+
3
+ type CreateRevalidateHandlerOptions = {
4
+ /**
5
+ * The webhook's signing secret; pass `process.env` straight in. A list
6
+ * accepts any of them, so a rotated secret can be added before the old one
7
+ * is removed. Checked on each request, not here: an unset variable at
8
+ * `next build` time must not fail the build. With no secret a request is
9
+ * answered 500 and nothing is revalidated.
10
+ */
11
+ secret: string | undefined | readonly (string | undefined)[];
12
+ /**
13
+ * Whose floor the notice's generation raises (see `noteMinGeneration`).
14
+ * Omitted, it applies to every client in the process: right for one store.
15
+ * With several stores, pass the `publishableKey` of this store's server
16
+ * client (or the `floorKey` that client names).
17
+ */
18
+ floorKey?: string;
19
+ /**
20
+ * Called once per cache tag to clear. Defaults to `revalidateTag` from
21
+ * `next/cache`.
22
+ */
23
+ revalidateTag?: (tag: string) => void;
24
+ };
25
+ /**
26
+ * The route handler for the catalog's `storefront.changed` webhook. It checks
27
+ * the `x-catalog-signature` header (HMAC-SHA256 over `<t>.<body>`, 300 s
28
+ * tolerance, any of the given secrets), clears the cache tags of the event's
29
+ * scopes and notes its generation so the next `/config` read is fresh.
30
+ * Answers 200 `{ revalidated }`, 401 for a missing or wrong signature, 400
31
+ * for a body that is not a change notice, 413 for a body over 64 KB and 500
32
+ * when no secret is set. A `test` event is acknowledged
33
+ * (`{ revalidated: [] }`) and does nothing else.
34
+ */
35
+ declare function createRevalidateHandler(options: CreateRevalidateHandlerOptions): (req: Request) => Promise<Response>;
36
+
37
+ /**
38
+ * For Next middleware: a request with `?throttle_preview=<token>` is answered
39
+ * with a 307 to the same URL without that parameter and the token in an
40
+ * HTTP-only `SameSite=None; Secure` cookie (one hour), so it works inside the
41
+ * dashboard's preview iframe. Any other request returns `null`.
42
+ */
43
+ declare function previewMiddleware(req: Request): Response | null;
44
+ /**
45
+ * The preview token of the current request (the `throttle_preview` cookie),
46
+ * for `createServerCatalogClient({ previewToken })`. Reads `cookies()` from
47
+ * `next/headers`, which is a promise in Next 15 and later and a plain object
48
+ * in Next 14. Call it where Next allows a request-scoped read.
49
+ */
50
+ declare function getPreviewToken(): Promise<string | undefined>;
51
+
52
+ /**
53
+ * Records `generation` as the minimum the next `/config` read of `floorKey`'s
54
+ * store (every store, when omitted) must reach. The largest value noted stays
55
+ * until a `/config` answer reaches it.
56
+ */
57
+ declare function noteMinGeneration(generation: number, floorKey?: string): void;
58
+
59
+ export { createRevalidateHandler, getPreviewToken, noteMinGeneration, previewMiddleware };
60
+ export type { CreateRevalidateHandlerOptions };
package/dist/next.d.ts ADDED
@@ -0,0 +1,60 @@
1
+ export { S as SDK_VERSION } from './version-ev3p03v2.js';
2
+
3
+ type CreateRevalidateHandlerOptions = {
4
+ /**
5
+ * The webhook's signing secret; pass `process.env` straight in. A list
6
+ * accepts any of them, so a rotated secret can be added before the old one
7
+ * is removed. Checked on each request, not here: an unset variable at
8
+ * `next build` time must not fail the build. With no secret a request is
9
+ * answered 500 and nothing is revalidated.
10
+ */
11
+ secret: string | undefined | readonly (string | undefined)[];
12
+ /**
13
+ * Whose floor the notice's generation raises (see `noteMinGeneration`).
14
+ * Omitted, it applies to every client in the process: right for one store.
15
+ * With several stores, pass the `publishableKey` of this store's server
16
+ * client (or the `floorKey` that client names).
17
+ */
18
+ floorKey?: string;
19
+ /**
20
+ * Called once per cache tag to clear. Defaults to `revalidateTag` from
21
+ * `next/cache`.
22
+ */
23
+ revalidateTag?: (tag: string) => void;
24
+ };
25
+ /**
26
+ * The route handler for the catalog's `storefront.changed` webhook. It checks
27
+ * the `x-catalog-signature` header (HMAC-SHA256 over `<t>.<body>`, 300 s
28
+ * tolerance, any of the given secrets), clears the cache tags of the event's
29
+ * scopes and notes its generation so the next `/config` read is fresh.
30
+ * Answers 200 `{ revalidated }`, 401 for a missing or wrong signature, 400
31
+ * for a body that is not a change notice, 413 for a body over 64 KB and 500
32
+ * when no secret is set. A `test` event is acknowledged
33
+ * (`{ revalidated: [] }`) and does nothing else.
34
+ */
35
+ declare function createRevalidateHandler(options: CreateRevalidateHandlerOptions): (req: Request) => Promise<Response>;
36
+
37
+ /**
38
+ * For Next middleware: a request with `?throttle_preview=<token>` is answered
39
+ * with a 307 to the same URL without that parameter and the token in an
40
+ * HTTP-only `SameSite=None; Secure` cookie (one hour), so it works inside the
41
+ * dashboard's preview iframe. Any other request returns `null`.
42
+ */
43
+ declare function previewMiddleware(req: Request): Response | null;
44
+ /**
45
+ * The preview token of the current request (the `throttle_preview` cookie),
46
+ * for `createServerCatalogClient({ previewToken })`. Reads `cookies()` from
47
+ * `next/headers`, which is a promise in Next 15 and later and a plain object
48
+ * in Next 14. Call it where Next allows a request-scoped read.
49
+ */
50
+ declare function getPreviewToken(): Promise<string | undefined>;
51
+
52
+ /**
53
+ * Records `generation` as the minimum the next `/config` read of `floorKey`'s
54
+ * store (every store, when omitted) must reach. The largest value noted stays
55
+ * until a `/config` answer reaches it.
56
+ */
57
+ declare function noteMinGeneration(generation: number, floorKey?: string): void;
58
+
59
+ export { createRevalidateHandler, getPreviewToken, noteMinGeneration, previewMiddleware };
60
+ export type { CreateRevalidateHandlerOptions };