efficient-storefront-blocks 0.77.0 → 0.79.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/dist/chunks/EditorPreviewCheckout-6S2Q3GXI.js +4 -0
- package/dist/chunks/{SiteEditorProvider-R3HXJAPW.js → SiteEditorProvider-B6JGOUMX.js} +1 -1
- package/dist/chunks/chunk-IL5OJ6VZ.js +1 -0
- package/dist/chunks/chunk-NE47RYTU.js +320 -0
- package/dist/chunks/{chunk-GDR5GGVW.js → chunk-WYNB6IMA.js} +1 -1
- package/dist/chunks/chunk-ZA227AIS.js +1 -0
- package/dist/chunks/{fitment-data-JNQKYQIB.js → fitment-data-KCPZ77HO.js} +1 -1
- package/dist/contract.js +1 -1
- package/dist/editor/lib/document/blocks/service/ContactCards/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/FooterEmailSignup/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/FooterMessaging/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/MessagingCards/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/OpeningHours/fields.js +1 -1
- package/dist/editor/lib/document/blocks/service/RateTable/fields.js +1 -1
- package/dist/editor/lib/document/box-header.d.ts +1 -1
- package/dist/editor/lib/document/config.js +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +28 -34
- package/dist/links.js +1 -1
- package/dist/render/app/globals.css +70 -1
- package/dist/render/built-with.json +1 -1
- package/dist/render/components/checkout/checkout-state.js +3 -3
- package/dist/render/components/product-hero/trust-bullets.js +1 -1
- package/dist/render/lib/api/index.d.ts +4 -0
- package/dist/render/lib/api/index.js +1 -1
- package/dist/render/lib/api/types.d.ts +48 -0
- package/dist/render/lib/checkout/pay-first.d.ts +5 -1
- package/dist/render/lib/checkout/pay-first.js +1 -1
- package/dist/render/lib/document/lazy-draws.js +1 -1
- package/dist/render/lib/wheels/plp-grid.d.ts +2 -1
- package/dist/render/lib/wheels/plp-grid.js +1 -1
- package/dist/words.d.ts +11 -0
- package/dist/words.js +4 -4
- package/package.json +3 -3
- package/dist/chunks/EditorPreviewCheckout-GNQP4MQ4.js +0 -4
- package/dist/chunks/chunk-BOJGJXIU.js +0 -311
- package/dist/chunks/chunk-CAULWKXR.js +0 -1
- package/dist/chunks/chunk-ZIZWJZ5T.js +0 -1
- /package/dist/chunks/{chunk-BOJGJXIU.js.LEGAL.txt → chunk-NE47RYTU.js.LEGAL.txt} +0 -0
- /package/dist/chunks/{chunk-OWYNZAAY.js → chunk-PBU5KHED.js} +0 -0
package/dist/links.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var g={bold:{open:"**",close:"**",placeholder:"bold text"},italic:{open:"_",close:"_",placeholder:"italic text"},strike:{open:"~~",close:"~~",placeholder:"struck out"},code:{open:"`",close:"`",placeholder:"code"},highlight:{open:"==",close:"==",placeholder:"highlighted text"},quiet:{open:"^^",close:"^^",placeholder:"quiet text"},underline:{open:"[",close:"]{underline}",placeholder:"underlined text"},sup:{open:"[",close:"]{sup}",placeholder:"superscript"},sub:{open:"[",close:"]{sub}",placeholder:"subscript"}};var Ue={bold:g.bold.placeholder,italic:g.italic.placeholder,strike:g.strike.placeholder,code:g.code.placeholder,highlight:g.highlight.placeholder,quiet:g.quiet.placeholder,link:"link text",underline:g.underline.placeholder,sup:g.sup.placeholder,sub:g.sub.placeholder,color:"colored text",style:"styled text"};var J=[{style:"bold",label:"B",name:"Strong",title:"Strong \xB7 **words** \xB7 \u2318B",shortcut:"b"},{style:"italic",label:"I",name:"Italic",title:"Italic \xB7 _words_ \xB7 \u2318I",shortcut:"i"},{style:"strike",label:"S",name:"Strikethrough",title:"Strikethrough \xB7 ~~words~~"},{style:"highlight",label:"\u25C6",name:"Emphasis",title:"Emphasis \xB7 ==words=="},{style:"quiet",label:"a",name:"Quiet",title:"Quiet \xB7 ^^words^^"},{style:"code",label:"\u2039\u203A",name:"Code",title:"Code"},{style:"link",label:"\u{1F517}",name:"Link",title:"Link \xB7 [words](https://\u2026) \xB7 \u2318K",shortcut:"k"},{style:"bullet",label:"\u2022",name:"Bulleted list",title:"Bulleted list"},{style:"number",label:"1.",name:"Numbered list",title:"Numbered list"},{style:"quote",label:"\u275D",name:"Quote",title:"Quote"},{style:"clear",label:"T\xD7",name:"Clear marks",title:"Clear marks \xB7 \u2318\u21E7X",shortcut:"shift+x"}];var x=[{open:"**",close:"**",kind:"bold"},{open:"==",close:"==",kind:"highlight"},{open:"~~",close:"~~",kind:"strike"},{open:"_",close:"_",kind:"italic",wordBoundary:!0},{open:"^^",close:"^^",kind:"quiet"},{open:"@@",close:"@@",kind:"highlight"},{open:"++",close:"++",kind:"bold",wordStart:!0}],ee=["highlight","quiet"],De=J.map(e=>e.style).filter(e=>x.some(t=>t.kind===e)).filter(e=>!ee.includes(e)),ze=[...x,{open:"*",close:"*",kind:"accent"}],$e=[...x,{open:"*",close:"*",kind:"accent"},{open:"#",close:"#",kind:"bold",notBefore:"0123456789"},{open:"[",close:"]",kind:"italic",notBefore:"(",notBeforeBlock:!0}];var Be=["http","https","mailto","tel"];function v(e){if(e===""||/[\s\u0000-\u001f\u007f]/.test(e))return!1;let t=/^([a-zA-Z][a-zA-Z0-9+.-]*):/.exec(e);return!t||Be.includes(t[1].toLowerCase())}var te=["width","profile","rim"];var We=/^\s*(\d{2,3})\s*\/\s*(\d{2,3})\s*[A-Za-z]*\s*(\d{2}(?:\.\d+)?)\s*$/,Ge={width:[100,500],profile:[20,100],rim:[10,30]};function U(e){let t=We.exec(e??"");if(!t)return null;let n={width:Number(t[1]),profile:Number(t[2]),rim:Number(t[3])};return te.every(i=>{let[a,u]=Ge[i];return n[i]>=a&&n[i]<=u})?n:null}function T(e){if(e.width==null)return"";if(e.profile==null)return String(e.width);let t=`${e.width}/${e.profile}`;return e.rim==null?t:`${t} R${e.rim}`}function ne(e){return[T({width:e.width}),T({width:e.width,profile:e.profile}),T(e)]}var S=["alloy-wheel","tyre"],re=["alloy-wheel"],L={"alloy-wheel":"Alloy wheels",tyre:"Tyres"};var Qt=S.map(e=>({value:e,label:L[e]}));function w(e){return e==null?[...re]:Array.isArray(e)?S.filter(t=>e.includes(t)):[...re]}var m=e=>e;function f(e){return m(e).kind==="tyre"?"tyre":"alloy-wheel"}function D(e){return m(e).brand??""}function ie(e){return m(e).prices??void 0}function oe(e){return m(e).inStock!==!1}function le(e){let t=m(e),n=f(e)==="tyre"?t.rimDiameters:t.sizes;return Array.isArray(n)?n.filter(r=>typeof r=="number"&&Number.isFinite(r)):[]}function z(e){return f(e)==="tyre"?[]:(m(e).finishes??[]).filter(t=>typeof t?.family=="string").map(t=>({family:t.family,color:t.color??null}))}function se(e){return z(e).map(t=>t.family)}function $(e){if(f(e)==="tyre")return[];let t=m(e);return Array.isArray(t.categories)?t.categories:t.process?[t.process]:[]}function ae(e){return f(e)==="tyre"?[]:m(e).spec?.pcds??[]}function ue(e){return f(e)!=="tyre"?[]:m(e).tyreTypes??[]}function ce(e){return f(e)!=="tyre"?[]:m(e).speedRatings??[]}function pe(e){if(f(e)!=="tyre")return[];let t=m(e).sizes;return Array.isArray(t)?t.map(n=>U(typeof n=="string"?n:null)).filter(n=>n!==null):[]}var B=e=>typeof e=="string"&&e?e:void 0;var de=null;function fe(e,t){return t?e.replace(/\{([A-Za-z][A-Za-z0-9_]*)\}/g,(n,r)=>Object.prototype.hasOwnProperty.call(t,r)?String(t[r]):n):e}function y(e,t){let n=de?de[e]:void 0;if(typeof n=="function"){try{let r=B(n(t??{}));if(r)return r}catch{}return fe(e,t)}return fe(B(n)??e,t)}var me="homepage";function W(e){return(e??"").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}var F=[{value:"page",label:"Page"},{value:"anchor",label:"Anchor"},{value:"blog",label:"Blog post",needs:"service"},{value:"product",label:"Product",needs:"commerce"},{value:"popup",label:"Popup"},{value:"custom",label:"Custom URL"}];function _(e){return e.offersCommerce&&e.offersService?F:F.filter(t=>!t.needs||(t.needs==="commerce"?e.offersCommerce:e.offersService))}var G="#popup:";function he(e){return`${G}${e}`}function ge(e){return e.startsWith(G)&&e.slice(G.length).trim()||null}function P(e){return e===me?"/":`/${e}`}function A(e){return`/journal/${e}`}function R(e){return`/wheels/${e}`}function E(e,t){return`${P(e)}#${t}`}function Ye(e){return typeof e=="string"?e.trim():e&&typeof e=="object"&&typeof e.text=="string"?e.text.trim():""}function I(...e){let t=new Set,n=[];for(let r of e)for(let i of r?.content??[]){let a=Ye(i?.props?.anchor);if(!a)continue;let u=W(a);!u||t.has(u)||(t.add(u),n.push({slug:u,name:a}))}return n}function ye(e){return/^\/wheels\/[^/?#]+(?:[?#].*)?$/.test(e)}var He=()=>({choosePage:y("Choose a page"),chooseSection:y("Choose a section"),noSections:y("No section anchors yet"),sectionHint:y("Jumps to a section on that page."),choosePost:y("Choose a post"),chooseProduct:y("Choose a product"),choosePopup:y("Choose a popup")});function O(e,t,n){if(!e)return"page";if(ge(e))return"popup";if(e.startsWith("/journal/"))return"blog";if(ye(e))return"product";if(e.includes("#")){let r=e.slice(0,e.indexOf("#"));if(r===""||r==="/"||t.includes(r))return"anchor"}return e==="/"||t.includes(e)||n&&n.listingPaths.includes(n.targetOf(e))?"page":"custom"}function Pe(e,t){let n=He(),r=e.pages.map(l=>({value:P(l.slug),label:l.title})),i=t?.pageOptions?t.pageOptions(r):r,a=i.map(l=>l.value),u=e.pages.map(l=>({label:l.title,options:I(...l.docs).map(c=>({value:E(l.slug,c.slug),label:c.name}))})).filter(l=>l.options.length>0),p=l=>{switch(l){case"page":return{type:"select",options:i,placeholder:n.choosePage};case"anchor":return{type:"groups",groups:u,placeholder:u.length?n.chooseSection:n.noSections};case"blog":return{type:"select",options:e.posts.map(c=>({value:A(c.slug),label:c.title||c.slug})),placeholder:n.choosePost};case"product":return{type:"select",options:e.products.map(c=>({value:c.href,label:c.name||c.href})),placeholder:n.chooseProduct};case"popup":return{type:"select",options:(e.popups??[]).map(c=>({value:he(c.slug),label:c.title||c.slug})),placeholder:n.choosePopup};case"custom":return{type:"text"}}},s=_(e.offers).map(l=>({value:l.value,label:y(l.label),target:p(l.value),...l.value==="anchor"?{hint:n.sectionHint}:{},...l.value==="blog"||l.value==="product"||l.value==="popup"?{hideWhenEmpty:!0}:{}}));if(!t)return{kinds:s,rules:{kindOf:l=>O(l,a),targetOf:l=>l,readFilter:()=>null,withFilter:l=>l}};let o=l=>{let c=t.withFilter(l,null);return t.listingPaths.includes(c)?c:l};return{kinds:s,rules:{kindOf:l=>O(l,a,{listingPaths:t.listingPaths,targetOf:o}),targetOf:o,readFilter:t.readFilter,withFilter:t.withFilter},filtersFor:l=>t.listingPaths.includes(l)?t.filtersFor(l):null}}function Y(e,t){return e.length===0?e:e.filter(n=>n.kind===void 0||n.kind===t)}function be(e,t){let n=t==="filter"?"filterOrder":"cardOrder",r=new Map;for(let i of e){let a=i[n];if(typeof a!="number"||!Number.isFinite(a))continue;let u=r.get(i.fieldKey);(u===void 0||a<u)&&r.set(i.fieldKey,a)}return i=>i?r.get(i):void 0}function Se(e,t,n,r){let i=new Map;for(let s of n){let o=s[r];typeof o=="number"&&i.set(s.fieldKey,o)}if(i.size===0)return e;let a=[],u=[];e.forEach((s,o)=>{let l=t(s);l&&(a.push(o),u.push({item:s,index:o,order:i.get(l)}))}),u.sort((s,o)=>s.order!==void 0&&o.order!==void 0?s.order-o.order||s.index-o.index:s.order!==void 0?-1:o.order!==void 0?1:s.index-o.index);let p=[...e];return a.forEach((s,o)=>{p[s]=u[o].item}),p.every((s,o)=>s===e[o])?e:p}function ke(e){return je(e,"filter")}var qe="collection";function H(e,t){return{tyreSizes:{},brands:{"alloy-wheel":"brand",tyre:"brand"},finishes:{"alloy-wheel":"wheel_finish_ref"},diameters:{"alloy-wheel":"diameter",tyre:"rim_diameter"},collections:{"alloy-wheel":qe},pcds:{"alloy-wheel":"pcd"},tyreTypes:{tyre:"tire_type"},speedRatings:{tyre:"speed_rating"}}[e]?.[t]}function je(e,t){let n=new Set(e.filter(r=>r[t]===!1).map(r=>r.fieldKey));return r=>!r||!n.has(r)}function Ze(e){return typeof e=="number"&&Number.isFinite(e)&&e>0}function xe(e,t){let n=e?.[t];return Ze(n)?n:null}function Te(e,t,n,r){if(n==null&&r==null)return!0;let i=xe(e,t);return!(i===null||n!=null&&i<n||r!=null&&i>r)}var Ve={recommended:"Recommended","price-asc":"Price \xB7 low to high","price-desc":"Price \xB7 high to low",new:"Newest",name:"Name A\u2013Z"},Mn=Object.keys(Ve);var Le=["tyreSizes","brands","finishes","diameters","collections","pcds","tyreTypes","speedRatings"],Qe={tyreSizes:["tyre"],brands:["alloy-wheel","tyre"],finishes:["alloy-wheel"],diameters:["alloy-wheel","tyre"],collections:["alloy-wheel"],pcds:["alloy-wheel"],tyreTypes:["tyre"],speedRatings:["tyre"]},Xe={diameters:"tyreSizes"};function Je(e){if(e.length===0)return[];let t=Le.filter(n=>e.every(r=>Qe[n].includes(r)));return t.filter(n=>{let r=Xe[n];return!r||!t.includes(r)})}function et(e){let t=new Set;for(let n of e)t.add(f(n));return[...t]}var we={tyreSizes:[],brands:[],finishes:[],diameters:[],collections:[],pcds:[],tyreTypes:[],speedRatings:[],priceMax:null,inStockOnly:!1,kind:null,sort:"recommended",page:1};function tt(e,t,n,r=null){if(r!=="kind"&&t.kind&&f(e)!==t.kind)return!1;for(let i of Le){if(r===i)continue;let a=t[i];if(a.length===0)continue;let u=a.map(String);if(!Fe(e,i).some(p=>u.includes(p)))return!1}return!(r!=="price"&&!Te(ie(e),n,null,t.priceMax)||r!=="inStock"&&t.inStockOnly&&!oe(e))}var nt={tyreSizes:"Size",brands:"Brand",finishes:"Colour",diameters:"Size \xB7 diameter",collections:"Collection",pcds:"PCD \xB7 fitment",tyreTypes:"Tyre type",speedRatings:"Speed rating"};function Fe(e,t){switch(t){case"tyreSizes":return[...new Set(pe(e).flatMap(ne))];case"brands":return D(e)?[D(e)]:[];case"finishes":return se(e);case"diameters":return le(e).map(String);case"collections":return $(e);case"pcds":return ae(e);case"tyreTypes":return ue(e);case"speedRatings":return ce(e)}}function rt(e){let t=new Map;for(let n of e)for(let r of z(n))r.color&&!t.has(r.family)&&t.set(r.family,r.color);return t}function _e(e,t,n,r=et(e),i=[]){let a=o=>ot(o,r,i),u=rt(e),p=Je(r).filter(o=>o!=="tyreSizes").filter(a).map(o=>{let l=t[o].map(String),c=new Set,M=new Map,k=new Map;for(let d of e){let b=Fe(d,o);for(let h of b)c.add(h);for(let h of new Set(b))k.set(h,(k.get(h)??0)+1);if(tt(d,t,n,o))for(let h of new Set(b))M.set(h,(M.get(h)??0)+1)}let ve=[...c].map(d=>({value:d,label:o==="diameters"?`${d}\u2033`:d,count:M.get(d)??0,checked:l.includes(d),swatch:o==="finishes"?u.get(d)??null:null})).sort((d,b)=>{if(o==="diameters")return Number(d.value)-Number(b.value);let h=(k.get(b.value)??0)-(k.get(d.value)??0);return h!==0?h:d.value.localeCompare(b.value)});return{key:o,label:nt[o],options:ve}}).filter(o=>o.options.length>it),s=[];for(let o of p){let l=lt(o.key,r,i);l!==void 0&&s.push({fieldKey:o.key,filterOrder:l})}return[...Se(p,o=>o.key,s,"filterOrder")]}var it=1;function Ae(e){return e.showCollection===!1?["collections"]:[]}function ot(e,t,n){return t.length===0||n.length===0?!0:t.some(r=>ke(Y(n,r))(H(e,r)))}function lt(e,t,n){if(n.length===0)return;let r;for(let i of t){let a=be(Y(n,i),"filter")(H(e,i));a!==void 0&&(r===void 0||a<r)&&(r=a)}return r}var q={tyreSizes:"tyreSize",brands:"brand",finishes:"colour",diameters:"size",collections:"collection",pcds:"pcd",tyreTypes:"tyreType",speedRatings:"speed"},j="type";var Re="AlloyWheelsListing";function Ee(e){return v(e.trim())}var C="/wheels",K="Products";function Ie(e,t){return t>1?`${K} \xB7 ${e}`:K}function Z(...e){for(let t of e){let n=(t?.content??[]).find(r=>r?.type===Re);if(n)return n.props??{}}return null}function N(...e){return Z(...e)!==null}function Oe(e,t){let n=e.filter(r=>N(...r.docs)).map(r=>P(r.slug));return n.length===0&&t.fallback?[C]:n}var V=[j,...Object.entries(q).filter(([e])=>e!=="tyreSizes").map(([,e])=>e)];function Ce(e){let t=e.indexOf("#"),n=t===-1?"":e.slice(t),r=t===-1?e:e.slice(0,t),i=r.indexOf("?");return{path:i===-1?r:r.slice(0,i),query:i===-1?"":r.slice(i+1),hash:n}}function st(e){try{return decodeURIComponent(e.replace(/\+/g," "))}catch{return e}}function Ke(e){let t=new URLSearchParams(Ce(e).query);for(let n of V){let r=t.get(n);if(r)return{param:n,value:r}}return null}function Q(e,t){let{path:n,query:r,hash:i}=Ce(e),a=r.split("&").filter(u=>u&&!V.includes(st(u.split("=")[0])));return t?.value&&a.push(`${encodeURIComponent(t.param)}=${encodeURIComponent(t.value)}`),`${n}${a.length?`?${a.join("&")}`:""}${i}`}function Ne(e,t){let n=Q(e,null);return t.includes(n)?n:e}function at(e,t,n=[]){return O(e,t,{listingPaths:n,targetOf:r=>Ne(r,n)})}function ut(e){return Array.isArray(e)?e.filter(t=>typeof t?.kind=="string"&&typeof t.field_key=="string").map(t=>({kind:t.kind,fieldKey:t.field_key,...typeof t.filter=="boolean"?{filter:t.filter}:{},filterOrder:t.filter_order??null})):[]}var Me="Product type",ct="AUD";function X(e,t){let n=t.listing??{},r=w(n.kinds),i=e.filter(s=>r.includes(f(s))),a=Ae(n),u=_e(i,we,ct,r,t.fieldUsage).filter(s=>!a.includes(s.key)).map(s=>({param:q[s.key],label:s.label,values:s.options.filter(o=>!o.value.includes(",")).map(o=>({value:o.value,label:o.label}))})).filter(s=>s.values.length>0),p=S.filter(s=>r.includes(s)&&i.some(o=>f(o)===s));return p.length>1&&u.unshift({param:j,label:Me,values:p.map(s=>({value:s,label:L[s]}))}),u}function pt(e){return t=>{let n=Oe(t,{fallback:e.offersCommerce}),r=t.filter(i=>N(...i.docs)).length;return{listingPaths:n,pageOptions:i=>{let a=i.map(u=>{let p=t.find(s=>P(s.slug)===u.value);return p&&N(...p.docs)?{...u,label:Ie(p.title,r)}:u});return r===0&&e.offersCommerce&&!a.some(u=>u.value===C)&&a.push({value:C,label:K}),a},filtersFor:i=>{if(!n.includes(i))return null;let a=t.find(u=>P(u.slug)===i);return X(e.catalogue,{listing:a?Z(...a.docs):null,fieldUsage:e.fieldUsage})},readFilter:Ke,withFilter:Q}}}function dt(e){let t=pt({catalogue:e.catalogue,fieldUsage:e.fieldUsage,offersCommerce:e.offers.offersCommerce})(e.pages),n=Pe({pages:e.pages,posts:e.posts,products:e.products.map(r=>({href:R(r.slug),name:r.name||r.slug})),offers:e.offers},t);return{...n,rules:{...n.rules,isSafe:Ee},filtersFor:n.filtersFor??(()=>null)}}function rr(e,t){return X(e,t)}export{C as BUILT_IN_LISTING_PATH,F as LINK_KINDS,V as LISTING_FILTER_PARAMS,K as LISTING_PAGE_LABEL,Me as PRODUCT_TYPE_FILTER_LABEL,E as anchorPath,ut as fieldUsageFromAdminRows,at as inferLinkKind,N as isProductListingPage,Ee as isSafeLink,_ as linkKindsFor,dt as linkPickerSetup,rr as listingFilterFields,Z as listingNode,Ie as listingPageLabel,Ne as listingTarget,I as pageAnchors,P as pagePath,A as postPath,Oe as productListingPaths,Ke as readListingFilter,R as wheelPath,Q as withListingFilter};
|
|
1
|
+
var g={bold:{open:"**",close:"**",placeholder:"bold text"},italic:{open:"_",close:"_",placeholder:"italic text"},strike:{open:"~~",close:"~~",placeholder:"struck out"},code:{open:"`",close:"`",placeholder:"code"},highlight:{open:"==",close:"==",placeholder:"highlighted text"},quiet:{open:"^^",close:"^^",placeholder:"quiet text"},underline:{open:"[",close:"]{underline}",placeholder:"underlined text"},sup:{open:"[",close:"]{sup}",placeholder:"superscript"},sub:{open:"[",close:"]{sub}",placeholder:"subscript"}};var De={bold:g.bold.placeholder,italic:g.italic.placeholder,strike:g.strike.placeholder,code:g.code.placeholder,highlight:g.highlight.placeholder,quiet:g.quiet.placeholder,link:"link text",underline:g.underline.placeholder,sup:g.sup.placeholder,sub:g.sub.placeholder,color:"colored text",style:"styled text"};var J=[{style:"bold",label:"B",name:"Strong",title:"Strong \xB7 **words** \xB7 \u2318B",shortcut:"b"},{style:"italic",label:"I",name:"Italic",title:"Italic \xB7 _words_ \xB7 \u2318I",shortcut:"i"},{style:"strike",label:"S",name:"Strikethrough",title:"Strikethrough \xB7 ~~words~~"},{style:"highlight",label:"\u25C6",name:"Emphasis",title:"Emphasis \xB7 ==words=="},{style:"quiet",label:"a",name:"Quiet",title:"Quiet \xB7 ^^words^^"},{style:"code",label:"\u2039\u203A",name:"Code",title:"Code"},{style:"link",label:"\u{1F517}",name:"Link",title:"Link \xB7 [words](https://\u2026) \xB7 \u2318K",shortcut:"k"},{style:"bullet",label:"\u2022",name:"Bulleted list",title:"Bulleted list"},{style:"number",label:"1.",name:"Numbered list",title:"Numbered list"},{style:"quote",label:"\u275D",name:"Quote",title:"Quote"},{style:"clear",label:"T\xD7",name:"Clear marks",title:"Clear marks \xB7 \u2318\u21E7X",shortcut:"shift+x"}];var x=[{open:"**",close:"**",kind:"bold"},{open:"==",close:"==",kind:"highlight"},{open:"~~",close:"~~",kind:"strike"},{open:"_",close:"_",kind:"italic",wordBoundary:!0},{open:"^^",close:"^^",kind:"quiet"},{open:"@@",close:"@@",kind:"highlight"},{open:"++",close:"++",kind:"bold",wordStart:!0}],ee=["highlight","quiet"],ze=J.map(e=>e.style).filter(e=>x.some(n=>n.kind===e)).filter(e=>!ee.includes(e)),$e=[...x,{open:"*",close:"*",kind:"accent"}],Be=[...x,{open:"*",close:"*",kind:"accent"},{open:"#",close:"#",kind:"bold",notBefore:"0123456789"},{open:"[",close:"]",kind:"italic",notBefore:"(",notBeforeBlock:!0}];var We=["http","https","mailto","tel"];function v(e){if(e===""||/[\s\u0000-\u001f\u007f]/.test(e))return!1;let n=/^([a-zA-Z][a-zA-Z0-9+.-]*):/.exec(e);return!n||We.includes(n[1].toLowerCase())}var ne=["width","profile","rim"];var Ge=/^\s*(\d{2,3})\s*\/\s*(\d{2,3})\s*[A-Za-z]*\s*(\d{2}(?:\.\d+)?)\s*$/,Ye={width:[100,500],profile:[20,100],rim:[10,30]};function U(e){let n=Ge.exec(e??"");if(!n)return null;let t={width:Number(n[1]),profile:Number(n[2]),rim:Number(n[3])};return ne.every(i=>{let[a,u]=Ye[i];return t[i]>=a&&t[i]<=u})?t:null}function T(e){if(e.width==null)return"";if(e.profile==null)return String(e.width);let n=`${e.width}/${e.profile}`;return e.rim==null?n:`${n} R${e.rim}`}function te(e){return[T({width:e.width}),T({width:e.width,profile:e.profile}),T(e)]}var S=["alloy-wheel","tyre"],re=["alloy-wheel"],L={"alloy-wheel":"Alloy wheels",tyre:"Tyres"};var Xn=S.map(e=>({value:e,label:L[e]}));function w(e){return e==null?[...re]:Array.isArray(e)?S.filter(n=>e.includes(n)):[...re]}var m=e=>e;function f(e){return m(e).kind==="tyre"?"tyre":"alloy-wheel"}function D(e){return m(e).brand??""}function ie(e){return m(e).prices??void 0}function oe(e){return m(e).inStock!==!1}function le(e){let n=m(e),t=f(e)==="tyre"?n.rimDiameters:n.sizes;return Array.isArray(t)?t.filter(r=>typeof r=="number"&&Number.isFinite(r)):[]}function z(e){return f(e)==="tyre"?[]:(m(e).finishes??[]).filter(n=>typeof n?.family=="string").map(n=>({family:n.family,color:n.color??null}))}function se(e){return z(e).map(n=>n.family)}function $(e){if(f(e)==="tyre")return[];let n=m(e);return Array.isArray(n.categories)?n.categories:n.process?[n.process]:[]}function ae(e){return f(e)==="tyre"?[]:m(e).spec?.pcds??[]}function ue(e){return f(e)!=="tyre"?[]:m(e).tyreTypes??[]}function ce(e){return f(e)!=="tyre"?[]:m(e).speedRatings??[]}function pe(e){if(f(e)!=="tyre")return[];let n=m(e).sizes;return Array.isArray(n)?n.map(t=>U(typeof t=="string"?t:null)).filter(t=>t!==null):[]}var B=e=>typeof e=="string"&&e?e:void 0;var de=null;function fe(e,n){return n?e.replace(/\{([A-Za-z][A-Za-z0-9_]*)\}/g,(t,r)=>Object.prototype.hasOwnProperty.call(n,r)?String(n[r]):t):e}function y(e,n){let t=de?de[e]:void 0;if(typeof t=="function"){try{let r=B(t(n??{}));if(r)return r}catch{}return fe(e,n)}return fe(B(t)??e,n)}function W(e){return(e??"").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}function me(e){return typeof e=="string"?e.trim():e&&typeof e=="object"&&typeof e.text=="string"?e.text.trim():""}var he="homepage";var F=[{value:"page",label:"Page"},{value:"anchor",label:"Anchor"},{value:"blog",label:"Blog post",needs:"service"},{value:"product",label:"Product",needs:"commerce"},{value:"popup",label:"Popup"},{value:"custom",label:"Custom URL"}];function _(e){return e.offersCommerce&&e.offersService?F:F.filter(n=>!n.needs||(n.needs==="commerce"?e.offersCommerce:e.offersService))}var G="#popup:";function ge(e){return`${G}${e}`}function ye(e){return e.startsWith(G)&&e.slice(G.length).trim()||null}function P(e){return e===he?"/":`/${e}`}function A(e){return`/journal/${e}`}function R(e){return`/wheels/${e}`}function E(e,n){return`${P(e)}#${n}`}function I(...e){let n=new Set,t=[];for(let r of e)for(let i of r?.content??[]){let a=me(i?.props?.anchor);if(!a)continue;let u=W(a);!u||n.has(u)||(n.add(u),t.push({slug:u,name:a}))}return t}function Pe(e){return/^\/wheels\/[^/?#]+(?:[?#].*)?$/.test(e)}var He=()=>({choosePage:y("Choose a page"),chooseSection:y("Choose a section"),noSections:y("No section anchors yet"),sectionHint:y("Jumps to a section on that page."),choosePost:y("Choose a post"),chooseProduct:y("Choose a product"),choosePopup:y("Choose a popup")});function O(e,n,t){if(!e)return"page";if(ye(e))return"popup";if(e.startsWith("/journal/"))return"blog";if(Pe(e))return"product";if(e.includes("#")){let r=e.slice(0,e.indexOf("#"));if(r===""||r==="/"||n.includes(r))return"anchor"}return e==="/"||n.includes(e)||t&&t.listingPaths.includes(t.targetOf(e))?"page":"custom"}function be(e,n){let t=He(),r=e.pages.map(l=>({value:P(l.slug),label:l.title})),i=n?.pageOptions?n.pageOptions(r):r,a=i.map(l=>l.value),u=e.pages.map(l=>({label:l.title,options:I(...l.docs).map(c=>({value:E(l.slug,c.slug),label:c.name}))})).filter(l=>l.options.length>0),p=l=>{switch(l){case"page":return{type:"select",options:i,placeholder:t.choosePage};case"anchor":return{type:"groups",groups:u,placeholder:u.length?t.chooseSection:t.noSections};case"blog":return{type:"select",options:e.posts.map(c=>({value:A(c.slug),label:c.title||c.slug})),placeholder:t.choosePost};case"product":return{type:"select",options:e.products.map(c=>({value:c.href,label:c.name||c.href})),placeholder:t.chooseProduct};case"popup":return{type:"select",options:(e.popups??[]).map(c=>({value:ge(c.slug),label:c.title||c.slug})),placeholder:t.choosePopup};case"custom":return{type:"text"}}},s=_(e.offers).map(l=>({value:l.value,label:y(l.label),target:p(l.value),...l.value==="anchor"?{hint:t.sectionHint}:{},...l.value==="blog"||l.value==="product"||l.value==="popup"?{hideWhenEmpty:!0}:{}}));if(!n)return{kinds:s,rules:{kindOf:l=>O(l,a),targetOf:l=>l,readFilter:()=>null,withFilter:l=>l}};let o=l=>{let c=n.withFilter(l,null);return n.listingPaths.includes(c)?c:l};return{kinds:s,rules:{kindOf:l=>O(l,a,{listingPaths:n.listingPaths,targetOf:o}),targetOf:o,readFilter:n.readFilter,withFilter:n.withFilter},filtersFor:l=>n.listingPaths.includes(l)?n.filtersFor(l):null}}function Y(e,n){return e.length===0?e:e.filter(t=>t.kind===void 0||t.kind===n)}function Se(e,n){let t=n==="filter"?"filterOrder":"cardOrder",r=new Map;for(let i of e){let a=i[t];if(typeof a!="number"||!Number.isFinite(a))continue;let u=r.get(i.fieldKey);(u===void 0||a<u)&&r.set(i.fieldKey,a)}return i=>i?r.get(i):void 0}function ke(e,n,t,r){let i=new Map;for(let s of t){let o=s[r];typeof o=="number"&&i.set(s.fieldKey,o)}if(i.size===0)return e;let a=[],u=[];e.forEach((s,o)=>{let l=n(s);l&&(a.push(o),u.push({item:s,index:o,order:i.get(l)}))}),u.sort((s,o)=>s.order!==void 0&&o.order!==void 0?s.order-o.order||s.index-o.index:s.order!==void 0?-1:o.order!==void 0?1:s.index-o.index);let p=[...e];return a.forEach((s,o)=>{p[s]=u[o].item}),p.every((s,o)=>s===e[o])?e:p}function xe(e){return je(e,"filter")}var qe="collection";function H(e,n){return{tyreSizes:{},brands:{"alloy-wheel":"brand",tyre:"brand"},finishes:{"alloy-wheel":"wheel_finish_ref"},diameters:{"alloy-wheel":"diameter",tyre:"rim_diameter"},collections:{"alloy-wheel":qe},pcds:{"alloy-wheel":"pcd"},tyreTypes:{tyre:"tire_type"},speedRatings:{tyre:"speed_rating"}}[e]?.[n]}function je(e,n){let t=new Set(e.filter(r=>r[n]===!1).map(r=>r.fieldKey));return r=>!r||!t.has(r)}function Ze(e){return typeof e=="number"&&Number.isFinite(e)&&e>0}function Te(e,n){let t=e?.[n];return Ze(t)?t:null}function Le(e,n,t,r){if(t==null&&r==null)return!0;let i=Te(e,n);return!(i===null||t!=null&&i<t||r!=null&&i>r)}var Ve={recommended:"Recommended","price-asc":"Price \xB7 low to high","price-desc":"Price \xB7 high to low",new:"Newest",name:"Name A\u2013Z"},Ut=Object.keys(Ve);var we=["tyreSizes","brands","finishes","diameters","collections","pcds","tyreTypes","speedRatings"],Qe={tyreSizes:["tyre"],brands:["alloy-wheel","tyre"],finishes:["alloy-wheel"],diameters:["alloy-wheel","tyre"],collections:["alloy-wheel"],pcds:["alloy-wheel"],tyreTypes:["tyre"],speedRatings:["tyre"]},Xe={diameters:"tyreSizes"};function Je(e){if(e.length===0)return[];let n=we.filter(t=>e.every(r=>Qe[t].includes(r)));return n.filter(t=>{let r=Xe[t];return!r||!n.includes(r)})}function en(e){let n=new Set;for(let t of e)n.add(f(t));return[...n]}var Fe={tyreSizes:[],brands:[],finishes:[],diameters:[],collections:[],pcds:[],tyreTypes:[],speedRatings:[],priceMax:null,inStockOnly:!1,kind:null,sort:"recommended",page:1};function nn(e,n,t,r=null){if(r!=="kind"&&n.kind&&f(e)!==n.kind)return!1;for(let i of we){if(r===i)continue;let a=n[i];if(a.length===0)continue;let u=a.map(String);if(!_e(e,i).some(p=>u.includes(p)))return!1}return!(r!=="price"&&!Le(ie(e),t,null,n.priceMax)||r!=="inStock"&&n.inStockOnly&&!oe(e))}var tn={tyreSizes:"Size",brands:"Brand",finishes:"Colour",diameters:"Size \xB7 diameter",collections:"Collection",pcds:"PCD \xB7 fitment",tyreTypes:"Tyre type",speedRatings:"Speed rating"};function _e(e,n){switch(n){case"tyreSizes":return[...new Set(pe(e).flatMap(te))];case"brands":return D(e)?[D(e)]:[];case"finishes":return se(e);case"diameters":return le(e).map(String);case"collections":return $(e);case"pcds":return ae(e);case"tyreTypes":return ue(e);case"speedRatings":return ce(e)}}function rn(e){let n=new Map;for(let t of e)for(let r of z(t))r.color&&!n.has(r.family)&&n.set(r.family,r.color);return n}function Ae(e,n,t,r=en(e),i=[]){let a=o=>ln(o,r,i),u=rn(e),p=Je(r).filter(o=>o!=="tyreSizes").filter(a).map(o=>{let l=n[o].map(String),c=new Set,M=new Map,k=new Map;for(let d of e){let b=_e(d,o);for(let h of b)c.add(h);for(let h of new Set(b))k.set(h,(k.get(h)??0)+1);if(nn(d,n,t,o))for(let h of new Set(b))M.set(h,(M.get(h)??0)+1)}let Ue=[...c].map(d=>({value:d,label:o==="diameters"?`${d}\u2033`:d,count:M.get(d)??0,checked:l.includes(d),swatch:o==="finishes"?u.get(d)??null:null})).sort((d,b)=>{if(o==="diameters")return Number(d.value)-Number(b.value);let h=(k.get(b.value)??0)-(k.get(d.value)??0);return h!==0?h:d.value.localeCompare(b.value)});return{key:o,label:tn[o],options:Ue}}).filter(o=>o.options.length>on),s=[];for(let o of p){let l=sn(o.key,r,i);l!==void 0&&s.push({fieldKey:o.key,filterOrder:l})}return[...ke(p,o=>o.key,s,"filterOrder")]}var on=1;function Re(e){return e.showCollection===!1?["collections"]:[]}function ln(e,n,t){return n.length===0||t.length===0?!0:n.some(r=>xe(Y(t,r))(H(e,r)))}function sn(e,n,t){if(t.length===0)return;let r;for(let i of n){let a=Se(Y(t,i),"filter")(H(e,i));a!==void 0&&(r===void 0||a<r)&&(r=a)}return r}var q={tyreSizes:"tyreSize",brands:"brand",finishes:"colour",diameters:"size",collections:"collection",pcds:"pcd",tyreTypes:"tyreType",speedRatings:"speed"},j="type";var Ee="AlloyWheelsListing";function Ie(e){return v(e.trim())}var C="/wheels",K="Products";function Oe(e,n){return n>1?`${K} \xB7 ${e}`:K}function Z(...e){for(let n of e){let t=(n?.content??[]).find(r=>r?.type===Ee);if(t)return t.props??{}}return null}function N(...e){return Z(...e)!==null}function Ce(e,n){let t=e.filter(r=>N(...r.docs)).map(r=>P(r.slug));return t.length===0&&n.fallback?[C]:t}var V=[j,...Object.entries(q).filter(([e])=>e!=="tyreSizes").map(([,e])=>e)];function Ke(e){let n=e.indexOf("#"),t=n===-1?"":e.slice(n),r=n===-1?e:e.slice(0,n),i=r.indexOf("?");return{path:i===-1?r:r.slice(0,i),query:i===-1?"":r.slice(i+1),hash:t}}function an(e){try{return decodeURIComponent(e.replace(/\+/g," "))}catch{return e}}function Ne(e){let n=new URLSearchParams(Ke(e).query);for(let t of V){let r=n.get(t);if(r)return{param:t,value:r}}return null}function Q(e,n){let{path:t,query:r,hash:i}=Ke(e),a=r.split("&").filter(u=>u&&!V.includes(an(u.split("=")[0])));return n?.value&&a.push(`${encodeURIComponent(n.param)}=${encodeURIComponent(n.value)}`),`${t}${a.length?`?${a.join("&")}`:""}${i}`}function Me(e,n){let t=Q(e,null);return n.includes(t)?t:e}function un(e,n,t=[]){return O(e,n,{listingPaths:t,targetOf:r=>Me(r,t)})}function cn(e){return Array.isArray(e)?e.filter(n=>typeof n?.kind=="string"&&typeof n.field_key=="string").map(n=>({kind:n.kind,fieldKey:n.field_key,...typeof n.filter=="boolean"?{filter:n.filter}:{},filterOrder:n.filter_order??null})):[]}var ve="Product type",pn="AUD";function X(e,n){let t=n.listing??{},r=w(t.kinds),i=e.filter(s=>r.includes(f(s))),a=Re(t),u=Ae(i,Fe,pn,r,n.fieldUsage).filter(s=>!a.includes(s.key)).map(s=>({param:q[s.key],label:s.label,values:s.options.filter(o=>!o.value.includes(",")).map(o=>({value:o.value,label:o.label}))})).filter(s=>s.values.length>0),p=S.filter(s=>r.includes(s)&&i.some(o=>f(o)===s));return p.length>1&&u.unshift({param:j,label:ve,values:p.map(s=>({value:s,label:L[s]}))}),u}function dn(e){return n=>{let t=Ce(n,{fallback:e.offersCommerce}),r=n.filter(i=>N(...i.docs)).length;return{listingPaths:t,pageOptions:i=>{let a=i.map(u=>{let p=n.find(s=>P(s.slug)===u.value);return p&&N(...p.docs)?{...u,label:Oe(p.title,r)}:u});return r===0&&e.offersCommerce&&!a.some(u=>u.value===C)&&a.push({value:C,label:K}),a},filtersFor:i=>{if(!t.includes(i))return null;let a=n.find(u=>P(u.slug)===i);return X(e.catalogue,{listing:a?Z(...a.docs):null,fieldUsage:e.fieldUsage})},readFilter:Ne,withFilter:Q}}}function fn(e){let n=dn({catalogue:e.catalogue,fieldUsage:e.fieldUsage,offersCommerce:e.offers.offersCommerce})(e.pages),t=be({pages:e.pages,posts:e.posts,products:e.products.map(r=>({href:R(r.slug),name:r.name||r.slug})),offers:e.offers},n);return{...t,rules:{...t.rules,isSafe:Ie},filtersFor:t.filtersFor??(()=>null)}}function or(e,n){return X(e,n)}export{C as BUILT_IN_LISTING_PATH,F as LINK_KINDS,V as LISTING_FILTER_PARAMS,K as LISTING_PAGE_LABEL,ve as PRODUCT_TYPE_FILTER_LABEL,E as anchorPath,cn as fieldUsageFromAdminRows,un as inferLinkKind,N as isProductListingPage,Ie as isSafeLink,_ as linkKindsFor,fn as linkPickerSetup,or as listingFilterFields,Z as listingNode,Oe as listingPageLabel,Me as listingTarget,I as pageAnchors,P as pagePath,A as postPath,Ce as productListingPaths,Ne as readListingFilter,R as wheelPath,Q as withListingFilter};
|
|
@@ -1514,6 +1514,14 @@ body:has([data-page-width="full"]) footer {
|
|
|
1514
1514
|
:where(.sf-section-stick ~ :not(.sf-section-stick)) {
|
|
1515
1515
|
position: relative;
|
|
1516
1516
|
}
|
|
1517
|
+
/* What comes after a pinned Scroll-Over Intro slides over it. The intro pins at
|
|
1518
|
+
z-index 1, so a position alone is not enough: every old section wears its own
|
|
1519
|
+
`relative z-[2]`, and this gives a Box the same. `:where()` weighs nothing, so
|
|
1520
|
+
a follower's own class keeps its position and layer (a second pinned intro). */
|
|
1521
|
+
:where(.sf-scroll-over ~ *) {
|
|
1522
|
+
position: relative;
|
|
1523
|
+
z-index: 2;
|
|
1524
|
+
}
|
|
1517
1525
|
/* The phone's own answer (below 720px, VIEW_TABLET_MIN, written as in the
|
|
1518
1526
|
phone padding block below). */
|
|
1519
1527
|
@media not all and (min-width: 720px) {
|
|
@@ -1924,6 +1932,13 @@ em.text-accent {
|
|
|
1924
1932
|
gap: var(--plp-grid-gap);
|
|
1925
1933
|
grid-template-columns: var(--plp-grid-cols-mobile);
|
|
1926
1934
|
}
|
|
1935
|
+
/* The site's phone gap reaches the gutter and the track arithmetic through this
|
|
1936
|
+
one property (PLP_GRID_GAP_TERM). A site with no phone value leaves it empty. */
|
|
1937
|
+
@media not all and (min-width: 720px) {
|
|
1938
|
+
.plp-card-grid {
|
|
1939
|
+
--plp-phone-gap: var(--sf-block-gap-phone-rem);
|
|
1940
|
+
}
|
|
1941
|
+
}
|
|
1927
1942
|
@media (min-width: 720px) {
|
|
1928
1943
|
.plp-card-grid {
|
|
1929
1944
|
grid-template-columns: var(--plp-grid-cols-tablet);
|
|
@@ -2576,16 +2591,42 @@ em.text-accent {
|
|
|
2576
2591
|
take its parent's. Every zone resets it here; a container's own value is
|
|
2577
2592
|
inline and beats this rule, and its blocks still inherit that value. */
|
|
2578
2593
|
--sf-gap-len-phone: initial;
|
|
2594
|
+
--sf-gap-len-tablet: initial;
|
|
2579
2595
|
}
|
|
2580
2596
|
/* Below 800px: the container's own phone Gap when it stores one (C25 row 2,
|
|
2581
2597
|
Lewis 2026-10-29: `--sf-gap-len-phone`, written by efficient-web-builder's
|
|
2582
2598
|
`containerGapProps`), else half the desktop length (the 2026-09-03 ruling).
|
|
2583
|
-
|
|
2599
|
+
A container that follows the site names the site's phone gap instead
|
|
2600
|
+
(`var(--sf-block-gap-on-phone)`, efficient-web-builder 47.2.0, #436), which
|
|
2601
|
+
is defined only below 720px on a site that stores one. With no phone value
|
|
2602
|
+
the declaration is invalid and the fallback is the old one, so no page moves. */
|
|
2584
2603
|
@media (max-width: 800px) {
|
|
2585
2604
|
.sf-gap-zone {
|
|
2586
2605
|
gap: var(--sf-gap-len-phone, calc(var(--sf-gap-len) / 2));
|
|
2587
2606
|
}
|
|
2588
2607
|
}
|
|
2608
|
+
/* The Tablet view's own Gap (three-views plan PR 5b; GG 2026-11-03), on
|
|
2609
|
+
`--sf-gap-len-tablet`, which efficient-web-builder's `containerGapProps`
|
|
2610
|
+
writes only when a tablet value is drawn, as it does the phone's. The widths
|
|
2611
|
+
are the Tablet view's: efficient-easel's VIEW_TABLET_MIN (720) up to, not
|
|
2612
|
+
including, VIEW_DESKTOP_MIN (1100), the builder's lib/content/view-values
|
|
2613
|
+
`TABLET_MEDIA`, the same string. The fallback is TODAY'S answer at each
|
|
2614
|
+
width, so a zone with no tablet value draws what it drew before: the desktop
|
|
2615
|
+
length from 800 up, and from 720 to 800 the phone rule above (its own phone
|
|
2616
|
+
length, else half). The second block restates that part, after the first.
|
|
2617
|
+
An empty PHONE value keeps the phone rule: it does not follow the tablet
|
|
2618
|
+
(GG 2026-11-03, the named exception in plan row 5b).
|
|
2619
|
+
scripts/test-gap-tablet-css.ts holds all of it. */
|
|
2620
|
+
@media (min-width: 720px) and (max-width: 1099.98px) {
|
|
2621
|
+
.sf-gap-zone {
|
|
2622
|
+
gap: var(--sf-gap-len-tablet, var(--sf-gap-len));
|
|
2623
|
+
}
|
|
2624
|
+
}
|
|
2625
|
+
@media (min-width: 720px) and (max-width: 800px) {
|
|
2626
|
+
.sf-gap-zone {
|
|
2627
|
+
gap: var(--sf-gap-len-tablet, var(--sf-gap-len-phone, calc(var(--sf-gap-len) / 2)));
|
|
2628
|
+
}
|
|
2629
|
+
}
|
|
2589
2630
|
/* A shared-rows card grid (`.sf-card-rows`, components/WheelCardFrame) moves
|
|
2590
2631
|
its row gap onto the cards as a margin, so `gap` above does not reach it.
|
|
2591
2632
|
Its phone answer is this property, named by the grid ONLY when it stores a
|
|
@@ -2599,6 +2640,18 @@ em.text-accent {
|
|
|
2599
2640
|
--sf-card-row-gap-auto: var(--sf-gap-len-phone, var(--sf-gap-len));
|
|
2600
2641
|
}
|
|
2601
2642
|
}
|
|
2643
|
+
/* …and in the Tablet view, its tablet length, with the same fallbacks as the
|
|
2644
|
+
zone's above. */
|
|
2645
|
+
@media (min-width: 720px) and (max-width: 1099.98px) {
|
|
2646
|
+
.sf-card-rows {
|
|
2647
|
+
--sf-card-row-gap-auto: var(--sf-gap-len-tablet, var(--sf-gap-len));
|
|
2648
|
+
}
|
|
2649
|
+
}
|
|
2650
|
+
@media (min-width: 720px) and (max-width: 800px) {
|
|
2651
|
+
.sf-card-rows {
|
|
2652
|
+
--sf-card-row-gap-auto: var(--sf-gap-len-tablet, var(--sf-gap-len-phone, var(--sf-gap-len)));
|
|
2653
|
+
}
|
|
2654
|
+
}
|
|
2602
2655
|
|
|
2603
2656
|
/* The overlap below zero halves on the same screen, for the same reason and by
|
|
2604
2657
|
the same ruling. It needs its OWN derived property rather than redefining
|
|
@@ -3229,6 +3282,22 @@ em.text-accent {
|
|
|
3229
3282
|
padding-block: 0;
|
|
3230
3283
|
}
|
|
3231
3284
|
|
|
3285
|
+
/* …and a block with a Size value (Content width, Width) is still a block of the
|
|
3286
|
+
Box. The builder's `div.sf-block-size` goes OUTSIDE everything the block brings
|
|
3287
|
+
with it (its blockSize pass), so that wrapper is then the Box's direct child and
|
|
3288
|
+
the frame's `py-4` came back: +32px on the Hartes US Home and About text.
|
|
3289
|
+
Each shape above, through it. */
|
|
3290
|
+
.sf-box-gap-only > .sf-block-size > *,
|
|
3291
|
+
.sf-box-gap-only > .sf-block-size > .sf-entrance > *,
|
|
3292
|
+
.sf-box-gap-only > .sf-block-size > .sf-section-pad > *,
|
|
3293
|
+
.sf-box-gap-only > .sf-block-size > .sf-entrance > .sf-section-pad > *,
|
|
3294
|
+
.sf-box-gap-only > [data-easel-block] > [data-sf-part-host] > .sf-block-size > *,
|
|
3295
|
+
.sf-box-gap-only > [data-easel-block] > [data-sf-part-host] > .sf-block-size > .sf-entrance > *,
|
|
3296
|
+
.sf-box-gap-only > [data-easel-block] > [data-sf-part-host] > .sf-block-size > .sf-section-pad > *,
|
|
3297
|
+
.sf-box-gap-only > [data-easel-block] > [data-sf-part-host] > .sf-block-size > .sf-entrance > .sf-section-pad > * {
|
|
3298
|
+
padding-block: 0;
|
|
3299
|
+
}
|
|
3300
|
+
|
|
3232
3301
|
/* ── THE VISITOR'S OWN "REDUCE MOTION" SETTING ──────────────────────────────
|
|
3233
3302
|
[ADD] The Site Respects Reduce Motion.
|
|
3234
3303
|
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use client";import{jsx as
|
|
2
|
-
`);return
|
|
3
|
-
${
|
|
1
|
+
"use client";import{jsx as S}from"react/jsx-runtime";import{createContext as wn,useContext as gn,useEffect as m,useMemo as At,useRef as f,useState as c}from"react";import{isOrderable as vt,useCart as kn}from"../CartContext.js";import{useCurrency as Cn}from"../CurrencyContext.js";import{getClickIds as bn}from"../../lib/click-ids.js";import{adConsentForOrder as Nn}from"../../lib/consent/choice.js";import{trackBeginCheckout as Pn,trackPurchase as Sn}from"../../lib/google-tag.js";import{trackMetaPurchase as An}from"../../lib/meta-pixel.js";import{ApiError as ke,api as j,products as y}from"../../lib/api/index.js";import{uuid as Ce}from"../../lib/uuid.js";import{orderLinesForSets as vn}from"../../lib/commerce.js";import{canPersist as xn,safeSessionStorage as C}from"efficient-web-builder/format/lib/safe-storage";import{AFTERPAY_CONTEXT_KEY as Kn,AFTERPAY_RETURN as En,GOCARDLESS_CONTEXT_KEY as Le,KLARNA_CONTEXT_KEY as $e,ZIP_CONTEXT_KEY as In,ZIP_RETURN as On,runWalletReturn as xt}from"../../lib/checkout/wallet-return.js";import{matchSubdivision as Tn}from"../../lib/checkout/match-subdivision.js";import{checkoutGone as Ye,checkoutWaiting as _n,BANK_WAITING as Rn,DROPPABLE_INTENT as Mn,NOT_CHECKED as Fe,PAY_FIRST_FLOW as Kt,paysFirst as Ln,readIntentStatus as $n,releaseHeldCheckout as Et,settlePayFirst as Yn}from"../../lib/checkout/pay-first.js";import{couponCodeForOrder as It,couponRefusedByOrder as Fn}from"../../lib/cart/coupon-preview.js";function Ot(a){const p=a.indexOf(`
|
|
2
|
+
`);return p===-1?[a,""]:[a.slice(0,p),a.slice(p+1)]}function Tt(a,{canParkContext:p}={canParkContext:!0}){const d=a.paymentMethods,i=[];return d.includes("card")&&i.push({key:"card",title:"Card",body:null,price:S("span",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-accent",children:"VISA · MC · AMEX"})}),d.includes("paypal")&&a.paypalClientId&&i.push({key:"paypal",title:"PayPal",body:null,price:S("span",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-accent",children:"PAYPAL · CARDS"})}),d.includes("afterpay")&&i.push({key:"afterpay",title:"Afterpay",body:null,price:S("span",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-accent",children:"4 × INTEREST-FREE"})}),d.includes("square")&&a.squareApplicationId&&a.squareLocationId&&i.push({key:"square",title:"Card (Square)",body:null,price:S("span",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-accent",children:"VISA · MC · AMEX"})}),d.includes("gocardless")&&p&&i.push({key:"gocardless",title:"Bank Direct Debit",body:null,price:S("span",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-accent",children:"PAY BY BANK"})}),d.includes("zip")&&i.push({key:"zip",title:"Zip",body:null,price:S("span",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-accent",children:"PAY IN 4"})}),d.includes("klarna")&&p&&i.push({key:"klarna",title:"Klarna",body:null,price:S("span",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-accent",children:"PAY LATER"})}),d.includes("bank")&&i.push({key:"bank",title:"Bank transfer",body:null,price:S("span",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-fg-dim",children:"Invoiced"})}),i}const cr="This shop does not take payment online yet. Please contact the shop to order.";class _t extends Error{}function Un(a,p){if(!a.orderNumber&&Ye(p))return p.message;const d=p instanceof ke?` (${p.message})`:"";return a.orderNumber?`Your order ${a.orderNumber} is saved, but the payment did not start${d}. Try the payment again — your order will not be placed twice.`:`Your items are held under ${a.checkoutNumber}, but the payment did not start${d}. Try the payment again — you will not be charged twice.`}const ar="Shipping cannot be calculated right now. Please try again.";function Bn({site:a,logo:p,preview:d=!1}){const{items:i,totals:A,coupon:M,refuseCoupon:Mt,deliveryOptions:Ue,shippingMethodId:Q,setShippingMethodId:Lt,setQuoteDestination:V,courier:$t,requote:Yt,identify:Be,clearCapturedCart:L,replaceItems:ze,removeCoupon:He}=kn(),Ft=Ue.find(e=>e.id===Q)?.pickupLocation??null,{country:qe,countries:q,activeCountry:De,formatMoney:Ut}=Cn(),[h,be]=c(()=>Tt(a)[0]?.key??null),[Je,Bt]=c(!0);m(()=>{Bt(xn(C))},[]);const[ee,b]=c(!1),[D,Ne]=c(""),[O,Pe]=c(""),[J,Se]=c(""),[te,ne]=c(""),[Ae,re]=c(""),[$,oe]=c(""),[T,ce]=c(""),[G,ae]=c(""),[u,se]=c(()=>qe||q[0]?.code||""),[v,ie]=c(""),[W,Ge]=c([]),[ve,xe]=c(null),[ue,X]=c(null),We=At(()=>q.find(e=>e.code===u)??De,[q,u,De]),zt=We?.postalLabel||"Postal Code",Ht=W[0]?.divisionType||"State / Province";m(()=>{if(!u){Ge([]),xe(u);return}xe(null);let e=!1;return y.listCountrySubdivisions(u).then(t=>{e||(Ge(t),xe(u),ie(""))}),()=>{e=!0}},[u]);const Xe=te.trim()!==""&&$.trim()!==""&&T.trim()!==""&&ve===u&&(W.length===0||v!=="")?T.trim():"";m(()=>{V(u?{country:u,subdivision:v,postcode:Xe}:null)},[u,v,Xe,V]),m(()=>()=>V(null),[V]);const qt=$t?.status==="unavailable",Dt=Yt,[le,Ze]=c(null),[Jt,je]=c([]),[Qe,Ke]=c("new"),[Ve,et]=c(!1),[Ee,Gt]=c("Home"),[Wt,tt]=c(null),[Y,Ie]=c(()=>Ce()),nt=f(null),[rt,k]=c(null),[Xt,w]=c(null),[ot,de]=c(null),[ct,Zt]=c(!1),[at,jt]=c(!1),[x,F]=c(null),[Qt,U]=c(!1),[g,K]=c(null),[Vt,N]=c(null),[en,tn]=c(!1),[nn,st]=c(!1),[rn,on]=c(!1),[cn,it]=c(!1),[ut,an]=c(!1),[sn,Oe]=c(!1),[Te,lt]=c(null),B=f(null),pe=f(i),_e=f(null),Re=f(null),dt=!!(rt||Te&&Te.kind!=="processing"||ut||ct||at||ot&&x?.orderNumber);m(()=>{dt&&(ze([]),He())},[dt,ze,He]);const pt=f(!1);m(()=>{d||pt.current||!i.some(vt)||(pt.current=!0,Pn({lines:i,currency:A.currency,value:A.subtotal-A.discount,coupon:M?.valid?M.code:void 0}))},[i,A,M,d]),m(()=>{Be(D,O.trim()||void 0)},[D,O,Be]);const mt=f(null),[me,un]=c(null);m(()=>{const e=mt.current;if(!me||!e)return;const t=()=>e.style.setProperty("--sf-checkout-header-h",`${me.offsetHeight}px`);t();const n=new ResizeObserver(t);return n.observe(me),()=>n.disconnect()},[me]),m(()=>{const e=n=>({setConfirming:n,land:k,markPaid:()=>U(!0),note:N,fail:w,clearCart:L}),t={search:window.location.search,storage:C,scrubQuery:()=>window.history.replaceState(null,"",window.location.pathname)};xt(En,{...t,capture:y.captureAfterpayPayment,page:e(tn)}),xt(On,{...t,capture:y.captureZipPayment,page:e(on)})},[]),m(()=>{const t=new URLSearchParams(window.location.search).get("gocardless");if(t!=="confirm"&&t!=="cancel")return;const n=C.getItem(Le);if(C.removeItem(Le),window.history.replaceState(null,"",window.location.pathname),!n)return;let r;try{r=JSON.parse(n)}catch{return}if(L(),t==="cancel"){N("The direct debit was not set up — our team will follow up on payment."),k(r.confirmation);return}st(!0),y.completeGocardlessPayment({idempotencyKey:r.idempotencyKey}).then(o=>{o.status==="paid"?U(!0):o.status==="declined"?N("The direct debit was declined — our team will follow up on payment."):N("Your direct debit is set up — the payment is collecting and will clear in a few days.")}).catch(()=>{N("We could not confirm the direct debit — our team will follow up on payment.")}).finally(()=>{k(r.confirmation),st(!1)})},[]),m(()=>{const e=new URLSearchParams(window.location.search),t=e.get("klarna");if(t!=="confirm"&&t!=="cancel")return;const n=C.getItem($e);C.removeItem($e);const r=e.get("authorization_token");if(window.history.replaceState(null,"",window.location.pathname),!n)return;let o;try{o=JSON.parse(n)}catch{return}if(L(),t==="cancel"||!r){N("The Klarna payment was not completed — our team will follow up on payment."),k(o.confirmation);return}it(!0),y.captureKlarnaPayment({idempotencyKey:o.idempotencyKey,authorizationToken:r}).then(s=>{s.status==="paid"?U(!0):s.status==="declined"?N("Klarna declined the payment — our team will follow up on payment."):N("Your Klarna payment is being reviewed — we'll confirm the outcome shortly.")}).catch(()=>{N("We could not confirm the Klarna payment — our team will follow up on payment.")}).finally(()=>{k(o.confirmation),it(!1)})},[]);function ft(e){const[t,n]=Ot(e.address);ne(t),re(n),oe(e.city),ce(e.zip_code),e.country&&se(e.country),e.phone&&ae(e.phone),X({country:e.country||null,state:e.state??""})}m(()=>{if(ue){if((ue.country||u)!==u){X(null);return}ve===u&&(ie(Tn(u,ue.state,W)),X(null))}},[ue,u,ve,W]),m(()=>{let e=!1;return(async()=>{try{const[t,n,r]=await Promise.all([j.me(),j.myProfile().catch(()=>null),j.myAddresses().catch(()=>[])]);if(e)return;Ze(t);const o=r.filter(Z=>Z.is_active);je(o),Ne(t.email);const s=(n?.contact_name??"").split(/\s+/);Pe(t.first_name||s[0]||""),Se(t.last_name||s.slice(1).join(" "));const l=t.phone||n?.phone;l&&ae(l);const R=o.find(Z=>Z.id===t.default_delivery_location)??o[0];if(R)Ke(R.id),ft(R);else if(n){const[Z,hn]=Ot(n.address??"");ne(Z),re(hn),oe(n.city??""),ce(n.zip_code??""),n.country&&se(n.country),X({country:n.country||null,state:n.state??""})}}catch{}})(),()=>{e=!0}},[]);function ln(){j.logout(),Ze(null),je([]),Ke("new"),et(!1),Ne(""),Pe(""),Se(""),ne(""),re(""),oe(""),ce(""),ae(""),se(qe||q[0]?.code||""),ie(""),X(null)}const z=At(()=>Tt(a,{canParkContext:Je}),[a,Je]);m(()=>{z.some(e=>e.key===h)||be(z[0]?.key??null)},[z,h]);const dn=z.length===0,fe=Ae.trim()?`${te}
|
|
3
|
+
${Ae.trim()}`:te,E=JSON.stringify([D,O,J,G,fe,$,v,T,u,i.map(e=>[e.id,e.qty]),Q,It(M),h,A.currency,le?.id??null]),ye=f(null),P=f(!1),H=f(null),he=f(!1),we=f(E);we.current=E;const yt=f(ee);yt.current=ee;const ht=()=>P.current&&we.current!==ye.current,_=f(null);m(()=>{yt.current||(E!==_.current&&(_.current=null),!(!P.current||!g||g.orderNumber)&&(E===ye.current||E===_.current||ge(g)))},[E,g]);async function ge(e){if(!he.current){he.current=!0,b(!0);try{const t=H.current?await $n(H.current):"none";if(t==="succeeded"||t==="processing"){P.current=!1,K(null),t==="succeeded"?await I(void 0,e):bt(e);return}if(t===void 0||!Mn.has(t)){_.current=we.current,K(e),w(t==="requires_action"?Rn:Fe);return}const n=await Et(Y);if(n==="committed"){P.current=!1,K(null),await I(void 0,e);return}if(n!=="released"){_.current=we.current,K(e),w(Fe);return}P.current=!1,H.current=null,_.current=null,w(null),K(null),Ie(Ce())}finally{he.current=!1,b(!1)}}}async function pn(){if(d||ee||he.current)return;if(g){if(P.current&&!g.orderNumber&&E!==ye.current){await ge(g);return}b(!0),w(null),await Me();const r=g.orderNumber?h:"card";r!==h&&be(r),await Nt(g,r,!g.orderNumber);return}if(i.length===0||A.repricing||!h||!z.some(r=>r.key===h))return;const e=i.filter(vt).flatMap(r=>vn(r.components,r.qty));if(e.length===0){w("Pick a size on each wheel's product page before checking out.");return}b(!0),w(null);let t,n=Y;try{const r=le?y.createOrderAuthed:y.createOrder,o=Nn(),s={customer:{email:D,name:`${O} ${J}`.trim(),phone:G.trim()||void 0,address:fe,city:$,state:v||void 0,zipCode:T,country:u},items:e,currency:A.currency,idempotencyKey:Y,shippingMethodId:Q??void 0,couponCode:It(M),...o==="denied"?{}:bn(),...o?{adConsent:o}:{},...Ln(h)?{checkoutFlow:Kt}:{}};B.current=()=>r(s),H.current=null,P.current=!1,_.current=null,ye.current=E,pe.current=i,kt(s,r);const l=await(!s.checkoutFlow&&Re.current===s.idempotencyKey?wt(s,r):r(s).then(R=>({answer:R,request:s})).catch(R=>mn(R,s,r)));if(!l)return;t=l.answer,n=l.request.idempotencyKey,t.orderNumber&&(Ct(t),L()),await Me()}catch(r){const o=Fn(r);o?(Mt(o),w(`${o} Your order has not been placed. Place it again to continue without the code.`)):r instanceof _t?w(Fe):w(r instanceof ke?r.message:"Could not place the order. Please try again."),b(!1);return}await Nt(t,h,!1,n)}async function mn(e,t,n){if(Ye(e))return gt(t,n);if(!_n(e))throw e;return Re.current=t.idempotencyKey,wt(t,n)}async function wt(e,t){const n=await Et(e.idempotencyKey);if(n==="released")return gt(e,t);if(n!=="committed")throw new _t;const r=_e.current?.key===e.idempotencyKey?_e.current:null;pe.current=r?.lines??i;const o=r?.send??(()=>t({...e,checkoutFlow:Kt}));B.current=o;const s=await o();return b(!1),await I(s,{...s,orderNumber:""}),await Me(),null}async function gt(e,t){const n={...e,idempotencyKey:Ce()};return Re.current=null,Ie(n.idempotencyKey),B.current=()=>t(n),kt(n,t),{answer:await t(n),request:n}}function kt(e,t){e.checkoutFlow&&(_e.current={key:e.idempotencyKey,send:()=>t(e),lines:i})}function Ct(e){Sn({confirmation:e,lines:pe.current,adsSendTo:a.googleAdsId&&a.googleAdsConversionLabel?`${a.googleAdsId}/${a.googleAdsConversionLabel}`:null}),An({confirmation:e,lines:pe.current})}async function I(e,t=x){if(!t)return;const n=e?async()=>e:B.current;if(t.orderNumber||!n){U(!0),k(t);return}L(),await Yn({checkoutNumber:t.checkoutNumber,resend:n,page:{setConfirming:an,land:k,markPaid:()=>U(!0),track:Ct,unplaced:lt}})}function bt(e=x){if(e){if(e.orderNumber){k(e);return}L(),lt({kind:"processing",checkoutNumber:e.checkoutNumber})}}async function Me(){const e=JSON.stringify([Ee.trim(),O,J,G.trim(),fe,$,v,T,u]);if(!(!le||!Ve||Qe!=="new"||nt.current===e))try{await j.createAddress({label:Ee.trim()||"Home",contact_name:`${O} ${J}`.trim(),phone:G.trim(),address:fe,city:$,zip_code:T,state:v,country:u}),nt.current=e,tt("Address saved to your account.")}catch{tt("We couldn't save the address to your account — you can add it under Account → Addresses.")}}async function Nt(e,t=h,n=!1,r=Y){K(null);try{if(t==="card"&&a.paymentMethods.includes("card")){const o=await y.createPaymentIntent({idempotencyKey:r});if(H.current=o,n&&ht()){await ge(e);return}let s=e;if(n){const l=await B.current?.().catch(()=>null);if(l?.orderNumber){await I(l,e);return}if(s=Pt(e,l)??{...e,expiresAt:null},ht()){await ge(e);return}}F(s),Oe(!1),de(o)}else if(t==="paypal"&&a.paymentMethods.includes("paypal"))F(e),Zt(!0);else if(t==="afterpay"&&a.paymentMethods.includes("afterpay")){const o=window.location.origin,s=await y.createAfterpayCheckout({idempotencyKey:r,confirmUrl:`${o}/checkout?afterpay=confirm`,cancelUrl:`${o}/checkout?afterpay=cancel`}),l={idempotencyKey:r,confirmation:e};C.setItem(Kn,JSON.stringify(l)),window.location.assign(s.redirectCheckoutUrl);return}else if(t==="square"&&a.paymentMethods.includes("square"))F(e),jt(!0);else if(t==="gocardless"&&a.paymentMethods.includes("gocardless")){const o=window.location.origin,s=await y.createGocardlessBillingRequest({idempotencyKey:r,confirmUrl:`${o}/checkout?gocardless=confirm`,cancelUrl:`${o}/checkout?gocardless=cancel`}),l={idempotencyKey:r,confirmation:e};C.setItem(Le,JSON.stringify(l)),window.location.assign(s.authorisationUrl);return}else if(t==="zip"&&a.paymentMethods.includes("zip")){const o=window.location.origin,s=await y.createZipCheckout({idempotencyKey:r,redirectUrl:`${o}/checkout?zip=return`}),l={idempotencyKey:r,confirmation:e};C.setItem(In,JSON.stringify(l)),window.location.assign(s.redirectUrl);return}else if(t==="klarna"&&a.paymentMethods.includes("klarna")){const o=window.location.origin,s=await y.createKlarnaCheckout({idempotencyKey:r,confirmUrl:`${o}/checkout?klarna=confirm`,cancelUrl:`${o}/checkout?klarna=cancel`}),l={idempotencyKey:r,confirmation:e};C.setItem($e,JSON.stringify(l)),window.location.assign(s.redirectUrl);return}else k(e)}catch(o){if((n||t==="card")&&o instanceof ke&&o.status===409){await I(void 0,e);return}St(e,o),b(!1)}}function Pt(e,t){return t&&!t.orderNumber&&t.status==="open"&&t.checkoutNumber===e.checkoutNumber?t:null}function St(e,t){w(Un(e,t)),!e.orderNumber&&Ye(t)?(P.current=!1,Ie(Ce())):K(e)}async function fn(e){if(!x)return;const t=x;try{const n=await y.createPaymentIntent({idempotencyKey:Y}),r=await B.current?.().catch(()=>null);if(r?.orderNumber){await I(r);return}const o=Pt(t,r);F(o??{...t,expiresAt:null}),Oe(e&&o!==null),H.current=n,de(n)}catch(n){if(n instanceof ke&&n.status===409){await I();return}de(null),F(null),St(t,n),b(!1)}}function yn(){x&&(P.current=!0,K(x),de(null),F(null),Oe(!1),b(!1))}return{site:a,logo:p,items:i,totals:A,coupon:M,deliveryOptions:Ue,courierUnavailable:qt,retryCourier:Dt,shippingMethodId:Q,setShippingMethodId:Lt,pickupLocation:Ft,servedCountries:q,formatMoney:Ut,payChoice:h,setPayChoice:be,placing:ee,email:D,setEmail:Ne,firstName:O,setFirstName:Pe,lastName:J,setLastName:Se,address1:te,setAddress1:ne,address2:Ae,setAddress2:re,city:$,setCity:oe,postcode:T,setPostcode:ce,phone:G,setPhone:ae,country:u,setCountry:se,subdivision:v,setSubdivision:ie,subdivisions:W,destination:We,postcodeLabel:zt,subdivisionLabel:Ht,me:le,savedAddresses:Jt,selectedAddressId:Qe,setSelectedAddressId:Ke,saveAddress:Ve,setSaveAddress:et,saveLabel:Ee,setSaveLabel:Gt,addressSaveNote:Wt,idemKey:Y,confirmation:rt,setConfirmation:k,orderError:Xt,payment:ot,paypalStep:ct,squareStep:at,pendingConf:x,paid:Qt,setPaid:U,unpaidOrder:g,payNote:Vt,afterpayConfirming:en,gocardlessConfirming:nn,zipConfirming:rn,klarnaConfirming:cn,cardConfirming:ut,checkoutResult:Te,confirmCardPayment:I,cardStillProcessing:bt,renewCardPayment:fn,holdRenewed:sn,leaveCardPayment:yn,checkoutRootRef:mt,setCheckoutHeaderEl:un,fillFromAddress:ft,checkoutSignOut:ln,payOptions:z,noPaymentMethod:dn,placeOrder:pn}}const Rt=wn(null);function sr({children:a,...p}){const d=Bn(p);return S(Rt.Provider,{value:d,children:a})}function ir(){const a=gn(Rt);if(!a)throw new Error("useCheckout must be used inside CheckoutStateProvider");return a}export{sr as CheckoutStateProvider,cr as NO_PAYMENT_METHOD_NOTE,ar as SHIPPING_RETRY_NOTE,Tt as buildPayOptions,Un as paymentNotStartedMessage,ir as useCheckout};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as
|
|
1
|
+
import{jsx as t}from"react/jsx-runtime";import{InsideSiteColumn as o}from"efficient-web-builder/render/components/SiteGutterFrame";const e="border-t border-line pt-5";function l(r){return r&&!Array.isArray(r)?r:void 0}function m(r,n){if(!r)return null;const i=n?e:`${e} empty:hidden`;return t(o,{children:t(r,{className:i,minEmptyHeight:40})})}export{e as TRUST_BULLETS_ROW_CLASS,m as trustBulletsRow,l as trustBulletsSlot};
|
|
@@ -266,6 +266,8 @@ export type CouponPreview = CouponValidateResponse & {
|
|
|
266
266
|
askedAsShopper: boolean;
|
|
267
267
|
};
|
|
268
268
|
export type PaymentIntentRequest = components["schemas"]["PaymentIntentRequest"];
|
|
269
|
+
export type CheckoutRelease = components["schemas"]["CheckoutRelease"];
|
|
270
|
+
export type CheckoutReleaseKeyRequest = components["schemas"]["CheckoutReleaseKeyRequest"];
|
|
269
271
|
export type PaymentIntent = components["schemas"]["PaymentIntent"];
|
|
270
272
|
export type PaypalOrderRequest = components["schemas"]["PaypalOrderRequest"];
|
|
271
273
|
export type PaypalOrder = components["schemas"]["PaypalOrder"];
|
|
@@ -331,6 +333,7 @@ export declare const fitment: {
|
|
|
331
333
|
};
|
|
332
334
|
export declare const products: {
|
|
333
335
|
listWheels: (process?: string | null, opts?: ListReadOpts) => Promise<WheelSummary[]>;
|
|
336
|
+
listWheelsBySlug: (slugs: readonly string[], opts?: ListReadOpts) => Promise<WheelSummary[]>;
|
|
334
337
|
listCatalog: (kinds: readonly ProductKind[], vehicle?: TyreFitVehicleQuery | null) => Promise<ProductSummary[]>;
|
|
335
338
|
getWheel: (slug: string) => Promise<Wheel>;
|
|
336
339
|
getTyre: (slug: string) => Promise<Tyre>;
|
|
@@ -360,6 +363,7 @@ export declare const products: {
|
|
|
360
363
|
createOrderAuthed: (body: OrderRequest) => Promise<OrderConfirmation>;
|
|
361
364
|
lookupOrder: (body: OrderLookupRequest) => Promise<OrderTracking>;
|
|
362
365
|
createPaymentIntent: (body: PaymentIntentRequest) => Promise<PaymentIntent>;
|
|
366
|
+
releaseCheckout: (body: CheckoutReleaseKeyRequest) => Promise<CheckoutRelease>;
|
|
363
367
|
createPaypalOrder: (body: PaypalOrderRequest) => Promise<PaypalOrder>;
|
|
364
368
|
capturePaypalOrder: (body: PaypalCaptureRequest) => Promise<PaymentOutcome>;
|
|
365
369
|
createAfterpayCheckout: (body: AfterpayCheckoutRequest) => Promise<AfterpayCheckout>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{PREVIEW_TOKEN_HEADER as tt,SITE_HOST_HEADER as et,SITE_SLUG_HEADER as rt}from"../site-headers.js";import{PRODUCT_API_BASE as at,PRODUCT_BACKEND_URL as k}from"./origins.js";import{backendHopHeaders as st,clientIpFromForwardedFor as nt,FORWARDED_FOR_HEADER as ot,hopCachingOf as it}from"../forwarded-for.js";import ct from"efficient-web-builder/format/lib/document/media-manifest.json";import{auth as P}from"../auth.js";import{efficientClientOpen as dt}from"efficient-easel/screen/lib/session";import{listableWheelSummaries as J}from"../wheels/listable-wheels.js";import{dropRenderlessFinishes as L}from"../wheels/renderable-finishes.js";const ut=process.env.NEXT_PUBLIC_API_URL??"http://localhost:8000";class m extends Error{status;data;constructor(e,s,o){super(s),this.status=e,this.data=o}}const U="Unable to reach the server. This could be a problem with your internet connection, or the server may be undergoing maintenance or an upgrade. Please try again shortly.",lt=new Set([502,503,504]),I=0,pt="This editor runs on its host's own backend, which does not serve this request.",yt=5e3,ht=15e3,ft=()=>typeof window>"u"?yt:ht;function D(t){const e=(t.method??"GET").toUpperCase();if(!(t.body!=null||e!=="GET"&&e!=="HEAD")&&!(t.audience!=null&&t.audience!=="shop")&&typeof AbortSignal?.timeout=="function")return AbortSignal.timeout(ft())}const x=t=>t instanceof Error&&t.name==="TimeoutError",H=(t,e)=>lt.has(t)?U:e,gt=["admin","venue"];let F="admin";function ne(t){F=gt.includes(t)?t:"admin"}function mt(){return F}const wt=/^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{1,8})*$/;let M=null;function oe(t){M=t&&wt.test(t)?t:null}function St(){return M}function Pt(t){if(typeof window>"u"||!t.startsWith("/api/v1/"))return t;const e=j();return!e||/[?&]site=/.test(t)?t:E(t,`site=${encodeURIComponent(e)}`)}async function i(t,e={}){const{token:s,baseUrl:o,headers:l,audience:p,...w}=e;if(typeof window<"u"&&!dt())throw new m(I,pt,null);if(typeof window>"u"&&o===void 0)throw new Error(`apiFetch(${JSON.stringify(t)}) ran on the server without an explicit baseUrl. The API_URL default it would inherit is browser-only (the prod image bakes NEXT_PUBLIC_API_URL="" for same-origin use, which a Node fetch cannot resolve). Pass a base explicitly: \`await backendOpts()\` (or baseUrl: PRODUCT_FETCH_BASE) for product reads, or the server-only PRODUCT_BACKEND_URL env for other backend surfaces.`);const a=typeof FormData<"u"&&w.body instanceof FormData;let r;try{r=await fetch(`${o??ut}${Pt(t)}`,{...w,headers:{...a?{}:{"Content-Type":"application/json"},...s?{Authorization:`Bearer ${s}`}:{},...p===null?{}:{"X-Portal-Audience":p??"shop"},...l},signal:w.signal??D({...w,audience:p})})}catch(y){throw y instanceof TypeError||x(y)?new m(I,U,null):y}let n;try{n=await r.text()}catch(y){throw x(y)?new m(I,U,null):y}let c=null;if(n)try{c=JSON.parse(n)}catch{throw new m(r.status,r.ok?"Expected JSON but received a non-JSON response":H(r.status,r.statusText),n)}if(!r.ok){const y=(c&&typeof c=="object"&&"detail"in c&&typeof c.detail=="string"?c.detail:null)??H(r.status,r.statusText);throw new m(r.status,y,c)}return c}let b=null;async function B(){return b||(b=Ot().finally(()=>{b=null}),b)}async function Ot(){const t=P.takeLegacyRefresh(),e=await bt.refresh(t??void 0);return P.setTokens(e.access),e.access}async function q(){return P.getAccess()??B()}async function h(t,e={}){let s;try{s=await q()}catch{throw P.clear(),new m(401,"Not signed in",null)}try{return await i(t,{...e,token:s})}catch(o){if(!(o instanceof m)||o.status!==401)throw o;try{const l=await B();return await i(t,{...e,token:l})}catch{throw P.clear(),o}}}async function G(t,e={}){if(P.getAccess())try{return{data:await h(t,e),asShopper:!0}}catch(s){if(!(s instanceof m)||s.status!==401)throw s}return{data:await i(t,e),asShopper:!1}}async function W(){const t=await h("/api/auth/me/");if(t.portal!=="shop")throw P.clear(),new m(403,"This session is not valid for this shop.",null);return t}const bt={login:(t,e)=>i("/api/auth/login/",{method:"POST",body:JSON.stringify({email:t,password:e,portal:"shop"}),credentials:"include"}),refresh:t=>i("/api/auth/refresh/",{method:"POST",body:JSON.stringify(t?{refresh:t,portal:"shop"}:{portal:"shop"}),credentials:"include"}),logout:async()=>{P.clear();try{await i("/api/auth/logout/",{method:"POST",body:JSON.stringify({portal:"shop"}),credentials:"include"})}catch{}},restoreSession:async()=>{const t=await q();return await W(),t},me:W,updateMe:t=>h("/api/auth/me/",{method:"PATCH",body:JSON.stringify(t)}),changePassword:(t,e)=>h("/api/auth/me/",{method:"PATCH",body:JSON.stringify({password:e,old_password:t})}),changeEmail:(t,e)=>h("/api/shop-portal/change-email/",{method:"POST",body:JSON.stringify({new_email:t,current_password:e})}),myProfile:()=>h("/api/shop-portal/profile/"),updateMyProfile:t=>h("/api/shop-portal/profile/",{method:"PATCH",body:JSON.stringify(t)}),myAddresses:()=>h("/api/shop-portal/delivery-locations/"),createAddress:t=>h("/api/shop-portal/delivery-locations/",{method:"POST",body:JSON.stringify(t)}),updateAddress:(t,e)=>h(`/api/shop-portal/delivery-locations/${t}/`,{method:"PATCH",body:JSON.stringify(e)}),deleteAddress:t=>h(`/api/shop-portal/delivery-locations/${t}/`,{method:"DELETE"}),passwordResetRequest:t=>i("/api/auth/password-reset/",{method:"POST",body:JSON.stringify({email:t})}),passwordResetConfirm:(t,e,s)=>i("/api/auth/password-reset/confirm/",{method:"POST",body:JSON.stringify({uid:t,token:e,new_password:s})}),brands:()=>h("/api/products/brands/"),myOrders:()=>h("/api/shop-portal/orders/").then(t=>t.results),myOrder:t=>h(`/api/shop-portal/orders/${t}/`),cancelOrder:t=>h(`/api/shop-portal/orders/${t}/cancel/`,{method:"POST"}),myReturns:t=>h(`/api/shop-portal/returns/${t?`?order=${encodeURIComponent(t)}`:""}`).then(e=>e.results),createReturn:t=>h("/api/shop-portal/returns/",{method:"POST",body:JSON.stringify(t)}),withdrawReturn:t=>h(`/api/shop-portal/returns/${t}/cancel/`,{method:"POST"}),uploadReturnPhoto:(t,e)=>{const s=new FormData;return s.append("claim_item",t),s.append("file",e),s.append("media_type",e.type.startsWith("video/")?"video":"image"),h("/api/shop-portal/return-media/",{method:"POST",body:s})}};import{media as At,absolutizeApiUrl as N}from"efficient-web-builder/render/lib/media";import{analyzeLogoSvg as Tt,isSvgUrl as Rt}from"efficient-web-builder/format/lib/logo/reverse-svg";import{getEditorSiteId as Et}from"efficient-web-builder/render/lib/editor-site";import{shopRouteBase as Ct,webRuntimeSiteSlug as j}from"efficient-web-builder/format/lib/web-runtime";function g(t){if(typeof t=="string")return t.startsWith("/media/")?At(t):t;if(Array.isArray(t))return t.map(g);if(t&&typeof t=="object"){const e={};for(const[s,o]of Object.entries(t))e[s]=s==="captions"&&o&&typeof o=="object"&&!Array.isArray(o)?Object.fromEntries(Object.entries(o).map(([l,p])=>[g(l),p])):g(o);return e}return t}import{PRODUCT_API_BASE as we}from"./origins.js";const z=typeof window>"u"&&k!=="",$t=z?k:at,_t=Ct,O=()=>({baseUrl:_t(),audience:null});function d(t,e){const s=e?`?process=${encodeURIComponent(e)}`:"";return`/api/v1${t}${s}`}const Ut=100,K=50;function V(t,e,s){const o=new URLSearchParams;for(const[l,p]of Object.entries(e))p!=null&&p!==""&&o.set(l,String(p));return o.set("pageSize",String(Ut)),s&&o.set("cursor",s),`/api/v1${t}?${o.toString()}`}function It(t,e){return V("/wheels",{process:t},e)}function Nt(t,e,s){return V("/products",{kind:t.join(","),make:e?.make,model:e?.model,year:e?.year,modification:e?.modification},s)}function vt(t){if(!t)return null;try{return new URL(t,"http://cursor.invalid").searchParams.get("cursor")}catch{return null}}async function X(t,e,s=()=>!1){const o=[];let l=null;try{for(let p=0;p<K;p++){const w=await i(await e(l),await u());if(o.push(...w.results),l=vt(w.next),!l)break}l&&console.warn(`[${t}] stopped at ${K} pages (${o.length} rows); catalog may be truncated`)}catch(p){if(s(p))throw p;console.warn(`[${t}] product API unavailable, returning []`,p)}return o}const kt=t=>t instanceof m&&t.status===400;function Jt(t){return t.flatMap(e=>e.kind==="alloy-wheel"?J([e]):[e])}async function Z(){return(await Lt()).host}async function Lt(){try{const{headers:t}=await import("next/headers"),e=await t(),s=p=>p?.split(",")[0]?.split(":")[0]?.trim().toLowerCase()||null,o=s(e.get(et)??e.get("x-forwarded-host")??e.get("host")),l=s(e.get("host"));return{host:o,matchesRequestHost:o!==null&&o===l}}catch{return{host:null,matchesRequestHost:!1}}}async function Dt(){try{const{headers:t}=await import("next/headers");return nt((await t()).get(ot))}catch{return null}}async function xt(){try{const{headers:t}=await import("next/headers");return(await t()).get(rt)||null}catch{return null}}async function Ht(){const t=await xt();if(t)return`site=${encodeURIComponent(t)}`;const e=await Z();return e?`host=${encodeURIComponent(e)}`:""}async function f(t){if(typeof window<"u"){const e=j();return e?E(t,`site=${encodeURIComponent(e)}`):t}return E(t,await Ht())}function E(t,e){return e?`${t}${t.includes("?")?"&":"?"}${e}`:t}const Ft="preview";async function Mt(){if(typeof window<"u")return null;try{const{headers:t}=await import("next/headers");return(await t()).get(tt)}catch{return null}}async function Bt(){try{const{headers:t}=await import("next/headers");return(await t()).get("user-agent")}catch{return null}}async function v(t,e){const s=await Mt();if(s===null)return[await f(t),await u(e)];const o=E(await f(t),`${Ft}=${encodeURIComponent(s)}`),{next:l,cache:p,...w}=e??{},a=await u({...w,cache:"no-store"}),r=await Bt();return r&&(a.headers={...a.headers,"user-agent":r}),[o,a]}async function qt(t){if(!z)return;const[e,s]=await Promise.all([Z(),Dt()]),o=st(e,s,t);return Object.keys(o).length>0?o:void 0}async function u(t){const e=await qt(it(t)),s={baseUrl:$t,...t};return e&&(s.headers={...e,...t?.headers}),s}const A=typeof window>"u";function T(t,e){const s=new URLSearchParams;for(const[l,p]of Object.entries(e))p!==void 0&&p!==""&&s.set(l,String(p));const o=s.toString();return`/api/v1/fitment${t}${o?`?${o}`:""}`}const le={listMakes:async t=>{if(A){const{fitmentData:s}=await import("./fitment-data.js");return s.makes(t)}return(await i(T("/makes",{region:t}),O())).results},listModels:async(t,e)=>{if(A){const{fitmentData:o}=await import("./fitment-data.js");return o.models(t,e)}return(await i(T("/models",{make:t,region:e}),O())).results},listYears:async(t,e,s)=>{if(A){const{fitmentData:l}=await import("./fitment-data.js");return l.years(t,e,s)}return(await i(T("/years",{make:t,model:e,region:s}),O())).results},listModifications:async(t,e,s,o)=>{if(A){const{fitmentData:p}=await import("./fitment-data.js");return p.modifications(t,e,s,o)}return(await i(T("/modifications",{make:t,model:e,year:s,region:o}),O())).results},getStockFitment:async(t,e,s,o,l)=>{if(A){const{fitmentData:p}=await import("./fitment-data.js");return p.stockFitment(t,e,s,o,l)}return i(T("/stock-fitment",{make:t,model:e,year:s,modification:o,region:l}),O())}},pe={listWheels:async(t,e={})=>{const s=await X("products.listWheels",async o=>await f(It(t,o)),e.throwOnFailure?()=>!0:void 0);return J(g(s))},listCatalog:async(t,e)=>{if(t.length===0)throw new Error("products.listCatalog() needs at least one kind. An empty list would omit `kind`, which the contract reads as `alloy-wheel` — so the call would silently return the wheel catalog instead of nothing.");const s=await X("products.listCatalog",async o=>await f(Nt(t,e,o)),kt);return Jt(g(s))},getWheel:async t=>L(g(await i(await f(d(`/wheels/${t}`)),await u()))),getTyre:async t=>g(await i(await f(d(`/tyres/${t}`)),await u())),listBundles:async(t={})=>{try{return await i(await f(d("/bundles")),await u())}catch(e){if(t.throwOnFailure)throw e;return[]}},getBundle:async t=>i(await f(d(`/bundles/${t}`)),await u()),listGalleryBuilds:async(t={})=>{const{process:e=null,wheelSlug:s=null}=t;if(typeof window>"u"){const{listGalleryBuilds:o}=await import("./gallery-builds-data.js");return g(o(e,s))}try{const o=new URLSearchParams;e&&o.set("process",e),s&&o.set("wheelSlug",s);const l=o.toString(),p=await i(`/api/v1/gallery-builds${l?`?${l}`:""}`,O());return g(p.results)}catch(o){return console.warn("[products.listGalleryBuilds] product API unavailable, returning []",o),[]}},getSite:async()=>i(await f(d("/site")),await u()),getSiteBySlug:async t=>i(`${d("/site")}?${new URLSearchParams({site:t})}`,typeof window>"u"?await u():void 0),listPages:async()=>g(await i(await f(d("/pages")),await u())),listPopups:async()=>i(await f(d("/popups")),await u()),listProductTemplates:async()=>{try{return await i(await f(d("/product-templates")),await u())}catch(t){return console.warn("[products.listProductTemplates] unavailable, returning []",t),[]}},listDynamicPages:async t=>{const e=t?`?recordType=${encodeURIComponent(t)}`:"";try{return await i(await f(`${d("/dynamic-pages")}${e}`),await u())}catch(s){if(s instanceof m&&s.status===404)return[];throw s}},getRecord:async(t,e)=>{try{return await i(await f(d(`/records/${encodeURIComponent(t)}/${encodeURIComponent(e)}`)),await u())}catch(s){if(s instanceof m&&s.status===404)return null;throw s}},listRecordKeys:async t=>{try{const e=await i(await f(d(`/records/${encodeURIComponent(t)}`)),await u({cache:"no-store"}));return Array.isArray(e?.keys)?e.keys.filter(s=>typeof s=="string"&&s!==""):[]}catch(e){if(e instanceof m&&e.status===404)return[];throw e}},listProductTypeChoices:async()=>{try{return await i(await f(d("/product-type-choices")),await u())}catch(t){return console.warn("[products.listProductTypeChoices] unavailable, returning []",t),[]}},listFieldUsage:async()=>{try{return await i(await f(d("/field-usage")),await u())}catch(t){return console.warn("[products.listFieldUsage] unavailable, returning []",t),[]}},getPage:async(t,e={})=>{const s=e.record?`?record=${encodeURIComponent(e.record)}`:"",[o,l]=await v(d(`/pages/${t}`)+s,e.revalidate!==void 0?{next:{revalidate:e.revalidate}}:void 0);return g(await i(o,l))},listBlogPosts:async(t={},{throwOnFailure:e=!1}={})=>{const s=t.category?`?category=${encodeURIComponent(t.category)}`:"";try{return(await i(d("/blog-posts")+s,await u())).map(l=>({...l,coverImage:N(l.coverImage)??""}))}catch(o){if(e)throw o;return console.warn("[products.listBlogPosts] blog API unavailable, returning []",o),[]}},getBlogPost:async t=>{const e=await i(d(`/blog-posts/${t}`),await u());return{...e,coverImage:N(e.coverImage)??""}},createOrder:async t=>i(d("/orders"),await u({method:"POST",body:JSON.stringify(t)})),createOrderAuthed:async t=>h(d("/orders"),await u({method:"POST",body:JSON.stringify(t)})),lookupOrder:async t=>i(d("/orders/lookup"),await u({method:"POST",body:JSON.stringify(t)})),createPaymentIntent:async t=>i(d("/payments/intent"),await u({method:"POST",body:JSON.stringify(t)})),createPaypalOrder:async t=>i(d("/payments/paypal/order"),await u({method:"POST",body:JSON.stringify(t)})),capturePaypalOrder:async t=>i(d("/payments/paypal/capture"),await u({method:"POST",body:JSON.stringify(t)})),createAfterpayCheckout:async t=>i(d("/payments/afterpay/checkout"),await u({method:"POST",body:JSON.stringify(t)})),captureAfterpayPayment:async t=>i(d("/payments/afterpay/capture"),await u({method:"POST",body:JSON.stringify(t)})),chargeSquare:async t=>i(d("/payments/square/charge"),await u({method:"POST",body:JSON.stringify(t)})),createGocardlessBillingRequest:async t=>i(d("/payments/gocardless/billing-request"),await u({method:"POST",body:JSON.stringify(t)})),completeGocardlessPayment:async t=>i(d("/payments/gocardless/complete"),await u({method:"POST",body:JSON.stringify(t)})),createZipCheckout:async t=>i(d("/payments/zip/checkout"),await u({method:"POST",body:JSON.stringify(t)})),captureZipPayment:async t=>i(d("/payments/zip/capture"),await u({method:"POST",body:JSON.stringify(t)})),createKlarnaCheckout:async t=>i(d("/payments/klarna/checkout"),await u({method:"POST",body:JSON.stringify(t)})),captureKlarnaPayment:async t=>i(d("/payments/klarna/capture"),await u({method:"POST",body:JSON.stringify(t)})),createStockAlert:async t=>i(d("/stock-alerts"),await u({method:"POST",body:JSON.stringify(t)})),createPreOrderIntent:async t=>i(d("/pre-order-intents"),await u({method:"POST",body:JSON.stringify(t)})),createNewsletterSubscription:async t=>i(d("/newsletter-subscriptions"),await u({method:"POST",body:JSON.stringify(t)})),unsubscribeNewsletter:async t=>i(d("/newsletter-unsubscribe"),await u({method:"POST",body:JSON.stringify(t)})),captureCart:async t=>i(d("/carts"),await u({method:"POST",body:JSON.stringify(t)})),restoreCart:async t=>i(d("/carts/restore"),await u({method:"POST",body:JSON.stringify(t)})),unsubscribeCartReminders:async t=>i(d("/carts/unsubscribe"),await u({method:"POST",body:JSON.stringify(t)})),listReviews:async(t={})=>{const e=new URLSearchParams;t.limit&&e.set("limit",String(t.limit)),t.designCode&&e.set("designCode",t.designCode);const s=d("/reviews"),o=e.toString();try{return await i(await f(o?`${s}?${o}`:s),await u())}catch(l){return console.warn("[products.listReviews] product API unavailable, returning []",l),[]}},submitReview:async t=>i(d("/reviews"),await u({method:"POST",body:JSON.stringify(t)})),getForm:async t=>i(d(`/forms/${encodeURIComponent(t)}`),await u()),submitForm:async(t,e)=>i(d(`/forms/${encodeURIComponent(t)}/submissions`),await u({method:"POST",body:JSON.stringify(e)})),listShippingMethods:async()=>{try{return await i(d("/shipping-methods"),await u())}catch(t){return console.warn("[products.listShippingMethods] product API unavailable, returning []",t),[]}},listCountrySubdivisions:async t=>{try{return await i(d(`/countries/${encodeURIComponent(t)}/subdivisions`),await u())}catch(e){return console.warn("[products.listCountrySubdivisions] unavailable, returning []",e),[]}},quoteCart:async t=>{const e=d("/cart/quote"),s=await u({method:"POST",body:JSON.stringify(t)});return t.couponCode?(await G(e,s)).data:i(e,s)},validateCoupon:async t=>{const{data:e,asShopper:s}=await G(d("/coupons/validate"),await u({method:"POST",body:JSON.stringify(t)}));return{...e,askedAsShopper:s}},getHeaderSettings:async()=>{const t=D({method:"GET"}),e=await i(...await v(d("/header-settings"),{signal:t})),s=N(e.logoUrl);let o=null,l=null;if(s&&Rt(s)){const p=await Tt(s,t);p&&(o=p.reversed,l=p.inkIsDark)}return{...e,logoUrl:s,logoReversed:o,logoInkIsDark:l}},getThemeSettings:async()=>i(...await v(d("/theme-settings"))),getChatSettings:async()=>i(await f(d("/chat-settings")),await u())},ye={listServices:async()=>{try{return await i(d("/bookings/services"),await u())}catch(t){return console.warn("[bookings.listServices] API unavailable, returning []",t),{results:[],currency:"USD"}}},getAvailability:async(t,e)=>i(d(`/bookings/availability?service=${encodeURIComponent(t)}&date=${e}`),await u()),create:async t=>i(d("/bookings"),await u({method:"POST",body:JSON.stringify(t)})),get:async t=>i(d(`/bookings/manage/${encodeURIComponent(t)}`),await u()),cancel:async t=>i(d(`/bookings/manage/${encodeURIComponent(t)}/cancel`),await u({method:"POST"})),createPaymentIntent:async t=>i(d("/bookings/payments/intent"),await u({method:"POST",body:JSON.stringify({manageToken:t})}))};class Gt extends Error{slug;count;constructor(e,s){super(`Slug "${e}" exists on ${s} websites; a site is required to pick one.`),this.slug=e,this.count=s,this.name="AmbiguousPageSlugError"}}const C=(t,e,s)=>{const o=new URLSearchParams({...e?{site:e}:{},...s?{draft:"1"}:{}}).toString();return`/api/storefront/${t}/${o?`?${o}`:""}`},$=t=>`/api/storefront/sites/${encodeURIComponent(t)}/`,Wt=t=>`${$(t)}currencies/`,jt="/api/storefront/media/ingest/";class zt extends Error{constructor(){super("This editor is not connected to a website, so an upload has nowhere to go. Open the page from the website the file should belong to, then try again."),this.name="MediaUploadDestinationError"}}function Kt(){const t=Et();if(!t)throw new zt;return`${jt}?${new URLSearchParams({site:t})}`}const Vt="X-Puck-Media-Manifest",Y=ct.contentHash,_={"X-Media-Manifest":Y,[Vt]:Y},he=Q({});function Q(t){return(e,s={})=>{const o=St(),l=t.headers||o?{...o?{"Accept-Language":o}:{},...t.headers,...s.headers}:void 0;return i(e,{...s,...t.baseUrl!==void 0?{baseUrl:t.baseUrl}:{},...l?{headers:l}:{},audience:t.audience??mt()})}}function Xt(t={}){const e=Q(t),s=t.siteDrafts===!0,o=a=>C("header-settings",a,s),l=a=>C("theme-settings",a,s),p=a=>C("chat-settings",a,s),w=a=>C("social-settings",a,s);return{findPageBySlug:async(a,r,n)=>{const c=new URLSearchParams({slug:a});n&&c.set("site",n);const y=await e(`/api/storefront/pages/?${c.toString()}`,{token:r}),S=Array.isArray(y)?y:y.results??[];if(!n&&S.length>1)throw new Gt(a,S.length);return S[0]??null},getPageById:(a,r)=>e(`/api/storefront/pages/${a}/`,{token:r}),saveLayout:(a,r,n,c,y)=>e(`/api/storefront/pages/${a}/`,{method:"PATCH",body:JSON.stringify({layout:r,expected_updated_at:c,...y?{client_id:y}:{}}),token:n}),duplicatePage:(a,r,n)=>e(`/api/storefront/pages/${a}/duplicate/`,{method:"POST",body:JSON.stringify({title:r.title,slug:r.slug}),token:n}),geocode:(a,r,n)=>e(`/api/storefront/geocode/?${new URLSearchParams(n?{q:a,country:n}:{q:a})}`,{token:r}),listBlockSources:a=>e("/api/storefront/block-sources/",{token:a}),listRecordTypes:a=>e("/api/storefront/record-types/",{token:a}),createPagePreviewLink:(a,r)=>e(`/api/storefront/pages/${a}/preview-link/`,{method:"POST",token:r}),claimPageEditLock:(a,r,n,c=!1)=>e(`/api/storefront/pages/${a}/edit-lock/`,{method:"POST",body:JSON.stringify({client_id:n,takeover:c}),token:r}),releasePageEditLock:(a,r)=>e(`/api/storefront/pages/${a}/edit-lock/`,{method:"DELETE",token:r}),createTemplate:(a,r,n)=>e("/api/storefront/page-templates/",{method:"POST",body:JSON.stringify({name:a,layout:r}),headers:_,token:n}),getTemplate:(a,r)=>e(`/api/storefront/page-templates/${a}/`,{token:r}),saveTemplateLayout:(a,r,n)=>e(`/api/storefront/page-templates/${a}/`,{method:"PATCH",body:JSON.stringify({layout:r}),headers:_,token:n}),listTemplatePages:async(a,r)=>{const n=await e(`/api/storefront/template-pages/?template=${encodeURIComponent(a)}`,{token:r});return Array.isArray(n)?n:n.results??[]},findTemplatePageBySlug:async(a,r,n)=>{const c=await e(`/api/storefront/template-pages/?template=${encodeURIComponent(a)}&slug=${encodeURIComponent(r)}`,{token:n});return(Array.isArray(c)?c:c.results??[])[0]??null},createTemplatePage:(a,r,n)=>e("/api/storefront/template-pages/",{method:"POST",body:JSON.stringify({template:a,...r}),headers:_,token:n}),saveTemplatePageLayout:(a,r,n)=>e(`/api/storefront/template-pages/${a}/`,{method:"PATCH",body:JSON.stringify({layout:r}),headers:_,token:n}),deleteTemplatePage:(a,r,n)=>e(`/api/storefront/template-pages/${a}/`,{method:"DELETE",token:r,...n?.keepalive?{keepalive:!0}:{}}),listPages:async(a,r)=>{const n=new URLSearchParams({no_page:"true"});r&&n.set("site",r);const c=await e(`/api/storefront/pages/?${n.toString()}`,{token:a});return Array.isArray(c)?c:c.results??[]},createPage:(a,r,n,c)=>e("/api/storefront/pages/",{method:"POST",body:JSON.stringify({title:a,slug:r,layout:n}),token:c}),deletePage:(a,r)=>e(`/api/storefront/pages/${a}/`,{method:"DELETE",token:r}),getHeaderSettings:(a,r)=>e(o(r),{token:a}),listMenus:async(a,r)=>{const n=new URLSearchParams({no_page:"true"});r&&n.set("site",r);const c=await e(`/api/storefront/menus/?${n}`,{token:a});return Array.isArray(c)?c:c.results??[]},listBlogPosts:async(a,r={})=>{const n=new URLSearchParams({no_page:"true"});r.visibleOnly&&n.set("is_visible","true"),r.siteId&&n.set("site",r.siteId);const c=await e(`/api/storefront/blog-posts/?${n.toString()}`,{token:a});return Array.isArray(c)?c:c.results??[]},listFieldUsage:async(a,r)=>{const n=await e(`/api/storefront/field-usage/?site=${encodeURIComponent(r)}`,{token:a});return Array.isArray(n?.entries)?n.entries:[]},listCategories:async(a,r={})=>{const n=new URLSearchParams({no_page:"true"});r.visibleOnly&&n.set("is_visible","true"),r.siteId&&n.set("site",r.siteId);const c=await e(`/api/storefront/categories/?${n.toString()}`,{token:a});return[...Array.isArray(c)?c:c.results??[]].sort((S,R)=>S.sort_order-R.sort_order||S.name.localeCompare(R.name))},listForms:async(a,r={})=>{const n=new URLSearchParams({no_page:"true"});r.siteId&&n.set("site",r.siteId);const c=await e(`/api/storefront/forms/?${n.toString()}`,{token:a});return[...Array.isArray(c)?c:c.results??[]].sort((S,R)=>S.title.localeCompare(R.title))},listWheelSummaries:async(a,r={})=>{const n=new URLSearchParams;r.siteId&&n.set("site",r.siteId);const c=n.toString(),y=await e(`/api/storefront/wheel-curations/summaries/${c?`?${c}`:""}`,{token:a});return g(y)},listProducts:async(a,r={})=>{const n=new URLSearchParams;r.kinds?.length&&n.set("kind",r.kinds.join(",")),r.siteId&&n.set("site",r.siteId);const c=n.toString(),y=await e(`/api/storefront/products/${c?`?${c}`:""}`,{token:a});return g(y)},getWheelDetail:async(a,r,n={})=>{const c=new URLSearchParams({slug:r});return n.siteId&&c.set("site",n.siteId),L(g(await e(`/api/storefront/wheel-curations/detail/?${c.toString()}`,{token:a})))},updateHeaderSettings:(a,r,n)=>e(o(n),{method:"PATCH",body:JSON.stringify(a),token:r}),getSite:(a,r)=>e($(a),{token:r}),listSites:async a=>{const r=await e("/api/storefront/sites/?no_page=true",{token:a});return Array.isArray(r)?r:r.results??[]},listSiteCurrencies:async(a,r)=>{const n=await e(Wt(a),{token:r});return Array.isArray(n)?n:[]},publishSite:(a,r)=>e(`${$(a)}publish/`,{method:"POST",token:r}),getSiteLiveState:(a,r)=>e(`${$(a)}live-state/`,{token:r}),getThemeSettings:(a,r)=>e(l(r),{token:a}),updateThemeSettings:(a,r,n)=>e(l(n),{method:"PATCH",body:JSON.stringify(a),token:r}),getChatSettings:(a,r)=>e(p(r),{token:a}),updateChatSettings:(a,r,n)=>e(p(n),{method:"PATCH",body:JSON.stringify(a),token:r}),getSocialSettings:(a,r)=>e(w(r),{token:a}),updateSocialSettings:(a,r,n)=>e(w(n),{method:"PATCH",body:JSON.stringify(a),token:r}),uploadHeaderLogo:(a,r,n)=>{const c=new FormData;return c.append("logo",a),e(o(n),{method:"PATCH",body:c,token:r})},clearHeaderLogo:(a,r)=>e(o(r),{method:"PATCH",body:JSON.stringify({logo:null}),token:a}),setHeaderLogoFromAsset:(a,r,n)=>e(o(n),{method:"PATCH",body:JSON.stringify({logo_asset_id:a}),token:r}),uploadMedia:async(a,r)=>{const n=new FormData;return n.append("file",a),e(Kt(),{method:"POST",body:n,token:r})},listMedia:async(a,r)=>{const n=new URLSearchParams({no_page:"true"});r&&n.set("kind",r);const c=await e(`/api/storefront/media-assets/?${n.toString()}`,{token:a});return Array.isArray(c)?c:c.results??[]}}}const fe=Xt({siteDrafts:!0});export{ut as API_URL,Gt as AmbiguousPageSlugError,m as ApiError,ht as BROWSER_READ_TIMEOUT_MS,pt as EFFICIENT_CLIENT_CLOSED_MESSAGE,zt as MediaUploadDestinationError,Ft as PREVIEW_PARAM,we as PRODUCT_API_BASE,yt as SERVER_READ_TIMEOUT_MS,U as SERVER_UNREACHABLE_MESSAGE,I as STATUS_NETWORK_ERROR,he as adminFetch,bt as api,i as apiFetch,E as appendSiteQuery,ye as bookings,Xt as createStorefrontAdmin,D as defaultRequestDeadline,Kt as editorMediaUploadPath,mt as editorPortalAudience,St as editorRequestLanguage,le as fitment,pe as products,ft as readDeadlineMs,Dt as resolveClientIp,g as resolveMediaUrls,Mt as resolvePreviewToken,Z as resolveSiteHost,Lt as resolveSiteHostSource,xt as resolveSiteSlug,oe as setEditorLanguage,ne as setEditorPortalAudience,fe as storefrontAdmin};
|
|
1
|
+
import{PREVIEW_TOKEN_HEADER as at,SITE_HOST_HEADER as st,SITE_SLUG_HEADER as nt}from"../site-headers.js";import{PRODUCT_API_BASE as ot,PRODUCT_BACKEND_URL as D}from"./origins.js";import{backendHopHeaders as it,clientIpFromForwardedFor as ct,FORWARDED_FOR_HEADER as dt,hopCachingOf as ut}from"../forwarded-for.js";import lt from"efficient-web-builder/format/lib/document/media-manifest.json";import{auth as P}from"../auth.js";import{efficientClientOpen as pt}from"efficient-easel/screen/lib/session";import{listableWheelSummaries as U}from"../wheels/listable-wheels.js";import{dropRenderlessFinishes as x}from"../wheels/renderable-finishes.js";const yt=process.env.NEXT_PUBLIC_API_URL??"http://localhost:8000";class m extends Error{status;data;constructor(e,s,o){super(s),this.status=e,this.data=o}}const I="Unable to reach the server. This could be a problem with your internet connection, or the server may be undergoing maintenance or an upgrade. Please try again shortly.",ht=new Set([502,503,504]),N=0,ft="This editor runs on its host's own backend, which does not serve this request.",gt=5e3,wt=15e3,mt=()=>typeof window>"u"?gt:wt;function H(t){const e=(t.method??"GET").toUpperCase();if(!(t.body!=null||e!=="GET"&&e!=="HEAD")&&!(t.audience!=null&&t.audience!=="shop")&&typeof AbortSignal?.timeout=="function")return AbortSignal.timeout(mt())}const F=t=>t instanceof Error&&t.name==="TimeoutError",M=(t,e)=>ht.has(t)?I:e,St=["admin","venue"];let B="admin";function ie(t){B=St.includes(t)?t:"admin"}function Pt(){return B}const Ot=/^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{1,8})*$/;let q=null;function ce(t){q=t&&Ot.test(t)?t:null}function bt(){return q}function At(t){if(typeof window>"u"||!t.startsWith("/api/v1/"))return t;const e=K();return!e||/[?&]site=/.test(t)?t:E(t,`site=${encodeURIComponent(e)}`)}async function i(t,e={}){const{token:s,baseUrl:o,headers:l,audience:p,...w}=e;if(typeof window<"u"&&!pt())throw new m(N,ft,null);if(typeof window>"u"&&o===void 0)throw new Error(`apiFetch(${JSON.stringify(t)}) ran on the server without an explicit baseUrl. The API_URL default it would inherit is browser-only (the prod image bakes NEXT_PUBLIC_API_URL="" for same-origin use, which a Node fetch cannot resolve). Pass a base explicitly: \`await backendOpts()\` (or baseUrl: PRODUCT_FETCH_BASE) for product reads, or the server-only PRODUCT_BACKEND_URL env for other backend surfaces.`);const r=typeof FormData<"u"&&w.body instanceof FormData;let a;try{a=await fetch(`${o??yt}${At(t)}`,{...w,headers:{...r?{}:{"Content-Type":"application/json"},...s?{Authorization:`Bearer ${s}`}:{},...p===null?{}:{"X-Portal-Audience":p??"shop"},...l},signal:w.signal??H({...w,audience:p})})}catch(y){throw y instanceof TypeError||F(y)?new m(N,I,null):y}let n;try{n=await a.text()}catch(y){throw F(y)?new m(N,I,null):y}let c=null;if(n)try{c=JSON.parse(n)}catch{throw new m(a.status,a.ok?"Expected JSON but received a non-JSON response":M(a.status,a.statusText),n)}if(!a.ok){const y=(c&&typeof c=="object"&&"detail"in c&&typeof c.detail=="string"?c.detail:null)??M(a.status,a.statusText);throw new m(a.status,y,c)}return c}let b=null;async function G(){return b||(b=Tt().finally(()=>{b=null}),b)}async function Tt(){const t=P.takeLegacyRefresh(),e=await Rt.refresh(t??void 0);return P.setTokens(e.access),e.access}async function W(){return P.getAccess()??G()}async function h(t,e={}){let s;try{s=await W()}catch{throw P.clear(),new m(401,"Not signed in",null)}try{return await i(t,{...e,token:s})}catch(o){if(!(o instanceof m)||o.status!==401)throw o;try{const l=await G();return await i(t,{...e,token:l})}catch{throw P.clear(),o}}}async function j(t,e={}){if(P.getAccess())try{return{data:await h(t,e),asShopper:!0}}catch(s){if(!(s instanceof m)||s.status!==401)throw s}return{data:await i(t,e),asShopper:!1}}async function z(){const t=await h("/api/auth/me/");if(t.portal!=="shop")throw P.clear(),new m(403,"This session is not valid for this shop.",null);return t}const Rt={login:(t,e)=>i("/api/auth/login/",{method:"POST",body:JSON.stringify({email:t,password:e,portal:"shop"}),credentials:"include"}),refresh:t=>i("/api/auth/refresh/",{method:"POST",body:JSON.stringify(t?{refresh:t,portal:"shop"}:{portal:"shop"}),credentials:"include"}),logout:async()=>{P.clear();try{await i("/api/auth/logout/",{method:"POST",body:JSON.stringify({portal:"shop"}),credentials:"include"})}catch{}},restoreSession:async()=>{const t=await W();return await z(),t},me:z,updateMe:t=>h("/api/auth/me/",{method:"PATCH",body:JSON.stringify(t)}),changePassword:(t,e)=>h("/api/auth/me/",{method:"PATCH",body:JSON.stringify({password:e,old_password:t})}),changeEmail:(t,e)=>h("/api/shop-portal/change-email/",{method:"POST",body:JSON.stringify({new_email:t,current_password:e})}),myProfile:()=>h("/api/shop-portal/profile/"),updateMyProfile:t=>h("/api/shop-portal/profile/",{method:"PATCH",body:JSON.stringify(t)}),myAddresses:()=>h("/api/shop-portal/delivery-locations/"),createAddress:t=>h("/api/shop-portal/delivery-locations/",{method:"POST",body:JSON.stringify(t)}),updateAddress:(t,e)=>h(`/api/shop-portal/delivery-locations/${t}/`,{method:"PATCH",body:JSON.stringify(e)}),deleteAddress:t=>h(`/api/shop-portal/delivery-locations/${t}/`,{method:"DELETE"}),passwordResetRequest:t=>i("/api/auth/password-reset/",{method:"POST",body:JSON.stringify({email:t})}),passwordResetConfirm:(t,e,s)=>i("/api/auth/password-reset/confirm/",{method:"POST",body:JSON.stringify({uid:t,token:e,new_password:s})}),brands:()=>h("/api/products/brands/"),myOrders:()=>h("/api/shop-portal/orders/").then(t=>t.results),myOrder:t=>h(`/api/shop-portal/orders/${t}/`),cancelOrder:t=>h(`/api/shop-portal/orders/${t}/cancel/`,{method:"POST"}),myReturns:t=>h(`/api/shop-portal/returns/${t?`?order=${encodeURIComponent(t)}`:""}`).then(e=>e.results),createReturn:t=>h("/api/shop-portal/returns/",{method:"POST",body:JSON.stringify(t)}),withdrawReturn:t=>h(`/api/shop-portal/returns/${t}/cancel/`,{method:"POST"}),uploadReturnPhoto:(t,e)=>{const s=new FormData;return s.append("claim_item",t),s.append("file",e),s.append("media_type",e.type.startsWith("video/")?"video":"image"),h("/api/shop-portal/return-media/",{method:"POST",body:s})}};import{media as Et,absolutizeApiUrl as v}from"efficient-web-builder/render/lib/media";import{analyzeLogoSvg as Ct,isSvgUrl as $t}from"efficient-web-builder/format/lib/logo/reverse-svg";import{getEditorSiteId as _t}from"efficient-web-builder/render/lib/editor-site";import{shopRouteBase as Ut,webRuntimeSiteSlug as K}from"efficient-web-builder/format/lib/web-runtime";function g(t){if(typeof t=="string")return t.startsWith("/media/")?Et(t):t;if(Array.isArray(t))return t.map(g);if(t&&typeof t=="object"){const e={};for(const[s,o]of Object.entries(t))e[s]=s==="captions"&&o&&typeof o=="object"&&!Array.isArray(o)?Object.fromEntries(Object.entries(o).map(([l,p])=>[g(l),p])):g(o);return e}return t}import{PRODUCT_API_BASE as Pe}from"./origins.js";const V=typeof window>"u"&&D!=="",It=V?D:ot,Nt=Ut,O=()=>({baseUrl:Nt(),audience:null});function d(t,e){const s=e?`?process=${encodeURIComponent(e)}`:"";return`/api/v1${t}${s}`}const X=100,Z=50;function k(t,e,s){const o=new URLSearchParams;for(const[l,p]of Object.entries(e))p!=null&&p!==""&&o.set(l,String(p));return o.set("pageSize",String(X)),s&&o.set("cursor",s),`/api/v1${t}?${o.toString()}`}function vt(t,e){return k("/wheels",{process:t},e)}const Y=X;function kt(t,e){return k("/wheels",{slug:t.join(",")},e)}function Lt(t,e,s){return k("/products",{kind:t.join(","),make:e?.make,model:e?.model,year:e?.year,modification:e?.modification},s)}function Jt(t){if(!t)return null;try{return new URL(t,"http://cursor.invalid").searchParams.get("cursor")}catch{return null}}async function L(t,e,s=()=>!1){const o=[];let l=null;try{for(let p=0;p<Z;p++){const w=await i(await e(l),await u());if(o.push(...w.results),l=Jt(w.next),!l)break}l&&console.warn(`[${t}] stopped at ${Z} pages (${o.length} rows); catalog may be truncated`)}catch(p){if(s(p))throw p;console.warn(`[${t}] product API unavailable, returning []`,p)}return o}const Q=t=>t instanceof m&&t.status===400;function Dt(t){return t.flatMap(e=>e.kind==="alloy-wheel"?U([e]):[e])}async function tt(){return(await xt()).host}async function xt(){try{const{headers:t}=await import("next/headers"),e=await t(),s=p=>p?.split(",")[0]?.split(":")[0]?.trim().toLowerCase()||null,o=s(e.get(st)??e.get("x-forwarded-host")??e.get("host")),l=s(e.get("host"));return{host:o,matchesRequestHost:o!==null&&o===l}}catch{return{host:null,matchesRequestHost:!1}}}async function Ht(){try{const{headers:t}=await import("next/headers");return ct((await t()).get(dt))}catch{return null}}async function Ft(){try{const{headers:t}=await import("next/headers");return(await t()).get(nt)||null}catch{return null}}async function Mt(){const t=await Ft();if(t)return`site=${encodeURIComponent(t)}`;const e=await tt();return e?`host=${encodeURIComponent(e)}`:""}async function f(t){if(typeof window<"u"){const e=K();return e?E(t,`site=${encodeURIComponent(e)}`):t}return E(t,await Mt())}function E(t,e){return e?`${t}${t.includes("?")?"&":"?"}${e}`:t}const Bt="preview";async function qt(){if(typeof window<"u")return null;try{const{headers:t}=await import("next/headers");return(await t()).get(at)}catch{return null}}async function Gt(){try{const{headers:t}=await import("next/headers");return(await t()).get("user-agent")}catch{return null}}async function J(t,e){const s=await qt();if(s===null)return[await f(t),await u(e)];const o=E(await f(t),`${Bt}=${encodeURIComponent(s)}`),{next:l,cache:p,...w}=e??{},r=await u({...w,cache:"no-store"}),a=await Gt();return a&&(r.headers={...r.headers,"user-agent":a}),[o,r]}async function Wt(t){if(!V)return;const[e,s]=await Promise.all([tt(),Ht()]),o=it(e,s,t);return Object.keys(o).length>0?o:void 0}async function u(t){const e=await Wt(ut(t)),s={baseUrl:It,...t};return e&&(s.headers={...e,...t?.headers}),s}const A=typeof window>"u";function T(t,e){const s=new URLSearchParams;for(const[l,p]of Object.entries(e))p!==void 0&&p!==""&&s.set(l,String(p));const o=s.toString();return`/api/v1/fitment${t}${o?`?${o}`:""}`}const ye={listMakes:async t=>{if(A){const{fitmentData:s}=await import("./fitment-data.js");return s.makes(t)}return(await i(T("/makes",{region:t}),O())).results},listModels:async(t,e)=>{if(A){const{fitmentData:o}=await import("./fitment-data.js");return o.models(t,e)}return(await i(T("/models",{make:t,region:e}),O())).results},listYears:async(t,e,s)=>{if(A){const{fitmentData:l}=await import("./fitment-data.js");return l.years(t,e,s)}return(await i(T("/years",{make:t,model:e,region:s}),O())).results},listModifications:async(t,e,s,o)=>{if(A){const{fitmentData:p}=await import("./fitment-data.js");return p.modifications(t,e,s,o)}return(await i(T("/modifications",{make:t,model:e,year:s,region:o}),O())).results},getStockFitment:async(t,e,s,o,l)=>{if(A){const{fitmentData:p}=await import("./fitment-data.js");return p.stockFitment(t,e,s,o,l)}return i(T("/stock-fitment",{make:t,model:e,year:s,modification:o,region:l}),O())}},he={listWheels:async(t,e={})=>{const s=await L("products.listWheels",async o=>await f(vt(t,o)),e.throwOnFailure?()=>!0:void 0);return U(g(s))},listWheelsBySlug:async(t,e={})=>{const s=[...new Set(t.map(r=>r.trim()).filter(Boolean))];if(s.length===0)return[];const o=[];for(let r=0;r<s.length;r+=Y)o.push(s.slice(r,r+Y));const l=await Promise.all(o.map(r=>L("products.listWheelsBySlug",async a=>await f(kt(r,a)),e.throwOnFailure?()=>!0:Q))),p=new Set(s),w=l.flat().filter(r=>p.has(r.slug));return U(g(w))},listCatalog:async(t,e)=>{if(t.length===0)throw new Error("products.listCatalog() needs at least one kind. An empty list would omit `kind`, which the contract reads as `alloy-wheel` — so the call would silently return the wheel catalog instead of nothing.");const s=await L("products.listCatalog",async o=>await f(Lt(t,e,o)),Q);return Dt(g(s))},getWheel:async t=>x(g(await i(await f(d(`/wheels/${t}`)),await u()))),getTyre:async t=>g(await i(await f(d(`/tyres/${t}`)),await u())),listBundles:async(t={})=>{try{return await i(await f(d("/bundles")),await u())}catch(e){if(t.throwOnFailure)throw e;return[]}},getBundle:async t=>i(await f(d(`/bundles/${t}`)),await u()),listGalleryBuilds:async(t={})=>{const{process:e=null,wheelSlug:s=null}=t;if(typeof window>"u"){const{listGalleryBuilds:o}=await import("./gallery-builds-data.js");return g(o(e,s))}try{const o=new URLSearchParams;e&&o.set("process",e),s&&o.set("wheelSlug",s);const l=o.toString(),p=await i(`/api/v1/gallery-builds${l?`?${l}`:""}`,O());return g(p.results)}catch(o){return console.warn("[products.listGalleryBuilds] product API unavailable, returning []",o),[]}},getSite:async()=>i(await f(d("/site")),await u()),getSiteBySlug:async t=>i(`${d("/site")}?${new URLSearchParams({site:t})}`,typeof window>"u"?await u():void 0),listPages:async()=>g(await i(await f(d("/pages")),await u())),listPopups:async()=>i(await f(d("/popups")),await u()),listProductTemplates:async()=>{try{return await i(await f(d("/product-templates")),await u())}catch(t){return console.warn("[products.listProductTemplates] unavailable, returning []",t),[]}},listDynamicPages:async t=>{const e=t?`?recordType=${encodeURIComponent(t)}`:"";try{return await i(await f(`${d("/dynamic-pages")}${e}`),await u())}catch(s){if(s instanceof m&&s.status===404)return[];throw s}},getRecord:async(t,e)=>{try{return await i(await f(d(`/records/${encodeURIComponent(t)}/${encodeURIComponent(e)}`)),await u())}catch(s){if(s instanceof m&&s.status===404)return null;throw s}},listRecordKeys:async t=>{try{const e=await i(await f(d(`/records/${encodeURIComponent(t)}`)),await u({cache:"no-store"}));return Array.isArray(e?.keys)?e.keys.filter(s=>typeof s=="string"&&s!==""):[]}catch(e){if(e instanceof m&&e.status===404)return[];throw e}},listProductTypeChoices:async()=>{try{return await i(await f(d("/product-type-choices")),await u())}catch(t){return console.warn("[products.listProductTypeChoices] unavailable, returning []",t),[]}},listFieldUsage:async()=>{try{return await i(await f(d("/field-usage")),await u())}catch(t){return console.warn("[products.listFieldUsage] unavailable, returning []",t),[]}},getPage:async(t,e={})=>{const s=e.record?`?record=${encodeURIComponent(e.record)}`:"",[o,l]=await J(d(`/pages/${t}`)+s,e.revalidate!==void 0?{next:{revalidate:e.revalidate}}:void 0);return g(await i(o,l))},listBlogPosts:async(t={},{throwOnFailure:e=!1}={})=>{const s=t.category?`?category=${encodeURIComponent(t.category)}`:"";try{return(await i(d("/blog-posts")+s,await u())).map(l=>({...l,coverImage:v(l.coverImage)??""}))}catch(o){if(e)throw o;return console.warn("[products.listBlogPosts] blog API unavailable, returning []",o),[]}},getBlogPost:async t=>{const e=await i(d(`/blog-posts/${t}`),await u());return{...e,coverImage:v(e.coverImage)??""}},createOrder:async t=>i(d("/orders"),await u({method:"POST",body:JSON.stringify(t)})),createOrderAuthed:async t=>h(d("/orders"),await u({method:"POST",body:JSON.stringify(t)})),lookupOrder:async t=>i(d("/orders/lookup"),await u({method:"POST",body:JSON.stringify(t)})),createPaymentIntent:async t=>i(d("/payments/intent"),await u({method:"POST",body:JSON.stringify(t)})),releaseCheckout:async t=>i(d("/checkouts/release"),await u({method:"POST",body:JSON.stringify(t)})),createPaypalOrder:async t=>i(d("/payments/paypal/order"),await u({method:"POST",body:JSON.stringify(t)})),capturePaypalOrder:async t=>i(d("/payments/paypal/capture"),await u({method:"POST",body:JSON.stringify(t)})),createAfterpayCheckout:async t=>i(d("/payments/afterpay/checkout"),await u({method:"POST",body:JSON.stringify(t)})),captureAfterpayPayment:async t=>i(d("/payments/afterpay/capture"),await u({method:"POST",body:JSON.stringify(t)})),chargeSquare:async t=>i(d("/payments/square/charge"),await u({method:"POST",body:JSON.stringify(t)})),createGocardlessBillingRequest:async t=>i(d("/payments/gocardless/billing-request"),await u({method:"POST",body:JSON.stringify(t)})),completeGocardlessPayment:async t=>i(d("/payments/gocardless/complete"),await u({method:"POST",body:JSON.stringify(t)})),createZipCheckout:async t=>i(d("/payments/zip/checkout"),await u({method:"POST",body:JSON.stringify(t)})),captureZipPayment:async t=>i(d("/payments/zip/capture"),await u({method:"POST",body:JSON.stringify(t)})),createKlarnaCheckout:async t=>i(d("/payments/klarna/checkout"),await u({method:"POST",body:JSON.stringify(t)})),captureKlarnaPayment:async t=>i(d("/payments/klarna/capture"),await u({method:"POST",body:JSON.stringify(t)})),createStockAlert:async t=>i(d("/stock-alerts"),await u({method:"POST",body:JSON.stringify(t)})),createPreOrderIntent:async t=>i(d("/pre-order-intents"),await u({method:"POST",body:JSON.stringify(t)})),createNewsletterSubscription:async t=>i(d("/newsletter-subscriptions"),await u({method:"POST",body:JSON.stringify(t)})),unsubscribeNewsletter:async t=>i(d("/newsletter-unsubscribe"),await u({method:"POST",body:JSON.stringify(t)})),captureCart:async t=>i(d("/carts"),await u({method:"POST",body:JSON.stringify(t)})),restoreCart:async t=>i(d("/carts/restore"),await u({method:"POST",body:JSON.stringify(t)})),unsubscribeCartReminders:async t=>i(d("/carts/unsubscribe"),await u({method:"POST",body:JSON.stringify(t)})),listReviews:async(t={})=>{const e=new URLSearchParams;t.limit&&e.set("limit",String(t.limit)),t.designCode&&e.set("designCode",t.designCode);const s=d("/reviews"),o=e.toString();try{return await i(await f(o?`${s}?${o}`:s),await u())}catch(l){return console.warn("[products.listReviews] product API unavailable, returning []",l),[]}},submitReview:async t=>i(d("/reviews"),await u({method:"POST",body:JSON.stringify(t)})),getForm:async t=>i(d(`/forms/${encodeURIComponent(t)}`),await u()),submitForm:async(t,e)=>i(d(`/forms/${encodeURIComponent(t)}/submissions`),await u({method:"POST",body:JSON.stringify(e)})),listShippingMethods:async()=>{try{return await i(d("/shipping-methods"),await u())}catch(t){return console.warn("[products.listShippingMethods] product API unavailable, returning []",t),[]}},listCountrySubdivisions:async t=>{try{return await i(d(`/countries/${encodeURIComponent(t)}/subdivisions`),await u())}catch(e){return console.warn("[products.listCountrySubdivisions] unavailable, returning []",e),[]}},quoteCart:async t=>{const e=d("/cart/quote"),s=await u({method:"POST",body:JSON.stringify(t)});return t.couponCode?(await j(e,s)).data:i(e,s)},validateCoupon:async t=>{const{data:e,asShopper:s}=await j(d("/coupons/validate"),await u({method:"POST",body:JSON.stringify(t)}));return{...e,askedAsShopper:s}},getHeaderSettings:async()=>{const t=H({method:"GET"}),e=await i(...await J(d("/header-settings"),{signal:t})),s=v(e.logoUrl);let o=null,l=null;if(s&&$t(s)){const p=await Ct(s,t);p&&(o=p.reversed,l=p.inkIsDark)}return{...e,logoUrl:s,logoReversed:o,logoInkIsDark:l}},getThemeSettings:async()=>i(...await J(d("/theme-settings"))),getChatSettings:async()=>i(await f(d("/chat-settings")),await u())},fe={listServices:async()=>{try{return await i(d("/bookings/services"),await u())}catch(t){return console.warn("[bookings.listServices] API unavailable, returning []",t),{results:[],currency:"USD"}}},getAvailability:async(t,e)=>i(d(`/bookings/availability?service=${encodeURIComponent(t)}&date=${e}`),await u()),create:async t=>i(d("/bookings"),await u({method:"POST",body:JSON.stringify(t)})),get:async t=>i(d(`/bookings/manage/${encodeURIComponent(t)}`),await u()),cancel:async t=>i(d(`/bookings/manage/${encodeURIComponent(t)}/cancel`),await u({method:"POST"})),createPaymentIntent:async t=>i(d("/bookings/payments/intent"),await u({method:"POST",body:JSON.stringify({manageToken:t})}))};class jt extends Error{slug;count;constructor(e,s){super(`Slug "${e}" exists on ${s} websites; a site is required to pick one.`),this.slug=e,this.count=s,this.name="AmbiguousPageSlugError"}}const C=(t,e,s)=>{const o=new URLSearchParams({...e?{site:e}:{},...s?{draft:"1"}:{}}).toString();return`/api/storefront/${t}/${o?`?${o}`:""}`},$=t=>`/api/storefront/sites/${encodeURIComponent(t)}/`,zt=t=>`${$(t)}currencies/`,Kt="/api/storefront/media/ingest/";class Vt extends Error{constructor(){super("This editor is not connected to a website, so an upload has nowhere to go. Open the page from the website the file should belong to, then try again."),this.name="MediaUploadDestinationError"}}function Xt(){const t=_t();if(!t)throw new Vt;return`${Kt}?${new URLSearchParams({site:t})}`}const Zt="X-Puck-Media-Manifest",et=lt.contentHash,_={"X-Media-Manifest":et,[Zt]:et},ge=rt({});function rt(t){return(e,s={})=>{const o=bt(),l=t.headers||o?{...o?{"Accept-Language":o}:{},...t.headers,...s.headers}:void 0;return i(e,{...s,...t.baseUrl!==void 0?{baseUrl:t.baseUrl}:{},...l?{headers:l}:{},audience:t.audience??Pt()})}}function Yt(t={}){const e=rt(t),s=t.siteDrafts===!0,o=r=>C("header-settings",r,s),l=r=>C("theme-settings",r,s),p=r=>C("chat-settings",r,s),w=r=>C("social-settings",r,s);return{findPageBySlug:async(r,a,n)=>{const c=new URLSearchParams({slug:r});n&&c.set("site",n);const y=await e(`/api/storefront/pages/?${c.toString()}`,{token:a}),S=Array.isArray(y)?y:y.results??[];if(!n&&S.length>1)throw new jt(r,S.length);return S[0]??null},getPageById:(r,a)=>e(`/api/storefront/pages/${r}/`,{token:a}),saveLayout:(r,a,n,c,y)=>e(`/api/storefront/pages/${r}/`,{method:"PATCH",body:JSON.stringify({layout:a,expected_updated_at:c,...y?{client_id:y}:{}}),token:n}),duplicatePage:(r,a,n)=>e(`/api/storefront/pages/${r}/duplicate/`,{method:"POST",body:JSON.stringify({title:a.title,slug:a.slug}),token:n}),geocode:(r,a,n)=>e(`/api/storefront/geocode/?${new URLSearchParams(n?{q:r,country:n}:{q:r})}`,{token:a}),listBlockSources:r=>e("/api/storefront/block-sources/",{token:r}),listRecordTypes:r=>e("/api/storefront/record-types/",{token:r}),createPagePreviewLink:(r,a)=>e(`/api/storefront/pages/${r}/preview-link/`,{method:"POST",token:a}),claimPageEditLock:(r,a,n,c=!1)=>e(`/api/storefront/pages/${r}/edit-lock/`,{method:"POST",body:JSON.stringify({client_id:n,takeover:c}),token:a}),releasePageEditLock:(r,a)=>e(`/api/storefront/pages/${r}/edit-lock/`,{method:"DELETE",token:a}),createTemplate:(r,a,n)=>e("/api/storefront/page-templates/",{method:"POST",body:JSON.stringify({name:r,layout:a}),headers:_,token:n}),getTemplate:(r,a)=>e(`/api/storefront/page-templates/${r}/`,{token:a}),saveTemplateLayout:(r,a,n)=>e(`/api/storefront/page-templates/${r}/`,{method:"PATCH",body:JSON.stringify({layout:a}),headers:_,token:n}),listTemplatePages:async(r,a)=>{const n=await e(`/api/storefront/template-pages/?template=${encodeURIComponent(r)}`,{token:a});return Array.isArray(n)?n:n.results??[]},findTemplatePageBySlug:async(r,a,n)=>{const c=await e(`/api/storefront/template-pages/?template=${encodeURIComponent(r)}&slug=${encodeURIComponent(a)}`,{token:n});return(Array.isArray(c)?c:c.results??[])[0]??null},createTemplatePage:(r,a,n)=>e("/api/storefront/template-pages/",{method:"POST",body:JSON.stringify({template:r,...a}),headers:_,token:n}),saveTemplatePageLayout:(r,a,n)=>e(`/api/storefront/template-pages/${r}/`,{method:"PATCH",body:JSON.stringify({layout:a}),headers:_,token:n}),deleteTemplatePage:(r,a,n)=>e(`/api/storefront/template-pages/${r}/`,{method:"DELETE",token:a,...n?.keepalive?{keepalive:!0}:{}}),listPages:async(r,a)=>{const n=new URLSearchParams({no_page:"true"});a&&n.set("site",a);const c=await e(`/api/storefront/pages/?${n.toString()}`,{token:r});return Array.isArray(c)?c:c.results??[]},createPage:(r,a,n,c)=>e("/api/storefront/pages/",{method:"POST",body:JSON.stringify({title:r,slug:a,layout:n}),token:c}),deletePage:(r,a)=>e(`/api/storefront/pages/${r}/`,{method:"DELETE",token:a}),getHeaderSettings:(r,a)=>e(o(a),{token:r}),listMenus:async(r,a)=>{const n=new URLSearchParams({no_page:"true"});a&&n.set("site",a);const c=await e(`/api/storefront/menus/?${n}`,{token:r});return Array.isArray(c)?c:c.results??[]},listBlogPosts:async(r,a={})=>{const n=new URLSearchParams({no_page:"true"});a.visibleOnly&&n.set("is_visible","true"),a.siteId&&n.set("site",a.siteId);const c=await e(`/api/storefront/blog-posts/?${n.toString()}`,{token:r});return Array.isArray(c)?c:c.results??[]},listFieldUsage:async(r,a)=>{const n=await e(`/api/storefront/field-usage/?site=${encodeURIComponent(a)}`,{token:r});return Array.isArray(n?.entries)?n.entries:[]},listCategories:async(r,a={})=>{const n=new URLSearchParams({no_page:"true"});a.visibleOnly&&n.set("is_visible","true"),a.siteId&&n.set("site",a.siteId);const c=await e(`/api/storefront/categories/?${n.toString()}`,{token:r});return[...Array.isArray(c)?c:c.results??[]].sort((S,R)=>S.sort_order-R.sort_order||S.name.localeCompare(R.name))},listForms:async(r,a={})=>{const n=new URLSearchParams({no_page:"true"});a.siteId&&n.set("site",a.siteId);const c=await e(`/api/storefront/forms/?${n.toString()}`,{token:r});return[...Array.isArray(c)?c:c.results??[]].sort((S,R)=>S.title.localeCompare(R.title))},listWheelSummaries:async(r,a={})=>{const n=new URLSearchParams;a.siteId&&n.set("site",a.siteId);const c=n.toString(),y=await e(`/api/storefront/wheel-curations/summaries/${c?`?${c}`:""}`,{token:r});return g(y)},listProducts:async(r,a={})=>{const n=new URLSearchParams;a.kinds?.length&&n.set("kind",a.kinds.join(",")),a.siteId&&n.set("site",a.siteId);const c=n.toString(),y=await e(`/api/storefront/products/${c?`?${c}`:""}`,{token:r});return g(y)},getWheelDetail:async(r,a,n={})=>{const c=new URLSearchParams({slug:a});return n.siteId&&c.set("site",n.siteId),x(g(await e(`/api/storefront/wheel-curations/detail/?${c.toString()}`,{token:r})))},updateHeaderSettings:(r,a,n)=>e(o(n),{method:"PATCH",body:JSON.stringify(r),token:a}),getSite:(r,a)=>e($(r),{token:a}),listSites:async r=>{const a=await e("/api/storefront/sites/?no_page=true",{token:r});return Array.isArray(a)?a:a.results??[]},listSiteCurrencies:async(r,a)=>{const n=await e(zt(r),{token:a});return Array.isArray(n)?n:[]},publishSite:(r,a)=>e(`${$(r)}publish/`,{method:"POST",token:a}),getSiteLiveState:(r,a)=>e(`${$(r)}live-state/`,{token:a}),getThemeSettings:(r,a)=>e(l(a),{token:r}),updateThemeSettings:(r,a,n)=>e(l(n),{method:"PATCH",body:JSON.stringify(r),token:a}),getChatSettings:(r,a)=>e(p(a),{token:r}),updateChatSettings:(r,a,n)=>e(p(n),{method:"PATCH",body:JSON.stringify(r),token:a}),getSocialSettings:(r,a)=>e(w(a),{token:r}),updateSocialSettings:(r,a,n)=>e(w(n),{method:"PATCH",body:JSON.stringify(r),token:a}),uploadHeaderLogo:(r,a,n)=>{const c=new FormData;return c.append("logo",r),e(o(n),{method:"PATCH",body:c,token:a})},clearHeaderLogo:(r,a)=>e(o(a),{method:"PATCH",body:JSON.stringify({logo:null}),token:r}),setHeaderLogoFromAsset:(r,a,n)=>e(o(n),{method:"PATCH",body:JSON.stringify({logo_asset_id:r}),token:a}),uploadMedia:async(r,a)=>{const n=new FormData;return n.append("file",r),e(Xt(),{method:"POST",body:n,token:a})},listMedia:async(r,a)=>{const n=new URLSearchParams({no_page:"true"});a&&n.set("kind",a);const c=await e(`/api/storefront/media-assets/?${n.toString()}`,{token:r});return Array.isArray(c)?c:c.results??[]}}}const we=Yt({siteDrafts:!0});export{yt as API_URL,jt as AmbiguousPageSlugError,m as ApiError,wt as BROWSER_READ_TIMEOUT_MS,ft as EFFICIENT_CLIENT_CLOSED_MESSAGE,Vt as MediaUploadDestinationError,Bt as PREVIEW_PARAM,Pe as PRODUCT_API_BASE,gt as SERVER_READ_TIMEOUT_MS,I as SERVER_UNREACHABLE_MESSAGE,N as STATUS_NETWORK_ERROR,ge as adminFetch,Rt as api,i as apiFetch,E as appendSiteQuery,fe as bookings,Yt as createStorefrontAdmin,H as defaultRequestDeadline,Xt as editorMediaUploadPath,Pt as editorPortalAudience,bt as editorRequestLanguage,ye as fitment,he as products,mt as readDeadlineMs,Ht as resolveClientIp,g as resolveMediaUrls,qt as resolvePreviewToken,tt as resolveSiteHost,xt as resolveSiteHostSource,Ft as resolveSiteSlug,ce as setEditorLanguage,ie as setEditorPortalAudience,we as storefrontAdmin};
|