@occluze/tether 0.7.0 → 0.7.2
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 +51 -109
- package/dist/esm/astro.js +1 -1
- package/dist/esm/chunks/{account-UIPWJQ3Y.js → account-W4FBRKXA.js} +1 -1
- package/dist/esm/chunks/{account-pages-6ROA6Y4V.js → account-pages-IM3OQTOP.js} +1 -1
- package/dist/esm/chunks/analytics-QDVOLZY3.js +1 -0
- package/dist/esm/chunks/{chunk-T44MUL4Y.js → chunk-AUVAN3KZ.js} +1 -1
- package/dist/esm/chunks/chunk-BMDYNMRC.js +1 -0
- package/dist/esm/chunks/chunk-CUL66KRA.js +1 -0
- package/dist/esm/chunks/{chunk-6OZJCAGZ.js → chunk-CVNRODH3.js} +1 -1
- package/dist/esm/chunks/{chunk-5Z5O3767.js → chunk-CXHPBT7N.js} +1 -1
- package/dist/esm/chunks/chunk-GF6JTI65.js +1 -0
- package/dist/esm/chunks/chunk-MRSDJPBC.js +1 -0
- package/dist/esm/chunks/chunk-NYDZPTLP.js +1 -0
- package/dist/esm/chunks/chunk-QDHLXXAZ.js +1 -0
- package/dist/esm/chunks/{chunk-4GCXM764.js → chunk-QUECUXHD.js} +1 -1
- package/dist/esm/chunks/chunk-RJY76ESL.js +1 -0
- package/dist/esm/chunks/chunk-RPI5C3EJ.js +1 -0
- package/dist/esm/chunks/{chunk-BFTZR4OB.js → chunk-YC4JXWRG.js} +2 -2
- package/dist/esm/chunks/{diagnose-3FEKRIEK.js → diagnose-3XHPZZNP.js} +1 -1
- package/dist/esm/chunks/extras-C724KKG6.js +1 -0
- package/dist/esm/chunks/{markets-ui-FD6NI2OG.js → markets-ui-WBWWQAGU.js} +1 -1
- package/dist/esm/chunks/{search-UJ73YBQ5.js → search-5NFIZBPJ.js} +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/server.js +2 -2
- package/dist/tether.account-pages.js +13 -3
- package/dist/tether.account-pages.min.js +1 -1
- package/dist/tether.account.js +13 -3
- package/dist/tether.account.min.js +1 -1
- package/dist/tether.analytics.js +18 -3
- package/dist/tether.analytics.min.js +1 -1
- package/dist/tether.diagnose.js +20 -5
- package/dist/tether.diagnose.min.js +2 -2
- package/dist/tether.extras.js +52 -28
- package/dist/tether.extras.min.js +1 -1
- package/dist/tether.js +353 -288
- package/dist/tether.markets.js +31 -5
- package/dist/tether.markets.min.js +1 -1
- package/dist/tether.min.js +2 -2
- package/dist/tether.min.js.map +4 -4
- package/dist/tether.search.js +18 -3
- package/dist/tether.search.min.js +1 -1
- package/dist/types/server/src/shared/cart-id.d.ts +2 -0
- package/dist/types/src/cart/mutations.d.ts +6 -0
- package/dist/types/src/cart/store.d.ts +5 -2
- package/dist/types/src/cart.d.ts +3 -2
- package/dist/types/src/client.d.ts +61 -22
- package/dist/types/src/config.d.ts +6 -1
- package/dist/types/src/index.d.ts +2 -2
- package/dist/types/src/markets.d.ts +9 -2
- package/dist/types/src/product-shape.d.ts +3 -1
- package/dist/types/src/uri.d.ts +6 -0
- package/package.json +54 -6
- package/dist/esm/chunks/analytics-2V632IRV.js +0 -1
- package/dist/esm/chunks/chunk-56FCLJJD.js +0 -1
- package/dist/esm/chunks/chunk-A5SYCVQM.js +0 -1
- package/dist/esm/chunks/chunk-BA4LQJJQ.js +0 -1
- package/dist/esm/chunks/chunk-C5JYQCWH.js +0 -1
- package/dist/esm/chunks/chunk-E5YO6274.js +0 -1
- package/dist/esm/chunks/chunk-MPDWM2NN.js +0 -1
- package/dist/esm/chunks/chunk-YLUULATY.js +0 -1
- package/dist/esm/chunks/extras-6POFBNOP.js +0 -1
- package/src/account/addresses-view.ts +0 -58
- package/src/account/answers.ts +0 -79
- package/src/account/markup.ts +0 -36
- package/src/account/operations.ts +0 -145
- package/src/account/order-lines.ts +0 -75
- package/src/account/order-list.ts +0 -107
- package/src/account/order-page.ts +0 -137
- package/src/account/page-answers.ts +0 -317
- package/src/account/page-events.ts +0 -253
- package/src/account/server-client.ts +0 -183
- package/src/account/subscriptions-view.ts +0 -115
- package/src/account-api.ts +0 -98
- package/src/account-marks.ts +0 -35
- package/src/account-pages.ts +0 -81
- package/src/account.ts +0 -284
- package/src/amounts.ts +0 -64
- package/src/analytics-shopify.ts +0 -246
- package/src/analytics.ts +0 -315
- package/src/api-version.ts +0 -79
- package/src/astro.ts +0 -272
- package/src/cart/cart-shape.ts +0 -25
- package/src/cart/checkout.ts +0 -101
- package/src/cart/drawer.ts +0 -125
- package/src/cart/mutations.ts +0 -237
- package/src/cart/render.ts +0 -266
- package/src/cart/store.ts +0 -279
- package/src/cart.ts +0 -345
- package/src/client.ts +0 -391
- package/src/collection.ts +0 -175
- package/src/config-sections.ts +0 -284
- package/src/config.ts +0 -480
- package/src/controls/cart-controls.ts +0 -123
- package/src/controls/discount.ts +0 -75
- package/src/controls/extras.ts +0 -54
- package/src/controls/navigation.ts +0 -77
- package/src/diagnose-markup.ts +0 -298
- package/src/diagnose.ts +0 -294
- package/src/dom.ts +0 -268
- package/src/extras.ts +0 -136
- package/src/fragments.ts +0 -261
- package/src/globals.d.ts +0 -15
- package/src/images.ts +0 -91
- package/src/index.ts +0 -415
- package/src/initial.ts +0 -101
- package/src/lazy-iife.ts +0 -197
- package/src/lazy.ts +0 -42
- package/src/loader.ts +0 -363
- package/src/market-codes.ts +0 -6
- package/src/markets-ui.ts +0 -227
- package/src/markets.ts +0 -246
- package/src/markup.ts +0 -127
- package/src/mounting.ts +0 -264
- package/src/page-market.ts +0 -110
- package/src/part-integrity.ts +0 -7
- package/src/parts/account-pages.ts +0 -7
- package/src/parts/account.ts +0 -7
- package/src/parts/analytics.ts +0 -7
- package/src/parts/diagnose.ts +0 -7
- package/src/parts/extras.ts +0 -7
- package/src/parts/markets.ts +0 -7
- package/src/parts/search.ts +0 -7
- package/src/presets/barba.ts +0 -194
- package/src/product-events.ts +0 -115
- package/src/product-render.ts +0 -218
- package/src/product-shape.ts +0 -49
- package/src/product-state.ts +0 -318
- package/src/product.ts +0 -308
- package/src/repeaters.ts +0 -161
- package/src/search.ts +0 -305
- package/src/selling-plans.ts +0 -145
- package/src/server.ts +0 -211
- package/src/shopify-values.ts +0 -91
- package/src/status.ts +0 -106
- package/src/storage.ts +0 -34
- package/src/store-html.ts +0 -359
- package/src/storefront/catalog.ts +0 -196
- package/src/storefront/json-ld.ts +0 -144
- package/src/variant-render.ts +0 -139
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{var
|
|
1
|
+
(()=>{var U=Object.defineProperty;var $=(t,n)=>{for(var e in n)U(t,e,{get:n[e],enumerable:!0})};var k={};$(k,{startAnalytics:()=>yt});var G=window.Tether.__core["config.ts"],[a,bt,_,vt,wt,l,Tt]=G;var W=window.Tether.__core["dom.ts"],[C,_t,Ct,Et,xt,At,Pt,St,Lt,E,Nt,It,Rt,Vt,p,Dt,Mt,qt]=W;var Y=window.Tether.__core["cart.ts"],[b]=Y;var H=window.Tether.__core["product.ts"],[x]=H;var J=window.Tether.__core["client.ts"],[jt,A,Ut,P,$t]=J;var Z=500,S={"default-banner":"https://cdn.shopify.com/shopifycloud/privacy-banner/storefront-banner.js",other:"https://cdn.shopify.com/shopifycloud/consent-tracking-api/v0.2/consent-tracking-api.js"},z="https://cdn.shopify.com/storefront/analytics/shopify.js",N=()=>window,y=()=>N().Shopify;function I(){let t=a.analytics?.shopify;return typeof t=="object"?t:{}}function R(){try{let t=y()?.customerPrivacy;return t?.consentStatus==="loaded"&&t.currentVisitorConsent?.()?.analytics!=="no"&&!!t.analyticsProcessingAllowed?.()}catch{return!1}}function K(t){let n=`hydrogen:${t}`;return{getTrackingValues:()=>{let e=R()?y()?.customerPrivacy?.__internal:void 0;return{uniqueToken:e?.uniqueToken?.({generateFallback:!0,tag:n})??"",visitToken:e?.visitToken?.({generateFallback:!0,tag:n})??""}}}}var X=t=>(n,e)=>{let r=t.subscribers.get(n)??new Set;return t.subscribers.set(n,r),r.add(e),()=>t.subscribers.get(n)?.delete(e)};function Q(t){let n=[],e=[],r={shop:{shopId:t,channel:"headless"},consent:{mode:I().consent||"no-banner"}},o=()=>{if(R())for(let i of n)for(;i.next<e.length;i.next+=1){let s=e[i.next];s&&tt(i,s)}},c={getConfig:()=>r,publish(i,s={}){if(e.push({event:i,payload:{shop:r.shop,url:window.location.href,...s}}),e.length>Z){e.shift();for(let u of n)u.next=Math.max(0,u.next-1)}o()},addDestination(i){let s={name:i.name,next:0,subscribers:new Map,context:K(i.name)};return Promise.resolve(i.setup?.({subscribe:X(s),getConfig:c.getConfig})).then(()=>{n.push(s),o()}).catch(u=>{l(u,`analytics ${i.name}`)}),()=>{let u=n.indexOf(s);u>=0&&n.splice(u,1)}}};return document.addEventListener("consentTrackingApiLoaded",o),document.addEventListener("visitorConsentCollected",o),c}function tt(t,{event:n,payload:e}){t.subscribers.get(n)?.forEach(r=>{try{r(e,t.context)}catch(o){l(o,`analytics ${t.name}`)}})}function L(t){let n=document.createElement("script");n.src=t,n.async=!0,document.head.appendChild(n)}async function V(t){let n=y();if(n?.analytics)return n.analytics;let e=await A("query TetherShopId { shop { id } }",{},P({shop:{id:"string"}}),{context:!1}),r=y()??{};N().Shopify=r,r.country=a.country??"US";let[o="en"]=(a.locale||"en").split("-");r.locale=o.toLowerCase(),r.shop=a.domain,r.routes={root:"/",match:()=>({pageTemplateName:t()?"product":"page"}),...r.routes};let{proxy:c,consent:i}=I();r.customerPrivacy={...r.customerPrivacy,config:c?{isHeadless:!0,asyncConsent:!0,asyncVisitorState:!0,consentDomain:window.location.host}:{isHeadless:!0,storefrontAccessToken:a.token,checkoutRootDomain:a.domain}};let s=Q(e.shop.id);return r.analytics=s,L(i==="default-banner"?S["default-banner"]:S.other),L(z),_("shopify analytics ready",e.shop.id),s}var nt="Default Title",D=100,et=200,rt=t=>t?parseFloat(t.amount):0,M=t=>(t??"").split("/").pop()??"";function T(t,n,e=1,r){let o={item_id:n?.sku||M(n?.id)||M(t.id),item_name:t.title,item_variant:n?.title===nt?void 0:n?.title,item_brand:t.vendor||void 0,item_category:t.productType||void 0,price:rt(n?.price??t.priceRange?.minVariantPrice),quantity:e};return r!=null&&(o.index=r),o}var h=(t,n=t.quantity)=>T(t.merchandise.product,t.merchandise,n);function f(t){let n=t.reduce((e,r)=>e+r.price*(r.quantity||1),0);return Math.round(n*D)/D}var ot=(t,n,e=1)=>({id:t.id,title:t.title,price:n.price,vendor:t.vendor||"",variantId:n.id,variantTitle:n.title,quantity:e,sku:n.sku||void 0,productType:t.productType||void 0}),q=t=>({id:t.id,quantity:t.quantity,merchandise:{id:t.merchandise.id,title:t.merchandise.title,price:t.merchandise.price,sku:t.merchandise.sku,product:{id:t.merchandise.product.id,title:t.merchandise.product.title,vendor:t.merchandise.product.vendor||"",handle:t.merchandise.product.handle}}});function it(){let{dataLayer:t}=a.analytics??{},n=typeof t=="string"?t:"dataLayer",e=Reflect.get(window,n);if(Array.isArray(e))return e;let r=[];return Reflect.set(window,n,r),r}function st(t,n){let e=it();if(!n){e.push({event:t});return}e.push({ecommerce:null}),e.push({event:t,ecommerce:n})}var m=null,v=null,O=null,w=new WeakSet;function d(t,n,e,r){a.analytics?.dataLayer&&st(t,n),m&&e&&m.publish(e,r);try{a.analytics?.onEvent?.(t,n)}catch(o){l(o,"analytics onEvent")}}function F(){let t=document.querySelector(p("product"));return!t||t.closest(`${p("collection")},${p("products")},${p("recommendations")}`)?null:x.get(t)??null}function at({product:t,scope:n}){if(w.has(n.root)||F()!==n)return;w.add(n.root);let e=n.variant??t.variants.nodes[0],r=[T(t,e)],o=e?[ot(t,e)]:[];d("view_item",{currency:e?.price.currencyCode,value:f(r),items:r},"product_viewed",{products:o})}function ct({products:t,collection:n}){let e=t.slice(0,et).map((o,c)=>T(o,o.variants.nodes[0],1,c)),r={item_list_id:n?.handle||"products",item_list_name:n?.title||"Products"};if(!n){d("view_item_list",{...r,items:e});return}d("view_item_list",{...r,items:e},"collection_viewed",{collection:{id:n.id,handle:n.handle}})}function ut(t,n,e){let r=t?.cost.totalAmount.currencyCode;n.forEach((o,c)=>{let i=e.get(c),s=o.quantity-(i?.quantity??0);if(s<=0)return;let u=[h(o,s)];d("add_to_cart",{currency:r,value:f(u),items:u},"product_added_to_cart",{cart:t,prevCart:O,currentLine:q(o),prevLine:i?q(i):void 0})}),e.forEach((o,c)=>{let i=o.quantity-(n.get(c)?.quantity??0);if(i<=0)return;let s=[h(o,i)];d("remove_from_cart",{currency:r,value:f(s),items:s})})}function dt({cart:t,reason:n}){let e=new Map((t?.lines.nodes??[]).map(r=>[r.merchandise.id,r]));v&&n!=="load"&&n!=="pending"&&ut(t,e,v),v=e,O=t}function lt(){let t=b.lines.map(n=>h(n));d("view_cart",{currency:b.state?.cost.totalAmount.currencyCode,value:f(t),items:t})}function pt({cart:t}){if(!t)return;let n=t.lines.nodes.map(r=>h(r)),e=t.discountCodes.filter(r=>r.applicable).map(r=>r.code);d("begin_checkout",{currency:t.cost.totalAmount.currencyCode,value:f(n),coupon:e.join(",")||void 0,items:n})}var ft={"product-ready":at,"list-ready":ct,"cart-updated":dt,"cart-toggled":({open:t})=>{t&<()},checkout:pt,search:({term:t})=>{t&&d("search",{search_term:t},"search_viewed",{searchTerm:t})}};function mt(t,n){ft[n](t.detail)}function B(t){if(t.type==="astro:page-load"){w=new WeakSet,m?.publish("page_viewed",{});return}C.forEach(n=>{E(t,n)&&mt(t,n)})}async function yt(t){a.analytics?.shopify&&(m=await V(()=>F()!=null).catch(n=>(l(n,"shopify analytics"),null))),m?.publish("page_viewed",{}),t.splice(0).forEach(B),t.push=(...n)=>(n.forEach(B),t.length)}function g(t){return t!==null&&typeof t=="object"&&!Array.isArray(t)}function ht(t){return g(t)&&g(t.__core)&&g(t.__parts)}function j(t,n){let e=Reflect.get(window,"Tether");if(!ht(e))throw new Error(`tether.${t}.js runs after the Tether script, which loads it, and needs its window.Tether`);e.__parts[t]=n}j("analytics",k);})();
|
package/dist/tether.diagnose.js
CHANGED
|
@@ -70,9 +70,9 @@
|
|
|
70
70
|
let note = `supported until about ${supportedUntil.toISOString().slice(0, 7)}`;
|
|
71
71
|
if (!isReleased) note = "not released yet (release candidate at best)";
|
|
72
72
|
else if (monthsLeft <= 0) {
|
|
73
|
-
note = "no longer supported: Shopify falls back to the oldest supported version. Upgrade (see
|
|
73
|
+
note = "no longer supported: Shopify falls back to the oldest supported version. Upgrade (see docs/reference.md)";
|
|
74
74
|
} else if (monthsLeft < UPGRADE_WARNING_MONTHS) {
|
|
75
|
-
note = `${note}: plan the upgrade to ${nextApiVersion(version)} or later (see
|
|
75
|
+
note = `${note}: plan the upgrade to ${nextApiVersion(version)} or later (see docs/reference.md)`;
|
|
76
76
|
}
|
|
77
77
|
return {
|
|
78
78
|
version,
|
|
@@ -522,8 +522,23 @@
|
|
|
522
522
|
console.groupEnd();
|
|
523
523
|
}
|
|
524
524
|
|
|
525
|
+
// server/src/shared/json.ts
|
|
526
|
+
function isRecord(value) {
|
|
527
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
// src/part-registry.ts
|
|
531
|
+
function isTetherInternals(value) {
|
|
532
|
+
return isRecord(value) && isRecord(value["__core"]) && isRecord(value["__parts"]);
|
|
533
|
+
}
|
|
534
|
+
function registerPart(name, part) {
|
|
535
|
+
const tether = Reflect.get(window, "Tether");
|
|
536
|
+
if (!isTetherInternals(tether)) {
|
|
537
|
+
throw new Error(`tether.${name}.js runs after the Tether script, which loads it, and needs its window.Tether`);
|
|
538
|
+
}
|
|
539
|
+
tether.__parts[name] = part;
|
|
540
|
+
}
|
|
541
|
+
|
|
525
542
|
// src/parts/diagnose.ts
|
|
526
|
-
|
|
527
|
-
if (!Tether) throw new Error("tether.diagnose.js runs after the Tether script, which loads it");
|
|
528
|
-
Tether.__parts.diagnose = diagnose_exports;
|
|
543
|
+
registerPart("diagnose", diagnose_exports);
|
|
529
544
|
})();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(()=>{var
|
|
1
|
+
(()=>{var L=Object.defineProperty;var Y=(e,n)=>{for(var t in n)L(e,t,{get:n[t],enumerable:!0})};var P={};Y(P,{apiVersionStatus:()=>y,checkMarkup:()=>k,diagnose:()=>ke,didYouMean:()=>f});var G=window.Tether.__core["config.ts"],[a,E,$e,Re,Te,Ae,_e]=G;var B=window.Tether.__core["client.ts"],[$,R,Ne,T,xe]=B;var Q=window.Tether.__core["dom.ts"],[De,p,Oe,Ve,Ue,Ie,m,Ce,A,qe,He,Le,d,Ye,l,Ge,Be,Qe]=Q;var j=window.Tether.__core["loader.ts"],[Ke,_]=j;var K=window.Tether.__core["selling-plans.ts"],[v]=K;var W=window.Tether.__core["status.ts"],[N,h]=W;var F=/^(\d{4})-(01|04|07|10)$/;function M(e){let n=F.exec(typeof e=="string"?e:"");return n?{year:Number(n[1]),month:Number(n[2])}:null}var z=(e,n)=>`${e}-${String(n).padStart(2,"0")}`;function x(e,n=1){let t=M(e);if(!t)throw new Error(`not a quarterly Shopify API version: ${e}`);let r=t.year*4+(t.month-1)/3+n;return z(Math.floor(r/4),r%4*3+1)}function y(e,n=new Date){if(e==="unstable")return{version:e,ok:!1,note:'"unstable" changes without notice: pin a dated version such as 2026-07'};let t=M(e);if(!t)return{version:e,ok:!1,note:"not a quarterly version (YYYY-01, -04, -07 or -10)"};let r=new Date(Date.UTC(t.year,t.month-1,1)),s=new Date(Date.UTC(t.year,t.month-1+12,1)),o=(s.getTime()-n.getTime())/2630016e3,i=r<=n,c=`supported until about ${s.toISOString().slice(0,7)}`;return i?o<=0?c="no longer supported: Shopify falls back to the oldest supported version. Upgrade (see docs/reference.md)":o<3&&(c=`${c}: plan the upgrade to ${x(e)} or later (see docs/reference.md)`):c="not released yet (release candidate at best)",{version:e,ok:i&&o>0,monthsLeft:Math.round(o),next:x(e),note:c}}var J=window.Tether.__core["lazy.ts"],[D]=J;var O=new Set(["in-stock","out-of-stock","backorder","low-stock","plenty-in-stock","on-sale","not-on-sale","has-variants","single-variant","subscription-available","subscription-unavailable","subscription-only","one-time-available","subscription-selected","one-time-selected","has-savings","loading","ready","error","not-found","cart-empty","cart-filled","cart-has-subscription","cart-no-subscription","cart-has-discount","cart-error","cart-warning","list-empty","list-filled","search-empty","search-results","logged-in","logged-out","orders-empty","orders-loading","addresses-loading","addresses-empty","addresses-error","subscriptions-loading","subscriptions-empty","subscriptions-error"]),V=new Set(["title","description","description-text","vendor","type","handle","published-at","price","total-price","compare-at-price","unit-price","min-price","max-price","discount-percentage","discount-amount","variant-title","variant-id","sku","barcode","stock","quantity","featured-image","variant-image","images","tags","link","url","one-time-price","subscription-price","subscription-savings","subscription-savings-amount","checkout-charge","plan-name","plan-description","plan-group","option-value","swatch","image"]),U=new Set(`account account-bind account-link account-login account-logout add-label add-to-cart adding-text
|
|
2
2
|
always-enabled bind cart-checkout-charge cart-clear cart-close cart-count cart-discounts cart-drawer cart-label cart-lines
|
|
3
3
|
cart-note cart-open cart-subtotal cart-total cart-warning checkout code collection collection-bind countries country
|
|
4
4
|
country-bind country-label country-select default-plan default-purchase discount discount-code discount-form discount-input
|
|
@@ -11,4 +11,4 @@
|
|
|
11
11
|
plan-value product products purchase purchase-mode qty qty-minus qty-plus quantity recommendations reverse search
|
|
12
12
|
search-bind search-collections search-input search-limit search-min search-products search-queries search-results
|
|
13
13
|
search-state show soldout-text sort state subscribe-text variant variant-select variant-url max-width max-height crop
|
|
14
|
-
sig label hydrated busy`.split(/\s+/).filter(Boolean)),
|
|
14
|
+
sig label hydrated busy`.split(/\s+/).filter(Boolean)),X=["bind","option-list","option","variant-select","add-to-cart","purchase","plan-list","plan","qty","line-attribute"],Z=["option-list","plan-list","cart-lines","list"],w="metafield:",ee=/^image:\d+$/,te=2;function ne(e,n){let t=Array.from({length:n.length+1},(r,s)=>s);for(let r=1;r<=e.length;r++){let s=[r];for(let o=1;o<=n.length;o++){let i=(t[o-1]??0)+(e[r-1]===n[o-1]?0:1);s.push(Math.min((t[o]??0)+1,(s[o-1]??0)+1,i))}t=s}return t[n.length]??0}function f(e,n,t=""){let r=null,s=1/0;for(let i of n){let c=ne(e,i);c<s&&(s=c,r=i)}let o=Math.max(2,Math.floor(e.length/4));return r!==null&&s<=o?` Did you mean "${t}${r}"?`:""}function re(e){let n=e.id?`#${e.id}`:"",t=e.className&&typeof e.className=="string"?e.className.trim().split(/\s+/):[],r=t.length?`.${t.slice(0,te).join(".")}`:"";return`<${e.tagName.toLowerCase()}${n}${r}>`}var I=()=>`${l("collection")},${l("products")},${l("recommendations")}`;function oe(e,n){d(e,l("product")).forEach(t=>{if(t.closest(I())&&t.closest(l("list")))return;let{key:r,fromUrl:s,raw:o}=h(t);o?s&&!r&&n("warn",`${p("product")}="${o}" but this URL has no value for it (e.g. ?handle=my-product).`,t):n("error",`${p("product")} has no value. Bind it to the Shopify handle (CMS field), or use "url:handle".`,t)})}function se(e,n){for(let t of X)d(e,l(t)).forEach(r=>{r.closest(l("product"))||t==="line-attribute"&&r.closest(l("group"))||n("warn",`${p(t)} outside any ${p("product")}: it does nothing here.`,r)});d(e,l("group-add")).forEach(t=>{t.closest(l("group"))||n("warn",`${p("group-add")} outside a ${p("group")}.`,t)});for(let t of Z)d(e,l(t)).forEach(r=>{!r.firstElementChild&&!A(r)&&n("warn",`${p(t)} without a template child: put one example element inside it.`,r)});d(e,I()).forEach(t=>{d(t,l("list")).length||n("error",`List without a ${p("list")} child: products have nowhere to render.`,t)})}function ie(e,n){d(e,l("show")).forEach(t=>{let r=m(t,"show")??"";O.has(r)||n("warn",`Unknown ${p("show")}="${r}".${f(r,O)}`,t)}),d(e,l("bind")).forEach(t=>{let r=m(t,"bind")||"";!r||V.has(r)||ee.test(r)||r.startsWith(w)||n("warn",`Unknown ${p("bind")}="${r}": it stays empty.${f(r,V)}`,t)})}function ae(e,n){d(e,l("bind")).forEach(t=>{let r=m(t,"bind")||"";if(!r.startsWith(w))return;let s=r.slice(w.length);a.metafields.some(i=>(typeof i=="string"?i:`${i.namespace}.${i.key}`)===s)||n("error",`${p("bind")}="${r}" but "${s}" is not in config.metafields, so it stays empty.`,t)})}function ce(e,n){let t=`${a.prefix}-`,r=new Set;d(e,"*").forEach(s=>{for(let{name:o}of s.attributes){if(!o.startsWith(t))continue;let i=o.slice(t.length);U.has(i)||r.has(i)||(r.add(i),n("warn",`Unknown attribute ${o}: Tether ignores it.${f(i,U,t)}`,s))}})}function le(e,n){let t=d(e,l("cart-drawer")).length;d(e,l("cart-open")).length&&!t&&n("warn",`${p("cart-open")} exists but there is no ${p("cart-drawer")} on this page.`),t>1&&n("warn",`More than one ${p("cart-drawer")}.`),d(e,`[${p("state")}="error"]`).forEach(r=>{r.matches(N())&&n("error",`Scope failed to load (${m(r,"error")||"error"}).`,r)})}function k(e=document){let n=[],t=(r,s,o)=>{n.push(o?{level:r,message:s,element:re(o),el:o}:{level:r,message:s})};return oe(e,t),se(e,t),ie(e,t),ce(e,t),ae(e,t),le(e,t),n}var ue=20,de=3,C=4;function pe(e){return e?`${e.slice(0,C)}\u2026${e.slice(-C)} (${e.length} chars)`:"(missing)"}function q(e,n){if(e instanceof Error&&e.message)return e.message;let t=typeof e=="object"&&e!==null?Reflect.get(e,"code"):void 0;return typeof t=="string"&&t?t:n}function me(){return{domain:a.domain||"(missing)",token:pe(a.token),apiVersion:a.apiVersion,endpoint:a.domain?$():null,country:a.country,language:a.language,locale:a.locale,markets:a.markets,prefix:a.prefix,productPath:a.productPath,metafields:a.metafields,autoMount:a.autoMount,observe:a.observe,onError:typeof a.onError=="function"}}async function fe(){return{country:a.country||null,language:a.language||null,locale:a.locale||null,detected:a.markets?.detect?(await D("markets")).detectMarket(a.markets):null}}function ge({ok:e,monthsLeft:n,note:t}){return e&&(n===void 0||n>=de)?null:{level:e?"warn":"error",message:`apiVersion ${a.apiVersion}: ${t}`}}var he=T({shop:{name:"string",primaryDomain:{url:"string"},paymentSettings:{currencyCode:"string"}}});async function be(){if(!E())return{kind:"not-configured"};let e=Date.now();try{let n=await R("query TetherDiagnose { shop { name primaryDomain { url } paymentSettings { currencyCode } } }",{},he,{context:!1});return{kind:"reachable",shop:{name:n.shop.name,url:n.shop.primaryDomain.url,currency:n.shop.paymentSettings.currencyCode},latencyMs:Date.now()-e}}catch(n){return{kind:"unreachable",error:n,latencyMs:Date.now()-e}}}function ye(e,n,t){let r=[],s=t.options.map(i=>i.name),o=d(e,l("product")).filter(i=>h(i).key===n&&i.querySelector(l("add-to-cart")));for(let i of o){let c=new Set(d(i,`${l("option-list")},select${l("option")}`).map(u=>m(u,"option-list")||m(u,"option")));if(!(!c.size&&d(i,`select${l("variant-select")}`).length)){if(!a.language)for(let u of c)!u||s.includes(u)||r.push({level:"warn",message:`Product "${t.handle}" has no option "${u}" (its options: ${s.join(", ")||"none"}).${f(u,s)}`});for(let u of t.options)u.optionValues.length<=1||c.has(u.name)||r.push({level:"warn",message:`Product "${t.handle}": option "${u.name}" (${u.optionValues.length} values) has no tether-option-list, so visitors can't choose it.`})}}return r}async function we(e,n){let t=d(e,l("product")).map(o=>h(o).key),r=[...new Set(t.filter(o=>o!==null&&o!==""))].slice(0,ue);(await Promise.allSettled(r.map(o=>_(o)))).forEach((o,i)=>{let c=r[i]??"";if(o.status==="rejected"){let g=q(o.reason,"not loaded");n.products.push({key:c,error:o.reason instanceof Error?o.reason.message:void 0}),n.problems.push({level:"error",message:`Product "${c}": ${g}. Is it published to the Headless channel?`});return}let u=o.value,S=v(u);n.products.push({key:c,handle:u.handle,title:u.title,plans:S.length,requiresSellingPlan:u.requiresSellingPlan});for(let g of S)n.sellingPlans.push({product:u.handle,group:g.group.name,plan:g.name,id:g.id});n.problems.push(...ye(e,c,u))})}async function ke({root:e=document,silent:n=!1,version:t="",now:r=new Date}={}){let s=await be(),o={version:t,config:me(),apiVersion:y(a.apiVersion,r),market:await fe(),reachable:s.kind==="reachable",shop:s.kind==="reachable"?s.shop:null,latencyMs:s.kind==="not-configured"?null:s.latencyMs,products:[],sellingPlans:[],problems:[]};switch(s.kind){case"not-configured":o.problems.push({level:"error",message:"TETHER_CONFIG needs domain and token."});break;case"unreachable":o.problems.push({level:"error",message:`Storefront API not reachable: ${q(s.error,"unknown error")}`});break;case"reachable":await we(e,o);break}let i=ge(o.apiVersion);return i&&o.problems.push(i),typeof document<"u"&&o.problems.push(...k(e)),n||Pe(o),o}function Pe(e){let n=e.problems.filter(c=>c.level==="error").length,t=e.problems.length-n;console.group(`[${a.prefix}] diagnose: ${n?`${n} error(s)`:"no errors"}, ${t} warning(s)`),console.log("version",e.version,"| API",e.apiVersion.version,`(${e.apiVersion.note})`),console.log("config",e.config);let{country:r,language:s,detected:o}=e.market,i=[r,s].filter(Boolean).join(" / ")||"the store default";console.log("market",`in use: ${i}`,o?`(detection picks ${JSON.stringify(o)})`:""),console.log(e.shop?`Storefront API reachable: ${e.shop.name} (${e.latencyMs??0} ms)`:"Storefront API NOT reachable"),e.products.length&&console.table(e.products),e.sellingPlans.length?console.table(e.sellingPlans):e.reachable&&console.log("No selling plans on the products of this page.");for(let c of e.problems)c.level==="error"?console.error(c.message,c.el??""):console.warn(c.message,c.el??"");console.groupEnd()}function b(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function Se(e){return b(e)&&b(e.__core)&&b(e.__parts)}function H(e,n){let t=Reflect.get(window,"Tether");if(!Se(t))throw new Error(`tether.${e}.js runs after the Tether script, which loads it, and needs its window.Tether`);t.__parts[e]=n}H("diagnose",P);})();
|
package/dist/tether.extras.js
CHANGED
|
@@ -29,10 +29,36 @@
|
|
|
29
29
|
var m4 = window.Tether.__core["cart.ts"];
|
|
30
30
|
var [Cart] = m4;
|
|
31
31
|
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
// tether-core:page-market.ts
|
|
33
|
+
var m5 = window.Tether.__core["page-market.ts"];
|
|
34
|
+
var [setCountry] = m5;
|
|
35
|
+
|
|
36
|
+
// tether-core:market-codes.ts
|
|
37
|
+
var m6 = window.Tether.__core["market-codes.ts"];
|
|
38
|
+
var [toCountry, toLanguage] = m6;
|
|
39
|
+
|
|
40
|
+
// src/markets.ts
|
|
41
|
+
var storageKey = () => `${cfg.prefix}:market:${cfg.domain}`;
|
|
42
|
+
function parseJsonOrNull(text) {
|
|
43
|
+
try {
|
|
44
|
+
return JSON.parse(text);
|
|
45
|
+
} catch (error) {
|
|
46
|
+
if (error instanceof SyntaxError) return null;
|
|
47
|
+
throw error;
|
|
48
|
+
}
|
|
35
49
|
}
|
|
50
|
+
function toMarket(value) {
|
|
51
|
+
if (typeof value !== "object" || value === null) return null;
|
|
52
|
+
const country = toCountry(Reflect.get(value, "country"));
|
|
53
|
+
if (!country) return null;
|
|
54
|
+
const locale = Reflect.get(value, "locale");
|
|
55
|
+
return {
|
|
56
|
+
country,
|
|
57
|
+
language: toLanguage(Reflect.get(value, "language")) ?? void 0,
|
|
58
|
+
locale: typeof locale === "string" && locale ? locale : void 0
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
var parseSavedMarket = (text) => toMarket(parseJsonOrNull(text));
|
|
36
62
|
|
|
37
63
|
// src/extras.ts
|
|
38
64
|
function groupAttributes(group, name) {
|
|
@@ -63,22 +89,6 @@
|
|
|
63
89
|
return null;
|
|
64
90
|
}
|
|
65
91
|
}
|
|
66
|
-
function parseStoredMarket(text) {
|
|
67
|
-
let value;
|
|
68
|
-
try {
|
|
69
|
-
value = JSON.parse(text);
|
|
70
|
-
} catch {
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
if (!isRecord(value)) return null;
|
|
74
|
-
const { country, language, locale } = value;
|
|
75
|
-
if (typeof country !== "string" || !country) return null;
|
|
76
|
-
return {
|
|
77
|
-
country,
|
|
78
|
-
language: typeof language === "string" ? language : null,
|
|
79
|
-
locale: typeof locale === "string" ? locale : void 0
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
92
|
function onStorage(event) {
|
|
83
93
|
if (event.key === cfg.storageKey || event.key === `${cfg.storageKey}:seen`) {
|
|
84
94
|
Cart.init().catch((error) => {
|
|
@@ -86,12 +96,11 @@
|
|
|
86
96
|
});
|
|
87
97
|
return;
|
|
88
98
|
}
|
|
89
|
-
if (event.key !==
|
|
90
|
-
const market =
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
tether.setCountry(market.country, options).catch((error) => {
|
|
99
|
+
if (event.key !== storageKey() || !event.newValue) return;
|
|
100
|
+
const market = parseSavedMarket(event.newValue);
|
|
101
|
+
if (!market) return;
|
|
102
|
+
const options = { language: market.language ?? null, locale: market.locale, remember: false };
|
|
103
|
+
setCountry(market.country, options).catch((error) => {
|
|
95
104
|
reportError(error, "market from another tab");
|
|
96
105
|
});
|
|
97
106
|
}
|
|
@@ -117,8 +126,23 @@
|
|
|
117
126
|
replaceUrlIfAllowed(url);
|
|
118
127
|
}
|
|
119
128
|
|
|
129
|
+
// server/src/shared/json.ts
|
|
130
|
+
function isRecord(value) {
|
|
131
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// src/part-registry.ts
|
|
135
|
+
function isTetherInternals(value) {
|
|
136
|
+
return isRecord(value) && isRecord(value["__core"]) && isRecord(value["__parts"]);
|
|
137
|
+
}
|
|
138
|
+
function registerPart(name, part) {
|
|
139
|
+
const tether = Reflect.get(window, "Tether");
|
|
140
|
+
if (!isTetherInternals(tether)) {
|
|
141
|
+
throw new Error(`tether.${name}.js runs after the Tether script, which loads it, and needs its window.Tether`);
|
|
142
|
+
}
|
|
143
|
+
tether.__parts[name] = part;
|
|
144
|
+
}
|
|
145
|
+
|
|
120
146
|
// src/parts/extras.ts
|
|
121
|
-
|
|
122
|
-
if (!Tether) throw new Error("tether.extras.js runs after the Tether script, which loads it");
|
|
123
|
-
Tether.__parts.extras = extras_exports;
|
|
147
|
+
registerPart("extras", extras_exports);
|
|
124
148
|
})();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{var
|
|
1
|
+
(()=>{var N=Object.defineProperty;var R=(e,t)=>{for(var n in t)N(e,n,{get:t[n],enumerable:!0})};var f={};R(f,{addGroup:()=>q,onStorage:()=>j,writeVariantUrl:()=>V});var O=window.Tether.__core["config.ts"],[c,Y,Z,P,I,i,p]=O;var v=window.Tether.__core["dom.ts"],[Q,X,m,y,ee,te,k,w,ne,re,h,oe,S,ae,s,ce,ue,ie]=v;var U=window.Tether.__core["product.ts"],[C]=U;var K=window.Tether.__core["cart.ts"],[d]=K;var F=window.Tether.__core["page-market.ts"],[M]=F;var H=window.Tether.__core["market-codes.ts"],[x,b]=H;var E=()=>`${c.prefix}:market:${c.domain}`;function $(e){try{return JSON.parse(e)}catch(t){if(t instanceof SyntaxError)return null;throw t}}function D(e){if(typeof e!="object"||e===null)return null;let t=x(Reflect.get(e,"country"));if(!t)return null;let n=Reflect.get(e,"locale");return{country:t,language:b(Reflect.get(e,"language"))??void 0,locale:typeof n=="string"&&n?n:void 0}}var T=e=>D($(e));function J(e,t){let n=m(h(e,"line-attributes"));return t?[{key:"_group",value:t},...n]:n}async function q(e){let t=e.closest(s("group"));if(!t)return null;let n=k(t,"group"),r=J(t,n),u=S(t,s("product")).flatMap(a=>{let o=C.get(a);if(!o?.variant?.availableForSale||o.quantity<=0)return[];let g=o.getLine();return g?[{...g,attributes:[...g.attributes??[],...r]}]:[]});if(!u.length)return p("group-add: nothing selected"),null;try{let a=await d.add(u);return y("group-added",{group:n,lines:u},t),a}catch(a){return i(a,"group add"),null}}function j(e){if(e.key===c.storageKey||e.key===`${c.storageKey}:seen`){d.init().catch(r=>{i(r,"cart from another tab")});return}if(e.key!==E()||!e.newValue)return;let t=T(e.newValue);if(!t)return;let n={language:t.language??null,locale:t.locale,remember:!1};M(t.country,n).catch(r=>{i(r,"market from another tab")})}var _=new WeakMap,L=e=>e.split("/").pop()??e;function z(e){try{window.history.replaceState(window.history.state,"",e)}catch{}}function V(e,{variant:t,sellingPlanId:n}){let r=`${t.id}|${n??""}`,u=_.get(e);if(_.set(e,r),!u||u===r)return;let a=c.variantUrl&&document.querySelector(s("product"))===e;if(!w(e,"variant-url")&&!a)return;let o=new URL(window.location.href);o.searchParams.set("variant",L(t.id)),n?o.searchParams.set("selling_plan",L(n)):o.searchParams.delete("selling_plan"),z(o)}function l(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function W(e){return l(e)&&l(e.__core)&&l(e.__parts)}function A(e,t){let n=Reflect.get(window,"Tether");if(!W(n))throw new Error(`tether.${e}.js runs after the Tether script, which loads it, and needs its window.Tether`);n.__parts[e]=t}A("extras",f);})();
|