@korajs/auth 0.5.0 → 0.6.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,203 @@
1
+ // src/bindings/create-auth-session.ts
2
+ function createAuthSession(client) {
3
+ let state = client.state;
4
+ let isLoading = true;
5
+ let initError = null;
6
+ let lastError = null;
7
+ const listeners = /* @__PURE__ */ new Set();
8
+ let snapshot = buildSnapshot2();
9
+ const refreshSnapshot = () => {
10
+ snapshot = buildSnapshot2();
11
+ };
12
+ const notify = () => {
13
+ refreshSnapshot();
14
+ for (const listener of listeners) {
15
+ listener();
16
+ }
17
+ };
18
+ function buildSnapshot2() {
19
+ return {
20
+ state,
21
+ user: client.currentUser,
22
+ isAuthenticated: state === "authenticated",
23
+ isLoading,
24
+ initError,
25
+ error: lastError
26
+ };
27
+ }
28
+ const captureError = (error) => {
29
+ lastError = error instanceof Error ? error.message : String(error);
30
+ notify();
31
+ };
32
+ const run = async (action) => {
33
+ lastError = null;
34
+ try {
35
+ await action();
36
+ } catch (error) {
37
+ captureError(error);
38
+ }
39
+ };
40
+ const runWithResult = async (action) => {
41
+ lastError = null;
42
+ try {
43
+ return await action();
44
+ } catch (error) {
45
+ captureError(error);
46
+ return null;
47
+ }
48
+ };
49
+ const unsubscribeAuth = client.onAuthChange((nextState) => {
50
+ state = nextState;
51
+ notify();
52
+ });
53
+ void client.initialize().then(() => {
54
+ state = client.state;
55
+ isLoading = false;
56
+ notify();
57
+ }).catch((error) => {
58
+ initError = error instanceof Error ? error : new Error(String(error));
59
+ isLoading = false;
60
+ notify();
61
+ });
62
+ return {
63
+ client,
64
+ getSnapshot: () => snapshot,
65
+ subscribe(listener) {
66
+ listeners.add(listener);
67
+ return () => {
68
+ listeners.delete(listener);
69
+ };
70
+ },
71
+ signUp: (params) => run(async () => {
72
+ await client.signUp(params);
73
+ }),
74
+ signIn: (params) => run(async () => {
75
+ await client.signIn(params);
76
+ }),
77
+ signInWithOAuth: async (provider, options) => {
78
+ lastError = null;
79
+ try {
80
+ return await client.signInWithOAuth(provider, options);
81
+ } catch (error) {
82
+ captureError(error);
83
+ throw error instanceof Error ? error : new Error(String(error));
84
+ }
85
+ },
86
+ completeOAuthSignIn: (provider, params) => run(async () => {
87
+ await client.completeOAuthSignIn(provider, params);
88
+ }),
89
+ getOAuthAuthorizationUrl: async (provider, options) => {
90
+ lastError = null;
91
+ try {
92
+ return await client.getOAuthAuthorizationUrl(provider, options);
93
+ } catch (error) {
94
+ captureError(error);
95
+ throw error instanceof Error ? error : new Error(String(error));
96
+ }
97
+ },
98
+ linkOAuth: (provider, params) => runWithResult(async () => client.linkOAuth(provider, params)),
99
+ listLinkedAccounts: () => runWithResult(async () => client.listLinkedAccounts()).then((value) => value ?? []),
100
+ unlinkOAuth: (provider) => run(async () => {
101
+ await client.unlinkOAuth(provider);
102
+ }),
103
+ signOut: () => run(async () => {
104
+ await client.signOut();
105
+ }),
106
+ destroy() {
107
+ unsubscribeAuth();
108
+ listeners.clear();
109
+ }
110
+ };
111
+ }
112
+
113
+ // src/bindings/create-org-session.ts
114
+ var ROLE_LEVELS = {
115
+ viewer: 10,
116
+ billing: 15,
117
+ member: 20,
118
+ admin: 30,
119
+ owner: 40
120
+ };
121
+ function checkOrgPermission(currentRole, requiredRole) {
122
+ if (!currentRole) return false;
123
+ const currentLevel = ROLE_LEVELS[currentRole] ?? 0;
124
+ const requiredLevel = ROLE_LEVELS[requiredRole] ?? 0;
125
+ return currentLevel >= requiredLevel;
126
+ }
127
+ function createOrgSession(client) {
128
+ let snapshot = buildSnapshot(client);
129
+ const listeners = /* @__PURE__ */ new Set();
130
+ const notify = () => {
131
+ snapshot = buildSnapshot(client);
132
+ for (const listener of listeners) {
133
+ listener();
134
+ }
135
+ };
136
+ const unsubscribeOrgChange = client.onOrgChange(notify);
137
+ return {
138
+ client,
139
+ getSnapshot: () => snapshot,
140
+ subscribe(listener) {
141
+ listeners.add(listener);
142
+ return () => {
143
+ listeners.delete(listener);
144
+ };
145
+ },
146
+ checkPermission(requiredRole) {
147
+ return checkOrgPermission(snapshot.role, requiredRole);
148
+ },
149
+ destroy() {
150
+ unsubscribeOrgChange();
151
+ listeners.clear();
152
+ }
153
+ };
154
+ }
155
+ function buildSnapshot(client) {
156
+ return {
157
+ orgId: client.activeOrgId,
158
+ org: client.activeOrg,
159
+ role: client.activeRole
160
+ };
161
+ }
162
+ function createOrgMembersActions(client, orgId, onError) {
163
+ return {
164
+ async refresh() {
165
+ await client.listMembers(orgId);
166
+ },
167
+ async invite(email, role) {
168
+ try {
169
+ return await client.inviteMember(orgId, { email, role });
170
+ } catch (error) {
171
+ const message = error instanceof Error ? error.message : String(error);
172
+ onError(message);
173
+ throw error;
174
+ }
175
+ },
176
+ async removeMember(userId) {
177
+ try {
178
+ await client.removeMember(orgId, userId);
179
+ } catch (error) {
180
+ onError(error instanceof Error ? error.message : String(error));
181
+ }
182
+ },
183
+ async updateRole(userId, role) {
184
+ try {
185
+ await client.updateMemberRole(orgId, userId, role);
186
+ } catch (error) {
187
+ onError(error instanceof Error ? error.message : String(error));
188
+ }
189
+ }
190
+ };
191
+ }
192
+ async function loadOrgMembers(client, orgId) {
193
+ return client.listMembers(orgId);
194
+ }
195
+
196
+ export {
197
+ createAuthSession,
198
+ checkOrgPermission,
199
+ createOrgSession,
200
+ createOrgMembersActions,
201
+ loadOrgMembers
202
+ };
203
+ //# sourceMappingURL=chunk-7OXBRSJL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/bindings/create-auth-session.ts","../src/bindings/create-org-session.ts"],"sourcesContent":["import type {\n\tAuthClient,\n\tAuthState,\n\tAuthUser,\n\tLinkedOAuthAccount,\n\tOAuthAuthorizationOptions,\n\tOAuthAuthorizationResult,\n\tOAuthCallbackParams,\n} from '../client/auth-client'\n\nexport interface AuthSessionSnapshot {\n\tstate: AuthState\n\tuser: AuthUser | null\n\tisAuthenticated: boolean\n\tisLoading: boolean\n\tinitError: Error | null\n\terror: string | null\n}\n\nexport interface AuthSession {\n\treadonly client: AuthClient\n\tgetSnapshot(): AuthSessionSnapshot\n\tsubscribe(listener: () => void): () => void\n\tsignUp(params: {\n\t\temail: string\n\t\tpassword: string\n\t\tname?: string\n\t\tdeviceId?: string\n\t\tdevicePublicKey?: string\n\t}): Promise<void>\n\tsignIn(params: {\n\t\temail: string\n\t\tpassword: string\n\t\tdeviceId?: string\n\t\tdevicePublicKey?: string\n\t}): Promise<void>\n\tsignInWithOAuth(\n\t\tprovider: string,\n\t\toptions?: OAuthAuthorizationOptions,\n\t): Promise<OAuthAuthorizationResult>\n\tcompleteOAuthSignIn(provider: string, params: OAuthCallbackParams): Promise<void>\n\tgetOAuthAuthorizationUrl(\n\t\tprovider: string,\n\t\toptions?: OAuthAuthorizationOptions,\n\t): Promise<OAuthAuthorizationResult>\n\tlinkOAuth(provider: string, params: OAuthCallbackParams): Promise<LinkedOAuthAccount | null>\n\tlistLinkedAccounts(): Promise<LinkedOAuthAccount[]>\n\tunlinkOAuth(provider: string): Promise<void>\n\tsignOut(): Promise<void>\n\tdestroy(): void\n}\n\n/**\n * Framework-agnostic auth session: initialization, reactive snapshot, and client methods.\n */\nexport function createAuthSession(client: AuthClient): AuthSession {\n\tlet state: AuthState = client.state\n\tlet isLoading = true\n\tlet initError: Error | null = null\n\tlet lastError: string | null = null\n\n\tconst listeners = new Set<() => void>()\n\tlet snapshot = buildSnapshot()\n\n\tconst refreshSnapshot = (): void => {\n\t\tsnapshot = buildSnapshot()\n\t}\n\n\tconst notify = (): void => {\n\t\trefreshSnapshot()\n\t\tfor (const listener of listeners) {\n\t\t\tlistener()\n\t\t}\n\t}\n\n\tfunction buildSnapshot(): AuthSessionSnapshot {\n\t\treturn {\n\t\t\tstate,\n\t\t\tuser: client.currentUser,\n\t\t\tisAuthenticated: state === 'authenticated',\n\t\t\tisLoading,\n\t\t\tinitError,\n\t\t\terror: lastError,\n\t\t}\n\t}\n\n\tconst captureError = (error: unknown): void => {\n\t\tlastError = error instanceof Error ? error.message : String(error)\n\t\tnotify()\n\t}\n\n\tconst run = async (action: () => Promise<void>): Promise<void> => {\n\t\tlastError = null\n\t\ttry {\n\t\t\tawait action()\n\t\t} catch (error) {\n\t\t\tcaptureError(error)\n\t\t}\n\t}\n\n\tconst runWithResult = async <T>(action: () => Promise<T>): Promise<T | null> => {\n\t\tlastError = null\n\t\ttry {\n\t\t\treturn await action()\n\t\t} catch (error) {\n\t\t\tcaptureError(error)\n\t\t\treturn null\n\t\t}\n\t}\n\n\tconst unsubscribeAuth = client.onAuthChange((nextState) => {\n\t\tstate = nextState\n\t\tnotify()\n\t})\n\n\tvoid client\n\t\t.initialize()\n\t\t.then(() => {\n\t\t\tstate = client.state\n\t\t\tisLoading = false\n\t\t\tnotify()\n\t\t})\n\t\t.catch((error: unknown) => {\n\t\t\tinitError = error instanceof Error ? error : new Error(String(error))\n\t\t\tisLoading = false\n\t\t\tnotify()\n\t\t})\n\n\treturn {\n\t\tclient,\n\t\tgetSnapshot: () => snapshot,\n\t\tsubscribe(listener) {\n\t\t\tlisteners.add(listener)\n\t\t\treturn () => {\n\t\t\t\tlisteners.delete(listener)\n\t\t\t}\n\t\t},\n\t\tsignUp: (params) =>\n\t\t\trun(async () => {\n\t\t\t\tawait client.signUp(params)\n\t\t\t}),\n\t\tsignIn: (params) =>\n\t\t\trun(async () => {\n\t\t\t\tawait client.signIn(params)\n\t\t\t}),\n\t\tsignInWithOAuth: async (provider, options) => {\n\t\t\tlastError = null\n\t\t\ttry {\n\t\t\t\treturn await client.signInWithOAuth(provider, options)\n\t\t\t} catch (error) {\n\t\t\t\tcaptureError(error)\n\t\t\t\tthrow error instanceof Error ? error : new Error(String(error))\n\t\t\t}\n\t\t},\n\t\tcompleteOAuthSignIn: (provider, params) =>\n\t\t\trun(async () => {\n\t\t\t\tawait client.completeOAuthSignIn(provider, params)\n\t\t\t}),\n\t\tgetOAuthAuthorizationUrl: async (provider, options) => {\n\t\t\tlastError = null\n\t\t\ttry {\n\t\t\t\treturn await client.getOAuthAuthorizationUrl(provider, options)\n\t\t\t} catch (error) {\n\t\t\t\tcaptureError(error)\n\t\t\t\tthrow error instanceof Error ? error : new Error(String(error))\n\t\t\t}\n\t\t},\n\t\tlinkOAuth: (provider, params) =>\n\t\t\trunWithResult(async () => client.linkOAuth(provider, params)),\n\t\tlistLinkedAccounts: () =>\n\t\t\trunWithResult(async () => client.listLinkedAccounts()).then((value) => value ?? []),\n\t\tunlinkOAuth: (provider) =>\n\t\t\trun(async () => {\n\t\t\t\tawait client.unlinkOAuth(provider)\n\t\t\t}),\n\t\tsignOut: () =>\n\t\t\trun(async () => {\n\t\t\t\tawait client.signOut()\n\t\t\t}),\n\t\tdestroy() {\n\t\t\tunsubscribeAuth()\n\t\t\tlisteners.clear()\n\t\t},\n\t}\n}\n","import type {\n\tClientInvitation,\n\tClientMembership,\n\tClientOrganization,\n\tOrgClient,\n} from '../client/org-client'\n\nexport interface OrgSnapshot {\n\torgId: string | null\n\torg: ClientOrganization | null\n\trole: string | null\n}\n\nexport interface OrgSession {\n\treadonly client: OrgClient\n\tgetSnapshot(): OrgSnapshot\n\tsubscribe(listener: () => void): () => void\n\tcheckPermission(requiredRole: string): boolean\n\tdestroy(): void\n}\n\nconst ROLE_LEVELS: Record<string, number> = {\n\tviewer: 10,\n\tbilling: 15,\n\tmember: 20,\n\tadmin: 30,\n\towner: 40,\n}\n\nexport function checkOrgPermission(currentRole: string | null, requiredRole: string): boolean {\n\tif (!currentRole) return false\n\tconst currentLevel = ROLE_LEVELS[currentRole] ?? 0\n\tconst requiredLevel = ROLE_LEVELS[requiredRole] ?? 0\n\treturn currentLevel >= requiredLevel\n}\n\n/**\n * Framework-agnostic org session with reactive snapshot subscription.\n */\nexport function createOrgSession(client: OrgClient): OrgSession {\n\tlet snapshot = buildSnapshot(client)\n\tconst listeners = new Set<() => void>()\n\n\tconst notify = (): void => {\n\t\tsnapshot = buildSnapshot(client)\n\t\tfor (const listener of listeners) {\n\t\t\tlistener()\n\t\t}\n\t}\n\n\tconst unsubscribeOrgChange = client.onOrgChange(notify)\n\n\treturn {\n\t\tclient,\n\t\tgetSnapshot: () => snapshot,\n\t\tsubscribe(listener: () => void): () => void {\n\t\t\tlisteners.add(listener)\n\t\t\treturn () => {\n\t\t\t\tlisteners.delete(listener)\n\t\t\t}\n\t\t},\n\t\tcheckPermission(requiredRole: string): boolean {\n\t\t\treturn checkOrgPermission(snapshot.role, requiredRole)\n\t\t},\n\t\tdestroy(): void {\n\t\t\tunsubscribeOrgChange()\n\t\t\tlisteners.clear()\n\t\t},\n\t}\n}\n\nfunction buildSnapshot(client: OrgClient): OrgSnapshot {\n\treturn {\n\t\torgId: client.activeOrgId,\n\t\torg: client.activeOrg,\n\t\trole: client.activeRole,\n\t}\n}\n\nexport interface UseOrgMembersActions {\n\trefresh: () => Promise<void>\n\tinvite: (email: string, role: string) => Promise<ClientInvitation>\n\tremoveMember: (userId: string) => Promise<void>\n\tupdateRole: (userId: string, role: string) => Promise<void>\n}\n\n/**\n * Shared org member management actions (loading state remains framework-specific).\n */\nexport function createOrgMembersActions(\n\tclient: OrgClient,\n\torgId: string,\n\tonError: (message: string) => void,\n): UseOrgMembersActions {\n\treturn {\n\t\tasync refresh(): Promise<void> {\n\t\t\tawait client.listMembers(orgId)\n\t\t},\n\t\tasync invite(email: string, role: string): Promise<ClientInvitation> {\n\t\t\ttry {\n\t\t\t\treturn await client.inviteMember(orgId, { email, role })\n\t\t\t} catch (error) {\n\t\t\t\tconst message = error instanceof Error ? error.message : String(error)\n\t\t\t\tonError(message)\n\t\t\t\tthrow error\n\t\t\t}\n\t\t},\n\t\tasync removeMember(userId: string): Promise<void> {\n\t\t\ttry {\n\t\t\t\tawait client.removeMember(orgId, userId)\n\t\t\t} catch (error) {\n\t\t\t\tonError(error instanceof Error ? error.message : String(error))\n\t\t\t}\n\t\t},\n\t\tasync updateRole(userId: string, role: string): Promise<void> {\n\t\t\ttry {\n\t\t\t\tawait client.updateMemberRole(orgId, userId, role)\n\t\t\t} catch (error) {\n\t\t\t\tonError(error instanceof Error ? error.message : String(error))\n\t\t\t}\n\t\t},\n\t}\n}\n\nexport async function loadOrgMembers(\n\tclient: OrgClient,\n\torgId: string,\n): Promise<ClientMembership[]> {\n\treturn client.listMembers(orgId)\n}\n"],"mappings":"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","names":["buildSnapshot"]}
@@ -490,6 +490,45 @@ declare class AuthClient {
490
490
  private request;
491
491
  }
492
492
 
493
+ interface AuthSessionSnapshot {
494
+ state: AuthState;
495
+ user: AuthUser | null;
496
+ isAuthenticated: boolean;
497
+ isLoading: boolean;
498
+ initError: Error | null;
499
+ error: string | null;
500
+ }
501
+ interface AuthSession {
502
+ readonly client: AuthClient;
503
+ getSnapshot(): AuthSessionSnapshot;
504
+ subscribe(listener: () => void): () => void;
505
+ signUp(params: {
506
+ email: string;
507
+ password: string;
508
+ name?: string;
509
+ deviceId?: string;
510
+ devicePublicKey?: string;
511
+ }): Promise<void>;
512
+ signIn(params: {
513
+ email: string;
514
+ password: string;
515
+ deviceId?: string;
516
+ devicePublicKey?: string;
517
+ }): Promise<void>;
518
+ signInWithOAuth(provider: string, options?: OAuthAuthorizationOptions): Promise<OAuthAuthorizationResult>;
519
+ completeOAuthSignIn(provider: string, params: OAuthCallbackParams): Promise<void>;
520
+ getOAuthAuthorizationUrl(provider: string, options?: OAuthAuthorizationOptions): Promise<OAuthAuthorizationResult>;
521
+ linkOAuth(provider: string, params: OAuthCallbackParams): Promise<LinkedOAuthAccount | null>;
522
+ listLinkedAccounts(): Promise<LinkedOAuthAccount[]>;
523
+ unlinkOAuth(provider: string): Promise<void>;
524
+ signOut(): Promise<void>;
525
+ destroy(): void;
526
+ }
527
+ /**
528
+ * Framework-agnostic auth session: initialization, reactive snapshot, and client methods.
529
+ */
530
+ declare function createAuthSession(client: AuthClient): AuthSession;
531
+
493
532
  /**
494
533
  * Organization info returned by the server.
495
534
  */
@@ -662,4 +701,22 @@ declare class OrgClient {
662
701
  private request;
663
702
  }
664
703
 
665
- export { type AuthClientConfig as A, type ClientInvitation as C, type DeviceKeyStore as D, InMemoryDeviceKeyStore as I, type LinkedOAuthAccount as L, type OAuthAuthorizationOptions as O, type PersistentDeviceIdentityOptions as P, type AuthTokenStorage as a, type AuthKeyValueStorage as b, type AuthDeviceIdentityProvider as c, AuthClient as d, type AuthState as e, type AuthDeviceIdentity as f, AuthDeviceIdentityError as g, AuthError as h, type AuthTokenStorageOptions as i, type AuthUser as j, type ClientMembership as k, type ClientOrganization as l, DeviceKeyStoreError as m, IndexedDBDeviceKeyStore as n, type OAuthAuthorizationResult as o, type OAuthCallbackParams as p, OrgClient as q, type OrgClientConfig as r, OrgClientError as s, createAuthTokenStorage as t, createDeviceKeyStore as u, createMemoryAuthTokenStorage as v, createPersistentDeviceIdentity as w, createWebStorageAuthTokenStorage as x };
704
+ interface OrgSnapshot {
705
+ orgId: string | null;
706
+ org: ClientOrganization | null;
707
+ role: string | null;
708
+ }
709
+ interface OrgSession {
710
+ readonly client: OrgClient;
711
+ getSnapshot(): OrgSnapshot;
712
+ subscribe(listener: () => void): () => void;
713
+ checkPermission(requiredRole: string): boolean;
714
+ destroy(): void;
715
+ }
716
+ declare function checkOrgPermission(currentRole: string | null, requiredRole: string): boolean;
717
+ /**
718
+ * Framework-agnostic org session with reactive snapshot subscription.
719
+ */
720
+ declare function createOrgSession(client: OrgClient): OrgSession;
721
+
722
+ export { type AuthClientConfig as A, createDeviceKeyStore as B, type ClientInvitation as C, type DeviceKeyStore as D, createMemoryAuthTokenStorage as E, createOrgSession as F, createPersistentDeviceIdentity as G, createWebStorageAuthTokenStorage as H, InMemoryDeviceKeyStore as I, type LinkedOAuthAccount as L, type OAuthAuthorizationOptions as O, type PersistentDeviceIdentityOptions as P, type AuthTokenStorage as a, type AuthKeyValueStorage as b, type AuthDeviceIdentityProvider as c, AuthClient as d, type AuthState as e, type AuthDeviceIdentity as f, AuthDeviceIdentityError as g, AuthError as h, type AuthSession as i, type AuthSessionSnapshot as j, type AuthTokenStorageOptions as k, type AuthUser as l, type ClientMembership as m, type ClientOrganization as n, DeviceKeyStoreError as o, IndexedDBDeviceKeyStore as p, type OAuthAuthorizationResult as q, type OAuthCallbackParams as r, OrgClient as s, type OrgClientConfig as t, OrgClientError as u, type OrgSession as v, type OrgSnapshot as w, checkOrgPermission as x, createAuthSession as y, createAuthTokenStorage as z };
@@ -490,6 +490,45 @@ declare class AuthClient {
490
490
  private request;
491
491
  }
492
492
 
493
+ interface AuthSessionSnapshot {
494
+ state: AuthState;
495
+ user: AuthUser | null;
496
+ isAuthenticated: boolean;
497
+ isLoading: boolean;
498
+ initError: Error | null;
499
+ error: string | null;
500
+ }
501
+ interface AuthSession {
502
+ readonly client: AuthClient;
503
+ getSnapshot(): AuthSessionSnapshot;
504
+ subscribe(listener: () => void): () => void;
505
+ signUp(params: {
506
+ email: string;
507
+ password: string;
508
+ name?: string;
509
+ deviceId?: string;
510
+ devicePublicKey?: string;
511
+ }): Promise<void>;
512
+ signIn(params: {
513
+ email: string;
514
+ password: string;
515
+ deviceId?: string;
516
+ devicePublicKey?: string;
517
+ }): Promise<void>;
518
+ signInWithOAuth(provider: string, options?: OAuthAuthorizationOptions): Promise<OAuthAuthorizationResult>;
519
+ completeOAuthSignIn(provider: string, params: OAuthCallbackParams): Promise<void>;
520
+ getOAuthAuthorizationUrl(provider: string, options?: OAuthAuthorizationOptions): Promise<OAuthAuthorizationResult>;
521
+ linkOAuth(provider: string, params: OAuthCallbackParams): Promise<LinkedOAuthAccount | null>;
522
+ listLinkedAccounts(): Promise<LinkedOAuthAccount[]>;
523
+ unlinkOAuth(provider: string): Promise<void>;
524
+ signOut(): Promise<void>;
525
+ destroy(): void;
526
+ }
527
+ /**
528
+ * Framework-agnostic auth session: initialization, reactive snapshot, and client methods.
529
+ */
530
+ declare function createAuthSession(client: AuthClient): AuthSession;
531
+
493
532
  /**
494
533
  * Organization info returned by the server.
495
534
  */
@@ -662,4 +701,22 @@ declare class OrgClient {
662
701
  private request;
663
702
  }
664
703
 
665
- export { type AuthClientConfig as A, type ClientInvitation as C, type DeviceKeyStore as D, InMemoryDeviceKeyStore as I, type LinkedOAuthAccount as L, type OAuthAuthorizationOptions as O, type PersistentDeviceIdentityOptions as P, type AuthTokenStorage as a, type AuthKeyValueStorage as b, type AuthDeviceIdentityProvider as c, AuthClient as d, type AuthState as e, type AuthDeviceIdentity as f, AuthDeviceIdentityError as g, AuthError as h, type AuthTokenStorageOptions as i, type AuthUser as j, type ClientMembership as k, type ClientOrganization as l, DeviceKeyStoreError as m, IndexedDBDeviceKeyStore as n, type OAuthAuthorizationResult as o, type OAuthCallbackParams as p, OrgClient as q, type OrgClientConfig as r, OrgClientError as s, createAuthTokenStorage as t, createDeviceKeyStore as u, createMemoryAuthTokenStorage as v, createPersistentDeviceIdentity as w, createWebStorageAuthTokenStorage as x };
704
+ interface OrgSnapshot {
705
+ orgId: string | null;
706
+ org: ClientOrganization | null;
707
+ role: string | null;
708
+ }
709
+ interface OrgSession {
710
+ readonly client: OrgClient;
711
+ getSnapshot(): OrgSnapshot;
712
+ subscribe(listener: () => void): () => void;
713
+ checkPermission(requiredRole: string): boolean;
714
+ destroy(): void;
715
+ }
716
+ declare function checkOrgPermission(currentRole: string | null, requiredRole: string): boolean;
717
+ /**
718
+ * Framework-agnostic org session with reactive snapshot subscription.
719
+ */
720
+ declare function createOrgSession(client: OrgClient): OrgSession;
721
+
722
+ export { type AuthClientConfig as A, createDeviceKeyStore as B, type ClientInvitation as C, type DeviceKeyStore as D, createMemoryAuthTokenStorage as E, createOrgSession as F, createPersistentDeviceIdentity as G, createWebStorageAuthTokenStorage as H, InMemoryDeviceKeyStore as I, type LinkedOAuthAccount as L, type OAuthAuthorizationOptions as O, type PersistentDeviceIdentityOptions as P, type AuthTokenStorage as a, type AuthKeyValueStorage as b, type AuthDeviceIdentityProvider as c, AuthClient as d, type AuthState as e, type AuthDeviceIdentity as f, AuthDeviceIdentityError as g, AuthError as h, type AuthSession as i, type AuthSessionSnapshot as j, type AuthTokenStorageOptions as k, type AuthUser as l, type ClientMembership as m, type ClientOrganization as n, DeviceKeyStoreError as o, IndexedDBDeviceKeyStore as p, type OAuthAuthorizationResult as q, type OAuthCallbackParams as r, OrgClient as s, type OrgClientConfig as t, OrgClientError as u, type OrgSession as v, type OrgSnapshot as w, checkOrgPermission as x, createAuthSession as y, createAuthTokenStorage as z };
package/dist/index.cjs CHANGED
@@ -41,12 +41,15 @@ __export(index_exports, {
41
41
  PasskeyUnsupportedError: () => PasskeyUnsupportedError,
42
42
  TokenStore: () => TokenStore,
43
43
  authenticateWithPasskey: () => authenticateWithPasskey,
44
+ checkOrgPermission: () => checkOrgPermission,
44
45
  computePublicKeyThumbprint: () => computePublicKeyThumbprint,
46
+ createAuthSession: () => createAuthSession,
45
47
  createAuthTokenStorage: () => createAuthTokenStorage,
46
48
  createDeviceKeyStore: () => createDeviceKeyStore,
47
49
  createKoraAuth: () => createKoraAuth,
48
50
  createKoraAuthSync: () => createKoraAuthSync,
49
51
  createMemoryAuthTokenStorage: () => createMemoryAuthTokenStorage,
52
+ createOrgSession: () => createOrgSession,
50
53
  createPasskeyCredential: () => createPasskeyCredential,
51
54
  createPersistentDeviceIdentity: () => createPersistentDeviceIdentity,
52
55
  createWebStorageAuthTokenStorage: () => createWebStorageAuthTokenStorage,
@@ -1243,6 +1246,168 @@ function createKoraAuthSync(options) {
1243
1246
  return binding;
1244
1247
  }
1245
1248
 
1249
+ // src/bindings/create-auth-session.ts
1250
+ function createAuthSession(client) {
1251
+ let state = client.state;
1252
+ let isLoading = true;
1253
+ let initError = null;
1254
+ let lastError = null;
1255
+ const listeners = /* @__PURE__ */ new Set();
1256
+ let snapshot = buildSnapshot2();
1257
+ const refreshSnapshot = () => {
1258
+ snapshot = buildSnapshot2();
1259
+ };
1260
+ const notify = () => {
1261
+ refreshSnapshot();
1262
+ for (const listener of listeners) {
1263
+ listener();
1264
+ }
1265
+ };
1266
+ function buildSnapshot2() {
1267
+ return {
1268
+ state,
1269
+ user: client.currentUser,
1270
+ isAuthenticated: state === "authenticated",
1271
+ isLoading,
1272
+ initError,
1273
+ error: lastError
1274
+ };
1275
+ }
1276
+ const captureError = (error) => {
1277
+ lastError = error instanceof Error ? error.message : String(error);
1278
+ notify();
1279
+ };
1280
+ const run = async (action) => {
1281
+ lastError = null;
1282
+ try {
1283
+ await action();
1284
+ } catch (error) {
1285
+ captureError(error);
1286
+ }
1287
+ };
1288
+ const runWithResult = async (action) => {
1289
+ lastError = null;
1290
+ try {
1291
+ return await action();
1292
+ } catch (error) {
1293
+ captureError(error);
1294
+ return null;
1295
+ }
1296
+ };
1297
+ const unsubscribeAuth = client.onAuthChange((nextState) => {
1298
+ state = nextState;
1299
+ notify();
1300
+ });
1301
+ void client.initialize().then(() => {
1302
+ state = client.state;
1303
+ isLoading = false;
1304
+ notify();
1305
+ }).catch((error) => {
1306
+ initError = error instanceof Error ? error : new Error(String(error));
1307
+ isLoading = false;
1308
+ notify();
1309
+ });
1310
+ return {
1311
+ client,
1312
+ getSnapshot: () => snapshot,
1313
+ subscribe(listener) {
1314
+ listeners.add(listener);
1315
+ return () => {
1316
+ listeners.delete(listener);
1317
+ };
1318
+ },
1319
+ signUp: (params) => run(async () => {
1320
+ await client.signUp(params);
1321
+ }),
1322
+ signIn: (params) => run(async () => {
1323
+ await client.signIn(params);
1324
+ }),
1325
+ signInWithOAuth: async (provider, options) => {
1326
+ lastError = null;
1327
+ try {
1328
+ return await client.signInWithOAuth(provider, options);
1329
+ } catch (error) {
1330
+ captureError(error);
1331
+ throw error instanceof Error ? error : new Error(String(error));
1332
+ }
1333
+ },
1334
+ completeOAuthSignIn: (provider, params) => run(async () => {
1335
+ await client.completeOAuthSignIn(provider, params);
1336
+ }),
1337
+ getOAuthAuthorizationUrl: async (provider, options) => {
1338
+ lastError = null;
1339
+ try {
1340
+ return await client.getOAuthAuthorizationUrl(provider, options);
1341
+ } catch (error) {
1342
+ captureError(error);
1343
+ throw error instanceof Error ? error : new Error(String(error));
1344
+ }
1345
+ },
1346
+ linkOAuth: (provider, params) => runWithResult(async () => client.linkOAuth(provider, params)),
1347
+ listLinkedAccounts: () => runWithResult(async () => client.listLinkedAccounts()).then((value) => value ?? []),
1348
+ unlinkOAuth: (provider) => run(async () => {
1349
+ await client.unlinkOAuth(provider);
1350
+ }),
1351
+ signOut: () => run(async () => {
1352
+ await client.signOut();
1353
+ }),
1354
+ destroy() {
1355
+ unsubscribeAuth();
1356
+ listeners.clear();
1357
+ }
1358
+ };
1359
+ }
1360
+
1361
+ // src/bindings/create-org-session.ts
1362
+ var ROLE_LEVELS = {
1363
+ viewer: 10,
1364
+ billing: 15,
1365
+ member: 20,
1366
+ admin: 30,
1367
+ owner: 40
1368
+ };
1369
+ function checkOrgPermission(currentRole, requiredRole) {
1370
+ if (!currentRole) return false;
1371
+ const currentLevel = ROLE_LEVELS[currentRole] ?? 0;
1372
+ const requiredLevel = ROLE_LEVELS[requiredRole] ?? 0;
1373
+ return currentLevel >= requiredLevel;
1374
+ }
1375
+ function createOrgSession(client) {
1376
+ let snapshot = buildSnapshot(client);
1377
+ const listeners = /* @__PURE__ */ new Set();
1378
+ const notify = () => {
1379
+ snapshot = buildSnapshot(client);
1380
+ for (const listener of listeners) {
1381
+ listener();
1382
+ }
1383
+ };
1384
+ const unsubscribeOrgChange = client.onOrgChange(notify);
1385
+ return {
1386
+ client,
1387
+ getSnapshot: () => snapshot,
1388
+ subscribe(listener) {
1389
+ listeners.add(listener);
1390
+ return () => {
1391
+ listeners.delete(listener);
1392
+ };
1393
+ },
1394
+ checkPermission(requiredRole) {
1395
+ return checkOrgPermission(snapshot.role, requiredRole);
1396
+ },
1397
+ destroy() {
1398
+ unsubscribeOrgChange();
1399
+ listeners.clear();
1400
+ }
1401
+ };
1402
+ }
1403
+ function buildSnapshot(client) {
1404
+ return {
1405
+ orgId: client.activeOrgId,
1406
+ org: client.activeOrg,
1407
+ role: client.activeRole
1408
+ };
1409
+ }
1410
+
1246
1411
  // src/client/org-client.ts
1247
1412
  var import_core6 = require("@korajs/core");
1248
1413
  var OrgClientError = class extends import_core6.KoraError {
@@ -2619,12 +2784,15 @@ function isEncryptedEnvelope(field) {
2619
2784
  PasskeyUnsupportedError,
2620
2785
  TokenStore,
2621
2786
  authenticateWithPasskey,
2787
+ checkOrgPermission,
2622
2788
  computePublicKeyThumbprint,
2789
+ createAuthSession,
2623
2790
  createAuthTokenStorage,
2624
2791
  createDeviceKeyStore,
2625
2792
  createKoraAuth,
2626
2793
  createKoraAuthSync,
2627
2794
  createMemoryAuthTokenStorage,
2795
+ createOrgSession,
2628
2796
  createPasskeyCredential,
2629
2797
  createPersistentDeviceIdentity,
2630
2798
  createWebStorageAuthTokenStorage,