@usethrottle/catalog 1.2.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +111 -15
  3. package/dist/admin.cjs +16 -16
  4. package/dist/admin.d.cts +15 -2
  5. package/dist/admin.d.ts +15 -2
  6. package/dist/admin.js +1 -1
  7. package/dist/{catalog-error-yTBMAdCv.d.cts → catalog-error-BKN5hNWP.d.cts} +11 -1
  8. package/dist/{catalog-error-7DCsTyB2.d.ts → catalog-error-BnabMMEy.d.ts} +11 -1
  9. package/dist/{chunk-JNBKKAMP.js → chunk-3FX2HISB.js} +97 -2
  10. package/dist/{chunk-B2DYAHNR.cjs → chunk-J2GHGQY6.cjs} +334 -43
  11. package/dist/{chunk-TDMDOHD3.cjs → chunk-OKWXS3FD.cjs} +110 -15
  12. package/dist/chunk-PZ3SFYH4.cjs +192 -0
  13. package/dist/chunk-SN6STYPW.js +192 -0
  14. package/dist/{chunk-55G4ZTD5.js → chunk-VJHA7J7B.js} +315 -24
  15. package/dist/{client-Dm6I4nAZ.d.ts → client-B6CsU_v9.d.ts} +1 -1
  16. package/dist/{client-BrHJCyBP.d.cts → client-terkEl6u.d.cts} +1 -1
  17. package/dist/{contract-types-BPSzY_Co.d.cts → contract-types-D2-SSPM9.d.cts} +241 -11
  18. package/dist/{contract-types-BPSzY_Co.d.ts → contract-types-D2-SSPM9.d.ts} +241 -11
  19. package/dist/index.cjs +34 -2
  20. package/dist/index.d.cts +56 -7
  21. package/dist/index.d.ts +56 -7
  22. package/dist/index.js +35 -3
  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 +7 -4
  29. package/dist/react-extras.d.ts +7 -4
  30. package/dist/react-extras.js +20 -2
  31. package/dist/react.cjs +130 -54
  32. package/dist/react.d.cts +52 -11
  33. package/dist/react.d.ts +52 -11
  34. package/dist/react.js +112 -36
  35. package/dist/server.cjs +58 -66
  36. package/dist/server.d.cts +58 -10
  37. package/dist/server.d.ts +58 -10
  38. package/dist/server.js +52 -60
  39. package/dist/{types-BlYCKzB8.d.ts → types-jNpOwEUw.d.cts} +81 -8
  40. package/dist/{types-BTrqSprj.d.cts → types-z57bkjjB.d.ts} +81 -8
  41. package/dist/url.d.cts +2 -1
  42. package/dist/url.d.ts +2 -1
  43. package/dist/{use-query-QOEBuYlp.d.ts → use-query-COqRZJnC.d.ts} +1 -1
  44. package/dist/{use-query-BZgjxGPO.d.cts → use-query-H1xgL3_e.d.cts} +1 -1
  45. package/package.json +17 -2
@@ -1,9 +1,24 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return 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; }
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(); } } 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
2
 
3
3
  var _chunkETV4XYOVcjs = require('./chunk-ETV4XYOV.cjs');
4
4
 
5
5
  // src/version.ts
6
- var SDK_VERSION = true ? "1.2.0" : "0.0.0-dev";
6
+ var SDK_VERSION = true ? "1.4.0" : "0.0.0-dev";
7
+
8
+ // src/index.ts
9
+ var _money = require('@usethrottle/money'); var money = _interopRequireWildcard(_money);
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+
7
22
 
8
23
  // src/errors/catalog-error.ts
9
24
  var _errors = require('@usethrottle/errors');
@@ -125,7 +140,6 @@ var SUGGEST_MIN_CHARS = 2;
125
140
  var INDEXING_REVALIDATE_MS = 3e4;
126
141
  var CACHE_TAG = "throttle-catalog";
127
142
  var TAG_MAX_CHARS = 256;
128
- var DEFAULT_REVALIDATE_S = 60;
129
143
  var LIST_PAGE_SIZE = 100;
130
144
  var LIST_MAX_HANDLES = 5e4;
131
145
  var CATEGORY_TREE_MAX_DEPTH = 10;
@@ -167,6 +181,8 @@ var ERROR_KINDS = Object.freeze({
167
181
  ALREADY_REVIEWED: "base",
168
182
  REVIEW_QUEUE_FULL: "rateLimited",
169
183
  REVIEW_VERIFICATION_UNAVAILABLE: "base",
184
+ PAGE_NOT_FOUND: "base",
185
+ PREVIEW_EXPIRED: "base",
170
186
  // Throttle cart-session codes.
171
187
  price_locked: "base",
172
188
  quantity_unavailable: "cartLine",
@@ -190,6 +206,8 @@ var ERROR_KINDS = Object.freeze({
190
206
  cart_session_not_found: "base",
191
207
  origin_not_allowed: "origin",
192
208
  checkout_unavailable: "base",
209
+ cart_owner_mismatch: "base",
210
+ cart_resolver_mismatch: "base",
193
211
  // Client codes.
194
212
  TIMEOUT: "timeout",
195
213
  NETWORK_ERROR: "network",
@@ -371,7 +389,8 @@ var RESERVED_HEADERS = /* @__PURE__ */ new Set([
371
389
  "x-customer-token",
372
390
  "if-none-match",
373
391
  "idempotency-key",
374
- "content-type"
392
+ "content-type",
393
+ "x-storefront-preview"
375
394
  ]);
376
395
  var MAX_TIMEOUT_MS = 2147483647;
377
396
  function optionError(code, message) {
@@ -422,6 +441,16 @@ function checkTimeout(timeoutMs) {
422
441
  }
423
442
  return Math.min(timeoutMs, MAX_TIMEOUT_MS);
424
443
  }
444
+ function checkPreviewToken(token) {
445
+ if (token === void 0 || token === "") return void 0;
446
+ if (typeof token !== "string" || !/^[\x21-\x7e]+$/u.test(token)) {
447
+ throw optionError(
448
+ "INVALID_REQUEST",
449
+ "previewToken must be a string of visible ASCII characters."
450
+ );
451
+ }
452
+ return token;
453
+ }
425
454
  function checkBaseUrl(baseUrl) {
426
455
  if (!isHttpUrl(baseUrl)) {
427
456
  throw optionError(
@@ -456,7 +485,8 @@ function resolveOptions(options) {
456
485
  cacheScope: options.cacheScope,
457
486
  indexingMaxWaitSeconds: retry === false ? null : _nullishCoalesce(_optionalChain([retry, 'optionalAccess', _14 => _14.maxWaitSeconds]), () => ( INDEXING_MAX_WAIT_S)),
458
487
  headers: checkHeaders(options.headers),
459
- keyInQuery: keyInQuery === true
488
+ keyInQuery: keyInQuery === true,
489
+ previewToken: checkPreviewToken(options.previewToken)
460
490
  };
461
491
  }
462
492
 
@@ -618,7 +648,8 @@ function createTransport(o) {
618
648
  }
619
649
  let cacheKey;
620
650
  let cached;
621
- const bypassCache = spec.tokenFree === true && keyInUrl;
651
+ const previewToken = spec.preview === true ? o.previewToken : void 0;
652
+ const bypassCache = spec.tokenFree === true && keyInUrl || previewToken !== void 0;
622
653
  if (isGet && !bypassCache && o.cache !== void 0 && spec.ifNoneMatch === void 0) {
623
654
  try {
624
655
  const scope = o.cacheScope === void 0 || spec.tokenFree === true ? "" : o.cacheScope();
@@ -636,6 +667,8 @@ function createTransport(o) {
636
667
  if (!keyInUrl) headers["x-catalog-key"] = o.publishableKey;
637
668
  if (!isGet) headers["content-type"] = "application/json";
638
669
  if (ifNoneMatch !== void 0) headers["if-none-match"] = ifNoneMatch;
670
+ if (previewToken !== void 0)
671
+ headers["x-storefront-preview"] = previewToken;
639
672
  if (spec.idempotencyKey !== void 0)
640
673
  headers["idempotency-key"] = spec.idempotencyKey;
641
674
  const body = isGet ? void 0 : JSON.stringify(_nullishCoalesce(spec.body, () => ( {})));
@@ -660,7 +693,7 @@ function createTransport(o) {
660
693
  method: spec.method,
661
694
  headers: token === null ? headers : { ...headers, "x-customer-token": token }
662
695
  };
663
- if (token !== null) {
696
+ if (token !== null || previewToken !== void 0) {
664
697
  delete init.next;
665
698
  init.cache = "no-store";
666
699
  } else if (call.next !== void 0) init.next = call.next;
@@ -731,6 +764,9 @@ function createTransport(o) {
731
764
  function createCartSession(options, sessionId, throttleBaseUrl) {
732
765
  const base = (_nullishCoalesce(throttleBaseUrl, () => ( THROTTLE_API_URL))).replace(/\/+$/u, "");
733
766
  async function call(method, tail, body, opts, accept) {
767
+ return (await exchange(method, tail, body, opts, accept)).data;
768
+ }
769
+ async function exchange(method, tail, body, opts, accept) {
734
770
  const signal = _optionalChain([opts, 'optionalAccess', _30 => _30.signal]);
735
771
  if (_optionalChain([signal, 'optionalAccess', _31 => _31.aborted])) throw signal.reason;
736
772
  const timeoutMs = _optionalChain([opts, 'optionalAccess', _32 => _32.timeoutMs]) === void 0 ? options.timeoutMs : checkTimeout(opts.timeoutMs);
@@ -768,7 +804,10 @@ function createCartSession(options, sessionId, throttleBaseUrl) {
768
804
  retryable: false
769
805
  });
770
806
  }
771
- return data;
807
+ return {
808
+ data,
809
+ meta: parsed.meta
810
+ };
772
811
  }
773
812
  throw toCatalogError(mapInput);
774
813
  }
@@ -811,6 +850,27 @@ function createCartSession(options, sessionId, throttleBaseUrl) {
811
850
  opts,
812
851
  (data) => isHttpUrl(data.checkoutUrl)
813
852
  );
853
+ },
854
+ absorb: async (fromSessionId, opts) => {
855
+ const { data, meta } = await exchange(
856
+ "POST",
857
+ () => "/absorb",
858
+ { fromSessionId },
859
+ opts
860
+ );
861
+ if (typeof data.cart !== "object" || data.cart === null)
862
+ throw new CatalogError({
863
+ code: "INVALID_RESPONSE",
864
+ message: "Throttle answered an absorb without a cart.",
865
+ statusCode: 200,
866
+ source: "throttle",
867
+ retryable: false
868
+ });
869
+ const warnings = _optionalChain([meta, 'optionalAccess', _36 => _36.warnings]);
870
+ return {
871
+ cart: data.cart,
872
+ warnings: Array.isArray(warnings) ? warnings : []
873
+ };
814
874
  }
815
875
  };
816
876
  }
@@ -839,7 +899,7 @@ function createCarts(transport, options) {
839
899
  // The input's own currency and locale win over the call's and the
840
900
  // client's; the return URLs are sent unchanged (P6-R2).
841
901
  create: async (input, opts) => {
842
- if (_optionalChain([opts, 'optionalAccess', _36 => _36.signal, 'optionalAccess', _37 => _37.aborted])) throw opts.signal.reason;
902
+ if (_optionalChain([opts, 'optionalAccess', _37 => _37.signal, 'optionalAccess', _38 => _38.aborted])) throw opts.signal.reason;
843
903
  for (const field of [
844
904
  "returnUrl",
845
905
  "cancelUrl",
@@ -862,17 +922,56 @@ function createCarts(transport, options) {
862
922
  customerToken: "optional",
863
923
  tokenFallback: "throw",
864
924
  featureRoute: true,
865
- ..._optionalChain([opts, 'optionalAccess', _38 => _38.idempotencyKey]) === void 0 ? {} : { idempotencyKey: opts.idempotencyKey }
925
+ ..._optionalChain([opts, 'optionalAccess', _39 => _39.idempotencyKey]) === void 0 ? {} : { idempotencyKey: opts.idempotencyKey }
866
926
  },
867
927
  opts
868
928
  );
869
929
  },
870
- session: (sessionId, opts) => createCartSession(options, sessionId, _optionalChain([opts, 'optionalAccess', _39 => _39.throttleBaseUrl]))
930
+ session: (sessionId, opts) => createCartSession(options, sessionId, _optionalChain([opts, 'optionalAccess', _40 => _40.throttleBaseUrl]))
871
931
  };
872
932
  }
873
933
 
874
- // src/core/products.ts
934
+ // src/core/pages.ts
875
935
  var SF = "/v1/storefront";
936
+ function createPages(transport) {
937
+ return {
938
+ list: (call) => read(
939
+ transport,
940
+ {
941
+ method: "GET",
942
+ path: `${SF}/pages`,
943
+ query: buildQuery({ minGeneration: _optionalChain([call, 'optionalAccess', _41 => _41.minGeneration]) }, [
944
+ "minGeneration"
945
+ ]),
946
+ customerToken: "none",
947
+ tokenFallback: "anonymous",
948
+ featureRoute: true,
949
+ context: "locale",
950
+ preview: true
951
+ },
952
+ call
953
+ ),
954
+ get: (handle, call) => read(
955
+ transport,
956
+ {
957
+ method: "GET",
958
+ path: `${SF}/pages/${pathSegment(handle)}`,
959
+ query: buildQuery({ minGeneration: _optionalChain([call, 'optionalAccess', _42 => _42.minGeneration]) }, [
960
+ "minGeneration"
961
+ ]),
962
+ customerToken: "none",
963
+ tokenFallback: "anonymous",
964
+ featureRoute: false,
965
+ context: "locale",
966
+ preview: true
967
+ },
968
+ call
969
+ )
970
+ };
971
+ }
972
+
973
+ // src/core/products.ts
974
+ var SF2 = "/v1/storefront";
876
975
  var LIST_ORDER = [
877
976
  "q",
878
977
  "category",
@@ -908,11 +1007,11 @@ function productsQuery(query = {}) {
908
1007
  featured: query.featured,
909
1008
  handles: query.handles,
910
1009
  skus: query.skus,
911
- year: _optionalChain([vehicle, 'optionalAccess', _40 => _40.year]),
912
- make: _optionalChain([vehicle, 'optionalAccess', _41 => _41.make]),
913
- model: _optionalChain([vehicle, 'optionalAccess', _42 => _42.model]),
914
- submodel: _optionalChain([vehicle, 'optionalAccess', _43 => _43.submodel]),
915
- engine: _optionalChain([vehicle, 'optionalAccess', _44 => _44.engine]),
1010
+ year: _optionalChain([vehicle, 'optionalAccess', _43 => _43.year]),
1011
+ make: _optionalChain([vehicle, 'optionalAccess', _44 => _44.make]),
1012
+ model: _optionalChain([vehicle, 'optionalAccess', _45 => _45.model]),
1013
+ submodel: _optionalChain([vehicle, 'optionalAccess', _46 => _46.submodel]),
1014
+ engine: _optionalChain([vehicle, 'optionalAccess', _47 => _47.engine]),
916
1015
  sort: query.sort,
917
1016
  limit: query.limit,
918
1017
  page: query.page,
@@ -934,7 +1033,7 @@ function createProducts(transport) {
934
1033
  transport,
935
1034
  {
936
1035
  method: "GET",
937
- path: `${SF}/products`,
1036
+ path: `${SF2}/products`,
938
1037
  query: productsQuery(query),
939
1038
  customerToken: "optional",
940
1039
  tokenFallback: "anonymous",
@@ -947,10 +1046,10 @@ function createProducts(transport) {
947
1046
  transport,
948
1047
  {
949
1048
  method: "GET",
950
- path: `${SF}/products/${pathSegment(handle)}`,
1049
+ path: `${SF2}/products/${pathSegment(handle)}`,
951
1050
  // Always the full product (P6-R18).
952
1051
  query: buildQuery(
953
- { fields: "full", include: commaList(_optionalChain([opts, 'optionalAccess', _45 => _45.include])) },
1052
+ { fields: "full", include: commaList(_optionalChain([opts, 'optionalAccess', _48 => _48.include])) },
954
1053
  ["fields", "include"]
955
1054
  ),
956
1055
  customerToken: "optional",
@@ -964,9 +1063,9 @@ function createProducts(transport) {
964
1063
  transport,
965
1064
  {
966
1065
  method: "GET",
967
- path: `${SF}/products/${pathSegment(handle)}/related`,
1066
+ path: `${SF2}/products/${pathSegment(handle)}/related`,
968
1067
  query: buildQuery(
969
- { limit: _optionalChain([opts, 'optionalAccess', _46 => _46.limit]), fields: commaList(_optionalChain([opts, 'optionalAccess', _47 => _47.fields])) },
1068
+ { limit: _optionalChain([opts, 'optionalAccess', _49 => _49.limit]), fields: commaList(_optionalChain([opts, 'optionalAccess', _50 => _50.fields])) },
970
1069
  ["limit", "fields"]
971
1070
  ),
972
1071
  customerToken: "optional",
@@ -984,7 +1083,7 @@ function createFilters(transport) {
984
1083
  transport,
985
1084
  {
986
1085
  method: "GET",
987
- path: `${SF}/filters/${pathSegment(key)}/values`,
1086
+ path: `${SF2}/filters/${pathSegment(key)}/values`,
988
1087
  query: productsQuery(query),
989
1088
  customerToken: "none",
990
1089
  tokenFallback: "anonymous",
@@ -1001,8 +1100,8 @@ function createSuggest(transport) {
1001
1100
  transport,
1002
1101
  {
1003
1102
  method: "GET",
1004
- path: `${SF}/suggest`,
1005
- query: buildQuery({ q, limit: _optionalChain([opts, 'optionalAccess', _48 => _48.limit]) }, ["q", "limit"]),
1103
+ path: `${SF2}/suggest`,
1104
+ query: buildQuery({ q, limit: _optionalChain([opts, 'optionalAccess', _51 => _51.limit]) }, ["q", "limit"]),
1006
1105
  // Never a customer token (P8-R22): list prices for everyone.
1007
1106
  customerToken: "none",
1008
1107
  tokenFree: true,
@@ -1027,10 +1126,10 @@ function createReviews(transport) {
1027
1126
  path: reviewsPath(handle),
1028
1127
  query: buildQuery(
1029
1128
  {
1030
- sort: _optionalChain([opts, 'optionalAccess', _49 => _49.sort]),
1031
- rating: _optionalChain([opts, 'optionalAccess', _50 => _50.rating]),
1032
- limit: _optionalChain([opts, 'optionalAccess', _51 => _51.limit]),
1033
- cursor: _optionalChain([opts, 'optionalAccess', _52 => _52.cursor])
1129
+ sort: _optionalChain([opts, 'optionalAccess', _52 => _52.sort]),
1130
+ rating: _optionalChain([opts, 'optionalAccess', _53 => _53.rating]),
1131
+ limit: _optionalChain([opts, 'optionalAccess', _54 => _54.limit]),
1132
+ cursor: _optionalChain([opts, 'optionalAccess', _55 => _55.cursor])
1034
1133
  },
1035
1134
  ["sort", "rating", "limit", "cursor"]
1036
1135
  ),
@@ -1062,23 +1161,192 @@ function createReviews(transport) {
1062
1161
  customerToken: "required",
1063
1162
  tokenFallback: "throw",
1064
1163
  featureRoute: false,
1065
- ..._optionalChain([opts, 'optionalAccess', _53 => _53.idempotencyKey]) === void 0 ? {} : { idempotencyKey: opts.idempotencyKey }
1164
+ ..._optionalChain([opts, 'optionalAccess', _56 => _56.idempotencyKey]) === void 0 ? {} : { idempotencyKey: opts.idempotencyKey }
1066
1165
  },
1067
1166
  opts
1068
1167
  )
1069
1168
  };
1070
1169
  }
1071
1170
 
1171
+ // src/core/settings.ts
1172
+ var DEFAULT_STRINGS = {
1173
+ "shop.title": "Shop",
1174
+ "shop.description": "Browse the full catalog.",
1175
+ "search.title": "Search",
1176
+ "search.placeholder": "Search products",
1177
+ "search.results": 'Results for "{q}"',
1178
+ "empty.search": "No results found. Try a different search.",
1179
+ "empty.listing": "No products match your filters.",
1180
+ "empty.category": "No products in this category yet.",
1181
+ "empty.collection": "No products in this collection yet.",
1182
+ "empty.cart": "Your cart is empty.",
1183
+ "cart.title": "Cart",
1184
+ "cart.checkout": "Checkout",
1185
+ "cart.continueShopping": "Continue shopping",
1186
+ "filters.title": "Filters",
1187
+ "filters.clearAll": "Clear all",
1188
+ "filters.apply": "Apply",
1189
+ "filters.showMore": "Show more",
1190
+ "filters.showLess": "Show less",
1191
+ "filters.priceMin": "Min",
1192
+ "filters.priceMax": "Max",
1193
+ "boolean.yes": "Yes",
1194
+ "boolean.no": "No",
1195
+ "sort.label": "Sort by",
1196
+ "listing.count": "{count} products",
1197
+ "listing.loadMore": "Load more",
1198
+ "listing.loading": "Loading\u2026",
1199
+ "listing.previous": "Previous",
1200
+ "listing.next": "Next",
1201
+ "product.addToCart": "Add to cart",
1202
+ "product.quantity": "Quantity",
1203
+ "product.selectOption": "Select {option}",
1204
+ "product.sku": "SKU",
1205
+ "product.description": "Description",
1206
+ "product.specs": "Specifications",
1207
+ "product.shipping": "Shipping",
1208
+ "product.tags": "Tags",
1209
+ "product.categories": "Categories",
1210
+ "product.related": "You may also like",
1211
+ "product.reviews": "Reviews",
1212
+ "product.noReviews": "No reviews yet.",
1213
+ "product.writeReview": "Write a review",
1214
+ "home.shopAll": "Shop all",
1215
+ "home.featured": "Featured",
1216
+ "home.newest": "New arrivals",
1217
+ "home.bestRated": "Best rated",
1218
+ "home.categories": "Shop by category",
1219
+ "footer.copyright": "\xA9 {year} {store}. All rights reserved.",
1220
+ "nav.menu": "Menu",
1221
+ "nav.account": "Account",
1222
+ "nav.cart": "Cart",
1223
+ "error.notFound": "Page not found",
1224
+ "error.generic": "Something went wrong. Please try again."
1225
+ };
1226
+ function t(settings, key, vars) {
1227
+ const text = _optionalChain([settings, 'optionalAccess', _57 => _57.strings, 'optionalAccess', _58 => _58[key]]) || DEFAULT_STRINGS[key];
1228
+ return vars === void 0 ? text : text.replace(
1229
+ /\{(\w+)\}/gu,
1230
+ (whole, name) => Object.hasOwn(vars, name) ? String(vars[name]) : whole
1231
+ );
1232
+ }
1233
+ function fill(pattern, name, value) {
1234
+ return pattern.split(`{${name}}`).join(encodeURIComponent(value));
1235
+ }
1236
+ var SAFE_HREF = /^(?:https?:\/\/[^\s]|\/(?![/\\]))/iu;
1237
+ var UNSAFE_CHARACTER2 = /[\u0000-\u0020\u007f\s]/u;
1238
+ function resolveMenuTarget(settings, target) {
1239
+ const { routes } = settings;
1240
+ const { kind, handle, q, href } = target;
1241
+ switch (kind) {
1242
+ case "product":
1243
+ case "category":
1244
+ case "collection":
1245
+ case "page":
1246
+ return handle === void 0 ? null : fill(routes[kind], "handle", handle);
1247
+ case "search":
1248
+ return q === void 0 ? null : fill(routes.search, "q", q);
1249
+ case "url":
1250
+ return href !== void 0 && !UNSAFE_CHARACTER2.test(href) && SAFE_HREF.test(href) ? href : null;
1251
+ default:
1252
+ return null;
1253
+ }
1254
+ }
1255
+ var SERIF = /* @__PURE__ */ new Set([
1256
+ "Instrument Serif",
1257
+ "Playfair Display",
1258
+ "Lora",
1259
+ "Merriweather",
1260
+ "Cormorant Garamond",
1261
+ "EB Garamond",
1262
+ "Libre Baskerville",
1263
+ "Source Serif 4",
1264
+ "Fraunces",
1265
+ "DM Serif Display"
1266
+ ]);
1267
+ var MONO = /* @__PURE__ */ new Set([
1268
+ "DM Mono",
1269
+ "JetBrains Mono",
1270
+ "IBM Plex Mono",
1271
+ "Space Mono"
1272
+ ]);
1273
+ var WEIGHTS_OF = {
1274
+ "Instrument Serif": [400],
1275
+ "DM Serif Display": [400],
1276
+ "Bebas Neue": [400],
1277
+ "Archivo Black": [400],
1278
+ Merriweather: [400, 700],
1279
+ "Libre Baskerville": [400, 700],
1280
+ Lato: [400, 700],
1281
+ "Space Mono": [400, 700],
1282
+ "DM Mono": [400, 500]
1283
+ };
1284
+ var STACKS = {
1285
+ sans: "system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif",
1286
+ serif: "Georgia, 'Times New Roman', serif",
1287
+ mono: "ui-monospace, SFMono-Regular, Menlo, Consolas, monospace"
1288
+ };
1289
+ function fontStylesheetHref(theme) {
1290
+ const families = /* @__PURE__ */ new Set();
1291
+ for (const family of [
1292
+ theme.fonts.heading,
1293
+ theme.fonts.body,
1294
+ theme.fonts.mono
1295
+ ])
1296
+ if (!family.startsWith("system-")) families.add(family);
1297
+ if (families.size === 0) return null;
1298
+ let href = "https://fonts.googleapis.com/css2?";
1299
+ for (const family of families) {
1300
+ const weights = _nullishCoalesce(WEIGHTS_OF[family], () => ( [400, 500, 600, 700]));
1301
+ href += `family=${family.replace(/ /gu, "+")}:wght@${weights.join(";")}&`;
1302
+ }
1303
+ return `${href}display=swap`;
1304
+ }
1305
+ function fontStack(family) {
1306
+ if (family.startsWith("system-"))
1307
+ return _nullishCoalesce(STACKS[family.slice(7)], () => ( STACKS.sans));
1308
+ const kind = SERIF.has(family) ? "serif" : MONO.has(family) ? "mono" : "sans";
1309
+ return `'${family}', ${STACKS[kind]}`;
1310
+ }
1311
+ function toAuthAppearance(theme, scheme) {
1312
+ const p = theme[scheme];
1313
+ return {
1314
+ theme: scheme,
1315
+ variables: {
1316
+ colorPrimary: p.colorPrimary,
1317
+ colorPrimaryForeground: p.colorPrimaryForeground,
1318
+ colorBackground: p.colorBackground,
1319
+ colorSurface: p.colorSurface,
1320
+ colorForeground: p.colorForeground,
1321
+ colorMuted: p.colorMuted,
1322
+ colorMutedForeground: p.colorMutedForeground,
1323
+ colorBorder: p.colorBorder,
1324
+ colorBorderControl: p.colorBorderControl,
1325
+ colorDanger: p.colorDanger,
1326
+ colorSuccess: p.colorSuccess,
1327
+ colorWarning: p.colorWarning,
1328
+ fontFamily: fontStack(theme.fonts.body),
1329
+ borderRadius: `${theme.radius}px`
1330
+ }
1331
+ };
1332
+ }
1333
+ function createSettings(config) {
1334
+ return async (call) => {
1335
+ const { settings, settingsVersion, generation } = await config(call);
1336
+ return { settings, settingsVersion, generation };
1337
+ };
1338
+ }
1339
+
1072
1340
  // src/core/taxonomy.ts
1073
- var SF2 = "/v1/storefront";
1341
+ var SF3 = "/v1/storefront";
1074
1342
  function createCategories(transport) {
1075
1343
  return {
1076
1344
  tree: (opts) => read(
1077
1345
  transport,
1078
1346
  {
1079
1347
  method: "GET",
1080
- path: `${SF2}/categories`,
1081
- query: buildQuery({ depth: _optionalChain([opts, 'optionalAccess', _54 => _54.depth]) }, ["depth"]),
1348
+ path: `${SF3}/categories`,
1349
+ query: buildQuery({ depth: _optionalChain([opts, 'optionalAccess', _59 => _59.depth]) }, ["depth"]),
1082
1350
  customerToken: "none",
1083
1351
  tokenFallback: "anonymous",
1084
1352
  featureRoute: true,
@@ -1090,7 +1358,7 @@ function createCategories(transport) {
1090
1358
  transport,
1091
1359
  {
1092
1360
  method: "GET",
1093
- path: `${SF2}/categories/${pathSegment(handle)}`,
1361
+ path: `${SF3}/categories/${pathSegment(handle)}`,
1094
1362
  customerToken: "none",
1095
1363
  tokenFallback: "anonymous",
1096
1364
  featureRoute: false,
@@ -1106,8 +1374,8 @@ function createTags(transport) {
1106
1374
  transport,
1107
1375
  {
1108
1376
  method: "GET",
1109
- path: `${SF2}/tags`,
1110
- query: buildQuery({ q: _optionalChain([opts, 'optionalAccess', _55 => _55.q]), limit: _optionalChain([opts, 'optionalAccess', _56 => _56.limit]) }, ["q", "limit"]),
1377
+ path: `${SF3}/tags`,
1378
+ query: buildQuery({ q: _optionalChain([opts, 'optionalAccess', _60 => _60.q]), limit: _optionalChain([opts, 'optionalAccess', _61 => _61.limit]) }, ["q", "limit"]),
1111
1379
  customerToken: "none",
1112
1380
  tokenFallback: "anonymous",
1113
1381
  featureRoute: true
@@ -1122,8 +1390,8 @@ function createCollections(transport) {
1122
1390
  transport,
1123
1391
  {
1124
1392
  method: "GET",
1125
- path: `${SF2}/collections`,
1126
- query: buildQuery({ limit: _optionalChain([opts, 'optionalAccess', _57 => _57.limit]), cursor: _optionalChain([opts, 'optionalAccess', _58 => _58.cursor]) }, [
1393
+ path: `${SF3}/collections`,
1394
+ query: buildQuery({ limit: _optionalChain([opts, 'optionalAccess', _62 => _62.limit]), cursor: _optionalChain([opts, 'optionalAccess', _63 => _63.cursor]) }, [
1127
1395
  "limit",
1128
1396
  "cursor"
1129
1397
  ]),
@@ -1138,7 +1406,7 @@ function createCollections(transport) {
1138
1406
  transport,
1139
1407
  {
1140
1408
  method: "GET",
1141
- path: `${SF2}/collections/${pathSegment(handle)}`,
1409
+ path: `${SF3}/collections/${pathSegment(handle)}`,
1142
1410
  customerToken: "none",
1143
1411
  tokenFallback: "anonymous",
1144
1412
  featureRoute: false,
@@ -1153,10 +1421,15 @@ function createConfig(transport) {
1153
1421
  transport,
1154
1422
  {
1155
1423
  method: "GET",
1156
- path: `${SF2}/config`,
1424
+ path: `${SF3}/config`,
1425
+ query: buildQuery({ minGeneration: _optionalChain([call, 'optionalAccess', _64 => _64.minGeneration]) }, [
1426
+ "minGeneration"
1427
+ ]),
1157
1428
  customerToken: "none",
1158
1429
  tokenFallback: "anonymous",
1159
- featureRoute: true
1430
+ featureRoute: true,
1431
+ context: "locale",
1432
+ preview: true
1160
1433
  },
1161
1434
  call
1162
1435
  );
@@ -1169,6 +1442,7 @@ var TRANSPORT = Symbol.for(
1169
1442
  function createCatalogClient(options) {
1170
1443
  const resolved = resolveOptions(options);
1171
1444
  const transport = createTransport(resolved);
1445
+ const config = createConfig(transport);
1172
1446
  return {
1173
1447
  [TRANSPORT]: transport,
1174
1448
  products: createProducts(transport),
@@ -1177,7 +1451,9 @@ function createCatalogClient(options) {
1177
1451
  tags: createTags(transport),
1178
1452
  collections: createCollections(transport),
1179
1453
  suggest: createSuggest(transport),
1180
- config: createConfig(transport),
1454
+ config,
1455
+ settings: createSettings(config),
1456
+ pages: createPages(transport),
1181
1457
  reviews: createReviews(transport),
1182
1458
  carts: createCarts(transport, resolved)
1183
1459
  };
@@ -1209,4 +1485,19 @@ function createCatalogClient(options) {
1209
1485
 
1210
1486
 
1211
1487
 
1212
- exports.SDK_VERSION = SDK_VERSION; exports.CatalogError = CatalogError; exports.RateLimitedError = RateLimitedError; exports.OriginNotAllowedError = OriginNotAllowedError; exports.CustomerTokenInvalidError = CustomerTokenInvalidError; exports.CartLineError = CartLineError; exports.TimeoutError = TimeoutError; exports.NetworkError = NetworkError; exports.FeatureUnavailableError = FeatureUnavailableError; exports.isCatalogError = isCatalogError; exports.DEFAULT_BASE_URL = DEFAULT_BASE_URL; exports.THROTTLE_CHECKOUT_URL = THROTTLE_CHECKOUT_URL; exports.RATE_LIMIT_DEFAULT_RETRY_S = RATE_LIMIT_DEFAULT_RETRY_S; exports.STALE_MS = STALE_MS; exports.CACHE_MAX_ENTRIES = CACHE_MAX_ENTRIES; exports.SUGGEST_DEBOUNCE_MS = SUGGEST_DEBOUNCE_MS; exports.SUGGEST_MIN_CHARS = SUGGEST_MIN_CHARS; exports.INDEXING_REVALIDATE_MS = INDEXING_REVALIDATE_MS; exports.CACHE_TAG = CACHE_TAG; exports.TAG_MAX_CHARS = TAG_MAX_CHARS; exports.DEFAULT_REVALIDATE_S = DEFAULT_REVALIDATE_S; exports.LIST_PAGE_SIZE = LIST_PAGE_SIZE; exports.LIST_MAX_HANDLES = LIST_MAX_HANDLES; exports.CATEGORY_TREE_MAX_DEPTH = CATEGORY_TREE_MAX_DEPTH; exports.createCatalogClient = createCatalogClient;
1488
+
1489
+
1490
+
1491
+
1492
+
1493
+
1494
+
1495
+
1496
+
1497
+
1498
+
1499
+
1500
+
1501
+
1502
+
1503
+ exports.SDK_VERSION = SDK_VERSION; exports.CatalogError = CatalogError; exports.RateLimitedError = RateLimitedError; exports.OriginNotAllowedError = OriginNotAllowedError; exports.CustomerTokenInvalidError = CustomerTokenInvalidError; exports.CartLineError = CartLineError; exports.TimeoutError = TimeoutError; exports.NetworkError = NetworkError; exports.FeatureUnavailableError = FeatureUnavailableError; exports.isCatalogError = isCatalogError; exports.DEFAULT_BASE_URL = DEFAULT_BASE_URL; exports.THROTTLE_CHECKOUT_URL = THROTTLE_CHECKOUT_URL; exports.RATE_LIMIT_DEFAULT_RETRY_S = RATE_LIMIT_DEFAULT_RETRY_S; exports.STALE_MS = STALE_MS; exports.CACHE_MAX_ENTRIES = CACHE_MAX_ENTRIES; exports.SUGGEST_DEBOUNCE_MS = SUGGEST_DEBOUNCE_MS; exports.SUGGEST_MIN_CHARS = SUGGEST_MIN_CHARS; exports.INDEXING_REVALIDATE_MS = INDEXING_REVALIDATE_MS; exports.CACHE_TAG = CACHE_TAG; exports.TAG_MAX_CHARS = TAG_MAX_CHARS; exports.LIST_PAGE_SIZE = LIST_PAGE_SIZE; exports.LIST_MAX_HANDLES = LIST_MAX_HANDLES; exports.CATEGORY_TREE_MAX_DEPTH = CATEGORY_TREE_MAX_DEPTH; exports.DEFAULT_STRINGS = DEFAULT_STRINGS; exports.t = t; exports.resolveMenuTarget = resolveMenuTarget; exports.fontStylesheetHref = fontStylesheetHref; exports.toAuthAppearance = toAuthAppearance; exports.createCatalogClient = createCatalogClient; exports.money = money; exports.CURRENCIES = _money.CURRENCIES; exports.UnknownCurrencyError = _money.UnknownCurrencyError; exports.currencySymbol = _money.currencySymbol; exports.formatMoney = _money.formatMoney; exports.isKnownCurrency = _money.isKnownCurrency; exports.minorUnitsOf = _money.minorUnitsOf; exports.moneyValue = _money.moneyValue; exports.parseMoney = _money.parseMoney; exports.toDecimalString = _money.toDecimalString; exports.toMinor = _money.toMinor;