@mindbase/express-knowledge 1.0.12 → 1.0.13

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/types/index.ts CHANGED
@@ -1,85 +1,85 @@
1
- import type { knowledge } from "../orm/Knowledge.schema";
2
- import type { knowledgeTag } from "../orm/Tag.schema";
3
-
4
- // ==================== 枚举类型 ====================
5
-
6
- /**
7
- * 安全级别
8
- */
9
- export enum KnowledgeSafe {
10
- PUB = 0, // 公开(所有人可见)
11
- SHARED = 1, // 登录共享(登录用户可见)
12
- PRIVATE = 2, // 个人私密(仅创建者可见)
13
- }
14
-
15
- /**
16
- * 节点类型
17
- */
18
- export enum KnowledgeType {
19
- FOLDER = 0, // 文件夹
20
- NOTE = 1, // 笔记
21
- BOOK = 2, // 书籍
22
- }
23
-
24
- // ==================== 接口类型 ====================
25
-
26
- /**
27
- * 知识库基础信息
28
- */
29
- export interface Knowledge {
30
- id: number;
31
- name: string;
32
- path: string;
33
- level: number;
34
- type: KnowledgeType;
35
- safe: KnowledgeSafe;
36
- userId: number;
37
- // 书籍特有字段
38
- coverImage?: string | null;
39
- author?: string | null;
40
- isbn?: string | null;
41
- description?: string | null;
42
- created: Date;
43
- updated: Date;
44
- isDelete: number;
45
- isTop: number;
46
- content?: string | null;
47
- contentText?: string | null;
48
- viewType: number;
49
- }
50
-
51
- /**
52
- * 树节点(带子节点)
53
- */
54
- export interface KnowledgeTreeNode extends Knowledge {
55
- children?: KnowledgeTreeNode[];
56
- }
57
-
58
- /**
59
- * 标签
60
- */
61
- export interface KnowledgeTag {
62
- id: number;
63
- name: string;
64
- color?: string | null;
65
- userId?: number | null;
66
- created?: Date;
67
- }
68
-
69
- /**
70
- * 标签关联
71
- */
72
- export interface KnowledgeTagRelation {
73
- knowledgeId: number;
74
- tagId: number;
75
- }
76
-
77
- /**
78
- * 创建知识库输入
79
- */
80
- export type InsertKnowledge = Partial<Omit<typeof knowledge.$inferInsert, "id">>;
81
-
82
- /**
83
- * 插入标签输入
84
- */
85
- export type InsertTag = typeof knowledgeTag.$inferInsert;
1
+ import type { knowledge } from "../orm/Knowledge.schema";
2
+ import type { knowledgeTag } from "../orm/Tag.schema";
3
+
4
+ // ==================== 枚举类型 ====================
5
+
6
+ /**
7
+ * 安全级别
8
+ */
9
+ export enum KnowledgeSafe {
10
+ PUB = 0, // 公开(所有人可见)
11
+ SHARED = 1, // 登录共享(登录用户可见)
12
+ PRIVATE = 2, // 个人私密(仅创建者可见)
13
+ }
14
+
15
+ /**
16
+ * 节点类型
17
+ */
18
+ export enum KnowledgeType {
19
+ FOLDER = 0, // 文件夹
20
+ NOTE = 1, // 笔记
21
+ BOOK = 2, // 书籍
22
+ }
23
+
24
+ // ==================== 接口类型 ====================
25
+
26
+ /**
27
+ * 知识库基础信息
28
+ */
29
+ export interface Knowledge {
30
+ id: number;
31
+ name: string;
32
+ path: string;
33
+ level: number;
34
+ type: KnowledgeType;
35
+ safe: KnowledgeSafe;
36
+ userId: number;
37
+ // 书籍特有字段
38
+ coverImage?: string | null;
39
+ author?: string | null;
40
+ isbn?: string | null;
41
+ description?: string | null;
42
+ created: Date;
43
+ updated: Date;
44
+ isDelete: number;
45
+ isTop: number;
46
+ content?: string | null;
47
+ contentText?: string | null;
48
+ viewType: number;
49
+ }
50
+
51
+ /**
52
+ * 树节点(带子节点)
53
+ */
54
+ export interface KnowledgeTreeNode extends Knowledge {
55
+ children?: KnowledgeTreeNode[];
56
+ }
57
+
58
+ /**
59
+ * 标签
60
+ */
61
+ export interface KnowledgeTag {
62
+ id: number;
63
+ name: string;
64
+ color?: string | null;
65
+ userId?: number | null;
66
+ created?: Date;
67
+ }
68
+
69
+ /**
70
+ * 标签关联
71
+ */
72
+ export interface KnowledgeTagRelation {
73
+ knowledgeId: number;
74
+ tagId: number;
75
+ }
76
+
77
+ /**
78
+ * 创建知识库输入
79
+ */
80
+ export type InsertKnowledge = Partial<Omit<typeof knowledge.$inferInsert, "id">>;
81
+
82
+ /**
83
+ * 插入标签输入
84
+ */
85
+ export type InsertTag = typeof knowledgeTag.$inferInsert;
@@ -1,47 +1,47 @@
1
- /**
2
- * 物化路径工具函数
3
- */
4
-
5
- /**
6
- * 构建新节点路径
7
- * @param parentPath 父节点路径
8
- * @param id 新节点ID
9
- * @returns 新节点路径
10
- */
11
- export function buildPath(parentPath: string, id: number): string {
12
- return `${parentPath}${id}/`;
13
- }
14
-
15
- /**
16
- * 从路径计算层级
17
- * @param path 节点路径
18
- * @returns 层级深度(根节点为0)
19
- */
20
- export function getLevel(path: string): number {
21
- // path 格式: "/1/3/7/" -> 分割后 ['', '1', '3', '7', '']
22
- // 减2是因为前后各有一个空字符串
23
- const parts = path.split("/").filter(Boolean);
24
- return parts.length - 1;
25
- }
26
-
27
- /**
28
- * 验证路径是否有效(防止循环引用)
29
- * @param newPath 新路径
30
- * @param oldPath 旧路径
31
- * @returns 是否有效
32
- */
33
- export function validatePath(newPath: string, oldPath: string): boolean {
34
- // 不能将节点移动到自己的后代节点下
35
- // 如果新父节点的 path 以旧节点的 path 开头,说明是后代
36
- return !newPath.startsWith(oldPath);
37
- }
38
-
39
- /**
40
- * 检查是否为后代节点
41
- * @param ancestorPath 祖先节点路径
42
- * @param descendantPath 后代节点路径
43
- * @returns 是否为后代
44
- */
45
- export function isDescendant(ancestorPath: string, descendantPath: string): boolean {
46
- return descendantPath.startsWith(ancestorPath) && ancestorPath !== descendantPath;
47
- }
1
+ /**
2
+ * 物化路径工具函数
3
+ */
4
+
5
+ /**
6
+ * 构建新节点路径
7
+ * @param parentPath 父节点路径
8
+ * @param id 新节点ID
9
+ * @returns 新节点路径
10
+ */
11
+ export function buildPath(parentPath: string, id: number): string {
12
+ return `${parentPath}${id}/`;
13
+ }
14
+
15
+ /**
16
+ * 从路径计算层级
17
+ * @param path 节点路径
18
+ * @returns 层级深度(根节点为0)
19
+ */
20
+ export function getLevel(path: string): number {
21
+ // path 格式: "/1/3/7/" -> 分割后 ['', '1', '3', '7', '']
22
+ // 减2是因为前后各有一个空字符串
23
+ const parts = path.split("/").filter(Boolean);
24
+ return parts.length - 1;
25
+ }
26
+
27
+ /**
28
+ * 验证路径是否有效(防止循环引用)
29
+ * @param newPath 新路径
30
+ * @param oldPath 旧路径
31
+ * @returns 是否有效
32
+ */
33
+ export function validatePath(newPath: string, oldPath: string): boolean {
34
+ // 不能将节点移动到自己的后代节点下
35
+ // 如果新父节点的 path 以旧节点的 path 开头,说明是后代
36
+ return !newPath.startsWith(oldPath);
37
+ }
38
+
39
+ /**
40
+ * 检查是否为后代节点
41
+ * @param ancestorPath 祖先节点路径
42
+ * @param descendantPath 后代节点路径
43
+ * @returns 是否为后代
44
+ */
45
+ export function isDescendant(ancestorPath: string, descendantPath: string): boolean {
46
+ return descendantPath.startsWith(ancestorPath) && ancestorPath !== descendantPath;
47
+ }
@@ -1,57 +1,57 @@
1
- import type { KnowledgeTreeNode, Knowledge } from "../types";
2
-
3
- /**
4
- * 将扁平数组转换为树形结构
5
- * @param nodes 扁平节点数组
6
- * @param parentId 父节点ID(可选,用于构建子树)
7
- * @returns 树形结构
8
- */
9
- export function buildTree(
10
- nodes: Knowledge[],
11
- parentId: number | null = null
12
- ): KnowledgeTreeNode[] {
13
- // 按 isTop 降序、created 降序排序
14
- const sortedNodes = [...nodes].sort((a, b) => {
15
- if (a.isTop !== b.isTop) {
16
- return b.isTop - a.isTop;
17
- }
18
- return b.created.getTime() - a.created.getTime();
19
- });
20
-
21
- // 如果指定了 parentId,先找到该节点
22
- if (parentId !== null) {
23
- const parent = sortedNodes.find(n => n.id === parentId);
24
- if (!parent) return [];
25
-
26
- // 查找该节点的直接子节点
27
- const children = sortedNodes.filter(n =>
28
- n.path.startsWith(parent.path) &&
29
- n.level === parent.level + 1
30
- );
31
-
32
- return children.map(child => buildNodeTree(child, sortedNodes));
33
- }
34
-
35
- // 否则返回根节点(level=0)的树
36
- const rootNodes = sortedNodes.filter(n => n.level === 0);
37
- return rootNodes.map(node => buildNodeTree(node, sortedNodes));
38
- }
39
-
40
- /**
41
- * 递归构建节点树
42
- */
43
- function buildNodeTree(node: Knowledge, allNodes: Knowledge[]): KnowledgeTreeNode {
44
- const treeNode: KnowledgeTreeNode = { ...node };
45
-
46
- // 查找直接子节点
47
- const children = allNodes.filter(n =>
48
- n.path.startsWith(node.path) &&
49
- n.level === node.level + 1
50
- );
51
-
52
- if (children.length > 0) {
53
- treeNode.children = children.map(child => buildNodeTree(child, allNodes));
54
- }
55
-
56
- return treeNode;
57
- }
1
+ import type { KnowledgeTreeNode, Knowledge } from "../types";
2
+
3
+ /**
4
+ * 将扁平数组转换为树形结构
5
+ * @param nodes 扁平节点数组
6
+ * @param parentId 父节点ID(可选,用于构建子树)
7
+ * @returns 树形结构
8
+ */
9
+ export function buildTree(
10
+ nodes: Knowledge[],
11
+ parentId: number | null = null
12
+ ): KnowledgeTreeNode[] {
13
+ // 按 isTop 降序、created 降序排序
14
+ const sortedNodes = [...nodes].sort((a, b) => {
15
+ if (a.isTop !== b.isTop) {
16
+ return b.isTop - a.isTop;
17
+ }
18
+ return b.created.getTime() - a.created.getTime();
19
+ });
20
+
21
+ // 如果指定了 parentId,先找到该节点
22
+ if (parentId !== null) {
23
+ const parent = sortedNodes.find(n => n.id === parentId);
24
+ if (!parent) return [];
25
+
26
+ // 查找该节点的直接子节点
27
+ const children = sortedNodes.filter(n =>
28
+ n.path.startsWith(parent.path) &&
29
+ n.level === parent.level + 1
30
+ );
31
+
32
+ return children.map(child => buildNodeTree(child, sortedNodes));
33
+ }
34
+
35
+ // 否则返回根节点(level=0)的树
36
+ const rootNodes = sortedNodes.filter(n => n.level === 0);
37
+ return rootNodes.map(node => buildNodeTree(node, sortedNodes));
38
+ }
39
+
40
+ /**
41
+ * 递归构建节点树
42
+ */
43
+ function buildNodeTree(node: Knowledge, allNodes: Knowledge[]): KnowledgeTreeNode {
44
+ const treeNode: KnowledgeTreeNode = { ...node };
45
+
46
+ // 查找直接子节点
47
+ const children = allNodes.filter(n =>
48
+ n.path.startsWith(node.path) &&
49
+ n.level === node.level + 1
50
+ );
51
+
52
+ if (children.length > 0) {
53
+ treeNode.children = children.map(child => buildNodeTree(child, allNodes));
54
+ }
55
+
56
+ return treeNode;
57
+ }