commerce-kit 0.0.41 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,10 +1,238 @@
1
- import{revalidateTag as P}from"next/cache";import R from"stripe";import{z as S}from"zod";import{neon as pt}from"@neondatabase/serverless";var T;process.env.DATABASE_URL&&(T=pt(process.env.DATABASE_URL));var lt=process.env.STRIPE_SECRET_KEY,mt=process.env.STRIPE_CURRENCY,y={StripeSecretKey:lt,StripeCurrency:mt};import{z as c}from"zod";function b(t,e){if(!t)throw new Error(e)}var H=async t=>{try{return[null,await t]}catch(e){return[e instanceof Error?e:new Error(String(e)),null]}},N=t=>{if(t==null)return 0;if(typeof t=="number")return t;let e=Number.parseInt(t,10);return Number.isNaN(e)?0:e},Y=t=>{if(t==null)return null;try{return JSON.parse(t)}catch{return null}};var ft=t=>t.toString().replace(/\\/g,"\\\\").replace(/"/g,'\\"'),V=t=>Object.entries(t).map(([e,n])=>`${e}:"${ft(n)}"`).join(" AND ").trim();function q(t){return t.toSorted((e,n)=>{let a=Number(e.metadata.order),o=Number(n.metadata.order);return Number.isNaN(a)&&Number.isNaN(o)||a===o?n.updated-e.updated:Number.isNaN(a)?1:Number.isNaN(o)?-1:a-o})}var gt=c.object({category:c.string().optional(),order:c.coerce.number().optional(),slug:c.string(),variant:c.string().optional(),stock:c.coerce.number().optional().transform(t=>t===void 0?Number.POSITIVE_INFINITY:t),digitalAsset:c.string().optional(),preview:c.string().optional()});function O({default_price:t,marketing_features:e,...n}){return b(t,"Product must have a default price"),b(typeof t=="object","Product default price must be an object"),{...n,default_price:t,marketing_features:e.map(a=>a.name).filter(Boolean),metadata:gt.parse(n.metadata)}}function yt(t){return!!(t.active&&!t.deleted&&t.default_price)}function W(t){return{...t,data:t.data.filter(yt)}}function K(t){return t.data.map(O)}function Z(t){return t}function tt(t){return t.data.map(Z)}function Q(t){return t.filter((e,n,a)=>n===a.findIndex(o=>o.metadata.slug===e.metadata.slug))}var et=t=>!t.deleted&&t.active,F=c.object({shippingRateId:c.string().optional(),taxCalculationId:c.string().optional(),taxCalculationExp:c.string().optional(),taxId:c.string().optional(),couponCode:c.string().optional(),taxedAmount:c.string().optional(),"billingAddress.city":c.string().optional(),"billingAddress.country":c.string().optional(),"billingAddress.line1":c.string().optional(),"billingAddress.line2":c.string().optional(),"billingAddress.name":c.string().optional(),"billingAddress.postalCode":c.string().optional(),"billingAddress.state":c.string().optional(),netAmount:c.string().optional(),taxBreakdown0:c.string().optional(),taxBreakdown1:c.string().optional(),taxBreakdown2:c.string().optional(),taxBreakdown3:c.string().optional(),taxBreakdown4:c.string().optional(),taxBreakdown5:c.string().optional()}).and(c.record(c.string(),c.string())),rt=c.object({taxType:c.string(),taxPercentage:c.string(),taxAmount:c.number()});function z(t){let e=t.payment_method;b(typeof e!="string","Payment method should not be a string");let n=t.customer;b(typeof n!="string"&&!n?.deleted,"Customer should not be a string");let a=F.parse(t.metadata),o=Object.entries(a).filter(([r])=>r.startsWith("taxBreakdown")).map(([r,i])=>{let u=rt.safeParse(Y(String(i)));return u.success?u.data:null}).filter(Boolean);return{...t,metadata:a,customer:n,payment_method:e,taxBreakdown:o}}function nt({payment_method:t,latest_charge:e,...n}){b(typeof t=="object","Payment method is missing from order"),b(typeof e=="object","Latest charge is missing from order");let a=F.parse(n.metadata),o=Object.entries(a).filter(([r])=>r.startsWith("taxBreakdown")).map(([r,i])=>{let u=rt.safeParse(Y(String(i)));return u.success?u.data:null}).filter(Boolean);return{...n,payment_method:t,latest_charge:e,taxBreakdown:o,metadata:a}}var v={DEBUG:0,LOG:1,WARN:2,ERROR:3},ht="LOG",xt=process.env.LOG_LEVEL&&process.env.LOG_LEVEL in v?process.env.LOG_LEVEL:ht,B=v[xt],d={time(t){B>v.DEBUG||console.time(t)},timeEnd(t){B>v.DEBUG||console.timeEnd(t)},log(...t){B>v.LOG||console.log(...t)},dir(t,e){B>v.LOG||console.dir(t,e)},warn(...t){B>v.WARN||console.warn(...t)},error(...t){B>v.ERROR||console.error(...t)}};var _=t=>t.filter(Boolean),x={accountGetById:{tags:({accountId:t})=>_(["account",t&&`account-${t}`]),revalidate:()=>{}},cartGetById:{tags:({cartId:t})=>_(["cart",`cart-${t}`]),revalidate:()=>{}},createTaxCalculation:{tags:({cartId:t})=>_(["tax-calculations",`tax-calculations-${t}`]),revalidate:()=>{}},fileGetById:{tags:({fileId:t})=>_(["files",`file-${t}`]),revalidate:()=>{}},orderGetById:{tags:({orderId:t})=>_(["order",`order-${t}`]),revalidate:()=>{}},productBrowse:{tags:({category:t})=>_(["product",t&&`category-${t}`]),revalidate:()=>{}},productGetById:{tags:({productId:t})=>_(["product",`product-${t}`]),revalidate:()=>{}},productGetBySlug:{tags:({productSlug:t})=>_(["product",`product-${t}`]),revalidate:()=>{}},shippingBrowse:{tags:()=>_(["shipping"]),revalidate:()=>{}},shippingGetById:{tags:({shippingId:t})=>_(["shipping",`shipping-${t}`]),revalidate:()=>{}},taxDefaultGet:{tags:()=>_(["tax-settings"]),revalidate:()=>{}}};import at from"stripe";var wt=(t,e)=>!t||!e?t:[...t,`prefix-${e}`,...t.map(n=>`${e}-${n}`)],m=({tags:t,revalidate:e,cache:n,tagPrefix:a,secretKey:o})=>{let r=o??y.StripeSecretKey;if(!r)throw new Error("Missing `secretKey` parameter and `STRIPE_SECRET_KEY` env variable.");let i=wt(t,a);return new at(r,{typescript:!0,apiVersion:"2025-08-27.basil",httpClient:at.createFetchHttpClient(((f,s)=>fetch(f,{...s,cache:n??s?.cache,next:{tags:i??s?.next?.tags,revalidate:e??s?.next?.revalidate}}))),appInfo:{name:"Commerce SDK",version:"beta",url:"https://yournextstore.com",partner_id:"CONS-003378"}})};var l=async()=>{let t={stripeAccount:void 0,storeId:void 0,secretKey:void 0,publishableKey:void 0};return await global?.__ynsFindStripeAccount?.()??t};var j=1e3;function oe({productId:t,cartId:e}){return e?Ct({cartId:e,productId:t,operation:"INCREASE",clearTaxCalculation:!0}):_t({productId:t})}async function Ct({productId:t,cartId:e,operation:n,clearTaxCalculation:a}){let[o,r]=await Promise.all([k(t),ct(e)]);if(!o)throw new Error(`Product not found: ${t}`);if(!r)throw new Error(`Cart not found: ${e}`);if(o.metadata.stock<=0)throw Error(`Product ${t} is out of stock`);if(!y.StripeCurrency)throw new Error("Missing `STRIPE_CURRENCY` env variable");if(y.StripeCurrency.toLowerCase()!==o.default_price.currency.toLowerCase())throw new Error(`Product currency ${o.default_price.currency} does not match cart currency ${y.StripeCurrency}`);let i=r.cart.metadata??{},s=N(i[t])+(n==="INCREASE"?1:-1);s<=0?i[t]="":i[t]=s.toString();let w=vt(r)+(o.default_price.unit_amount??0);try{return await E({paymentIntentId:e,data:{metadata:i,amount:w||j},clearTaxCalculation:a})}catch(h){d.error(h)}finally{P(`cart-${e}`)}}async function $(t){let{stripeAccount:e,storeId:n,secretKey:a}=await l(),o=m({secretKey:a,tagPrefix:n,tags:x.cartGetById.tags({cartId:t}),cache:"force-cache"});try{let r=await o.paymentIntents.retrieve(t,{expand:["payment_method","customer"]},{stripeAccount:e});if(it.includes(r.status)){let i=z(r);if(!i)return null;let u=await X(i.metadata),{metadata:{shippingRateId:f}}=i,s=f&&await L(f);return{cart:i,lines:u.map(({product:w,quantity:h})=>w?{product:w,quantity:h}:null).filter(Boolean),shippingRate:s||null}}}catch(r){if(d.error(r),r instanceof R.errors.StripeError&&r.code==="resource_missing")return null;throw r}}async function _t({productId:t}={}){let{stripeAccount:e,storeId:n,secretKey:a}=await l(),o=m({secretKey:a,tagPrefix:n,cache:"no-cache"});if(!y.StripeCurrency)throw new Error("Missing `STRIPE_CURRENCY` env variable");try{let r=t?await k(t):null;if(r&&r.metadata.stock<=0)throw Error(`Product ${t} is out of stock`);return await o.paymentIntents.create({currency:y.StripeCurrency,amount:r?.default_price.unit_amount||j,automatic_payment_methods:{enabled:!0},metadata:{...r&&{[r.id]:"1"}}},{stripeAccount:e})}catch(r){throw d.error(r),r}}async function ie({cart:t,add:e}){if(!e)return t;let n=await k(e);if(!n)return d.warn(`Product not found: ${e}`),t;let o=(t?.lines.find(i=>i.product.id===e)?t.lines:[...t?.lines??[],{product:n,quantity:0}]).map(i=>i.product.id===e?{...i,quantity:i.quantity+1}:i),r=t?U(t)+(n.default_price.unit_amount??0):n.default_price.unit_amount??0;return{...t,cart:{...t?.cart,amount:r},lines:o}}async function se({cartId:t,productId:e,quantity:n}){let[a,o]=await Promise.all([J(e),$(t)]);if(!a)throw new Error(`Product not found: ${e}`);if(!o)throw new Error(`Cart not found: ${t}`);if(y.StripeCurrency?.toLowerCase()!==a.default_price.currency.toLowerCase())throw new Error(`Product currency ${a.default_price.currency} does not match cart currency ${y.StripeCurrency}`);let r=o.cart.metadata??{};n<=0?r[e]="":r[e]=n.toString();let i=U(o)+(a.default_price.unit_amount??0);try{return await E({paymentIntentId:t,data:{metadata:r,amount:i||j}})}catch(u){d.error(u)}finally{P(`cart-${t}`)}}async function J(t){let{stripeAccount:e,storeId:n,secretKey:a}=await l(),o=m({secretKey:a,tagPrefix:n,tags:x.productGetById.tags({productId:t}),cache:"force-cache"});try{let r=await o.products.retrieve(t,{expand:["default_price"]},{stripeAccount:e});return O(r)}catch(r){if(r instanceof R.errors.StripeError&&r.code==="resource_missing")return null;throw r}}async function ce({slug:t}){let{stripeAccount:e,storeId:n,secretKey:a}=await l(),r=await m({secretKey:a,tagPrefix:n,tags:x.productGetBySlug.tags({productSlug:t}),cache:"force-cache"}).products.search({query:V({active:!0,'metadata["slug"]':t}),expand:["data.default_price"]},{stripeAccount:e});if(r.data.length>1&&r.data.some(i=>!i.metadata.variant))throw new Error(`Multiple products found with the same slug (${t}) but no variant set.`);return await Promise.allSettled(r.data.map(i=>J(i.id))),q(K(W(r)))}async function St(t){let{stripeAccount:e,storeId:n,secretKey:a}=await l();if(t.filter?.category){let i=t.filter?.category,f=await m({secretKey:a,tagPrefix:n,tags:x.productBrowse.tags({category:i}),cache:"force-cache"}).products.search({limit:100,query:V({active:!0,'metadata["category"]':i}),expand:["data.default_price"]},{stripeAccount:e});return q(Q(K(W(f)))).slice(t.offset||0,t.first)}let r=await m({secretKey:a,tagPrefix:n,tags:x.productBrowse.tags({}),cache:"force-cache"}).products.list({limit:100,active:!0,expand:["data.default_price"]},{stripeAccount:e});return q(Q(K(W(r))).filter(et)).slice(t.offset||0,t.first)}async function ue(){let{stripeAccount:t,storeId:e,secretKey:n}=await l(),o=await m({secretKey:n,tagPrefix:e,tags:x.shippingBrowse.tags(),cache:"force-cache"}).shippingRates.list({active:!0},{stripeAccount:t});return tt(o)}async function L(t){let{stripeAccount:e,storeId:n,secretKey:a}=await l(),o=m({secretKey:a,tagPrefix:n,tags:x.shippingGetById.tags({shippingId:t}),cache:"force-cache"});try{let r=await o.shippingRates.retrieve(t,{},{stripeAccount:e});return r}catch(r){if(d.error(r),r instanceof R.errors.StripeError&&r.code==="resource_missing")return null;throw r}}async function de(){let e=(await St({first:100})).map(a=>a.metadata.category).filter(Boolean),n=new Set(e);return Array.from(n)}async function pe(t){let{stripeAccount:e,storeId:n,secretKey:a}=await l(),o=m({secretKey:a,tagPrefix:n,tags:x.fileGetById.tags({fileId:t}),cache:"force-cache"});try{return await o.fileLinks.create({file:t},{stripeAccount:e})}catch(r){if(d.error(r),r instanceof R.errors.StripeError&&r.code==="resource_missing")return null;throw r}}async function le(){let{stripeAccount:t,storeId:e,secretKey:n}=await l(),a=m({secretKey:n,tagPrefix:e,tags:x.accountGetById.tags({}),cache:"force-cache"});try{let[o,r]=await H(a.accounts.retrieve({expand:["settings.branding.logo"]},{stripeAccount:t})),i=r?.settings?.branding.logo??null;return!i||typeof i=="string"?{account:r,logo:null}:{account:r,logo:i}}catch(o){if(d.error(o),o instanceof R.errors.StripeError&&o.code==="resource_missing")return null;throw o}}async function bt(t){let{stripeAccount:e,storeId:n,secretKey:a}=await l(),o=m({secretKey:a,tagPrefix:n,tags:x.orderGetById.tags({orderId:t}),cache:"force-cache"});try{let r=await o.paymentIntents.retrieve(t,{expand:["payment_method","latest_charge","customer"]},{stripeAccount:e});return nt(r)}catch(r){if(r instanceof R.errors.StripeError&&r.code==="resource_missing")return null;throw r}}async function me(t){let e=await bt(t);if(!e)return null;let n=st(e.metadata),a=await Promise.all(n.map(async([i,u])=>({product:await k(i),quantity:u}))),{metadata:{shippingRateId:o}}=e,r=o&&await L(o);return{order:e,lines:a.map(({product:i,quantity:u})=>i?{product:i,quantity:u}:null).filter(Boolean),shippingRate:r||null}}var k=async t=>{let{stripeAccount:e,storeId:n,secretKey:a}=await l(),o=m({secretKey:a,tagPrefix:n,tags:x.productGetById.tags({productId:t}),cache:"force-cache"});try{let r=await o.products.retrieve(t,{expand:["default_price"]},{stripeAccount:e});return O(r)}catch(r){if(r instanceof R.errors.StripeError&&r.code==="resource_missing")return null;throw r}},it=["requires_action","requires_confirmation","requires_capture","requires_payment_method"],st=t=>Object.entries(t??{}).filter(([e])=>e.startsWith("prod_")).map(([e,n])=>[e,N(n)]).filter(([,e])=>e&&Number.isFinite(e)&&e>0),Rt=async t=>{let{stripeAccount:e,storeId:n,secretKey:a}=await l(),o=m({secretKey:a,tagPrefix:n,tags:x.cartGetById.tags({cartId:t}),cache:"force-cache"});try{let r=await o.paymentIntents.retrieve(t,{expand:["payment_method"]},{stripeAccount:e}),i=typeof r.customer=="string"?await ut(r.customer):null;if(it.includes(r.status))return z({...r,customer:i})}catch(r){if(d.error(r),r instanceof R.errors.StripeError&&r.code==="resource_missing")return null;throw r}};async function X(t){let e=st(t);return await Promise.all(e.map(async([a,o])=>({product:await k(a),quantity:o})))}var ct=async t=>{let e=await Rt(t);if(!e)return null;let n=await X(e.metadata),{metadata:{shippingRateId:a}}=e,o=a&&await L(a);return{cart:e,lines:n.map(({product:r,quantity:i})=>r?{product:r,quantity:i}:null).filter(Boolean),shippingRate:o||null}},vt=t=>t?t.cart.metadata?.taxCalculationId?t.cart.amount:(t.shippingRate?.fixed_amount?.amount??0)+t.lines.reduce((e,{product:n,quantity:a})=>e+(n.default_price?.unit_amount??0)*a,0):0,Pt=["billingAddress.country","billingAddress.postalCode","billingAddress.state","taxId","shippingRateId","couponCode"];function Et({oldCart:t,data:e,mergedMetadata:n,lines:a}){if(!process.env.ENABLE_STRIPE_TAX)return!1;let o=Date.now(),r=n.taxCalculationExp?Number.parseInt(n.taxCalculationExp,10)*1e3:null;if(!r||o>=r)return!0;let i=t.cart.metadata.netAmount||t.cart.amount,u=e.amount,f=Pt.some(p=>!n[p]&&!t.cart.metadata[p]?!1:n[p]!==t.cart.metadata[p]),s=a.length!==t.lines.length||a.some(p=>{let C=t.lines.find(A=>A.product.id===p.product?.id);return p.product?.default_price.unit_amount!==C?.product.default_price.unit_amount||p.quantity!==C?.quantity});return u&&i!==u||f||s}var fe=t=>S.object({name:S.string({message:t.nameRequired}).min(1,t.nameRequired),city:S.string({message:t.cityRequired}).min(1,t.cityRequired),country:S.string({message:t.countryRequired}).min(1,t.countryRequired),line1:S.string({message:t.line1Required}).min(1,t.line1Required),line2:S.string().optional().nullable().default(""),postalCode:S.string({message:t.postalCodeRequired}).min(1,t.postalCodeRequired),state:S.string().optional().nullable().default(""),phone:S.string().optional().nullable().default(""),taxId:S.string().optional().nullable().default(""),email:S.string().optional().nullable().default("")}),At=async({lineItems:t,billingAddress:e,cartId:n,shippingRateId:a,taxId:o})=>{if(!process.env.ENABLE_STRIPE_TAX)return null;if(!y.StripeCurrency)throw new Error("Missing `STRIPE_CURRENCY` env variable");let{stripeAccount:r,storeId:i,secretKey:u}=await l(),f=m({secretKey:u,tagPrefix:i,tags:x.createTaxCalculation.tags({cartId:n}),cache:"force-cache"});if(!e?.country)return null;let s=a?await L(a):null,w=typeof s?.tax_code=="string"?s.tax_code:s?.tax_code?.id,h=await Bt(),p=y.StripeCurrency==="usd"||y.StripeCurrency==="cad"?"exclusive":"inclusive",C=h.defaults.tax_behavior==="inferred_by_currency"?p:h.defaults.tax_behavior??p;h.defaults.tax_behavior||d.warn(`Tax behavior not set in Stripe settings. Inferring from currency ${y.StripeCurrency}: ${p}.`),d.time(`createTaxCalculation ${n}`);let A=await f.tax.calculations.create({expand:["line_items"],line_items:t.map(M=>({...M,tax_behavior:M.tax_behavior??C})),currency:y.StripeCurrency,shipping_cost:s?.active&&s?.fixed_amount?{amount:s.fixed_amount.amount,tax_behavior:s.tax_behavior==="inclusive"?"inclusive":s.tax_behavior==="exclusive"?"exclusive":C,tax_code:w??h.defaults.tax_code??void 0}:void 0,customer_details:{tax_ids:o?[{type:"eu_vat",value:o}]:void 0,address_source:"billing",address:{country:e.country,city:e?.city,line1:e?.line1,line2:e?.line2,postal_code:e?.postalCode,state:e?.state}}},{stripeAccount:r});return d.timeEnd(`createTaxCalculation ${n}`),console.log(JSON.stringify(A).length),A},ot={taxBreakdown0:"",taxBreakdown1:"",taxBreakdown2:"",taxBreakdown3:"",taxBreakdown4:"",taxBreakdown5:""};async function ut(t){let{stripeAccount:e,storeId:n,secretKey:a}=await l(),o=m({secretKey:a,tagPrefix:n,tags:["customers",`customers-${t}`],cache:"force-cache"});try{let r=await o.customers.retrieve(t,{},{stripeAccount:e});return r.deleted?null:r}catch(r){if(d.error(r),r instanceof R.errors.StripeError&&r.code==="resource_missing")return null;throw r}}function It(t,e){return e.coupon.amount_off?Math.max(t-e.coupon.amount_off,0):e.coupon.percent_off?Math.floor(t*(1-e.coupon.percent_off/100)):t}var E=async({paymentIntentId:t,data:e,customerOverride:n,clearTaxCalculation:a})=>{let{stripeAccount:o,storeId:r,secretKey:i}=await l(),u=await ct(t);b(u,`Cart not found: ${t}`);let f=e.amount?e.amount.toString():null,s=F.parse({...u.cart.metadata,...e.metadata});d.time("getProductsFromMetadata");let w=await X(s);d.timeEnd("getProductsFromMetadata");let h=!a&&Et({oldCart:u,data:e,mergedMetadata:s,lines:w});console.log({shouldRecalculateTax:h});let p=h?await At({cartId:t,taxId:s.taxId??null,shippingRateId:s.shippingRateId??null,billingAddress:{country:s["billingAddress.country"]??"",city:s["billingAddress.city"]??"",line1:s["billingAddress.line1"]??"",line2:s["billingAddress.line2"]??"",name:s["billingAddress.name"]??"",postalCode:s["billingAddress.postalCode"]??"",state:s["billingAddress.state"]??""},lineItems:w.map(({product:g,quantity:G})=>{if(g?.default_price.unit_amount)return{product:g.id,reference:[g.metadata.slug,g.metadata.variant].filter(Boolean).join("-"),quantity:G,amount:g.default_price.unit_amount*G,tax_behavior:g.default_price.tax_behavior==="exclusive"?"exclusive":g.default_price.tax_behavior==="inclusive"?"inclusive":void 0,tax_code:g.tax_code?typeof g.tax_code=="string"?g.tax_code:g.tax_code.id:void 0}}).filter(Boolean)}):null,C=n??(e.customer?await ut(e.customer):u.cart.customer);console.log({customer:C});let A=m({secretKey:i,tagPrefix:r,cache:"no-cache"});d.time(`paymentIntents.update ${t}`);let M=p&&Object.fromEntries(p.tax_breakdown.map(g=>({taxType:g.tax_rate_details.tax_type,taxPercentage:g.tax_rate_details.percentage_decimal,taxAmount:g.amount})).map((g,G)=>[`taxBreakdown${G}`,JSON.stringify(g)])),I=p?p.amount_total:e.amount,D=I&&C?.discount?.coupon.valid?It(I,C.discount):I;console.log({"discount.coupon.amount_off":C?.discount?.coupon.amount_off,"discount.coupon.percent_off":C?.discount?.coupon.percent_off,discountedAmount:D,taxedAmount:I,"taxCalculation.amount_total":p?.amount_total,"data.amount":e.amount,netAmount:f});let dt=await A.paymentIntents.update(t,{...e,...D&&{amount:D},metadata:{...s,...f&&{netAmount:f},...I&&{taxedAmount:I},...p?{...ot,...M,taxCalculationId:p.id,taxCalculationExp:p?.expires_at}:{...a&&{...ot,taxCalculationId:"",taxCalculationExp:""}}}},{stripeAccount:o});return d.timeEnd(`paymentIntents.update ${t}`),dt},U=t=>t?t.cart.metadata?.taxCalculationId?t.cart.amount:(t.shippingRate?.fixed_amount?.amount??0)+Tt(t):0,Tt=t=>t?t.lines.reduce((e,{product:n,quantity:a})=>e+(n.default_price?.unit_amount??0)*a,0):0;async function ge({productId:t,cartId:e,operation:n,clearTaxCalculation:a}){let[o,r]=await Promise.all([J(t),$(e)]);if(!o)throw new Error(`Product not found: ${t}`);if(!r)throw new Error(`Cart not found: ${e}`);if(y.StripeCurrency?.toLowerCase()!==o.default_price.currency.toLowerCase())throw new Error(`Product currency ${o.default_price.currency} does not match cart currency ${y.StripeCurrency}`);let i=r.cart.metadata??{},s=N(i[t])+(n==="INCREASE"?1:-1);s<=0?i[t]="":i[t]=s.toString();let w=U(r)+(o.default_price.unit_amount??0);try{return await E({paymentIntentId:e,data:{metadata:i,amount:w||j},clearTaxCalculation:a})}catch(h){d.error(h)}finally{P(`cart-${e}`)}}var ye=async({cartId:t,email:e})=>{let n=await $(t);if(!n)throw new Error(`Cart not found: ${t}`);try{return await E({paymentIntentId:t,data:{metadata:{...n.cart.metadata,email:e}}})}catch(a){d.error(a)}finally{P(`cart-${t}`)}},he=async({cartId:t,taxId:e})=>{let n=await $(t);if(!n)throw new Error(`Cart not found: ${t}`);try{return await E({paymentIntentId:t,data:{metadata:{...n.cart.metadata,taxId:e}}})}catch(a){d.error(a)}finally{P(`cart-${t}`)}};async function xe({cartId:t,shippingRateId:e}){let n=await $(t);if(!n)throw new Error(`Cart not found: ${t}`);d.time(`cartSaveShipping ${t}`);let a=await L(e);if(d.timeEnd(`cartSaveShipping ${t}`),!a)throw new Error(`Shipping rate not found: ${e}`);try{d.time(`updatePaymentIntent ${t}`);let o=await E({paymentIntentId:t,data:{metadata:{...n.cart.metadata,shippingRateId:e},amount:U({...n,shippingRate:a})}});return d.timeEnd(`updatePaymentIntent ${t}`),o}catch(o){d.error(o)}finally{P(`cart-${t}`)}}async function we({cartId:t,billingAddress:e}){if(!await $(t))throw new Error(`Cart not found: ${t}`);try{return await E({paymentIntentId:t,data:{metadata:{"billingAddress.name":e.name,"billingAddress.phone":e.phone,"billingAddress.city":e.city,"billingAddress.country":e.country,"billingAddress.line1":e.line1,"billingAddress.line2":e.line2??"","billingAddress.postalCode":e.postalCode,"billingAddress.state":e.state??"","billingAddress.email":e.email??""}}})}catch(a){d.error(a)}finally{P(`cart-${t}`)}}async function Bt(){let{stripeAccount:t,storeId:e,secretKey:n}=await l();return await m({secretKey:n,tagPrefix:e,tags:["tax-settings"],cache:"force-cache"}).tax.settings.retrieve({},{stripeAccount:t})}function Ce(t){return Object.entries(t??{}).filter(([e])=>e.startsWith("prod_")).map(([e,n])=>[e,N(n)]).filter(([,e])=>e&&Number.isFinite(e)&&e>0).length}async function _e(t){if(!T)return null;let{storeId:e}=await l();return await T`
2
- select * from reviews
3
- where product_id = ${t.productId} and store_id = ${e}
4
- order by created_at desc
5
- limit ${t.first??100}
6
- offset ${t.offset??0}
7
- `}async function Se(t){if(!T)return null;let{storeId:e}=await l();return await T`
8
- insert into reviews (store_id, product_id, author, email, content, rating, created_at, updated_at)
9
- values (${e}, ${t.productId}, ${t.author}, ${t.email}, ${t.content}, ${t.rating}, now(), now())
10
- `}var be=l;export{le as accountGet,vt as calculateCartTotalNet,Tt as calculateCartTotalNetWithoutShipping,U as calculateCartTotalPossiblyWithTax,oe as cartAdd,ie as cartAddOptimistic,ge as cartChangeQuantity,Ce as cartCount,_t as cartCreate,$ as cartGet,we as cartSaveBillingAddress,ye as cartSaveEmail,xe as cartSaveShipping,he as cartSaveTax,se as cartSetQuantity,Ct as cartUpdateQuantity,de as categoryBrowse,be as contextGet,pe as fileGet,fe as getAddressSchema,ct as getCartWithProductsById,st as getProductsFromCart,X as getProductsFromMetadata,me as orderGet,St as productBrowse,ce as productGet,J as productGetById,Se as productReviewAdd,_e as productReviewBrowse,m as provider,ue as shippingBrowse,L as shippingGet,Bt as taxDefaultGet,E as updatePaymentIntent};
1
+ var C=Object.defineProperty;var p=(e,r)=>()=>(e&&(r=e(e=0)),r);var w=(e,r)=>{for(var t in r)C(e,t,{get:r[t],enumerable:!0})};function g(e){return!e||e.length===0?c:`
2
+ query ProductQuery($slug: String!) {
3
+ product(slug: $slug) {
4
+ ${e.join(`
5
+ `)}
6
+ }
7
+ }
8
+ `}function y(e){return!e||e.length===0?d:`
9
+ query ProductsQuery(
10
+ $offset: Int
11
+ $limit: Int
12
+ $category: String
13
+ $query: String
14
+ $active: Boolean
15
+ $excludeBundles: Boolean
16
+ $orderBy: String
17
+ $orderDirection: String
18
+ ) {
19
+ products(
20
+ offset: $offset
21
+ limit: $limit
22
+ category: $category
23
+ query: $query
24
+ active: $active
25
+ excludeBundles: $excludeBundles
26
+ orderBy: $orderBy
27
+ orderDirection: $orderDirection
28
+ ) {
29
+ data {
30
+ ${e.join(`
31
+ `)}
32
+ }
33
+ meta {
34
+ count
35
+ offset
36
+ limit
37
+ hasMore
38
+ }
39
+ }
40
+ }
41
+ `}var m,d,c,R,P,v=p(()=>{"use strict";m=`
42
+ fragment ProductFragment on Product {
43
+ id
44
+ name
45
+ slug
46
+ summary
47
+ images
48
+ active
49
+ type
50
+ createdAt
51
+ updatedAt
52
+ category {
53
+ id
54
+ name
55
+ slug
56
+ description
57
+ image
58
+ }
59
+ variants {
60
+ id
61
+ price
62
+ originalPrice
63
+ prePromotionPrice
64
+ stock
65
+ shippable
66
+ attributes
67
+ combinations {
68
+ id
69
+ variantValue {
70
+ id
71
+ value
72
+ colorValue
73
+ variantType {
74
+ id
75
+ label
76
+ type
77
+ }
78
+ }
79
+ }
80
+ }
81
+ collections {
82
+ id
83
+ name
84
+ slug
85
+ description
86
+ image
87
+ active
88
+ }
89
+ bundleProducts {
90
+ id
91
+ quantity
92
+ position
93
+ variant {
94
+ id
95
+ price
96
+ originalPrice
97
+ stock
98
+ }
99
+ }
100
+ bundleDiscountPercentage
101
+ }
102
+ `,d=`
103
+ query ProductsQuery(
104
+ $offset: Int
105
+ $limit: Int
106
+ $category: String
107
+ $query: String
108
+ $active: Boolean
109
+ $excludeBundles: Boolean
110
+ $orderBy: String
111
+ $orderDirection: String
112
+ ) {
113
+ products(
114
+ offset: $offset
115
+ limit: $limit
116
+ category: $category
117
+ query: $query
118
+ active: $active
119
+ excludeBundles: $excludeBundles
120
+ orderBy: $orderBy
121
+ orderDirection: $orderDirection
122
+ ) {
123
+ data {
124
+ ...ProductFragment
125
+ }
126
+ meta {
127
+ count
128
+ offset
129
+ limit
130
+ hasMore
131
+ }
132
+ }
133
+ }
134
+ ${m}
135
+ `,c=`
136
+ query ProductQuery($slug: String!) {
137
+ product(slug: $slug) {
138
+ ...ProductFragment
139
+ }
140
+ }
141
+ ${m}
142
+ `,R=`
143
+ fragment CartFragment on Cart {
144
+ id
145
+ customerId
146
+ storeId
147
+ shippingId
148
+ couponId
149
+ billingAddressId
150
+ shippingAddressId
151
+ stripePaymentIntentId
152
+ checkoutSessionId
153
+ addonData
154
+ createdAt
155
+ updatedAt
156
+ customer {
157
+ id
158
+ email
159
+ userId
160
+ user {
161
+ id
162
+ email
163
+ name
164
+ }
165
+ }
166
+ coupon {
167
+ code
168
+ type
169
+ value
170
+ startDate
171
+ endDate
172
+ }
173
+ lineItems {
174
+ id
175
+ cartId
176
+ productVariantId
177
+ subscriptionId
178
+ quantity
179
+ createdAt
180
+ updatedAt
181
+ productVariant {
182
+ id
183
+ price
184
+ originalPrice
185
+ stock
186
+ shippable
187
+ attributes
188
+ }
189
+ subscription {
190
+ id
191
+ name
192
+ price
193
+ interval
194
+ intervalCount
195
+ }
196
+ }
197
+ billingAddress {
198
+ id
199
+ name
200
+ company
201
+ line1
202
+ line2
203
+ city
204
+ state
205
+ postalCode
206
+ country
207
+ phone
208
+ type
209
+ }
210
+ shippingAddress {
211
+ id
212
+ name
213
+ company
214
+ line1
215
+ line2
216
+ city
217
+ state
218
+ postalCode
219
+ country
220
+ phone
221
+ type
222
+ }
223
+ shipping {
224
+ id
225
+ name
226
+ price
227
+ minValue
228
+ maxValue
229
+ }
230
+ }
231
+ `,P=`
232
+ query CartQuery($id: String!) {
233
+ cart(id: $id) {
234
+ ...CartFragment
235
+ }
236
+ }
237
+ ${R}
238
+ `});var f={};w(f,{YnsProvider:()=>n,createYnsProvider:()=>T});function T(e){return new n(e)}var n,h=p(()=>{"use strict";v();n=class{config;constructor(r){this.config=r}async graphqlRequest(r,t){let o=await fetch(`${this.config.endpoint}/api/graphql`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.token}`},body:JSON.stringify({query:r,variables:t})});if(!o.ok)throw new Error(`YNS GraphQL request failed: ${o.status} ${o.statusText}`);let i=await o.json();if(i.errors)throw new Error(`YNS GraphQL errors: ${JSON.stringify(i.errors)}`);return i.data}async restRequest(r,t="GET",o){let i=await fetch(`${this.config.endpoint}/api${r}`,{method:t,headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.token}`},body:o?JSON.stringify(o):void 0});if(!i.ok)throw new Error(`YNS REST request failed: ${i.status} ${i.statusText}`);return i.json()}mapYnsProduct(r){return{id:r.id,name:r.name,slug:r.slug,summary:r.summary,images:r.images||[],active:r.active,price:r.variants?.[0]?.price?Number.parseFloat(r.variants[0].price):0,currency:"USD",stock:r.variants?.[0]?.stock,category:r.category,variants:r.variants?.map(t=>({id:t.id,price:Number.parseFloat(t.price),stock:t.stock,attributes:t.attributes}))||[]}}mapYnsCart(r){let t=r.lineItems?.map(i=>({id:i.id,productId:i.productVariant?.id||"",variantId:i.productVariantId,quantity:i.quantity,price:Number.parseFloat(i.productVariant?.price||"0")}))||[],o=t.reduce((i,a)=>i+a.price*a.quantity,0);return{id:r.id,customerId:r.customerId,items:t,total:o,currency:"USD",createdAt:r.createdAt,updatedAt:r.updatedAt}}async productBrowse(r){let t=r.fields?y(r.fields):d,o={offset:r.offset||0,limit:r.first||r.offset||10,category:r.category,query:r.query,active:r.active,excludeBundles:!1,orderBy:r.orderBy,orderDirection:r.orderDirection},i=await this.graphqlRequest(t,o);return{data:i.products.data.map(a=>this.mapYnsProduct(a)),meta:i.products.meta}}async productGet(r){if(!r.slug&&!r.id)throw new Error("Either slug or id is required for productGet");let t=r.fields?g(r.fields):c,o={slug:r.slug},i=await this.graphqlRequest(t,o);return i.product?this.mapYnsProduct(i.product):null}async cartAdd(r){let t={variantId:r.variantId,cartId:r.cartId,subscriptionId:r.subscriptionId};return await this.restRequest("/cart","POST",t)}async cartUpdate(r){let t={variantId:r.variantId,quantity:r.quantity};return await this.restRequest(`/cart/${r.cartId}`,"PUT",t)}async cartClear(r){return await this.restRequest(`/cart/${r.cartId}`,"DELETE")}async cartGet(r){let t=await this.graphqlRequest(P,{id:r.cartId});return t.cart?this.mapYnsCart(t.cart):null}}});function s(e,r){if(!e)throw new Error(r)}var l=e=>{s(Number.isInteger(e),"Value must be an integer")};var I=e=>(s(e.length===3,"currency needs to be a 3-letter code"),b[e.toUpperCase()]??2);var $=({amount:e,currency:r})=>{l(e);let t=I(r),o=10**t;return Number.parseFloat((e/o).toFixed(t))},S=({amount:e,currency:r,locale:t="en-US"})=>{let o=$({amount:e,currency:r});return new Intl.NumberFormat(t,{style:"currency",currency:r}).format(o)},b={BIF:0,CLP:0,DJF:0,GNF:0,JPY:0,KMF:0,KRW:0,MGA:0,PYG:0,RWF:0,UGX:0,VND:0,VUV:0,XAF:0,XOF:0,XPF:0,BHD:3,JOD:3,KWD:3,OMR:3,TND:3};var u=class{config;provider;providerPromise;constructor(r){if(this.config=r||this.detectFromEnv(),!this.config.endpoint||!this.config.token)throw new Error("YNS configuration required. Provide endpoint and token in constructor or set YNS_ENDPOINT and YNS_TOKEN environment variables.")}detectFromEnv(){return{endpoint:process.env.YNS_ENDPOINT||"",token:process.env.YNS_TOKEN||""}}async getProvider(){return this.provider?this.provider:(this.providerPromise||(this.providerPromise=this.loadProvider()),this.provider=await this.providerPromise,this.provider)}async loadProvider(){try{let{createYnsProvider:r}=await Promise.resolve().then(()=>(h(),f));return r(this.config)}catch(r){throw new Error(`Failed to initialize YNS provider: ${r instanceof Error?r.message:"Unknown error"}`)}}get product(){return{browse:async(r={})=>(await this.getProvider()).productBrowse(r),get:async r=>(await this.getProvider()).productGet(r),search:async r=>{let t=await this.getProvider();if(!t.productSearch)throw new Error("Product search is not supported by YNS provider");return t.productSearch(r)}}}get cart(){return{add:async r=>(await this.getProvider()).cartAdd(r),update:async r=>(await this.getProvider()).cartUpdate(r),clear:async r=>(await this.getProvider()).cartClear(r),get:async r=>(await this.getProvider()).cartGet(r)}}get order(){return{get:async r=>{let t=await this.getProvider();if(!t.orderGet)throw new Error("Order retrieval is not supported by YNS provider");return t.orderGet(r)},list:async(r={})=>{let t=await this.getProvider();if(!t.orderList)throw new Error("Order listing is not supported by YNS provider");return t.orderList(r)}}}};export{u as Commerce,S as formatMoney};
@@ -0,0 +1,140 @@
1
+ interface BaseProvider {
2
+ productBrowse(params: ProductBrowseParams): Promise<ProductBrowseResult>;
3
+ productGet(params: ProductGetParams): Promise<Product | null>;
4
+ productSearch?(params: ProductSearchParams): Promise<ProductSearchResult>;
5
+ cartAdd(params: CartAddParams): Promise<{
6
+ cartId: string;
7
+ }>;
8
+ cartUpdate(params: CartUpdateParams): Promise<{
9
+ cartId: string;
10
+ }>;
11
+ cartClear(params: CartClearParams): Promise<{
12
+ cartId: string;
13
+ }>;
14
+ cartGet(params: CartGetParams): Promise<Cart | null>;
15
+ orderGet?(params: OrderGetParams): Promise<Order | null>;
16
+ orderList?(params: OrderListParams): Promise<OrderListResult>;
17
+ }
18
+ interface StripeProviderConfig {
19
+ secretKey?: string;
20
+ tagPrefix?: string;
21
+ }
22
+ interface YnsProviderConfig {
23
+ endpoint: string;
24
+ token: string;
25
+ }
26
+ interface Product {
27
+ id: string;
28
+ name: string;
29
+ slug?: string;
30
+ summary?: string;
31
+ images: string[];
32
+ active: boolean;
33
+ price: number;
34
+ currency: string;
35
+ stock?: number;
36
+ }
37
+ interface Cart {
38
+ id: string;
39
+ customerId?: string;
40
+ items: CartItem[];
41
+ total: number;
42
+ currency: string;
43
+ createdAt: string;
44
+ updatedAt: string;
45
+ }
46
+ interface CartItem {
47
+ id: string;
48
+ productId: string;
49
+ variantId?: string;
50
+ quantity: number;
51
+ price: number;
52
+ }
53
+ interface Order {
54
+ id: string;
55
+ customerId?: string;
56
+ items: CartItem[];
57
+ total: number;
58
+ currency: string;
59
+ status: string;
60
+ createdAt: string;
61
+ updatedAt: string;
62
+ }
63
+ interface ProductBrowseParams {
64
+ first?: number;
65
+ offset?: number;
66
+ category?: string;
67
+ query?: string;
68
+ active?: boolean;
69
+ orderBy?: string;
70
+ orderDirection?: "asc" | "desc";
71
+ fields?: string[];
72
+ _provider?: "stripe" | "yns";
73
+ }
74
+ interface ProductGetParams {
75
+ slug?: string;
76
+ id?: string;
77
+ fields?: string[];
78
+ _provider?: "stripe" | "yns";
79
+ }
80
+ interface ProductSearchParams {
81
+ query: string;
82
+ limit?: number;
83
+ fields?: string[];
84
+ _provider?: "stripe" | "yns";
85
+ }
86
+ interface CartAddParams {
87
+ variantId: string;
88
+ cartId?: string;
89
+ quantity?: number;
90
+ subscriptionId?: string;
91
+ _provider?: "stripe" | "yns";
92
+ }
93
+ interface CartUpdateParams {
94
+ cartId: string;
95
+ variantId: string;
96
+ quantity: number;
97
+ _provider?: "stripe" | "yns";
98
+ }
99
+ interface CartClearParams {
100
+ cartId: string;
101
+ _provider?: "stripe" | "yns";
102
+ }
103
+ interface CartGetParams {
104
+ cartId: string;
105
+ _provider?: "stripe" | "yns";
106
+ }
107
+ interface OrderGetParams {
108
+ orderId: string;
109
+ _provider?: "stripe" | "yns";
110
+ }
111
+ interface OrderListParams {
112
+ customerId?: string;
113
+ limit?: number;
114
+ offset?: number;
115
+ _provider?: "stripe" | "yns";
116
+ }
117
+ interface ProductBrowseResult {
118
+ data: Product[];
119
+ meta: {
120
+ count: number;
121
+ offset: number;
122
+ limit: number;
123
+ hasMore: boolean;
124
+ };
125
+ }
126
+ interface ProductSearchResult {
127
+ data: Product[];
128
+ total: number;
129
+ }
130
+ interface OrderListResult {
131
+ data: Order[];
132
+ meta: {
133
+ count: number;
134
+ offset: number;
135
+ limit: number;
136
+ hasMore: boolean;
137
+ };
138
+ }
139
+
140
+ export type { BaseProvider as B, Cart as C, Order as O, Product as P, StripeProviderConfig as S, YnsProviderConfig as Y, CartAddParams as a, CartClearParams as b, CartGetParams as c, CartItem as d, CartUpdateParams as e, OrderGetParams as f, OrderListParams as g, OrderListResult as h, ProductBrowseParams as i, ProductBrowseResult as j, ProductGetParams as k, ProductSearchParams as l, ProductSearchResult as m };
@@ -0,0 +1,77 @@
1
+ import { S as StripeProviderConfig, i as ProductBrowseParams, j as ProductBrowseResult, k as ProductGetParams, P as Product, a as CartAddParams, e as CartUpdateParams, b as CartClearParams, c as CartGetParams, C as Cart } from './provider-CvZe8Dqo.js';
2
+
3
+ /**
4
+ * Stripe Commerce client - zero-config constructor
5
+ * Reads configuration from environment variables by default
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { Commerce } from "commerce-kit/stripe";
10
+ *
11
+ * // Zero config - uses STRIPE_SECRET_KEY from environment
12
+ * const commerce = new Commerce();
13
+ *
14
+ * const products = await commerce.product.browse({ first: 10 });
15
+ * const result = await commerce.cart.add({ variantId: "price_123", quantity: 1 });
16
+ * ```
17
+ */
18
+ declare class Commerce {
19
+ private config;
20
+ private provider?;
21
+ private providerPromise?;
22
+ constructor(config?: StripeProviderConfig);
23
+ /**
24
+ * Detect Stripe configuration from environment variables
25
+ */
26
+ private detectFromEnv;
27
+ /**
28
+ * Lazy-load and cache provider instance
29
+ */
30
+ private getProvider;
31
+ /**
32
+ * Load Stripe provider
33
+ */
34
+ private loadProvider;
35
+ /**
36
+ * Product operations - Stripe specific
37
+ */
38
+ get product(): {
39
+ /**
40
+ * Browse/list products with Stripe-specific parameters
41
+ */
42
+ browse: (params?: ProductBrowseParams) => Promise<ProductBrowseResult>;
43
+ /**
44
+ * Get single product by ID or slug
45
+ */
46
+ get: (params: ProductGetParams) => Promise<Product | null>;
47
+ };
48
+ /**
49
+ * Cart operations - Stripe specific
50
+ */
51
+ get cart(): {
52
+ /**
53
+ * Add item to cart
54
+ */
55
+ add: (params: CartAddParams) => Promise<{
56
+ cartId: string;
57
+ }>;
58
+ /**
59
+ * Update item in cart
60
+ */
61
+ update: (params: CartUpdateParams) => Promise<{
62
+ cartId: string;
63
+ }>;
64
+ /**
65
+ * Clear cart
66
+ */
67
+ clear: (params: CartClearParams) => Promise<{
68
+ cartId: string;
69
+ }>;
70
+ /**
71
+ * Get cart details
72
+ */
73
+ get: (params: CartGetParams) => Promise<Cart | null>;
74
+ };
75
+ }
76
+
77
+ export { Commerce };
package/dist/stripe.js ADDED
@@ -0,0 +1 @@
1
+ var xt=Object.defineProperty;var P=(t,e)=>()=>(t&&(e=t(t=0)),e);var wt=(t,e)=>{for(var a in e)xt(t,a,{get:e[a],enumerable:!0})};var Ct,Pt,y,M=P(()=>{"use strict";Ct=process.env.STRIPE_SECRET_KEY,Pt=process.env.STRIPE_CURRENCY,y={StripeSecretKey:Ct,StripeCurrency:Pt}});function _(t,e){if(!t)throw new Error(e)}var q,J,K=P(()=>{"use strict";q=t=>{if(t==null)return 0;if(typeof t=="number")return t;let e=Number.parseInt(t,10);return Number.isNaN(e)?0:e},J=t=>{if(t==null)return null;try{return JSON.parse(t)}catch{return null}}});var vt,O,W=P(()=>{"use strict";vt=t=>t.toString().replace(/\\/g,"\\\\").replace(/"/g,'\\"'),O=t=>Object.entries(t).map(([e,a])=>`${e}:"${vt(a)}"`).join(" AND ").trim()});import{z as i}from"zod";function B(t){return t.toSorted((e,a)=>{let n=Number(e.metadata.order),o=Number(a.metadata.order);return Number.isNaN(n)&&Number.isNaN(o)||n===o?a.updated-e.updated:Number.isNaN(n)?1:Number.isNaN(o)?-1:n-o})}function $({default_price:t,marketing_features:e,...a}){return _(t,"Product must have a default price"),_(typeof t=="object","Product default price must be an object"),{...a,default_price:t,marketing_features:e.map(n=>n.name).filter(Boolean),metadata:St.parse(a.metadata)}}function _t(t){return!!(t.active&&!t.deleted&&t.default_price)}function N(t){return{...t,data:t.data.filter(_t)}}function L(t){return t.data.map($)}function U(t){return t.filter((e,a,n)=>a===n.findIndex(o=>o.metadata.slug===e.metadata.slug))}function Y(t){let e=t.payment_method;_(typeof e!="string","Payment method should not be a string");let a=t.customer;_(typeof a!="string"&&!a?.deleted,"Customer should not be a string");let n=F.parse(t.metadata),o=Object.entries(n).filter(([r])=>r.startsWith("taxBreakdown")).map(([r,s])=>{let d=It.safeParse(J(String(s)));return d.success?d.data:null}).filter(Boolean);return{...t,metadata:n,customer:a,payment_method:e,taxBreakdown:o}}var St,X,F,It,H=P(()=>{"use strict";K();W();St=i.object({category:i.string().optional(),order:i.coerce.number().optional(),slug:i.string(),variant:i.string().optional(),stock:i.coerce.number().optional().transform(t=>t===void 0?Number.POSITIVE_INFINITY:t),digitalAsset:i.string().optional(),preview:i.string().optional()});X=t=>!t.deleted&&t.active,F=i.object({shippingRateId:i.string().optional(),taxCalculationId:i.string().optional(),taxCalculationExp:i.string().optional(),taxId:i.string().optional(),couponCode:i.string().optional(),taxedAmount:i.string().optional(),"billingAddress.city":i.string().optional(),"billingAddress.country":i.string().optional(),"billingAddress.line1":i.string().optional(),"billingAddress.line2":i.string().optional(),"billingAddress.name":i.string().optional(),"billingAddress.postalCode":i.string().optional(),"billingAddress.state":i.string().optional(),netAmount:i.string().optional(),taxBreakdown0:i.string().optional(),taxBreakdown1:i.string().optional(),taxBreakdown2:i.string().optional(),taxBreakdown3:i.string().optional(),taxBreakdown4:i.string().optional(),taxBreakdown5:i.string().optional()}).and(i.record(i.string(),i.string())),It=i.object({taxType:i.string(),taxPercentage:i.string(),taxAmount:i.number()})});var S,Et,Rt,R,m,Z=P(()=>{"use strict";S={DEBUG:0,LOG:1,WARN:2,ERROR:3},Et="LOG",Rt=process.env.LOG_LEVEL&&process.env.LOG_LEVEL in S?process.env.LOG_LEVEL:Et,R=S[Rt],m={time(t){R>S.DEBUG||console.time(t)},timeEnd(t){R>S.DEBUG||console.timeEnd(t)},log(...t){R>S.LOG||console.log(...t)},dir(t,e){R>S.LOG||console.dir(t,e)},warn(...t){R>S.WARN||console.warn(...t)},error(...t){R>S.ERROR||console.error(...t)}}});var w,v,tt=P(()=>{"use strict";w=t=>t.filter(Boolean),v={accountGetById:{tags:({accountId:t})=>w(["account",t&&`account-${t}`]),revalidate:()=>{}},cartGetById:{tags:({cartId:t})=>w(["cart",`cart-${t}`]),revalidate:()=>{}},createTaxCalculation:{tags:({cartId:t})=>w(["tax-calculations",`tax-calculations-${t}`]),revalidate:()=>{}},fileGetById:{tags:({fileId:t})=>w(["files",`file-${t}`]),revalidate:()=>{}},orderGetById:{tags:({orderId:t})=>w(["order",`order-${t}`]),revalidate:()=>{}},productBrowse:{tags:({category:t})=>w(["product",t&&`category-${t}`]),revalidate:()=>{}},productGetById:{tags:({productId:t})=>w(["product",`product-${t}`]),revalidate:()=>{}},productGetBySlug:{tags:({productSlug:t})=>w(["product",`product-${t}`]),revalidate:()=>{}},shippingBrowse:{tags:()=>w(["shipping"]),revalidate:()=>{}},shippingGetById:{tags:({shippingId:t})=>w(["shipping",`shipping-${t}`]),revalidate:()=>{}},taxDefaultGet:{tags:()=>w(["tax-settings"]),revalidate:()=>{}}}});import et from"stripe";var bt,f,rt=P(()=>{"use strict";M();bt=(t,e)=>!t||!e?t:[...t,`prefix-${e}`,...t.map(a=>`${e}-${a}`)],f=({tags:t,revalidate:e,cache:a,tagPrefix:n,secretKey:o})=>{let r=o??y.StripeSecretKey;if(!r)throw new Error("Missing `secretKey` parameter and `STRIPE_SECRET_KEY` env variable.");let s=bt(t,n);return new et(r,{typescript:!0,apiVersion:"2025-08-27.basil",httpClient:et.createFetchHttpClient(((l,c)=>fetch(l,{...c,cache:a??c?.cache,next:{tags:s??c?.next?.tags,revalidate:e??c?.next?.revalidate}}))),appInfo:{name:"Commerce SDK",version:"beta",url:"https://yournextstore.com",partner_id:"CONS-003378"}})}});var h,at=P(()=>{"use strict";h=async()=>{let t={stripeAccount:void 0,storeId:void 0,secretKey:void 0,publishableKey:void 0};return await global?.__ynsFindStripeAccount?.()??t}});import{revalidateTag as At}from"next/cache";import b from"stripe";import{z as ue}from"zod";function it({productId:t,cartId:e}){return e?j({cartId:e,productId:t,operation:"INCREASE",clearTaxCalculation:!0}):Tt({productId:t})}async function j({productId:t,cartId:e,operation:a,clearTaxCalculation:n}){let[o,r]=await Promise.all([Q(t),pt(e)]);if(!o)throw new Error(`Product not found: ${t}`);if(!r)throw new Error(`Cart not found: ${e}`);if(o.metadata.stock<=0)throw Error(`Product ${t} is out of stock`);if(!y.StripeCurrency)throw new Error("Missing `STRIPE_CURRENCY` env variable");if(y.StripeCurrency.toLowerCase()!==o.default_price.currency.toLowerCase())throw new Error(`Product currency ${o.default_price.currency} does not match cart currency ${y.StripeCurrency}`);let s=r.cart.metadata??{},c=q(s[t])+(a==="INCREASE"?1:-1);c<=0?s[t]="":s[t]=c.toString();let C=Nt(r)+(o.default_price.unit_amount??0);try{return await qt({paymentIntentId:e,data:{metadata:s,amount:C||ot},clearTaxCalculation:n})}catch(g){m.error(g)}finally{At(`cart-${e}`)}}async function st(t){let{stripeAccount:e,storeId:a,secretKey:n}=await h(),o=f({secretKey:n,tagPrefix:a,tags:v.cartGetById.tags({cartId:t}),cache:"force-cache"});try{let r=await o.paymentIntents.retrieve(t,{expand:["payment_method","customer"]},{stripeAccount:e});if(dt.includes(r.status)){let s=Y(r);if(!s)return null;let d=await z(s.metadata),{metadata:{shippingRateId:l}}=s,c=l&&await V(l);return{cart:s,lines:d.map(({product:C,quantity:g})=>C?{product:C,quantity:g}:null).filter(Boolean),shippingRate:c||null}}}catch(r){if(m.error(r),r instanceof b.errors.StripeError&&r.code==="resource_missing")return null;throw r}}async function Tt({productId:t}={}){let{stripeAccount:e,storeId:a,secretKey:n}=await h(),o=f({secretKey:n,tagPrefix:a,cache:"no-cache"});if(!y.StripeCurrency)throw new Error("Missing `STRIPE_CURRENCY` env variable");try{let r=t?await Q(t):null;if(r&&r.metadata.stock<=0)throw Error(`Product ${t} is out of stock`);return await o.paymentIntents.create({currency:y.StripeCurrency,amount:r?.default_price.unit_amount||ot,automatic_payment_methods:{enabled:!0},metadata:{...r&&{[r.id]:"1"}}},{stripeAccount:e})}catch(r){throw m.error(r),r}}async function D(t){let{stripeAccount:e,storeId:a,secretKey:n}=await h(),o=f({secretKey:n,tagPrefix:a,tags:v.productGetById.tags({productId:t}),cache:"force-cache"});try{let r=await o.products.retrieve(t,{expand:["default_price"]},{stripeAccount:e});return $(r)}catch(r){if(r instanceof b.errors.StripeError&&r.code==="resource_missing")return null;throw r}}async function ct({slug:t}){let{stripeAccount:e,storeId:a,secretKey:n}=await h(),r=await f({secretKey:n,tagPrefix:a,tags:v.productGetBySlug.tags({productSlug:t}),cache:"force-cache"}).products.search({query:O({active:!0,'metadata["slug"]':t}),expand:["data.default_price"]},{stripeAccount:e});if(r.data.length>1&&r.data.some(s=>!s.metadata.variant))throw new Error(`Multiple products found with the same slug (${t}) but no variant set.`);return await Promise.allSettled(r.data.map(s=>D(s.id))),B(L(N(r)))}async function ut(t){let{stripeAccount:e,storeId:a,secretKey:n}=await h();if(t.filter?.category){let s=t.filter?.category,l=await f({secretKey:n,tagPrefix:a,tags:v.productBrowse.tags({category:s}),cache:"force-cache"}).products.search({limit:100,query:O({active:!0,'metadata["category"]':s}),expand:["data.default_price"]},{stripeAccount:e});return B(U(L(N(l)))).slice(t.offset||0,t.first)}let r=await f({secretKey:n,tagPrefix:a,tags:v.productBrowse.tags({}),cache:"force-cache"}).products.list({limit:100,active:!0,expand:["data.default_price"]},{stripeAccount:e});return B(U(L(N(r))).filter(X)).slice(t.offset||0,t.first)}async function V(t){let{stripeAccount:e,storeId:a,secretKey:n}=await h(),o=f({secretKey:n,tagPrefix:a,tags:v.shippingGetById.tags({shippingId:t}),cache:"force-cache"});try{let r=await o.shippingRates.retrieve(t,{},{stripeAccount:e});return r}catch(r){if(m.error(r),r instanceof b.errors.StripeError&&r.code==="resource_missing")return null;throw r}}async function z(t){let e=Bt(t);return await Promise.all(e.map(async([n,o])=>({product:await Q(n),quantity:o})))}function Gt({oldCart:t,data:e,mergedMetadata:a,lines:n}){if(!process.env.ENABLE_STRIPE_TAX)return!1;let o=Date.now(),r=a.taxCalculationExp?Number.parseInt(a.taxCalculationExp,10)*1e3:null;if(!r||o>=r)return!0;let s=t.cart.metadata.netAmount||t.cart.amount,d=e.amount,l=Lt.some(u=>!a[u]&&!t.cart.metadata[u]?!1:a[u]!==t.cart.metadata[u]),c=n.length!==t.lines.length||n.some(u=>{let x=t.lines.find(I=>I.product.id===u.product?.id);return u.product?.default_price.unit_amount!==x?.product.default_price.unit_amount||u.quantity!==x?.quantity});return d&&s!==d||l||c}async function lt(t){let{stripeAccount:e,storeId:a,secretKey:n}=await h(),o=f({secretKey:n,tagPrefix:a,tags:["customers",`customers-${t}`],cache:"force-cache"});try{let r=await o.customers.retrieve(t,{},{stripeAccount:e});return r.deleted?null:r}catch(r){if(m.error(r),r instanceof b.errors.StripeError&&r.code==="resource_missing")return null;throw r}}function Mt(t,e){return e.coupon.amount_off?Math.max(t-e.coupon.amount_off,0):e.coupon.percent_off?Math.floor(t*(1-e.coupon.percent_off/100)):t}async function Kt(){let{stripeAccount:t,storeId:e,secretKey:a}=await h();return await f({secretKey:a,tagPrefix:e,tags:["tax-settings"],cache:"force-cache"}).tax.settings.retrieve({},{stripeAccount:t})}var ot,Q,dt,Bt,$t,pt,Nt,Lt,kt,nt,qt,mt=P(()=>{"use strict";M();H();Z();tt();rt();W();K();at();ot=1e3;Q=async t=>{let{stripeAccount:e,storeId:a,secretKey:n}=await h(),o=f({secretKey:n,tagPrefix:a,tags:v.productGetById.tags({productId:t}),cache:"force-cache"});try{let r=await o.products.retrieve(t,{expand:["default_price"]},{stripeAccount:e});return $(r)}catch(r){if(r instanceof b.errors.StripeError&&r.code==="resource_missing")return null;throw r}},dt=["requires_action","requires_confirmation","requires_capture","requires_payment_method"],Bt=t=>Object.entries(t??{}).filter(([e])=>e.startsWith("prod_")).map(([e,a])=>[e,q(a)]).filter(([,e])=>e&&Number.isFinite(e)&&e>0),$t=async t=>{let{stripeAccount:e,storeId:a,secretKey:n}=await h(),o=f({secretKey:n,tagPrefix:a,tags:v.cartGetById.tags({cartId:t}),cache:"force-cache"});try{let r=await o.paymentIntents.retrieve(t,{expand:["payment_method"]},{stripeAccount:e}),s=typeof r.customer=="string"?await lt(r.customer):null;if(dt.includes(r.status))return Y({...r,customer:s})}catch(r){if(m.error(r),r instanceof b.errors.StripeError&&r.code==="resource_missing")return null;throw r}};pt=async t=>{let e=await $t(t);if(!e)return null;let a=await z(e.metadata),{metadata:{shippingRateId:n}}=e,o=n&&await V(n);return{cart:e,lines:a.map(({product:r,quantity:s})=>r?{product:r,quantity:s}:null).filter(Boolean),shippingRate:o||null}},Nt=t=>t?t.cart.metadata?.taxCalculationId?t.cart.amount:(t.shippingRate?.fixed_amount?.amount??0)+t.lines.reduce((e,{product:a,quantity:n})=>e+(a.default_price?.unit_amount??0)*n,0):0,Lt=["billingAddress.country","billingAddress.postalCode","billingAddress.state","taxId","shippingRateId","couponCode"];kt=async({lineItems:t,billingAddress:e,cartId:a,shippingRateId:n,taxId:o})=>{if(!process.env.ENABLE_STRIPE_TAX)return null;if(!y.StripeCurrency)throw new Error("Missing `STRIPE_CURRENCY` env variable");let{stripeAccount:r,storeId:s,secretKey:d}=await h(),l=f({secretKey:d,tagPrefix:s,tags:v.createTaxCalculation.tags({cartId:a}),cache:"force-cache"});if(!e?.country)return null;let c=n?await V(n):null,C=typeof c?.tax_code=="string"?c.tax_code:c?.tax_code?.id,g=await Kt(),u=y.StripeCurrency==="usd"||y.StripeCurrency==="cad"?"exclusive":"inclusive",x=g.defaults.tax_behavior==="inferred_by_currency"?u:g.defaults.tax_behavior??u;g.defaults.tax_behavior||m.warn(`Tax behavior not set in Stripe settings. Inferring from currency ${y.StripeCurrency}: ${u}.`),m.time(`createTaxCalculation ${a}`);let I=await l.tax.calculations.create({expand:["line_items"],line_items:t.map(A=>({...A,tax_behavior:A.tax_behavior??x})),currency:y.StripeCurrency,shipping_cost:c?.active&&c?.fixed_amount?{amount:c.fixed_amount.amount,tax_behavior:c.tax_behavior==="inclusive"?"inclusive":c.tax_behavior==="exclusive"?"exclusive":x,tax_code:C??g.defaults.tax_code??void 0}:void 0,customer_details:{tax_ids:o?[{type:"eu_vat",value:o}]:void 0,address_source:"billing",address:{country:e.country,city:e?.city,line1:e?.line1,line2:e?.line2,postal_code:e?.postalCode,state:e?.state}}},{stripeAccount:r});return m.timeEnd(`createTaxCalculation ${a}`),console.log(JSON.stringify(I).length),I},nt={taxBreakdown0:"",taxBreakdown1:"",taxBreakdown2:"",taxBreakdown3:"",taxBreakdown4:"",taxBreakdown5:""};qt=async({paymentIntentId:t,data:e,customerOverride:a,clearTaxCalculation:n})=>{let{stripeAccount:o,storeId:r,secretKey:s}=await h(),d=await pt(t);_(d,`Cart not found: ${t}`);let l=e.amount?e.amount.toString():null,c=F.parse({...d.cart.metadata,...e.metadata});m.time("getProductsFromMetadata");let C=await z(c);m.timeEnd("getProductsFromMetadata");let g=!n&&Gt({oldCart:d,data:e,mergedMetadata:c,lines:C});console.log({shouldRecalculateTax:g});let u=g?await kt({cartId:t,taxId:c.taxId??null,shippingRateId:c.shippingRateId??null,billingAddress:{country:c["billingAddress.country"]??"",city:c["billingAddress.city"]??"",line1:c["billingAddress.line1"]??"",line2:c["billingAddress.line2"]??"",name:c["billingAddress.name"]??"",postalCode:c["billingAddress.postalCode"]??"",state:c["billingAddress.state"]??""},lineItems:C.map(({product:p,quantity:T})=>{if(p?.default_price.unit_amount)return{product:p.id,reference:[p.metadata.slug,p.metadata.variant].filter(Boolean).join("-"),quantity:T,amount:p.default_price.unit_amount*T,tax_behavior:p.default_price.tax_behavior==="exclusive"?"exclusive":p.default_price.tax_behavior==="inclusive"?"inclusive":void 0,tax_code:p.tax_code?typeof p.tax_code=="string"?p.tax_code:p.tax_code.id:void 0}}).filter(Boolean)}):null,x=a??(e.customer?await lt(e.customer):d.cart.customer);console.log({customer:x});let I=f({secretKey:s,tagPrefix:r,cache:"no-cache"});m.time(`paymentIntents.update ${t}`);let A=u&&Object.fromEntries(u.tax_breakdown.map(p=>({taxType:p.tax_rate_details.tax_type,taxPercentage:p.tax_rate_details.percentage_decimal,taxAmount:p.amount})).map((p,T)=>[`taxBreakdown${T}`,JSON.stringify(p)])),E=u?u.amount_total:e.amount,k=E&&x?.discount?.coupon.valid?Mt(E,x.discount):E;console.log({"discount.coupon.amount_off":x?.discount?.coupon.amount_off,"discount.coupon.percent_off":x?.discount?.coupon.percent_off,discountedAmount:k,taxedAmount:E,"taxCalculation.amount_total":u?.amount_total,"data.amount":e.amount,netAmount:l});let ht=await I.paymentIntents.update(t,{...e,...k&&{amount:k},metadata:{...c,...l&&{netAmount:l},...E&&{taxedAmount:E},...u?{...nt,...A,taxCalculationId:u.id,taxCalculationExp:u?.expires_at}:{...n&&{...nt,taxCalculationId:"",taxCalculationExp:""}}}},{stripeAccount:o});return m.timeEnd(`paymentIntents.update ${t}`),ht}});var ft={};wt(ft,{StripeProvider:()=>G,createStripeProvider:()=>Wt});function Wt(t){return new G(t)}var G,gt=P(()=>{"use strict";mt();G=class{constructor(e){this.config=e}mapStripeProduct(e){let a=e.default_price?.unit_amount||0,n=e.default_price?.currency||"usd";return{id:e.id,name:e.name,slug:e.metadata?.slug,summary:e.description,images:e.images||[],active:e.active,price:a/100,currency:n.toUpperCase(),stock:Number.parseInt(e.metadata?.stock||"0",10),stripeId:e.id,metadata:e.metadata||{}}}async productBrowse(e){let a=await ut({first:e.first||10,...e}),n=a.data.map(o=>this.mapStripeProduct(o));return{data:n,meta:{count:a.totalCount||n.length,offset:e.offset||0,limit:e.first||10,hasMore:n.length===(e.first||10)}}}async productGet(e){if(e.fields&&console.warn("GraphQL field selection not supported for Stripe provider. Ignoring 'fields' parameter."),e.slug){let a=await ct({slug:e.slug});return a?this.mapStripeProduct(a):null}if(e.id){let a=await D(e.id);return a?this.mapStripeProduct(a):null}throw new Error("Either slug or id is required for productGet")}async cartAdd(e){return{cartId:(await it({productId:e.variantId,cartId:e.cartId}))?.id||e.cartId||""}}async cartUpdate(e){let a=e.quantity>0?"INCREASE":"DECREASE";return{cartId:(await j({cartId:e.cartId,productId:e.variantId,operation:a}))?.id||e.cartId}}async cartClear(e){throw new Error("Cart clear not yet implemented for Stripe provider")}async cartGet(e){let a=await st(e.cartId);if(!a)return null;let n=a.lines.map(r=>({id:r.product?.id||"",productId:r.product?.id||"",variantId:r.product?.id,quantity:r.quantity,price:(r.product?.default_price?.unit_amount||0)/100})),o=n.reduce((r,s)=>r+s.price*s.quantity,0);return{id:a.cart.id,customerId:a.cart.customer,items:n,total:o,currency:a.cart.currency?.toUpperCase()||"USD",createdAt:new Date(a.cart.created*1e3).toISOString(),updatedAt:new Date().toISOString()}}}});var yt=class{config;provider;providerPromise;constructor(e){if(this.config=e||this.detectFromEnv(),!this.config.secretKey&&!process.env.STRIPE_SECRET_KEY)throw new Error("Stripe configuration required. Provide secretKey in constructor or set STRIPE_SECRET_KEY environment variable.")}detectFromEnv(){return{secretKey:process.env.STRIPE_SECRET_KEY,tagPrefix:process.env.STRIPE_TAG_PREFIX}}async getProvider(){return this.provider?this.provider:(this.providerPromise||(this.providerPromise=this.loadProvider()),this.provider=await this.providerPromise,this.provider)}async loadProvider(){try{let{createStripeProvider:e}=await Promise.resolve().then(()=>(gt(),ft));return e(this.config)}catch(e){throw new Error(`Failed to initialize Stripe provider: ${e instanceof Error?e.message:"Unknown error"}`)}}get product(){return{browse:async(e={})=>(await this.getProvider()).productBrowse(e),get:async e=>(await this.getProvider()).productGet(e)}}get cart(){return{add:async e=>(await this.getProvider()).cartAdd(e),update:async e=>(await this.getProvider()).cartUpdate(e),clear:async e=>(await this.getProvider()).cartClear(e),get:async e=>(await this.getProvider()).cartGet(e)}}};export{yt as Commerce};
@@ -0,0 +1,22 @@
1
+ type YnsFindStripeAccountResult = {
2
+ stripeAccount: string | undefined;
3
+ storeId: string | undefined;
4
+ secretKey: string | undefined;
5
+ publishableKey: string | undefined;
6
+ };
7
+ type YnsContextResult = {
8
+ stripeAccount: string | undefined;
9
+ storeId: string | undefined;
10
+ secretKey: string | undefined;
11
+ publishableKey: string | undefined;
12
+ };
13
+ declare global {
14
+ /**
15
+ * ⚠️ Warning: This might be `undefined` but TypeScript doesn't have a syntax to express that.
16
+ * @see https://github.com/microsoft/TypeScript/issues/36057
17
+ */
18
+ function __ynsFindStripeAccount(): YnsFindStripeAccountResult | undefined | Promise<YnsFindStripeAccountResult | undefined>;
19
+ }
20
+ declare const getYnsContext: () => Promise<YnsContextResult>;
21
+
22
+ export { getYnsContext };
@@ -0,0 +1 @@
1
+ var t=async()=>{let e={stripeAccount:void 0,storeId:void 0,secretKey:void 0,publishableKey:void 0};return await global?.__ynsFindStripeAccount?.()??e};export{t as getYnsContext};