@kavachos/vue 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,180 @@
1
+ import * as vue from 'vue';
2
+ import { InjectionKey, App } from 'vue';
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
+ basePath: string;
62
+ signIn: (email: string, password: string) => Promise<ActionResult>;
63
+ signUp: (email: string, password: string, name?: string) => Promise<ActionResult>;
64
+ signOut: () => Promise<void>;
65
+ refresh: () => Promise<void>;
66
+ }
67
+
68
+ /**
69
+ * Returns the current session, loading state, and a manual refresh function.
70
+ */
71
+ declare function useSession(): {
72
+ readonly session: KavachSession | null;
73
+ readonly isLoading: boolean;
74
+ refresh: () => Promise<void>;
75
+ };
76
+ /**
77
+ * Returns the current user, loading state, and authentication status.
78
+ */
79
+ declare function useUser(): {
80
+ readonly user: KavachUser | null;
81
+ readonly isAuthenticated: boolean;
82
+ readonly isLoading: boolean;
83
+ };
84
+ /**
85
+ * Returns a signIn function plus local loading and error state.
86
+ */
87
+ declare function useSignIn(): {
88
+ signIn: (email: string, password: string) => Promise<ActionResult>;
89
+ isLoading: vue.Ref<boolean, boolean>;
90
+ error: vue.Ref<string | null, string | null>;
91
+ };
92
+ /**
93
+ * Returns a signUp function plus local loading and error state.
94
+ */
95
+ declare function useSignUp(): {
96
+ signUp: (email: string, password: string, name?: string) => Promise<ActionResult>;
97
+ isLoading: vue.Ref<boolean, boolean>;
98
+ error: vue.Ref<string | null, string | null>;
99
+ };
100
+ /**
101
+ * Returns a signOut function.
102
+ */
103
+ declare function useSignOut(): {
104
+ signOut: () => Promise<void>;
105
+ };
106
+ /**
107
+ * Manages agent identity records for a given user.
108
+ *
109
+ * Fetches the agent list and exposes create, revoke, and rotate helpers.
110
+ * All mutations refresh the list automatically.
111
+ */
112
+ declare function useAgents(): {
113
+ agents: vue.Ref<{
114
+ id: string;
115
+ ownerId: string;
116
+ name: string;
117
+ type: "autonomous" | "delegated" | "service";
118
+ token: string;
119
+ permissions: {
120
+ resource: string;
121
+ actions: string[];
122
+ constraints?: {
123
+ maxCallsPerHour?: number | undefined;
124
+ allowedArgPatterns?: string[] | undefined;
125
+ requireApproval?: boolean | undefined;
126
+ timeWindow?: {
127
+ start: string;
128
+ end: string;
129
+ } | undefined;
130
+ ipAllowlist?: string[] | undefined;
131
+ } | undefined;
132
+ }[];
133
+ status: "active" | "revoked" | "expired";
134
+ expiresAt: string | null;
135
+ createdAt: string;
136
+ updatedAt: string;
137
+ }[], KavachAgent[] | {
138
+ id: string;
139
+ ownerId: string;
140
+ name: string;
141
+ type: "autonomous" | "delegated" | "service";
142
+ token: string;
143
+ permissions: {
144
+ resource: string;
145
+ actions: string[];
146
+ constraints?: {
147
+ maxCallsPerHour?: number | undefined;
148
+ allowedArgPatterns?: string[] | undefined;
149
+ requireApproval?: boolean | undefined;
150
+ timeWindow?: {
151
+ start: string;
152
+ end: string;
153
+ } | undefined;
154
+ ipAllowlist?: string[] | undefined;
155
+ } | undefined;
156
+ }[];
157
+ status: "active" | "revoked" | "expired";
158
+ expiresAt: string | null;
159
+ createdAt: string;
160
+ updatedAt: string;
161
+ }[]>;
162
+ isLoading: vue.Ref<boolean, boolean>;
163
+ error: vue.Ref<string | null, string | null>;
164
+ load: () => Promise<void>;
165
+ create: (input: CreateAgentInput) => Promise<ActionResult<KavachAgent>>;
166
+ revoke: (agentId: string) => Promise<ActionResult>;
167
+ rotate: (agentId: string) => Promise<ActionResult<KavachAgent>>;
168
+ };
169
+
170
+ declare const KAVACH_KEY: InjectionKey<KavachContextValue>;
171
+ declare function useRequiredContext(composableName: string): KavachContextValue;
172
+ interface KavachPluginOptions {
173
+ /** Base path where KavachOS is mounted. Defaults to "/api/kavach". */
174
+ basePath?: string;
175
+ }
176
+ declare function createKavachPlugin(options?: KavachPluginOptions): {
177
+ install(app: App): void;
178
+ };
179
+
180
+ export { type ActionResult, type CreateAgentInput, KAVACH_KEY, type KavachAgent, type KavachContextValue, type KavachPermission, type KavachPluginOptions, type KavachSession, type KavachUser, createKavachPlugin, useAgents, useRequiredContext, useSession, useSignIn, useSignOut, useSignUp, useUser };
package/dist/index.js ADDED
@@ -0,0 +1,318 @@
1
+ // src/composables.ts
2
+ import { ref as ref2 } from "vue";
3
+
4
+ // src/plugin.ts
5
+ import { inject, ref } from "vue";
6
+ var KAVACH_KEY = /* @__PURE__ */ Symbol("kavach");
7
+ function useRequiredContext(composableName) {
8
+ const ctx = inject(KAVACH_KEY);
9
+ if (!ctx) {
10
+ throw new Error(
11
+ `${composableName} must be used inside a component wrapped by createKavachPlugin`
12
+ );
13
+ }
14
+ return ctx;
15
+ }
16
+ function createKavachPlugin(options = {}) {
17
+ return {
18
+ install(app) {
19
+ const base = (options.basePath ?? "/api/kavach").replace(/\/$/, "");
20
+ const session = ref(null);
21
+ const isLoading = ref(true);
22
+ async function fetchSession() {
23
+ if (typeof window === "undefined") {
24
+ isLoading.value = false;
25
+ return;
26
+ }
27
+ try {
28
+ const res = await fetch(`${base}/session`, {
29
+ credentials: "include"
30
+ });
31
+ if (res.ok) {
32
+ const json = await res.json();
33
+ session.value = json.data ?? null;
34
+ } else {
35
+ session.value = null;
36
+ }
37
+ } catch {
38
+ session.value = null;
39
+ }
40
+ }
41
+ async function refresh() {
42
+ await fetchSession();
43
+ }
44
+ async function signIn(email, password) {
45
+ try {
46
+ const res = await fetch(`${base}/sign-in/email`, {
47
+ method: "POST",
48
+ credentials: "include",
49
+ headers: { "Content-Type": "application/json" },
50
+ body: JSON.stringify({ email, password })
51
+ });
52
+ const json = await res.json();
53
+ if (!res.ok) {
54
+ const errBody = json;
55
+ return {
56
+ success: false,
57
+ error: errBody.error?.message ?? `Sign-in failed (${res.status})`
58
+ };
59
+ }
60
+ const okBody = json;
61
+ session.value = okBody.data;
62
+ return { success: true, data: void 0 };
63
+ } catch (err) {
64
+ return {
65
+ success: false,
66
+ error: err instanceof Error ? err.message : "Network error"
67
+ };
68
+ }
69
+ }
70
+ async function signUp(email, password, name) {
71
+ try {
72
+ const res = await fetch(`${base}/sign-up/email`, {
73
+ method: "POST",
74
+ credentials: "include",
75
+ headers: { "Content-Type": "application/json" },
76
+ body: JSON.stringify({ email, password, name })
77
+ });
78
+ const json = await res.json();
79
+ if (!res.ok) {
80
+ const errBody = json;
81
+ return {
82
+ success: false,
83
+ error: errBody.error?.message ?? `Sign-up failed (${res.status})`
84
+ };
85
+ }
86
+ const okBody = json;
87
+ session.value = okBody.data;
88
+ return { success: true, data: void 0 };
89
+ } catch (err) {
90
+ return {
91
+ success: false,
92
+ error: err instanceof Error ? err.message : "Network error"
93
+ };
94
+ }
95
+ }
96
+ async function signOut() {
97
+ try {
98
+ await fetch(`${base}/sign-out`, {
99
+ method: "POST",
100
+ credentials: "include"
101
+ });
102
+ } finally {
103
+ session.value = null;
104
+ }
105
+ }
106
+ isLoading.value = true;
107
+ void fetchSession().finally(() => {
108
+ isLoading.value = false;
109
+ });
110
+ const context = {
111
+ get session() {
112
+ return session.value;
113
+ },
114
+ get user() {
115
+ return session.value?.user ?? null;
116
+ },
117
+ get isLoading() {
118
+ return isLoading.value;
119
+ },
120
+ get isAuthenticated() {
121
+ return session.value !== null;
122
+ },
123
+ basePath: base,
124
+ signIn,
125
+ signUp,
126
+ signOut,
127
+ refresh
128
+ };
129
+ app.provide(KAVACH_KEY, context);
130
+ }
131
+ };
132
+ }
133
+
134
+ // src/composables.ts
135
+ function useSession() {
136
+ const ctx = useRequiredContext("useSession");
137
+ return {
138
+ get session() {
139
+ return ctx.session;
140
+ },
141
+ get isLoading() {
142
+ return ctx.isLoading;
143
+ },
144
+ refresh: ctx.refresh
145
+ };
146
+ }
147
+ function useUser() {
148
+ const ctx = useRequiredContext("useUser");
149
+ return {
150
+ get user() {
151
+ return ctx.user;
152
+ },
153
+ get isAuthenticated() {
154
+ return ctx.isAuthenticated;
155
+ },
156
+ get isLoading() {
157
+ return ctx.isLoading;
158
+ }
159
+ };
160
+ }
161
+ function useSignIn() {
162
+ const ctx = useRequiredContext("useSignIn");
163
+ const isLoading = ref2(false);
164
+ const error = ref2(null);
165
+ async function signIn(email, password) {
166
+ isLoading.value = true;
167
+ error.value = null;
168
+ const result = await ctx.signIn(email, password);
169
+ if (!result.success) {
170
+ error.value = result.error;
171
+ }
172
+ isLoading.value = false;
173
+ return result;
174
+ }
175
+ return { signIn, isLoading, error };
176
+ }
177
+ function useSignUp() {
178
+ const ctx = useRequiredContext("useSignUp");
179
+ const isLoading = ref2(false);
180
+ const error = ref2(null);
181
+ async function signUp(email, password, name) {
182
+ isLoading.value = true;
183
+ error.value = null;
184
+ const result = await ctx.signUp(email, password, name);
185
+ if (!result.success) {
186
+ error.value = result.error;
187
+ }
188
+ isLoading.value = false;
189
+ return result;
190
+ }
191
+ return { signUp, isLoading, error };
192
+ }
193
+ function useSignOut() {
194
+ const ctx = useRequiredContext("useSignOut");
195
+ return { signOut: ctx.signOut };
196
+ }
197
+ function extractError(body, fallback) {
198
+ 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") {
199
+ return body.error.message;
200
+ }
201
+ return fallback;
202
+ }
203
+ function useAgents() {
204
+ const ctx = useRequiredContext("useAgents");
205
+ const base = ctx.basePath;
206
+ const agents = ref2([]);
207
+ const isLoading = ref2(false);
208
+ const error = ref2(null);
209
+ async function load() {
210
+ if (!ctx.user) {
211
+ agents.value = [];
212
+ return;
213
+ }
214
+ isLoading.value = true;
215
+ error.value = null;
216
+ try {
217
+ const res = await fetch(`${base}/agents?userId=${encodeURIComponent(ctx.user.id)}`, {
218
+ credentials: "include"
219
+ });
220
+ const json = await res.json();
221
+ if (!res.ok) {
222
+ error.value = extractError(json, `Failed to load agents (${res.status})`);
223
+ return;
224
+ }
225
+ agents.value = json.data;
226
+ } catch (err) {
227
+ error.value = err instanceof Error ? err.message : "Network error";
228
+ } finally {
229
+ isLoading.value = false;
230
+ }
231
+ }
232
+ if (typeof window !== "undefined" && ctx.user) {
233
+ void load();
234
+ }
235
+ async function create(input) {
236
+ try {
237
+ const res = await fetch(`${base}/agents`, {
238
+ method: "POST",
239
+ credentials: "include",
240
+ headers: { "Content-Type": "application/json" },
241
+ body: JSON.stringify(input)
242
+ });
243
+ const json = await res.json();
244
+ if (!res.ok) {
245
+ return {
246
+ success: false,
247
+ error: extractError(json, `Failed to create agent (${res.status})`)
248
+ };
249
+ }
250
+ const agent = json.data;
251
+ await load();
252
+ return { success: true, data: agent };
253
+ } catch (err) {
254
+ return {
255
+ success: false,
256
+ error: err instanceof Error ? err.message : "Network error"
257
+ };
258
+ }
259
+ }
260
+ async function revoke(agentId) {
261
+ try {
262
+ const res = await fetch(`${base}/agents/${encodeURIComponent(agentId)}`, {
263
+ method: "DELETE",
264
+ credentials: "include"
265
+ });
266
+ if (!res.ok && res.status !== 204) {
267
+ const json = await res.json().catch(() => null);
268
+ return {
269
+ success: false,
270
+ error: extractError(json, `Failed to revoke agent (${res.status})`)
271
+ };
272
+ }
273
+ await load();
274
+ return { success: true, data: void 0 };
275
+ } catch (err) {
276
+ return {
277
+ success: false,
278
+ error: err instanceof Error ? err.message : "Network error"
279
+ };
280
+ }
281
+ }
282
+ async function rotate(agentId) {
283
+ try {
284
+ const res = await fetch(`${base}/agents/${encodeURIComponent(agentId)}/rotate`, {
285
+ method: "POST",
286
+ credentials: "include"
287
+ });
288
+ const json = await res.json();
289
+ if (!res.ok) {
290
+ return {
291
+ success: false,
292
+ error: extractError(json, `Failed to rotate agent token (${res.status})`)
293
+ };
294
+ }
295
+ const agent = json.data;
296
+ await load();
297
+ return { success: true, data: agent };
298
+ } catch (err) {
299
+ return {
300
+ success: false,
301
+ error: err instanceof Error ? err.message : "Network error"
302
+ };
303
+ }
304
+ }
305
+ return { agents, isLoading, error, load, create, revoke, rotate };
306
+ }
307
+ export {
308
+ KAVACH_KEY,
309
+ createKavachPlugin,
310
+ useAgents,
311
+ useRequiredContext,
312
+ useSession,
313
+ useSignIn,
314
+ useSignOut,
315
+ useSignUp,
316
+ useUser
317
+ };
318
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/composables.ts","../src/plugin.ts"],"sourcesContent":["import { ref } from \"vue\";\nimport { useRequiredContext } from \"./plugin.js\";\nimport type { ActionResult, CreateAgentInput, KavachAgent } from \"./types.js\";\n\n// ─── useSession ───────────────────────────────────────────────────────────────\n\n/**\n * Returns the current session, loading state, and a manual refresh function.\n */\nexport function useSession() {\n\tconst ctx = useRequiredContext(\"useSession\");\n\treturn {\n\t\tget session() {\n\t\t\treturn ctx.session;\n\t\t},\n\t\tget isLoading() {\n\t\t\treturn ctx.isLoading;\n\t\t},\n\t\trefresh: ctx.refresh,\n\t};\n}\n\n// ─── useUser ──────────────────────────────────────────────────────────────────\n\n/**\n * Returns the current user, loading state, and authentication status.\n */\nexport function useUser() {\n\tconst ctx = useRequiredContext(\"useUser\");\n\treturn {\n\t\tget user() {\n\t\t\treturn ctx.user;\n\t\t},\n\t\tget isAuthenticated() {\n\t\t\treturn ctx.isAuthenticated;\n\t\t},\n\t\tget isLoading() {\n\t\t\treturn ctx.isLoading;\n\t\t},\n\t};\n}\n\n// ─── useSignIn ────────────────────────────────────────────────────────────────\n\n/**\n * Returns a signIn function plus local loading and error state.\n */\nexport function useSignIn() {\n\tconst ctx = useRequiredContext(\"useSignIn\");\n\tconst isLoading = ref(false);\n\tconst error = ref<string | null>(null);\n\n\tasync function signIn(email: string, password: string): Promise<ActionResult> {\n\t\tisLoading.value = true;\n\t\terror.value = null;\n\t\tconst result = await ctx.signIn(email, password);\n\t\tif (!result.success) {\n\t\t\terror.value = result.error;\n\t\t}\n\t\tisLoading.value = false;\n\t\treturn result;\n\t}\n\n\treturn { signIn, 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 ctx = useRequiredContext(\"useSignUp\");\n\tconst isLoading = ref(false);\n\tconst error = ref<string | null>(null);\n\n\tasync function signUp(email: string, password: string, name?: string): Promise<ActionResult> {\n\t\tisLoading.value = true;\n\t\terror.value = null;\n\t\tconst result = await ctx.signUp(email, password, name);\n\t\tif (!result.success) {\n\t\t\terror.value = result.error;\n\t\t}\n\t\tisLoading.value = false;\n\t\treturn result;\n\t}\n\n\treturn { signUp, isLoading, error };\n}\n\n// ─── useSignOut ───────────────────────────────────────────────────────────────\n\n/**\n * Returns a signOut function.\n */\nexport function useSignOut() {\n\tconst ctx = useRequiredContext(\"useSignOut\");\n\treturn { signOut: ctx.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() {\n\tconst ctx = useRequiredContext(\"useAgents\");\n\tconst base = ctx.basePath;\n\n\tconst agents = ref<KavachAgent[]>([]);\n\tconst isLoading = ref(false);\n\tconst error = ref<string | null>(null);\n\n\tasync function load(): Promise<void> {\n\t\tif (!ctx.user) {\n\t\t\tagents.value = [];\n\t\t\treturn;\n\t\t}\n\t\tisLoading.value = true;\n\t\terror.value = null;\n\t\ttry {\n\t\t\tconst res = await fetch(`${base}/agents?userId=${encodeURIComponent(ctx.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\terror.value = extractError(json, `Failed to load agents (${res.status})`);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tagents.value = (json as AgentApiResponse).data;\n\t\t} catch (err) {\n\t\t\terror.value = err instanceof Error ? err.message : \"Network error\";\n\t\t} finally {\n\t\t\tisLoading.value = false;\n\t\t}\n\t}\n\n\t// Load once when invoked in browser context and user is available\n\tif (typeof window !== \"undefined\" && ctx.user) {\n\t\tvoid load();\n\t}\n\n\tasync function create(input: CreateAgentInput): Promise<ActionResult<KavachAgent>> {\n\t\ttry {\n\t\t\tconst res = await fetch(`${base}/agents`, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tcredentials: \"include\",\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\tbody: JSON.stringify(input),\n\t\t\t});\n\t\t\tconst json: unknown = await res.json();\n\t\t\tif (!res.ok) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: extractError(json, `Failed to create agent (${res.status})`),\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst agent = (json as AgentSingleApiResponse).data;\n\t\t\tawait load();\n\t\t\treturn { success: true, data: agent };\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: err instanceof Error ? err.message : \"Network error\",\n\t\t\t};\n\t\t}\n\t}\n\n\tasync function revoke(agentId: string): Promise<ActionResult> {\n\t\ttry {\n\t\t\tconst res = await fetch(`${base}/agents/${encodeURIComponent(agentId)}`, {\n\t\t\t\tmethod: \"DELETE\",\n\t\t\t\tcredentials: \"include\",\n\t\t\t});\n\t\t\tif (!res.ok && res.status !== 204) {\n\t\t\t\tconst json: unknown = await res.json().catch(() => null);\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: extractError(json, `Failed to revoke agent (${res.status})`),\n\t\t\t\t};\n\t\t\t}\n\t\t\tawait load();\n\t\t\treturn { success: true, data: undefined };\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: err instanceof Error ? err.message : \"Network error\",\n\t\t\t};\n\t\t}\n\t}\n\n\tasync function rotate(agentId: string): Promise<ActionResult<KavachAgent>> {\n\t\ttry {\n\t\t\tconst res = await fetch(`${base}/agents/${encodeURIComponent(agentId)}/rotate`, {\n\t\t\t\tmethod: \"POST\",\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\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: extractError(json, `Failed to rotate agent token (${res.status})`),\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst agent = (json as AgentSingleApiResponse).data;\n\t\t\tawait load();\n\t\t\treturn { success: true, data: agent };\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: err instanceof Error ? err.message : \"Network error\",\n\t\t\t};\n\t\t}\n\t}\n\n\treturn { agents, isLoading, error, load, create, revoke, rotate };\n}\n","import type { App, InjectionKey, Ref } from \"vue\";\nimport { inject, ref } from \"vue\";\nimport type { ActionResult, KavachContextValue, KavachSession, KavachUser } from \"./types.js\";\n\n// ─── Injection key ────────────────────────────────────────────────────────────\n\nexport const KAVACH_KEY: InjectionKey<KavachContextValue> = Symbol(\"kavach\");\n\n// ─── useRequiredContext ───────────────────────────────────────────────────────\n\nexport function useRequiredContext(composableName: string): KavachContextValue {\n\tconst ctx = inject(KAVACH_KEY);\n\tif (!ctx) {\n\t\tthrow new Error(\n\t\t\t`${composableName} must be used inside a component wrapped by createKavachPlugin`,\n\t\t);\n\t}\n\treturn ctx;\n}\n\n// ─── Plugin ───────────────────────────────────────────────────────────────────\n\nexport interface KavachPluginOptions {\n\t/** Base path where KavachOS is mounted. Defaults to \"/api/kavach\". */\n\tbasePath?: string;\n}\n\nexport function createKavachPlugin(options: KavachPluginOptions = {}) {\n\treturn {\n\t\tinstall(app: App) {\n\t\t\tconst base = (options.basePath ?? \"/api/kavach\").replace(/\\/$/, \"\");\n\n\t\t\tconst session: Ref<KavachSession | null> = ref(null);\n\t\t\tconst isLoading: Ref<boolean> = ref(true);\n\n\t\t\tasync function fetchSession(): Promise<void> {\n\t\t\t\tif (typeof window === \"undefined\") {\n\t\t\t\t\tisLoading.value = false;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst res = await fetch(`${base}/session`, {\n\t\t\t\t\t\tcredentials: \"include\",\n\t\t\t\t\t});\n\t\t\t\t\tif (res.ok) {\n\t\t\t\t\t\tconst json = (await res.json()) as { data?: KavachSession };\n\t\t\t\t\t\tsession.value = json.data ?? null;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsession.value = null;\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\tsession.value = null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tasync function refresh(): Promise<void> {\n\t\t\t\tawait fetchSession();\n\t\t\t}\n\n\t\t\tasync function signIn(email: string, password: string): Promise<ActionResult> {\n\t\t\t\ttry {\n\t\t\t\t\tconst res = await fetch(`${base}/sign-in/email`, {\n\t\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\t\tcredentials: \"include\",\n\t\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\t\tbody: JSON.stringify({ email, password }),\n\t\t\t\t\t});\n\t\t\t\t\tconst json = (await res.json()) as\n\t\t\t\t\t\t| { data: KavachSession }\n\t\t\t\t\t\t| { error: { code: string; message: string } };\n\n\t\t\t\t\tif (!res.ok) {\n\t\t\t\t\t\tconst errBody = json as { error: { code: string; message: string } };\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\terror: errBody.error?.message ?? `Sign-in failed (${res.status})`,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\tconst okBody = json as { data: KavachSession };\n\t\t\t\t\tsession.value = okBody.data;\n\t\t\t\t\treturn { success: true, data: undefined };\n\t\t\t\t} catch (err) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\terror: err instanceof Error ? err.message : \"Network error\",\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tasync function signUp(email: string, password: string, name?: string): Promise<ActionResult> {\n\t\t\t\ttry {\n\t\t\t\t\tconst res = await fetch(`${base}/sign-up/email`, {\n\t\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\t\tcredentials: \"include\",\n\t\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\t\tbody: JSON.stringify({ email, password, name }),\n\t\t\t\t\t});\n\t\t\t\t\tconst json = (await res.json()) as\n\t\t\t\t\t\t| { data: KavachSession }\n\t\t\t\t\t\t| { error: { code: string; message: string } };\n\n\t\t\t\t\tif (!res.ok) {\n\t\t\t\t\t\tconst errBody = json as { error: { code: string; message: string } };\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\terror: errBody.error?.message ?? `Sign-up failed (${res.status})`,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\tconst okBody = json as { data: KavachSession };\n\t\t\t\t\tsession.value = okBody.data;\n\t\t\t\t\treturn { success: true, data: undefined };\n\t\t\t\t} catch (err) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\terror: err instanceof Error ? err.message : \"Network error\",\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tasync function signOut(): Promise<void> {\n\t\t\t\ttry {\n\t\t\t\t\tawait fetch(`${base}/sign-out`, {\n\t\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\t\tcredentials: \"include\",\n\t\t\t\t\t});\n\t\t\t\t} finally {\n\t\t\t\t\tsession.value = null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Kick off the initial session fetch\n\t\t\tisLoading.value = true;\n\t\t\tvoid fetchSession().finally(() => {\n\t\t\t\tisLoading.value = false;\n\t\t\t});\n\n\t\t\tconst context: KavachContextValue = {\n\t\t\t\tget session() {\n\t\t\t\t\treturn session.value;\n\t\t\t\t},\n\t\t\t\tget user(): KavachUser | null {\n\t\t\t\t\treturn session.value?.user ?? null;\n\t\t\t\t},\n\t\t\t\tget isLoading() {\n\t\t\t\t\treturn isLoading.value;\n\t\t\t\t},\n\t\t\t\tget isAuthenticated() {\n\t\t\t\t\treturn session.value !== null;\n\t\t\t\t},\n\t\t\t\tbasePath: base,\n\t\t\t\tsignIn,\n\t\t\t\tsignUp,\n\t\t\t\tsignOut,\n\t\t\t\trefresh,\n\t\t\t};\n\n\t\t\tapp.provide(KAVACH_KEY, context);\n\t\t},\n\t};\n}\n"],"mappings":"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","names":["ref","ref"]}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@kavachos/vue",
3
+ "version": "0.0.3",
4
+ "description": "Vue 3 composables 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/vue"
23
+ },
24
+ "peerDependencies": {
25
+ "vue": ">=3.3.0"
26
+ },
27
+ "devDependencies": {
28
+ "vue": "^3.5.0",
29
+ "tsup": "^8.4.0",
30
+ "typescript": "^5.8.0"
31
+ },
32
+ "scripts": {
33
+ "build": "tsup",
34
+ "typecheck": "tsc --noEmit"
35
+ }
36
+ }