@reauth-dev/sdk 0.1.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.
@@ -0,0 +1,127 @@
1
+ import { R as ReauthConfig, a as ReauthSession, T as TokenResponse, S as SubscriptionPlan, U as UserSubscription, C as CheckoutSession, b as TransactionsPaginationOptions, B as BalanceTransaction } from './types-D8oOYbeC.js';
2
+ export { A as AuthResult, h as ChargeOptions, i as DepositOptions, D as DomainEndUserClaims, e as ReauthServerConfig, f as RequestLike, g as SubscriptionInfo, c as User, d as UserDetails } from './types-D8oOYbeC.js';
3
+
4
+ /**
5
+ * Create a reauth client for browser-side authentication.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * const reauth = createReauthClient({ domain: 'yourdomain.com' });
10
+ *
11
+ * // Check if user is authenticated
12
+ * const session = await reauth.getSession();
13
+ * if (!session.valid) {
14
+ * reauth.login(); // Redirect to login page
15
+ * }
16
+ *
17
+ * // Log out
18
+ * await reauth.logout();
19
+ * ```
20
+ */
21
+ declare function createReauthClient(config: ReauthConfig): {
22
+ /**
23
+ * Redirect the user to the reauth.dev login page.
24
+ * After successful login, they'll be redirected back to your configured redirect URL.
25
+ */
26
+ login(): void;
27
+ /**
28
+ * Check if the user is authenticated.
29
+ * Returns session info including user ID, email, and roles.
30
+ */
31
+ getSession(): Promise<ReauthSession>;
32
+ /**
33
+ * Refresh the access token using the refresh token.
34
+ * Call this when getSession() returns valid: false but no error_code.
35
+ * @returns true if refresh succeeded, false otherwise
36
+ */
37
+ refresh(): Promise<boolean>;
38
+ /**
39
+ * Get an access token for Bearer authentication.
40
+ * Use this when calling your own API that uses local token verification.
41
+ *
42
+ * @returns TokenResponse with access token, or null if not authenticated
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * const tokenResponse = await reauth.getToken();
47
+ * if (tokenResponse) {
48
+ * fetch('/api/data', {
49
+ * headers: { Authorization: `Bearer ${tokenResponse.accessToken}` }
50
+ * });
51
+ * }
52
+ * ```
53
+ */
54
+ getToken(): Promise<TokenResponse | null>;
55
+ /**
56
+ * Log out the user by clearing all session cookies.
57
+ */
58
+ logout(): Promise<void>;
59
+ /**
60
+ * Delete the user's own account (self-service).
61
+ * @returns true if deletion succeeded, false otherwise
62
+ */
63
+ deleteAccount(): Promise<boolean>;
64
+ /**
65
+ * Get available subscription plans for the domain.
66
+ * Only returns public plans sorted by display order.
67
+ */
68
+ getPlans(): Promise<SubscriptionPlan[]>;
69
+ /**
70
+ * Get the current user's subscription status.
71
+ */
72
+ getSubscription(): Promise<UserSubscription>;
73
+ /**
74
+ * Create a Stripe checkout session to subscribe to a plan.
75
+ * @param planCode The plan code to subscribe to
76
+ * @param successUrl URL to redirect to after successful payment
77
+ * @param cancelUrl URL to redirect to if checkout is canceled
78
+ * @returns Checkout session with URL to redirect the user to
79
+ */
80
+ createCheckout(planCode: string, successUrl: string, cancelUrl: string): Promise<CheckoutSession>;
81
+ /**
82
+ * Redirect user to subscribe to a plan.
83
+ * Creates a checkout session and redirects to Stripe.
84
+ * @param planCode The plan code to subscribe to
85
+ */
86
+ subscribe(planCode: string): Promise<void>;
87
+ /**
88
+ * Open the Stripe customer portal for managing subscription.
89
+ * @param returnUrl URL to return to after leaving the portal
90
+ */
91
+ openBillingPortal(returnUrl?: string): Promise<void>;
92
+ /**
93
+ * Cancel the user's subscription at period end.
94
+ * @returns true if cancellation succeeded
95
+ */
96
+ cancelSubscription(): Promise<boolean>;
97
+ /**
98
+ * Get the current user's balance.
99
+ * @returns Object with the current balance
100
+ */
101
+ getBalance(): Promise<{
102
+ balance: number;
103
+ }>;
104
+ /**
105
+ * Get the current user's balance transaction history.
106
+ * @param opts - Optional pagination (limit, offset)
107
+ * @returns Object with array of transactions (newest first)
108
+ */
109
+ getTransactions(opts?: TransactionsPaginationOptions): Promise<{
110
+ transactions: BalanceTransaction[];
111
+ }>;
112
+ };
113
+ type ReauthClient = ReturnType<typeof createReauthClient>;
114
+
115
+ declare enum ReauthErrorCode {
116
+ /**
117
+ * OAuth retry window expired. The OAuth flow must be restarted.
118
+ */
119
+ OAUTH_RETRY_EXPIRED = "OAUTH_RETRY_EXPIRED"
120
+ }
121
+ type ReauthError = {
122
+ code: ReauthErrorCode | string;
123
+ message?: string;
124
+ };
125
+ declare function requiresOAuthRestart(error: ReauthError | null | undefined): boolean;
126
+
127
+ export { BalanceTransaction, type ReauthClient, ReauthConfig, type ReauthError, ReauthErrorCode, ReauthSession, TokenResponse, TransactionsPaginationOptions, createReauthClient, requiresOAuthRestart };
package/dist/index.js ADDED
@@ -0,0 +1,308 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ ReauthErrorCode: () => ReauthErrorCode,
24
+ createReauthClient: () => createReauthClient,
25
+ requiresOAuthRestart: () => requiresOAuthRestart
26
+ });
27
+ module.exports = __toCommonJS(src_exports);
28
+
29
+ // src/client.ts
30
+ function createReauthClient(config) {
31
+ const { domain } = config;
32
+ const baseUrl = `https://reauth.${domain}/api/public`;
33
+ return {
34
+ /**
35
+ * Redirect the user to the reauth.dev login page.
36
+ * After successful login, they'll be redirected back to your configured redirect URL.
37
+ */
38
+ login() {
39
+ if (typeof window === "undefined") {
40
+ throw new Error("login() can only be called in browser");
41
+ }
42
+ window.location.href = `https://reauth.${domain}/`;
43
+ },
44
+ /**
45
+ * Check if the user is authenticated.
46
+ * Returns session info including user ID, email, and roles.
47
+ */
48
+ async getSession() {
49
+ const res = await fetch(`${baseUrl}/auth/session`, {
50
+ credentials: "include"
51
+ });
52
+ return res.json();
53
+ },
54
+ /**
55
+ * Refresh the access token using the refresh token.
56
+ * Call this when getSession() returns valid: false but no error_code.
57
+ * @returns true if refresh succeeded, false otherwise
58
+ */
59
+ async refresh() {
60
+ const res = await fetch(`${baseUrl}/auth/refresh`, {
61
+ method: "POST",
62
+ credentials: "include"
63
+ });
64
+ return res.ok;
65
+ },
66
+ /**
67
+ * Get an access token for Bearer authentication.
68
+ * Use this when calling your own API that uses local token verification.
69
+ *
70
+ * @returns TokenResponse with access token, or null if not authenticated
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * const tokenResponse = await reauth.getToken();
75
+ * if (tokenResponse) {
76
+ * fetch('/api/data', {
77
+ * headers: { Authorization: `Bearer ${tokenResponse.accessToken}` }
78
+ * });
79
+ * }
80
+ * ```
81
+ */
82
+ async getToken() {
83
+ try {
84
+ const res = await fetch(`${baseUrl}/auth/token`, {
85
+ method: "GET",
86
+ credentials: "include"
87
+ });
88
+ if (!res.ok) {
89
+ if (res.status === 401) return null;
90
+ throw new Error(`Failed to get token: ${res.status}`);
91
+ }
92
+ const data = await res.json();
93
+ return {
94
+ accessToken: data.access_token,
95
+ expiresIn: data.expires_in,
96
+ tokenType: data.token_type
97
+ };
98
+ } catch {
99
+ return null;
100
+ }
101
+ },
102
+ /**
103
+ * Log out the user by clearing all session cookies.
104
+ */
105
+ async logout() {
106
+ await fetch(`${baseUrl}/auth/logout`, {
107
+ method: "POST",
108
+ credentials: "include"
109
+ });
110
+ },
111
+ /**
112
+ * Delete the user's own account (self-service).
113
+ * @returns true if deletion succeeded, false otherwise
114
+ */
115
+ async deleteAccount() {
116
+ const res = await fetch(`${baseUrl}/auth/account`, {
117
+ method: "DELETE",
118
+ credentials: "include"
119
+ });
120
+ return res.ok;
121
+ },
122
+ // ========================================================================
123
+ // Billing Methods
124
+ // ========================================================================
125
+ /**
126
+ * Get available subscription plans for the domain.
127
+ * Only returns public plans sorted by display order.
128
+ */
129
+ async getPlans() {
130
+ const res = await fetch(`${baseUrl}/billing/plans`, {
131
+ credentials: "include"
132
+ });
133
+ if (!res.ok) return [];
134
+ const data = await res.json();
135
+ return data.map(
136
+ (p) => ({
137
+ id: p.id,
138
+ code: p.code,
139
+ name: p.name,
140
+ description: p.description,
141
+ priceCents: p.price_cents,
142
+ currency: p.currency,
143
+ interval: p.interval,
144
+ intervalCount: p.interval_count,
145
+ trialDays: p.trial_days,
146
+ features: p.features,
147
+ displayOrder: p.display_order
148
+ })
149
+ );
150
+ },
151
+ /**
152
+ * Get the current user's subscription status.
153
+ */
154
+ async getSubscription() {
155
+ const res = await fetch(`${baseUrl}/billing/subscription`, {
156
+ credentials: "include"
157
+ });
158
+ const data = await res.json();
159
+ return {
160
+ id: data.id,
161
+ planCode: data.plan_code,
162
+ planName: data.plan_name,
163
+ status: data.status,
164
+ currentPeriodEnd: data.current_period_end,
165
+ trialEnd: data.trial_end,
166
+ cancelAtPeriodEnd: data.cancel_at_period_end
167
+ };
168
+ },
169
+ /**
170
+ * Create a Stripe checkout session to subscribe to a plan.
171
+ * @param planCode The plan code to subscribe to
172
+ * @param successUrl URL to redirect to after successful payment
173
+ * @param cancelUrl URL to redirect to if checkout is canceled
174
+ * @returns Checkout session with URL to redirect the user to
175
+ */
176
+ async createCheckout(planCode, successUrl, cancelUrl) {
177
+ const res = await fetch(`${baseUrl}/billing/checkout`, {
178
+ method: "POST",
179
+ headers: { "Content-Type": "application/json" },
180
+ credentials: "include",
181
+ body: JSON.stringify({
182
+ plan_code: planCode,
183
+ success_url: successUrl,
184
+ cancel_url: cancelUrl
185
+ })
186
+ });
187
+ if (!res.ok) {
188
+ const err = await res.json().catch(() => ({}));
189
+ throw new Error(err.message || "Failed to create checkout session");
190
+ }
191
+ const data = await res.json();
192
+ return { checkoutUrl: data.checkout_url };
193
+ },
194
+ /**
195
+ * Redirect user to subscribe to a plan.
196
+ * Creates a checkout session and redirects to Stripe.
197
+ * @param planCode The plan code to subscribe to
198
+ */
199
+ async subscribe(planCode) {
200
+ if (typeof window === "undefined") {
201
+ throw new Error("subscribe() can only be called in browser");
202
+ }
203
+ const currentUrl = window.location.href;
204
+ const { checkoutUrl } = await this.createCheckout(
205
+ planCode,
206
+ currentUrl,
207
+ currentUrl
208
+ );
209
+ window.location.href = checkoutUrl;
210
+ },
211
+ /**
212
+ * Open the Stripe customer portal for managing subscription.
213
+ * @param returnUrl URL to return to after leaving the portal
214
+ */
215
+ async openBillingPortal(returnUrl) {
216
+ if (typeof window === "undefined") {
217
+ throw new Error("openBillingPortal() can only be called in browser");
218
+ }
219
+ const res = await fetch(`${baseUrl}/billing/portal`, {
220
+ method: "POST",
221
+ headers: { "Content-Type": "application/json" },
222
+ credentials: "include",
223
+ body: JSON.stringify({
224
+ return_url: returnUrl || window.location.href
225
+ })
226
+ });
227
+ if (!res.ok) {
228
+ throw new Error("Failed to open billing portal");
229
+ }
230
+ const data = await res.json();
231
+ window.location.href = data.portal_url;
232
+ },
233
+ /**
234
+ * Cancel the user's subscription at period end.
235
+ * @returns true if cancellation succeeded
236
+ */
237
+ async cancelSubscription() {
238
+ const res = await fetch(`${baseUrl}/billing/cancel`, {
239
+ method: "POST",
240
+ credentials: "include"
241
+ });
242
+ return res.ok;
243
+ },
244
+ // ========================================================================
245
+ // Balance Methods
246
+ // ========================================================================
247
+ /**
248
+ * Get the current user's balance.
249
+ * @returns Object with the current balance
250
+ */
251
+ async getBalance() {
252
+ const res = await fetch(`${baseUrl}/balance`, {
253
+ credentials: "include"
254
+ });
255
+ if (!res.ok) {
256
+ if (res.status === 401) throw new Error("Not authenticated");
257
+ throw new Error(`Failed to get balance: ${res.status}`);
258
+ }
259
+ return res.json();
260
+ },
261
+ /**
262
+ * Get the current user's balance transaction history.
263
+ * @param opts - Optional pagination (limit, offset)
264
+ * @returns Object with array of transactions (newest first)
265
+ */
266
+ async getTransactions(opts) {
267
+ const params = new URLSearchParams();
268
+ if (opts?.limit !== void 0) params.set("limit", String(opts.limit));
269
+ if (opts?.offset !== void 0) params.set("offset", String(opts.offset));
270
+ const qs = params.toString();
271
+ const res = await fetch(
272
+ `${baseUrl}/balance/transactions${qs ? `?${qs}` : ""}`,
273
+ { credentials: "include" }
274
+ );
275
+ if (!res.ok) {
276
+ if (res.status === 401) throw new Error("Not authenticated");
277
+ throw new Error(`Failed to get transactions: ${res.status}`);
278
+ }
279
+ const data = await res.json();
280
+ return {
281
+ transactions: data.transactions.map(
282
+ (t) => ({
283
+ id: t.id,
284
+ amountDelta: t.amount_delta,
285
+ reason: t.reason,
286
+ balanceAfter: t.balance_after,
287
+ createdAt: t.created_at
288
+ })
289
+ )
290
+ };
291
+ }
292
+ };
293
+ }
294
+
295
+ // src/errors.ts
296
+ var ReauthErrorCode = /* @__PURE__ */ ((ReauthErrorCode2) => {
297
+ ReauthErrorCode2["OAUTH_RETRY_EXPIRED"] = "OAUTH_RETRY_EXPIRED";
298
+ return ReauthErrorCode2;
299
+ })(ReauthErrorCode || {});
300
+ function requiresOAuthRestart(error) {
301
+ return error?.code === "OAUTH_RETRY_EXPIRED" /* OAUTH_RETRY_EXPIRED */;
302
+ }
303
+ // Annotate the CommonJS export names for ESM import in node:
304
+ 0 && (module.exports = {
305
+ ReauthErrorCode,
306
+ createReauthClient,
307
+ requiresOAuthRestart
308
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,17 @@
1
+ import {
2
+ createReauthClient
3
+ } from "./chunk-JX2J36FS.mjs";
4
+
5
+ // src/errors.ts
6
+ var ReauthErrorCode = /* @__PURE__ */ ((ReauthErrorCode2) => {
7
+ ReauthErrorCode2["OAUTH_RETRY_EXPIRED"] = "OAUTH_RETRY_EXPIRED";
8
+ return ReauthErrorCode2;
9
+ })(ReauthErrorCode || {});
10
+ function requiresOAuthRestart(error) {
11
+ return error?.code === "OAUTH_RETRY_EXPIRED" /* OAUTH_RETRY_EXPIRED */;
12
+ }
13
+ export {
14
+ ReauthErrorCode,
15
+ createReauthClient,
16
+ requiresOAuthRestart
17
+ };
@@ -0,0 +1,123 @@
1
+ import { R as ReauthConfig, c as User } from '../types-D8oOYbeC.mjs';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
+ import { ReactNode } from 'react';
4
+
5
+ /**
6
+ * React hook for authentication state management.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * function MyComponent() {
11
+ * const { user, loading, login, logout } = useAuth({ domain: 'yourdomain.com' });
12
+ *
13
+ * if (loading) return <div>Loading...</div>;
14
+ * if (!user) return <button onClick={login}>Sign in</button>;
15
+ *
16
+ * return (
17
+ * <div>
18
+ * Welcome {user.email}
19
+ * <button onClick={logout}>Sign out</button>
20
+ * </div>
21
+ * );
22
+ * }
23
+ * ```
24
+ */
25
+ declare function useAuth(config: ReauthConfig): {
26
+ login: () => void;
27
+ logout: () => Promise<void>;
28
+ refetch: () => Promise<void>;
29
+ user: User | null;
30
+ loading: boolean;
31
+ error: string | null;
32
+ isOnWaitlist: boolean;
33
+ waitlistPosition: number | null;
34
+ };
35
+
36
+ type AuthContextType = {
37
+ user: User | null;
38
+ loading: boolean;
39
+ error: string | null;
40
+ isOnWaitlist: boolean;
41
+ waitlistPosition: number | null;
42
+ login: () => void;
43
+ logout: () => Promise<void>;
44
+ refetch: () => Promise<void>;
45
+ };
46
+ type AuthProviderProps = {
47
+ config: ReauthConfig;
48
+ children: ReactNode;
49
+ };
50
+ /**
51
+ * Provider component that wraps your app and provides auth context.
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * // app/layout.tsx
56
+ * import { AuthProvider } from '@reauth-dev/sdk/react';
57
+ *
58
+ * export default function RootLayout({ children }) {
59
+ * return (
60
+ * <AuthProvider config={{ domain: 'yourdomain.com' }}>
61
+ * {children}
62
+ * </AuthProvider>
63
+ * );
64
+ * }
65
+ * ```
66
+ */
67
+ declare function AuthProvider({ config, children }: AuthProviderProps): react_jsx_runtime.JSX.Element;
68
+ /**
69
+ * Hook to access auth context from within AuthProvider.
70
+ *
71
+ * @example
72
+ * ```typescript
73
+ * function UserMenu() {
74
+ * const { user, logout } = useAuthContext();
75
+ *
76
+ * return (
77
+ * <div>
78
+ * {user?.email}
79
+ * <button onClick={logout}>Sign out</button>
80
+ * </div>
81
+ * );
82
+ * }
83
+ * ```
84
+ */
85
+ declare function useAuthContext(): AuthContextType;
86
+
87
+ type ProtectedRouteProps = {
88
+ children: ReactNode;
89
+ /** Content to show while loading */
90
+ fallback?: ReactNode;
91
+ /** Custom handler when user is not authenticated (default: redirect to login) */
92
+ onUnauthenticated?: () => void;
93
+ /** Custom handler when user is on waitlist */
94
+ onWaitlist?: () => void;
95
+ };
96
+ /**
97
+ * Component that protects its children from unauthenticated access.
98
+ * Automatically redirects to login if user is not authenticated.
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * // Basic usage
103
+ * <ProtectedRoute>
104
+ * <Dashboard />
105
+ * </ProtectedRoute>
106
+ *
107
+ * // With loading fallback
108
+ * <ProtectedRoute fallback={<LoadingSpinner />}>
109
+ * <Dashboard />
110
+ * </ProtectedRoute>
111
+ *
112
+ * // With custom handlers
113
+ * <ProtectedRoute
114
+ * onUnauthenticated={() => router.push('/login')}
115
+ * onWaitlist={() => router.push('/waitlist')}
116
+ * >
117
+ * <Dashboard />
118
+ * </ProtectedRoute>
119
+ * ```
120
+ */
121
+ declare function ProtectedRoute({ children, fallback, onUnauthenticated, onWaitlist, }: ProtectedRouteProps): react_jsx_runtime.JSX.Element | null;
122
+
123
+ export { AuthProvider, ProtectedRoute, useAuth, useAuthContext };
@@ -0,0 +1,123 @@
1
+ import { R as ReauthConfig, c as User } from '../types-D8oOYbeC.js';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
+ import { ReactNode } from 'react';
4
+
5
+ /**
6
+ * React hook for authentication state management.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * function MyComponent() {
11
+ * const { user, loading, login, logout } = useAuth({ domain: 'yourdomain.com' });
12
+ *
13
+ * if (loading) return <div>Loading...</div>;
14
+ * if (!user) return <button onClick={login}>Sign in</button>;
15
+ *
16
+ * return (
17
+ * <div>
18
+ * Welcome {user.email}
19
+ * <button onClick={logout}>Sign out</button>
20
+ * </div>
21
+ * );
22
+ * }
23
+ * ```
24
+ */
25
+ declare function useAuth(config: ReauthConfig): {
26
+ login: () => void;
27
+ logout: () => Promise<void>;
28
+ refetch: () => Promise<void>;
29
+ user: User | null;
30
+ loading: boolean;
31
+ error: string | null;
32
+ isOnWaitlist: boolean;
33
+ waitlistPosition: number | null;
34
+ };
35
+
36
+ type AuthContextType = {
37
+ user: User | null;
38
+ loading: boolean;
39
+ error: string | null;
40
+ isOnWaitlist: boolean;
41
+ waitlistPosition: number | null;
42
+ login: () => void;
43
+ logout: () => Promise<void>;
44
+ refetch: () => Promise<void>;
45
+ };
46
+ type AuthProviderProps = {
47
+ config: ReauthConfig;
48
+ children: ReactNode;
49
+ };
50
+ /**
51
+ * Provider component that wraps your app and provides auth context.
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * // app/layout.tsx
56
+ * import { AuthProvider } from '@reauth-dev/sdk/react';
57
+ *
58
+ * export default function RootLayout({ children }) {
59
+ * return (
60
+ * <AuthProvider config={{ domain: 'yourdomain.com' }}>
61
+ * {children}
62
+ * </AuthProvider>
63
+ * );
64
+ * }
65
+ * ```
66
+ */
67
+ declare function AuthProvider({ config, children }: AuthProviderProps): react_jsx_runtime.JSX.Element;
68
+ /**
69
+ * Hook to access auth context from within AuthProvider.
70
+ *
71
+ * @example
72
+ * ```typescript
73
+ * function UserMenu() {
74
+ * const { user, logout } = useAuthContext();
75
+ *
76
+ * return (
77
+ * <div>
78
+ * {user?.email}
79
+ * <button onClick={logout}>Sign out</button>
80
+ * </div>
81
+ * );
82
+ * }
83
+ * ```
84
+ */
85
+ declare function useAuthContext(): AuthContextType;
86
+
87
+ type ProtectedRouteProps = {
88
+ children: ReactNode;
89
+ /** Content to show while loading */
90
+ fallback?: ReactNode;
91
+ /** Custom handler when user is not authenticated (default: redirect to login) */
92
+ onUnauthenticated?: () => void;
93
+ /** Custom handler when user is on waitlist */
94
+ onWaitlist?: () => void;
95
+ };
96
+ /**
97
+ * Component that protects its children from unauthenticated access.
98
+ * Automatically redirects to login if user is not authenticated.
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * // Basic usage
103
+ * <ProtectedRoute>
104
+ * <Dashboard />
105
+ * </ProtectedRoute>
106
+ *
107
+ * // With loading fallback
108
+ * <ProtectedRoute fallback={<LoadingSpinner />}>
109
+ * <Dashboard />
110
+ * </ProtectedRoute>
111
+ *
112
+ * // With custom handlers
113
+ * <ProtectedRoute
114
+ * onUnauthenticated={() => router.push('/login')}
115
+ * onWaitlist={() => router.push('/waitlist')}
116
+ * >
117
+ * <Dashboard />
118
+ * </ProtectedRoute>
119
+ * ```
120
+ */
121
+ declare function ProtectedRoute({ children, fallback, onUnauthenticated, onWaitlist, }: ProtectedRouteProps): react_jsx_runtime.JSX.Element | null;
122
+
123
+ export { AuthProvider, ProtectedRoute, useAuth, useAuthContext };