@swr-login/react 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,250 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { SWRLoginConfig, AuthResponse, User, PluginManager, TokenManager, AuthEventEmitter, AuthStateMachine, BroadcastSync } from '@swr-login/core';
3
+ import React from 'react';
4
+
5
+ interface SWRLoginProviderProps {
6
+ /** Authentication configuration */
7
+ config: SWRLoginConfig;
8
+ children: React.ReactNode;
9
+ }
10
+ /**
11
+ * SWRLoginProvider initializes the auth system and provides context to all child hooks.
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * import { SWRLoginProvider } from '@swr-login/react';
16
+ * import { JWTAdapter } from '@swr-login/adapter-jwt';
17
+ * import { PasswordPlugin } from '@swr-login/plugin-password';
18
+ *
19
+ * function App() {
20
+ * return (
21
+ * <SWRLoginProvider
22
+ * config={{
23
+ * adapter: JWTAdapter(),
24
+ * plugins: [PasswordPlugin({ loginUrl: '/api/login' })],
25
+ * }}
26
+ * >
27
+ * <YourApp />
28
+ * </SWRLoginProvider>
29
+ * );
30
+ * }
31
+ * ```
32
+ */
33
+ declare function SWRLoginProvider({ config, children }: SWRLoginProviderProps): react_jsx_runtime.JSX.Element;
34
+
35
+ interface UseLoginOptions {
36
+ /** Plugin name to use for login */
37
+ pluginName?: string;
38
+ }
39
+ interface UseLoginReturn<TCredentials = unknown> {
40
+ /**
41
+ * Trigger login with specified credentials.
42
+ * If pluginName was not provided in options, it must be passed as first argument.
43
+ */
44
+ login: (credentialsOrPluginName: TCredentials | string, credentials?: TCredentials) => Promise<AuthResponse>;
45
+ /** Whether a login request is in progress */
46
+ isLoading: boolean;
47
+ /** Last login error, if any */
48
+ error: Error | null;
49
+ /** Reset error state */
50
+ reset: () => void;
51
+ }
52
+ /**
53
+ * Hook to trigger login flow via a registered plugin.
54
+ *
55
+ * @param pluginName - Optional default plugin name
56
+ *
57
+ * @example
58
+ * ```tsx
59
+ * // With default plugin
60
+ * const { login, isLoading, error } = useLogin('password');
61
+ * await login({ username: 'alice', password: 'secret' });
62
+ *
63
+ * // Without default plugin (specify at call time)
64
+ * const { login } = useLogin();
65
+ * await login('oauth-google', { redirect: false });
66
+ * ```
67
+ */
68
+ declare function useLogin<TCredentials = unknown>(pluginName?: string): UseLoginReturn<TCredentials>;
69
+
70
+ declare const AUTH_KEY = "__swr_login_user__";
71
+ interface UseUserReturn<T extends User = User> {
72
+ /** Current authenticated user, or null if not logged in */
73
+ user: T | null;
74
+ /** Whether user data is being fetched */
75
+ isLoading: boolean;
76
+ /** Whether user is authenticated */
77
+ isAuthenticated: boolean;
78
+ /** Error from fetching user data */
79
+ error: Error | undefined;
80
+ /**
81
+ * Manually update cached user data.
82
+ * Call with `null` to clear, or with a user object to update.
83
+ */
84
+ mutate: (data?: T | null) => Promise<void>;
85
+ }
86
+ /**
87
+ * Hook to access current user data via SWR cache.
88
+ *
89
+ * Uses SWR's stale-while-revalidate strategy:
90
+ * - Immediately returns cached user data
91
+ * - Revalidates in the background using the configured fetchUser function
92
+ * - Automatically syncs across all components using this hook
93
+ *
94
+ * @example
95
+ * ```tsx
96
+ * const { user, isLoading, isAuthenticated } = useUser<MyUser>();
97
+ *
98
+ * if (isLoading) return <Spinner />;
99
+ * if (!isAuthenticated) return <LoginPage />;
100
+ * return <Dashboard user={user} />;
101
+ * ```
102
+ */
103
+ declare function useUser<T extends User = User>(): UseUserReturn<T>;
104
+
105
+ interface UseLogoutOptions {
106
+ /** Specific plugin to call logout on */
107
+ pluginName?: string;
108
+ /** Whether to broadcast logout to other tabs (default: true) */
109
+ broadcast?: boolean;
110
+ }
111
+ interface UseLogoutReturn {
112
+ /** Execute logout */
113
+ logout: (options?: UseLogoutOptions) => Promise<void>;
114
+ /** Whether logout is in progress */
115
+ isLoading: boolean;
116
+ }
117
+ /**
118
+ * Hook to perform secure logout with cross-tab sync.
119
+ *
120
+ * Logout flow:
121
+ * 1. Call plugin logout (if applicable)
122
+ * 2. Clear stored tokens
123
+ * 3. Clear SWR cache (mutate user to null)
124
+ * 4. Broadcast logout to other tabs
125
+ * 5. Transition state to 'unauthenticated'
126
+ *
127
+ * @example
128
+ * ```tsx
129
+ * const { logout, isLoading } = useLogout();
130
+ *
131
+ * <button onClick={() => logout()} disabled={isLoading}>
132
+ * Sign Out
133
+ * </button>
134
+ * ```
135
+ */
136
+ declare function useLogout(): UseLogoutReturn;
137
+
138
+ interface SessionInfo {
139
+ /** Current access token */
140
+ accessToken: string | null;
141
+ /** Current refresh token */
142
+ refreshToken: string | null;
143
+ /** Token expiration timestamp (ms since epoch) */
144
+ expiresAt: number | null;
145
+ /** Whether the access token has expired */
146
+ isExpired: boolean;
147
+ /** Whether tokens exist (regardless of expiry) */
148
+ hasTokens: boolean;
149
+ }
150
+ /**
151
+ * Hook to access raw session/token information.
152
+ *
153
+ * Useful for:
154
+ * - Adding Authorization headers to custom requests
155
+ * - Checking token expiry status
156
+ * - Debugging session state
157
+ *
158
+ * @example
159
+ * ```tsx
160
+ * const { accessToken, isExpired } = useSession();
161
+ *
162
+ * const fetchData = () => fetch('/api/data', {
163
+ * headers: { Authorization: `Bearer ${accessToken}` },
164
+ * });
165
+ * ```
166
+ */
167
+ declare function useSession(): SessionInfo;
168
+
169
+ interface UsePermissionReturn {
170
+ /** Check if user has a specific permission */
171
+ hasPermission: (permission: string) => boolean;
172
+ /** Check if user has a specific role */
173
+ hasRole: (role: string) => boolean;
174
+ /** Check if user has all specified permissions */
175
+ hasAllPermissions: (permissions: string[]) => boolean;
176
+ /** Check if user has any of the specified permissions */
177
+ hasAnyPermission: (permissions: string[]) => boolean;
178
+ /** Check if user has all specified roles */
179
+ hasAllRoles: (roles: string[]) => boolean;
180
+ /** Check if user has any of the specified roles */
181
+ hasAnyRole: (roles: string[]) => boolean;
182
+ }
183
+ /**
184
+ * Hook for checking user permissions and roles.
185
+ *
186
+ * Reads from the `permissions` and `roles` arrays on the User object.
187
+ *
188
+ * @example
189
+ * ```tsx
190
+ * const { hasPermission, hasRole } = usePermission();
191
+ *
192
+ * if (hasPermission('admin:write')) {
193
+ * // Show admin controls
194
+ * }
195
+ *
196
+ * if (hasRole('editor')) {
197
+ * // Show editor tools
198
+ * }
199
+ * ```
200
+ */
201
+ declare function usePermission(): UsePermissionReturn;
202
+
203
+ interface AuthGuardProps {
204
+ children: React.ReactNode;
205
+ /** Required permissions (checked against user.permissions) */
206
+ permissions?: string[];
207
+ /** Required roles (checked against user.roles) */
208
+ roles?: string[];
209
+ /** If true, ALL permissions/roles must match. If false, ANY match suffices. (default: false) */
210
+ requireAll?: boolean;
211
+ /** Component to render when user is not authenticated or lacks permissions */
212
+ fallback?: React.ReactNode;
213
+ /** Component to render while checking auth status */
214
+ loadingComponent?: React.ReactNode;
215
+ }
216
+ /**
217
+ * Declarative auth guard component.
218
+ * Protects child content based on authentication state and permissions/roles.
219
+ *
220
+ * @example
221
+ * ```tsx
222
+ * <AuthGuard
223
+ * permissions={['admin', 'editor']}
224
+ * requireAll={false}
225
+ * fallback={<Navigate to="/login" />}
226
+ * loadingComponent={<Skeleton />}
227
+ * >
228
+ * <AdminPanel />
229
+ * </AuthGuard>
230
+ * ```
231
+ */
232
+ declare function AuthGuard({ children, permissions, roles, requireAll, fallback, loadingComponent, }: AuthGuardProps): react_jsx_runtime.JSX.Element;
233
+
234
+ /** Internal context value passed through SWRLoginProvider */
235
+ interface AuthContextValue {
236
+ pluginManager: PluginManager;
237
+ tokenManager: TokenManager;
238
+ emitter: AuthEventEmitter;
239
+ stateMachine: AuthStateMachine;
240
+ broadcastSync: BroadcastSync | null;
241
+ config: SWRLoginConfig;
242
+ }
243
+ /**
244
+ * Internal hook to access auth context.
245
+ * Must be used within SWRLoginProvider.
246
+ * @throws Error if used outside of SWRLoginProvider
247
+ */
248
+ declare function useAuthContext(): AuthContextValue;
249
+
250
+ export { AUTH_KEY, type AuthContextValue, AuthGuard, type AuthGuardProps, SWRLoginProvider, type SWRLoginProviderProps, type SessionInfo, type UseLoginOptions, type UseLoginReturn, type UseLogoutOptions, type UseLogoutReturn, type UsePermissionReturn, type UseUserReturn, useAuthContext, useLogin, useLogout, usePermission, useSession, useUser };
@@ -0,0 +1,250 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { SWRLoginConfig, AuthResponse, User, PluginManager, TokenManager, AuthEventEmitter, AuthStateMachine, BroadcastSync } from '@swr-login/core';
3
+ import React from 'react';
4
+
5
+ interface SWRLoginProviderProps {
6
+ /** Authentication configuration */
7
+ config: SWRLoginConfig;
8
+ children: React.ReactNode;
9
+ }
10
+ /**
11
+ * SWRLoginProvider initializes the auth system and provides context to all child hooks.
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * import { SWRLoginProvider } from '@swr-login/react';
16
+ * import { JWTAdapter } from '@swr-login/adapter-jwt';
17
+ * import { PasswordPlugin } from '@swr-login/plugin-password';
18
+ *
19
+ * function App() {
20
+ * return (
21
+ * <SWRLoginProvider
22
+ * config={{
23
+ * adapter: JWTAdapter(),
24
+ * plugins: [PasswordPlugin({ loginUrl: '/api/login' })],
25
+ * }}
26
+ * >
27
+ * <YourApp />
28
+ * </SWRLoginProvider>
29
+ * );
30
+ * }
31
+ * ```
32
+ */
33
+ declare function SWRLoginProvider({ config, children }: SWRLoginProviderProps): react_jsx_runtime.JSX.Element;
34
+
35
+ interface UseLoginOptions {
36
+ /** Plugin name to use for login */
37
+ pluginName?: string;
38
+ }
39
+ interface UseLoginReturn<TCredentials = unknown> {
40
+ /**
41
+ * Trigger login with specified credentials.
42
+ * If pluginName was not provided in options, it must be passed as first argument.
43
+ */
44
+ login: (credentialsOrPluginName: TCredentials | string, credentials?: TCredentials) => Promise<AuthResponse>;
45
+ /** Whether a login request is in progress */
46
+ isLoading: boolean;
47
+ /** Last login error, if any */
48
+ error: Error | null;
49
+ /** Reset error state */
50
+ reset: () => void;
51
+ }
52
+ /**
53
+ * Hook to trigger login flow via a registered plugin.
54
+ *
55
+ * @param pluginName - Optional default plugin name
56
+ *
57
+ * @example
58
+ * ```tsx
59
+ * // With default plugin
60
+ * const { login, isLoading, error } = useLogin('password');
61
+ * await login({ username: 'alice', password: 'secret' });
62
+ *
63
+ * // Without default plugin (specify at call time)
64
+ * const { login } = useLogin();
65
+ * await login('oauth-google', { redirect: false });
66
+ * ```
67
+ */
68
+ declare function useLogin<TCredentials = unknown>(pluginName?: string): UseLoginReturn<TCredentials>;
69
+
70
+ declare const AUTH_KEY = "__swr_login_user__";
71
+ interface UseUserReturn<T extends User = User> {
72
+ /** Current authenticated user, or null if not logged in */
73
+ user: T | null;
74
+ /** Whether user data is being fetched */
75
+ isLoading: boolean;
76
+ /** Whether user is authenticated */
77
+ isAuthenticated: boolean;
78
+ /** Error from fetching user data */
79
+ error: Error | undefined;
80
+ /**
81
+ * Manually update cached user data.
82
+ * Call with `null` to clear, or with a user object to update.
83
+ */
84
+ mutate: (data?: T | null) => Promise<void>;
85
+ }
86
+ /**
87
+ * Hook to access current user data via SWR cache.
88
+ *
89
+ * Uses SWR's stale-while-revalidate strategy:
90
+ * - Immediately returns cached user data
91
+ * - Revalidates in the background using the configured fetchUser function
92
+ * - Automatically syncs across all components using this hook
93
+ *
94
+ * @example
95
+ * ```tsx
96
+ * const { user, isLoading, isAuthenticated } = useUser<MyUser>();
97
+ *
98
+ * if (isLoading) return <Spinner />;
99
+ * if (!isAuthenticated) return <LoginPage />;
100
+ * return <Dashboard user={user} />;
101
+ * ```
102
+ */
103
+ declare function useUser<T extends User = User>(): UseUserReturn<T>;
104
+
105
+ interface UseLogoutOptions {
106
+ /** Specific plugin to call logout on */
107
+ pluginName?: string;
108
+ /** Whether to broadcast logout to other tabs (default: true) */
109
+ broadcast?: boolean;
110
+ }
111
+ interface UseLogoutReturn {
112
+ /** Execute logout */
113
+ logout: (options?: UseLogoutOptions) => Promise<void>;
114
+ /** Whether logout is in progress */
115
+ isLoading: boolean;
116
+ }
117
+ /**
118
+ * Hook to perform secure logout with cross-tab sync.
119
+ *
120
+ * Logout flow:
121
+ * 1. Call plugin logout (if applicable)
122
+ * 2. Clear stored tokens
123
+ * 3. Clear SWR cache (mutate user to null)
124
+ * 4. Broadcast logout to other tabs
125
+ * 5. Transition state to 'unauthenticated'
126
+ *
127
+ * @example
128
+ * ```tsx
129
+ * const { logout, isLoading } = useLogout();
130
+ *
131
+ * <button onClick={() => logout()} disabled={isLoading}>
132
+ * Sign Out
133
+ * </button>
134
+ * ```
135
+ */
136
+ declare function useLogout(): UseLogoutReturn;
137
+
138
+ interface SessionInfo {
139
+ /** Current access token */
140
+ accessToken: string | null;
141
+ /** Current refresh token */
142
+ refreshToken: string | null;
143
+ /** Token expiration timestamp (ms since epoch) */
144
+ expiresAt: number | null;
145
+ /** Whether the access token has expired */
146
+ isExpired: boolean;
147
+ /** Whether tokens exist (regardless of expiry) */
148
+ hasTokens: boolean;
149
+ }
150
+ /**
151
+ * Hook to access raw session/token information.
152
+ *
153
+ * Useful for:
154
+ * - Adding Authorization headers to custom requests
155
+ * - Checking token expiry status
156
+ * - Debugging session state
157
+ *
158
+ * @example
159
+ * ```tsx
160
+ * const { accessToken, isExpired } = useSession();
161
+ *
162
+ * const fetchData = () => fetch('/api/data', {
163
+ * headers: { Authorization: `Bearer ${accessToken}` },
164
+ * });
165
+ * ```
166
+ */
167
+ declare function useSession(): SessionInfo;
168
+
169
+ interface UsePermissionReturn {
170
+ /** Check if user has a specific permission */
171
+ hasPermission: (permission: string) => boolean;
172
+ /** Check if user has a specific role */
173
+ hasRole: (role: string) => boolean;
174
+ /** Check if user has all specified permissions */
175
+ hasAllPermissions: (permissions: string[]) => boolean;
176
+ /** Check if user has any of the specified permissions */
177
+ hasAnyPermission: (permissions: string[]) => boolean;
178
+ /** Check if user has all specified roles */
179
+ hasAllRoles: (roles: string[]) => boolean;
180
+ /** Check if user has any of the specified roles */
181
+ hasAnyRole: (roles: string[]) => boolean;
182
+ }
183
+ /**
184
+ * Hook for checking user permissions and roles.
185
+ *
186
+ * Reads from the `permissions` and `roles` arrays on the User object.
187
+ *
188
+ * @example
189
+ * ```tsx
190
+ * const { hasPermission, hasRole } = usePermission();
191
+ *
192
+ * if (hasPermission('admin:write')) {
193
+ * // Show admin controls
194
+ * }
195
+ *
196
+ * if (hasRole('editor')) {
197
+ * // Show editor tools
198
+ * }
199
+ * ```
200
+ */
201
+ declare function usePermission(): UsePermissionReturn;
202
+
203
+ interface AuthGuardProps {
204
+ children: React.ReactNode;
205
+ /** Required permissions (checked against user.permissions) */
206
+ permissions?: string[];
207
+ /** Required roles (checked against user.roles) */
208
+ roles?: string[];
209
+ /** If true, ALL permissions/roles must match. If false, ANY match suffices. (default: false) */
210
+ requireAll?: boolean;
211
+ /** Component to render when user is not authenticated or lacks permissions */
212
+ fallback?: React.ReactNode;
213
+ /** Component to render while checking auth status */
214
+ loadingComponent?: React.ReactNode;
215
+ }
216
+ /**
217
+ * Declarative auth guard component.
218
+ * Protects child content based on authentication state and permissions/roles.
219
+ *
220
+ * @example
221
+ * ```tsx
222
+ * <AuthGuard
223
+ * permissions={['admin', 'editor']}
224
+ * requireAll={false}
225
+ * fallback={<Navigate to="/login" />}
226
+ * loadingComponent={<Skeleton />}
227
+ * >
228
+ * <AdminPanel />
229
+ * </AuthGuard>
230
+ * ```
231
+ */
232
+ declare function AuthGuard({ children, permissions, roles, requireAll, fallback, loadingComponent, }: AuthGuardProps): react_jsx_runtime.JSX.Element;
233
+
234
+ /** Internal context value passed through SWRLoginProvider */
235
+ interface AuthContextValue {
236
+ pluginManager: PluginManager;
237
+ tokenManager: TokenManager;
238
+ emitter: AuthEventEmitter;
239
+ stateMachine: AuthStateMachine;
240
+ broadcastSync: BroadcastSync | null;
241
+ config: SWRLoginConfig;
242
+ }
243
+ /**
244
+ * Internal hook to access auth context.
245
+ * Must be used within SWRLoginProvider.
246
+ * @throws Error if used outside of SWRLoginProvider
247
+ */
248
+ declare function useAuthContext(): AuthContextValue;
249
+
250
+ export { AUTH_KEY, type AuthContextValue, AuthGuard, type AuthGuardProps, SWRLoginProvider, type SWRLoginProviderProps, type SessionInfo, type UseLoginOptions, type UseLoginReturn, type UseLogoutOptions, type UseLogoutReturn, type UsePermissionReturn, type UseUserReturn, useAuthContext, useLogin, useLogout, usePermission, useSession, useUser };