@gately/react 1.0.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.
- package/README.md +277 -0
- package/dist/context.d.ts +35 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +199 -0
- package/dist/context.mjs +193 -0
- package/dist/hooks/context.d.ts +35 -0
- package/dist/hooks/context.d.ts.map +1 -0
- package/dist/hooks/hooks/index.d.ts +11 -0
- package/dist/hooks/hooks/index.d.ts.map +1 -0
- package/dist/hooks/hooks/useAuth.d.ts +38 -0
- package/dist/hooks/hooks/useAuth.d.ts.map +1 -0
- package/dist/hooks/hooks/useProtected.d.ts +29 -0
- package/dist/hooks/hooks/useProtected.d.ts.map +1 -0
- package/dist/hooks/hooks/useUser.d.ts +42 -0
- package/dist/hooks/hooks/useUser.d.ts.map +1 -0
- package/dist/hooks/index.d.ts +11 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +212 -0
- package/dist/hooks/index.mjs +208 -0
- package/dist/hooks/useAuth.d.ts +38 -0
- package/dist/hooks/useAuth.d.ts.map +1 -0
- package/dist/hooks/useProtected.d.ts +29 -0
- package/dist/hooks/useProtected.d.ts.map +1 -0
- package/dist/hooks/useUser.d.ts +42 -0
- package/dist/hooks/useUser.d.ts.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +397 -0
- package/dist/index.mjs +391 -0
- package/package.json +73 -0
package/README.md
ADDED
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
# @gately/react
|
|
2
|
+
|
|
3
|
+
React SDK for Gately authentication and user management.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @gately/react @gately/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
Wrap your app with `GatelyProvider`:
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { GatelyProvider } from '@gately/react'
|
|
17
|
+
|
|
18
|
+
function App() {
|
|
19
|
+
return (
|
|
20
|
+
<GatelyProvider projectId="your-project-id">
|
|
21
|
+
<YourApp />
|
|
22
|
+
</GatelyProvider>
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Use the hooks in your components:
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
import { useAuth, useUser, useProtected } from '@gately/react'
|
|
31
|
+
|
|
32
|
+
function LoginForm() {
|
|
33
|
+
const { login, isLoading, error } = useAuth()
|
|
34
|
+
|
|
35
|
+
const handleLogin = async (email: string, password: string) => {
|
|
36
|
+
try {
|
|
37
|
+
await login(email, password)
|
|
38
|
+
} catch (err) {
|
|
39
|
+
console.error('Login failed:', err)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<form onSubmit={(e) => {
|
|
45
|
+
e.preventDefault()
|
|
46
|
+
handleLogin('user@example.com', 'password')
|
|
47
|
+
}}>
|
|
48
|
+
{error && <p>{error.message}</p>}
|
|
49
|
+
<button disabled={isLoading}>
|
|
50
|
+
{isLoading ? 'Logging in...' : 'Log In'}
|
|
51
|
+
</button>
|
|
52
|
+
</form>
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Hooks
|
|
58
|
+
|
|
59
|
+
### `useAuth()`
|
|
60
|
+
|
|
61
|
+
Main hook for accessing authentication context.
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
const {
|
|
65
|
+
user, // Current user or null
|
|
66
|
+
session, // Current session or null
|
|
67
|
+
isLoading, // Loading state
|
|
68
|
+
isAuthenticated, // Is user authenticated
|
|
69
|
+
error, // Any error from auth operations
|
|
70
|
+
|
|
71
|
+
// Auth methods
|
|
72
|
+
login,
|
|
73
|
+
signup,
|
|
74
|
+
logout,
|
|
75
|
+
sendMagicLink,
|
|
76
|
+
resetPassword,
|
|
77
|
+
fetchSession,
|
|
78
|
+
|
|
79
|
+
// User methods
|
|
80
|
+
getUserProfile,
|
|
81
|
+
updateUserProfile,
|
|
82
|
+
deleteUserAccount,
|
|
83
|
+
changePassword,
|
|
84
|
+
|
|
85
|
+
// Direct client access
|
|
86
|
+
client
|
|
87
|
+
} = useAuth()
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### `useUser()`
|
|
91
|
+
|
|
92
|
+
Hook for accessing and managing user profile data.
|
|
93
|
+
|
|
94
|
+
```tsx
|
|
95
|
+
const {
|
|
96
|
+
user, // Current user
|
|
97
|
+
profile, // User profile data
|
|
98
|
+
isLoading, // Loading state
|
|
99
|
+
error, // Any error from operations
|
|
100
|
+
refetch, // Refetch profile
|
|
101
|
+
update, // Update profile
|
|
102
|
+
delete // Delete user account
|
|
103
|
+
} = useUser()
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### `useProtected()`
|
|
107
|
+
|
|
108
|
+
Hook for protecting components that require authentication.
|
|
109
|
+
|
|
110
|
+
```tsx
|
|
111
|
+
const {
|
|
112
|
+
isAuthenticated, // Is user authenticated
|
|
113
|
+
isLoading, // Loading state
|
|
114
|
+
user // Current user
|
|
115
|
+
} = useProtected()
|
|
116
|
+
|
|
117
|
+
if (!isAuthenticated) {
|
|
118
|
+
return <p>Please log in</p>
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Examples
|
|
123
|
+
|
|
124
|
+
### Login Form
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
function LoginForm() {
|
|
128
|
+
const { login, isLoading, error } = useAuth()
|
|
129
|
+
const [email, setEmail] = useState('')
|
|
130
|
+
const [password, setPassword] = useState('')
|
|
131
|
+
|
|
132
|
+
const handleSubmit = async (e: React.FormEvent) => {
|
|
133
|
+
e.preventDefault()
|
|
134
|
+
try {
|
|
135
|
+
await login(email, password)
|
|
136
|
+
} catch (err) {
|
|
137
|
+
console.error('Login failed:', err)
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return (
|
|
142
|
+
<form onSubmit={handleSubmit}>
|
|
143
|
+
{error && <p style={{ color: 'red' }}>{error.message}</p>}
|
|
144
|
+
<input
|
|
145
|
+
type="email"
|
|
146
|
+
value={email}
|
|
147
|
+
onChange={(e) => setEmail(e.target.value)}
|
|
148
|
+
placeholder="Email"
|
|
149
|
+
disabled={isLoading}
|
|
150
|
+
/>
|
|
151
|
+
<input
|
|
152
|
+
type="password"
|
|
153
|
+
value={password}
|
|
154
|
+
onChange={(e) => setPassword(e.target.value)}
|
|
155
|
+
placeholder="Password"
|
|
156
|
+
disabled={isLoading}
|
|
157
|
+
/>
|
|
158
|
+
<button type="submit" disabled={isLoading}>
|
|
159
|
+
{isLoading ? 'Logging in...' : 'Log In'}
|
|
160
|
+
</button>
|
|
161
|
+
</form>
|
|
162
|
+
)
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### User Profile
|
|
167
|
+
|
|
168
|
+
```tsx
|
|
169
|
+
function UserProfile() {
|
|
170
|
+
const { user, profile, isLoading, update } = useUser()
|
|
171
|
+
|
|
172
|
+
if (isLoading) return <p>Loading...</p>
|
|
173
|
+
if (!user) return <p>Not logged in</p>
|
|
174
|
+
|
|
175
|
+
const handleUpdateName = async () => {
|
|
176
|
+
const newName = prompt('Enter new name:')
|
|
177
|
+
if (newName) {
|
|
178
|
+
await update({ name: newName })
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return (
|
|
183
|
+
<div>
|
|
184
|
+
<p>Email: {user.email}</p>
|
|
185
|
+
<p>Name: {profile?.name || 'Not set'}</p>
|
|
186
|
+
<button onClick={handleUpdateName}>Update Name</button>
|
|
187
|
+
</div>
|
|
188
|
+
)
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Protected Route
|
|
193
|
+
|
|
194
|
+
```tsx
|
|
195
|
+
function ProtectedPage() {
|
|
196
|
+
const { isAuthenticated, isLoading } = useProtected()
|
|
197
|
+
|
|
198
|
+
if (isLoading) return <p>Loading...</p>
|
|
199
|
+
if (!isAuthenticated) return <p>Please log in to access this page</p>
|
|
200
|
+
|
|
201
|
+
return <div>Protected content</div>
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Sign Up
|
|
206
|
+
|
|
207
|
+
```tsx
|
|
208
|
+
function SignUpForm() {
|
|
209
|
+
const { signup, isLoading, error } = useAuth()
|
|
210
|
+
const [email, setEmail] = useState('')
|
|
211
|
+
const [password, setPassword] = useState('')
|
|
212
|
+
|
|
213
|
+
const handleSubmit = async (e: React.FormEvent) => {
|
|
214
|
+
e.preventDefault()
|
|
215
|
+
try {
|
|
216
|
+
await signup(email, password, {
|
|
217
|
+
name: 'New User'
|
|
218
|
+
})
|
|
219
|
+
} catch (err) {
|
|
220
|
+
console.error('Signup failed:', err)
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return (
|
|
225
|
+
<form onSubmit={handleSubmit}>
|
|
226
|
+
{error && <p style={{ color: 'red' }}>{error.message}</p>}
|
|
227
|
+
<input
|
|
228
|
+
type="email"
|
|
229
|
+
value={email}
|
|
230
|
+
onChange={(e) => setEmail(e.target.value)}
|
|
231
|
+
placeholder="Email"
|
|
232
|
+
disabled={isLoading}
|
|
233
|
+
/>
|
|
234
|
+
<input
|
|
235
|
+
type="password"
|
|
236
|
+
value={password}
|
|
237
|
+
onChange={(e) => setPassword(e.target.value)}
|
|
238
|
+
placeholder="Password"
|
|
239
|
+
disabled={isLoading}
|
|
240
|
+
/>
|
|
241
|
+
<button type="submit" disabled={isLoading}>
|
|
242
|
+
{isLoading ? 'Signing up...' : 'Sign Up'}
|
|
243
|
+
</button>
|
|
244
|
+
</form>
|
|
245
|
+
)
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Configuration
|
|
250
|
+
|
|
251
|
+
Pass options to `GatelyProvider`:
|
|
252
|
+
|
|
253
|
+
```tsx
|
|
254
|
+
<GatelyProvider
|
|
255
|
+
projectId="your-project-id"
|
|
256
|
+
apiUrl="https://api.yourdomain.com" // Optional
|
|
257
|
+
autoRefresh={true} // Optional, default: true
|
|
258
|
+
>
|
|
259
|
+
<App />
|
|
260
|
+
</GatelyProvider>
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## Building
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
npm run build
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## Testing
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
npm run test
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## License
|
|
276
|
+
|
|
277
|
+
MIT
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gately React Context
|
|
3
|
+
* Provides authentication state and methods to React components
|
|
4
|
+
*/
|
|
5
|
+
import React, { ReactNode } from 'react';
|
|
6
|
+
import { GatelyClient } from '@gately/sdk';
|
|
7
|
+
import type { Session, User } from '@gately/sdk';
|
|
8
|
+
export interface GatelyContextValue {
|
|
9
|
+
user: User | null;
|
|
10
|
+
session: Session | null;
|
|
11
|
+
isLoading: boolean;
|
|
12
|
+
isAuthenticated: boolean;
|
|
13
|
+
error: Error | null;
|
|
14
|
+
login: (email: string, password: string) => Promise<any>;
|
|
15
|
+
signup: (email: string, password: string, metadata?: any) => Promise<any>;
|
|
16
|
+
logout: () => Promise<void>;
|
|
17
|
+
sendMagicLink: (email: string, redirectTo?: string) => Promise<void>;
|
|
18
|
+
resetPassword: (email: string) => Promise<void>;
|
|
19
|
+
fetchSession: () => Promise<Session | null>;
|
|
20
|
+
getUserProfile: () => Promise<any>;
|
|
21
|
+
updateUserProfile: (updates: any) => Promise<any>;
|
|
22
|
+
deleteUserAccount: () => Promise<void>;
|
|
23
|
+
changePassword: (current: string, newPassword: string) => Promise<void>;
|
|
24
|
+
client: GatelyClient | null;
|
|
25
|
+
}
|
|
26
|
+
export declare const GatelyContext: React.Context<GatelyContextValue | undefined>;
|
|
27
|
+
export interface GatelyProviderProps {
|
|
28
|
+
projectId: string;
|
|
29
|
+
apiUrl?: string;
|
|
30
|
+
children: ReactNode;
|
|
31
|
+
autoRefresh?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export declare function GatelyProvider({ projectId, apiUrl, children, autoRefresh }: GatelyProviderProps): React.FunctionComponentElement<React.ProviderProps<GatelyContextValue | undefined>>;
|
|
34
|
+
export default GatelyProvider;
|
|
35
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,EAAiB,SAAS,EAAoC,MAAM,OAAO,CAAA;AACzF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAEhD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAA;IACjB,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;IACvB,SAAS,EAAE,OAAO,CAAA;IAClB,eAAe,EAAE,OAAO,CAAA;IACxB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;IACnB,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;IACxD,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;IACzE,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3B,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACpE,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/C,YAAY,EAAE,MAAM,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;IAC3C,cAAc,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,CAAA;IAClC,iBAAiB,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;IACjD,iBAAiB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACtC,cAAc,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACvE,MAAM,EAAE,YAAY,GAAG,IAAI,CAAA;CAC5B;AAED,eAAO,MAAM,aAAa,+CAA2D,CAAA;AAErF,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,SAAS,CAAA;IACnB,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED,wBAAgB,cAAc,CAAC,EAC7B,SAAS,EACT,MAAM,EACN,QAAQ,EACR,WAAkB,EACnB,EAAE,mBAAmB,uFA+KrB;AAED,eAAe,cAAc,CAAA"}
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var React = require('react');
|
|
6
|
+
var sdk = require('@gately/sdk');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Gately React Context
|
|
10
|
+
* Provides authentication state and methods to React components
|
|
11
|
+
*/
|
|
12
|
+
const GatelyContext = React.createContext(undefined);
|
|
13
|
+
function GatelyProvider({ projectId, apiUrl, children, autoRefresh = true }) {
|
|
14
|
+
const [client] = React.useState(() => {
|
|
15
|
+
if (typeof window === 'undefined')
|
|
16
|
+
return null;
|
|
17
|
+
try {
|
|
18
|
+
return new sdk.GatelyClient(projectId, { apiUrl, autoRefresh });
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
console.error('Failed to initialize Gately client:', error);
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
const [user, setUser] = React.useState(null);
|
|
26
|
+
const [session, setSession] = React.useState(null);
|
|
27
|
+
const [isLoading, setIsLoading] = React.useState(true);
|
|
28
|
+
const [error, setError] = React.useState(null);
|
|
29
|
+
React.useEffect(() => {
|
|
30
|
+
if (!client)
|
|
31
|
+
return;
|
|
32
|
+
setIsLoading(true);
|
|
33
|
+
setUser(client.getUser());
|
|
34
|
+
setSession(client.getSession());
|
|
35
|
+
setIsLoading(false);
|
|
36
|
+
const handleAuthStateChange = (newUser, newSession) => {
|
|
37
|
+
setUser(newUser);
|
|
38
|
+
setSession(newSession);
|
|
39
|
+
setError(null);
|
|
40
|
+
};
|
|
41
|
+
client.onAuthStateChange(handleAuthStateChange);
|
|
42
|
+
return () => {
|
|
43
|
+
client.offAuthStateChange(handleAuthStateChange);
|
|
44
|
+
};
|
|
45
|
+
}, [client]);
|
|
46
|
+
const login = React.useCallback(async (email, password) => {
|
|
47
|
+
if (!client)
|
|
48
|
+
throw new Error('Gately client not initialized');
|
|
49
|
+
setError(null);
|
|
50
|
+
try {
|
|
51
|
+
return await client.login(email, password);
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
55
|
+
setError(error);
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
58
|
+
}, [client]);
|
|
59
|
+
const signup = React.useCallback(async (email, password, metadata) => {
|
|
60
|
+
if (!client)
|
|
61
|
+
throw new Error('Gately client not initialized');
|
|
62
|
+
setError(null);
|
|
63
|
+
try {
|
|
64
|
+
return await client.signup(email, password, metadata);
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
68
|
+
setError(error);
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
}, [client]);
|
|
72
|
+
const logout = React.useCallback(async () => {
|
|
73
|
+
if (!client)
|
|
74
|
+
throw new Error('Gately client not initialized');
|
|
75
|
+
setError(null);
|
|
76
|
+
try {
|
|
77
|
+
await client.logout();
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
81
|
+
setError(error);
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
}, [client]);
|
|
85
|
+
const sendMagicLink = React.useCallback(async (email, redirectTo) => {
|
|
86
|
+
if (!client)
|
|
87
|
+
throw new Error('Gately client not initialized');
|
|
88
|
+
setError(null);
|
|
89
|
+
try {
|
|
90
|
+
await client.sendMagicLink(email, { redirectTo });
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
94
|
+
setError(error);
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
}, [client]);
|
|
98
|
+
const resetPassword = React.useCallback(async (email) => {
|
|
99
|
+
if (!client)
|
|
100
|
+
throw new Error('Gately client not initialized');
|
|
101
|
+
setError(null);
|
|
102
|
+
try {
|
|
103
|
+
await client.resetPassword(email);
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
106
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
107
|
+
setError(error);
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
}, [client]);
|
|
111
|
+
const fetchSession = React.useCallback(async () => {
|
|
112
|
+
if (!client)
|
|
113
|
+
throw new Error('Gately client not initialized');
|
|
114
|
+
setError(null);
|
|
115
|
+
try {
|
|
116
|
+
return await client.fetchSession();
|
|
117
|
+
}
|
|
118
|
+
catch (err) {
|
|
119
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
120
|
+
setError(error);
|
|
121
|
+
throw error;
|
|
122
|
+
}
|
|
123
|
+
}, [client]);
|
|
124
|
+
const getUserProfile = React.useCallback(async () => {
|
|
125
|
+
if (!client)
|
|
126
|
+
throw new Error('Gately client not initialized');
|
|
127
|
+
setError(null);
|
|
128
|
+
try {
|
|
129
|
+
return await client.getUserProfile();
|
|
130
|
+
}
|
|
131
|
+
catch (err) {
|
|
132
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
133
|
+
setError(error);
|
|
134
|
+
throw error;
|
|
135
|
+
}
|
|
136
|
+
}, [client]);
|
|
137
|
+
const updateUserProfile = React.useCallback(async (updates) => {
|
|
138
|
+
if (!client)
|
|
139
|
+
throw new Error('Gately client not initialized');
|
|
140
|
+
setError(null);
|
|
141
|
+
try {
|
|
142
|
+
return await client.updateUserProfile(updates);
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
146
|
+
setError(error);
|
|
147
|
+
throw error;
|
|
148
|
+
}
|
|
149
|
+
}, [client]);
|
|
150
|
+
const deleteUserAccount = React.useCallback(async () => {
|
|
151
|
+
if (!client)
|
|
152
|
+
throw new Error('Gately client not initialized');
|
|
153
|
+
setError(null);
|
|
154
|
+
try {
|
|
155
|
+
await client.deleteUserAccount();
|
|
156
|
+
}
|
|
157
|
+
catch (err) {
|
|
158
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
159
|
+
setError(error);
|
|
160
|
+
throw error;
|
|
161
|
+
}
|
|
162
|
+
}, [client]);
|
|
163
|
+
const changePassword = React.useCallback(async (current, newPassword) => {
|
|
164
|
+
if (!client)
|
|
165
|
+
throw new Error('Gately client not initialized');
|
|
166
|
+
setError(null);
|
|
167
|
+
try {
|
|
168
|
+
await client.changePassword(current, newPassword);
|
|
169
|
+
}
|
|
170
|
+
catch (err) {
|
|
171
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
172
|
+
setError(error);
|
|
173
|
+
throw error;
|
|
174
|
+
}
|
|
175
|
+
}, [client]);
|
|
176
|
+
const value = {
|
|
177
|
+
user,
|
|
178
|
+
session,
|
|
179
|
+
isLoading,
|
|
180
|
+
isAuthenticated: !!session && new Date(session.expires_at) > new Date(),
|
|
181
|
+
error,
|
|
182
|
+
login,
|
|
183
|
+
signup,
|
|
184
|
+
logout,
|
|
185
|
+
sendMagicLink,
|
|
186
|
+
resetPassword,
|
|
187
|
+
fetchSession,
|
|
188
|
+
getUserProfile,
|
|
189
|
+
updateUserProfile,
|
|
190
|
+
deleteUserAccount,
|
|
191
|
+
changePassword,
|
|
192
|
+
client
|
|
193
|
+
};
|
|
194
|
+
return React.createElement(GatelyContext.Provider, { value }, children);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
exports.GatelyContext = GatelyContext;
|
|
198
|
+
exports.GatelyProvider = GatelyProvider;
|
|
199
|
+
exports.default = GatelyProvider;
|
package/dist/context.mjs
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import React, { createContext, useState, useEffect, useCallback } from 'react';
|
|
2
|
+
import { GatelyClient } from '@gately/sdk';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Gately React Context
|
|
6
|
+
* Provides authentication state and methods to React components
|
|
7
|
+
*/
|
|
8
|
+
const GatelyContext = createContext(undefined);
|
|
9
|
+
function GatelyProvider({ projectId, apiUrl, children, autoRefresh = true }) {
|
|
10
|
+
const [client] = useState(() => {
|
|
11
|
+
if (typeof window === 'undefined')
|
|
12
|
+
return null;
|
|
13
|
+
try {
|
|
14
|
+
return new GatelyClient(projectId, { apiUrl, autoRefresh });
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
console.error('Failed to initialize Gately client:', error);
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
const [user, setUser] = useState(null);
|
|
22
|
+
const [session, setSession] = useState(null);
|
|
23
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
24
|
+
const [error, setError] = useState(null);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (!client)
|
|
27
|
+
return;
|
|
28
|
+
setIsLoading(true);
|
|
29
|
+
setUser(client.getUser());
|
|
30
|
+
setSession(client.getSession());
|
|
31
|
+
setIsLoading(false);
|
|
32
|
+
const handleAuthStateChange = (newUser, newSession) => {
|
|
33
|
+
setUser(newUser);
|
|
34
|
+
setSession(newSession);
|
|
35
|
+
setError(null);
|
|
36
|
+
};
|
|
37
|
+
client.onAuthStateChange(handleAuthStateChange);
|
|
38
|
+
return () => {
|
|
39
|
+
client.offAuthStateChange(handleAuthStateChange);
|
|
40
|
+
};
|
|
41
|
+
}, [client]);
|
|
42
|
+
const login = useCallback(async (email, password) => {
|
|
43
|
+
if (!client)
|
|
44
|
+
throw new Error('Gately client not initialized');
|
|
45
|
+
setError(null);
|
|
46
|
+
try {
|
|
47
|
+
return await client.login(email, password);
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
51
|
+
setError(error);
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
}, [client]);
|
|
55
|
+
const signup = useCallback(async (email, password, metadata) => {
|
|
56
|
+
if (!client)
|
|
57
|
+
throw new Error('Gately client not initialized');
|
|
58
|
+
setError(null);
|
|
59
|
+
try {
|
|
60
|
+
return await client.signup(email, password, metadata);
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
64
|
+
setError(error);
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
}, [client]);
|
|
68
|
+
const logout = useCallback(async () => {
|
|
69
|
+
if (!client)
|
|
70
|
+
throw new Error('Gately client not initialized');
|
|
71
|
+
setError(null);
|
|
72
|
+
try {
|
|
73
|
+
await client.logout();
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
77
|
+
setError(error);
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
}, [client]);
|
|
81
|
+
const sendMagicLink = useCallback(async (email, redirectTo) => {
|
|
82
|
+
if (!client)
|
|
83
|
+
throw new Error('Gately client not initialized');
|
|
84
|
+
setError(null);
|
|
85
|
+
try {
|
|
86
|
+
await client.sendMagicLink(email, { redirectTo });
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
90
|
+
setError(error);
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
}, [client]);
|
|
94
|
+
const resetPassword = useCallback(async (email) => {
|
|
95
|
+
if (!client)
|
|
96
|
+
throw new Error('Gately client not initialized');
|
|
97
|
+
setError(null);
|
|
98
|
+
try {
|
|
99
|
+
await client.resetPassword(email);
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
103
|
+
setError(error);
|
|
104
|
+
throw error;
|
|
105
|
+
}
|
|
106
|
+
}, [client]);
|
|
107
|
+
const fetchSession = useCallback(async () => {
|
|
108
|
+
if (!client)
|
|
109
|
+
throw new Error('Gately client not initialized');
|
|
110
|
+
setError(null);
|
|
111
|
+
try {
|
|
112
|
+
return await client.fetchSession();
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
116
|
+
setError(error);
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
}, [client]);
|
|
120
|
+
const getUserProfile = useCallback(async () => {
|
|
121
|
+
if (!client)
|
|
122
|
+
throw new Error('Gately client not initialized');
|
|
123
|
+
setError(null);
|
|
124
|
+
try {
|
|
125
|
+
return await client.getUserProfile();
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
129
|
+
setError(error);
|
|
130
|
+
throw error;
|
|
131
|
+
}
|
|
132
|
+
}, [client]);
|
|
133
|
+
const updateUserProfile = useCallback(async (updates) => {
|
|
134
|
+
if (!client)
|
|
135
|
+
throw new Error('Gately client not initialized');
|
|
136
|
+
setError(null);
|
|
137
|
+
try {
|
|
138
|
+
return await client.updateUserProfile(updates);
|
|
139
|
+
}
|
|
140
|
+
catch (err) {
|
|
141
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
142
|
+
setError(error);
|
|
143
|
+
throw error;
|
|
144
|
+
}
|
|
145
|
+
}, [client]);
|
|
146
|
+
const deleteUserAccount = useCallback(async () => {
|
|
147
|
+
if (!client)
|
|
148
|
+
throw new Error('Gately client not initialized');
|
|
149
|
+
setError(null);
|
|
150
|
+
try {
|
|
151
|
+
await client.deleteUserAccount();
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
155
|
+
setError(error);
|
|
156
|
+
throw error;
|
|
157
|
+
}
|
|
158
|
+
}, [client]);
|
|
159
|
+
const changePassword = useCallback(async (current, newPassword) => {
|
|
160
|
+
if (!client)
|
|
161
|
+
throw new Error('Gately client not initialized');
|
|
162
|
+
setError(null);
|
|
163
|
+
try {
|
|
164
|
+
await client.changePassword(current, newPassword);
|
|
165
|
+
}
|
|
166
|
+
catch (err) {
|
|
167
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
168
|
+
setError(error);
|
|
169
|
+
throw error;
|
|
170
|
+
}
|
|
171
|
+
}, [client]);
|
|
172
|
+
const value = {
|
|
173
|
+
user,
|
|
174
|
+
session,
|
|
175
|
+
isLoading,
|
|
176
|
+
isAuthenticated: !!session && new Date(session.expires_at) > new Date(),
|
|
177
|
+
error,
|
|
178
|
+
login,
|
|
179
|
+
signup,
|
|
180
|
+
logout,
|
|
181
|
+
sendMagicLink,
|
|
182
|
+
resetPassword,
|
|
183
|
+
fetchSession,
|
|
184
|
+
getUserProfile,
|
|
185
|
+
updateUserProfile,
|
|
186
|
+
deleteUserAccount,
|
|
187
|
+
changePassword,
|
|
188
|
+
client
|
|
189
|
+
};
|
|
190
|
+
return React.createElement(GatelyContext.Provider, { value }, children);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export { GatelyContext, GatelyProvider, GatelyProvider as default };
|