@behindthescenes/cart 0.0.6 → 0.0.8

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.
@@ -1 +1 @@
1
- var P="https://api.bts.it.com/v2/website/cart",v="bts-cart",F="default",G=1;class r extends Error{code;status;constructor(C,w,f){super(w);this.name="BTSCartError",this.code=C,this.status=f}}function N(){return typeof window>"u"?null:window}function _(){try{return N()?.localStorage}catch{return}}function $(C){return(C??P).replace(/\/$/,"")}function U(C){if(!Number.isFinite(C??1))return 1;return Math.min(99,Math.max(1,Math.floor(C??1)))}function J(C){return{items:C.map((w)=>({...w}))}}function z(C){if(C.discountEligibleTierOrProductIds?.length)return[...new Set(C.discountEligibleTierOrProductIds.filter(Boolean))];return[...new Set([C.accessTierId,C.productId,C.lineItemId].filter((w)=>Boolean(w)))]}function M(C){let w=new Set;for(let f of C)for(let B of[f.lineItemId,f.accessTierId,f.productId])if(B)w.add(B);return C.map((f)=>{if(!f.discount)return f;let B=z(f);if(B.length===0||!B.some((A)=>w.has(A))){let A={...f};return delete A.discount,delete A.discountEligibleTierOrProductIds,A}return f})}function Q(C,w){let f=new Headers(C);if(!w)return f;return new Headers(w).forEach((B,A)=>f.set(A,B)),f}function W(C){let w=C.checkoutLinkId.trim();try{let f=w.includes("://")?w:w.startsWith("/")?`https://bts-cart.invalid${w}`:w,B=new URL(f),A=B.pathname.split("/").filter(Boolean),T=A.indexOf("c"),R=T>=0?A[T+1]:A.at(-1);if(R)return{checkoutLinkId:R,discountCode:C.discountCode??B.searchParams.get("discountCode")??void 0}}catch{}return{checkoutLinkId:w,discountCode:C.discountCode}}class I{siteKey;endpoint;debug;persist;storageKey;storage;checkoutLinks;defaultCheckoutLinkKey;requestHeaders;items=[];listeners=new Set;constructor(C){this.siteKey=C.siteKey,this.endpoint=$(C.endpoint),this.debug=C.debug??!1,this.persist=C.persist??!0,this.storageKey=C.storageKey??v,this.storage=C.storage??_(),this.checkoutLinks=C.checkoutLinks??{},this.defaultCheckoutLinkKey=C.defaultCheckoutLinkKey??Object.keys(this.checkoutLinks)[0]??F,this.requestHeaders=C.requestHeaders,this.rehydrate()}static init(C){return new I(C)}getItems(){return J(this.items).items}getState(){return J(this.items)}getItemCount(){return this.items.reduce((C,w)=>C+w.quantity,0)}getSubtotal(){return this.items.reduce((C,w)=>C+(w.fullPrice??w.unitPrice)*w.quantity,0)}getTotal(){return this.items.reduce((C,w)=>C+w.unitPrice*w.quantity,0)}subscribe(C){return this.listeners.add(C),C(this.getState()),()=>{this.listeners.delete(C)}}destroy(){this.listeners.clear()}rehydrate(){if(!this.persist||!this.storage)return;try{let C=this.storage.getItem(this.storageKey);if(!C)return;let w=JSON.parse(C),f=Array.isArray(w)?w:w.items;if(!Array.isArray(f))return;this.items=M(f.map((B)=>this.normalizeItem(B)).filter((B)=>Boolean(B))),this.emit()}catch(C){this.log("Failed to hydrate cart",C)}}addItem(C){let w=this.normalizeItem(C);if(!w)return;let f=this.items.find((B)=>B.id===w.id);if(f){this.setQuantity(f.id,f.quantity+w.quantity);return}this.items=[...this.items,w],this.commit()}removeItem(C){this.items=this.items.filter((w)=>w.id!==C),this.commit()}setQuantity(C,w){let f=Math.floor(w);this.items=f<=0?this.items.filter((B)=>B.id!==C):this.items.map((B)=>B.id===C?{...B,quantity:f}:B),this.commit()}increment(C,w=1){let f=this.items.find((B)=>B.id===C);if(f)this.setQuantity(C,f.quantity+Math.max(1,Math.floor(w)))}decrement(C,w=1){let f=this.items.find((B)=>B.id===C);if(f)this.setQuantity(C,f.quantity-Math.max(1,Math.floor(w)))}clear(){if(this.items=[],this.persist&&this.storage)try{this.storage.removeItem(this.storageKey)}catch(C){this.log("Failed to clear cart storage",C)}this.emit()}async resolveCheckoutUrl(C=this.defaultCheckoutLinkKey){let w=this.checkoutLinks[C];if(!w)throw new r("checkout_link_not_found",`Unknown checkout link key: ${C}`);let f=W(w),B=this.itemsForCheckout(C,w),A={siteKey:this.siteKey,checkoutLinkId:f.checkoutLinkId,mode:w.mode,...f.discountCode?{discountCode:f.discountCode}:{},...B.length>0?{items:B}:{}};return(await this.post("/checkout-url",A)).checkoutUrl}async checkout(C=this.defaultCheckoutLinkKey){let w=await this.resolveCheckoutUrl(C),f=N();if(f)f.location.assign(w);return w}itemsForCheckout(C,w){if(w.mode==="static")return[];let f=this.items.filter((B)=>B.checkoutLinkKey===C).map((B)=>({lineItemId:B.lineItemId,quantity:B.quantity,...B.discount?{discount:B.discount}:{}}));if(f.length===0)throw new r("cart_empty","Your cart is empty.");return f}normalizeItem(C){if(!C.id||!C.lineItemId||typeof C.unitPrice!=="number")return null;let w=typeof C.name==="string"&&C.name.trim().length>0?C.name.trim():"Item";return{...C,id:C.id,lineItemId:C.lineItemId,checkoutLinkKey:C.checkoutLinkKey??this.defaultCheckoutLinkKey,name:w,unitPrice:C.unitPrice,quantity:U(C.quantity)}}async post(C,w){let f=`${this.endpoint}${C}`,B=JSON.stringify(w),A={"Content-Type":"application/json"},T={body:w,bodyText:B,endpoint:this.endpoint,headers:A,path:C,siteKey:this.siteKey,url:f},R=typeof this.requestHeaders==="function"?await this.requestHeaders(T):this.requestHeaders,X=Q(A,R),b=await fetch(f,{method:"POST",headers:X,body:B}),S=await b.json().catch(()=>null);if(!b.ok){let Y=typeof S?.code==="string"&&S.code.length>0?S.code:"request_failed",Z=typeof S?.message==="string"&&S.message.length>0?S.message:"Cart request failed";throw new r(Y,Z,b.status)}if(!S||typeof S!=="object"||S.ok!==!0||typeof S.checkoutUrl!=="string"||S.checkoutUrl.length===0)throw new r("request_failed","Cart response was invalid.",b.status);return S}commit(){if(this.items=M(this.items),this.persist&&this.storage)try{let C={version:G,items:this.items};this.storage.setItem(this.storageKey,JSON.stringify(C))}catch(C){this.log("Failed to persist cart",C)}this.emit()}emit(){let C=this.getState();for(let w of this.listeners)w(C)}log(...C){if(this.debug)console.log("[@behindthescenes/cart]",...C)}}function D(C){return I.init(C)}function O(C){return typeof C==="object"&&C!==null&&!Array.isArray(C)}function V(C){let w=typeof window>"u"?null:window;if(!w)return;let[f,B,A]=C;if(typeof f!=="string")return;if(f==="config"){if(!O(B))return;w.btsCart?.destroy?.(),w.btsCart=D(B);return}let T=w.btsCart;if(!T)return;if(f==="add"&&O(B)){T.addItem(B);return}if(f==="remove"&&typeof B==="string"){T.removeItem(B);return}if(f==="quantity"&&typeof B==="string"&&typeof A==="number"){T.setQuantity(B,A);return}if(f==="clear"){T.clear();return}if(f==="checkout")T.checkout(typeof B==="string"?B:void 0)}if(typeof window<"u"){let C=Array.isArray(window.btsCartDataLayer)?[...window.btsCartDataLayer]:[];window.btsCartDataLayer=Array.isArray(window.btsCartDataLayer)?window.btsCartDataLayer:[],window.BTSCart={BTSCart:I,createBTSCart:D},window.createBTSCart=D;for(let w of C)V(Array.from(w));window.btsCartCommand=(...w)=>{window.btsCartDataLayer?.push(w),V(w)}}export{D as createBTSCart,I as BTSCart};
1
+ var P="https://api.bts.it.com/v2/website/cart",v="bts-cart",F="default",G=1;class w extends Error{code;status;constructor(C,r,f){super(r);this.name="BTSCartError",this.code=C,this.status=f}}function N(){try{return globalThis.window??null}catch{return null}}function $(){try{return N()?.localStorage}catch{return}}function U(C){return(C??P).replace(/\/$/,"")}function z(C){if(!Number.isFinite(C??1))return 1;return Math.min(99,Math.max(1,Math.floor(C??1)))}function J(C){return{items:C.map((r)=>({...r}))}}function Q(C){if(C.discountEligibleTierOrProductIds?.length)return[...new Set(C.discountEligibleTierOrProductIds.filter(Boolean))];return[...new Set([C.accessTierId,C.productId,C.lineItemId].filter((r)=>Boolean(r)))]}function M(C){let r=new Set;for(let f of C)for(let B of[f.lineItemId,f.accessTierId,f.productId])if(B)r.add(B);return C.map((f)=>{if(!f.discount)return f;let B=Q(f);if(B.length===0||!B.some((A)=>r.has(A))){let A={...f};return delete A.discount,delete A.discountEligibleTierOrProductIds,A}return f})}function q(C,r){let f=new Headers(C);if(!r)return f;return new Headers(r).forEach((B,A)=>f.set(A,B)),f}function H(C){let r=C.checkoutLinkId.trim();try{let f=r.includes("://")?r:r.startsWith("/")?`https://bts-cart.invalid${r}`:r,B=new URL(f),A=B.pathname.split("/").filter(Boolean),T=A.indexOf("c"),R=T>=0?A[T+1]:A.at(-1);if(R)return{checkoutLinkId:R,discountCode:C.discountCode??B.searchParams.get("discountCode")??void 0}}catch{}return{checkoutLinkId:r,discountCode:C.discountCode}}class I{siteKey;endpoint;debug;persist;storageKey;storage;checkoutLinks;defaultCheckoutLinkKey;requestHeaders;items=[];listeners=new Set;constructor(C){this.siteKey=C.siteKey,this.endpoint=U(C.endpoint),this.debug=C.debug??!1,this.persist=C.persist??!0,this.storageKey=C.storageKey??v,this.storage=C.storage??$(),this.checkoutLinks=C.checkoutLinks??{},this.defaultCheckoutLinkKey=C.defaultCheckoutLinkKey??Object.keys(this.checkoutLinks)[0]??F,this.requestHeaders=C.requestHeaders,this.rehydrate()}static init(C){return new I(C)}getItems(){return J(this.items).items}getState(){return J(this.items)}getItemCount(){return this.items.reduce((C,r)=>C+r.quantity,0)}getSubtotal(){return this.items.reduce((C,r)=>C+(r.fullPrice??r.unitPrice)*r.quantity,0)}getTotal(){return this.items.reduce((C,r)=>C+r.unitPrice*r.quantity,0)}subscribe(C){return this.listeners.add(C),C(this.getState()),()=>{this.listeners.delete(C)}}destroy(){this.listeners.clear()}rehydrate(){if(!this.persist||!this.storage)return;try{let C=this.storage.getItem(this.storageKey);if(!C)return;let r=JSON.parse(C),f=Array.isArray(r)?r:r.items;if(!Array.isArray(f))return;this.items=M(f.map((B)=>this.normalizeItem(B)).filter((B)=>Boolean(B))),this.emit()}catch(C){this.log("Failed to hydrate cart",C)}}addItem(C){let r=this.normalizeItem(C);if(!r)return;let f=this.items.find((B)=>B.id===r.id);if(f){this.setQuantity(f.id,f.quantity+r.quantity);return}this.items=[...this.items,r],this.commit()}removeItem(C){this.items=this.items.filter((r)=>r.id!==C),this.commit()}setQuantity(C,r){let f=Math.floor(r);this.items=f<=0?this.items.filter((B)=>B.id!==C):this.items.map((B)=>B.id===C?{...B,quantity:f}:B),this.commit()}increment(C,r=1){let f=this.items.find((B)=>B.id===C);if(f)this.setQuantity(C,f.quantity+Math.max(1,Math.floor(r)))}decrement(C,r=1){let f=this.items.find((B)=>B.id===C);if(f)this.setQuantity(C,f.quantity-Math.max(1,Math.floor(r)))}clear(){if(this.items=[],this.persist&&this.storage)try{this.storage.removeItem(this.storageKey)}catch(C){this.log("Failed to clear cart storage",C)}this.emit()}async resolveCheckoutUrl(C=this.defaultCheckoutLinkKey){let r=this.checkoutLinks[C];if(!r)throw new w("checkout_link_not_found",`Unknown checkout link key: ${C}`);let f=H(r),B=this.itemsForCheckout(C,r),A={siteKey:this.siteKey,checkoutLinkId:f.checkoutLinkId,mode:r.mode,...f.discountCode?{discountCode:f.discountCode}:{},...B.length>0?{items:B}:{}};return(await this.post("/checkout-url",A)).checkoutUrl}async checkout(C=this.defaultCheckoutLinkKey){let r=await this.resolveCheckoutUrl(C),f=N();if(f)f.location.assign(r);return r}itemsForCheckout(C,r){if(r.mode==="static")return[];let f=this.items.filter((B)=>B.checkoutLinkKey===C).map((B)=>({lineItemId:B.lineItemId,quantity:B.quantity,...B.discount?{discount:B.discount}:{}}));if(f.length===0)throw new w("cart_empty","Your cart is empty.");return f}normalizeItem(C){if(!C.id||!C.lineItemId||typeof C.unitPrice!=="number")return null;let r=typeof C.name==="string"&&C.name.trim().length>0?C.name.trim():"Item";return{...C,id:C.id,lineItemId:C.lineItemId,checkoutLinkKey:C.checkoutLinkKey??this.defaultCheckoutLinkKey,name:r,unitPrice:C.unitPrice,quantity:z(C.quantity)}}async post(C,r){let f=`${this.endpoint}${C}`,B=JSON.stringify(r),A={"Content-Type":"application/json"},T={body:r,bodyText:B,endpoint:this.endpoint,headers:A,path:C,siteKey:this.siteKey,url:f},R=typeof this.requestHeaders==="function"?await this.requestHeaders(T):this.requestHeaders,Y=q(A,R),W=await fetch(f,{method:"POST",headers:Y,body:B}),b=await W.json().catch(()=>null);if(!W.ok){let Z=typeof b?.code==="string"&&b.code.length>0?b.code:"request_failed",_=typeof b?.message==="string"&&b.message.length>0?b.message:"Cart request failed";throw new w(Z,_,W.status)}if(!b||typeof b!=="object"||b.ok!==!0||typeof b.checkoutUrl!=="string"||b.checkoutUrl.length===0)throw new w("request_failed","Cart response was invalid.",W.status);return b}commit(){if(this.items=M(this.items),this.persist&&this.storage)try{let C={version:G,items:this.items};this.storage.setItem(this.storageKey,JSON.stringify(C))}catch(C){this.log("Failed to persist cart",C)}this.emit()}emit(){let C=this.getState();for(let r of this.listeners)r(C)}log(...C){if(this.debug)console.log("[@behindthescenes/cart]",...C)}}function D(C){return I.init(C)}function O(C){return typeof C==="object"&&C!==null&&!Array.isArray(C)}function X(){try{return globalThis.window??null}catch{return null}}function V(C){let r=X();if(!r)return;let[f,B,A]=C;if(typeof f!=="string")return;if(f==="config"){if(!O(B))return;r.btsCart?.destroy?.(),r.btsCart=D(B);return}let T=r.btsCart;if(!T)return;if(f==="add"&&O(B)){T.addItem(B);return}if(f==="remove"&&typeof B==="string"){T.removeItem(B);return}if(f==="quantity"&&typeof B==="string"&&typeof A==="number"){T.setQuantity(B,A);return}if(f==="clear"){T.clear();return}if(f==="checkout")T.checkout(typeof B==="string"?B:void 0)}var S=X();if(S){let C=Array.isArray(S.btsCartDataLayer)?[...S.btsCartDataLayer]:[];S.btsCartDataLayer=Array.isArray(S.btsCartDataLayer)?S.btsCartDataLayer:[],S.BTSCart={BTSCart:I,createBTSCart:D},S.createBTSCart=D;for(let r of C)V(Array.from(r));S.btsCartCommand=(...r)=>{S.btsCartDataLayer?.push(r),V(r)}}export{D as createBTSCart,I as BTSCart};
package/dist/cjs/index.js CHANGED
@@ -1 +1 @@
1
- var{defineProperty:Z,getOwnPropertyNames:q,getOwnPropertyDescriptor:B}=Object,I=Object.prototype.hasOwnProperty;function b(A){return this[A]}var T=(A)=>{var F=(_??=new WeakMap).get(A),G;if(F)return F;if(F=Z({},"__esModule",{value:!0}),A&&typeof A==="object"||typeof A==="function"){for(var J of q(A))if(!I.call(F,J))Z(F,J,{get:b.bind(A,J),enumerable:!(G=B(A,J))||G.enumerable})}return _.set(A,F),F},_;var j=(A)=>A;function C(A,F){this[A]=j.bind(null,F)}var K=(A,F)=>{for(var G in F)Z(A,G,{get:F[G],enumerable:!0,configurable:!0,set:C.bind(F,G)})};var k={};K(k,{createBTSCart:()=>h,BTSCartError:()=>O,BTSCart:()=>Y});module.exports=T(k);var $="https://api.bts.it.com/v2/website/cart",R="bts-cart",z="default",W=1;class O extends Error{code;status;constructor(A,F,G){super(F);this.name="BTSCartError",this.code=A,this.status=G}}function U(){return typeof window>"u"?null:window}function S(){try{return U()?.localStorage}catch{return}}function w(A){return(A??$).replace(/\/$/,"")}function L(A){if(!Number.isFinite(A??1))return 1;return Math.min(99,Math.max(1,Math.floor(A??1)))}function v(A){return{items:A.map((F)=>({...F}))}}function x(A){if(A.discountEligibleTierOrProductIds?.length)return[...new Set(A.discountEligibleTierOrProductIds.filter(Boolean))];return[...new Set([A.accessTierId,A.productId,A.lineItemId].filter((F)=>Boolean(F)))]}function Q(A){let F=new Set;for(let G of A)for(let J of[G.lineItemId,G.accessTierId,G.productId])if(J)F.add(J);return A.map((G)=>{if(!G.discount)return G;let J=x(G);if(J.length===0||!J.some((M)=>F.has(M))){let M={...G};return delete M.discount,delete M.discountEligibleTierOrProductIds,M}return G})}function f(A,F){let G=new Headers(A);if(!F)return G;return new Headers(F).forEach((J,M)=>G.set(M,J)),G}function g(A){let F=A.checkoutLinkId.trim();try{let G=F.includes("://")?F:F.startsWith("/")?`https://bts-cart.invalid${F}`:F,J=new URL(G),M=J.pathname.split("/").filter(Boolean),P=M.indexOf("c"),V=P>=0?M[P+1]:M.at(-1);if(V)return{checkoutLinkId:V,discountCode:A.discountCode??J.searchParams.get("discountCode")??void 0}}catch{}return{checkoutLinkId:F,discountCode:A.discountCode}}class Y{siteKey;endpoint;debug;persist;storageKey;storage;checkoutLinks;defaultCheckoutLinkKey;requestHeaders;items=[];listeners=new Set;constructor(A){this.siteKey=A.siteKey,this.endpoint=w(A.endpoint),this.debug=A.debug??!1,this.persist=A.persist??!0,this.storageKey=A.storageKey??R,this.storage=A.storage??S(),this.checkoutLinks=A.checkoutLinks??{},this.defaultCheckoutLinkKey=A.defaultCheckoutLinkKey??Object.keys(this.checkoutLinks)[0]??z,this.requestHeaders=A.requestHeaders,this.rehydrate()}static init(A){return new Y(A)}getItems(){return v(this.items).items}getState(){return v(this.items)}getItemCount(){return this.items.reduce((A,F)=>A+F.quantity,0)}getSubtotal(){return this.items.reduce((A,F)=>A+(F.fullPrice??F.unitPrice)*F.quantity,0)}getTotal(){return this.items.reduce((A,F)=>A+F.unitPrice*F.quantity,0)}subscribe(A){return this.listeners.add(A),A(this.getState()),()=>{this.listeners.delete(A)}}destroy(){this.listeners.clear()}rehydrate(){if(!this.persist||!this.storage)return;try{let A=this.storage.getItem(this.storageKey);if(!A)return;let F=JSON.parse(A),G=Array.isArray(F)?F:F.items;if(!Array.isArray(G))return;this.items=Q(G.map((J)=>this.normalizeItem(J)).filter((J)=>Boolean(J))),this.emit()}catch(A){this.log("Failed to hydrate cart",A)}}addItem(A){let F=this.normalizeItem(A);if(!F)return;let G=this.items.find((J)=>J.id===F.id);if(G){this.setQuantity(G.id,G.quantity+F.quantity);return}this.items=[...this.items,F],this.commit()}removeItem(A){this.items=this.items.filter((F)=>F.id!==A),this.commit()}setQuantity(A,F){let G=Math.floor(F);this.items=G<=0?this.items.filter((J)=>J.id!==A):this.items.map((J)=>J.id===A?{...J,quantity:G}:J),this.commit()}increment(A,F=1){let G=this.items.find((J)=>J.id===A);if(G)this.setQuantity(A,G.quantity+Math.max(1,Math.floor(F)))}decrement(A,F=1){let G=this.items.find((J)=>J.id===A);if(G)this.setQuantity(A,G.quantity-Math.max(1,Math.floor(F)))}clear(){if(this.items=[],this.persist&&this.storage)try{this.storage.removeItem(this.storageKey)}catch(A){this.log("Failed to clear cart storage",A)}this.emit()}async resolveCheckoutUrl(A=this.defaultCheckoutLinkKey){let F=this.checkoutLinks[A];if(!F)throw new O("checkout_link_not_found",`Unknown checkout link key: ${A}`);let G=g(F),J=this.itemsForCheckout(A,F),M={siteKey:this.siteKey,checkoutLinkId:G.checkoutLinkId,mode:F.mode,...G.discountCode?{discountCode:G.discountCode}:{},...J.length>0?{items:J}:{}};return(await this.post("/checkout-url",M)).checkoutUrl}async checkout(A=this.defaultCheckoutLinkKey){let F=await this.resolveCheckoutUrl(A),G=U();if(G)G.location.assign(F);return F}itemsForCheckout(A,F){if(F.mode==="static")return[];let G=this.items.filter((J)=>J.checkoutLinkKey===A).map((J)=>({lineItemId:J.lineItemId,quantity:J.quantity,...J.discount?{discount:J.discount}:{}}));if(G.length===0)throw new O("cart_empty","Your cart is empty.");return G}normalizeItem(A){if(!A.id||!A.lineItemId||typeof A.unitPrice!=="number")return null;let F=typeof A.name==="string"&&A.name.trim().length>0?A.name.trim():"Item";return{...A,id:A.id,lineItemId:A.lineItemId,checkoutLinkKey:A.checkoutLinkKey??this.defaultCheckoutLinkKey,name:F,unitPrice:A.unitPrice,quantity:L(A.quantity)}}async post(A,F){let G=`${this.endpoint}${A}`,J=JSON.stringify(F),M={"Content-Type":"application/json"},P={body:F,bodyText:J,endpoint:this.endpoint,headers:M,path:A,siteKey:this.siteKey,url:G},V=typeof this.requestHeaders==="function"?await this.requestHeaders(P):this.requestHeaders,H=f(M,V),X=await fetch(G,{method:"POST",headers:H,body:J}),N=await X.json().catch(()=>null);if(!X.ok){let D=typeof N?.code==="string"&&N.code.length>0?N.code:"request_failed",E=typeof N?.message==="string"&&N.message.length>0?N.message:"Cart request failed";throw new O(D,E,X.status)}if(!N||typeof N!=="object"||N.ok!==!0||typeof N.checkoutUrl!=="string"||N.checkoutUrl.length===0)throw new O("request_failed","Cart response was invalid.",X.status);return N}commit(){if(this.items=Q(this.items),this.persist&&this.storage)try{let A={version:W,items:this.items};this.storage.setItem(this.storageKey,JSON.stringify(A))}catch(A){this.log("Failed to persist cart",A)}this.emit()}emit(){let A=this.getState();for(let F of this.listeners)F(A)}log(...A){if(this.debug)console.log("[@behindthescenes/cart]",...A)}}function h(A){return Y.init(A)}
1
+ var{defineProperty:Z,getOwnPropertyNames:q,getOwnPropertyDescriptor:B}=Object,I=Object.prototype.hasOwnProperty;function b(A){return this[A]}var T=(A)=>{var F=(_??=new WeakMap).get(A),G;if(F)return F;if(F=Z({},"__esModule",{value:!0}),A&&typeof A==="object"||typeof A==="function"){for(var J of q(A))if(!I.call(F,J))Z(F,J,{get:b.bind(A,J),enumerable:!(G=B(A,J))||G.enumerable})}return _.set(A,F),F},_;var j=(A)=>A;function C(A,F){this[A]=j.bind(null,F)}var K=(A,F)=>{for(var G in F)Z(A,G,{get:F[G],enumerable:!0,configurable:!0,set:C.bind(F,G)})};var k={};K(k,{createBTSCart:()=>h,BTSCartError:()=>O,BTSCart:()=>Y});module.exports=T(k);var $="https://api.bts.it.com/v2/website/cart",R="bts-cart",z="default",W=1;class O extends Error{code;status;constructor(A,F,G){super(F);this.name="BTSCartError",this.code=A,this.status=G}}function U(){try{return globalThis.window??null}catch{return null}}function S(){try{return U()?.localStorage}catch{return}}function w(A){return(A??$).replace(/\/$/,"")}function L(A){if(!Number.isFinite(A??1))return 1;return Math.min(99,Math.max(1,Math.floor(A??1)))}function v(A){return{items:A.map((F)=>({...F}))}}function x(A){if(A.discountEligibleTierOrProductIds?.length)return[...new Set(A.discountEligibleTierOrProductIds.filter(Boolean))];return[...new Set([A.accessTierId,A.productId,A.lineItemId].filter((F)=>Boolean(F)))]}function Q(A){let F=new Set;for(let G of A)for(let J of[G.lineItemId,G.accessTierId,G.productId])if(J)F.add(J);return A.map((G)=>{if(!G.discount)return G;let J=x(G);if(J.length===0||!J.some((M)=>F.has(M))){let M={...G};return delete M.discount,delete M.discountEligibleTierOrProductIds,M}return G})}function f(A,F){let G=new Headers(A);if(!F)return G;return new Headers(F).forEach((J,M)=>G.set(M,J)),G}function g(A){let F=A.checkoutLinkId.trim();try{let G=F.includes("://")?F:F.startsWith("/")?`https://bts-cart.invalid${F}`:F,J=new URL(G),M=J.pathname.split("/").filter(Boolean),P=M.indexOf("c"),V=P>=0?M[P+1]:M.at(-1);if(V)return{checkoutLinkId:V,discountCode:A.discountCode??J.searchParams.get("discountCode")??void 0}}catch{}return{checkoutLinkId:F,discountCode:A.discountCode}}class Y{siteKey;endpoint;debug;persist;storageKey;storage;checkoutLinks;defaultCheckoutLinkKey;requestHeaders;items=[];listeners=new Set;constructor(A){this.siteKey=A.siteKey,this.endpoint=w(A.endpoint),this.debug=A.debug??!1,this.persist=A.persist??!0,this.storageKey=A.storageKey??R,this.storage=A.storage??S(),this.checkoutLinks=A.checkoutLinks??{},this.defaultCheckoutLinkKey=A.defaultCheckoutLinkKey??Object.keys(this.checkoutLinks)[0]??z,this.requestHeaders=A.requestHeaders,this.rehydrate()}static init(A){return new Y(A)}getItems(){return v(this.items).items}getState(){return v(this.items)}getItemCount(){return this.items.reduce((A,F)=>A+F.quantity,0)}getSubtotal(){return this.items.reduce((A,F)=>A+(F.fullPrice??F.unitPrice)*F.quantity,0)}getTotal(){return this.items.reduce((A,F)=>A+F.unitPrice*F.quantity,0)}subscribe(A){return this.listeners.add(A),A(this.getState()),()=>{this.listeners.delete(A)}}destroy(){this.listeners.clear()}rehydrate(){if(!this.persist||!this.storage)return;try{let A=this.storage.getItem(this.storageKey);if(!A)return;let F=JSON.parse(A),G=Array.isArray(F)?F:F.items;if(!Array.isArray(G))return;this.items=Q(G.map((J)=>this.normalizeItem(J)).filter((J)=>Boolean(J))),this.emit()}catch(A){this.log("Failed to hydrate cart",A)}}addItem(A){let F=this.normalizeItem(A);if(!F)return;let G=this.items.find((J)=>J.id===F.id);if(G){this.setQuantity(G.id,G.quantity+F.quantity);return}this.items=[...this.items,F],this.commit()}removeItem(A){this.items=this.items.filter((F)=>F.id!==A),this.commit()}setQuantity(A,F){let G=Math.floor(F);this.items=G<=0?this.items.filter((J)=>J.id!==A):this.items.map((J)=>J.id===A?{...J,quantity:G}:J),this.commit()}increment(A,F=1){let G=this.items.find((J)=>J.id===A);if(G)this.setQuantity(A,G.quantity+Math.max(1,Math.floor(F)))}decrement(A,F=1){let G=this.items.find((J)=>J.id===A);if(G)this.setQuantity(A,G.quantity-Math.max(1,Math.floor(F)))}clear(){if(this.items=[],this.persist&&this.storage)try{this.storage.removeItem(this.storageKey)}catch(A){this.log("Failed to clear cart storage",A)}this.emit()}async resolveCheckoutUrl(A=this.defaultCheckoutLinkKey){let F=this.checkoutLinks[A];if(!F)throw new O("checkout_link_not_found",`Unknown checkout link key: ${A}`);let G=g(F),J=this.itemsForCheckout(A,F),M={siteKey:this.siteKey,checkoutLinkId:G.checkoutLinkId,mode:F.mode,...G.discountCode?{discountCode:G.discountCode}:{},...J.length>0?{items:J}:{}};return(await this.post("/checkout-url",M)).checkoutUrl}async checkout(A=this.defaultCheckoutLinkKey){let F=await this.resolveCheckoutUrl(A),G=U();if(G)G.location.assign(F);return F}itemsForCheckout(A,F){if(F.mode==="static")return[];let G=this.items.filter((J)=>J.checkoutLinkKey===A).map((J)=>({lineItemId:J.lineItemId,quantity:J.quantity,...J.discount?{discount:J.discount}:{}}));if(G.length===0)throw new O("cart_empty","Your cart is empty.");return G}normalizeItem(A){if(!A.id||!A.lineItemId||typeof A.unitPrice!=="number")return null;let F=typeof A.name==="string"&&A.name.trim().length>0?A.name.trim():"Item";return{...A,id:A.id,lineItemId:A.lineItemId,checkoutLinkKey:A.checkoutLinkKey??this.defaultCheckoutLinkKey,name:F,unitPrice:A.unitPrice,quantity:L(A.quantity)}}async post(A,F){let G=`${this.endpoint}${A}`,J=JSON.stringify(F),M={"Content-Type":"application/json"},P={body:F,bodyText:J,endpoint:this.endpoint,headers:M,path:A,siteKey:this.siteKey,url:G},V=typeof this.requestHeaders==="function"?await this.requestHeaders(P):this.requestHeaders,H=f(M,V),X=await fetch(G,{method:"POST",headers:H,body:J}),N=await X.json().catch(()=>null);if(!X.ok){let D=typeof N?.code==="string"&&N.code.length>0?N.code:"request_failed",E=typeof N?.message==="string"&&N.message.length>0?N.message:"Cart request failed";throw new O(D,E,X.status)}if(!N||typeof N!=="object"||N.ok!==!0||typeof N.checkoutUrl!=="string"||N.checkoutUrl.length===0)throw new O("request_failed","Cart response was invalid.",X.status);return N}commit(){if(this.items=Q(this.items),this.persist&&this.storage)try{let A={version:W,items:this.items};this.storage.setItem(this.storageKey,JSON.stringify(A))}catch(A){this.log("Failed to persist cart",A)}this.emit()}emit(){let A=this.getState();for(let F of this.listeners)F(A)}log(...A){if(this.debug)console.log("[@behindthescenes/cart]",...A)}}function h(A){return Y.init(A)}
package/dist/esm/index.js CHANGED
@@ -1 +1 @@
1
- var Z="https://api.bts.it.com/v2/website/cart",_="bts-cart",$="default",R=1;class O extends Error{code;status;constructor(A,F,G){super(F);this.name="BTSCartError",this.code=A,this.status=G}}function v(){return typeof window>"u"?null:window}function D(){try{return v()?.localStorage}catch{return}}function E(A){return(A??Z).replace(/\/$/,"")}function q(A){if(!Number.isFinite(A??1))return 1;return Math.min(99,Math.max(1,Math.floor(A??1)))}function z(A){return{items:A.map((F)=>({...F}))}}function B(A){if(A.discountEligibleTierOrProductIds?.length)return[...new Set(A.discountEligibleTierOrProductIds.filter(Boolean))];return[...new Set([A.accessTierId,A.productId,A.lineItemId].filter((F)=>Boolean(F)))]}function W(A){let F=new Set;for(let G of A)for(let J of[G.lineItemId,G.accessTierId,G.productId])if(J)F.add(J);return A.map((G)=>{if(!G.discount)return G;let J=B(G);if(J.length===0||!J.some((M)=>F.has(M))){let M={...G};return delete M.discount,delete M.discountEligibleTierOrProductIds,M}return G})}function I(A,F){let G=new Headers(A);if(!F)return G;return new Headers(F).forEach((J,M)=>G.set(M,J)),G}function b(A){let F=A.checkoutLinkId.trim();try{let G=F.includes("://")?F:F.startsWith("/")?`https://bts-cart.invalid${F}`:F,J=new URL(G),M=J.pathname.split("/").filter(Boolean),P=M.indexOf("c"),V=P>=0?M[P+1]:M.at(-1);if(V)return{checkoutLinkId:V,discountCode:A.discountCode??J.searchParams.get("discountCode")??void 0}}catch{}return{checkoutLinkId:F,discountCode:A.discountCode}}class Y{siteKey;endpoint;debug;persist;storageKey;storage;checkoutLinks;defaultCheckoutLinkKey;requestHeaders;items=[];listeners=new Set;constructor(A){this.siteKey=A.siteKey,this.endpoint=E(A.endpoint),this.debug=A.debug??!1,this.persist=A.persist??!0,this.storageKey=A.storageKey??_,this.storage=A.storage??D(),this.checkoutLinks=A.checkoutLinks??{},this.defaultCheckoutLinkKey=A.defaultCheckoutLinkKey??Object.keys(this.checkoutLinks)[0]??$,this.requestHeaders=A.requestHeaders,this.rehydrate()}static init(A){return new Y(A)}getItems(){return z(this.items).items}getState(){return z(this.items)}getItemCount(){return this.items.reduce((A,F)=>A+F.quantity,0)}getSubtotal(){return this.items.reduce((A,F)=>A+(F.fullPrice??F.unitPrice)*F.quantity,0)}getTotal(){return this.items.reduce((A,F)=>A+F.unitPrice*F.quantity,0)}subscribe(A){return this.listeners.add(A),A(this.getState()),()=>{this.listeners.delete(A)}}destroy(){this.listeners.clear()}rehydrate(){if(!this.persist||!this.storage)return;try{let A=this.storage.getItem(this.storageKey);if(!A)return;let F=JSON.parse(A),G=Array.isArray(F)?F:F.items;if(!Array.isArray(G))return;this.items=W(G.map((J)=>this.normalizeItem(J)).filter((J)=>Boolean(J))),this.emit()}catch(A){this.log("Failed to hydrate cart",A)}}addItem(A){let F=this.normalizeItem(A);if(!F)return;let G=this.items.find((J)=>J.id===F.id);if(G){this.setQuantity(G.id,G.quantity+F.quantity);return}this.items=[...this.items,F],this.commit()}removeItem(A){this.items=this.items.filter((F)=>F.id!==A),this.commit()}setQuantity(A,F){let G=Math.floor(F);this.items=G<=0?this.items.filter((J)=>J.id!==A):this.items.map((J)=>J.id===A?{...J,quantity:G}:J),this.commit()}increment(A,F=1){let G=this.items.find((J)=>J.id===A);if(G)this.setQuantity(A,G.quantity+Math.max(1,Math.floor(F)))}decrement(A,F=1){let G=this.items.find((J)=>J.id===A);if(G)this.setQuantity(A,G.quantity-Math.max(1,Math.floor(F)))}clear(){if(this.items=[],this.persist&&this.storage)try{this.storage.removeItem(this.storageKey)}catch(A){this.log("Failed to clear cart storage",A)}this.emit()}async resolveCheckoutUrl(A=this.defaultCheckoutLinkKey){let F=this.checkoutLinks[A];if(!F)throw new O("checkout_link_not_found",`Unknown checkout link key: ${A}`);let G=b(F),J=this.itemsForCheckout(A,F),M={siteKey:this.siteKey,checkoutLinkId:G.checkoutLinkId,mode:F.mode,...G.discountCode?{discountCode:G.discountCode}:{},...J.length>0?{items:J}:{}};return(await this.post("/checkout-url",M)).checkoutUrl}async checkout(A=this.defaultCheckoutLinkKey){let F=await this.resolveCheckoutUrl(A),G=v();if(G)G.location.assign(F);return F}itemsForCheckout(A,F){if(F.mode==="static")return[];let G=this.items.filter((J)=>J.checkoutLinkKey===A).map((J)=>({lineItemId:J.lineItemId,quantity:J.quantity,...J.discount?{discount:J.discount}:{}}));if(G.length===0)throw new O("cart_empty","Your cart is empty.");return G}normalizeItem(A){if(!A.id||!A.lineItemId||typeof A.unitPrice!=="number")return null;let F=typeof A.name==="string"&&A.name.trim().length>0?A.name.trim():"Item";return{...A,id:A.id,lineItemId:A.lineItemId,checkoutLinkKey:A.checkoutLinkKey??this.defaultCheckoutLinkKey,name:F,unitPrice:A.unitPrice,quantity:q(A.quantity)}}async post(A,F){let G=`${this.endpoint}${A}`,J=JSON.stringify(F),M={"Content-Type":"application/json"},P={body:F,bodyText:J,endpoint:this.endpoint,headers:M,path:A,siteKey:this.siteKey,url:G},V=typeof this.requestHeaders==="function"?await this.requestHeaders(P):this.requestHeaders,Q=I(M,V),X=await fetch(G,{method:"POST",headers:Q,body:J}),N=await X.json().catch(()=>null);if(!X.ok){let U=typeof N?.code==="string"&&N.code.length>0?N.code:"request_failed",H=typeof N?.message==="string"&&N.message.length>0?N.message:"Cart request failed";throw new O(U,H,X.status)}if(!N||typeof N!=="object"||N.ok!==!0||typeof N.checkoutUrl!=="string"||N.checkoutUrl.length===0)throw new O("request_failed","Cart response was invalid.",X.status);return N}commit(){if(this.items=W(this.items),this.persist&&this.storage)try{let A={version:R,items:this.items};this.storage.setItem(this.storageKey,JSON.stringify(A))}catch(A){this.log("Failed to persist cart",A)}this.emit()}emit(){let A=this.getState();for(let F of this.listeners)F(A)}log(...A){if(this.debug)console.log("[@behindthescenes/cart]",...A)}}function S(A){return Y.init(A)}export{S as createBTSCart,O as BTSCartError,Y as BTSCart};
1
+ var Z="https://api.bts.it.com/v2/website/cart",_="bts-cart",$="default",R=1;class O extends Error{code;status;constructor(A,F,G){super(F);this.name="BTSCartError",this.code=A,this.status=G}}function v(){try{return globalThis.window??null}catch{return null}}function D(){try{return v()?.localStorage}catch{return}}function E(A){return(A??Z).replace(/\/$/,"")}function q(A){if(!Number.isFinite(A??1))return 1;return Math.min(99,Math.max(1,Math.floor(A??1)))}function z(A){return{items:A.map((F)=>({...F}))}}function B(A){if(A.discountEligibleTierOrProductIds?.length)return[...new Set(A.discountEligibleTierOrProductIds.filter(Boolean))];return[...new Set([A.accessTierId,A.productId,A.lineItemId].filter((F)=>Boolean(F)))]}function W(A){let F=new Set;for(let G of A)for(let J of[G.lineItemId,G.accessTierId,G.productId])if(J)F.add(J);return A.map((G)=>{if(!G.discount)return G;let J=B(G);if(J.length===0||!J.some((M)=>F.has(M))){let M={...G};return delete M.discount,delete M.discountEligibleTierOrProductIds,M}return G})}function I(A,F){let G=new Headers(A);if(!F)return G;return new Headers(F).forEach((J,M)=>G.set(M,J)),G}function b(A){let F=A.checkoutLinkId.trim();try{let G=F.includes("://")?F:F.startsWith("/")?`https://bts-cart.invalid${F}`:F,J=new URL(G),M=J.pathname.split("/").filter(Boolean),P=M.indexOf("c"),V=P>=0?M[P+1]:M.at(-1);if(V)return{checkoutLinkId:V,discountCode:A.discountCode??J.searchParams.get("discountCode")??void 0}}catch{}return{checkoutLinkId:F,discountCode:A.discountCode}}class Y{siteKey;endpoint;debug;persist;storageKey;storage;checkoutLinks;defaultCheckoutLinkKey;requestHeaders;items=[];listeners=new Set;constructor(A){this.siteKey=A.siteKey,this.endpoint=E(A.endpoint),this.debug=A.debug??!1,this.persist=A.persist??!0,this.storageKey=A.storageKey??_,this.storage=A.storage??D(),this.checkoutLinks=A.checkoutLinks??{},this.defaultCheckoutLinkKey=A.defaultCheckoutLinkKey??Object.keys(this.checkoutLinks)[0]??$,this.requestHeaders=A.requestHeaders,this.rehydrate()}static init(A){return new Y(A)}getItems(){return z(this.items).items}getState(){return z(this.items)}getItemCount(){return this.items.reduce((A,F)=>A+F.quantity,0)}getSubtotal(){return this.items.reduce((A,F)=>A+(F.fullPrice??F.unitPrice)*F.quantity,0)}getTotal(){return this.items.reduce((A,F)=>A+F.unitPrice*F.quantity,0)}subscribe(A){return this.listeners.add(A),A(this.getState()),()=>{this.listeners.delete(A)}}destroy(){this.listeners.clear()}rehydrate(){if(!this.persist||!this.storage)return;try{let A=this.storage.getItem(this.storageKey);if(!A)return;let F=JSON.parse(A),G=Array.isArray(F)?F:F.items;if(!Array.isArray(G))return;this.items=W(G.map((J)=>this.normalizeItem(J)).filter((J)=>Boolean(J))),this.emit()}catch(A){this.log("Failed to hydrate cart",A)}}addItem(A){let F=this.normalizeItem(A);if(!F)return;let G=this.items.find((J)=>J.id===F.id);if(G){this.setQuantity(G.id,G.quantity+F.quantity);return}this.items=[...this.items,F],this.commit()}removeItem(A){this.items=this.items.filter((F)=>F.id!==A),this.commit()}setQuantity(A,F){let G=Math.floor(F);this.items=G<=0?this.items.filter((J)=>J.id!==A):this.items.map((J)=>J.id===A?{...J,quantity:G}:J),this.commit()}increment(A,F=1){let G=this.items.find((J)=>J.id===A);if(G)this.setQuantity(A,G.quantity+Math.max(1,Math.floor(F)))}decrement(A,F=1){let G=this.items.find((J)=>J.id===A);if(G)this.setQuantity(A,G.quantity-Math.max(1,Math.floor(F)))}clear(){if(this.items=[],this.persist&&this.storage)try{this.storage.removeItem(this.storageKey)}catch(A){this.log("Failed to clear cart storage",A)}this.emit()}async resolveCheckoutUrl(A=this.defaultCheckoutLinkKey){let F=this.checkoutLinks[A];if(!F)throw new O("checkout_link_not_found",`Unknown checkout link key: ${A}`);let G=b(F),J=this.itemsForCheckout(A,F),M={siteKey:this.siteKey,checkoutLinkId:G.checkoutLinkId,mode:F.mode,...G.discountCode?{discountCode:G.discountCode}:{},...J.length>0?{items:J}:{}};return(await this.post("/checkout-url",M)).checkoutUrl}async checkout(A=this.defaultCheckoutLinkKey){let F=await this.resolveCheckoutUrl(A),G=v();if(G)G.location.assign(F);return F}itemsForCheckout(A,F){if(F.mode==="static")return[];let G=this.items.filter((J)=>J.checkoutLinkKey===A).map((J)=>({lineItemId:J.lineItemId,quantity:J.quantity,...J.discount?{discount:J.discount}:{}}));if(G.length===0)throw new O("cart_empty","Your cart is empty.");return G}normalizeItem(A){if(!A.id||!A.lineItemId||typeof A.unitPrice!=="number")return null;let F=typeof A.name==="string"&&A.name.trim().length>0?A.name.trim():"Item";return{...A,id:A.id,lineItemId:A.lineItemId,checkoutLinkKey:A.checkoutLinkKey??this.defaultCheckoutLinkKey,name:F,unitPrice:A.unitPrice,quantity:q(A.quantity)}}async post(A,F){let G=`${this.endpoint}${A}`,J=JSON.stringify(F),M={"Content-Type":"application/json"},P={body:F,bodyText:J,endpoint:this.endpoint,headers:M,path:A,siteKey:this.siteKey,url:G},V=typeof this.requestHeaders==="function"?await this.requestHeaders(P):this.requestHeaders,Q=I(M,V),X=await fetch(G,{method:"POST",headers:Q,body:J}),N=await X.json().catch(()=>null);if(!X.ok){let U=typeof N?.code==="string"&&N.code.length>0?N.code:"request_failed",H=typeof N?.message==="string"&&N.message.length>0?N.message:"Cart request failed";throw new O(U,H,X.status)}if(!N||typeof N!=="object"||N.ok!==!0||typeof N.checkoutUrl!=="string"||N.checkoutUrl.length===0)throw new O("request_failed","Cart response was invalid.",X.status);return N}commit(){if(this.items=W(this.items),this.persist&&this.storage)try{let A={version:R,items:this.items};this.storage.setItem(this.storageKey,JSON.stringify(A))}catch(A){this.log("Failed to persist cart",A)}this.emit()}emit(){let A=this.getState();for(let F of this.listeners)F(A)}log(...A){if(this.debug)console.log("[@behindthescenes/cart]",...A)}}function S(A){return Y.init(A)}export{S as createBTSCart,O as BTSCartError,Y as BTSCart};
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@behindthescenes/cart",
3
- "version": "0.0.6",
4
- "generatedAt": "2026-05-15T09:38:53.907Z",
3
+ "version": "0.0.8",
4
+ "generatedAt": "2026-05-15T10:30:41.615Z",
5
5
  "artifacts": {
6
6
  "browser": "browser/browser.js",
7
7
  "cjs": "cjs/index.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@behindthescenes/cart",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "Browser cart SDK for BTS external-site checkout links.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",