@whispering233/ai-editor-shared 0.0.15 → 0.0.20
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/constants/backup.d.ts +2 -2
- package/dist/constants/backup.d.ts.map +1 -1
- package/dist/constants/backup.js +2 -2
- package/dist/constants/backup.js.map +1 -1
- package/dist/constants/entity.d.ts +2 -4
- package/dist/constants/entity.d.ts.map +1 -1
- package/dist/constants/entity.js +10 -2
- package/dist/constants/entity.js.map +1 -1
- package/dist/constants/outline.d.ts +2 -0
- package/dist/constants/outline.d.ts.map +1 -1
- package/dist/constants/outline.js +6 -0
- package/dist/constants/outline.js.map +1 -1
- package/dist/types/api.d.ts +65 -18
- package/dist/types/api.d.ts.map +1 -1
- package/dist/types/api.js +81 -9
- package/dist/types/api.js.map +1 -1
- package/dist/types/entity.d.ts +6 -0
- package/dist/types/entity.d.ts.map +1 -1
- package/dist/types/project.d.ts +19 -3
- package/dist/types/project.d.ts.map +1 -1
- package/dist/types/tool.d.ts +6 -14
- package/dist/types/tool.d.ts.map +1 -1
- package/dist/types/tool.js +7 -5
- package/dist/types/tool.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/mapping.d.ts +4 -2
- package/dist/utils/mapping.d.ts.map +1 -1
- package/dist/utils/mapping.js +6 -4
- package/dist/utils/mapping.js.map +1 -1
- package/dist/utils/reference-file.d.ts +39 -0
- package/dist/utils/reference-file.d.ts.map +1 -0
- package/dist/utils/reference-file.js +131 -0
- package/dist/utils/reference-file.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
// 参考资料文件工具纯函数(决策 43,批次十一)
|
|
2
|
+
// 职责:md 文件(YAML frontmatter + markdown 正文)的解析/序列化 + 文件名 sanitize。
|
|
3
|
+
// 约束(shared 硬约束):纯 TS 无 Node 内置模块——仅字符串处理,client 可打包。
|
|
4
|
+
// 契约来源:doc/design/decisions.md 决策 43(文件 = 真相源:frontmatter 自包含可重建索引)、
|
|
5
|
+
// doc/database/schema.md(reference data 字段 kind/file_name/file_mtime)。
|
|
6
|
+
//
|
|
7
|
+
// frontmatter 格式(决策 43 Q1=方案 A):
|
|
8
|
+
// ---
|
|
9
|
+
// title: 五行相生相克 摘抄
|
|
10
|
+
// category: material
|
|
11
|
+
// tags: [五行, 设定]
|
|
12
|
+
// ---
|
|
13
|
+
// 正文 markdown…
|
|
14
|
+
// 解析容错:frontmatter 缺失/非法 → 按纯 markdown 处理(title=undefined、category=undefined、
|
|
15
|
+
// tags=[]、body=全文),调用方兜底(title=文件名去扩展名、category=material)。
|
|
16
|
+
/** YAML frontmatter 边界标记(须独占一行) */
|
|
17
|
+
export const FRONTMATTER_DELIMITER = "---";
|
|
18
|
+
/** 提取 frontmatter 块内原始行(不含 --- 边界)与正文偏移;无 frontmatter → null */
|
|
19
|
+
function splitFrontmatter(text) {
|
|
20
|
+
// 首行必须是 ---(允许前导空行?不——严格首行,Obsidian/Typora 惯例)
|
|
21
|
+
if (!text.startsWith(`${FRONTMATTER_DELIMITER}\n`))
|
|
22
|
+
return null;
|
|
23
|
+
const firstNl = text.indexOf("\n");
|
|
24
|
+
const rest = text.slice(firstNl + 1);
|
|
25
|
+
// 找闭合 ---(独占一行)
|
|
26
|
+
const lines = rest.split("\n");
|
|
27
|
+
for (let i = 0; i < lines.length; i++) {
|
|
28
|
+
if (lines[i].trim() === FRONTMATTER_DELIMITER) {
|
|
29
|
+
const body = lines.slice(i + 1).join("\n");
|
|
30
|
+
// 去掉 body 开头单个换行(--- 闭合行后紧跟空行是惯例,保留语义不吞内容)
|
|
31
|
+
// 与末尾恰一个换行(POSIX 文件末尾换行惯例;roundtrip 稳定:serialize 输出 \n → parse 去掉)
|
|
32
|
+
return { rawLines: lines.slice(0, i), body: body.replace(/^\n/, "").replace(/\n$/, "") };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// 有起始无闭合 → 视为无 frontmatter(容错:全文当正文)
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
/** 解析单行 `key: value`(引号剥离:'…'/"…";值去首尾空白;无冒号 → null) */
|
|
39
|
+
function parseKeyValue(line) {
|
|
40
|
+
const idx = line.indexOf(":");
|
|
41
|
+
if (idx <= 0)
|
|
42
|
+
return null;
|
|
43
|
+
const key = line.slice(0, idx).trim();
|
|
44
|
+
const raw = line.slice(idx + 1).trim();
|
|
45
|
+
if (key === "")
|
|
46
|
+
return null;
|
|
47
|
+
// 行内数组 `tags: [a, b]` → 剥离括号后逗号分片
|
|
48
|
+
if (raw.startsWith("[") && raw.endsWith("]")) {
|
|
49
|
+
return { key, value: raw.slice(1, -1) };
|
|
50
|
+
}
|
|
51
|
+
// 引号包裹值
|
|
52
|
+
const unquoted = raw.replace(/^(['"])(.*)\1$/, "$2");
|
|
53
|
+
return { key, value: unquoted.trim() };
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* 解析 md 文件文本(frontmatter + 正文;决策 43)。
|
|
57
|
+
* 容错:无 frontmatter / 起始无闭合 → 全当正文;单行值数组/引号/注释行(# 开头)跳过;
|
|
58
|
+
* 重复 key 后者覆盖;未知 key 忽略(title/category/tags 之外的字段不进入索引,但序列化时保留——
|
|
59
|
+
* 见 serializeReferenceFile 的 extraLines 参数)。
|
|
60
|
+
*/
|
|
61
|
+
export function parseReferenceFrontmatter(text) {
|
|
62
|
+
const block = splitFrontmatter(text);
|
|
63
|
+
if (block === null)
|
|
64
|
+
return { tags: [], extraLines: [], body: text };
|
|
65
|
+
let title;
|
|
66
|
+
let category;
|
|
67
|
+
const tags = [];
|
|
68
|
+
const unknown = [];
|
|
69
|
+
for (const line of block.rawLines) {
|
|
70
|
+
const trimmed = line.trim();
|
|
71
|
+
if (trimmed === "" || trimmed.startsWith("#"))
|
|
72
|
+
continue;
|
|
73
|
+
const kv = parseKeyValue(trimmed);
|
|
74
|
+
if (kv === null)
|
|
75
|
+
continue;
|
|
76
|
+
if (kv.key === "title")
|
|
77
|
+
title = kv.value;
|
|
78
|
+
else if (kv.key === "category")
|
|
79
|
+
category = kv.value;
|
|
80
|
+
else if (kv.key === "tags") {
|
|
81
|
+
tags.length = 0;
|
|
82
|
+
for (const part of kv.value.split(",")) {
|
|
83
|
+
const t = part.trim();
|
|
84
|
+
if (t !== "")
|
|
85
|
+
tags.push(t);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
unknown.push(line); // 保留未知行(序列化时原样写回,防外部编辑器自定义字段丢失)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return { title, category, tags, extraLines: unknown, body: block.body };
|
|
93
|
+
}
|
|
94
|
+
/** 序列化参考文件全文(frontmatter + 正文;决策 43 格式) */
|
|
95
|
+
export function serializeReferenceFile(input) {
|
|
96
|
+
const lines = [FRONTMATTER_DELIMITER];
|
|
97
|
+
lines.push(`title: ${input.title}`);
|
|
98
|
+
lines.push(`category: ${input.category}`);
|
|
99
|
+
lines.push(`tags: [${input.tags.join(", ")}]`);
|
|
100
|
+
for (const line of input.extraLines ?? [])
|
|
101
|
+
lines.push(line);
|
|
102
|
+
lines.push(FRONTMATTER_DELIMITER);
|
|
103
|
+
// 全部前导换行归一(body 空行分隔:frontmatter 后恰一个空行再进正文)
|
|
104
|
+
const body = input.body.replace(/^\n+/, "");
|
|
105
|
+
if (body !== "")
|
|
106
|
+
lines.push("", body);
|
|
107
|
+
return `${lines.join("\n")}\n`;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* 文件名 sanitize(决策 43:创建时标题作文件名;禁路径分隔符/保留字符/控制字符/纯点)。
|
|
111
|
+
* 规则对齐 sanitizeBackupName(B2.6)心智:Windows 保留字符 `\ / : * ? " < > |`、控制字符、
|
|
112
|
+
* 首尾空白/点、纯点(. / ..)全部清除/替换;空结果 → "未命名";截断 100 字符(name 上限)。
|
|
113
|
+
* 返回不含 .md 扩展名的基名(调用方自行拼接)。
|
|
114
|
+
*/
|
|
115
|
+
export function sanitizeReferenceFileName(name) {
|
|
116
|
+
// 保留 CJK/字母数字/空格/常见标点(- _ . ()【】、,。;:!?·),其余替换为空格后折叠
|
|
117
|
+
const cleaned = name
|
|
118
|
+
// 控制字符与路径分隔符/保留字符 → 空格
|
|
119
|
+
.replace(/[\u0000-\u001f\u007f\\/:*?"<>|]/g, " ")
|
|
120
|
+
// 连续空白折叠 + 首尾清理
|
|
121
|
+
.replace(/\s+/g, " ")
|
|
122
|
+
.trim()
|
|
123
|
+
// 首尾点清理(Windows 尾点/点号问题),保留内部点(如「1.2 节」)
|
|
124
|
+
.replace(/^\.+|\.+$/g, "")
|
|
125
|
+
.slice(0, 100)
|
|
126
|
+
.trim();
|
|
127
|
+
if (cleaned === "" || cleaned === "." || cleaned === "..")
|
|
128
|
+
return "未命名";
|
|
129
|
+
return cleaned;
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=reference-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reference-file.js","sourceRoot":"","sources":["../../src/utils/reference-file.ts"],"names":[],"mappings":"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"}
|