1import{translateDiscountPricesResponse}from"./customer-discount-prices-translator.js";const selectors={priceOnSale:".price",discount:".price__sale .price-item--sale",original:".price__sale .price-item--regular",discountBadge:".customer-discount-prices-badge",productGrid:"#ProductGridContainer",predictiveSearchContainer:"[data-predictive-search]"},observedContainers=[selectors.productGrid,selectors.predictiveSearchContainer],classes={priceOnSale:"price--on-sale",customerDiscountMarker:"js-customer-discount-prices"},attributes={productVariantId:"bss-b2b-variant-id",originalPrice:"data-original-price",originalCompareAtPrice:"data-original-compare-at-price"},STORAGE_KEY_PREFIX="customerDiscountPrices_";class CustomerDiscountPrices{constructor(options={}){this.discountData=null,this.isProcessing=!1,this.options={debug:window.customerDiscountConfig?.debug??!1,apiUrl:window.customerDiscountConfig?.apiUrl||"/apps/pa-proxy/api/verify/discount",customerId:window.customerDiscountConfig?.customerId||null,translations:window.customerDiscountConfig?.translations||{},cacheTtlSeconds:window.customerDiscountConfig?.cacheTtlSeconds||300,customerStageToken:window.customerDiscountConfig?.customerStageToken||null},this.init()}init(){document.addEventListener("DOMContentLoaded",()=>{this.isCustomerLoggedIn()||this.clearCacheIfExists(),this.loadDiscountData(),observedContainers.forEach(selector=>this.observeContainer(selector))})}async generateCartToken(){let cart=null;try{if(cart=await(await fetch("/cart.js")).json(),cart.token&&cart.token.includes("?key=")&&cart.customer_id===this.options.customerId)return cart.token}catch(error){this.options.debug&&console.log("CustomerDiscountPrices: Error checking existing cart:",error)}try{const update=await fetch("/cart/update.js",{method:"POST",headers:{"X-Requested-With":"XMLHttpRequest","Content-Type":"application/json;"},body:JSON.stringify({attributes:{_token_generation:JSON.stringify({timestamp:Date.now()})}})});if(!update.ok)throw new Error(`Cart update failed: ${update.status} ${update.statusText}`);let cartToken=null;for(let i=0;i<10;i++){const cart2=await(await fetch("/cart.js")).json();if(cart2.token&&cart2.token.includes("?key=")&&cart2.customer_id===this.options.customerId){cartToken=cart2.token;break}await new Promise(res=>setTimeout(res,200))}return cartToken}catch(error){return this.options.debug&&console.log("CustomerDiscountPrices: Error generating token via cart attributes:",error),null}}async loadDiscountData({skipCache=!1}={}){if(this.isProcessing){this.options.debug&&console.log("CustomerDiscountPrices: Already processing, skipping request");return}if(this.isCustomerLoggedIn()){if(!skipCache){const cached=this.getCachedDiscountData();if(cached){this.options.debug&&console.log("CustomerDiscountPrices: Using cached discount data (loadDiscountData):",cached),this.discountData=cached,this.updatePricesInDOM();return}else this.options.debug&&console.log("CustomerDiscountPrices: No cached data found, will make API call")}this.isProcessing=!0;try{let customerToken=null;customerToken=await this.generateCartToken();const customerData=await this.getCustomerData(customerToken);if(!customerData.customerToken){this.options.debug&&console.log("CustomerDiscountPrices: No customer token available, skipping API call."),this.isProcessing=!1;return}const formData=new FormData;if(formData.append("cid",customerData.customerId||""),formData.append("ctk",customerData.customerToken||""),this.options.debug){console.group("CustomerDiscountPrices - API Request"),console.log("URL:",this.options.apiUrl),console.log("FormData entries:");for(let[key,value]of formData.entries())console.log(`${key}: ${value}`);console.groupEnd()}const response=await fetch(this.options.apiUrl,{method:"POST",body:formData,credentials:"include"});if(!response.ok)throw new Error(`API request failed: ${response.status} ${response.statusText}`);const rawData=await response.json();this.discountData=translateDiscountPricesResponse(rawData),this.setCachedDiscountData(this.discountData),this.options.debug&&(console.group("CustomerDiscountPrice
1s - API Response"),console.log("Raw Response:",rawData),console.log("Transformed Data:",this.discountData),console.groupEnd()),this.updatePricesInDOM()}catch(error){console.error("CustomerDiscountPrices - API Error:",error)}finally{this.isProcessing=!1}}}isCustomerLoggedIn(){return!!this.options.customerId}async getCustomerData(forcedToken=null){const customerId=this.options.customerId;let customerToken="";if(window.isLocalPure){if(!this.options.customerStageToken)return console.log("%cLOCAL ISSUE: customerStageToken not configured for pure local development. To use a remote token (local-remote mode), connect to a remote store with 'shopify theme dev --store=stage-plugin-alliance.myshopify.com' or add the customerStageToken to the customerDiscountConfig object in the theme.liquid file.","font-weight: bold;"),{customerId,customerToken:""};customerToken=this.options.customerStageToken}else try{customerToken=(await(await fetch("/cart.js")).json()).token||"",forcedToken&&(customerToken=forcedToken)}catch(error){const mode=window.isLocalRemote?"local-remote":"stage";console.error(`Error fetching cart token in ${mode} mode:`,error)}return{customerId,customerToken}}updatePricesInDOM(){!this.discountData||!this.discountData.products||this.discountData.products.forEach(product=>{document.querySelectorAll(`[${attributes.productVariantId}="${product.variantId}"]`).forEach(priceContainerEl=>{this.handlePriceUpdate(priceContainerEl,product)})})}handlePriceUpdate(priceContainerEl,product){const priceOnSaleEl=priceContainerEl.closest(selectors.priceOnSale);priceOnSaleEl.classList.add(classes.customerDiscountMarker);const isPriceOnSale=priceOnSaleEl.classList.contains(classes.priceOnSale),discountEl=priceContainerEl.querySelector(selectors.discount),originalEl=priceContainerEl.querySelector(selectors.original),domPrices=this.extractPricesFromDOM(priceContainerEl);if(domPrices.original<=product.price.discount){priceOnSaleEl.classList.add("is-special-case"),this.options.debug&&console.log(`CustomerDiscountPrices: Skipping price update for variant ${product.variantId} - original price (${domPrices.original}) <= discount price (${product.price.discount})`);return}discountEl&&originalEl&&(originalEl.textContent=this.formatPriceCurrency(domPrices.original),discountEl.textContent=this.formatPriceCurrency(product.price.discount)),isPriceOnSale||priceOnSaleEl.classList.add(classes.priceOnSale);const discountBadgeEl=priceContainerEl.querySelector(selectors.discountBadge);discountBadgeEl&&discountBadgeEl.classList.remove("hidden")}extractPricesFromDOM(priceContainerEl){const result={original:0,originalCompareAt:0};return result.original=parseFloat(priceContainerEl.getAttribute(attributes.originalPrice)||"0"),result.originalCompareAt=parseFloat(priceContainerEl.getAttribute(attributes.originalCompareAtPrice)||"0"),result}observeContainer(selector){const container=document.querySelector(selector);container&&new MutationObserver((mutationsList,observer2)=>{if(observer2.disconnect(),mutationsList.some(mutation=>Array.from(mutation.addedNodes).some(node=>node.nodeType===1&&(node.hasAttribute&&node.hasAttribute(attributes.productVariantId)||node.querySelector&&node.querySelector(`[${attributes.productVariantId}]`))))){const cached=this.getCachedDiscountData();cached?(this.options.debug&&console.log(`CustomerDiscountPrices: Using cached discount data (observer for ${selector}):`,cached),this.discountData=cached,this.updatePricesInDOM()):this.loadDiscountData({skipCache:!0})}observer2.observe(container,{childList:!0,subtree:!0})}).observe(container,{childList:!0,subtree:!0})}formatPriceCurrency(number,currency="USD",languageFormat="en-US"){return Intl.NumberFormat(languageFormat,{style:"currency",currency}).format(number)}getCacheKey(){return`${STORAGE_KEY_PREFIX}${this.options.customerId}`}getCachedDiscountData(){const cacheKey=this.getCacheKey(),cached=localStorage.getItem(cacheKey);if(!cached)return null;try{const parsed=JSON.parse(cached),now=Date.now(),cacheTime=Date.parse(parsed.timestamp);return cacheTime&&(now-cacheTime)/1e3<this.options.cacheTtlSeconds?parsed.data:(localStorage.removeItem(cacheKey),null)}catch{return localStorage.removeItem(cacheKey),null}}setCachedDiscountData(data){const cacheKey=this.getCacheKey();localStorage.setItem(cacheKey,JSON.stringify({timestamp:new Date().toISOString(),data}))}clearCacheIfExists(){Object.keys(localStorage).filter(key=>
1key.startsWith(STORAGE_KEY_PREFIX)).forEach(key=>localStorage.removeItem(key))}}function initializeCustomerDiscountPrices(){window.customerDiscountConfig||console.warn("CustomerDiscountPrices: No configuration found, using defaults"),window.customerDiscountPrices=new CustomerDiscountPrices}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",initializeCustomerDiscountPrices):initializeCustomerDiscountPrices();export{CustomerDiscountPrices}; 2//# sourceMappingURL=/cdn/shop/t/3/assets/customer-discount-prices.js.map?v=87694368541472082791762420197
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.