@mindbase/express-knowledge 1.0.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.
@@ -0,0 +1,27 @@
1
+ import {
2
+ batchCreateKnowledgeSchema,
3
+ batchDetailKnowledgeSchema,
4
+ createKnowledgeSchema,
5
+ knowledge,
6
+ listKnowledgeSchema,
7
+ moveKnowledgeSchema,
8
+ searchKnowledgeSchema,
9
+ updateIsTopSchema,
10
+ updateKnowledgeSchema,
11
+ updateSafeSchema
12
+ } from "./chunk-Y47QRG3M.mjs";
13
+ import "./chunk-GWIBTASJ.mjs";
14
+ import "./chunk-VHBDNZOQ.mjs";
15
+ export {
16
+ batchCreateKnowledgeSchema,
17
+ batchDetailKnowledgeSchema,
18
+ createKnowledgeSchema,
19
+ knowledge,
20
+ listKnowledgeSchema,
21
+ moveKnowledgeSchema,
22
+ searchKnowledgeSchema,
23
+ updateIsTopSchema,
24
+ updateKnowledgeSchema,
25
+ updateSafeSchema
26
+ };
27
+ //# sourceMappingURL=Knowledge.schema-7KD5X7KG.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,303 @@
1
+ import {
2
+ knowledge
3
+ } from "./chunk-Y47QRG3M.mjs";
4
+ import "./chunk-GWIBTASJ.mjs";
5
+ import "./chunk-VHBDNZOQ.mjs";
6
+
7
+ // service/KnowledgeService.ts
8
+ import { eq, and, or, like, sql, desc, inArray } from "drizzle-orm";
9
+
10
+ // utils/path-builder.ts
11
+ function buildPath(parentPath, id) {
12
+ return `${parentPath}${id}/`;
13
+ }
14
+ function isDescendant(ancestorPath, descendantPath) {
15
+ return descendantPath.startsWith(ancestorPath) && ancestorPath !== descendantPath;
16
+ }
17
+
18
+ // service/KnowledgeService.ts
19
+ var _db;
20
+ function initKnowledgeService(db) {
21
+ _db = db;
22
+ }
23
+ function getDB() {
24
+ if (!_db) throw new Error("KnowledgeService not initialized with DB");
25
+ return _db;
26
+ }
27
+ async function createKnowledge(data) {
28
+ const db = getDB();
29
+ const now = /* @__PURE__ */ new Date();
30
+ let parentPath = "/";
31
+ let level = 0;
32
+ if (data.parentId) {
33
+ const [parent] = await db.select().from(knowledge).where(and(eq(knowledge.id, data.parentId), eq(knowledge.isDelete, 0))).limit(1);
34
+ if (!parent) {
35
+ throw new Error("\u7236\u8282\u70B9\u4E0D\u5B58\u5728");
36
+ }
37
+ parentPath = parent.path;
38
+ level = parent.level + 1;
39
+ }
40
+ const result = await db.insert(knowledge).values({
41
+ name: data.name,
42
+ type: data.type ?? 0,
43
+ safe: data.safe ?? 0,
44
+ userId: data.userId,
45
+ description: data.description,
46
+ content: data.content,
47
+ contentText: data.contentText,
48
+ viewType: data.viewType,
49
+ coverImage: data.coverImage,
50
+ author: data.author,
51
+ isbn: data.isbn,
52
+ created: now,
53
+ updated: now,
54
+ isDelete: 0,
55
+ isTop: 0,
56
+ path: "/",
57
+ // 临时值
58
+ level: 0
59
+ // 临时值
60
+ }).execute();
61
+ const lastId = result.lastInsertRowid;
62
+ const finalPath = buildPath(parentPath, lastId);
63
+ await db.update(knowledge).set({ path: finalPath, level }).where(eq(knowledge.id, lastId)).execute();
64
+ return getKnowledgeById(lastId);
65
+ }
66
+ async function createKnowledgeBatch(items, userId, parentId) {
67
+ const results = [];
68
+ for (const item of items) {
69
+ try {
70
+ const result = await createKnowledge({ ...item, userId, parentId });
71
+ results.push({ success: true, data: result });
72
+ } catch (error) {
73
+ results.push({ success: false, error: error instanceof Error ? error.message : String(error) });
74
+ }
75
+ }
76
+ return results;
77
+ }
78
+ async function listKnowledge(options) {
79
+ const db = getDB();
80
+ const { pageIndex, pageSize, level, type, safe = [0], userId, isAdmin } = options;
81
+ let conditions = [eq(knowledge.isDelete, 0)];
82
+ if (level !== void 0) {
83
+ conditions.push(eq(knowledge.level, level));
84
+ }
85
+ if (type !== void 0) {
86
+ conditions.push(eq(knowledge.type, type));
87
+ }
88
+ const safeConditions = [];
89
+ for (const s of safe) {
90
+ switch (s) {
91
+ case 0:
92
+ safeConditions.push(eq(knowledge.safe, s));
93
+ break;
94
+ case 1:
95
+ if (userId) {
96
+ safeConditions.push(eq(knowledge.safe, s));
97
+ }
98
+ break;
99
+ case 2:
100
+ if (userId) {
101
+ safeConditions.push(
102
+ and(eq(knowledge.safe, s), isAdmin ? sql`1=1` : eq(knowledge.userId, userId))
103
+ );
104
+ }
105
+ break;
106
+ }
107
+ }
108
+ if (safeConditions.length > 0) {
109
+ conditions.push(or(...safeConditions));
110
+ }
111
+ const offset = (pageIndex - 1) * pageSize;
112
+ const list = await db.select().from(knowledge).where(and(...conditions)).limit(pageSize).offset(offset).orderBy(desc(knowledge.isTop), desc(knowledge.created)).execute();
113
+ const [totalResult] = await db.select({ count: sql`count(*)` }).from(knowledge).where(and(...conditions)).execute();
114
+ return {
115
+ list,
116
+ total: totalResult.count,
117
+ pageIndex,
118
+ pageSize
119
+ };
120
+ }
121
+ async function getKnowledgeById(id) {
122
+ const db = getDB();
123
+ const [item] = await db.select().from(knowledge).where(and(eq(knowledge.id, id), eq(knowledge.isDelete, 0))).limit(1);
124
+ return item || null;
125
+ }
126
+ async function getKnowledgeByIds(ids) {
127
+ const db = getDB();
128
+ if (ids.length === 0) return [];
129
+ return await db.select().from(knowledge).where(and(inArray(knowledge.id, ids), eq(knowledge.isDelete, 0))).execute();
130
+ }
131
+ async function getKnowledgeTree(options) {
132
+ const db = getDB();
133
+ const { parentId = null, safe = [0], userId, isAdmin } = options;
134
+ let conditions = [eq(knowledge.isDelete, 0)];
135
+ const safeConditions = [];
136
+ for (const s of safe) {
137
+ switch (s) {
138
+ case 0:
139
+ safeConditions.push(eq(knowledge.safe, s));
140
+ break;
141
+ case 1:
142
+ if (userId) {
143
+ safeConditions.push(eq(knowledge.safe, s));
144
+ }
145
+ break;
146
+ case 2:
147
+ if (userId) {
148
+ safeConditions.push(
149
+ and(eq(knowledge.safe, s), isAdmin ? sql`1=1` : eq(knowledge.userId, userId))
150
+ );
151
+ }
152
+ break;
153
+ }
154
+ }
155
+ if (safeConditions.length > 0) {
156
+ conditions.push(or(...safeConditions));
157
+ }
158
+ if (parentId !== null) {
159
+ const [parent] = await db.select().from(knowledge).where(and(eq(knowledge.id, parentId), eq(knowledge.isDelete, 0))).limit(1);
160
+ if (!parent) return [];
161
+ conditions.push(like(knowledge.path, `${parent.path}%`));
162
+ }
163
+ const allNodes = await db.select().from(knowledge).where(and(...conditions)).orderBy(desc(knowledge.isTop), knowledge.name).execute();
164
+ const { buildTree } = await import("./tree-builder-XZ4OA2TD.mjs");
165
+ return buildTree(allNodes, parentId);
166
+ }
167
+ async function getChildren(parentId) {
168
+ const db = getDB();
169
+ const [parent] = await db.select().from(knowledge).where(and(eq(knowledge.id, parentId), eq(knowledge.isDelete, 0))).limit(1);
170
+ if (!parent) {
171
+ throw new Error("\u7236\u8282\u70B9\u4E0D\u5B58\u5728");
172
+ }
173
+ return await db.select().from(knowledge).where(
174
+ and(
175
+ eq(knowledge.isDelete, 0),
176
+ like(knowledge.path, `${parent.path}%`),
177
+ eq(knowledge.level, parent.level + 1)
178
+ )
179
+ ).orderBy(desc(knowledge.isTop), knowledge.name).execute();
180
+ }
181
+ async function updateKnowledge(id, data, userId) {
182
+ const db = getDB();
183
+ const now = /* @__PURE__ */ new Date();
184
+ const result = await db.update(knowledge).set({
185
+ ...data.name !== void 0 && { name: data.name },
186
+ ...data.description !== void 0 && { description: data.description },
187
+ ...data.content !== void 0 && { content: data.content },
188
+ ...data.contentText !== void 0 && { contentText: data.contentText },
189
+ ...data.viewType !== void 0 && { viewType: data.viewType },
190
+ ...data.coverImage !== void 0 && { coverImage: data.coverImage },
191
+ ...data.author !== void 0 && { author: data.author },
192
+ ...data.isbn !== void 0 && { isbn: data.isbn },
193
+ updated: now
194
+ }).where(and(eq(knowledge.id, id), eq(knowledge.userId, userId))).execute();
195
+ return result;
196
+ }
197
+ async function moveKnowledge(nodeId, newParentId, userId) {
198
+ const db = getDB();
199
+ const [node] = await db.select().from(knowledge).where(and(eq(knowledge.id, nodeId), eq(knowledge.isDelete, 0))).limit(1);
200
+ const [newParent] = await db.select().from(knowledge).where(and(eq(knowledge.id, newParentId), eq(knowledge.isDelete, 0))).limit(1);
201
+ if (!node || !newParent) {
202
+ throw new Error("\u8282\u70B9\u4E0D\u5B58\u5728");
203
+ }
204
+ if (node.userId !== userId) {
205
+ throw new Error("\u65E0\u6743\u64CD\u4F5C\u6B64\u8282\u70B9");
206
+ }
207
+ if (isDescendant(node.path, newParent.path)) {
208
+ throw new Error("\u4E0D\u80FD\u79FB\u52A8\u5230\u81EA\u5DF1\u7684\u540E\u4EE3\u8282\u70B9");
209
+ }
210
+ const oldPath = node.path;
211
+ const newPath = buildPath(newParent.path, nodeId);
212
+ const levelDiff = newParent.level + 1 - node.level;
213
+ await db.update(knowledge).set({
214
+ path: sql`REPLACE(${knowledge.path}, ${oldPath}, ${newPath})`,
215
+ level: sql`${knowledge.level} + ${levelDiff}`
216
+ }).where(or(like(knowledge.path, `${oldPath}%`), eq(knowledge.path, oldPath))).execute();
217
+ return getKnowledgeById(nodeId);
218
+ }
219
+ async function updateIsTop(id, isTop, userId) {
220
+ const db = getDB();
221
+ const now = /* @__PURE__ */ new Date();
222
+ await db.update(knowledge).set({ isTop, updated: now }).where(and(eq(knowledge.id, id), eq(knowledge.userId, userId))).execute();
223
+ return getKnowledgeById(id);
224
+ }
225
+ async function updateSafe(id, safe, userId) {
226
+ const db = getDB();
227
+ const now = /* @__PURE__ */ new Date();
228
+ await db.update(knowledge).set({ safe, updated: now }).where(and(eq(knowledge.id, id), eq(knowledge.userId, userId))).execute();
229
+ return getKnowledgeById(id);
230
+ }
231
+ async function deleteKnowledge(id, userId) {
232
+ const db = getDB();
233
+ const now = /* @__PURE__ */ new Date();
234
+ await db.update(knowledge).set({ isDelete: 1, updated: now }).where(and(eq(knowledge.id, id), eq(knowledge.userId, userId))).execute();
235
+ return { success: true };
236
+ }
237
+ async function deleteKnowledgeReal(id) {
238
+ const db = getDB();
239
+ await db.delete(knowledge).where(eq(knowledge.id, id)).execute();
240
+ return { success: true };
241
+ }
242
+ async function searchKnowledge(options) {
243
+ const db = getDB();
244
+ const { keyword, pageIndex = 1, pageSize = 10, safe = [0], userId, isAdmin } = options;
245
+ let conditions = [
246
+ eq(knowledge.isDelete, 0),
247
+ or(
248
+ like(knowledge.name, `%${keyword}%`),
249
+ like(knowledge.description, `%${keyword}%`),
250
+ like(knowledge.contentText, `%${keyword}%`)
251
+ )
252
+ ];
253
+ const safeConditions = [];
254
+ for (const s of safe) {
255
+ switch (s) {
256
+ case 0:
257
+ safeConditions.push(eq(knowledge.safe, s));
258
+ break;
259
+ case 1:
260
+ if (userId) {
261
+ safeConditions.push(eq(knowledge.safe, s));
262
+ }
263
+ break;
264
+ case 2:
265
+ if (userId) {
266
+ safeConditions.push(
267
+ and(eq(knowledge.safe, s), isAdmin ? sql`1=1` : eq(knowledge.userId, userId))
268
+ );
269
+ }
270
+ break;
271
+ }
272
+ }
273
+ if (safeConditions.length > 0) {
274
+ conditions.push(or(...safeConditions));
275
+ }
276
+ const offset = (pageIndex - 1) * pageSize;
277
+ const list = await db.select().from(knowledge).where(and(...conditions)).limit(pageSize).offset(offset).orderBy(desc(knowledge.created)).execute();
278
+ const [totalResult] = await db.select({ count: sql`count(*)` }).from(knowledge).where(and(...conditions)).execute();
279
+ return {
280
+ list,
281
+ total: totalResult.count,
282
+ pageIndex,
283
+ pageSize
284
+ };
285
+ }
286
+ export {
287
+ createKnowledge,
288
+ createKnowledgeBatch,
289
+ deleteKnowledge,
290
+ deleteKnowledgeReal,
291
+ getChildren,
292
+ getKnowledgeById,
293
+ getKnowledgeByIds,
294
+ getKnowledgeTree,
295
+ initKnowledgeService,
296
+ listKnowledge,
297
+ moveKnowledge,
298
+ searchKnowledge,
299
+ updateIsTop,
300
+ updateKnowledge,
301
+ updateSafe
302
+ };
303
+ //# sourceMappingURL=KnowledgeService-YZHS7UHY.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../service/KnowledgeService.ts","../utils/path-builder.ts"],"sourcesContent":["import { knowledge } from \"../orm/Knowledge.schema\";\r\nimport { eq, and, or, like, sql, desc, inArray } from \"drizzle-orm\";\r\nimport { buildPath, getLevel, validatePath, isDescendant } from \"../utils/path-builder\";\r\nimport type { Knowledge, KnowledgeSafe, InsertKnowledge } from \"../types\";\r\n\r\nlet _db: any;\r\n\r\n/**\r\n * 初始化 Service 的数据库实例\r\n */\r\nexport function initKnowledgeService(db: any) {\r\n _db = db;\r\n}\r\n\r\nfunction getDB() {\r\n if (!_db) throw new Error(\"KnowledgeService not initialized with DB\");\r\n return _db;\r\n}\r\n\r\n// ==================== CRUD 操作 ====================\r\n\r\n/**\r\n * 创建知识库内容\r\n */\r\nexport async function createKnowledge(data: InsertKnowledge & { userId: number }) {\r\n const db = getDB();\r\n const now = new Date();\r\n\r\n // 如果有父节点,获取父节点信息\r\n let parentPath = \"/\";\r\n let level = 0;\r\n\r\n if (data.parentId) {\r\n const [parent] = await db\r\n .select()\r\n .from(knowledge)\r\n .where(and(eq(knowledge.id, data.parentId), eq(knowledge.isDelete, 0)))\r\n .limit(1);\r\n\r\n if (!parent) {\r\n throw new Error(\"父节点不存在\");\r\n }\r\n\r\n parentPath = parent.path;\r\n level = parent.level + 1;\r\n }\r\n\r\n // 先插入基础数据(不含 path 和 level)\r\n const result = await db\r\n .insert(knowledge)\r\n .values({\r\n name: data.name,\r\n type: data.type ?? 0,\r\n safe: data.safe ?? 0,\r\n userId: data.userId,\r\n description: data.description,\r\n content: data.content,\r\n contentText: data.contentText,\r\n viewType: data.viewType,\r\n coverImage: data.coverImage,\r\n author: data.author,\r\n isbn: data.isbn,\r\n created: now,\r\n updated: now,\r\n isDelete: 0,\r\n isTop: 0,\r\n path: \"/\", // 临时值\r\n level: 0, // 临时值\r\n })\r\n .execute();\r\n\r\n // 获取插入的 ID\r\n const lastId = result.lastInsertRowid as number;\r\n\r\n // 更新 path 和 level\r\n const finalPath = buildPath(parentPath, lastId);\r\n await db\r\n .update(knowledge)\r\n .set({ path: finalPath, level })\r\n .where(eq(knowledge.id, lastId))\r\n .execute();\r\n\r\n return getKnowledgeById(lastId);\r\n}\r\n\r\n/**\r\n * 批量创建知识库内容\r\n */\r\nexport async function createKnowledgeBatch(items: Array<{ name: string; type: number }>, userId: number, parentId?: number) {\r\n const results = [];\r\n\r\n for (const item of items) {\r\n try {\r\n const result = await createKnowledge({ ...item, userId, parentId });\r\n results.push({ success: true, data: result });\r\n } catch (error) {\r\n results.push({ success: false, error: error instanceof Error ? error.message : String(error) });\r\n }\r\n }\r\n\r\n return results;\r\n}\r\n\r\n/**\r\n * 分页获取知识库列表\r\n */\r\nexport async function listKnowledge(options: {\r\n pageIndex: number;\r\n pageSize: number;\r\n level?: number;\r\n type?: number;\r\n safe?: number[];\r\n userId?: number;\r\n isAdmin?: boolean;\r\n}) {\r\n const db = getDB();\r\n const { pageIndex, pageSize, level, type, safe = [0], userId, isAdmin } = options;\r\n\r\n let conditions = [eq(knowledge.isDelete, 0)];\r\n\r\n // 层级筛选\r\n if (level !== undefined) {\r\n conditions.push(eq(knowledge.level, level));\r\n }\r\n\r\n // 类型筛选\r\n if (type !== undefined) {\r\n conditions.push(eq(knowledge.type, type));\r\n }\r\n\r\n // 权限筛选\r\n const safeConditions = [];\r\n for (const s of safe) {\r\n switch (s) {\r\n case 0: // 公开\r\n safeConditions.push(eq(knowledge.safe, s));\r\n break;\r\n case 1: // 登录共享\r\n if (userId) {\r\n safeConditions.push(eq(knowledge.safe, s));\r\n }\r\n break;\r\n case 2: // 个人私密\r\n if (userId) {\r\n safeConditions.push(\r\n and(eq(knowledge.safe, s), isAdmin ? sql`1=1` : eq(knowledge.userId, userId))\r\n );\r\n }\r\n break;\r\n }\r\n }\r\n\r\n if (safeConditions.length > 0) {\r\n conditions.push(or(...safeConditions));\r\n }\r\n\r\n const offset = (pageIndex - 1) * pageSize;\r\n\r\n const list = await db\r\n .select()\r\n .from(knowledge)\r\n .where(and(...conditions))\r\n .limit(pageSize)\r\n .offset(offset)\r\n .orderBy(desc(knowledge.isTop), desc(knowledge.created))\r\n .execute();\r\n\r\n const [totalResult] = await db\r\n .select({ count: sql<number>`count(*)` })\r\n .from(knowledge)\r\n .where(and(...conditions))\r\n .execute();\r\n\r\n return {\r\n list,\r\n total: totalResult.count,\r\n pageIndex,\r\n pageSize,\r\n };\r\n}\r\n\r\n/**\r\n * 获取知识库详情\r\n */\r\nexport async function getKnowledgeById(id: number): Promise<Knowledge | null> {\r\n const db = getDB();\r\n const [item] = await db\r\n .select()\r\n .from(knowledge)\r\n .where(and(eq(knowledge.id, id), eq(knowledge.isDelete, 0)))\r\n .limit(1);\r\n\r\n return item || null;\r\n}\r\n\r\n/**\r\n * 批量获取知识库详情\r\n */\r\nexport async function getKnowledgeByIds(ids: number[]): Promise<Knowledge[]> {\r\n const db = getDB();\r\n if (ids.length === 0) return [];\r\n\r\n return await db\r\n .select()\r\n .from(knowledge)\r\n .where(and(inArray(knowledge.id, ids), eq(knowledge.isDelete, 0)))\r\n .execute();\r\n}\r\n\r\n/**\r\n * 获取知识库目录树\r\n */\r\nexport async function getKnowledgeTree(options: {\r\n parentId?: number | null;\r\n safe?: number[];\r\n userId?: number;\r\n isAdmin?: boolean;\r\n}) {\r\n const db = getDB();\r\n const { parentId = null, safe = [0], userId, isAdmin } = options;\r\n\r\n let conditions = [eq(knowledge.isDelete, 0)];\r\n\r\n // 权限筛选\r\n const safeConditions = [];\r\n for (const s of safe) {\r\n switch (s) {\r\n case 0: // 公开\r\n safeConditions.push(eq(knowledge.safe, s));\r\n break;\r\n case 1: // 登录共享\r\n if (userId) {\r\n safeConditions.push(eq(knowledge.safe, s));\r\n }\r\n break;\r\n case 2: // 个人私密\r\n if (userId) {\r\n safeConditions.push(\r\n and(eq(knowledge.safe, s), isAdmin ? sql`1=1` : eq(knowledge.userId, userId))\r\n );\r\n }\r\n break;\r\n }\r\n }\r\n\r\n if (safeConditions.length > 0) {\r\n conditions.push(or(...safeConditions));\r\n }\r\n\r\n // 如果指定了 parentId,只获取该节点下的子树\r\n if (parentId !== null) {\r\n const [parent] = await db\r\n .select()\r\n .from(knowledge)\r\n .where(and(eq(knowledge.id, parentId), eq(knowledge.isDelete, 0)))\r\n .limit(1);\r\n\r\n if (!parent) return [];\r\n\r\n conditions.push(like(knowledge.path, `${parent.path}%`));\r\n }\r\n\r\n const allNodes = await db\r\n .select()\r\n .from(knowledge)\r\n .where(and(...conditions))\r\n .orderBy(desc(knowledge.isTop), knowledge.name)\r\n .execute();\r\n\r\n // 使用 tree-builder 构建树形结构\r\n const { buildTree } = await import(\"../utils/tree-builder\");\r\n return buildTree(allNodes, parentId);\r\n}\r\n\r\n/**\r\n * 获取子节点列表\r\n */\r\nexport async function getChildren(parentId: number) {\r\n const db = getDB();\r\n\r\n const [parent] = await db\r\n .select()\r\n .from(knowledge)\r\n .where(and(eq(knowledge.id, parentId), eq(knowledge.isDelete, 0)))\r\n .limit(1);\r\n\r\n if (!parent) {\r\n throw new Error(\"父节点不存在\");\r\n }\r\n\r\n return await db\r\n .select()\r\n .from(knowledge)\r\n .where(\r\n and(\r\n eq(knowledge.isDelete, 0),\r\n like(knowledge.path, `${parent.path}%`),\r\n eq(knowledge.level, parent.level + 1)\r\n )\r\n )\r\n .orderBy(desc(knowledge.isTop), knowledge.name)\r\n .execute();\r\n}\r\n\r\n/**\r\n * 更新知识库内容\r\n */\r\nexport async function updateKnowledge(id: number, data: Partial<InsertKnowledge>, userId: number) {\r\n const db = getDB();\r\n const now = new Date();\r\n\r\n const result = await db\r\n .update(knowledge)\r\n .set({\r\n ...(data.name !== undefined && { name: data.name }),\r\n ...(data.description !== undefined && { description: data.description }),\r\n ...(data.content !== undefined && { content: data.content }),\r\n ...(data.contentText !== undefined && { contentText: data.contentText }),\r\n ...(data.viewType !== undefined && { viewType: data.viewType }),\r\n ...(data.coverImage !== undefined && { coverImage: data.coverImage }),\r\n ...(data.author !== undefined && { author: data.author }),\r\n ...(data.isbn !== undefined && { isbn: data.isbn }),\r\n updated: now,\r\n })\r\n .where(and(eq(knowledge.id, id), eq(knowledge.userId, userId)))\r\n .execute();\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * 移动节点(更新整个子树的 path 和 level)\r\n */\r\nexport async function moveKnowledge(nodeId: number, newParentId: number, userId: number) {\r\n const db = getDB();\r\n\r\n // 1. 获取节点和新父节点信息\r\n const [node] = await db\r\n .select()\r\n .from(knowledge)\r\n .where(and(eq(knowledge.id, nodeId), eq(knowledge.isDelete, 0)))\r\n .limit(1);\r\n\r\n const [newParent] = await db\r\n .select()\r\n .from(knowledge)\r\n .where(and(eq(knowledge.id, newParentId), eq(knowledge.isDelete, 0)))\r\n .limit(1);\r\n\r\n if (!node || !newParent) {\r\n throw new Error(\"节点不存在\");\r\n }\r\n\r\n // 权限检查\r\n if (node.userId !== userId) {\r\n throw new Error(\"无权操作此节点\");\r\n }\r\n\r\n // 2. 防止循环:不能移动到自己的后代节点\r\n if (isDescendant(node.path, newParent.path)) {\r\n throw new Error(\"不能移动到自己的后代节点\");\r\n }\r\n\r\n const oldPath = node.path;\r\n const newPath = buildPath(newParent.path, nodeId);\r\n const levelDiff = newParent.level + 1 - node.level;\r\n\r\n // 3. 批量更新整个子树\r\n await db\r\n .update(knowledge)\r\n .set({\r\n path: sql`REPLACE(${knowledge.path}, ${oldPath}, ${newPath})`,\r\n level: sql`${knowledge.level} + ${levelDiff}`,\r\n })\r\n .where(or(like(knowledge.path, `${oldPath}%`), eq(knowledge.path, oldPath)))\r\n .execute();\r\n\r\n return getKnowledgeById(nodeId);\r\n}\r\n\r\n/**\r\n * 更新置顶状态\r\n */\r\nexport async function updateIsTop(id: number, isTop: number, userId: number) {\r\n const db = getDB();\r\n const now = new Date();\r\n\r\n await db\r\n .update(knowledge)\r\n .set({ isTop, updated: now })\r\n .where(and(eq(knowledge.id, id), eq(knowledge.userId, userId)))\r\n .execute();\r\n\r\n return getKnowledgeById(id);\r\n}\r\n\r\n/**\r\n * 更新安全等级\r\n */\r\nexport async function updateSafe(id: number, safe: KnowledgeSafe, userId: number) {\r\n const db = getDB();\r\n const now = new Date();\r\n\r\n await db\r\n .update(knowledge)\r\n .set({ safe, updated: now })\r\n .where(and(eq(knowledge.id, id), eq(knowledge.userId, userId)))\r\n .execute();\r\n\r\n return getKnowledgeById(id);\r\n}\r\n\r\n/**\r\n * 逻辑删除\r\n */\r\nexport async function deleteKnowledge(id: number, userId: number) {\r\n const db = getDB();\r\n const now = new Date();\r\n\r\n await db\r\n .update(knowledge)\r\n .set({ isDelete: 1, updated: now })\r\n .where(and(eq(knowledge.id, id), eq(knowledge.userId, userId)))\r\n .execute();\r\n\r\n return { success: true };\r\n}\r\n\r\n/**\r\n * 真实删除(管理员)\r\n */\r\nexport async function deleteKnowledgeReal(id: number) {\r\n const db = getDB();\r\n\r\n await db\r\n .delete(knowledge)\r\n .where(eq(knowledge.id, id))\r\n .execute();\r\n\r\n return { success: true };\r\n}\r\n\r\n/**\r\n * 搜索知识库内容\r\n */\r\nexport async function searchKnowledge(options: {\r\n keyword: string;\r\n pageIndex?: number;\r\n pageSize?: number;\r\n safe?: number[];\r\n userId?: number;\r\n isAdmin?: boolean;\r\n}) {\r\n const db = getDB();\r\n const { keyword, pageIndex = 1, pageSize = 10, safe = [0], userId, isAdmin } = options;\r\n\r\n let conditions = [\r\n eq(knowledge.isDelete, 0),\r\n or(\r\n like(knowledge.name, `%${keyword}%`),\r\n like(knowledge.description, `%${keyword}%`),\r\n like(knowledge.contentText, `%${keyword}%`)\r\n ),\r\n ];\r\n\r\n // 权限筛选\r\n const safeConditions = [];\r\n for (const s of safe) {\r\n switch (s) {\r\n case 0: // 公开\r\n safeConditions.push(eq(knowledge.safe, s));\r\n break;\r\n case 1: // 登录共享\r\n if (userId) {\r\n safeConditions.push(eq(knowledge.safe, s));\r\n }\r\n break;\r\n case 2: // 个人私密\r\n if (userId) {\r\n safeConditions.push(\r\n and(eq(knowledge.safe, s), isAdmin ? sql`1=1` : eq(knowledge.userId, userId))\r\n );\r\n }\r\n break;\r\n }\r\n }\r\n\r\n if (safeConditions.length > 0) {\r\n conditions.push(or(...safeConditions));\r\n }\r\n\r\n const offset = (pageIndex - 1) * pageSize;\r\n\r\n const list = await db\r\n .select()\r\n .from(knowledge)\r\n .where(and(...conditions))\r\n .limit(pageSize)\r\n .offset(offset)\r\n .orderBy(desc(knowledge.created))\r\n .execute();\r\n\r\n const [totalResult] = await db\r\n .select({ count: sql<number>`count(*)` })\r\n .from(knowledge)\r\n .where(and(...conditions))\r\n .execute();\r\n\r\n return {\r\n list,\r\n total: totalResult.count,\r\n pageIndex,\r\n pageSize,\r\n };\r\n}\r\n","/**\r\n * 物化路径工具函数\r\n */\r\n\r\n/**\r\n * 构建新节点路径\r\n * @param parentPath 父节点路径\r\n * @param id 新节点ID\r\n * @returns 新节点路径\r\n */\r\nexport function buildPath(parentPath: string, id: number): string {\r\n return `${parentPath}${id}/`;\r\n}\r\n\r\n/**\r\n * 从路径计算层级\r\n * @param path 节点路径\r\n * @returns 层级深度(根节点为0)\r\n */\r\nexport function getLevel(path: string): number {\r\n // path 格式: \"/1/3/7/\" -> 分割后 ['', '1', '3', '7', '']\r\n // 减2是因为前后各有一个空字符串\r\n const parts = path.split(\"/\").filter(Boolean);\r\n return parts.length - 1;\r\n}\r\n\r\n/**\r\n * 验证路径是否有效(防止循环引用)\r\n * @param newPath 新路径\r\n * @param oldPath 旧路径\r\n * @returns 是否有效\r\n */\r\nexport function validatePath(newPath: string, oldPath: string): boolean {\r\n // 不能将节点移动到自己的后代节点下\r\n // 如果新父节点的 path 以旧节点的 path 开头,说明是后代\r\n return !newPath.startsWith(oldPath);\r\n}\r\n\r\n/**\r\n * 检查是否为后代节点\r\n * @param ancestorPath 祖先节点路径\r\n * @param descendantPath 后代节点路径\r\n * @returns 是否为后代\r\n */\r\nexport function isDescendant(ancestorPath: string, descendantPath: string): boolean {\r\n return descendantPath.startsWith(ancestorPath) && ancestorPath !== descendantPath;\r\n}\r\n"],"mappings":"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","names":[]}
@@ -0,0 +1,163 @@
1
+ import {
2
+ knowledgeTag,
3
+ knowledgeTagRelation
4
+ } from "./chunk-S3ZXTYZ2.mjs";
5
+ import "./chunk-GWIBTASJ.mjs";
6
+ import "./chunk-VHBDNZOQ.mjs";
7
+
8
+ // service/TagService.ts
9
+ import { eq, and, inArray } from "drizzle-orm";
10
+ var _db;
11
+ function initTagService(db) {
12
+ _db = db;
13
+ }
14
+ function getDB() {
15
+ if (!_db) throw new Error("TagService not initialized with DB");
16
+ return _db;
17
+ }
18
+ async function createTag(data) {
19
+ const db = getDB();
20
+ const now = /* @__PURE__ */ new Date();
21
+ const result = await db.insert(knowledgeTag).values({
22
+ name: data.name,
23
+ color: data.color,
24
+ userId: data.userId,
25
+ created: now
26
+ }).execute();
27
+ const lastId = result.lastInsertRowid;
28
+ return getTagById(lastId);
29
+ }
30
+ async function getTagById(id) {
31
+ const db = getDB();
32
+ const [tag] = await db.select().from(knowledgeTag).where(eq(knowledgeTag.id, id)).limit(1);
33
+ return tag || null;
34
+ }
35
+ async function listTags(userId) {
36
+ const db = getDB();
37
+ let conditions = [];
38
+ if (userId !== void 0) {
39
+ conditions.push(eq(knowledgeTag.userId, userId));
40
+ }
41
+ return await db.select().from(knowledgeTag).where(conditions.length > 0 ? and(...conditions) : void 0).orderBy(knowledgeTag.name).execute();
42
+ }
43
+ async function updateTag(id, data, userId) {
44
+ const db = getDB();
45
+ const [tag] = await db.select().from(knowledgeTag).where(and(eq(knowledgeTag.id, id), eq(knowledgeTag.userId, userId))).limit(1);
46
+ if (!tag) {
47
+ throw new Error("\u6807\u7B7E\u4E0D\u5B58\u5728\u6216\u65E0\u6743\u64CD\u4F5C");
48
+ }
49
+ await db.update(knowledgeTag).set({
50
+ ...data.name !== void 0 && { name: data.name },
51
+ ...data.color !== void 0 && { color: data.color }
52
+ }).where(eq(knowledgeTag.id, id)).execute();
53
+ return getTagById(id);
54
+ }
55
+ async function deleteTag(id, userId) {
56
+ const db = getDB();
57
+ const [tag] = await db.select().from(knowledgeTag).where(and(eq(knowledgeTag.id, id), eq(knowledgeTag.userId, userId))).limit(1);
58
+ if (!tag) {
59
+ throw new Error("\u6807\u7B7E\u4E0D\u5B58\u5728\u6216\u65E0\u6743\u64CD\u4F5C");
60
+ }
61
+ await db.delete(knowledgeTagRelation).where(eq(knowledgeTagRelation.tagId, id)).execute();
62
+ await db.delete(knowledgeTag).where(eq(knowledgeTag.id, id)).execute();
63
+ return { success: true };
64
+ }
65
+ async function addTagToKnowledge(knowledgeId, tagId, userId) {
66
+ const db = getDB();
67
+ const [tag] = await db.select().from(knowledgeTag).where(eq(knowledgeTag.id, tagId)).limit(1);
68
+ if (!tag) {
69
+ throw new Error("\u6807\u7B7E\u4E0D\u5B58\u5728");
70
+ }
71
+ const [existing] = await db.select().from(knowledgeTagRelation).where(
72
+ and(
73
+ eq(knowledgeTagRelation.knowledgeId, knowledgeId),
74
+ eq(knowledgeTagRelation.tagId, tagId)
75
+ )
76
+ ).limit(1);
77
+ if (existing) {
78
+ return { success: true, message: "\u6807\u7B7E\u5DF2\u5B58\u5728" };
79
+ }
80
+ await db.insert(knowledgeTagRelation).values({
81
+ knowledgeId,
82
+ tagId
83
+ }).execute();
84
+ return { success: true };
85
+ }
86
+ async function removeTagFromKnowledge(knowledgeId, tagId) {
87
+ const db = getDB();
88
+ await db.delete(knowledgeTagRelation).where(
89
+ and(
90
+ eq(knowledgeTagRelation.knowledgeId, knowledgeId),
91
+ eq(knowledgeTagRelation.tagId, tagId)
92
+ )
93
+ ).execute();
94
+ return { success: true };
95
+ }
96
+ async function getKnowledgeTags(knowledgeId) {
97
+ const db = getDB();
98
+ return await db.select({
99
+ id: knowledgeTag.id,
100
+ name: knowledgeTag.name,
101
+ color: knowledgeTag.color
102
+ }).from(knowledgeTagRelation).innerJoin(knowledgeTag, eq(knowledgeTagRelation.tagId, knowledgeTag.id)).where(eq(knowledgeTagRelation.knowledgeId, knowledgeId)).execute();
103
+ }
104
+ async function getKnowledgeByTag(tagId, options) {
105
+ const db = getDB();
106
+ const { pageIndex = 1, pageSize = 10, safe = [0], userId, isAdmin } = options;
107
+ const relations = await db.select().from(knowledgeTagRelation).where(eq2(knowledgeTagRelation.tagId, tagId)).execute();
108
+ if (relations.length === 0) {
109
+ return { list: [], total: 0, pageIndex, pageSize };
110
+ }
111
+ const knowledgeIds = relations.map((r) => r.knowledgeId);
112
+ const { knowledge } = await import("./Knowledge.schema-7KD5X7KG.mjs");
113
+ const { eq: eq2, and: and2, or, sql, desc } = await import("drizzle-orm");
114
+ let conditions = [
115
+ eq2(knowledge.isDelete, 0),
116
+ inArray(knowledge.id, knowledgeIds)
117
+ ];
118
+ const safeConditions = [];
119
+ for (const s of safe) {
120
+ switch (s) {
121
+ case 0:
122
+ safeConditions.push(eq2(knowledge.safe, s));
123
+ break;
124
+ case 1:
125
+ if (userId) {
126
+ safeConditions.push(eq2(knowledge.safe, s));
127
+ }
128
+ break;
129
+ case 2:
130
+ if (userId) {
131
+ safeConditions.push(
132
+ and2(eq2(knowledge.safe, s), isAdmin ? sql`1=1` : eq2(knowledge.userId, userId))
133
+ );
134
+ }
135
+ break;
136
+ }
137
+ }
138
+ if (safeConditions.length > 0) {
139
+ conditions.push(or(...safeConditions));
140
+ }
141
+ const offset = (pageIndex - 1) * pageSize;
142
+ const list = await db.select().from(knowledge).where(and2(...conditions)).limit(pageSize).offset(offset).orderBy(desc(knowledge.created)).execute();
143
+ const [totalResult] = await db.select({ count: sql`count(*)` }).from(knowledge).where(and2(...conditions)).execute();
144
+ return {
145
+ list,
146
+ total: totalResult.count,
147
+ pageIndex,
148
+ pageSize
149
+ };
150
+ }
151
+ export {
152
+ addTagToKnowledge,
153
+ createTag,
154
+ deleteTag,
155
+ getKnowledgeByTag,
156
+ getKnowledgeTags,
157
+ getTagById,
158
+ initTagService,
159
+ listTags,
160
+ removeTagFromKnowledge,
161
+ updateTag
162
+ };
163
+ //# sourceMappingURL=TagService-VX6SB3S6.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../service/TagService.ts"],"sourcesContent":["import { knowledgeTag, knowledgeTagRelation } from \"../orm/Tag.schema\";\r\nimport { eq, and, inArray } from \"drizzle-orm\";\r\nimport type { InsertTag } from \"../types\";\r\n\r\nlet _db: any;\r\n\r\n/**\r\n * 初始化 Service 的数据库实例\r\n */\r\nexport function initTagService(db: any) {\r\n _db = db;\r\n}\r\n\r\nfunction getDB() {\r\n if (!_db) throw new Error(\"TagService not initialized with DB\");\r\n return _db;\r\n}\r\n\r\n// ==================== 标签管理 ====================\r\n\r\n/**\r\n * 创建标签\r\n */\r\nexport async function createTag(data: InsertTag & { userId?: number }) {\r\n const db = getDB();\r\n const now = new Date();\r\n\r\n const result = await db\r\n .insert(knowledgeTag)\r\n .values({\r\n name: data.name,\r\n color: data.color,\r\n userId: data.userId,\r\n created: now,\r\n })\r\n .execute();\r\n\r\n const lastId = result.lastInsertRowid as number;\r\n return getTagById(lastId);\r\n}\r\n\r\n/**\r\n * 获取标签详情\r\n */\r\nexport async function getTagById(id: number) {\r\n const db = getDB();\r\n const [tag] = await db\r\n .select()\r\n .from(knowledgeTag)\r\n .where(eq(knowledgeTag.id, id))\r\n .limit(1);\r\n\r\n return tag || null;\r\n}\r\n\r\n/**\r\n * 获取标签列表\r\n */\r\nexport async function listTags(userId?: number) {\r\n const db = getDB();\r\n\r\n let conditions = [];\r\n if (userId !== undefined) {\r\n conditions.push(eq(knowledgeTag.userId, userId));\r\n }\r\n\r\n return await db\r\n .select()\r\n .from(knowledgeTag)\r\n .where(conditions.length > 0 ? and(...conditions) : undefined)\r\n .orderBy(knowledgeTag.name)\r\n .execute();\r\n}\r\n\r\n/**\r\n * 更新标签\r\n */\r\nexport async function updateTag(id: number, data: Partial<InsertTag>, userId: number) {\r\n const db = getDB();\r\n\r\n // 检查权限\r\n const [tag] = await db\r\n .select()\r\n .from(knowledgeTag)\r\n .where(and(eq(knowledgeTag.id, id), eq(knowledgeTag.userId, userId)))\r\n .limit(1);\r\n\r\n if (!tag) {\r\n throw new Error(\"标签不存在或无权操作\");\r\n }\r\n\r\n await db\r\n .update(knowledgeTag)\r\n .set({\r\n ...(data.name !== undefined && { name: data.name }),\r\n ...(data.color !== undefined && { color: data.color }),\r\n })\r\n .where(eq(knowledgeTag.id, id))\r\n .execute();\r\n\r\n return getTagById(id);\r\n}\r\n\r\n/**\r\n * 删除标签\r\n */\r\nexport async function deleteTag(id: number, userId: number) {\r\n const db = getDB();\r\n\r\n // 检查权限\r\n const [tag] = await db\r\n .select()\r\n .from(knowledgeTag)\r\n .where(and(eq(knowledgeTag.id, id), eq(knowledgeTag.userId, userId)))\r\n .limit(1);\r\n\r\n if (!tag) {\r\n throw new Error(\"标签不存在或无权操作\");\r\n }\r\n\r\n // 删除标签关联\r\n await db\r\n .delete(knowledgeTagRelation)\r\n .where(eq(knowledgeTagRelation.tagId, id))\r\n .execute();\r\n\r\n // 删除标签\r\n await db\r\n .delete(knowledgeTag)\r\n .where(eq(knowledgeTag.id, id))\r\n .execute();\r\n\r\n return { success: true };\r\n}\r\n\r\n// ==================== 标签关联 ====================\r\n\r\n/**\r\n * 为知识库内容添加标签\r\n */\r\nexport async function addTagToKnowledge(knowledgeId: number, tagId: number, userId: number) {\r\n const db = getDB();\r\n\r\n // 检查标签是否存在\r\n const [tag] = await db\r\n .select()\r\n .from(knowledgeTag)\r\n .where(eq(knowledgeTag.id, tagId))\r\n .limit(1);\r\n\r\n if (!tag) {\r\n throw new Error(\"标签不存在\");\r\n }\r\n\r\n // 检查是否已存在关联\r\n const [existing] = await db\r\n .select()\r\n .from(knowledgeTagRelation)\r\n .where(\r\n and(\r\n eq(knowledgeTagRelation.knowledgeId, knowledgeId),\r\n eq(knowledgeTagRelation.tagId, tagId)\r\n )\r\n )\r\n .limit(1);\r\n\r\n if (existing) {\r\n return { success: true, message: \"标签已存在\" };\r\n }\r\n\r\n // 创建关联\r\n await db\r\n .insert(knowledgeTagRelation)\r\n .values({\r\n knowledgeId,\r\n tagId,\r\n })\r\n .execute();\r\n\r\n return { success: true };\r\n}\r\n\r\n/**\r\n * 移除知识库内容的标签\r\n */\r\nexport async function removeTagFromKnowledge(knowledgeId: number, tagId: number) {\r\n const db = getDB();\r\n\r\n await db\r\n .delete(knowledgeTagRelation)\r\n .where(\r\n and(\r\n eq(knowledgeTagRelation.knowledgeId, knowledgeId),\r\n eq(knowledgeTagRelation.tagId, tagId)\r\n )\r\n )\r\n .execute();\r\n\r\n return { success: true };\r\n}\r\n\r\n/**\r\n * 获取知识库内容的标签列表\r\n */\r\nexport async function getKnowledgeTags(knowledgeId: number) {\r\n const db = getDB();\r\n\r\n return await db\r\n .select({\r\n id: knowledgeTag.id,\r\n name: knowledgeTag.name,\r\n color: knowledgeTag.color,\r\n })\r\n .from(knowledgeTagRelation)\r\n .innerJoin(knowledgeTag, eq(knowledgeTagRelation.tagId, knowledgeTag.id))\r\n .where(eq(knowledgeTagRelation.knowledgeId, knowledgeId))\r\n .execute();\r\n}\r\n\r\n/**\r\n * 按标签查询知识库内容\r\n */\r\nexport async function getKnowledgeByTag(tagId: number, options: {\r\n pageIndex?: number;\r\n pageSize?: number;\r\n safe?: number[];\r\n userId?: number;\r\n isAdmin?: boolean;\r\n}) {\r\n const db = getDB();\r\n const { pageIndex = 1, pageSize = 10, safe = [0], userId, isAdmin } = options;\r\n\r\n // 获取带有该标签的知识库 ID 列表\r\n const relations = await db\r\n .select()\r\n .from(knowledgeTagRelation)\r\n .where(eq(knowledgeTagRelation.tagId, tagId))\r\n .execute();\r\n\r\n if (relations.length === 0) {\r\n return { list: [], total: 0, pageIndex, pageSize };\r\n }\r\n\r\n const knowledgeIds = relations.map(r => r.knowledgeId);\r\n\r\n // 导入 knowledge 表\r\n const { knowledge } = await import(\"../orm/Knowledge.schema\");\r\n const { eq, and, or, sql, desc } = await import(\"drizzle-orm\");\r\n\r\n let conditions = [\r\n eq(knowledge.isDelete, 0),\r\n inArray(knowledge.id, knowledgeIds),\r\n ];\r\n\r\n // 权限筛选\r\n const safeConditions = [];\r\n for (const s of safe) {\r\n switch (s) {\r\n case 0: // 公开\r\n safeConditions.push(eq(knowledge.safe, s));\r\n break;\r\n case 1: // 登录共享\r\n if (userId) {\r\n safeConditions.push(eq(knowledge.safe, s));\r\n }\r\n break;\r\n case 2: // 个人私密\r\n if (userId) {\r\n safeConditions.push(\r\n and(eq(knowledge.safe, s), isAdmin ? sql`1=1` : eq(knowledge.userId, userId))\r\n );\r\n }\r\n break;\r\n }\r\n }\r\n\r\n if (safeConditions.length > 0) {\r\n conditions.push(or(...safeConditions));\r\n }\r\n\r\n const offset = (pageIndex - 1) * pageSize;\r\n\r\n const list = await db\r\n .select()\r\n .from(knowledge)\r\n .where(and(...conditions))\r\n .limit(pageSize)\r\n .offset(offset)\r\n .orderBy(desc(knowledge.created))\r\n .execute();\r\n\r\n const [totalResult] = await db\r\n .select({ count: sql<number>`count(*)` })\r\n .from(knowledge)\r\n .where(and(...conditions))\r\n .execute();\r\n\r\n return {\r\n list,\r\n total: totalResult.count,\r\n pageIndex,\r\n pageSize,\r\n };\r\n}\r\n"],"mappings":"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","names":["eq","and"]}
@@ -0,0 +1,40 @@
1
+ // ../../node_modules/drizzle-zod/index.mjs
2
+ import { getTableColumns as e, is as t } from "drizzle-orm";
3
+ import { MySqlVarChar as n, MySqlVarBinary as r, MySqlChar as o } from "drizzle-orm/mysql-core";
4
+ import { PgUUID as i, PgChar as a, PgVarchar as l } from "drizzle-orm/pg-core";
5
+ import { SQLiteText as s } from "drizzle-orm/sqlite-core";
6
+ import { z as u } from "zod";
7
+ var m = u.union([u.string(), u.number(), u.boolean(), u.null()]);
8
+ var f = u.lazy((() => u.union([m, u.array(f), u.record(f)])));
9
+ function c(t2, n2) {
10
+ const r2 = e(t2), o2 = Object.entries(r2);
11
+ let i2 = Object.fromEntries(o2.map((([e2, t3]) => [e2, p(t3)])));
12
+ n2 && (i2 = Object.assign(i2, Object.fromEntries(Object.entries(n2).map((([e2, t3]) => [e2, "function" == typeof t3 ? t3(i2) : t3])))));
13
+ for (const [e2, t3] of o2) t3.notNull ? t3.hasDefault && (i2[e2] = i2[e2].optional()) : i2[e2] = i2[e2].nullable().optional();
14
+ return u.object(i2);
15
+ }
16
+ function p(e2) {
17
+ let m2;
18
+ if ((function(e3) {
19
+ return "enumValues" in e3 && Array.isArray(e3.enumValues) && e3.enumValues.length > 0;
20
+ })(e2) && (m2 = e2.enumValues.length ? u.enum(e2.enumValues) : u.string()), !m2) {
21
+ if (t(e2, i)) m2 = u.string().uuid();
22
+ else if ("custom" === e2.dataType) m2 = u.any();
23
+ else if ("json" === e2.dataType) m2 = f;
24
+ else if ("array" === e2.dataType) m2 = u.array(p(e2.baseColumn));
25
+ else if ("number" === e2.dataType) m2 = u.number();
26
+ else if ("bigint" === e2.dataType) m2 = u.bigint();
27
+ else if ("boolean" === e2.dataType) m2 = u.boolean();
28
+ else if ("date" === e2.dataType) m2 = u.date();
29
+ else if ("string" === e2.dataType) {
30
+ let i2 = u.string();
31
+ (t(e2, a) || t(e2, l) || t(e2, n) || t(e2, r) || t(e2, o) || t(e2, s)) && "number" == typeof e2.length && (i2 = i2.max(e2.length)), m2 = i2;
32
+ }
33
+ }
34
+ return m2 || (m2 = u.any()), m2;
35
+ }
36
+
37
+ export {
38
+ c
39
+ };
40
+ //# sourceMappingURL=chunk-GWIBTASJ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../node_modules/src/index.ts"],"sourcesContent":[null],"mappings":";;;;;;AAeA,IAAMA,IAAgBC,EAAEC,MAAM,CAACD,EAAEE,OAAAA,GAAUF,EAAEG,OAAAA,GAAUH,EAAEI,QAAAA,GAAWJ,EAAEK,KAAAA,CAAAA,CAAAA;AAAtE,IAGaC,IAA8BN,EAAEO,MAAK,MACjDP,EAAEC,MAAM,CAACF,GAAeC,EAAEQ,MAAMF,CAAAA,GAAaN,EAAES,OAAOH,CAAAA,CAAAA,CAAAA,EAAAA;AA+EjD,SAAUI,EAIfC,IAIAC,IAAAA;AAKA,QAAMC,KAAUC,EAAgBH,EAAAA,GAC1BI,KAAgBC,OAAOC,QAAQJ,EAAAA;AAErC,MAAIK,KAAgBF,OAAOG,YAAYJ,GAAcK,KAAI,CAAA,CAAEC,IAAMC,EAAAA,MACzD,CAACD,IAAME,EAAkBD,EAAAA,CAAAA,EAAAA,CAAAA;AAG7BV,EAAAA,OACHM,KAAgBF,OAAOQ,OACtBN,IACAF,OAAOG,YACNH,OAAOC,QAAQL,EAAAA,EAAQQ,KAAI,CAAA,CAAEC,IAAMI,EAAAA,MAC3B,CACNJ,IACwB,cAAA,OAAjBI,KACJA,GAAaP,EAAAA,IACbO,EAAAA,EAAAA,CAAAA,CAAAA;AAOR,aAAK,CAAOJ,IAAMC,EAAAA,KAAWP,GACvBO,CAAAA,GAAOI,UAEDJ,GAAOK,eACjBT,GAAcG,EAAAA,IAAQH,GAAcG,EAAAA,EAAOO,SAAAA,KAF3CV,GAAcG,EAAAA,IAAQH,GAAcG,EAAAA,EAAOQ,SAAAA,EAAWD,SAAAA;AAMxD,SAAO5B,EAAE8B,OAAOZ,EAAAA;AACjB;AAmDA,SAASa,EAAkBC,IAAAA;AAC1B,MAAIC;AAMJ,OAXD,SAAoBD,IAAAA;AACnB,WAAO,gBAAgBA,MAAUE,MAAMC,QAAQH,GAAOI,UAAAA,KAAeJ,GAAOI,WAAWC,SAAS;EACjG,GAKgBL,EAAAA,MACdC,KAAOD,GAAOI,WAAWC,SAASC,EAAEC,KAAKP,GAAOI,UAAAA,IAAcE,EAAEE,OAAAA,IAAAA,CAG5DP;AACJ,QAAIQ,EAAGT,IAAQU,CAAAA,EACdT,CAAAA,KAAOK,EAAEE,OAAAA,EAASG,KAAAA;aACY,aAApBX,GAAOY,SACjBX,CAAAA,KAAOK,EAAEO,IAAAA;aACqB,WAApBb,GAAOY,SACjBX,CAAAA,KAAOa;aACuB,YAApBd,GAAOY,SACjBX,CAAAA,KAAOK,EAAES,MAAMhB,EAAmBC,GAA6BgB,UAAAA,CAAAA;aACjC,aAApBhB,GAAOY,SACjBX,CAAAA,KAAOK,EAAEW,OAAAA;aACqB,aAApBjB,GAAOY,SACjBX,CAAAA,KAAOK,EAAEY,OAAAA;aACqB,cAApBlB,GAAOY,SACjBX,CAAAA,KAAOK,EAAEa,QAAAA;aACqB,WAApBnB,GAAOY,SACjBX,CAAAA,KAAOK,EAAEc,KAAAA;aACqB,aAApBpB,GAAOY,UAAuB;AACxC,UAAIS,KAAQf,EAAEE,OAAAA;AAAAA,OAGZC,EAAGT,IAAQsB,CAAAA,KAAWb,EAAGT,IAAQuB,CAAAA,KAAcd,EAAGT,IAAQwB,CAAAA,KACvDf,EAAGT,IAAQyB,CAAAA,KAAmBhB,EAAGT,IAAQ0B,CAAAA,KAAcjB,EAAGT,IAAQ2B,CAAAA,MACzC,YAAA,OAAlB3B,GAAOK,WAElBgB,KAAQA,GAAMO,IAAI5B,GAAOK,MAAAA,IAG1BJ,KAAOoB;IACP;;AAOF,SAJKpB,OACJA,KAAOK,EAAEO,IAAAA,IAGHZ;AACR;","names":["literalSchema","z","union","string","number","boolean","null","jsonSchema","lazy","array","record","createInsertSchema","table","refine","columns","getTableColumns","columnEntries","Object","entries","schemaEntries","fromEntries","map","name","column","mapColumnToSchema","assign","refineColumn","notNull","hasDefault","optional","nullable","object","mapColumnToSchema","column","type","Array","isArray","enumValues","length","z","enum","string","is","PgUUID","uuid","dataType","any","jsonSchema","array","baseColumn","number","bigint","boolean","date","sType","PgChar","PgVarchar","MySqlVarChar","MySqlVarBinary","MySqlChar","SQLiteText","max"]}
@@ -0,0 +1,40 @@
1
+ import {
2
+ c
3
+ } from "./chunk-GWIBTASJ.mjs";
4
+
5
+ // orm/Tag.schema.ts
6
+ import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core";
7
+ import { z } from "zod";
8
+ var knowledgeTag = sqliteTable("knowledge_tag", {
9
+ id: integer("id").primaryKey({ autoIncrement: true }),
10
+ name: text("name").notNull().unique(),
11
+ color: text("color"),
12
+ userId: integer("user_id"),
13
+ created: integer("created", { mode: "timestamp" })
14
+ });
15
+ var knowledgeTagRelation = sqliteTable("knowledge_tag_relation", {
16
+ knowledgeId: integer("knowledge_id").notNull(),
17
+ tagId: integer("tag_id").notNull()
18
+ });
19
+ var createTagSchema = c(knowledgeTag, {
20
+ name: z.string().min(1, "\u6807\u7B7E\u540D\u4E0D\u80FD\u4E3A\u7A7A").max(50, "\u6807\u7B7E\u540D\u4E0D\u80FD\u8D85\u8FC750\u5B57\u7B26"),
21
+ color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, "\u989C\u8272\u5FC5\u987B\u662F\u5341\u516D\u8FDB\u5236\u683C\u5F0F").optional()
22
+ }).pick({
23
+ name: true,
24
+ color: true
25
+ });
26
+ var updateTagSchema = c(knowledgeTag).partial().extend({
27
+ id: z.number({ required_error: "\u6807\u7B7EID\u4E0D\u80FD\u4E3A\u7A7A" })
28
+ });
29
+ var addTagRelationSchema = z.object({
30
+ tagId: z.number({ required_error: "\u6807\u7B7EID\u4E0D\u80FD\u4E3A\u7A7A" })
31
+ });
32
+
33
+ export {
34
+ knowledgeTag,
35
+ knowledgeTagRelation,
36
+ createTagSchema,
37
+ updateTagSchema,
38
+ addTagRelationSchema
39
+ };
40
+ //# sourceMappingURL=chunk-S3ZXTYZ2.mjs.map