@insforge/nextjs 1.0.5-dev.6 → 1.0.5-dev.8

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.
@@ -1,28 +1,170 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { InsforgeProviderProps, InitialAuthState, useInsforge as useInsforge$1 } from '@insforge/react';
3
+ export { InitialAuthState } from '@insforge/react';
4
+ import { InsForgeClient } from '@insforge/sdk';
3
5
 
4
- interface ExtendedProviderProps extends InsforgeProviderProps {
6
+ /**
7
+ * Props for InsforgeBrowserProvider
8
+ */
9
+ interface InsforgeBrowserProviderProps extends InsforgeProviderProps {
10
+ children: React.ReactNode;
11
+ /**
12
+ * The InsForge SDK client instance.
13
+ *
14
+ * **Important:** Use the same client instance that you use for database,
15
+ * storage, and other SDK operations. This ensures authentication tokens
16
+ * are shared correctly.
17
+ */
18
+ client: InsForgeClient;
19
+ /**
20
+ * URL to redirect to after successful sign in
21
+ * @default '/'
22
+ */
5
23
  afterSignInUrl?: string;
6
- onSignIn?: (authToken: string) => Promise<void>;
7
- onSignOut?: () => Promise<void>;
8
- onRefresh?: (authToken: string) => Promise<void>;
9
24
  /**
10
- * Initial auth state from server (for SSR hydration)
11
- * @internal
25
+ * Callback when auth state changes
26
+ */
27
+ onAuthChange?: (user: any) => void;
28
+ /**
29
+ * Initial auth state from server (for SSR hydration).
30
+ * Get this using `getAuthFromCookies()`.
12
31
  */
13
32
  initialState?: InitialAuthState;
14
33
  }
15
34
  /**
16
- * Client Insforge Provider for Next.js
35
+ * Browser-side Insforge Provider for Next.js
36
+ *
37
+ * This provider manages authentication state on the client side and automatically
38
+ * syncs tokens to HTTP-only cookies via `/api/auth` route for server-side access.
39
+ *
40
+ * **Key Features:**
41
+ * - Uses YOUR SDK client instance (shared with database/storage operations)
42
+ * - Automatic token sync to HTTP-only cookies
43
+ * - SSR hydration support via `initialState`
44
+ * - Works with Next.js App Router
45
+ *
46
+ * ---
47
+ *
48
+ * ## Setup Guide
49
+ *
50
+ * ### Step 1: Create your SDK client
51
+ *
52
+ * @example
53
+ * ```tsx
54
+ * // lib/insforge.ts
55
+ * 'use client';
56
+ * import { createClient } from '@insforge/sdk';
57
+ *
58
+ * export const insforge = createClient({
59
+ * baseUrl: process.env.NEXT_PUBLIC_INSFORGE_URL!,
60
+ * anonKey: process.env.NEXT_PUBLIC_INSFORGE_ANON_KEY!,
61
+ * });
62
+ * ```
63
+ *
64
+ * ### Step 2: Create your Providers component
65
+ *
66
+ * @example
67
+ * ```tsx
68
+ * // app/providers.tsx
69
+ * 'use client';
70
+ * import { InsforgeBrowserProvider, type InitialAuthState } from '@insforge/nextjs';
71
+ * import { insforge } from '@/lib/insforge';
72
+ *
73
+ * export function Providers({
74
+ * children,
75
+ * initialState,
76
+ * }: {
77
+ * children: React.ReactNode;
78
+ * initialState?: InitialAuthState;
79
+ * }) {
80
+ * return (
81
+ * <InsforgeBrowserProvider
82
+ * client={insforge}
83
+ * initialState={initialState}
84
+ * afterSignInUrl="/dashboard"
85
+ * >
86
+ * {children}
87
+ * </InsforgeBrowserProvider>
88
+ * );
89
+ * }
90
+ * ```
91
+ *
92
+ * ### Step 3: Use in your root layout
93
+ *
94
+ * @example
95
+ * ```tsx
96
+ * // app/layout.tsx
97
+ * import { getAuthFromCookies } from '@insforge/nextjs';
98
+ * import { Providers } from './providers';
99
+ *
100
+ * export default async function RootLayout({
101
+ * children,
102
+ * }: {
103
+ * children: React.ReactNode;
104
+ * }) {
105
+ * const initialState = await getAuthFromCookies();
106
+ *
107
+ * return (
108
+ * <html>
109
+ * <body>
110
+ * <Providers initialState={initialState}>
111
+ * {children}
112
+ * </Providers>
113
+ * </body>
114
+ * </html>
115
+ * );
116
+ * }
117
+ * ```
118
+ *
119
+ * ### Step 4: Use auth components and hooks
120
+ *
121
+ * @example
122
+ * ```tsx
123
+ * // app/page.tsx
124
+ * 'use client';
125
+ * import { SignIn, UserButton, useInsforge } from '@insforge/nextjs';
126
+ *
127
+ * export default function Page() {
128
+ * const { isSignedIn, user } = useInsforge();
129
+ *
130
+ * if (!isSignedIn) return <SignIn />;
131
+ *
132
+ * return (
133
+ * <div>
134
+ * <UserButton />
135
+ * <p>Welcome {user?.email}</p>
136
+ * </div>
137
+ * );
138
+ * }
139
+ * ```
140
+ *
141
+ * ---
142
+ *
143
+ * ## Why pass your own client?
144
+ *
145
+ * Authentication tokens are stored in the SDK client instance's memory.
146
+ * If auth components use a different client than your app, they won't share
147
+ * tokens, causing authentication to fail for database/storage operations.
148
+ *
149
+ * By passing YOUR client to the provider, all operations use the same
150
+ * authenticated session.
151
+ */
152
+ declare function InsforgeBrowserProvider({ children, client, afterSignInUrl, onAuthChange, initialState, }: InsforgeBrowserProviderProps): react_jsx_runtime.JSX.Element;
153
+ /**
154
+ * @deprecated Use `InsforgeBrowserProvider` instead.
17
155
  *
18
- * This is a Client Component ('use client') that:
19
- * 1. Receives initialState from Server Provider
20
- * 2. Manages authentication state on the client
21
- * 3. Syncs tokens to HTTP-only cookies via /api/auth
156
+ * This alias is kept for backward compatibility and will be removed in a future version.
22
157
  *
23
- * @internal - Not intended for direct use. Use the Server Provider instead.
158
+ * Migration:
159
+ * ```tsx
160
+ * // Before
161
+ * import { ClientInsforgeProvider } from '@insforge/nextjs';
162
+ *
163
+ * // After
164
+ * import { InsforgeBrowserProvider } from '@insforge/nextjs';
165
+ * ```
24
166
  */
25
- declare function ClientInsforgeProvider({ children, client, afterSignInUrl, onAuthChange, initialState, }: ExtendedProviderProps): react_jsx_runtime.JSX.Element;
167
+ declare const ClientInsforgeProvider: typeof InsforgeBrowserProvider;
26
168
  /**
27
169
  * Hook to access Insforge context
28
170
  *
@@ -46,4 +188,4 @@ declare function ClientInsforgeProvider({ children, client, afterSignInUrl, onAu
46
188
  */
47
189
  declare const useInsforge: typeof useInsforge$1;
48
190
 
49
- export { ClientInsforgeProvider, useInsforge };
191
+ export { ClientInsforgeProvider, InsforgeBrowserProvider, type InsforgeBrowserProviderProps, useInsforge };
@@ -1,3 +1,4 @@
1
- export { ClientInsforgeProvider as InsforgeProvider } from './client/provider.js';
1
+ export { ClientInsforgeProvider, InsforgeBrowserProvider, InsforgeBrowserProvider as InsforgeProvider } from './client/provider.js';
2
2
  import 'react/jsx-runtime';
3
3
  import '@insforge/react';
4
+ import '@insforge/sdk';
@@ -2,6 +2,7 @@ import { InsforgeProvider } from './server/InsforgeProvider.js';
2
2
  import 'react/jsx-runtime';
3
3
  import 'react';
4
4
  import '@insforge/react';
5
+ import '@insforge/sdk';
5
6
 
6
7
  type ServerComponentsServerModuleTypes = {
7
8
  InsforgeProvider: typeof InsforgeProvider;
@@ -21,10 +21,10 @@ async function syncTokenToCookie(token) {
21
21
  });
22
22
  if (!response.ok) {
23
23
  const errorText = await response.text();
24
- console.error("[Insforge Client Provider] sync-token failed:", errorText);
24
+ console.error("[InsforgeBrowserProvider] sync-token failed:", errorText);
25
25
  }
26
26
  } catch (err) {
27
- console.error("[Insforge Client Provider] Failed to sync token to cookie:", err);
27
+ console.error("[InsforgeBrowserProvider] Failed to sync token to cookie:", err);
28
28
  }
29
29
  }
30
30
  async function handleSignIn(token) {
@@ -39,7 +39,7 @@ async function handleSignOut() {
39
39
  } catch {
40
40
  }
41
41
  }
42
- function ClientInsforgeProvider({
42
+ function InsforgeBrowserProvider({
43
43
  children,
44
44
  client,
45
45
  afterSignInUrl = "/",
@@ -58,9 +58,11 @@ function ClientInsforgeProvider({
58
58
  };
59
59
  return /* @__PURE__ */ jsx(StyleProvider, { children: /* @__PURE__ */ jsx(NavigationProvider, { adapter: NavigationAdapter, children: /* @__PURE__ */ jsx(InsforgeProviderCore, { ...providerProps, children }) }) });
60
60
  }
61
+ const ClientInsforgeProvider = InsforgeBrowserProvider;
61
62
  const useInsforge = useReactInsforge;
62
63
  export {
63
64
  ClientInsforgeProvider,
65
+ InsforgeBrowserProvider,
64
66
  useInsforge
65
67
  };
66
68
  //# sourceMappingURL=provider.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/client/provider.tsx"],"sourcesContent":["'use client';\n\nimport {\n InsforgeProviderCore,\n type InsforgeProviderProps,\n type InitialAuthState,\n useInsforge as useReactInsforge,\n NavigationProvider,\n StyleProvider,\n} from '@insforge/react';\nimport { NavigationAdapter } from '../navigation';\n\n// Extended interface for Next.js provider\ninterface ExtendedProviderProps extends InsforgeProviderProps {\n afterSignInUrl?: string;\n onSignIn?: (authToken: string) => Promise<void>;\n onSignOut?: () => Promise<void>;\n onRefresh?: (authToken: string) => Promise<void>;\n /**\n * Initial auth state from server (for SSR hydration)\n * @internal\n */\n initialState?: InitialAuthState;\n}\n\n// Sync token to server-side cookie using Authorization header\nasync function syncTokenToCookie(token: string): Promise<void> {\n try {\n const response = await fetch('/api/auth', {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n action: 'sync-token',\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n console.error('[Insforge Client Provider] sync-token failed:', errorText);\n }\n } catch (err) {\n console.error('[Insforge Client Provider] Failed to sync token to cookie:', err);\n }\n}\n\n// Sync token to server-side cookie on sign in\nasync function handleSignIn(token: string): Promise<void> {\n await syncTokenToCookie(token);\n}\n\n// Sync token to server-side cookie on refresh (page load/refresh)\nasync function handleRefresh(token: string): Promise<void> {\n await syncTokenToCookie(token);\n}\n\n// Clear HTTP-only cookie on sign out\nasync function handleSignOut(): Promise<void> {\n try {\n await fetch('/api/auth', { method: 'DELETE' });\n } catch {\n // API route doesn't exist - ignore\n }\n}\n\n/**\n * Client Insforge Provider for Next.js\n *\n * This is a Client Component ('use client') that:\n * 1. Receives initialState from Server Provider\n * 2. Manages authentication state on the client\n * 3. Syncs tokens to HTTP-only cookies via /api/auth\n *\n * @internal - Not intended for direct use. Use the Server Provider instead.\n */\nexport function ClientInsforgeProvider({\n children,\n client,\n afterSignInUrl = '/',\n onAuthChange,\n initialState,\n}: ExtendedProviderProps) {\n const providerProps: ExtendedProviderProps = {\n children,\n client,\n afterSignInUrl,\n onAuthChange,\n onSignIn: handleSignIn,\n onSignOut: handleSignOut,\n onRefresh: handleRefresh,\n initialState,\n };\n\n return (\n <StyleProvider>\n <NavigationProvider adapter={NavigationAdapter}>\n <InsforgeProviderCore {...providerProps}>{children}</InsforgeProviderCore>\n </NavigationProvider>\n </StyleProvider>\n );\n}\n\n/**\n * Hook to access Insforge context\n *\n * Re-exports the hook from @insforge/react for convenience.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { user, isSignedIn, signOut } = useInsforge();\n *\n * if (!isSignedIn) return <SignIn />;\n *\n * return (\n * <div>\n * <p>Welcome {user.email}</p>\n * <button onClick={signOut}>Sign Out</button>\n * </div>\n * );\n * }\n * ```\n */\nexport const useInsforge = useReactInsforge;\n"],"mappings":";AAkGQ;AAhGR;AAAA,EACE;AAAA,EAGA,eAAe;AAAA,EACf;AAAA,EACA;AAAA,OACK;AACP,SAAS,yBAAyB;AAgBlC,eAAe,kBAAkB,OAA8B;AAC7D,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,aAAa;AAAA,MACxC,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,eAAe,UAAU,KAAK;AAAA,QAC9B,gBAAgB;AAAA,MAClB;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB,QAAQ;AAAA,MACV,CAAC;AAAA,IACH,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,YAAY,MAAM,SAAS,KAAK;AACtC,cAAQ,MAAM,iDAAiD,SAAS;AAAA,IAC1E;AAAA,EACF,SAAS,KAAK;AACZ,YAAQ,MAAM,8DAA8D,GAAG;AAAA,EACjF;AACF;AAGA,eAAe,aAAa,OAA8B;AACxD,QAAM,kBAAkB,KAAK;AAC/B;AAGA,eAAe,cAAc,OAA8B;AACzD,QAAM,kBAAkB,KAAK;AAC/B;AAGA,eAAe,gBAA+B;AAC5C,MAAI;AACF,UAAM,MAAM,aAAa,EAAE,QAAQ,SAAS,CAAC;AAAA,EAC/C,QAAQ;AAAA,EAER;AACF;AAYO,SAAS,uBAAuB;AAAA,EACrC;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB;AAAA,EACA;AACF,GAA0B;AACxB,QAAM,gBAAuC;AAAA,IAC3C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV,WAAW;AAAA,IACX,WAAW;AAAA,IACX;AAAA,EACF;AAEA,SACE,oBAAC,iBACC,8BAAC,sBAAmB,SAAS,mBAC3B,8BAAC,wBAAsB,GAAG,eAAgB,UAAS,GACrD,GACF;AAEJ;AAuBO,MAAM,cAAc;","names":[]}
1
+ {"version":3,"sources":["../../../src/client/provider.tsx"],"sourcesContent":["'use client';\n\nimport {\n InsforgeProviderCore,\n type InsforgeProviderProps,\n type InitialAuthState,\n useInsforge as useReactInsforge,\n NavigationProvider,\n StyleProvider,\n} from '@insforge/react';\nimport { NavigationAdapter } from '../navigation';\nimport type { InsForgeClient } from '@insforge/sdk';\n\n/**\n * Props for InsforgeBrowserProvider\n */\nexport interface InsforgeBrowserProviderProps extends InsforgeProviderProps {\n children: React.ReactNode;\n /**\n * The InsForge SDK client instance.\n * \n * **Important:** Use the same client instance that you use for database,\n * storage, and other SDK operations. This ensures authentication tokens\n * are shared correctly.\n */\n client: InsForgeClient;\n /**\n * URL to redirect to after successful sign in\n * @default '/'\n */\n afterSignInUrl?: string;\n /**\n * Callback when auth state changes\n */\n onAuthChange?: (user: any) => void;\n /**\n * Initial auth state from server (for SSR hydration).\n * Get this using `getAuthFromCookies()`.\n */\n initialState?: InitialAuthState;\n}\n\n// Sync token to server-side cookie using Authorization header\nasync function syncTokenToCookie(token: string): Promise<void> {\n try {\n const response = await fetch('/api/auth', {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n action: 'sync-token',\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n console.error('[InsforgeBrowserProvider] sync-token failed:', errorText);\n }\n } catch (err) {\n console.error('[InsforgeBrowserProvider] Failed to sync token to cookie:', err);\n }\n}\n\n// Sync token to server-side cookie on sign in\nasync function handleSignIn(token: string): Promise<void> {\n await syncTokenToCookie(token);\n}\n\n// Sync token to server-side cookie on refresh (page load/refresh)\nasync function handleRefresh(token: string): Promise<void> {\n await syncTokenToCookie(token);\n}\n\n// Clear HTTP-only cookie on sign out\nasync function handleSignOut(): Promise<void> {\n try {\n await fetch('/api/auth', { method: 'DELETE' });\n } catch {\n // API route doesn't exist - ignore\n }\n}\n\n/**\n * Browser-side Insforge Provider for Next.js\n *\n * This provider manages authentication state on the client side and automatically\n * syncs tokens to HTTP-only cookies via `/api/auth` route for server-side access.\n *\n * **Key Features:**\n * - Uses YOUR SDK client instance (shared with database/storage operations)\n * - Automatic token sync to HTTP-only cookies\n * - SSR hydration support via `initialState`\n * - Works with Next.js App Router\n *\n * ---\n *\n * ## Setup Guide\n *\n * ### Step 1: Create your SDK client\n *\n * @example\n * ```tsx\n * // lib/insforge.ts\n * 'use client';\n * import { createClient } from '@insforge/sdk';\n *\n * export const insforge = createClient({\n * baseUrl: process.env.NEXT_PUBLIC_INSFORGE_URL!,\n * anonKey: process.env.NEXT_PUBLIC_INSFORGE_ANON_KEY!,\n * });\n * ```\n *\n * ### Step 2: Create your Providers component\n *\n * @example\n * ```tsx\n * // app/providers.tsx\n * 'use client';\n * import { InsforgeBrowserProvider, type InitialAuthState } from '@insforge/nextjs';\n * import { insforge } from '@/lib/insforge';\n *\n * export function Providers({\n * children,\n * initialState,\n * }: {\n * children: React.ReactNode;\n * initialState?: InitialAuthState;\n * }) {\n * return (\n * <InsforgeBrowserProvider\n * client={insforge}\n * initialState={initialState}\n * afterSignInUrl=\"/dashboard\"\n * >\n * {children}\n * </InsforgeBrowserProvider>\n * );\n * }\n * ```\n *\n * ### Step 3: Use in your root layout\n *\n * @example\n * ```tsx\n * // app/layout.tsx\n * import { getAuthFromCookies } from '@insforge/nextjs';\n * import { Providers } from './providers';\n *\n * export default async function RootLayout({\n * children,\n * }: {\n * children: React.ReactNode;\n * }) {\n * const initialState = await getAuthFromCookies();\n *\n * return (\n * <html>\n * <body>\n * <Providers initialState={initialState}>\n * {children}\n * </Providers>\n * </body>\n * </html>\n * );\n * }\n * ```\n *\n * ### Step 4: Use auth components and hooks\n *\n * @example\n * ```tsx\n * // app/page.tsx\n * 'use client';\n * import { SignIn, UserButton, useInsforge } from '@insforge/nextjs';\n *\n * export default function Page() {\n * const { isSignedIn, user } = useInsforge();\n *\n * if (!isSignedIn) return <SignIn />;\n *\n * return (\n * <div>\n * <UserButton />\n * <p>Welcome {user?.email}</p>\n * </div>\n * );\n * }\n * ```\n *\n * ---\n *\n * ## Why pass your own client?\n *\n * Authentication tokens are stored in the SDK client instance's memory.\n * If auth components use a different client than your app, they won't share\n * tokens, causing authentication to fail for database/storage operations.\n *\n * By passing YOUR client to the provider, all operations use the same\n * authenticated session.\n */\nexport function InsforgeBrowserProvider({\n children,\n client,\n afterSignInUrl = '/',\n onAuthChange,\n initialState,\n}: InsforgeBrowserProviderProps) {\n const providerProps: InsforgeProviderProps = {\n children,\n client,\n afterSignInUrl,\n onAuthChange,\n onSignIn: handleSignIn,\n onSignOut: handleSignOut,\n onRefresh: handleRefresh,\n initialState,\n };\n\n return (\n <StyleProvider>\n <NavigationProvider adapter={NavigationAdapter}>\n <InsforgeProviderCore {...providerProps}>{children}</InsforgeProviderCore>\n </NavigationProvider>\n </StyleProvider>\n );\n}\n\n/**\n * @deprecated Use `InsforgeBrowserProvider` instead.\n *\n * This alias is kept for backward compatibility and will be removed in a future version.\n *\n * Migration:\n * ```tsx\n * // Before\n * import { ClientInsforgeProvider } from '@insforge/nextjs';\n *\n * // After\n * import { InsforgeBrowserProvider } from '@insforge/nextjs';\n * ```\n */\nexport const ClientInsforgeProvider = InsforgeBrowserProvider;\n\n/**\n * Hook to access Insforge context\n *\n * Re-exports the hook from @insforge/react for convenience.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { user, isSignedIn, signOut } = useInsforge();\n *\n * if (!isSignedIn) return <SignIn />;\n *\n * return (\n * <div>\n * <p>Welcome {user.email}</p>\n * <button onClick={signOut}>Sign Out</button>\n * </div>\n * );\n * }\n * ```\n */\nexport const useInsforge = useReactInsforge;\n\n// Re-export types\nexport type { InitialAuthState };\n"],"mappings":";AA+NQ;AA7NR;AAAA,EACE;AAAA,EAGA,eAAe;AAAA,EACf;AAAA,EACA;AAAA,OACK;AACP,SAAS,yBAAyB;AAiClC,eAAe,kBAAkB,OAA8B;AAC7D,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,aAAa;AAAA,MACxC,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,eAAe,UAAU,KAAK;AAAA,QAC9B,gBAAgB;AAAA,MAClB;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB,QAAQ;AAAA,MACV,CAAC;AAAA,IACH,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,YAAY,MAAM,SAAS,KAAK;AACtC,cAAQ,MAAM,gDAAgD,SAAS;AAAA,IACzE;AAAA,EACF,SAAS,KAAK;AACZ,YAAQ,MAAM,6DAA6D,GAAG;AAAA,EAChF;AACF;AAGA,eAAe,aAAa,OAA8B;AACxD,QAAM,kBAAkB,KAAK;AAC/B;AAGA,eAAe,cAAc,OAA8B;AACzD,QAAM,kBAAkB,KAAK;AAC/B;AAGA,eAAe,gBAA+B;AAC5C,MAAI;AACF,UAAM,MAAM,aAAa,EAAE,QAAQ,SAAS,CAAC;AAAA,EAC/C,QAAQ;AAAA,EAER;AACF;AAwHO,SAAS,wBAAwB;AAAA,EACtC;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB;AAAA,EACA;AACF,GAAiC;AAC/B,QAAM,gBAAuC;AAAA,IAC3C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV,WAAW;AAAA,IACX,WAAW;AAAA,IACX;AAAA,EACF;AAEA,SACE,oBAAC,iBACC,8BAAC,sBAAmB,SAAS,mBAC3B,8BAAC,wBAAsB,GAAG,eAAgB,UAAS,GACrD,GACF;AAEJ;AAgBO,MAAM,yBAAyB;AAuB/B,MAAM,cAAc;","names":[]}
@@ -1,6 +1,12 @@
1
1
  "use client";
2
- import { ClientInsforgeProvider } from "./client/provider";
2
+ import {
3
+ InsforgeBrowserProvider,
4
+ InsforgeBrowserProvider as InsforgeBrowserProvider2,
5
+ ClientInsforgeProvider
6
+ } from "./client/provider";
3
7
  export {
4
- ClientInsforgeProvider as InsforgeProvider
8
+ ClientInsforgeProvider,
9
+ InsforgeBrowserProvider,
10
+ InsforgeBrowserProvider2 as InsforgeProvider
5
11
  };
6
12
  //# sourceMappingURL=components.client.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components.client.ts"],"sourcesContent":["'use client';\n\n// Client Component exports (from client folder)\n// This file is used when code runs in a Client Component (browser environment)\nexport { ClientInsforgeProvider as InsforgeProvider } from './client/provider';\n"],"mappings":";AAIA,SAAmC,8BAAwB;","names":[]}
1
+ {"version":3,"sources":["../../src/components.client.ts"],"sourcesContent":["'use client';\n\n// Client Component exports (from client folder)\n// This file is used when code runs in a Client Component (browser environment)\n\n// Export both names for flexibility\n// InsforgeBrowserProvider is the recommended name for Next.js\n// InsforgeProvider is kept for backward compatibility with conditional exports\nexport { \n InsforgeBrowserProvider,\n InsforgeBrowserProvider as InsforgeProvider,\n ClientInsforgeProvider, // Deprecated alias\n} from './client/provider';\n"],"mappings":";AAQA;AAAA,EACE;AAAA,EAC2B,2BAA3BA;AAAA,EACA;AAAA,OACK;","names":["InsforgeBrowserProvider"]}
package/dist/esm/index.js CHANGED
@@ -1,4 +1,8 @@
1
1
  import { InsforgeProvider } from "#components";
2
+ import {
3
+ InsforgeBrowserProvider,
4
+ ClientInsforgeProvider
5
+ } from "./client/provider";
2
6
  import { useInsforge } from "./client/provider";
3
7
  import {
4
8
  SignIn,
@@ -38,6 +42,8 @@ import {
38
42
  AuthResetPasswordVerificationStep
39
43
  } from "./client/components";
40
44
  import { useAuth, useUser, usePublicAuthConfig } from "./client/hooks";
45
+ import { getAuthFromCookies } from "./server/InsforgeProvider";
46
+ import { auth } from "./server/auth";
41
47
  export {
42
48
  AuthBranding,
43
49
  AuthContainer,
@@ -54,8 +60,10 @@ export {
54
60
  AuthResetPasswordVerificationStep,
55
61
  AuthSubmitButton,
56
62
  AuthVerificationCodeInput,
63
+ ClientInsforgeProvider,
57
64
  ForgotPassword,
58
65
  ForgotPasswordForm,
66
+ InsforgeBrowserProvider,
59
67
  InsforgeProvider,
60
68
  Protect,
61
69
  ResetPassword,
@@ -71,6 +79,8 @@ export {
71
79
  UserButton,
72
80
  VerifyEmail,
73
81
  VerifyEmailStatus,
82
+ auth,
83
+ getAuthFromCookies,
74
84
  useAuth,
75
85
  useInsforge,
76
86
  usePublicAuthConfig,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["// Provider - Uses conditional exports to provide correct version\n// In Server Components: exports from server/InsforgeProvider (async, uses next/headers)\n// In Client Components: exports from client/provider (use client)\nexport { InsforgeProvider } from '#components';\n\n// Hooks (from client)\nexport { useInsforge } from './client/provider';\n\n/**\n * These need to be explicitly listed. Do not use an * here.\n * If you do, app router will break.\n *\n * Pattern learned from @clerk/nextjs\n */\n\n// Main UI Components\nexport {\n SignIn,\n SignUp,\n ForgotPassword,\n ResetPassword,\n VerifyEmail,\n UserButton,\n Protect,\n SignedIn,\n SignedOut,\n SignInButton,\n SignUpButton,\n} from './client/components';\n\n// Form Components\nexport {\n SignInForm,\n SignUpForm,\n ForgotPasswordForm,\n ResetPasswordForm,\n VerifyEmailStatus,\n} from './client/components';\n\n// Atom Components\nexport {\n AuthBranding,\n AuthContainer,\n AuthHeader,\n AuthErrorBanner,\n AuthFormField,\n AuthPasswordField,\n AuthPasswordStrengthIndicator,\n AuthSubmitButton,\n AuthLink,\n AuthDivider,\n AuthOAuthButton,\n AuthOAuthProviders,\n AuthVerificationCodeInput,\n AuthEmailVerificationStep,\n AuthResetPasswordVerificationStep,\n} from './client/components';\n\n// Component Types\nexport type {\n SignInProps,\n SignUpProps,\n ForgotPasswordProps,\n ResetPasswordProps,\n VerifyEmailProps,\n UserButtonProps,\n ProtectProps,\n ConditionalProps,\n SignInFormProps,\n SignUpFormProps,\n ForgotPasswordFormProps,\n ResetPasswordFormProps,\n VerifyEmailStatusProps,\n AuthContainerProps,\n AuthHeaderProps,\n AuthErrorBannerProps,\n AuthFormFieldProps,\n AuthPasswordFieldProps,\n AuthPasswordStrengthIndicatorProps,\n AuthSubmitButtonProps,\n AuthLinkProps,\n AuthDividerProps,\n AuthOAuthButtonProps,\n AuthOAuthProvidersProps,\n AuthVerificationCodeInputProps,\n} from './client/components';\n\n// Hooks\nexport { useAuth, useUser, usePublicAuthConfig } from './client/hooks';\n"],"mappings":"AAGA,SAAS,wBAAwB;AAGjC,SAAS,mBAAmB;AAU5B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAgCP,SAAS,SAAS,SAAS,2BAA2B;","names":[]}
1
+ {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["// Provider - Uses conditional exports to provide correct version\n// In Server Components: exports from server/InsforgeProvider (async, uses next/headers)\n// In Client Components: exports from client/provider (use client)\nexport { InsforgeProvider } from '#components';\n\n// Browser Provider - The recommended way to use Insforge in Next.js\n// Use this directly in a client component for proper SDK client sharing\nexport { \n InsforgeBrowserProvider,\n ClientInsforgeProvider, // Deprecated alias\n type InsforgeBrowserProviderProps,\n type InitialAuthState,\n} from './client/provider';\n\n// Hooks (from client)\nexport { useInsforge } from './client/provider';\n\n/**\n * These need to be explicitly listed. Do not use an * here.\n * If you do, app router will break.\n *\n * Pattern learned from @clerk/nextjs\n */\n\n// Main UI Components\nexport {\n SignIn,\n SignUp,\n ForgotPassword,\n ResetPassword,\n VerifyEmail,\n UserButton,\n Protect,\n SignedIn,\n SignedOut,\n SignInButton,\n SignUpButton,\n} from './client/components';\n\n// Form Components\nexport {\n SignInForm,\n SignUpForm,\n ForgotPasswordForm,\n ResetPasswordForm,\n VerifyEmailStatus,\n} from './client/components';\n\n// Atom Components\nexport {\n AuthBranding,\n AuthContainer,\n AuthHeader,\n AuthErrorBanner,\n AuthFormField,\n AuthPasswordField,\n AuthPasswordStrengthIndicator,\n AuthSubmitButton,\n AuthLink,\n AuthDivider,\n AuthOAuthButton,\n AuthOAuthProviders,\n AuthVerificationCodeInput,\n AuthEmailVerificationStep,\n AuthResetPasswordVerificationStep,\n} from './client/components';\n\n// Component Types\nexport type {\n SignInProps,\n SignUpProps,\n ForgotPasswordProps,\n ResetPasswordProps,\n VerifyEmailProps,\n UserButtonProps,\n ProtectProps,\n ConditionalProps,\n SignInFormProps,\n SignUpFormProps,\n ForgotPasswordFormProps,\n ResetPasswordFormProps,\n VerifyEmailStatusProps,\n AuthContainerProps,\n AuthHeaderProps,\n AuthErrorBannerProps,\n AuthFormFieldProps,\n AuthPasswordFieldProps,\n AuthPasswordStrengthIndicatorProps,\n AuthSubmitButtonProps,\n AuthLinkProps,\n AuthDividerProps,\n AuthOAuthButtonProps,\n AuthOAuthProvidersProps,\n AuthVerificationCodeInputProps,\n} from './client/components';\n\n// Hooks\nexport { useAuth, useUser, usePublicAuthConfig } from './client/hooks';\n\n// Server utilities (use in Server Components only)\nexport { getAuthFromCookies } from './server/InsforgeProvider';\nexport { auth, type InsforgeAuth } from './server/auth';\n"],"mappings":"AAGA,SAAS,wBAAwB;AAIjC;AAAA,EACE;AAAA,EACA;AAAA,OAGK;AAGP,SAAS,mBAAmB;AAU5B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAgCP,SAAS,SAAS,SAAS,2BAA2B;AAGtD,SAAS,0BAA0B;AACnC,SAAS,YAA+B;","names":[]}
@@ -1,5 +1,5 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { ClientInsforgeProvider } from "../client/provider";
2
+ import { InsforgeBrowserProvider } from "../client/provider";
3
3
  import { cookies } from "next/headers";
4
4
  import { COOKIE_NAMES, parseUserCookie } from "../lib/cookies";
5
5
  async function getAuthFromCookies() {
@@ -36,7 +36,7 @@ async function getAuthFromCookies() {
36
36
  async function InsforgeProvider(props) {
37
37
  const { children, dynamic = true, client, ...restProps } = props;
38
38
  const initialAuth = dynamic ? await getAuthFromCookies() : { user: null, userId: null };
39
- return /* @__PURE__ */ jsx(ClientInsforgeProvider, { client, initialState: initialAuth, ...restProps, children });
39
+ return /* @__PURE__ */ jsx(InsforgeBrowserProvider, { client, initialState: initialAuth, ...restProps, children });
40
40
  }
41
41
  export {
42
42
  InsforgeProvider,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/server/InsforgeProvider.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport { ClientInsforgeProvider } from '../client/provider';\nimport type { InsforgeProviderProps, InitialAuthState } from '@insforge/react';\nimport { cookies } from 'next/headers';\nimport { COOKIE_NAMES, parseUserCookie } from '../lib/cookies';\n\nexport interface InsforgeProviderServerProps extends Omit<InsforgeProviderProps, 'initialState'> {\n children: ReactNode;\n /**\n * Opt into dynamic rendering to read auth state from cookies during SSR.\n *\n * - When true: Reads cookies on server, prevents content flashing, opts into dynamic rendering\n * - When false: Static rendering, may see brief content flash during hydration\n *\n * Following Clerk's pattern: dynamic prop controls server-side auth state access\n *\n * @default false\n *\n * @example\n * ```tsx\n * <InsforgeProvider baseUrl={...} dynamic>\n * {children}\n * </InsforgeProvider>\n * ```\n */\n dynamic?: boolean;\n}\n\n/**\n * Get initial auth state from cookies (server-side)\n *\n * This helper reads the authentication state from cookies set by the SDK.\n * Use this in Server Components or Server Actions to get the initial auth state\n * and pass it to the InsforgeProvider via initialState prop.\n *\n * This prevents hydration mismatches by ensuring SSR and client render have the same state.\n *\n * @example\n * ```tsx\n * // app/layout.tsx (Server Component)\n * import { InsforgeProvider } from '@insforge/nextjs';\n * import { getAuthFromCookies } from '@insforge/nextjs/api/auth-helpers';\n *\n * export default async function RootLayout({ children }) {\n * const initialAuth = await getAuthFromCookies();\n *\n * return (\n * <html>\n * <body>\n * <InsforgeProvider\n * baseUrl={process.env.NEXT_PUBLIC_INSFORGE_BASE_URL!}\n * initialState={initialAuth}\n * >\n * {children}\n * </InsforgeProvider>\n * </body>\n * </html>\n * );\n * }\n * ```\n *\n * @returns Initial auth state with user and userId, or empty object if not authenticated\n */\nexport async function getAuthFromCookies(): Promise<InitialAuthState> {\n try {\n const cookieStore = await cookies();\n\n // Read session token from cookie (set by middleware or /api/auth route)\n const token = cookieStore.get(COOKIE_NAMES.SESSION)?.value || null;\n\n if (!token) {\n // Not authenticated - return null to indicate signed out\n return {\n user: null,\n userId: null,\n };\n }\n\n // Read user identity from cookie (set by middleware or /api/auth route)\n const userCookie = cookieStore.get(COOKIE_NAMES.USER)?.value;\n\n try {\n const user = parseUserCookie(userCookie);\n\n // Return basic user info from cookie\n // This is lightweight data for SSR hydration only\n // Full profile will be loaded by SDK's getCurrentUser() after hydration\n return {\n user,\n userId: user?.id || null,\n };\n } catch {\n // Invalid user data in cookie\n return {\n user: null,\n userId: null,\n };\n }\n } catch (error) {\n // Error reading cookies (might be in middleware or edge runtime)\n console.error('[Insforge] Error reading cookies:', error);\n return {\n user: null,\n userId: null,\n };\n }\n}\n\n/**\n * Server Component Provider for Insforge\n *\n * This is a Server Component (no 'use client') that:\n * 1. Optionally reads auth state from cookies on the server (when dynamic=true)\n * 2. Passes initialState to the Client Provider\n * 3. Ensures SSR and client hydration match perfectly\n *\n * Following Clerk's pattern: packages/nextjs/src/app-router/server/ClerkProvider.tsx\n *\n * @example\n * ```tsx\n * // app/layout.tsx (Server Component)\n * import { InsforgeProvider } from '@insforge/nextjs';\n * import { insforge } from '@/lib/insforge';\n *\n * export default async function RootLayout({ children }) {\n * return (\n * <html>\n * <body>\n * <InsforgeProvider\n * client={insforge}\n * dynamic // 👈 Enable dynamic rendering for SSR auth\n * >\n * {children}\n * </InsforgeProvider>\n * </body>\n * </html>\n * );\n * }\n * ```\n */\nexport async function InsforgeProvider(props: InsforgeProviderServerProps) {\n const { children, dynamic = true, client, ...restProps } = props;\n\n // Only read cookies if dynamic=true (opts into dynamic rendering)\n // When dynamic=false, Next.js can statically generate the page\n const initialAuth = dynamic ? await getAuthFromCookies() : { user: null, userId: null };\n\n // Pass initialState to Client Provider\n return (\n <ClientInsforgeProvider client={client} initialState={initialAuth} {...restProps}>\n {children}\n </ClientInsforgeProvider>\n );\n}\n"],"mappings":"AAqJI;AApJJ,SAAS,8BAA8B;AAEvC,SAAS,eAAe;AACxB,SAAS,cAAc,uBAAuB;AA2D9C,eAAsB,qBAAgD;AACpE,MAAI;AACF,UAAM,cAAc,MAAM,QAAQ;AAGlC,UAAM,QAAQ,YAAY,IAAI,aAAa,OAAO,GAAG,SAAS;AAE9D,QAAI,CAAC,OAAO;AAEV,aAAO;AAAA,QACL,MAAM;AAAA,QACN,QAAQ;AAAA,MACV;AAAA,IACF;AAGA,UAAM,aAAa,YAAY,IAAI,aAAa,IAAI,GAAG;AAEvD,QAAI;AACF,YAAM,OAAO,gBAAgB,UAAU;AAKvC,aAAO;AAAA,QACL;AAAA,QACA,QAAQ,MAAM,MAAM;AAAA,MACtB;AAAA,IACF,QAAQ;AAEN,aAAO;AAAA,QACL,MAAM;AAAA,QACN,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AAEd,YAAQ,MAAM,qCAAqC,KAAK;AACxD,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ;AAAA,IACV;AAAA,EACF;AACF;AAkCA,eAAsB,iBAAiB,OAAoC;AACzE,QAAM,EAAE,UAAU,UAAU,MAAM,QAAQ,GAAG,UAAU,IAAI;AAI3D,QAAM,cAAc,UAAU,MAAM,mBAAmB,IAAI,EAAE,MAAM,MAAM,QAAQ,KAAK;AAGtF,SACE,oBAAC,0BAAuB,QAAgB,cAAc,aAAc,GAAG,WACpE,UACH;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/server/InsforgeProvider.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport { InsforgeBrowserProvider } from '../client/provider';\nimport type { InsforgeProviderProps, InitialAuthState } from '@insforge/react';\nimport { cookies } from 'next/headers';\nimport { COOKIE_NAMES, parseUserCookie } from '../lib/cookies';\nimport type { InsForgeClient } from '@insforge/sdk';\n\nexport interface InsforgeProviderServerProps extends Omit<InsforgeProviderProps, 'initialState'> {\n children: ReactNode;\n /**\n * The InsForge SDK client instance.\n * \n * ⚠️ **Warning:** In Next.js, SDK client instances (class objects) cannot be\n * passed from Server Components to Client Components. You should use\n * `InsforgeBrowserProvider` directly in a client component instead.\n */\n client: InsForgeClient;\n /**\n * Opt into dynamic rendering to read auth state from cookies during SSR.\n *\n * - When true: Reads cookies on server, prevents content flashing, opts into dynamic rendering\n * - When false: Static rendering, may see brief content flash during hydration\n *\n * @default true\n */\n dynamic?: boolean;\n}\n\n/**\n * Get initial auth state from cookies (server-side)\n *\n * This helper reads the authentication state from cookies set by the SDK.\n * Use this in Server Components to get the initial auth state and pass it\n * to `InsforgeBrowserProvider` via the `initialState` prop.\n *\n * This prevents hydration mismatches by ensuring SSR and client render have the same state.\n *\n * @example\n * ```tsx\n * // app/layout.tsx (Server Component)\n * import { getAuthFromCookies } from '@insforge/nextjs';\n * import { Providers } from './providers';\n *\n * export default async function RootLayout({ children }) {\n * const initialState = await getAuthFromCookies();\n *\n * return (\n * <html>\n * <body>\n * <Providers initialState={initialState}>\n * {children}\n * </Providers>\n * </body>\n * </html>\n * );\n * }\n * ```\n *\n * @returns Initial auth state with user and userId, or null values if not authenticated\n */\nexport async function getAuthFromCookies(): Promise<InitialAuthState> {\n try {\n const cookieStore = await cookies();\n\n // Read session token from cookie (set by middleware or /api/auth route)\n const token = cookieStore.get(COOKIE_NAMES.SESSION)?.value || null;\n\n if (!token) {\n // Not authenticated - return null to indicate signed out\n return {\n user: null,\n userId: null,\n };\n }\n\n // Read user identity from cookie (set by middleware or /api/auth route)\n const userCookie = cookieStore.get(COOKIE_NAMES.USER)?.value;\n\n try {\n const user = parseUserCookie(userCookie);\n\n // Return basic user info from cookie\n // This is lightweight data for SSR hydration only\n // Full profile will be loaded by SDK's getCurrentUser() after hydration\n return {\n user,\n userId: user?.id || null,\n };\n } catch {\n // Invalid user data in cookie\n return {\n user: null,\n userId: null,\n };\n }\n } catch (error) {\n // Error reading cookies (might be in middleware or edge runtime)\n console.error('[Insforge] Error reading cookies:', error);\n return {\n user: null,\n userId: null,\n };\n }\n}\n\n/**\n * @deprecated **This component is deprecated.** Use `InsforgeBrowserProvider` instead.\n *\n * This Server Component wrapper doesn't work correctly because SDK client instances\n * (class objects) cannot be serialized and passed from Server to Client Components.\n *\n * ---\n *\n * ## Migration Guide\n *\n * ### Before (deprecated):\n * ```tsx\n * // app/layout.tsx\n * import { InsforgeProvider } from '@insforge/nextjs';\n * import { insforge } from '@/lib/insforge';\n *\n * export default function RootLayout({ children }) {\n * return (\n * <InsforgeProvider client={insforge}> // This fails!\n * {children}\n * </InsforgeProvider>\n * );\n * }\n * ```\n *\n * ### After (recommended):\n *\n * **Step 1:** Create a client-side Providers component:\n * ```tsx\n * // app/providers.tsx\n * 'use client';\n * import { InsforgeBrowserProvider, type InitialAuthState } from '@insforge/nextjs';\n * import { insforge } from '@/lib/insforge';\n *\n * export function Providers({\n * children,\n * initialState,\n * }: {\n * children: React.ReactNode;\n * initialState?: InitialAuthState;\n * }) {\n * return (\n * <InsforgeBrowserProvider client={insforge} initialState={initialState}>\n * {children}\n * </InsforgeBrowserProvider>\n * );\n * }\n * ```\n *\n * **Step 2:** Use it in your layout:\n * ```tsx\n * // app/layout.tsx\n * import { getAuthFromCookies } from '@insforge/nextjs';\n * import { Providers } from './providers';\n *\n * export default async function RootLayout({ children }) {\n * const initialState = await getAuthFromCookies();\n *\n * return (\n * <html>\n * <body>\n * <Providers initialState={initialState}>\n * {children}\n * </Providers>\n * </body>\n * </html>\n * );\n * }\n * ```\n *\n * ---\n *\n * @see InsforgeBrowserProvider - The recommended client-side provider\n * @see getAuthFromCookies - Helper to get initial auth state for SSR\n */\nexport async function InsforgeProvider(props: InsforgeProviderServerProps) {\n const { children, dynamic = true, client, ...restProps } = props;\n\n // Only read cookies if dynamic=true (opts into dynamic rendering)\n // When dynamic=false, Next.js can statically generate the page\n const initialAuth = dynamic ? await getAuthFromCookies() : { user: null, userId: null };\n\n // Pass initialState to Client Provider\n // Note: This will fail at runtime because `client` is a class instance\n return (\n <InsforgeBrowserProvider client={client} initialState={initialAuth} {...restProps}>\n {children}\n </InsforgeBrowserProvider>\n );\n}\n"],"mappings":"AA8LI;AA7LJ,SAAS,+BAA+B;AAExC,SAAS,eAAe;AACxB,SAAS,cAAc,uBAAuB;AAwD9C,eAAsB,qBAAgD;AACpE,MAAI;AACF,UAAM,cAAc,MAAM,QAAQ;AAGlC,UAAM,QAAQ,YAAY,IAAI,aAAa,OAAO,GAAG,SAAS;AAE9D,QAAI,CAAC,OAAO;AAEV,aAAO;AAAA,QACL,MAAM;AAAA,QACN,QAAQ;AAAA,MACV;AAAA,IACF;AAGA,UAAM,aAAa,YAAY,IAAI,aAAa,IAAI,GAAG;AAEvD,QAAI;AACF,YAAM,OAAO,gBAAgB,UAAU;AAKvC,aAAO;AAAA,QACL;AAAA,QACA,QAAQ,MAAM,MAAM;AAAA,MACtB;AAAA,IACF,QAAQ;AAEN,aAAO;AAAA,QACL,MAAM;AAAA,QACN,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AAEd,YAAQ,MAAM,qCAAqC,KAAK;AACxD,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ;AAAA,IACV;AAAA,EACF;AACF;AA6EA,eAAsB,iBAAiB,OAAoC;AACzE,QAAM,EAAE,UAAU,UAAU,MAAM,QAAQ,GAAG,UAAU,IAAI;AAI3D,QAAM,cAAc,UAAU,MAAM,mBAAmB,IAAI,EAAE,MAAM,MAAM,QAAQ,KAAK;AAItF,SACE,oBAAC,2BAAwB,QAAgB,cAAc,aAAc,GAAG,WACrE,UACH;AAEJ;","names":[]}
@@ -1,7 +1,9 @@
1
- import { InsforgeProvider } from "./InsforgeProvider";
1
+ import { getAuthFromCookies } from "./InsforgeProvider";
2
2
  import { auth } from "./auth";
3
+ import { InsforgeProvider } from "./InsforgeProvider";
3
4
  export {
4
5
  InsforgeProvider,
5
- auth
6
+ auth,
7
+ getAuthFromCookies
6
8
  };
7
9
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/server/index.ts"],"sourcesContent":["// Server-side exports (Server Components, no 'use client')\nexport { InsforgeProvider } from './InsforgeProvider';\nexport { auth } from './auth';\nexport type { InsforgeAuth } from './auth';\n"],"mappings":"AACA,SAAS,wBAAwB;AACjC,SAAS,YAAY;","names":[]}
1
+ {"version":3,"sources":["../../../src/server/index.ts"],"sourcesContent":["// Server-side exports (Server Components, no 'use client')\n\n// Auth helpers\nexport { getAuthFromCookies } from './InsforgeProvider';\nexport { auth } from './auth';\nexport type { InsforgeAuth } from './auth';\n\n// Deprecated: Server Provider (doesn't work due to Next.js serialization constraints)\n// Use InsforgeBrowserProvider directly in a client component instead\nexport { InsforgeProvider } from './InsforgeProvider';\n"],"mappings":"AAGA,SAAS,0BAA0B;AACnC,SAAS,YAAY;AAKrB,SAAS,wBAAwB;","names":[]}
package/dist/index.d.ts CHANGED
@@ -1,8 +1,11 @@
1
- export { InsforgeProvider } from './server/InsforgeProvider.js';
2
- export { useInsforge } from './client/provider.js';
1
+ export { InsforgeProvider, getAuthFromCookies } from './server/InsforgeProvider.js';
2
+ export { ClientInsforgeProvider, InsforgeBrowserProvider, InsforgeBrowserProviderProps, useInsforge } from './client/provider.js';
3
3
  export { AuthBranding, AuthContainer, AuthContainerProps, AuthDivider, AuthDividerProps, AuthEmailVerificationStep, AuthErrorBanner, AuthErrorBannerProps, AuthFormField, AuthFormFieldProps, AuthHeader, AuthHeaderProps, AuthLink, AuthLinkProps, AuthOAuthButton, AuthOAuthButtonProps, AuthOAuthProviders, AuthOAuthProvidersProps, AuthPasswordField, AuthPasswordFieldProps, AuthPasswordStrengthIndicator, AuthPasswordStrengthIndicatorProps, AuthResetPasswordVerificationStep, AuthSubmitButton, AuthSubmitButtonProps, AuthVerificationCodeInput, AuthVerificationCodeInputProps, ConditionalProps, ForgotPassword, ForgotPasswordForm, ForgotPasswordFormProps, ForgotPasswordProps, Protect, ProtectProps, ResetPassword, ResetPasswordForm, ResetPasswordFormProps, ResetPasswordProps, SignIn, SignInButton, SignInForm, SignInFormProps, SignInProps, SignUp, SignUpButton, SignUpForm, SignUpFormProps, SignUpProps, SignedIn, SignedOut, UserButton, UserButtonProps, VerifyEmail, VerifyEmailProps, VerifyEmailStatus, VerifyEmailStatusProps } from '@insforge/react/components';
4
4
  export { useAuth, usePublicAuthConfig, useUser } from './client/hooks.js';
5
+ export { InsforgeAuth, auth } from './server/auth.js';
6
+ export { InitialAuthState } from '@insforge/react';
5
7
  import 'react/jsx-runtime';
6
8
  import 'react';
7
- import '@insforge/react';
9
+ import '@insforge/sdk';
8
10
  import '@insforge/shared-schemas';
11
+ import '@insforge/shared';
@@ -1,25 +1,25 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
3
  import { InsforgeProviderProps, InitialAuthState } from '@insforge/react';
4
+ import { InsForgeClient } from '@insforge/sdk';
4
5
 
5
6
  interface InsforgeProviderServerProps extends Omit<InsforgeProviderProps, 'initialState'> {
6
7
  children: ReactNode;
8
+ /**
9
+ * The InsForge SDK client instance.
10
+ *
11
+ * ⚠️ **Warning:** In Next.js, SDK client instances (class objects) cannot be
12
+ * passed from Server Components to Client Components. You should use
13
+ * `InsforgeBrowserProvider` directly in a client component instead.
14
+ */
15
+ client: InsForgeClient;
7
16
  /**
8
17
  * Opt into dynamic rendering to read auth state from cookies during SSR.
9
18
  *
10
19
  * - When true: Reads cookies on server, prevents content flashing, opts into dynamic rendering
11
20
  * - When false: Static rendering, may see brief content flash during hydration
12
21
  *
13
- * Following Clerk's pattern: dynamic prop controls server-side auth state access
14
- *
15
- * @default false
16
- *
17
- * @example
18
- * ```tsx
19
- * <InsforgeProvider baseUrl={...} dynamic>
20
- * {children}
21
- * </InsforgeProvider>
22
- * ```
22
+ * @default true
23
23
  */
24
24
  dynamic?: boolean;
25
25
  }
@@ -27,69 +27,109 @@ interface InsforgeProviderServerProps extends Omit<InsforgeProviderProps, 'initi
27
27
  * Get initial auth state from cookies (server-side)
28
28
  *
29
29
  * This helper reads the authentication state from cookies set by the SDK.
30
- * Use this in Server Components or Server Actions to get the initial auth state
31
- * and pass it to the InsforgeProvider via initialState prop.
30
+ * Use this in Server Components to get the initial auth state and pass it
31
+ * to `InsforgeBrowserProvider` via the `initialState` prop.
32
32
  *
33
33
  * This prevents hydration mismatches by ensuring SSR and client render have the same state.
34
34
  *
35
35
  * @example
36
36
  * ```tsx
37
37
  * // app/layout.tsx (Server Component)
38
- * import { InsforgeProvider } from '@insforge/nextjs';
39
- * import { getAuthFromCookies } from '@insforge/nextjs/api/auth-helpers';
38
+ * import { getAuthFromCookies } from '@insforge/nextjs';
39
+ * import { Providers } from './providers';
40
40
  *
41
41
  * export default async function RootLayout({ children }) {
42
- * const initialAuth = await getAuthFromCookies();
42
+ * const initialState = await getAuthFromCookies();
43
43
  *
44
44
  * return (
45
45
  * <html>
46
46
  * <body>
47
- * <InsforgeProvider
48
- * baseUrl={process.env.NEXT_PUBLIC_INSFORGE_BASE_URL!}
49
- * initialState={initialAuth}
50
- * >
47
+ * <Providers initialState={initialState}>
51
48
  * {children}
52
- * </InsforgeProvider>
49
+ * </Providers>
53
50
  * </body>
54
51
  * </html>
55
52
  * );
56
53
  * }
57
54
  * ```
58
55
  *
59
- * @returns Initial auth state with user and userId, or empty object if not authenticated
56
+ * @returns Initial auth state with user and userId, or null values if not authenticated
60
57
  */
61
58
  declare function getAuthFromCookies(): Promise<InitialAuthState>;
62
59
  /**
63
- * Server Component Provider for Insforge
60
+ * @deprecated **This component is deprecated.** Use `InsforgeBrowserProvider` instead.
64
61
  *
65
- * This is a Server Component (no 'use client') that:
66
- * 1. Optionally reads auth state from cookies on the server (when dynamic=true)
67
- * 2. Passes initialState to the Client Provider
68
- * 3. Ensures SSR and client hydration match perfectly
62
+ * This Server Component wrapper doesn't work correctly because SDK client instances
63
+ * (class objects) cannot be serialized and passed from Server to Client Components.
69
64
  *
70
- * Following Clerk's pattern: packages/nextjs/src/app-router/server/ClerkProvider.tsx
65
+ * ---
71
66
  *
72
- * @example
67
+ * ## Migration Guide
68
+ *
69
+ * ### Before (deprecated):
73
70
  * ```tsx
74
- * // app/layout.tsx (Server Component)
71
+ * // app/layout.tsx
75
72
  * import { InsforgeProvider } from '@insforge/nextjs';
76
73
  * import { insforge } from '@/lib/insforge';
77
74
  *
75
+ * export default function RootLayout({ children }) {
76
+ * return (
77
+ * <InsforgeProvider client={insforge}> // ❌ This fails!
78
+ * {children}
79
+ * </InsforgeProvider>
80
+ * );
81
+ * }
82
+ * ```
83
+ *
84
+ * ### After (recommended):
85
+ *
86
+ * **Step 1:** Create a client-side Providers component:
87
+ * ```tsx
88
+ * // app/providers.tsx
89
+ * 'use client';
90
+ * import { InsforgeBrowserProvider, type InitialAuthState } from '@insforge/nextjs';
91
+ * import { insforge } from '@/lib/insforge';
92
+ *
93
+ * export function Providers({
94
+ * children,
95
+ * initialState,
96
+ * }: {
97
+ * children: React.ReactNode;
98
+ * initialState?: InitialAuthState;
99
+ * }) {
100
+ * return (
101
+ * <InsforgeBrowserProvider client={insforge} initialState={initialState}>
102
+ * {children}
103
+ * </InsforgeBrowserProvider>
104
+ * );
105
+ * }
106
+ * ```
107
+ *
108
+ * **Step 2:** Use it in your layout:
109
+ * ```tsx
110
+ * // app/layout.tsx
111
+ * import { getAuthFromCookies } from '@insforge/nextjs';
112
+ * import { Providers } from './providers';
113
+ *
78
114
  * export default async function RootLayout({ children }) {
115
+ * const initialState = await getAuthFromCookies();
116
+ *
79
117
  * return (
80
118
  * <html>
81
119
  * <body>
82
- * <InsforgeProvider
83
- * client={insforge}
84
- * dynamic // 👈 Enable dynamic rendering for SSR auth
85
- * >
120
+ * <Providers initialState={initialState}>
86
121
  * {children}
87
- * </InsforgeProvider>
122
+ * </Providers>
88
123
  * </body>
89
124
  * </html>
90
125
  * );
91
126
  * }
92
127
  * ```
128
+ *
129
+ * ---
130
+ *
131
+ * @see InsforgeBrowserProvider - The recommended client-side provider
132
+ * @see getAuthFromCookies - Helper to get initial auth state for SSR
93
133
  */
94
134
  declare function InsforgeProvider(props: InsforgeProviderServerProps): Promise<react_jsx_runtime.JSX.Element>;
95
135
 
@@ -1,6 +1,7 @@
1
- export { InsforgeProvider } from './InsforgeProvider.js';
1
+ export { InsforgeProvider, getAuthFromCookies } from './InsforgeProvider.js';
2
2
  export { InsforgeAuth, auth } from './auth.js';
3
3
  import 'react/jsx-runtime';
4
4
  import 'react';
5
5
  import '@insforge/react';
6
+ import '@insforge/sdk';
6
7
  import '@insforge/shared';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@insforge/nextjs",
3
- "version": "1.0.5-dev.6",
3
+ "version": "1.0.5-dev.8",
4
4
  "description": "Pre-built authentication UI components for Next.js with Insforge backend - zero configuration required",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",