🚀 Big News:Socket Has Acquired Secure Annex.Learn More
Socket
Book a DemoSign in
Socket

@cocartheadless/sdk

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@cocartheadless/sdk - npm Package Compare versions

Comparing version
1.0.0
to
1.1.0
+3
dist/index.global.js
"use strict";var CoCartSDK=(()=>{var $=Object.defineProperty;var O=Object.getOwnPropertyDescriptor;var V=Object.getOwnPropertyNames;var J=Object.prototype.hasOwnProperty;var H=(i,e)=>{for(var t in e)$(i,t,{get:e[t],enumerable:!0})},D=(i,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of V(e))!J.call(i,s)&&s!==t&&$(i,s,{get:()=>e[s],enumerable:!(r=O(e,s))||r.enumerable});return i};var L=i=>D($({},"__esModule",{value:!0}),i);var U={};H(U,{AuthenticationError:()=>g,Cart:()=>b,CoCart:()=>I,CoCartError:()=>c,CurrencyFormatter:()=>j,EncryptedStorage:()=>P,Endpoint:()=>h,JwtManager:()=>d,LocalStorage:()=>w,MemoryStorage:()=>R,Paginator:()=>C,Products:()=>k,Response:()=>y,SessionManager:()=>_,Sessions:()=>v,Store:()=>T,TimezoneHelper:()=>E,ValidationError:()=>m,VersionError:()=>f,validateEmail:()=>N,validateProductId:()=>K,validateQuantity:()=>x});var y=class{statusCode;headers;body;data=null;constructor(e,t,r){this.statusCode=e,this.headers=t,this.body=r}toObject(){if(this.data===null)try{this.data=JSON.parse(this.body)}catch{this.data={}}return this.data}toJson(e=!0){return JSON.stringify(this.toObject(),null,e?2:void 0)}isSuccessful(){return this.statusCode>=200&&this.statusCode<300}isError(){return this.statusCode>=400}get(e,t){let r=this.toObject(),s=e.split("."),n=r;for(let a of s){if(n==null||typeof n!="object")return t;n=n[a]}return n!==void 0?n:t}has(e){let t=this.toObject(),r=e.split("."),s=t;for(let n of r){if(s==null||typeof s!="object"||!(n in s))return!1;s=s[n]}return!0}getHeader(e,t=null){return this.headers.get(e)??t}getCartKey(){return this.getHeader("Cart-Key")}getCartHash(){return this.get("cart_hash",null)}getItems(){return this.get("items",[])}getTotals(){return this.get("totals",{})}getItemCount(){return this.get("item_count",0)}hasItems(){return this.getItemCount()>0}isEmpty(){return this.getItemCount()===0}getNotices(){return this.get("notices",[])}getCoupons(){return this.get("coupons",[])}hasCoupons(){return this.getCoupons().length>0}getCustomer(){return this.get("customer",{})}getCurrency(){return this.get("currency",{})}getShippingMethods(){return this.get("shipping",[])}getFees(){return this.get("fees",[])}getCrossSells(){return this.get("cross_sells",[])}getTotalResults(){let e=this.getHeader("X-WP-Total");return e!==null?parseInt(e,10):null}getTotalPages(){let e=this.getHeader("X-WP-TotalPages");return e!==null?parseInt(e,10):null}getETag(){return this.getHeader("ETag")}isNotModified(){return this.statusCode===304}getCacheStatus(){return this.getHeader("CoCart-Cache")}getErrorCode(){return this.isError()?this.get("code",null):null}getErrorMessage(){return this.isError()?this.get("message",null):null}};var c=class extends Error{httpCode;errorCode;responseData;constructor(e,t=0,r=null,s={}){super(e),this.name="CoCartError",this.httpCode=t,this.errorCode=r,this.responseData=s}};var g=class extends c{constructor(e,t=401,r=null,s={}){super(e,t,r,s),this.name="AuthenticationError"}};var m=class extends c{constructor(e,t=400,r=null,s={}){super(e,t,r,s),this.name="ValidationError"}};var f=class extends c{constructor(e){super(`${e}() requires CoCart Basic. Please upgrade from the legacy CoCart plugin to use this feature.`,0,"cocart_version_required"),this.name="VersionError"}};var R=class{store=new Map;get(e){return this.store.get(e)??null}set(e,t){this.store.set(e,t)}delete(e){this.store.delete(e)}};var w=class{prefix;constructor(e="cocart_"){this.prefix=e}get(e){return globalThis.localStorage.getItem(this.prefix+e)}set(e,t){globalThis.localStorage.setItem(this.prefix+e,t)}delete(e){globalThis.localStorage.removeItem(this.prefix+e)}};var P=class{prefix;cryptoKey=null;keyPromise=null;encryptionKey;constructor(e,t){this.encryptionKey=e,this.prefix=t?.prefix??"cocart_enc_"}async get(e){let t=globalThis.localStorage.getItem(this.prefix+e);if(t===null)return null;try{let r=await this.getKey(),s=this.base64ToBytes(t),n=s.slice(0,12),a=s.slice(12),o=await globalThis.crypto.subtle.decrypt({name:"AES-GCM",iv:n},r,a);return new TextDecoder().decode(o)}catch{return globalThis.localStorage.removeItem(this.prefix+e),null}}async set(e,t){let r=await this.getKey(),s=globalThis.crypto.getRandomValues(new Uint8Array(12)),n=new TextEncoder().encode(t),a=await globalThis.crypto.subtle.encrypt({name:"AES-GCM",iv:s},r,n),o=new Uint8Array(s.length+a.byteLength);o.set(s,0),o.set(new Uint8Array(a),s.length),globalThis.localStorage.setItem(this.prefix+e,this.bytesToBase64(o))}delete(e){globalThis.localStorage.removeItem(this.prefix+e)}async getKey(){return this.cryptoKey?this.cryptoKey:(this.keyPromise||(this.keyPromise=this.deriveKey()),this.cryptoKey=await this.keyPromise,this.cryptoKey)}async deriveKey(){let e=this.getOrCreateSalt(),t=await globalThis.crypto.subtle.importKey("raw",new TextEncoder().encode(this.encryptionKey),"PBKDF2",!1,["deriveKey"]);return globalThis.crypto.subtle.deriveKey({name:"PBKDF2",salt:e.buffer,iterations:1e5,hash:"SHA-256"},t,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"])}getOrCreateSalt(){let e=this.prefix+"_salt",t=globalThis.localStorage.getItem(e);if(t)return this.base64ToBytes(t);let r=globalThis.crypto.getRandomValues(new Uint8Array(16));return globalThis.localStorage.setItem(e,this.bytesToBase64(r)),r}bytesToBase64(e){let t="";for(let r=0;r<e.length;r++)t+=String.fromCharCode(e[r]);return btoa(t)}base64ToBytes(e){let t=atob(e),r=new Uint8Array(t.length);for(let s=0;s<t.length;s++)r[s]=t.charCodeAt(s);return r}};var h=class{client;endpoint="";constructor(e){this.client=e}buildPath(e=""){return e?this.endpoint.replace(/\/+$/,"")+"/"+e.replace(/^\/+/,""):this.endpoint}async get(e,t){let r=typeof e=="string"?e:"",s=typeof e=="object"?e:t;try{return await this.client.get(this.buildPath(r),s)}catch(n){this.handleNoRoute(n)}}async post(e="",t,r){try{return await this.client.post(this.buildPath(e),t,r)}catch(s){this.handleNoRoute(s)}}async put(e="",t,r){try{return await this.client.put(this.buildPath(e),t,r)}catch(s){this.handleNoRoute(s)}}async delete(e="",t){try{return await this.client.delete(this.buildPath(e),t)}catch(r){this.handleNoRoute(r)}}handleNoRoute(e){throw e instanceof c&&e.errorCode==="rest_no_route"?new c("This method is only available with another CoCart plugin. Please ask support for assistance!",404,"cocart_plugin_required"):e}};function K(i){let e=typeof i=="string"?parseInt(i,10):i;if(!Number.isFinite(e)||e<1||Math.floor(e)!==e)throw new m("Product ID must be a positive integer",0,"cocart_invalid_product_id")}function x(i){if(!Number.isFinite(i)||i<1)throw new m("Quantity must be a positive number",0,"cocart_invalid_quantity")}function N(i){if(!i||!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(i))throw new m("A valid email address is required",0,"cocart_invalid_email")}var b=class extends h{endpoint="cart";async get(e,t){return typeof e=="object"||e===void 0?this.client.get(this.endpoint,e?this.stringifyParams(e):void 0):super.get(e,t)}async getFiltered(e){return this.client.get(this.endpoint,{_fields:e.join(",")})}async addItem(e,t=1,r={}){K(e),x(t);let s={id:String(e),quantity:String(t),...r};return this.post("add-item",s)}async addItems(e){let t=e.map(r=>({...r,id:String(r.id),quantity:String(r.quantity)}));return this.post("add-items",{items:t})}async updateItem(e,t,r={}){x(t);let s={quantity:String(t),...r};return this.post(`item/${e}`,s)}async updateItems(e){let t;return Array.isArray(e)?t=e.map(r=>({...r,quantity:String(r.quantity)})):t=Object.entries(e).map(([r,s])=>({item_key:r,quantity:String(s)})),this.post("update",{items:t})}async removeItem(e){return this.delete(`item/${e}`)}async removeItems(e){let t=e.map(r=>({item_key:r,quantity:"0"}));return this.post("update",{items:t})}async restoreItem(e){return this.put(`item/${e}`)}async getRemovedItems(){return super.get("",{_fields:"removed_items"})}async clear(){return this.post("clear")}async empty(){return this.clear()}async calculate(e={}){return this.post("calculate",e)}async getTotals(e=!1){let t=e?{html:"true"}:void 0;return this.client.get("cart/totals",t)}async getItemCount(){return this.client.get("cart/items/count")}async create(){return this.client.requiresBasic("cart()->create"),this.post("")}async getItems(e){return super.get("items",e)}async getItem(e,t){return super.get("item/"+e,t)}async update(e){return this.post("update",e)}async applyCoupon(e){return this.post("apply-coupon",{coupon:e})}async removeCoupon(e){return this.delete(`coupons/${e}`)}async getCoupons(){return super.get("",{_fields:"coupons"})}async checkCoupons(){return super.get("coupons/validate")}async updateCustomer(e={},t={}){let r={};for(let[s,n]of Object.entries(e))r[`billing_${s}`]=n;for(let[s,n]of Object.entries(t))r[`shipping_${s}`]=n;return this.post("update",r)}async getCustomer(){return super.get("",{_fields:"customer"})}async getShippingMethods(){return super.get("",{_fields:"shipping"})}async setShippingMethod(e){return this.post("set-shipping-method",{method_key:e})}async calculateShipping(e){return this.post("calculate/shipping",e)}async getFees(){return super.get("",{_fields:"fees"})}async addFee(e,t,r=!1){return this.post("add-fee",{name:e,amount:t,taxable:r})}async removeFees(){return this.post("remove-fees")}async getCrossSells(){return super.get("",{_fields:"cross_sells"})}async add(e,t=1){return this.addItem(e,t)}async addVariation(e,t=1,r={}){return this.addItem(e,t,{variation:r})}stringifyParams(e){let t={};for(let[r,s]of Object.entries(e))s!=null&&(t[r]=String(s));return t}};var C=class{fetchPage;startPage;constructor(e,t=1){this.fetchPage=e,this.startPage=t}async*[Symbol.asyncIterator](){let e=this.startPage;for(;;){let t=await this.fetchPage(e);yield t;let r=t.getTotalPages();if(r===null||e>=r)break;e++}}async toArray(){let e=[];for await(let t of this)e.push(t);return e}};var k=class extends h{endpoint="products";async all(e){return this.get("",e?this.stringifyParams(e):void 0)}async find(e,t){return this.get(String(e),t?this.stringifyParams(t):void 0)}async findBySlug(e,t){return this.client.requiresBasic("products()->findBySlug"),this.get(e,t?this.stringifyParams(t):void 0)}async search(e,t={}){return this.all({...t,search:e})}async byCategory(e,t={}){return this.all({...t,category:e})}async byTag(e,t={}){return this.all({...t,tag:e})}async featured(e={}){return this.all({...e,featured:!0})}async onSale(e={}){return this.all({...e,on_sale:!0})}async byPriceRange(e,t,r={}){let s={...r};return e!=null&&(s.min_price=e),t!=null&&(s.max_price=t),this.all(s)}async sortBy(e,t="asc",r={}){return this.all({...r,orderby:e,order:t})}async byStockStatus(e,t={}){return this.all({...t,stock_status:e})}async paginate(e=1,t=10,r={}){return this.all({...r,page:e,per_page:t})}allPaginated(e={}){return new C(t=>this.all({...e,page:t}))}async variations(e,t){return this.get(`${e}/variations`,t)}async variation(e,t,r){return this.client.requiresBasic("products()->variation"),this.get(`${e}/variations/${t}`,r)}async categories(e){return this.get("categories",e)}async category(e,t){return this.client.requiresBasic("products()->category"),this.get(`categories/${e}`,t)}async tags(e){return this.get("tags",e)}async tag(e,t){return this.client.requiresBasic("products()->tag"),this.get(`tags/${e}`,t)}async attributes(e){return this.get("attributes",e)}async attribute(e,t){return this.get(`attributes/${e}`,t)}async attributeTerms(e,t){return this.get(`attributes/${e}/terms`,t)}async attributeTerm(e,t,r){return this.get(`attributes/${e}/terms/${t}`,r)}async attributeBySlug(e,t){return this.client.requiresBasic("products()->attributeBySlug"),this.get(`attributes/${e}`,t)}async attributeTermsBySlug(e,t){return this.client.requiresBasic("products()->attributeTermsBySlug"),this.get(`attributes/${e}/terms`,t)}async attributeTermBySlug(e,t,r){return this.client.requiresBasic("products()->attributeTermBySlug"),this.get(`attributes/${e}/terms/${t}`,r)}async brands(e){return this.client.requiresBasic("products()->brands"),this.get("brands",e)}async brand(e,t){return this.client.requiresBasic("products()->brand"),this.get(`brands/${e}`,t)}async byBrand(e,t={}){return this.client.requiresBasic("products()->byBrand"),this.all({...t,brand:e})}async reviews(e){return this.get("reviews",e)}async productReviews(e,t={}){return this.reviews({...t,product:String(e)})}async myReviews(e){return this.client.requiresBasic("products()->myReviews"),this.get("reviews/mine",e)}async seo(e){return this.get(`${e}/seo`)}async seoBySlug(e){return this.get(`${e}/seo`)}stringifyParams(e){let t={};for(let[r,s]of Object.entries(e))s!=null&&(t[r]=String(s));return t}};var T=class extends h{endpoint="store";async info(e){return this.get("",e)}};var v=class extends h{endpoint="sessions";async all(e){return this.get("",e)}async find(e,t){return this.client.get("session/"+e,t)}async destroy(e){return this.client.delete("session/"+e)}async getItems(e){return this.client.get("session/"+e+"/items")}async bySession(e){return this.client.get("session/"+String(e))}async destroySession(e){return this.client.delete("session/"+String(e))}};var d=class{client;storage;tokenStorageKey="cocart_jwt_token";refreshTokenStorageKey="cocart_jwt_refresh_token";autoRefresh=!1;isRefreshing=!1;constructor(e,t=null,r={}){this.client=e,this.storage=t,r.autoRefresh!==void 0&&(this.autoRefresh=r.autoRefresh),r.tokenStorageKey&&(this.tokenStorageKey=r.tokenStorageKey),r.refreshTokenStorageKey&&(this.refreshTokenStorageKey=r.refreshTokenStorageKey)}async restoreTokensFromStorage(){if(!this.storage)return;let e=await this.storage.get(this.tokenStorageKey),t=await this.storage.get(this.refreshTokenStorageKey);e&&this.client.setJwtToken(e),t&&this.client.setRefreshToken(t)}async login(e,t){let r=await this.client.post("login",{username:e,password:t}),n=r.toObject().extras,a=n?.jwt_token,o=n?.jwt_refresh;if(a)this.client.setJwtToken(a),o&&this.client.setRefreshToken(o),await this.persistTokens();else throw new g("JWT token not found in login response. Is the CoCart JWT Authentication plugin installed?",0,"cocart_jwt_missing");return r}async refresh(e){let t=e??this.client.getRefreshToken();if(!t)throw new g("No refresh token available. Please login first.",0,"cocart_jwt_no_refresh_token");let r=`${this.client.getNamespace()}/jwt/refresh-token`,s=await this.client.requestRaw("POST",r,void 0,{refresh_token:t}),n=s.toObject(),a=n.token,o=n.refresh_token;return a&&this.client.setJwtToken(a),o&&this.client.setRefreshToken(o),await this.persistTokens(),s}async validate(){if(!this.client.hasJwtToken())return!1;try{let e=`${this.client.getNamespace()}/jwt/validate-token`;return(await this.client.requestRaw("POST",e)).isSuccessful()}catch(e){if(e instanceof g)return!1;throw e}}async withAutoRefresh(e){try{return await e(this.client)}catch(t){if(t instanceof g&&!this.isRefreshing&&this.client.getRefreshToken()){this.isRefreshing=!0;try{return await this.refresh(),await e(this.client)}catch{throw t}finally{this.isRefreshing=!1}}throw t}}async clearTokens(){return this.client.clearJwtToken(),this.storage&&(await this.storage.delete(this.tokenStorageKey),await this.storage.delete(this.refreshTokenStorageKey)),this}hasTokens(){return this.client.hasJwtToken()}isTokenExpired(e=30){let t=this.client.getJwtToken();if(!t)return!0;let r=this.decodeTokenPayload(t);return r?r.exp?Date.now()/1e3>=r.exp-e:!1:!0}getTokenExpiry(){let e=this.client.getJwtToken();return e?this.decodeTokenPayload(e)?.exp??null:null}setAutoRefresh(e){return this.autoRefresh=e,this}isAutoRefreshEnabled(){return this.autoRefresh}getClient(){return this.client}decodeTokenPayload(e){let t=e.split(".");if(t.length!==3)return null;try{let r=atob(t[1].replace(/-/g,"+").replace(/_/g,"/"));return JSON.parse(r)}catch{return null}}async persistTokens(){if(!this.storage)return;let e=this.client.getJwtToken(),t=this.client.getRefreshToken();e&&await this.storage.set(this.tokenStorageKey,e),t&&await this.storage.set(this.refreshTokenStorageKey,t)}};function F(){return typeof globalThis<"u"&&typeof globalThis.localStorage<"u"?new w:new R}var I=class i{static VERSION="1.0.0";static API_VERSION="v2";storeUrl;restPrefix="wp-json";namespace="cocart";storageKey="cocart_cart_key";cartKey=null;auth=null;jwtToken=null;refreshTokenValue=null;consumerKey=null;consumerSecret=null;maxRetries=0;timeout=3e4;customHeaders={};lastResponseValue=null;storage;debug=!1;authHeaderName="Authorization";responseTransformer=null;etagEnabled=!0;etagCache=new Map;mainPlugin="basic";listeners={};jwtManagerInstance=null;cartInstance=null;productsInstance=null;storeInstance=null;sessionsInstance=null;constructor(e,t={}){this.storeUrl=e.replace(/\/+$/,""),t.storage?this.storage=t.storage:t.encryptionKey?this.storage=new P(t.encryptionKey):this.storage=F(),t.cartKey&&(this.cartKey=t.cartKey),t.username&&t.password&&(this.auth={username:t.username,password:t.password}),t.jwtToken&&(this.jwtToken=t.jwtToken),t.jwtRefreshToken&&(this.refreshTokenValue=t.jwtRefreshToken),t.consumerKey&&t.consumerSecret&&(this.consumerKey=t.consumerKey,this.consumerSecret=t.consumerSecret),t.timeout!==void 0&&(this.timeout=t.timeout),t.restPrefix!==void 0&&(this.restPrefix=t.restPrefix.replace(/^\/+|\/+$/g,"")),t.namespace!==void 0&&(this.namespace=t.namespace.replace(/^\/+|\/+$/g,"")),t.headers&&(this.customHeaders={...t.headers}),t.storageKey&&(this.storageKey=t.storageKey),t.maxRetries!==void 0&&(this.maxRetries=Math.max(0,t.maxRetries)),t.debug!==void 0&&(this.debug=t.debug),t.authHeaderName&&(this.authHeaderName=t.authHeaderName),t.responseTransformer&&(this.responseTransformer=t.responseTransformer),t.etag!==void 0&&(this.etagEnabled=t.etag),t.mainPlugin&&(this.mainPlugin=t.mainPlugin)}static create(e){return new i(e)}async restoreSession(){if(this.cartKey===null){let e=await this.storage.get(this.storageKey);e&&(this.cartKey=e)}}setCartKey(e){return this.cartKey=e,this}getCartKey(){return this.cartKey}setAuth(e,t){return this.auth={username:e,password:t},this.jwtToken=null,this}setJwtToken(e){return this.jwtToken=e,this.auth=null,this}getJwtToken(){return this.jwtToken}setRefreshToken(e){return this.refreshTokenValue=e,this}getRefreshToken(){return this.refreshTokenValue}hasJwtToken(){return this.jwtToken!==null&&this.jwtToken!==""}clearJwtToken(){return this.jwtToken=null,this.refreshTokenValue=null,this}setWooCommerceCredentials(e,t){return this.consumerKey=e,this.consumerSecret=t,this}setTimeout(e){return this.timeout=e,this}setMaxRetries(e){return this.maxRetries=Math.max(0,e),this}setRestPrefix(e){return this.restPrefix=e.replace(/^\/+|\/+$/g,""),this}getRestPrefix(){return this.restPrefix}setNamespace(e){return this.namespace=e.replace(/^\/+|\/+$/g,""),this}getNamespace(){return this.namespace}addHeader(e,t){return this.customHeaders[e]=t,this}setStorage(e){return this.storage=e,this}getStorage(){return this.storage}setDebug(e){return this.debug=e,this}setAuthHeaderName(e){return this.authHeaderName=e,this}setETag(e){return this.etagEnabled=e,this}clearETagCache(){return this.etagCache.clear(),this}getMainPlugin(){return this.mainPlugin}setMainPlugin(e){return this.mainPlugin=e,this}requiresBasic(e){if(this.mainPlugin==="legacy")throw new f(e)}setResponseTransformer(e){return this.responseTransformer=e,this}on(e,t){return this.listeners[e]||(this.listeners[e]=new Set),this.listeners[e].add(t),this}off(e,t){return this.listeners[e]?.delete(t),this}emit(e,t){if(this.debug&&this.logDebug(e,t),this.listeners[e])for(let r of this.listeners[e])try{r(t)}catch{}}logDebug(e,t){let r="[CoCart]",s=t;switch(e){case"request":console.log(`${r} ${s.method} ${s.url}`);break;case"response":console.log(`${r} ${s.method} ${s.url} \u2192 ${s.status} (${s.duration}ms)`);break;case"error":console.error(`${r} ${s.method} ${s.url} \u2192 Error:`,s.error);break;case"retry":console.log(`${r} Retry ${s.attempt}/${s.maxRetries} after ${s.delay}ms (${s.reason})`);break;case"auth:refresh":console.log(`${r} JWT token refresh ${s.success?"succeeded":"failed"}`);break}}jwt(){return this.jwtManagerInstance===null&&(this.jwtManagerInstance=new d(this,this.storage,{autoRefresh:!0})),this.jwtManagerInstance}async login(e,t){return this.jwt().login(e,t)}async logout(){try{await this.post("logout")}catch{}return await this.jwt().clearTokens(),this}isAuthenticated(){return this.auth!==null||this.jwtToken!==null&&this.jwtToken!==""}isGuest(){return!this.isAuthenticated()}async clearSession(){return this.auth=null,this.jwtToken=null,this.refreshTokenValue=null,this.cartKey=null,await this.storage.delete(this.storageKey),this}async transferCartToCustomer(e,t){let r=this.cartKey;return this.setAuth(e,t),r?this.cart().get({cart_key:r}):this.cart().get()}cart(){return this.cartInstance===null&&(this.cartInstance=new b(this)),this.cartInstance}products(){return this.productsInstance===null&&(this.productsInstance=new k(this)),this.productsInstance}store(){return this.storeInstance===null&&(this.storeInstance=new T(this)),this.storeInstance}sessions(){return this.sessionsInstance===null&&(this.sessionsInstance=new v(this)),this.sessionsInstance}async get(e,t){return this.request("GET",e,t)}async post(e,t,r){return this.request("POST",e,r,t)}async put(e,t,r){return this.request("PUT",e,r,t)}async delete(e,t){return this.request("DELETE",e,t)}async request(e,t,r,s){try{return await this.executeRequest(e,t,r,s)}catch(n){if(n instanceof g&&this.jwtManagerInstance?.isAutoRefreshEnabled()&&this.refreshTokenValue!==null)try{return await this.jwtManagerInstance.refresh(),this.emit("auth:refresh",{success:!0}),await this.executeRequest(e,t,r,s)}catch{throw this.emit("auth:refresh",{success:!1}),n}throw n}}async requestRaw(e,t,r,s){let n=`${this.storeUrl}/${this.restPrefix}/${t.replace(/^\/+/,"")}`;r&&Object.keys(r).length>0&&(n+="?"+new URLSearchParams(r).toString());let a=this.buildHeaders(),o=s?JSON.stringify(s):void 0,u=await this.fetchWithTimeout(e,n,a,o),S=await u.text();return this.lastResponseValue=new y(u.status,u.headers,S),await this.extractCartKeyFromHeaders(this.lastResponseValue),u.status>=400&&this.handleErrorResponse(this.lastResponseValue),this.applyTransformer(this.lastResponseValue)}getLastResponse(){return this.lastResponseValue}getStoreUrl(){return this.storeUrl}async executeRequest(e,t,r,s){let n=this.buildUrl(t,r),a=this.buildHeaders(),o=s?JSON.stringify(s):void 0;if(e==="GET"&&this.etagEnabled&&!r?._skip_cache){let l=this.etagCache.get(n);l&&(a["If-None-Match"]=l)}this.emit("request",{method:e,url:n,headers:a,body:o});let u=0,S=Date.now();for(;;){let l;try{l=await this.fetchWithTimeout(e,n,a,o)}catch(p){if(u<this.maxRetries&&this.isTransientError(p)){u++;let q=this.getRetryDelay(u);this.emit("retry",{method:e,url:n,attempt:u,maxRetries:this.maxRetries,delay:q,reason:"transient_error"}),await this.retrySleep(u);continue}let M=p instanceof c?p:new c(p instanceof Error?p.message:"Network error",0,"network_error");throw this.emit("error",{method:e,url:n,error:M}),M}let B=await l.text(),A=Date.now()-S;if(this.lastResponseValue=new y(l.status,l.headers,B),await this.extractCartKeyFromHeaders(this.lastResponseValue),e==="GET"&&this.etagEnabled){let p=this.lastResponseValue.getETag();p&&this.etagCache.set(n,p)}if(u<this.maxRetries&&this.isRetryableStatus(l.status)){u++;let p=this.getRetryDelay(u,this.lastResponseValue);this.emit("retry",{method:e,url:n,attempt:u,maxRetries:this.maxRetries,delay:p,reason:`http_${l.status}`}),await this.retrySleep(u,this.lastResponseValue);continue}return l.status>=400&&(this.emit("response",{method:e,url:n,status:l.status,duration:A}),this.handleErrorResponse(this.lastResponseValue,e,n)),this.emit("response",{method:e,url:n,status:l.status,duration:A}),this.applyTransformer(this.lastResponseValue)}}async fetchWithTimeout(e,t,r,s){let n=new AbortController,a=setTimeout(()=>n.abort(),this.timeout);try{return await fetch(t,{method:e,headers:r,body:s,signal:n.signal})}catch(o){throw o instanceof DOMException&&o.name==="AbortError"?new c(`Request timed out after ${this.timeout}ms`,0,"request_timeout"):o}finally{clearTimeout(a)}}buildUrl(e,t){let r={...t??{}};this.cartKey&&!this.isAuthenticated()&&(r.cart_key=this.cartKey),this.mainPlugin==="legacy"?"_fields"in r&&!("fields"in r)&&(r.fields=r._fields,delete r._fields):"fields"in r&&!("_fields"in r)&&(r._fields=r.fields,delete r.fields);let s=`${this.storeUrl}/${this.restPrefix}/${this.namespace}/${i.API_VERSION}/${e.replace(/^\/+/,"")}`;return Object.keys(r).length>0&&(s+="?"+new URLSearchParams(r).toString()),s}buildHeaders(){let e={Accept:"application/json","Content-Type":"application/json","User-Agent":`CoCart-TS-SDK/${i.VERSION}`};return this.jwtToken?e[this.authHeaderName]=`Bearer ${this.jwtToken}`:this.auth?e[this.authHeaderName]=`Basic ${btoa(`${this.auth.username}:${this.auth.password}`)}`:this.consumerKey&&this.consumerSecret&&(e[this.authHeaderName]=`Basic ${btoa(`${this.consumerKey}:${this.consumerSecret}`)}`),this.cartKey&&!this.isAuthenticated()&&(e["Cart-Key"]=this.cartKey),{...e,...this.customHeaders}}async extractCartKeyFromHeaders(e){let t=e.getHeader("Cart-Key");t!==null&&(this.cartKey=t,await this.storage.set(this.storageKey,t))}handleErrorResponse(e,t,r){let s=e.toObject(),n=s.code??"unknown_error",a=s.message??"An unknown error occurred",o=e.statusCode,u=t&&r?`${t} ${r}: `:"",S=n!=="unknown_error"?` [${n}]`:"",l=`${u}${a}${S}`;throw o===401||o===403||typeof n=="string"&&n.includes("authenticat")?new g(l,o,n,s):o===400||typeof n=="string"&&(n.includes("invalid")||n.includes("missing"))?new m(l,o,n,s):new c(l,o,n,s)}isTransientError(e){if(e instanceof c){let t=e.message.toLowerCase();return t.includes("timeout")||t.includes("timed out")||t.includes("connection")}return!1}isRetryableStatus(e){return e===429||e===503}getRetryDelay(e,t){if(t){let r=t.getHeader("Retry-After");if(r!==null&&!isNaN(Number(r)))return Math.min(Number(r),60)*1e3}return Math.min(Math.pow(2,e-1),30)*1e3}async retrySleep(e,t){if(t){let r=t.getHeader("Retry-After");if(r!==null&&!isNaN(Number(r))){await this.sleep(Math.min(Number(r),60)*1e3);return}}await this.sleep(Math.min(Math.pow(2,e-1),30)*1e3)}applyTransformer(e){return this.responseTransformer?this.responseTransformer(e):e}sleep(e){return new Promise(t=>setTimeout(t,e))}};var _=class{client;storage;storageKey="cocart_cart_key";jwtManagerInstance=null;constructor(e,t=null){this.client=e,this.storage=t}setStorageKey(e){return this.storageKey=e,this}getCartKey(){return this.client.getCartKey()}async setCartKey(e){return this.client.setCartKey(e),this.storage&&await this.storage.set(this.storageKey,e),this}async initializeCart(){let t=(await this.client.cart().get()).getCartKey()??this.client.getCartKey();return t&&this.storage&&await this.storage.set(this.storageKey,t),t}async login(e,t,r=!0){let s=this.client.getCartKey();return this.client.setAuth(e,t),await this.clearStoredCartKey(),r&&s?this.client.cart().get({cart_key:s}):this.client.cart().get()}async loginWithToken(e){let t=this.client.getCartKey();return this.client.setJwtToken(e),await this.clearStoredCartKey(),t?this.client.cart().get({cart_key:t}):this.client.cart().get()}jwt(e={}){return this.jwtManagerInstance===null&&(this.jwtManagerInstance=new d(this.client,this.storage,e)),this.jwtManagerInstance}async loginWithJwt(e,t,r=!0){let s=this.client.getCartKey(),n=await this.jwt().login(e,t);return await this.clearStoredCartKey(),r&&s&&await this.client.cart().get({cart_key:s}),n}async logout(){return this.jwtManagerInstance&&await this.jwtManagerInstance.clearTokens(),await this.client.clearSession(),await this.clearStoredCartKey(),this}isAuthenticated(){return this.client.isAuthenticated()}isGuest(){return this.client.isGuest()}getClient(){return this.client}async clearStoredCartKey(){this.storage&&await this.storage.delete(this.storageKey)}};var j=class{format(e,t){let r=e/Math.pow(10,t.currency_minor_unit);try{return new Intl.NumberFormat(void 0,{style:"currency",currency:t.currency_code,minimumFractionDigits:t.currency_minor_unit,maximumFractionDigits:t.currency_minor_unit}).format(r)}catch{return`${t.currency_prefix}${r.toFixed(t.currency_minor_unit)}${t.currency_suffix}`}}formatDecimal(e,t){return(e/Math.pow(10,t.currency_minor_unit)).toFixed(t.currency_minor_unit)}};var E=class{detectTimezone(){return Intl.DateTimeFormat().resolvedOptions().timeZone}convert(e,t,r){let s=new Date(e);if(!e.includes("Z")&&!e.includes("+")&&!/\d{2}:\d{2}$/.test(e)){let n=new Intl.DateTimeFormat("en-US",{timeZone:t,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1}).format(s),a=new Date(n);if(!isNaN(a.getTime()))return this.formatInTimezone(a,r)}return this.formatInTimezone(s,r)}toLocal(e,t="UTC"){return this.convert(e,t,this.detectTimezone())}formatInTimezone(e,t){return new Intl.DateTimeFormat("sv-SE",{timeZone:t,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1}).format(e).replace(" ","T")}};return L(U);})();
if(typeof CoCartSDK!=="undefined"){Object.assign(typeof window!=="undefined"?window:globalThis,CoCartSDK);}
//# sourceMappingURL=index.global.js.map

Sorry, the diff of this file is too big to display

+4
-2
{
"name": "@cocartheadless/sdk",
"version": "1.0.0",
"version": "1.1.0",
"description": "Official TypeScript SDK for the CoCart REST API",

@@ -9,2 +9,4 @@ "type": "module",

"types": "./dist/index.d.ts",
"unpkg": "./dist/index.global.js",
"jsdelivr": "./dist/index.global.js",
"exports": {

@@ -86,3 +88,3 @@ ".": {

"scripts": {
"build": "tsup --config tsup.config.ts && tsup --config tsup.adapters.ts",
"build": "tsup --config tsup.config.ts && tsup --config tsup.adapters.ts && tsup --config tsup.cdn.ts",
"dev": "tsup --watch",

@@ -89,0 +91,0 @@ "typecheck": "tsc --noEmit",

# @cocartheadless/sdk
[![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue?style=for-the-badge&labelColor=000000)](https://www.typescriptlang.org/)
[![npm version](https://img.shields.io/npm/v/@cocartheadless/sdk?style=for-the-badge&labelColor=000000)](https://www.npmjs.com/package/@cocartheadless/sdk)
[![jsDelivr hits](https://img.shields.io/jsdelivr/npm/hm/@cocartheadless/sdk?style=for-the-badge&labelColor=000000)](https://www.jsdelivr.com/package/npm/@cocartheadless/sdk)
[![Zero Dependencies](https://img.shields.io/badge/dependencies-0-brightgreen?style=for-the-badge&labelColor=000000)](https://www.npmjs.com/package/@cocartheadless/sdk)
[![Tests](https://img.shields.io/github/actions/workflow/status/cocart-headless/cocart-js/tests.yml?label=tests&style=for-the-badge&labelColor=000000)](https://github.com/cocart-headless/cocart-js/actions/workflows/tests.yml)

@@ -9,3 +13,3 @@ [![License](https://img.shields.io/github/license/jayanratna/resend-php?color=9cf&style=for-the-badge&labelColor=000000)](https://github.com/cocart-headless/cocart-js/blob/main/LICENSE)

> [!IMPORTANT]
> This SDK is still in development and not yet ready for production use. Provide feedback if you experience a bug.
> This SDK is looking for feedback, if you experience a bug please report it.

@@ -83,2 +87,38 @@ ## TODO to complete the SDK

### Via CDN (Framer, Webflow, plain HTML)
For platforms like **Framer**, **Webflow**, or any environment where you just need a `<script>` tag — no npm required:
**jsDelivr:**
```html
<script src="https://cdn.jsdelivr.net/npm/@cocartheadless/sdk/dist/index.global.js"></script>
```
**unpkg:**
```html
<script src="https://unpkg.com/@cocartheadless/sdk/dist/index.global.js"></script>
```
Then use it:
```html
<script>
const client = new CoCart('https://your-store.com');
</script>
```
This loads a single minified file that exposes all SDK exports under the `CoCart` global. See the dedicated guides for [Framer](docs/framer.md) and [Webflow](docs/webflow.md).
You can also pin a specific version:
```html
<!-- jsDelivr -->
<script src="https://cdn.jsdelivr.net/npm/@cocartheadless/sdk@1.1.0/dist/index.global.js"></script>
<!-- unpkg -->
<script src="https://unpkg.com/@cocartheadless/sdk@1.1.0/dist/index.global.js"></script>
```
## Quick Start

@@ -145,2 +185,4 @@

| [Deno](src/adapters/deno/README.md) | `Deno.serve()`, Fresh islands |
| [Framer](docs/framer.md) | CDN script, Code Overrides, product display |
| [Webflow](docs/webflow.md) | CDN script, custom code, dynamic elements |

@@ -147,0 +189,0 @@ ## Features