@occluze/tether 0.9.2 → 0.9.3
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/README.md +1 -1
- package/dist/esm/astro.js +2 -2
- package/dist/esm/chunks/account-3MYRPPTR.js +1 -0
- package/dist/esm/chunks/{account-pages-FIXSWJH7.js → account-pages-OZHK5HHY.js} +1 -1
- package/dist/esm/chunks/{analytics-MO2ZWBOD.js → analytics-QHX2YHZS.js} +1 -1
- package/dist/esm/chunks/chunk-24KD36UC.js +1 -0
- package/dist/esm/chunks/{chunk-FI4NIWAD.js → chunk-2G6U6ZYV.js} +1 -1
- package/dist/esm/chunks/{chunk-IJAMRI33.js → chunk-74SGIWQE.js} +1 -1
- package/dist/esm/chunks/{chunk-SZRDO62E.js → chunk-A3GZFAB3.js} +1 -1
- package/dist/esm/chunks/chunk-A6BZFYZY.js +1 -0
- package/dist/esm/chunks/{chunk-Y3NKKN2O.js → chunk-EYG7QGPA.js} +1 -1
- package/dist/esm/chunks/{chunk-7ZXEVDOS.js → chunk-FX7EJ6RB.js} +1 -1
- package/dist/esm/chunks/{chunk-7CRTJV25.js → chunk-GCGRUVYO.js} +1 -1
- package/dist/esm/chunks/{chunk-CRKJ2VEX.js → chunk-LSB7RVRZ.js} +1 -1
- package/dist/esm/chunks/{chunk-BVO7KK2M.js → chunk-NF5H2Q7V.js} +1 -1
- package/dist/esm/chunks/chunk-PZERNTCD.js +1 -0
- package/dist/esm/chunks/chunk-RVWHBZAF.js +1 -0
- package/dist/esm/chunks/chunk-SJNNEEDX.js +1 -0
- package/dist/esm/chunks/{chunk-DM5LEAWM.js → chunk-SOLTIZAI.js} +1 -1
- package/dist/esm/chunks/{chunk-FWMPL6PR.js → chunk-WHNUPECA.js} +1 -1
- package/dist/esm/chunks/{chunk-OENVX4NY.js → chunk-ZB4FBE6W.js} +1 -1
- package/dist/esm/chunks/{diagnose-XSZPWEG7.js → diagnose-O3QCZTHT.js} +1 -1
- package/dist/esm/chunks/{extras-DZIOTZ3H.js → extras-O6ZRL5FK.js} +1 -1
- package/dist/esm/chunks/lists-XF33XENI.js +1 -0
- package/dist/esm/chunks/{markets-ui-DEEYV4KT.js → markets-ui-V2ROBFZP.js} +1 -1
- package/dist/esm/chunks/search-ZLKIFARH.js +1 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/server.js +2 -2
- package/dist/tether.account-pages.js +2 -2
- package/dist/tether.account-pages.min.js +1 -1
- package/dist/tether.account.js +4 -7
- package/dist/tether.account.min.js +1 -1
- package/dist/tether.analytics.js +1 -1
- package/dist/tether.analytics.min.js +1 -1
- package/dist/tether.diagnose.js +1 -1
- package/dist/tether.diagnose.min.js +1 -1
- package/dist/tether.extras.js +1 -1
- package/dist/tether.extras.min.js +1 -1
- package/dist/tether.js +105 -63
- package/dist/tether.lists.js +11 -7
- package/dist/tether.lists.min.js +1 -1
- package/dist/tether.markets.js +1 -1
- package/dist/tether.markets.min.js +1 -1
- package/dist/tether.min.js +1 -1
- package/dist/tether.min.js.map +4 -4
- package/dist/tether.search.js +4 -6
- package/dist/tether.search.min.js +1 -1
- package/dist/types/server/src/shared/metafield-ref.d.ts +15 -0
- package/dist/types/src/dom.d.ts +12 -0
- package/dist/types/src/shopify-values.d.ts +2 -0
- package/dist/types/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/dist/esm/chunks/account-XBGNTM7V.js +0 -1
- package/dist/esm/chunks/chunk-2J3MTS3E.js +0 -1
- package/dist/esm/chunks/chunk-4FR3CUO2.js +0 -1
- package/dist/esm/chunks/chunk-H6IORH7O.js +0 -1
- package/dist/esm/chunks/chunk-OATTAXPO.js +0 -1
- package/dist/esm/chunks/chunk-OJAV2I3C.js +0 -1
- package/dist/esm/chunks/lists-OJGSVQMM.js +0 -1
- package/dist/esm/chunks/search-A6HF5PMJ.js +0 -1
package/dist/tether.js
CHANGED
|
@@ -28,9 +28,19 @@
|
|
|
28
28
|
return isRecord(value) ? value[key] : void 0;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
// src/
|
|
32
|
-
var
|
|
31
|
+
// server/src/shared/metafield-ref.ts
|
|
32
|
+
var METAFIELD_KEY = /^[A-Za-z0-9_.-]+$/;
|
|
33
33
|
var METAFIELD_NAMESPACE = /^(\$app(:[A-Za-z0-9_-]+)?|[A-Za-z0-9_.-]+)$/;
|
|
34
|
+
var isMetafieldIdentifier = (namespace, key) => METAFIELD_NAMESPACE.test(namespace) && METAFIELD_KEY.test(key);
|
|
35
|
+
function metafieldIdentifierOf(ref) {
|
|
36
|
+
const dot = ref.indexOf(".");
|
|
37
|
+
if (dot <= 0) return null;
|
|
38
|
+
const namespace = ref.slice(0, dot);
|
|
39
|
+
const key = ref.slice(dot + 1);
|
|
40
|
+
return isMetafieldIdentifier(namespace, key) ? { namespace, key } : null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// src/config-sections.ts
|
|
34
44
|
var HOSTNAME = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;
|
|
35
45
|
var COOKIE_NAME = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
|
|
36
46
|
var GLOBAL_NAME = /^[A-Za-z_$][\w$]*$/;
|
|
@@ -99,18 +109,12 @@
|
|
|
99
109
|
return origins;
|
|
100
110
|
}
|
|
101
111
|
function toMetafieldIdentifier(ref) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
namespace = dot > 0 ? ref.slice(0, dot) : "";
|
|
107
|
-
key = ref.slice(dot + 1);
|
|
108
|
-
} else if (typeof ref === "object" && ref !== null) {
|
|
109
|
-
namespace = Reflect.get(ref, "namespace");
|
|
110
|
-
key = Reflect.get(ref, "key");
|
|
111
|
-
}
|
|
112
|
+
if (typeof ref === "string") return metafieldIdentifierOf(ref);
|
|
113
|
+
if (typeof ref !== "object" || ref === null) return null;
|
|
114
|
+
const namespace = Reflect.get(ref, "namespace");
|
|
115
|
+
const key = Reflect.get(ref, "key");
|
|
112
116
|
if (typeof namespace !== "string" || typeof key !== "string") return null;
|
|
113
|
-
return
|
|
117
|
+
return isMetafieldIdentifier(namespace, key) ? { namespace, key } : null;
|
|
114
118
|
}
|
|
115
119
|
function metafieldsOption(value, invalid) {
|
|
116
120
|
if (!Array.isArray(value)) {
|
|
@@ -220,6 +224,45 @@
|
|
|
220
224
|
return LANGUAGE.test(primary) ? primary : null;
|
|
221
225
|
}
|
|
222
226
|
|
|
227
|
+
// src/shopify-values.ts
|
|
228
|
+
var MAX_CONNECTION_SIZE = 250;
|
|
229
|
+
function isHttpsUrl(url2) {
|
|
230
|
+
if (typeof url2 !== "string") return false;
|
|
231
|
+
try {
|
|
232
|
+
return new URL(url2).protocol === "https:";
|
|
233
|
+
} catch {
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
function formatMoney(money, locale) {
|
|
238
|
+
if (!money) return "";
|
|
239
|
+
const amount = parseFloat(money.amount);
|
|
240
|
+
if (Number.isNaN(amount)) return "";
|
|
241
|
+
try {
|
|
242
|
+
return new Intl.NumberFormat(locale || void 0, { style: "currency", currency: money.currencyCode }).format(
|
|
243
|
+
amount
|
|
244
|
+
);
|
|
245
|
+
} catch {
|
|
246
|
+
return `${money.currencyCode} ${amount.toFixed(2)}`;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
function productUrl(productPath, handle, id) {
|
|
250
|
+
if (!/\{(handle|id)\}/.test(productPath)) {
|
|
251
|
+
return handle ? `${productPath.replace(/\/$/, "")}/${encodeURIComponent(handle)}` : null;
|
|
252
|
+
}
|
|
253
|
+
const numericId2 = id ? id.split("/").at(-1) ?? "" : "";
|
|
254
|
+
if (productPath.includes("{handle}") && !handle) return null;
|
|
255
|
+
if (productPath.includes("{id}") && !numericId2) return null;
|
|
256
|
+
return productPath.replace(/\{handle\}/g, encodeURIComponent(handle ?? "")).replace(/\{id\}/g, encodeURIComponent(numericId2));
|
|
257
|
+
}
|
|
258
|
+
function productKey(raw) {
|
|
259
|
+
const value = String(raw ?? "").trim();
|
|
260
|
+
if (!value) return null;
|
|
261
|
+
if (value.startsWith("gid://")) return value;
|
|
262
|
+
if (/^\d+$/.test(value)) return `gid://shopify/Product/${value}`;
|
|
263
|
+
return /\/products\/([^/?#]+)/.exec(value)?.[1] ?? value;
|
|
264
|
+
}
|
|
265
|
+
|
|
223
266
|
// src/config.ts
|
|
224
267
|
var DEFAULTS = {
|
|
225
268
|
domain: "",
|
|
@@ -297,7 +340,7 @@
|
|
|
297
340
|
"astro",
|
|
298
341
|
"debug"
|
|
299
342
|
];
|
|
300
|
-
var TEXT_OPTIONS = ["token", "productPath", "collectionPath"
|
|
343
|
+
var TEXT_OPTIONS = ["token", "productPath", "collectionPath"];
|
|
301
344
|
var COUNT_OPTIONS = [
|
|
302
345
|
"imagesFirst",
|
|
303
346
|
"variantsFirst",
|
|
@@ -330,7 +373,7 @@
|
|
|
330
373
|
}
|
|
331
374
|
function warnUnknownKeys(options) {
|
|
332
375
|
for (const key of Object.keys(options)) {
|
|
333
|
-
if (!(key
|
|
376
|
+
if (!Object.hasOwn(DEFAULTS, key)) warn(`unknown option ${JSON.stringify(key)}: ignored`);
|
|
334
377
|
}
|
|
335
378
|
}
|
|
336
379
|
function setHook(config, name, value) {
|
|
@@ -342,16 +385,22 @@
|
|
|
342
385
|
}
|
|
343
386
|
var MAX_TIMER_MS = 2147483647;
|
|
344
387
|
var MAX_RETRIES = 10;
|
|
345
|
-
var
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
388
|
+
var CONNECTION_RANGE = { min: 1, max: MAX_CONNECTION_SIZE };
|
|
389
|
+
var COUNT_RANGES = {
|
|
390
|
+
imagesFirst: CONNECTION_RANGE,
|
|
391
|
+
variantsFirst: CONNECTION_RANGE,
|
|
392
|
+
sellingPlanGroupsFirst: CONNECTION_RANGE,
|
|
393
|
+
sellingPlansFirst: CONNECTION_RANGE,
|
|
394
|
+
collectionFirst: CONNECTION_RANGE,
|
|
395
|
+
requestTimeout: { max: MAX_TIMER_MS },
|
|
396
|
+
searchDelay: { max: MAX_TIMER_MS },
|
|
397
|
+
retries: { max: MAX_RETRIES }
|
|
349
398
|
};
|
|
350
399
|
function countOption(name, value) {
|
|
351
|
-
|
|
400
|
+
const { min = 0, max: maximum } = COUNT_RANGES[name] ?? {};
|
|
401
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value < min) {
|
|
352
402
|
return invalidOption(name, value, DEFAULTS[name]);
|
|
353
403
|
}
|
|
354
|
-
const maximum = COUNT_MAXIMUMS[name];
|
|
355
404
|
if (maximum === void 0 || value <= maximum) return value;
|
|
356
405
|
warn(`${name} ${String(value)} is more than its maximum: using ${String(maximum)}`);
|
|
357
406
|
return maximum;
|
|
@@ -362,6 +411,10 @@
|
|
|
362
411
|
function textOption(name, value) {
|
|
363
412
|
return typeof value === "string" ? value : invalidOption(name, value, DEFAULTS[name]);
|
|
364
413
|
}
|
|
414
|
+
var CLASS_TOKEN = /^\S+$/;
|
|
415
|
+
function classOption(name, value) {
|
|
416
|
+
return typeof value === "string" && CLASS_TOKEN.test(value) ? value : invalidOption(name, value, DEFAULTS[name]);
|
|
417
|
+
}
|
|
365
418
|
function localeOption(value) {
|
|
366
419
|
if (value === void 0 || value === null || value === "") return void 0;
|
|
367
420
|
try {
|
|
@@ -408,7 +461,8 @@
|
|
|
408
461
|
metafields: metafieldsOption(options.metafields ?? [], dropped),
|
|
409
462
|
embedOrigins: embedOriginsOption(options.embedOrigins ?? [], dropped),
|
|
410
463
|
checkoutTarget: choiceOption("checkoutTarget", options.checkoutTarget, ["_self", "_blank"]),
|
|
411
|
-
defaultPurchase: choiceOption("defaultPurchase", options.defaultPurchase, ["one-time", "subscription"])
|
|
464
|
+
defaultPurchase: choiceOption("defaultPurchase", options.defaultPurchase, ["one-time", "subscription"]),
|
|
465
|
+
cartDrawerOpenClass: classOption("cartDrawerOpenClass", options.cartDrawerOpenClass)
|
|
412
466
|
};
|
|
413
467
|
for (const name of COUNT_OPTIONS) resolved[name] = countOption(name, options[name]);
|
|
414
468
|
for (const name of SWITCH_OPTIONS) resolved[name] = switchOption(name, options[name]);
|
|
@@ -881,44 +935,6 @@
|
|
|
881
935
|
return template.content;
|
|
882
936
|
}
|
|
883
937
|
|
|
884
|
-
// src/shopify-values.ts
|
|
885
|
-
function isHttpsUrl(url2) {
|
|
886
|
-
if (typeof url2 !== "string") return false;
|
|
887
|
-
try {
|
|
888
|
-
return new URL(url2).protocol === "https:";
|
|
889
|
-
} catch {
|
|
890
|
-
return false;
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
|
-
function formatMoney(money, locale) {
|
|
894
|
-
if (!money) return "";
|
|
895
|
-
const amount = parseFloat(money.amount);
|
|
896
|
-
if (Number.isNaN(amount)) return "";
|
|
897
|
-
try {
|
|
898
|
-
return new Intl.NumberFormat(locale || void 0, { style: "currency", currency: money.currencyCode }).format(
|
|
899
|
-
amount
|
|
900
|
-
);
|
|
901
|
-
} catch {
|
|
902
|
-
return `${money.currencyCode} ${amount.toFixed(2)}`;
|
|
903
|
-
}
|
|
904
|
-
}
|
|
905
|
-
function productUrl(productPath, handle, id) {
|
|
906
|
-
if (!/\{(handle|id)\}/.test(productPath)) {
|
|
907
|
-
return handle ? `${productPath.replace(/\/$/, "")}/${encodeURIComponent(handle)}` : null;
|
|
908
|
-
}
|
|
909
|
-
const numericId2 = id ? id.split("/").at(-1) ?? "" : "";
|
|
910
|
-
if (productPath.includes("{handle}") && !handle) return null;
|
|
911
|
-
if (productPath.includes("{id}") && !numericId2) return null;
|
|
912
|
-
return productPath.replace(/\{handle\}/g, encodeURIComponent(handle ?? "")).replace(/\{id\}/g, encodeURIComponent(numericId2));
|
|
913
|
-
}
|
|
914
|
-
function productKey(raw) {
|
|
915
|
-
const value = String(raw ?? "").trim();
|
|
916
|
-
if (!value) return null;
|
|
917
|
-
if (value.startsWith("gid://")) return value;
|
|
918
|
-
if (/^\d+$/.test(value)) return `gid://shopify/Product/${value}`;
|
|
919
|
-
return /\/products\/([^/?#]+)/.exec(value)?.[1] ?? value;
|
|
920
|
-
}
|
|
921
|
-
|
|
922
938
|
// src/images.ts
|
|
923
939
|
function imageUrl(url2, { width, height, crop } = {}) {
|
|
924
940
|
if (!url2) return url2;
|
|
@@ -1209,6 +1225,31 @@
|
|
|
1209
1225
|
return null;
|
|
1210
1226
|
}
|
|
1211
1227
|
}
|
|
1228
|
+
var INTEGER_TEXT = /^-?\d+$/;
|
|
1229
|
+
var invalidIntegerAttributes = /* @__PURE__ */ new WeakMap();
|
|
1230
|
+
function warnInvalidAttribute(el, name, message) {
|
|
1231
|
+
const warned = invalidIntegerAttributes.get(el) ?? /* @__PURE__ */ new Set();
|
|
1232
|
+
invalidIntegerAttributes.set(el, warned);
|
|
1233
|
+
if (warned.has(name)) return;
|
|
1234
|
+
warned.add(name);
|
|
1235
|
+
warn(`${attr(name)} ${message}`, el);
|
|
1236
|
+
}
|
|
1237
|
+
function integerAttribute(el, name, { min, max, fallback }) {
|
|
1238
|
+
const raw = get(el, name)?.trim();
|
|
1239
|
+
if (!raw) return fallback;
|
|
1240
|
+
const value = INTEGER_TEXT.test(raw) ? Number(raw) : Number.NaN;
|
|
1241
|
+
if (Number.isNaN(value) || value < min) {
|
|
1242
|
+
warnInvalidAttribute(
|
|
1243
|
+
el,
|
|
1244
|
+
name,
|
|
1245
|
+
`${JSON.stringify(raw)} is not a whole number from ${String(min)}: using ${String(fallback)}`
|
|
1246
|
+
);
|
|
1247
|
+
return fallback;
|
|
1248
|
+
}
|
|
1249
|
+
if (max === void 0 || value <= max) return value;
|
|
1250
|
+
warnInvalidAttribute(el, name, `${raw} is more than its maximum: using ${String(max)}`);
|
|
1251
|
+
return max;
|
|
1252
|
+
}
|
|
1212
1253
|
function attributeText(value) {
|
|
1213
1254
|
if (value === null || value === void 0) return "";
|
|
1214
1255
|
if (typeof value === "string") return value;
|
|
@@ -3440,7 +3481,7 @@
|
|
|
3440
3481
|
}
|
|
3441
3482
|
|
|
3442
3483
|
// src/part-integrity.ts
|
|
3443
|
-
var PART_INTEGRITY = { "tether.diagnose.js": "sha384-
|
|
3484
|
+
var PART_INTEGRITY = { "tether.diagnose.js": "sha384-V4pclvaqH/qR/arn2rEkiL09rESoS1Z5AEE01ZSaFNlDU+sXXpOhKprwno6MT998", "tether.markets.js": "sha384-5wg1XGIKHX3Q4SX9E1xoYiJT653F0uCs7WCJ36Rf+YX6o1VJhuK6m59ZuUuqgxXw", "tether.search.js": "sha384-KMmZKdaQq6+LzU7kFva2DYZ7dh425RhHClXfVPHp8dNDGn1eG2UEMuPooowJOQtt", "tether.lists.js": "sha384-L/+3bMN1EifET4EcFWBk5IAFywRaC0uilAX3eYLeGqmX9zkPFjS/SvVSklpRwSSA", "tether.extras.js": "sha384-/SMjz6qCFAOV0wwvEVNhQxtT/1pyx4hRxDJHOxHB6M3uclAvItSULKZqJvaehH+i", "tether.account.js": "sha384-CVXd+K/5Wc9mSdfMM6cE1BYN4kjFWCXpEfoLq/jU0zy1C+V4SXfyTCyXloVFMMs7", "tether.account-pages.js": "sha384-bUUsp/0dKGSGzjctzF1FgLcCvgBGh+wQw95IhbjU+ckMo78vzetzlI2+QuNQugaI", "tether.analytics.js": "sha384-DBXy5gOU7crMr0xSS4TjnZN1Q8Slz3h18Ih/jLBjwYRVFE1fGzdR9PBuHnKOxc0E" };
|
|
3444
3485
|
|
|
3445
3486
|
// src/part-registry.ts
|
|
3446
3487
|
function isTetherInternals(value) {
|
|
@@ -3448,7 +3489,7 @@
|
|
|
3448
3489
|
}
|
|
3449
3490
|
|
|
3450
3491
|
// src/version.ts
|
|
3451
|
-
var VERSION = "0.9.
|
|
3492
|
+
var VERSION = "0.9.3";
|
|
3452
3493
|
|
|
3453
3494
|
// src/lazy-iife.ts
|
|
3454
3495
|
var coreModules = {
|
|
@@ -3470,6 +3511,7 @@
|
|
|
3470
3511
|
get,
|
|
3471
3512
|
has,
|
|
3472
3513
|
hasTemplate,
|
|
3514
|
+
integerAttribute,
|
|
3473
3515
|
isOwnEvent,
|
|
3474
3516
|
notifyLayoutChanged,
|
|
3475
3517
|
parseJSONAttr,
|
|
@@ -3515,7 +3557,7 @@
|
|
|
3515
3557
|
return [setCountry];
|
|
3516
3558
|
},
|
|
3517
3559
|
get "shopify-values.ts"() {
|
|
3518
|
-
return [isHttpsUrl];
|
|
3560
|
+
return [isHttpsUrl, MAX_CONNECTION_SIZE];
|
|
3519
3561
|
},
|
|
3520
3562
|
// Parts that load other parts (account → account-pages) use this same loader.
|
|
3521
3563
|
get "lazy.ts"() {
|
package/dist/tether.lists.js
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
|
|
26
26
|
// tether-core:dom.ts
|
|
27
27
|
var m3 = window.Tether.__core["dom.ts"];
|
|
28
|
-
var [ANALYTICS_EVENTS, attr, attributesFromJson, busy, emit, formatDate, formatMoney, get, has, hasTemplate, isOwnEvent, notifyLayoutChanged, parseJSONAttr, productUrl, qsa, repeat, scoped, sel, setImage, setStoreHtml, setText, show] = m3;
|
|
28
|
+
var [ANALYTICS_EVENTS, attr, attributesFromJson, busy, emit, formatDate, formatMoney, get, has, hasTemplate, integerAttribute, isOwnEvent, notifyLayoutChanged, parseJSONAttr, productUrl, qsa, repeat, scoped, sel, setImage, setStoreHtml, setText, show] = m3;
|
|
29
29
|
|
|
30
30
|
// tether-core:fragments.ts
|
|
31
31
|
var m4 = window.Tether.__core["fragments.ts"];
|
|
@@ -71,6 +71,10 @@
|
|
|
71
71
|
var m7 = window.Tether.__core["collection.ts"];
|
|
72
72
|
var [listSelector] = m7;
|
|
73
73
|
|
|
74
|
+
// tether-core:shopify-values.ts
|
|
75
|
+
var m8 = window.Tether.__core["shopify-values.ts"];
|
|
76
|
+
var [isHttpsUrl, MAX_CONNECTION_SIZE] = m8;
|
|
77
|
+
|
|
74
78
|
// src/lists.ts
|
|
75
79
|
var URL_QUERY_SOURCE = "url:";
|
|
76
80
|
var COLLECTION_QUERY = `query TetherCollection($handle:String!,$first:Int!,$after:String,$sortKey:ProductCollectionSortKeys,$reverse:Boolean,$filters:[ProductFilter!]){collection(handle:$handle){${collectionFields()} products(first:$first,after:$after,sortKey:$sortKey,reverse:$reverse,filters:$filters){nodes{...TetherProduct}pageInfo{hasNextPage endCursor}}}}`;
|
|
@@ -126,7 +130,7 @@
|
|
|
126
130
|
return list;
|
|
127
131
|
}
|
|
128
132
|
var isElement = (target) => target instanceof window.Element;
|
|
129
|
-
var
|
|
133
|
+
var listLimit = (root, fallback) => integerAttribute(root, "limit", { min: 1, max: MAX_CONNECTION_SIZE, fallback });
|
|
130
134
|
var toIntent = (raw) => raw === "COMPLEMENTARY" ? "COMPLEMENTARY" : "RELATED";
|
|
131
135
|
var ListScope = class {
|
|
132
136
|
constructor(root) {
|
|
@@ -151,9 +155,10 @@
|
|
|
151
155
|
/** The collection or search query of the list's attributes. */
|
|
152
156
|
options() {
|
|
153
157
|
const { root } = this;
|
|
154
|
-
const query = {
|
|
155
|
-
|
|
156
|
-
|
|
158
|
+
const query = {
|
|
159
|
+
reverse: get(root, "reverse") === "true",
|
|
160
|
+
first: listLimit(root, cfg.collectionFirst)
|
|
161
|
+
};
|
|
157
162
|
const sortKey = get(root, "sort");
|
|
158
163
|
if (sortKey) query.sortKey = sortKey;
|
|
159
164
|
if (has(root, "collection")) {
|
|
@@ -185,8 +190,7 @@
|
|
|
185
190
|
if (has(this.root, "recommendations")) {
|
|
186
191
|
const recommendations = await this.loadRecommendations();
|
|
187
192
|
if (stale()) return;
|
|
188
|
-
|
|
189
|
-
this.products = limit ? recommendations.slice(0, limit) : recommendations;
|
|
193
|
+
this.products = recommendations.slice(0, listLimit(this.root, recommendations.length));
|
|
190
194
|
} else {
|
|
191
195
|
const page = await getProducts({ ...this.options(), after: more ? this.pageInfo?.endCursor ?? null : null });
|
|
192
196
|
if (stale()) return;
|
package/dist/tether.lists.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{var
|
|
1
|
+
(()=>{var b=Object.defineProperty;var rt=(e,t,o)=>t in e?b(e,t,{enumerable:!0,configurable:!0,writable:!0,value:o}):e[t]=o;var nt=(e,t)=>{for(var o in t)b(e,o,{get:t[o],enumerable:!0})};var a=(e,t,o)=>rt(e,typeof t!="symbol"?t+"":t,o);var O={};nt(O,{getProducts:()=>X,getRecommendations:()=>G,loadList:()=>yt});var st=window.Tether.__core["config.ts"],[P,Et,xt,It,Ct,A,Nt]=st;var it=window.Tether.__core["client.ts"],[$t,l,ct,T,u,E]=it;var at=window.Tether.__core["dom.ts"],[kt,x,Ot,L,p,St,bt,s,m,At,M,Lt,K,Mt,Kt,Ut,U,F,c,q,v,I,f]=at;var dt=window.Tether.__core["fragments.ts"],[D]=dt;var lt=window.Tether.__core["loader.ts"],[vt,Dt,H,h,g]=lt;function d(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}var C={amount:"string",currencyCode:"string"},Q={id:"string",handle:"string",title:"string",options:["object"],images:{nodes:["object"]},priceRange:{minVariantPrice:C,maxVariantPrice:C},variants:{nodes:[{id:"string",price:C,selectedOptions:["object"]}]}},Y={nodes:[Q],pageInfo:{hasNextPage:"boolean"}};var j=u({collection:T({handle:"string",products:Y})}),z=u({products:Y}),B=u({productRecommendations:T([Q])});var ut=window.Tether.__core["status.ts"],[Vt,N,R,$]=ut;var pt=window.Tether.__core["collection.ts"],[_]=pt;var mt=window.Tether.__core["shopify-values.ts"],[Jt,V]=mt;var W="url:",ft=`query TetherCollection($handle:String!,$first:Int!,$after:String,$sortKey:ProductCollectionSortKeys,$reverse:Boolean,$filters:[ProductFilter!]){collection(handle:$handle){${D()} products(first:$first,after:$after,sortKey:$sortKey,reverse:$reverse,filters:$filters){nodes{...TetherProduct}pageInfo{hasNextPage endCursor}}}}`,ht="query TetherSearch($first:Int!,$after:String,$query:String,$sortKey:ProductSortKeys,$reverse:Boolean){products(first:$first,after:$after,query:$query,sortKey:$sortKey,reverse:$reverse){nodes{...TetherProduct}pageInfo{hasNextPage endCursor}}}";async function X({collection:e,query:t,first:o=P.collectionFirst,after:r=null,sortKey:n,reverse:i=!1,filters:et}={}){if(e){let S=await l(g(ft),{handle:e,first:o,after:r,sortKey:n||void 0,reverse:i,filters:et??void 0},j);if(!S.collection)throw new E(`Collection not found: ${e}`,{code:"NOT_FOUND"});let{products:y,...ot}=S.collection;return y.nodes.forEach(h),{collection:ot,products:y.nodes,pageInfo:y.pageInfo}}let w=await l(g(ht),{first:o,after:r,query:t||void 0,sortKey:n||void 0,reverse:i},z);return w.products.nodes.forEach(h),{collection:null,products:w.products.nodes,pageInfo:w.products.pageInfo}}async function G(e,t="RELATED"){let o=H(typeof e=="object"?e?.id:e);if(!o)throw new E("No product for recommendations",{code:"NOT_FOUND"});let r=o.startsWith("gid://"),i=(await l(g(`query TetherRecs(${r?"$id: ID!":"$handle: String!"},$intent:ProductRecommendationIntent){productRecommendations(${r?"productId: $id":"productHandle: $handle"},intent:$intent){...TetherProduct}}`),r?{id:o,intent:t}:{handle:o,intent:t},B)).productRecommendations??[];return i.forEach(h),i}var gt=e=>e instanceof window.Element,Z=(e,t)=>M(e,"limit",{min:1,max:V,fallback:t}),wt=e=>e==="COMPLEMENTARY"?"COMPLEMENTARY":"RELATED",k=class{constructor(t){a(this,"root");a(this,"products",[]);a(this,"pageInfo",null);a(this,"collection",null);a(this,"loadToken",0);this.root=t,t.addEventListener("click",o=>{if(!gt(o.target))return;let r=o.target.closest(c("load-more"));r?.closest(_())===t&&(o.preventDefault(),L(r,()=>this.load(!0)))})}$(t){return F(this.root,t,_())}options(){let{root:t}=this,o={reverse:s(t,"reverse")==="true",first:Z(t,P.collectionFirst)},r=s(t,"sort");if(r&&(o.sortKey=r),m(t,"collection"))return o.collection=s(t,"collection")??"",o;let n=s(t,"products")??"";return o.query=n.startsWith(W)?new URL(window.location.href).searchParams.get(n.slice(W.length))||"":n,o}async loadRecommendations(){let{key:t}=R(this.root,window.location,"recommendations"),o=this.root.closest(c("product"));return!t&&o&&({key:t}=R(o)),G(t,wt(s(this.root,"intent")))}async load(t=!1){this.loadToken+=1;let o=this.loadToken,r=()=>o!==this.loadToken;try{if(m(this.root,"recommendations")){let n=await this.loadRecommendations();if(r())return;this.products=n.slice(0,Z(this.root,n.length))}else{let n=await X({...this.options(),after:t?this.pageInfo?.endCursor??null:null});if(r())return;this.collection=n.collection,this.pageInfo=n.pageInfo,this.products=t?[...this.products,...n.products]:n.products}this.render(),$(this.root,"ready"),p("list-ready",{products:this.products,collection:this.collection},this.root)}catch(n){if(r())return;t||$(this.root,N(n)?"not-found":"error",n),N(n)&&m(this.root,"recommendations")||A(n,"list load failed"),p("error",{error:n,context:"list"},this.root)}}render(){let{collection:t}=this;this.$(c("collection-bind")).forEach(r=>{switch(s(r,"collection-bind")??""){case"title":I(r,t?.title??"");break;case"description":v(r,t?.descriptionHtml);break;case"image":q(r,t?.image?.url,t?.image?.altText||t?.title);break;case"count":I(r,this.products.length);break}}),this.$(c("list")).forEach(r=>{U(r,this.products,(n,i)=>{n.setAttribute(x("product"),i.handle),n.removeAttribute(x("state"))}),p("list-rendered",{container:r},this.root)});let o=this.products.length===0;this.$(c("show")).forEach(r=>{let n=s(r,"show");n==="list-empty"&&f(r,o),n==="list-filled"&&f(r,!o)}),this.$(c("load-more")).forEach(r=>{f(r,!!this.pageInfo?.hasNextPage)}),K("list")}},J=new WeakMap;function yt(e){let t=J.get(e);return t||(t=new k(e),J.set(e,t)),t.load()}function Pt(e){return d(e)&&d(e.__core)&&d(e.__parts)}function tt(e,t){let o=Reflect.get(window,"Tether");if(!Pt(o))throw new Error(`tether.${e}.js runs after the Tether script, which loads it, and needs its window.Tether`);o.__parts[e]=t}tt("lists",O);})();
|
package/dist/tether.markets.js
CHANGED
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
|
|
37
37
|
// tether-core:dom.ts
|
|
38
38
|
var m6 = window.Tether.__core["dom.ts"];
|
|
39
|
-
var [ANALYTICS_EVENTS, attr, attributesFromJson, busy, emit, formatDate, formatMoney, get, has, hasTemplate, isOwnEvent, notifyLayoutChanged, parseJSONAttr, productUrl, qsa, repeat, scoped, sel, setImage, setStoreHtml, setText, show] = m6;
|
|
39
|
+
var [ANALYTICS_EVENTS, attr, attributesFromJson, busy, emit, formatDate, formatMoney, get, has, hasTemplate, integerAttribute, isOwnEvent, notifyLayoutChanged, parseJSONAttr, productUrl, qsa, repeat, scoped, sel, setImage, setStoreHtml, setText, show] = m6;
|
|
40
40
|
|
|
41
41
|
// tether-core:mounting.ts
|
|
42
42
|
var m7 = window.Tether.__core["mounting.ts"];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{var G=Object.defineProperty;var V=(e,t)=>{for(var n in t)G(e,n,{get:t[n],enumerable:!0})};var b={};V(b,{detectMarket:()=>K,getLocalization:()=>J,renderCountrySelects:()=>L,setCountry:()=>Ee});var Z=window.Tether.__core["config.ts"],[
|
|
1
|
+
(()=>{var G=Object.defineProperty;var V=(e,t)=>{for(var n in t)G(e,n,{get:t[n],enumerable:!0})};var b={};V(b,{detectMarket:()=>K,getLocalization:()=>J,renderCountrySelects:()=>L,setCountry:()=>Ee});var Z=window.Tether.__core["config.ts"],[i,Ae,Ne,M,S,C,ve]=Z;var Q=window.Tether.__core["client.ts"],[Ie,x,ze,Re,T,E]=Q;var X=window.Tether.__core["cart.ts"],[g]=X;var ee=window.Tether.__core["collection.ts"],[P]=ee;var te=window.Tether.__core["loader.ts"],[_,De,je,Ke,$e]=te;var ne=window.Tether.__core["dom.ts"],[Je,m,Ye,Be,A,We,Ge,N,Ve,Ze,Qe,Xe,et,tt,nt,ot,rt,at,w,it,ct,ut,lt]=ne;var oe=window.Tether.__core["mounting.ts"],[v,O,I,z,R,k]=oe;var re=window.Tether.__core["market-codes.ts"],[s,d]=re;function U(e,t="localStorage"){try{return window[t].getItem(e)}catch{return null}}function H(e,t,n="localStorage"){try{window[n].setItem(e,t)}catch{}}function F(e){try{return decodeURIComponent(e)}catch(t){if(t instanceof URIError)return e;throw t}}var ae="tether_country",D=()=>`${i.prefix}:market:${i.domain}`,j={getItem:e=>U(e)};function ie(){let e=typeof window<"u";return{document:typeof document<"u"?document:null,location:e?window.location:null,storage:j,global:e?window:{}}}function ce(e){try{return JSON.parse(e)}catch(t){if(t instanceof SyntaxError)return null;throw t}}function ue(e){if(typeof e!="object"||e===null)return null;let t=s(Reflect.get(e,"country"));if(!t)return null;let n=Reflect.get(e,"locale");return{country:t,language:d(Reflect.get(e,"language"))??void 0,locale:typeof n=="string"&&n?n:void 0}}var le=e=>ue(ce(e));function se(e=j){let t=e.getItem(D());return t?le(t):null}function de(e,t){if(!e||!t)return null;let n=e.cookie.split(";").map(a=>a.trim()).find(a=>a.startsWith(`${t}=`));return n?F(n.slice(t.length+1)):null}function h(e,t){if(!e||!t)return null;let n=t.toLowerCase(),a=Object.keys(e).find(o=>o.toLowerCase()===n);return a?e[a]??null:null}function ge(e,t){let n=r=>t.document?.querySelector(`meta[name="${r}"]`)?.getAttribute("content"),a=Reflect.get(t.global,"TETHER_COUNTRY"),o=Reflect.get(t.global,"TETHER_LANGUAGE"),c=n("tether-country")||de(t.document,e.cookie||ae);return{country:a||c,language:o||n("tether-language")}}function fe(e,t){let n=(t.location?.pathname??"/").split("/").find(u=>u!==""),a=h(e.locales,n);if(a)return a;let o=t.document?.documentElement.getAttribute("lang");if(!o)return null;let c=h(e.locales,o)??h(e.locales,o.split("-")[0]);if(c)return{locale:o,...c};if(e.locales&&e.strict)return null;let r=o.split("-")[1];return{language:o,country:r?.length===2?r:null,locale:o}}function me(e,t,n){switch(e){case"saved":return t.remember===!1?null:se(n.storage);case"server":return ge(t,n);case"webflow":return fe(t,n)}}function pe(e){return e?e===!0?M:e:["saved"]}function K(e=i.markets,t=ie()){let n=(e===i.markets?e:S(e))??{};if(n.detect===!1)return{};let a={},o={sources:a};for(let c of pe(n.detect)){let r=me(c,n,t);if(!r)continue;let u=s(r.country),l=d(r.language),f=typeof r.locale=="string"&&r.locale?r.locale:null;u&&!o.country&&(o.country=u,a.country=c),l&&!o.language&&(o.language=l,a.language=c),f&&!o.locale&&(o.locale=f,a.locale=c)}return o}function $(e){if(i.markets?.remember===!1)return;let t={country:e.country,language:e.language||void 0,locale:e.locale||void 0};H(D(),JSON.stringify(t))}var ye="{name} ({currency})",Ce="name",p=null;function we(){p=null}var ke="query TetherLocalization{localization{country{isoCode name currency{isoCode symbol}}language{isoCode name}availableCountries{isoCode name currency{isoCode symbol}availableLanguages{isoCode name}}}}",q={isoCode:"string",name:"string",currency:"object"},he=T({localization:{country:q,availableCountries:[q]}});function J(){return p??(p=x(ke,{},he).then(e=>e.localization,e=>{throw p=null,e})),p}function Y(e,t){switch(t){case"name":return e.name;case"code":return e.isoCode;case"currency":return e.currency.isoCode;case"symbol":return e.currency.symbol;default:return""}}var Le=(e,t)=>e.replace(/\{(name|code|currency|symbol)\}/g,(n,a)=>Y(t,a));function be(e,t,n){let a=e.getAttribute(m("country-label"))||ye,o=(e.getAttribute(m("countries"))||"").toUpperCase().split(/[\s,]+/).filter(Boolean),c=o.length?o.map(r=>t.find(u=>u.isoCode===r)).filter(r=>r!==void 0):t;e.replaceChildren(...c.map(r=>new Option(Le(a,r),r.isoCode))),e.value=n,e.value!==n&&(e.selectedIndex=-1),e.disabled=c.length<2&&!e.hasAttribute(m("always-enabled"))}function Me(e,t,n){let a=(i.country||n.country.isoCode).toUpperCase(),o=[...n.availableCountries].sort((r,u)=>r.name.localeCompare(u.name,i.locale||void 0)),c=o.find(r=>r.isoCode===a)??n.country;e.forEach(r=>{be(r,o,a)}),t.forEach(r=>{r.textContent=Y(c,N(r,"country-bind")||Ce)})}function L(e=document){let t=k(e,`select${w("country-select")}`),n=k(e,w("country-bind"));return!t.length&&!n.length?Promise.resolve():J().then(a=>{Me(t,n,a)}).catch(a=>{C(a,"country select")})}var Se=e=>Object.values(i.markets?.locales??{}).find(t=>s(t.country)===e);function xe(e,t){return e!==void 0?d(e):t?t.language?d(t.language):void 0:i.language}function Te(e){_();let t=[];return g.id()&&t.push(g.setBuyerIdentity({countryCode:e},{create:!1}).catch(n=>{C(n,"cart country")})),R(),v.forEach(n=>t.push(n.load())),O.forEach(n=>{n.closest(P())||(I.delete(n),z(n))}),t}async function Ee(e,{language:t,locale:n,remember:a=!0}={}){let o=s(e);if(!o)throw new E(`Not a country code: ${e}`,{code:"INVALID_COUNTRY"});let c=Se(o),r=n||c?.locale,u=r||i.locale,l=xe(t,c),f=o!==i.country||l!==i.language||u!==i.locale;if(i.country=o,i.language=l||void 0,i.locale=u,a&&$({country:o,language:l,locale:r}),!f)return L(),g.state;t!==void 0&&we();let W=Te(o);return L(),A("country-changed",{country:o,language:i.language}),await Promise.all(W),g.state}function y(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function Pe(e){return y(e)&&y(e.__core)&&y(e.__parts)}function B(e,t){let n=Reflect.get(window,"Tether");if(!Pe(n))throw new Error(`tether.${e}.js runs after the Tether script, which loads it, and needs its window.Tether`);n.__parts[e]=t}B("markets",b);})();
|