efficient-storefront-blocks 0.78.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.
Files changed (38) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/chunks/EditorPreviewCheckout-6S2Q3GXI.js +4 -0
  3. package/dist/chunks/{SiteEditorProvider-YTZPWUDV.js → SiteEditorProvider-B6JGOUMX.js} +1 -1
  4. package/dist/chunks/chunk-IL5OJ6VZ.js +1 -0
  5. package/dist/chunks/chunk-NE47RYTU.js +320 -0
  6. package/dist/chunks/{chunk-4O66UMLS.js → chunk-WYNB6IMA.js} +1 -1
  7. package/dist/chunks/chunk-ZA227AIS.js +1 -0
  8. package/dist/chunks/{fitment-data-VU5A7VKV.js → fitment-data-KCPZ77HO.js} +1 -1
  9. package/dist/contract.js +1 -1
  10. package/dist/editor/lib/document/blocks/service/ContactCards/fields.js +1 -1
  11. package/dist/editor/lib/document/blocks/service/FooterEmailSignup/fields.js +1 -1
  12. package/dist/editor/lib/document/blocks/service/FooterMessaging/fields.js +1 -1
  13. package/dist/editor/lib/document/blocks/service/MessagingCards/fields.js +1 -1
  14. package/dist/editor/lib/document/blocks/service/OpeningHours/fields.js +1 -1
  15. package/dist/editor/lib/document/blocks/service/RateTable/fields.js +1 -1
  16. package/dist/editor/lib/document/box-header.d.ts +1 -1
  17. package/dist/editor/lib/document/config.js +1 -1
  18. package/dist/index.d.ts +2 -0
  19. package/dist/index.js +28 -34
  20. package/dist/links.js +1 -1
  21. package/dist/render/app/globals.css +39 -1
  22. package/dist/render/built-with.json +1 -1
  23. package/dist/render/components/checkout/checkout-state.js +3 -3
  24. package/dist/render/lib/api/index.d.ts +3 -0
  25. package/dist/render/lib/api/index.js +1 -1
  26. package/dist/render/lib/api/types.d.ts +46 -0
  27. package/dist/render/lib/checkout/pay-first.d.ts +5 -1
  28. package/dist/render/lib/checkout/pay-first.js +1 -1
  29. package/dist/render/lib/document/lazy-draws.js +1 -1
  30. package/dist/words.d.ts +11 -0
  31. package/dist/words.js +4 -4
  32. package/package.json +3 -3
  33. package/dist/chunks/EditorPreviewCheckout-IEFQC4T3.js +0 -4
  34. package/dist/chunks/chunk-LZTJCQ4A.js +0 -311
  35. package/dist/chunks/chunk-MZPZ4B7Y.js +0 -1
  36. package/dist/chunks/chunk-WC4XIVX3.js +0 -1
  37. /package/dist/chunks/{chunk-LZTJCQ4A.js.LEGAL.txt → chunk-NE47RYTU.js.LEGAL.txt} +0 -0
  38. /package/dist/chunks/{chunk-TI4ZGDSG.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};
@@ -2591,16 +2591,42 @@ em.text-accent {
2591
2591
  take its parent's. Every zone resets it here; a container's own value is
2592
2592
  inline and beats this rule, and its blocks still inherit that value. */
2593
2593
  --sf-gap-len-phone: initial;
2594
+ --sf-gap-len-tablet: initial;
2594
2595
  }
2595
2596
  /* Below 800px: the container's own phone Gap when it stores one (C25 row 2,
2596
2597
  Lewis 2026-10-29: `--sf-gap-len-phone`, written by efficient-web-builder's
2597
2598
  `containerGapProps`), else half the desktop length (the 2026-09-03 ruling).
2598
- With no phone value the fallback is the old declaration, so no page moves. */
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. */
2599
2603
  @media (max-width: 800px) {
2600
2604
  .sf-gap-zone {
2601
2605
  gap: var(--sf-gap-len-phone, calc(var(--sf-gap-len) / 2));
2602
2606
  }
2603
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
+ }
2604
2630
  /* A shared-rows card grid (`.sf-card-rows`, components/WheelCardFrame) moves
2605
2631
  its row gap onto the cards as a margin, so `gap` above does not reach it.
2606
2632
  Its phone answer is this property, named by the grid ONLY when it stores a
@@ -2614,6 +2640,18 @@ em.text-accent {
2614
2640
  --sf-card-row-gap-auto: var(--sf-gap-len-phone, var(--sf-gap-len));
2615
2641
  }
2616
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
+ }
2617
2655
 
2618
2656
  /* The overlap below zero halves on the same screen, for the same reason and by
2619
2657
  the same ruling. It needs its OWN derived property rather than redefining
@@ -1,3 +1,3 @@
1
1
  {
2
- "efficient-web-builder": "47.1.0"
2
+ "efficient-web-builder": "48.1.1"
3
3
  }
@@ -1,3 +1,3 @@
1
- "use client";import{jsx as N}from"react/jsx-runtime";import{createContext as an,useContext as sn,useEffect as p,useMemo as wt,useRef as y,useState as r}from"react";import{isOrderable as kt,useCart as un}from"../CartContext.js";import{useCurrency as ln}from"../CurrencyContext.js";import{getClickIds as dn}from"../../lib/click-ids.js";import{adConsentForOrder as pn}from"../../lib/consent/choice.js";import{trackBeginCheckout as mn,trackPurchase as fn}from"../../lib/google-tag.js";import{trackMetaPurchase as yn}from"../../lib/meta-pixel.js";import{ApiError as ye,api as X,products as m}from"../../lib/api/index.js";import{uuid as Ie}from"../../lib/uuid.js";import{orderLinesForSets as hn}from"../../lib/commerce.js";import{canPersist as gn,safeSessionStorage as k}from"efficient-web-builder/format/lib/safe-storage";import{AFTERPAY_CONTEXT_KEY as wn,AFTERPAY_RETURN as kn,GOCARDLESS_CONTEXT_KEY as Te,KLARNA_CONTEXT_KEY as Ke,ZIP_CONTEXT_KEY as Cn,ZIP_RETURN as bn,runWalletReturn as Ct}from"../../lib/checkout/wallet-return.js";import{matchSubdivision as Nn}from"../../lib/checkout/match-subdivision.js";import{checkoutGone as bt,DROPPABLE_INTENT as Pn,NOT_CHECKED as Sn,PAY_FIRST_FLOW as An,paysFirst as vn,readIntentStatus as xn,settlePayFirst as En}from"../../lib/checkout/pay-first.js";import{couponCodeForOrder as Nt,couponRefusedByOrder as On}from"../../lib/cart/coupon-preview.js";function Pt(c){const d=c.indexOf(`
2
- `);return d===-1?[c,""]:[c.slice(0,d),c.slice(d+1)]}function St(c,{canParkContext:d}={canParkContext:!0}){const u=c.paymentMethods,i=[];return u.includes("card")&&i.push({key:"card",title:"Card",body:null,price:N("span",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-accent",children:"VISA · MC · AMEX"})}),u.includes("paypal")&&c.paypalClientId&&i.push({key:"paypal",title:"PayPal",body:null,price:N("span",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-accent",children:"PAYPAL · CARDS"})}),u.includes("afterpay")&&i.push({key:"afterpay",title:"Afterpay",body:null,price:N("span",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-accent",children:"4 × INTEREST-FREE"})}),u.includes("square")&&c.squareApplicationId&&c.squareLocationId&&i.push({key:"square",title:"Card (Square)",body:null,price:N("span",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-accent",children:"VISA · MC · AMEX"})}),u.includes("gocardless")&&d&&i.push({key:"gocardless",title:"Bank Direct Debit",body:null,price:N("span",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-accent",children:"PAY BY BANK"})}),u.includes("zip")&&i.push({key:"zip",title:"Zip",body:null,price:N("span",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-accent",children:"PAY IN 4"})}),u.includes("klarna")&&d&&i.push({key:"klarna",title:"Klarna",body:null,price:N("span",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-accent",children:"PAY LATER"})}),u.includes("bank")&&i.push({key:"bank",title:"Bank transfer",body:null,price:N("span",{className:"font-mono text-[12px] uppercase tracking-[0.2em] text-fg-dim",children:"Invoiced"})}),i}const Zn="This shop does not take payment online yet. Please contact the shop to order.";function In(c,d){if(!c.orderNumber&&bt(d))return d.message;const u=d instanceof ye?` (${d.message})`:"";return c.orderNumber?`Your order ${c.orderNumber} is saved, but the payment did not start${u}. Try the payment again — your order will not be placed twice.`:`Your items are held under ${c.checkoutNumber}, but the payment did not start${u}. Try the payment again — you will not be charged twice.`}const Wn="Shipping cannot be calculated right now. Please try again.";function Tn({site:c,logo:d,preview:u=!1}){const{items:i,totals:P,coupon:T,refuseCoupon:vt,deliveryOptions:Re,shippingMethodId:Z,setShippingMethodId:xt,setQuoteDestination:W,courier:Et,requote:Ot,identify:_e,clearCapturedCart:K,replaceItems:Me,removeCoupon:Le}=un(),It=Re.find(e=>e.id===Z)?.pickupLocation??null,{country:$e,countries:B,activeCountry:Ye,formatMoney:Tt}=ln(),[g,he]=r(()=>St(c)[0]?.key??null),[Ue,Kt]=r(!0);p(()=>{Kt(gn(k))},[]);const[j,S]=r(!1),[F,ge]=r(""),[O,we]=r(""),[z,ke]=r(""),[Q,V]=r(""),[Ce,ee]=r(""),[R,te]=r(""),[I,ne]=r(""),[D,re]=r(""),[s,oe]=r(()=>$e||B[0]?.code||""),[A,ce]=r(""),[H,qe]=r([]),[be,Ne]=r(null),[ae,J]=r(null),Be=wt(()=>B.find(e=>e.code===s)??Ye,[B,s,Ye]),Rt=Be?.postalLabel||"Postal Code",_t=H[0]?.divisionType||"State / Province";p(()=>{if(!s){qe([]),Ne(s);return}Ne(null);let e=!1;return m.listCountrySubdivisions(s).then(t=>{e||(qe(t),Ne(s),ce(""))}),()=>{e=!0}},[s]);const Fe=Q.trim()!==""&&R.trim()!==""&&I.trim()!==""&&be===s&&(H.length===0||A!=="")?I.trim():"";p(()=>{W(s?{country:s,subdivision:A,postcode:Fe}:null)},[s,A,Fe,W]),p(()=>()=>W(null),[W]);const Mt=Et?.status==="unavailable",Lt=Ot,[se,ze]=r(null),[$t,De]=r([]),[He,Pe]=r("new"),[Je,Ge]=r(!1),[Se,Yt]=r("Home"),[Ut,Xe]=r(null),[f,Ze]=r(()=>Ie()),We=y(null),[je,w]=r(null),[qt,C]=r(null),[Qe,ie]=r(null),[Ve,Bt]=r(!1),[et,Ft]=r(!1),[v,_]=r(null),[zt,M]=r(!1),[h,L]=r(null),[Dt,b]=r(null),[Ht,Jt]=r(!1),[Gt,tt]=r(!1),[Xt,Zt]=r(!1),[Wt,nt]=r(!1),[rt,jt]=r(!1),[Qt,Ae]=r(!1),[ve,ot]=r(null),ue=y(null),xe=y(i),ct=!!(je||ve&&ve.kind!=="processing"||rt||Ve||et||Qe&&v?.orderNumber);p(()=>{ct&&(Me([]),Le())},[ct,Me,Le]);const at=y(!1);p(()=>{u||at.current||!i.some(kt)||(at.current=!0,mn({lines:i,currency:P.currency,value:P.subtotal-P.discount,coupon:T?.valid?T.code:void 0}))},[i,P,T,u]),p(()=>{_e(F,O.trim()||void 0)},[F,O,_e]);const st=y(null),[le,Vt]=r(null);p(()=>{const e=st.current;if(!le||!e)return;const t=()=>e.style.setProperty("--sf-checkout-header-h",`${le.offsetHeight}px`);t();const n=new ResizeObserver(t);return n.observe(le),()=>n.disconnect()},[le]),p(()=>{const e=n=>({setConfirming:n,land:w,markPaid:()=>M(!0),note:b,fail:C,clearCart:K}),t={search:window.location.search,storage:k,scrubQuery:()=>window.history.replaceState(null,"",window.location.pathname)};Ct(kn,{...t,capture:m.captureAfterpayPayment,page:e(Jt)}),Ct(bn,{...t,capture:m.captureZipPayment,page:e(Zt)})},[]),p(()=>{const t=new URLSearchParams(window.location.search).get("gocardless");if(t!=="confirm"&&t!=="cancel")return;const n=k.getItem(Te);if(k.removeItem(Te),window.history.replaceState(null,"",window.location.pathname),!n)return;let o;try{o=JSON.parse(n)}catch{return}if(K(),t==="cancel"){b("The direct debit was not set up — our team will follow up on payment."),w(o.confirmation);return}tt(!0),m.completeGocardlessPayment({idempotencyKey:o.idempotencyKey}).then(a=>{a.status==="paid"?M(!0):a.status==="declined"?b("The direct debit was declined — our team will follow up on payment."):b("Your direct debit is set up — the payment is collecting and will clear in a few days.")}).catch(()=>{b("We could not confirm the direct debit — our team will follow up on payment.")}).finally(()=>{w(o.confirmation),tt(!1)})},[]),p(()=>{const e=new URLSearchParams(window.location.search),t=e.get("klarna");if(t!=="confirm"&&t!=="cancel")return;const n=k.getItem(Ke);k.removeItem(Ke);const o=e.get("authorization_token");if(window.history.replaceState(null,"",window.location.pathname),!n)return;let a;try{a=JSON.parse(n)}catch{return}if(K(),t==="cancel"||!o){b("The Klarna payment was not completed — our team will follow up on payment."),w(a.confirmation);return}nt(!0),m.captureKlarnaPayment({idempotencyKey:a.idempotencyKey,authorizationToken:o}).then(l=>{l.status==="paid"?M(!0):l.status==="declined"?b("Klarna declined the payment — our team will follow up on payment."):b("Your Klarna payment is being reviewed — we'll confirm the outcome shortly.")}).catch(()=>{b("We could not confirm the Klarna payment — our team will follow up on payment.")}).finally(()=>{w(a.confirmation),nt(!1)})},[]);function it(e){const[t,n]=Pt(e.address);V(t),ee(n),te(e.city),ne(e.zip_code),e.country&&oe(e.country),e.phone&&re(e.phone),J({country:e.country||null,state:e.state??""})}p(()=>{if(ae){if((ae.country||s)!==s){J(null);return}be===s&&(ce(Nn(s,ae.state,H)),J(null))}},[ae,s,be,H]),p(()=>{let e=!1;return(async()=>{try{const[t,n,o]=await Promise.all([X.me(),X.myProfile().catch(()=>null),X.myAddresses().catch(()=>[])]);if(e)return;ze(t);const a=o.filter(G=>G.is_active);De(a),ge(t.email);const l=(n?.contact_name??"").split(/\s+/);we(t.first_name||l[0]||""),ke(t.last_name||l.slice(1).join(" "));const gt=t.phone||n?.phone;gt&&re(gt);const Oe=a.find(G=>G.id===t.default_delivery_location)??a[0];if(Oe)Pe(Oe.id),it(Oe);else if(n){const[G,cn]=Pt(n.address??"");V(G),ee(cn),te(n.city??""),ne(n.zip_code??""),n.country&&oe(n.country),J({country:n.country||null,state:n.state??""})}}catch{}})(),()=>{e=!0}},[]);function en(){X.logout(),ze(null),De([]),Pe("new"),Ge(!1),ge(""),we(""),ke(""),V(""),ee(""),te(""),ne(""),re(""),oe($e||B[0]?.code||""),ce(""),J(null)}const $=wt(()=>St(c,{canParkContext:Ue}),[c,Ue]);p(()=>{$.some(e=>e.key===g)||he($[0]?.key??null)},[$,g]);const tn=$.length===0,de=Ce.trim()?`${Q}
3
- ${Ce.trim()}`:Q,x=JSON.stringify([F,O,z,D,de,R,A,I,s,i.map(e=>[e.id,e.qty]),Z,Nt(T),g,P.currency,se?.id??null]),pe=y(null),E=y(!1),Y=y(null),me=y(!1),Ee=y(x);Ee.current=x;const ut=y(j);ut.current=j;const lt=()=>E.current&&Ee.current!==pe.current,U=y(null);p(()=>{ut.current||(x!==U.current&&(U.current=null),!(!E.current||!h||h.orderNumber)&&(x===pe.current||x===U.current||fe(h)))},[x,h]);async function fe(e){if(!me.current){me.current=!0,S(!0);try{const t=Y.current?await xn(Y.current):"none";if(t==="succeeded"||t==="processing"){E.current=!1,L(null),t==="succeeded"?await q(void 0,e):pt(e);return}if(t===void 0||!Pn.has(t)){U.current=Ee.current,L(e),C(Sn);return}E.current=!1,Y.current=null,U.current=null,C(null),L(null),Ze(Ie())}finally{me.current=!1,S(!1)}}}async function nn(){if(u||j||me.current)return;if(h){if(E.current&&!h.orderNumber&&x!==pe.current){await fe(h);return}S(!0),C(null),await mt();const n=h.orderNumber?g:"card";n!==g&&he(n),await ft(h,n,!h.orderNumber);return}if(i.length===0||P.repricing||!g||!$.some(n=>n.key===g))return;const e=i.filter(kt).flatMap(n=>hn(n.components,n.qty));if(e.length===0){C("Pick a size on each wheel's product page before checking out.");return}S(!0),C(null);let t;try{const n=se?m.createOrderAuthed:m.createOrder,o=pn(),a={customer:{email:F,name:`${O} ${z}`.trim(),phone:D.trim()||void 0,address:de,city:R,state:A||void 0,zipCode:I,country:s},items:e,currency:P.currency,idempotencyKey:f,shippingMethodId:Z??void 0,couponCode:Nt(T),...o==="denied"?{}:dn(),...o?{adConsent:o}:{},...vn(g)?{checkoutFlow:An}:{}};ue.current=()=>n(a),Y.current=null,E.current=!1,U.current=null,pe.current=x,xe.current=i,t=await n(a),t.orderNumber&&(dt(t),K()),await mt()}catch(n){const o=On(n);o?(vt(o),C(`${o} Your order has not been placed. Place it again to continue without the code.`)):C(n instanceof ye?n.message:"Could not place the order. Please try again."),S(!1);return}await ft(t)}function dt(e){fn({confirmation:e,lines:xe.current,adsSendTo:c.googleAdsId&&c.googleAdsConversionLabel?`${c.googleAdsId}/${c.googleAdsConversionLabel}`:null}),yn({confirmation:e,lines:xe.current})}async function q(e,t=v){if(!t)return;const n=e?async()=>e:ue.current;if(t.orderNumber||!n){M(!0),w(t);return}K(),await En({checkoutNumber:t.checkoutNumber,resend:n,page:{setConfirming:jt,land:w,markPaid:()=>M(!0),track:dt,unplaced:ot}})}function pt(e=v){if(e){if(e.orderNumber){w(e);return}K(),ot({kind:"processing",checkoutNumber:e.checkoutNumber})}}async function mt(){const e=JSON.stringify([Se.trim(),O,z,D.trim(),de,R,A,I,s]);if(!(!se||!Je||He!=="new"||We.current===e))try{await X.createAddress({label:Se.trim()||"Home",contact_name:`${O} ${z}`.trim(),phone:D.trim(),address:de,city:R,zip_code:I,state:A,country:s}),We.current=e,Xe("Address saved to your account.")}catch{Xe("We couldn't save the address to your account — you can add it under Account → Addresses.")}}async function ft(e,t=g,n=!1){L(null);try{if(t==="card"&&c.paymentMethods.includes("card")){const o=await m.createPaymentIntent({idempotencyKey:f});if(Y.current=o,n&&lt()){await fe(e);return}let a=e;if(n){const l=await ue.current?.().catch(()=>null);if(l?.orderNumber){await q(l,e);return}if(a=yt(e,l)??{...e,expiresAt:null},lt()){await fe(e);return}}_(a),Ae(!1),ie(o)}else if(t==="paypal"&&c.paymentMethods.includes("paypal"))_(e),Bt(!0);else if(t==="afterpay"&&c.paymentMethods.includes("afterpay")){const o=window.location.origin,a=await m.createAfterpayCheckout({idempotencyKey:f,confirmUrl:`${o}/checkout?afterpay=confirm`,cancelUrl:`${o}/checkout?afterpay=cancel`}),l={idempotencyKey:f,confirmation:e};k.setItem(wn,JSON.stringify(l)),window.location.assign(a.redirectCheckoutUrl);return}else if(t==="square"&&c.paymentMethods.includes("square"))_(e),Ft(!0);else if(t==="gocardless"&&c.paymentMethods.includes("gocardless")){const o=window.location.origin,a=await m.createGocardlessBillingRequest({idempotencyKey:f,confirmUrl:`${o}/checkout?gocardless=confirm`,cancelUrl:`${o}/checkout?gocardless=cancel`}),l={idempotencyKey:f,confirmation:e};k.setItem(Te,JSON.stringify(l)),window.location.assign(a.authorisationUrl);return}else if(t==="zip"&&c.paymentMethods.includes("zip")){const o=window.location.origin,a=await m.createZipCheckout({idempotencyKey:f,redirectUrl:`${o}/checkout?zip=return`}),l={idempotencyKey:f,confirmation:e};k.setItem(Cn,JSON.stringify(l)),window.location.assign(a.redirectUrl);return}else if(t==="klarna"&&c.paymentMethods.includes("klarna")){const o=window.location.origin,a=await m.createKlarnaCheckout({idempotencyKey:f,confirmUrl:`${o}/checkout?klarna=confirm`,cancelUrl:`${o}/checkout?klarna=cancel`}),l={idempotencyKey:f,confirmation:e};k.setItem(Ke,JSON.stringify(l)),window.location.assign(a.redirectUrl);return}else w(e)}catch(o){if(n&&o instanceof ye&&o.status===409){await q(void 0,e);return}ht(e,o),S(!1)}}function yt(e,t){return t&&!t.orderNumber&&t.status==="open"&&t.checkoutNumber===e.checkoutNumber?t:null}function ht(e,t){C(In(e,t)),!e.orderNumber&&bt(t)?(E.current=!1,Ze(Ie())):L(e)}async function rn(e){if(!v)return;const t=v;try{const n=await m.createPaymentIntent({idempotencyKey:f}),o=await ue.current?.().catch(()=>null);if(o?.orderNumber){await q(o);return}const a=yt(t,o);_(a??{...t,expiresAt:null}),Ae(e&&a!==null),Y.current=n,ie(n)}catch(n){if(n instanceof ye&&n.status===409){await q();return}ie(null),_(null),ht(t,n),S(!1)}}function on(){v&&(E.current=!0,L(v),ie(null),_(null),Ae(!1),S(!1))}return{site:c,logo:d,items:i,totals:P,coupon:T,deliveryOptions:Re,courierUnavailable:Mt,retryCourier:Lt,shippingMethodId:Z,setShippingMethodId:xt,pickupLocation:It,servedCountries:B,formatMoney:Tt,payChoice:g,setPayChoice:he,placing:j,email:F,setEmail:ge,firstName:O,setFirstName:we,lastName:z,setLastName:ke,address1:Q,setAddress1:V,address2:Ce,setAddress2:ee,city:R,setCity:te,postcode:I,setPostcode:ne,phone:D,setPhone:re,country:s,setCountry:oe,subdivision:A,setSubdivision:ce,subdivisions:H,destination:Be,postcodeLabel:Rt,subdivisionLabel:_t,me:se,savedAddresses:$t,selectedAddressId:He,setSelectedAddressId:Pe,saveAddress:Je,setSaveAddress:Ge,saveLabel:Se,setSaveLabel:Yt,addressSaveNote:Ut,idemKey:f,confirmation:je,setConfirmation:w,orderError:qt,payment:Qe,paypalStep:Ve,squareStep:et,pendingConf:v,paid:zt,setPaid:M,unpaidOrder:h,payNote:Dt,afterpayConfirming:Ht,gocardlessConfirming:Gt,zipConfirming:Xt,klarnaConfirming:Wt,cardConfirming:rt,checkoutResult:ve,confirmCardPayment:q,cardStillProcessing:pt,renewCardPayment:rn,holdRenewed:Qt,leaveCardPayment:on,checkoutRootRef:st,setCheckoutHeaderEl:Vt,fillFromAddress:it,checkoutSignOut:en,payOptions:$,noPaymentMethod:tn,placeOrder:nn}}const At=an(null);function jn({children:c,...d}){const u=Tn(d);return N(At.Provider,{value:u,children:c})}function Qn(){const c=sn(At);if(!c)throw new Error("useCheckout must be used inside CheckoutStateProvider");return c}export{jn as CheckoutStateProvider,Zn as NO_PAYMENT_METHOD_NOTE,Wn as SHIPPING_RETRY_NOTE,St as buildPayOptions,In as paymentNotStartedMessage,Qn as useCheckout};
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};
@@ -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"];
@@ -361,6 +363,7 @@ export declare const products: {
361
363
  createOrderAuthed: (body: OrderRequest) => Promise<OrderConfirmation>;
362
364
  lookupOrder: (body: OrderLookupRequest) => Promise<OrderTracking>;
363
365
  createPaymentIntent: (body: PaymentIntentRequest) => Promise<PaymentIntent>;
366
+ releaseCheckout: (body: CheckoutReleaseKeyRequest) => Promise<CheckoutRelease>;
364
367
  createPaypalOrder: (body: PaypalOrderRequest) => Promise<PaypalOrder>;
365
368
  capturePaypalOrder: (body: PaypalCaptureRequest) => Promise<PaymentOutcome>;
366
369
  createAfterpayCheckout: (body: AfterpayCheckoutRequest) => Promise<AfterpayCheckout>;
@@ -1 +1 @@
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)})),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};
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};
@@ -447,6 +447,22 @@ export interface paths {
447
447
  patch?: never;
448
448
  trace?: never;
449
449
  };
450
+ "/checkouts/release": {
451
+ parameters: {
452
+ query?: never;
453
+ header?: never;
454
+ path?: never;
455
+ cookie?: never;
456
+ };
457
+ get?: never;
458
+ put?: never;
459
+ post: operations["releaseCheckout"];
460
+ delete?: never;
461
+ options?: never;
462
+ head?: never;
463
+ patch?: never;
464
+ trace?: never;
465
+ };
450
466
  "/payments/intent": {
451
467
  parameters: {
452
468
  query?: never;
@@ -1679,6 +1695,12 @@ export interface components {
1679
1695
  adConsent?: "granted" | "denied";
1680
1696
  checkoutFlow?: 1 | 2;
1681
1697
  };
1698
+ CheckoutReleaseKeyRequest: {
1699
+ idempotencyKey: string;
1700
+ };
1701
+ CheckoutRelease: {
1702
+ status: "released" | "held" | "committed";
1703
+ };
1682
1704
  PaymentIntentRequest: {
1683
1705
  idempotencyKey: string;
1684
1706
  };
@@ -2871,6 +2893,30 @@ export interface operations {
2871
2893
  404: components["responses"]["NotFound"];
2872
2894
  };
2873
2895
  };
2896
+ releaseCheckout: {
2897
+ parameters: {
2898
+ query?: never;
2899
+ header?: never;
2900
+ path?: never;
2901
+ cookie?: never;
2902
+ };
2903
+ requestBody: {
2904
+ content: {
2905
+ "application/json": components["schemas"]["CheckoutReleaseKeyRequest"];
2906
+ };
2907
+ };
2908
+ responses: {
2909
+ 200: {
2910
+ headers: {
2911
+ [name: string]: unknown;
2912
+ };
2913
+ content: {
2914
+ "application/json": components["schemas"]["CheckoutRelease"];
2915
+ };
2916
+ };
2917
+ 400: components["responses"]["BadRequest"];
2918
+ };
2919
+ };
2874
2920
  createPaymentIntent: {
2875
2921
  parameters: {
2876
2922
  query?: never;
@@ -1,16 +1,20 @@
1
- import { type OrderConfirmation } from "../api/index.js";
1
+ import { type CheckoutRelease, type OrderConfirmation } from "../api/index.js";
2
2
  import type { LandingOrder } from "./wallet-return.js";
3
3
  export declare const PAY_FIRST_FLOW = 2;
4
4
  export declare function paysFirst(method: string | null): boolean;
5
5
  export declare const CHECKOUT_UNAVAILABLE = "checkout_unavailable";
6
+ export declare const CHECKOUT_WAITING = "checkout_waiting";
6
7
  export declare const NOT_CHECKED = "We could not check your payment. Please try again.";
8
+ export declare const BANK_WAITING = "Your bank is still waiting for you to approve this payment, so your order stays as it was. Finish the approval, or try again in a few minutes.";
7
9
  export declare const INTENT_READ_MS = 10000;
8
10
  export declare function readIntentStatus(intent: {
9
11
  publishableKey: string;
10
12
  clientSecret: string;
11
13
  }, ms?: number): Promise<string | undefined>;
12
14
  export declare const DROPPABLE_INTENT: Set<string>;
15
+ export declare function releaseHeldCheckout(idempotencyKey: string, ms?: number): Promise<CheckoutRelease["status"] | undefined>;
13
16
  export declare function checkoutGone(err: unknown): boolean;
17
+ export declare function checkoutWaiting(err: unknown): boolean;
14
18
  export declare function orderReference(conf: Pick<OrderConfirmation, "orderNumber" | "checkoutNumber">): string;
15
19
  export type PayFirstResult = {
16
20
  kind: "pending" | "processing" | "refunded" | "expired";
@@ -1 +1 @@
1
- import{loadStripe as c}from"@stripe/stripe-js";import{ApiError as i}from"../api/index.js";const m=2;function y(e){return e==="card"}const u="checkout_unavailable",f="We could not check your payment. Please try again.",d=1e4;async function k(e,n=d){let t;const r=new Promise(o=>{t=setTimeout(()=>o(void 0),n)}),a=(async()=>{try{return(await(await c(e.publishableKey))?.retrievePaymentIntent(e.clientSecret))?.paymentIntent?.status}catch{return}})();try{return await Promise.race([a,r])}finally{clearTimeout(t)}}const x=new Set(["none","requires_payment_method","canceled"]);function N(e){return e instanceof i&&typeof e.data=="object"&&e.data!==null&&e.data.code===u}function h(e){return e.orderNumber||e.checkoutNumber}function s(e){return e.orderNumber?{kind:"placed",order:e}:{kind:e.status==="released"?"refunded":e.status==="expired"?"expired":"pending",checkoutNumber:e.checkoutNumber}}async function _({checkoutNumber:e,resend:n,page:t}){t.setConfirming(!0);let r;try{r=s(await n())}catch{r={kind:"pending",checkoutNumber:e}}r.kind==="placed"?(t.markPaid(),t.track(r.order),t.land(r.order)):t.unplaced({...r,checkoutNumber:r.checkoutNumber||e}),t.setConfirming(!1)}export{u as CHECKOUT_UNAVAILABLE,x as DROPPABLE_INTENT,d as INTENT_READ_MS,f as NOT_CHECKED,m as PAY_FIRST_FLOW,N as checkoutGone,h as orderReference,s as payFirstOutcome,y as paysFirst,k as readIntentStatus,_ as settlePayFirst};
1
+ import{loadStripe as c}from"@stripe/stripe-js";import{ApiError as s,products as d}from"../api/index.js";const h=2;function k(e){return e==="card"}const l="checkout_unavailable",p="checkout_waiting",x="We could not check your payment. Please try again.",N="Your bank is still waiting for you to approve this payment, so your order stays as it was. Finish the approval, or try again in a few minutes.",a=1e4;async function T(e,n=a){let t;const r=new Promise(i=>{t=setTimeout(()=>i(void 0),n)}),o=(async()=>{try{return(await(await c(e.publishableKey))?.retrievePaymentIntent(e.clientSecret))?.paymentIntent?.status}catch{return}})();try{return await Promise.race([o,r])}finally{clearTimeout(t)}}const _=new Set(["none","requires_payment_method","canceled"]);async function w(e,n=a){let t;const r=new Promise(o=>{t=setTimeout(()=>o(void 0),n)});try{return await Promise.race([d.releaseCheckout({idempotencyKey:e}).then(o=>o.status,()=>{}),r])}finally{clearTimeout(t)}}function u(e,n){return e instanceof s&&typeof e.data=="object"&&e.data!==null&&e.data.code===n}function b(e){return u(e,l)}function I(e){return u(e,p)}function P(e){return e.orderNumber||e.checkoutNumber}function m(e){return e.orderNumber?{kind:"placed",order:e}:{kind:e.status==="released"?"refunded":e.status==="expired"?"expired":"pending",checkoutNumber:e.checkoutNumber}}async function A({checkoutNumber:e,resend:n,page:t}){t.setConfirming(!0);let r;try{r=m(await n())}catch{r={kind:"pending",checkoutNumber:e}}r.kind==="placed"?(t.markPaid(),t.track(r.order),t.land(r.order)):t.unplaced({...r,checkoutNumber:r.checkoutNumber||e}),t.setConfirming(!1)}export{N as BANK_WAITING,l as CHECKOUT_UNAVAILABLE,p as CHECKOUT_WAITING,_ as DROPPABLE_INTENT,a as INTENT_READ_MS,x as NOT_CHECKED,h as PAY_FIRST_FLOW,b as checkoutGone,I as checkoutWaiting,P as orderReference,m as payFirstOutcome,k as paysFirst,T as readIntentStatus,w as releaseHeldCheckout,A as settlePayFirst};