@kavachos/react 0.0.3

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 KavachOS
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,130 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+
4
+ interface KavachUser {
5
+ id: string;
6
+ email?: string;
7
+ name?: string;
8
+ image?: string;
9
+ }
10
+ interface KavachSession {
11
+ token: string;
12
+ user: KavachUser;
13
+ expiresAt?: string;
14
+ }
15
+ interface KavachAgent {
16
+ id: string;
17
+ ownerId: string;
18
+ name: string;
19
+ type: "autonomous" | "delegated" | "service";
20
+ token: string;
21
+ permissions: KavachPermission[];
22
+ status: "active" | "revoked" | "expired";
23
+ expiresAt: string | null;
24
+ createdAt: string;
25
+ updatedAt: string;
26
+ }
27
+ interface KavachPermission {
28
+ resource: string;
29
+ actions: string[];
30
+ constraints?: {
31
+ maxCallsPerHour?: number;
32
+ allowedArgPatterns?: string[];
33
+ requireApproval?: boolean;
34
+ timeWindow?: {
35
+ start: string;
36
+ end: string;
37
+ };
38
+ ipAllowlist?: string[];
39
+ };
40
+ }
41
+ interface CreateAgentInput {
42
+ ownerId: string;
43
+ name: string;
44
+ type: "autonomous" | "delegated" | "service";
45
+ permissions: KavachPermission[];
46
+ expiresAt?: string;
47
+ metadata?: Record<string, unknown>;
48
+ }
49
+ type ActionResult<T = void> = {
50
+ success: true;
51
+ data: T;
52
+ } | {
53
+ success: false;
54
+ error: string;
55
+ };
56
+ interface KavachContextValue {
57
+ session: KavachSession | null;
58
+ user: KavachUser | null;
59
+ isLoading: boolean;
60
+ isAuthenticated: boolean;
61
+ signIn: (email: string, password: string) => Promise<ActionResult>;
62
+ signUp: (email: string, password: string, name?: string) => Promise<ActionResult>;
63
+ signOut: () => Promise<void>;
64
+ refresh: () => Promise<void>;
65
+ }
66
+
67
+ declare const KavachContext: react.Context<KavachContextValue | null>;
68
+ declare function useKavachContext(): KavachContextValue;
69
+ interface KavachProviderProps {
70
+ children: ReactNode;
71
+ /** Base path where KavachOS is mounted. Defaults to "/api/kavach". */
72
+ basePath?: string;
73
+ }
74
+ declare function KavachProvider({ children, basePath, }: KavachProviderProps): ReactNode;
75
+
76
+ /**
77
+ * Returns the current session, loading state, and a manual refresh function.
78
+ */
79
+ declare function useSession(): {
80
+ session: KavachSession | null;
81
+ isLoading: boolean;
82
+ refresh: () => Promise<void>;
83
+ };
84
+ /**
85
+ * Returns the current user, loading state, and authentication status.
86
+ */
87
+ declare function useUser(): {
88
+ user: KavachUser | null;
89
+ isLoading: boolean;
90
+ isAuthenticated: boolean;
91
+ };
92
+ /**
93
+ * Returns a signIn function plus local loading and error state.
94
+ */
95
+ declare function useSignIn(): {
96
+ signIn: (email: string, password: string) => Promise<ActionResult>;
97
+ isLoading: boolean;
98
+ error: string | null;
99
+ };
100
+ /**
101
+ * Returns a signUp function plus local loading and error state.
102
+ */
103
+ declare function useSignUp(): {
104
+ signUp: (email: string, password: string, name?: string) => Promise<ActionResult>;
105
+ isLoading: boolean;
106
+ error: string | null;
107
+ };
108
+ /**
109
+ * Returns a signOut function.
110
+ */
111
+ declare function useSignOut(): {
112
+ signOut: () => Promise<void>;
113
+ };
114
+ /**
115
+ * Manages agent identity records for a given user.
116
+ *
117
+ * Fetches the agent list and exposes create, revoke, and rotate helpers.
118
+ * All mutations refresh the list automatically.
119
+ */
120
+ declare function useAgents(basePath?: string): {
121
+ agents: KavachAgent[];
122
+ isLoading: boolean;
123
+ error: string | null;
124
+ load: () => Promise<void>;
125
+ create: (input: CreateAgentInput) => Promise<ActionResult<KavachAgent>>;
126
+ revoke: (agentId: string) => Promise<ActionResult>;
127
+ rotate: (agentId: string) => Promise<ActionResult<KavachAgent>>;
128
+ };
129
+
130
+ export { type ActionResult, type CreateAgentInput, type KavachAgent, KavachContext, type KavachContextValue, type KavachPermission, KavachProvider, type KavachProviderProps, type KavachSession, type KavachUser, useAgents, useKavachContext, useSession, useSignIn, useSignOut, useSignUp, useUser };
package/dist/index.js ADDED
@@ -0,0 +1,324 @@
1
+ // src/context.tsx
2
+ import { createContext, useCallback, useContext, useEffect, useState } from "react";
3
+ import { jsx } from "react/jsx-runtime";
4
+ var KavachContext = createContext(null);
5
+ function useKavachContext() {
6
+ const ctx = useContext(KavachContext);
7
+ if (!ctx) {
8
+ throw new Error("useKavachContext must be used inside <KavachProvider>");
9
+ }
10
+ return ctx;
11
+ }
12
+ function KavachProvider({
13
+ children,
14
+ basePath = "/api/kavach"
15
+ }) {
16
+ const [session, setSession] = useState(null);
17
+ const [isLoading, setIsLoading] = useState(true);
18
+ const base = basePath.replace(/\/$/, "");
19
+ const fetchSession = useCallback(async () => {
20
+ try {
21
+ const res = await fetch(`${base}/session`, {
22
+ credentials: "include"
23
+ });
24
+ if (res.ok) {
25
+ const json = await res.json();
26
+ setSession(json.data ?? null);
27
+ } else {
28
+ setSession(null);
29
+ }
30
+ } catch {
31
+ setSession(null);
32
+ }
33
+ }, [base]);
34
+ useEffect(() => {
35
+ if (typeof window === "undefined") {
36
+ setIsLoading(false);
37
+ return;
38
+ }
39
+ setIsLoading(true);
40
+ void fetchSession().finally(() => {
41
+ setIsLoading(false);
42
+ });
43
+ }, [fetchSession]);
44
+ const refresh = useCallback(async () => {
45
+ await fetchSession();
46
+ }, [fetchSession]);
47
+ const signIn = useCallback(
48
+ async (email, password) => {
49
+ try {
50
+ const res = await fetch(`${base}/sign-in/email`, {
51
+ method: "POST",
52
+ credentials: "include",
53
+ headers: { "Content-Type": "application/json" },
54
+ body: JSON.stringify({ email, password })
55
+ });
56
+ const json = await res.json();
57
+ if (!res.ok) {
58
+ const errBody = json;
59
+ return {
60
+ success: false,
61
+ error: errBody.error?.message ?? `Sign-in failed (${res.status})`
62
+ };
63
+ }
64
+ const okBody = json;
65
+ setSession(okBody.data);
66
+ return { success: true, data: void 0 };
67
+ } catch (err) {
68
+ return {
69
+ success: false,
70
+ error: err instanceof Error ? err.message : "Network error"
71
+ };
72
+ }
73
+ },
74
+ [base]
75
+ );
76
+ const signUp = useCallback(
77
+ async (email, password, name) => {
78
+ try {
79
+ const res = await fetch(`${base}/sign-up/email`, {
80
+ method: "POST",
81
+ credentials: "include",
82
+ headers: { "Content-Type": "application/json" },
83
+ body: JSON.stringify({ email, password, name })
84
+ });
85
+ const json = await res.json();
86
+ if (!res.ok) {
87
+ const errBody = json;
88
+ return {
89
+ success: false,
90
+ error: errBody.error?.message ?? `Sign-up failed (${res.status})`
91
+ };
92
+ }
93
+ const okBody = json;
94
+ setSession(okBody.data);
95
+ return { success: true, data: void 0 };
96
+ } catch (err) {
97
+ return {
98
+ success: false,
99
+ error: err instanceof Error ? err.message : "Network error"
100
+ };
101
+ }
102
+ },
103
+ [base]
104
+ );
105
+ const signOut = useCallback(async () => {
106
+ try {
107
+ await fetch(`${base}/sign-out`, {
108
+ method: "POST",
109
+ credentials: "include"
110
+ });
111
+ } finally {
112
+ setSession(null);
113
+ }
114
+ }, [base]);
115
+ const user = session?.user ?? null;
116
+ const value = {
117
+ session,
118
+ user,
119
+ isLoading,
120
+ isAuthenticated: session !== null,
121
+ signIn,
122
+ signUp,
123
+ signOut,
124
+ refresh
125
+ };
126
+ return /* @__PURE__ */ jsx(KavachContext.Provider, { value, children });
127
+ }
128
+
129
+ // src/hooks.ts
130
+ import { useCallback as useCallback2, useContext as useContext2, useState as useState2 } from "react";
131
+ function useRequiredContext(hookName) {
132
+ const ctx = useContext2(KavachContext);
133
+ if (!ctx) {
134
+ throw new Error(`${hookName} must be used inside <KavachProvider>`);
135
+ }
136
+ return ctx;
137
+ }
138
+ function useSession() {
139
+ const { session, isLoading, refresh } = useRequiredContext("useSession");
140
+ return { session, isLoading, refresh };
141
+ }
142
+ function useUser() {
143
+ const { user, isLoading, isAuthenticated } = useRequiredContext("useUser");
144
+ return { user, isLoading, isAuthenticated };
145
+ }
146
+ function useSignIn() {
147
+ const { signIn } = useRequiredContext("useSignIn");
148
+ const [isLoading, setIsLoading] = useState2(false);
149
+ const [error, setError] = useState2(null);
150
+ const execute = useCallback2(
151
+ async (email, password) => {
152
+ setIsLoading(true);
153
+ setError(null);
154
+ const result = await signIn(email, password);
155
+ if (!result.success) {
156
+ setError(result.error);
157
+ }
158
+ setIsLoading(false);
159
+ return result;
160
+ },
161
+ [signIn]
162
+ );
163
+ return { signIn: execute, isLoading, error };
164
+ }
165
+ function useSignUp() {
166
+ const { signUp } = useRequiredContext("useSignUp");
167
+ const [isLoading, setIsLoading] = useState2(false);
168
+ const [error, setError] = useState2(null);
169
+ const execute = useCallback2(
170
+ async (email, password, name) => {
171
+ setIsLoading(true);
172
+ setError(null);
173
+ const result = await signUp(email, password, name);
174
+ if (!result.success) {
175
+ setError(result.error);
176
+ }
177
+ setIsLoading(false);
178
+ return result;
179
+ },
180
+ [signUp]
181
+ );
182
+ return { signUp: execute, isLoading, error };
183
+ }
184
+ function useSignOut() {
185
+ const { signOut } = useRequiredContext("useSignOut");
186
+ return { signOut };
187
+ }
188
+ function extractError(body, fallback) {
189
+ if (body !== null && typeof body === "object" && "error" in body && body.error !== null && typeof body.error === "object" && "message" in body.error && typeof body.error.message === "string") {
190
+ return body.error.message;
191
+ }
192
+ return fallback;
193
+ }
194
+ function useAgents(basePath = "/api/kavach") {
195
+ const { user } = useRequiredContext("useAgents");
196
+ const base = basePath.replace(/\/$/, "");
197
+ const [agents, setAgents] = useState2([]);
198
+ const [isLoading, setIsLoading] = useState2(false);
199
+ const [error, setError] = useState2(null);
200
+ const load = useCallback2(async () => {
201
+ if (!user) {
202
+ setAgents([]);
203
+ return;
204
+ }
205
+ setIsLoading(true);
206
+ setError(null);
207
+ try {
208
+ const res = await fetch(`${base}/agents?userId=${encodeURIComponent(user.id)}`, {
209
+ credentials: "include"
210
+ });
211
+ const json = await res.json();
212
+ if (!res.ok) {
213
+ setError(extractError(json, `Failed to load agents (${res.status})`));
214
+ return;
215
+ }
216
+ setAgents(json.data);
217
+ } catch (err) {
218
+ setError(err instanceof Error ? err.message : "Network error");
219
+ } finally {
220
+ setIsLoading(false);
221
+ }
222
+ }, [base, user]);
223
+ const [loaded, setLoaded] = useState2(false);
224
+ if (user && !loaded) {
225
+ setLoaded(true);
226
+ void Promise.resolve().then(load);
227
+ }
228
+ if (!user && loaded) {
229
+ setLoaded(false);
230
+ setAgents([]);
231
+ }
232
+ const create = useCallback2(
233
+ async (input) => {
234
+ try {
235
+ const res = await fetch(`${base}/agents`, {
236
+ method: "POST",
237
+ credentials: "include",
238
+ headers: { "Content-Type": "application/json" },
239
+ body: JSON.stringify(input)
240
+ });
241
+ const json = await res.json();
242
+ if (!res.ok) {
243
+ return {
244
+ success: false,
245
+ error: extractError(json, `Failed to create agent (${res.status})`)
246
+ };
247
+ }
248
+ const agent = json.data;
249
+ await load();
250
+ return { success: true, data: agent };
251
+ } catch (err) {
252
+ return {
253
+ success: false,
254
+ error: err instanceof Error ? err.message : "Network error"
255
+ };
256
+ }
257
+ },
258
+ [base, load]
259
+ );
260
+ const revoke = useCallback2(
261
+ async (agentId) => {
262
+ try {
263
+ const res = await fetch(`${base}/agents/${encodeURIComponent(agentId)}`, {
264
+ method: "DELETE",
265
+ credentials: "include"
266
+ });
267
+ if (!res.ok && res.status !== 204) {
268
+ const json = await res.json().catch(() => null);
269
+ return {
270
+ success: false,
271
+ error: extractError(json, `Failed to revoke agent (${res.status})`)
272
+ };
273
+ }
274
+ await load();
275
+ return { success: true, data: void 0 };
276
+ } catch (err) {
277
+ return {
278
+ success: false,
279
+ error: err instanceof Error ? err.message : "Network error"
280
+ };
281
+ }
282
+ },
283
+ [base, load]
284
+ );
285
+ const rotate = useCallback2(
286
+ async (agentId) => {
287
+ try {
288
+ const res = await fetch(`${base}/agents/${encodeURIComponent(agentId)}/rotate`, {
289
+ method: "POST",
290
+ credentials: "include"
291
+ });
292
+ const json = await res.json();
293
+ if (!res.ok) {
294
+ return {
295
+ success: false,
296
+ error: extractError(json, `Failed to rotate agent token (${res.status})`)
297
+ };
298
+ }
299
+ const agent = json.data;
300
+ await load();
301
+ return { success: true, data: agent };
302
+ } catch (err) {
303
+ return {
304
+ success: false,
305
+ error: err instanceof Error ? err.message : "Network error"
306
+ };
307
+ }
308
+ },
309
+ [base, load]
310
+ );
311
+ return { agents, isLoading, error, load, create, revoke, rotate };
312
+ }
313
+ export {
314
+ KavachContext,
315
+ KavachProvider,
316
+ useAgents,
317
+ useKavachContext,
318
+ useSession,
319
+ useSignIn,
320
+ useSignOut,
321
+ useSignUp,
322
+ useUser
323
+ };
324
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/context.tsx","../src/hooks.ts"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { createContext, useCallback, useContext, useEffect, useState } from \"react\";\nimport type { ActionResult, KavachContextValue, KavachSession, KavachUser } from \"./types.js\";\n\n// ─── Context ──────────────────────────────────────────────────────────────────\n\nexport const KavachContext = createContext<KavachContextValue | null>(null);\n\nexport function useKavachContext(): KavachContextValue {\n\tconst ctx = useContext(KavachContext);\n\tif (!ctx) {\n\t\tthrow new Error(\"useKavachContext must be used inside <KavachProvider>\");\n\t}\n\treturn ctx;\n}\n\n// ─── Provider ─────────────────────────────────────────────────────────────────\n\nexport interface KavachProviderProps {\n\tchildren: ReactNode;\n\t/** Base path where KavachOS is mounted. Defaults to \"/api/kavach\". */\n\tbasePath?: string;\n}\n\nexport function KavachProvider({\n\tchildren,\n\tbasePath = \"/api/kavach\",\n}: KavachProviderProps): ReactNode {\n\tconst [session, setSession] = useState<KavachSession | null>(null);\n\tconst [isLoading, setIsLoading] = useState(true);\n\n\t// Strip trailing slash from basePath once\n\tconst base = basePath.replace(/\\/$/, \"\");\n\n\tconst fetchSession = useCallback(async (): Promise<void> => {\n\t\ttry {\n\t\t\tconst res = await fetch(`${base}/session`, {\n\t\t\t\tcredentials: \"include\",\n\t\t\t});\n\t\t\tif (res.ok) {\n\t\t\t\tconst json = (await res.json()) as { data?: KavachSession };\n\t\t\t\tsetSession(json.data ?? null);\n\t\t\t} else {\n\t\t\t\tsetSession(null);\n\t\t\t}\n\t\t} catch {\n\t\t\tsetSession(null);\n\t\t}\n\t}, [base]);\n\n\t// Fetch session on mount (only in browser)\n\tuseEffect(() => {\n\t\tif (typeof window === \"undefined\") {\n\t\t\tsetIsLoading(false);\n\t\t\treturn;\n\t\t}\n\t\tsetIsLoading(true);\n\t\tvoid fetchSession().finally(() => {\n\t\t\tsetIsLoading(false);\n\t\t});\n\t}, [fetchSession]);\n\n\tconst refresh = useCallback(async (): Promise<void> => {\n\t\tawait fetchSession();\n\t}, [fetchSession]);\n\n\tconst signIn = useCallback(\n\t\tasync (email: string, password: string): Promise<ActionResult> => {\n\t\t\ttry {\n\t\t\t\tconst res = await fetch(`${base}/sign-in/email`, {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tcredentials: \"include\",\n\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\tbody: JSON.stringify({ email, password }),\n\t\t\t\t});\n\t\t\t\tconst json = (await res.json()) as\n\t\t\t\t\t| { data: KavachSession }\n\t\t\t\t\t| { error: { code: string; message: string } };\n\n\t\t\t\tif (!res.ok) {\n\t\t\t\t\tconst errBody = json as { error: { code: string; message: string } };\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\terror: errBody.error?.message ?? `Sign-in failed (${res.status})`,\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tconst okBody = json as { data: KavachSession };\n\t\t\t\tsetSession(okBody.data);\n\t\t\t\treturn { success: true, data: undefined };\n\t\t\t} catch (err) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: err instanceof Error ? err.message : \"Network error\",\n\t\t\t\t};\n\t\t\t}\n\t\t},\n\t\t[base],\n\t);\n\n\tconst signUp = useCallback(\n\t\tasync (email: string, password: string, name?: string): Promise<ActionResult> => {\n\t\t\ttry {\n\t\t\t\tconst res = await fetch(`${base}/sign-up/email`, {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tcredentials: \"include\",\n\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\tbody: JSON.stringify({ email, password, name }),\n\t\t\t\t});\n\t\t\t\tconst json = (await res.json()) as\n\t\t\t\t\t| { data: KavachSession }\n\t\t\t\t\t| { error: { code: string; message: string } };\n\n\t\t\t\tif (!res.ok) {\n\t\t\t\t\tconst errBody = json as { error: { code: string; message: string } };\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\terror: errBody.error?.message ?? `Sign-up failed (${res.status})`,\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tconst okBody = json as { data: KavachSession };\n\t\t\t\tsetSession(okBody.data);\n\t\t\t\treturn { success: true, data: undefined };\n\t\t\t} catch (err) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: err instanceof Error ? err.message : \"Network error\",\n\t\t\t\t};\n\t\t\t}\n\t\t},\n\t\t[base],\n\t);\n\n\tconst signOut = useCallback(async (): Promise<void> => {\n\t\ttry {\n\t\t\tawait fetch(`${base}/sign-out`, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tcredentials: \"include\",\n\t\t\t});\n\t\t} finally {\n\t\t\tsetSession(null);\n\t\t}\n\t}, [base]);\n\n\tconst user: KavachUser | null = session?.user ?? null;\n\n\tconst value: KavachContextValue = {\n\t\tsession,\n\t\tuser,\n\t\tisLoading,\n\t\tisAuthenticated: session !== null,\n\t\tsignIn,\n\t\tsignUp,\n\t\tsignOut,\n\t\trefresh,\n\t};\n\n\treturn <KavachContext.Provider value={value}>{children}</KavachContext.Provider>;\n}\n","import { useCallback, useContext, useState } from \"react\";\nimport { KavachContext } from \"./context.js\";\nimport type { ActionResult, CreateAgentInput, KavachAgent } from \"./types.js\";\n\n// ─── Guards ────────────────────────────────────────────────────────────────────\n\nfunction useRequiredContext(hookName: string) {\n\tconst ctx = useContext(KavachContext);\n\tif (!ctx) {\n\t\tthrow new Error(`${hookName} must be used inside <KavachProvider>`);\n\t}\n\treturn ctx;\n}\n\n// ─── useSession ───────────────────────────────────────────────────────────────\n\n/**\n * Returns the current session, loading state, and a manual refresh function.\n */\nexport function useSession() {\n\tconst { session, isLoading, refresh } = useRequiredContext(\"useSession\");\n\treturn { session, isLoading, refresh };\n}\n\n// ─── useUser ──────────────────────────────────────────────────────────────────\n\n/**\n * Returns the current user, loading state, and authentication status.\n */\nexport function useUser() {\n\tconst { user, isLoading, isAuthenticated } = useRequiredContext(\"useUser\");\n\treturn { user, isLoading, isAuthenticated };\n}\n\n// ─── useSignIn ────────────────────────────────────────────────────────────────\n\n/**\n * Returns a signIn function plus local loading and error state.\n */\nexport function useSignIn() {\n\tconst { signIn } = useRequiredContext(\"useSignIn\");\n\tconst [isLoading, setIsLoading] = useState(false);\n\tconst [error, setError] = useState<string | null>(null);\n\n\tconst execute = useCallback(\n\t\tasync (email: string, password: string): Promise<ActionResult> => {\n\t\t\tsetIsLoading(true);\n\t\t\tsetError(null);\n\t\t\tconst result = await signIn(email, password);\n\t\t\tif (!result.success) {\n\t\t\t\tsetError(result.error);\n\t\t\t}\n\t\t\tsetIsLoading(false);\n\t\t\treturn result;\n\t\t},\n\t\t[signIn],\n\t);\n\n\treturn { signIn: execute, isLoading, error };\n}\n\n// ─── useSignUp ────────────────────────────────────────────────────────────────\n\n/**\n * Returns a signUp function plus local loading and error state.\n */\nexport function useSignUp() {\n\tconst { signUp } = useRequiredContext(\"useSignUp\");\n\tconst [isLoading, setIsLoading] = useState(false);\n\tconst [error, setError] = useState<string | null>(null);\n\n\tconst execute = useCallback(\n\t\tasync (email: string, password: string, name?: string): Promise<ActionResult> => {\n\t\t\tsetIsLoading(true);\n\t\t\tsetError(null);\n\t\t\tconst result = await signUp(email, password, name);\n\t\t\tif (!result.success) {\n\t\t\t\tsetError(result.error);\n\t\t\t}\n\t\t\tsetIsLoading(false);\n\t\t\treturn result;\n\t\t},\n\t\t[signUp],\n\t);\n\n\treturn { signUp: execute, isLoading, error };\n}\n\n// ─── useSignOut ───────────────────────────────────────────────────────────────\n\n/**\n * Returns a signOut function.\n */\nexport function useSignOut() {\n\tconst { signOut } = useRequiredContext(\"useSignOut\");\n\treturn { signOut };\n}\n\n// ─── useAgents ────────────────────────────────────────────────────────────────\n\ninterface AgentApiResponse {\n\tdata: KavachAgent[];\n}\n\ninterface AgentSingleApiResponse {\n\tdata: KavachAgent;\n}\n\ninterface ApiErrorResponse {\n\terror: {\n\t\tcode: string;\n\t\tmessage: string;\n\t};\n}\n\nfunction extractError(body: unknown, fallback: string): string {\n\tif (\n\t\tbody !== null &&\n\t\ttypeof body === \"object\" &&\n\t\t\"error\" in body &&\n\t\tbody.error !== null &&\n\t\ttypeof body.error === \"object\" &&\n\t\t\"message\" in body.error &&\n\t\ttypeof (body as ApiErrorResponse).error.message === \"string\"\n\t) {\n\t\treturn (body as ApiErrorResponse).error.message;\n\t}\n\treturn fallback;\n}\n\n/**\n * Manages agent identity records for a given user.\n *\n * Fetches the agent list and exposes create, revoke, and rotate helpers.\n * All mutations refresh the list automatically.\n */\nexport function useAgents(basePath = \"/api/kavach\") {\n\tconst { user } = useRequiredContext(\"useAgents\");\n\tconst base = basePath.replace(/\\/$/, \"\");\n\n\tconst [agents, setAgents] = useState<KavachAgent[]>([]);\n\tconst [isLoading, setIsLoading] = useState(false);\n\tconst [error, setError] = useState<string | null>(null);\n\n\tconst load = useCallback(async (): Promise<void> => {\n\t\tif (!user) {\n\t\t\tsetAgents([]);\n\t\t\treturn;\n\t\t}\n\t\tsetIsLoading(true);\n\t\tsetError(null);\n\t\ttry {\n\t\t\tconst res = await fetch(`${base}/agents?userId=${encodeURIComponent(user.id)}`, {\n\t\t\t\tcredentials: \"include\",\n\t\t\t});\n\t\t\tconst json: unknown = await res.json();\n\t\t\tif (!res.ok) {\n\t\t\t\tsetError(extractError(json, `Failed to load agents (${res.status})`));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsetAgents((json as AgentApiResponse).data);\n\t\t} catch (err) {\n\t\t\tsetError(err instanceof Error ? err.message : \"Network error\");\n\t\t} finally {\n\t\t\tsetIsLoading(false);\n\t\t}\n\t}, [base, user]);\n\n\t// Load once when user is available\n\tconst [loaded, setLoaded] = useState(false);\n\tif (user && !loaded) {\n\t\tsetLoaded(true);\n\t\t// Use a microtask to avoid calling setState during render\n\t\tvoid Promise.resolve().then(load);\n\t}\n\tif (!user && loaded) {\n\t\tsetLoaded(false);\n\t\tsetAgents([]);\n\t}\n\n\tconst create = useCallback(\n\t\tasync (input: CreateAgentInput): Promise<ActionResult<KavachAgent>> => {\n\t\t\ttry {\n\t\t\t\tconst res = await fetch(`${base}/agents`, {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tcredentials: \"include\",\n\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\tbody: JSON.stringify(input),\n\t\t\t\t});\n\t\t\t\tconst json: unknown = await res.json();\n\t\t\t\tif (!res.ok) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\terror: extractError(json, `Failed to create agent (${res.status})`),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tconst agent = (json as AgentSingleApiResponse).data;\n\t\t\t\tawait load();\n\t\t\t\treturn { success: true, data: agent };\n\t\t\t} catch (err) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: err instanceof Error ? err.message : \"Network error\",\n\t\t\t\t};\n\t\t\t}\n\t\t},\n\t\t[base, load],\n\t);\n\n\tconst revoke = useCallback(\n\t\tasync (agentId: string): Promise<ActionResult> => {\n\t\t\ttry {\n\t\t\t\tconst res = await fetch(`${base}/agents/${encodeURIComponent(agentId)}`, {\n\t\t\t\t\tmethod: \"DELETE\",\n\t\t\t\t\tcredentials: \"include\",\n\t\t\t\t});\n\t\t\t\tif (!res.ok && res.status !== 204) {\n\t\t\t\t\tconst json: unknown = await res.json().catch(() => null);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\terror: extractError(json, `Failed to revoke agent (${res.status})`),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tawait load();\n\t\t\t\treturn { success: true, data: undefined };\n\t\t\t} catch (err) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: err instanceof Error ? err.message : \"Network error\",\n\t\t\t\t};\n\t\t\t}\n\t\t},\n\t\t[base, load],\n\t);\n\n\tconst rotate = useCallback(\n\t\tasync (agentId: string): Promise<ActionResult<KavachAgent>> => {\n\t\t\ttry {\n\t\t\t\tconst res = await fetch(`${base}/agents/${encodeURIComponent(agentId)}/rotate`, {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tcredentials: \"include\",\n\t\t\t\t});\n\t\t\t\tconst json: unknown = await res.json();\n\t\t\t\tif (!res.ok) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\terror: extractError(json, `Failed to rotate agent token (${res.status})`),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tconst agent = (json as AgentSingleApiResponse).data;\n\t\t\t\tawait load();\n\t\t\t\treturn { success: true, data: agent };\n\t\t\t} catch (err) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: err instanceof Error ? err.message : \"Network error\",\n\t\t\t\t};\n\t\t\t}\n\t\t},\n\t\t[base, load],\n\t);\n\n\treturn { agents, isLoading, error, load, create, revoke, rotate };\n}\n"],"mappings":"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","names":["useCallback","useContext","useState","useContext","useState","useCallback"]}
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@kavachos/react",
3
+ "version": "0.0.3",
4
+ "description": "React hooks for KavachOS auth",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "license": "MIT",
18
+ "author": "KavachOS <hello@kavachos.com>",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "https://github.com/kavachos/kavachos.git",
22
+ "directory": "packages/react"
23
+ },
24
+ "peerDependencies": {
25
+ "react": ">=18.0.0"
26
+ },
27
+ "devDependencies": {
28
+ "react": "^19.0.0",
29
+ "@types/react": "^19.0.0",
30
+ "tsup": "^8.4.0",
31
+ "typescript": "^5.8.0"
32
+ },
33
+ "scripts": {
34
+ "build": "tsup",
35
+ "typecheck": "tsc --noEmit"
36
+ }
37
+ }