@houzhen888/groove-grow 0.0.2 → 0.0.3

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.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { g as CustomerPlanEligibility, h as CustomerResource, i as CustomerState, j as CustomerStateSnapshot, k as CustomerStateStore, O as Offer, l as OfferUnavailableReason, m as PendingPurchaseStore, n as PurchaseHost, o as PurchaseTicketTransport, p as createFunnelClient, c as createGroove, q as createPurchaseHostClient, r as createPurchaseTicketTransport, s as formatCouponDiscount, t as formatCouponMoney, u as formatCouponTerms, v as showFunnel } from './index-VzF48VxI.js';
2
- export { G as GrooveError, e as GrooveOptions } from './transport-DrW-__2k.js';
1
+ export { g as CustomerPlanEligibility, h as CustomerResource, i as CustomerState, j as CustomerStateSnapshot, k as CustomerStateStore, O as Offer, l as OfferUnavailableReason, m as PendingPurchaseStore, n as PurchaseHost, o as PurchaseTicketTransport, p as createFunnelClient, c as createGroove, q as createPurchaseHostClient, r as createPurchaseTicketTransport, s as formatCouponDiscount, t as formatCouponMoney, u as formatCouponTerms, v as showFunnel } from './index-CbW7E8PR.js';
2
+ export { G as GrooveError, e as GrooveOptions } from './transport-CPPD6uzW.js';
3
3
  import 'zod';
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{a as T,c as Q}from"./chunk-ORSJMBMZ.js";import{a as r,b as O}from"./chunk-ZPYBAV5Z.js";import{Gd as F,Pd as x,Ta as J,Td as H,Ua as K,Va as B,Wd as m,bc as q,cd as U,de as G,fe as j,md as R,nd as M,pd as _}from"./chunk-D5TMAVB3.js";function L(a){let n=0,d=new Set,l=i=>{let f=R.safeParse(i);if(!f.success||!f.data.submissionTicket||f.data.nextStep.provider!==a.host.provider)throw new r("INVALID_REQUEST","Original purchase ticket unavailable");let u=f.data;if(u.scope.projectId!==a.scope.projectId||u.scope.environment!==a.scope.environment)throw new r("SCOPE_MISMATCH","Stored purchase belongs to another App or environment");return u},o=(i,f)=>{let u=_.safeParse(f);if(!u.success||u.data.intentId!==i.id)throw new r("INVALID_RESPONSE","Invalid purchase confirmation");if(u.data.state!=="fulfilled"&&u.data.finishTransactionKeys.length!==0)throw new r("INVALID_RESPONSE","Unfulfilled purchases cannot finish store transactions");return u.data};async function w(i,f){if(f.provider!==i.nextStep.provider)throw new r("INVALID_REQUEST","Purchase provider mismatch");let u=o(i,await a.tickets.submit(i,M.parse(f)));return u.state==="fulfilled"&&(await a.host.confirmed(f,u),await a.pending.remove(i.id)),u}return{identityChanged(){n++},async purchase(i,f=crypto.randomUUID()){let u=n;if(d.has(i))throw new r("CONFLICT","A purchase is already in progress");d.add(i);try{let g=await a.prepare(i,f),I=R.safeParse(g);if(!I.success)throw new r("INVALID_RESPONSE","Invalid purchase intent");let h=I.data;if(h.scope.projectId!==a.scope.projectId||h.scope.environment!==a.scope.environment)throw new r("SCOPE_MISMATCH","Purchase intent belongs to another App or environment");if(h.protocolVersion!==U||h.nextStep.provider!==a.host.provider||!h.submissionTicket)throw new r("INVALID_RESPONSE","Native purchase intent required");if(u!==n)throw new r("IDENTITY_CHANGED","Identity changed before purchase");if(Date.parse(h.expiresAt)<=Date.now())throw new r("INVALID_RESPONSE","Purchase intent expired");let E=await a.pending.get(h.id);if(E)return l(E),{state:"pending",intentId:h.id};if(await a.pending.put(h),u!==n)throw await a.pending.remove(h.id),new r("IDENTITY_CHANGED","Identity changed before store launch");let v=await a.host.purchase(h);if(v.state==="canceled")return a.host.provider==="apple"&&await a.pending.remove(h.id),u===n?{state:"canceled"}:{state:"delivered_to_original_identity"};if(v.state==="pending")return u===n?{state:"pending",intentId:h.id}:{state:"delivered_to_original_identity"};let e=await w(h,v.evidence);return u===n?{state:"result",result:e}:{state:"delivered_to_original_identity"}}finally{d.delete(i)}},async recover(i,f){let u=l(await a.pending.get(i));if(u.id!==i)throw new r("INVALID_RESPONSE","Stored intent identity mismatch");return w(u,f)},async status(i){let f=l(await a.pending.get(i));if(f.id!==i)throw new r("INVALID_RESPONSE","Stored intent identity mismatch");return o(f,await a.tickets.status(f))}}}import{z as Y}from"zod";function V(a){let n=new URL(a.baseUrl);if(n.username||n.password||n.search||n.hash||n.protocol!=="https:"&&!(n.protocol==="http:"&&["localhost","127.0.0.1","[::1]"].includes(n.hostname)))throw new r("INVALID_URL","Purchase submission requires HTTPS or localhost");let d=a.timeoutMs??1e4;if(!Number.isFinite(d)||d<=0||d>12e4)throw new r("INVALID_TIMEOUT","Invalid purchase timeout");let l=a.fetch??globalThis.fetch.bind(globalThis);async function o(w,i,f){if(!i.submissionTicket)throw new r("INVALID_TOKEN","Original purchase ticket required");if(a.scope&&(i.scope.projectId!==a.scope.projectId||i.scope.environment!==a.scope.environment))throw new r("SCOPE_MISMATCH","Purchase scope mismatch");let u=new AbortController,g,I=setTimeout(()=>u.abort(),d),h,E=new Promise((e,t)=>{h=()=>{g?.cancel().catch(()=>{}),t(new r("TIMEOUT","Purchase submission timed out"))},u.signal.addEventListener("abort",h,{once:!0})}),v=async()=>{let e=await l(`${n.toString().replace(/\/$/,"")}/api/v1/purchases/${w}`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${i.submissionTicket}`,"X-Groove-Project":i.scope.projectId,"X-Groove-Environment":i.scope.environment},body:JSON.stringify({protocolVersion:1,intentId:i.id,...f?{evidence:f}:{}}),signal:u.signal,redirect:"error",cache:"no-store",credentials:"omit"});if(u.signal.aborted)throw new r("TIMEOUT","Purchase submission timed out");if(!e.ok)throw new r("PURCHASE_SUBMISSION_FAILED","Unable to submit this purchase",e.status);if(g=e.body?.getReader(),!g)throw new r("INVALID_RESPONSE","Invalid purchase response");let t=[],s=0,p;try{for(;;){let{done:y,value:b}=await g.read();if(y)break;if(s+=b.byteLength,s>65536)throw await g.cancel(),new r("INVALID_RESPONSE","Purchase response exceeds the size limit");t.push(b)}let S=new Uint8Array(s),c=0;for(let y of t)S.set(y,c),c+=y.byteLength;p=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(S))}catch(S){throw S instanceof r?S:new r("INVALID_RESPONSE","Invalid purchase response")}finally{g.releaseLock()}if(u.signal.aborted)throw new r("TIMEOUT","Purchase submission timed out");let N=Y.strictObject({status:_}).safeParse(p);if(!N.success||N.data.status.intentId!==i.id)throw new r("INVALID_RESPONSE","Invalid purchase response");return N.data.status};try{return await Promise.race([v(),E])}finally{clearTimeout(I),u.signal.removeEventListener("abort",h)}}return{submit:(w,i)=>o("submit",w,i),status:w=>o("status",w)}}function z(a){let n=Object.freeze({status:"idle",data:null,error:null,stale:!0}),d=0,l=null,o=0,w=new Set,i=!1;function f(I){n=Object.freeze(I),!i&&(i=!0,queueMicrotask(()=>{i=!1;for(let h of w)h()}))}function u(I){if(l)return l;if(!I&&n.data&&!n.stale&&Date.now()<o)return Promise.resolve(n.data);let h=d;f({...n,status:"loading",error:null});let E=Promise.resolve().then(()=>{if(h!==d)throw new r("IDENTITY_CHANGED","Customer state changed before loading");return a()}).then(v=>(h===d&&(o=Date.now()+3e4,f({status:"ready",data:v,error:null,stale:!1})),v),v=>{let e=v instanceof r?v:new r("INVALID_RESPONSE","Customer state could not be read");throw h===d&&f({...n,data:["UNAUTHENTICATED","FORBIDDEN","SCOPE_MISMATCH","NOT_IDENTIFIED","IDENTITY_CHANGED"].includes(e.code)?null:n.data,status:"error",error:e,stale:!0}),e}).finally(()=>{l===E&&(l=null)});return l=E,E}return{store:{getSnapshot:()=>n,subscribe(I){return w.add(I),()=>{w.delete(I)}},load:()=>u(!1),refresh:()=>u(!0)},clear(){d+=1,o=0,l=null,f({status:"idle",data:null,error:null,stale:!0})},invalidate(){d+=1,l=null,f({...n,stale:!0}),w.size&&n.data&&u(!0).catch(()=>{})}}}function $(){let a=new Map,n=0,d=(l,o)=>{a.delete(l),n-=o.bytes};return{clear(){a.clear(),n=0},candidate(l){let o=Date.now();for(let[i,f]of a)f.expires<=o&&d(i,f);let w=a.get(l);return w&&(a.delete(l),a.set(l,w)),w},hydrate(l,o,w,i){if(w===null){let I=i?.identity;if(!I||I.contentTag!==o.contentTag||I.scope.projectId!==o.scope.projectId||I.scope.environment!==o.scope.environment||I.campaignId!==o.campaignId||I.versionId!==o.versionId||I.locale!==o.locale)throw new r("INVALID_RESPONSE","Omitted surface design does not match the request cache");return JSON.parse(i.json)}let f=JSON.stringify(w),u=new TextEncoder().encode(f).length,g=a.get(l);if(g&&d(l,g),u<=q.documentBytes)for(a.set(l,{identity:{...o,scope:{...o.scope}},json:f,bytes:u,expires:Date.now()+15*6e4}),n+=u;a.size>16||n>2*1024*1024;){let[I,h]=a.entries().next().value;d(I,h)}return JSON.parse(f)}}}var k=new WeakMap;function W(a){if(!/^gg_fr_[A-Za-z0-9_-]{43}$/.test(a.runToken))throw new r("INVALID_TOKEN","Flow credential required");let n={...a,scope:a.scope?{...a.scope}:void 0},d=a.runToken,l=O(n);l.identify(d);let o,w=!1,i=new Set,f=()=>{for(let e of i)try{e()}catch{}},u=0,g=new Set;function I(e=!1){u+=1,o=void 0,w=!1,f();for(let t of g)t.reset();g.clear(),e?l.reset():l.identify(d)}function h(e){let t=j.safeParse(e);if(!t.success||!t.data.run)throw new r("INVALID_RESPONSE","Funnel run required");return t.data}async function E(e){let t=G.safeParse(e);if(!t.success)throw new r("INVALID_REQUEST","Invalid Funnel request");return h(await l.request("funnels",t.data))}let v={get webViewUrl(){return l.webViewUrl()},get:()=>E({operation:"get"}),track:e=>E({operation:"event",...e}),node:(e,t,s=crypto.randomUUID())=>E({operation:"node",nodeId:e,outcome:t,requestId:s,...o?{customerToken:o}:{}}),async authenticate(e){if(!/^gg_ct_[A-Za-z0-9_-]{32,128}$/.test(e))throw new r("INVALID_TOKEN","Customer token required");I();let t=u,s=O(n);s.identify(e),g.add(s);try{let p=h(await s.request("funnels",{operation:"link",runToken:d}));if(t!==u)throw new r("IDENTITY_CHANGED","Customer identity changed during authentication");return o=e,w=!0,f(),p}finally{g.delete(s)}},identify(e){if(!/^gg_ct_[A-Za-z0-9_-]{32,128}$/.test(e))throw new r("INVALID_TOKEN","Customer token required");I(),o=e,f()},isAuthenticated:()=>!!o,reset(){I(!0)}};return k.set(v,{get:()=>o,isVerified:()=>w,subscribe(e){return i.add(e),()=>{i.delete(e)}}}),v}async function Z(a,n){let d=(await n.client.get()).run,l=!1,o=Promise.resolve(),w="",i,f=d.history,u=new Map,g,I,h=()=>{let c=k.get(n.client)?.get();if(!(!n.customerClient||l)){if(I?.destroy(),I=void 0,!c){g.updateCustomerData({nodes:{}});return}if(!k.get(n.client)?.isVerified()){g.updateCustomerData({nodes:{}}),n.client.authenticate(c).catch(y=>T(n.onError,y));return}n.customerClient.identify(c),I=Q(d.document,n.customerClient,{locale:d.locale,onData:y=>g.updateCustomerData(y),onCheckout:n.onCreditPackCheckout,onError:n.onError})}},E=c=>{T(n.onState,c,d)},v=c=>{o=o.then(async()=>{l||await c()}).catch(async y=>{if(!l){try{if(d=(await n.client.get()).run,l)return;if(i?.status==="waiting"&&d.nodeId!==i.nodeId){for(let C of u.keys())C.startsWith(i.nodeId+":")&&u.delete(C);g.resolveFunnel({target:d.nodeId});return}}catch{}if(l)return;g.resolveFunnel({label:"\u6682\u65F6\u65E0\u6CD5\u7EE7\u7EED\uFF0C\u8BF7\u91CD\u8BD5\u786E\u8BA4\u3002"}),T(n.onError,y)}})},e=async c=>{let y=d.document.funnel.nodes.find(D=>D.id===i?.nodeId);if(!y)return;if((y.type==="auth"||y.type==="purchase"&&!n.client.isAuthenticated())&&c!=="cancel")try{let D=await n.onAuthenticate();if(l)return;D?d=(await n.client.authenticate(D)).run:c="cancel"}catch(D){c="failure",T(n.onError,D)}if(l)return;let b=y.id+":"+c,C=u.get(b);C||(C=crypto.randomUUID(),u.set(b,C));let P=await n.client.node(y.id,c,C);if(l)return;if(P.target)for(let D of u.keys())D.startsWith(y.id+":")&&u.delete(D);d=P.run??d,P.checkout&&T(n.onCheckout,P.checkout);let A=P.price?`${(P.price.amountCents/100).toFixed(2)} ${P.price.currency.toUpperCase()}`:"";g.resolveFunnel({target:P.target,label:P.pending?P.trialTerms??`${A} \u7B49\u5F85\u670D\u52A1\u7AEF\u786E\u8BA4\uFF1B\u4ED8\u6B3E\u540E\u70B9\u51FB\u7EE7\u7EED\u786E\u8BA4\u3002`:void 0,checkoutUrl:P.checkout?.url})};if(d.status!=="running")return a.textContent=d.status==="completed"?"\u6B64\u6D41\u7A0B\u5DF2\u5B8C\u6210\u3002":"\u6B64\u6D41\u7A0B\u5DF2\u5173\u95ED\u3002",{destroy(){},async close(){},snapshot:()=>d};let{mountScreenPreview:t}=await import("./popup.js");g=t(a,{mode:"live",rendererUrl:n.client.webViewUrl,onCustomerDataIntent:c=>{I?.intent(c).catch(y=>T(n.onError,y))},onFunnelState(c){let y=c.history.length<f.length;f=c.history,i=c,c.status!=="completed"&&E(c);let b=`${c.status}:${c.nodeId}`;w!==b&&(w=b,v(async()=>{let C=await n.client.track({eventId:crypto.randomUUID(),nodeId:c.nodeId,type:"enter",back:y});if(!l&&(d=C.run,c.status==="waiting"&&await e("begin"),c.status==="completed")){let P=await n.client.track({eventId:crypto.randomUUID(),nodeId:c.nodeId,type:"complete"});if(l)return;d=P.run,E(c)}}))},onFunnelIntent(c){v(()=>e(c))},onError(c){T(n.onError,new Error(c))}});let s=d.document.pages.find(c=>c.id===d.nodeId),p=n.resume?.versionId===d.versionId&&n.resume.state.nodeId===d.nodeId?n.resume.state:{status:s?"running":"waiting",nodeId:d.nodeId,pageId:s?.id??null,history:d.history,answers:{}};g.update(d.document,d.locale,{resume:p});try{await g.ready}catch(c){throw l=!0,g.destroy(),c}let N=k.get(n.client)?.subscribe(h);h();let S;return{snapshot:()=>d,destroy(){l=!0,I?.destroy(),N?.(),g.destroy()},close(){if(S)return S;if(l)return Promise.resolve();let c=i?.nodeId??d.nodeId;return l=!0,I?.destroy(),N?.(),g.destroy(),S=n.client.track({eventId:crypto.randomUUID(),nodeId:c,type:"close"}).then(()=>{}),S}}}function Pe(a){let n=O(a),d=a.locale,l=a.currency,o=n.request,w=$(),i=0;async function f(e,t,s,p){let N=i,S=w.candidate(e);try{let c=await o(t,{...s,...S?{cachedContentTag:S.identity.contentTag}:{}});if(N!==i)throw new r("IDENTITY_CHANGED","Customer identity changed while reading surface content");return p(c,S)}catch(c){throw N===i&&c instanceof r&&(c.status===401||c.status===403||["NOT_IDENTIFIED","SCOPE_MISMATCH","INVALID_RESPONSE"].includes(c.code))&&w.clear(),c}}let u=new Map,g=new Set,I=e=>{for(let t of g)try{t(e)}catch{}},h=()=>{for(let e of u.values())e.invalidate()};async function E(e={}){let t=m.getCustomerState,s=t.request.omit({customerId:!0,entityId:!0}).safeParse(e);if(!s.success)throw new r("INVALID_REQUEST","Invalid customer state request");let p=t.response.safeParse(await o(t.path,s.data));if(!p.success)throw new r("INVALID_RESPONSE","Invalid customer state response");let N={memberships:"membership",entitlements:"features",credits:"resources"};if(s.data.include.some(S=>!Object.hasOwn(p.data.state,N[S])))throw new r("INVALID_RESPONSE","Customer state omitted a requested section");return p.data}if(a.nativeCommerce&&!a.scope)throw new r("INVALID_SCOPE","Native purchases require an explicit App and environment");let v=a.nativeCommerce&&a.scope?L({scope:a.scope,host:a.nativeCommerce.host,pending:a.nativeCommerce.pending,tickets:V(a),prepare:async(e,t)=>{let s=await o("purchases/intents",{protocolVersion:1,bindingId:e,idempotencyKey:t});if(!s||typeof s!="object"||!("intent"in s))throw new r("INVALID_RESPONSE","Invalid purchase intent response");return s.intent}}):null;return{purchases:v,get webViewUrl(){return n.webViewUrl()},subscribeIdentity(e){return g.add(e),()=>{g.delete(e)}},async getPage(e){let t=m.getPage,s=t.request.omit({entityId:!0,cachedContentTag:!0}).safeParse({...e,locale:e.locale??d});if(!s.success)throw new r("INVALID_REQUEST","Invalid Page request");let p=JSON.stringify(["page",s.data.pageId,s.data.locale]);return f(p,t.path,s.data,(N,S)=>{let c=t.response.safeParse(N);if(!c.success||c.data.pageId!==s.data.pageId)throw new r("INVALID_RESPONSE","Invalid published Page response");let{contentTag:y,document:b,...C}=c.data,P=w.hydrate(p,{scope:C.scope,campaignId:C.pageId,versionId:C.versionId,locale:C.locale,contentTag:y},b,S);if(P.surface!=="page")throw new r("INVALID_RESPONSE","Invalid published Page surface");return{...C,document:P}})},async listOfferHistory(e={}){let t=m.listOfferHistory,s=t.request.safeParse(e);if(!s.success||s.data.customerId||s.data.entityId)throw new r("INVALID_REQUEST","Invalid offer history request");let p=t.response.safeParse(await o(t.path,s.data));if(!p.success)throw new r("INVALID_RESPONSE","Invalid offer history response");return p.data},getCustomerState:E,createCustomerStateStore(e={}){let t=m.getCustomerState.request.omit({customerId:!0,entityId:!0}).safeParse(e);if(!t.success)throw new r("INVALID_REQUEST","Invalid customer state request");t.data.include.sort();let s=JSON.stringify(t.data),p=u.get(s);return p||(p=z(async()=>(await E(t.data)).state),u.set(s,p)),p.store},async listCustomerPlans(e={}){let t=m.listCustomerPlans,s=t.request.omit({customerId:!0,entityId:!0}).safeParse({...e,currency:e.currency??l});if(!s.success)throw new r("INVALID_REQUEST","Invalid customer plan request");let p=t.response.safeParse(await o(t.path,s.data));if(!p.success)throw new r("INVALID_RESPONSE","Invalid customer plan response");return p.data},identify(e){if(e.startsWith("gg_sk_"))throw new r("INVALID_TOKEN","Secret API keys must not be used in the browser SDK");n.identify(e),i++,w.clear(),v?.identityChanged();for(let t of u.values())t.clear();I(!0)},reset(){v?.identityChanged(),n.reset(),i++,w.clear();for(let e of u.values())e.clear();I(!1)},async listCreditPacks(e={}){let t=m.listCreditPacks,s=t.request.safeParse(e);if(!s.success)throw new r("INVALID_REQUEST","Invalid credit pack request");let p=t.response.safeParse(await o(t.path,s.data));if(!p.success)throw new r("INVALID_RESPONSE","Invalid credit pack response");return p.data},async listCreditPackOrders(e={}){let t=m.listCreditPackOrders,s=t.request.safeParse(e);if(!s.success)throw new r("INVALID_REQUEST","Invalid credit pack request");let p=t.response.safeParse(await o(t.path,s.data));if(!p.success)throw new r("INVALID_RESPONSE","Invalid credit pack response");return p.data},async createCreditPackCheckout(e){let t=m.createCreditPackCheckout,s=t.request.safeParse(e);if(!s.success)throw new r("INVALID_REQUEST","Invalid credit pack request");let p=t.response.safeParse(await o(t.path,s.data));if(!p.success)throw new r("INVALID_RESPONSE","Invalid credit pack response");return p.data},async listCreditTransactions(e={}){let t=m.listCreditTransactions,s=t.request.safeParse(e);if(!s.success)throw new r("INVALID_REQUEST","Invalid history cursor");let p=t.response.safeParse(await o(t.path,s.data));if(!p.success)throw new r("INVALID_RESPONSE","Invalid credit history");return p.data},async getBalances(){let e=m.getBalances.response.safeParse(await o("credits/balances",{}));if(!e.success)throw new r("INVALID_RESPONSE","Invalid credit balances");return e.data.account},async checkCredits(e){let t=m.checkCredits.request.safeParse(e);if(!t.success)throw new r("INVALID_REQUEST","Invalid credit check");let s=m.checkCredits.response.safeParse(await o("credits/check",t.data));if(!s.success)throw new r("INVALID_RESPONSE","Invalid credit check response");return s.data},async refreshSurface(e){let t=m.refreshSurface.request.safeParse({...e,currency:e.currency??l});if(!t.success)throw new r("INVALID_REQUEST","Invalid surface context request");let s=m.refreshSurface.response.safeParse(await o("surfaces/context",t.data));if(!s.success)throw new r("INVALID_RESPONSE","Invalid surface context response");return s.data.capabilities},async purchaseSurface(e){let t=m.purchaseSurface.request.safeParse({...e,currency:e.currency??l});if(!t.success)throw new r("INVALID_REQUEST","Invalid surface checkout input");let s=m.purchaseSurface.response.safeParse(await o("surfaces/purchase",t.data));if(!s.success)throw new r("INVALID_RESPONSE","Invalid surface checkout response");return s.data},async createCheckout(e,t={}){if(t===null||typeof t!="object"||Array.isArray(t))throw new r("INVALID_REQUEST","Checkout options must be an object");let s=m.createCheckout.request.safeParse({...t,currency:t.currency??l,planVersionId:e,requestId:t.requestId??crypto.randomUUID(),...t.offerId?{offerId:t.offerId}:{},...t.promotionCode?{promotionCode:t.promotionCode}:{}});if(!s.success)throw new r("INVALID_REQUEST","Invalid checkout request");let p=m.createCheckout.response.safeParse(await o("billing/checkout",s.data));if(!p.success)throw new r("INVALID_RESPONSE","Invalid checkout response");return p.data},async getMemberships(){let e=m.getMemberships.response.safeParse(await o("memberships",{},"GET"));if(!e.success)throw new r("INVALID_RESPONSE","Invalid membership response");return e.data.membership},async previewMembership(e){let t=m.previewMembership.request.safeParse(e);if(!t.success)throw new r("INVALID_REQUEST","Invalid membership preview");let s=m.previewMembership.response.safeParse(await o("memberships/preview",t.data));if(!s.success)throw new r("INVALID_RESPONSE","Invalid membership preview response");return s.data.preview},async manageMembership(e){let t=m.manageMembership.request.safeParse(e);if(!t.success)throw new r("INVALID_REQUEST","Invalid membership change");let s=m.manageMembership.response.safeParse(await o("memberships/manage",t.data));if(!s.success)throw new r("INVALID_RESPONSE","Invalid membership change response");return h(),s.data},async getTrialEligibility(e){let t=m.getTrialEligibility.request.safeParse({planVersionId:e});if(!t.success)throw new r("INVALID_REQUEST","Invalid trial plan");let s=m.getTrialEligibility.response.safeParse(await o("memberships/trial/eligibility",t.data));if(!s.success)throw new r("INVALID_RESPONSE","Invalid trial eligibility response");return s.data.eligibility},async startTrial(e){let t=m.startTrial.request.safeParse(e);if(!t.success)throw new r("INVALID_REQUEST","Invalid trial request");let s=m.startTrial.response.safeParse(await o("memberships/trial",t.data));if(!s.success)throw new r("INVALID_RESPONSE","Invalid trial response");return h(),s.data},async getSubscriptions(){let e=m.listSubscriptions.response.safeParse(await o("billing/subscriptions",{},"GET"));if(!e.success)throw new r("INVALID_RESPONSE","Invalid subscriptions response");return e.data.subscriptions},async getPopup(e,t={}){let s=typeof navigator>"u"?void 0:[...new Set([...navigator.languages??[],navigator.language])].filter(S=>typeof S=="string"&&S.length<=35).slice(0,10),p=m.resolvePopup.request.safeParse({trigger:e,requestId:t.requestId??crypto.randomUUID(),locale:t.locale??d,currency:t.currency??l,acceptLanguages:s});if(!p.success)throw new r("INVALID_REQUEST","Invalid popup trigger or request ID");let N=JSON.stringify(["popup",p.data.trigger,p.data.locale,p.data.acceptLanguages]);return f(N,"popups/resolve",p.data,(S,c)=>{let y=m.resolvePopup.response.safeParse(S);if(!y.success)throw new r("INVALID_RESPONSE","Invalid popup response");let b=y.data.delivery;if(!b)return null;let{contentTag:C,popup:P,...A}=b,D=w.hydrate(N,{scope:y.data.scope,campaignId:A.campaignId,versionId:A.versionId,locale:A.locale,contentTag:C},P,c);return F.parse({...A,popup:D})})},async trackPopup(e){let t=m.trackPopup.request.safeParse(e);if(!t.success)throw new r("INVALID_EVENT","Invalid popup event");if(!m.trackPopup.response.safeParse(await o("popups/events",t.data)).success)throw new r("INVALID_RESPONSE","Invalid event acknowledgement")},async listPlans(){let e=x.safeParse(await o("plans",{},"GET"));if(!e.success)throw new r("INVALID_RESPONSE","Invalid plans response");return e.data},async getEntitlements(){let e=H.safeParse(await o("entitlements",{}));if(!e.success)throw new r("INVALID_RESPONSE","Invalid entitlements response");return e.data},async listOffers(){let e=m.listOffers.response.safeParse(await o("offers",{},"GET"));if(!e.success)throw new r("INVALID_RESPONSE","Invalid offers response");return e.data.offers},async claimOffer(e){let t=m.claimOffer.request.safeParse({...e,requestId:e.requestId??crypto.randomUUID()});if(!t.success)throw new r("INVALID_REQUEST","Invalid offer claim");let s=m.claimOffer.response.safeParse(await o("offers/claim",t.data));if(!s.success)throw new r("INVALID_RESPONSE","Invalid offer response");return{offer:s.data.offer,reason:s.data.reason}}}}export{r as GrooveError,W as createFunnelClient,Pe as createGroove,L as createPurchaseHostClient,V as createPurchaseTicketTransport,K as formatCouponDiscount,J as formatCouponMoney,B as formatCouponTerms,Z as showFunnel};
1
+ import{a as O,d as X}from"./chunk-MGI4EQLR.js";import{a as r,b as q}from"./chunk-O5ZKLGES.js";import{$d as h,Ld as $,Ud as B,Xa as re,Ya as se,Yd as W,Za as ne,gc as Q,h as j,hd as z,le as K,me as Y,oe as Z,rd as H,sd as J,ud as U}from"./chunk-B5O7FDKE.js";function G(i){let a=0,s=new Set,u=c=>{let m=H.safeParse(c);if(!m.success||!m.data.submissionTicket||m.data.nextStep.provider!==i.host.provider)throw new r("INVALID_REQUEST","Original purchase ticket unavailable");let l=m.data;if(l.scope.projectId!==i.scope.projectId||l.scope.environment!==i.scope.environment)throw new r("SCOPE_MISMATCH","Stored purchase belongs to another App or environment");return l},o=(c,m)=>{let l=U.safeParse(m);if(!l.success||l.data.intentId!==c.id)throw new r("INVALID_RESPONSE","Invalid purchase confirmation");if(l.data.state!=="fulfilled"&&l.data.finishTransactionKeys.length!==0)throw new r("INVALID_RESPONSE","Unfulfilled purchases cannot finish store transactions");return l.data};async function w(c,m){if(m.provider!==c.nextStep.provider)throw new r("INVALID_REQUEST","Purchase provider mismatch");let l=o(c,await i.tickets.submit(c,J.parse(m)));return l.state==="fulfilled"&&(await i.host.confirmed(m,l),await i.pending.remove(c.id)),l}return{identityChanged(){a++},async purchase(c,m=crypto.randomUUID()){let l=a;if(s.has(c))throw new r("CONFLICT","A purchase is already in progress");s.add(c);try{let g=await i.prepare(c,m),f=H.safeParse(g);if(!f.success)throw new r("INVALID_RESPONSE","Invalid purchase intent");let I=f.data;if(I.scope.projectId!==i.scope.projectId||I.scope.environment!==i.scope.environment)throw new r("SCOPE_MISMATCH","Purchase intent belongs to another App or environment");if(I.protocolVersion!==z||I.nextStep.provider!==i.host.provider||!I.submissionTicket)throw new r("INVALID_RESPONSE","Native purchase intent required");if(l!==a)throw new r("IDENTITY_CHANGED","Identity changed before purchase");if(Date.parse(I.expiresAt)<=Date.now())throw new r("INVALID_RESPONSE","Purchase intent expired");let v=await i.pending.get(I.id);if(v)return u(v),{state:"pending",intentId:I.id};if(await i.pending.put(I),l!==a)throw await i.pending.remove(I.id),new r("IDENTITY_CHANGED","Identity changed before store launch");let S=await i.host.purchase(I);if(S.state==="canceled")return i.host.provider==="apple"&&await i.pending.remove(I.id),l===a?{state:"canceled"}:{state:"delivered_to_original_identity"};if(S.state==="pending")return l===a?{state:"pending",intentId:I.id}:{state:"delivered_to_original_identity"};let e=await w(I,S.evidence);return l===a?{state:"result",result:e}:{state:"delivered_to_original_identity"}}catch(g){throw l!==a&&!(g instanceof r&&g.code==="IDENTITY_CHANGED")?new r("IDENTITY_CHANGED","Identity changed during purchase"):g}finally{s.delete(c)}},async recover(c,m){let l=u(await i.pending.get(c));if(l.id!==c)throw new r("INVALID_RESPONSE","Stored intent identity mismatch");return w(l,m)},async status(c){let m=u(await i.pending.get(c));if(m.id!==c)throw new r("INVALID_RESPONSE","Stored intent identity mismatch");return o(m,await i.tickets.status(m))}}}import{z as ae}from"zod";function x(i){let a=new URL(i.baseUrl);if(a.username||a.password||a.search||a.hash||a.protocol!=="https:"&&!(a.protocol==="http:"&&["localhost","127.0.0.1","[::1]"].includes(a.hostname)))throw new r("INVALID_URL","Purchase submission requires HTTPS or localhost");let s=i.timeoutMs??1e4;if(!Number.isFinite(s)||s<=0||s>12e4)throw new r("INVALID_TIMEOUT","Invalid purchase timeout");let u=i.fetch??globalThis.fetch.bind(globalThis);async function o(w,c,m){if(!c.submissionTicket)throw new r("INVALID_TOKEN","Original purchase ticket required");if(i.scope&&(c.scope.projectId!==i.scope.projectId||c.scope.environment!==i.scope.environment))throw new r("SCOPE_MISMATCH","Purchase scope mismatch");let l=new AbortController,g,f=setTimeout(()=>l.abort(),s),I,v=new Promise((e,t)=>{I=()=>{g?.cancel().catch(()=>{}),t(new r("TIMEOUT","Purchase submission timed out"))},l.signal.addEventListener("abort",I,{once:!0})}),S=async()=>{let e=await u(`${a.toString().replace(/\/$/,"")}/api/v1/purchases/${w}`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${c.submissionTicket}`,"X-Groove-Project":c.scope.projectId,"X-Groove-Environment":c.scope.environment},body:JSON.stringify({protocolVersion:1,intentId:c.id,...m?{evidence:m}:{}}),signal:l.signal,redirect:"error",cache:"no-store",credentials:"omit"});if(l.signal.aborted)throw new r("TIMEOUT","Purchase submission timed out");if(!e.ok)throw new r("PURCHASE_SUBMISSION_FAILED","Unable to submit this purchase",e.status);if(g=e.body?.getReader(),!g)throw new r("INVALID_RESPONSE","Invalid purchase response");let t=[],n=0,p;try{for(;;){let{done:A,value:_}=await g.read();if(A)break;if(n+=_.byteLength,n>65536)throw await g.cancel(),new r("INVALID_RESPONSE","Purchase response exceeds the size limit");t.push(_)}let E=new Uint8Array(n),P=0;for(let A of t)E.set(A,P),P+=A.byteLength;p=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(E))}catch(E){throw E instanceof r?E:new r("INVALID_RESPONSE","Invalid purchase response")}finally{g.releaseLock()}if(l.signal.aborted)throw new r("TIMEOUT","Purchase submission timed out");let b=ae.strictObject({status:U}).safeParse(p);if(!b.success||b.data.status.intentId!==c.id)throw new r("INVALID_RESPONSE","Invalid purchase response");return b.data.status};try{return await Promise.race([S(),v])}finally{clearTimeout(f),l.signal.removeEventListener("abort",I)}}return{submit:(w,c)=>o("submit",w,c),status:w=>o("status",w)}}function ee(i){let a=Object.freeze({status:"idle",data:null,error:null,stale:!0}),s=0,u=null,o=0,w=new Set,c=!1;function m(f){a=Object.freeze(f),!c&&(c=!0,queueMicrotask(()=>{c=!1;for(let I of w)I()}))}function l(f){if(u)return u;if(!f&&a.data&&!a.stale&&Date.now()<o)return Promise.resolve(a.data);let I=s;m({...a,status:"loading",error:null});let v=Promise.resolve().then(()=>{if(I!==s)throw new r("IDENTITY_CHANGED","Customer state changed before loading");return i()}).then(S=>(I===s&&(o=Date.now()+3e4,m({status:"ready",data:S,error:null,stale:!1})),S),S=>{let e=S instanceof r?S:new r("INVALID_RESPONSE","Customer state could not be read");throw I===s&&m({...a,data:["UNAUTHENTICATED","FORBIDDEN","SCOPE_MISMATCH","NOT_IDENTIFIED","IDENTITY_CHANGED"].includes(e.code)?null:a.data,status:"error",error:e,stale:!0}),e}).finally(()=>{u===v&&(u=null)});return u=v,v}return{store:{getSnapshot:()=>a,subscribe(f){return w.add(f),()=>{w.delete(f)}},load:()=>l(!1),refresh:()=>l(!0)},clear(){s+=1,o=0,u=null,m({status:"idle",data:null,error:null,stale:!0})},invalidate(){s+=1,u=null,m({...a,stale:!0}),w.size&&a.data&&l(!0).catch(()=>{})}}}function te(){let i=new Map,a=0,s=(u,o)=>{i.delete(u),a-=o.bytes};return{clear(){i.clear(),a=0},candidate(u){let o=Date.now();for(let[c,m]of i)m.expires<=o&&s(c,m);let w=i.get(u);return w&&(i.delete(u),i.set(u,w)),w},hydrate(u,o,w,c){if(w===null){let f=c?.identity;if(!f||f.contentTag!==o.contentTag||f.scope.projectId!==o.scope.projectId||f.scope.environment!==o.scope.environment||f.campaignId!==o.campaignId||f.versionId!==o.versionId||f.locale!==o.locale)throw new r("INVALID_RESPONSE","Omitted surface design does not match the request cache");return JSON.parse(c.json)}let m=JSON.stringify(w),l=new TextEncoder().encode(m).length,g=i.get(u);if(g&&s(u,g),l<=Q.documentBytes)for(i.set(u,{identity:{...o,scope:{...o.scope}},json:m,bytes:l,expires:Date.now()+15*6e4}),a+=l;i.size>16||a>2*1024*1024;){let[f,I]=i.entries().next().value;s(f,I)}return JSON.parse(m)}}}var M=new WeakMap;function oe(i){if(!/^gg_fr_[A-Za-z0-9_-]{43}$/.test(i.runToken))throw new r("INVALID_TOKEN","Flow credential required");let a={...i,timeoutMs:i.timeoutMs??35e3,scope:i.scope?{...i.scope}:void 0},s=i.runToken,u=q(a);u.identify(s);let o,w=!1,c=new Set,m=()=>{for(let e of c)try{e()}catch{}},l=0,g=new Set;function f(e=!1){l+=1,o=void 0,w=!1;for(let t of g)t.reset();g.clear(),e?u.reset():u.identify(s),m()}function I(e){let t=Z.safeParse(e);if(!t.success||!t.data.run)throw new r("INVALID_RESPONSE","Funnel run required");return t.data}async function v(e){let t=Y.safeParse(e);if(!t.success)throw new r("INVALID_REQUEST","Invalid Funnel request");return I(await u.request("funnels",t.data))}let S={get webViewUrl(){return u.webViewUrl()},get:()=>v({operation:"get",...o?{customerToken:o}:{}}),track:e=>v({operation:"event",...e,...o?{customerToken:o}:{}}),saveAnswers:e=>v({operation:"answers",...e,...o?{customerToken:o}:{}}),node:(e,t,n=crypto.randomUUID())=>v({operation:"node",nodeId:e,outcome:t,requestId:n,...o?{customerToken:o}:{}}),async authenticate(e){if(!/^gg_ct_[A-Za-z0-9_-]{32,128}$/.test(e))throw new r("INVALID_TOKEN","Customer token required");f();let t=l,n=q(a);n.identify(e),g.add(n);try{let p=I(await n.request("funnels",{operation:"link",runToken:s}));if(t!==l)throw new r("IDENTITY_CHANGED","Customer identity changed during authentication");return o=e,w=!0,m(),p}finally{g.delete(n)}},identify(e){if(!/^gg_ct_[A-Za-z0-9_-]{32,128}$/.test(e))throw new r("INVALID_TOKEN","Customer token required");f(),o=e,m()},isAuthenticated:()=>!!o,reset(){f(!0)}};return M.set(S,{get:()=>o,isVerified:()=>w,subscribe(e){return c.add(e),()=>{c.delete(e)}}}),S}async function ie(i,a){let s=(await a.client.get()).run,u=!1,o=Promise.resolve(),w="",c,m=s.history,l=new Map,g=d=>{for(let y of l.keys())y.startsWith(d+":")&&l.delete(y)},f,I,v,S=0,e=0,t=0,n=()=>{let d=M.get(a.client)?.get();if(!(!a.customerClient||u)){if(I?.destroy(),I=void 0,!d){f.updateCustomerData({nodes:{}});return}if(!M.get(a.client)?.isVerified()){f.updateCustomerData({nodes:{}});let y=e;a.client.authenticate(d).then(N=>{u||y!==e||(s=N.run,e+=1,f.updateCapabilities(s.capabilities))}).catch(N=>{u||O(a.onError,N)});return}a.customerClient.identify(d),I=X(s.document,a.customerClient,{locale:s.locale,onData:y=>f.updateCustomerData(y),onCheckout:a.onCreditPackCheckout,onError:a.onError})}},p=d=>{O(a.onState,d,s)},b=()=>{u=!0,I?.destroy(),v?.(),f?.destroy();let d=i.ownerDocument.createElement("p");d.setAttribute("role","status"),d.textContent=s.locale.startsWith("zh")?s.status==="completed"?"\u6B64\u6D41\u7A0B\u5DF2\u5B8C\u6210\u3002":"\u6B64\u6D41\u7A0B\u5DF2\u5173\u95ED\u3002":s.status==="completed"?"This flow is complete.":"This flow is closed.",i.replaceChildren(d)},E=d=>{let y=t;o=o.then(async()=>{!u&&y===t&&await d()}).catch(async N=>{if(!u){try{if(s=(await a.client.get()).run,e+=1,u)return;if(c&&s.nodeId!==c.nodeId&&g(c.nodeId),f.updateCapabilities(s.capabilities),s.status!=="running"||s.nodeId!==c?.nodeId||JSON.stringify(s.answers)!==JSON.stringify(c?.answers)){if(O(a.onError,N),t+=1,s.status!=="running"){s.status==="completed"&&p({status:"completed",nodeId:s.nodeId,pageId:null,answers:s.answers,history:s.history}),b();return}let C=s.document.pages.find(V=>V.id===s.nodeId);m=s.history,w="",f.update(s.document,s.locale,{resume:{status:C?"running":"waiting",nodeId:s.nodeId,pageId:C?.id??null,answers:s.answers,history:s.history},parameters:s.parameters,capabilities:s.capabilities});return}}catch{}if(u)return;f.resolveFunnel({label:s.locale.startsWith("zh")?"\u6682\u65F6\u65E0\u6CD5\u7EE7\u7EED\uFF0C\u8BF7\u91CD\u8BD5\u786E\u8BA4\u3002":"Unable to continue. Please try confirming again."}),O(a.onError,N)}})},P=async d=>{let y=s.document.funnel.nodes.find(D=>D.id===c?.nodeId);if(!y)return;if((y.type==="auth"||y.type==="purchase"&&!a.client.isAuthenticated())&&d!=="cancel")try{let D=await a.onAuthenticate();if(u)return;D?(s=(await a.client.authenticate(D)).run,e+=1,f.updateCapabilities(s.capabilities)):d="cancel"}catch(D){d="failure",O(a.onError,D)}if(u)return;let N=y.id+":"+d,L=l.get(N);L||(L=crypto.randomUUID(),l.set(N,L));let C=await a.client.node(y.id,d,L);if(u)return;C.target&&g(y.id),s=C.run,e+=1,f.updateCapabilities(s.capabilities),C.checkout&&O(a.onCheckout,C.checkout);let V=C.price?j(C.price.amountCents,C.price.currency,s.locale)+(C.price.interval==="month"?s.locale.startsWith("zh")?" / \u6708":" / month":C.price.interval==="year"?s.locale.startsWith("zh")?" / \u5E74":" / year":""):"";f.resolveFunnel({target:C.target,label:C.pending?C.trialTerms??`${V} ${s.locale.startsWith("zh")?"\u7B49\u5F85\u670D\u52A1\u7AEF\u786E\u8BA4\uFF1B\u4ED8\u6B3E\u540E\u70B9\u51FB\u7EE7\u7EED\u786E\u8BA4\u3002":"Waiting for server confirmation. After payment, confirm to continue."}`:void 0,checkoutUrl:C.checkout?.url})};if(s.status!=="running")return b(),{destroy(){},async close(){},snapshot:()=>s};let{mountScreenPreview:A}=await import("./popup.js");f=A(i,{mode:"live",rendererUrl:a.client.webViewUrl,onCustomerDataIntent:d=>{I?.intent(d).catch(y=>O(a.onError,y))},onFunnelState(d){let y=d.history.length<m.length;m=d.history,c=d,d.status!=="completed"&&p(d);let N=`${d.status}:${d.nodeId}`,L=w!==N;w=N,E(async()=>{let C=K(s.document,s.nodeId,d.answers);if(Object.entries(C).some(([T,F])=>JSON.stringify(s.answers[T])!==JSON.stringify(F))){let T=await a.client.saveAnswers({nodeId:s.nodeId,requestId:crypto.randomUUID(),revision:s.answersRevision,answers:C});if(u)return;s=T.run,e+=1}if(!L)return;let V={eventId:crypto.randomUUID(),nodeId:d.nodeId,type:"enter",back:y},D;try{try{D=await a.client.track(V)}catch(T){if(!(T instanceof r)||T.status!==503)throw T;await new Promise(F=>setTimeout(F,1e3)),D=await a.client.track(V)}}catch(T){if(!(T instanceof r)||!["NETWORK_ERROR","TIMEOUT"].includes(T.code)||(D=await a.client.get(),D.run?.status!=="running"||D.run.nodeId!==d.nodeId))throw T;O(a.onError,T)}if(!u&&(s=D.run,e+=1,f.updateCapabilities(s.capabilities),d.status==="waiting"&&await P("begin"),d.status==="completed")){let T=await a.client.track({eventId:crypto.randomUUID(),nodeId:d.nodeId,type:"complete"});if(u)return;s=T.run,e+=1,b(),p(d)}})},onFunnelIntent(d){E(()=>P(d))},onError(d){O(a.onError,new Error(d))}});let _=s.document.pages.find(d=>d.id===s.nodeId),k=a.resume?.versionId===s.versionId&&a.resume.state.nodeId===s.nodeId?{...a.resume.state,answers:s.answers}:{status:_?"running":"waiting",nodeId:s.nodeId,pageId:_?.id??null,history:s.history,answers:s.answers};f.update(s.document,s.locale,{resume:k,capabilities:s.capabilities,parameters:s.parameters});try{await f.ready}catch(d){throw u=!0,f.destroy(),d}v=M.get(a.client)?.subscribe(()=>{let d=++S;s={...s,capabilities:{nodes:{},plans:{},pickers:{},diagnostics:[]}},f.updateCapabilities(s.capabilities),n();let y=e;a.client.get().then(N=>{u||d!==S||y!==e||(s=N.run,e+=1,f.updateCapabilities(s.capabilities))}).catch(N=>{!u&&d===S&&!(N instanceof r&&["IDENTITY_CHANGED","NOT_IDENTIFIED"].includes(N.code))&&O(a.onError,N)})}),a.customerClient&&n();let R;return{snapshot:()=>s,destroy(){u=!0,I?.destroy(),v?.(),f.destroy()},close(){if(R)return R;if(u)return Promise.resolve();let d=c?.nodeId??s.nodeId;return u=!0,I?.destroy(),v?.(),f.destroy(),R=a.client.track({eventId:crypto.randomUUID(),nodeId:d,type:"close"}).then(()=>{}),R}}}function _e(i){let a=q(i),s=i.locale,u=i.currency,o=a.request,w=te(),c=0;async function m(e,t,n,p){let b=c,E=w.candidate(e);try{let P=await o(t,{...n,...E?{cachedContentTag:E.identity.contentTag}:{}});if(b!==c)throw new r("IDENTITY_CHANGED","Customer identity changed while reading surface content");return p(P,E)}catch(P){throw b===c&&P instanceof r&&(P.status===401||P.status===403||["NOT_IDENTIFIED","SCOPE_MISMATCH","INVALID_RESPONSE"].includes(P.code))&&w.clear(),P}}let l=new Map,g=new Set,f=e=>{for(let t of g)try{t(e)}catch{}},I=()=>{for(let e of l.values())e.invalidate()};async function v(e={}){let t=h.getCustomerState,n=t.request.omit({customerId:!0,entityId:!0}).safeParse(e);if(!n.success)throw new r("INVALID_REQUEST","Invalid customer state request");let p=t.response.safeParse(await o(t.path,n.data));if(!p.success)throw new r("INVALID_RESPONSE","Invalid customer state response");let b={memberships:"membership",entitlements:"features",credits:"resources"};if(n.data.include.some(E=>!Object.hasOwn(p.data.state,b[E])))throw new r("INVALID_RESPONSE","Customer state omitted a requested section");return p.data}if(i.nativeCommerce&&!i.scope)throw new r("INVALID_SCOPE","Native purchases require an explicit App and environment");let S=i.nativeCommerce&&i.scope?G({scope:i.scope,host:i.nativeCommerce.host,pending:i.nativeCommerce.pending,tickets:x(i),prepare:async(e,t)=>{let n=await o("purchases/intents",{protocolVersion:1,bindingId:e,idempotencyKey:t});if(!n||typeof n!="object"||!("intent"in n))throw new r("INVALID_RESPONSE","Invalid purchase intent response");return n.intent}}):null;return{purchases:S,get webViewUrl(){return a.webViewUrl()},subscribeIdentity(e){return g.add(e),()=>{g.delete(e)}},async getPage(e){let t=h.getPage,n=t.request.omit({entityId:!0,cachedContentTag:!0}).safeParse({...e,locale:e.locale??s});if(!n.success)throw new r("INVALID_REQUEST","Invalid Page request");let p=JSON.stringify(["page",n.data.pageId,n.data.locale]);return m(p,t.path,n.data,(b,E)=>{let P=t.response.safeParse(b);if(!P.success||P.data.pageId!==n.data.pageId)throw new r("INVALID_RESPONSE","Invalid published Page response");let{contentTag:A,document:_,...k}=P.data,R=w.hydrate(p,{scope:k.scope,campaignId:k.pageId,versionId:k.versionId,locale:k.locale,contentTag:A},_,E);if(R.surface!=="page")throw new r("INVALID_RESPONSE","Invalid published Page surface");return{...k,document:R}})},async listOfferHistory(e={}){let t=h.listOfferHistory,n=t.request.safeParse(e);if(!n.success||n.data.customerId||n.data.entityId)throw new r("INVALID_REQUEST","Invalid offer history request");let p=t.response.safeParse(await o(t.path,n.data));if(!p.success)throw new r("INVALID_RESPONSE","Invalid offer history response");return p.data},getCustomerState:v,createCustomerStateStore(e={}){let t=h.getCustomerState.request.omit({customerId:!0,entityId:!0}).safeParse(e);if(!t.success)throw new r("INVALID_REQUEST","Invalid customer state request");t.data.include.sort();let n=JSON.stringify(t.data),p=l.get(n);return p||(p=ee(async()=>(await v(t.data)).state),l.set(n,p)),p.store},async listCustomerPlans(e={}){let t=h.listCustomerPlans,n=t.request.omit({customerId:!0,entityId:!0}).safeParse({...e,currency:e.currency??u});if(!n.success)throw new r("INVALID_REQUEST","Invalid customer plan request");let p=t.response.safeParse(await o(t.path,n.data));if(!p.success)throw new r("INVALID_RESPONSE","Invalid customer plan response");return p.data},identify(e){if(e.startsWith("gg_sk_"))throw new r("INVALID_TOKEN","Secret API keys must not be used in the browser SDK");a.identify(e),c++,w.clear(),S?.identityChanged();for(let t of l.values())t.clear();f(!0)},reset(){S?.identityChanged(),a.reset(),c++,w.clear();for(let e of l.values())e.clear();f(!1)},async listCreditPacks(e={}){let t=h.listCreditPacks,n=t.request.safeParse(e);if(!n.success)throw new r("INVALID_REQUEST","Invalid credit pack request");let p=t.response.safeParse(await o(t.path,n.data));if(!p.success)throw new r("INVALID_RESPONSE","Invalid credit pack response");return p.data},async listCreditPackOrders(e={}){let t=h.listCreditPackOrders,n=t.request.safeParse(e);if(!n.success)throw new r("INVALID_REQUEST","Invalid credit pack request");let p=t.response.safeParse(await o(t.path,n.data));if(!p.success)throw new r("INVALID_RESPONSE","Invalid credit pack response");return p.data},async createCreditPackCheckout(e){let t=h.createCreditPackCheckout,n=t.request.safeParse(e);if(!n.success)throw new r("INVALID_REQUEST","Invalid credit pack request");let p=t.response.safeParse(await o(t.path,n.data));if(!p.success)throw new r("INVALID_RESPONSE","Invalid credit pack response");return p.data},async listCreditTransactions(e={}){let t=h.listCreditTransactions,n=t.request.safeParse(e);if(!n.success)throw new r("INVALID_REQUEST","Invalid history cursor");let p=t.response.safeParse(await o(t.path,n.data));if(!p.success)throw new r("INVALID_RESPONSE","Invalid credit history");return p.data},async listCreditBalances(e={}){let t=h.listCreditBalances,n=t.request.omit({customerId:!0,entityId:!0}).safeParse(e);if(!n.success)throw new r("INVALID_REQUEST","Invalid balance page");let p=t.response.safeParse(await o(t.path,n.data));if(!p.success)throw new r("INVALID_RESPONSE","Invalid balance page response");return p.data},async getBalances(){let e=h.getBalances.response.safeParse(await o("credits/balances",{}));if(!e.success)throw new r("INVALID_RESPONSE","Invalid credit balances");return e.data.account},async checkCredits(e){let t=h.checkCredits.request.safeParse(e);if(!t.success)throw new r("INVALID_REQUEST","Invalid credit check");let n=h.checkCredits.response.safeParse(await o("credits/check",t.data));if(!n.success)throw new r("INVALID_RESPONSE","Invalid credit check response");return n.data},async refreshSurface(e){let t=h.refreshSurface.request.safeParse({...e,currency:e.currency??u});if(!t.success)throw new r("INVALID_REQUEST","Invalid surface context request");let n=h.refreshSurface.response.safeParse(await o("surfaces/context",t.data));if(!n.success)throw new r("INVALID_RESPONSE","Invalid surface context response");return n.data.capabilities},async purchaseSurface(e){let t=h.purchaseSurface.request.safeParse({...e,currency:e.currency??u});if(!t.success)throw new r("INVALID_REQUEST","Invalid surface checkout input");let n=h.purchaseSurface.response.safeParse(await o("surfaces/purchase",t.data));if(!n.success)throw new r("INVALID_RESPONSE","Invalid surface checkout response");return n.data},async createCheckout(e,t={}){if(t===null||typeof t!="object"||Array.isArray(t))throw new r("INVALID_REQUEST","Checkout options must be an object");let n=h.createCheckout.request.safeParse({...t,currency:t.currency??u,planVersionId:e,requestId:t.requestId??crypto.randomUUID(),...t.offerId?{offerId:t.offerId}:{},...t.promotionCode?{promotionCode:t.promotionCode}:{}});if(!n.success)throw new r("INVALID_REQUEST","Invalid checkout request");let p=h.createCheckout.response.safeParse(await o("billing/checkout",n.data));if(!p.success)throw new r("INVALID_RESPONSE","Invalid checkout response");return p.data},async getMemberships(){let e=h.getMemberships.response.safeParse(await o("memberships",{},"GET"));if(!e.success)throw new r("INVALID_RESPONSE","Invalid membership response");return e.data.membership},async previewMembership(e){let t=h.previewMembership.request.safeParse(e);if(!t.success)throw new r("INVALID_REQUEST","Invalid membership preview");let n=h.previewMembership.response.safeParse(await o("memberships/preview",t.data));if(!n.success)throw new r("INVALID_RESPONSE","Invalid membership preview response");return n.data.preview},async manageMembership(e){let t=h.manageMembership.request.safeParse(e);if(!t.success)throw new r("INVALID_REQUEST","Invalid membership change");let n=h.manageMembership.response.safeParse(await o("memberships/manage",t.data));if(!n.success)throw new r("INVALID_RESPONSE","Invalid membership change response");return I(),n.data},async getTrialEligibility(e){let t=h.getTrialEligibility.request.safeParse({planVersionId:e});if(!t.success)throw new r("INVALID_REQUEST","Invalid trial plan");let n=h.getTrialEligibility.response.safeParse(await o("memberships/trial/eligibility",t.data));if(!n.success)throw new r("INVALID_RESPONSE","Invalid trial eligibility response");return n.data.eligibility},async startTrial(e){let t=h.startTrial.request.safeParse(e);if(!t.success)throw new r("INVALID_REQUEST","Invalid trial request");let n=h.startTrial.response.safeParse(await o("memberships/trial",t.data));if(!n.success)throw new r("INVALID_RESPONSE","Invalid trial response");return I(),n.data},async getSubscriptions(){let e=h.listSubscriptions.response.safeParse(await o("billing/subscriptions",{},"GET"));if(!e.success)throw new r("INVALID_RESPONSE","Invalid subscriptions response");return e.data.subscriptions},async getPopup(e,t={}){let n=typeof navigator>"u"?void 0:[...new Set([...navigator.languages??[],navigator.language])].filter(E=>typeof E=="string"&&E.length<=35).slice(0,10),p=h.resolvePopup.request.safeParse({trigger:e,requestId:t.requestId??crypto.randomUUID(),locale:t.locale??s,currency:t.currency??u,acceptLanguages:n});if(!p.success)throw new r("INVALID_REQUEST","Invalid popup trigger or request ID");let b=JSON.stringify(["popup",p.data.trigger,p.data.locale,p.data.acceptLanguages]);return m(b,"popups/resolve",p.data,(E,P)=>{let A=h.resolvePopup.response.safeParse(E);if(!A.success)throw new r("INVALID_RESPONSE","Invalid popup response");let _=A.data.delivery;if(!_)return null;let{contentTag:k,popup:R,...d}=_,y=w.hydrate(b,{scope:A.data.scope,campaignId:d.campaignId,versionId:d.versionId,locale:d.locale,contentTag:k},R,P);return $.parse({...d,popup:y})})},async trackPopup(e){let t=h.trackPopup.request.safeParse(e);if(!t.success)throw new r("INVALID_EVENT","Invalid popup event");if(!h.trackPopup.response.safeParse(await o("popups/events",t.data)).success)throw new r("INVALID_RESPONSE","Invalid event acknowledgement")},async listPlans(){let e=B.safeParse(await o("plans",{},"GET"));if(!e.success)throw new r("INVALID_RESPONSE","Invalid plans response");return e.data},async getEntitlements(){let e=W.safeParse(await o("entitlements",{}));if(!e.success)throw new r("INVALID_RESPONSE","Invalid entitlements response");return e.data},async listOffers(){let e=h.listOffers.response.safeParse(await o("offers",{},"GET"));if(!e.success)throw new r("INVALID_RESPONSE","Invalid offers response");return e.data.offers},async claimOffer(e){let t=h.claimOffer.request.safeParse({...e,requestId:e.requestId??crypto.randomUUID()});if(!t.success)throw new r("INVALID_REQUEST","Invalid offer claim");let n=h.claimOffer.response.safeParse(await o("offers/claim",t.data));if(!n.success)throw new r("INVALID_RESPONSE","Invalid offer response");return{offer:n.data.offer,reason:n.data.reason}}}}export{r as GrooveError,oe as createFunnelClient,_e as createGroove,G as createPurchaseHostClient,x as createPurchaseTicketTransport,se as formatCouponDiscount,re as formatCouponMoney,ne as formatCouponTerms,ie as showFunnel};
package/dist/popup.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { S as ScreenNode, a as ScreenDocument, b as SurfaceData, C as Currency } from './transport-DrW-__2k.js';
2
- import { C as CustomerPageData, F as FunnelState, a as CustomerPageClient, c as createGroove, b as createCustomerPageController, d as CustomerDataIntent, P as PopupEvent } from './index-VzF48VxI.js';
3
- export { e as CustomerPageController, f as formatCustomerDecimal } from './index-VzF48VxI.js';
1
+ import { S as ScreenNode, a as ScreenDocument, b as SurfaceData, C as Currency } from './transport-CPPD6uzW.js';
2
+ import { C as CustomerPageData, F as FunnelState, a as CustomerPageClient, c as createGroove, b as createCustomerPageController, d as CustomerDataIntent, P as PopupEvent } from './index-CbW7E8PR.js';
3
+ export { e as CustomerPageController, f as formatCustomerDecimal } from './index-CbW7E8PR.js';
4
4
  import { WindowLike } from 'dompurify';
5
5
  import 'zod';
6
6
 
@@ -65,7 +65,7 @@ type PopupHandle = {
65
65
  updateCapabilities: (data: SurfaceData) => void;
66
66
  };
67
67
  /** Explicit host trigger; delivery and telemetry failures stay outside host callbacks. */
68
- declare function showRemotePopup(client: Pick<ReturnType<typeof createGroove>, "getPopup" | "trackPopup" | "claimOffer"> & Partial<Pick<ReturnType<typeof createGroove>, "purchaseSurface" | "refreshSurface">> & {
68
+ declare function showRemotePopup(client: Pick<ReturnType<typeof createGroove>, "getPopup" | "trackPopup" | "claimOffer"> & Partial<Pick<ReturnType<typeof createGroove>, "purchaseSurface" | "refreshSurface" | "subscribeIdentity">> & {
69
69
  readonly webViewUrl?: string;
70
70
  }, trigger: string, options?: {
71
71
  requestId?: string;
@@ -104,10 +104,12 @@ type ScreenPreviewHandle = {
104
104
  options?: {
105
105
  startPageId?: string;
106
106
  resume?: FunnelState;
107
+ parameters?: Record<string, string>;
107
108
  capabilities?: SurfaceData;
108
109
  customerData?: CustomerPageData;
109
110
  }): void;
110
111
  updateCustomerData(data: CustomerPageData): void;
112
+ updateCapabilities(data: SurfaceData): void;
111
113
  /** 编辑模式下的悬停与选中描边。 */
112
114
  highlight(hoverId: string | null, selectedId: string | null): void;
113
115
  resolveFunnel(result: {