@lobehub/chat 0.162.24 → 0.163.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.
Files changed (96) hide show
  1. package/.github/workflows/release.yml +21 -2
  2. package/.github/workflows/sync.yml +1 -1
  3. package/.github/workflows/test.yml +35 -4
  4. package/CHANGELOG.md +50 -0
  5. package/LICENSE +38 -21
  6. package/README.md +8 -8
  7. package/README.zh-CN.md +8 -8
  8. package/codecov.yml +11 -0
  9. package/docs/self-hosting/platform/zeabur.mdx +1 -1
  10. package/docs/self-hosting/platform/zeabur.zh-CN.mdx +1 -1
  11. package/drizzle.config.ts +29 -0
  12. package/next.config.mjs +3 -0
  13. package/package.json +25 -5
  14. package/scripts/migrateServerDB/index.ts +30 -0
  15. package/src/app/(main)/(mobile)/me/(home)/features/useCategory.tsx +2 -1
  16. package/src/app/(main)/chat/@session/features/SessionListContent/List/Item/Actions.tsx +95 -88
  17. package/src/app/(main)/chat/settings/features/HeaderContent.tsx +37 -31
  18. package/src/app/(main)/settings/llm/components/ProviderConfig/index.tsx +11 -1
  19. package/src/app/api/middleware/auth/index.ts +1 -1
  20. package/src/app/api/webhooks/clerk/__tests__/fixtures/createUser.json +73 -0
  21. package/src/app/api/webhooks/clerk/route.ts +159 -0
  22. package/src/app/api/webhooks/clerk/validateRequest.ts +22 -0
  23. package/src/app/trpc/edge/[trpc]/route.ts +1 -1
  24. package/src/app/trpc/lambda/[trpc]/route.ts +26 -0
  25. package/src/config/auth.ts +2 -0
  26. package/src/config/db.ts +13 -1
  27. package/src/database/server/core/db.ts +44 -0
  28. package/src/database/server/core/dbForTest.ts +45 -0
  29. package/src/database/server/index.ts +1 -0
  30. package/src/database/server/migrations/0000_init.sql +439 -0
  31. package/src/database/server/migrations/0001_add_client_id.sql +9 -0
  32. package/src/database/server/migrations/0002_amusing_puma.sql +9 -0
  33. package/src/database/server/migrations/meta/0000_snapshot.json +1583 -0
  34. package/src/database/server/migrations/meta/0001_snapshot.json +1636 -0
  35. package/src/database/server/migrations/meta/0002_snapshot.json +1630 -0
  36. package/src/database/server/migrations/meta/_journal.json +27 -0
  37. package/src/database/server/models/__tests__/file.test.ts +140 -0
  38. package/src/database/server/models/__tests__/message.test.ts +847 -0
  39. package/src/database/server/models/__tests__/plugin.test.ts +172 -0
  40. package/src/database/server/models/__tests__/session.test.ts +595 -0
  41. package/src/database/server/models/__tests__/topic.test.ts +623 -0
  42. package/src/database/server/models/__tests__/user.test.ts +173 -0
  43. package/src/database/server/models/_template.ts +44 -0
  44. package/src/database/server/models/file.ts +51 -0
  45. package/src/database/server/models/message.ts +378 -0
  46. package/src/database/server/models/plugin.ts +63 -0
  47. package/src/database/server/models/session.ts +290 -0
  48. package/src/database/server/models/sessionGroup.ts +69 -0
  49. package/src/database/server/models/topic.ts +265 -0
  50. package/src/database/server/models/user.ts +138 -0
  51. package/src/database/server/modules/DataImporter/__tests__/fixtures/messages.json +1101 -0
  52. package/src/database/server/modules/DataImporter/__tests__/index.test.ts +954 -0
  53. package/src/database/server/modules/DataImporter/index.ts +333 -0
  54. package/src/database/server/schemas/_id.ts +15 -0
  55. package/src/database/server/schemas/lobechat.ts +601 -0
  56. package/src/database/server/utils/idGenerator.test.ts +39 -0
  57. package/src/database/server/utils/idGenerator.ts +26 -0
  58. package/src/features/AgentSetting/AgentModal/index.tsx +6 -7
  59. package/src/features/User/UserPanel/useMenu.tsx +43 -37
  60. package/src/libs/trpc/client.ts +52 -3
  61. package/src/server/files/s3.ts +21 -1
  62. package/src/server/keyVaultsEncrypt/index.test.ts +62 -0
  63. package/src/server/keyVaultsEncrypt/index.ts +93 -0
  64. package/src/server/mock.ts +1 -1
  65. package/src/server/routers/{index.ts → edge/index.ts} +3 -3
  66. package/src/server/routers/lambda/file.ts +49 -0
  67. package/src/server/routers/lambda/importer.ts +54 -0
  68. package/src/server/routers/lambda/index.ts +28 -0
  69. package/src/server/routers/lambda/message.ts +165 -0
  70. package/src/server/routers/lambda/plugin.ts +100 -0
  71. package/src/server/routers/lambda/session.ts +194 -0
  72. package/src/server/routers/lambda/sessionGroup.ts +77 -0
  73. package/src/server/routers/lambda/topic.ts +134 -0
  74. package/src/server/routers/lambda/user.ts +57 -0
  75. package/src/services/file/index.ts +4 -7
  76. package/src/services/file/server.ts +45 -0
  77. package/src/services/import/index.ts +4 -1
  78. package/src/services/import/server.ts +115 -0
  79. package/src/services/message/index.ts +4 -8
  80. package/src/services/message/server.ts +93 -0
  81. package/src/services/plugin/index.ts +4 -9
  82. package/src/services/plugin/server.ts +46 -0
  83. package/src/services/session/index.ts +4 -8
  84. package/src/services/session/server.ts +148 -0
  85. package/src/services/topic/index.ts +4 -9
  86. package/src/services/topic/server.ts +68 -0
  87. package/src/services/user/index.ts +4 -9
  88. package/src/services/user/server.ts +28 -0
  89. package/src/store/user/slices/modelList/selectors/keyVaults.test.ts +201 -0
  90. package/src/store/user/slices/modelList/selectors/keyVaults.ts +15 -3
  91. package/src/store/user/slices/modelList/selectors/modelConfig.test.ts +29 -1
  92. package/src/store/user/slices/modelList/selectors/modelConfig.ts +21 -1
  93. package/src/types/user/settings/keyVaults.ts +1 -1
  94. package/tests/setup-db.ts +7 -0
  95. package/vitest.config.ts +2 -1
  96. package/vitest.server.config.ts +23 -0
@@ -0,0 +1,27 @@
1
+ {
2
+ "dialect": "postgresql",
3
+ "entries": [
4
+ {
5
+ "idx": 0,
6
+ "version": "6",
7
+ "when": 1716982944425,
8
+ "tag": "0000_init",
9
+ "breakpoints": true
10
+ },
11
+ {
12
+ "idx": 1,
13
+ "version": "6",
14
+ "when": 1717153686544,
15
+ "tag": "0001_add_client_id",
16
+ "breakpoints": true
17
+ },
18
+ {
19
+ "idx": 2,
20
+ "version": "6",
21
+ "when": 1717587734458,
22
+ "tag": "0002_amusing_puma",
23
+ "breakpoints": true
24
+ }
25
+ ],
26
+ "version": "6"
27
+ }
@@ -0,0 +1,140 @@
1
+ // @vitest-environment node
2
+ import { eq } from 'drizzle-orm';
3
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
4
+
5
+ import { getTestDBInstance } from '@/database/server/core/dbForTest';
6
+
7
+ import { files, users } from '../../schemas/lobechat';
8
+ import { FileModel } from '../file';
9
+
10
+ let serverDB = await getTestDBInstance();
11
+
12
+ vi.mock('@/database/server/core/db', async () => ({
13
+ get serverDB() {
14
+ return serverDB;
15
+ },
16
+ }));
17
+
18
+ const userId = 'file-model-test-user-id';
19
+ const fileModel = new FileModel(userId);
20
+
21
+ beforeEach(async () => {
22
+ await serverDB.delete(users).where(eq(users.id, userId));
23
+ await serverDB.insert(users).values({ id: userId });
24
+ });
25
+
26
+ afterEach(async () => {
27
+ await serverDB.delete(users).where(eq(users.id, userId));
28
+ await serverDB.delete(files).where(eq(files.userId, userId));
29
+ });
30
+
31
+ describe('FileModel', () => {
32
+ it('should create a new file', async () => {
33
+ const params = {
34
+ name: 'test-file.txt',
35
+ url: 'https://example.com/test-file.txt',
36
+ size: 100,
37
+ fileType: 'text/plain',
38
+ };
39
+
40
+ const { id } = await fileModel.create(params);
41
+ expect(id).toBeDefined();
42
+
43
+ const file = await serverDB.query.files.findFirst({ where: eq(files.id, id) });
44
+ expect(file).toMatchObject({ ...params, userId });
45
+ });
46
+
47
+ it('should delete a file by id', async () => {
48
+ const { id } = await fileModel.create({
49
+ name: 'test-file.txt',
50
+ url: 'https://example.com/test-file.txt',
51
+ size: 100,
52
+ fileType: 'text/plain',
53
+ });
54
+
55
+ await fileModel.delete(id);
56
+
57
+ const file = await serverDB.query.files.findFirst({ where: eq(files.id, id) });
58
+ expect(file).toBeUndefined();
59
+ });
60
+
61
+ it('should clear all files for the user', async () => {
62
+ await fileModel.create({
63
+ name: 'test-file-1.txt',
64
+ url: 'https://example.com/test-file-1.txt',
65
+ size: 100,
66
+ fileType: 'text/plain',
67
+ });
68
+ await fileModel.create({
69
+ name: 'test-file-2.txt',
70
+ url: 'https://example.com/test-file-2.txt',
71
+ size: 200,
72
+ fileType: 'text/plain',
73
+ });
74
+
75
+ await fileModel.clear();
76
+
77
+ const userFiles = await serverDB.query.files.findMany({ where: eq(files.userId, userId) });
78
+ expect(userFiles).toHaveLength(0);
79
+ });
80
+
81
+ it('should query files for the user', async () => {
82
+ await fileModel.create({
83
+ name: 'test-file-1.txt',
84
+ url: 'https://example.com/test-file-1.txt',
85
+ size: 100,
86
+ fileType: 'text/plain',
87
+ });
88
+ await fileModel.create({
89
+ name: 'test-file-2.txt',
90
+ url: 'https://example.com/test-file-2.txt',
91
+ size: 200,
92
+ fileType: 'text/plain',
93
+ });
94
+
95
+ const userFiles = await fileModel.query();
96
+ expect(userFiles).toHaveLength(2);
97
+ expect(userFiles[0].name).toBe('test-file-2.txt');
98
+ expect(userFiles[1].name).toBe('test-file-1.txt');
99
+ });
100
+
101
+ it('should find a file by id', async () => {
102
+ const { id } = await fileModel.create({
103
+ name: 'test-file.txt',
104
+ url: 'https://example.com/test-file.txt',
105
+ size: 100,
106
+ fileType: 'text/plain',
107
+ });
108
+
109
+ const file = await fileModel.findById(id);
110
+ expect(file).toMatchObject({
111
+ id,
112
+ name: 'test-file.txt',
113
+ url: 'https://example.com/test-file.txt',
114
+ size: 100,
115
+ fileType: 'text/plain',
116
+ userId,
117
+ });
118
+ });
119
+
120
+ it('should update a file', async () => {
121
+ const { id } = await fileModel.create({
122
+ name: 'test-file.txt',
123
+ url: 'https://example.com/test-file.txt',
124
+ size: 100,
125
+ fileType: 'text/plain',
126
+ });
127
+
128
+ await fileModel.update(id, { name: 'updated-test-file.txt', size: 200 });
129
+
130
+ const updatedFile = await serverDB.query.files.findFirst({ where: eq(files.id, id) });
131
+ expect(updatedFile).toMatchObject({
132
+ id,
133
+ name: 'updated-test-file.txt',
134
+ url: 'https://example.com/test-file.txt',
135
+ size: 200,
136
+ fileType: 'text/plain',
137
+ userId,
138
+ });
139
+ });
140
+ });