@btst/stack 2.1.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/index.cjs +9 -1
- package/dist/api/index.d.cts +4 -4
- package/dist/api/index.d.mts +4 -4
- package/dist/api/index.d.ts +4 -4
- package/dist/api/index.mjs +9 -1
- package/dist/client/index.d.cts +2 -2
- package/dist/client/index.d.mts +2 -2
- package/dist/client/index.d.ts +2 -2
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/packages/stack/src/plugins/ai-chat/api/getters.cjs +42 -0
- package/dist/packages/stack/src/plugins/ai-chat/api/getters.mjs +39 -0
- package/dist/packages/stack/src/plugins/ai-chat/api/plugin.cjs +5 -0
- package/dist/packages/stack/src/plugins/ai-chat/api/plugin.mjs +5 -0
- package/dist/packages/stack/src/plugins/blog/api/getters.cjs +131 -0
- package/dist/packages/stack/src/plugins/blog/api/getters.mjs +127 -0
- package/dist/packages/stack/src/plugins/blog/api/plugin.cjs +60 -107
- package/dist/packages/stack/src/plugins/blog/api/plugin.mjs +60 -107
- package/dist/packages/stack/src/plugins/blog/api/query-key-defs.cjs +18 -0
- package/dist/packages/stack/src/plugins/blog/api/query-key-defs.mjs +15 -0
- package/dist/packages/stack/src/plugins/blog/api/serializers.cjs +21 -0
- package/dist/packages/stack/src/plugins/blog/api/serializers.mjs +18 -0
- package/dist/packages/stack/src/plugins/blog/client/plugin.cjs +16 -1
- package/dist/packages/stack/src/plugins/blog/client/plugin.mjs +17 -2
- package/dist/packages/stack/src/plugins/cms/api/getters.cjs +156 -0
- package/dist/packages/stack/src/plugins/cms/api/getters.mjs +147 -0
- package/dist/packages/stack/src/plugins/cms/api/plugin.cjs +624 -617
- package/dist/packages/stack/src/plugins/cms/api/plugin.mjs +623 -616
- package/dist/packages/stack/src/plugins/cms/api/query-key-defs.cjs +29 -0
- package/dist/packages/stack/src/plugins/cms/api/query-key-defs.mjs +26 -0
- package/dist/packages/stack/src/plugins/cms/client/components/pages/content-editor-page.internal.cjs +1 -1
- package/dist/packages/stack/src/plugins/cms/client/components/pages/content-editor-page.internal.mjs +1 -1
- package/dist/packages/stack/src/plugins/cms/client/hooks/cms-hooks.cjs +6 -3
- package/dist/packages/stack/src/plugins/cms/client/hooks/cms-hooks.mjs +6 -3
- package/dist/packages/stack/src/plugins/cms/client/plugin.cjs +15 -0
- package/dist/packages/stack/src/plugins/cms/client/plugin.mjs +16 -1
- package/dist/packages/stack/src/plugins/form-builder/api/getters.cjs +120 -0
- package/dist/packages/stack/src/plugins/form-builder/api/getters.mjs +112 -0
- package/dist/packages/stack/src/plugins/form-builder/api/plugin.cjs +75 -86
- package/dist/packages/stack/src/plugins/form-builder/api/plugin.mjs +71 -82
- package/dist/packages/stack/src/plugins/form-builder/api/query-key-defs.cjs +37 -0
- package/dist/packages/stack/src/plugins/form-builder/api/query-key-defs.mjs +33 -0
- package/dist/packages/stack/src/plugins/form-builder/client/components/pages/submissions-page.internal.cjs +1 -1
- package/dist/packages/stack/src/plugins/form-builder/client/components/pages/submissions-page.internal.mjs +1 -1
- package/dist/packages/stack/src/plugins/form-builder/client/plugin.cjs +15 -0
- package/dist/packages/stack/src/plugins/form-builder/client/plugin.mjs +16 -1
- package/dist/packages/stack/src/plugins/kanban/api/getters.cjs +84 -0
- package/dist/packages/stack/src/plugins/kanban/api/getters.mjs +81 -0
- package/dist/packages/stack/src/plugins/kanban/api/plugin.cjs +37 -123
- package/dist/packages/stack/src/plugins/kanban/api/plugin.mjs +37 -123
- package/dist/packages/stack/src/plugins/kanban/api/query-key-defs.cjs +26 -0
- package/dist/packages/stack/src/plugins/kanban/api/query-key-defs.mjs +23 -0
- package/dist/packages/stack/src/plugins/kanban/api/serializers.cjs +30 -0
- package/dist/packages/stack/src/plugins/kanban/api/serializers.mjs +26 -0
- package/dist/packages/stack/src/plugins/kanban/client/plugin.cjs +11 -1
- package/dist/packages/stack/src/plugins/kanban/client/plugin.mjs +12 -2
- package/dist/packages/stack/src/plugins/utils.cjs +6 -0
- package/dist/packages/stack/src/plugins/utils.mjs +6 -1
- package/dist/plugins/ai-chat/api/index.cjs +3 -0
- package/dist/plugins/ai-chat/api/index.d.cts +27 -4
- package/dist/plugins/ai-chat/api/index.d.mts +27 -4
- package/dist/plugins/ai-chat/api/index.d.ts +27 -4
- package/dist/plugins/ai-chat/api/index.mjs +1 -0
- package/dist/plugins/ai-chat/client/hooks/index.d.cts +2 -2
- package/dist/plugins/ai-chat/client/hooks/index.d.mts +2 -2
- package/dist/plugins/ai-chat/client/hooks/index.d.ts +2 -2
- package/dist/plugins/ai-chat/query-keys.d.cts +9 -284
- package/dist/plugins/ai-chat/query-keys.d.mts +9 -284
- package/dist/plugins/ai-chat/query-keys.d.ts +9 -284
- package/dist/plugins/api/index.d.cts +4 -3
- package/dist/plugins/api/index.d.mts +4 -3
- package/dist/plugins/api/index.d.ts +4 -3
- package/dist/plugins/blog/api/index.cjs +9 -0
- package/dist/plugins/blog/api/index.d.cts +20 -4
- package/dist/plugins/blog/api/index.d.mts +20 -4
- package/dist/plugins/blog/api/index.d.ts +20 -4
- package/dist/plugins/blog/api/index.mjs +3 -0
- package/dist/plugins/blog/client/hooks/index.d.cts +5 -5
- package/dist/plugins/blog/client/hooks/index.d.mts +5 -5
- package/dist/plugins/blog/client/hooks/index.d.ts +5 -5
- package/dist/plugins/blog/client/index.d.cts +1 -1
- package/dist/plugins/blog/client/index.d.mts +1 -1
- package/dist/plugins/blog/client/index.d.ts +1 -1
- package/dist/plugins/blog/query-keys.cjs +13 -9
- package/dist/plugins/blog/query-keys.d.cts +8 -333
- package/dist/plugins/blog/query-keys.d.mts +8 -333
- package/dist/plugins/blog/query-keys.d.ts +8 -333
- package/dist/plugins/blog/query-keys.mjs +13 -9
- package/dist/plugins/client/index.cjs +1 -0
- package/dist/plugins/client/index.d.cts +10 -3
- package/dist/plugins/client/index.d.mts +10 -3
- package/dist/plugins/client/index.d.ts +10 -3
- package/dist/plugins/client/index.mjs +1 -1
- package/dist/plugins/cms/api/index.cjs +10 -0
- package/dist/plugins/cms/api/index.d.cts +7 -163
- package/dist/plugins/cms/api/index.d.mts +7 -163
- package/dist/plugins/cms/api/index.d.ts +7 -163
- package/dist/plugins/cms/api/index.mjs +2 -0
- package/dist/plugins/cms/client/hooks/index.d.cts +1 -1
- package/dist/plugins/cms/client/hooks/index.d.mts +1 -1
- package/dist/plugins/cms/client/hooks/index.d.ts +1 -1
- package/dist/plugins/cms/query-keys.cjs +2 -1
- package/dist/plugins/cms/query-keys.d.cts +6 -9
- package/dist/plugins/cms/query-keys.d.mts +6 -9
- package/dist/plugins/cms/query-keys.d.ts +6 -9
- package/dist/plugins/cms/query-keys.mjs +2 -1
- package/dist/plugins/form-builder/api/index.cjs +10 -0
- package/dist/plugins/form-builder/api/index.d.cts +7 -141
- package/dist/plugins/form-builder/api/index.d.mts +7 -141
- package/dist/plugins/form-builder/api/index.d.ts +7 -141
- package/dist/plugins/form-builder/api/index.mjs +2 -0
- package/dist/plugins/form-builder/client/components/index.d.cts +1 -1
- package/dist/plugins/form-builder/client/components/index.d.mts +1 -1
- package/dist/plugins/form-builder/client/components/index.d.ts +1 -1
- package/dist/plugins/form-builder/client/hooks/index.d.cts +1 -1
- package/dist/plugins/form-builder/client/hooks/index.d.mts +1 -1
- package/dist/plugins/form-builder/client/hooks/index.d.ts +1 -1
- package/dist/plugins/form-builder/query-keys.cjs +3 -2
- package/dist/plugins/form-builder/query-keys.d.cts +7 -6
- package/dist/plugins/form-builder/query-keys.d.mts +7 -6
- package/dist/plugins/form-builder/query-keys.d.ts +7 -6
- package/dist/plugins/form-builder/query-keys.mjs +3 -2
- package/dist/plugins/kanban/api/index.cjs +9 -0
- package/dist/plugins/kanban/api/index.d.cts +17 -395
- package/dist/plugins/kanban/api/index.d.mts +17 -395
- package/dist/plugins/kanban/api/index.d.ts +17 -395
- package/dist/plugins/kanban/api/index.mjs +3 -0
- package/dist/plugins/kanban/client/components/index.d.cts +1 -1
- package/dist/plugins/kanban/client/components/index.d.mts +1 -1
- package/dist/plugins/kanban/client/components/index.d.ts +1 -1
- package/dist/plugins/kanban/client/hooks/index.d.cts +1 -1
- package/dist/plugins/kanban/client/hooks/index.d.mts +1 -1
- package/dist/plugins/kanban/client/hooks/index.d.ts +1 -1
- package/dist/plugins/kanban/client/index.d.cts +1 -1
- package/dist/plugins/kanban/client/index.d.mts +1 -1
- package/dist/plugins/kanban/client/index.d.ts +1 -1
- package/dist/plugins/kanban/query-keys.cjs +6 -12
- package/dist/plugins/kanban/query-keys.d.cts +5 -16
- package/dist/plugins/kanban/query-keys.d.mts +5 -16
- package/dist/plugins/kanban/query-keys.d.ts +5 -16
- package/dist/plugins/kanban/query-keys.mjs +6 -12
- package/dist/plugins/open-api/api/index.d.cts +2 -2
- package/dist/plugins/open-api/api/index.d.mts +2 -2
- package/dist/plugins/open-api/api/index.d.ts +2 -2
- package/dist/plugins/route-docs/client/index.d.cts +1 -1
- package/dist/plugins/route-docs/client/index.d.mts +1 -1
- package/dist/plugins/route-docs/client/index.d.ts +1 -1
- package/dist/plugins/ui-builder/index.d.cts +1 -1
- package/dist/plugins/ui-builder/index.d.mts +1 -1
- package/dist/plugins/ui-builder/index.d.ts +1 -1
- package/dist/shared/{stack.BoA0xkJv.d.cts → stack.7n9Y_u7N.d.cts} +33 -7
- package/dist/shared/{stack.BoA0xkJv.d.mts → stack.7n9Y_u7N.d.mts} +33 -7
- package/dist/shared/{stack.BoA0xkJv.d.ts → stack.7n9Y_u7N.d.ts} +33 -7
- package/dist/shared/stack.B1EeBt1b.d.ts +297 -0
- package/dist/shared/stack.BIXEI6v_.d.mts +419 -0
- package/dist/shared/stack.BKfolAyK.d.ts +419 -0
- package/dist/shared/stack.BeSm90va.d.ts +289 -0
- package/dist/shared/stack.BpolpQpf.d.cts +445 -0
- package/dist/shared/stack.C5dtIncc.d.mts +293 -0
- package/dist/shared/stack.CIP6QS9l.d.ts +293 -0
- package/dist/shared/stack.CMh_EdxW.d.cts +289 -0
- package/dist/shared/stack.CP68pFEH.d.mts +297 -0
- package/dist/shared/{stack.BsXokfNh.d.mts → stack.CVDTkMoO.d.cts} +8 -2
- package/dist/shared/{stack.BsXokfNh.d.ts → stack.CVDTkMoO.d.mts} +8 -2
- package/dist/shared/{stack.BsXokfNh.d.cts → stack.CVDTkMoO.d.ts} +8 -2
- package/dist/shared/{stack.DKDMI-QO.d.mts → stack.DJaKVY7v.d.cts} +7 -1
- package/dist/shared/{stack.DKDMI-QO.d.ts → stack.DJaKVY7v.d.mts} +7 -1
- package/dist/shared/{stack.DKDMI-QO.d.cts → stack.DJaKVY7v.d.ts} +7 -1
- package/dist/shared/{stack.DzH_wcvr.d.mts → stack.DdI5W6MB.d.cts} +9 -3
- package/dist/shared/{stack.DzH_wcvr.d.ts → stack.DdI5W6MB.d.mts} +9 -3
- package/dist/shared/{stack.DzH_wcvr.d.cts → stack.DdI5W6MB.d.ts} +9 -3
- package/dist/shared/stack.Dg09R0oB.d.mts +289 -0
- package/dist/shared/stack.Dw0Ly2TM.d.cts +293 -0
- package/dist/shared/stack.IdtKDRka.d.cts +297 -0
- package/dist/shared/stack.TIBF2AOx.d.ts +445 -0
- package/dist/shared/stack.rTy7-wQU.d.mts +445 -0
- package/dist/shared/stack.snB1EDP7.d.cts +419 -0
- package/package.json +3 -3
- package/src/__tests__/stack-api.test.ts +118 -0
- package/src/api/index.ts +15 -1
- package/src/plugins/ai-chat/__tests__/getters.test.ts +109 -0
- package/src/plugins/ai-chat/api/getters.ts +71 -0
- package/src/plugins/ai-chat/api/index.ts +1 -0
- package/src/plugins/ai-chat/api/plugin.ts +8 -0
- package/src/plugins/api/index.ts +3 -1
- package/src/plugins/blog/__tests__/getters.test.ts +540 -0
- package/src/plugins/blog/api/getters.ts +243 -0
- package/src/plugins/blog/api/index.ts +9 -0
- package/src/plugins/blog/api/plugin.ts +98 -141
- package/src/plugins/blog/api/query-key-defs.ts +46 -0
- package/src/plugins/blog/api/serializers.ts +27 -0
- package/src/plugins/blog/client/plugin.tsx +21 -1
- package/src/plugins/blog/query-keys.ts +21 -20
- package/src/plugins/client/index.ts +1 -1
- package/src/plugins/cms/__tests__/getters.test.ts +206 -0
- package/src/plugins/cms/api/getters.ts +268 -0
- package/src/plugins/cms/api/index.ts +15 -1
- package/src/plugins/cms/api/plugin.ts +151 -150
- package/src/plugins/cms/api/query-key-defs.ts +53 -0
- package/src/plugins/cms/api/serializers.ts +12 -0
- package/src/plugins/cms/client/components/pages/content-editor-page.internal.tsx +1 -1
- package/src/plugins/cms/client/hooks/cms-hooks.tsx +3 -0
- package/src/plugins/cms/client/plugin.tsx +19 -0
- package/src/plugins/cms/query-keys.ts +2 -1
- package/src/plugins/cms/types.ts +1 -1
- package/src/plugins/form-builder/__tests__/getters.test.ts +159 -0
- package/src/plugins/form-builder/api/getters.ts +226 -0
- package/src/plugins/form-builder/api/index.ts +15 -1
- package/src/plugins/form-builder/api/plugin.ts +107 -109
- package/src/plugins/form-builder/api/query-key-defs.ts +79 -0
- package/src/plugins/form-builder/api/serializers.ts +12 -0
- package/src/plugins/form-builder/client/components/pages/submissions-page.internal.tsx +1 -1
- package/src/plugins/form-builder/client/plugin.tsx +19 -0
- package/src/plugins/form-builder/query-keys.ts +6 -2
- package/src/plugins/form-builder/types.ts +2 -2
- package/src/plugins/kanban/__tests__/getters.test.ts +172 -0
- package/src/plugins/kanban/api/getters.ts +149 -0
- package/src/plugins/kanban/api/index.ts +4 -0
- package/src/plugins/kanban/api/plugin.ts +65 -146
- package/src/plugins/kanban/api/query-key-defs.ts +54 -0
- package/src/plugins/kanban/api/serializers.ts +49 -0
- package/src/plugins/kanban/client/plugin.tsx +15 -1
- package/src/plugins/kanban/query-keys.ts +10 -14
- package/src/plugins/utils.ts +19 -0
- package/src/types.ts +44 -5
- package/dist/shared/{stack.CbuN2zVV.d.cts → stack.CBON0dWL.d.cts} +7 -7
- package/dist/shared/{stack.CbuN2zVV.d.mts → stack.CBON0dWL.d.mts} +7 -7
- package/dist/shared/{stack.CbuN2zVV.d.ts → stack.CBON0dWL.d.ts} +7 -7
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from "vitest";
|
|
2
|
+
import { createMemoryAdapter } from "@btst/adapter-memory";
|
|
3
|
+
import { defineDb } from "@btst/db";
|
|
4
|
+
import type { Adapter } from "@btst/db";
|
|
5
|
+
import { aiChatSchema } from "../db";
|
|
6
|
+
import { getAllConversations, getConversationById } from "../api/getters";
|
|
7
|
+
|
|
8
|
+
const createTestAdapter = (): Adapter => {
|
|
9
|
+
const db = defineDb({}).use(aiChatSchema);
|
|
10
|
+
return createMemoryAdapter(db)({});
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
async function createConversation(
|
|
14
|
+
adapter: Adapter,
|
|
15
|
+
title: string,
|
|
16
|
+
userId?: string,
|
|
17
|
+
): Promise<any> {
|
|
18
|
+
return adapter.create({
|
|
19
|
+
model: "conversation",
|
|
20
|
+
data: {
|
|
21
|
+
title,
|
|
22
|
+
...(userId ? { userId } : {}),
|
|
23
|
+
createdAt: new Date(),
|
|
24
|
+
updatedAt: new Date(),
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
describe("ai-chat getters", () => {
|
|
30
|
+
let adapter: Adapter;
|
|
31
|
+
|
|
32
|
+
beforeEach(() => {
|
|
33
|
+
adapter = createTestAdapter();
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
describe("getAllConversations", () => {
|
|
37
|
+
it("returns empty array when no conversations exist", async () => {
|
|
38
|
+
const convs = await getAllConversations(adapter);
|
|
39
|
+
expect(convs).toEqual([]);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it("returns all conversations sorted by updatedAt desc", async () => {
|
|
43
|
+
await createConversation(adapter, "First");
|
|
44
|
+
await createConversation(adapter, "Second");
|
|
45
|
+
|
|
46
|
+
const convs = await getAllConversations(adapter);
|
|
47
|
+
expect(convs).toHaveLength(2);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("filters conversations by userId", async () => {
|
|
51
|
+
await createConversation(adapter, "Alice Conv", "user-alice");
|
|
52
|
+
await createConversation(adapter, "Bob Conv", "user-bob");
|
|
53
|
+
await createConversation(adapter, "No User Conv");
|
|
54
|
+
|
|
55
|
+
const aliceConvs = await getAllConversations(adapter, "user-alice");
|
|
56
|
+
expect(aliceConvs).toHaveLength(1);
|
|
57
|
+
expect(aliceConvs[0]!.title).toBe("Alice Conv");
|
|
58
|
+
|
|
59
|
+
const allConvs = await getAllConversations(adapter);
|
|
60
|
+
expect(allConvs).toHaveLength(3);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
describe("getConversationById", () => {
|
|
65
|
+
it("returns null when conversation does not exist", async () => {
|
|
66
|
+
const conv = await getConversationById(adapter, "nonexistent");
|
|
67
|
+
expect(conv).toBeNull();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it("returns conversation with messages", async () => {
|
|
71
|
+
const conv = (await createConversation(adapter, "My Chat")) as any;
|
|
72
|
+
|
|
73
|
+
await adapter.create({
|
|
74
|
+
model: "message",
|
|
75
|
+
data: {
|
|
76
|
+
conversationId: conv.id,
|
|
77
|
+
role: "user",
|
|
78
|
+
content: JSON.stringify([{ type: "text", text: "Hello!" }]),
|
|
79
|
+
createdAt: new Date(Date.now() - 1000),
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
await adapter.create({
|
|
83
|
+
model: "message",
|
|
84
|
+
data: {
|
|
85
|
+
conversationId: conv.id,
|
|
86
|
+
role: "assistant",
|
|
87
|
+
content: JSON.stringify([{ type: "text", text: "Hi there!" }]),
|
|
88
|
+
createdAt: new Date(),
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
const result = await getConversationById(adapter, conv.id);
|
|
93
|
+
expect(result).not.toBeNull();
|
|
94
|
+
expect(result!.id).toBe(conv.id);
|
|
95
|
+
expect(result!.title).toBe("My Chat");
|
|
96
|
+
expect(result!.messages).toHaveLength(2);
|
|
97
|
+
expect(result!.messages[0]!.role).toBe("user");
|
|
98
|
+
expect(result!.messages[1]!.role).toBe("assistant");
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it("returns conversation with empty messages array if none exist", async () => {
|
|
102
|
+
const conv = (await createConversation(adapter, "Empty Chat")) as any;
|
|
103
|
+
|
|
104
|
+
const result = await getConversationById(adapter, conv.id);
|
|
105
|
+
expect(result).not.toBeNull();
|
|
106
|
+
expect(result!.messages).toEqual([]);
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
});
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { Adapter } from "@btst/db";
|
|
2
|
+
import type { Conversation, ConversationWithMessages, Message } from "../types";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Retrieve all conversations, optionally filtered by userId.
|
|
6
|
+
* Pure DB function - no hooks, no HTTP context. Safe for server-side use.
|
|
7
|
+
*
|
|
8
|
+
* @param adapter - The database adapter
|
|
9
|
+
* @param userId - Optional user ID to filter conversations by owner
|
|
10
|
+
*/
|
|
11
|
+
export async function getAllConversations(
|
|
12
|
+
adapter: Adapter,
|
|
13
|
+
userId?: string,
|
|
14
|
+
): Promise<Conversation[]> {
|
|
15
|
+
const whereConditions: Array<{
|
|
16
|
+
field: string;
|
|
17
|
+
value: string;
|
|
18
|
+
operator: "eq";
|
|
19
|
+
}> = [];
|
|
20
|
+
|
|
21
|
+
if (userId) {
|
|
22
|
+
whereConditions.push({
|
|
23
|
+
field: "userId",
|
|
24
|
+
value: userId,
|
|
25
|
+
operator: "eq" as const,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return adapter.findMany<Conversation>({
|
|
30
|
+
model: "conversation",
|
|
31
|
+
where: whereConditions.length > 0 ? whereConditions : undefined,
|
|
32
|
+
sortBy: { field: "updatedAt", direction: "desc" },
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Retrieve a single conversation by its ID, including all messages.
|
|
38
|
+
* Returns null if the conversation is not found.
|
|
39
|
+
* Pure DB function - no hooks, no HTTP context. Safe for server-side use.
|
|
40
|
+
*
|
|
41
|
+
* @param adapter - The database adapter
|
|
42
|
+
* @param id - The conversation ID
|
|
43
|
+
*/
|
|
44
|
+
export async function getConversationById(
|
|
45
|
+
adapter: Adapter,
|
|
46
|
+
id: string,
|
|
47
|
+
): Promise<(Conversation & { messages: Message[] }) | null> {
|
|
48
|
+
const conversations = await adapter.findMany<ConversationWithMessages>({
|
|
49
|
+
model: "conversation",
|
|
50
|
+
where: [{ field: "id", value: id, operator: "eq" as const }],
|
|
51
|
+
limit: 1,
|
|
52
|
+
join: {
|
|
53
|
+
message: true,
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
if (!conversations.length) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const conversation = conversations[0]!;
|
|
62
|
+
const messages = (conversation.message || []).sort(
|
|
63
|
+
(a, b) => a.createdAt.getTime() - b.createdAt.getTime(),
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
const { message: _, ...conversationWithoutJoin } = conversation;
|
|
67
|
+
return {
|
|
68
|
+
...conversationWithoutJoin,
|
|
69
|
+
messages,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
updateConversationSchema,
|
|
17
17
|
} from "../schemas";
|
|
18
18
|
import type { Conversation, ConversationWithMessages, Message } from "../types";
|
|
19
|
+
import { getAllConversations, getConversationById } from "./getters";
|
|
19
20
|
|
|
20
21
|
/**
|
|
21
22
|
* Context passed to AI Chat API hooks
|
|
@@ -286,6 +287,13 @@ export const aiChatBackendPlugin = (config: AiChatBackendConfig) =>
|
|
|
286
287
|
name: "ai-chat",
|
|
287
288
|
// Always include db schema - in public mode we just don't use it
|
|
288
289
|
dbPlugin: dbSchema,
|
|
290
|
+
|
|
291
|
+
api: (adapter) => ({
|
|
292
|
+
getAllConversations: (userId?: string) =>
|
|
293
|
+
getAllConversations(adapter, userId),
|
|
294
|
+
getConversationById: (id: string) => getConversationById(adapter, id),
|
|
295
|
+
}),
|
|
296
|
+
|
|
289
297
|
routes: (adapter: Adapter) => {
|
|
290
298
|
const mode = config.mode ?? "authenticated";
|
|
291
299
|
const isPublicMode = mode === "public";
|
package/src/plugins/api/index.ts
CHANGED
|
@@ -42,9 +42,11 @@ export { createDbPlugin } from "@btst/db";
|
|
|
42
42
|
* ```
|
|
43
43
|
*
|
|
44
44
|
* @template TRoutes - The exact shape of routes (auto-inferred from routes function)
|
|
45
|
+
* @template TApi - The shape of the server-side api surface (auto-inferred from api factory)
|
|
45
46
|
*/
|
|
46
47
|
export function defineBackendPlugin<
|
|
47
48
|
TRoutes extends Record<string, Endpoint> = Record<string, Endpoint>,
|
|
48
|
-
|
|
49
|
+
TApi extends Record<string, (...args: any[]) => any> = never,
|
|
50
|
+
>(plugin: BackendPlugin<TRoutes, TApi>): BackendPlugin<TRoutes, TApi> {
|
|
49
51
|
return plugin;
|
|
50
52
|
}
|