@korajs/auth 0.1.0 → 0.3.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 +69 -30
- package/dist/chunk-FSU4SK32.js +786 -0
- package/dist/chunk-FSU4SK32.js.map +1 -0
- package/dist/chunk-HOZXDR6Y.js +52 -0
- package/dist/chunk-HOZXDR6Y.js.map +1 -0
- package/dist/index.cjs +1538 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +708 -5
- package/dist/index.d.ts +708 -5
- package/dist/index.js +926 -3
- package/dist/index.js.map +1 -1
- package/dist/{device-identity-DiwdLsUB.d.cts → operation-encryptor-DRmKNWpF.d.cts} +148 -2
- package/dist/{device-identity-DiwdLsUB.d.ts → operation-encryptor-DRmKNWpF.d.ts} +148 -2
- package/dist/{auth-client-CrDNuh10.d.cts → org-client-BVTLKcIk.d.cts} +177 -3
- package/dist/{auth-client-CrDNuh10.d.ts → org-client-BVTLKcIk.d.ts} +177 -3
- package/dist/password-hash-HDH6VQCQ.js +9 -0
- package/dist/password-hash-HDH6VQCQ.js.map +1 -0
- package/dist/react.cjs +183 -2
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +107 -2
- package/dist/react.d.ts +107 -2
- package/dist/react.js +186 -1
- package/dist/react.js.map +1 -1
- package/dist/server.cjs +4945 -224
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +3039 -29
- package/dist/server.d.ts +3039 -29
- package/dist/server.js +4272 -92
- package/dist/server.js.map +1 -1
- package/package.json +5 -5
- package/dist/chunk-L554ZDPY.js +0 -174
- package/dist/chunk-L554ZDPY.js.map +0 -1
|
@@ -62,6 +62,7 @@ declare class AuthClient {
|
|
|
62
62
|
private _state;
|
|
63
63
|
private _user;
|
|
64
64
|
private _refreshPromise;
|
|
65
|
+
private _initialized;
|
|
65
66
|
/**
|
|
66
67
|
* Creates a new AuthClient.
|
|
67
68
|
*
|
|
@@ -108,8 +109,9 @@ declare class AuthClient {
|
|
|
108
109
|
/**
|
|
109
110
|
* Sign out the current user.
|
|
110
111
|
*
|
|
111
|
-
* Clears local tokens and
|
|
112
|
-
*
|
|
112
|
+
* Clears local tokens and attempts to revoke the refresh token on the server
|
|
113
|
+
* (best-effort — succeeds even if the server is unreachable). This ensures that
|
|
114
|
+
* stolen refresh tokens cannot be used after the user explicitly signs out.
|
|
113
115
|
*/
|
|
114
116
|
signOut(): Promise<void>;
|
|
115
117
|
/**
|
|
@@ -178,4 +180,176 @@ declare class AuthClient {
|
|
|
178
180
|
private request;
|
|
179
181
|
}
|
|
180
182
|
|
|
181
|
-
|
|
183
|
+
/**
|
|
184
|
+
* Organization info returned by the server.
|
|
185
|
+
*/
|
|
186
|
+
interface ClientOrganization {
|
|
187
|
+
id: string;
|
|
188
|
+
name: string;
|
|
189
|
+
slug: string;
|
|
190
|
+
ownerId: string;
|
|
191
|
+
createdAt: number;
|
|
192
|
+
updatedAt: number;
|
|
193
|
+
metadata: Record<string, unknown>;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Membership info returned by the server.
|
|
197
|
+
*/
|
|
198
|
+
interface ClientMembership {
|
|
199
|
+
id: string;
|
|
200
|
+
orgId: string;
|
|
201
|
+
userId: string;
|
|
202
|
+
role: string;
|
|
203
|
+
invitedBy: string | null;
|
|
204
|
+
joinedAt: number;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Invitation info returned by the server.
|
|
208
|
+
*/
|
|
209
|
+
interface ClientInvitation {
|
|
210
|
+
id: string;
|
|
211
|
+
orgId: string;
|
|
212
|
+
email: string;
|
|
213
|
+
role: string;
|
|
214
|
+
invitedBy: string;
|
|
215
|
+
token: string;
|
|
216
|
+
createdAt: number;
|
|
217
|
+
expiresAt: number;
|
|
218
|
+
status: string;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Configuration for the OrgClient.
|
|
222
|
+
*/
|
|
223
|
+
interface OrgClientConfig {
|
|
224
|
+
/** Base URL of the auth/org server */
|
|
225
|
+
serverUrl: string;
|
|
226
|
+
/** Function that returns a valid access token for authenticated requests */
|
|
227
|
+
getAccessToken: () => Promise<string | null>;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Thrown when an org operation fails.
|
|
231
|
+
*/
|
|
232
|
+
declare class OrgClientError extends KoraError {
|
|
233
|
+
constructor(message: string, code: string, context?: Record<string, unknown>);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Client-side organization manager.
|
|
237
|
+
*
|
|
238
|
+
* Handles org CRUD, member management, invitations, and active org switching.
|
|
239
|
+
* Framework-agnostic — works in any JavaScript environment with `fetch`.
|
|
240
|
+
*
|
|
241
|
+
* @example
|
|
242
|
+
* ```typescript
|
|
243
|
+
* const orgClient = new OrgClient({
|
|
244
|
+
* serverUrl: 'http://localhost:3001',
|
|
245
|
+
* getAccessToken: () => authClient.getAccessToken(),
|
|
246
|
+
* })
|
|
247
|
+
*
|
|
248
|
+
* const org = await orgClient.createOrg({ name: 'Acme Inc', slug: 'acme' })
|
|
249
|
+
* orgClient.switchOrg(org.id)
|
|
250
|
+
* ```
|
|
251
|
+
*/
|
|
252
|
+
declare class OrgClient {
|
|
253
|
+
private readonly serverUrl;
|
|
254
|
+
private readonly getAccessToken;
|
|
255
|
+
private readonly listeners;
|
|
256
|
+
private _activeOrgId;
|
|
257
|
+
private _activeOrg;
|
|
258
|
+
private _activeRole;
|
|
259
|
+
constructor(config: OrgClientConfig);
|
|
260
|
+
/** Currently active organization ID */
|
|
261
|
+
get activeOrgId(): string | null;
|
|
262
|
+
/** Currently active organization */
|
|
263
|
+
get activeOrg(): ClientOrganization | null;
|
|
264
|
+
/** Current user's role in the active organization */
|
|
265
|
+
get activeRole(): string | null;
|
|
266
|
+
/**
|
|
267
|
+
* Create a new organization.
|
|
268
|
+
*/
|
|
269
|
+
createOrg(params: {
|
|
270
|
+
name: string;
|
|
271
|
+
slug?: string;
|
|
272
|
+
metadata?: Record<string, unknown>;
|
|
273
|
+
}): Promise<ClientOrganization>;
|
|
274
|
+
/**
|
|
275
|
+
* List all organizations the current user belongs to.
|
|
276
|
+
*/
|
|
277
|
+
listOrgs(): Promise<ClientOrganization[]>;
|
|
278
|
+
/**
|
|
279
|
+
* Get an organization by ID.
|
|
280
|
+
*/
|
|
281
|
+
getOrg(orgId: string): Promise<ClientOrganization>;
|
|
282
|
+
/**
|
|
283
|
+
* Update an organization.
|
|
284
|
+
*/
|
|
285
|
+
updateOrg(orgId: string, params: {
|
|
286
|
+
name?: string;
|
|
287
|
+
slug?: string;
|
|
288
|
+
metadata?: Record<string, unknown>;
|
|
289
|
+
}): Promise<ClientOrganization>;
|
|
290
|
+
/**
|
|
291
|
+
* Delete an organization.
|
|
292
|
+
*/
|
|
293
|
+
deleteOrg(orgId: string): Promise<void>;
|
|
294
|
+
/**
|
|
295
|
+
* Switch the active organization context.
|
|
296
|
+
* Fetches the org details and the user's membership/role.
|
|
297
|
+
*/
|
|
298
|
+
switchOrg(orgId: string): Promise<void>;
|
|
299
|
+
/**
|
|
300
|
+
* Clear the active organization (no org selected).
|
|
301
|
+
*/
|
|
302
|
+
clearActiveOrg(): void;
|
|
303
|
+
/**
|
|
304
|
+
* List members of an organization.
|
|
305
|
+
*/
|
|
306
|
+
listMembers(orgId: string): Promise<ClientMembership[]>;
|
|
307
|
+
/**
|
|
308
|
+
* Remove a member from an organization.
|
|
309
|
+
*/
|
|
310
|
+
removeMember(orgId: string, userId: string): Promise<void>;
|
|
311
|
+
/**
|
|
312
|
+
* Update a member's role.
|
|
313
|
+
*/
|
|
314
|
+
updateMemberRole(orgId: string, userId: string, role: string): Promise<ClientMembership>;
|
|
315
|
+
/**
|
|
316
|
+
* Transfer ownership to another member.
|
|
317
|
+
*/
|
|
318
|
+
transferOwnership(orgId: string, newOwnerId: string): Promise<void>;
|
|
319
|
+
/**
|
|
320
|
+
* Leave an organization (remove yourself).
|
|
321
|
+
*/
|
|
322
|
+
leaveOrg(orgId: string): Promise<void>;
|
|
323
|
+
/**
|
|
324
|
+
* Invite a user to an organization by email.
|
|
325
|
+
*/
|
|
326
|
+
inviteMember(orgId: string, params: {
|
|
327
|
+
email: string;
|
|
328
|
+
role: string;
|
|
329
|
+
}): Promise<ClientInvitation>;
|
|
330
|
+
/**
|
|
331
|
+
* Accept an invitation by token.
|
|
332
|
+
*/
|
|
333
|
+
acceptInvitation(token: string): Promise<ClientMembership>;
|
|
334
|
+
/**
|
|
335
|
+
* List pending invitations for an organization.
|
|
336
|
+
*/
|
|
337
|
+
listInvitations(orgId: string): Promise<ClientInvitation[]>;
|
|
338
|
+
/**
|
|
339
|
+
* Revoke a pending invitation.
|
|
340
|
+
*/
|
|
341
|
+
revokeInvitation(orgId: string, invitationId: string): Promise<void>;
|
|
342
|
+
/**
|
|
343
|
+
* List pending invitations for the current user's email.
|
|
344
|
+
*/
|
|
345
|
+
listMyInvitations(email: string): Promise<ClientInvitation[]>;
|
|
346
|
+
/**
|
|
347
|
+
* Subscribe to active org changes.
|
|
348
|
+
* @returns Unsubscribe function
|
|
349
|
+
*/
|
|
350
|
+
onOrgChange(callback: (orgId: string | null) => void): () => void;
|
|
351
|
+
private notifyListeners;
|
|
352
|
+
private request;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
export { AuthClient as A, type ClientInvitation as C, OrgClient as O, type AuthClientConfig as a, AuthError as b, type AuthState as c, type AuthUser as d, type ClientMembership as e, type ClientOrganization as f, type OrgClientConfig as g, OrgClientError as h };
|
|
@@ -62,6 +62,7 @@ declare class AuthClient {
|
|
|
62
62
|
private _state;
|
|
63
63
|
private _user;
|
|
64
64
|
private _refreshPromise;
|
|
65
|
+
private _initialized;
|
|
65
66
|
/**
|
|
66
67
|
* Creates a new AuthClient.
|
|
67
68
|
*
|
|
@@ -108,8 +109,9 @@ declare class AuthClient {
|
|
|
108
109
|
/**
|
|
109
110
|
* Sign out the current user.
|
|
110
111
|
*
|
|
111
|
-
* Clears local tokens and
|
|
112
|
-
*
|
|
112
|
+
* Clears local tokens and attempts to revoke the refresh token on the server
|
|
113
|
+
* (best-effort — succeeds even if the server is unreachable). This ensures that
|
|
114
|
+
* stolen refresh tokens cannot be used after the user explicitly signs out.
|
|
113
115
|
*/
|
|
114
116
|
signOut(): Promise<void>;
|
|
115
117
|
/**
|
|
@@ -178,4 +180,176 @@ declare class AuthClient {
|
|
|
178
180
|
private request;
|
|
179
181
|
}
|
|
180
182
|
|
|
181
|
-
|
|
183
|
+
/**
|
|
184
|
+
* Organization info returned by the server.
|
|
185
|
+
*/
|
|
186
|
+
interface ClientOrganization {
|
|
187
|
+
id: string;
|
|
188
|
+
name: string;
|
|
189
|
+
slug: string;
|
|
190
|
+
ownerId: string;
|
|
191
|
+
createdAt: number;
|
|
192
|
+
updatedAt: number;
|
|
193
|
+
metadata: Record<string, unknown>;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Membership info returned by the server.
|
|
197
|
+
*/
|
|
198
|
+
interface ClientMembership {
|
|
199
|
+
id: string;
|
|
200
|
+
orgId: string;
|
|
201
|
+
userId: string;
|
|
202
|
+
role: string;
|
|
203
|
+
invitedBy: string | null;
|
|
204
|
+
joinedAt: number;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Invitation info returned by the server.
|
|
208
|
+
*/
|
|
209
|
+
interface ClientInvitation {
|
|
210
|
+
id: string;
|
|
211
|
+
orgId: string;
|
|
212
|
+
email: string;
|
|
213
|
+
role: string;
|
|
214
|
+
invitedBy: string;
|
|
215
|
+
token: string;
|
|
216
|
+
createdAt: number;
|
|
217
|
+
expiresAt: number;
|
|
218
|
+
status: string;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Configuration for the OrgClient.
|
|
222
|
+
*/
|
|
223
|
+
interface OrgClientConfig {
|
|
224
|
+
/** Base URL of the auth/org server */
|
|
225
|
+
serverUrl: string;
|
|
226
|
+
/** Function that returns a valid access token for authenticated requests */
|
|
227
|
+
getAccessToken: () => Promise<string | null>;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Thrown when an org operation fails.
|
|
231
|
+
*/
|
|
232
|
+
declare class OrgClientError extends KoraError {
|
|
233
|
+
constructor(message: string, code: string, context?: Record<string, unknown>);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Client-side organization manager.
|
|
237
|
+
*
|
|
238
|
+
* Handles org CRUD, member management, invitations, and active org switching.
|
|
239
|
+
* Framework-agnostic — works in any JavaScript environment with `fetch`.
|
|
240
|
+
*
|
|
241
|
+
* @example
|
|
242
|
+
* ```typescript
|
|
243
|
+
* const orgClient = new OrgClient({
|
|
244
|
+
* serverUrl: 'http://localhost:3001',
|
|
245
|
+
* getAccessToken: () => authClient.getAccessToken(),
|
|
246
|
+
* })
|
|
247
|
+
*
|
|
248
|
+
* const org = await orgClient.createOrg({ name: 'Acme Inc', slug: 'acme' })
|
|
249
|
+
* orgClient.switchOrg(org.id)
|
|
250
|
+
* ```
|
|
251
|
+
*/
|
|
252
|
+
declare class OrgClient {
|
|
253
|
+
private readonly serverUrl;
|
|
254
|
+
private readonly getAccessToken;
|
|
255
|
+
private readonly listeners;
|
|
256
|
+
private _activeOrgId;
|
|
257
|
+
private _activeOrg;
|
|
258
|
+
private _activeRole;
|
|
259
|
+
constructor(config: OrgClientConfig);
|
|
260
|
+
/** Currently active organization ID */
|
|
261
|
+
get activeOrgId(): string | null;
|
|
262
|
+
/** Currently active organization */
|
|
263
|
+
get activeOrg(): ClientOrganization | null;
|
|
264
|
+
/** Current user's role in the active organization */
|
|
265
|
+
get activeRole(): string | null;
|
|
266
|
+
/**
|
|
267
|
+
* Create a new organization.
|
|
268
|
+
*/
|
|
269
|
+
createOrg(params: {
|
|
270
|
+
name: string;
|
|
271
|
+
slug?: string;
|
|
272
|
+
metadata?: Record<string, unknown>;
|
|
273
|
+
}): Promise<ClientOrganization>;
|
|
274
|
+
/**
|
|
275
|
+
* List all organizations the current user belongs to.
|
|
276
|
+
*/
|
|
277
|
+
listOrgs(): Promise<ClientOrganization[]>;
|
|
278
|
+
/**
|
|
279
|
+
* Get an organization by ID.
|
|
280
|
+
*/
|
|
281
|
+
getOrg(orgId: string): Promise<ClientOrganization>;
|
|
282
|
+
/**
|
|
283
|
+
* Update an organization.
|
|
284
|
+
*/
|
|
285
|
+
updateOrg(orgId: string, params: {
|
|
286
|
+
name?: string;
|
|
287
|
+
slug?: string;
|
|
288
|
+
metadata?: Record<string, unknown>;
|
|
289
|
+
}): Promise<ClientOrganization>;
|
|
290
|
+
/**
|
|
291
|
+
* Delete an organization.
|
|
292
|
+
*/
|
|
293
|
+
deleteOrg(orgId: string): Promise<void>;
|
|
294
|
+
/**
|
|
295
|
+
* Switch the active organization context.
|
|
296
|
+
* Fetches the org details and the user's membership/role.
|
|
297
|
+
*/
|
|
298
|
+
switchOrg(orgId: string): Promise<void>;
|
|
299
|
+
/**
|
|
300
|
+
* Clear the active organization (no org selected).
|
|
301
|
+
*/
|
|
302
|
+
clearActiveOrg(): void;
|
|
303
|
+
/**
|
|
304
|
+
* List members of an organization.
|
|
305
|
+
*/
|
|
306
|
+
listMembers(orgId: string): Promise<ClientMembership[]>;
|
|
307
|
+
/**
|
|
308
|
+
* Remove a member from an organization.
|
|
309
|
+
*/
|
|
310
|
+
removeMember(orgId: string, userId: string): Promise<void>;
|
|
311
|
+
/**
|
|
312
|
+
* Update a member's role.
|
|
313
|
+
*/
|
|
314
|
+
updateMemberRole(orgId: string, userId: string, role: string): Promise<ClientMembership>;
|
|
315
|
+
/**
|
|
316
|
+
* Transfer ownership to another member.
|
|
317
|
+
*/
|
|
318
|
+
transferOwnership(orgId: string, newOwnerId: string): Promise<void>;
|
|
319
|
+
/**
|
|
320
|
+
* Leave an organization (remove yourself).
|
|
321
|
+
*/
|
|
322
|
+
leaveOrg(orgId: string): Promise<void>;
|
|
323
|
+
/**
|
|
324
|
+
* Invite a user to an organization by email.
|
|
325
|
+
*/
|
|
326
|
+
inviteMember(orgId: string, params: {
|
|
327
|
+
email: string;
|
|
328
|
+
role: string;
|
|
329
|
+
}): Promise<ClientInvitation>;
|
|
330
|
+
/**
|
|
331
|
+
* Accept an invitation by token.
|
|
332
|
+
*/
|
|
333
|
+
acceptInvitation(token: string): Promise<ClientMembership>;
|
|
334
|
+
/**
|
|
335
|
+
* List pending invitations for an organization.
|
|
336
|
+
*/
|
|
337
|
+
listInvitations(orgId: string): Promise<ClientInvitation[]>;
|
|
338
|
+
/**
|
|
339
|
+
* Revoke a pending invitation.
|
|
340
|
+
*/
|
|
341
|
+
revokeInvitation(orgId: string, invitationId: string): Promise<void>;
|
|
342
|
+
/**
|
|
343
|
+
* List pending invitations for the current user's email.
|
|
344
|
+
*/
|
|
345
|
+
listMyInvitations(email: string): Promise<ClientInvitation[]>;
|
|
346
|
+
/**
|
|
347
|
+
* Subscribe to active org changes.
|
|
348
|
+
* @returns Unsubscribe function
|
|
349
|
+
*/
|
|
350
|
+
onOrgChange(callback: (orgId: string | null) => void): () => void;
|
|
351
|
+
private notifyListeners;
|
|
352
|
+
private request;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
export { AuthClient as A, type ClientInvitation as C, OrgClient as O, type AuthClientConfig as a, AuthError as b, type AuthState as c, type AuthUser as d, type ClientMembership as e, type ClientOrganization as f, type OrgClientConfig as g, OrgClientError as h };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/react.cjs
CHANGED
|
@@ -22,9 +22,13 @@ var react_exports = {};
|
|
|
22
22
|
__export(react_exports, {
|
|
23
23
|
AuthContext: () => AuthContext,
|
|
24
24
|
AuthProvider: () => AuthProvider,
|
|
25
|
+
OrgContext: () => OrgContext,
|
|
25
26
|
useAuth: () => useAuth,
|
|
26
27
|
useAuthStatus: () => useAuthStatus,
|
|
27
|
-
useCurrentUser: () => useCurrentUser
|
|
28
|
+
useCurrentUser: () => useCurrentUser,
|
|
29
|
+
useOrg: () => useOrg,
|
|
30
|
+
useOrgMembers: () => useOrgMembers,
|
|
31
|
+
usePermission: () => usePermission
|
|
28
32
|
});
|
|
29
33
|
module.exports = __toCommonJS(react_exports);
|
|
30
34
|
|
|
@@ -195,12 +199,189 @@ function useAuthStatus() {
|
|
|
195
199
|
isLoading
|
|
196
200
|
};
|
|
197
201
|
}
|
|
202
|
+
|
|
203
|
+
// src/react/org-hooks.ts
|
|
204
|
+
var import_react4 = require("react");
|
|
205
|
+
var OrgContext = (0, import_react4.createContext)(null);
|
|
206
|
+
function useOrgContext() {
|
|
207
|
+
const ctx = (0, import_react4.useContext)(OrgContext);
|
|
208
|
+
if (ctx === null) {
|
|
209
|
+
throw new Error(
|
|
210
|
+
"useOrg / useOrgMembers / usePermission must be used within an <OrgProvider>. Wrap your component tree with <OrgProvider client={orgClient}>."
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
return ctx;
|
|
214
|
+
}
|
|
215
|
+
function useOrg() {
|
|
216
|
+
const { client } = useOrgContext();
|
|
217
|
+
const [error, setError] = (0, import_react4.useState)(null);
|
|
218
|
+
const orgSnapshotRef = (0, import_react4.useRef)({
|
|
219
|
+
orgId: client.activeOrgId,
|
|
220
|
+
org: client.activeOrg,
|
|
221
|
+
role: client.activeRole
|
|
222
|
+
});
|
|
223
|
+
const subscribe = (0, import_react4.useCallback)(
|
|
224
|
+
(onStoreChange) => {
|
|
225
|
+
return client.onOrgChange(() => {
|
|
226
|
+
orgSnapshotRef.current = {
|
|
227
|
+
orgId: client.activeOrgId,
|
|
228
|
+
org: client.activeOrg,
|
|
229
|
+
role: client.activeRole
|
|
230
|
+
};
|
|
231
|
+
onStoreChange();
|
|
232
|
+
});
|
|
233
|
+
},
|
|
234
|
+
[client]
|
|
235
|
+
);
|
|
236
|
+
const getSnapshot = (0, import_react4.useCallback)(() => orgSnapshotRef.current, []);
|
|
237
|
+
const { orgId, org, role } = (0, import_react4.useSyncExternalStore)(subscribe, getSnapshot);
|
|
238
|
+
const switchOrg = (0, import_react4.useCallback)(
|
|
239
|
+
async (newOrgId) => {
|
|
240
|
+
setError(null);
|
|
241
|
+
try {
|
|
242
|
+
await client.switchOrg(newOrgId);
|
|
243
|
+
} catch (err) {
|
|
244
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
[client]
|
|
248
|
+
);
|
|
249
|
+
const createOrg = (0, import_react4.useCallback)(
|
|
250
|
+
async (params) => {
|
|
251
|
+
setError(null);
|
|
252
|
+
try {
|
|
253
|
+
return await client.createOrg(params);
|
|
254
|
+
} catch (err) {
|
|
255
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
256
|
+
setError(msg);
|
|
257
|
+
throw err;
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
[client]
|
|
261
|
+
);
|
|
262
|
+
const leaveOrg = (0, import_react4.useCallback)(async () => {
|
|
263
|
+
if (!orgId) return;
|
|
264
|
+
setError(null);
|
|
265
|
+
try {
|
|
266
|
+
await client.leaveOrg(orgId);
|
|
267
|
+
} catch (err) {
|
|
268
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
269
|
+
}
|
|
270
|
+
}, [client, orgId]);
|
|
271
|
+
const clearOrg = (0, import_react4.useCallback)(() => {
|
|
272
|
+
client.clearActiveOrg();
|
|
273
|
+
}, [client]);
|
|
274
|
+
const listOrgs = (0, import_react4.useCallback)(async () => {
|
|
275
|
+
try {
|
|
276
|
+
return await client.listOrgs();
|
|
277
|
+
} catch (err) {
|
|
278
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
279
|
+
return [];
|
|
280
|
+
}
|
|
281
|
+
}, [client]);
|
|
282
|
+
return { org, role, orgId, switchOrg, createOrg, leaveOrg, clearOrg, listOrgs, error };
|
|
283
|
+
}
|
|
284
|
+
function useOrgMembers(orgId) {
|
|
285
|
+
const { client } = useOrgContext();
|
|
286
|
+
const [members, setMembers] = (0, import_react4.useState)([]);
|
|
287
|
+
const [isLoading, setIsLoading] = (0, import_react4.useState)(true);
|
|
288
|
+
const [error, setError] = (0, import_react4.useState)(null);
|
|
289
|
+
const refresh = (0, import_react4.useCallback)(async () => {
|
|
290
|
+
setIsLoading(true);
|
|
291
|
+
setError(null);
|
|
292
|
+
try {
|
|
293
|
+
const result = await client.listMembers(orgId);
|
|
294
|
+
setMembers(result);
|
|
295
|
+
} catch (err) {
|
|
296
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
297
|
+
} finally {
|
|
298
|
+
setIsLoading(false);
|
|
299
|
+
}
|
|
300
|
+
}, [client, orgId]);
|
|
301
|
+
(0, import_react4.useEffect)(() => {
|
|
302
|
+
refresh();
|
|
303
|
+
}, [refresh]);
|
|
304
|
+
const invite = (0, import_react4.useCallback)(
|
|
305
|
+
async (email, role) => {
|
|
306
|
+
setError(null);
|
|
307
|
+
try {
|
|
308
|
+
const result = await client.inviteMember(orgId, { email, role });
|
|
309
|
+
return result;
|
|
310
|
+
} catch (err) {
|
|
311
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
312
|
+
setError(msg);
|
|
313
|
+
throw err;
|
|
314
|
+
}
|
|
315
|
+
},
|
|
316
|
+
[client, orgId]
|
|
317
|
+
);
|
|
318
|
+
const removeMember = (0, import_react4.useCallback)(
|
|
319
|
+
async (userId) => {
|
|
320
|
+
setError(null);
|
|
321
|
+
try {
|
|
322
|
+
await client.removeMember(orgId, userId);
|
|
323
|
+
await refresh();
|
|
324
|
+
} catch (err) {
|
|
325
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
[client, orgId, refresh]
|
|
329
|
+
);
|
|
330
|
+
const updateRole = (0, import_react4.useCallback)(
|
|
331
|
+
async (userId, role) => {
|
|
332
|
+
setError(null);
|
|
333
|
+
try {
|
|
334
|
+
await client.updateMemberRole(orgId, userId, role);
|
|
335
|
+
await refresh();
|
|
336
|
+
} catch (err) {
|
|
337
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
338
|
+
}
|
|
339
|
+
},
|
|
340
|
+
[client, orgId, refresh]
|
|
341
|
+
);
|
|
342
|
+
return { members, isLoading, refresh, invite, removeMember, updateRole, error };
|
|
343
|
+
}
|
|
344
|
+
function usePermission(requiredRole) {
|
|
345
|
+
const { client } = useOrgContext();
|
|
346
|
+
const snapshotRef = (0, import_react4.useRef)(checkPermission(client.activeRole, requiredRole));
|
|
347
|
+
const subscribe = (0, import_react4.useCallback)(
|
|
348
|
+
(onStoreChange) => {
|
|
349
|
+
return client.onOrgChange(() => {
|
|
350
|
+
const newValue = checkPermission(client.activeRole, requiredRole);
|
|
351
|
+
if (newValue !== snapshotRef.current) {
|
|
352
|
+
snapshotRef.current = newValue;
|
|
353
|
+
onStoreChange();
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
},
|
|
357
|
+
[client, requiredRole]
|
|
358
|
+
);
|
|
359
|
+
const getSnapshot = (0, import_react4.useCallback)(() => snapshotRef.current, []);
|
|
360
|
+
return (0, import_react4.useSyncExternalStore)(subscribe, getSnapshot);
|
|
361
|
+
}
|
|
362
|
+
var ROLE_LEVELS = {
|
|
363
|
+
viewer: 10,
|
|
364
|
+
billing: 15,
|
|
365
|
+
member: 20,
|
|
366
|
+
admin: 30,
|
|
367
|
+
owner: 40
|
|
368
|
+
};
|
|
369
|
+
function checkPermission(currentRole, requiredRole) {
|
|
370
|
+
if (!currentRole) return false;
|
|
371
|
+
const currentLevel = ROLE_LEVELS[currentRole] ?? 0;
|
|
372
|
+
const requiredLevel = ROLE_LEVELS[requiredRole] ?? 0;
|
|
373
|
+
return currentLevel >= requiredLevel;
|
|
374
|
+
}
|
|
198
375
|
// Annotate the CommonJS export names for ESM import in node:
|
|
199
376
|
0 && (module.exports = {
|
|
200
377
|
AuthContext,
|
|
201
378
|
AuthProvider,
|
|
379
|
+
OrgContext,
|
|
202
380
|
useAuth,
|
|
203
381
|
useAuthStatus,
|
|
204
|
-
useCurrentUser
|
|
382
|
+
useCurrentUser,
|
|
383
|
+
useOrg,
|
|
384
|
+
useOrgMembers,
|
|
385
|
+
usePermission
|
|
205
386
|
});
|
|
206
387
|
//# sourceMappingURL=react.cjs.map
|