@usethrottle/catalog 1.3.0 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/README.md +105 -9
- package/dist/admin.cjs +16 -16
- package/dist/admin.d.cts +14 -2
- package/dist/admin.d.ts +14 -2
- package/dist/admin.js +1 -1
- package/dist/{catalog-error-BOaSKgY3.d.cts → catalog-error-bG1XHquN.d.cts} +1 -1
- package/dist/{catalog-error-CSoPS0-d.d.ts → catalog-error-c3BVgU6k.d.ts} +1 -1
- package/dist/{chunk-2YQNMBDI.cjs → chunk-2ODFFMZ4.cjs} +274 -38
- package/dist/chunk-5AJS3CX5.cjs +192 -0
- package/dist/{chunk-CADIHOIR.js → chunk-6K7H7HBD.js} +89 -2
- package/dist/chunk-P3ABGAF5.js +192 -0
- package/dist/{chunk-3DLH56OX.js → chunk-STNQNHNZ.js} +258 -22
- package/dist/{chunk-GU63WFXI.cjs → chunk-VOOX3WJY.cjs} +102 -15
- package/dist/{client-6j1Iz-iJ.d.cts → client-CGGlbacq.d.cts} +1 -1
- package/dist/{client-B3mL2-xJ.d.ts → client-CNsVr2lR.d.ts} +1 -1
- package/dist/{contract-types-BRyonOYH.d.cts → contract-types-BJMeJSTz.d.cts} +269 -2
- package/dist/{contract-types-BRyonOYH.d.ts → contract-types-BJMeJSTz.d.ts} +269 -2
- package/dist/index.cjs +12 -2
- package/dist/index.d.cts +53 -7
- package/dist/index.d.ts +53 -7
- package/dist/index.js +11 -1
- package/dist/next.cjs +180 -0
- package/dist/next.d.cts +60 -0
- package/dist/next.d.ts +60 -0
- package/dist/next.js +180 -0
- package/dist/react-extras.cjs +27 -9
- package/dist/react-extras.d.cts +6 -4
- package/dist/react-extras.d.ts +6 -4
- package/dist/react-extras.js +20 -2
- package/dist/react.cjs +18 -14
- package/dist/react.d.cts +22 -5
- package/dist/react.d.ts +22 -5
- package/dist/react.js +6 -2
- package/dist/server.cjs +58 -66
- package/dist/server.d.cts +57 -10
- package/dist/server.d.ts +57 -10
- package/dist/server.js +52 -60
- package/dist/{types-D0PywKnN.d.cts → types-BtBxMbM5.d.cts} +40 -3
- package/dist/{types-BfveENg1.d.ts → types-dKvIfrVH.d.ts} +40 -3
- package/dist/url.d.cts +1 -1
- package/dist/url.d.ts +1 -1
- package/dist/{use-query-UWf6Pi5g.d.cts → use-query-C2rfTJd4.d.cts} +1 -1
- package/dist/{use-query-CR7r5tam.d.ts → use-query-DeCj1hXt.d.ts} +1 -1
- package/package.json +16 -2
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-PKBMQBKP.js";
|
|
4
4
|
|
|
5
5
|
// src/version.ts
|
|
6
|
-
var SDK_VERSION = true ? "1.
|
|
6
|
+
var SDK_VERSION = true ? "1.4.1" : "0.0.0-dev";
|
|
7
7
|
|
|
8
8
|
// src/index.ts
|
|
9
9
|
import * as money from "@usethrottle/money";
|
|
@@ -140,7 +140,6 @@ var SUGGEST_MIN_CHARS = 2;
|
|
|
140
140
|
var INDEXING_REVALIDATE_MS = 3e4;
|
|
141
141
|
var CACHE_TAG = "throttle-catalog";
|
|
142
142
|
var TAG_MAX_CHARS = 256;
|
|
143
|
-
var DEFAULT_REVALIDATE_S = 60;
|
|
144
143
|
var LIST_PAGE_SIZE = 100;
|
|
145
144
|
var LIST_MAX_HANDLES = 5e4;
|
|
146
145
|
var CATEGORY_TREE_MAX_DEPTH = 10;
|
|
@@ -182,6 +181,8 @@ var ERROR_KINDS = Object.freeze({
|
|
|
182
181
|
ALREADY_REVIEWED: "base",
|
|
183
182
|
REVIEW_QUEUE_FULL: "rateLimited",
|
|
184
183
|
REVIEW_VERIFICATION_UNAVAILABLE: "base",
|
|
184
|
+
PAGE_NOT_FOUND: "base",
|
|
185
|
+
PREVIEW_EXPIRED: "base",
|
|
185
186
|
// Throttle cart-session codes.
|
|
186
187
|
price_locked: "base",
|
|
187
188
|
quantity_unavailable: "cartLine",
|
|
@@ -388,7 +389,8 @@ var RESERVED_HEADERS = /* @__PURE__ */ new Set([
|
|
|
388
389
|
"x-customer-token",
|
|
389
390
|
"if-none-match",
|
|
390
391
|
"idempotency-key",
|
|
391
|
-
"content-type"
|
|
392
|
+
"content-type",
|
|
393
|
+
"x-storefront-preview"
|
|
392
394
|
]);
|
|
393
395
|
var MAX_TIMEOUT_MS = 2147483647;
|
|
394
396
|
function optionError(code, message) {
|
|
@@ -439,6 +441,16 @@ function checkTimeout(timeoutMs) {
|
|
|
439
441
|
}
|
|
440
442
|
return Math.min(timeoutMs, MAX_TIMEOUT_MS);
|
|
441
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
|
+
}
|
|
442
454
|
function checkBaseUrl(baseUrl) {
|
|
443
455
|
if (!isHttpUrl(baseUrl)) {
|
|
444
456
|
throw optionError(
|
|
@@ -473,7 +485,8 @@ function resolveOptions(options) {
|
|
|
473
485
|
cacheScope: options.cacheScope,
|
|
474
486
|
indexingMaxWaitSeconds: retry === false ? null : retry?.maxWaitSeconds ?? INDEXING_MAX_WAIT_S,
|
|
475
487
|
headers: checkHeaders(options.headers),
|
|
476
|
-
keyInQuery: keyInQuery === true
|
|
488
|
+
keyInQuery: keyInQuery === true,
|
|
489
|
+
previewToken: checkPreviewToken(options.previewToken)
|
|
477
490
|
};
|
|
478
491
|
}
|
|
479
492
|
|
|
@@ -635,7 +648,8 @@ function createTransport(o) {
|
|
|
635
648
|
}
|
|
636
649
|
let cacheKey;
|
|
637
650
|
let cached;
|
|
638
|
-
const
|
|
651
|
+
const previewToken = spec.preview === true ? o.previewToken : void 0;
|
|
652
|
+
const bypassCache = spec.tokenFree === true && keyInUrl || previewToken !== void 0;
|
|
639
653
|
if (isGet && !bypassCache && o.cache !== void 0 && spec.ifNoneMatch === void 0) {
|
|
640
654
|
try {
|
|
641
655
|
const scope = o.cacheScope === void 0 || spec.tokenFree === true ? "" : o.cacheScope();
|
|
@@ -653,6 +667,8 @@ function createTransport(o) {
|
|
|
653
667
|
if (!keyInUrl) headers["x-catalog-key"] = o.publishableKey;
|
|
654
668
|
if (!isGet) headers["content-type"] = "application/json";
|
|
655
669
|
if (ifNoneMatch !== void 0) headers["if-none-match"] = ifNoneMatch;
|
|
670
|
+
if (previewToken !== void 0)
|
|
671
|
+
headers["x-storefront-preview"] = previewToken;
|
|
656
672
|
if (spec.idempotencyKey !== void 0)
|
|
657
673
|
headers["idempotency-key"] = spec.idempotencyKey;
|
|
658
674
|
const body = isGet ? void 0 : JSON.stringify(spec.body ?? {});
|
|
@@ -677,7 +693,7 @@ function createTransport(o) {
|
|
|
677
693
|
method: spec.method,
|
|
678
694
|
headers: token === null ? headers : { ...headers, "x-customer-token": token }
|
|
679
695
|
};
|
|
680
|
-
if (token !== null) {
|
|
696
|
+
if (token !== null || previewToken !== void 0) {
|
|
681
697
|
delete init.next;
|
|
682
698
|
init.cache = "no-store";
|
|
683
699
|
} else if (call.next !== void 0) init.next = call.next;
|
|
@@ -915,8 +931,47 @@ function createCarts(transport, options) {
|
|
|
915
931
|
};
|
|
916
932
|
}
|
|
917
933
|
|
|
918
|
-
// src/core/
|
|
934
|
+
// src/core/pages.ts
|
|
919
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: call?.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: call?.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";
|
|
920
975
|
var LIST_ORDER = [
|
|
921
976
|
"q",
|
|
922
977
|
"category",
|
|
@@ -978,7 +1033,7 @@ function createProducts(transport) {
|
|
|
978
1033
|
transport,
|
|
979
1034
|
{
|
|
980
1035
|
method: "GET",
|
|
981
|
-
path: `${
|
|
1036
|
+
path: `${SF2}/products`,
|
|
982
1037
|
query: productsQuery(query),
|
|
983
1038
|
customerToken: "optional",
|
|
984
1039
|
tokenFallback: "anonymous",
|
|
@@ -991,7 +1046,7 @@ function createProducts(transport) {
|
|
|
991
1046
|
transport,
|
|
992
1047
|
{
|
|
993
1048
|
method: "GET",
|
|
994
|
-
path: `${
|
|
1049
|
+
path: `${SF2}/products/${pathSegment(handle)}`,
|
|
995
1050
|
// Always the full product (P6-R18).
|
|
996
1051
|
query: buildQuery(
|
|
997
1052
|
{ fields: "full", include: commaList(opts?.include) },
|
|
@@ -1008,7 +1063,7 @@ function createProducts(transport) {
|
|
|
1008
1063
|
transport,
|
|
1009
1064
|
{
|
|
1010
1065
|
method: "GET",
|
|
1011
|
-
path: `${
|
|
1066
|
+
path: `${SF2}/products/${pathSegment(handle)}/related`,
|
|
1012
1067
|
query: buildQuery(
|
|
1013
1068
|
{ limit: opts?.limit, fields: commaList(opts?.fields) },
|
|
1014
1069
|
["limit", "fields"]
|
|
@@ -1028,7 +1083,7 @@ function createFilters(transport) {
|
|
|
1028
1083
|
transport,
|
|
1029
1084
|
{
|
|
1030
1085
|
method: "GET",
|
|
1031
|
-
path: `${
|
|
1086
|
+
path: `${SF2}/filters/${pathSegment(key)}/values`,
|
|
1032
1087
|
query: productsQuery(query),
|
|
1033
1088
|
customerToken: "none",
|
|
1034
1089
|
tokenFallback: "anonymous",
|
|
@@ -1045,7 +1100,7 @@ function createSuggest(transport) {
|
|
|
1045
1100
|
transport,
|
|
1046
1101
|
{
|
|
1047
1102
|
method: "GET",
|
|
1048
|
-
path: `${
|
|
1103
|
+
path: `${SF2}/suggest`,
|
|
1049
1104
|
query: buildQuery({ q, limit: opts?.limit }, ["q", "limit"]),
|
|
1050
1105
|
// Never a customer token (P8-R22): list prices for everyone.
|
|
1051
1106
|
customerToken: "none",
|
|
@@ -1113,15 +1168,184 @@ function createReviews(transport) {
|
|
|
1113
1168
|
};
|
|
1114
1169
|
}
|
|
1115
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 = settings?.strings?.[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 = 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 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
|
+
|
|
1116
1340
|
// src/core/taxonomy.ts
|
|
1117
|
-
var
|
|
1341
|
+
var SF3 = "/v1/storefront";
|
|
1118
1342
|
function createCategories(transport) {
|
|
1119
1343
|
return {
|
|
1120
1344
|
tree: (opts) => read(
|
|
1121
1345
|
transport,
|
|
1122
1346
|
{
|
|
1123
1347
|
method: "GET",
|
|
1124
|
-
path: `${
|
|
1348
|
+
path: `${SF3}/categories`,
|
|
1125
1349
|
query: buildQuery({ depth: opts?.depth }, ["depth"]),
|
|
1126
1350
|
customerToken: "none",
|
|
1127
1351
|
tokenFallback: "anonymous",
|
|
@@ -1134,7 +1358,7 @@ function createCategories(transport) {
|
|
|
1134
1358
|
transport,
|
|
1135
1359
|
{
|
|
1136
1360
|
method: "GET",
|
|
1137
|
-
path: `${
|
|
1361
|
+
path: `${SF3}/categories/${pathSegment(handle)}`,
|
|
1138
1362
|
customerToken: "none",
|
|
1139
1363
|
tokenFallback: "anonymous",
|
|
1140
1364
|
featureRoute: false,
|
|
@@ -1150,7 +1374,7 @@ function createTags(transport) {
|
|
|
1150
1374
|
transport,
|
|
1151
1375
|
{
|
|
1152
1376
|
method: "GET",
|
|
1153
|
-
path: `${
|
|
1377
|
+
path: `${SF3}/tags`,
|
|
1154
1378
|
query: buildQuery({ q: opts?.q, limit: opts?.limit }, ["q", "limit"]),
|
|
1155
1379
|
customerToken: "none",
|
|
1156
1380
|
tokenFallback: "anonymous",
|
|
@@ -1166,7 +1390,7 @@ function createCollections(transport) {
|
|
|
1166
1390
|
transport,
|
|
1167
1391
|
{
|
|
1168
1392
|
method: "GET",
|
|
1169
|
-
path: `${
|
|
1393
|
+
path: `${SF3}/collections`,
|
|
1170
1394
|
query: buildQuery({ limit: opts?.limit, cursor: opts?.cursor }, [
|
|
1171
1395
|
"limit",
|
|
1172
1396
|
"cursor"
|
|
@@ -1182,7 +1406,7 @@ function createCollections(transport) {
|
|
|
1182
1406
|
transport,
|
|
1183
1407
|
{
|
|
1184
1408
|
method: "GET",
|
|
1185
|
-
path: `${
|
|
1409
|
+
path: `${SF3}/collections/${pathSegment(handle)}`,
|
|
1186
1410
|
customerToken: "none",
|
|
1187
1411
|
tokenFallback: "anonymous",
|
|
1188
1412
|
featureRoute: false,
|
|
@@ -1197,10 +1421,15 @@ function createConfig(transport) {
|
|
|
1197
1421
|
transport,
|
|
1198
1422
|
{
|
|
1199
1423
|
method: "GET",
|
|
1200
|
-
path: `${
|
|
1424
|
+
path: `${SF3}/config`,
|
|
1425
|
+
query: buildQuery({ minGeneration: call?.minGeneration }, [
|
|
1426
|
+
"minGeneration"
|
|
1427
|
+
]),
|
|
1201
1428
|
customerToken: "none",
|
|
1202
1429
|
tokenFallback: "anonymous",
|
|
1203
|
-
featureRoute: true
|
|
1430
|
+
featureRoute: true,
|
|
1431
|
+
context: "locale",
|
|
1432
|
+
preview: true
|
|
1204
1433
|
},
|
|
1205
1434
|
call
|
|
1206
1435
|
);
|
|
@@ -1213,6 +1442,7 @@ var TRANSPORT = Symbol.for(
|
|
|
1213
1442
|
function createCatalogClient(options) {
|
|
1214
1443
|
const resolved = resolveOptions(options);
|
|
1215
1444
|
const transport = createTransport(resolved);
|
|
1445
|
+
const config = createConfig(transport);
|
|
1216
1446
|
return {
|
|
1217
1447
|
[TRANSPORT]: transport,
|
|
1218
1448
|
products: createProducts(transport),
|
|
@@ -1221,7 +1451,9 @@ function createCatalogClient(options) {
|
|
|
1221
1451
|
tags: createTags(transport),
|
|
1222
1452
|
collections: createCollections(transport),
|
|
1223
1453
|
suggest: createSuggest(transport),
|
|
1224
|
-
config
|
|
1454
|
+
config,
|
|
1455
|
+
settings: createSettings(config),
|
|
1456
|
+
pages: createPages(transport),
|
|
1225
1457
|
reviews: createReviews(transport),
|
|
1226
1458
|
carts: createCarts(transport, resolved)
|
|
1227
1459
|
};
|
|
@@ -1248,10 +1480,14 @@ export {
|
|
|
1248
1480
|
INDEXING_REVALIDATE_MS,
|
|
1249
1481
|
CACHE_TAG,
|
|
1250
1482
|
TAG_MAX_CHARS,
|
|
1251
|
-
DEFAULT_REVALIDATE_S,
|
|
1252
1483
|
LIST_PAGE_SIZE,
|
|
1253
1484
|
LIST_MAX_HANDLES,
|
|
1254
1485
|
CATEGORY_TREE_MAX_DEPTH,
|
|
1486
|
+
DEFAULT_STRINGS,
|
|
1487
|
+
t,
|
|
1488
|
+
resolveMenuTarget,
|
|
1489
|
+
fontStylesheetHref,
|
|
1490
|
+
toAuthAppearance,
|
|
1255
1491
|
createCatalogClient,
|
|
1256
1492
|
money,
|
|
1257
1493
|
CURRENCIES,
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
var
|
|
9
|
+
var _chunk2ODFFMZ4cjs = require('./chunk-2ODFFMZ4.cjs');
|
|
10
10
|
|
|
11
11
|
// src/react/provider.tsx
|
|
12
12
|
|
|
@@ -32,7 +32,7 @@ function createStore(client, options = {}) {
|
|
|
32
32
|
let until = 0;
|
|
33
33
|
let cause;
|
|
34
34
|
let pauseTimer;
|
|
35
|
-
const pausedError = () => new (0,
|
|
35
|
+
const pausedError = () => new (0, _chunk2ODFFMZ4cjs.RateLimitedError)({
|
|
36
36
|
code: _nullishCoalesce(_optionalChain([cause, 'optionalAccess', _ => _.code]), () => ( "RATE_LIMITED")),
|
|
37
37
|
message: _nullishCoalesce(_optionalChain([cause, 'optionalAccess', _2 => _2.message]), () => ( "Too many requests.")),
|
|
38
38
|
statusCode: 429,
|
|
@@ -54,7 +54,7 @@ function createStore(client, options = {}) {
|
|
|
54
54
|
retries: 0
|
|
55
55
|
};
|
|
56
56
|
for (const [oldKey, old] of entries) {
|
|
57
|
-
if (entries.size <
|
|
57
|
+
if (entries.size < _chunk2ODFFMZ4cjs.CACHE_MAX_ENTRIES) break;
|
|
58
58
|
if (old.subs.size === 0 && old.flight === void 0) {
|
|
59
59
|
clearTimeout(old.timer);
|
|
60
60
|
entries.delete(oldKey);
|
|
@@ -73,7 +73,7 @@ function createStore(client, options = {}) {
|
|
|
73
73
|
else entry.indexing = false;
|
|
74
74
|
}, ms);
|
|
75
75
|
};
|
|
76
|
-
function fetchKey(key, run, { force = false, staleMs =
|
|
76
|
+
function fetchKey(key, run, { force = false, staleMs = _chunk2ODFFMZ4cjs.STALE_MS } = {}) {
|
|
77
77
|
const entry = touch(key);
|
|
78
78
|
entry.run = run;
|
|
79
79
|
if (entry.promise !== void 0 && !_optionalChain([entry, 'access', _4 => _4.flight, 'optionalAccess', _5 => _5.signal, 'access', _6 => _6.aborted]))
|
|
@@ -125,7 +125,7 @@ function createStore(client, options = {}) {
|
|
|
125
125
|
return;
|
|
126
126
|
}
|
|
127
127
|
if (_optionalChain([result, 'access', _7 => _7.data, 'optionalAccess', _8 => _8.indexing]) === true) {
|
|
128
|
-
if (!entry.indexing) later(key, entry,
|
|
128
|
+
if (!entry.indexing) later(key, entry, _chunk2ODFFMZ4cjs.INDEXING_REVALIDATE_MS);
|
|
129
129
|
} else {
|
|
130
130
|
entry.indexing = false;
|
|
131
131
|
}
|
|
@@ -138,7 +138,7 @@ function createStore(client, options = {}) {
|
|
|
138
138
|
},
|
|
139
139
|
(error) => {
|
|
140
140
|
if (!current()) return;
|
|
141
|
-
const retryMs = (_nullishCoalesce(error.retryAfterSeconds, () => (
|
|
141
|
+
const retryMs = (_nullishCoalesce(error.retryAfterSeconds, () => ( _chunk2ODFFMZ4cjs.RATE_LIMIT_DEFAULT_RETRY_S))) * 1e3;
|
|
142
142
|
if (error.statusCode === 429 && error.code === "RATE_LIMITED")
|
|
143
143
|
pause(now() + retryMs, error);
|
|
144
144
|
else if (error.code === "STOREFRONT_INDEXING") {
|
|
@@ -183,6 +183,21 @@ function createStore(client, options = {}) {
|
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
185
|
}
|
|
186
|
+
function invalidate() {
|
|
187
|
+
for (const [key, entry] of [...entries]) {
|
|
188
|
+
clearTimeout(entry.timer);
|
|
189
|
+
clearTimeout(entry.retry);
|
|
190
|
+
_optionalChain([entry, 'access', _12 => _12.flight, 'optionalAccess', _13 => _13.abort, 'call', _14 => _14()]);
|
|
191
|
+
if (entry.subs.size === 0) {
|
|
192
|
+
entries.delete(key);
|
|
193
|
+
} else {
|
|
194
|
+
entry.etag = entry.flight = entry.promise = void 0;
|
|
195
|
+
entry.indexing = false;
|
|
196
|
+
entry.retries = 0;
|
|
197
|
+
if (entry.run) void fetchKey(key, entry.run, { force: true });
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
186
201
|
return {
|
|
187
202
|
subscribe(key, listener) {
|
|
188
203
|
const entry = touch(key);
|
|
@@ -190,11 +205,11 @@ function createStore(client, options = {}) {
|
|
|
190
205
|
return () => {
|
|
191
206
|
entry.subs.delete(listener);
|
|
192
207
|
void done.then(() => {
|
|
193
|
-
if (entry.subs.size === 0) _optionalChain([entry, 'access',
|
|
208
|
+
if (entry.subs.size === 0) _optionalChain([entry, 'access', _15 => _15.flight, 'optionalAccess', _16 => _16.abort, 'call', _17 => _17()]);
|
|
194
209
|
});
|
|
195
210
|
};
|
|
196
211
|
},
|
|
197
|
-
get: (key, initial, stale) => key === null ? EMPTY : _nullishCoalesce(_optionalChain([(_nullishCoalesce(entries.get(key), () => ( (initial === void 0 ? void 0 : touch(key, initial, stale))))), 'optionalAccess',
|
|
212
|
+
get: (key, initial, stale) => key === null ? EMPTY : _nullishCoalesce(_optionalChain([(_nullishCoalesce(entries.get(key), () => ( (initial === void 0 ? void 0 : touch(key, initial, stale))))), 'optionalAccess', _18 => _18.snap]), () => ( EMPTY)),
|
|
198
213
|
getServer(key, initial, stale) {
|
|
199
214
|
if (key === null || initial === void 0) return EMPTY;
|
|
200
215
|
const entry = _nullishCoalesce(entries.get(key), () => ( touch(key, initial, stale)));
|
|
@@ -202,6 +217,7 @@ function createStore(client, options = {}) {
|
|
|
202
217
|
},
|
|
203
218
|
fetch: fetchKey,
|
|
204
219
|
clear,
|
|
220
|
+
invalidate,
|
|
205
221
|
pause,
|
|
206
222
|
pausedUntil: () => until > now() ? until : 0,
|
|
207
223
|
dispose() {
|
|
@@ -249,7 +265,7 @@ function CatalogProvider(props) {
|
|
|
249
265
|
const mounted = _react.useRef.call(void 0, null);
|
|
250
266
|
const store = _react.useMemo.call(void 0, () => {
|
|
251
267
|
const next = createStore(client);
|
|
252
|
-
next.pause(_nullishCoalesce(_optionalChain([mounted, 'access',
|
|
268
|
+
next.pause(_nullishCoalesce(_optionalChain([mounted, 'access', _19 => _19.current, 'optionalAccess', _20 => _20.pausedUntil, 'call', _21 => _21()]), () => ( 0)));
|
|
253
269
|
return next;
|
|
254
270
|
}, [client, customerKey]);
|
|
255
271
|
_react.useEffect.call(void 0, () => {
|
|
@@ -281,9 +297,9 @@ function CatalogProvider(props) {
|
|
|
281
297
|
rest.customerCart,
|
|
282
298
|
rest.throttleBaseUrl,
|
|
283
299
|
rest.throttleCheckoutUrl,
|
|
284
|
-
_optionalChain([urls, 'optionalAccess',
|
|
285
|
-
_optionalChain([urls, 'optionalAccess',
|
|
286
|
-
_optionalChain([urls, 'optionalAccess',
|
|
300
|
+
_optionalChain([urls, 'optionalAccess', _22 => _22.returnUrl]),
|
|
301
|
+
_optionalChain([urls, 'optionalAccess', _23 => _23.cancelUrl]),
|
|
302
|
+
_optionalChain([urls, 'optionalAccess', _24 => _24.storefrontUrl])
|
|
287
303
|
]
|
|
288
304
|
);
|
|
289
305
|
cart.context = value;
|
|
@@ -417,9 +433,9 @@ function useDebounced(q, ms) {
|
|
|
417
433
|
return _react.useSyncExternalStore.call(void 0, box.subscribe, box.get, box.get);
|
|
418
434
|
}
|
|
419
435
|
function useSuggest(q, options = {}) {
|
|
420
|
-
const settled = useDebounced(q, _nullishCoalesce(options.debounceMs, () => (
|
|
436
|
+
const settled = useDebounced(q, _nullishCoalesce(options.debounceMs, () => ( _chunk2ODFFMZ4cjs.SUGGEST_DEBOUNCE_MS)));
|
|
421
437
|
const extra = defined({ limit: options.limit });
|
|
422
|
-
const long = (value) => value.trim().length >=
|
|
438
|
+
const long = (value) => value.trim().length >= _chunk2ODFFMZ4cjs.SUGGEST_MIN_CHARS;
|
|
423
439
|
return useQuery(
|
|
424
440
|
"suggest",
|
|
425
441
|
{ q: settled, ...extra },
|
|
@@ -466,6 +482,75 @@ function useConfig(options) {
|
|
|
466
482
|
options
|
|
467
483
|
);
|
|
468
484
|
}
|
|
485
|
+
function useStorefrontSettings(options) {
|
|
486
|
+
return useQuery(
|
|
487
|
+
"settings",
|
|
488
|
+
null,
|
|
489
|
+
(client, call) => client.settings(call),
|
|
490
|
+
options
|
|
491
|
+
);
|
|
492
|
+
}
|
|
493
|
+
var watches = /* @__PURE__ */ new WeakMap();
|
|
494
|
+
var watchRun = (client, call) => client.config(call);
|
|
495
|
+
var pageDocument = () => Reflect.get(globalThis, "document");
|
|
496
|
+
function watch(store, intervalMs, listener) {
|
|
497
|
+
let w = watches.get(store);
|
|
498
|
+
if (w === void 0) {
|
|
499
|
+
const key = `\0${catalogQueryKey("generation", null)}`;
|
|
500
|
+
const visible = () => pageDocument().visibilityState === "visible";
|
|
501
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
502
|
+
let known;
|
|
503
|
+
let hiddenAt = visible() ? 0 : Date.now();
|
|
504
|
+
const check = async () => {
|
|
505
|
+
if (!visible()) return;
|
|
506
|
+
await store.fetch(key, watchRun, { force: true });
|
|
507
|
+
const data = store.get(key).data;
|
|
508
|
+
if (watches.get(store) !== w || _optionalChain([data, 'optionalAccess', _25 => _25.generation]) === void 0) return;
|
|
509
|
+
const changed = known !== void 0 && data.generation !== known;
|
|
510
|
+
known = data.generation;
|
|
511
|
+
if (changed) {
|
|
512
|
+
store.invalidate();
|
|
513
|
+
for (const { current } of [...listeners]) _optionalChain([current, 'optionalCall', _26 => _26(known)]);
|
|
514
|
+
}
|
|
515
|
+
};
|
|
516
|
+
const onVisibility = () => {
|
|
517
|
+
if (!visible()) hiddenAt = Date.now();
|
|
518
|
+
else {
|
|
519
|
+
if (known === void 0 || Date.now() - hiddenAt >= intervalMs)
|
|
520
|
+
void check();
|
|
521
|
+
hiddenAt = 0;
|
|
522
|
+
}
|
|
523
|
+
};
|
|
524
|
+
void check();
|
|
525
|
+
const timer = setInterval(() => void check(), intervalMs);
|
|
526
|
+
const doc = pageDocument();
|
|
527
|
+
doc.addEventListener("visibilitychange", onVisibility);
|
|
528
|
+
w = {
|
|
529
|
+
listeners,
|
|
530
|
+
stop() {
|
|
531
|
+
clearInterval(timer);
|
|
532
|
+
doc.removeEventListener("visibilitychange", onVisibility);
|
|
533
|
+
watches.delete(store);
|
|
534
|
+
}
|
|
535
|
+
};
|
|
536
|
+
watches.set(store, w);
|
|
537
|
+
}
|
|
538
|
+
const mine = w;
|
|
539
|
+
mine.listeners.add(listener);
|
|
540
|
+
return () => {
|
|
541
|
+
mine.listeners.delete(listener);
|
|
542
|
+
if (mine.listeners.size === 0) mine.stop();
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
function useGenerationWatch({
|
|
546
|
+
intervalMs = 6e4,
|
|
547
|
+
onChange
|
|
548
|
+
} = {}) {
|
|
549
|
+
const { store } = useCatalogContext();
|
|
550
|
+
const latest = _react.useRef.call(void 0, onChange);
|
|
551
|
+
latest.current = onChange;
|
|
552
|
+
_react.useEffect.call(void 0, () => watch(store, intervalMs, latest), [store, intervalMs]);
|
|
553
|
+
}
|
|
469
554
|
function useFilterValues(key, query = {}, options) {
|
|
470
555
|
return useQuery(
|
|
471
556
|
"filterValues",
|
|
@@ -493,4 +578,6 @@ function useFilterValues(key, query = {}, options) {
|
|
|
493
578
|
|
|
494
579
|
|
|
495
580
|
|
|
496
|
-
|
|
581
|
+
|
|
582
|
+
|
|
583
|
+
exports.createMemoryCartStorage = createMemoryCartStorage; exports.useCatalogContext = useCatalogContext; exports.CatalogProvider = CatalogProvider; exports.useCustomerKey = useCustomerKey; exports.useCatalog = useCatalog; exports.catalogQueryKey = catalogQueryKey; exports.useQuery = useQuery; exports.defined = defined; exports.useProducts = useProducts; exports.useProduct = useProduct; exports.useRelated = useRelated; exports.useSuggest = useSuggest; exports.useCategories = useCategories; exports.useCollection = useCollection; exports.useReviews = useReviews; exports.useConfig = useConfig; exports.useStorefrontSettings = useStorefrontSettings; exports.useGenerationWatch = useGenerationWatch; exports.useFilterValues = useFilterValues;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { D as RequestSpec, c as CallOptions, o as CatalogNamespaces, l as CatalogClientOptions } from './types-BtBxMbM5.cjs';
|
|
2
2
|
|
|
3
3
|
/** A `304` is possible only when `ifNoneMatch` (not the client cache) sent `If-None-Match`. */
|
|
4
4
|
type TransportResult<T> = {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { D as RequestSpec, c as CallOptions, o as CatalogNamespaces, l as CatalogClientOptions } from './types-dKvIfrVH.js';
|
|
2
2
|
|
|
3
3
|
/** A `304` is possible only when `ifNoneMatch` (not the client cache) sent `If-None-Match`. */
|
|
4
4
|
type TransportResult<T> = {
|