@uninspired/auth-client 1.0.20 → 1.0.21
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 +51 -2
- package/dist/index.d.ts +45 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -34,13 +34,57 @@ bun add react react-dom
|
|
|
34
34
|
| **Login URL builder** | Generate a link to the accounts page with a post-login redirect back to your app |
|
|
35
35
|
| **Checkout URL builder** | Generate a link to the hosted checkout flow |
|
|
36
36
|
| **Newsletter** | Subscribe/unsubscribe from mailing lists |
|
|
37
|
-
| **PostHog integration** | Auto-identify users in PostHog when authenticated
|
|
37
|
+
| **PostHog integration** | Auto-identify users in PostHog when authenticated; product super property, `feature used`, and `checkout started` helpers |
|
|
38
38
|
| **Meta ad attribution** | Auto-capture `fbclid` → `_fbc`/`_fbp` cookies; `trackViewContent` / `trackMetaEvent` for CAPI (no Pixel JS, no PII) |
|
|
39
39
|
|
|
40
40
|
Authentication methods (magic link, email OTP, passkey) are handled on the accounts page — this client manages sessions and purchase data, not the login UI itself.
|
|
41
41
|
|
|
42
42
|
## Quick start (React)
|
|
43
43
|
|
|
44
|
+
Wrap `PostHogProvider` **above** `AuthProvider`, pass `product`, then call analytics helpers from `useAuth()`:
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
import { PostHogProvider } from "@posthog/react";
|
|
48
|
+
import posthog from "posthog-js";
|
|
49
|
+
import { AuthProvider, useAuth } from "@uninspired/auth-client";
|
|
50
|
+
|
|
51
|
+
function App() {
|
|
52
|
+
return (
|
|
53
|
+
<PostHogProvider client={posthog}>
|
|
54
|
+
<AuthProvider
|
|
55
|
+
baseUrl="https://auth.uninspired.app"
|
|
56
|
+
frontendUrl="https://uninspired.app"
|
|
57
|
+
product="mixd"
|
|
58
|
+
>
|
|
59
|
+
<MyApp />
|
|
60
|
+
</AuthProvider>
|
|
61
|
+
</PostHogProvider>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function MyApp() {
|
|
66
|
+
const { captureFeatureUsed } = useAuth();
|
|
67
|
+
|
|
68
|
+
function onExport() {
|
|
69
|
+
captureFeatureUsed("export video", { format: "mp4" });
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// ...
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Vanilla helpers (no React) are also exported:
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import {
|
|
80
|
+
captureFeatureUsed,
|
|
81
|
+
captureCheckoutStarted,
|
|
82
|
+
registerProduct,
|
|
83
|
+
} from "@uninspired/auth-client";
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Quick start (React, auth only)
|
|
87
|
+
|
|
44
88
|
```tsx
|
|
45
89
|
import { AuthProvider, useAuth } from "@uninspired/auth-client";
|
|
46
90
|
|
|
@@ -197,6 +241,7 @@ See [docs/ad-attribution.md](../../docs/ad-attribution.md).
|
|
|
197
241
|
| ------------------ | ------------------------ | ----------------------------- |
|
|
198
242
|
| `baseUrl` | `string` | Auth API URL |
|
|
199
243
|
| `frontendUrl` | `string` | Accounts frontend URL |
|
|
244
|
+
| `product` | `AnalyticsProduct?` | Registers PostHog super property on mount (`mixd`, `momentum`, `unpinned`, `accounts`) |
|
|
200
245
|
| `initialSession` | `Session \| null?` | Pre-fetched session for SSR |
|
|
201
246
|
| `initialPurchases` | `UserPurchases \| null?` | Pre-fetched purchases for SSR |
|
|
202
247
|
| `authClient` | `AuthClient?` | Custom client instance |
|
|
@@ -208,7 +253,8 @@ The provider automatically:
|
|
|
208
253
|
2. Signs in anonymously only after revalidation confirms no session exists
|
|
209
254
|
3. Fetches purchases when a session is available
|
|
210
255
|
4. Identifies the user in PostHog when authenticated
|
|
211
|
-
5.
|
|
256
|
+
5. Registers the `product` super property when `product` is set
|
|
257
|
+
6. Captures Meta click ids (`fbclid` → `_fbc`/`_fbp`) on mount
|
|
212
258
|
|
|
213
259
|
### `useAuth()` return value
|
|
214
260
|
|
|
@@ -227,6 +273,9 @@ The provider automatically:
|
|
|
227
273
|
| `trackMetaEvent` | `AuthClient["trackMetaEvent"]` | Send Meta CAPI event (no PII) |
|
|
228
274
|
| `trackViewContent` | `AuthClient["trackViewContent"]` | Convenience wrapper for product views |
|
|
229
275
|
| `getMetaAttribution` | `AuthClient["getMetaAttribution"]` | Read `_fbc` / `_fbp` cookies |
|
|
276
|
+
| `captureFeatureUsed` | `(featureName, extra?) => void` | PostHog `feature used` event |
|
|
277
|
+
| `captureCheckoutStarted` | `({ plan, product? }) => void` | PostHog `checkout started` event |
|
|
278
|
+
| `registerProduct` | `(product) => void` | Override PostHog `product` super property |
|
|
230
279
|
| `isPurchased` | `(priceIds: string[]) => boolean` | Check one-time purchase |
|
|
231
280
|
| `isSubscribed` | `(priceIds: string[], productId: string) => boolean` | Check active subscription |
|
|
232
281
|
|
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,21 @@ import { QueryClient } from "@tanstack/react-query";
|
|
|
5
5
|
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|
|
6
6
|
import { Session as Session$1, User } from "better-auth";
|
|
7
7
|
|
|
8
|
+
//#region ../types/src/analytics.d.ts
|
|
9
|
+
declare const ANALYTICS_PRODUCTS: readonly ["mixd", "momentum", "unpinned", "accounts"];
|
|
10
|
+
type AnalyticsProduct = (typeof ANALYTICS_PRODUCTS)[number];
|
|
11
|
+
declare const ANALYTICS_EVENTS: {
|
|
12
|
+
readonly USER_SIGNED_UP: "user signed up";
|
|
13
|
+
readonly USER_LOGGED_IN: "user logged in";
|
|
14
|
+
readonly TRIAL_STARTED: "trial started";
|
|
15
|
+
readonly CHECKOUT_STARTED: "checkout started";
|
|
16
|
+
readonly CHECKOUT_COMPLETED: "checkout completed";
|
|
17
|
+
readonly FEATURE_USED: "feature used";
|
|
18
|
+
};
|
|
19
|
+
type AnalyticsEvent = (typeof ANALYTICS_EVENTS)[keyof typeof ANALYTICS_EVENTS];
|
|
20
|
+
type AuthMethod = "magic_link" | "email_otp" | "passkey";
|
|
21
|
+
declare function isAnalyticsProduct(value: string): value is AnalyticsProduct;
|
|
22
|
+
//#endregion
|
|
8
23
|
//#region ../types/src/purchases.d.ts
|
|
9
24
|
declare const userPurchasesSchema: z.ZodObject<{
|
|
10
25
|
stripe: z.ZodArray<z.ZodObject<{
|
|
@@ -131,6 +146,21 @@ declare class AuthClient {
|
|
|
131
146
|
}) => string;
|
|
132
147
|
}
|
|
133
148
|
//#endregion
|
|
149
|
+
//#region src/analytics.d.ts
|
|
150
|
+
interface PostHogAnalyticsClient {
|
|
151
|
+
capture: (event: string, properties?: Record<string, unknown>) => void;
|
|
152
|
+
register?: (properties: Record<string, unknown>) => void;
|
|
153
|
+
}
|
|
154
|
+
declare function registerProduct(ph: PostHogAnalyticsClient | null | undefined, product: AnalyticsProduct): void;
|
|
155
|
+
declare function captureFeatureUsed(ph: PostHogAnalyticsClient | null | undefined, featureName: string, extra?: Record<string, unknown>): void;
|
|
156
|
+
declare function captureCheckoutStarted(ph: PostHogAnalyticsClient | null | undefined, {
|
|
157
|
+
plan,
|
|
158
|
+
product
|
|
159
|
+
}: {
|
|
160
|
+
plan: string;
|
|
161
|
+
product?: AnalyticsProduct;
|
|
162
|
+
}): void;
|
|
163
|
+
//#endregion
|
|
134
164
|
//#region src/react/AuthContext.d.ts
|
|
135
165
|
type AuthContextType = {
|
|
136
166
|
session: Session | null;
|
|
@@ -145,6 +175,12 @@ type AuthContextType = {
|
|
|
145
175
|
trackMetaEvent: AuthClient["trackMetaEvent"];
|
|
146
176
|
trackViewContent: AuthClient["trackViewContent"];
|
|
147
177
|
getMetaAttribution: AuthClient["getMetaAttribution"];
|
|
178
|
+
captureFeatureUsed: (featureName: string, extra?: Record<string, unknown>) => void;
|
|
179
|
+
captureCheckoutStarted: (options: {
|
|
180
|
+
plan: string;
|
|
181
|
+
product?: AnalyticsProduct;
|
|
182
|
+
}) => void;
|
|
183
|
+
registerProduct: (product: AnalyticsProduct) => void;
|
|
148
184
|
isPurchased: (priceIds: string[]) => boolean;
|
|
149
185
|
isSubscribed: (priceIds: string[], productId: string) => boolean;
|
|
150
186
|
isLoggedIn: boolean;
|
|
@@ -157,6 +193,7 @@ interface AuthProviderProps extends PropsWithChildren {
|
|
|
157
193
|
queryClient?: QueryClient;
|
|
158
194
|
baseUrl: string;
|
|
159
195
|
frontendUrl: string;
|
|
196
|
+
product?: AnalyticsProduct;
|
|
160
197
|
initialSession?: Session | null;
|
|
161
198
|
initialPurchases?: UserPurchases | null;
|
|
162
199
|
}
|
|
@@ -164,6 +201,7 @@ declare const AuthProvider: ({
|
|
|
164
201
|
children,
|
|
165
202
|
baseUrl,
|
|
166
203
|
frontendUrl,
|
|
204
|
+
product,
|
|
167
205
|
initialSession,
|
|
168
206
|
initialPurchases,
|
|
169
207
|
authClient: providedAuthClient,
|
|
@@ -184,10 +222,16 @@ declare function useAuth(): {
|
|
|
184
222
|
trackMetaEvent: AuthClient["trackMetaEvent"];
|
|
185
223
|
trackViewContent: AuthClient["trackViewContent"];
|
|
186
224
|
getMetaAttribution: AuthClient["getMetaAttribution"];
|
|
225
|
+
captureFeatureUsed: (featureName: string, extra?: Record<string, unknown>) => void;
|
|
226
|
+
captureCheckoutStarted: (options: {
|
|
227
|
+
plan: string;
|
|
228
|
+
product?: AnalyticsProduct;
|
|
229
|
+
}) => void;
|
|
230
|
+
registerProduct: (product: AnalyticsProduct) => void;
|
|
187
231
|
isPurchased: (priceIds: string[]) => boolean;
|
|
188
232
|
isSubscribed: (priceIds: string[], productId: string) => boolean;
|
|
189
233
|
isLoggedIn: boolean;
|
|
190
234
|
};
|
|
191
235
|
//#endregion
|
|
192
|
-
export { AuthClient, AuthContext, AuthContextType, AuthProvider, AuthProviderProps, type MetaAttributionCookies, type Session, type UserPurchases, buildFbcFromFbclid, captureMetaClickId, getMetaCookieDomain, parseMetaAttributionFromCookieHeader, readMetaAttributionCookies, useAuth };
|
|
236
|
+
export { ANALYTICS_EVENTS, ANALYTICS_PRODUCTS, type AnalyticsEvent, type AnalyticsProduct, AuthClient, AuthContext, AuthContextType, type AuthMethod, AuthProvider, AuthProviderProps, type MetaAttributionCookies, PostHogAnalyticsClient, type Session, type UserPurchases, buildFbcFromFbclid, captureCheckoutStarted, captureFeatureUsed, captureMetaClickId, getMetaCookieDomain, isAnalyticsProduct, parseMetaAttributionFromCookieHeader, readMetaAttributionCookies, registerProduct, useAuth };
|
|
193
237
|
//# sourceMappingURL=index.d.ts.map
|
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{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 _=[`mixd`,`momentum`,`unpinned`,`accounts`],v={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 y(e){return _.includes(e)}const b=o.object({id:o.string(),createdAt:o.coerce.date(),status:o.string(),items:o.array(o.object({priceId:o.string(),productId:o.string()}))}),x=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())}),S=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())}),C=o.array(S),w=o.object({customerId:o.string().optional(),subscriptions:o.array(b),transactions:o.array(x)});o.object({stripe:C,paddle:w});const T=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()}),E=o.object({type:o.literal(`redirect`),redirectUrl:o.url(),appName:o.string().optional()}),D=o.object({type:o.literal(`auth`),returnUrl:o.string()}),O=o.discriminatedUnion(`type`,[T,E,D]);o.object({intent:O.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 k=o.object({currencyCode:o.string(),originalAmount:o.string(),originalFormatted:o.string()}),A=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:k.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(A)}),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(A)}),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 j=o.enum([`ViewContent`,`InitiateCheckout`]);o.object({event_name:j,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 M(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 N(e,t=Date.now()){return`fb.1.${t}.${e}`}const P=`_fbc`,F=`_fbp`;function I(){return Math.floor(Math.random()*1e10).toString()}function L(e){let t=new URL(e).hostname;if(!(t===`localhost`||t===`127.0.0.1`))return`.${t}`}function R(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 z(e,t,n){if(typeof document>`u`)return;let r=L(n),i=[`${e}=${encodeURIComponent(t)}`,`Path=/`,`Secure`,`SameSite=Lax`,`Max-Age=7776000`];r&&i.push(`Domain=${r}`),document.cookie=i.join(`; `)}function B(){return{fbc:R(P),fbp:R(F)}}function V(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&&(z(P,N(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=R(F);return a||(a=`fb.1.${Date.now()}.${I()}`,z(F,a,t)),B()}var H=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=()=>B();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 U(e,t){e?.register?.({product:t})}function W(e,t,n){e?.capture(v.FEATURE_USED,{feature_name:t,...n})}function G(e,{plan:t,product:n}){n&&U(e,n),e?.capture(v.CHECKOUT_STARTED,{plan:t,...n?{product:n}:{}})}const K=s(null),q=({children:e,baseUrl:t,frontendUrl:n,product:r,initialSession:i,initialPurchases:a,authClient:o,queryClient:s})=>{let l=h(),_=d(()=>o??new H(t,n),[t,n,o]),v=d(()=>s??new p,[s]),{data:y,isFetching:b,refetch:x}=m({queryKey:[`us-auth-session`],staleTime:0,initialData:i,queryFn:_.getSession},v),S=d(()=>!(!y||y.user.isAnonymous),[y]),C=f(!1);u(()=>{V({frontendUrl:n})},[n]),u(()=>{r&&U(l,r)},[l,r]);let w=c(e=>{U(l,e)},[l]),T=c((e,t)=>{W(l,e,t)},[l]),E=c(e=>{G(l,e)},[l]);u(()=>{b||y===null&&(C.current||(C.current=!0,_.signInAnonymously().then(e=>{v.setQueryData([`us-auth-session`],e)}).catch(e=>console.error(e))))},[_,b,v,y]),u(()=>{y?.user&&l&&l.get_distinct_id()!==y.user.id&&l.identify(y.user.id,{email:y.user.email})},[y,l]);let{data:D,isFetching:O,refetch:k}=m({queryKey:[`us-auth-purchases`],staleTime:1e3*60,initialData:a,queryFn:_.getPurchases},v),A=d(()=>_.getLoginUrl,[_]),j=d(()=>_.getCheckoutUrl,[_]),M=c(e=>_.signOut(()=>{l?.reset(),e?.()}),[_,l]),N=d(()=>_.trackMetaEvent,[_]),P=d(()=>_.trackViewContent,[_]),F=d(()=>_.getMetaAttribution,[_]),I=c(e=>D?D.paddle.transactions.some(t=>t.items.some(t=>e.includes(t))&&!t.adjustments.some(e=>e.status===`approved`&&e.action===`refund`)):!1,[D]),L=c((e,t)=>{if(!D)return!1;let n=D.paddle.subscriptions.some(n=>n.items.some(n=>e.includes(n.priceId)||t===n.productId)&&n.status===`active`),r=D.stripe.some(t=>t.status===`active`&&t.items.some(t=>e.includes(t)));return n||r},[D]);return g(K.Provider,{value:{session:y??null,isSessionFetching:b,refetchSession:async()=>{await x()},purchases:D??null,isPurchasesFetching:O,refetchPurchases:async()=>{await k()},signOut:M,getLoginUrl:A,getCheckoutUrl:j,trackMetaEvent:N,trackViewContent:P,getMetaAttribution:F,captureFeatureUsed:T,captureCheckoutStarted:E,registerProduct:w,isSubscribed:L,isPurchased:I,isLoggedIn:S},children:e})};function J(){let e=l(K);if(!e)throw Error(`useAuth must be used within an AuthProvider`);return e}export{v as ANALYTICS_EVENTS,_ as ANALYTICS_PRODUCTS,H as AuthClient,K as AuthContext,q as AuthProvider,N as buildFbcFromFbclid,G as captureCheckoutStarted,W as captureFeatureUsed,V as captureMetaClickId,L as getMetaCookieDomain,y as isAnalyticsProduct,M as parseMetaAttributionFromCookieHeader,B as readMetaAttributionCookies,U as registerProduct,J as useAuth};
|
|
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","registerProduct","captureFeatureUsed","captureCheckoutStarted"],"sources":["../../types/src/analytics.ts","../../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/analytics.ts","../src/react/AuthContext.ts","../src/react/AuthProvider.tsx","../src/react/useAuth.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","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 {\n ANALYTICS_EVENTS,\n type AnalyticsProduct,\n} from \"@us-auth/types\";\n\nexport interface PostHogAnalyticsClient {\n capture: (\n event: string,\n properties?: Record<string, unknown>,\n ) => 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 {\n ANALYTICS_EVENTS,\n ANALYTICS_PRODUCTS,\n type AnalyticsProduct,\n type AnalyticsEvent,\n type AuthMethod,\n isAnalyticsProduct,\n} from \"@us-auth/types\";\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 trackMetaEvent: AuthClient[\"trackMetaEvent\"];\n trackViewContent: AuthClient[\"trackViewContent\"];\n getMetaAttribution: AuthClient[\"getMetaAttribution\"];\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);\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, AnalyticsProduct } from \"@us-auth/types\";\nimport { QueryClient, useQuery } from \"@tanstack/react-query\";\nimport { usePostHog } from \"@posthog/react\";\nimport { captureMetaClickId } from \"../metaAttribution\";\nimport {\n captureCheckoutStarted as captureCheckoutStartedEvent,\n captureFeatureUsed as captureFeatureUsedEvent,\n registerProduct as registerProductEvent,\n} from \"../analytics\";\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 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 useEffect(() => {\n if (product) {\n registerProductEvent(ph, product);\n }\n }, [ph, product]);\n\n const registerProduct = useCallback(\n (nextProduct: AnalyticsProduct) => {\n registerProductEvent(ph, nextProduct);\n },\n [ph],\n );\n\n const captureFeatureUsed = useCallback(\n (featureName: string, extra?: Record<string, unknown>) => {\n captureFeatureUsedEvent(ph, featureName, extra);\n },\n [ph],\n );\n\n const captureCheckoutStarted = useCallback(\n (options: { plan: string; product?: AnalyticsProduct }) => {\n captureCheckoutStartedEvent(ph, options);\n },\n [ph],\n );\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 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"],"mappings":"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"}
|