@insforge/react 0.6.4 → 0.6.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/atoms.cjs +3 -2
- package/dist/atoms.cjs.map +1 -1
- package/dist/atoms.js +3 -2
- package/dist/atoms.js.map +1 -1
- package/dist/components.cjs +17 -22
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.cts +16 -0
- package/dist/components.d.ts +16 -0
- package/dist/components.js +17 -22
- package/dist/components.js.map +1 -1
- package/dist/forms.cjs +3 -2
- package/dist/forms.cjs.map +1 -1
- package/dist/forms.js +3 -2
- package/dist/forms.js.map +1 -1
- package/dist/hooks.cjs +3 -2
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.d.cts +2 -2
- package/dist/hooks.d.ts +2 -2
- package/dist/hooks.js +3 -2
- package/dist/hooks.js.map +1 -1
- package/dist/index.cjs +63 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -2
- package/dist/index.d.ts +11 -2
- package/dist/index.js +63 -34
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -14,6 +14,10 @@ import '@insforge/sdk';
|
|
|
14
14
|
import '@insforge/shared-schemas';
|
|
15
15
|
import 'zod';
|
|
16
16
|
|
|
17
|
+
interface InitialAuthState {
|
|
18
|
+
user?: InsforgeUser | null;
|
|
19
|
+
userId?: string | null;
|
|
20
|
+
}
|
|
17
21
|
interface InsforgeProviderProps {
|
|
18
22
|
children: ReactNode;
|
|
19
23
|
baseUrl: string;
|
|
@@ -25,6 +29,11 @@ interface InsforgeProviderProps {
|
|
|
25
29
|
onAuthChange?: (user: InsforgeUser | null) => void;
|
|
26
30
|
onSignIn?: (authToken: string) => Promise<void>;
|
|
27
31
|
onSignOut?: () => Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Initial auth state from server (for SSR hydration)
|
|
34
|
+
* @internal - Not intended for public use, used by Next.js package
|
|
35
|
+
*/
|
|
36
|
+
initialState?: InitialAuthState;
|
|
28
37
|
}
|
|
29
38
|
/**
|
|
30
39
|
* Unified Insforge Provider - manages authentication state and configuration
|
|
@@ -64,7 +73,7 @@ interface InsforgeProviderProps {
|
|
|
64
73
|
* </InsforgeProvider>
|
|
65
74
|
* ```
|
|
66
75
|
*/
|
|
67
|
-
declare function InsforgeProviderCore({ children, baseUrl, afterSignInUrl, onAuthChange, onSignIn, onSignOut, }: InsforgeProviderProps): react_jsx_runtime.JSX.Element;
|
|
76
|
+
declare function InsforgeProviderCore({ children, baseUrl, afterSignInUrl, onAuthChange, onSignIn, onSignOut, initialState, }: InsforgeProviderProps): react_jsx_runtime.JSX.Element;
|
|
68
77
|
declare function InsforgeProvider(props: InsforgeProviderProps): react_jsx_runtime.JSX.Element;
|
|
69
78
|
/**
|
|
70
79
|
* Hook to access Insforge context
|
|
@@ -100,4 +109,4 @@ declare function getProviderConfig(provider: OAuthProvider): OAuthProviderConfig
|
|
|
100
109
|
*/
|
|
101
110
|
declare function getAllProviderConfigs(): Partial<Record<OAuthProvider, OAuthProviderConfig>>;
|
|
102
111
|
|
|
103
|
-
export { InsforgeProvider, InsforgeProviderCore, type InsforgeProviderProps, OAUTH_PROVIDER_CONFIG, OAuthProviderConfig, getAllProviderConfigs, getProviderConfig, useInsforge };
|
|
112
|
+
export { type InitialAuthState, InsforgeProvider, InsforgeProviderCore, type InsforgeProviderProps, OAUTH_PROVIDER_CONFIG, OAuthProviderConfig, getAllProviderConfigs, getProviderConfig, useInsforge };
|
package/dist/index.d.ts
CHANGED
|
@@ -14,6 +14,10 @@ import '@insforge/sdk';
|
|
|
14
14
|
import '@insforge/shared-schemas';
|
|
15
15
|
import 'zod';
|
|
16
16
|
|
|
17
|
+
interface InitialAuthState {
|
|
18
|
+
user?: InsforgeUser | null;
|
|
19
|
+
userId?: string | null;
|
|
20
|
+
}
|
|
17
21
|
interface InsforgeProviderProps {
|
|
18
22
|
children: ReactNode;
|
|
19
23
|
baseUrl: string;
|
|
@@ -25,6 +29,11 @@ interface InsforgeProviderProps {
|
|
|
25
29
|
onAuthChange?: (user: InsforgeUser | null) => void;
|
|
26
30
|
onSignIn?: (authToken: string) => Promise<void>;
|
|
27
31
|
onSignOut?: () => Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Initial auth state from server (for SSR hydration)
|
|
34
|
+
* @internal - Not intended for public use, used by Next.js package
|
|
35
|
+
*/
|
|
36
|
+
initialState?: InitialAuthState;
|
|
28
37
|
}
|
|
29
38
|
/**
|
|
30
39
|
* Unified Insforge Provider - manages authentication state and configuration
|
|
@@ -64,7 +73,7 @@ interface InsforgeProviderProps {
|
|
|
64
73
|
* </InsforgeProvider>
|
|
65
74
|
* ```
|
|
66
75
|
*/
|
|
67
|
-
declare function InsforgeProviderCore({ children, baseUrl, afterSignInUrl, onAuthChange, onSignIn, onSignOut, }: InsforgeProviderProps): react_jsx_runtime.JSX.Element;
|
|
76
|
+
declare function InsforgeProviderCore({ children, baseUrl, afterSignInUrl, onAuthChange, onSignIn, onSignOut, initialState, }: InsforgeProviderProps): react_jsx_runtime.JSX.Element;
|
|
68
77
|
declare function InsforgeProvider(props: InsforgeProviderProps): react_jsx_runtime.JSX.Element;
|
|
69
78
|
/**
|
|
70
79
|
* Hook to access Insforge context
|
|
@@ -100,4 +109,4 @@ declare function getProviderConfig(provider: OAuthProvider): OAuthProviderConfig
|
|
|
100
109
|
*/
|
|
101
110
|
declare function getAllProviderConfigs(): Partial<Record<OAuthProvider, OAuthProviderConfig>>;
|
|
102
111
|
|
|
103
|
-
export { InsforgeProvider, InsforgeProviderCore, type InsforgeProviderProps, OAUTH_PROVIDER_CONFIG, OAuthProviderConfig, getAllProviderConfigs, getProviderConfig, useInsforge };
|
|
112
|
+
export { type InitialAuthState, InsforgeProvider, InsforgeProviderCore, type InsforgeProviderProps, OAUTH_PROVIDER_CONFIG, OAuthProviderConfig, getAllProviderConfigs, getProviderConfig, useInsforge };
|
package/dist/index.js
CHANGED
|
@@ -67,7 +67,7 @@ var InsforgeManager = class _InsforgeManager {
|
|
|
67
67
|
// Static private instance
|
|
68
68
|
static instance = null;
|
|
69
69
|
// State storage
|
|
70
|
-
user =
|
|
70
|
+
user = void 0;
|
|
71
71
|
isLoaded = false;
|
|
72
72
|
isInitializing = false;
|
|
73
73
|
sdk;
|
|
@@ -80,11 +80,8 @@ var InsforgeManager = class _InsforgeManager {
|
|
|
80
80
|
constructor(config) {
|
|
81
81
|
this.config = config;
|
|
82
82
|
this.sdk = createClient({ baseUrl: config.baseUrl });
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
this.isLoaded = true;
|
|
86
|
-
this.user = null;
|
|
87
|
-
}
|
|
83
|
+
this.user = void 0;
|
|
84
|
+
this.isLoaded = false;
|
|
88
85
|
}
|
|
89
86
|
// Public access method (Singleton core)
|
|
90
87
|
static getInstance(config) {
|
|
@@ -107,26 +104,36 @@ var InsforgeManager = class _InsforgeManager {
|
|
|
107
104
|
this.config = { ...this.config, ...config };
|
|
108
105
|
}
|
|
109
106
|
// Public initialization method
|
|
107
|
+
// Following Clerk's pattern: Even if we have initialState (isLoaded=true from cookies),
|
|
108
|
+
// we still need to load full user data from SDK/API
|
|
110
109
|
async initialize() {
|
|
111
|
-
if (this.isLoaded) {
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
110
|
if (this.isInitializing) {
|
|
115
111
|
return;
|
|
116
112
|
}
|
|
117
113
|
this.isInitializing = true;
|
|
118
114
|
try {
|
|
119
|
-
|
|
115
|
+
const sessionResult = this.sdk.auth.getCurrentSession();
|
|
116
|
+
const hasToken = !!sessionResult.data?.session?.accessToken;
|
|
117
|
+
if (hasToken) {
|
|
118
|
+
await this.loadAuthState();
|
|
119
|
+
} else if (this.user === void 0) {
|
|
120
|
+
this.user = null;
|
|
121
|
+
this.isLoaded = true;
|
|
122
|
+
this.notifyListeners();
|
|
123
|
+
}
|
|
120
124
|
} finally {
|
|
121
125
|
this.isInitializing = false;
|
|
122
126
|
}
|
|
123
127
|
}
|
|
124
128
|
// Get current state
|
|
125
129
|
getState() {
|
|
130
|
+
const userId = this.user === void 0 ? void 0 : this.user === null ? null : this.user.id;
|
|
131
|
+
const isSignedIn = this.user === void 0 ? void 0 : this.user !== null;
|
|
126
132
|
return {
|
|
127
133
|
user: this.user,
|
|
134
|
+
userId,
|
|
128
135
|
isLoaded: this.isLoaded,
|
|
129
|
-
isSignedIn
|
|
136
|
+
isSignedIn
|
|
130
137
|
};
|
|
131
138
|
}
|
|
132
139
|
// Subscription mechanism
|
|
@@ -139,6 +146,8 @@ var InsforgeManager = class _InsforgeManager {
|
|
|
139
146
|
this.listeners.forEach((listener) => listener(state));
|
|
140
147
|
}
|
|
141
148
|
// Load auth state
|
|
149
|
+
// This loads the FULL user data from SDK (including complete profile)
|
|
150
|
+
// Called after hydration to get complete user information beyond what's in cookies
|
|
142
151
|
async loadAuthState() {
|
|
143
152
|
try {
|
|
144
153
|
const sessionResult = this.sdk.auth.getCurrentSession();
|
|
@@ -161,6 +170,7 @@ var InsforgeManager = class _InsforgeManager {
|
|
|
161
170
|
email: userResult.data.user.email,
|
|
162
171
|
name: profile?.nickname || "",
|
|
163
172
|
avatarUrl: profile?.avatarUrl || ""
|
|
173
|
+
// You can add more profile fields here as needed
|
|
164
174
|
};
|
|
165
175
|
this.user = userData;
|
|
166
176
|
if (this.config.onAuthChange) {
|
|
@@ -421,6 +431,22 @@ var InsforgeManager = class _InsforgeManager {
|
|
|
421
431
|
}
|
|
422
432
|
this.notifyListeners();
|
|
423
433
|
}
|
|
434
|
+
// Set initial state from server (for SSR hydration)
|
|
435
|
+
// This is ONLY basic user info from cookies, not full profile
|
|
436
|
+
// Following Clerk's pattern: initialState prevents hydration mismatch
|
|
437
|
+
// but full user data is still loaded via initialize()
|
|
438
|
+
setInitialState(initialState) {
|
|
439
|
+
if (this.user !== void 0) {
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
if (initialState.userId) {
|
|
443
|
+
this.user = initialState.user ?? null;
|
|
444
|
+
} else {
|
|
445
|
+
this.user = null;
|
|
446
|
+
}
|
|
447
|
+
this.isLoaded = true;
|
|
448
|
+
this.notifyListeners();
|
|
449
|
+
}
|
|
424
450
|
getConfig() {
|
|
425
451
|
return this.config;
|
|
426
452
|
}
|
|
@@ -461,7 +487,8 @@ function InsforgeProviderCore({
|
|
|
461
487
|
afterSignInUrl = "/",
|
|
462
488
|
onAuthChange,
|
|
463
489
|
onSignIn,
|
|
464
|
-
onSignOut
|
|
490
|
+
onSignOut,
|
|
491
|
+
initialState
|
|
465
492
|
}) {
|
|
466
493
|
const manager = useMemo(
|
|
467
494
|
() => InsforgeManager.getInstance({
|
|
@@ -473,6 +500,12 @@ function InsforgeProviderCore({
|
|
|
473
500
|
}),
|
|
474
501
|
[baseUrl, afterSignInUrl, onAuthChange, onSignIn, onSignOut]
|
|
475
502
|
);
|
|
503
|
+
if (initialState) {
|
|
504
|
+
const currentState = manager.getState();
|
|
505
|
+
if (currentState.userId === void 0 && initialState.userId !== void 0) {
|
|
506
|
+
manager.setInitialState(initialState);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
476
509
|
const [state, setState] = useState(() => manager.getState());
|
|
477
510
|
useEffect(() => {
|
|
478
511
|
const unsubscribe = manager.subscribe((newState) => {
|
|
@@ -492,6 +525,7 @@ function InsforgeProviderCore({
|
|
|
492
525
|
() => ({
|
|
493
526
|
// State from Manager
|
|
494
527
|
user: state.user,
|
|
528
|
+
userId: state.userId,
|
|
495
529
|
isLoaded: state.isLoaded,
|
|
496
530
|
isSignedIn: state.isSignedIn,
|
|
497
531
|
// Methods delegated to Manager
|
|
@@ -523,9 +557,10 @@ function useInsforge() {
|
|
|
523
557
|
const context = useContext(InsforgeContext);
|
|
524
558
|
if (!context) {
|
|
525
559
|
return {
|
|
526
|
-
user:
|
|
560
|
+
user: void 0,
|
|
561
|
+
userId: void 0,
|
|
527
562
|
isLoaded: false,
|
|
528
|
-
isSignedIn:
|
|
563
|
+
isSignedIn: void 0,
|
|
529
564
|
setUser: () => {
|
|
530
565
|
},
|
|
531
566
|
signIn: () => Promise.resolve({ error: "SSR mode" }),
|
|
@@ -2505,16 +2540,16 @@ function Protect({
|
|
|
2505
2540
|
condition,
|
|
2506
2541
|
onRedirect
|
|
2507
2542
|
}) {
|
|
2508
|
-
const {
|
|
2543
|
+
const { userId, user } = useInsforge();
|
|
2509
2544
|
const resolvedRedirectTo = useMemo(() => resolveAuthPath(redirectTo), [redirectTo]);
|
|
2510
2545
|
useEffect(() => {
|
|
2511
|
-
if (
|
|
2546
|
+
if (userId === null) {
|
|
2512
2547
|
if (onRedirect) {
|
|
2513
2548
|
onRedirect(resolvedRedirectTo);
|
|
2514
2549
|
} else {
|
|
2515
2550
|
window.location.href = resolvedRedirectTo;
|
|
2516
2551
|
}
|
|
2517
|
-
} else if (
|
|
2552
|
+
} else if (userId && condition && user) {
|
|
2518
2553
|
if (!condition(user)) {
|
|
2519
2554
|
if (onRedirect) {
|
|
2520
2555
|
onRedirect(resolvedRedirectTo);
|
|
@@ -2523,11 +2558,11 @@ function Protect({
|
|
|
2523
2558
|
}
|
|
2524
2559
|
}
|
|
2525
2560
|
}
|
|
2526
|
-
}, [
|
|
2527
|
-
if (
|
|
2561
|
+
}, [userId, resolvedRedirectTo, condition, user, onRedirect]);
|
|
2562
|
+
if (userId === void 0) {
|
|
2528
2563
|
return fallback || /* @__PURE__ */ jsx("div", { className: "insforge-loading", children: "Loading..." });
|
|
2529
2564
|
}
|
|
2530
|
-
if (
|
|
2565
|
+
if (userId === null) {
|
|
2531
2566
|
return fallback || null;
|
|
2532
2567
|
}
|
|
2533
2568
|
if (condition && user && !condition(user)) {
|
|
@@ -2536,24 +2571,18 @@ function Protect({
|
|
|
2536
2571
|
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
2537
2572
|
}
|
|
2538
2573
|
function SignedIn({ children }) {
|
|
2539
|
-
const {
|
|
2540
|
-
if (
|
|
2541
|
-
return
|
|
2574
|
+
const { userId } = useInsforge();
|
|
2575
|
+
if (userId) {
|
|
2576
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
2542
2577
|
}
|
|
2543
|
-
|
|
2544
|
-
return null;
|
|
2545
|
-
}
|
|
2546
|
-
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
2578
|
+
return null;
|
|
2547
2579
|
}
|
|
2548
2580
|
function SignedOut({ children }) {
|
|
2549
|
-
const {
|
|
2550
|
-
if (
|
|
2551
|
-
return
|
|
2581
|
+
const { userId } = useInsforge();
|
|
2582
|
+
if (userId === null) {
|
|
2583
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
2552
2584
|
}
|
|
2553
|
-
|
|
2554
|
-
return null;
|
|
2555
|
-
}
|
|
2556
|
-
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
2585
|
+
return null;
|
|
2557
2586
|
}
|
|
2558
2587
|
function SignInButton({ children, className }) {
|
|
2559
2588
|
const { afterSignInUrl, baseUrl } = useInsforge();
|