@behindthescenes/cart 0.0.31 → 0.0.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/browser.js +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/manifest.json +2 -2
- package/dist/types/index.d.ts +1 -15
- package/package.json +1 -1
package/dist/browser/browser.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var _="https://api.bts.it.com/v2/website/cart",W="bts-cart",A="default",Q=2;function P(){try{return globalThis.window??null}catch{return null}}function O(){try{return globalThis.localStorage??P()?.localStorage??null}catch{return null}}var p=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],g=["fbclid","gclid","gbraid","wbraid","ttclid","li_fat_id","msclkid","_fbp","_fbc"];function h(B){if(!B)return{utm:{},clickIds:{}};try{let F=JSON.parse(B);if(!F||typeof F!=="object"||Array.isArray(F))return{utm:{},clickIds:{}};let X=F,G=X.utm&&typeof X.utm==="object"&&!Array.isArray(X.utm)?Object.fromEntries(Object.entries(X.utm).filter((Z)=>typeof Z[1]==="string"&&Z[1].length>0)):{},$=X.clickIds&&typeof X.clickIds==="object"&&!Array.isArray(X.clickIds)?Object.fromEntries(Object.entries(X.clickIds).filter((Z)=>typeof Z[1]==="string"&&Z[1].length>0)):{};return{utm:G,clickIds:$}}catch{return{utm:{},clickIds:{}}}}function R(B,F){let X=new URL(B);X.searchParams.set("bts_site",F);let G=O(),$=G?.getItem("bts_analytics_jt")?.trim();if($)X.searchParams.set("bts_jt",$);let{utm:Z,clickIds:N}=h(G?.getItem("bts_analytics_attr")??null);for(let Y of p){let J=Z[Y];if(J)X.searchParams.set(Y,J)}for(let Y of g){let J=N[Y];if(J)X.searchParams.set(Y,J)}return X.toString()}class V extends Error{code;status;available;sold_out;quantity_exceeded;details;constructor(B,F,X,G,$,Z,N){super(F);this.name="BTSCartError",this.code=B,this.status=X,this.details=G,this.available=$,this.sold_out=Z,this.quantity_exceeded=N}}function y(){return O()??void 0}function k(B){return(B??_).replace(/\/$/,"")}function C(B){if(!Number.isFinite(B??1))return 1;return Math.max(1,Math.floor(B??1))}function j(B){return{items:B.map((F)=>({...F}))}}function S(B){let F=B?.trim();return F&&F.length>0?F:void 0}function v(B){return B.accessTierId??B.productId??B.lineItemId}function u(B){if(B.discountEligibleTierOrProductIds?.length)return[...new Set(B.discountEligibleTierOrProductIds.filter(Boolean))];return[...new Set([B.accessTierId,B.productId,B.lineItemId].filter((F)=>Boolean(F)))]}function K(B){let F=new Set;for(let X of B)for(let G of[X.lineItemId,X.accessTierId,X.productId])if(G)F.add(G);return B.map((X)=>{if(!X.discount)return X;let G=u(X);if(G.length===0||!G.some(($)=>F.has($))){let $={...X};return delete $.discount,delete $.discountEligibleTierOrProductIds,$}return X})}function c(B,F){let X=new Headers(B);if(!F)return X;return new Headers(F).forEach((G,$)=>X.set($,G)),X}function T(B){let F=B.checkoutLinkId.trim();try{let X=F.includes("://")?F:F.startsWith("/")?`https://bts-cart.invalid${F}`:F,G=new URL(X),$=G.pathname.split("/").filter(Boolean),Z=$.indexOf("c"),N=Z>=0?$[Z+1]:$.at(-1);if(N)return{checkoutLinkId:N,discountCode:B.discountCode??G.searchParams.get("discountCode")??void 0}}catch{}return{checkoutLinkId:F,discountCode:B.discountCode}}function q(B){let F=B?.details;if(!Array.isArray(F))return;let X=F.flatMap((G)=>{if(!G||typeof G!=="object")return[];let $=typeof G.lineItemId==="string"?G.lineItemId:"",Z=typeof G.reason==="string"?G.reason:"";if(!$||!Z)return[];let N=typeof G.discountCode==="string"?G.discountCode:void 0,Y=typeof G.requestedQuantity==="number"?G.requestedQuantity:void 0,J=typeof G.adjustedQuantity==="number"?G.adjustedQuantity:void 0;if(!N&&!(Y!==void 0||J!==void 0||Z==="line_item_sold_out"||Z==="quantity_exceeded"||Z==="product_unavailable"))return[];return[{lineItemId:$,...typeof G.productId==="string"?{productId:G.productId}:{},...typeof G.accessTierId==="string"?{accessTierId:G.accessTierId}:{},...N?{discountCode:N}:{},...typeof G.discountId==="string"?{discountId:G.discountId}:{},reason:Z,...Y!==void 0?{requestedQuantity:Y}:{},...J!==void 0?{adjustedQuantity:J}:{}}]});return X.length>0?X:void 0}var l=new Set(["discounts_invalid","quantity_invalid","cart_adjusted"]);function m(B){return B.reason==="line_item_sold_out"||B.reason==="product_unavailable"||B.adjustedQuantity===0}function w(B){if(B==="invalid_quantities")return"quantity_invalid";if(B==="invalid_discounts")return"discounts_invalid";return B}function E(B){return l.has(B)}function s(B){let F=B.sold_out===!0||B.code==="line_item_sold_out"||B.code==="product_unavailable",X=B.quantity_exceeded===!0||B.code==="quantity_exceeded";return{ok:!1,available:!F,sold_out:F,quantity_exceeded:X}}function d(B){return[...new Set([B.lineItemId,B.accessTierId,B.productId].filter((F)=>Boolean(F)))]}function D(B,F){let X=d(B);return[F.lineItemId,F.accessTierId,F.productId].filter(($)=>Boolean($)).some(($)=>X.includes($))}class U{siteKey;endpoint;debug;persist;storageKey;storage;checkoutLinks;defaultCheckoutLinkKey;requestHeaders;items=[];listeners=new Set;constructor(B){this.siteKey=B.siteKey,this.endpoint=k(B.endpoint),this.debug=B.debug??!1,this.persist=B.persist??!0,this.storageKey=B.storageKey??W,this.storage=B.storage??y(),this.checkoutLinks=B.checkoutLinks??{},this.defaultCheckoutLinkKey=B.defaultCheckoutLinkKey??Object.keys(this.checkoutLinks)[0]??A,this.requestHeaders=B.requestHeaders,this.rehydrate()}static init(B){return new U(B)}getItems(){return j(this.items).items}getState(){return j(this.items)}getItemCount(){return this.items.reduce((B,F)=>B+F.quantity,0)}getSubtotal(){return this.items.reduce((B,F)=>B+(F.fullPrice??F.unitPrice)*F.quantity,0)}getTotal(){return this.items.reduce((B,F)=>B+F.unitPrice*F.quantity,0)}subscribe(B){return this.listeners.add(B),B(this.getState()),()=>{this.listeners.delete(B)}}destroy(){this.listeners.clear()}rehydrate(){if(!this.persist||!this.storage)return;try{let B=this.storage.getItem(this.storageKey);if(!B)return;let F=JSON.parse(B);if(Array.isArray(F)||F.version!==Q){this.storage.removeItem(this.storageKey);return}let X=F.items;if(!Array.isArray(X))return;this.items=K(X.map((G)=>this.normalizeItem(G)).filter((G)=>Boolean(G))),this.emit()}catch(B){this.log("Failed to hydrate cart",B)}}addItem(B){let F=this.normalizeItem(B);if(!F)return;let X=this.items.find((G)=>G.id===F.id);if(X){this.setQuantity(X.id,X.quantity+F.quantity);return}this.items=[...this.items,F],this.commit()}removeItem(B){this.items=this.items.filter((F)=>F.id!==B),this.commit()}setQuantity(B,F){let X=Math.floor(F);this.items=X<=0?this.items.filter((G)=>G.id!==B):this.items.map((G)=>G.id===B?{...G,quantity:X}:G),this.commit()}increment(B,F=1){let X=this.items.find((G)=>G.id===B);if(X)this.setQuantity(B,X.quantity+Math.max(1,Math.floor(F)))}decrement(B,F=1){let X=this.items.find((G)=>G.id===B);if(X)this.setQuantity(B,X.quantity-Math.max(1,Math.floor(F)))}clear(){if(this.items=[],this.persist&&this.storage)try{this.storage.removeItem(this.storageKey)}catch(B){this.log("Failed to clear cart storage",B)}this.emit()}removeDiscountForLineItem(B){this.items=this.items.map((F)=>{if(!D(F,{lineItemId:B,reason:"discount"}))return F;if(!F.discount)return F;let X={...F,unitPrice:F.fullPrice??F.unitPrice};return delete X.discount,delete X.discountEligibleTierOrProductIds,X}),this.commit()}async checkIfItemsAvailable(B){let F=[];for(let X of B){let G=await this.checkIfItemAvailable(this.defaultCheckoutLinkKey,X.lineItemId,X.discountId);if(G instanceof V)throw new V(G.code,G.message);F.push(G)}return F}async checkIfItemAvailable(B=this.defaultCheckoutLinkKey,F,X){let G=this.checkoutLinks[B];if(!G)throw new V("checkout_link_not_found",`Unknown checkout link key: ${B}`);let $=T(G),Z={siteKey:this.siteKey,checkoutLinkId:$.checkoutLinkId,mode:G.mode,lineItemId:F,...X?{discountId:X}:{}};try{let N=await this.post("/check-availability",Z);if(typeof N.ok!=="boolean")throw new V("request_failed","Availability check response was invalid.");let Y=N;return{...Y,available:Y.ok===!0&&Y.sold_out!==!0,sold_out:Y.sold_out===!0,quantity_exceeded:Y.quantity_exceeded===!0}}catch(N){if(N instanceof V){if(N.details?.length)this.reconcileCartAdjustments(N.details);if(N.code==="line_item_sold_out"||N.code==="product_unavailable"||N.code==="quantity_exceeded")return s(N)}throw N}}async isCatalogLineSoldOut(B=this.defaultCheckoutLinkKey,F,X){let G=this.checkoutLinks[B];if(!G)throw new V("checkout_link_not_found",`Unknown checkout link key: ${B}`);let $=T(G),Z=v(F),N={siteKey:this.siteKey,checkoutLinkId:$.checkoutLinkId,mode:G.mode,items:[{lineItemId:Z,quantity:C(X?.quantity),...X?.discount?{discount:X.discount}:{}}]},Y=await this.post("/validate-discounts",N);if(Y.ok===!0)return!1;return q(Y)?.some(m)??!1}async validateCheckout(B=this.defaultCheckoutLinkKey){let F=this.checkoutLinks[B];if(!F)throw new V("checkout_link_not_found",`Unknown checkout link key: ${B}`);let X=T(F),G=this.itemsForCheckout(B,F),$={siteKey:this.siteKey,checkoutLinkId:X.checkoutLinkId,mode:F.mode,...X.discountCode?{discountCode:X.discountCode}:{},...G.length>0?{items:G}:{}};try{let Z=await this.post("/validate-discounts",$);if(typeof Z.ok!=="boolean")throw new V("request_failed","Cart response was invalid.");if(Z.ok===!1){let N=w(typeof Z.code==="string"&&Z.code.length>0?Z.code:"request_failed"),Y=typeof Z.message==="string"&&Z.message.length>0?Z.message:"Unable to validate cart.",J=q(Z);if(E(N))throw this.reconcileCartAdjustments(J),new V(N,Y,200,J);throw new V(N,Y,200,J)}return Z}catch(Z){if(Z instanceof V){if(E(Z.code))throw this.reconcileCartAdjustments(Z.details),new V(Z.code,Z.message,Z.status,Z.details);throw new V(Z.code,Z.message,Z.status)}throw new V("request_failed","Failed to validate checkout.",void 0,void 0)}}async resolveCheckoutUrl(B=this.defaultCheckoutLinkKey){let F=this.checkoutLinks[B];if(!F)throw new V("checkout_link_not_found",`Unknown checkout link key: ${B}`);let X=T(F),G=this.itemsForCheckout(B,F),$={siteKey:this.siteKey,checkoutLinkId:X.checkoutLinkId,mode:F.mode,...X.discountCode?{discountCode:X.discountCode}:{},...G.length>0?{items:G}:{}};try{let Z=await this.post("/checkout-url",$);if(Z.ok!==!0||typeof Z.checkoutUrl!=="string"||Z.checkoutUrl.length===0)throw new V("request_failed","Cart response was invalid.");return R(Z.checkoutUrl,this.siteKey)}catch(Z){if(Z instanceof V){if(E(Z.code))throw this.reconcileCartAdjustments(Z.details),new V(Z.code,Z.message,Z.status,Z.details);throw new V(Z.code,Z.message,Z.status)}throw new V("request_failed","Failed to resolve checkout URL.",void 0,void 0)}}async checkout(B=this.defaultCheckoutLinkKey){try{let F=await this.resolveCheckoutUrl(B),X=P();if(X)X.location.assign(F);return F}catch(F){if(F instanceof V){if(E(F.code))throw this.reconcileCartAdjustments(F.details),new V(F.code,F.message,F.status,F.details);throw new V(F.code,F.message,F.status)}throw new V("request_failed","Failed to resolve checkout URL.",void 0,void 0)}}itemsForCheckout(B,F){if(F.mode==="static")return[];let X=this.items.filter((G)=>G.checkoutLinkKey===B).map((G)=>({lineItemId:v(G),quantity:G.quantity,...G.discount?{discount:G.discount}:{}}));if(X.length===0)throw new V("cart_empty","Your cart is empty.");return X}normalizeItem(B){let F=S(B.accessTierId),X=S(B.productId),G=S(B.lineItemId)??F??X;if(!B.id||!G||typeof B.unitPrice!=="number")return null;let $=typeof B.name==="string"&&B.name.trim().length>0?B.name.trim():"Item";return{...B,id:B.id,lineItemId:G,...F?{accessTierId:F}:{},...X?{productId:X}:{},checkoutLinkKey:B.checkoutLinkKey??this.defaultCheckoutLinkKey,name:$,unitPrice:B.unitPrice,quantity:C(B.quantity)}}reconcileCartAdjustments(B){if(!B?.length)return;let F=[...this.items],X=!1;for(let G of B){if(G.discountCode){F=F.map((Z)=>{if(!D(Z,G))return Z;let N={...Z,unitPrice:Z.fullPrice??Z.unitPrice};return delete N.discount,delete N.discountEligibleTierOrProductIds,X=!0,N});continue}if(G.reason==="line_item_sold_out"||G.reason==="product_unavailable"||G.adjustedQuantity===0){let Z=F.length;if(F=F.filter((N)=>!D(N,G)),F.length!==Z)X=!0;continue}if(G.reason==="quantity_exceeded"&&typeof G.adjustedQuantity==="number"&&G.adjustedQuantity>0){let Z=G.adjustedQuantity;F=F.map((N)=>{if(!D(N,G))return N;return X=!0,{...N,quantity:Z}})}}if(!X)return;this.items=F,this.commit()}async post(B,F){let X=`${this.endpoint}${B}`,G=JSON.stringify(F),$={"Content-Type":"application/json"},Z={body:F,bodyText:G,endpoint:this.endpoint,headers:$,path:B,siteKey:this.siteKey,url:X},N=typeof this.requestHeaders==="function"?await this.requestHeaders(Z):this.requestHeaders,Y=c($,N),J=await fetch(X,{method:"POST",headers:Y,body:G}),H=await J.json().catch(()=>null);if(!J.ok){let b=typeof H?.code==="string"&&H.code.length>0?H.code:"request_failed",f=w(b),I=typeof H?.message==="string"&&H.message.length>0?H.message:"Cart request failed";throw new V(f,I,J.status,q(H),typeof H?.available==="boolean"?H.available:void 0,typeof H?.sold_out==="boolean"?H.sold_out:void 0,typeof H?.quantity_exceeded==="boolean"?H.quantity_exceeded:void 0)}if(!H||typeof H!=="object")throw new V("request_failed","Cart response was invalid.",J.status);return H}commit(){if(this.items=K(this.items),this.persist&&this.storage)try{let B={version:Q,items:this.items};this.storage.setItem(this.storageKey,JSON.stringify(B))}catch(B){this.log("Failed to persist cart",B)}this.emit()}emit(){let B=this.getState();for(let F of this.listeners)F(B)}log(...B){if(this.debug)console.log("[@behindthescenes/cart]",...B)}}function z(B){return U.init(B)}function x(B){return typeof B==="object"&&B!==null&&!Array.isArray(B)}function L(B){let F=P();if(!F)return;let[X,G,$]=B;if(typeof X!=="string")return;if(X==="config"){if(!x(G))return;F.btsCart?.destroy?.(),F.btsCart=z(G);return}let Z=F.btsCart;if(!Z)return;if(X==="add"&&x(G)){Z.addItem(G);return}if(X==="remove"&&typeof G==="string"){Z.removeItem(G);return}if(X==="quantity"&&typeof G==="string"&&typeof $==="number"){Z.setQuantity(G,$);return}if(X==="clear"){Z.clear();return}if(X==="checkout")Z.checkout(typeof G==="string"?G:void 0)}var M=P();if(M){let B=Array.isArray(M.btsCartDataLayer)?[...M.btsCartDataLayer]:[];M.btsCartDataLayer=Array.isArray(M.btsCartDataLayer)?M.btsCartDataLayer:[],M.BTSCart={BTSCart:U,createBTSCart:z},M.createBTSCart=z;for(let F of B)L(Array.from(F));M.btsCartCommand=(...F)=>{M.btsCartDataLayer?.push(F),L(F)}}export{z as createBTSCart,U as BTSCart};
|
|
1
|
+
var S="https://api.bts.it.com/v2/website/cart",Q="bts-cart",q="default",z=2;function D(){try{return globalThis.window??null}catch{return null}}function O(){try{return globalThis.localStorage??D()?.localStorage??null}catch{return null}}var w=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],b=["fbclid","gclid","gbraid","wbraid","ttclid","li_fat_id","msclkid","_fbp","_fbc"];function x(B){if(!B)return{utm:{},clickIds:{}};try{let F=JSON.parse(B);if(!F||typeof F!=="object"||Array.isArray(F))return{utm:{},clickIds:{}};let N=F,G=N.utm&&typeof N.utm==="object"&&!Array.isArray(N.utm)?Object.fromEntries(Object.entries(N.utm).filter((X)=>typeof X[1]==="string"&&X[1].length>0)):{},Z=N.clickIds&&typeof N.clickIds==="object"&&!Array.isArray(N.clickIds)?Object.fromEntries(Object.entries(N.clickIds).filter((X)=>typeof X[1]==="string"&&X[1].length>0)):{};return{utm:G,clickIds:Z}}catch{return{utm:{},clickIds:{}}}}function C(B,F){let N=new URL(B);N.searchParams.set("bts_site",F);let G=O(),Z=G?.getItem("bts_analytics_jt")?.trim();if(Z)N.searchParams.set("bts_jt",Z);let{utm:X,clickIds:$}=x(G?.getItem("bts_analytics_attr")??null);for(let E of w){let Y=X[E];if(Y)N.searchParams.set(E,Y)}for(let E of b){let Y=$[E];if(Y)N.searchParams.set(E,Y)}return N.toString()}class J extends Error{code;status;available;sold_out;quantity_exceeded;details;constructor(B,F,N,G,Z,X,$){super(F);this.name="BTSCartError",this.code=B,this.status=N,this.details=G,this.available=Z,this.sold_out=X,this.quantity_exceeded=$}}function f(){return O()??void 0}function p(B){return(B??S).replace(/\/$/,"")}function I(B){if(!Number.isFinite(B??1))return 1;return Math.max(1,Math.floor(B??1))}function R(B){return{items:B.map((F)=>({...F}))}}function U(B){let F=B?.trim();return F&&F.length>0?F:void 0}function g(B){return B.accessTierId??B.productId??B.lineItemId}function h(B){if(B.discountEligibleTierOrProductIds?.length)return[...new Set(B.discountEligibleTierOrProductIds.filter(Boolean))];return[...new Set([B.accessTierId,B.productId,B.lineItemId].filter((F)=>Boolean(F)))]}function W(B){let F=new Set;for(let N of B)for(let G of[N.lineItemId,N.accessTierId,N.productId])if(G)F.add(G);return B.map((N)=>{if(!N.discount)return N;let G=h(N);if(G.length===0||!G.some((Z)=>F.has(Z))){let Z={...N};return delete Z.discount,delete Z.discountEligibleTierOrProductIds,Z}return N})}function y(B,F){let N=new Headers(B);if(!F)return N;return new Headers(F).forEach((G,Z)=>N.set(Z,G)),N}function _(B){let F=B.checkoutLinkId.trim();try{let N=F.includes("://")?F:F.startsWith("/")?`https://bts-cart.invalid${F}`:F,G=new URL(N),Z=G.pathname.split("/").filter(Boolean),X=Z.indexOf("c"),$=X>=0?Z[X+1]:Z.at(-1);if($)return{checkoutLinkId:$,discountCode:B.discountCode??G.searchParams.get("discountCode")??void 0}}catch{}return{checkoutLinkId:F,discountCode:B.discountCode}}function k(B){let F=B?.details;if(!Array.isArray(F))return;let N=F.flatMap((G)=>{if(!G||typeof G!=="object")return[];let Z=typeof G.lineItemId==="string"?G.lineItemId:"",X=typeof G.reason==="string"?G.reason:"";if(!Z||!X)return[];let $=typeof G.discountCode==="string"?G.discountCode:void 0,E=typeof G.requestedQuantity==="number"?G.requestedQuantity:void 0,Y=typeof G.adjustedQuantity==="number"?G.adjustedQuantity:void 0;if(!$&&!(E!==void 0||Y!==void 0||X==="line_item_sold_out"||X==="quantity_exceeded"||X==="product_unavailable"))return[];return[{lineItemId:Z,...typeof G.productId==="string"?{productId:G.productId}:{},...typeof G.accessTierId==="string"?{accessTierId:G.accessTierId}:{},...$?{discountCode:$}:{},...typeof G.discountId==="string"?{discountId:G.discountId}:{},reason:X,...E!==void 0?{requestedQuantity:E}:{},...Y!==void 0?{adjustedQuantity:Y}:{}}]});return N.length>0?N:void 0}var u=new Set(["discounts_invalid","quantity_invalid","cart_adjusted"]);function A(B){return u.has(B)}function c(B){return[...new Set([B.lineItemId,B.accessTierId,B.productId].filter((F)=>Boolean(F)))]}function P(B,F){let N=c(B);return[F.lineItemId,F.accessTierId,F.productId].filter((Z)=>Boolean(Z)).some((Z)=>N.includes(Z))}class H{siteKey;endpoint;debug;persist;storageKey;storage;checkoutLinks;defaultCheckoutLinkKey;requestHeaders;items=[];listeners=new Set;constructor(B){this.siteKey=B.siteKey,this.endpoint=p(B.endpoint),this.debug=B.debug??!1,this.persist=B.persist??!0,this.storageKey=B.storageKey??Q,this.storage=B.storage??f(),this.checkoutLinks=B.checkoutLinks??{},this.defaultCheckoutLinkKey=B.defaultCheckoutLinkKey??Object.keys(this.checkoutLinks)[0]??q,this.requestHeaders=B.requestHeaders,this.rehydrate()}static init(B){return new H(B)}getItems(){return R(this.items).items}getState(){return R(this.items)}getItemCount(){return this.items.reduce((B,F)=>B+F.quantity,0)}getSubtotal(){return this.items.reduce((B,F)=>B+(F.fullPrice??F.unitPrice)*F.quantity,0)}getTotal(){return this.items.reduce((B,F)=>B+F.unitPrice*F.quantity,0)}subscribe(B){return this.listeners.add(B),B(this.getState()),()=>{this.listeners.delete(B)}}destroy(){this.listeners.clear()}rehydrate(){if(!this.persist||!this.storage)return;try{let B=this.storage.getItem(this.storageKey);if(!B)return;let F=JSON.parse(B);if(Array.isArray(F)||F.version!==z){this.storage.removeItem(this.storageKey);return}let N=F.items;if(!Array.isArray(N))return;this.items=W(N.map((G)=>this.normalizeItem(G)).filter((G)=>Boolean(G))),this.emit()}catch(B){this.log("Failed to hydrate cart",B)}}addItem(B){let F=this.normalizeItem(B);if(!F)return;let N=this.items.find((G)=>G.id===F.id);if(N){this.setQuantity(N.id,N.quantity+F.quantity);return}this.items=[...this.items,F],this.commit()}removeItem(B){this.items=this.items.filter((F)=>F.id!==B),this.commit()}setQuantity(B,F){let N=Math.floor(F);this.items=N<=0?this.items.filter((G)=>G.id!==B):this.items.map((G)=>G.id===B?{...G,quantity:N}:G),this.commit()}increment(B,F=1){let N=this.items.find((G)=>G.id===B);if(N)this.setQuantity(B,N.quantity+Math.max(1,Math.floor(F)))}decrement(B,F=1){let N=this.items.find((G)=>G.id===B);if(N)this.setQuantity(B,N.quantity-Math.max(1,Math.floor(F)))}clear(){if(this.items=[],this.persist&&this.storage)try{this.storage.removeItem(this.storageKey)}catch(B){this.log("Failed to clear cart storage",B)}this.emit()}removeDiscountForLineItem(B){this.items=this.items.map((F)=>{if(!P(F,{lineItemId:B,reason:"discount"}))return F;if(!F.discount)return F;let N={...F,unitPrice:F.fullPrice??F.unitPrice};return delete N.discount,delete N.discountEligibleTierOrProductIds,N}),this.commit()}async checkIfItemsAvailable(B){let F=[];for(let N of B){let G=await this.checkIfItemAvailable(this.defaultCheckoutLinkKey,N.lineItemId,N.discountId);if(G instanceof J)throw new J(G.code,G.message);F.push(G)}return F}async checkIfItemAvailable(B=this.defaultCheckoutLinkKey,F,N){let G=this.checkoutLinks[B];if(!G)throw new J("checkout_link_not_found",`Unknown checkout link key: ${B}`);let Z=_(G),X={siteKey:this.siteKey,checkoutLinkId:Z.checkoutLinkId,mode:G.mode,lineItemId:F,...N?{discountId:N}:{}};try{let $=await this.post("/check-availability",X);if(typeof $.ok!=="boolean")throw new J("request_failed","Availability check response was invalid.");return $}catch($){if($ instanceof J){if($.details?.length)this.reconcileCartAdjustments($.details);if($.code==="line_item_sold_out"||$.code==="product_unavailable"||$.code==="quantity_exceeded")return{ok:!1,available:$.available??!1,sold_out:$.sold_out??$.code==="line_item_sold_out",quantity_exceeded:$.quantity_exceeded??($.code==="line_item_sold_out"||$.code==="quantity_exceeded")}}throw $}}async validateCheckout(B=this.defaultCheckoutLinkKey){let F=this.checkoutLinks[B];if(!F)throw new J("checkout_link_not_found",`Unknown checkout link key: ${B}`);let N=_(F),G=this.itemsForCheckout(B,F),Z={siteKey:this.siteKey,checkoutLinkId:N.checkoutLinkId,mode:F.mode,...N.discountCode?{discountCode:N.discountCode}:{},...G.length>0?{items:G}:{}};try{let X=await this.post("/validate-discounts",Z);if(typeof X.ok!=="boolean")throw new J("request_failed","Cart response was invalid.");return X}catch(X){if(X instanceof J){if(A(X.code))throw this.reconcileCartAdjustments(X.details),new J(X.code,X.message,X.status,X.details);throw new J(X.code,X.message,X.status)}throw new J("request_failed","Failed to validate checkout.",void 0,void 0)}}async resolveCheckoutUrl(B=this.defaultCheckoutLinkKey){let F=this.checkoutLinks[B];if(!F)throw new J("checkout_link_not_found",`Unknown checkout link key: ${B}`);let N=_(F),G=this.itemsForCheckout(B,F),Z={siteKey:this.siteKey,checkoutLinkId:N.checkoutLinkId,mode:F.mode,...N.discountCode?{discountCode:N.discountCode}:{},...G.length>0?{items:G}:{}};try{let X=await this.post("/checkout-url",Z);if(X.ok!==!0||typeof X.checkoutUrl!=="string"||X.checkoutUrl.length===0)throw new J("request_failed","Cart response was invalid.");return C(X.checkoutUrl,this.siteKey)}catch(X){if(X instanceof J){if(A(X.code))throw this.reconcileCartAdjustments(X.details),new J(X.code,X.message,X.status,X.details);throw new J(X.code,X.message,X.status)}throw new J("request_failed","Failed to resolve checkout URL.",void 0,void 0)}}async checkout(B=this.defaultCheckoutLinkKey){try{let F=await this.resolveCheckoutUrl(B),N=D();if(N)N.location.assign(F);return F}catch(F){if(F instanceof J){if(A(F.code))throw this.reconcileCartAdjustments(F.details),new J(F.code,F.message,F.status,F.details);throw new J(F.code,F.message,F.status)}throw new J("request_failed","Failed to resolve checkout URL.",void 0,void 0)}}itemsForCheckout(B,F){if(F.mode==="static")return[];let N=this.items.filter((G)=>G.checkoutLinkKey===B).map((G)=>({lineItemId:g(G),quantity:G.quantity,...G.discount?{discount:G.discount}:{}}));if(N.length===0)throw new J("cart_empty","Your cart is empty.");return N}normalizeItem(B){let F=U(B.accessTierId),N=U(B.productId),G=U(B.lineItemId)??F??N;if(!B.id||!G||typeof B.unitPrice!=="number")return null;let Z=typeof B.name==="string"&&B.name.trim().length>0?B.name.trim():"Item";return{...B,id:B.id,lineItemId:G,...F?{accessTierId:F}:{},...N?{productId:N}:{},checkoutLinkKey:B.checkoutLinkKey??this.defaultCheckoutLinkKey,name:Z,unitPrice:B.unitPrice,quantity:I(B.quantity)}}reconcileCartAdjustments(B){if(!B?.length)return;let F=[...this.items],N=!1;for(let G of B){if(G.discountCode){F=F.map((X)=>{if(!P(X,G))return X;let $={...X,unitPrice:X.fullPrice??X.unitPrice};return delete $.discount,delete $.discountEligibleTierOrProductIds,N=!0,$});continue}if(G.reason==="line_item_sold_out"||G.reason==="product_unavailable"||G.adjustedQuantity===0){let X=F.length;if(F=F.filter(($)=>!P($,G)),F.length!==X)N=!0;continue}if(G.reason==="quantity_exceeded"&&typeof G.adjustedQuantity==="number"&&G.adjustedQuantity>0){let X=G.adjustedQuantity;F=F.map(($)=>{if(!P($,G))return $;return N=!0,{...$,quantity:X}})}}if(!N)return;this.items=F,this.commit()}async post(B,F){let N=`${this.endpoint}${B}`,G=JSON.stringify(F),Z={"Content-Type":"application/json"},X={body:F,bodyText:G,endpoint:this.endpoint,headers:Z,path:B,siteKey:this.siteKey,url:N},$=typeof this.requestHeaders==="function"?await this.requestHeaders(X):this.requestHeaders,E=y(Z,$),Y=await fetch(N,{method:"POST",headers:E,body:G}),V=await Y.json().catch(()=>null);if(!Y.ok){let K=typeof V?.code==="string"&&V.code.length>0?V.code:"request_failed",L=typeof V?.message==="string"&&V.message.length>0?V.message:"Cart request failed";throw new J(K,L,Y.status,k(V),typeof V?.available==="boolean"?V.available:void 0,typeof V?.sold_out==="boolean"?V.sold_out:void 0,typeof V?.quantity_exceeded==="boolean"?V.quantity_exceeded:void 0)}if(!V||typeof V!=="object")throw new J("request_failed","Cart response was invalid.",Y.status);return V}commit(){if(this.items=W(this.items),this.persist&&this.storage)try{let B={version:z,items:this.items};this.storage.setItem(this.storageKey,JSON.stringify(B))}catch(B){this.log("Failed to persist cart",B)}this.emit()}emit(){let B=this.getState();for(let F of this.listeners)F(B)}log(...B){if(this.debug)console.log("[@behindthescenes/cart]",...B)}}function T(B){return H.init(B)}function v(B){return typeof B==="object"&&B!==null&&!Array.isArray(B)}function j(B){let F=D();if(!F)return;let[N,G,Z]=B;if(typeof N!=="string")return;if(N==="config"){if(!v(G))return;F.btsCart?.destroy?.(),F.btsCart=T(G);return}let X=F.btsCart;if(!X)return;if(N==="add"&&v(G)){X.addItem(G);return}if(N==="remove"&&typeof G==="string"){X.removeItem(G);return}if(N==="quantity"&&typeof G==="string"&&typeof Z==="number"){X.setQuantity(G,Z);return}if(N==="clear"){X.clear();return}if(N==="checkout")X.checkout(typeof G==="string"?G:void 0)}var M=D();if(M){let B=Array.isArray(M.btsCartDataLayer)?[...M.btsCartDataLayer]:[];M.btsCartDataLayer=Array.isArray(M.btsCartDataLayer)?M.btsCartDataLayer:[],M.BTSCart={BTSCart:H,createBTSCart:T},M.createBTSCart=T;for(let F of B)j(Array.from(F));M.btsCartCommand=(...F)=>{M.btsCartDataLayer?.push(F),j(F)}}export{T as createBTSCart,H as BTSCart};
|
package/dist/cjs/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var{defineProperty:z,getOwnPropertyNames:p,getOwnPropertyDescriptor:h}=Object,y=Object.prototype.hasOwnProperty;function k(B){return this[B]}var c=(B)=>{var F=(_??=new WeakMap).get(B),G;if(F)return F;if(F=z({},"__esModule",{value:!0}),B&&typeof B==="object"||typeof B==="function"){for(var X of p(B))if(!y.call(F,X))z(F,X,{get:k.bind(B,X),enumerable:!(G=h(B,X))||G.enumerable})}return _.set(B,F),F},_;var u=(B)=>B;function m(B,F){this[B]=u.bind(null,F)}var l=(B,F)=>{for(var G in F)z(B,G,{get:F[G],enumerable:!0,configurable:!0,set:m.bind(F,G)})};var FB={};l(FB,{resolveLineItemIdForCheckout:()=>q,normalizeCartAdjustmentDetails:()=>E,isSoldOutAdjustmentDetail:()=>f,isCartAdjustmentErrorCode:()=>t,createBTSCart:()=>BB,catalogIdsForCartLine:()=>x,BTSCartError:()=>P,BTSCart:()=>O});module.exports=c(FB);var R="https://api.bts.it.com/v2/website/cart",S="bts-cart",A="default",D=2;function T(){try{return globalThis.window??null}catch{return null}}function H(){try{return globalThis.localStorage??T()?.localStorage??null}catch{return null}}var s=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],d=["fbclid","gclid","gbraid","wbraid","ttclid","li_fat_id","msclkid","_fbp","_fbc"];function a(B){if(!B)return{utm:{},clickIds:{}};try{let F=JSON.parse(B);if(!F||typeof F!=="object"||Array.isArray(F))return{utm:{},clickIds:{}};let G=F,X=G.utm&&typeof G.utm==="object"&&!Array.isArray(G.utm)?Object.fromEntries(Object.entries(G.utm).filter((Z)=>typeof Z[1]==="string"&&Z[1].length>0)):{},N=G.clickIds&&typeof G.clickIds==="object"&&!Array.isArray(G.clickIds)?Object.fromEntries(Object.entries(G.clickIds).filter((Z)=>typeof Z[1]==="string"&&Z[1].length>0)):{};return{utm:X,clickIds:N}}catch{return{utm:{},clickIds:{}}}}function w(B,F){let G=new URL(B);G.searchParams.set("bts_site",F);let X=H(),N=X?.getItem("bts_analytics_jt")?.trim();if(N)G.searchParams.set("bts_jt",N);let{utm:Z,clickIds:$}=a(X?.getItem("bts_analytics_attr")??null);for(let V of s){let Y=Z[V];if(Y)G.searchParams.set(V,Y)}for(let V of d){let Y=$[V];if(Y)G.searchParams.set(V,Y)}return G.toString()}class P extends Error{code;status;available;sold_out;quantity_exceeded;details;constructor(B,F,G,X,N,Z,$){super(F);this.name="BTSCartError",this.code=B,this.status=G,this.details=X,this.available=N,this.sold_out=Z,this.quantity_exceeded=$}}function o(){return H()??void 0}function n(B){return(B??R).replace(/\/$/,"")}function v(B){if(!Number.isFinite(B??1))return 1;return Math.max(1,Math.floor(B??1))}function C(B){return{items:B.map((F)=>({...F}))}}function Q(B){let F=B?.trim();return F&&F.length>0?F:void 0}function q(B){return B.accessTierId??B.productId??B.lineItemId}function r(B){if(B.discountEligibleTierOrProductIds?.length)return[...new Set(B.discountEligibleTierOrProductIds.filter(Boolean))];return[...new Set([B.accessTierId,B.productId,B.lineItemId].filter((F)=>Boolean(F)))]}function j(B){let F=new Set;for(let G of B)for(let X of[G.lineItemId,G.accessTierId,G.productId])if(X)F.add(X);return B.map((G)=>{if(!G.discount)return G;let X=r(G);if(X.length===0||!X.some((N)=>F.has(N))){let N={...G};return delete N.discount,delete N.discountEligibleTierOrProductIds,N}return G})}function i(B,F){let G=new Headers(B);if(!F)return G;return new Headers(F).forEach((X,N)=>G.set(N,X)),G}function M(B){let F=B.checkoutLinkId.trim();try{let G=F.includes("://")?F:F.startsWith("/")?`https://bts-cart.invalid${F}`:F,X=new URL(G),N=X.pathname.split("/").filter(Boolean),Z=N.indexOf("c"),$=Z>=0?N[Z+1]:N.at(-1);if($)return{checkoutLinkId:$,discountCode:B.discountCode??X.searchParams.get("discountCode")??void 0}}catch{}return{checkoutLinkId:F,discountCode:B.discountCode}}function E(B){let F=B?.details;if(!Array.isArray(F))return;let G=F.flatMap((X)=>{if(!X||typeof X!=="object")return[];let N=typeof X.lineItemId==="string"?X.lineItemId:"",Z=typeof X.reason==="string"?X.reason:"";if(!N||!Z)return[];let $=typeof X.discountCode==="string"?X.discountCode:void 0,V=typeof X.requestedQuantity==="number"?X.requestedQuantity:void 0,Y=typeof X.adjustedQuantity==="number"?X.adjustedQuantity:void 0;if(!$&&!(V!==void 0||Y!==void 0||Z==="line_item_sold_out"||Z==="quantity_exceeded"||Z==="product_unavailable"))return[];return[{lineItemId:N,...typeof X.productId==="string"?{productId:X.productId}:{},...typeof X.accessTierId==="string"?{accessTierId:X.accessTierId}:{},...$?{discountCode:$}:{},...typeof X.discountId==="string"?{discountId:X.discountId}:{},reason:Z,...V!==void 0?{requestedQuantity:V}:{},...Y!==void 0?{adjustedQuantity:Y}:{}}]});return G.length>0?G:void 0}var K=new Set(["discounts_invalid","quantity_invalid","cart_adjusted"]);function f(B){return B.reason==="line_item_sold_out"||B.reason==="product_unavailable"||B.adjustedQuantity===0}function t(B){return K.has(B)||B==="invalid_quantities"||B==="invalid_discounts"}function b(B){if(B==="invalid_quantities")return"quantity_invalid";if(B==="invalid_discounts")return"discounts_invalid";return B}function W(B){return K.has(B)}function e(B){let F=B.sold_out===!0||B.code==="line_item_sold_out"||B.code==="product_unavailable",G=B.quantity_exceeded===!0||B.code==="quantity_exceeded";return{ok:!1,available:!F,sold_out:F,quantity_exceeded:G}}function x(B){return[...new Set([B.lineItemId,B.accessTierId,B.productId].filter((F)=>Boolean(F)))]}function U(B,F){let G=x(B);return[F.lineItemId,F.accessTierId,F.productId].filter((N)=>Boolean(N)).some((N)=>G.includes(N))}class O{siteKey;endpoint;debug;persist;storageKey;storage;checkoutLinks;defaultCheckoutLinkKey;requestHeaders;items=[];listeners=new Set;constructor(B){this.siteKey=B.siteKey,this.endpoint=n(B.endpoint),this.debug=B.debug??!1,this.persist=B.persist??!0,this.storageKey=B.storageKey??S,this.storage=B.storage??o(),this.checkoutLinks=B.checkoutLinks??{},this.defaultCheckoutLinkKey=B.defaultCheckoutLinkKey??Object.keys(this.checkoutLinks)[0]??A,this.requestHeaders=B.requestHeaders,this.rehydrate()}static init(B){return new O(B)}getItems(){return C(this.items).items}getState(){return C(this.items)}getItemCount(){return this.items.reduce((B,F)=>B+F.quantity,0)}getSubtotal(){return this.items.reduce((B,F)=>B+(F.fullPrice??F.unitPrice)*F.quantity,0)}getTotal(){return this.items.reduce((B,F)=>B+F.unitPrice*F.quantity,0)}subscribe(B){return this.listeners.add(B),B(this.getState()),()=>{this.listeners.delete(B)}}destroy(){this.listeners.clear()}rehydrate(){if(!this.persist||!this.storage)return;try{let B=this.storage.getItem(this.storageKey);if(!B)return;let F=JSON.parse(B);if(Array.isArray(F)||F.version!==D){this.storage.removeItem(this.storageKey);return}let G=F.items;if(!Array.isArray(G))return;this.items=j(G.map((X)=>this.normalizeItem(X)).filter((X)=>Boolean(X))),this.emit()}catch(B){this.log("Failed to hydrate cart",B)}}addItem(B){let F=this.normalizeItem(B);if(!F)return;let G=this.items.find((X)=>X.id===F.id);if(G){this.setQuantity(G.id,G.quantity+F.quantity);return}this.items=[...this.items,F],this.commit()}removeItem(B){this.items=this.items.filter((F)=>F.id!==B),this.commit()}setQuantity(B,F){let G=Math.floor(F);this.items=G<=0?this.items.filter((X)=>X.id!==B):this.items.map((X)=>X.id===B?{...X,quantity:G}:X),this.commit()}increment(B,F=1){let G=this.items.find((X)=>X.id===B);if(G)this.setQuantity(B,G.quantity+Math.max(1,Math.floor(F)))}decrement(B,F=1){let G=this.items.find((X)=>X.id===B);if(G)this.setQuantity(B,G.quantity-Math.max(1,Math.floor(F)))}clear(){if(this.items=[],this.persist&&this.storage)try{this.storage.removeItem(this.storageKey)}catch(B){this.log("Failed to clear cart storage",B)}this.emit()}removeDiscountForLineItem(B){this.items=this.items.map((F)=>{if(!U(F,{lineItemId:B,reason:"discount"}))return F;if(!F.discount)return F;let G={...F,unitPrice:F.fullPrice??F.unitPrice};return delete G.discount,delete G.discountEligibleTierOrProductIds,G}),this.commit()}async checkIfItemsAvailable(B){let F=[];for(let G of B){let X=await this.checkIfItemAvailable(this.defaultCheckoutLinkKey,G.lineItemId,G.discountId);if(X instanceof P)throw new P(X.code,X.message);F.push(X)}return F}async checkIfItemAvailable(B=this.defaultCheckoutLinkKey,F,G){let X=this.checkoutLinks[B];if(!X)throw new P("checkout_link_not_found",`Unknown checkout link key: ${B}`);let N=M(X),Z={siteKey:this.siteKey,checkoutLinkId:N.checkoutLinkId,mode:X.mode,lineItemId:F,...G?{discountId:G}:{}};try{let $=await this.post("/check-availability",Z);if(typeof $.ok!=="boolean")throw new P("request_failed","Availability check response was invalid.");let V=$;return{...V,available:V.ok===!0&&V.sold_out!==!0,sold_out:V.sold_out===!0,quantity_exceeded:V.quantity_exceeded===!0}}catch($){if($ instanceof P){if($.details?.length)this.reconcileCartAdjustments($.details);if($.code==="line_item_sold_out"||$.code==="product_unavailable"||$.code==="quantity_exceeded")return e($)}throw $}}async isCatalogLineSoldOut(B=this.defaultCheckoutLinkKey,F,G){let X=this.checkoutLinks[B];if(!X)throw new P("checkout_link_not_found",`Unknown checkout link key: ${B}`);let N=M(X),Z=q(F),$={siteKey:this.siteKey,checkoutLinkId:N.checkoutLinkId,mode:X.mode,items:[{lineItemId:Z,quantity:v(G?.quantity),...G?.discount?{discount:G.discount}:{}}]},V=await this.post("/validate-discounts",$);if(V.ok===!0)return!1;return E(V)?.some(f)??!1}async validateCheckout(B=this.defaultCheckoutLinkKey){let F=this.checkoutLinks[B];if(!F)throw new P("checkout_link_not_found",`Unknown checkout link key: ${B}`);let G=M(F),X=this.itemsForCheckout(B,F),N={siteKey:this.siteKey,checkoutLinkId:G.checkoutLinkId,mode:F.mode,...G.discountCode?{discountCode:G.discountCode}:{},...X.length>0?{items:X}:{}};try{let Z=await this.post("/validate-discounts",N);if(typeof Z.ok!=="boolean")throw new P("request_failed","Cart response was invalid.");if(Z.ok===!1){let $=b(typeof Z.code==="string"&&Z.code.length>0?Z.code:"request_failed"),V=typeof Z.message==="string"&&Z.message.length>0?Z.message:"Unable to validate cart.",Y=E(Z);if(W($))throw this.reconcileCartAdjustments(Y),new P($,V,200,Y);throw new P($,V,200,Y)}return Z}catch(Z){if(Z instanceof P){if(W(Z.code))throw this.reconcileCartAdjustments(Z.details),new P(Z.code,Z.message,Z.status,Z.details);throw new P(Z.code,Z.message,Z.status)}throw new P("request_failed","Failed to validate checkout.",void 0,void 0)}}async resolveCheckoutUrl(B=this.defaultCheckoutLinkKey){let F=this.checkoutLinks[B];if(!F)throw new P("checkout_link_not_found",`Unknown checkout link key: ${B}`);let G=M(F),X=this.itemsForCheckout(B,F),N={siteKey:this.siteKey,checkoutLinkId:G.checkoutLinkId,mode:F.mode,...G.discountCode?{discountCode:G.discountCode}:{},...X.length>0?{items:X}:{}};try{let Z=await this.post("/checkout-url",N);if(Z.ok!==!0||typeof Z.checkoutUrl!=="string"||Z.checkoutUrl.length===0)throw new P("request_failed","Cart response was invalid.");return w(Z.checkoutUrl,this.siteKey)}catch(Z){if(Z instanceof P){if(W(Z.code))throw this.reconcileCartAdjustments(Z.details),new P(Z.code,Z.message,Z.status,Z.details);throw new P(Z.code,Z.message,Z.status)}throw new P("request_failed","Failed to resolve checkout URL.",void 0,void 0)}}async checkout(B=this.defaultCheckoutLinkKey){try{let F=await this.resolveCheckoutUrl(B),G=T();if(G)G.location.assign(F);return F}catch(F){if(F instanceof P){if(W(F.code))throw this.reconcileCartAdjustments(F.details),new P(F.code,F.message,F.status,F.details);throw new P(F.code,F.message,F.status)}throw new P("request_failed","Failed to resolve checkout URL.",void 0,void 0)}}itemsForCheckout(B,F){if(F.mode==="static")return[];let G=this.items.filter((X)=>X.checkoutLinkKey===B).map((X)=>({lineItemId:q(X),quantity:X.quantity,...X.discount?{discount:X.discount}:{}}));if(G.length===0)throw new P("cart_empty","Your cart is empty.");return G}normalizeItem(B){let F=Q(B.accessTierId),G=Q(B.productId),X=Q(B.lineItemId)??F??G;if(!B.id||!X||typeof B.unitPrice!=="number")return null;let N=typeof B.name==="string"&&B.name.trim().length>0?B.name.trim():"Item";return{...B,id:B.id,lineItemId:X,...F?{accessTierId:F}:{},...G?{productId:G}:{},checkoutLinkKey:B.checkoutLinkKey??this.defaultCheckoutLinkKey,name:N,unitPrice:B.unitPrice,quantity:v(B.quantity)}}reconcileCartAdjustments(B){if(!B?.length)return;let F=[...this.items],G=!1;for(let X of B){if(X.discountCode){F=F.map((Z)=>{if(!U(Z,X))return Z;let $={...Z,unitPrice:Z.fullPrice??Z.unitPrice};return delete $.discount,delete $.discountEligibleTierOrProductIds,G=!0,$});continue}if(X.reason==="line_item_sold_out"||X.reason==="product_unavailable"||X.adjustedQuantity===0){let Z=F.length;if(F=F.filter(($)=>!U($,X)),F.length!==Z)G=!0;continue}if(X.reason==="quantity_exceeded"&&typeof X.adjustedQuantity==="number"&&X.adjustedQuantity>0){let Z=X.adjustedQuantity;F=F.map(($)=>{if(!U($,X))return $;return G=!0,{...$,quantity:Z}})}}if(!G)return;this.items=F,this.commit()}async post(B,F){let G=`${this.endpoint}${B}`,X=JSON.stringify(F),N={"Content-Type":"application/json"},Z={body:F,bodyText:X,endpoint:this.endpoint,headers:N,path:B,siteKey:this.siteKey,url:G},$=typeof this.requestHeaders==="function"?await this.requestHeaders(Z):this.requestHeaders,V=i(N,$),Y=await fetch(G,{method:"POST",headers:V,body:X}),J=await Y.json().catch(()=>null);if(!Y.ok){let L=typeof J?.code==="string"&&J.code.length>0?J.code:"request_failed",I=b(L),g=typeof J?.message==="string"&&J.message.length>0?J.message:"Cart request failed";throw new P(I,g,Y.status,E(J),typeof J?.available==="boolean"?J.available:void 0,typeof J?.sold_out==="boolean"?J.sold_out:void 0,typeof J?.quantity_exceeded==="boolean"?J.quantity_exceeded:void 0)}if(!J||typeof J!=="object")throw new P("request_failed","Cart response was invalid.",Y.status);return J}commit(){if(this.items=j(this.items),this.persist&&this.storage)try{let B={version:D,items:this.items};this.storage.setItem(this.storageKey,JSON.stringify(B))}catch(B){this.log("Failed to persist cart",B)}this.emit()}emit(){let B=this.getState();for(let F of this.listeners)F(B)}log(...B){if(this.debug)console.log("[@behindthescenes/cart]",...B)}}function BB(B){return O.init(B)}
|
|
1
|
+
var{defineProperty:O,getOwnPropertyNames:K,getOwnPropertyDescriptor:f}=Object,L=Object.prototype.hasOwnProperty;function x(B){return this[B]}var g=(B)=>{var F=(_??=new WeakMap).get(B),N;if(F)return F;if(F=O({},"__esModule",{value:!0}),B&&typeof B==="object"||typeof B==="function"){for(var G of K(B))if(!L.call(F,G))O(F,G,{get:x.bind(B,G),enumerable:!(N=f(B,G))||N.enumerable})}return _.set(B,F),F},_;var I=(B)=>B;function p(B,F){this[B]=I.bind(null,F)}var h=(B,F)=>{for(var N in F)O(B,N,{get:F[N],enumerable:!0,configurable:!0,set:p.bind(F,N)})};var r={};h(r,{resolveLineItemIdForCheckout:()=>w,createBTSCart:()=>n,catalogIdsForCartLine:()=>v,BTSCartError:()=>E,BTSCart:()=>H});module.exports=g(r);var A="https://api.bts.it.com/v2/website/cart",Q="bts-cart",R="default",z=2;function D(){try{return globalThis.window??null}catch{return null}}function Y(){try{return globalThis.localStorage??D()?.localStorage??null}catch{return null}}var y=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],k=["fbclid","gclid","gbraid","wbraid","ttclid","li_fat_id","msclkid","_fbp","_fbc"];function c(B){if(!B)return{utm:{},clickIds:{}};try{let F=JSON.parse(B);if(!F||typeof F!=="object"||Array.isArray(F))return{utm:{},clickIds:{}};let N=F,G=N.utm&&typeof N.utm==="object"&&!Array.isArray(N.utm)?Object.fromEntries(Object.entries(N.utm).filter((X)=>typeof X[1]==="string"&&X[1].length>0)):{},$=N.clickIds&&typeof N.clickIds==="object"&&!Array.isArray(N.clickIds)?Object.fromEntries(Object.entries(N.clickIds).filter((X)=>typeof X[1]==="string"&&X[1].length>0)):{};return{utm:G,clickIds:$}}catch{return{utm:{},clickIds:{}}}}function q(B,F){let N=new URL(B);N.searchParams.set("bts_site",F);let G=Y(),$=G?.getItem("bts_analytics_jt")?.trim();if($)N.searchParams.set("bts_jt",$);let{utm:X,clickIds:Z}=c(G?.getItem("bts_analytics_attr")??null);for(let V of y){let P=X[V];if(P)N.searchParams.set(V,P)}for(let V of k){let P=Z[V];if(P)N.searchParams.set(V,P)}return N.toString()}class E extends Error{code;status;available;sold_out;quantity_exceeded;details;constructor(B,F,N,G,$,X,Z){super(F);this.name="BTSCartError",this.code=B,this.status=N,this.details=G,this.available=$,this.sold_out=X,this.quantity_exceeded=Z}}function l(){return Y()??void 0}function u(B){return(B??A).replace(/\/$/,"")}function s(B){if(!Number.isFinite(B??1))return 1;return Math.max(1,Math.floor(B??1))}function S(B){return{items:B.map((F)=>({...F}))}}function U(B){let F=B?.trim();return F&&F.length>0?F:void 0}function w(B){return B.accessTierId??B.productId??B.lineItemId}function m(B){if(B.discountEligibleTierOrProductIds?.length)return[...new Set(B.discountEligibleTierOrProductIds.filter(Boolean))];return[...new Set([B.accessTierId,B.productId,B.lineItemId].filter((F)=>Boolean(F)))]}function C(B){let F=new Set;for(let N of B)for(let G of[N.lineItemId,N.accessTierId,N.productId])if(G)F.add(G);return B.map((N)=>{if(!N.discount)return N;let G=m(N);if(G.length===0||!G.some(($)=>F.has($))){let $={...N};return delete $.discount,delete $.discountEligibleTierOrProductIds,$}return N})}function d(B,F){let N=new Headers(B);if(!F)return N;return new Headers(F).forEach((G,$)=>N.set($,G)),N}function W(B){let F=B.checkoutLinkId.trim();try{let N=F.includes("://")?F:F.startsWith("/")?`https://bts-cart.invalid${F}`:F,G=new URL(N),$=G.pathname.split("/").filter(Boolean),X=$.indexOf("c"),Z=X>=0?$[X+1]:$.at(-1);if(Z)return{checkoutLinkId:Z,discountCode:B.discountCode??G.searchParams.get("discountCode")??void 0}}catch{}return{checkoutLinkId:F,discountCode:B.discountCode}}function a(B){let F=B?.details;if(!Array.isArray(F))return;let N=F.flatMap((G)=>{if(!G||typeof G!=="object")return[];let $=typeof G.lineItemId==="string"?G.lineItemId:"",X=typeof G.reason==="string"?G.reason:"";if(!$||!X)return[];let Z=typeof G.discountCode==="string"?G.discountCode:void 0,V=typeof G.requestedQuantity==="number"?G.requestedQuantity:void 0,P=typeof G.adjustedQuantity==="number"?G.adjustedQuantity:void 0;if(!Z&&!(V!==void 0||P!==void 0||X==="line_item_sold_out"||X==="quantity_exceeded"||X==="product_unavailable"))return[];return[{lineItemId:$,...typeof G.productId==="string"?{productId:G.productId}:{},...typeof G.accessTierId==="string"?{accessTierId:G.accessTierId}:{},...Z?{discountCode:Z}:{},...typeof G.discountId==="string"?{discountId:G.discountId}:{},reason:X,...V!==void 0?{requestedQuantity:V}:{},...P!==void 0?{adjustedQuantity:P}:{}}]});return N.length>0?N:void 0}var o=new Set(["discounts_invalid","quantity_invalid","cart_adjusted"]);function T(B){return o.has(B)}function v(B){return[...new Set([B.lineItemId,B.accessTierId,B.productId].filter((F)=>Boolean(F)))]}function M(B,F){let N=v(B);return[F.lineItemId,F.accessTierId,F.productId].filter(($)=>Boolean($)).some(($)=>N.includes($))}class H{siteKey;endpoint;debug;persist;storageKey;storage;checkoutLinks;defaultCheckoutLinkKey;requestHeaders;items=[];listeners=new Set;constructor(B){this.siteKey=B.siteKey,this.endpoint=u(B.endpoint),this.debug=B.debug??!1,this.persist=B.persist??!0,this.storageKey=B.storageKey??Q,this.storage=B.storage??l(),this.checkoutLinks=B.checkoutLinks??{},this.defaultCheckoutLinkKey=B.defaultCheckoutLinkKey??Object.keys(this.checkoutLinks)[0]??R,this.requestHeaders=B.requestHeaders,this.rehydrate()}static init(B){return new H(B)}getItems(){return S(this.items).items}getState(){return S(this.items)}getItemCount(){return this.items.reduce((B,F)=>B+F.quantity,0)}getSubtotal(){return this.items.reduce((B,F)=>B+(F.fullPrice??F.unitPrice)*F.quantity,0)}getTotal(){return this.items.reduce((B,F)=>B+F.unitPrice*F.quantity,0)}subscribe(B){return this.listeners.add(B),B(this.getState()),()=>{this.listeners.delete(B)}}destroy(){this.listeners.clear()}rehydrate(){if(!this.persist||!this.storage)return;try{let B=this.storage.getItem(this.storageKey);if(!B)return;let F=JSON.parse(B);if(Array.isArray(F)||F.version!==z){this.storage.removeItem(this.storageKey);return}let N=F.items;if(!Array.isArray(N))return;this.items=C(N.map((G)=>this.normalizeItem(G)).filter((G)=>Boolean(G))),this.emit()}catch(B){this.log("Failed to hydrate cart",B)}}addItem(B){let F=this.normalizeItem(B);if(!F)return;let N=this.items.find((G)=>G.id===F.id);if(N){this.setQuantity(N.id,N.quantity+F.quantity);return}this.items=[...this.items,F],this.commit()}removeItem(B){this.items=this.items.filter((F)=>F.id!==B),this.commit()}setQuantity(B,F){let N=Math.floor(F);this.items=N<=0?this.items.filter((G)=>G.id!==B):this.items.map((G)=>G.id===B?{...G,quantity:N}:G),this.commit()}increment(B,F=1){let N=this.items.find((G)=>G.id===B);if(N)this.setQuantity(B,N.quantity+Math.max(1,Math.floor(F)))}decrement(B,F=1){let N=this.items.find((G)=>G.id===B);if(N)this.setQuantity(B,N.quantity-Math.max(1,Math.floor(F)))}clear(){if(this.items=[],this.persist&&this.storage)try{this.storage.removeItem(this.storageKey)}catch(B){this.log("Failed to clear cart storage",B)}this.emit()}removeDiscountForLineItem(B){this.items=this.items.map((F)=>{if(!M(F,{lineItemId:B,reason:"discount"}))return F;if(!F.discount)return F;let N={...F,unitPrice:F.fullPrice??F.unitPrice};return delete N.discount,delete N.discountEligibleTierOrProductIds,N}),this.commit()}async checkIfItemsAvailable(B){let F=[];for(let N of B){let G=await this.checkIfItemAvailable(this.defaultCheckoutLinkKey,N.lineItemId,N.discountId);if(G instanceof E)throw new E(G.code,G.message);F.push(G)}return F}async checkIfItemAvailable(B=this.defaultCheckoutLinkKey,F,N){let G=this.checkoutLinks[B];if(!G)throw new E("checkout_link_not_found",`Unknown checkout link key: ${B}`);let $=W(G),X={siteKey:this.siteKey,checkoutLinkId:$.checkoutLinkId,mode:G.mode,lineItemId:F,...N?{discountId:N}:{}};try{let Z=await this.post("/check-availability",X);if(typeof Z.ok!=="boolean")throw new E("request_failed","Availability check response was invalid.");return Z}catch(Z){if(Z instanceof E){if(Z.details?.length)this.reconcileCartAdjustments(Z.details);if(Z.code==="line_item_sold_out"||Z.code==="product_unavailable"||Z.code==="quantity_exceeded")return{ok:!1,available:Z.available??!1,sold_out:Z.sold_out??Z.code==="line_item_sold_out",quantity_exceeded:Z.quantity_exceeded??(Z.code==="line_item_sold_out"||Z.code==="quantity_exceeded")}}throw Z}}async validateCheckout(B=this.defaultCheckoutLinkKey){let F=this.checkoutLinks[B];if(!F)throw new E("checkout_link_not_found",`Unknown checkout link key: ${B}`);let N=W(F),G=this.itemsForCheckout(B,F),$={siteKey:this.siteKey,checkoutLinkId:N.checkoutLinkId,mode:F.mode,...N.discountCode?{discountCode:N.discountCode}:{},...G.length>0?{items:G}:{}};try{let X=await this.post("/validate-discounts",$);if(typeof X.ok!=="boolean")throw new E("request_failed","Cart response was invalid.");return X}catch(X){if(X instanceof E){if(T(X.code))throw this.reconcileCartAdjustments(X.details),new E(X.code,X.message,X.status,X.details);throw new E(X.code,X.message,X.status)}throw new E("request_failed","Failed to validate checkout.",void 0,void 0)}}async resolveCheckoutUrl(B=this.defaultCheckoutLinkKey){let F=this.checkoutLinks[B];if(!F)throw new E("checkout_link_not_found",`Unknown checkout link key: ${B}`);let N=W(F),G=this.itemsForCheckout(B,F),$={siteKey:this.siteKey,checkoutLinkId:N.checkoutLinkId,mode:F.mode,...N.discountCode?{discountCode:N.discountCode}:{},...G.length>0?{items:G}:{}};try{let X=await this.post("/checkout-url",$);if(X.ok!==!0||typeof X.checkoutUrl!=="string"||X.checkoutUrl.length===0)throw new E("request_failed","Cart response was invalid.");return q(X.checkoutUrl,this.siteKey)}catch(X){if(X instanceof E){if(T(X.code))throw this.reconcileCartAdjustments(X.details),new E(X.code,X.message,X.status,X.details);throw new E(X.code,X.message,X.status)}throw new E("request_failed","Failed to resolve checkout URL.",void 0,void 0)}}async checkout(B=this.defaultCheckoutLinkKey){try{let F=await this.resolveCheckoutUrl(B),N=D();if(N)N.location.assign(F);return F}catch(F){if(F instanceof E){if(T(F.code))throw this.reconcileCartAdjustments(F.details),new E(F.code,F.message,F.status,F.details);throw new E(F.code,F.message,F.status)}throw new E("request_failed","Failed to resolve checkout URL.",void 0,void 0)}}itemsForCheckout(B,F){if(F.mode==="static")return[];let N=this.items.filter((G)=>G.checkoutLinkKey===B).map((G)=>({lineItemId:w(G),quantity:G.quantity,...G.discount?{discount:G.discount}:{}}));if(N.length===0)throw new E("cart_empty","Your cart is empty.");return N}normalizeItem(B){let F=U(B.accessTierId),N=U(B.productId),G=U(B.lineItemId)??F??N;if(!B.id||!G||typeof B.unitPrice!=="number")return null;let $=typeof B.name==="string"&&B.name.trim().length>0?B.name.trim():"Item";return{...B,id:B.id,lineItemId:G,...F?{accessTierId:F}:{},...N?{productId:N}:{},checkoutLinkKey:B.checkoutLinkKey??this.defaultCheckoutLinkKey,name:$,unitPrice:B.unitPrice,quantity:s(B.quantity)}}reconcileCartAdjustments(B){if(!B?.length)return;let F=[...this.items],N=!1;for(let G of B){if(G.discountCode){F=F.map((X)=>{if(!M(X,G))return X;let Z={...X,unitPrice:X.fullPrice??X.unitPrice};return delete Z.discount,delete Z.discountEligibleTierOrProductIds,N=!0,Z});continue}if(G.reason==="line_item_sold_out"||G.reason==="product_unavailable"||G.adjustedQuantity===0){let X=F.length;if(F=F.filter((Z)=>!M(Z,G)),F.length!==X)N=!0;continue}if(G.reason==="quantity_exceeded"&&typeof G.adjustedQuantity==="number"&&G.adjustedQuantity>0){let X=G.adjustedQuantity;F=F.map((Z)=>{if(!M(Z,G))return Z;return N=!0,{...Z,quantity:X}})}}if(!N)return;this.items=F,this.commit()}async post(B,F){let N=`${this.endpoint}${B}`,G=JSON.stringify(F),$={"Content-Type":"application/json"},X={body:F,bodyText:G,endpoint:this.endpoint,headers:$,path:B,siteKey:this.siteKey,url:N},Z=typeof this.requestHeaders==="function"?await this.requestHeaders(X):this.requestHeaders,V=d($,Z),P=await fetch(N,{method:"POST",headers:V,body:G}),J=await P.json().catch(()=>null);if(!P.ok){let b=typeof J?.code==="string"&&J.code.length>0?J.code:"request_failed",j=typeof J?.message==="string"&&J.message.length>0?J.message:"Cart request failed";throw new E(b,j,P.status,a(J),typeof J?.available==="boolean"?J.available:void 0,typeof J?.sold_out==="boolean"?J.sold_out:void 0,typeof J?.quantity_exceeded==="boolean"?J.quantity_exceeded:void 0)}if(!J||typeof J!=="object")throw new E("request_failed","Cart response was invalid.",P.status);return J}commit(){if(this.items=C(this.items),this.persist&&this.storage)try{let B={version:z,items:this.items};this.storage.setItem(this.storageKey,JSON.stringify(B))}catch(B){this.log("Failed to persist cart",B)}this.emit()}emit(){let B=this.getState();for(let F of this.listeners)F(B)}log(...B){if(this.debug)console.log("[@behindthescenes/cart]",...B)}}function n(B){return H.init(B)}
|
package/dist/esm/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var Q="https://api.bts.it.com/v2/website/cart",q="bts-cart",_="default",E=2;function O(){try{return globalThis.window??null}catch{return null}}function H(){try{return globalThis.localStorage??O()?.localStorage??null}catch{return null}}var x=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],L=["fbclid","gclid","gbraid","wbraid","ttclid","li_fat_id","msclkid","_fbp","_fbc"];function I(B){if(!B)return{utm:{},clickIds:{}};try{let F=JSON.parse(B);if(!F||typeof F!=="object"||Array.isArray(F))return{utm:{},clickIds:{}};let X=F,G=X.utm&&typeof X.utm==="object"&&!Array.isArray(X.utm)?Object.fromEntries(Object.entries(X.utm).filter((Z)=>typeof Z[1]==="string"&&Z[1].length>0)):{},N=X.clickIds&&typeof X.clickIds==="object"&&!Array.isArray(X.clickIds)?Object.fromEntries(Object.entries(X.clickIds).filter((Z)=>typeof Z[1]==="string"&&Z[1].length>0)):{};return{utm:G,clickIds:N}}catch{return{utm:{},clickIds:{}}}}function R(B,F){let X=new URL(B);X.searchParams.set("bts_site",F);let G=H(),N=G?.getItem("bts_analytics_jt")?.trim();if(N)X.searchParams.set("bts_jt",N);let{utm:Z,clickIds:$}=I(G?.getItem("bts_analytics_attr")??null);for(let V of x){let Y=Z[V];if(Y)X.searchParams.set(V,Y)}for(let V of L){let Y=$[V];if(Y)X.searchParams.set(V,Y)}return X.toString()}class P extends Error{code;status;available;sold_out;quantity_exceeded;details;constructor(B,F,X,G,N,Z,$){super(F);this.name="BTSCartError",this.code=B,this.status=X,this.details=G,this.available=N,this.sold_out=Z,this.quantity_exceeded=$}}function g(){return H()??void 0}function p(B){return(B??Q).replace(/\/$/,"")}function S(B){if(!Number.isFinite(B??1))return 1;return Math.max(1,Math.floor(B??1))}function A(B){return{items:B.map((F)=>({...F}))}}function z(B){let F=B?.trim();return F&&F.length>0?F:void 0}function w(B){return B.accessTierId??B.productId??B.lineItemId}function h(B){if(B.discountEligibleTierOrProductIds?.length)return[...new Set(B.discountEligibleTierOrProductIds.filter(Boolean))];return[...new Set([B.accessTierId,B.productId,B.lineItemId].filter((F)=>Boolean(F)))]}function v(B){let F=new Set;for(let X of B)for(let G of[X.lineItemId,X.accessTierId,X.productId])if(G)F.add(G);return B.map((X)=>{if(!X.discount)return X;let G=h(X);if(G.length===0||!G.some((N)=>F.has(N))){let N={...X};return delete N.discount,delete N.discountEligibleTierOrProductIds,N}return X})}function y(B,F){let X=new Headers(B);if(!F)return X;return new Headers(F).forEach((G,N)=>X.set(N,G)),X}function M(B){let F=B.checkoutLinkId.trim();try{let X=F.includes("://")?F:F.startsWith("/")?`https://bts-cart.invalid${F}`:F,G=new URL(X),N=G.pathname.split("/").filter(Boolean),Z=N.indexOf("c"),$=Z>=0?N[Z+1]:N.at(-1);if($)return{checkoutLinkId:$,discountCode:B.discountCode??G.searchParams.get("discountCode")??void 0}}catch{}return{checkoutLinkId:F,discountCode:B.discountCode}}function D(B){let F=B?.details;if(!Array.isArray(F))return;let X=F.flatMap((G)=>{if(!G||typeof G!=="object")return[];let N=typeof G.lineItemId==="string"?G.lineItemId:"",Z=typeof G.reason==="string"?G.reason:"";if(!N||!Z)return[];let $=typeof G.discountCode==="string"?G.discountCode:void 0,V=typeof G.requestedQuantity==="number"?G.requestedQuantity:void 0,Y=typeof G.adjustedQuantity==="number"?G.adjustedQuantity:void 0;if(!$&&!(V!==void 0||Y!==void 0||Z==="line_item_sold_out"||Z==="quantity_exceeded"||Z==="product_unavailable"))return[];return[{lineItemId:N,...typeof G.productId==="string"?{productId:G.productId}:{},...typeof G.accessTierId==="string"?{accessTierId:G.accessTierId}:{},...$?{discountCode:$}:{},...typeof G.discountId==="string"?{discountId:G.discountId}:{},reason:Z,...V!==void 0?{requestedQuantity:V}:{},...Y!==void 0?{adjustedQuantity:Y}:{}}]});return X.length>0?X:void 0}var j=new Set(["discounts_invalid","quantity_invalid","cart_adjusted"]);function k(B){return B.reason==="line_item_sold_out"||B.reason==="product_unavailable"||B.adjustedQuantity===0}function BB(B){return j.has(B)||B==="invalid_quantities"||B==="invalid_discounts"}function C(B){if(B==="invalid_quantities")return"quantity_invalid";if(B==="invalid_discounts")return"discounts_invalid";return B}function W(B){return j.has(B)}function c(B){let F=B.sold_out===!0||B.code==="line_item_sold_out"||B.code==="product_unavailable",X=B.quantity_exceeded===!0||B.code==="quantity_exceeded";return{ok:!1,available:!F,sold_out:F,quantity_exceeded:X}}function u(B){return[...new Set([B.lineItemId,B.accessTierId,B.productId].filter((F)=>Boolean(F)))]}function U(B,F){let X=u(B);return[F.lineItemId,F.accessTierId,F.productId].filter((N)=>Boolean(N)).some((N)=>X.includes(N))}class T{siteKey;endpoint;debug;persist;storageKey;storage;checkoutLinks;defaultCheckoutLinkKey;requestHeaders;items=[];listeners=new Set;constructor(B){this.siteKey=B.siteKey,this.endpoint=p(B.endpoint),this.debug=B.debug??!1,this.persist=B.persist??!0,this.storageKey=B.storageKey??q,this.storage=B.storage??g(),this.checkoutLinks=B.checkoutLinks??{},this.defaultCheckoutLinkKey=B.defaultCheckoutLinkKey??Object.keys(this.checkoutLinks)[0]??_,this.requestHeaders=B.requestHeaders,this.rehydrate()}static init(B){return new T(B)}getItems(){return A(this.items).items}getState(){return A(this.items)}getItemCount(){return this.items.reduce((B,F)=>B+F.quantity,0)}getSubtotal(){return this.items.reduce((B,F)=>B+(F.fullPrice??F.unitPrice)*F.quantity,0)}getTotal(){return this.items.reduce((B,F)=>B+F.unitPrice*F.quantity,0)}subscribe(B){return this.listeners.add(B),B(this.getState()),()=>{this.listeners.delete(B)}}destroy(){this.listeners.clear()}rehydrate(){if(!this.persist||!this.storage)return;try{let B=this.storage.getItem(this.storageKey);if(!B)return;let F=JSON.parse(B);if(Array.isArray(F)||F.version!==E){this.storage.removeItem(this.storageKey);return}let X=F.items;if(!Array.isArray(X))return;this.items=v(X.map((G)=>this.normalizeItem(G)).filter((G)=>Boolean(G))),this.emit()}catch(B){this.log("Failed to hydrate cart",B)}}addItem(B){let F=this.normalizeItem(B);if(!F)return;let X=this.items.find((G)=>G.id===F.id);if(X){this.setQuantity(X.id,X.quantity+F.quantity);return}this.items=[...this.items,F],this.commit()}removeItem(B){this.items=this.items.filter((F)=>F.id!==B),this.commit()}setQuantity(B,F){let X=Math.floor(F);this.items=X<=0?this.items.filter((G)=>G.id!==B):this.items.map((G)=>G.id===B?{...G,quantity:X}:G),this.commit()}increment(B,F=1){let X=this.items.find((G)=>G.id===B);if(X)this.setQuantity(B,X.quantity+Math.max(1,Math.floor(F)))}decrement(B,F=1){let X=this.items.find((G)=>G.id===B);if(X)this.setQuantity(B,X.quantity-Math.max(1,Math.floor(F)))}clear(){if(this.items=[],this.persist&&this.storage)try{this.storage.removeItem(this.storageKey)}catch(B){this.log("Failed to clear cart storage",B)}this.emit()}removeDiscountForLineItem(B){this.items=this.items.map((F)=>{if(!U(F,{lineItemId:B,reason:"discount"}))return F;if(!F.discount)return F;let X={...F,unitPrice:F.fullPrice??F.unitPrice};return delete X.discount,delete X.discountEligibleTierOrProductIds,X}),this.commit()}async checkIfItemsAvailable(B){let F=[];for(let X of B){let G=await this.checkIfItemAvailable(this.defaultCheckoutLinkKey,X.lineItemId,X.discountId);if(G instanceof P)throw new P(G.code,G.message);F.push(G)}return F}async checkIfItemAvailable(B=this.defaultCheckoutLinkKey,F,X){let G=this.checkoutLinks[B];if(!G)throw new P("checkout_link_not_found",`Unknown checkout link key: ${B}`);let N=M(G),Z={siteKey:this.siteKey,checkoutLinkId:N.checkoutLinkId,mode:G.mode,lineItemId:F,...X?{discountId:X}:{}};try{let $=await this.post("/check-availability",Z);if(typeof $.ok!=="boolean")throw new P("request_failed","Availability check response was invalid.");let V=$;return{...V,available:V.ok===!0&&V.sold_out!==!0,sold_out:V.sold_out===!0,quantity_exceeded:V.quantity_exceeded===!0}}catch($){if($ instanceof P){if($.details?.length)this.reconcileCartAdjustments($.details);if($.code==="line_item_sold_out"||$.code==="product_unavailable"||$.code==="quantity_exceeded")return c($)}throw $}}async isCatalogLineSoldOut(B=this.defaultCheckoutLinkKey,F,X){let G=this.checkoutLinks[B];if(!G)throw new P("checkout_link_not_found",`Unknown checkout link key: ${B}`);let N=M(G),Z=w(F),$={siteKey:this.siteKey,checkoutLinkId:N.checkoutLinkId,mode:G.mode,items:[{lineItemId:Z,quantity:S(X?.quantity),...X?.discount?{discount:X.discount}:{}}]},V=await this.post("/validate-discounts",$);if(V.ok===!0)return!1;return D(V)?.some(k)??!1}async validateCheckout(B=this.defaultCheckoutLinkKey){let F=this.checkoutLinks[B];if(!F)throw new P("checkout_link_not_found",`Unknown checkout link key: ${B}`);let X=M(F),G=this.itemsForCheckout(B,F),N={siteKey:this.siteKey,checkoutLinkId:X.checkoutLinkId,mode:F.mode,...X.discountCode?{discountCode:X.discountCode}:{},...G.length>0?{items:G}:{}};try{let Z=await this.post("/validate-discounts",N);if(typeof Z.ok!=="boolean")throw new P("request_failed","Cart response was invalid.");if(Z.ok===!1){let $=C(typeof Z.code==="string"&&Z.code.length>0?Z.code:"request_failed"),V=typeof Z.message==="string"&&Z.message.length>0?Z.message:"Unable to validate cart.",Y=D(Z);if(W($))throw this.reconcileCartAdjustments(Y),new P($,V,200,Y);throw new P($,V,200,Y)}return Z}catch(Z){if(Z instanceof P){if(W(Z.code))throw this.reconcileCartAdjustments(Z.details),new P(Z.code,Z.message,Z.status,Z.details);throw new P(Z.code,Z.message,Z.status)}throw new P("request_failed","Failed to validate checkout.",void 0,void 0)}}async resolveCheckoutUrl(B=this.defaultCheckoutLinkKey){let F=this.checkoutLinks[B];if(!F)throw new P("checkout_link_not_found",`Unknown checkout link key: ${B}`);let X=M(F),G=this.itemsForCheckout(B,F),N={siteKey:this.siteKey,checkoutLinkId:X.checkoutLinkId,mode:F.mode,...X.discountCode?{discountCode:X.discountCode}:{},...G.length>0?{items:G}:{}};try{let Z=await this.post("/checkout-url",N);if(Z.ok!==!0||typeof Z.checkoutUrl!=="string"||Z.checkoutUrl.length===0)throw new P("request_failed","Cart response was invalid.");return R(Z.checkoutUrl,this.siteKey)}catch(Z){if(Z instanceof P){if(W(Z.code))throw this.reconcileCartAdjustments(Z.details),new P(Z.code,Z.message,Z.status,Z.details);throw new P(Z.code,Z.message,Z.status)}throw new P("request_failed","Failed to resolve checkout URL.",void 0,void 0)}}async checkout(B=this.defaultCheckoutLinkKey){try{let F=await this.resolveCheckoutUrl(B),X=O();if(X)X.location.assign(F);return F}catch(F){if(F instanceof P){if(W(F.code))throw this.reconcileCartAdjustments(F.details),new P(F.code,F.message,F.status,F.details);throw new P(F.code,F.message,F.status)}throw new P("request_failed","Failed to resolve checkout URL.",void 0,void 0)}}itemsForCheckout(B,F){if(F.mode==="static")return[];let X=this.items.filter((G)=>G.checkoutLinkKey===B).map((G)=>({lineItemId:w(G),quantity:G.quantity,...G.discount?{discount:G.discount}:{}}));if(X.length===0)throw new P("cart_empty","Your cart is empty.");return X}normalizeItem(B){let F=z(B.accessTierId),X=z(B.productId),G=z(B.lineItemId)??F??X;if(!B.id||!G||typeof B.unitPrice!=="number")return null;let N=typeof B.name==="string"&&B.name.trim().length>0?B.name.trim():"Item";return{...B,id:B.id,lineItemId:G,...F?{accessTierId:F}:{},...X?{productId:X}:{},checkoutLinkKey:B.checkoutLinkKey??this.defaultCheckoutLinkKey,name:N,unitPrice:B.unitPrice,quantity:S(B.quantity)}}reconcileCartAdjustments(B){if(!B?.length)return;let F=[...this.items],X=!1;for(let G of B){if(G.discountCode){F=F.map((Z)=>{if(!U(Z,G))return Z;let $={...Z,unitPrice:Z.fullPrice??Z.unitPrice};return delete $.discount,delete $.discountEligibleTierOrProductIds,X=!0,$});continue}if(G.reason==="line_item_sold_out"||G.reason==="product_unavailable"||G.adjustedQuantity===0){let Z=F.length;if(F=F.filter(($)=>!U($,G)),F.length!==Z)X=!0;continue}if(G.reason==="quantity_exceeded"&&typeof G.adjustedQuantity==="number"&&G.adjustedQuantity>0){let Z=G.adjustedQuantity;F=F.map(($)=>{if(!U($,G))return $;return X=!0,{...$,quantity:Z}})}}if(!X)return;this.items=F,this.commit()}async post(B,F){let X=`${this.endpoint}${B}`,G=JSON.stringify(F),N={"Content-Type":"application/json"},Z={body:F,bodyText:G,endpoint:this.endpoint,headers:N,path:B,siteKey:this.siteKey,url:X},$=typeof this.requestHeaders==="function"?await this.requestHeaders(Z):this.requestHeaders,V=y(N,$),Y=await fetch(X,{method:"POST",headers:V,body:G}),J=await Y.json().catch(()=>null);if(!Y.ok){let b=typeof J?.code==="string"&&J.code.length>0?J.code:"request_failed",K=C(b),f=typeof J?.message==="string"&&J.message.length>0?J.message:"Cart request failed";throw new P(K,f,Y.status,D(J),typeof J?.available==="boolean"?J.available:void 0,typeof J?.sold_out==="boolean"?J.sold_out:void 0,typeof J?.quantity_exceeded==="boolean"?J.quantity_exceeded:void 0)}if(!J||typeof J!=="object")throw new P("request_failed","Cart response was invalid.",Y.status);return J}commit(){if(this.items=v(this.items),this.persist&&this.storage)try{let B={version:E,items:this.items};this.storage.setItem(this.storageKey,JSON.stringify(B))}catch(B){this.log("Failed to persist cart",B)}this.emit()}emit(){let B=this.getState();for(let F of this.listeners)F(B)}log(...B){if(this.debug)console.log("[@behindthescenes/cart]",...B)}}function FB(B){return T.init(B)}export{w as resolveLineItemIdForCheckout,D as normalizeCartAdjustmentDetails,k as isSoldOutAdjustmentDetail,BB as isCartAdjustmentErrorCode,FB as createBTSCart,u as catalogIdsForCartLine,P as BTSCartError,T as BTSCart};
|
|
1
|
+
var T="https://api.bts.it.com/v2/website/cart",_="bts-cart",A="default",H=2;function O(){try{return globalThis.window??null}catch{return null}}function Y(){try{return globalThis.localStorage??O()?.localStorage??null}catch{return null}}var w=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],v=["fbclid","gclid","gbraid","wbraid","ttclid","li_fat_id","msclkid","_fbp","_fbc"];function b(B){if(!B)return{utm:{},clickIds:{}};try{let F=JSON.parse(B);if(!F||typeof F!=="object"||Array.isArray(F))return{utm:{},clickIds:{}};let N=F,G=N.utm&&typeof N.utm==="object"&&!Array.isArray(N.utm)?Object.fromEntries(Object.entries(N.utm).filter((X)=>typeof X[1]==="string"&&X[1].length>0)):{},$=N.clickIds&&typeof N.clickIds==="object"&&!Array.isArray(N.clickIds)?Object.fromEntries(Object.entries(N.clickIds).filter((X)=>typeof X[1]==="string"&&X[1].length>0)):{};return{utm:G,clickIds:$}}catch{return{utm:{},clickIds:{}}}}function Q(B,F){let N=new URL(B);N.searchParams.set("bts_site",F);let G=Y(),$=G?.getItem("bts_analytics_jt")?.trim();if($)N.searchParams.set("bts_jt",$);let{utm:X,clickIds:Z}=b(G?.getItem("bts_analytics_attr")??null);for(let V of w){let P=X[V];if(P)N.searchParams.set(V,P)}for(let V of v){let P=Z[V];if(P)N.searchParams.set(V,P)}return N.toString()}class E extends Error{code;status;available;sold_out;quantity_exceeded;details;constructor(B,F,N,G,$,X,Z){super(F);this.name="BTSCartError",this.code=B,this.status=N,this.details=G,this.available=$,this.sold_out=X,this.quantity_exceeded=Z}}function j(){return Y()??void 0}function K(B){return(B??T).replace(/\/$/,"")}function f(B){if(!Number.isFinite(B??1))return 1;return Math.max(1,Math.floor(B??1))}function R(B){return{items:B.map((F)=>({...F}))}}function z(B){let F=B?.trim();return F&&F.length>0?F:void 0}function L(B){return B.accessTierId??B.productId??B.lineItemId}function x(B){if(B.discountEligibleTierOrProductIds?.length)return[...new Set(B.discountEligibleTierOrProductIds.filter(Boolean))];return[...new Set([B.accessTierId,B.productId,B.lineItemId].filter((F)=>Boolean(F)))]}function q(B){let F=new Set;for(let N of B)for(let G of[N.lineItemId,N.accessTierId,N.productId])if(G)F.add(G);return B.map((N)=>{if(!N.discount)return N;let G=x(N);if(G.length===0||!G.some(($)=>F.has($))){let $={...N};return delete $.discount,delete $.discountEligibleTierOrProductIds,$}return N})}function g(B,F){let N=new Headers(B);if(!F)return N;return new Headers(F).forEach((G,$)=>N.set($,G)),N}function D(B){let F=B.checkoutLinkId.trim();try{let N=F.includes("://")?F:F.startsWith("/")?`https://bts-cart.invalid${F}`:F,G=new URL(N),$=G.pathname.split("/").filter(Boolean),X=$.indexOf("c"),Z=X>=0?$[X+1]:$.at(-1);if(Z)return{checkoutLinkId:Z,discountCode:B.discountCode??G.searchParams.get("discountCode")??void 0}}catch{}return{checkoutLinkId:F,discountCode:B.discountCode}}function I(B){let F=B?.details;if(!Array.isArray(F))return;let N=F.flatMap((G)=>{if(!G||typeof G!=="object")return[];let $=typeof G.lineItemId==="string"?G.lineItemId:"",X=typeof G.reason==="string"?G.reason:"";if(!$||!X)return[];let Z=typeof G.discountCode==="string"?G.discountCode:void 0,V=typeof G.requestedQuantity==="number"?G.requestedQuantity:void 0,P=typeof G.adjustedQuantity==="number"?G.adjustedQuantity:void 0;if(!Z&&!(V!==void 0||P!==void 0||X==="line_item_sold_out"||X==="quantity_exceeded"||X==="product_unavailable"))return[];return[{lineItemId:$,...typeof G.productId==="string"?{productId:G.productId}:{},...typeof G.accessTierId==="string"?{accessTierId:G.accessTierId}:{},...Z?{discountCode:Z}:{},...typeof G.discountId==="string"?{discountId:G.discountId}:{},reason:X,...V!==void 0?{requestedQuantity:V}:{},...P!==void 0?{adjustedQuantity:P}:{}}]});return N.length>0?N:void 0}var p=new Set(["discounts_invalid","quantity_invalid","cart_adjusted"]);function U(B){return p.has(B)}function h(B){return[...new Set([B.lineItemId,B.accessTierId,B.productId].filter((F)=>Boolean(F)))]}function M(B,F){let N=h(B);return[F.lineItemId,F.accessTierId,F.productId].filter(($)=>Boolean($)).some(($)=>N.includes($))}class W{siteKey;endpoint;debug;persist;storageKey;storage;checkoutLinks;defaultCheckoutLinkKey;requestHeaders;items=[];listeners=new Set;constructor(B){this.siteKey=B.siteKey,this.endpoint=K(B.endpoint),this.debug=B.debug??!1,this.persist=B.persist??!0,this.storageKey=B.storageKey??_,this.storage=B.storage??j(),this.checkoutLinks=B.checkoutLinks??{},this.defaultCheckoutLinkKey=B.defaultCheckoutLinkKey??Object.keys(this.checkoutLinks)[0]??A,this.requestHeaders=B.requestHeaders,this.rehydrate()}static init(B){return new W(B)}getItems(){return R(this.items).items}getState(){return R(this.items)}getItemCount(){return this.items.reduce((B,F)=>B+F.quantity,0)}getSubtotal(){return this.items.reduce((B,F)=>B+(F.fullPrice??F.unitPrice)*F.quantity,0)}getTotal(){return this.items.reduce((B,F)=>B+F.unitPrice*F.quantity,0)}subscribe(B){return this.listeners.add(B),B(this.getState()),()=>{this.listeners.delete(B)}}destroy(){this.listeners.clear()}rehydrate(){if(!this.persist||!this.storage)return;try{let B=this.storage.getItem(this.storageKey);if(!B)return;let F=JSON.parse(B);if(Array.isArray(F)||F.version!==H){this.storage.removeItem(this.storageKey);return}let N=F.items;if(!Array.isArray(N))return;this.items=q(N.map((G)=>this.normalizeItem(G)).filter((G)=>Boolean(G))),this.emit()}catch(B){this.log("Failed to hydrate cart",B)}}addItem(B){let F=this.normalizeItem(B);if(!F)return;let N=this.items.find((G)=>G.id===F.id);if(N){this.setQuantity(N.id,N.quantity+F.quantity);return}this.items=[...this.items,F],this.commit()}removeItem(B){this.items=this.items.filter((F)=>F.id!==B),this.commit()}setQuantity(B,F){let N=Math.floor(F);this.items=N<=0?this.items.filter((G)=>G.id!==B):this.items.map((G)=>G.id===B?{...G,quantity:N}:G),this.commit()}increment(B,F=1){let N=this.items.find((G)=>G.id===B);if(N)this.setQuantity(B,N.quantity+Math.max(1,Math.floor(F)))}decrement(B,F=1){let N=this.items.find((G)=>G.id===B);if(N)this.setQuantity(B,N.quantity-Math.max(1,Math.floor(F)))}clear(){if(this.items=[],this.persist&&this.storage)try{this.storage.removeItem(this.storageKey)}catch(B){this.log("Failed to clear cart storage",B)}this.emit()}removeDiscountForLineItem(B){this.items=this.items.map((F)=>{if(!M(F,{lineItemId:B,reason:"discount"}))return F;if(!F.discount)return F;let N={...F,unitPrice:F.fullPrice??F.unitPrice};return delete N.discount,delete N.discountEligibleTierOrProductIds,N}),this.commit()}async checkIfItemsAvailable(B){let F=[];for(let N of B){let G=await this.checkIfItemAvailable(this.defaultCheckoutLinkKey,N.lineItemId,N.discountId);if(G instanceof E)throw new E(G.code,G.message);F.push(G)}return F}async checkIfItemAvailable(B=this.defaultCheckoutLinkKey,F,N){let G=this.checkoutLinks[B];if(!G)throw new E("checkout_link_not_found",`Unknown checkout link key: ${B}`);let $=D(G),X={siteKey:this.siteKey,checkoutLinkId:$.checkoutLinkId,mode:G.mode,lineItemId:F,...N?{discountId:N}:{}};try{let Z=await this.post("/check-availability",X);if(typeof Z.ok!=="boolean")throw new E("request_failed","Availability check response was invalid.");return Z}catch(Z){if(Z instanceof E){if(Z.details?.length)this.reconcileCartAdjustments(Z.details);if(Z.code==="line_item_sold_out"||Z.code==="product_unavailable"||Z.code==="quantity_exceeded")return{ok:!1,available:Z.available??!1,sold_out:Z.sold_out??Z.code==="line_item_sold_out",quantity_exceeded:Z.quantity_exceeded??(Z.code==="line_item_sold_out"||Z.code==="quantity_exceeded")}}throw Z}}async validateCheckout(B=this.defaultCheckoutLinkKey){let F=this.checkoutLinks[B];if(!F)throw new E("checkout_link_not_found",`Unknown checkout link key: ${B}`);let N=D(F),G=this.itemsForCheckout(B,F),$={siteKey:this.siteKey,checkoutLinkId:N.checkoutLinkId,mode:F.mode,...N.discountCode?{discountCode:N.discountCode}:{},...G.length>0?{items:G}:{}};try{let X=await this.post("/validate-discounts",$);if(typeof X.ok!=="boolean")throw new E("request_failed","Cart response was invalid.");return X}catch(X){if(X instanceof E){if(U(X.code))throw this.reconcileCartAdjustments(X.details),new E(X.code,X.message,X.status,X.details);throw new E(X.code,X.message,X.status)}throw new E("request_failed","Failed to validate checkout.",void 0,void 0)}}async resolveCheckoutUrl(B=this.defaultCheckoutLinkKey){let F=this.checkoutLinks[B];if(!F)throw new E("checkout_link_not_found",`Unknown checkout link key: ${B}`);let N=D(F),G=this.itemsForCheckout(B,F),$={siteKey:this.siteKey,checkoutLinkId:N.checkoutLinkId,mode:F.mode,...N.discountCode?{discountCode:N.discountCode}:{},...G.length>0?{items:G}:{}};try{let X=await this.post("/checkout-url",$);if(X.ok!==!0||typeof X.checkoutUrl!=="string"||X.checkoutUrl.length===0)throw new E("request_failed","Cart response was invalid.");return Q(X.checkoutUrl,this.siteKey)}catch(X){if(X instanceof E){if(U(X.code))throw this.reconcileCartAdjustments(X.details),new E(X.code,X.message,X.status,X.details);throw new E(X.code,X.message,X.status)}throw new E("request_failed","Failed to resolve checkout URL.",void 0,void 0)}}async checkout(B=this.defaultCheckoutLinkKey){try{let F=await this.resolveCheckoutUrl(B),N=O();if(N)N.location.assign(F);return F}catch(F){if(F instanceof E){if(U(F.code))throw this.reconcileCartAdjustments(F.details),new E(F.code,F.message,F.status,F.details);throw new E(F.code,F.message,F.status)}throw new E("request_failed","Failed to resolve checkout URL.",void 0,void 0)}}itemsForCheckout(B,F){if(F.mode==="static")return[];let N=this.items.filter((G)=>G.checkoutLinkKey===B).map((G)=>({lineItemId:L(G),quantity:G.quantity,...G.discount?{discount:G.discount}:{}}));if(N.length===0)throw new E("cart_empty","Your cart is empty.");return N}normalizeItem(B){let F=z(B.accessTierId),N=z(B.productId),G=z(B.lineItemId)??F??N;if(!B.id||!G||typeof B.unitPrice!=="number")return null;let $=typeof B.name==="string"&&B.name.trim().length>0?B.name.trim():"Item";return{...B,id:B.id,lineItemId:G,...F?{accessTierId:F}:{},...N?{productId:N}:{},checkoutLinkKey:B.checkoutLinkKey??this.defaultCheckoutLinkKey,name:$,unitPrice:B.unitPrice,quantity:f(B.quantity)}}reconcileCartAdjustments(B){if(!B?.length)return;let F=[...this.items],N=!1;for(let G of B){if(G.discountCode){F=F.map((X)=>{if(!M(X,G))return X;let Z={...X,unitPrice:X.fullPrice??X.unitPrice};return delete Z.discount,delete Z.discountEligibleTierOrProductIds,N=!0,Z});continue}if(G.reason==="line_item_sold_out"||G.reason==="product_unavailable"||G.adjustedQuantity===0){let X=F.length;if(F=F.filter((Z)=>!M(Z,G)),F.length!==X)N=!0;continue}if(G.reason==="quantity_exceeded"&&typeof G.adjustedQuantity==="number"&&G.adjustedQuantity>0){let X=G.adjustedQuantity;F=F.map((Z)=>{if(!M(Z,G))return Z;return N=!0,{...Z,quantity:X}})}}if(!N)return;this.items=F,this.commit()}async post(B,F){let N=`${this.endpoint}${B}`,G=JSON.stringify(F),$={"Content-Type":"application/json"},X={body:F,bodyText:G,endpoint:this.endpoint,headers:$,path:B,siteKey:this.siteKey,url:N},Z=typeof this.requestHeaders==="function"?await this.requestHeaders(X):this.requestHeaders,V=g($,Z),P=await fetch(N,{method:"POST",headers:V,body:G}),J=await P.json().catch(()=>null);if(!P.ok){let S=typeof J?.code==="string"&&J.code.length>0?J.code:"request_failed",C=typeof J?.message==="string"&&J.message.length>0?J.message:"Cart request failed";throw new E(S,C,P.status,I(J),typeof J?.available==="boolean"?J.available:void 0,typeof J?.sold_out==="boolean"?J.sold_out:void 0,typeof J?.quantity_exceeded==="boolean"?J.quantity_exceeded:void 0)}if(!J||typeof J!=="object")throw new E("request_failed","Cart response was invalid.",P.status);return J}commit(){if(this.items=q(this.items),this.persist&&this.storage)try{let B={version:H,items:this.items};this.storage.setItem(this.storageKey,JSON.stringify(B))}catch(B){this.log("Failed to persist cart",B)}this.emit()}emit(){let B=this.getState();for(let F of this.listeners)F(B)}log(...B){if(this.debug)console.log("[@behindthescenes/cart]",...B)}}function r(B){return W.init(B)}export{L as resolveLineItemIdForCheckout,r as createBTSCart,h as catalogIdsForCartLine,E as BTSCartError,W as BTSCart};
|
package/dist/manifest.json
CHANGED
package/dist/types/index.d.ts
CHANGED
|
@@ -1,16 +1,10 @@
|
|
|
1
|
-
import type { BTSCartAvailabilityCheckResponse,
|
|
1
|
+
import type { BTSCartAvailabilityCheckResponse, BTSCartInit, BTSCartItem, BTSCartItemInput, BTSCartListener, BTSCartState } from "./types/index.types";
|
|
2
2
|
import { BTSCartError } from "./types/index.types";
|
|
3
3
|
/**
|
|
4
4
|
* Prefer catalog UUIDs on checkout-url — matches `resolveDynamicCheckoutCartLineItem` (tier/product
|
|
5
5
|
* id, then persisted line-item pk).
|
|
6
6
|
*/
|
|
7
7
|
export declare function resolveLineItemIdForCheckout(item: Pick<BTSCartItem, "lineItemId" | "productId" | "accessTierId">): string;
|
|
8
|
-
export type CartAdjustmentDetail = NonNullable<BTSCartError["details"]>[number];
|
|
9
|
-
/** Parse `details` from a cart API error body (validate-discounts, checkout-url, check-availability). */
|
|
10
|
-
export declare function normalizeCartAdjustmentDetails(json: Record<string, unknown> | null): BTSCartError["details"];
|
|
11
|
-
/** Whether a checkout adjustment detail means the line cannot be purchased (qty 0 / unavailable). */
|
|
12
|
-
export declare function isSoldOutAdjustmentDetail(detail: CartAdjustmentDetail): boolean;
|
|
13
|
-
export declare function isCartAdjustmentErrorCode(code: string): code is BTSCartErrorCode;
|
|
14
8
|
/** All catalog identifiers for a line — matches API adjustment details and `resolveDynamicCheckoutCartLineItem`. */
|
|
15
9
|
export declare function catalogIdsForCartLine(item: Pick<BTSCartItem, "lineItemId" | "productId" | "accessTierId">): string[];
|
|
16
10
|
export declare class BTSCart {
|
|
@@ -69,14 +63,6 @@ export declare class BTSCart {
|
|
|
69
63
|
sold_out: boolean;
|
|
70
64
|
quantity_exceeded: boolean;
|
|
71
65
|
}>;
|
|
72
|
-
/**
|
|
73
|
-
* Uses `POST /validate-discounts` (same rules as checkout). Prefer this over
|
|
74
|
-
* `checkIfItemAvailable` when `/check-availability` is not deployed.
|
|
75
|
-
*/
|
|
76
|
-
isCatalogLineSoldOut(checkoutLinkKey: string | undefined, catalog: Pick<BTSCartItem, "lineItemId" | "productId" | "accessTierId">, options?: {
|
|
77
|
-
discount?: string;
|
|
78
|
-
quantity?: number;
|
|
79
|
-
}): Promise<boolean>;
|
|
80
66
|
validateCheckout(checkoutLinkKey?: string): Promise<{
|
|
81
67
|
ok: boolean;
|
|
82
68
|
errors?: BTSCartError["details"];
|