efficient-storefront-blocks 0.61.0 → 0.62.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 (139) hide show
  1. package/CHANGELOG.md +63 -1
  2. package/dist/chunks/{EditorPreviewCheckout-55ERZEPV.js → EditorPreviewCheckout-BQFPYYBS.js} +1 -1
  3. package/dist/chunks/{SiteEditorProvider-XF374NLZ.js → SiteEditorProvider-3E6XWZIS.js} +1 -1
  4. package/dist/chunks/chunk-4BQ44OLC.js +250 -0
  5. package/dist/chunks/chunk-MT5KWSYX.js +1 -0
  6. package/dist/chunks/chunk-OJ4OD3N6.js +1 -0
  7. package/dist/chunks/{fitment-data-RORHKBID.js → fitment-data-PWZAAUFK.js} +1 -1
  8. package/dist/editor/components/EditorPreviewChat.js +4 -4
  9. package/dist/editor/components/PreviewHeader.d.ts +1 -1
  10. package/dist/editor/components/PreviewHeader.js +4 -4
  11. package/dist/editor/lib/efficient-backend.d.ts +1 -0
  12. package/dist/editor/lib/efficient-backend.js +1 -1
  13. package/dist/editor/lib/efficient-block-sources.d.ts +2 -0
  14. package/dist/editor/lib/efficient-block-sources.js +1 -0
  15. package/dist/editor/lib/puck/blocks/commerce/EuTyreLabelBlock/fields.d.ts +2 -0
  16. package/dist/editor/lib/puck/blocks/commerce/EuTyreLabelBlock/fields.js +1 -0
  17. package/dist/editor/lib/puck/blocks/commerce/ProductGallery/fields.d.ts +6 -0
  18. package/dist/editor/lib/puck/blocks/commerce/ProductGallery/fields.js +1 -0
  19. package/dist/editor/lib/puck/blocks/commerce/ProductHero/fields.js +1 -1
  20. package/dist/editor/lib/puck/blocks/commerce/index.d.ts +1 -1
  21. package/dist/editor/lib/puck/blocks/commerce/index.js +1 -1
  22. package/dist/editor/lib/puck/blocks/service/RatingBlock/fields.d.ts +2 -0
  23. package/dist/editor/lib/puck/blocks/service/RatingBlock/fields.js +1 -0
  24. package/dist/editor/lib/puck/blocks/service/index.d.ts +1 -1
  25. package/dist/editor/lib/puck/blocks/service/index.js +1 -1
  26. package/dist/editor/lib/puck/config.js +1 -1
  27. package/dist/editor/lib/storefront-editor-words.d.ts +1 -0
  28. package/dist/editor/lib/storefront-editor-words.js +1 -1
  29. package/dist/editor.css +1 -1
  30. package/dist/index.d.ts +8 -0
  31. package/dist/index.js +101 -81
  32. package/dist/render/app/globals.css +70 -14
  33. package/dist/render/built-with.json +1 -1
  34. package/dist/render/components/CartContext.d.ts +1 -0
  35. package/dist/render/components/CartContext.js +1 -1
  36. package/dist/render/components/CartDrawer.d.ts +0 -8
  37. package/dist/render/components/CartDrawer.js +2 -2
  38. package/dist/render/components/ChatWidget.js +1 -1
  39. package/dist/render/components/EuTyreLabels.d.ts +3 -0
  40. package/dist/render/components/EuTyreLabels.js +1 -1
  41. package/dist/render/components/FooterMenu.js +1 -1
  42. package/dist/render/components/FormBlock.js +1 -1
  43. package/dist/render/components/GalleryItem.js +1 -1
  44. package/dist/render/components/Header.js +1 -1
  45. package/dist/render/components/LegalLine.js +1 -1
  46. package/dist/render/components/PopupFrame.d.ts +2 -1
  47. package/dist/render/components/PopupFrame.js +1 -1
  48. package/dist/render/components/PopupHost.d.ts +17 -0
  49. package/dist/render/components/PopupHost.js +1 -0
  50. package/dist/render/components/ProductCard.js +1 -1
  51. package/dist/render/components/ProductGallery.d.ts +15 -0
  52. package/dist/render/components/ProductGallery.js +1 -0
  53. package/dist/render/components/ProductHeroPanel.js +1 -1
  54. package/dist/render/components/RatingStars.d.ts +4 -0
  55. package/dist/render/components/RatingStars.js +1 -0
  56. package/dist/render/components/Reviews.js +1 -1
  57. package/dist/render/components/StorefrontProviders.d.ts +1 -3
  58. package/dist/render/components/StorefrontProviders.js +1 -1
  59. package/dist/render/components/SubscribePopupContext.d.ts +3 -15
  60. package/dist/render/components/SubscribePopupContext.js +1 -1
  61. package/dist/render/components/TyrePlpCard.js +1 -1
  62. package/dist/render/components/WheelCardFrame.d.ts +3 -27
  63. package/dist/render/components/WheelCardFrame.js +1 -1
  64. package/dist/render/components/card-pieces/CardBuyButton.d.ts +7 -0
  65. package/dist/render/components/card-pieces/CardBuyButton.js +1 -0
  66. package/dist/render/components/card-pieces/CardFinishSwatches.d.ts +5 -0
  67. package/dist/render/components/card-pieces/CardFinishSwatches.js +1 -0
  68. package/dist/render/components/card-pieces/CardPrice.d.ts +7 -0
  69. package/dist/render/components/card-pieces/CardPrice.js +1 -0
  70. package/dist/render/components/card-pieces/CardProductBadge.d.ts +7 -0
  71. package/dist/render/components/card-pieces/CardProductBadge.js +1 -0
  72. package/dist/render/components/card-pieces/CardSizes.d.ts +9 -0
  73. package/dist/render/components/card-pieces/CardSizes.js +1 -0
  74. package/dist/render/components/card-pieces/ProductCardState.d.ts +53 -0
  75. package/dist/render/components/card-pieces/ProductCardState.js +1 -0
  76. package/dist/render/components/card-pieces/card-row.d.ts +20 -0
  77. package/dist/render/components/card-pieces/card-row.js +1 -0
  78. package/dist/render/components/cart/drawer-parts.d.ts +28 -0
  79. package/dist/render/components/cart/drawer-parts.js +1 -0
  80. package/dist/render/components/pdp-dynamic/DynamicEuTyreLabel.d.ts +3 -0
  81. package/dist/render/components/pdp-dynamic/DynamicEuTyreLabel.js +1 -1
  82. package/dist/render/components/pdp-dynamic/DynamicProductGallery.d.ts +9 -0
  83. package/dist/render/components/pdp-dynamic/DynamicProductGallery.js +1 -0
  84. package/dist/render/components/useHeaderBar.js +1 -1
  85. package/dist/render/components/useIsLightTheme.d.ts +1 -0
  86. package/dist/render/components/useIsLightTheme.js +1 -0
  87. package/dist/render/components/wheels-plp/PlpCard.d.ts +3 -2
  88. package/dist/render/components/wheels-plp/PlpCard.js +1 -1
  89. package/dist/render/components/wheels-plp/usePlpCardSelection.d.ts +1 -1
  90. package/dist/render/components/wheels-plp/usePlpCardSelection.js +1 -1
  91. package/dist/render/lib/api/index.d.ts +4 -2
  92. package/dist/render/lib/api/index.js +1 -1
  93. package/dist/render/lib/api/types.d.ts +48 -1
  94. package/dist/render/lib/chrome-load.d.ts +1 -1
  95. package/dist/render/lib/chrome-load.js +1 -1
  96. package/dist/render/lib/content/product-hero.d.ts +1 -0
  97. package/dist/render/lib/content/product-hero.js +1 -1
  98. package/dist/render/lib/header-fit.d.ts +2 -0
  99. package/dist/render/lib/header-fit.js +1 -0
  100. package/dist/render/lib/popup/popup-stores.d.ts +2 -0
  101. package/dist/render/lib/popup/popup-stores.js +1 -0
  102. package/dist/render/lib/puck/blocks/commerce/EuTyreLabelBlock/meta.d.ts +2 -0
  103. package/dist/render/lib/puck/blocks/commerce/EuTyreLabelBlock/meta.js +1 -0
  104. package/dist/render/lib/puck/blocks/commerce/EuTyreLabelBlock/render.d.ts +2 -0
  105. package/dist/render/lib/puck/blocks/commerce/EuTyreLabelBlock/render.js +1 -0
  106. package/dist/render/lib/puck/blocks/commerce/ProductGallery/meta.d.ts +2 -0
  107. package/dist/render/lib/puck/blocks/commerce/ProductGallery/meta.js +1 -0
  108. package/dist/render/lib/puck/blocks/commerce/ProductGallery/render.d.ts +2 -0
  109. package/dist/render/lib/puck/blocks/commerce/ProductGallery/render.js +1 -0
  110. package/dist/render/lib/puck/blocks/commerce/metas.d.ts +2 -0
  111. package/dist/render/lib/puck/blocks/commerce/metas.js +1 -1
  112. package/dist/render/lib/puck/blocks/commerce/renders.d.ts +2 -0
  113. package/dist/render/lib/puck/blocks/commerce/renders.js +1 -1
  114. package/dist/render/lib/puck/blocks/service/RatingBlock/meta.d.ts +3 -0
  115. package/dist/render/lib/puck/blocks/service/RatingBlock/meta.js +1 -0
  116. package/dist/render/lib/puck/blocks/service/RatingBlock/render.d.ts +2 -0
  117. package/dist/render/lib/puck/blocks/service/RatingBlock/render.js +1 -0
  118. package/dist/render/lib/puck/blocks/service/metas.d.ts +1 -0
  119. package/dist/render/lib/puck/blocks/service/metas.js +1 -1
  120. package/dist/render/lib/puck/blocks/service/renders.d.ts +1 -0
  121. package/dist/render/lib/puck/blocks/service/renders.js +1 -1
  122. package/dist/render/lib/puck/lazy-draws.js +1 -1
  123. package/dist/render/lib/storefront-page-groups.js +1 -1
  124. package/dist/render/lib/wheels/plp-fitment-match.d.ts +4 -0
  125. package/dist/render/lib/wheels/plp-fitment-match.js +1 -1
  126. package/dist/render/lib/wheels/spec-sheet.js +1 -1
  127. package/dist/words.d.ts +2 -2
  128. package/dist/words.js +3 -3
  129. package/package.json +4 -4
  130. package/dist/chunks/chunk-FCCEAXMM.js +0 -1
  131. package/dist/chunks/chunk-VVQ7KFQO.js +0 -1
  132. package/dist/chunks/chunk-YNI65Q6Z.js +0 -250
  133. package/dist/render/components/wheels-plp/useWheelCardBottom.d.ts +0 -20
  134. package/dist/render/components/wheels-plp/useWheelCardBottom.js +0 -1
  135. package/dist/render/lib/popup/popup-rules.d.ts +0 -25
  136. package/dist/render/lib/popup/popup-rules.js +0 -1
  137. /package/dist/chunks/{chunk-YNI65Q6Z.js.LEGAL.txt → chunk-4BQ44OLC.js.LEGAL.txt} +0 -0
  138. /package/dist/chunks/{chunk-VT346MLP.js → chunk-FZFBLN7K.js} +0 -0
  139. /package/dist/chunks/{chunk-I6VNNXUI.js → chunk-TRUOK5AD.js} +0 -0
@@ -0,0 +1,28 @@
1
+ import type { RefObject } from "react";
2
+ import { type CartLine } from "../CartContext.js";
3
+ import type { TyreSummary } from "../../lib/api/index.js";
4
+ import { type CartDrawerContent } from "efficient-web-builder/format/lib/content/cart-drawer";
5
+ export declare function CartDrawerHeader({ content, closeRef, }: {
6
+ content: CartDrawerContent;
7
+ closeRef?: RefObject<HTMLButtonElement | null>;
8
+ }): import("react").JSX.Element;
9
+ export declare function CartStatusRail({ content }: {
10
+ content: CartDrawerContent;
11
+ }): import("react").JSX.Element;
12
+ export declare function CartLines({ content, tyres, }: {
13
+ content: CartDrawerContent;
14
+ tyres: ReadonlyMap<string, TyreSummary>;
15
+ }): import("react").JSX.Element;
16
+ export declare function CartUpsell(): import("react").JSX.Element;
17
+ export declare function CartCouponRow(): import("react").JSX.Element;
18
+ export declare function CartTrustMarkers({ content }: {
19
+ content: CartDrawerContent;
20
+ }): import("react").JSX.Element;
21
+ export declare function CartTotals(): import("react").JSX.Element;
22
+ export declare function CartActions(): import("react").JSX.Element;
23
+ export declare function CartLineRow({ line, tyre, onRemove, onQtyChange, }: {
24
+ line: CartLine;
25
+ tyre?: TyreSummary | null;
26
+ onRemove: () => void;
27
+ onQtyChange: (q: number) => void;
28
+ }): import("react").JSX.Element;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as t,jsxs as a,Fragment as c}from"react/jsx-runtime";import u from"next/link";import{FREE_PRICE as b,UNPRICED_LABEL as N}from"../../lib/wheels/price-display.js";import k from"../CartLineThumbnail.js";import w from"../CouponField.js";import C from"../QuantityStepper.js";import j from"efficient-web-builder/render/components/RMark";import{lineTotal as y,useCart as d}from"../CartContext.js";import{COUPON_DEFERRED_TOTAL as B}from"../../lib/cart/coupon-preview.js";import{shippingWords as S,TAX_PENDING as T}from"../../lib/cart/shipping-status.js";import{useCurrency as g}from"../CurrencyContext.js";import{cartSubtitle as F}from"efficient-web-builder/format/lib/content/cart-drawer";function G({content:e,closeRef:r}){const{close:n,items:s}=d(),l=r;return a("header",{className:"flex flex-shrink-0 flex-col gap-4 border-b border-line px-8 pb-6 pt-8 max-[640px]:px-6 max-[640px]:pt-6 max-[640px]:pb-5",children:[a("div",{className:"flex items-center justify-between",children:[a("span",{className:"flex items-center gap-3 font-mono text-[10px] uppercase tracking-[0.3em] text-accent",children:[e.kickerBadge?t("span",{className:"border px-2 py-1 text-[10px]",style:{background:"color-mix(in oklab, var(--accent) 12%, transparent)",borderColor:"color-mix(in oklab, var(--accent) 50%, transparent)"},children:e.kickerBadge}):null,(e.kickerBadge?"· ":"")+e.kickerText]}),t("button",{ref:l,type:"button",onClick:n,"aria-label":"Close cart",className:"flex h-8 w-8 items-center justify-center border border-line text-[14px] text-fg-dim transition-colors hover:border-accent hover:text-accent",children:"✕"})]}),a("h1",{className:"font-display text-[38px] font-medium uppercase leading-[0.95] tracking-[-0.03em] max-[640px]:text-[30px]",children:[e.titleLead+" ",t("em",{className:"font-serif font-normal italic text-accent tracking-[-0.02em] normal-case",children:e.titleAccent})]}),t("p",{className:"font-serif text-[13px] italic leading-[1.5] text-fg-dim",children:F(e,s.length)})]})}function H({content:e}){const{totals:r}=d(),{activeCountry:n}=g(),s=n?.name??e.shipsToFallback,l=1+(e.leadTimeValue?1:0)+(s?1:0);return t(c,{children:a("div",{className:`grid flex-shrink-0 ${$[l-1]} gap-px border-b border-line bg-line`,children:[t(h,{label:"Items",value:a(c,{children:[t("em",{className:"font-serif font-normal italic text-accent",children:r.sets})," set",r.sets===1?"":"s"," · ",r.units," item",r.units===1?"":"s"]})}),e.leadTimeValue?t(h,{label:"Lead time",value:e.leadTimeValue}):null,s?t(h,{label:"Ships to",value:s}):null]})})}function X({content:e,tyres:r}){const{items:n,remove:s,setQty:l}=d();return t(c,{children:n.length===0?t(U,{content:e}):n.map(o=>t(_,{line:o,tyre:r.get(o.slug),onRemove:()=>s(o.id),onQtyChange:m=>l(o.id,m)},o.id))})}function Y(){const{items:e,totals:r,bundles:n}=d(),{formatMoney:s}=g(),l=new Set(e.flatMap(i=>(i.components??[]).map(x=>x.partNumber))),o=new Set(r.appliedBundles.map(i=>i.slug)),m=n.filter(i=>!o.has(i.slug)).filter(i=>i.components.some(x=>l.has(x.partNumber))).slice(0,2);return t(c,{children:m.length>0&&a("section",{className:"border-b border-line px-8 py-6 max-[640px]:px-6",style:{background:"color-mix(in oklab, var(--site-surface) 60%, transparent)"},children:[a("div",{className:"mb-4 flex items-center justify-between font-mono text-[10px] uppercase tracking-[0.3em] text-accent",children:[t("span",{children:"You may also need"}),t("span",{className:"font-display text-[11px] normal-case tracking-[0.08em] text-fg-dim",children:"Buy together, save"})]}),t("div",{className:"grid grid-cols-2 gap-2 max-[640px]:grid-cols-1",children:m.map(i=>t(R,{href:`/bundles/${i.slug}`,title:i.name,sub:E(i,r.currency,s)},i.slug))})]})})}function J(){return t(c,{children:t("section",{className:"border-b border-line px-8 py-6 max-[640px]:px-6",children:t(w,{})})})}function Z({content:e}){return t(c,{children:e.promises.length>0&&t("div",{className:"flex flex-wrap justify-center gap-5 border-b border-line px-8 pt-6 pb-8 font-mono text-[9px] uppercase tracking-[0.24em] text-fg-dim max-[640px]:px-6",children:e.promises.map(r=>t(L,{children:r},r))})})}function ee(){const{totals:e,coupon:r}=d(),{formatMoney:n}=g();return t(c,{children:a("div",{className:"flex flex-shrink-0 flex-col gap-2 border-t border-line px-8 pt-5 max-[640px]:px-6",children:[t(p,{label:`Subtotal · ${e.sets} set${e.sets===1?"":"s"}`,value:n(e.subtotal,e.currency)}),e.appliedBundles.map(s=>t(p,{label:`Bundle · ${s.name}${s.multiples>1?` ×${s.multiples}`:""}`,value:a("span",{style:{color:"var(--green)"},children:["− ",n(s.discount,e.currency)]})},s.slug)),e.discount>0&&r?.valid&&t(p,{label:`Coupon · ${r.code}`,value:a("span",{style:{color:"var(--green)"},children:["− ",n(e.discount,e.currency)]})}),r?.deferred&&t(p,{label:`Coupon · ${r.code}`,value:B}),r?.valid&&r.effects?.gift&&t(p,{label:`Free gift · ${r.effects.gift.partNumber}${r.effects.gift.quantity>1?` ×${r.effects.gift.quantity}`:""}`,value:t("span",{style:{color:"var(--green)"},children:b})}),t(p,{label:"Shipping",value:e.shippingStatus==="free"?t("span",{style:{color:"var(--green)"},children:b}):S(e.shippingStatus)??n(e.shipping,e.currency)}),e.tax&&(e.tax.charged?t(p,{label:e.tax.inclusive?`${e.tax.name} included · ${e.tax.rate}%`:e.tax.name,value:n(e.tax.amount,e.currency)}):e.tax.name?t(p,{label:e.tax.name,value:T}):null),a("div",{className:"mt-2 flex items-center justify-between border-t border-line pt-4 text-fg",children:[a("span",{className:"font-display text-[22px] font-medium tracking-[-0.02em] normal-case",children:["Total ",t("em",{className:"font-serif font-normal italic text-accent",children:"due"})]}),t("span",{className:"text-right font-display text-[30px] font-medium tracking-[-0.025em] text-fg",children:e.repricing?"…":n(e.grand,e.currency)})]})]})})}function te(){const{items:e,close:r}=d();return t(c,{children:a("div",{className:"flex flex-shrink-0 flex-col gap-3 px-8 pb-6 pt-4 max-[640px]:px-6",children:[a(u,{href:"/checkout",onClick:r,"aria-disabled":e.length===0,className:["group flex items-center justify-between border px-5 py-5 font-mono text-[12px] uppercase tracking-[0.3em] transition-colors",e.length===0?"pointer-events-none cursor-not-allowed border-line bg-surface text-fg-dim":"border-btn bg-btn text-btn-ink hover:border-fg hover:bg-fg"].join(" "),children:["Begin checkout",t("span",{className:"transition-transform group-hover:translate-x-1",children:"→"})]}),t("div",{className:"flex items-center justify-between px-1 py-2 font-mono text-[10px] uppercase tracking-[0.24em] text-fg-dim",children:t(u,{href:"/wheels",onClick:r,className:"text-fg transition-colors hover:text-accent",children:"← Keep browsing"})})]})})}const $=["grid-cols-1","grid-cols-2","grid-cols-3"];function h({label:e,value:r}){return a("div",{className:"flex flex-col gap-1 bg-bg px-4 py-4",children:[t("span",{className:"font-mono text-[9px] uppercase tracking-[0.26em] text-fg-dim",children:e}),t("span",{className:"font-display text-[14px] font-medium tracking-[-0.005em] text-fg",children:r})]})}function _({line:e,tyre:r,onRemove:n,onQtyChange:s}){const{catalog:l,totals:o}=d(),m=(e.components??[]).reduce((f,v)=>f+(o.freeUnitsByPartNumber[v.partNumber]??0),0),{currency:i,formatMoney:x}=g();return a(c,{children:[a("article",{className:"grid grid-cols-[96px_1fr] gap-5 border-b border-line px-8 py-6 transition-colors hover:bg-[color-mix(in_oklab,var(--site-surface)_60%,transparent)] max-[640px]:grid-cols-[78px_1fr] max-[640px]:px-6 max-[640px]:py-5",children:[t(k,{line:e,catalog:l,tyre:r}),a("div",{className:"flex min-w-0 flex-col gap-2",children:[a("div",{className:"flex items-start justify-between gap-3",children:[a("span",{className:"font-mono text-[9px] uppercase tracking-[0.26em] text-accent",children:["N° ",e.positionNo," · ",e.process==="FusionForge®"?a(c,{children:["FusionForge",t(j,{})]}):e.process]}),t("span",{className:"whitespace-nowrap font-display text-[16px] font-medium tracking-[-0.015em] text-fg",children:y(e,i)===null?N:x(y(e,i),i)})]}),a("h3",{className:"mt-0.5 font-display text-[22px] font-medium uppercase leading-none tracking-[-0.02em]",children:[e.name.lead,t("em",{className:"font-serif font-normal italic text-accent tracking-[-0.01em] normal-case",children:e.name.accent})]}),e.config.length>0&&a("div",{className:"mt-1 flex flex-wrap gap-2",children:[e.config.map(f=>t("span",{className:["border px-2 py-1 font-mono text-[9px] uppercase tracking-[0.18em]",f.gold?"border-[color-mix(in_oklab,var(--accent)_45%,var(--site-line))] text-accent":"border-line text-fg-dim"].join(" "),children:f.label},f.label)),m>0&&a("span",{className:"border border-accent bg-accent px-2 py-1 font-mono text-[9px] uppercase tracking-[0.18em] text-bg",children:[m,"× free"]})]}),a("div",{className:"mt-3 flex items-center justify-between gap-3",children:[t(C,{value:e.qty,onChange:s,size:"small"}),a("div",{className:"flex gap-4 font-mono text-[10px] uppercase tracking-[0.22em]",children:[t(u,{href:e.href??`/wheels/${e.slug}`,className:"text-fg-dim transition-colors hover:text-accent",children:e.href?"View product":"Edit finish"}),t("button",{type:"button",onClick:n,className:"text-fg-dim transition-colors hover:text-alert",children:"Remove"})]})]})]})]}),e.verifiedFor&&a("div",{className:"mx-8 -mt-px flex items-start gap-3 border-t-0 px-4 py-4 font-display text-[13px] leading-[1.45] text-fg max-[640px]:mx-6",style:{background:"color-mix(in oklab, var(--accent) 8%, transparent)",border:"1px solid color-mix(in oklab, var(--accent) 35%, var(--site-line))",borderTop:"0"},children:[t("span",{className:"flex-shrink-0 pt-px font-mono text-[10px] uppercase tracking-[0.24em] text-accent",children:"Fits"}),a("span",{children:["Verified for your ",t("strong",{className:"font-medium text-accent",children:e.verifiedFor}),". Final torque values shipped with the wheels."]})]})]})}function R({title:e,sub:r,href:n}){return a(u,{href:n,className:"flex items-center justify-between border border-line bg-bg px-4 py-3 text-left transition-colors hover:border-accent",children:[a("span",{className:"flex min-w-0 flex-col gap-1",children:[t("span",{className:"overflow-hidden text-ellipsis whitespace-nowrap font-display text-[13px] font-medium tracking-[-0.005em] text-fg",children:e}),t("span",{className:"font-mono text-[9px] uppercase tracking-[0.22em] text-fg-dim",children:r})]}),t("span",{className:"ml-2 flex h-6 w-6 flex-shrink-0 items-center justify-center font-mono text-[13px] text-accent",style:{borderColor:"color-mix(in oklab, var(--accent) 45%, var(--site-line))",borderWidth:1,borderStyle:"solid"},children:"+"})]})}function E(e,r,n){const s=e.savings[r];if(s===void 0)return"Buy together";const l=n(s,r);return e.savingIsFrom?`Save from ${l}`:`Save ${l}`}function L({children:e}){return t("span",{className:"inline-flex items-center gap-2 before:text-[6px] before:text-accent before:content-['●']",children:e})}function p({label:e,value:r}){return a("div",{className:"flex items-center justify-between font-mono text-[11px] uppercase tracking-[0.18em] text-fg-dim",children:[t("span",{children:e}),t("strong",{className:"font-display text-[14px] font-normal tracking-[-0.005em] normal-case text-fg",children:r})]})}function U({content:e}){return a("div",{className:"flex flex-col items-center justify-center gap-3 px-8 py-20 text-center",children:[t("span",{className:"font-mono text-[10px] uppercase tracking-[0.3em] text-accent",children:e.emptyKicker}),t("p",{className:"font-serif text-[16px] italic leading-[1.5] text-fg-dim",children:e.emptyBody}),a(u,{href:"/wheels",className:"mt-3 inline-flex items-center gap-3 border border-line px-5 py-3 font-mono text-[11px] uppercase tracking-[0.3em] text-fg transition-colors hover:border-accent hover:text-accent",children:["Browse the catalog ",t("span",{className:"text-accent",children:"→"})]})]})}export{te as CartActions,J as CartCouponRow,G as CartDrawerHeader,_ as CartLineRow,X as CartLines,H as CartStatusRail,ee as CartTotals,Z as CartTrustMarkers,Y as CartUpsell};
@@ -5,4 +5,7 @@ interface Props {
5
5
  editing?: boolean;
6
6
  }
7
7
  export default function DynamicEuTyreLabel(props: Props): import("react").JSX.Element;
8
+ export declare function DynamicEuTyreLabelBlock({ editing }: {
9
+ editing?: boolean;
10
+ }): import("react").JSX.Element;
8
11
  export {};
@@ -1 +1 @@
1
- "use client";import{jsx as e}from"react/jsx-runtime";import l,{EU_LABEL_BAND as m}from"../EuTyreLabels.js";import c from"../SectionBand.js";import u from"./KindGate.js";import{useEuTyreLabels as p}from"../useEuTyreLabels.js";import{useCurrentProduct as d}from"../../lib/puck/current-product.js";import{useSampleProduct as f}from"./useSampleProduct.js";import{say as y}from"efficient-web-builder/format/lib/editor-words";const b=["tyre"];function E(r){return e(u,{kinds:b,type:"EuTyreLabel",editing:r.editing,children:e(h,{...r})})}function h({num:r,editing:t=!1}){const o=d(),a=f(t&&!o),n=o?.product??a,i=n?.kind==="tyre"?n.source.variants:[],s=p(i);return s.length===0&&t?e(c,{className:m,children:e("p",{className:"font-mono text-[length:var(--size-label,13px)] uppercase tracking-[0.18em] text-fg-dim",children:y("The EU label appears here for every size with an EPREL registration number. It is read live from the registry and never stored.")})}):e(l,{labels:s,num:r??"",capped:!1})}export{E as default,b as supportedKinds};
1
+ "use client";import{jsx as r}from"react/jsx-runtime";import c,{EU_LABEL_BAND as m,EuTyreLabelGrades as d}from"../EuTyreLabels.js";import p from"../SectionBand.js";import a from"./KindGate.js";import{useEuTyreLabels as f}from"../useEuTyreLabels.js";import{useCurrentProduct as y}from"../../lib/puck/current-product.js";import{useSampleProduct as b}from"./useSampleProduct.js";import{say as E}from"efficient-web-builder/format/lib/editor-words";const s=["tyre"];function L(e){return r(a,{kinds:s,type:"EuTyreLabel",editing:e.editing,children:r(T,{...e})})}function T({num:e,editing:t=!1}){const n=l(t);return n.length===0&&t?r(p,{className:m,children:r(i,{})}):r(c,{labels:n,num:e??"",capped:!1})}function _({editing:e=!1}){return r(a,{kinds:s,type:"EuTyreLabel",editing:e,children:r(h,{editing:e})})}function h({editing:e}){const t=l(e);return t.length===0?e?r(i,{}):null:r(d,{labels:t})}function l(e){const t=y(),n=b(e&&!t),o=t?.product??n,u=o?.kind==="tyre"?o.source.variants:[];return f(u)}function i(){return r("p",{className:"font-mono text-[length:var(--size-label,13px)] uppercase tracking-[0.18em] text-fg-dim",children:E("The EU label appears here for every size with an EPREL registration number. It is read live from the registry and never stored.")})}export{_ as DynamicEuTyreLabelBlock,L as default,s as supportedKinds};
@@ -0,0 +1,9 @@
1
+ import type { HeroGalleryMode, HeroImageFit } from "../../lib/sections/hero-gallery.js";
2
+ interface GalleryLook {
3
+ galleryMode?: HeroGalleryMode;
4
+ imageFit?: HeroImageFit;
5
+ }
6
+ export default function DynamicProductGallery({ editing, ...look }: {
7
+ editing?: boolean;
8
+ } & GalleryLook): import("react").JSX.Element | null;
9
+ export {};
@@ -0,0 +1 @@
1
+ "use client";import{jsx as e,Fragment as s,jsxs as c}from"react/jsx-runtime";import l from"../ProductGallery.js";import a from"../ProductLightbox.js";import{SECTION_NOTICE_TEXT_CLASS as p}from"../SectionNotice.js";import{heroView as d}from"../product-hero/hero-view.js";import{useIsLightTheme as f}from"../useIsLightTheme.js";import{useLightbox as g}from"../useLightbox.js";import{useProductSelection as x}from"../useProductSelection.js";import{useCurrentProduct as h}from"../../lib/puck/current-product.js";import{say as L}from"efficient-web-builder/format/lib/editor-words";import{useSampleProduct as S}from"./useSampleProduct.js";function b({editing:o=!1,...t}){const r=h();return r?e(n,{product:r.product,selection:r.selection,onLightbox:r.openLightbox,editing:o,...t}):o?e(y,{...t}):null}function n({product:o,selection:t,onLightbox:r,editing:i,...u}){const m=f();return e(l,{product:o,view:d(o,t,i),angleIdx:t.angleIdx,onSelect:t.setAngleIdx,isLight:m,onLightbox:r,...u})}function y(o){const t=S(!0);return t?e(I,{product:t,...o}):e("p",{className:p,children:L("Loading sample product…")})}function I({product:o,...t}){const r=x(o,{editing:!0}),i=g();return c(s,{children:[e(n,{product:o,selection:r,onLightbox:i.open,editing:!0,...t}),e(a,{item:i.item,onClose:i.close})]})}export{b as default};
@@ -1 +1 @@
1
- "use client";import{useEffect as u,useRef as w,useState as m}from"react";import{HEADER_DRAWN_HEIGHT_VAR as p,HEADER_SET_HEIGHT_VAR as R}from"efficient-web-builder/render/lib/puck/header-clearance";function A({stickyMode:o,heightPx:i}){const c=w(null),[E,b]=m(!1),[v,f]=m(!1);return u(()=>{const e=c.current?.ownerDocument?.defaultView??window,s=i;let n=e.scrollY;function l(){const t=e.scrollY;b(t>10),o==="on_scroll_up"&&(t<=s?f(!1):t>n+4?f(!0):t<n-4&&f(!1)),n=t}return l(),e.addEventListener("scroll",l,{passive:!0}),()=>e.removeEventListener("scroll",l)},[o,i]),u(()=>{o!=="on_scroll_up"&&f(!1)},[o]),u(()=>{const e=c.current?.ownerDocument?.documentElement;e&&e.style.setProperty(R,`${i}px`)},[i]),u(()=>{const e=c.current,s=e?.ownerDocument,n=s?.defaultView;if(!e||!s||!n)return;let l="";const t=a=>{const r=`${Math.round(a)}px`;r!==l&&(l=r,s.documentElement.style.setProperty(p,r),s.body?.style.setProperty(p,r))};if(typeof n.ResizeObserver!="function"){t(e.getBoundingClientRect().height);return}const d=new n.ResizeObserver(a=>{const r=a[0]?.borderBoxSize?.[0];t(r?r.blockSize:e.getBoundingClientRect().height)});return d.observe(e),()=>d.disconnect()},[]),u(()=>{const e=c.current?.ownerDocument?.documentElement;e&&e.setAttribute("data-header-sticky",o)},[o]),{headerRef:c,scrolled:E,navHidden:v}}export{A as useHeaderBar};
1
+ "use client";import{useEffect as l,useLayoutEffect as R,useRef as H,useState as m}from"react";import{HEADER_DRAWN_HEIGHT_VAR as v,HEADER_SET_HEIGHT_VAR as _}from"efficient-web-builder/render/lib/puck/header-clearance";import{fitHeaderToRow as w}from"../lib/header-fit.js";function z({stickyMode:u,heightPx:f}){const s=H(null),[E,b]=m(!1),[p,a]=m(!1);return l(()=>{const e=s.current?.ownerDocument?.defaultView??window,r=f;let n=e.scrollY;function o(){const t=e.scrollY;b(t>10),u==="on_scroll_up"&&(t<=r?a(!1):t>n+4?a(!0):t<n-4&&a(!1)),n=t}return o(),e.addEventListener("scroll",o,{passive:!0}),()=>e.removeEventListener("scroll",o)},[u,f]),l(()=>{u!=="on_scroll_up"&&a(!1)},[u]),l(()=>{const e=s.current?.ownerDocument?.documentElement;e&&e.style.setProperty(_,`${f}px`)},[f]),l(()=>{const e=s.current,r=e?.ownerDocument,n=r?.defaultView;if(!e||!r||!n)return;let o="";const t=d=>{const c=`${Math.round(d)}px`;c!==o&&(o=c,r.documentElement.style.setProperty(v,c),r.body?.style.setProperty(v,c))};if(typeof n.ResizeObserver!="function"){t(e.getBoundingClientRect().height);return}const i=new n.ResizeObserver(d=>{const c=d[0]?.borderBoxSize?.[0];t(c?c.blockSize:e.getBoundingClientRect().height)});return i.observe(e),()=>i.disconnect()},[]),l(()=>{const e=s.current?.ownerDocument?.documentElement;e&&e.setAttribute("data-header-sticky",u)},[u]),R(()=>{s.current&&w(s.current)}),l(()=>{const e=s.current,r=e?.ownerDocument,n=r?.defaultView;if(!e||!r||!n)return;let o=!0;const t=()=>{o&&w(e)};e.addEventListener("load",t,!0),r.fonts?.ready.then(t,()=>{});const i=typeof n.ResizeObserver=="function"?new n.ResizeObserver(t):null;return i?.observe(e),()=>{o=!1,e.removeEventListener("load",t,!0),i?.disconnect()}},[]),{headerRef:s,scrolled:E,navHidden:p}}export{z as useHeaderBar};
@@ -0,0 +1 @@
1
+ export declare function useIsLightTheme(): boolean;
@@ -0,0 +1 @@
1
+ "use client";import{useEffect as u,useState as o}from"react";function i(){const[n,s]=o(!1);return u(()=>{const t=()=>{s(document.documentElement.getAttribute("data-theme")==="light")};t();const e=new MutationObserver(t);return e.observe(document.documentElement,{attributes:!0,attributeFilter:["data-theme"]}),()=>e.disconnect()},[]),n}export{i as useIsLightTheme};
@@ -2,7 +2,7 @@ import type { WheelSummary } from "../../lib/api/index.js";
2
2
  import { type CardIndexFormat, type CardOutline } from "efficient-web-builder/format/lib/sections/product-card-style";
3
3
  import { type FieldUsageAnswer } from "../../lib/content/field-usage.js";
4
4
  import { type VehicleFitment } from "../../lib/wheels/plp-fitment-match.js";
5
- export default function PlpCard({ wheel, colours, fit, editing, brandPlate, kindLabel, showBrand, showProcess, coverIndex, fieldUsage, spinOnHover, imageBackgroundFill, showBadge, outline, indexBadge, showCardSizes, showCardBuy, showCardPage, showCardPrice, showCardFinishes, imageSizes, }: {
5
+ export interface PlpCardProps {
6
6
  wheel: WheelSummary;
7
7
  colours?: readonly string[];
8
8
  fit?: VehicleFitment | null;
@@ -24,4 +24,5 @@ export default function PlpCard({ wheel, colours, fit, editing, brandPlate, kind
24
24
  showCardPrice?: boolean;
25
25
  showCardFinishes?: boolean;
26
26
  imageSizes?: string;
27
- }): import("react").JSX.Element;
27
+ }
28
+ export default function PlpCard({ wheel, colours, fit, editing, brandPlate, kindLabel, showBrand, showProcess, coverIndex, fieldUsage, spinOnHover, imageBackgroundFill, showBadge, outline, indexBadge, showCardSizes, showCardBuy, showCardPage, showCardPrice, showCardFinishes, imageSizes, }: PlpCardProps): import("react").JSX.Element;
@@ -1 +1 @@
1
- "use client";import{jsx as t,Fragment as oe,jsxs as re}from"react/jsx-runtime";import{CARD_IMAGE_SIZES as te}from"../../lib/sections/card-image-sizes.js";import{LISTING_CARD_SHOW as p}from"../../lib/sections/card-show-defaults.js";import ne from"next/image";import{useState as se}from"react";import ae from"../BrandPlate.js";import{useCurrency as ie}from"../CurrencyContext.js";import le from"../FinishSwatches.js";import{wheelCardEyebrow as ce,wheelCardEyebrowShows as me}from"../ProductCardEyebrow.js";import{withRMark as h}from"efficient-web-builder/render/components/RMark";import de from"../WheelPlaceholder.js";import ue,{cardSpecFields as fe,WheelCardBadge as S,WheelCardCorners as pe}from"../WheelCardFrame.js";import{formatPrice as he}from"../../lib/commerce.js";import{CARD_IMAGE_BG_OFF as Se}from"efficient-web-builder/format/lib/content/card-image-background";import{itemBrand as be}from"../../lib/catalog/plp-item.js";import{CARD_INDEX_BADGE_CLASS as ge,CARD_INDEX_CLASS as Ce,DEFAULT_CARD_INDEX_FORMAT as _e,DEFAULT_CARD_OUTLINE as Ee}from"efficient-web-builder/format/lib/sections/product-card-style";import{applyCardAnswers as Ae}from"../../lib/content/field-usage.js";import{useWheelCardBottom as Ie}from"./useWheelCardBottom.js";import{setLabel as we}from"../../lib/wheels/variants.js";import{setBuildLabel as Fe,wheelCardPriceLine as Le,setIsWide as ye,setSecondSrc as Be,summarySetBuild as De}from"../../lib/wheels/set-mode.js";import{PLP_GRID_GAP_VAR as Pe}from"../../lib/wheels/plp-grid.js";import{FITMENT_FIELD_SEPARATOR as Re,wheelCardSpecFacts as ve}from"../../lib/wheels/plp-fitment-match.js";import{formatSelectionPrice as xe,formatSelectionWasPrice as Ne,resolveSelectionPrice as Te}from"../../lib/wheels/price-display.js";import{coverSrcForWheel as We,DEFAULT_COVER_INDEX as Ge,resolvePaintedSrc as $e}from"../../lib/wheels/cover-rendering.js";import{usePlpCardSelection as ke}from"./usePlpCardSelection.js";const Oe=[];function je({wheel:o,colours:B,fit:b=null,editing:D=!1,brandPlate:P=!1,kindLabel:g=null,showBrand:C=!0,showProcess:_=!1,coverIndex:R=Ge,fieldUsage:c=Oe,spinOnHover:v=!1,imageBackgroundFill:x=Se,showBadge:N=!0,outline:T=Ee,indexBadge:W=_e,showCardSizes:G=p.showCardSizes,showCardBuy:$=p.showCardBuy,showCardPage:k=p.showCardPage,showCardPrice:O=!0,showCardFinishes:E=!0,imageSizes:j=te}){const{currency:i}=ie(),e=ke(o,B),M=We(o,R,e.finish?.name,e.shownSrc,b?.holes),n=Te(o,e.selectedVariant,i,1),V=Ne(n,i),[A,z]=se(()=>new Set),X=r=>z(a=>a.has(r)?a:new Set(a).add(r)),m=$e({overrideSrc:M,hookSrc:e.shownSrc,failed:A}),d=be(o),I=Ie({wheel:o,sel:e,price:n,editing:D,show:{buy:$,page:k}}),Me=e.detailState==="ready",Ve=e.unsellable,H=v?"transition-transform duration-700 [transition-timing-function:cubic-bezier(.2,.6,.2,1)] group-hover:rotate-[72deg]":"",w=(r,a)=>t(ne,{src:r,alt:a,width:800,height:800,sizes:j,className:["block h-full w-full object-contain",H].filter(Boolean).join(" "),draggable:!1,onError:()=>X(r)},r),F=e.finish?`${o.name} — ${e.finish.name}`:o.name,U=m?w(m,F):t(de,{imageLabel:o.name}),L=De(o),s=ye(L),Z=Fe(L),u=s?Be(o.finishes?.find(r=>r.name===e.finish?.name),m):null,q=u&&!A.has(u)?w(u,`${F} — right`):void 0,y=W!=="off"?t("span",{"aria-hidden":!0,className:`${Ce} ${ge}`}):null,l=N?o.badge:null,f=s?Z:null,J=n.onSale||l||f||s?t(pe,{set:s,numbered:y!=null,right:[n.onSale?t(S,{tone:"solid",children:"Sale"}):null,f?t(S,{tone:"outline",children:f}):l?t(S,{tone:l==="new"?"solid":"outline",children:l==="new"?"New":"Bestseller"}):null]}):null,K=E&&e.finishes.length>0&&e.availability.some(Boolean)?t(le,{finishes:e.finishes,availability:e.availability,selectedIdx:e.selectedIdx,hoverIdx:e.hoverIdx,activeFinish:e.finish,onSelect:e.setSelectedIdx,onHover:e.setHoverIdx,showLabel:!1}):null,Q=Ae(ve(o,b,{sizes:G}),c).map(r=>r.text),Y=n.priced&&n.setTotal!=null&&e.selectedVariant?`${we(e.selectedVariant)} · ${he(n.setTotal,i)}`:null,ee=ce({kindLabel:g,brand:C&&d?h(d):null,process:_&&o.process?h(o.process):null},c);return re(oe,{children:[t(ue,{href:`/wheels/${o.slug}`,wide:s,setGridGap:`var(${Pe})`,identityLink:!0,containerProps:{onPointerEnter:e.arm,onTouchStart:e.arm,onFocusCapture:e.arm},probes:e.probes,outline:T,imageBackgroundFill:x,indexBadge:y,badges:J,image:U,imageSecond:q,plate:P?t(ae,{brand:d,logo:o.brandLogo}):null,eyebrow:ee,wholeCardLink:!0,reserveEyebrow:me({kind:!!g,brand:C,process:_},c),name:h(o.name),spec:fe(Q,Re),was:V,price:Le(xe(n,i),n.priced),metaLine:Y,swatches:K,reserveSwatches:E,showPrice:O,actions:I.actions}),I.dialog]})}export{je as default};
1
+ "use client";import{jsx as o,Fragment as $,jsxs as j}from"react/jsx-runtime";import{CARD_IMAGE_SIZES as M}from"../../lib/sections/card-image-sizes.js";import{LISTING_CARD_SHOW as P}from"../../lib/sections/card-show-defaults.js";import X from"next/image";import{useState as U}from"react";import H from"../BrandPlate.js";import V,{CardBuyDialog as Z}from"../card-pieces/CardBuyButton.js";import q from"../card-pieces/CardFinishSwatches.js";import J from"../card-pieces/CardPrice.js";import K from"../card-pieces/CardProductBadge.js";import{useWheelCardState as Q,WheelCardStateProvider as Y}from"../card-pieces/ProductCardState.js";import{wheelCardEyebrow as ee,wheelCardEyebrowShows as re}from"../ProductCardEyebrow.js";import{withRMark as I}from"efficient-web-builder/render/components/RMark";import oe from"../WheelPlaceholder.js";import ae,{cardSpecFields as te}from"../WheelCardFrame.js";import{CARD_IMAGE_BG_OFF as ne}from"efficient-web-builder/format/lib/content/card-image-background";import{itemBrand as se}from"../../lib/catalog/plp-item.js";import{CARD_INDEX_BADGE_CLASS as ie,CARD_INDEX_CLASS as le,DEFAULT_CARD_INDEX_FORMAT as de,DEFAULT_CARD_OUTLINE as me}from"efficient-web-builder/format/lib/sections/product-card-style";import{applyCardAnswers as ce}from"../../lib/content/field-usage.js";import{setSecondSrc as he}from"../../lib/wheels/set-mode.js";import{PLP_GRID_GAP_VAR as ue}from"../../lib/wheels/plp-grid.js";import{FITMENT_FIELD_SEPARATOR as pe,wheelCardSpecFacts as fe}from"../../lib/wheels/plp-fitment-match.js";import{coverSrcForWheel as we,DEFAULT_COVER_INDEX as Se,resolvePaintedSrc as Ce}from"../../lib/wheels/cover-rendering.js";const ge=[];function _e({wheel:s,colours:c,fit:i=null,editing:l=!1,brandPlate:d=!1,kindLabel:h=null,showBrand:t=!0,showProcess:u=!1,coverIndex:p=Se,fieldUsage:f=ge,spinOnHover:w=!1,imageBackgroundFill:S=ne,showBadge:C=!0,outline:g=me,indexBadge:_=de,showCardSizes:E=P.showCardSizes,showCardBuy:b=P.showCardBuy,showCardPage:A=P.showCardPage,showCardPrice:e=!0,showCardFinishes:r=!0,imageSizes:m=M}){return o(Y,{wheel:s,colours:c,editing:l,children:o(Ee,{fit:i,brandPlate:d,kindLabel:h,showBrand:t,showProcess:u,coverIndex:p,fieldUsage:f,spinOnHover:w,imageBackgroundFill:S,showBadge:C,outline:g,indexBadge:_,showCardSizes:E,showCardBuy:b,showCardPage:A,showCardPrice:e,showCardFinishes:r,imageSizes:m})})}function Ee({fit:s,brandPlate:c,kindLabel:i,showBrand:l,showProcess:d,coverIndex:h,fieldUsage:t,spinOnHover:u,imageBackgroundFill:p,showBadge:f,outline:w,indexBadge:S,showCardSizes:C,showCardBuy:g,showCardPage:_,showCardPrice:E,showCardFinishes:b,imageSizes:A}){const{wheel:e,sel:r,isSet:m}=Q(),T=we(e,h,r.finish?.name,r.shownSrc,s?.holes),[R,x]=U(()=>new Set),k=a=>x(n=>n.has(a)?n:new Set(n).add(a)),F=Ce({overrideSrc:T,hookSrc:r.shownSrc,failed:R}),B=se(e),G=u?"transition-transform duration-700 [transition-timing-function:cubic-bezier(.2,.6,.2,1)] group-hover:rotate-[72deg]":"",y=(a,n)=>o(X,{src:a,alt:n,width:800,height:800,sizes:A,className:["block h-full w-full object-contain",G].filter(Boolean).join(" "),draggable:!1,onError:()=>k(a)},a),L=r.finish?`${e.name} — ${r.finish.name}`:e.name,O=F?y(F,L):o(oe,{imageLabel:e.name}),D=m?he(e.finishes?.find(a=>a.name===r.finish?.name),F):null,v=D&&!R.has(D)?y(D,`${L} — right`):void 0,N=S!=="off"?o("span",{"aria-hidden":!0,className:`${le} ${ie}`}):null,z=ce(fe(e,s,{sizes:C}),t).map(a=>a.text),W=ee({kindLabel:i,brand:l&&B?I(B):null,process:d&&e.process?I(e.process):null},t);return j($,{children:[o(ae,{href:`/wheels/${e.slug}`,wide:m,setGridGap:`var(${ue})`,identityLink:!0,containerProps:{onPointerEnter:r.arm,onTouchStart:r.arm,onFocusCapture:r.arm},probes:r.probes,outline:w,imageBackgroundFill:p,indexBadge:N,badges:o(K,{show:f,numbered:N!=null,sale:!0}),image:O,imageSecond:v,plate:c?o(H,{brand:B,logo:e.brandLogo}):null,eyebrow:W,wholeCardLink:!0,reserveEyebrow:re({kind:!!i,brand:l,process:d},t),name:I(e.name),spec:te(z,pe),price:o(J,{show:E,setTotal:!0,wasFollowsSize:!0}),swatches:o(q,{show:b,showSingle:!0}),buy:o(V,{buy:g,page:_})}),o(Z,{})]})}export{_e as default};
@@ -15,4 +15,4 @@ export interface PlpCardSelection extends FinishSelection {
15
15
  canAdd: boolean;
16
16
  unsellable: boolean;
17
17
  }
18
- export declare function usePlpCardSelection(wheel: WheelSummary, colours?: readonly string[]): PlpCardSelection;
18
+ export declare function usePlpCardSelection(wheel: WheelSummary, colours?: readonly string[], defaultFinish?: string): PlpCardSelection;
@@ -1 +1 @@
1
- "use client";import{useCallback as z,useEffect as p,useMemo as c,useRef as F,useState as V}from"react";import{useFinishSelection as j}from"../useFinishSelection.js";import{useWheelDetail as B}from"../useWheelDetail.js";import{firstFinishInFamilies as E}from"../../lib/wheels/finish-colour-match.js";import{isRenderableFinish as L}from"../../lib/wheels/renderable-finishes.js";import{variantsForFinish as v}from"../../lib/wheels/variant-spec.js";import{findVariant as M,firstSellableFinishIndex as P,isOneWheelDesign as U,isVariantOutOfStock as _,outOfStockVariantsForFinish as q}from"../../lib/wheels/variants.js";const G=[];function $(s,a=G){const i=c(()=>s.finishes.filter(L),[s.finishes]),u=i.length>0,r=j(i,s.coverImage??null,s.defaultFinish??void 0),[C,R]=V(!1),W=z(()=>{u&&R(!0)},[u]),{state:f,wheel:O}=B(s.slug,C),t=c(()=>O?.variants??[],[O]),n=r.selectedIdx>=0?i[r.selectedIdx]?.name??null:null,[g,x]=V(null),{setSelectedIdx:o}=r,d=F(!1),A=z(e=>{d.current=!0,o(e)},[o]),m=a.join(","),I=F(null);p(()=>{if(I.current===m)return;I.current=m;const e=E(i,a);e<0||(d.current=!0,o(e))},[m,a,i,o]);const b=F(!1);p(()=>{if(b.current||d.current||t.length===0||!n||(b.current=!0,v(t,n).length>0))return;const e=P(t,i.map(S=>S.name),r.availability);e>=0&&o(e)},[t,n,i,r.availability,o]);const l=c(()=>v(t,n),[t,n]),k=U(s);p(()=>{x(e=>e&&l.some(S=>S.size===e)?e:k&&l.length===1?l[0].size:null)},[l,k]);const h=M(t,n,g),y=_(h),D=h!=null&&!y,K=!u||f==="error"||f==="ready"&&l.length===0,N=c(()=>q(t,n),[t,n]);return{...r,setSelectedIdx:A,finishes:i,arm:W,detailState:f,confirmedFinishName:n,sizeOptions:l,size:g,setSize:x,selectedVariant:h,outOfStock:y,outOfStockVariants:N,canAdd:D,unsellable:K}}export{$ as usePlpCardSelection};
1
+ "use client";import{useCallback as z,useEffect as p,useMemo as c,useRef as F,useState as V}from"react";import{useFinishSelection as B}from"../useFinishSelection.js";import{useWheelDetail as E}from"../useWheelDetail.js";import{firstFinishInFamilies as L}from"../../lib/wheels/finish-colour-match.js";import{isRenderableFinish as M}from"../../lib/wheels/renderable-finishes.js";import{variantsForFinish as v}from"../../lib/wheels/variant-spec.js";import{findVariant as P,firstSellableFinishIndex as U,isOneWheelDesign as _,isVariantOutOfStock as q,outOfStockVariantsForFinish as G}from"../../lib/wheels/variants.js";const H=[];function w(s,a=H,C){const i=c(()=>s.finishes.filter(M),[s.finishes]),u=i.length>0,r=B(i,s.coverImage??null,C??s.defaultFinish??void 0),[R,W]=V(!1),A=z(()=>{u&&W(!0)},[u]),{state:f,wheel:O}=E(s.slug,R),t=c(()=>O?.variants??[],[O]),n=r.selectedIdx>=0?i[r.selectedIdx]?.name??null:null,[g,x]=V(null),{setSelectedIdx:o}=r,d=F(!1),D=z(e=>{d.current=!0,o(e)},[o]),m=a.join(","),I=F(null);p(()=>{if(I.current===m)return;I.current=m;const e=L(i,a);e<0||(d.current=!0,o(e))},[m,a,i,o]);const b=F(!1);p(()=>{if(b.current||d.current||t.length===0||!n||(b.current=!0,v(t,n).length>0))return;const e=U(t,i.map(S=>S.name),r.availability);e>=0&&o(e)},[t,n,i,r.availability,o]);const l=c(()=>v(t,n),[t,n]),k=_(s);p(()=>{x(e=>e&&l.some(S=>S.size===e)?e:k&&l.length===1?l[0].size:null)},[l,k]);const h=P(t,n,g),y=q(h),K=h!=null&&!y,N=!u||f==="error"||f==="ready"&&l.length===0,j=c(()=>G(t,n),[t,n]);return{...r,setSelectedIdx:D,finishes:i,arm:A,detailState:f,confirmedFinishName:n,sizeOptions:l,size:g,setSize:x,selectedVariant:h,outOfStock:y,outOfStockVariants:j,canAdd:K,unsellable:N}}export{w as usePlpCardSelection};
@@ -199,7 +199,7 @@ export type Brand = {
199
199
  client_name: string;
200
200
  design_count: number;
201
201
  };
202
- import type { components } from "./types.js";
202
+ import type { components, operations } from "./types.js";
203
203
  export declare function resolveMediaUrls<T>(value: T): T;
204
204
  export type Process = components["schemas"]["Process"];
205
205
  export type FinishFamily = components["schemas"]["FinishFamily"];
@@ -237,6 +237,7 @@ export type TyreFitVariant = components["schemas"]["TyreFitVariant"];
237
237
  export type TyreFitVehicle = components["schemas"]["TyreFitVehicle"];
238
238
  export type Site = components["schemas"]["Site"];
239
239
  export type PageStub = components["schemas"]["PageStub"];
240
+ export type PopupStub = components["schemas"]["PopupStub"];
240
241
  export type Page = components["schemas"]["Page"];
241
242
  export type ProductTemplateStub = components["schemas"]["ProductTemplateStub"];
242
243
  export type DynamicPageStub = components["schemas"]["DynamicPageStub"];
@@ -339,6 +340,7 @@ export declare const products: {
339
340
  getSite: () => Promise<Site>;
340
341
  getSiteBySlug: (slug: string) => Promise<Site>;
341
342
  listPages: () => Promise<PageStub[]>;
343
+ listPopups: () => Promise<PopupStub[]>;
342
344
  listProductTemplates: () => Promise<ProductTemplateStub[]>;
343
345
  listDynamicPages: (recordType?: string) => Promise<DynamicPageStub[]>;
344
346
  getRecord: (type: string, key: string) => Promise<PublicRecord | null>;
@@ -349,7 +351,7 @@ export declare const products: {
349
351
  revalidate?: number;
350
352
  record?: string;
351
353
  }) => Promise<Page>;
352
- listBlogPosts: () => Promise<BlogPostSummary[]>;
354
+ listBlogPosts: (opts?: NonNullable<operations["listBlogPosts"]["parameters"]["query"]>) => Promise<BlogPostSummary[]>;
353
355
  getBlogPost: (slug: string) => Promise<BlogPostDetail>;
354
356
  createOrder: (body: OrderRequest) => Promise<OrderConfirmation>;
355
357
  createOrderAuthed: (body: OrderRequest) => Promise<OrderConfirmation>;
@@ -1 +1 @@
1
- import{PREVIEW_TOKEN_HEADER as Y,SITE_HOST_HEADER as tt,SITE_SLUG_HEADER as et}from"../site-headers.js";import{PRODUCT_API_BASE as rt,PRODUCT_BACKEND_URL as k}from"./origins.js";import{backendHopHeaders as at,clientIpFromForwardedFor as st,FORWARDED_FOR_HEADER as nt,hopCachingOf as ot}from"../forwarded-for.js";import it from"efficient-web-builder/format/lib/puck/media-manifest.json";import{auth as P}from"../auth.js";import{efficientClientOpen as ct}from"efficient-easel/screen/lib/session";import{listableWheelSummaries as J}from"../wheels/listable-wheels.js";import{dropRenderlessFinishes as L}from"../wheels/renderable-finishes.js";const dt=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 _="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.",ut=new Set([502,503,504]),N=0,lt="This editor runs on its host's own backend, which does not serve this request.",pt=5e3,yt=15e3,ht=()=>typeof window>"u"?pt:yt;function D(t){const e=(t.method??"GET").toUpperCase();if(!(t.body!=null||e!=="GET"&&e!=="HEAD")&&!(t.audience!=null&&t.audience!=="shop")&&typeof AbortSignal?.timeout=="function")return AbortSignal.timeout(ht())}const x=t=>t instanceof Error&&t.name==="TimeoutError",H=(t,e)=>ut.has(t)?_:e,ft=["admin","venue"];let F="admin";function ae(t){F=ft.includes(t)?t:"admin"}function gt(){return F}const mt=/^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{1,8})*$/;let M=null;function se(t){M=t&&mt.test(t)?t:null}function wt(){return M}function St(t){if(typeof window>"u"||!t.startsWith("/api/v1/"))return t;const e=j();return!e||/[?&]site=/.test(t)?t:C(t,`site=${encodeURIComponent(e)}`)}async function i(t,e={}){const{token:s,baseUrl:o,headers:l,audience:p,...w}=e;if(typeof window<"u"&&!ct())throw new m(N,lt,null);if(typeof window>"u"&&o===void 0)throw new Error(`apiFetch(${JSON.stringify(t)}) ran on the server without an explicit baseUrl. The API_URL default it would inherit is browser-only (the prod image bakes NEXT_PUBLIC_API_URL="" for same-origin use, which a Node fetch cannot resolve). Pass a base explicitly: \`await backendOpts()\` (or baseUrl: PRODUCT_FETCH_BASE) for product reads, or the server-only PRODUCT_BACKEND_URL env for other backend surfaces.`);const a=typeof FormData<"u"&&w.body instanceof FormData;let r;try{r=await fetch(`${o??dt}${St(t)}`,{...w,headers:{...a?{}:{"Content-Type":"application/json"},...s?{Authorization:`Bearer ${s}`}:{},...p===null?{}:{"X-Portal-Audience":p??"shop"},...l},signal:w.signal??D({...w,audience:p})})}catch(y){throw y instanceof TypeError||x(y)?new m(N,_,null):y}let n;try{n=await r.text()}catch(y){throw x(y)?new m(N,_,null):y}let c=null;if(n)try{c=JSON.parse(n)}catch{throw new m(r.status,r.ok?"Expected JSON but received a non-JSON response":H(r.status,r.statusText),n)}if(!r.ok){const y=(c&&typeof c=="object"&&"detail"in c&&typeof c.detail=="string"?c.detail:null)??H(r.status,r.statusText);throw new m(r.status,y,c)}return c}let b=null;async function B(){return b||(b=Pt().finally(()=>{b=null}),b)}async function Pt(){const t=P.takeLegacyRefresh(),e=await Ot.refresh(t??void 0);return P.setTokens(e.access),e.access}async function q(){return P.getAccess()??B()}async function h(t,e={}){let s;try{s=await q()}catch{throw P.clear(),new m(401,"Not signed in",null)}try{return await i(t,{...e,token:s})}catch(o){if(!(o instanceof m)||o.status!==401)throw o;try{const l=await B();return await i(t,{...e,token:l})}catch{throw P.clear(),o}}}async function G(t,e={}){if(P.getAccess())try{return{data:await h(t,e),asShopper:!0}}catch(s){if(!(s instanceof m)||s.status!==401)throw s}return{data:await i(t,e),asShopper:!1}}async function W(){const t=await h("/api/auth/me/");if(t.portal!=="shop")throw P.clear(),new m(403,"This session is not valid for this shop.",null);return t}const Ot={login:(t,e)=>i("/api/auth/login/",{method:"POST",body:JSON.stringify({email:t,password:e,portal:"shop"}),credentials:"include"}),refresh:t=>i("/api/auth/refresh/",{method:"POST",body:JSON.stringify(t?{refresh:t,portal:"shop"}:{portal:"shop"}),credentials:"include"}),logout:async()=>{P.clear();try{await i("/api/auth/logout/",{method:"POST",body:JSON.stringify({portal:"shop"}),credentials:"include"})}catch{}},restoreSession:async()=>{const t=await q();return await W(),t},me:W,updateMe:t=>h("/api/auth/me/",{method:"PATCH",body:JSON.stringify(t)}),changePassword:(t,e)=>h("/api/auth/me/",{method:"PATCH",body:JSON.stringify({password:e,old_password:t})}),changeEmail:(t,e)=>h("/api/shop-portal/change-email/",{method:"POST",body:JSON.stringify({new_email:t,current_password:e})}),myProfile:()=>h("/api/shop-portal/profile/"),updateMyProfile:t=>h("/api/shop-portal/profile/",{method:"PATCH",body:JSON.stringify(t)}),myAddresses:()=>h("/api/shop-portal/delivery-locations/"),createAddress:t=>h("/api/shop-portal/delivery-locations/",{method:"POST",body:JSON.stringify(t)}),updateAddress:(t,e)=>h(`/api/shop-portal/delivery-locations/${t}/`,{method:"PATCH",body:JSON.stringify(e)}),deleteAddress:t=>h(`/api/shop-portal/delivery-locations/${t}/`,{method:"DELETE"}),passwordResetRequest:t=>i("/api/auth/password-reset/",{method:"POST",body:JSON.stringify({email:t})}),passwordResetConfirm:(t,e,s)=>i("/api/auth/password-reset/confirm/",{method:"POST",body:JSON.stringify({uid:t,token:e,new_password:s})}),brands:()=>h("/api/products/brands/"),myOrders:()=>h("/api/shop-portal/orders/").then(t=>t.results),myOrder:t=>h(`/api/shop-portal/orders/${t}/`),cancelOrder:t=>h(`/api/shop-portal/orders/${t}/cancel/`,{method:"POST"}),myReturns:t=>h(`/api/shop-portal/returns/${t?`?order=${encodeURIComponent(t)}`:""}`).then(e=>e.results),createReturn:t=>h("/api/shop-portal/returns/",{method:"POST",body:JSON.stringify(t)}),withdrawReturn:t=>h(`/api/shop-portal/returns/${t}/cancel/`,{method:"POST"}),uploadReturnPhoto:(t,e)=>{const s=new FormData;return s.append("claim_item",t),s.append("file",e),s.append("media_type",e.type.startsWith("video/")?"video":"image"),h("/api/shop-portal/return-media/",{method:"POST",body:s})}};import{media as bt,absolutizeApiUrl as v}from"efficient-web-builder/render/lib/media";import{analyzeLogoSvg as Tt,isSvgUrl as At}from"efficient-web-builder/format/lib/logo/reverse-svg";import{getEditorSiteId as Rt}from"efficient-web-builder/render/lib/editor-site";import{shopRouteBase as Et,webRuntimeSiteSlug as j}from"efficient-web-builder/format/lib/web-runtime";function g(t){if(typeof t=="string")return t.startsWith("/media/")?bt(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 ge}from"./origins.js";const z=typeof window>"u"&&k!=="",Ct=z?k:rt,$t=Et,O=()=>({baseUrl:$t(),audience:null});function d(t,e){const s=e?`?process=${encodeURIComponent(e)}`:"";return`/api/v1${t}${s}`}const Ut=100,K=50;function V(t,e,s){const o=new URLSearchParams;for(const[l,p]of Object.entries(e))p!=null&&p!==""&&o.set(l,String(p));return o.set("pageSize",String(Ut)),s&&o.set("cursor",s),`/api/v1${t}?${o.toString()}`}function _t(t,e){return V("/wheels",{process:t},e)}function Nt(t,e,s){return V("/products",{kind:t.join(","),make:e?.make,model:e?.model,year:e?.year,modification:e?.modification},s)}function vt(t){if(!t)return null;try{return new URL(t,"http://cursor.invalid").searchParams.get("cursor")}catch{return null}}async function X(t,e,s=()=>!1){const o=[];let l=null;try{for(let p=0;p<K;p++){const w=await i(await e(l),await u());if(o.push(...w.results),l=vt(w.next),!l)break}l&&console.warn(`[${t}] stopped at ${K} pages (${o.length} rows); catalog may be truncated`)}catch(p){if(s(p))throw p;console.warn(`[${t}] product API unavailable, returning []`,p)}return o}const It=t=>t instanceof m&&t.status===400;function kt(t){return t.flatMap(e=>e.kind==="alloy-wheel"?J([e]):[e])}async function Z(){return(await Jt()).host}async function Jt(){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(tt)??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 Lt(){try{const{headers:t}=await import("next/headers");return st((await t()).get(nt))}catch{return null}}async function Dt(){try{const{headers:t}=await import("next/headers");return(await t()).get(et)||null}catch{return null}}async function xt(){const t=await Dt();if(t)return`site=${encodeURIComponent(t)}`;const e=await Z();return e?`host=${encodeURIComponent(e)}`:""}async function f(t){if(typeof window<"u"){const e=j();return e?C(t,`site=${encodeURIComponent(e)}`):t}return C(t,await xt())}function C(t,e){return e?`${t}${t.includes("?")?"&":"?"}${e}`:t}const Ht="preview";async function Ft(){if(typeof window<"u")return null;try{const{headers:t}=await import("next/headers");return(await t()).get(Y)}catch{return null}}async function Mt(){try{const{headers:t}=await import("next/headers");return(await t()).get("user-agent")}catch{return null}}async function I(t,e){const s=await Ft();if(s===null)return[await f(t),await u(e)];const o=C(await f(t),`${Ht}=${encodeURIComponent(s)}`),{next:l,cache:p,...w}=e??{},a=await u({...w,cache:"no-store"}),r=await Mt();return r&&(a.headers={...a.headers,"user-agent":r}),[o,a]}async function Bt(t){if(!z)return;const[e,s]=await Promise.all([Z(),Lt()]),o=at(e,s,t);return Object.keys(o).length>0?o:void 0}async function u(t){const e=await Bt(ot(t)),s={baseUrl:Ct,...t};return e&&(s.headers={...e,...t?.headers}),s}const T=typeof window>"u";function A(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 de={listMakes:async t=>{if(T){const{fitmentData:s}=await import("./fitment-data.js");return s.makes(t)}return(await i(A("/makes",{region:t}),O())).results},listModels:async(t,e)=>{if(T){const{fitmentData:o}=await import("./fitment-data.js");return o.models(t,e)}return(await i(A("/models",{make:t,region:e}),O())).results},listYears:async(t,e,s)=>{if(T){const{fitmentData:l}=await import("./fitment-data.js");return l.years(t,e,s)}return(await i(A("/years",{make:t,model:e,region:s}),O())).results},listModifications:async(t,e,s,o)=>{if(T){const{fitmentData:p}=await import("./fitment-data.js");return p.modifications(t,e,s,o)}return(await i(A("/modifications",{make:t,model:e,year:s,region:o}),O())).results},getStockFitment:async(t,e,s,o,l)=>{if(T){const{fitmentData:p}=await import("./fitment-data.js");return p.stockFitment(t,e,s,o,l)}return i(A("/stock-fitment",{make:t,model:e,year:s,modification:o,region:l}),O())}},ue={listWheels:async t=>{const e=await X("products.listWheels",async s=>await f(_t(t,s)));return J(g(e))},listCatalog:async(t,e)=>{if(t.length===0)throw new Error("products.listCatalog() needs at least one kind. An empty list would omit `kind`, which the contract reads as `alloy-wheel` — so the call would silently return the wheel catalog instead of nothing.");const s=await X("products.listCatalog",async o=>await f(Nt(t,e,o)),It);return kt(g(s))},getWheel:async t=>L(g(await i(await f(d(`/wheels/${t}`)),await u()))),getTyre:async t=>g(await i(await f(d(`/tyres/${t}`)),await u())),listBundles:async()=>{try{return await i(await f(d("/bundles")),await u())}catch{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())),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 I(d(`/pages/${t}`)+s,e.revalidate!==void 0?{next:{revalidate:e.revalidate}}:void 0);return g(await i(o,l))},listBlogPosts:async()=>{try{return(await i(d("/blog-posts"),await u())).map(e=>({...e,coverImage:v(e.coverImage)??""}))}catch(t){return console.warn("[products.listBlogPosts] blog API unavailable, returning []",t),[]}},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 G(e,s)).data:i(e,s)},validateCoupon:async t=>{const{data:e,asShopper:s}=await G(d("/coupons/validate"),await u({method:"POST",body:JSON.stringify(t)}));return{...e,askedAsShopper:s}},getHeaderSettings:async()=>{const t=D({method:"GET"}),e=await i(...await I(d("/header-settings"),{signal:t})),s=v(e.logoUrl);let o=null,l=null;if(s&&At(s)){const p=await Tt(s,t);p&&(o=p.reversed,l=p.inkIsDark)}return{...e,logoUrl:s,logoReversed:o,logoInkIsDark:l}},getThemeSettings:async()=>i(...await I(d("/theme-settings"))),getChatSettings:async()=>i(await f(d("/chat-settings")),await u())},le={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 qt 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 $=(t,e,s)=>{const o=new URLSearchParams({...e?{site:e}:{},...s?{draft:"1"}:{}}).toString();return`/api/storefront/${t}/${o?`?${o}`:""}`},R=t=>`/api/storefront/sites/${encodeURIComponent(t)}/`,Gt=t=>`${R(t)}currencies/`,Wt="/api/storefront/media/ingest/";class jt 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 zt(){const t=Rt();if(!t)throw new jt;return`${Wt}?${new URLSearchParams({site:t})}`}const U={"X-Puck-Media-Manifest":it.contentHash},pe=Q({});function Q(t){return(e,s={})=>{const o=wt(),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??gt()})}}function Kt(t={}){const e=Q(t),s=t.siteDrafts===!0,o=a=>$("header-settings",a,s),l=a=>$("theme-settings",a,s),p=a=>$("chat-settings",a,s),w=a=>$("social-settings",a,s);return{findPageBySlug:async(a,r,n)=>{const c=new URLSearchParams({slug:a});n&&c.set("site",n);const y=await e(`/api/storefront/pages/?${c.toString()}`,{token:r}),S=Array.isArray(y)?y:y.results??[];if(!n&&S.length>1)throw new qt(a,S.length);return S[0]??null},getPageById:(a,r)=>e(`/api/storefront/pages/${a}/`,{token:r}),saveLayout:(a,r,n,c,y)=>e(`/api/storefront/pages/${a}/`,{method:"PATCH",body:JSON.stringify({layout:r,expected_updated_at:c,...y?{client_id:y}:{}}),token:n}),duplicatePage:(a,r,n)=>e(`/api/storefront/pages/${a}/duplicate/`,{method:"POST",body:JSON.stringify({title:r.title,slug:r.slug}),token:n}),geocode:(a,r,n)=>e(`/api/storefront/geocode/?${new URLSearchParams(n?{q:a,country:n}:{q:a})}`,{token:r}),createPagePreviewLink:(a,r)=>e(`/api/storefront/pages/${a}/preview-link/`,{method:"POST",token:r}),claimPageEditLock:(a,r,n,c=!1)=>e(`/api/storefront/pages/${a}/edit-lock/`,{method:"POST",body:JSON.stringify({client_id:n,takeover:c}),token:r}),releasePageEditLock:(a,r)=>e(`/api/storefront/pages/${a}/edit-lock/`,{method:"DELETE",token:r}),createTemplate:(a,r,n)=>e("/api/storefront/page-templates/",{method:"POST",body:JSON.stringify({name:a,layout:r}),headers:U,token:n}),getTemplate:(a,r)=>e(`/api/storefront/page-templates/${a}/`,{token:r}),saveTemplateLayout:(a,r,n)=>e(`/api/storefront/page-templates/${a}/`,{method:"PATCH",body:JSON.stringify({layout:r}),headers:U,token:n}),listTemplatePages:async(a,r)=>{const n=await e(`/api/storefront/template-pages/?template=${encodeURIComponent(a)}`,{token:r});return Array.isArray(n)?n:n.results??[]},findTemplatePageBySlug:async(a,r,n)=>{const c=await e(`/api/storefront/template-pages/?template=${encodeURIComponent(a)}&slug=${encodeURIComponent(r)}`,{token:n});return(Array.isArray(c)?c:c.results??[])[0]??null},createTemplatePage:(a,r,n)=>e("/api/storefront/template-pages/",{method:"POST",body:JSON.stringify({template:a,...r}),headers:U,token:n}),saveTemplatePageLayout:(a,r,n)=>e(`/api/storefront/template-pages/${a}/`,{method:"PATCH",body:JSON.stringify({layout:r}),headers:U,token:n}),deleteTemplatePage:(a,r,n)=>e(`/api/storefront/template-pages/${a}/`,{method:"DELETE",token:r,...n?.keepalive?{keepalive:!0}:{}}),listPages:async(a,r)=>{const n=new URLSearchParams({no_page:"true"});r&&n.set("site",r);const c=await e(`/api/storefront/pages/?${n.toString()}`,{token:a});return Array.isArray(c)?c:c.results??[]},createPage:(a,r,n,c)=>e("/api/storefront/pages/",{method:"POST",body:JSON.stringify({title:a,slug:r,layout:n}),token:c}),deletePage:(a,r)=>e(`/api/storefront/pages/${a}/`,{method:"DELETE",token:r}),getHeaderSettings:(a,r)=>e(o(r),{token:a}),listMenus:async(a,r)=>{const n=new URLSearchParams({no_page:"true"});r&&n.set("site",r);const c=await e(`/api/storefront/menus/?${n}`,{token:a});return Array.isArray(c)?c:c.results??[]},listBlogPosts:async(a,r={})=>{const n=new URLSearchParams({no_page:"true"});r.visibleOnly&&n.set("is_visible","true"),r.siteId&&n.set("site",r.siteId);const c=await e(`/api/storefront/blog-posts/?${n.toString()}`,{token:a});return Array.isArray(c)?c:c.results??[]},listFieldUsage:async(a,r)=>{const n=await e(`/api/storefront/field-usage/?site=${encodeURIComponent(r)}`,{token:a});return Array.isArray(n?.entries)?n.entries:[]},listCategories:async(a,r={})=>{const n=new URLSearchParams({no_page:"true"});r.visibleOnly&&n.set("is_visible","true"),r.siteId&&n.set("site",r.siteId);const c=await e(`/api/storefront/categories/?${n.toString()}`,{token:a});return[...Array.isArray(c)?c:c.results??[]].sort((S,E)=>S.sort_order-E.sort_order||S.name.localeCompare(E.name))},listForms:async(a,r={})=>{const n=new URLSearchParams({no_page:"true"});r.siteId&&n.set("site",r.siteId);const c=await e(`/api/storefront/forms/?${n.toString()}`,{token:a});return[...Array.isArray(c)?c:c.results??[]].sort((S,E)=>S.title.localeCompare(E.title))},listWheelSummaries:async(a,r={})=>{const n=new URLSearchParams;r.siteId&&n.set("site",r.siteId);const c=n.toString(),y=await e(`/api/storefront/wheel-curations/summaries/${c?`?${c}`:""}`,{token:a});return g(y)},listProducts:async(a,r={})=>{const n=new URLSearchParams;r.kinds?.length&&n.set("kind",r.kinds.join(",")),r.siteId&&n.set("site",r.siteId);const c=n.toString(),y=await e(`/api/storefront/products/${c?`?${c}`:""}`,{token:a});return g(y)},getWheelDetail:async(a,r,n={})=>{const c=new URLSearchParams({slug:r});return n.siteId&&c.set("site",n.siteId),L(g(await e(`/api/storefront/wheel-curations/detail/?${c.toString()}`,{token:a})))},updateHeaderSettings:(a,r,n)=>e(o(n),{method:"PATCH",body:JSON.stringify(a),token:r}),getSite:(a,r)=>e(R(a),{token:r}),listSites:async a=>{const r=await e("/api/storefront/sites/?no_page=true",{token:a});return Array.isArray(r)?r:r.results??[]},listSiteCurrencies:async(a,r)=>{const n=await e(Gt(a),{token:r});return Array.isArray(n)?n:[]},publishSite:(a,r)=>e(`${R(a)}publish/`,{method:"POST",token:r}),getSiteLiveState:(a,r)=>e(`${R(a)}live-state/`,{token:r}),updateSite:(a,r,n)=>e(R(a),{method:"PATCH",body:JSON.stringify(r),token:n}),getThemeSettings:(a,r)=>e(l(r),{token:a}),updateThemeSettings:(a,r,n)=>e(l(n),{method:"PATCH",body:JSON.stringify(a),token:r}),getChatSettings:(a,r)=>e(p(r),{token:a}),updateChatSettings:(a,r,n)=>e(p(n),{method:"PATCH",body:JSON.stringify(a),token:r}),getSocialSettings:(a,r)=>e(w(r),{token:a}),updateSocialSettings:(a,r,n)=>e(w(n),{method:"PATCH",body:JSON.stringify(a),token:r}),uploadHeaderLogo:(a,r,n)=>{const c=new FormData;return c.append("logo",a),e(o(n),{method:"PATCH",body:c,token:r})},clearHeaderLogo:(a,r)=>e(o(r),{method:"PATCH",body:JSON.stringify({logo:null}),token:a}),setHeaderLogoFromAsset:(a,r,n)=>e(o(n),{method:"PATCH",body:JSON.stringify({logo_asset_id:a}),token:r}),uploadMedia:async(a,r)=>{const n=new FormData;return n.append("file",a),e(zt(),{method:"POST",body:n,token:r})},listMedia:async(a,r)=>{const n=new URLSearchParams({no_page:"true"});r&&n.set("kind",r);const c=await e(`/api/storefront/media-assets/?${n.toString()}`,{token:a});return Array.isArray(c)?c:c.results??[]}}}const ye=Kt({siteDrafts:!0});export{dt as API_URL,qt as AmbiguousPageSlugError,m as ApiError,yt as BROWSER_READ_TIMEOUT_MS,lt as EFFICIENT_CLIENT_CLOSED_MESSAGE,jt as MediaUploadDestinationError,Ht as PREVIEW_PARAM,ge as PRODUCT_API_BASE,pt as SERVER_READ_TIMEOUT_MS,_ as SERVER_UNREACHABLE_MESSAGE,N as STATUS_NETWORK_ERROR,pe as adminFetch,Ot as api,i as apiFetch,C as appendSiteQuery,le as bookings,Kt as createStorefrontAdmin,D as defaultRequestDeadline,zt as editorMediaUploadPath,gt as editorPortalAudience,wt as editorRequestLanguage,de as fitment,ue as products,ht as readDeadlineMs,Lt as resolveClientIp,g as resolveMediaUrls,Ft as resolvePreviewToken,Z as resolveSiteHost,Jt as resolveSiteHostSource,Dt as resolveSiteSlug,se as setEditorLanguage,ae as setEditorPortalAudience,ye as storefrontAdmin};
1
+ import{PREVIEW_TOKEN_HEADER as Y,SITE_HOST_HEADER as tt,SITE_SLUG_HEADER as et}from"../site-headers.js";import{PRODUCT_API_BASE as rt,PRODUCT_BACKEND_URL as k}from"./origins.js";import{backendHopHeaders as at,clientIpFromForwardedFor as st,FORWARDED_FOR_HEADER as nt,hopCachingOf as ot}from"../forwarded-for.js";import it from"efficient-web-builder/format/lib/puck/media-manifest.json";import{auth as P}from"../auth.js";import{efficientClientOpen as ct}from"efficient-easel/screen/lib/session";import{listableWheelSummaries as J}from"../wheels/listable-wheels.js";import{dropRenderlessFinishes as L}from"../wheels/renderable-finishes.js";const dt=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 _="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.",ut=new Set([502,503,504]),N=0,lt="This editor runs on its host's own backend, which does not serve this request.",pt=5e3,yt=15e3,ht=()=>typeof window>"u"?pt:yt;function D(t){const e=(t.method??"GET").toUpperCase();if(!(t.body!=null||e!=="GET"&&e!=="HEAD")&&!(t.audience!=null&&t.audience!=="shop")&&typeof AbortSignal?.timeout=="function")return AbortSignal.timeout(ht())}const x=t=>t instanceof Error&&t.name==="TimeoutError",H=(t,e)=>ut.has(t)?_:e,ft=["admin","venue"];let F="admin";function ae(t){F=ft.includes(t)?t:"admin"}function gt(){return F}const mt=/^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{1,8})*$/;let M=null;function se(t){M=t&&mt.test(t)?t:null}function wt(){return M}function St(t){if(typeof window>"u"||!t.startsWith("/api/v1/"))return t;const e=j();return!e||/[?&]site=/.test(t)?t:C(t,`site=${encodeURIComponent(e)}`)}async function i(t,e={}){const{token:s,baseUrl:o,headers:l,audience:p,...w}=e;if(typeof window<"u"&&!ct())throw new m(N,lt,null);if(typeof window>"u"&&o===void 0)throw new Error(`apiFetch(${JSON.stringify(t)}) ran on the server without an explicit baseUrl. The API_URL default it would inherit is browser-only (the prod image bakes NEXT_PUBLIC_API_URL="" for same-origin use, which a Node fetch cannot resolve). Pass a base explicitly: \`await backendOpts()\` (or baseUrl: PRODUCT_FETCH_BASE) for product reads, or the server-only PRODUCT_BACKEND_URL env for other backend surfaces.`);const a=typeof FormData<"u"&&w.body instanceof FormData;let r;try{r=await fetch(`${o??dt}${St(t)}`,{...w,headers:{...a?{}:{"Content-Type":"application/json"},...s?{Authorization:`Bearer ${s}`}:{},...p===null?{}:{"X-Portal-Audience":p??"shop"},...l},signal:w.signal??D({...w,audience:p})})}catch(y){throw y instanceof TypeError||x(y)?new m(N,_,null):y}let n;try{n=await r.text()}catch(y){throw x(y)?new m(N,_,null):y}let c=null;if(n)try{c=JSON.parse(n)}catch{throw new m(r.status,r.ok?"Expected JSON but received a non-JSON response":H(r.status,r.statusText),n)}if(!r.ok){const y=(c&&typeof c=="object"&&"detail"in c&&typeof c.detail=="string"?c.detail:null)??H(r.status,r.statusText);throw new m(r.status,y,c)}return c}let b=null;async function q(){return b||(b=Pt().finally(()=>{b=null}),b)}async function Pt(){const t=P.takeLegacyRefresh(),e=await Ot.refresh(t??void 0);return P.setTokens(e.access),e.access}async function B(){return P.getAccess()??q()}async function h(t,e={}){let s;try{s=await B()}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 q();return await i(t,{...e,token:l})}catch{throw P.clear(),o}}}async function G(t,e={}){if(P.getAccess())try{return{data:await h(t,e),asShopper:!0}}catch(s){if(!(s instanceof m)||s.status!==401)throw s}return{data:await i(t,e),asShopper:!1}}async function W(){const t=await h("/api/auth/me/");if(t.portal!=="shop")throw P.clear(),new m(403,"This session is not valid for this shop.",null);return t}const Ot={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 B();return await W(),t},me:W,updateMe:t=>h("/api/auth/me/",{method:"PATCH",body:JSON.stringify(t)}),changePassword:(t,e)=>h("/api/auth/me/",{method:"PATCH",body:JSON.stringify({password:e,old_password:t})}),changeEmail:(t,e)=>h("/api/shop-portal/change-email/",{method:"POST",body:JSON.stringify({new_email:t,current_password:e})}),myProfile:()=>h("/api/shop-portal/profile/"),updateMyProfile:t=>h("/api/shop-portal/profile/",{method:"PATCH",body:JSON.stringify(t)}),myAddresses:()=>h("/api/shop-portal/delivery-locations/"),createAddress:t=>h("/api/shop-portal/delivery-locations/",{method:"POST",body:JSON.stringify(t)}),updateAddress:(t,e)=>h(`/api/shop-portal/delivery-locations/${t}/`,{method:"PATCH",body:JSON.stringify(e)}),deleteAddress:t=>h(`/api/shop-portal/delivery-locations/${t}/`,{method:"DELETE"}),passwordResetRequest:t=>i("/api/auth/password-reset/",{method:"POST",body:JSON.stringify({email:t})}),passwordResetConfirm:(t,e,s)=>i("/api/auth/password-reset/confirm/",{method:"POST",body:JSON.stringify({uid:t,token:e,new_password:s})}),brands:()=>h("/api/products/brands/"),myOrders:()=>h("/api/shop-portal/orders/").then(t=>t.results),myOrder:t=>h(`/api/shop-portal/orders/${t}/`),cancelOrder:t=>h(`/api/shop-portal/orders/${t}/cancel/`,{method:"POST"}),myReturns:t=>h(`/api/shop-portal/returns/${t?`?order=${encodeURIComponent(t)}`:""}`).then(e=>e.results),createReturn:t=>h("/api/shop-portal/returns/",{method:"POST",body:JSON.stringify(t)}),withdrawReturn:t=>h(`/api/shop-portal/returns/${t}/cancel/`,{method:"POST"}),uploadReturnPhoto:(t,e)=>{const s=new FormData;return s.append("claim_item",t),s.append("file",e),s.append("media_type",e.type.startsWith("video/")?"video":"image"),h("/api/shop-portal/return-media/",{method:"POST",body:s})}};import{media as bt,absolutizeApiUrl as v}from"efficient-web-builder/render/lib/media";import{analyzeLogoSvg as Tt,isSvgUrl as At}from"efficient-web-builder/format/lib/logo/reverse-svg";import{getEditorSiteId as Rt}from"efficient-web-builder/render/lib/editor-site";import{shopRouteBase as Et,webRuntimeSiteSlug as j}from"efficient-web-builder/format/lib/web-runtime";function g(t){if(typeof t=="string")return t.startsWith("/media/")?bt(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 ge}from"./origins.js";const z=typeof window>"u"&&k!=="",Ct=z?k:rt,$t=Et,O=()=>({baseUrl:$t(),audience:null});function d(t,e){const s=e?`?process=${encodeURIComponent(e)}`:"";return`/api/v1${t}${s}`}const Ut=100,K=50;function V(t,e,s){const o=new URLSearchParams;for(const[l,p]of Object.entries(e))p!=null&&p!==""&&o.set(l,String(p));return o.set("pageSize",String(Ut)),s&&o.set("cursor",s),`/api/v1${t}?${o.toString()}`}function _t(t,e){return V("/wheels",{process:t},e)}function Nt(t,e,s){return V("/products",{kind:t.join(","),make:e?.make,model:e?.model,year:e?.year,modification:e?.modification},s)}function vt(t){if(!t)return null;try{return new URL(t,"http://cursor.invalid").searchParams.get("cursor")}catch{return null}}async function X(t,e,s=()=>!1){const o=[];let l=null;try{for(let p=0;p<K;p++){const w=await i(await e(l),await u());if(o.push(...w.results),l=vt(w.next),!l)break}l&&console.warn(`[${t}] stopped at ${K} pages (${o.length} rows); catalog may be truncated`)}catch(p){if(s(p))throw p;console.warn(`[${t}] product API unavailable, returning []`,p)}return o}const It=t=>t instanceof m&&t.status===400;function kt(t){return t.flatMap(e=>e.kind==="alloy-wheel"?J([e]):[e])}async function Z(){return(await Jt()).host}async function Jt(){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(tt)??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 Lt(){try{const{headers:t}=await import("next/headers");return st((await t()).get(nt))}catch{return null}}async function Dt(){try{const{headers:t}=await import("next/headers");return(await t()).get(et)||null}catch{return null}}async function xt(){const t=await Dt();if(t)return`site=${encodeURIComponent(t)}`;const e=await Z();return e?`host=${encodeURIComponent(e)}`:""}async function f(t){if(typeof window<"u"){const e=j();return e?C(t,`site=${encodeURIComponent(e)}`):t}return C(t,await xt())}function C(t,e){return e?`${t}${t.includes("?")?"&":"?"}${e}`:t}const Ht="preview";async function Ft(){if(typeof window<"u")return null;try{const{headers:t}=await import("next/headers");return(await t()).get(Y)}catch{return null}}async function Mt(){try{const{headers:t}=await import("next/headers");return(await t()).get("user-agent")}catch{return null}}async function I(t,e){const s=await Ft();if(s===null)return[await f(t),await u(e)];const o=C(await f(t),`${Ht}=${encodeURIComponent(s)}`),{next:l,cache:p,...w}=e??{},a=await u({...w,cache:"no-store"}),r=await Mt();return r&&(a.headers={...a.headers,"user-agent":r}),[o,a]}async function qt(t){if(!z)return;const[e,s]=await Promise.all([Z(),Lt()]),o=at(e,s,t);return Object.keys(o).length>0?o:void 0}async function u(t){const e=await qt(ot(t)),s={baseUrl:Ct,...t};return e&&(s.headers={...e,...t?.headers}),s}const T=typeof window>"u";function A(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 de={listMakes:async t=>{if(T){const{fitmentData:s}=await import("./fitment-data.js");return s.makes(t)}return(await i(A("/makes",{region:t}),O())).results},listModels:async(t,e)=>{if(T){const{fitmentData:o}=await import("./fitment-data.js");return o.models(t,e)}return(await i(A("/models",{make:t,region:e}),O())).results},listYears:async(t,e,s)=>{if(T){const{fitmentData:l}=await import("./fitment-data.js");return l.years(t,e,s)}return(await i(A("/years",{make:t,model:e,region:s}),O())).results},listModifications:async(t,e,s,o)=>{if(T){const{fitmentData:p}=await import("./fitment-data.js");return p.modifications(t,e,s,o)}return(await i(A("/modifications",{make:t,model:e,year:s,region:o}),O())).results},getStockFitment:async(t,e,s,o,l)=>{if(T){const{fitmentData:p}=await import("./fitment-data.js");return p.stockFitment(t,e,s,o,l)}return i(A("/stock-fitment",{make:t,model:e,year:s,modification:o,region:l}),O())}},ue={listWheels:async t=>{const e=await X("products.listWheels",async s=>await f(_t(t,s)));return J(g(e))},listCatalog:async(t,e)=>{if(t.length===0)throw new Error("products.listCatalog() needs at least one kind. An empty list would omit `kind`, which the contract reads as `alloy-wheel` — so the call would silently return the wheel catalog instead of nothing.");const s=await X("products.listCatalog",async o=>await f(Nt(t,e,o)),It);return kt(g(s))},getWheel:async t=>L(g(await i(await f(d(`/wheels/${t}`)),await u()))),getTyre:async t=>g(await i(await f(d(`/tyres/${t}`)),await u())),listBundles:async()=>{try{return await i(await f(d("/bundles")),await u())}catch{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 I(d(`/pages/${t}`)+s,e.revalidate!==void 0?{next:{revalidate:e.revalidate}}:void 0);return g(await i(o,l))},listBlogPosts:async(t={})=>{const e=t.category?`?category=${encodeURIComponent(t.category)}`:"";try{return(await i(d("/blog-posts")+e,await u())).map(o=>({...o,coverImage:v(o.coverImage)??""}))}catch(s){return console.warn("[products.listBlogPosts] blog API unavailable, returning []",s),[]}},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 G(e,s)).data:i(e,s)},validateCoupon:async t=>{const{data:e,asShopper:s}=await G(d("/coupons/validate"),await u({method:"POST",body:JSON.stringify(t)}));return{...e,askedAsShopper:s}},getHeaderSettings:async()=>{const t=D({method:"GET"}),e=await i(...await I(d("/header-settings"),{signal:t})),s=v(e.logoUrl);let o=null,l=null;if(s&&At(s)){const p=await Tt(s,t);p&&(o=p.reversed,l=p.inkIsDark)}return{...e,logoUrl:s,logoReversed:o,logoInkIsDark:l}},getThemeSettings:async()=>i(...await I(d("/theme-settings"))),getChatSettings:async()=>i(await f(d("/chat-settings")),await u())},le={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 Bt 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 $=(t,e,s)=>{const o=new URLSearchParams({...e?{site:e}:{},...s?{draft:"1"}:{}}).toString();return`/api/storefront/${t}/${o?`?${o}`:""}`},R=t=>`/api/storefront/sites/${encodeURIComponent(t)}/`,Gt=t=>`${R(t)}currencies/`,Wt="/api/storefront/media/ingest/";class jt 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 zt(){const t=Rt();if(!t)throw new jt;return`${Wt}?${new URLSearchParams({site:t})}`}const U={"X-Puck-Media-Manifest":it.contentHash},pe=Q({});function Q(t){return(e,s={})=>{const o=wt(),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??gt()})}}function Kt(t={}){const e=Q(t),s=t.siteDrafts===!0,o=a=>$("header-settings",a,s),l=a=>$("theme-settings",a,s),p=a=>$("chat-settings",a,s),w=a=>$("social-settings",a,s);return{findPageBySlug:async(a,r,n)=>{const c=new URLSearchParams({slug:a});n&&c.set("site",n);const y=await e(`/api/storefront/pages/?${c.toString()}`,{token:r}),S=Array.isArray(y)?y:y.results??[];if(!n&&S.length>1)throw new Bt(a,S.length);return S[0]??null},getPageById:(a,r)=>e(`/api/storefront/pages/${a}/`,{token:r}),saveLayout:(a,r,n,c,y)=>e(`/api/storefront/pages/${a}/`,{method:"PATCH",body:JSON.stringify({layout:r,expected_updated_at:c,...y?{client_id:y}:{}}),token:n}),duplicatePage:(a,r,n)=>e(`/api/storefront/pages/${a}/duplicate/`,{method:"POST",body:JSON.stringify({title:r.title,slug:r.slug}),token:n}),geocode:(a,r,n)=>e(`/api/storefront/geocode/?${new URLSearchParams(n?{q:a,country:n}:{q:a})}`,{token:r}),createPagePreviewLink:(a,r)=>e(`/api/storefront/pages/${a}/preview-link/`,{method:"POST",token:r}),claimPageEditLock:(a,r,n,c=!1)=>e(`/api/storefront/pages/${a}/edit-lock/`,{method:"POST",body:JSON.stringify({client_id:n,takeover:c}),token:r}),releasePageEditLock:(a,r)=>e(`/api/storefront/pages/${a}/edit-lock/`,{method:"DELETE",token:r}),createTemplate:(a,r,n)=>e("/api/storefront/page-templates/",{method:"POST",body:JSON.stringify({name:a,layout:r}),headers:U,token:n}),getTemplate:(a,r)=>e(`/api/storefront/page-templates/${a}/`,{token:r}),saveTemplateLayout:(a,r,n)=>e(`/api/storefront/page-templates/${a}/`,{method:"PATCH",body:JSON.stringify({layout:r}),headers:U,token:n}),listTemplatePages:async(a,r)=>{const n=await e(`/api/storefront/template-pages/?template=${encodeURIComponent(a)}`,{token:r});return Array.isArray(n)?n:n.results??[]},findTemplatePageBySlug:async(a,r,n)=>{const c=await e(`/api/storefront/template-pages/?template=${encodeURIComponent(a)}&slug=${encodeURIComponent(r)}`,{token:n});return(Array.isArray(c)?c:c.results??[])[0]??null},createTemplatePage:(a,r,n)=>e("/api/storefront/template-pages/",{method:"POST",body:JSON.stringify({template:a,...r}),headers:U,token:n}),saveTemplatePageLayout:(a,r,n)=>e(`/api/storefront/template-pages/${a}/`,{method:"PATCH",body:JSON.stringify({layout:r}),headers:U,token:n}),deleteTemplatePage:(a,r,n)=>e(`/api/storefront/template-pages/${a}/`,{method:"DELETE",token:r,...n?.keepalive?{keepalive:!0}:{}}),listPages:async(a,r)=>{const n=new URLSearchParams({no_page:"true"});r&&n.set("site",r);const c=await e(`/api/storefront/pages/?${n.toString()}`,{token:a});return Array.isArray(c)?c:c.results??[]},createPage:(a,r,n,c)=>e("/api/storefront/pages/",{method:"POST",body:JSON.stringify({title:a,slug:r,layout:n}),token:c}),deletePage:(a,r)=>e(`/api/storefront/pages/${a}/`,{method:"DELETE",token:r}),getHeaderSettings:(a,r)=>e(o(r),{token:a}),listMenus:async(a,r)=>{const n=new URLSearchParams({no_page:"true"});r&&n.set("site",r);const c=await e(`/api/storefront/menus/?${n}`,{token:a});return Array.isArray(c)?c:c.results??[]},listBlogPosts:async(a,r={})=>{const n=new URLSearchParams({no_page:"true"});r.visibleOnly&&n.set("is_visible","true"),r.siteId&&n.set("site",r.siteId);const c=await e(`/api/storefront/blog-posts/?${n.toString()}`,{token:a});return Array.isArray(c)?c:c.results??[]},listFieldUsage:async(a,r)=>{const n=await e(`/api/storefront/field-usage/?site=${encodeURIComponent(r)}`,{token:a});return Array.isArray(n?.entries)?n.entries:[]},listCategories:async(a,r={})=>{const n=new URLSearchParams({no_page:"true"});r.visibleOnly&&n.set("is_visible","true"),r.siteId&&n.set("site",r.siteId);const c=await e(`/api/storefront/categories/?${n.toString()}`,{token:a});return[...Array.isArray(c)?c:c.results??[]].sort((S,E)=>S.sort_order-E.sort_order||S.name.localeCompare(E.name))},listForms:async(a,r={})=>{const n=new URLSearchParams({no_page:"true"});r.siteId&&n.set("site",r.siteId);const c=await e(`/api/storefront/forms/?${n.toString()}`,{token:a});return[...Array.isArray(c)?c:c.results??[]].sort((S,E)=>S.title.localeCompare(E.title))},listWheelSummaries:async(a,r={})=>{const n=new URLSearchParams;r.siteId&&n.set("site",r.siteId);const c=n.toString(),y=await e(`/api/storefront/wheel-curations/summaries/${c?`?${c}`:""}`,{token:a});return g(y)},listProducts:async(a,r={})=>{const n=new URLSearchParams;r.kinds?.length&&n.set("kind",r.kinds.join(",")),r.siteId&&n.set("site",r.siteId);const c=n.toString(),y=await e(`/api/storefront/products/${c?`?${c}`:""}`,{token:a});return g(y)},getWheelDetail:async(a,r,n={})=>{const c=new URLSearchParams({slug:r});return n.siteId&&c.set("site",n.siteId),L(g(await e(`/api/storefront/wheel-curations/detail/?${c.toString()}`,{token:a})))},updateHeaderSettings:(a,r,n)=>e(o(n),{method:"PATCH",body:JSON.stringify(a),token:r}),getSite:(a,r)=>e(R(a),{token:r}),listSites:async a=>{const r=await e("/api/storefront/sites/?no_page=true",{token:a});return Array.isArray(r)?r:r.results??[]},listSiteCurrencies:async(a,r)=>{const n=await e(Gt(a),{token:r});return Array.isArray(n)?n:[]},publishSite:(a,r)=>e(`${R(a)}publish/`,{method:"POST",token:r}),getSiteLiveState:(a,r)=>e(`${R(a)}live-state/`,{token:r}),updateSite:(a,r,n)=>e(R(a),{method:"PATCH",body:JSON.stringify(r),token:n}),getThemeSettings:(a,r)=>e(l(r),{token:a}),updateThemeSettings:(a,r,n)=>e(l(n),{method:"PATCH",body:JSON.stringify(a),token:r}),getChatSettings:(a,r)=>e(p(r),{token:a}),updateChatSettings:(a,r,n)=>e(p(n),{method:"PATCH",body:JSON.stringify(a),token:r}),getSocialSettings:(a,r)=>e(w(r),{token:a}),updateSocialSettings:(a,r,n)=>e(w(n),{method:"PATCH",body:JSON.stringify(a),token:r}),uploadHeaderLogo:(a,r,n)=>{const c=new FormData;return c.append("logo",a),e(o(n),{method:"PATCH",body:c,token:r})},clearHeaderLogo:(a,r)=>e(o(r),{method:"PATCH",body:JSON.stringify({logo:null}),token:a}),setHeaderLogoFromAsset:(a,r,n)=>e(o(n),{method:"PATCH",body:JSON.stringify({logo_asset_id:a}),token:r}),uploadMedia:async(a,r)=>{const n=new FormData;return n.append("file",a),e(zt(),{method:"POST",body:n,token:r})},listMedia:async(a,r)=>{const n=new URLSearchParams({no_page:"true"});r&&n.set("kind",r);const c=await e(`/api/storefront/media-assets/?${n.toString()}`,{token:a});return Array.isArray(c)?c:c.results??[]}}}const ye=Kt({siteDrafts:!0});export{dt as API_URL,Bt as AmbiguousPageSlugError,m as ApiError,yt as BROWSER_READ_TIMEOUT_MS,lt as EFFICIENT_CLIENT_CLOSED_MESSAGE,jt as MediaUploadDestinationError,Ht as PREVIEW_PARAM,ge as PRODUCT_API_BASE,pt as SERVER_READ_TIMEOUT_MS,_ as SERVER_UNREACHABLE_MESSAGE,N as STATUS_NETWORK_ERROR,pe as adminFetch,Ot as api,i as apiFetch,C as appendSiteQuery,le as bookings,Kt as createStorefrontAdmin,D as defaultRequestDeadline,zt as editorMediaUploadPath,gt as editorPortalAudience,wt as editorRequestLanguage,de as fitment,ue as products,ht as readDeadlineMs,Lt as resolveClientIp,g as resolveMediaUrls,Ft as resolvePreviewToken,Z as resolveSiteHost,Jt as resolveSiteHostSource,Dt as resolveSiteSlug,se as setEditorLanguage,ae as setEditorPortalAudience,ye as storefrontAdmin};
@@ -287,6 +287,22 @@ export interface paths {
287
287
  patch?: never;
288
288
  trace?: never;
289
289
  };
290
+ "/popups": {
291
+ parameters: {
292
+ query?: never;
293
+ header?: never;
294
+ path?: never;
295
+ cookie?: never;
296
+ };
297
+ get: operations["listPopups"];
298
+ put?: never;
299
+ post?: never;
300
+ delete?: never;
301
+ options?: never;
302
+ head?: never;
303
+ patch?: never;
304
+ trace?: never;
305
+ };
290
306
  "/dynamic-pages": {
291
307
  parameters: {
292
308
  query?: never;
@@ -1409,6 +1425,13 @@ export interface components {
1409
1425
  title: string;
1410
1426
  seoTitle: string;
1411
1427
  };
1428
+ PopupStub: {
1429
+ slug: string;
1430
+ title: string;
1431
+ settings: {
1432
+ [key: string]: unknown;
1433
+ };
1434
+ };
1412
1435
  Page: {
1413
1436
  slug: string;
1414
1437
  title: string;
@@ -2603,6 +2626,28 @@ export interface operations {
2603
2626
  };
2604
2627
  };
2605
2628
  };
2629
+ listPopups: {
2630
+ parameters: {
2631
+ query?: {
2632
+ site?: components["parameters"]["SiteSlug"];
2633
+ host?: components["parameters"]["SiteHost"];
2634
+ };
2635
+ header?: never;
2636
+ path?: never;
2637
+ cookie?: never;
2638
+ };
2639
+ requestBody?: never;
2640
+ responses: {
2641
+ 200: {
2642
+ headers: {
2643
+ [name: string]: unknown;
2644
+ };
2645
+ content: {
2646
+ "application/json": components["schemas"]["PopupStub"][];
2647
+ };
2648
+ };
2649
+ };
2650
+ };
2606
2651
  listDynamicPages: {
2607
2652
  parameters: {
2608
2653
  query?: {
@@ -2723,7 +2768,9 @@ export interface operations {
2723
2768
  };
2724
2769
  listBlogPosts: {
2725
2770
  parameters: {
2726
- query?: never;
2771
+ query?: {
2772
+ category?: string;
2773
+ };
2727
2774
  header?: never;
2728
2775
  path?: never;
2729
2776
  cookie?: never;
@@ -1,4 +1,4 @@
1
- export declare const CHROME_LOAD_NAMES: readonly ["footer", "subscribe", "cartDrawer", "consentBanner", "header", "site", "theme", "chat"];
1
+ export declare const CHROME_LOAD_NAMES: readonly ["footer", "subscribe", "cartDrawer", "consentBanner", "popups", "header", "site", "theme", "chat"];
2
2
  export type ChromeLoadName = (typeof CHROME_LOAD_NAMES)[number];
3
3
  export declare const CHROME_ABSENT_STATUS = 404;
4
4
  export type ChromeLoadOutcome = {
@@ -1 +1 @@
1
- import{ApiError as a}from"./api/index.js";const c=["footer","subscribe","cartDrawer","consentBanner","header","site","theme","chat"],i=404;function u(t){if(t instanceof a&&t.status===i)return{state:"absent"};const e=t instanceof a?t.status:-1,r=t instanceof Error?t.message:String(t);return{state:"failed",status:e,detail:r}}const f="[storefront:chrome-load-failed]";function d(t,e){console.error(`${f} ${t} status=${e.status} — serving fallback chrome`,e.detail)}async function h(t,e,r,s){try{const o=await e();return s?.(o)?{value:o,outcome:{state:"absent"}}:{value:o,outcome:{state:"ok"}}}catch(o){const n=u(o);return n.state==="failed"&&d(t,n),{value:r,outcome:n}}}const E=t=>({value:t,outcome:{state:"ok"}});function x(t){return c.filter(e=>t[e]?.state==="failed")}function l(t){return t.length>0?t.join(","):void 0}function O(t){const e=l(t);return e===void 0?{}:{"data-sf-chrome-failed":e}}function m(t){return t==="production"?"silent":"banner"}const _=m(process.env.NODE_ENV);export{i as CHROME_ABSENT_STATUS,f as CHROME_LOAD_FAILED_TOKEN,c as CHROME_LOAD_NAMES,_ as CHROME_SIGNAL_MODE,l as chromeFailedAttr,O as chromeFailedProps,x as chromeLoadFailures,E as chromeLoadOk,m as chromeSignalMode,u as classifyChromeLoadError,h as loadChrome,d as reportChromeLoadFailure};
1
+ import{ApiError as a}from"./api/index.js";const c=["footer","subscribe","cartDrawer","consentBanner","popups","header","site","theme","chat"],i=404;function u(t){if(t instanceof a&&t.status===i)return{state:"absent"};const e=t instanceof a?t.status:-1,r=t instanceof Error?t.message:String(t);return{state:"failed",status:e,detail:r}}const f="[storefront:chrome-load-failed]";function d(t,e){console.error(`${f} ${t} status=${e.status} — serving fallback chrome`,e.detail)}async function h(t,e,r,s){try{const o=await e();return s?.(o)?{value:o,outcome:{state:"absent"}}:{value:o,outcome:{state:"ok"}}}catch(o){const n=u(o);return n.state==="failed"&&d(t,n),{value:r,outcome:n}}}const E=t=>({value:t,outcome:{state:"ok"}});function x(t){return c.filter(e=>t[e]?.state==="failed")}function l(t){return t.length>0?t.join(","):void 0}function O(t){const e=l(t);return e===void 0?{}:{"data-sf-chrome-failed":e}}function p(t){return t==="production"?"silent":"banner"}const _=p(process.env.NODE_ENV);export{i as CHROME_ABSENT_STATUS,f as CHROME_LOAD_FAILED_TOKEN,c as CHROME_LOAD_NAMES,_ as CHROME_SIGNAL_MODE,l as chromeFailedAttr,O as chromeFailedProps,x as chromeLoadFailures,E as chromeLoadOk,p as chromeSignalMode,u as classifyChromeLoadError,h as loadChrome,d as reportChromeLoadFailure};
@@ -8,6 +8,7 @@ export interface ProductHeroContent {
8
8
  export declare const PRODUCT_HERO_BULLETS_PROP = "heroBullets";
9
9
  export declare const HERO_BULLET_SEPARATOR = "\u00B7";
10
10
  export declare const PRODUCT_HERO_DEFAULTS: ProductHeroContent;
11
+ export declare const HERO_BULLET_EXAMPLE: ProductHeroBullet;
11
12
  export declare function heroBulletLine(bullet: ProductHeroBullet): string;
12
13
  export declare function parseHeroBullet(line: string): ProductHeroBullet | null;
13
14
  export declare function resolveProductHeroContent(rootProps: Record<string, unknown> | undefined | null): ProductHeroContent;
@@ -1 +1 @@
1
- import{authoredString as i}from"efficient-web-builder/format/lib/content/authored-props";const o="heroBullets",n="·",a={bullets:[{label:"Free shipping",detail:"USA, UK, AUS"},{label:"Lifetime warranty",detail:"structural"}]};function c(t){return t.detail?`${t.label} ${n} ${t.detail}`:t.label}function s(t){const e=t.trim();if(!e)return null;const l=e.indexOf(n);return l<0?{label:e,detail:""}:{label:e.slice(0,l).trim(),detail:e.slice(l+n.length).trim()}}function p(t){const e=(t??{})[o];return Array.isArray(e)?{bullets:e.map(r=>s(typeof r=="string"?r:i(r?.text,""))).filter(r=>r!==null)}:a}export{n as HERO_BULLET_SEPARATOR,o as PRODUCT_HERO_BULLETS_PROP,a as PRODUCT_HERO_DEFAULTS,c as heroBulletLine,s as parseHeroBullet,p as resolveProductHeroContent};
1
+ import{authoredString as o}from"efficient-web-builder/format/lib/content/authored-props";const i="heroBullets",n="·",s={bullets:[]},c={label:"Free shipping",detail:"USA, UK, AUS"};function p(t){return t.detail?`${t.label} ${n} ${t.detail}`:t.label}function a(t){const e=t.trim();if(!e)return null;const l=e.indexOf(n);return l<0?{label:e,detail:""}:{label:e.slice(0,l).trim(),detail:e.slice(l+n.length).trim()}}function E(t){const e=(t??{})[i];return Array.isArray(e)?{bullets:e.map(r=>a(typeof r=="string"?r:o(r?.text,""))).filter(r=>r!==null)}:s}export{c as HERO_BULLET_EXAMPLE,n as HERO_BULLET_SEPARATOR,i as PRODUCT_HERO_BULLETS_PROP,s as PRODUCT_HERO_DEFAULTS,p as heroBulletLine,a as parseHeroBullet,E as resolveProductHeroContent};
@@ -0,0 +1,2 @@
1
+ export declare const HEADER_FIT_ATTR = "data-header-fit";
2
+ export declare function fitHeaderToRow(header: HTMLElement): boolean;
@@ -0,0 +1 @@
1
+ const i="data-header-fit",f=.5;function l(e){e.removeAttribute(i);const n=e.ownerDocument.defaultView;if(!n)return!1;let o=!1;for(const t of e.querySelectorAll("[data-header-band]")){if(n.getComputedStyle(t).display==="none")continue;const r=t.parentElement?.clientWidth??0,s=t.style.width;t.style.width="max-content";const d=t.offsetWidth;if(t.style.width=s,d>r+.5){o=!0;break}}return o&&e.setAttribute(i,"phone"),o}export{i as HEADER_FIT_ATTR,l as fitHeaderToRow};
@@ -0,0 +1,2 @@
1
+ import type { PopupStores } from "efficient-web-builder/format/lib/popup/rules";
2
+ export declare const POPUP_STORES: PopupStores;
@@ -0,0 +1 @@
1
+ import{safeLocalStorage as o,safeSessionStorage as s}from"efficient-web-builder/format/lib/safe-storage";const a={session:s,local:o};export{a as POPUP_STORES};
@@ -0,0 +1,2 @@
1
+ import type { BlockRender } from "efficient-web-builder/format/lib/puck/blocks/block-types";
2
+ export declare const EuTyreLabelBlockMeta: Omit<BlockRender, "render">;
@@ -0,0 +1 @@
1
+ const e={label:"EU Tyre Label"};export{e as EuTyreLabelBlockMeta};
@@ -0,0 +1,2 @@
1
+ import type { BlockRender } from "efficient-web-builder/format/lib/puck/blocks/block-types";
2
+ export declare const EuTyreLabelBlockRender: BlockRender;
@@ -0,0 +1 @@
1
+ import{jsx as r}from"react/jsx-runtime";import{DynamicEuTyreLabelBlock as o}from"../../../../../components/pdp-dynamic/DynamicEuTyreLabel.js";import{EuTyreLabelBlockMeta as i}from"./meta.js";const c={...i,render:e=>r(o,{editing:e.puck?.isEditing})};export{c as EuTyreLabelBlockRender};
@@ -0,0 +1,2 @@
1
+ import type { BlockRender } from "efficient-web-builder/format/lib/puck/blocks/block-types";
2
+ export declare const ProductGalleryMeta: Omit<BlockRender, "render">;
@@ -0,0 +1 @@
1
+ import{DEFAULT_HERO_GALLERY_MODE as e,DEFAULT_HERO_IMAGE_FIT as l}from"../../../../sections/hero-gallery.js";const o={label:"Product Gallery",defaultProps:{galleryMode:e,imageFit:l}};export{o as ProductGalleryMeta};
@@ -0,0 +1,2 @@
1
+ import type { BlockRender } from "efficient-web-builder/format/lib/puck/blocks/block-types";
2
+ export declare const ProductGalleryRender: BlockRender;
@@ -0,0 +1 @@
1
+ import{jsx as r}from"react/jsx-runtime";import o from"../../../../../components/pdp-dynamic/DynamicProductGallery.js";import{parseHeroGalleryMode as i,parseHeroImageFit as t}from"../../../../sections/hero-gallery.js";import{ProductGalleryMeta as a}from"./meta.js";const y={...a,render:e=>r(o,{editing:e.puck?.isEditing,galleryMode:i(e.galleryMode),imageFit:t(e.imageFit)})};export{y as ProductGalleryRender};
@@ -13,12 +13,14 @@ export declare const COMMERCE_METAS: {
13
13
  DeliveryOptions: Omit<BlockRender, "render">;
14
14
  DetailRows: Omit<BlockRender, "render">;
15
15
  EuTyreLabel: Omit<BlockRender, "render">;
16
+ EuTyreLabelBlock: Omit<BlockRender, "render">;
16
17
  FitmentFinder: Omit<BlockRender, "render">;
17
18
  FitmentTable: Omit<BlockRender, "render">;
18
19
  Gallery: Omit<BlockRender, "render">;
19
20
  GalleryB: Omit<BlockRender, "render">;
20
21
  GalleryItem: Omit<BlockRender, "render">;
21
22
  Header: Omit<BlockRender, "render">;
23
+ ProductGallery: Omit<BlockRender, "render">;
22
24
  ProductGrid: Omit<BlockRender, "render">;
23
25
  ProductHero: Omit<BlockRender, "render">;
24
26
  ProductRef: Omit<BlockRender, "render">;
@@ -1 +1 @@
1
- import{AccountBlockMeta as t}from"./AccountBlock/meta.js";import{AlloyWheelsListingMeta as e}from"./AlloyWheelsListing/meta.js";import{BundleOfferMeta as r}from"./BundleOffer/meta.js";import{CartBlockMeta as o}from"./CartBlock/meta.js";import{CatalogFilterBarMeta as m}from"./CatalogFilterBar/meta.js";import{CheckoutCTAMeta as i}from"./CheckoutCTA/meta.js";import{CollectionCardMeta as a}from"./CollectionCard/meta.js";import{CollectionsMeta as l}from"./Collections/meta.js";import{CompatibleTyresMeta as c}from"./CompatibleTyres/meta.js";import{CountrySwitchBlockMeta as p}from"./CountrySwitchBlock/meta.js";import{DeliveryOptionsMeta as f}from"./DeliveryOptions/meta.js";import{DetailRowsMeta as M}from"./DetailRows/meta.js";import{EuTyreLabelMeta as n}from"./EuTyreLabel/meta.js";import{FitmentFinderMeta as d}from"./FitmentFinder/meta.js";import{FitmentTableMeta as y}from"./FitmentTable/meta.js";import{GalleryBMeta as C}from"./GalleryB/meta.js";import{GalleryItemMeta as u}from"./GalleryItem/meta.js";import{GalleryMeta as s}from"./Gallery/meta.js";import{HeaderMeta as T}from"./Header/meta.js";import{ProductGridMeta as B}from"./ProductGrid/meta.js";import{ProductHeroMeta as h}from"./ProductHero/meta.js";import{ProductRefMeta as k}from"./ProductRef/meta.js";import{RelatedProductsMeta as S}from"./RelatedProducts/meta.js";import{SearchBlockMeta as F}from"./SearchBlock/meta.js";import{SpecTableMeta as b}from"./SpecTable/meta.js";import{ThemeSwitchBlockMeta as G}from"./ThemeSwitchBlock/meta.js";import{TyreFitmentMeta as P}from"./TyreFitment/meta.js";import{TyreSizesMeta as A}from"./TyreSizes/meta.js";const rt={AccountBlock:t,AlloyWheelsListing:e,BundleOffer:r,CartBlock:o,CatalogFilterBar:m,CheckoutCTA:i,CollectionCard:a,Collections:l,CompatibleTyres:c,CountrySwitchBlock:p,DeliveryOptions:f,DetailRows:M,EuTyreLabel:n,FitmentFinder:d,FitmentTable:y,Gallery:s,GalleryB:C,GalleryItem:u,Header:T,ProductGrid:B,ProductHero:h,ProductRef:k,RelatedProducts:S,SearchBlock:F,SpecTable:b,ThemeSwitchBlock:G,TyreFitment:P,TyreSizes:A};export{rt as COMMERCE_METAS};
1
+ import{AccountBlockMeta as t}from"./AccountBlock/meta.js";import{AlloyWheelsListingMeta as e}from"./AlloyWheelsListing/meta.js";import{BundleOfferMeta as r}from"./BundleOffer/meta.js";import{CartBlockMeta as o}from"./CartBlock/meta.js";import{CatalogFilterBarMeta as m}from"./CatalogFilterBar/meta.js";import{CheckoutCTAMeta as a}from"./CheckoutCTA/meta.js";import{CollectionCardMeta as i}from"./CollectionCard/meta.js";import{CollectionsMeta as l}from"./Collections/meta.js";import{CompatibleTyresMeta as c}from"./CompatibleTyres/meta.js";import{CountrySwitchBlockMeta as p}from"./CountrySwitchBlock/meta.js";import{DeliveryOptionsMeta as f}from"./DeliveryOptions/meta.js";import{DetailRowsMeta as M}from"./DetailRows/meta.js";import{EuTyreLabelMeta as y}from"./EuTyreLabel/meta.js";import{EuTyreLabelBlockMeta as n}from"./EuTyreLabelBlock/meta.js";import{FitmentFinderMeta as d}from"./FitmentFinder/meta.js";import{FitmentTableMeta as u}from"./FitmentTable/meta.js";import{GalleryBMeta as C}from"./GalleryB/meta.js";import{GalleryItemMeta as T}from"./GalleryItem/meta.js";import{GalleryMeta as B}from"./Gallery/meta.js";import{HeaderMeta as s}from"./Header/meta.js";import{ProductGalleryMeta as k}from"./ProductGallery/meta.js";import{ProductGridMeta as h}from"./ProductGrid/meta.js";import{ProductHeroMeta as S}from"./ProductHero/meta.js";import{ProductRefMeta as b}from"./ProductRef/meta.js";import{RelatedProductsMeta as F}from"./RelatedProducts/meta.js";import{SearchBlockMeta as G}from"./SearchBlock/meta.js";import{SpecTableMeta as P}from"./SpecTable/meta.js";import{ThemeSwitchBlockMeta as A}from"./ThemeSwitchBlock/meta.js";import{TyreFitmentMeta as E}from"./TyreFitment/meta.js";import{TyreSizesMeta as R}from"./TyreSizes/meta.js";const it={AccountBlock:t,AlloyWheelsListing:e,BundleOffer:r,CartBlock:o,CatalogFilterBar:m,CheckoutCTA:a,CollectionCard:i,Collections:l,CompatibleTyres:c,CountrySwitchBlock:p,DeliveryOptions:f,DetailRows:M,EuTyreLabel:y,EuTyreLabelBlock:n,FitmentFinder:d,FitmentTable:u,Gallery:B,GalleryB:C,GalleryItem:T,Header:s,ProductGallery:k,ProductGrid:h,ProductHero:S,ProductRef:b,RelatedProducts:F,SearchBlock:G,SpecTable:P,ThemeSwitchBlock:A,TyreFitment:E,TyreSizes:R};export{it as COMMERCE_METAS};
@@ -13,12 +13,14 @@ export declare const COMMERCE_RENDERS: {
13
13
  DeliveryOptions: BlockRender;
14
14
  DetailRows: BlockRender;
15
15
  EuTyreLabel: BlockRender;
16
+ EuTyreLabelBlock: BlockRender;
16
17
  FitmentFinder: BlockRender;
17
18
  FitmentTable: BlockRender;
18
19
  Gallery: BlockRender;
19
20
  GalleryB: BlockRender;
20
21
  GalleryItem: BlockRender;
21
22
  Header: BlockRender;
23
+ ProductGallery: BlockRender;
22
24
  ProductGrid: BlockRender;
23
25
  ProductHero: BlockRender;
24
26
  ProductRef: BlockRender;