@uninspired/auth-client 1.0.20 → 2.0.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/README.md +124 -23
- package/dist/cookie-banner.d.ts +12 -0
- package/dist/cookie-banner.js +2 -0
- package/dist/cookie-banner.js.map +1 -0
- package/dist/index.d.ts +1875 -45
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/purgeLegacyTracking-C4nrnU7N.js +2 -0
- package/dist/purgeLegacyTracking-C4nrnU7N.js.map +1 -0
- package/package.json +27 -3
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{anonymousClient as e,emailOTPClient as t,magicLinkClient as n}from"better-auth/client/plugins";import{passkeyClient as r}from"@better-auth/passkey/client";import{createAuthClient as i}from"better-auth/client";import{hc as a}from"hono/client";import{z as o}from"zod";import{createContext as s,useCallback as c,useContext as l,useEffect as u,useMemo as d,useRef as f}from"react";import{QueryClient as p,useQuery as m}from"@tanstack/react-query";import{usePostHog as h}from"@posthog/react";import{jsx as g}from"react/jsx-runtime";const _=o.object({id:o.string(),createdAt:o.coerce.date(),status:o.string(),items:o.array(o.object({priceId:o.string(),productId:o.string()}))}),v=o.object({id:o.string(),createdAt:o.coerce.date(),adjustments:o.array(o.object({id:o.string(),createdAt:o.coerce.date(),action:o.enum([`credit`,`refund`,`chargeback`,`chargeback_reverse`,`chargeback_warning`,`chargeback_warning_reverse`,`credit_reverse`]),type:o.enum([`full`,`partial`]),status:o.enum([`pending_approval`,`approved`,`rejected`,`reversed`])})),items:o.array(o.string())}),y=o.object({id:o.string(),customerId:o.string(),created:o.coerce.date(),status:o.enum([`active`,`trialing`,`canceled`,`past_due`,`paused`,`incomplete`,`incomplete_expired`,`unpaid`]),items:o.array(o.string())}),b=o.array(y),x=o.object({customerId:o.string().optional(),subscriptions:o.array(_),transactions:o.array(v)});o.object({stripe:b,paddle:x});const S=o.object({type:o.literal(`checkout`),priceId:o.string(),additionalPriceIds:o.array(o.string()).optional(),productId:o.string().optional(),discountCode:o.string().optional(),loginUrl:o.string().refine(e=>{let t=decodeURIComponent(e);return o.url().safeParse(t).success}).transform(e=>decodeURIComponent(e)).optional(),pricingUrl:o.string().refine(e=>{let t=decodeURIComponent(e);return o.url().safeParse(t).success}).transform(e=>decodeURIComponent(e)).optional(),successUrl:o.string().refine(e=>{let t=decodeURIComponent(e);return o.url().safeParse(t).success}).transform(e=>decodeURIComponent(e)).optional()}),C=o.object({type:o.literal(`redirect`),redirectUrl:o.url(),appName:o.string().optional()}),w=o.object({type:o.literal(`auth`),returnUrl:o.string()}),T=o.discriminatedUnion(`type`,[S,C,w]);o.object({intent:T.optional()}),o.object({priceId:o.string(),additionalPriceIds:o.array(o.string()).optional(),productId:o.string(),quantity:o.coerce.number().int().min(1).max(999).optional(),discountCode:o.string().optional(),loginUrl:o.string().refine(e=>{let t=decodeURIComponent(e);return o.url().safeParse(t).success}).transform(e=>decodeURIComponent(e)).optional(),pricingUrl:o.string().refine(e=>{let t=decodeURIComponent(e);return o.url().safeParse(t).success}).transform(e=>decodeURIComponent(e)).optional(),successUrl:o.string().refine(e=>{let t=decodeURIComponent(e);return o.url().safeParse(t).success}).transform(e=>decodeURIComponent(e)).optional(),fbclid:o.string().optional()}),o.enum([`missing_purchases`,`invalid_redirect_hosts`,`already_owned`,`invalid_prices`,`invalid_discount`,`internal_server_error`]),o.object({slug:o.string().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),productId:o.string().min(1),discountPercent:o.number().int().min(1).max(100),startsAt:o.coerce.date(),endsAt:o.coerce.date()}).extend({id:o.string().min(1)}),o.object({id:o.string().min(1)}),o.object({id:o.string(),slug:o.string(),productId:o.string(),discountPercent:o.number(),startsAt:o.coerce.date(),endsAt:o.coerce.date(),shortLinkUrl:o.string(),promoPageUrl:o.string(),createdAt:o.coerce.date()});const E=o.object({currencyCode:o.string(),originalAmount:o.string(),originalFormatted:o.string()}),D=o.object({id:o.string(),name:o.string().nullable(),description:o.string().nullable(),customData:o.custom(e=>e===null||typeof e==`object`).nullable(),billingCycle:o.object({interval:o.enum([`day`,`week`,`month`,`year`]),frequency:o.number()}).nullable(),unitPrice:o.object({amount:o.string(),currencyCode:o.string()}).nullable(),unitPriceOverrides:o.array(o.object({countryCodes:o.array(o.string()),unitPrice:o.object({amount:o.string(),currencyCode:o.string()})})).nullable(),owned:o.boolean(),preview:E.optional()});o.object({slug:o.string(),productId:o.string(),productName:o.string(),productDescription:o.string().nullable(),discountPercent:o.number(),isActive:o.boolean(),alreadyRedeemed:o.boolean(),prices:o.array(D)}),o.object({discountCode:o.string(),checkoutUrl:o.string()}),o.object({slug:o.string().min(1),priceId:o.string().min(1)}),o.object({productId:o.string(),productName:o.string(),productDescription:o.string().nullable(),discountPercent:o.number(),valid:o.boolean(),prices:o.array(D)}),o.object({productId:o.string().min(1),priceId:o.string().min(1),ref:o.string().min(1)}),o.object({discountCode:o.string(),checkoutUrl:o.string()}),o.enum([`ViewContent`,`InitiateCheckout`,`Purchase`]);const O=o.enum([`ViewContent`,`InitiateCheckout`]);o.object({event_name:O,content_ids:o.array(o.string()).optional(),content_type:o.string().optional(),event_source_url:o.string().url().optional(),value:o.number().optional(),currency:o.string().optional(),event_id:o.string().optional()});function k(e){if(!e)return{};let t={};for(let n of e.split(`;`)){let e=n.trim();if(!e)continue;let r=e.indexOf(`=`);if(r===-1)continue;let i=e.slice(0,r),a=e.slice(r+1);t[i]=decodeURIComponent(a)}return{fbc:t._fbc,fbp:t._fbp}}function A(e,t=Date.now()){return`fb.1.${t}.${e}`}const j=`_fbc`,M=`_fbp`;function N(){return Math.floor(Math.random()*1e10).toString()}function P(e){let t=new URL(e).hostname;if(!(t===`localhost`||t===`127.0.0.1`))return`.${t}`}function F(e){if(typeof document>`u`)return;let t=document.cookie.split(`;`).map(e=>e.trim()).find(t=>t.startsWith(`${e}=`));if(t)return decodeURIComponent(t.slice(e.length+1))}function I(e,t,n){if(typeof document>`u`)return;let r=P(n),i=[`${e}=${encodeURIComponent(t)}`,`Path=/`,`Secure`,`SameSite=Lax`,`Max-Age=7776000`];r&&i.push(`Domain=${r}`),document.cookie=i.join(`; `)}function L(){return{fbc:F(j),fbp:F(M)}}function R(e){if(typeof window>`u`)return{};let{frontendUrl:t,stripFbclidFromUrl:n=!0}=e,r=new URLSearchParams(window.location.search),i=r.get(`fbclid`);if(i&&(I(j,A(i),t),n)){r.delete(`fbclid`);let e=r.toString(),t=`${window.location.pathname}${e?`?${e}`:``}${window.location.hash}`;window.history.replaceState({},``,t)}let a=F(M);return a||(a=`fb.1.${Date.now()}.${N()}`,I(M,a,t)),L()}var z=class{#e;#t;#n;#r;constructor(o,s,c){this.#r=c,this.#e=s,this.#t=i({baseURL:o,plugins:[e(),n(),t(),r()]}),this.#n=a(new URL(`/api/app`,o).toString(),{fetch:(e,t)=>fetch(e,{...t,credentials:`include`})})}getSession=async()=>{let{data:e,error:t}=await this.#t.getSession({},{headers:this.#r?{Cookie:this.#r}:void 0});if(t)throw t;return e};signInAnonymously=async()=>{let{error:e}=await this.#t.signIn.anonymous();if(e)throw e;return this.getSession()};signOut=async e=>{let{error:t}=await this.#t.signOut({fetchOptions:{onSuccess:e}},{headers:this.#r?{Cookie:this.#r}:void 0});if(t)throw t};getPurchases=async()=>{let e=await this.#n.purchases.$get(void 0,{headers:this.#r?{Cookie:this.#r}:void 0});if(!e.ok)throw Error(`Failed to get purchases`,{cause:await e.text()});return await e.json()};#i=(e,t)=>JSON.stringify({type:`redirect`,redirectUrl:e,appName:t});trackMetaEvent=async e=>{let t=await this.#n.meta.events.$post({json:e});if(!t.ok)throw Error(`Failed to track Meta event`,{cause:await t.text()})};trackViewContent=async e=>{let t=e.eventSourceUrl??(typeof window<`u`?window.location.href:void 0);await this.trackMetaEvent({event_name:`ViewContent`,content_ids:e.contentIds,content_type:e.contentType??`product`,...t?{event_source_url:t}:{}})};getMetaAttribution=()=>L();getLoginUrl=e=>{let t=new URL(`/login`,this.#e);return e?.redirectUrl&&t.searchParams.set(`intent`,this.#i(e.redirectUrl,e.appName)),t.toString()};getCheckoutUrl=e=>{let t=new URL(`/auth/checkout`,this.#e);return t.searchParams.set(`priceId`,e.priceId),t.searchParams.set(`productId`,e.productId),e.discountCode&&t.searchParams.set(`discountCode`,e.discountCode),e.successUrl&&t.searchParams.set(`successUrl`,e.successUrl),t.searchParams.set(`quantity`,e.quantity?.toString()??`1`),t.toString()}};const B=s(null),V=({children:e,baseUrl:t,frontendUrl:n,initialSession:r,initialPurchases:i,authClient:a,queryClient:o})=>{let s=h(),l=d(()=>a??new z(t,n),[t,n,a]),_=d(()=>o??new p,[o]),{data:v,isFetching:y,refetch:b}=m({queryKey:[`us-auth-session`],staleTime:0,initialData:r,queryFn:l.getSession},_),x=d(()=>!(!v||v.user.isAnonymous),[v]),S=f(!1);u(()=>{R({frontendUrl:n})},[n]),u(()=>{y||v===null&&(S.current||(S.current=!0,l.signInAnonymously().then(e=>{_.setQueryData([`us-auth-session`],e)}).catch(e=>console.error(e))))},[l,y,_,v]),u(()=>{v?.user&&s&&s.get_distinct_id()!==v.user.id&&s.identify(v.user.id,{email:v.user.email})},[v,s]);let{data:C,isFetching:w,refetch:T}=m({queryKey:[`us-auth-purchases`],staleTime:1e3*60,initialData:i,queryFn:l.getPurchases},_),E=d(()=>l.getLoginUrl,[l]),D=d(()=>l.getCheckoutUrl,[l]),O=c(e=>l.signOut(()=>{s?.reset(),e?.()}),[l,s]),k=d(()=>l.trackMetaEvent,[l]),A=d(()=>l.trackViewContent,[l]),j=d(()=>l.getMetaAttribution,[l]),M=c(e=>C?C.paddle.transactions.some(t=>t.items.some(t=>e.includes(t))&&!t.adjustments.some(e=>e.status===`approved`&&e.action===`refund`)):!1,[C]),N=c((e,t)=>{if(!C)return!1;let n=C.paddle.subscriptions.some(n=>n.items.some(n=>e.includes(n.priceId)||t===n.productId)&&n.status===`active`),r=C.stripe.some(t=>t.status===`active`&&t.items.some(t=>e.includes(t)));return n||r},[C]);return g(B.Provider,{value:{session:v??null,isSessionFetching:y,refetchSession:async()=>{await b()},purchases:C??null,isPurchasesFetching:w,refetchPurchases:async()=>{await T()},signOut:O,getLoginUrl:E,getCheckoutUrl:D,trackMetaEvent:k,trackViewContent:A,getMetaAttribution:j,isSubscribed:N,isPurchased:M,isLoggedIn:x},children:e})};function H(){let e=l(B);if(!e)throw Error(`useAuth must be used within an AuthProvider`);return e}export{z as AuthClient,B as AuthContext,V as AuthProvider,A as buildFbcFromFbclid,R as captureMetaClickId,P as getMetaCookieDomain,k as parseMetaAttributionFromCookieHeader,L as readMetaAttributionCookies,H as useAuth};
|
|
1
|
+
import{a as e,c as t,d as n,f as r,i,l as a,n as o,o as s,r as c,s as l,t as u,u as d}from"./purgeLegacyTracking-C4nrnU7N.js";import{anonymousClient as f,emailOTPClient as p,magicLinkClient as m}from"better-auth/client/plugins";import{passkeyClient as h}from"@better-auth/passkey/client";import{createAuthClient as g}from"better-auth/client";import{hc as _}from"hono/client";import{createAuthClient as v}from"better-auth/react";import y from"zod";import{createContext as b,useCallback as x,useContext as S,useEffect as C,useMemo as w,useRef as T,useState as E}from"react";import D from"posthog-js";import{jsx as O}from"react/jsx-runtime";import{QueryClient as k,useQuery as A}from"@tanstack/react-query";var j=class{#e;#t;#n;#r;constructor(e,t,n){this.#r=n,this.#e=t,this.#t=g({baseURL:e,plugins:[f(),m(),p(),h()]}),this.#n=_(new URL(`/api/app`,e).toString(),{fetch:(e,t)=>fetch(e,{...t,credentials:`include`})})}getSession=async()=>{let{data:e,error:t}=await this.#t.getSession({},{headers:this.#r?{Cookie:this.#r}:void 0});if(t)throw t;return e};signInAnonymously=async()=>{let{error:e}=await this.#t.signIn.anonymous();if(e)throw e;return this.getSession()};signOut=async e=>{let{error:t}=await this.#t.signOut({fetchOptions:{onSuccess:e}},{headers:this.#r?{Cookie:this.#r}:void 0});if(t)throw t};getPurchases=async()=>{let e=await this.#n.purchases.$get(void 0,{headers:this.#r?{Cookie:this.#r}:void 0});if(!e.ok)throw Error(`Failed to get purchases`,{cause:await e.text()});return await e.json()};#i=(e,t)=>JSON.stringify({type:`redirect`,redirectUrl:e,appName:t});getLoginUrl=e=>{let t=new URL(`/login`,this.#e);return e?.redirectUrl&&t.searchParams.set(`intent`,this.#i(e.redirectUrl,e.appName)),t.toString()};getCheckoutUrl=e=>{let t=new URL(`/auth/checkout`,this.#e);return t.searchParams.set(`priceId`,e.priceId),t.searchParams.set(`productId`,e.productId),e.discountCode&&t.searchParams.set(`discountCode`,e.discountCode),e.successUrl&&t.searchParams.set(`successUrl`,e.successUrl),t.searchParams.set(`quantity`,e.quantity?.toString()??`1`),t.toString()}};function M(e){return v({baseURL:e,plugins:[f(),m(),p(),h()]})}const N=n;function P(e,t){e?.register?.({product:t})}function F(e,t,n){e?.capture(N.FEATURE_USED,{feature_name:t,...n})}function I(e,{plan:t,product:n}){n&&P(e,n),e?.capture(N.CHECKOUT_STARTED,{plan:t,...n?{product:n}:{}})}let L=!1;function R(e){if(typeof window>`u`||L)return;let t=window;if(!t.fbq){let e=((...t)=>{e.callMethod?e.callMethod(...t):e.queue?.push(t)});e.queue=[],e.loaded=!0,e.version=`2.0`,t.fbq=e,t._fbq||=e;let n=document.createElement(`script`);n.async=!0,n.src=`https://connect.facebook.net/en_US/fbevents.js`,document.head.appendChild(n)}t.fbq(`init`,e),t.fbq(`track`,`PageView`),L=!0}function z(){return L}function B(){if(typeof window>`u`)return;let e=window.fbq;e?.(`consent`,`revoke`)}function V(e,t,n){if(typeof window>`u`)return;let r=window.fbq;r&&(n?r(`track`,e,t,{eventID:n}):r(`track`,e,t))}const H=[`$current_url`,`$initial_current_url`,`$referrer`,`$initial_referrer`],ee=[`$pathname`,`$initial_pathname`];function U(e){return e.replace(/^\/s\/[^/]+/,`/s/[redacted]`)}function te(e){if(typeof e!=`string`)return e;try{let t=new URL(e);return t.search=``,t.hash=``,t.pathname=U(t.pathname),t.toString()}catch{return e}}function ne(e){return typeof e==`string`?U(e):e}function W(e){if(!e||!e.properties)return e;let t=e.properties;for(let e of H)e in t&&(t[e]=te(t[e]));for(let e of ee)e in t&&(t[e]=ne(t[e]));return e}function G(e){return e?.analytics?`opt_in`:`opt_out`}const re={defaults:`2026-05-30`,person_profiles:`identified_only`,cookieless_mode:`on_reject`,opt_out_capturing_by_default:!0,consent_persistence_name:`uninspired_ph_consent`,cross_subdomain_cookie:!0,cookie_expiration:180,mask_all_text:!0,mask_all_element_attributes:!0,disable_session_recording:!0,disable_surveys:!0,capture_heatmaps:!1,capture_exceptions:!0,before_send:W};let K=null;function q(e){return typeof window>`u`?null:K||(K=D.init(e.apiKey,{...re,api_host:e.apiHost,...e.uiHost?{ui_host:e.uiHost}:{}}),K)}function J(e,t){e&&(G(t)===`opt_in`?e.opt_in_capturing():e.opt_out_capturing())}var Y=class{ph;product;#e;#t;#n=!1;constructor(e){this.product=e.product,this.#e=e.metaPixelId,c(e.consentCookieDomain),u(),this.ph=e.posthog?q(e.posthog):null,this.ph&&P(this.ph,this.product)}start(){this.#n||(this.#n=!0,this.#t=a(()=>this.#r(i())),this.#r(i()))}stop(){this.#t?.(),this.#t=void 0,this.#n=!1}#r(e){J(this.ph,e),e?.marketing&&this.#e?R(this.#e):z()&&B()}#i(){return i()?.marketing===!0}getConsent(){return i()}setConsent(e){t(e)}capture(e,t){this.ph?.capture(e,t)}captureException(e,t){this.ph?.captureException(e,t)}identify(e){i()?.analytics&&this.ph?.get_distinct_id()!==e&&this.ph?.identify(e)}reset(){this.ph?.reset()}registerProduct(e){P(this.ph,e)}captureFeatureUsed(e,t){F(this.ph,e,t)}captureCheckoutStarted(e){I(this.ph,e)}trackPageView(){this.#i()&&V(`PageView`)}trackViewContent({contentId:e,value:t,currency:n}){this.#i()&&V(`ViewContent`,{content_ids:[e],content_type:`product`,...t===void 0?{}:{value:t},...n?{currency:n}:{}})}trackInitiateCheckout({contentIds:e,value:t,currency:n}={}){this.#i()&&V(`InitiateCheckout`,{...e?.length?{content_ids:e,content_type:`product`}:{},...t===void 0?{}:{value:t},...n?{currency:n}:{}})}trackPurchase({value:e,currency:t,contentIds:n,eventId:r}={}){this.#i()&&V(`Purchase`,{...n?.length?{content_ids:n,content_type:`product`}:{},...e===void 0?{}:{value:e},...t?{currency:t}:{}},r)}};const X=b(null),ie=({children:e,...t})=>{let n=T(null);return n.current||=new Y(t),C(()=>{let e=n.current;return e?.start(),()=>e?.stop()},[]),O(X.Provider,{value:n.current,children:e})};function Z(){return S(X)}const Q=b(null),ae=({children:e,baseUrl:t,frontendUrl:n,product:r,initialSession:i,initialPurchases:a,authClient:s,queryClient:c})=>{let l=w(()=>s??new j(t,n),[t,n,s]),u=w(()=>c??new k,[c]),f=Z(),{consent:p}=o(),m=p?.analytics===!0,{data:h,isFetching:g,status:_,refetch:v}=A({queryKey:[`us-auth-session`],staleTime:0,initialData:i,queryFn:l.getSession},u),y=w(()=>!(!h||h.user.isAnonymous),[h]),b=T(!1),S=x(e=>{f?.registerProduct(e)},[f]),E=x((e,t)=>{f?.captureFeatureUsed(e,t)},[f]),D=x(e=>{f?.captureCheckoutStarted(e)},[f]);C(()=>{r&&f?.registerProduct(r)},[f,r]),C(()=>{!f||!h?.user||h.user.isAnonymous||m&&f.identify(h.user.id)},[f,h,m]),C(()=>{g||_===`success`&&h===null&&(b.current||(b.current=!0,l.signInAnonymously().then(e=>{u.setQueryData([`us-auth-session`],e)}).catch(e=>console.error(e))))},[l,g,u,h,_]);let{data:M,isFetching:N,refetch:P}=A({queryKey:[`us-auth-purchases`],staleTime:1e3*60,initialData:a,queryFn:l.getPurchases},u),F=w(()=>l.getLoginUrl,[l]),I=w(()=>l.getCheckoutUrl,[l]),L=x(e=>l.signOut(()=>{u.setQueryData([`us-auth-session`],null),u.removeQueries({queryKey:[`us-auth-purchases`]}),f?.reset(),e?.()}),[l,u,f]),R=x(e=>M?M.paddle.transactions.some(t=>t.items.some(t=>e.includes(t))&&!d(t.adjustments)):!1,[M]),z=x((e,t)=>{if(!M)return!1;let n=M.paddle.subscriptions.some(n=>n.items.some(n=>e.includes(n.priceId)||t===n.productId)&&n.status===`active`),r=M.stripe.some(t=>t.status===`active`&&t.items.some(t=>e.includes(t)));return n||r},[M]);return O(Q.Provider,{value:{session:h??null,isSessionFetching:g,refetchSession:async()=>{await v()},purchases:M??null,isPurchasesFetching:N,refetchPurchases:async()=>{await P()},signOut:L,getLoginUrl:F,getCheckoutUrl:I,captureFeatureUsed:E,captureCheckoutStarted:D,registerProduct:S,isSubscribed:z,isPurchased:R,isLoggedIn:y},children:e})};function oe(){let e=S(Q);if(!e)throw Error(`useAuth must be used within an AuthProvider`);return e}const se=30;function $(e,t){return Math.max(0,Math.ceil((e-t)/1e3))}function ce(e,t){return t>0?`${e} (${t}s)`:e}const le=y.email(),ue=y.string().min(6).max(6).refine(e=>e.match(/^[0-9]{6}$/));function de({authClient:e,onVerified:t,onSendSuccess:n,onSendError:r,onVerifyError:i,resendCooldownSeconds:a=30}){let[o,s]=E(`email`),[c,l]=E(``),[u,d]=E(``),[f,p]=E(!1),[m,h]=E(!1),[g,_]=E(!1),[v,y]=E(()=>Date.now()+a*1e3),[b,S]=E(()=>Date.now()),C=w(()=>le.safeParse(c).success,[c]),T=w(()=>ue.safeParse(u).success,[u]),D=$(v,b),O=D>0,k=x(()=>{let e=Date.now();S(e),y(e+a*1e3)},[a]),A=x(async()=>{let{error:t}=await e.emailOtp.sendVerificationOtp({email:c,type:`sign-in`});if(t)throw t},[e,c]);return{step:o,email:c,setEmail:l,otp:u,setOtp:d,emailValid:C,otpValid:T,submitting:f,verifying:m,resending:g,remainingSeconds:D,isCoolingDown:O,submitEmail:x(async()=>{if(C){p(!0);try{await A(),n?.(),s(`otp`)}catch(e){r?.(e)}finally{p(!1)}}},[C,A,n,r]),resendOtp:x(async()=>{if(!(g||O)){_(!0);try{await A(),k(),n?.()}catch(e){r?.(e)}finally{_(!1)}}},[g,O,A,k,n,r]),verifyOtp:x(async()=>{if(T){h(!0);try{let{error:n}=await e.signIn.emailOtp({email:c,otp:u});if(n)throw n;await t()}catch(e){i?.(e),h(!1)}}},[T,e,c,u,t,i]),backToEmail:x(()=>{s(`email`),d(``)},[]),setNow:S,availableAt:v}}export{N as ANALYTICS_EVENTS,j as AuthClient,Q as AuthContext,ae as AuthProvider,se as RESEND_COOLDOWN_SECONDS,Y as TrackingClient,ie as TrackingProvider,I as captureCheckoutStarted,F as captureFeatureUsed,c as configureConsentDomain,M as createBetterAuthClient,i as getConsent,q as getOrInitPostHog,r as isAnalyticsProduct,e as isConsentPending,z as isMetaPixelLoaded,R as loadMetaPixel,G as posthogConsentAction,W as redactBeforeSend,s as refreshConsent,P as registerProduct,$ as remainingCooldownSeconds,ce as resendButtonLabel,l as resolveConsentCookieDomain,B as revokeMetaPixelConsent,t as setConsent,a as subscribeConsent,J as syncPostHogConsent,V as trackMetaPixel,oe as useAuth,de as useEmailOtpLoginFlow,Z as useTracking,o as useTrackingConsent};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["#cookie","#frontendUrl","#authClient","#appClient","#getRedirectIntent"],"sources":["../../types/src/purchases.ts","../../types/src/intent.ts","../../types/src/checkout.ts","../../types/src/promo.ts","../../types/src/affiliate.ts","../../types/src/meta.ts","../src/metaAttribution.ts","../src/AuthClient.ts","../src/react/AuthContext.ts","../src/react/AuthProvider.tsx","../src/react/useAuth.ts"],"sourcesContent":["import { z } from \"zod\";\n\nconst paddleSubscriptionSchema = z.object({\n id: z.string(),\n createdAt: z.coerce.date(),\n status: z.string(),\n items: z.array(\n z.object({\n priceId: z.string(),\n productId: z.string(),\n }),\n ),\n});\n\nexport const paddleTransactionSchema = z.object({\n id: z.string(),\n createdAt: z.coerce.date(),\n adjustments: z.array(\n z.object({\n id: z.string(),\n createdAt: z.coerce.date(),\n action: z.enum([\n \"credit\",\n \"refund\",\n \"chargeback\",\n \"chargeback_reverse\",\n \"chargeback_warning\",\n \"chargeback_warning_reverse\",\n \"credit_reverse\",\n ]),\n type: z.enum([\"full\", \"partial\"]),\n status: z.enum([\"pending_approval\", \"approved\", \"rejected\", \"reversed\"]),\n }),\n ),\n items: z.array(z.string()),\n});\n\nconst stripeSubscriptionSchema = z.object({\n id: z.string(),\n customerId: z.string(),\n created: z.coerce.date(),\n status: z.enum([\n \"active\",\n \"trialing\",\n \"canceled\",\n \"past_due\",\n \"paused\",\n \"incomplete\",\n \"incomplete_expired\",\n \"unpaid\",\n ]),\n items: z.array(z.string()),\n});\n\nexport const stripeDataSchema = z.array(stripeSubscriptionSchema);\n\nexport type StripeData = z.infer<typeof stripeDataSchema>;\n\nexport const paddleDataSchema = z.object({\n customerId: z.string().optional(),\n subscriptions: z.array(paddleSubscriptionSchema),\n transactions: z.array(paddleTransactionSchema),\n});\n\nexport type PaddleData = z.infer<typeof paddleDataSchema>;\n\nexport const userPurchasesSchema = z.object({\n stripe: stripeDataSchema,\n paddle: paddleDataSchema,\n});\n\nexport type UserPurchases = z.infer<typeof userPurchasesSchema>;\n","import { z } from \"zod\";\n\nexport const checkoutIntentSchema = z.object({\n type: z.literal(\"checkout\"),\n priceId: z.string(),\n additionalPriceIds: z.array(z.string()).optional(),\n productId: z.string().optional(),\n discountCode: z.string().optional(),\n loginUrl: z\n .string()\n .refine((v) => {\n const url = decodeURIComponent(v);\n return z.url().safeParse(url).success;\n })\n .transform((v) => decodeURIComponent(v))\n .optional(),\n pricingUrl: z\n .string()\n .refine((v) => {\n const url = decodeURIComponent(v);\n return z.url().safeParse(url).success;\n })\n .transform((v) => decodeURIComponent(v))\n .optional(),\n successUrl: z\n .string()\n .refine((v) => {\n const url = decodeURIComponent(v);\n return z.url().safeParse(url).success;\n })\n .transform((v) => decodeURIComponent(v))\n .optional(),\n});\nexport type CheckoutIntent = z.infer<typeof checkoutIntentSchema>;\n\nexport const redirectIntentSchema = z.object({\n type: z.literal(\"redirect\"),\n redirectUrl: z.url(),\n appName: z.string().optional(),\n});\nexport type RedirectIntent = z.infer<typeof redirectIntentSchema>;\n\nexport const authRouteIntentSchema = z.object({\n type: z.literal(\"auth\"),\n returnUrl: z.string(),\n});\nexport type AuthRouteIntent = z.infer<typeof authRouteIntentSchema>;\n\nexport const intentSchema = z.discriminatedUnion(\"type\", [\n checkoutIntentSchema,\n redirectIntentSchema,\n authRouteIntentSchema,\n]);\nexport type Intent = z.infer<typeof intentSchema>;\n\nexport const intentSearchSchema = z.object({\n intent: intentSchema.optional(),\n});\n","import { z } from \"zod\";\n\nexport const checkoutSearchSchema = z.object({\n priceId: z.string(),\n additionalPriceIds: z.array(z.string()).optional(),\n productId: z.string(),\n quantity: z.coerce.number().int().min(1).max(999).optional(),\n discountCode: z.string().optional(),\n loginUrl: z\n .string()\n .refine((v) => {\n const url = decodeURIComponent(v);\n return z.url().safeParse(url).success;\n })\n .transform((v) => decodeURIComponent(v))\n .optional(),\n pricingUrl: z\n .string()\n .refine((v) => {\n const url = decodeURIComponent(v);\n return z.url().safeParse(url).success;\n })\n .transform((v) => decodeURIComponent(v))\n .optional(),\n successUrl: z\n .string()\n .refine((v) => {\n const url = decodeURIComponent(v);\n return z.url().safeParse(url).success;\n })\n .transform((v) => decodeURIComponent(v))\n .optional(),\n fbclid: z.string().optional(),\n});\n\nexport type CheckoutSearch = z.infer<typeof checkoutSearchSchema>;\n\nexport const checkoutValidationErrorCodeSchema = z.enum([\n \"missing_purchases\",\n \"invalid_redirect_hosts\",\n \"already_owned\",\n \"invalid_prices\",\n \"invalid_discount\",\n \"internal_server_error\",\n]);\n\nexport type CheckoutValidationErrorCode = z.infer<\n typeof checkoutValidationErrorCodeSchema\n>;\n\nexport type CheckoutValidationError = {\n code: CheckoutValidationErrorCode;\n message: string;\n};\n","import { z } from \"zod\";\nimport type { PaddlePriceCustomData } from \"./catalog\";\n\nexport const createPromoInputSchema = z.object({\n slug: z\n .string()\n .min(1)\n .max(64)\n .regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),\n productId: z.string().min(1),\n discountPercent: z.number().int().min(1).max(100),\n startsAt: z.coerce.date(),\n endsAt: z.coerce.date(),\n});\n\nexport type CreatePromoInput = z.infer<typeof createPromoInputSchema>;\n\nexport const updatePromoInputSchema = createPromoInputSchema.extend({\n id: z.string().min(1),\n});\n\nexport type UpdatePromoInput = z.infer<typeof updatePromoInputSchema>;\n\nexport const deletePromoInputSchema = z.object({\n id: z.string().min(1),\n});\n\nexport type DeletePromoInput = z.infer<typeof deletePromoInputSchema>;\n\nexport const promoListItemSchema = z.object({\n id: z.string(),\n slug: z.string(),\n productId: z.string(),\n discountPercent: z.number(),\n startsAt: z.coerce.date(),\n endsAt: z.coerce.date(),\n shortLinkUrl: z.string(),\n promoPageUrl: z.string(),\n createdAt: z.coerce.date(),\n});\n\nexport type PromoListItem = z.infer<typeof promoListItemSchema>;\n\nexport const promoProductSelectPricePreviewSchema = z.object({\n currencyCode: z.string(),\n originalAmount: z.string(),\n originalFormatted: z.string(),\n});\n\nexport type PromoProductSelectPricePreview = z.infer<\n typeof promoProductSelectPricePreviewSchema\n>;\n\nexport const promoProductSelectPriceSchema = z.object({\n id: z.string(),\n name: z.string().nullable(),\n description: z.string().nullable(),\n customData: z.custom<PaddlePriceCustomData | null>(\n (val) => val === null || typeof val === \"object\",\n ).nullable(),\n billingCycle: z\n .object({\n interval: z.enum([\"day\", \"week\", \"month\", \"year\"]),\n frequency: z.number(),\n })\n .nullable(),\n unitPrice: z\n .object({\n amount: z.string(),\n currencyCode: z.string(),\n })\n .nullable(),\n unitPriceOverrides: z\n .array(\n z.object({\n countryCodes: z.array(z.string()),\n unitPrice: z.object({\n amount: z.string(),\n currencyCode: z.string(),\n }),\n }),\n )\n .nullable(),\n owned: z.boolean(),\n preview: promoProductSelectPricePreviewSchema.optional(),\n});\n\nexport const promoProductSelectSchema = z.object({\n slug: z.string(),\n productId: z.string(),\n productName: z.string(),\n productDescription: z.string().nullable(),\n discountPercent: z.number(),\n isActive: z.boolean(),\n alreadyRedeemed: z.boolean(),\n prices: z.array(promoProductSelectPriceSchema),\n});\n\nexport type PromoProductSelect = z.infer<typeof promoProductSelectSchema>;\n\nexport const createPromoCheckoutDiscountResponseSchema = z.object({\n discountCode: z.string(),\n checkoutUrl: z.string(),\n});\n\nexport type CreatePromoCheckoutDiscountResponse = z.infer<\n typeof createPromoCheckoutDiscountResponseSchema\n>;\n\nexport const createPromoCheckoutDiscountInputSchema = z.object({\n slug: z.string().min(1),\n priceId: z.string().min(1),\n});\n","import { z } from \"zod\";\nimport { promoProductSelectPriceSchema } from \"./promo\";\n\nexport const affiliateProductSelectSchema = z.object({\n productId: z.string(),\n productName: z.string(),\n productDescription: z.string().nullable(),\n discountPercent: z.number(),\n valid: z.boolean(),\n prices: z.array(promoProductSelectPriceSchema),\n});\n\nexport type AffiliateProductSelect = z.infer<typeof affiliateProductSelectSchema>;\n\nexport const createAffiliateCheckoutDiscountInputSchema = z.object({\n productId: z.string().min(1),\n priceId: z.string().min(1),\n ref: z.string().min(1),\n});\n\nexport type CreateAffiliateCheckoutDiscountInput = z.infer<\n typeof createAffiliateCheckoutDiscountInputSchema\n>;\n\nexport const createAffiliateCheckoutDiscountResponseSchema = z.object({\n discountCode: z.string(),\n checkoutUrl: z.string(),\n});\n\nexport type CreateAffiliateCheckoutDiscountResponse = z.infer<\n typeof createAffiliateCheckoutDiscountResponseSchema\n>;\n","import { z } from \"zod\";\n\nexport const metaEventNameSchema = z.enum([\n \"ViewContent\",\n \"InitiateCheckout\",\n \"Purchase\",\n]);\n\nexport type MetaEventName = z.infer<typeof metaEventNameSchema>;\n\n/** Client-callable events (Purchase is server/webhook-only). */\nexport const metaTrackEventNameSchema = z.enum([\n \"ViewContent\",\n \"InitiateCheckout\",\n]);\n\nexport type MetaTrackEventName = z.infer<typeof metaTrackEventNameSchema>;\n\nexport const metaTrackEventSchema = z.object({\n event_name: metaTrackEventNameSchema,\n content_ids: z.array(z.string()).optional(),\n content_type: z.string().optional(),\n event_source_url: z.string().url().optional(),\n value: z.number().optional(),\n currency: z.string().optional(),\n event_id: z.string().optional(),\n});\n\nexport type MetaTrackEventInput = z.infer<typeof metaTrackEventSchema>;\n\nexport type MetaAttributionCookies = {\n fbc?: string;\n fbp?: string;\n};\n\nexport function parseMetaAttributionFromCookieHeader(\n cookieHeader: string | undefined,\n): MetaAttributionCookies {\n if (!cookieHeader) return {};\n const cookies: Record<string, string> = {};\n for (const part of cookieHeader.split(\";\")) {\n const trimmed = part.trim();\n if (!trimmed) continue;\n const separator = trimmed.indexOf(\"=\");\n if (separator === -1) continue;\n const key = trimmed.slice(0, separator);\n const value = trimmed.slice(separator + 1);\n cookies[key] = decodeURIComponent(value);\n }\n return {\n fbc: cookies._fbc,\n fbp: cookies._fbp,\n };\n}\n\nexport function buildFbcFromFbclid(\n fbclid: string,\n seenAtMs = Date.now(),\n): string {\n return `fb.1.${seenAtMs}.${fbclid}`;\n}\n","const FBC_COOKIE = \"_fbc\";\nconst FBP_COOKIE = \"_fbp\";\nconst COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 90;\n\nexport type { MetaAttributionCookies } from \"@us-auth/types\";\nexport {\n buildFbcFromFbclid,\n parseMetaAttributionFromCookieHeader,\n} from \"@us-auth/types\";\nimport type { MetaAttributionCookies } from \"@us-auth/types\";\nimport { buildFbcFromFbclid } from \"@us-auth/types\";\n\nfunction randomId(): string {\n return Math.floor(Math.random() * 1e10).toString();\n}\n\nexport function getMetaCookieDomain(frontendUrl: string): string | undefined {\n const hostname = new URL(frontendUrl).hostname;\n if (hostname === \"localhost\" || hostname === \"127.0.0.1\") {\n return undefined;\n }\n return `.${hostname}`;\n}\n\nfunction readCookie(name: string): string | undefined {\n if (typeof document === \"undefined\") return undefined;\n const match = document.cookie\n .split(\";\")\n .map((part) => part.trim())\n .find((part) => part.startsWith(`${name}=`));\n if (!match) return undefined;\n return decodeURIComponent(match.slice(name.length + 1));\n}\n\nfunction writeCookie(\n name: string,\n value: string,\n frontendUrl: string,\n): void {\n if (typeof document === \"undefined\") return;\n const domain = getMetaCookieDomain(frontendUrl);\n const parts = [\n `${name}=${encodeURIComponent(value)}`,\n \"Path=/\",\n \"Secure\",\n \"SameSite=Lax\",\n `Max-Age=${COOKIE_MAX_AGE_SECONDS}`,\n ];\n if (domain) {\n parts.push(`Domain=${domain}`);\n }\n document.cookie = parts.join(\"; \");\n}\n\nexport function readMetaAttributionCookies(): MetaAttributionCookies {\n return {\n fbc: readCookie(FBC_COOKIE),\n fbp: readCookie(FBP_COOKIE),\n };\n}\n\nexport function captureMetaClickId(options: {\n frontendUrl: string;\n stripFbclidFromUrl?: boolean;\n}): MetaAttributionCookies {\n if (typeof window === \"undefined\") {\n return {};\n }\n\n const { frontendUrl, stripFbclidFromUrl = true } = options;\n const params = new URLSearchParams(window.location.search);\n const fbclid = params.get(\"fbclid\");\n\n if (fbclid) {\n writeCookie(FBC_COOKIE, buildFbcFromFbclid(fbclid), frontendUrl);\n if (stripFbclidFromUrl) {\n params.delete(\"fbclid\");\n const query = params.toString();\n const nextUrl = `${window.location.pathname}${query ? `?${query}` : \"\"}${window.location.hash}`;\n window.history.replaceState({}, \"\", nextUrl);\n }\n }\n\n let fbp = readCookie(FBP_COOKIE);\n if (!fbp) {\n fbp = `fb.1.${Date.now()}.${randomId()}`;\n writeCookie(FBP_COOKIE, fbp, frontendUrl);\n }\n\n return readMetaAttributionCookies();\n}\n","import {\n magicLinkClient,\n emailOTPClient,\n anonymousClient,\n} from \"better-auth/client/plugins\";\nimport { passkeyClient } from \"@better-auth/passkey/client\";\nimport { createAuthClient } from \"better-auth/client\";\nimport { hc } from \"hono/client\";\nimport type { AppRouter } from \"@us-auth/api/routers\";\nimport type {\n UserPurchases,\n Session,\n RedirectIntent,\n MetaTrackEventInput,\n} from \"@us-auth/types\";\nimport {\n readMetaAttributionCookies,\n type MetaAttributionCookies,\n} from \"./metaAttribution\";\n\nexport class AuthClient {\n #frontendUrl: string;\n #authClient;\n #appClient: ReturnType<typeof hc<AppRouter>>;\n #cookie: string | undefined;\n\n constructor(apiUrl: string, frontendUrl: string, cookie?: string) {\n this.#cookie = cookie;\n this.#frontendUrl = frontendUrl;\n this.#authClient = createAuthClient({\n baseURL: apiUrl,\n plugins: [\n anonymousClient(),\n magicLinkClient(),\n emailOTPClient(),\n passkeyClient(),\n ],\n });\n this.#appClient = hc<AppRouter>(new URL(\"/api/app\", apiUrl).toString(), {\n fetch: (url: any, init: any) =>\n fetch(url, {\n ...init,\n credentials: \"include\",\n }),\n });\n }\n\n // Authentication\n getSession = async (): Promise<Session | null> => {\n const { data, error } = await this.#authClient.getSession(\n {},\n {\n headers: this.#cookie\n ? {\n Cookie: this.#cookie,\n }\n : undefined,\n },\n );\n if (error) throw error;\n return data;\n };\n\n signInAnonymously = async (): Promise<Session | null> => {\n const { error } = await this.#authClient.signIn.anonymous();\n if (error) throw error;\n return this.getSession();\n };\n\n signOut = async (onSuccess?: () => void): Promise<void> => {\n const { error } = await this.#authClient.signOut(\n {\n fetchOptions: { onSuccess },\n },\n {\n headers: this.#cookie ? { Cookie: this.#cookie } : undefined,\n },\n );\n if (error) throw error;\n return;\n };\n\n // Purchases\n getPurchases = async (): Promise<UserPurchases | null> => {\n const res = await this.#appClient.purchases.$get(undefined, {\n headers: this.#cookie ? { Cookie: this.#cookie } : undefined,\n });\n if (!res.ok) {\n throw new Error(\"Failed to get purchases\", {\n cause: await res.text(),\n });\n }\n const data = await res.json();\n return data as UserPurchases | null;\n };\n\n #getRedirectIntent = (redirectUrl: string, appName?: string) => {\n return JSON.stringify({\n type: \"redirect\",\n redirectUrl,\n appName,\n } satisfies RedirectIntent);\n };\n\n // Meta CAPI attribution (no PII)\n trackMetaEvent = async (payload: MetaTrackEventInput): Promise<void> => {\n const res = await this.#appClient.meta.events.$post({\n json: payload,\n });\n if (!res.ok) {\n throw new Error(\"Failed to track Meta event\", {\n cause: await res.text(),\n });\n }\n };\n\n trackViewContent = async (options: {\n contentIds: string[];\n contentType?: string;\n eventSourceUrl?: string;\n }): Promise<void> => {\n const eventSourceUrl =\n options.eventSourceUrl ??\n (typeof window !== \"undefined\" ? window.location.href : undefined);\n await this.trackMetaEvent({\n event_name: \"ViewContent\",\n content_ids: options.contentIds,\n content_type: options.contentType ?? \"product\",\n ...(eventSourceUrl ? { event_source_url: eventSourceUrl } : {}),\n });\n };\n\n getMetaAttribution = (): MetaAttributionCookies => {\n return readMetaAttributionCookies();\n };\n\n // Utils\n getLoginUrl = (options?: { redirectUrl?: string; appName?: string }) => {\n const url = new URL(\"/login\", this.#frontendUrl);\n if (options?.redirectUrl) {\n url.searchParams.set(\n \"intent\",\n this.#getRedirectIntent(options.redirectUrl, options.appName),\n );\n }\n return url.toString();\n };\n\n getCheckoutUrl = (options: {\n priceId: string;\n productId: string;\n discountCode?: string;\n successUrl?: string;\n quantity?: number;\n }) => {\n const url = new URL(\"/auth/checkout\", this.#frontendUrl);\n url.searchParams.set(\"priceId\", options.priceId);\n url.searchParams.set(\"productId\", options.productId);\n if (options.discountCode) {\n url.searchParams.set(\"discountCode\", options.discountCode);\n }\n if (options.successUrl) {\n url.searchParams.set(\"successUrl\", options.successUrl);\n }\n url.searchParams.set(\"quantity\", options.quantity?.toString() ?? \"1\");\n return url.toString();\n };\n}\n","import { createContext } from \"react\";\nimport type { UserPurchases, Session } from \"@us-auth/types\";\nimport type { AuthClient } from \"../AuthClient\";\n\nexport type AuthContextType = {\n session: Session | null;\n isSessionFetching: boolean;\n refetchSession: () => Promise<void>;\n purchases: UserPurchases | null;\n isPurchasesFetching: boolean;\n refetchPurchases: () => Promise<void>;\n signOut: AuthClient[\"signOut\"];\n getLoginUrl: AuthClient[\"getLoginUrl\"];\n getCheckoutUrl: AuthClient[\"getCheckoutUrl\"];\n trackMetaEvent: AuthClient[\"trackMetaEvent\"];\n trackViewContent: AuthClient[\"trackViewContent\"];\n getMetaAttribution: AuthClient[\"getMetaAttribution\"];\n isPurchased: (priceIds: string[]) => boolean;\n isSubscribed: (priceIds: string[], productId: string) => boolean;\n isLoggedIn: boolean;\n} | null;\n\nexport const AuthContext = createContext<AuthContextType>(null);\n","import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n type PropsWithChildren,\n} from \"react\";\nimport { AuthContext } from \"./AuthContext\";\nimport { AuthClient } from \"../AuthClient\";\nimport type { Session, UserPurchases } from \"@us-auth/types\";\nimport { QueryClient, useQuery } from \"@tanstack/react-query\";\nimport { usePostHog } from \"@posthog/react\";\nimport { captureMetaClickId } from \"../metaAttribution\";\n\nexport interface AuthProviderProps extends PropsWithChildren {\n authClient?: AuthClient;\n queryClient?: QueryClient;\n baseUrl: string;\n frontendUrl: string;\n initialSession?: Session | null;\n initialPurchases?: UserPurchases | null;\n}\n\nexport const AuthProvider = ({\n children,\n baseUrl,\n frontendUrl,\n initialSession,\n initialPurchases,\n authClient: providedAuthClient,\n queryClient: providedQueryClient,\n}: AuthProviderProps) => {\n const ph = usePostHog();\n\n const authClient = useMemo(\n () =>\n providedAuthClient ?? new AuthClient(baseUrl, frontendUrl),\n [baseUrl, frontendUrl, providedAuthClient],\n );\n const queryClient = useMemo(\n () => providedQueryClient ?? new QueryClient(),\n [providedQueryClient],\n );\n\n const {\n data: session,\n isFetching: isSessionFetching,\n refetch: refetchSession,\n } = useQuery(\n {\n queryKey: [\"us-auth-session\"],\n staleTime: 0,\n initialData: initialSession,\n queryFn: authClient.getSession,\n },\n queryClient,\n );\n\n const isLoggedIn = useMemo(() => {\n if (!session || session.user.isAnonymous) return false;\n return true;\n }, [session]);\n\n const anonymousSignInAttempted = useRef(false);\n\n useEffect(() => {\n captureMetaClickId({ frontendUrl });\n }, [frontendUrl]);\n\n // Log unauthenticated users in anonymously automatically\n useEffect(() => {\n if (isSessionFetching) return;\n // Wait for the session query to settle to an explicit null, not undefined.\n if (session !== null) return;\n if (anonymousSignInAttempted.current) return;\n\n anonymousSignInAttempted.current = true;\n authClient\n .signInAnonymously()\n .then((newSession) => {\n queryClient.setQueryData([\"us-auth-session\"], newSession);\n })\n .catch((e) => console.error(e));\n }, [authClient, isSessionFetching, queryClient, session]);\n\n useEffect(() => {\n if (session?.user && ph) {\n const distinctId = ph.get_distinct_id();\n if (distinctId !== session.user.id) {\n ph.identify(session.user.id, {\n email: session.user.email,\n });\n }\n }\n }, [session, ph]);\n\n const {\n data: purchases,\n isFetching: isPurchasesFetching,\n refetch: refetchPurchases,\n } = useQuery(\n {\n queryKey: [\"us-auth-purchases\"],\n staleTime: 1000 * 60,\n initialData: initialPurchases,\n queryFn: authClient.getPurchases,\n },\n queryClient,\n );\n\n const getLoginUrl = useMemo(() => authClient.getLoginUrl, [authClient]);\n const getCheckoutUrl = useMemo(() => authClient.getCheckoutUrl, [authClient]);\n const signOut = useCallback(\n (onSuccess?: () => void) =>\n authClient.signOut(() => {\n ph?.reset();\n onSuccess?.();\n }),\n [authClient, ph],\n );\n const trackMetaEvent = useMemo(() => authClient.trackMetaEvent, [authClient]);\n const trackViewContent = useMemo(\n () => authClient.trackViewContent,\n [authClient],\n );\n const getMetaAttribution = useMemo(\n () => authClient.getMetaAttribution,\n [authClient],\n );\n\n const isPurchased = useCallback(\n (priceIds: string[]): boolean => {\n if (!purchases) return false;\n return purchases.paddle.transactions.some(\n (tra) =>\n tra.items.some((item) => priceIds.includes(item)) &&\n !tra.adjustments.some(\n (adj) => adj.status === \"approved\" && adj.action === \"refund\",\n ),\n );\n },\n [purchases],\n );\n\n const isSubscribed = useCallback(\n (priceIds: string[], productId: string): boolean => {\n if (!purchases) return false;\n\n const paddleSubscriptions = purchases.paddle.subscriptions.some(\n (sub) =>\n sub.items.some(\n (item) =>\n priceIds.includes(item.priceId) || productId === item.productId,\n ) && sub.status === \"active\",\n );\n\n const stripeSubscriptions = purchases.stripe.some(\n (sub) =>\n sub.status === \"active\" &&\n sub.items.some((item) => priceIds.includes(item)),\n );\n\n return paddleSubscriptions || stripeSubscriptions;\n },\n [purchases],\n );\n\n return (\n <AuthContext.Provider\n value={{\n session: session ?? null,\n isSessionFetching,\n refetchSession: async () => {\n await refetchSession();\n },\n purchases: purchases ?? null,\n isPurchasesFetching,\n refetchPurchases: async () => {\n await refetchPurchases();\n },\n signOut,\n getLoginUrl,\n getCheckoutUrl,\n trackMetaEvent,\n trackViewContent,\n getMetaAttribution,\n isSubscribed,\n isPurchased,\n isLoggedIn,\n }}\n >\n {children}\n </AuthContext.Provider>\n );\n};\n","import { useContext } from \"react\";\nimport { AuthContext } from \"./AuthContext\";\n\nexport function useAuth() {\n const ctx = useContext(AuthContext);\n if (!ctx) {\n throw new Error(\"useAuth must be used within an AuthProvider\");\n }\n return ctx;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["#cookie","#frontendUrl","#authClient","#appClient","#getRedirectIntent","createAuthClient","SHARED_ANALYTICS_EVENTS","#metaPixelId","#started","#unsubscribe","#applyConsent","#marketingGranted","z"],"sources":["../src/AuthClient.ts","../src/betterAuthClient.ts","../src/analytics.ts","../src/tracking/metaPixel.ts","../src/tracking/redaction.ts","../src/tracking/consentAction.ts","../src/tracking/posthog.ts","../src/tracking/TrackingClient.ts","../src/tracking/TrackingContext.ts","../src/tracking/TrackingProvider.tsx","../src/tracking/useTracking.ts","../src/react/AuthContext.ts","../src/react/AuthProvider.tsx","../src/react/useAuth.ts","../src/react/resendCooldown.ts","../src/react/useEmailOtpLoginFlow.ts"],"sourcesContent":["import {\n magicLinkClient,\n emailOTPClient,\n anonymousClient,\n} from \"better-auth/client/plugins\";\nimport { passkeyClient } from \"@better-auth/passkey/client\";\nimport { createAuthClient } from \"better-auth/client\";\nimport { hc } from \"hono/client\";\nimport type { AppRouter } from \"@us-auth/api/routers\";\nimport type {\n UserPurchases,\n Session,\n RedirectIntent,\n} from \"@us-auth/types\";\n\nexport class AuthClient {\n #frontendUrl: string;\n #authClient;\n #appClient: ReturnType<typeof hc<AppRouter>>;\n #cookie: string | undefined;\n\n constructor(apiUrl: string, frontendUrl: string, cookie?: string) {\n this.#cookie = cookie;\n this.#frontendUrl = frontendUrl;\n this.#authClient = createAuthClient({\n baseURL: apiUrl,\n plugins: [\n anonymousClient(),\n magicLinkClient(),\n emailOTPClient(),\n passkeyClient(),\n ],\n });\n this.#appClient = hc<AppRouter>(new URL(\"/api/app\", apiUrl).toString(), {\n fetch: (url: RequestInfo | URL, init?: RequestInit) =>\n fetch(url, {\n ...init,\n credentials: \"include\",\n }),\n });\n }\n\n // Authentication\n getSession = async (): Promise<Session | null> => {\n const { data, error } = await this.#authClient.getSession(\n {},\n {\n headers: this.#cookie\n ? {\n Cookie: this.#cookie,\n }\n : undefined,\n },\n );\n if (error) throw error;\n return data;\n };\n\n signInAnonymously = async (): Promise<Session | null> => {\n const { error } = await this.#authClient.signIn.anonymous();\n if (error) throw error;\n return this.getSession();\n };\n\n signOut = async (onSuccess?: () => void): Promise<void> => {\n const { error } = await this.#authClient.signOut(\n {\n fetchOptions: { onSuccess },\n },\n {\n headers: this.#cookie ? { Cookie: this.#cookie } : undefined,\n },\n );\n if (error) throw error;\n return;\n };\n\n // Purchases\n getPurchases = async (): Promise<UserPurchases | null> => {\n const res = await this.#appClient.purchases.$get(undefined, {\n headers: this.#cookie ? { Cookie: this.#cookie } : undefined,\n });\n if (!res.ok) {\n throw new Error(\"Failed to get purchases\", {\n cause: await res.text(),\n });\n }\n const data = await res.json();\n return data as UserPurchases | null;\n };\n\n #getRedirectIntent = (redirectUrl: string, appName?: string) => {\n return JSON.stringify({\n type: \"redirect\",\n redirectUrl,\n appName,\n } satisfies RedirectIntent);\n };\n\n // Utils\n getLoginUrl = (options?: { redirectUrl?: string; appName?: string }) => {\n const url = new URL(\"/login\", this.#frontendUrl);\n if (options?.redirectUrl) {\n url.searchParams.set(\n \"intent\",\n this.#getRedirectIntent(options.redirectUrl, options.appName),\n );\n }\n return url.toString();\n };\n\n getCheckoutUrl = (options: {\n priceId: string;\n productId: string;\n discountCode?: string;\n successUrl?: string;\n quantity?: number;\n }) => {\n const url = new URL(\"/auth/checkout\", this.#frontendUrl);\n url.searchParams.set(\"priceId\", options.priceId);\n url.searchParams.set(\"productId\", options.productId);\n if (options.discountCode) {\n url.searchParams.set(\"discountCode\", options.discountCode);\n }\n if (options.successUrl) {\n url.searchParams.set(\"successUrl\", options.successUrl);\n }\n url.searchParams.set(\"quantity\", options.quantity?.toString() ?? \"1\");\n return url.toString();\n };\n}\n","import {\n magicLinkClient,\n emailOTPClient,\n anonymousClient,\n} from \"better-auth/client/plugins\";\nimport { passkeyClient } from \"@better-auth/passkey/client\";\nimport { createAuthClient } from \"better-auth/react\";\n\nexport function createBetterAuthClient(baseURL: string) {\n return createAuthClient({\n baseURL,\n plugins: [\n anonymousClient(),\n magicLinkClient(),\n emailOTPClient(),\n passkeyClient(),\n ],\n });\n}\n\nexport type BetterAuthClient = ReturnType<typeof createBetterAuthClient>;\n","import {\n ANALYTICS_EVENTS as SHARED_ANALYTICS_EVENTS,\n isAnalyticsProduct,\n type AnalyticsProduct,\n type AuthMethod,\n} from \"@us-auth/types\";\n\n/**\n * Re-exported as a local binding: re-exporting the const directly from the\n * bundled `@us-auth/types` package trips the declaration bundler.\n */\nexport const ANALYTICS_EVENTS = SHARED_ANALYTICS_EVENTS;\n\nexport interface PostHogAnalyticsClient {\n capture: (event: string, properties?: Record<string, unknown>) => void;\n register?: (properties: Record<string, unknown>) => void;\n}\n\nexport function registerProduct(\n ph: PostHogAnalyticsClient | null | undefined,\n product: AnalyticsProduct,\n) {\n ph?.register?.({ product });\n}\n\nexport function captureFeatureUsed(\n ph: PostHogAnalyticsClient | null | undefined,\n featureName: string,\n extra?: Record<string, unknown>,\n) {\n ph?.capture(ANALYTICS_EVENTS.FEATURE_USED, {\n feature_name: featureName,\n ...extra,\n });\n}\n\nexport function captureCheckoutStarted(\n ph: PostHogAnalyticsClient | null | undefined,\n {\n plan,\n product,\n }: {\n plan: string;\n product?: AnalyticsProduct;\n },\n) {\n if (product) {\n registerProduct(ph, product);\n }\n ph?.capture(ANALYTICS_EVENTS.CHECKOUT_STARTED, {\n plan,\n ...(product ? { product } : {}),\n });\n}\n\nexport { isAnalyticsProduct };\nexport type { AnalyticsProduct, AuthMethod };\n","type FbqFunction = ((...args: unknown[]) => void) & {\n callMethod?: (...args: unknown[]) => void;\n queue?: unknown[][];\n loaded?: boolean;\n version?: string;\n};\n\ntype MetaWindow = Window & { fbq?: FbqFunction; _fbq?: FbqFunction };\n\nlet pixelLoaded = false;\n\n/** Injects the Meta Pixel base code and fires an initial PageView. Idempotent. */\nexport function loadMetaPixel(pixelId: string): void {\n if (typeof window === \"undefined\" || pixelLoaded) return;\n\n const w = window as MetaWindow;\n if (!w.fbq) {\n const fbq = ((...args: unknown[]) => {\n if (fbq.callMethod) fbq.callMethod(...args);\n else fbq.queue?.push(args);\n }) as FbqFunction;\n fbq.queue = [];\n fbq.loaded = true;\n fbq.version = \"2.0\";\n w.fbq = fbq;\n if (!w._fbq) w._fbq = fbq;\n\n const script = document.createElement(\"script\");\n script.async = true;\n script.src = \"https://connect.facebook.net/en_US/fbevents.js\";\n document.head.appendChild(script);\n }\n\n w.fbq(\"init\", pixelId);\n w.fbq(\"track\", \"PageView\");\n pixelLoaded = true;\n}\n\nexport function isMetaPixelLoaded(): boolean {\n return pixelLoaded;\n}\n\n/**\n * Tells an already-loaded pixel to stop sending when marketing consent is\n * withdrawn. Does not unload the script or clear cookies.\n */\nexport function revokeMetaPixelConsent(): void {\n if (typeof window === \"undefined\") return;\n const fbq = (window as MetaWindow).fbq;\n fbq?.(\"consent\", \"revoke\");\n}\n\n/** Fires a standard pixel event; `eventId` lets Meta dedupe on reloads. */\nexport function trackMetaPixel(\n event: string,\n params?: Record<string, unknown>,\n eventId?: string,\n): void {\n if (typeof window === \"undefined\") return;\n const fbq = (window as MetaWindow).fbq;\n if (!fbq) return;\n if (eventId) fbq(\"track\", event, params, { eventID: eventId });\n else fbq(\"track\", event, params);\n}\n","type RedactableEvent = { properties?: Record<string, unknown> };\n\nconst URL_PROPERTIES = [\n \"$current_url\",\n \"$initial_current_url\",\n \"$referrer\",\n \"$initial_referrer\",\n];\n\nconst PATH_PROPERTIES = [\"$pathname\", \"$initial_pathname\"];\n\nfunction redactPassphrasePath(pathname: string): string {\n return pathname.replace(/^\\/s\\/[^/]+/, \"/s/[redacted]\");\n}\n\nfunction redactUrl(value: unknown): unknown {\n if (typeof value !== \"string\") return value;\n try {\n const url = new URL(value);\n url.search = \"\";\n url.hash = \"\";\n url.pathname = redactPassphrasePath(url.pathname);\n return url.toString();\n } catch {\n return value;\n }\n}\n\nfunction redactPath(value: unknown): unknown {\n if (typeof value !== \"string\") return value;\n return redactPassphrasePath(value);\n}\n\n/**\n * Strips URL query strings and short-link passphrases from every event before\n * it leaves the browser. Together with `mask_all_text` this keeps autocapture\n * and pageviews PII-free without disabling them.\n *\n * Applies in every consent mode: it is PII hygiene, not a consent mitigation.\n */\nexport function redactBeforeSend<T extends RedactableEvent | null>(event: T): T {\n if (!event || !event.properties) return event;\n\n const properties = event.properties;\n for (const key of URL_PROPERTIES) {\n if (key in properties) {\n properties[key] = redactUrl(properties[key]);\n }\n }\n for (const key of PATH_PROPERTIES) {\n if (key in properties) {\n properties[key] = redactPath(properties[key]);\n }\n }\n\n return event;\n}","import type { ConsentState } from \"@us-auth/types\";\n\n/**\n * Pure mapping from consent state to the PostHog consent action.\n * Kept separate from the PostHog import so it is trivially testable.\n */\nexport function posthogConsentAction(\n consent: ConsentState,\n): \"opt_in\" | \"opt_out\" {\n return consent?.analytics ? \"opt_in\" : \"opt_out\";\n}","import posthog, { type PostHog } from \"posthog-js\";\nimport type { AnalyticsProduct, ConsentState } from \"@us-auth/types\";\nimport { redactBeforeSend } from \"./redaction\";\nimport { registerProduct as registerProductEvent } from \"../analytics\";\nimport { posthogConsentAction } from \"./consentAction\";\n\nexport { posthogConsentAction };\n\nexport interface PostHogConfigInput {\n apiKey: string;\n apiHost: string;\n uiHost?: string;\n}\n\n/**\n * PostHog runs in `on_reject` mode so the SDK's consent API can move us\n * between cookieless and full persistence at runtime. Every PII-hygiene\n * option is permanent in both modes; only persistence and `identify` change.\n */\nconst BASE_OPTIONS = {\n defaults: \"2026-05-30\" as const,\n person_profiles: \"identified_only\" as const,\n cookieless_mode: \"on_reject\" as const,\n // Belt-and-braces: before the consent sync runs, pending behaves as\n // \"not granted\" → cookieless capture rather than a full freeze.\n opt_out_capturing_by_default: true,\n // Keep PostHog's own consent record separate from `uninspired_consent`\n // (different value encoding).\n consent_persistence_name: \"uninspired_ph_consent\",\n cross_subdomain_cookie: true,\n cookie_expiration: 180,\n // Permanent PII hygiene — identical in both consent modes.\n mask_all_text: true,\n mask_all_element_attributes: true,\n disable_session_recording: true,\n disable_surveys: true,\n capture_heatmaps: false,\n capture_exceptions: true,\n before_send: redactBeforeSend,\n};\n\nlet cachedPh: PostHog | null = null;\n\nexport function getOrInitPostHog(config: PostHogConfigInput): PostHog | null {\n if (typeof window === \"undefined\") return null;\n if (cachedPh) return cachedPh;\n\n cachedPh = posthog.init(config.apiKey, {\n ...BASE_OPTIONS,\n api_host: config.apiHost,\n ...(config.uiHost ? { ui_host: config.uiHost } : {}),\n });\n\n return cachedPh;\n}\n\n/**\n * Mirrors the `uninspired_consent` decision into PostHog's own consent state.\n *\n * - granted → `opt_in_capturing()` upgrades to cookies + identify live\n * - pending → `opt_out_capturing()` keeps capturing cookielessly\n * - denied → same as pending (cookieless capture continues)\n */\nexport function syncPostHogConsent(ph: PostHog | null, consent: ConsentState) {\n if (!ph) return;\n if (posthogConsentAction(consent) === \"opt_in\") ph.opt_in_capturing();\n else ph.opt_out_capturing();\n}\n\nexport function registerTrackingProduct(\n ph: PostHog | null,\n product: AnalyticsProduct,\n) {\n registerProductEvent(ph, product);\n}\n","import type { PostHog } from \"posthog-js\";\nimport type { AnalyticsProduct, ConsentState, TrackingConsent } from \"@us-auth/types\";\nimport {\n configureConsentDomain,\n getConsent,\n setConsent as setConsentStore,\n subscribeConsent,\n} from \"../consent\";\nimport { purgeLegacyTracking } from \"../consent/purgeLegacyTracking\";\nimport {\n captureCheckoutStarted as captureCheckoutStartedEvent,\n captureFeatureUsed as captureFeatureUsedEvent,\n registerProduct as registerProductEvent,\n} from \"../analytics\";\nimport {\n isMetaPixelLoaded,\n loadMetaPixel,\n revokeMetaPixelConsent,\n trackMetaPixel,\n} from \"./metaPixel\";\nimport {\n getOrInitPostHog,\n syncPostHogConsent,\n type PostHogConfigInput,\n} from \"./posthog\";\n\nexport interface TrackingClientOptions {\n product: AnalyticsProduct;\n /** `null` disables PostHog entirely (product apps without analytics config). */\n posthog: PostHogConfigInput | null;\n metaPixelId?: string;\n /** `undefined` derives the domain, `\"\"` forces a host-only cookie. */\n consentCookieDomain?: string;\n}\n\nexport interface ViewContentOptions {\n contentId: string;\n value?: number;\n currency?: string;\n}\n\nexport interface InitiateCheckoutOptions {\n contentIds?: string[];\n value?: number;\n currency?: string;\n}\n\nexport interface PurchaseOptions {\n value?: number;\n currency?: string;\n contentIds?: string[];\n /** Paddle transaction id — lets Meta dedupe repeated browser events. */\n eventId?: string;\n}\n\n/**\n * Owns PostHog initialization and the Meta Pixel lifecycle for an app.\n *\n * PostHog capture always works (cookieless while pending/denied, full when\n * granted); `identify` and every Meta call are consent-gated.\n */\nexport class TrackingClient {\n readonly ph: PostHog | null;\n readonly product: AnalyticsProduct;\n\n #metaPixelId?: string;\n #unsubscribe?: () => void;\n #started = false;\n\n constructor(options: TrackingClientOptions) {\n this.product = options.product;\n this.#metaPixelId = options.metaPixelId;\n configureConsentDomain(options.consentCookieDomain);\n purgeLegacyTracking();\n this.ph = options.posthog ? getOrInitPostHog(options.posthog) : null;\n if (this.ph) registerProductEvent(this.ph, this.product);\n }\n\n start(): void {\n if (this.#started) return;\n this.#started = true;\n this.#unsubscribe = subscribeConsent(() =>\n this.#applyConsent(getConsent()),\n );\n this.#applyConsent(getConsent());\n }\n\n stop(): void {\n this.#unsubscribe?.();\n this.#unsubscribe = undefined;\n this.#started = false;\n }\n\n #applyConsent(consent: ConsentState): void {\n syncPostHogConsent(this.ph, consent);\n if (consent?.marketing && this.#metaPixelId) {\n loadMetaPixel(this.#metaPixelId);\n } else if (isMetaPixelLoaded()) {\n // Withdrawn after being granted: stop sends.\n revokeMetaPixelConsent();\n }\n }\n\n #marketingGranted(): boolean {\n return getConsent()?.marketing === true;\n }\n\n getConsent(): ConsentState {\n return getConsent();\n }\n\n setConsent(consent: TrackingConsent): void {\n setConsentStore(consent);\n }\n\n // --- PostHog -------------------------------------------------------------\n\n capture(event: string, properties?: Record<string, unknown>): void {\n this.ph?.capture(event, properties);\n }\n\n captureException(\n error: unknown,\n properties?: Record<string, unknown>,\n ): void {\n this.ph?.captureException(error, properties);\n }\n\n identify(userId: string): void {\n if (!getConsent()?.analytics) return;\n if (this.ph?.get_distinct_id() === userId) return;\n this.ph?.identify(userId);\n }\n\n reset(): void {\n this.ph?.reset();\n }\n\n registerProduct(product: AnalyticsProduct): void {\n registerProductEvent(this.ph, product);\n }\n\n captureFeatureUsed(featureName: string, extra?: Record<string, unknown>): void {\n captureFeatureUsedEvent(this.ph, featureName, extra);\n }\n\n captureCheckoutStarted(options: {\n plan: string;\n product?: AnalyticsProduct;\n }): void {\n captureCheckoutStartedEvent(this.ph, options);\n }\n\n // --- Meta Pixel ----------------------------------------------------------\n\n trackPageView(): void {\n if (!this.#marketingGranted()) return;\n trackMetaPixel(\"PageView\");\n }\n\n trackViewContent({ contentId, value, currency }: ViewContentOptions): void {\n if (!this.#marketingGranted()) return;\n trackMetaPixel(\"ViewContent\", {\n content_ids: [contentId],\n content_type: \"product\",\n ...(value !== undefined ? { value } : {}),\n ...(currency ? { currency } : {}),\n });\n }\n\n trackInitiateCheckout({\n contentIds,\n value,\n currency,\n }: InitiateCheckoutOptions = {}): void {\n if (!this.#marketingGranted()) return;\n trackMetaPixel(\"InitiateCheckout\", {\n ...(contentIds?.length\n ? { content_ids: contentIds, content_type: \"product\" }\n : {}),\n ...(value !== undefined ? { value } : {}),\n ...(currency ? { currency } : {}),\n });\n }\n\n trackPurchase({\n value,\n currency,\n contentIds,\n eventId,\n }: PurchaseOptions = {}): void {\n if (!this.#marketingGranted()) return;\n trackMetaPixel(\n \"Purchase\",\n {\n ...(contentIds?.length\n ? { content_ids: contentIds, content_type: \"product\" }\n : {}),\n ...(value !== undefined ? { value } : {}),\n ...(currency ? { currency } : {}),\n },\n eventId,\n );\n }\n}\n","import { createContext } from \"react\";\nimport type { TrackingClient } from \"./TrackingClient\";\n\nexport const TrackingContext = createContext<TrackingClient | null>(null);","import {\n useEffect,\n useRef,\n type PropsWithChildren,\n} from \"react\";\nimport { TrackingContext } from \"./TrackingContext\";\nimport {\n TrackingClient,\n type TrackingClientOptions,\n} from \"./TrackingClient\";\n\nexport interface TrackingProviderProps\n extends TrackingClientOptions,\n PropsWithChildren {}\n\n/**\n * Mount once per app, above `AuthProvider`. Owns PostHog init and the Meta\n * Pixel lifecycle, both driven by the shared consent cookie.\n */\nexport const TrackingProvider = ({\n children,\n ...options\n}: TrackingProviderProps) => {\n const clientRef = useRef<TrackingClient | null>(null);\n if (!clientRef.current) {\n clientRef.current = new TrackingClient(options);\n }\n\n useEffect(() => {\n const client = clientRef.current;\n client?.start();\n return () => client?.stop();\n }, []);\n\n return (\n <TrackingContext.Provider value={clientRef.current}>\n {children}\n </TrackingContext.Provider>\n );\n};\n","import { useContext } from \"react\";\nimport { TrackingContext } from \"./TrackingContext\";\nimport type { TrackingClient } from \"./TrackingClient\";\n\n/**\n * Returns the app's `TrackingClient`, or `null` when no `TrackingProvider`\n * wraps the tree (in which case all analytics no-op).\n */\nexport function useTracking(): TrackingClient | null {\n return useContext(TrackingContext);\n}","import { createContext } from \"react\";\nimport type { UserPurchases, Session, AnalyticsProduct } from \"@us-auth/types\";\nimport type { AuthClient } from \"../AuthClient\";\n\nexport type AuthContextType = {\n session: Session | null;\n isSessionFetching: boolean;\n refetchSession: () => Promise<void>;\n purchases: UserPurchases | null;\n isPurchasesFetching: boolean;\n refetchPurchases: () => Promise<void>;\n signOut: AuthClient[\"signOut\"];\n getLoginUrl: AuthClient[\"getLoginUrl\"];\n getCheckoutUrl: AuthClient[\"getCheckoutUrl\"];\n captureFeatureUsed: (\n featureName: string,\n extra?: Record<string, unknown>,\n ) => void;\n captureCheckoutStarted: (options: {\n plan: string;\n product?: AnalyticsProduct;\n }) => void;\n registerProduct: (product: AnalyticsProduct) => void;\n isPurchased: (priceIds: string[]) => boolean;\n isSubscribed: (priceIds: string[], productId: string) => boolean;\n isLoggedIn: boolean;\n} | null;\n\nexport const AuthContext = createContext<AuthContextType>(null);","import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n type PropsWithChildren,\n} from \"react\";\nimport { AuthContext } from \"./AuthContext\";\nimport { AuthClient } from \"../AuthClient\";\nimport type { Session, UserPurchases, AnalyticsProduct } from \"@us-auth/types\";\nimport { isPaddleTransactionRevoked } from \"@us-auth/types\";\nimport { QueryClient, useQuery } from \"@tanstack/react-query\";\nimport { useTracking } from \"../tracking/useTracking\";\nimport { useTrackingConsent } from \"../consent/useTrackingConsent\";\n\nexport interface AuthProviderProps extends PropsWithChildren {\n authClient?: AuthClient;\n queryClient?: QueryClient;\n baseUrl: string;\n frontendUrl: string;\n product?: AnalyticsProduct;\n initialSession?: Session | null;\n initialPurchases?: UserPurchases | null;\n}\n\nexport const AuthProvider = ({\n children,\n baseUrl,\n frontendUrl,\n product,\n initialSession,\n initialPurchases,\n authClient: providedAuthClient,\n queryClient: providedQueryClient,\n}: AuthProviderProps) => {\n const authClient = useMemo(\n () =>\n providedAuthClient ?? new AuthClient(baseUrl, frontendUrl),\n [baseUrl, frontendUrl, providedAuthClient],\n );\n const queryClient = useMemo(\n () => providedQueryClient ?? new QueryClient(),\n [providedQueryClient],\n );\n const tracking = useTracking();\n const { consent } = useTrackingConsent();\n const analyticsGranted = consent?.analytics === true;\n\n const {\n data: session,\n isFetching: isSessionFetching,\n status: sessionStatus,\n refetch: refetchSession,\n } = useQuery(\n {\n queryKey: [\"us-auth-session\"],\n staleTime: 0,\n initialData: initialSession,\n queryFn: authClient.getSession,\n },\n queryClient,\n );\n\n const isLoggedIn = useMemo(() => {\n if (!session || session.user.isAnonymous) return false;\n return true;\n }, [session]);\n\n const anonymousSignInAttempted = useRef(false);\n\n // Analytics delegates to the tracking client. PostHog capture works in every\n // consent mode (cookieless while pending/denied), so these stay callable;\n // the client itself gates identify and Meta.\n const registerProduct = useCallback(\n (nextProduct: AnalyticsProduct) => {\n tracking?.registerProduct(nextProduct);\n },\n [tracking],\n );\n\n const captureFeatureUsed = useCallback(\n (featureName: string, extra?: Record<string, unknown>) => {\n tracking?.captureFeatureUsed(featureName, extra);\n },\n [tracking],\n );\n\n const captureCheckoutStarted = useCallback(\n (options: { plan: string; product?: AnalyticsProduct }) => {\n tracking?.captureCheckoutStarted(options);\n },\n [tracking],\n );\n\n useEffect(() => {\n if (product) tracking?.registerProduct(product);\n }, [tracking, product]);\n\n // Identify only when analytics consent is granted, and re-run when consent\n // is granted mid-session. No email is ever sent — user id only.\n useEffect(() => {\n if (!tracking || !session?.user || session.user.isAnonymous) return;\n if (!analyticsGranted) return;\n tracking.identify(session.user.id);\n }, [tracking, session, analyticsGranted]);\n\n // Log unauthenticated users in anonymously automatically\n useEffect(() => {\n if (isSessionFetching) return;\n // Only treat the session as absent when the fetch actually SUCCEEDED and\n // returned null — a failed fetch keeps `data` at the initialData value\n // (null), and anonymous sign-in would overwrite a real session cookie.\n if (sessionStatus !== \"success\") return;\n if (session !== null) return;\n if (anonymousSignInAttempted.current) return;\n\n anonymousSignInAttempted.current = true;\n authClient\n .signInAnonymously()\n .then((newSession) => {\n queryClient.setQueryData([\"us-auth-session\"], newSession);\n })\n .catch((e) => console.error(e));\n }, [authClient, isSessionFetching, queryClient, session, sessionStatus]);\n\n const {\n data: purchases,\n isFetching: isPurchasesFetching,\n refetch: refetchPurchases,\n } = useQuery(\n {\n queryKey: [\"us-auth-purchases\"],\n staleTime: 1000 * 60,\n initialData: initialPurchases,\n queryFn: authClient.getPurchases,\n },\n queryClient,\n );\n\n const getLoginUrl = useMemo(() => authClient.getLoginUrl, [authClient]);\n const getCheckoutUrl = useMemo(() => authClient.getCheckoutUrl, [authClient]);\n const signOut = useCallback(\n (onSuccess?: () => void) =>\n authClient.signOut(() => {\n // Clear cached session/purchases so isLoggedIn, isPurchased and\n // isSubscribed stop serving the signed-out user immediately.\n queryClient.setQueryData([\"us-auth-session\"], null);\n queryClient.removeQueries({ queryKey: [\"us-auth-purchases\"] });\n // Drop the identified PostHog person so the next user starts fresh.\n tracking?.reset();\n onSuccess?.();\n }),\n [authClient, queryClient, tracking],\n );\n\n const isPurchased = useCallback(\n (priceIds: string[]): boolean => {\n if (!purchases) return false;\n return purchases.paddle.transactions.some(\n (tra) =>\n tra.items.some((item) => priceIds.includes(item)) &&\n !isPaddleTransactionRevoked(tra.adjustments),\n );\n },\n [purchases],\n );\n\n const isSubscribed = useCallback(\n (priceIds: string[], productId: string): boolean => {\n if (!purchases) return false;\n\n const paddleSubscriptions = purchases.paddle.subscriptions.some(\n (sub) =>\n sub.items.some(\n (item) =>\n priceIds.includes(item.priceId) || productId === item.productId,\n ) && sub.status === \"active\",\n );\n\n const stripeSubscriptions = purchases.stripe.some(\n (sub) =>\n sub.status === \"active\" &&\n sub.items.some((item) => priceIds.includes(item)),\n );\n\n return paddleSubscriptions || stripeSubscriptions;\n },\n [purchases],\n );\n\n return (\n <AuthContext.Provider\n value={{\n session: session ?? null,\n isSessionFetching,\n refetchSession: async () => {\n await refetchSession();\n },\n purchases: purchases ?? null,\n isPurchasesFetching,\n refetchPurchases: async () => {\n await refetchPurchases();\n },\n signOut,\n getLoginUrl,\n getCheckoutUrl,\n captureFeatureUsed,\n captureCheckoutStarted,\n registerProduct,\n isSubscribed,\n isPurchased,\n isLoggedIn,\n }}\n >\n {children}\n </AuthContext.Provider>\n );\n};\n","import { useContext } from \"react\";\nimport { AuthContext } from \"./AuthContext\";\n\nexport function useAuth() {\n const ctx = useContext(AuthContext);\n if (!ctx) {\n throw new Error(\"useAuth must be used within an AuthProvider\");\n }\n return ctx;\n}\n","export const RESEND_COOLDOWN_SECONDS = 30;\n\nexport function remainingCooldownSeconds(\n availableAt: number,\n now: number,\n): number {\n return Math.max(0, Math.ceil((availableAt - now) / 1000));\n}\n\nexport function resendButtonLabel(label: string, remainingSeconds: number) {\n return remainingSeconds > 0 ? `${label} (${remainingSeconds}s)` : label;\n}\n","import { useCallback, useMemo, useState } from \"react\";\nimport z from \"zod\";\nexport type EmailOtpAuthClient = {\n emailOtp: {\n sendVerificationOtp: (input: {\n email: string;\n type: \"sign-in\";\n }) => Promise<{ error?: unknown }>;\n };\n signIn: {\n emailOtp: (input: {\n email: string;\n otp: string;\n }) => Promise<{ error?: unknown }>;\n };\n};\nimport {\n remainingCooldownSeconds,\n RESEND_COOLDOWN_SECONDS,\n} from \"./resendCooldown\";\n\nconst emailSchema = z.email();\nconst otpSchema = z\n .string()\n .min(6)\n .max(6)\n .refine((otp) => otp.match(/^[0-9]{6}$/));\n\nexport type EmailOtpLoginFlowOptions = {\n authClient: EmailOtpAuthClient;\n onVerified: () => void | Promise<void>;\n onSendSuccess?: () => void;\n onSendError?: (error: unknown) => void;\n onVerifyError?: (error: unknown) => void;\n resendCooldownSeconds?: number;\n};\n\nexport function useEmailOtpLoginFlow({\n authClient,\n onVerified,\n onSendSuccess,\n onSendError,\n onVerifyError,\n resendCooldownSeconds = RESEND_COOLDOWN_SECONDS,\n}: EmailOtpLoginFlowOptions) {\n const [step, setStep] = useState<\"email\" | \"otp\">(\"email\");\n const [email, setEmail] = useState(\"\");\n const [otp, setOtp] = useState(\"\");\n const [submitting, setSubmitting] = useState(false);\n const [verifying, setVerifying] = useState(false);\n const [resending, setResending] = useState(false);\n const [availableAt, setAvailableAt] = useState(\n () => Date.now() + resendCooldownSeconds * 1000,\n );\n const [now, setNow] = useState(() => Date.now());\n\n const emailValid = useMemo(\n () => emailSchema.safeParse(email).success,\n [email],\n );\n const otpValid = useMemo(() => otpSchema.safeParse(otp).success, [otp]);\n const remainingSeconds = remainingCooldownSeconds(availableAt, now);\n const isCoolingDown = remainingSeconds > 0;\n\n const restartResendCooldown = useCallback(() => {\n const timestamp = Date.now();\n setNow(timestamp);\n setAvailableAt(timestamp + resendCooldownSeconds * 1000);\n }, [resendCooldownSeconds]);\n\n const sendOtp = useCallback(async () => {\n const { error } = await authClient.emailOtp.sendVerificationOtp({\n email,\n type: \"sign-in\",\n });\n if (error) throw error;\n }, [authClient, email]);\n\n const submitEmail = useCallback(async () => {\n if (!emailValid) return;\n setSubmitting(true);\n try {\n await sendOtp();\n onSendSuccess?.();\n setStep(\"otp\");\n } catch (error) {\n onSendError?.(error);\n } finally {\n setSubmitting(false);\n }\n }, [emailValid, sendOtp, onSendSuccess, onSendError]);\n\n const resendOtp = useCallback(async () => {\n if (resending || isCoolingDown) return;\n setResending(true);\n try {\n await sendOtp();\n restartResendCooldown();\n onSendSuccess?.();\n } catch (error) {\n onSendError?.(error);\n } finally {\n setResending(false);\n }\n }, [\n resending,\n isCoolingDown,\n sendOtp,\n restartResendCooldown,\n onSendSuccess,\n onSendError,\n ]);\n\n const verifyOtp = useCallback(async () => {\n if (!otpValid) return;\n setVerifying(true);\n try {\n const { error } = await authClient.signIn.emailOtp({ email, otp });\n if (error) throw error;\n await onVerified();\n } catch (error) {\n onVerifyError?.(error);\n setVerifying(false);\n }\n }, [otpValid, authClient, email, otp, onVerified, onVerifyError]);\n\n const backToEmail = useCallback(() => {\n setStep(\"email\");\n setOtp(\"\");\n }, []);\n\n return {\n step,\n email,\n setEmail,\n otp,\n setOtp,\n emailValid,\n otpValid,\n submitting,\n verifying,\n resending,\n remainingSeconds,\n isCoolingDown,\n submitEmail,\n resendOtp,\n verifyOtp,\n backToEmail,\n setNow,\n availableAt,\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{z as e}from"zod";import{useSyncExternalStore as t}from"react";const n=[`mixd`,`momentum`,`unpinned`,`accounts`],r={USER_SIGNED_UP:`user signed up`,USER_LOGGED_IN:`user logged in`,TRIAL_STARTED:`trial started`,CHECKOUT_STARTED:`checkout started`,CHECKOUT_COMPLETED:`checkout completed`,FEATURE_USED:`feature used`};function i(e){return n.includes(e)}const a=`uninspired_consent`;function o(e){if(!e)return null;let t=new URLSearchParams(e),n=t.get(`a`),r=t.get(`m`);return n===null&&r===null?null:{analytics:n===`1`,marketing:r===`1`}}function s(e){return new URLSearchParams({a:e.analytics?`1`:`0`,m:e.marketing?`1`:`0`}).toString()}const c=e.object({id:e.string(),createdAt:e.coerce.date(),status:e.string(),items:e.array(e.object({priceId:e.string(),productId:e.string()}))}),l=e.object({id:e.string(),createdAt:e.coerce.date(),adjustments:e.array(e.object({id:e.string(),createdAt:e.coerce.date(),action:e.enum([`credit`,`refund`,`chargeback`,`chargeback_reverse`,`chargeback_warning`,`chargeback_warning_reverse`,`credit_reverse`]),type:e.enum([`full`,`partial`]),status:e.enum([`pending_approval`,`approved`,`rejected`,`reversed`])})),items:e.array(e.string())}),u=e.object({id:e.string(),customerId:e.string(),created:e.coerce.date(),status:e.enum([`active`,`trialing`,`canceled`,`past_due`,`paused`,`incomplete`,`incomplete_expired`,`unpaid`]),items:e.array(e.string())}),d=e.array(u),f=e.object({customerId:e.string().optional(),subscriptions:e.array(c),transactions:e.array(l)});e.object({stripe:d,paddle:f});function p(e){return!(!e.some(e=>e.status===`approved`&&(e.action===`chargeback`||e.action===`refund`&&e.type===`full`))||e.some(e=>e.action===`chargeback_reverse`&&e.status===`approved`))}const m=Symbol(`json-parse-failed`);function h(e){if(typeof e!=`string`)return e;let t=e=>{try{return JSON.parse(e)}catch{return m}},n=t(e);if(n!==m)return n;try{let n=decodeURIComponent(e);if(n!==e){let e=t(n);if(e!==m)return e}}catch{}return e}function g(e){if(e==null||e===``)return;if(Array.isArray(e))return e.every(e=>typeof e==`string`)&&e.length>0?e:void 0;if(typeof e!=`string`)return;let t=h(e);if(Array.isArray(t)&&t.every(e=>typeof e==`string`))return t.length>0?t:void 0;if(typeof t!=`string`)return;let n=t.split(`,`).map(e=>e.trim()).filter(Boolean);return n.length>0?n:void 0}const _=e.object({type:e.literal(`checkout`),priceId:e.string(),additionalPriceIds:e.array(e.string()).optional(),productId:e.string().optional(),discountCode:e.string().optional(),loginUrl:e.string().refine(t=>{let n=decodeURIComponent(t);return e.url().safeParse(n).success}).transform(e=>decodeURIComponent(e)).optional(),pricingUrl:e.string().refine(t=>{let n=decodeURIComponent(t);return e.url().safeParse(n).success}).transform(e=>decodeURIComponent(e)).optional(),successUrl:e.string().refine(t=>{let n=decodeURIComponent(t);return e.url().safeParse(n).success}).transform(e=>decodeURIComponent(e)).optional()}),v=e.object({type:e.literal(`redirect`),redirectUrl:e.url(),appName:e.string().optional()}),y=e.object({type:e.literal(`auth`),returnUrl:e.string()}),b=e.discriminatedUnion(`type`,[_,v,y]),x=e.union([b,e.string()]).optional().transform(e=>{if(e!==void 0)return typeof e==`string`?b.parse(h(e)):e});e.object({intent:x,fbclid:e.string().optional()});const S=e.union([e.array(e.string()),e.string()]).optional().transform(e=>g(e));function C(e){try{return decodeURIComponent(e)}catch{return e}}function w(){return e.string().refine(t=>{let n=C(t);if(!e.url().safeParse(n).success)return!1;let r=new URL(n).protocol;return r===`http:`||r===`https:`}).transform(C)}e.object({priceId:e.string(),additionalPriceIds:S,productId:e.string(),quantity:e.coerce.number().int().min(1).max(999).optional(),discountCode:e.string().optional(),loginUrl:w().optional(),pricingUrl:w().optional(),successUrl:w().optional(),fbclid:e.string().optional(),ref:e.string().optional()}),e.enum([`missing_purchases`,`missing_customer`,`invalid_redirect_hosts`,`already_owned`,`invalid_prices`,`invalid_discount`,`internal_server_error`]),e.object({slug:e.string().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),productId:e.string().min(1),discountPercent:e.number().int().min(1).max(100),startsAt:e.coerce.date(),endsAt:e.coerce.date()}).extend({id:e.string().min(1)}),e.object({id:e.string().min(1)}),e.object({id:e.string(),slug:e.string(),productId:e.string(),discountPercent:e.number(),startsAt:e.coerce.date(),endsAt:e.coerce.date(),shortLinkUrl:e.string(),promoPageUrl:e.string(),createdAt:e.coerce.date()});const T=e.object({currencyCode:e.string(),originalAmount:e.string(),originalFormatted:e.string()}),E=e.object({id:e.string(),name:e.string().nullable(),description:e.string().nullable(),customData:e.custom(e=>e===null||typeof e==`object`).nullable(),billingCycle:e.object({interval:e.enum([`day`,`week`,`month`,`year`]),frequency:e.number()}).nullable(),unitPrice:e.object({amount:e.string(),currencyCode:e.string()}).nullable(),unitPriceOverrides:e.array(e.object({countryCodes:e.array(e.string()),unitPrice:e.object({amount:e.string(),currencyCode:e.string()})})).nullable(),owned:e.boolean(),preview:T.optional()});e.object({slug:e.string(),productId:e.string(),productName:e.string(),productDescription:e.string().nullable(),discountPercent:e.number(),isActive:e.boolean(),alreadyRedeemed:e.boolean(),prices:e.array(E)}),e.object({discountCode:e.string(),checkoutUrl:e.string()}),e.object({slug:e.string().min(1),priceId:e.string().min(1)}),e.object({ref:e.string(),fbclid:e.string().optional()}),e.object({productId:e.string(),productName:e.string(),productDescription:e.string().nullable(),discountPercent:e.number(),valid:e.boolean(),prices:e.array(E)}),e.object({productId:e.string().min(1),priceId:e.string().min(1),ref:e.string().min(1)}),e.object({discountCode:e.string(),checkoutUrl:e.string()}),e.object({email:e.email(),stripeCustomerIds:e.array(e.string()).optional()}),e.object({email:e.email()});const D=new Set;let O,k=!1,A=null;function j(){if(typeof document>`u`)return null;let e=`${a}=`,t=document.cookie.split(`;`).map(e=>e.trim()).find(t=>t.startsWith(e));return t?o(decodeURIComponent(t.slice(e.length))):null}function M(){for(let e of D)e()}function N(e,t){return e?.analytics===t?.analytics&&e?.marketing===t?.marketing}function P(){return k||=(A=j(),!0),A}function F(){return P()===null}function I(e){return D.add(e),()=>{D.delete(e)}}function L(e){O=e}function R(){if(O!==void 0)return O||void 0;if(typeof location>`u`)return;let{hostname:e}=location;if(e===`uninspired.app`||e.endsWith(`.uninspired.app`))return`.uninspired.app`}function z(e){if(typeof document>`u`)return;let t=[`${a}=${encodeURIComponent(s(e))}`,`Path=/`,`Max-Age=15552000`,`SameSite=Lax`];typeof location<`u`&&location.protocol===`https:`&&t.push(`Secure`);let n=R();n&&t.push(`Domain=${n}`),document.cookie=t.join(`; `)}function B(e){z(e),A=e,k=!0,M()}function V(){let e=j();N(e,A)&&k||(A=e,k=!0,M())}const H=()=>null;function U(){let e=t(I,P,H);return{consent:e,pending:e===null,setConsent:B}}const W=new Set([`_fbp`,`_fbc`,`uninspired_ph_consent`]);function G(e){return!!(W.has(e)||e.startsWith(`ph_`)||e.startsWith(`__ph_opt_in_out_`))}function K(e){let t=R(),n=`${e}=; Path=/; Max-Age=0; SameSite=Lax`;document.cookie=n,t&&(document.cookie=`${n}; Domain=${t}`)}function q(e){let t=[];for(let n=0;n<e.length;n++){let r=e.key(n);r&&G(r)&&t.push(r)}for(let n of t)e.removeItem(n)}function J(){if(typeof document>`u`||(V(),P()!==null))return;let e=[];for(let t of document.cookie.split(`;`)){let n=t.trim();if(!n)continue;let r=n.indexOf(`=`),i=r===-1?n:n.slice(0,r);i!==`uninspired_consent`&&G(i)&&e.push(i)}for(let t of e)K(t);try{typeof localStorage<`u`&&q(localStorage)}catch{}try{typeof sessionStorage<`u`&&q(sessionStorage)}catch{}}export{F as a,B as c,r as d,i as f,P as i,I as l,U as n,V as o,L as r,R as s,J as t,p as u};
|
|
2
|
+
//# sourceMappingURL=purgeLegacyTracking-C4nrnU7N.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"purgeLegacyTracking-C4nrnU7N.js","names":[],"sources":["../../types/src/analytics.ts","../../types/src/consent.ts","../../types/src/purchases.ts","../../types/src/searchParams.ts","../../types/src/intent.ts","../../types/src/checkout.ts","../../types/src/promo.ts","../../types/src/affiliate.ts","../../types/src/dataDeletion.ts","../src/consent/store.ts","../src/consent/useTrackingConsent.ts","../src/consent/purgeLegacyTracking.ts"],"sourcesContent":["export const ANALYTICS_PRODUCTS = [\n \"mixd\",\n \"momentum\",\n \"unpinned\",\n \"accounts\",\n] as const;\n\nexport type AnalyticsProduct = (typeof ANALYTICS_PRODUCTS)[number];\n\nexport const ANALYTICS_EVENTS = {\n USER_SIGNED_UP: \"user signed up\",\n USER_LOGGED_IN: \"user logged in\",\n TRIAL_STARTED: \"trial started\",\n CHECKOUT_STARTED: \"checkout started\",\n CHECKOUT_COMPLETED: \"checkout completed\",\n FEATURE_USED: \"feature used\",\n} as const;\n\nexport type AnalyticsEvent =\n (typeof ANALYTICS_EVENTS)[keyof typeof ANALYTICS_EVENTS];\n\nexport type AuthMethod = \"magic_link\" | \"email_otp\" | \"passkey\";\n\nexport function isAnalyticsProduct(value: string): value is AnalyticsProduct {\n return (ANALYTICS_PRODUCTS as readonly string[]).includes(value);\n}\n","/**\n * Cookie-consent state shared by the API worker and `@uninspired/auth-client`.\n *\n * The consent cookie is the single source of truth for whether a user has\n * answered the banner. Its absence means \"pending\" (no decision yet), which is\n * treated exactly like the PII-free tracking baseline everywhere.\n */\n\nexport interface TrackingConsent {\n /** PostHog: full mode (cookies + identify) vs the cookieless baseline. */\n analytics: boolean;\n /** Meta Pixel (the only marketing-category tracker). */\n marketing: boolean;\n}\n\n/** `null` = no decision recorded yet → the banner should be shown. */\nexport type ConsentState = TrackingConsent | null;\n\nexport const CONSENT_COOKIE_NAME = \"uninspired_consent\";\n\n/** 180 days, aligned with the PostHog `cookie_expiration` config. */\nexport const CONSENT_COOKIE_MAX_AGE_SECONDS = 15_552_000;\n\nexport function parseConsentCookieValue(\n value: string | undefined | null,\n): ConsentState {\n if (!value) return null;\n const params = new URLSearchParams(value);\n const analytics = params.get(\"a\");\n const marketing = params.get(\"m\");\n if (analytics === null && marketing === null) return null;\n return { analytics: analytics === \"1\", marketing: marketing === \"1\" };\n}\n\nexport function serializeConsentCookieValue(consent: TrackingConsent): string {\n return new URLSearchParams({\n a: consent.analytics ? \"1\" : \"0\",\n m: consent.marketing ? \"1\" : \"0\",\n }).toString();\n}\n\n/** Reads the consent cookie out of a raw `Cookie:` request header. */\nexport function readConsentFromCookieHeader(\n cookieHeader: string | undefined,\n): ConsentState {\n if (!cookieHeader) return null;\n for (const part of cookieHeader.split(\";\")) {\n const trimmed = part.trim();\n if (!trimmed) continue;\n const separator = trimmed.indexOf(\"=\");\n if (separator === -1) continue;\n const key = trimmed.slice(0, separator);\n if (key !== CONSENT_COOKIE_NAME) continue;\n return parseConsentCookieValue(\n decodeURIComponent(trimmed.slice(separator + 1)),\n );\n }\n return null;\n}\n\nexport function hasAnalyticsConsent(consent: ConsentState): boolean {\n return consent?.analytics === true;\n}\n\nexport function hasMarketingConsent(consent: ConsentState): boolean {\n return consent?.marketing === true;\n}\n","import { z } from \"zod\";\n\nconst paddleSubscriptionSchema = z.object({\n id: z.string(),\n createdAt: z.coerce.date(),\n status: z.string(),\n items: z.array(\n z.object({\n priceId: z.string(),\n productId: z.string(),\n }),\n ),\n});\n\nexport const paddleTransactionSchema = z.object({\n id: z.string(),\n createdAt: z.coerce.date(),\n adjustments: z.array(\n z.object({\n id: z.string(),\n createdAt: z.coerce.date(),\n action: z.enum([\n \"credit\",\n \"refund\",\n \"chargeback\",\n \"chargeback_reverse\",\n \"chargeback_warning\",\n \"chargeback_warning_reverse\",\n \"credit_reverse\",\n ]),\n type: z.enum([\"full\", \"partial\"]),\n status: z.enum([\"pending_approval\", \"approved\", \"rejected\", \"reversed\"]),\n }),\n ),\n items: z.array(z.string()),\n});\n\nconst stripeSubscriptionSchema = z.object({\n id: z.string(),\n customerId: z.string(),\n created: z.coerce.date(),\n status: z.enum([\n \"active\",\n \"trialing\",\n \"canceled\",\n \"past_due\",\n \"paused\",\n \"incomplete\",\n \"incomplete_expired\",\n \"unpaid\",\n ]),\n items: z.array(z.string()),\n});\n\nexport const stripeDataSchema = z.array(stripeSubscriptionSchema);\n\nexport type StripeData = z.infer<typeof stripeDataSchema>;\n\nexport const paddleDataSchema = z.object({\n customerId: z.string().optional(),\n subscriptions: z.array(paddleSubscriptionSchema),\n transactions: z.array(paddleTransactionSchema),\n});\n\nexport type PaddleData = z.infer<typeof paddleDataSchema>;\n\nexport const userPurchasesSchema = z.object({\n stripe: stripeDataSchema,\n paddle: paddleDataSchema,\n});\n\nexport type UserPurchases = z.infer<typeof userPurchasesSchema>;\n\nexport type PaddleTransactionAdjustment = z.infer<\n typeof paddleTransactionSchema\n>[\"adjustments\"][number];\n\n/**\n * Shared ownership semantics: Paddle adjustment payloads do not tell us which\n * price a partial refund targeted, so we treat only full refunds and approved\n * chargebacks as revoking the whole transaction. A partial refund must NOT\n * revoke every price on a multi-price transaction. A successfully disputed\n * (reversed) chargeback restores ownership.\n */\nexport function isPaddleTransactionRevoked(\n adjustments: PaddleTransactionAdjustment[],\n): boolean {\n const hasRevokingAdjustment = adjustments.some(\n (adj) =>\n adj.status === \"approved\" &&\n (adj.action === \"chargeback\" ||\n (adj.action === \"refund\" && adj.type === \"full\")),\n );\n if (!hasRevokingAdjustment) return false;\n\n // A won dispute reverses the chargeback and restores ownership.\n const chargebackReversed = adjustments.some(\n (adj) => adj.action === \"chargeback_reverse\" && adj.status === \"approved\",\n );\n if (chargebackReversed) return false;\n\n return true;\n}\n","/**\n * TanStack Router's defaultParseSearch always does two things, in order:\n * 1. URLSearchParams decoding (and, for repeated keys, aggregation into arrays)\n * 2. JSON.parse on remaining string values\n *\n * Callers that build URLs with URLSearchParams.set(JSON.stringify(...)) — this\n * package's auth-client, magic-link callback URLs, checkout recovery links —\n * round-trip through that pipeline. Callers that only URL-decode, or that\n * stringify arrays with String(array), leave a JSON or comma-separated string.\n *\n * These helpers accept both shapes so validateSearch does not depend on which\n * of those two steps already ran.\n */\n\nconst JSON_PARSE_FAILED = Symbol(\"json-parse-failed\");\n\nexport function parsePossiblyEncodedJson(value: unknown): unknown {\n if (typeof value !== \"string\") return value;\n\n const tryParse = (raw: string): unknown => {\n try {\n return JSON.parse(raw);\n } catch {\n return JSON_PARSE_FAILED;\n }\n };\n\n const direct = tryParse(value);\n if (direct !== JSON_PARSE_FAILED) return direct;\n\n try {\n const decoded = decodeURIComponent(value);\n if (decoded !== value) {\n const nested = tryParse(decoded);\n if (nested !== JSON_PARSE_FAILED) return nested;\n }\n } catch {\n // Malformed percent-encoding is left as the original string.\n }\n\n return value;\n}\n\nexport function parseSearchStringList(value: unknown): string[] | undefined {\n if (value === undefined || value === null || value === \"\") return undefined;\n\n if (Array.isArray(value)) {\n if (value.every((item) => typeof item === \"string\")) {\n return value.length > 0 ? value : undefined;\n }\n return undefined;\n }\n\n if (typeof value !== \"string\") return undefined;\n\n const parsed = parsePossiblyEncodedJson(value);\n if (\n Array.isArray(parsed) &&\n parsed.every((item) => typeof item === \"string\")\n ) {\n return parsed.length > 0 ? parsed : undefined;\n }\n\n if (typeof parsed !== \"string\") return undefined;\n\n const ids = parsed\n .split(\",\")\n .map((id) => id.trim())\n .filter(Boolean);\n return ids.length > 0 ? ids : undefined;\n}\n","import { z } from \"zod\";\nimport { parsePossiblyEncodedJson } from \"./searchParams\";\n\nexport const checkoutIntentSchema = z.object({\n type: z.literal(\"checkout\"),\n priceId: z.string(),\n additionalPriceIds: z.array(z.string()).optional(),\n productId: z.string().optional(),\n discountCode: z.string().optional(),\n loginUrl: z\n .string()\n .refine((v) => {\n const url = decodeURIComponent(v);\n return z.url().safeParse(url).success;\n })\n .transform((v) => decodeURIComponent(v))\n .optional(),\n pricingUrl: z\n .string()\n .refine((v) => {\n const url = decodeURIComponent(v);\n return z.url().safeParse(url).success;\n })\n .transform((v) => decodeURIComponent(v))\n .optional(),\n successUrl: z\n .string()\n .refine((v) => {\n const url = decodeURIComponent(v);\n return z.url().safeParse(url).success;\n })\n .transform((v) => decodeURIComponent(v))\n .optional(),\n});\nexport type CheckoutIntent = z.infer<typeof checkoutIntentSchema>;\n\nexport const redirectIntentSchema = z.object({\n type: z.literal(\"redirect\"),\n redirectUrl: z.url(),\n appName: z.string().optional(),\n});\nexport type RedirectIntent = z.infer<typeof redirectIntentSchema>;\n\nexport const authRouteIntentSchema = z.object({\n type: z.literal(\"auth\"),\n returnUrl: z.string(),\n});\nexport type AuthRouteIntent = z.infer<typeof authRouteIntentSchema>;\n\nexport const intentSchema = z.discriminatedUnion(\"type\", [\n checkoutIntentSchema,\n redirectIntentSchema,\n authRouteIntentSchema,\n]);\nexport type Intent = z.infer<typeof intentSchema>;\n\nexport const intentSearchParamSchema = z\n .union([intentSchema, z.string()])\n .optional()\n .transform((value) => {\n if (value === undefined) return undefined;\n if (typeof value !== \"string\") return value;\n return intentSchema.parse(parsePossiblyEncodedJson(value));\n });\n\nexport const intentSearchSchema = z.object({\n intent: intentSearchParamSchema,\n /** Preserved through login redirect so client can rebuild `_fbc` if cookies were blocked. */\n fbclid: z.string().optional(),\n});\n","import { z } from \"zod\";\nimport { parseSearchStringList } from \"./searchParams\";\n\nexport const additionalPriceIdsSearchSchema = z\n .union([z.array(z.string()), z.string()])\n .optional()\n .transform((value) => parseSearchStringList(value));\n\n// Safe decode: decodeURIComponent throws URIError on malformed sequences\n// (e.g. \"%\"), which would otherwise crash route validation.\nfunction safeDecodeURIComponent(value: string): string {\n try {\n return decodeURIComponent(value);\n } catch {\n return value;\n }\n}\n\n// URL fields are rendered into links and redirects by the app, so only\n// http/https are acceptable (z.url() alone also allows javascript:, etc.).\nfunction httpUrlSchema() {\n return z\n .string()\n .refine((v) => {\n const url = safeDecodeURIComponent(v);\n const parsed = z.url().safeParse(url);\n if (!parsed.success) return false;\n const protocol = new URL(url).protocol;\n return protocol === \"http:\" || protocol === \"https:\";\n })\n .transform(safeDecodeURIComponent);\n}\n\nexport const checkoutSearchSchema = z.object({\n priceId: z.string(),\n additionalPriceIds: additionalPriceIdsSearchSchema,\n productId: z.string(),\n quantity: z.coerce.number().int().min(1).max(999).optional(),\n discountCode: z.string().optional(),\n loginUrl: httpUrlSchema().optional(),\n pricingUrl: httpUrlSchema().optional(),\n successUrl: httpUrlSchema().optional(),\n fbclid: z.string().optional(),\n ref: z.string().optional(),\n});\n\nexport type CheckoutSearch = z.infer<typeof checkoutSearchSchema>;\n\nexport const checkoutValidationErrorCodeSchema = z.enum([\n \"missing_purchases\",\n \"missing_customer\",\n \"invalid_redirect_hosts\",\n \"already_owned\",\n \"invalid_prices\",\n \"invalid_discount\",\n \"internal_server_error\",\n]);\n\nexport type CheckoutValidationErrorCode = z.infer<\n typeof checkoutValidationErrorCodeSchema\n>;\n\nexport type CheckoutValidationError = {\n code: CheckoutValidationErrorCode;\n message: string;\n};\n","import { z } from \"zod\";\nimport type { PaddlePriceCustomData } from \"./catalog\";\n\nexport const createPromoInputSchema = z.object({\n slug: z\n .string()\n .min(1)\n .max(64)\n .regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),\n productId: z.string().min(1),\n discountPercent: z.number().int().min(1).max(100),\n startsAt: z.coerce.date(),\n endsAt: z.coerce.date(),\n});\n\nexport type CreatePromoInput = z.infer<typeof createPromoInputSchema>;\n\nexport const updatePromoInputSchema = createPromoInputSchema.extend({\n id: z.string().min(1),\n});\n\nexport type UpdatePromoInput = z.infer<typeof updatePromoInputSchema>;\n\nexport const deletePromoInputSchema = z.object({\n id: z.string().min(1),\n});\n\nexport type DeletePromoInput = z.infer<typeof deletePromoInputSchema>;\n\nexport const promoListItemSchema = z.object({\n id: z.string(),\n slug: z.string(),\n productId: z.string(),\n discountPercent: z.number(),\n startsAt: z.coerce.date(),\n endsAt: z.coerce.date(),\n shortLinkUrl: z.string(),\n promoPageUrl: z.string(),\n createdAt: z.coerce.date(),\n});\n\nexport type PromoListItem = z.infer<typeof promoListItemSchema>;\n\nexport const promoProductSelectPricePreviewSchema = z.object({\n currencyCode: z.string(),\n originalAmount: z.string(),\n originalFormatted: z.string(),\n});\n\nexport type PromoProductSelectPricePreview = z.infer<\n typeof promoProductSelectPricePreviewSchema\n>;\n\nexport const promoProductSelectPriceSchema = z.object({\n id: z.string(),\n name: z.string().nullable(),\n description: z.string().nullable(),\n customData: z.custom<PaddlePriceCustomData | null>(\n (val) => val === null || typeof val === \"object\",\n ).nullable(),\n billingCycle: z\n .object({\n interval: z.enum([\"day\", \"week\", \"month\", \"year\"]),\n frequency: z.number(),\n })\n .nullable(),\n unitPrice: z\n .object({\n amount: z.string(),\n currencyCode: z.string(),\n })\n .nullable(),\n unitPriceOverrides: z\n .array(\n z.object({\n countryCodes: z.array(z.string()),\n unitPrice: z.object({\n amount: z.string(),\n currencyCode: z.string(),\n }),\n }),\n )\n .nullable(),\n owned: z.boolean(),\n preview: promoProductSelectPricePreviewSchema.optional(),\n});\n\nexport const promoProductSelectSchema = z.object({\n slug: z.string(),\n productId: z.string(),\n productName: z.string(),\n productDescription: z.string().nullable(),\n discountPercent: z.number(),\n isActive: z.boolean(),\n alreadyRedeemed: z.boolean(),\n prices: z.array(promoProductSelectPriceSchema),\n});\n\nexport type PromoProductSelect = z.infer<typeof promoProductSelectSchema>;\n\nexport const createPromoCheckoutDiscountResponseSchema = z.object({\n discountCode: z.string(),\n checkoutUrl: z.string(),\n});\n\nexport type CreatePromoCheckoutDiscountResponse = z.infer<\n typeof createPromoCheckoutDiscountResponseSchema\n>;\n\nexport const createPromoCheckoutDiscountInputSchema = z.object({\n slug: z.string().min(1),\n priceId: z.string().min(1),\n});\n","import { z } from \"zod\";\nimport { promoProductSelectPriceSchema } from \"./promo\";\n\n/** Search params for affiliate product landing pages (accounts frontend). */\nexport const affiliateLandingSearchSchema = z.object({\n ref: z.string(),\n fbclid: z.string().optional(),\n});\n\nexport type AffiliateLandingSearch = z.infer<typeof affiliateLandingSearchSchema>;\n\nexport const affiliateProductSelectSchema = z.object({\n productId: z.string(),\n productName: z.string(),\n productDescription: z.string().nullable(),\n discountPercent: z.number(),\n valid: z.boolean(),\n prices: z.array(promoProductSelectPriceSchema),\n});\n\nexport type AffiliateProductSelect = z.infer<typeof affiliateProductSelectSchema>;\n\nexport const createAffiliateCheckoutDiscountInputSchema = z.object({\n productId: z.string().min(1),\n priceId: z.string().min(1),\n ref: z.string().min(1),\n});\n\nexport type CreateAffiliateCheckoutDiscountInput = z.infer<\n typeof createAffiliateCheckoutDiscountInputSchema\n>;\n\nexport const createAffiliateCheckoutDiscountResponseSchema = z.object({\n discountCode: z.string(),\n checkoutUrl: z.string(),\n});\n\nexport type CreateAffiliateCheckoutDiscountResponse = z.infer<\n typeof createAffiliateCheckoutDiscountResponseSchema\n>;\n","import { z } from \"zod\";\n\nexport const deleteAuthDataInputSchema = z.object({\n email: z.email(),\n stripeCustomerIds: z.array(z.string()).optional(),\n});\n\nexport type DeleteAuthDataInput = z.infer<typeof deleteAuthDataInputSchema>;\n\nexport type AuthUserSummary = {\n id: string;\n email: string;\n name: string;\n createdAt: number;\n};\n\nexport type AuthDataLookup = {\n user: AuthUserSummary | null;\n verificationCount: number;\n paddle: {\n customerIds: string[];\n subscriptionCount: number;\n transactionCount: number;\n };\n stripe: {\n subscriptionCount: number;\n };\n tolt: {\n partnerIds: string[];\n customerIds: string[];\n };\n};\n\nexport type DeleteAuthDataResult = {\n deleted: boolean;\n userId: string | null;\n};\n\nexport const deleteAffiliatesDataInputSchema = z.object({\n email: z.email(),\n});\n\nexport type DeleteAffiliatesDataInput = z.infer<\n typeof deleteAffiliatesDataInputSchema\n>;\n\nexport type AffiliatesUserSummary = {\n id: string;\n email: string;\n name: string;\n};\n\nexport type AffiliatesDataLookup = {\n user: AffiliatesUserSummary | null;\n verificationCount: number;\n};\n\nexport type DeleteAffiliatesDataResult = {\n deleted: boolean;\n userId: string | null;\n};\n\nexport type DataDeletionSystemId =\n | \"paddle\"\n | \"stripe\"\n | \"tolt\"\n | \"affiliatesD1\"\n | \"posthog\"\n | \"plunk\"\n | \"authD1\";\n\nexport type DataDeletionStepStatus = \"pending\" | \"running\" | \"waiting\" | \"done\" | \"error\";\n\nexport type DataDeletionStepResult = {\n system: DataDeletionSystemId;\n status: \"success\" | \"error\" | \"skipped\";\n message?: string;\n details?: string[];\n};\n\n/** JSON-safe value for data-export dumps (dates as epoch ms). */\nexport type DataExportJsonValue =\n | string\n | number\n | boolean\n | null\n | DataExportJsonValue[]\n | { [key: string]: DataExportJsonValue };\n\nexport type AuthDataExport = {\n email: string;\n user: DataExportJsonValue | null;\n sessions: DataExportJsonValue[];\n accounts: DataExportJsonValue[];\n passkeys: DataExportJsonValue[];\n verifications: DataExportJsonValue[];\n paddleCustomers: DataExportJsonValue[];\n paddleSubscriptions: DataExportJsonValue[];\n paddleSubscriptionItems: DataExportJsonValue[];\n paddleTransactions: DataExportJsonValue[];\n paddleTransactionItems: DataExportJsonValue[];\n paddleAdjustments: DataExportJsonValue[];\n stripeCustomers: DataExportJsonValue[];\n stripeSubscriptions: DataExportJsonValue[];\n stripeSubscriptionItems: DataExportJsonValue[];\n toltPartners: DataExportJsonValue[];\n toltCustomers: DataExportJsonValue[];\n toltLinks: DataExportJsonValue[];\n toltCommissions: DataExportJsonValue[];\n toltTransactions: DataExportJsonValue[];\n toltPromotionCodes: DataExportJsonValue[];\n};\n\nexport type AffiliatesDataExport = {\n email: string;\n user: DataExportJsonValue | null;\n sessions: DataExportJsonValue[];\n accounts: DataExportJsonValue[];\n verifications: DataExportJsonValue[];\n};\n","import {\n CONSENT_COOKIE_MAX_AGE_SECONDS,\n CONSENT_COOKIE_NAME,\n parseConsentCookieValue,\n serializeConsentCookieValue,\n type ConsentState,\n type TrackingConsent,\n} from \"@us-auth/types\";\n\ntype Listener = () => void;\n\nconst listeners = new Set<Listener>();\n\nlet configuredDomain: string | undefined;\nlet hasSnapshot = false;\nlet snapshot: ConsentState = null;\n\nfunction readFromDocument(): ConsentState {\n if (typeof document === \"undefined\") return null;\n const prefix = `${CONSENT_COOKIE_NAME}=`;\n const match = document.cookie\n .split(\";\")\n .map((part) => part.trim())\n .find((part) => part.startsWith(prefix));\n if (!match) return null;\n return parseConsentCookieValue(\n decodeURIComponent(match.slice(prefix.length)),\n );\n}\n\nfunction emit(): void {\n for (const listener of listeners) listener();\n}\n\nfunction isSameConsent(a: ConsentState, b: ConsentState): boolean {\n return a?.analytics === b?.analytics && a?.marketing === b?.marketing;\n}\n\n/**\n * The imperative consent API. This is the single source of truth for the\n * banner and works without React.\n */\nexport function getConsent(): ConsentState {\n if (!hasSnapshot) {\n snapshot = readFromDocument();\n hasSnapshot = true;\n }\n return snapshot;\n}\n\nexport function isConsentPending(): boolean {\n return getConsent() === null;\n}\n\nexport function subscribeConsent(listener: Listener): () => void {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n}\n\n/** Overrides the cookie domain; `undefined` derives it, `\"\"` forces host-only. */\nexport function configureConsentDomain(domain: string | undefined): void {\n configuredDomain = domain;\n}\n\n/** Parent domain for consent and legacy-tracking cookie expiry. */\nexport function resolveConsentCookieDomain(): string | undefined {\n if (configuredDomain !== undefined) return configuredDomain || undefined;\n if (typeof location === \"undefined\") return undefined;\n const { hostname } = location;\n if (hostname === \"uninspired.app\" || hostname.endsWith(\".uninspired.app\")) {\n return \".uninspired.app\";\n }\n return undefined;\n}\n\nfunction writeConsentCookie(consent: TrackingConsent): void {\n if (typeof document === \"undefined\") return;\n const parts = [\n `${CONSENT_COOKIE_NAME}=${encodeURIComponent(serializeConsentCookieValue(consent))}`,\n \"Path=/\",\n `Max-Age=${CONSENT_COOKIE_MAX_AGE_SECONDS}`,\n \"SameSite=Lax\",\n ];\n if (typeof location !== \"undefined\" && location.protocol === \"https:\") {\n parts.push(\"Secure\");\n }\n const domain = resolveConsentCookieDomain();\n if (domain) parts.push(`Domain=${domain}`);\n document.cookie = parts.join(\"; \");\n}\n\n/** Writes the decision and notifies subscribers. The only consent writer. */\nexport function setConsent(consent: TrackingConsent): void {\n writeConsentCookie(consent);\n snapshot = consent;\n hasSnapshot = true;\n emit();\n}\n\n/** Re-reads the cookie and notifies only when the decision changed. */\nexport function refreshConsent(): void {\n const next = readFromDocument();\n if (isSameConsent(next, snapshot) && hasSnapshot) return;\n snapshot = next;\n hasSnapshot = true;\n emit();\n}\n","import { useSyncExternalStore } from \"react\";\nimport type { ConsentState } from \"@us-auth/types\";\nimport { getConsent, setConsent, subscribeConsent } from \"./store\";\n\nexport interface TrackingConsentApi {\n consent: ConsentState;\n pending: boolean;\n setConsent: (consent: { analytics: boolean; marketing: boolean }) => void;\n}\n\nconst getServerSnapshot = (): ConsentState => null;\n\n/**\n * Banner-facing hook. Works without `TrackingProvider` because it reads the\n * consent store directly.\n */\nexport function useTrackingConsent(): TrackingConsentApi {\n const consent = useSyncExternalStore(\n subscribeConsent,\n getConsent,\n getServerSnapshot,\n );\n\n return {\n consent,\n pending: consent === null,\n setConsent,\n };\n}","import { CONSENT_COOKIE_NAME } from \"@us-auth/types\";\nimport {\n getConsent,\n refreshConsent,\n resolveConsentCookieDomain,\n} from \"./store\";\n\nconst EXACT_TRACKING_KEYS = new Set([\"_fbp\", \"_fbc\", \"uninspired_ph_consent\"]);\n\n/** Whether a cookie or storage key is a leftover PostHog / Meta tracker. */\nexport function isLegacyTrackingKey(key: string): boolean {\n if (EXACT_TRACKING_KEYS.has(key)) return true;\n if (key.startsWith(\"ph_\")) return true;\n if (key.startsWith(\"__ph_opt_in_out_\")) return true;\n return false;\n}\n\nfunction expireCookie(name: string): void {\n const domain = resolveConsentCookieDomain();\n const base = `${name}=; Path=/; Max-Age=0; SameSite=Lax`;\n document.cookie = base;\n if (domain) document.cookie = `${base}; Domain=${domain}`;\n}\n\nfunction purgeStorage(store: Storage): void {\n const keys: string[] = [];\n for (let i = 0; i < store.length; i++) {\n const key = store.key(i);\n if (key && isLegacyTrackingKey(key)) keys.push(key);\n }\n for (const key of keys) store.removeItem(key);\n}\n\n/**\n * Deletes leftover PostHog and Meta cookies/storage when consent is still\n * pending. Idempotent; no-ops once `uninspired_consent` exists.\n */\nexport function purgeLegacyTracking(): void {\n if (typeof document === \"undefined\") return;\n refreshConsent();\n if (getConsent() !== null) return;\n\n const names: string[] = [];\n for (const part of document.cookie.split(\";\")) {\n const trimmed = part.trim();\n if (!trimmed) continue;\n const eq = trimmed.indexOf(\"=\");\n const name = eq === -1 ? trimmed : trimmed.slice(0, eq);\n if (name === CONSENT_COOKIE_NAME) continue;\n if (isLegacyTrackingKey(name)) names.push(name);\n }\n for (const name of names) expireCookie(name);\n\n try {\n if (typeof localStorage !== \"undefined\") purgeStorage(localStorage);\n } catch {\n // private mode / blocked storage\n }\n try {\n if (typeof sessionStorage !== \"undefined\") purgeStorage(sessionStorage);\n } catch {\n // private mode / blocked storage\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uninspired/auth-client",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Auth client for Uninspired Studio Products",
|
|
5
5
|
"author": "Chris Kolb <chris@uninspired.studio>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -12,6 +12,11 @@
|
|
|
12
12
|
"types": "./dist/index.d.ts",
|
|
13
13
|
"import": "./dist/index.js",
|
|
14
14
|
"default": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./cookie-banner": {
|
|
17
|
+
"types": "./dist/cookie-banner.d.ts",
|
|
18
|
+
"import": "./dist/cookie-banner.js",
|
|
19
|
+
"default": "./dist/cookie-banner.js"
|
|
15
20
|
}
|
|
16
21
|
},
|
|
17
22
|
"files": [
|
|
@@ -27,17 +32,26 @@
|
|
|
27
32
|
"types": "./dist/index.d.ts",
|
|
28
33
|
"import": "./dist/index.js",
|
|
29
34
|
"default": "./dist/index.js"
|
|
35
|
+
},
|
|
36
|
+
"./cookie-banner": {
|
|
37
|
+
"types": "./dist/cookie-banner.d.ts",
|
|
38
|
+
"import": "./dist/cookie-banner.js",
|
|
39
|
+
"default": "./dist/cookie-banner.js"
|
|
30
40
|
}
|
|
31
41
|
}
|
|
32
42
|
},
|
|
33
43
|
"scripts": {
|
|
34
|
-
"build": "tsdown --config tsdown.config.ts",
|
|
44
|
+
"build": "bunx --bun tsdown --config tsdown.config.ts",
|
|
35
45
|
"check": "tsc --noEmit",
|
|
36
46
|
"lint": "eslint .",
|
|
47
|
+
"test": "bun test",
|
|
37
48
|
"prepack": "bun run build && node ../../scripts/apply-publish-config.mjs apply",
|
|
38
49
|
"postpack": "node ../../scripts/apply-publish-config.mjs restore"
|
|
39
50
|
},
|
|
40
51
|
"devDependencies": {
|
|
52
|
+
"@radix-ui/react-dialog": "^1.1.23",
|
|
53
|
+
"@subframe/core": "^1.155.0",
|
|
54
|
+
"@us-auth/components": "workspace:*",
|
|
41
55
|
"@us-auth/types": "workspace:*",
|
|
42
56
|
"@types/bun": "latest",
|
|
43
57
|
"@types/react": "^19",
|
|
@@ -51,13 +65,23 @@
|
|
|
51
65
|
"typescript": "^5",
|
|
52
66
|
"react": "^19",
|
|
53
67
|
"react-dom": "^19",
|
|
54
|
-
"@
|
|
68
|
+
"@subframe/core": "^1.155.0",
|
|
69
|
+
"@radix-ui/react-dialog": "^1.1.10"
|
|
70
|
+
},
|
|
71
|
+
"peerDependenciesMeta": {
|
|
72
|
+
"@subframe/core": {
|
|
73
|
+
"optional": true
|
|
74
|
+
},
|
|
75
|
+
"@radix-ui/react-dialog": {
|
|
76
|
+
"optional": true
|
|
77
|
+
}
|
|
55
78
|
},
|
|
56
79
|
"dependencies": {
|
|
57
80
|
"@better-auth/passkey": "^1.5.5",
|
|
58
81
|
"@tanstack/react-query": "^5.90.21",
|
|
59
82
|
"better-auth": "^1.5.5",
|
|
60
83
|
"hono": "^4.12.7",
|
|
84
|
+
"posthog-js": "^1.433.1",
|
|
61
85
|
"zod": "^4.3.6"
|
|
62
86
|
},
|
|
63
87
|
"module": "./dist/index.js"
|