@sprinterai/supabase 0.2.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/LICENSE +21 -0
- package/dist/__test-utils__/mock-supabase.d.ts +18 -0
- package/dist/__test-utils__/mock-supabase.d.ts.map +1 -0
- package/dist/__test-utils__/mock-supabase.js +89 -0
- package/dist/__test-utils__/mock-supabase.js.map +1 -0
- package/dist/auth/adapter.d.ts +41 -0
- package/dist/auth/adapter.d.ts.map +1 -0
- package/dist/auth/adapter.js +73 -0
- package/dist/auth/adapter.js.map +1 -0
- package/dist/auth/claims.d.ts +31 -0
- package/dist/auth/claims.d.ts.map +1 -0
- package/dist/auth/claims.js +31 -0
- package/dist/auth/claims.js.map +1 -0
- package/dist/auth/claims.test.d.ts +2 -0
- package/dist/auth/claims.test.d.ts.map +1 -0
- package/dist/auth/claims.test.js +32 -0
- package/dist/auth/claims.test.js.map +1 -0
- package/dist/auth/index.d.ts +5 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +4 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/permissions.d.ts +14 -0
- package/dist/auth/permissions.d.ts.map +1 -0
- package/dist/auth/permissions.js +25 -0
- package/dist/auth/permissions.js.map +1 -0
- package/dist/auth/permissions.test.d.ts +2 -0
- package/dist/auth/permissions.test.d.ts.map +1 -0
- package/dist/auth/permissions.test.js +40 -0
- package/dist/auth/permissions.test.js.map +1 -0
- package/dist/clients/admin.d.ts +9 -0
- package/dist/clients/admin.d.ts.map +1 -0
- package/dist/clients/admin.js +14 -0
- package/dist/clients/admin.js.map +1 -0
- package/dist/clients/admin.test.d.ts +2 -0
- package/dist/clients/admin.test.d.ts.map +1 -0
- package/dist/clients/admin.test.js +31 -0
- package/dist/clients/admin.test.js.map +1 -0
- package/dist/clients/browser.d.ts +9 -0
- package/dist/clients/browser.d.ts.map +1 -0
- package/dist/clients/browser.js +14 -0
- package/dist/clients/browser.js.map +1 -0
- package/dist/clients/browser.test.d.ts +2 -0
- package/dist/clients/browser.test.d.ts.map +1 -0
- package/dist/clients/browser.test.js +29 -0
- package/dist/clients/browser.test.js.map +1 -0
- package/dist/clients/index.d.ts +4 -0
- package/dist/clients/index.d.ts.map +1 -0
- package/dist/clients/index.js +4 -0
- package/dist/clients/index.js.map +1 -0
- package/dist/clients/server.d.ts +22 -0
- package/dist/clients/server.d.ts.map +1 -0
- package/dist/clients/server.js +25 -0
- package/dist/clients/server.js.map +1 -0
- package/dist/clients/server.test.d.ts +2 -0
- package/dist/clients/server.test.d.ts.map +1 -0
- package/dist/clients/server.test.js +26 -0
- package/dist/clients/server.test.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/realtime/channel.d.ts +24 -0
- package/dist/realtime/channel.d.ts.map +1 -0
- package/dist/realtime/channel.js +20 -0
- package/dist/realtime/channel.js.map +1 -0
- package/dist/realtime/index.d.ts +3 -0
- package/dist/realtime/index.d.ts.map +1 -0
- package/dist/realtime/index.js +2 -0
- package/dist/realtime/index.js.map +1 -0
- package/dist/stores/agent-store.d.ts +14 -0
- package/dist/stores/agent-store.d.ts.map +1 -0
- package/dist/stores/agent-store.js +47 -0
- package/dist/stores/agent-store.js.map +1 -0
- package/dist/stores/agent-store.test.d.ts +2 -0
- package/dist/stores/agent-store.test.d.ts.map +1 -0
- package/dist/stores/agent-store.test.js +64 -0
- package/dist/stores/agent-store.test.js.map +1 -0
- package/dist/stores/chat-store.d.ts +25 -0
- package/dist/stores/chat-store.d.ts.map +1 -0
- package/dist/stores/chat-store.js +148 -0
- package/dist/stores/chat-store.js.map +1 -0
- package/dist/stores/chat-store.test.d.ts +2 -0
- package/dist/stores/chat-store.test.d.ts.map +1 -0
- package/dist/stores/chat-store.test.js +83 -0
- package/dist/stores/chat-store.test.js.map +1 -0
- package/dist/stores/entity-store.d.ts +21 -0
- package/dist/stores/entity-store.d.ts.map +1 -0
- package/dist/stores/entity-store.js +169 -0
- package/dist/stores/entity-store.js.map +1 -0
- package/dist/stores/entity-store.test.d.ts +2 -0
- package/dist/stores/entity-store.test.d.ts.map +1 -0
- package/dist/stores/entity-store.test.js +125 -0
- package/dist/stores/entity-store.test.js.map +1 -0
- package/dist/stores/factory.d.ts +19 -0
- package/dist/stores/factory.d.ts.map +1 -0
- package/dist/stores/factory.js +25 -0
- package/dist/stores/factory.js.map +1 -0
- package/dist/stores/factory.test.d.ts +2 -0
- package/dist/stores/factory.test.d.ts.map +1 -0
- package/dist/stores/factory.test.js +41 -0
- package/dist/stores/factory.test.js.map +1 -0
- package/dist/stores/index.d.ts +11 -0
- package/dist/stores/index.d.ts.map +1 -0
- package/dist/stores/index.js +10 -0
- package/dist/stores/index.js.map +1 -0
- package/dist/stores/memory-store.d.ts +22 -0
- package/dist/stores/memory-store.d.ts.map +1 -0
- package/dist/stores/memory-store.js +59 -0
- package/dist/stores/memory-store.js.map +1 -0
- package/dist/stores/memory-store.test.d.ts +2 -0
- package/dist/stores/memory-store.test.d.ts.map +1 -0
- package/dist/stores/memory-store.test.js +70 -0
- package/dist/stores/memory-store.test.js.map +1 -0
- package/dist/stores/task-store.d.ts +17 -0
- package/dist/stores/task-store.d.ts.map +1 -0
- package/dist/stores/task-store.js +69 -0
- package/dist/stores/task-store.js.map +1 -0
- package/dist/stores/task-store.test.d.ts +2 -0
- package/dist/stores/task-store.test.d.ts.map +1 -0
- package/dist/stores/task-store.test.js +86 -0
- package/dist/stores/task-store.test.js.map +1 -0
- package/dist/stores/tenant-store.d.ts +11 -0
- package/dist/stores/tenant-store.d.ts.map +1 -0
- package/dist/stores/tenant-store.js +23 -0
- package/dist/stores/tenant-store.js.map +1 -0
- package/dist/stores/tool-store.d.ts +16 -0
- package/dist/stores/tool-store.d.ts.map +1 -0
- package/dist/stores/tool-store.js +50 -0
- package/dist/stores/tool-store.js.map +1 -0
- package/dist/stores/tool-store.test.d.ts +2 -0
- package/dist/stores/tool-store.test.d.ts.map +1 -0
- package/dist/stores/tool-store.test.js +56 -0
- package/dist/stores/tool-store.test.js.map +1 -0
- package/dist/stores/view-store.d.ts +14 -0
- package/dist/stores/view-store.d.ts.map +1 -0
- package/dist/stores/view-store.js +51 -0
- package/dist/stores/view-store.js.map +1 -0
- package/dist/stores/view-store.test.d.ts +2 -0
- package/dist/stores/view-store.test.d.ts.map +1 -0
- package/dist/stores/view-store.test.js +57 -0
- package/dist/stores/view-store.test.js.map +1 -0
- package/dist/tenant/actions.d.ts +44 -0
- package/dist/tenant/actions.d.ts.map +1 -0
- package/dist/tenant/actions.js +137 -0
- package/dist/tenant/actions.js.map +1 -0
- package/dist/tenant/constants.d.ts +9 -0
- package/dist/tenant/constants.d.ts.map +1 -0
- package/dist/tenant/constants.js +13 -0
- package/dist/tenant/constants.js.map +1 -0
- package/dist/tenant/constants.test.d.ts +2 -0
- package/dist/tenant/constants.test.d.ts.map +1 -0
- package/dist/tenant/constants.test.js +25 -0
- package/dist/tenant/constants.test.js.map +1 -0
- package/dist/tenant/context.d.ts +20 -0
- package/dist/tenant/context.d.ts.map +1 -0
- package/dist/tenant/context.js +99 -0
- package/dist/tenant/context.js.map +1 -0
- package/dist/tenant/index.d.ts +6 -0
- package/dist/tenant/index.d.ts.map +1 -0
- package/dist/tenant/index.js +5 -0
- package/dist/tenant/index.js.map +1 -0
- package/dist/tenant/roles.d.ts +7 -0
- package/dist/tenant/roles.d.ts.map +1 -0
- package/dist/tenant/roles.js +6 -0
- package/dist/tenant/roles.js.map +1 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/** Supabase-backed implementation of MemoryStore. */
|
|
2
|
+
export class SupabaseMemoryStore {
|
|
3
|
+
client;
|
|
4
|
+
constructor(client) {
|
|
5
|
+
this.client = client;
|
|
6
|
+
}
|
|
7
|
+
async getUserMemories(userId, options) {
|
|
8
|
+
let q = this.client
|
|
9
|
+
.from('user_memories')
|
|
10
|
+
.select('*')
|
|
11
|
+
.eq('user_id', userId)
|
|
12
|
+
.order('created_at', { ascending: false });
|
|
13
|
+
if (options?.source) {
|
|
14
|
+
q = q.eq('source', options.source);
|
|
15
|
+
}
|
|
16
|
+
q = q.limit(options?.limit ?? 50);
|
|
17
|
+
const { data, error } = await q;
|
|
18
|
+
if (error)
|
|
19
|
+
throw error;
|
|
20
|
+
return (data ?? []);
|
|
21
|
+
}
|
|
22
|
+
async saveMemory(input) {
|
|
23
|
+
const { data, error } = await this.client
|
|
24
|
+
.from('user_memories')
|
|
25
|
+
.insert({
|
|
26
|
+
user_id: input.userId,
|
|
27
|
+
content: input.content,
|
|
28
|
+
source: input.source,
|
|
29
|
+
})
|
|
30
|
+
.select('*')
|
|
31
|
+
.single();
|
|
32
|
+
if (error)
|
|
33
|
+
throw error;
|
|
34
|
+
return data;
|
|
35
|
+
}
|
|
36
|
+
async deleteMemory(id) {
|
|
37
|
+
const { error } = await this.client.from('user_memories').delete().eq('id', id);
|
|
38
|
+
if (error)
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
41
|
+
async searchSimilarMessages(query, options) {
|
|
42
|
+
// Fallback to ilike search when pgvector is not available.
|
|
43
|
+
// In production, this would use an RPC with embedding similarity.
|
|
44
|
+
let q = this.client
|
|
45
|
+
.from('user_memories')
|
|
46
|
+
.select('*')
|
|
47
|
+
.ilike('content', `%${query}%`)
|
|
48
|
+
.order('created_at', { ascending: false });
|
|
49
|
+
if (options?.userId) {
|
|
50
|
+
q = q.eq('user_id', options.userId);
|
|
51
|
+
}
|
|
52
|
+
q = q.limit(options?.limit ?? 10);
|
|
53
|
+
const { data, error } = await q;
|
|
54
|
+
if (error)
|
|
55
|
+
throw error;
|
|
56
|
+
return (data ?? []);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=memory-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-store.js","sourceRoot":"","sources":["../../src/stores/memory-store.ts"],"names":[],"mappings":"AAGA,qDAAqD;AACrD,MAAM,OAAO,mBAAmB;IACV;IAApB,YAAoB,MAAsB;QAAtB,WAAM,GAAN,MAAM,CAAgB;IAAG,CAAC;IAE9C,KAAK,CAAC,eAAe,CACnB,MAAc,EACd,OAGC;QAED,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM;aAChB,IAAI,CAAC,eAAe,CAAC;aACrB,MAAM,CAAC,GAAG,CAAC;aACX,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC;aACrB,KAAK,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QAE7C,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;YACpB,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACrC,CAAC;QAED,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QAElC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,CAAC;QAChC,IAAI,KAAK;YAAE,MAAM,KAAK,CAAC;QACvB,OAAO,CAAC,IAAI,IAAI,EAAE,CAAiB,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,KAIhB;QACC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM;aACtC,IAAI,CAAC,eAAe,CAAC;aACrB,MAAM,CAAC;YACN,OAAO,EAAE,KAAK,CAAC,MAAM;YACrB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,MAAM,EAAE,KAAK,CAAC,MAAM;SACrB,CAAC;aACD,MAAM,CAAC,GAAG,CAAC;aACX,MAAM,EAAE,CAAC;QAEZ,IAAI,KAAK;YAAE,MAAM,KAAK,CAAC;QACvB,OAAO,IAAkB,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,EAAU;QAC3B,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAEhF,IAAI,KAAK;YAAE,MAAM,KAAK,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,qBAAqB,CACzB,KAAa,EACb,OAGC;QAED,2DAA2D;QAC3D,kEAAkE;QAClE,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM;aAChB,IAAI,CAAC,eAAe,CAAC;aACrB,MAAM,CAAC,GAAG,CAAC;aACX,KAAK,CAAC,SAAS,EAAE,IAAI,KAAK,GAAG,CAAC;aAC9B,KAAK,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QAE7C,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;YACpB,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACtC,CAAC;QAED,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QAElC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,CAAC;QAChC,IAAI,KAAK;YAAE,MAAM,KAAK,CAAC;QACvB,OAAO,CAAC,IAAI,IAAI,EAAE,CAAiB,CAAC;IACtC,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-store.test.d.ts","sourceRoot":"","sources":["../../src/stores/memory-store.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { SupabaseMemoryStore } from "./memory-store";
|
|
3
|
+
import { createMockClient } from "../__test-utils__/mock-supabase";
|
|
4
|
+
describe("SupabaseMemoryStore", () => {
|
|
5
|
+
describe("getUserMemories", () => {
|
|
6
|
+
it("returns memories for a user", async () => {
|
|
7
|
+
const client = createMockClient();
|
|
8
|
+
const memories = [
|
|
9
|
+
{
|
|
10
|
+
id: "m-1",
|
|
11
|
+
user_id: "user-1",
|
|
12
|
+
content: "Prefers dark mode",
|
|
13
|
+
source: "user",
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
id: "m-2",
|
|
17
|
+
user_id: "user-1",
|
|
18
|
+
content: "Focuses on PE deals",
|
|
19
|
+
source: "agent",
|
|
20
|
+
},
|
|
21
|
+
];
|
|
22
|
+
client.mockTable("user_memories", { data: memories, error: null });
|
|
23
|
+
const store = new SupabaseMemoryStore(client);
|
|
24
|
+
const result = await store.getUserMemories("user-1");
|
|
25
|
+
expect(result).toHaveLength(2);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
describe("saveMemory", () => {
|
|
29
|
+
it("saves a new memory", async () => {
|
|
30
|
+
const client = createMockClient();
|
|
31
|
+
const memory = {
|
|
32
|
+
id: "m-new",
|
|
33
|
+
user_id: "user-1",
|
|
34
|
+
content: "New preference",
|
|
35
|
+
source: "user",
|
|
36
|
+
created_at: "2026-01-01",
|
|
37
|
+
updated_at: "2026-01-01",
|
|
38
|
+
};
|
|
39
|
+
client.mockTable("user_memories", { data: memory, error: null });
|
|
40
|
+
const store = new SupabaseMemoryStore(client);
|
|
41
|
+
const result = await store.saveMemory({
|
|
42
|
+
userId: "user-1",
|
|
43
|
+
content: "New preference",
|
|
44
|
+
source: "user",
|
|
45
|
+
});
|
|
46
|
+
expect(result.id).toBe("m-new");
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
describe("deleteMemory", () => {
|
|
50
|
+
it("deletes a memory without error", async () => {
|
|
51
|
+
const client = createMockClient();
|
|
52
|
+
client.mockTable("user_memories", { data: null, error: null });
|
|
53
|
+
const store = new SupabaseMemoryStore(client);
|
|
54
|
+
await expect(store.deleteMemory("m-1")).resolves.not.toThrow();
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
describe("searchSimilarMessages", () => {
|
|
58
|
+
it("returns matching memories via ilike fallback", async () => {
|
|
59
|
+
const client = createMockClient();
|
|
60
|
+
const memories = [
|
|
61
|
+
{ id: "m-1", content: "PE deal analysis", source: "agent" },
|
|
62
|
+
];
|
|
63
|
+
client.mockTable("user_memories", { data: memories, error: null });
|
|
64
|
+
const store = new SupabaseMemoryStore(client);
|
|
65
|
+
const result = await store.searchSimilarMessages("PE deal");
|
|
66
|
+
expect(result).toHaveLength(1);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
//# sourceMappingURL=memory-store.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-store.test.js","sourceRoot":"","sources":["../../src/stores/memory-store.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { TaskStore, TaskRecord, TaskStatus } from '@sprinterai/core';
|
|
2
|
+
import type { SupabaseClient } from '@supabase/supabase-js';
|
|
3
|
+
/** Supabase-backed implementation of TaskStore. */
|
|
4
|
+
export declare class SupabaseTaskStore implements TaskStore {
|
|
5
|
+
private client;
|
|
6
|
+
constructor(client: SupabaseClient);
|
|
7
|
+
getTask(id: string): Promise<TaskRecord | null>;
|
|
8
|
+
listTasks(options?: {
|
|
9
|
+
status?: TaskStatus;
|
|
10
|
+
assigneeId?: string;
|
|
11
|
+
entityId?: string;
|
|
12
|
+
limit?: number;
|
|
13
|
+
}): Promise<TaskRecord[]>;
|
|
14
|
+
createTask(input: Omit<TaskRecord, 'id' | 'created_at' | 'updated_at'>): Promise<TaskRecord>;
|
|
15
|
+
updateTask(id: string, input: Partial<Pick<TaskRecord, 'title' | 'description' | 'status' | 'assignee_type' | 'assignee_id' | 'metadata' | 'due_at' | 'completed_at'>>): Promise<TaskRecord>;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=task-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-store.d.ts","sourceRoot":"","sources":["../../src/stores/task-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,mDAAmD;AACnD,qBAAa,iBAAkB,YAAW,SAAS;IACrC,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,cAAc;IAEpC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAO/C,SAAS,CAAC,OAAO,CAAC,EAAE;QACxB,MAAM,CAAC,EAAE,UAAU,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAoBnB,UAAU,CACd,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,YAAY,GAAG,YAAY,CAAC,GAC1D,OAAO,CAAC,UAAU,CAAC;IAwBhB,UAAU,CACd,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,OAAO,CACZ,IAAI,CACF,UAAU,EACR,OAAO,GACP,aAAa,GACb,QAAQ,GACR,eAAe,GACf,aAAa,GACb,UAAU,GACV,QAAQ,GACR,cAAc,CACjB,CACF,GACA,OAAO,CAAC,UAAU,CAAC;CAgBvB"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/** Supabase-backed implementation of TaskStore. */
|
|
2
|
+
export class SupabaseTaskStore {
|
|
3
|
+
client;
|
|
4
|
+
constructor(client) {
|
|
5
|
+
this.client = client;
|
|
6
|
+
}
|
|
7
|
+
async getTask(id) {
|
|
8
|
+
const { data, error } = await this.client.from('tasks').select('*').eq('id', id).maybeSingle();
|
|
9
|
+
if (error)
|
|
10
|
+
throw error;
|
|
11
|
+
return data ?? null;
|
|
12
|
+
}
|
|
13
|
+
async listTasks(options) {
|
|
14
|
+
let q = this.client.from('tasks').select('*').order('created_at', { ascending: false });
|
|
15
|
+
if (options?.status) {
|
|
16
|
+
q = q.eq('status', options.status);
|
|
17
|
+
}
|
|
18
|
+
if (options?.assigneeId) {
|
|
19
|
+
q = q.eq('assignee_id', options.assigneeId);
|
|
20
|
+
}
|
|
21
|
+
if (options?.entityId) {
|
|
22
|
+
q = q.eq('entity_id', options.entityId);
|
|
23
|
+
}
|
|
24
|
+
q = q.limit(options?.limit ?? 50);
|
|
25
|
+
const { data, error } = await q;
|
|
26
|
+
if (error)
|
|
27
|
+
throw error;
|
|
28
|
+
return (data ?? []);
|
|
29
|
+
}
|
|
30
|
+
async createTask(input) {
|
|
31
|
+
const { data, error } = await this.client
|
|
32
|
+
.from('tasks')
|
|
33
|
+
.insert({
|
|
34
|
+
tenant_id: input.tenant_id,
|
|
35
|
+
title: input.title,
|
|
36
|
+
description: input.description,
|
|
37
|
+
status: input.status,
|
|
38
|
+
assignee_type: input.assignee_type,
|
|
39
|
+
assignee_id: input.assignee_id,
|
|
40
|
+
entity_id: input.entity_id,
|
|
41
|
+
parent_task_id: input.parent_task_id,
|
|
42
|
+
metadata: input.metadata,
|
|
43
|
+
due_at: input.due_at,
|
|
44
|
+
completed_at: input.completed_at,
|
|
45
|
+
created_by: input.created_by,
|
|
46
|
+
})
|
|
47
|
+
.select('*')
|
|
48
|
+
.single();
|
|
49
|
+
if (error)
|
|
50
|
+
throw error;
|
|
51
|
+
return data;
|
|
52
|
+
}
|
|
53
|
+
async updateTask(id, input) {
|
|
54
|
+
const updates = { ...input };
|
|
55
|
+
updates.updated_at = new Date().toISOString();
|
|
56
|
+
const { data, error } = await this.client
|
|
57
|
+
.from('tasks')
|
|
58
|
+
.update(updates)
|
|
59
|
+
.eq('id', id)
|
|
60
|
+
.select('*');
|
|
61
|
+
if (error)
|
|
62
|
+
throw error;
|
|
63
|
+
if (!data || data.length === 0) {
|
|
64
|
+
throw new Error('Task not found or no permission to update');
|
|
65
|
+
}
|
|
66
|
+
return data[0];
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=task-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-store.js","sourceRoot":"","sources":["../../src/stores/task-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-store.test.d.ts","sourceRoot":"","sources":["../../src/stores/task-store.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { SupabaseTaskStore } from "./task-store";
|
|
3
|
+
import { createMockClient } from "../__test-utils__/mock-supabase";
|
|
4
|
+
describe("SupabaseTaskStore", () => {
|
|
5
|
+
describe("getTask", () => {
|
|
6
|
+
it("returns task by ID", async () => {
|
|
7
|
+
const client = createMockClient();
|
|
8
|
+
const task = {
|
|
9
|
+
id: "task-1",
|
|
10
|
+
title: "Review proposal",
|
|
11
|
+
status: "pending",
|
|
12
|
+
};
|
|
13
|
+
client.mockTable("tasks", { data: task, error: null });
|
|
14
|
+
const store = new SupabaseTaskStore(client);
|
|
15
|
+
const result = await store.getTask("task-1");
|
|
16
|
+
expect(result).toEqual(task);
|
|
17
|
+
});
|
|
18
|
+
it("returns null when not found", async () => {
|
|
19
|
+
const client = createMockClient();
|
|
20
|
+
client.mockTable("tasks", { data: null, error: null });
|
|
21
|
+
const store = new SupabaseTaskStore(client);
|
|
22
|
+
const result = await store.getTask("nonexistent");
|
|
23
|
+
expect(result).toBeNull();
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
describe("listTasks", () => {
|
|
27
|
+
it("returns tasks", async () => {
|
|
28
|
+
const client = createMockClient();
|
|
29
|
+
const tasks = [
|
|
30
|
+
{ id: "task-1", status: "pending" },
|
|
31
|
+
{ id: "task-2", status: "completed" },
|
|
32
|
+
];
|
|
33
|
+
client.mockTable("tasks", { data: tasks, error: null });
|
|
34
|
+
const store = new SupabaseTaskStore(client);
|
|
35
|
+
const result = await store.listTasks();
|
|
36
|
+
expect(result).toHaveLength(2);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
describe("createTask", () => {
|
|
40
|
+
it("creates a task", async () => {
|
|
41
|
+
const client = createMockClient();
|
|
42
|
+
const task = {
|
|
43
|
+
id: "task-new",
|
|
44
|
+
title: "New task",
|
|
45
|
+
status: "pending",
|
|
46
|
+
created_at: "2026-01-01",
|
|
47
|
+
updated_at: "2026-01-01",
|
|
48
|
+
};
|
|
49
|
+
client.mockTable("tasks", { data: task, error: null });
|
|
50
|
+
const store = new SupabaseTaskStore(client);
|
|
51
|
+
const result = await store.createTask({
|
|
52
|
+
tenant_id: "t-1",
|
|
53
|
+
title: "New task",
|
|
54
|
+
description: null,
|
|
55
|
+
status: "pending",
|
|
56
|
+
assignee_type: null,
|
|
57
|
+
assignee_id: null,
|
|
58
|
+
entity_id: null,
|
|
59
|
+
parent_task_id: null,
|
|
60
|
+
metadata: null,
|
|
61
|
+
due_at: null,
|
|
62
|
+
completed_at: null,
|
|
63
|
+
created_by: "user-1",
|
|
64
|
+
});
|
|
65
|
+
expect(result.id).toBe("task-new");
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
describe("updateTask", () => {
|
|
69
|
+
it("updates a task using array pattern", async () => {
|
|
70
|
+
const client = createMockClient();
|
|
71
|
+
const updated = {
|
|
72
|
+
id: "task-1",
|
|
73
|
+
title: "Updated task",
|
|
74
|
+
status: "completed",
|
|
75
|
+
};
|
|
76
|
+
client.mockTable("tasks", { data: [updated], error: null });
|
|
77
|
+
const store = new SupabaseTaskStore(client);
|
|
78
|
+
const result = await store.updateTask("task-1", {
|
|
79
|
+
status: "completed",
|
|
80
|
+
completed_at: "2026-01-01",
|
|
81
|
+
});
|
|
82
|
+
expect(result.status).toBe("completed");
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
//# sourceMappingURL=task-store.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-store.test.js","sourceRoot":"","sources":["../../src/stores/task-store.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAEnE,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;QACvB,EAAE,CAAC,oBAAoB,EAAE,KAAK,IAAI,EAAE;YAClC,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;YAClC,MAAM,IAAI,GAAG;gBACX,EAAE,EAAE,QAAQ;gBACZ,KAAK,EAAE,iBAAiB;gBACxB,MAAM,EAAE,SAAS;aAClB,CAAC;YACF,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAEvD,MAAM,KAAK,GAAG,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAAC;YAC5C,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YAE7C,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;YAC3C,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;YAClC,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAEvD,MAAM,KAAK,GAAG,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAAC;YAC5C,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;YAElD,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;QACzB,EAAE,CAAC,eAAe,EAAE,KAAK,IAAI,EAAE;YAC7B,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;YAClC,MAAM,KAAK,GAAG;gBACZ,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE;gBACnC,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE;aACtC,CAAC;YACF,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAExD,MAAM,KAAK,GAAG,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAAC;YAC5C,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE,CAAC;YAEvC,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;QAC1B,EAAE,CAAC,gBAAgB,EAAE,KAAK,IAAI,EAAE;YAC9B,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;YAClC,MAAM,IAAI,GAAG;gBACX,EAAE,EAAE,UAAU;gBACd,KAAK,EAAE,UAAU;gBACjB,MAAM,EAAE,SAAS;gBACjB,UAAU,EAAE,YAAY;gBACxB,UAAU,EAAE,YAAY;aACzB,CAAC;YACF,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAEvD,MAAM,KAAK,GAAG,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAAC;YAC5C,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC;gBACpC,SAAS,EAAE,KAAK;gBAChB,KAAK,EAAE,UAAU;gBACjB,WAAW,EAAE,IAAI;gBACjB,MAAM,EAAE,SAAS;gBACjB,aAAa,EAAE,IAAI;gBACnB,WAAW,EAAE,IAAI;gBACjB,SAAS,EAAE,IAAI;gBACf,cAAc,EAAE,IAAI;gBACpB,QAAQ,EAAE,IAAI;gBACd,MAAM,EAAE,IAAI;gBACZ,YAAY,EAAE,IAAI;gBAClB,UAAU,EAAE,QAAQ;aACrB,CAAC,CAAC;YAEH,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;QAC1B,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;YAClD,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;YAClC,MAAM,OAAO,GAAG;gBACd,EAAE,EAAE,QAAQ;gBACZ,KAAK,EAAE,cAAc;gBACrB,MAAM,EAAE,WAAW;aACpB,CAAC;YACF,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAE5D,MAAM,KAAK,GAAG,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAAC;YAC5C,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,QAAQ,EAAE;gBAC9C,MAAM,EAAE,WAAW;gBACnB,YAAY,EAAE,YAAY;aAC3B,CAAC,CAAC;YAEH,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { TenantStore, TenantContext, AppPermission } from '@sprinterai/core';
|
|
2
|
+
import type { SupabaseClient } from '@supabase/supabase-js';
|
|
3
|
+
/** Supabase-backed implementation of TenantStore. */
|
|
4
|
+
export declare class SupabaseTenantStore implements TenantStore {
|
|
5
|
+
private client;
|
|
6
|
+
constructor(client: SupabaseClient);
|
|
7
|
+
getTenantContext(_userId: string, tenantId?: string): Promise<TenantContext>;
|
|
8
|
+
getPermissionsForRole(roleId: string): Promise<AppPermission[]>;
|
|
9
|
+
getUserPermissions(userId: string, tenantId: string): Promise<AppPermission[]>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=tenant-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-store.d.ts","sourceRoot":"","sources":["../../src/stores/tenant-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAClF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAK5D,qDAAqD;AACrD,qBAAa,mBAAoB,YAAW,WAAW;IACzC,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,cAAc;IAEpC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAQ5E,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAI/D,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;CAGrF"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { getUserPermissions, getPermissionsForRole } from '../auth/permissions';
|
|
2
|
+
import { getTenantContext } from '../tenant/context';
|
|
3
|
+
/** Supabase-backed implementation of TenantStore. */
|
|
4
|
+
export class SupabaseTenantStore {
|
|
5
|
+
client;
|
|
6
|
+
constructor(client) {
|
|
7
|
+
this.client = client;
|
|
8
|
+
}
|
|
9
|
+
async getTenantContext(_userId, tenantId) {
|
|
10
|
+
// The client is already scoped to the user session.
|
|
11
|
+
// tenantId override is passed as slug override if it looks like a slug.
|
|
12
|
+
return getTenantContext(this.client, {
|
|
13
|
+
tenantSlugOverride: tenantId,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
async getPermissionsForRole(roleId) {
|
|
17
|
+
return getPermissionsForRole(this.client, roleId);
|
|
18
|
+
}
|
|
19
|
+
async getUserPermissions(userId, tenantId) {
|
|
20
|
+
return getUserPermissions(this.client, userId, tenantId);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=tenant-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-store.js","sourceRoot":"","sources":["../../src/stores/tenant-store.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,qDAAqD;AACrD,MAAM,OAAO,mBAAmB;IACV;IAApB,YAAoB,MAAsB;QAAtB,WAAM,GAAN,MAAM,CAAgB;IAAG,CAAC;IAE9C,KAAK,CAAC,gBAAgB,CAAC,OAAe,EAAE,QAAiB;QACvD,oDAAoD;QACpD,wEAAwE;QACxE,OAAO,gBAAgB,CAAC,IAAI,CAAC,MAAM,EAAE;YACnC,kBAAkB,EAAE,QAAQ;SAC7B,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,qBAAqB,CAAC,MAAc;QACxC,OAAO,qBAAqB,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpD,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,MAAc,EAAE,QAAgB;QACvD,OAAO,kBAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC3D,CAAC;CACF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ToolStore, ToolRun } from '@sprinterai/core';
|
|
2
|
+
import type { SupabaseClient } from '@supabase/supabase-js';
|
|
3
|
+
/** Supabase-backed implementation of ToolStore. */
|
|
4
|
+
export declare class SupabaseToolStore implements ToolStore {
|
|
5
|
+
private client;
|
|
6
|
+
constructor(client: SupabaseClient);
|
|
7
|
+
recordToolRun(run: Omit<ToolRun, 'id' | 'created_at'>): Promise<ToolRun>;
|
|
8
|
+
getToolRuns(options: {
|
|
9
|
+
toolSlug?: string;
|
|
10
|
+
userId?: string;
|
|
11
|
+
chatId?: string;
|
|
12
|
+
sessionId?: string;
|
|
13
|
+
limit?: number;
|
|
14
|
+
}): Promise<ToolRun[]>;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=tool-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-store.d.ts","sourceRoot":"","sources":["../../src/stores/tool-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,mDAAmD;AACnD,qBAAa,iBAAkB,YAAW,SAAS;IACrC,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,cAAc;IAEpC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,GAAG,YAAY,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAuBxE,WAAW,CAAC,OAAO,EAAE;QACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;CAsBvB"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/** Supabase-backed implementation of ToolStore. */
|
|
2
|
+
export class SupabaseToolStore {
|
|
3
|
+
client;
|
|
4
|
+
constructor(client) {
|
|
5
|
+
this.client = client;
|
|
6
|
+
}
|
|
7
|
+
async recordToolRun(run) {
|
|
8
|
+
const { data, error } = await this.client
|
|
9
|
+
.from('tool_runs')
|
|
10
|
+
.insert({
|
|
11
|
+
tenant_id: run.tenant_id,
|
|
12
|
+
tool_slug: run.tool_slug,
|
|
13
|
+
user_id: run.user_id,
|
|
14
|
+
input: run.input,
|
|
15
|
+
output: run.output,
|
|
16
|
+
status: run.status,
|
|
17
|
+
error: run.error,
|
|
18
|
+
duration_ms: run.duration_ms,
|
|
19
|
+
source: run.source,
|
|
20
|
+
chat_id: run.chat_id,
|
|
21
|
+
session_id: run.session_id,
|
|
22
|
+
})
|
|
23
|
+
.select('*')
|
|
24
|
+
.single();
|
|
25
|
+
if (error)
|
|
26
|
+
throw error;
|
|
27
|
+
return data;
|
|
28
|
+
}
|
|
29
|
+
async getToolRuns(options) {
|
|
30
|
+
let q = this.client.from('tool_runs').select('*').order('created_at', { ascending: false });
|
|
31
|
+
if (options.toolSlug) {
|
|
32
|
+
q = q.eq('tool_slug', options.toolSlug);
|
|
33
|
+
}
|
|
34
|
+
if (options.userId) {
|
|
35
|
+
q = q.eq('user_id', options.userId);
|
|
36
|
+
}
|
|
37
|
+
if (options.chatId) {
|
|
38
|
+
q = q.eq('chat_id', options.chatId);
|
|
39
|
+
}
|
|
40
|
+
if (options.sessionId) {
|
|
41
|
+
q = q.eq('session_id', options.sessionId);
|
|
42
|
+
}
|
|
43
|
+
q = q.limit(options.limit ?? 50);
|
|
44
|
+
const { data, error } = await q;
|
|
45
|
+
if (error)
|
|
46
|
+
throw error;
|
|
47
|
+
return (data ?? []);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=tool-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-store.js","sourceRoot":"","sources":["../../src/stores/tool-store.ts"],"names":[],"mappings":"AAGA,mDAAmD;AACnD,MAAM,OAAO,iBAAiB;IACR;IAApB,YAAoB,MAAsB;QAAtB,WAAM,GAAN,MAAM,CAAgB;IAAG,CAAC;IAE9C,KAAK,CAAC,aAAa,CAAC,GAAuC;QACzD,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM;aACtC,IAAI,CAAC,WAAW,CAAC;aACjB,MAAM,CAAC;YACN,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,UAAU,EAAE,GAAG,CAAC,UAAU;SAC3B,CAAC;aACD,MAAM,CAAC,GAAG,CAAC;aACX,MAAM,EAAE,CAAC;QAEZ,IAAI,KAAK;YAAE,MAAM,KAAK,CAAC;QACvB,OAAO,IAAe,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAMjB;QACC,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QAE5F,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACrB,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,WAAW,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC1C,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACtC,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACtC,CAAC;QACD,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;YACtB,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QAC5C,CAAC;QAED,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QAEjC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,CAAC;QAChC,IAAI,KAAK;YAAE,MAAM,KAAK,CAAC;QACvB,OAAO,CAAC,IAAI,IAAI,EAAE,CAAc,CAAC;IACnC,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-store.test.d.ts","sourceRoot":"","sources":["../../src/stores/tool-store.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { SupabaseToolStore } from "./tool-store";
|
|
3
|
+
import { createMockClient } from "../__test-utils__/mock-supabase";
|
|
4
|
+
describe("SupabaseToolStore", () => {
|
|
5
|
+
describe("recordToolRun", () => {
|
|
6
|
+
it("inserts a tool run and returns it", async () => {
|
|
7
|
+
const client = createMockClient();
|
|
8
|
+
const run = {
|
|
9
|
+
id: "tr-1",
|
|
10
|
+
tenant_id: "t-1",
|
|
11
|
+
tool_slug: "web-search",
|
|
12
|
+
user_id: "user-1",
|
|
13
|
+
input: { query: "test" },
|
|
14
|
+
output: { results: [] },
|
|
15
|
+
status: "success",
|
|
16
|
+
error: null,
|
|
17
|
+
duration_ms: 150,
|
|
18
|
+
source: "web",
|
|
19
|
+
chat_id: null,
|
|
20
|
+
session_id: null,
|
|
21
|
+
created_at: "2026-01-01",
|
|
22
|
+
};
|
|
23
|
+
client.mockTable("tool_runs", { data: run, error: null });
|
|
24
|
+
const store = new SupabaseToolStore(client);
|
|
25
|
+
const result = await store.recordToolRun({
|
|
26
|
+
tenant_id: "t-1",
|
|
27
|
+
tool_slug: "web-search",
|
|
28
|
+
user_id: "user-1",
|
|
29
|
+
input: { query: "test" },
|
|
30
|
+
output: { results: [] },
|
|
31
|
+
status: "success",
|
|
32
|
+
error: null,
|
|
33
|
+
duration_ms: 150,
|
|
34
|
+
source: "web",
|
|
35
|
+
chat_id: null,
|
|
36
|
+
session_id: null,
|
|
37
|
+
});
|
|
38
|
+
expect(result.id).toBe("tr-1");
|
|
39
|
+
expect(result.tool_slug).toBe("web-search");
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
describe("getToolRuns", () => {
|
|
43
|
+
it("returns tool runs", async () => {
|
|
44
|
+
const client = createMockClient();
|
|
45
|
+
const runs = [
|
|
46
|
+
{ id: "tr-1", tool_slug: "web-search" },
|
|
47
|
+
{ id: "tr-2", tool_slug: "web-search" },
|
|
48
|
+
];
|
|
49
|
+
client.mockTable("tool_runs", { data: runs, error: null });
|
|
50
|
+
const store = new SupabaseToolStore(client);
|
|
51
|
+
const result = await store.getToolRuns({ toolSlug: "web-search" });
|
|
52
|
+
expect(result).toHaveLength(2);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
//# sourceMappingURL=tool-store.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-store.test.js","sourceRoot":"","sources":["../../src/stores/tool-store.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAEnE,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;QAC7B,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;YACjD,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;YAClC,MAAM,GAAG,GAAG;gBACV,EAAE,EAAE,MAAM;gBACV,SAAS,EAAE,KAAK;gBAChB,SAAS,EAAE,YAAY;gBACvB,OAAO,EAAE,QAAQ;gBACjB,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE;gBACxB,MAAM,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;gBACvB,MAAM,EAAE,SAAS;gBACjB,KAAK,EAAE,IAAI;gBACX,WAAW,EAAE,GAAG;gBAChB,MAAM,EAAE,KAAK;gBACb,OAAO,EAAE,IAAI;gBACb,UAAU,EAAE,IAAI;gBAChB,UAAU,EAAE,YAAY;aACzB,CAAC;YACF,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAE1D,MAAM,KAAK,GAAG,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAAC;YAC5C,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,aAAa,CAAC;gBACvC,SAAS,EAAE,KAAK;gBAChB,SAAS,EAAE,YAAY;gBACvB,OAAO,EAAE,QAAQ;gBACjB,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE;gBACxB,MAAM,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;gBACvB,MAAM,EAAE,SAAS;gBACjB,KAAK,EAAE,IAAI;gBACX,WAAW,EAAE,GAAG;gBAChB,MAAM,EAAE,KAAK;gBACb,OAAO,EAAE,IAAI;gBACb,UAAU,EAAE,IAAI;aACjB,CAAC,CAAC;YAEH,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC/B,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;QAC3B,EAAE,CAAC,mBAAmB,EAAE,KAAK,IAAI,EAAE;YACjC,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;YAClC,MAAM,IAAI,GAAG;gBACX,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE;gBACvC,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE;aACxC,CAAC;YACF,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAE3D,MAAM,KAAK,GAAG,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAAC;YAC5C,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,WAAW,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC;YAEnE,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ViewStore, ViewRecord } from '@sprinterai/core';
|
|
2
|
+
import type { SupabaseClient } from '@supabase/supabase-js';
|
|
3
|
+
/** Supabase-backed implementation of ViewStore. */
|
|
4
|
+
export declare class SupabaseViewStore implements ViewStore {
|
|
5
|
+
private client;
|
|
6
|
+
constructor(client: SupabaseClient);
|
|
7
|
+
getView(idOrSlug: string): Promise<ViewRecord | null>;
|
|
8
|
+
getDefaultView(entityTypeSlug: string, layout?: string): Promise<ViewRecord | null>;
|
|
9
|
+
listViews(options?: {
|
|
10
|
+
entityTypeSlug?: string;
|
|
11
|
+
layout?: string;
|
|
12
|
+
}): Promise<ViewRecord[]>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=view-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view-store.d.ts","sourceRoot":"","sources":["../../src/stores/view-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,mDAAmD;AACnD,qBAAa,iBAAkB,YAAW,SAAS;IACrC,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,cAAc;IAEpC,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAmBrD,cAAc,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAiBnF,SAAS,CAAC,OAAO,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;CAc/F"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/** Supabase-backed implementation of ViewStore. */
|
|
2
|
+
export class SupabaseViewStore {
|
|
3
|
+
client;
|
|
4
|
+
constructor(client) {
|
|
5
|
+
this.client = client;
|
|
6
|
+
}
|
|
7
|
+
async getView(idOrSlug) {
|
|
8
|
+
// Try by slug first, then by ID
|
|
9
|
+
const { data: bySlug } = await this.client
|
|
10
|
+
.from('views')
|
|
11
|
+
.select('*')
|
|
12
|
+
.eq('slug', idOrSlug)
|
|
13
|
+
.maybeSingle();
|
|
14
|
+
if (bySlug)
|
|
15
|
+
return bySlug;
|
|
16
|
+
const { data: byId } = await this.client
|
|
17
|
+
.from('views')
|
|
18
|
+
.select('*')
|
|
19
|
+
.eq('id', idOrSlug)
|
|
20
|
+
.maybeSingle();
|
|
21
|
+
return byId ?? null;
|
|
22
|
+
}
|
|
23
|
+
async getDefaultView(entityTypeSlug, layout) {
|
|
24
|
+
let q = this.client
|
|
25
|
+
.from('views')
|
|
26
|
+
.select('*')
|
|
27
|
+
.eq('entity_type_slug', entityTypeSlug)
|
|
28
|
+
.eq('is_default', true);
|
|
29
|
+
if (layout) {
|
|
30
|
+
q = q.eq('layout', layout);
|
|
31
|
+
}
|
|
32
|
+
const { data, error } = await q.limit(1).maybeSingle();
|
|
33
|
+
if (error)
|
|
34
|
+
throw error;
|
|
35
|
+
return data ?? null;
|
|
36
|
+
}
|
|
37
|
+
async listViews(options) {
|
|
38
|
+
let q = this.client.from('views').select('*').order('name');
|
|
39
|
+
if (options?.entityTypeSlug) {
|
|
40
|
+
q = q.eq('entity_type_slug', options.entityTypeSlug);
|
|
41
|
+
}
|
|
42
|
+
if (options?.layout) {
|
|
43
|
+
q = q.eq('layout', options.layout);
|
|
44
|
+
}
|
|
45
|
+
const { data, error } = await q;
|
|
46
|
+
if (error)
|
|
47
|
+
throw error;
|
|
48
|
+
return (data ?? []);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=view-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view-store.js","sourceRoot":"","sources":["../../src/stores/view-store.ts"],"names":[],"mappings":"AAGA,mDAAmD;AACnD,MAAM,OAAO,iBAAiB;IACR;IAApB,YAAoB,MAAsB;QAAtB,WAAM,GAAN,MAAM,CAAgB;IAAG,CAAC;IAE9C,KAAK,CAAC,OAAO,CAAC,QAAgB;QAC5B,gCAAgC;QAChC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM;aACvC,IAAI,CAAC,OAAO,CAAC;aACb,MAAM,CAAC,GAAG,CAAC;aACX,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC;aACpB,WAAW,EAAE,CAAC;QAEjB,IAAI,MAAM;YAAE,OAAO,MAAoB,CAAC;QAExC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM;aACrC,IAAI,CAAC,OAAO,CAAC;aACb,MAAM,CAAC,GAAG,CAAC;aACX,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC;aAClB,WAAW,EAAE,CAAC;QAEjB,OAAQ,IAAmB,IAAI,IAAI,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,cAAsB,EAAE,MAAe;QAC1D,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM;aAChB,IAAI,CAAC,OAAO,CAAC;aACb,MAAM,CAAC,GAAG,CAAC;aACX,EAAE,CAAC,kBAAkB,EAAE,cAAc,CAAC;aACtC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;QAE1B,IAAI,MAAM,EAAE,CAAC;YACX,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC7B,CAAC;QAED,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QAEvD,IAAI,KAAK;YAAE,MAAM,KAAK,CAAC;QACvB,OAAQ,IAAmB,IAAI,IAAI,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,OAAsD;QACpE,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAE5D,IAAI,OAAO,EAAE,cAAc,EAAE,CAAC;YAC5B,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,kBAAkB,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;QACvD,CAAC;QACD,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;YACpB,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACrC,CAAC;QAED,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,CAAC;QAChC,IAAI,KAAK;YAAE,MAAM,KAAK,CAAC;QACvB,OAAO,CAAC,IAAI,IAAI,EAAE,CAAiB,CAAC;IACtC,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view-store.test.d.ts","sourceRoot":"","sources":["../../src/stores/view-store.test.ts"],"names":[],"mappings":""}
|