@tnotesjs/core 0.6.0 → 0.7.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/config/templates.ts +0 -5
- package/dist/{chunk-IHFUHB4J.cjs → chunk-7FEANCT6.cjs} +17 -8
- package/dist/chunk-AGVER5MX.cjs +1746 -0
- package/dist/{chunk-TJ4527KA.cjs → chunk-BL22KD4V.cjs} +324 -950
- package/dist/{chunk-UNFSW5C2.js → chunk-GWG75A5M.js} +14 -5
- package/dist/{chunk-DUTS75WQ.js → chunk-XNO3PCEH.js} +374 -1000
- package/dist/chunk-ZEQS64PE.js +1746 -0
- package/dist/cli/index.cjs +76 -155
- package/dist/cli/index.js +10 -89
- package/dist/markdown/index.cjs +2 -3
- package/dist/markdown/index.d.cts +1 -1
- package/dist/markdown/index.d.ts +1 -1
- package/dist/markdown/index.js +1 -2
- package/dist/{types-CwBWwNVv.d.ts → types-C_d0fFeD.d.ts} +8 -1
- package/dist/{types-CpsEy8lA.d.cts → types-MRBGgJTX.d.cts} +8 -1
- package/dist/vitepress/config/index.cjs +200 -132
- package/dist/vitepress/config/index.js +187 -119
- package/dist/workspace/index.cjs +4 -1202
- package/dist/workspace/index.d.cts +2 -2
- package/dist/workspace/index.d.ts +2 -2
- package/dist/workspace/index.js +4 -1202
- package/package.json +2 -2
- package/services/file-watcher/folderChangeHandler.ts +19 -15
- package/services/file-watcher/globalUpdateCoordinator.ts +21 -27
- package/services/file-watcher/service.ts +1 -6
- package/services/index.ts +0 -1
- package/services/note/service.ts +4 -6
- package/services/readme/service.ts +11 -18
- package/services/reconcileToc.ts +20 -0
- package/utils/index.ts +0 -9
- package/{services/toc → utils}/moveTocInside.test.ts +1 -1
- package/vitepress/components/constants.ts +2 -2
- package/vitepress/components/sidebar.data.ts +8 -5
- package/vitepress/plugins/sidebarStructurePlugin.ts +242 -145
- package/dist/chunk-3R7QSABB.cjs +0 -502
- package/dist/chunk-CZXRQPFJ.js +0 -11
- package/dist/chunk-HXED7KVT.cjs +0 -11
- package/dist/chunk-U6IBLREL.js +0 -502
- package/services/toc/index.ts +0 -5
- package/services/toc/service.ts +0 -759
- package/utils/migrateReadmeToToc.test.ts +0 -111
- package/utils/migrateReadmeToToc.ts +0 -135
|
@@ -7,29 +7,10 @@ var _chunkMZIXIY2Ycjs = require('./chunk-MZIXIY2Y.cjs');
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
var _chunkAGVER5MXcjs = require('./chunk-AGVER5MX.cjs');
|
|
10
11
|
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
var _chunk3R7QSABBcjs = require('./chunk-3R7QSABB.cjs');
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
var _chunkHXED7KVTcjs = require('./chunk-HXED7KVT.cjs');
|
|
13
|
+
var _chunk7FEANCT6cjs = require('./chunk-7FEANCT6.cjs');
|
|
33
14
|
|
|
34
15
|
// utils/errorHandler.ts
|
|
35
16
|
var TNotesError = class _TNotesError extends Error {
|
|
@@ -419,7 +400,7 @@ function generateToc(titles, baseLevel = 2, eol = "\n") {
|
|
|
419
400
|
const toc = titles.map((title) => {
|
|
420
401
|
const level = title.indexOf(" ");
|
|
421
402
|
const text = title.slice(level).trim();
|
|
422
|
-
const anchor =
|
|
403
|
+
const anchor = _chunk7FEANCT6cjs.generateAnchor.call(void 0, text);
|
|
423
404
|
const indent = Math.max(0, (level - baseLevel) * 2);
|
|
424
405
|
return " ".repeat(indent) + `- [${text}](#${anchor})`;
|
|
425
406
|
}).join(eol);
|
|
@@ -476,81 +457,6 @@ function parseReadmeCompletedNotes(content) {
|
|
|
476
457
|
};
|
|
477
458
|
}
|
|
478
459
|
|
|
479
|
-
// utils/migrateReadmeToToc.ts
|
|
480
|
-
var README_TOC_END_TAG = "<!-- endregion:toc -->";
|
|
481
|
-
function extractReadmeBodyAfterToc(content) {
|
|
482
|
-
const endTagIndex = content.indexOf(README_TOC_END_TAG);
|
|
483
|
-
if (endTagIndex === -1) {
|
|
484
|
-
throw new Error(
|
|
485
|
-
`README.md \u4E2D\u672A\u627E\u5230 ${README_TOC_END_TAG}\uFF0C\u65E0\u6CD5\u6267\u884C init-toc \u8FC1\u79FB`
|
|
486
|
-
);
|
|
487
|
-
}
|
|
488
|
-
const afterTag = content.slice(endTagIndex + README_TOC_END_TAG.length);
|
|
489
|
-
return afterTag.split("\n");
|
|
490
|
-
}
|
|
491
|
-
function migrateReadmeToToc(content) {
|
|
492
|
-
const lines = extractReadmeBodyAfterToc(content);
|
|
493
|
-
const warnings = [];
|
|
494
|
-
const seenIndexes = /* @__PURE__ */ new Set();
|
|
495
|
-
const sections = [];
|
|
496
|
-
let currentHeading = null;
|
|
497
|
-
let currentGroup = [];
|
|
498
|
-
const flushGroup = () => {
|
|
499
|
-
if (currentGroup.length > 0) {
|
|
500
|
-
sections.push({ heading: currentHeading, items: currentGroup });
|
|
501
|
-
}
|
|
502
|
-
currentGroup = [];
|
|
503
|
-
};
|
|
504
|
-
for (const line of lines) {
|
|
505
|
-
const headingMatch = line.match(/^(#{2,})\s+(.+)$/);
|
|
506
|
-
if (headingMatch) {
|
|
507
|
-
flushGroup();
|
|
508
|
-
currentHeading = headingMatch[2].trim();
|
|
509
|
-
continue;
|
|
510
|
-
}
|
|
511
|
-
const parsed = _chunk3R7QSABBcjs.parseTocLine.call(void 0, line);
|
|
512
|
-
if (!parsed.isMatch || !parsed.noteIndex) continue;
|
|
513
|
-
if (seenIndexes.has(parsed.noteIndex)) {
|
|
514
|
-
warnings.push(`\u8DF3\u8FC7\u91CD\u590D\u7B14\u8BB0\u7D22\u5F15: ${parsed.noteIndex}`);
|
|
515
|
-
continue;
|
|
516
|
-
}
|
|
517
|
-
seenIndexes.add(parsed.noteIndex);
|
|
518
|
-
currentGroup.push({
|
|
519
|
-
noteIndex: parsed.noteIndex,
|
|
520
|
-
completed: parsed.completed
|
|
521
|
-
});
|
|
522
|
-
}
|
|
523
|
-
flushGroup();
|
|
524
|
-
const entries = [];
|
|
525
|
-
for (const section of sections) {
|
|
526
|
-
if (section.heading) {
|
|
527
|
-
entries.push({
|
|
528
|
-
kind: "folder",
|
|
529
|
-
folderTitle: section.heading,
|
|
530
|
-
indent: 0
|
|
531
|
-
});
|
|
532
|
-
for (const item of section.items) {
|
|
533
|
-
entries.push({
|
|
534
|
-
kind: "note",
|
|
535
|
-
noteIndex: item.noteIndex,
|
|
536
|
-
indent: 1,
|
|
537
|
-
completed: item.completed
|
|
538
|
-
});
|
|
539
|
-
}
|
|
540
|
-
continue;
|
|
541
|
-
}
|
|
542
|
-
for (const item of section.items) {
|
|
543
|
-
entries.push({
|
|
544
|
-
kind: "note",
|
|
545
|
-
noteIndex: item.noteIndex,
|
|
546
|
-
indent: 0,
|
|
547
|
-
completed: item.completed
|
|
548
|
-
});
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
return { entries, warnings };
|
|
552
|
-
}
|
|
553
|
-
|
|
554
460
|
// utils/portUtils.ts
|
|
555
461
|
|
|
556
462
|
function isPortInUse(port2) {
|
|
@@ -1213,7 +1119,6 @@ var COMMAND_NAMES = {
|
|
|
1213
1119
|
PULL: "pull",
|
|
1214
1120
|
PUSH: "push",
|
|
1215
1121
|
RENAME_NOTE: "rename-note",
|
|
1216
|
-
INIT_TOC: "init-toc",
|
|
1217
1122
|
INIT_SUB_REPO: "init-sub-repo",
|
|
1218
1123
|
UPDATE: "update",
|
|
1219
1124
|
UPDATE_COMPLETED_COUNT: "update-completed-count",
|
|
@@ -1223,7 +1128,6 @@ var COMMAND_DESCRIPTIONS = {
|
|
|
1223
1128
|
[COMMAND_NAMES.DEV]: "\u542F\u52A8\u77E5\u8BC6\u5E93\u5F00\u53D1\u670D\u52A1",
|
|
1224
1129
|
[COMMAND_NAMES.BUILD]: "\u6784\u5EFA\u77E5\u8BC6\u5E93",
|
|
1225
1130
|
[COMMAND_NAMES.PREVIEW]: "\u9884\u89C8\u6784\u5EFA\u540E\u7684\u77E5\u8BC6\u5E93",
|
|
1226
|
-
[COMMAND_NAMES.INIT_TOC]: "\u4ECE README.md \u521D\u59CB\u5316 TOC.md\uFF08v0.2.x \u8FC7\u6E21\u547D\u4EE4\uFF0Cv0.3.x \u79FB\u9664\uFF09",
|
|
1227
1131
|
[COMMAND_NAMES.INIT_SUB_REPO]: "\u521D\u59CB\u5316 TNotes \u5B50\u77E5\u8BC6\u5E93\uFF08\u4E00\u6B21\u6027\u811A\u624B\u67B6\uFF09",
|
|
1228
1132
|
[COMMAND_NAMES.UPDATE]: "\u6839\u636E\u7B14\u8BB0\u5185\u5BB9\u66F4\u65B0\u77E5\u8BC6\u5E93",
|
|
1229
1133
|
[COMMAND_NAMES.UPDATE_COMPLETED_COUNT]: "\u66F4\u65B0\u5B8C\u6210\u7B14\u8BB0\u6570\u91CF\u5386\u53F2\u8BB0\u5F55\uFF08\u8FD1 1 \u5E74\uFF0C\u6700\u8FD1 12 \u4E2A\u6708\uFF09",
|
|
@@ -1385,783 +1289,6 @@ var NoteIndexCache = class _NoteIndexCache {
|
|
|
1385
1289
|
}
|
|
1386
1290
|
};
|
|
1387
1291
|
|
|
1388
|
-
// services/toc/service.ts
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
// services/note/service.ts
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
var _uuid = require('uuid');
|
|
1400
|
-
var NoteService = class _NoteService {
|
|
1401
|
-
constructor() {
|
|
1402
|
-
this.ignoredConfigPaths = /* @__PURE__ */ new Set();
|
|
1403
|
-
this.noteManager = NoteManager.getInstance();
|
|
1404
|
-
this.noteIndexCache = NoteIndexCache.getInstance();
|
|
1405
|
-
}
|
|
1406
|
-
static getInstance() {
|
|
1407
|
-
if (!_NoteService.instance) {
|
|
1408
|
-
_NoteService.instance = new _NoteService();
|
|
1409
|
-
}
|
|
1410
|
-
return _NoteService.instance;
|
|
1411
|
-
}
|
|
1412
|
-
/**
|
|
1413
|
-
* 标记配置文件在下次变更时被忽略(防止 API 写入触发文件监听循环)
|
|
1414
|
-
* @param configPath - 配置文件路径
|
|
1415
|
-
*/
|
|
1416
|
-
ignoreNextConfigChange(configPath) {
|
|
1417
|
-
this.ignoredConfigPaths.add(configPath);
|
|
1418
|
-
}
|
|
1419
|
-
/**
|
|
1420
|
-
* 检查配置文件是否应该被忽略
|
|
1421
|
-
* @param configPath - 配置文件路径
|
|
1422
|
-
* @returns 是否应该忽略
|
|
1423
|
-
*/
|
|
1424
|
-
shouldIgnoreConfigChange(configPath) {
|
|
1425
|
-
if (this.ignoredConfigPaths.has(configPath)) {
|
|
1426
|
-
this.ignoredConfigPaths.delete(configPath);
|
|
1427
|
-
return true;
|
|
1428
|
-
}
|
|
1429
|
-
return false;
|
|
1430
|
-
}
|
|
1431
|
-
/**
|
|
1432
|
-
* 获取所有笔记
|
|
1433
|
-
* dev 模式下(缓存已初始化)从内存读取,其他模式回退到文件扫描
|
|
1434
|
-
* @returns 笔记信息数组
|
|
1435
|
-
*/
|
|
1436
|
-
getAllNotes() {
|
|
1437
|
-
if (this.noteIndexCache.isInitialized()) {
|
|
1438
|
-
return this.noteIndexCache.toNoteInfoList();
|
|
1439
|
-
}
|
|
1440
|
-
return this.noteManager.scanNotes();
|
|
1441
|
-
}
|
|
1442
|
-
/**
|
|
1443
|
-
* 获取笔记(通过索引)
|
|
1444
|
-
* @param noteIndex - 笔记索引(文件夹前 4 位数字)
|
|
1445
|
-
* @returns 笔记信息,未找到时返回 undefined
|
|
1446
|
-
*/
|
|
1447
|
-
getNoteByIndex(noteIndex) {
|
|
1448
|
-
return this.noteManager.getNoteByIndex(noteIndex);
|
|
1449
|
-
}
|
|
1450
|
-
/**
|
|
1451
|
-
* 创建新笔记
|
|
1452
|
-
* @param options - 创建选项
|
|
1453
|
-
* @returns 新创建的笔记信息
|
|
1454
|
-
*/
|
|
1455
|
-
async createNote(options = {}) {
|
|
1456
|
-
const {
|
|
1457
|
-
title = "new",
|
|
1458
|
-
category,
|
|
1459
|
-
enableDiscussions = false,
|
|
1460
|
-
configId,
|
|
1461
|
-
usedIndexes
|
|
1462
|
-
} = options;
|
|
1463
|
-
const noteIndex = this.generateNextNoteIndex(usedIndexes);
|
|
1464
|
-
const dirName = `${noteIndex}. ${title}`;
|
|
1465
|
-
const notePath = _path.join.call(void 0, NOTES_PATH, dirName);
|
|
1466
|
-
await ensureDirectory(notePath);
|
|
1467
|
-
const readmePath = _path.join.call(void 0, notePath, "README.md");
|
|
1468
|
-
const noteTitle = _chunk3R7QSABBcjs.generateNoteTitle.call(void 0, noteIndex, title, REPO_NOTES_URL);
|
|
1469
|
-
const readmeContent = noteTitle + "\n" + _chunk3R7QSABBcjs.getNewNoteReadmeBody.call(void 0, );
|
|
1470
|
-
_fs.writeFileSync.call(void 0, readmePath, readmeContent, "utf-8");
|
|
1471
|
-
const configPath = _path.join.call(void 0, notePath, ".tnotes.json");
|
|
1472
|
-
const config2 = {
|
|
1473
|
-
id: configId || _uuid.v4.call(void 0, ),
|
|
1474
|
-
// 配置 ID 使用 UUID(跨知识库唯一)
|
|
1475
|
-
bilibili: [],
|
|
1476
|
-
tnotes: [],
|
|
1477
|
-
yuque: [],
|
|
1478
|
-
done: false,
|
|
1479
|
-
category,
|
|
1480
|
-
enableDiscussions
|
|
1481
|
-
};
|
|
1482
|
-
this.noteManager.writeNoteConfig(configPath, config2);
|
|
1483
|
-
const noteInfo = {
|
|
1484
|
-
index: noteIndex,
|
|
1485
|
-
// 返回的 id 是笔记索引(目录前缀)
|
|
1486
|
-
path: notePath,
|
|
1487
|
-
dirName,
|
|
1488
|
-
readmePath,
|
|
1489
|
-
configPath,
|
|
1490
|
-
config: config2
|
|
1491
|
-
};
|
|
1492
|
-
if (this.noteIndexCache.isInitialized()) {
|
|
1493
|
-
this.noteIndexCache.add(noteInfo);
|
|
1494
|
-
}
|
|
1495
|
-
logger.info(`Created new note: ${dirName}`);
|
|
1496
|
-
return noteInfo;
|
|
1497
|
-
}
|
|
1498
|
-
/**
|
|
1499
|
-
* 删除笔记文件夹
|
|
1500
|
-
* @param noteIndex - 笔记索引
|
|
1501
|
-
* @returns 被删除的笔记信息
|
|
1502
|
-
*/
|
|
1503
|
-
async deleteNote(noteIndex) {
|
|
1504
|
-
const note = this.getNoteByIndex(noteIndex);
|
|
1505
|
-
if (!note) {
|
|
1506
|
-
throw new Error(`\u7B14\u8BB0\u672A\u627E\u5230: ${noteIndex}`);
|
|
1507
|
-
}
|
|
1508
|
-
await _fs.promises.rm(note.path, { recursive: true, force: true });
|
|
1509
|
-
if (this.noteIndexCache.isInitialized()) {
|
|
1510
|
-
this.noteIndexCache.delete(noteIndex);
|
|
1511
|
-
}
|
|
1512
|
-
logger.info(`Deleted note: ${note.dirName}`);
|
|
1513
|
-
return note;
|
|
1514
|
-
}
|
|
1515
|
-
/**
|
|
1516
|
-
* 生成下一个笔记索引(填充空缺)
|
|
1517
|
-
* @param usedIndexes - 可选的已使用编号集合,不传则内部扫描
|
|
1518
|
-
* @returns 新的笔记索引(4位数字字符串,从 0001 到 9999)
|
|
1519
|
-
*/
|
|
1520
|
-
generateNextNoteIndex(usedIndexes) {
|
|
1521
|
-
if (!usedIndexes) {
|
|
1522
|
-
const notes = this.getAllNotes();
|
|
1523
|
-
usedIndexes = /* @__PURE__ */ new Set();
|
|
1524
|
-
for (const note of notes) {
|
|
1525
|
-
const id = parseInt(note.index, 10);
|
|
1526
|
-
if (!isNaN(id) && id >= 1 && id <= 9999) {
|
|
1527
|
-
usedIndexes.add(id);
|
|
1528
|
-
}
|
|
1529
|
-
}
|
|
1530
|
-
}
|
|
1531
|
-
if (usedIndexes.size === 0) {
|
|
1532
|
-
return "0001";
|
|
1533
|
-
}
|
|
1534
|
-
for (let i = 1; i <= 9999; i++) {
|
|
1535
|
-
if (!usedIndexes.has(i)) {
|
|
1536
|
-
return i.toString().padStart(CONSTANTS.NOTE_INDEX_LENGTH, "0");
|
|
1537
|
-
}
|
|
1538
|
-
}
|
|
1539
|
-
throw new Error("\u6240\u6709\u7B14\u8BB0\u7F16\u53F7 (0001-9999) \u5DF2\u88AB\u5360\u7528\uFF0C\u65E0\u6CD5\u521B\u5EFA\u65B0\u7B14\u8BB0");
|
|
1540
|
-
}
|
|
1541
|
-
/**
|
|
1542
|
-
* 更新笔记配置
|
|
1543
|
-
* @param noteIndex - 笔记索引
|
|
1544
|
-
* @param updates - 配置更新
|
|
1545
|
-
*/
|
|
1546
|
-
async updateNoteConfig(noteIndex, updates) {
|
|
1547
|
-
const note = this.getNoteByIndex(noteIndex);
|
|
1548
|
-
if (!note || !note.config) {
|
|
1549
|
-
throw new Error(`Note not found or no config: ${noteIndex}`);
|
|
1550
|
-
}
|
|
1551
|
-
const oldConfig = { ...note.config };
|
|
1552
|
-
const updatedConfig = {
|
|
1553
|
-
...note.config,
|
|
1554
|
-
...updates
|
|
1555
|
-
};
|
|
1556
|
-
this.ignoreNextConfigChange(note.configPath);
|
|
1557
|
-
this.noteManager.updateNoteConfig(note, updatedConfig);
|
|
1558
|
-
this.noteIndexCache.updateConfig(noteIndex, updatedConfig);
|
|
1559
|
-
const needsGlobalUpdate = this.checkNeedsGlobalUpdate(
|
|
1560
|
-
oldConfig,
|
|
1561
|
-
updatedConfig
|
|
1562
|
-
);
|
|
1563
|
-
if (needsGlobalUpdate) {
|
|
1564
|
-
logger.info(`\u68C0\u6D4B\u5230\u5168\u5C40\u5B57\u6BB5\u53D8\u66F4 (${noteIndex})\uFF0C\u6B63\u5728\u589E\u91CF\u66F4\u65B0\u5168\u5C40\u6587\u4EF6...`);
|
|
1565
|
-
const tocService = TocService.getInstance();
|
|
1566
|
-
await tocService.updateNoteInToc(noteIndex, updates);
|
|
1567
|
-
await tocService.regenerateSidebar();
|
|
1568
|
-
logger.info(`\u5168\u5C40\u6587\u4EF6\u589E\u91CF\u66F4\u65B0\u5B8C\u6210 (${noteIndex})`);
|
|
1569
|
-
} else {
|
|
1570
|
-
logger.debug(`\u914D\u7F6E\u66F4\u65B0\u4E0D\u5F71\u54CD\u5168\u5C40\u6587\u4EF6 (${noteIndex})`);
|
|
1571
|
-
}
|
|
1572
|
-
}
|
|
1573
|
-
/**
|
|
1574
|
-
* 检查配置更新是否需要触发全局更新
|
|
1575
|
-
* @param oldConfig - 旧配置
|
|
1576
|
-
* @param newConfig - 新配置
|
|
1577
|
-
* @returns 是否需要全局更新
|
|
1578
|
-
*/
|
|
1579
|
-
checkNeedsGlobalUpdate(oldConfig, newConfig) {
|
|
1580
|
-
const globalFields = ["done"];
|
|
1581
|
-
for (const field of globalFields) {
|
|
1582
|
-
if (oldConfig[field] !== newConfig[field]) {
|
|
1583
|
-
return true;
|
|
1584
|
-
}
|
|
1585
|
-
}
|
|
1586
|
-
return false;
|
|
1587
|
-
}
|
|
1588
|
-
/**
|
|
1589
|
-
* 修正笔记标题
|
|
1590
|
-
* @param noteInfo - 笔记信息
|
|
1591
|
-
* @returns 是否进行了修正
|
|
1592
|
-
*/
|
|
1593
|
-
async fixNoteTitle(noteInfo) {
|
|
1594
|
-
try {
|
|
1595
|
-
const readmeContent = _fs.readFileSync.call(void 0, noteInfo.readmePath, "utf-8");
|
|
1596
|
-
if (readmeContent.length === 0) return false;
|
|
1597
|
-
const lines = readmeContent.split("\n");
|
|
1598
|
-
const match = noteInfo.dirName.match(/^\d{4}\.\s+(.+)$/);
|
|
1599
|
-
if (!match) {
|
|
1600
|
-
logger.warn(`\u68C0\u6D4B\u5230\u9519\u8BEF\u7684\u7B14\u8BB0\u76EE\u5F55\u540D\u79F0\uFF1A${noteInfo.dirName}`);
|
|
1601
|
-
return false;
|
|
1602
|
-
}
|
|
1603
|
-
const expectedTitle = match[1];
|
|
1604
|
-
const expectedH1 = _chunk3R7QSABBcjs.generateNoteTitle.call(void 0,
|
|
1605
|
-
noteInfo.index,
|
|
1606
|
-
expectedTitle,
|
|
1607
|
-
REPO_NOTES_URL
|
|
1608
|
-
);
|
|
1609
|
-
const firstLine = lines[0].trim();
|
|
1610
|
-
if (!firstLine.startsWith("# ")) {
|
|
1611
|
-
lines.unshift(expectedH1);
|
|
1612
|
-
_fs.writeFileSync.call(void 0, noteInfo.readmePath, lines.join("\n"), "utf-8");
|
|
1613
|
-
logger.info(`Added title to: ${noteInfo.dirName}`);
|
|
1614
|
-
return true;
|
|
1615
|
-
}
|
|
1616
|
-
if (firstLine !== expectedH1) {
|
|
1617
|
-
lines[0] = expectedH1;
|
|
1618
|
-
_fs.writeFileSync.call(void 0, noteInfo.readmePath, lines.join("\n"), "utf-8");
|
|
1619
|
-
logger.info(`Fixed title for: ${noteInfo.dirName}`);
|
|
1620
|
-
return true;
|
|
1621
|
-
}
|
|
1622
|
-
return false;
|
|
1623
|
-
} catch (error) {
|
|
1624
|
-
logger.error(`Failed to fix title for: ${noteInfo.dirName}`, error);
|
|
1625
|
-
return false;
|
|
1626
|
-
}
|
|
1627
|
-
}
|
|
1628
|
-
/**
|
|
1629
|
-
* 修正所有笔记的标题
|
|
1630
|
-
* @param providedNotes - 可选的笔记列表,不传则内部扫描
|
|
1631
|
-
* @returns 修正的笔记数量
|
|
1632
|
-
*/
|
|
1633
|
-
async fixAllNoteTitles(providedNotes) {
|
|
1634
|
-
const notes = _nullishCoalesce(providedNotes, () => ( this.getAllNotes()));
|
|
1635
|
-
let fixedCount = 0;
|
|
1636
|
-
for (const note of notes) {
|
|
1637
|
-
const fixed = await this.fixNoteTitle(note);
|
|
1638
|
-
if (fixed) {
|
|
1639
|
-
fixedCount++;
|
|
1640
|
-
}
|
|
1641
|
-
}
|
|
1642
|
-
if (fixedCount > 0) {
|
|
1643
|
-
logger.info(`Fixed ${fixedCount} note titles`);
|
|
1644
|
-
}
|
|
1645
|
-
return fixedCount;
|
|
1646
|
-
}
|
|
1647
|
-
};
|
|
1648
|
-
|
|
1649
|
-
// services/toc/service.ts
|
|
1650
|
-
var TocService = class _TocService {
|
|
1651
|
-
constructor() {
|
|
1652
|
-
this.noteManager = NoteManager.getInstance();
|
|
1653
|
-
this.configManager = _chunkMZIXIY2Ycjs.ConfigManager.getInstance();
|
|
1654
|
-
this.noteIndexCache = NoteIndexCache.getInstance();
|
|
1655
|
-
}
|
|
1656
|
-
static getInstance() {
|
|
1657
|
-
if (!_TocService.instance) {
|
|
1658
|
-
_TocService.instance = new _TocService();
|
|
1659
|
-
}
|
|
1660
|
-
return _TocService.instance;
|
|
1661
|
-
}
|
|
1662
|
-
/**
|
|
1663
|
-
* 确保 TOC.md 存在
|
|
1664
|
-
*/
|
|
1665
|
-
ensureTocExists() {
|
|
1666
|
-
if (!_fs.existsSync.call(void 0, ROOT_TOC_PATH)) {
|
|
1667
|
-
throw new Error(
|
|
1668
|
-
`TOC.md \u4E0D\u5B58\u5728: ${ROOT_TOC_PATH}\u3002\u8BF7\u5728\u77E5\u8BC6\u5E93\u6839\u76EE\u5F55\u521B\u5EFA TOC.md \u4F5C\u4E3A\u76EE\u5F55\u6570\u636E\u6E90\u3002`
|
|
1669
|
-
);
|
|
1670
|
-
}
|
|
1671
|
-
}
|
|
1672
|
-
/**
|
|
1673
|
-
* update 主流程:规范化 TOC.md
|
|
1674
|
-
*/
|
|
1675
|
-
async normalizeToc(notes) {
|
|
1676
|
-
this.ensureTocExists();
|
|
1677
|
-
const content = await _fs.promises.readFile(ROOT_TOC_PATH, "utf-8");
|
|
1678
|
-
const lines = content.split("\n");
|
|
1679
|
-
const tree = _chunk3R7QSABBcjs.parseTocToTree.call(void 0, lines, notes);
|
|
1680
|
-
const existingIndexes = /* @__PURE__ */ new Set();
|
|
1681
|
-
const collectNoteIndexes = (nodes) => {
|
|
1682
|
-
for (const node of nodes) {
|
|
1683
|
-
if (node.kind === "note") {
|
|
1684
|
-
existingIndexes.add(node.noteIndex);
|
|
1685
|
-
}
|
|
1686
|
-
collectNoteIndexes(node.children);
|
|
1687
|
-
}
|
|
1688
|
-
};
|
|
1689
|
-
collectNoteIndexes(tree);
|
|
1690
|
-
const missingNotes = notes.filter((n) => !existingIndexes.has(n.index));
|
|
1691
|
-
if (missingNotes.length > 0) {
|
|
1692
|
-
logger.info(`TOC.md \u8FFD\u52A0 ${missingNotes.length} \u7BC7\u7F3A\u5931\u7B14\u8BB0`);
|
|
1693
|
-
missingNotes.sort((a, b) => a.index.localeCompare(b.index));
|
|
1694
|
-
for (const note of missingNotes) {
|
|
1695
|
-
tree.push({
|
|
1696
|
-
kind: "note",
|
|
1697
|
-
noteIndex: note.index,
|
|
1698
|
-
indent: 0,
|
|
1699
|
-
tocLineIndex: 0,
|
|
1700
|
-
children: []
|
|
1701
|
-
});
|
|
1702
|
-
}
|
|
1703
|
-
}
|
|
1704
|
-
const configByIndex = /* @__PURE__ */ new Map();
|
|
1705
|
-
for (const note of notes) {
|
|
1706
|
-
configByIndex.set(note.index, {
|
|
1707
|
-
done: _chunk3R7QSABBcjs.getTocLineCompleted.call(void 0, note)
|
|
1708
|
-
});
|
|
1709
|
-
}
|
|
1710
|
-
const normalizedLines = _chunk3R7QSABBcjs.serializeTocTree.call(void 0, tree, notes, configByIndex);
|
|
1711
|
-
await this.writeTocLines(normalizedLines);
|
|
1712
|
-
logger.info("\u5DF2\u89C4\u8303\u5316 TOC.md");
|
|
1713
|
-
}
|
|
1714
|
-
/**
|
|
1715
|
-
* 从 TOC.md 重新生成 sidebar.json
|
|
1716
|
-
*/
|
|
1717
|
-
async regenerateSidebar(notes) {
|
|
1718
|
-
this.ensureTocExists();
|
|
1719
|
-
const allNotes = _nullishCoalesce(notes, () => ( (this.noteIndexCache.isInitialized() ? this.noteIndexCache.toNoteInfoList() : this.noteManager.scanNotes())));
|
|
1720
|
-
const content = _fs.readFileSync.call(void 0, ROOT_TOC_PATH, "utf-8");
|
|
1721
|
-
const lines = content.split("\n");
|
|
1722
|
-
const tree = _chunk3R7QSABBcjs.parseTocToTree.call(void 0, lines, allNotes);
|
|
1723
|
-
const sidebarShowNoteId2 = this.configManager.get("sidebarShowNoteId");
|
|
1724
|
-
const hierarchicalSidebar = _chunk3R7QSABBcjs.buildSidebarFromTocTree.call(void 0, tree, allNotes, {
|
|
1725
|
-
sidebarShowNoteId: sidebarShowNoteId2,
|
|
1726
|
-
sidebarIsCollapsed: true
|
|
1727
|
-
});
|
|
1728
|
-
const sidebarContent = JSON.stringify(hierarchicalSidebar, null, 2);
|
|
1729
|
-
const existingContent = _fs.existsSync.call(void 0, VP_SIDEBAR_PATH) ? _fs.readFileSync.call(void 0, VP_SIDEBAR_PATH, "utf-8") : "";
|
|
1730
|
-
if (sidebarContent !== existingContent) {
|
|
1731
|
-
_fs.writeFileSync.call(void 0, VP_SIDEBAR_PATH, sidebarContent, "utf-8");
|
|
1732
|
-
}
|
|
1733
|
-
logger.info("\u5DF2\u66F4\u65B0\u4FA7\u8FB9\u680F\u914D\u7F6E");
|
|
1734
|
-
}
|
|
1735
|
-
/**
|
|
1736
|
-
* 增量更新 TOC.md 中某笔记的完成状态与链接
|
|
1737
|
-
*/
|
|
1738
|
-
async updateNoteInToc(noteIndex, updates) {
|
|
1739
|
-
this.ensureTocExists();
|
|
1740
|
-
const item = this.noteIndexCache.getByNoteIndex(noteIndex);
|
|
1741
|
-
if (!item) {
|
|
1742
|
-
logger.warn(`\u5C1D\u8BD5\u66F4\u65B0 TOC \u4E2D\u4E0D\u5B58\u5728\u7684\u7B14\u8BB0: ${noteIndex}`);
|
|
1743
|
-
return;
|
|
1744
|
-
}
|
|
1745
|
-
const notes = this.noteIndexCache.isInitialized() ? this.noteIndexCache.toNoteInfoList() : this.noteManager.scanNotes();
|
|
1746
|
-
const note = _chunk3R7QSABBcjs.resolveNoteFromIndex.call(void 0, noteIndex, notes);
|
|
1747
|
-
if (!note) return;
|
|
1748
|
-
const mergedConfig = {
|
|
1749
|
-
...note.config,
|
|
1750
|
-
...updates,
|
|
1751
|
-
...item.noteConfig
|
|
1752
|
-
};
|
|
1753
|
-
const tempNote = {
|
|
1754
|
-
...note,
|
|
1755
|
-
dirName: item.folderName,
|
|
1756
|
-
config: mergedConfig
|
|
1757
|
-
};
|
|
1758
|
-
const lines = await this.readTocLines();
|
|
1759
|
-
let updated = false;
|
|
1760
|
-
for (let i = 0; i < lines.length; i++) {
|
|
1761
|
-
const parsed = _chunk3R7QSABBcjs.parseTocLine.call(void 0, lines[i]);
|
|
1762
|
-
if (parsed.noteIndex === noteIndex) {
|
|
1763
|
-
lines[i] = _chunk3R7QSABBcjs.buildTocLine.call(void 0,
|
|
1764
|
-
tempNote,
|
|
1765
|
-
parsed.indentLevel,
|
|
1766
|
-
_chunk3R7QSABBcjs.getTocLineCompleted.call(void 0, tempNote)
|
|
1767
|
-
);
|
|
1768
|
-
updated = true;
|
|
1769
|
-
}
|
|
1770
|
-
}
|
|
1771
|
-
if (updated) {
|
|
1772
|
-
await this.writeTocLines(lines);
|
|
1773
|
-
logger.info(`\u589E\u91CF\u66F4\u65B0 TOC.md \u4E2D\u7684\u7B14\u8BB0: ${noteIndex}`);
|
|
1774
|
-
} else {
|
|
1775
|
-
logger.warn(`TOC.md \u4E2D\u672A\u627E\u5230\u7B14\u8BB0: ${noteIndex}`);
|
|
1776
|
-
}
|
|
1777
|
-
}
|
|
1778
|
-
/**
|
|
1779
|
-
* 在 TOC.md 末尾或父节点下追加笔记
|
|
1780
|
-
*/
|
|
1781
|
-
async appendNoteToToc(noteIndex, options) {
|
|
1782
|
-
const item = this.noteIndexCache.getByNoteIndex(noteIndex);
|
|
1783
|
-
if (!item) {
|
|
1784
|
-
logger.warn(`\u5C1D\u8BD5\u6DFB\u52A0\u4E0D\u5B58\u5728\u7684\u7B14\u8BB0\u5230 TOC: ${noteIndex}`);
|
|
1785
|
-
return;
|
|
1786
|
-
}
|
|
1787
|
-
const notes = this.noteIndexCache.isInitialized() ? this.noteIndexCache.toNoteInfoList() : this.noteManager.scanNotes();
|
|
1788
|
-
const note = _chunk3R7QSABBcjs.resolveNoteFromIndex.call(void 0, noteIndex, notes);
|
|
1789
|
-
if (!note) return;
|
|
1790
|
-
const tempNote = {
|
|
1791
|
-
...note,
|
|
1792
|
-
dirName: item.folderName,
|
|
1793
|
-
config: item.noteConfig
|
|
1794
|
-
};
|
|
1795
|
-
if (!_fs.existsSync.call(void 0, ROOT_TOC_PATH)) {
|
|
1796
|
-
await this.writeTocLines([_chunk3R7QSABBcjs.buildTocLine.call(void 0, tempNote, 0, false)]);
|
|
1797
|
-
logger.info(`\u521B\u5EFA TOC.md \u5E76\u6DFB\u52A0\u7B14\u8BB0: ${noteIndex}`);
|
|
1798
|
-
return;
|
|
1799
|
-
}
|
|
1800
|
-
const lines = await this.readTocLines();
|
|
1801
|
-
if (_optionalChain([options, 'optionalAccess', _11 => _11.parentTocLineIndex]) !== void 0) {
|
|
1802
|
-
await this.insertNotesUnderTocLine(options.parentTocLineIndex, [tempNote]);
|
|
1803
|
-
return;
|
|
1804
|
-
}
|
|
1805
|
-
if (_optionalChain([options, 'optionalAccess', _12 => _12.parentNoteIndex])) {
|
|
1806
|
-
const parentIndex = _chunk3R7QSABBcjs.findTocLineIndex.call(void 0, lines, options.parentNoteIndex);
|
|
1807
|
-
await this.insertNotesUnderTocLine(parentIndex, [tempNote]);
|
|
1808
|
-
return;
|
|
1809
|
-
}
|
|
1810
|
-
if (_optionalChain([options, 'optionalAccess', _13 => _13.parentFolderPath]) && options.parentFolderPath.length > 0) {
|
|
1811
|
-
const folderIndex = _chunk3R7QSABBcjs.findFolderLineIndex.call(void 0, lines, options.parentFolderPath);
|
|
1812
|
-
await this.insertNotesUnderTocLine(folderIndex, [tempNote]);
|
|
1813
|
-
return;
|
|
1814
|
-
}
|
|
1815
|
-
lines.push(_chunk3R7QSABBcjs.buildTocLine.call(void 0, tempNote, 0, false));
|
|
1816
|
-
await this.writeTocLines(lines);
|
|
1817
|
-
logger.info(`\u5728 TOC.md \u672B\u5C3E\u6DFB\u52A0\u7B14\u8BB0: ${noteIndex}`);
|
|
1818
|
-
}
|
|
1819
|
-
/**
|
|
1820
|
-
* 删除前按 TOC 文档顺序获取上一项笔记索引;首项返回 null
|
|
1821
|
-
*/
|
|
1822
|
-
async getPreviousNoteIndexBeforeDelete(noteIndex) {
|
|
1823
|
-
if (!_fs.existsSync.call(void 0, ROOT_TOC_PATH)) return null;
|
|
1824
|
-
const lines = await this.readTocLines();
|
|
1825
|
-
return _chunk3R7QSABBcjs.getPreviousTocNoteIndex.call(void 0, lines, noteIndex);
|
|
1826
|
-
}
|
|
1827
|
-
/**
|
|
1828
|
-
* 从 TOC.md 删除笔记及其缩进子树
|
|
1829
|
-
*/
|
|
1830
|
-
async deleteNoteFromToc(noteIndex) {
|
|
1831
|
-
if (!_fs.existsSync.call(void 0, ROOT_TOC_PATH)) return;
|
|
1832
|
-
const lines = await this.readTocLines();
|
|
1833
|
-
let lineIndex;
|
|
1834
|
-
try {
|
|
1835
|
-
lineIndex = _chunk3R7QSABBcjs.findTocLineIndex.call(void 0, lines, noteIndex);
|
|
1836
|
-
} catch (e3) {
|
|
1837
|
-
logger.warn(`TOC.md \u4E2D\u672A\u627E\u5230\u7B14\u8BB0: ${noteIndex}`);
|
|
1838
|
-
return;
|
|
1839
|
-
}
|
|
1840
|
-
const { start, end } = _chunk3R7QSABBcjs.getTocEntrySubtreeRange.call(void 0, lines, lineIndex);
|
|
1841
|
-
lines.splice(start, end - start);
|
|
1842
|
-
await this.writeTocLines(lines);
|
|
1843
|
-
logger.info(`\u4ECE TOC.md \u5220\u9664\u7B14\u8BB0\u53CA\u5B50\u6811: ${noteIndex} (${end - start} \u884C)`);
|
|
1844
|
-
}
|
|
1845
|
-
/**
|
|
1846
|
-
* 重命名 TOC.md 中的笔记行(保留位置与缩进)
|
|
1847
|
-
*/
|
|
1848
|
-
async renameNoteInToc(noteIndex, newDirName) {
|
|
1849
|
-
if (!_fs.existsSync.call(void 0, ROOT_TOC_PATH)) return;
|
|
1850
|
-
const item = this.noteIndexCache.getByNoteIndex(noteIndex);
|
|
1851
|
-
const notes = this.noteIndexCache.isInitialized() ? this.noteIndexCache.toNoteInfoList() : this.noteManager.scanNotes();
|
|
1852
|
-
const note = _chunk3R7QSABBcjs.resolveNoteFromIndex.call(void 0, noteIndex, notes);
|
|
1853
|
-
if (!note) return;
|
|
1854
|
-
const tempNote = {
|
|
1855
|
-
...note,
|
|
1856
|
-
dirName: newDirName,
|
|
1857
|
-
config: _nullishCoalesce(_optionalChain([item, 'optionalAccess', _14 => _14.noteConfig]), () => ( note.config))
|
|
1858
|
-
};
|
|
1859
|
-
const lines = await this.readTocLines();
|
|
1860
|
-
let updated = false;
|
|
1861
|
-
for (let i = 0; i < lines.length; i++) {
|
|
1862
|
-
const parsed = _chunk3R7QSABBcjs.parseTocLine.call(void 0, lines[i]);
|
|
1863
|
-
if (parsed.noteIndex === noteIndex) {
|
|
1864
|
-
lines[i] = _chunk3R7QSABBcjs.buildTocLine.call(void 0,
|
|
1865
|
-
tempNote,
|
|
1866
|
-
parsed.indentLevel,
|
|
1867
|
-
parsed.completed
|
|
1868
|
-
);
|
|
1869
|
-
updated = true;
|
|
1870
|
-
}
|
|
1871
|
-
}
|
|
1872
|
-
if (updated) {
|
|
1873
|
-
await this.writeTocLines(lines);
|
|
1874
|
-
logger.info(`TOC.md \u91CD\u547D\u540D\u7B14\u8BB0: ${noteIndex} -> ${newDirName}`);
|
|
1875
|
-
}
|
|
1876
|
-
}
|
|
1877
|
-
/**
|
|
1878
|
-
* 移动笔记(含子树)到目标位置
|
|
1879
|
-
*/
|
|
1880
|
-
async moveNoteInToc(noteIndex, target) {
|
|
1881
|
-
const lines = await this.readTocLines();
|
|
1882
|
-
const sourceIndex = _chunk3R7QSABBcjs.findTocLineIndex.call(void 0, lines, noteIndex);
|
|
1883
|
-
await this.moveTocEntryByLineIndex(sourceIndex, target);
|
|
1884
|
-
}
|
|
1885
|
-
/**
|
|
1886
|
-
* 移动任意 TOC 行(分组或笔记)及其子树
|
|
1887
|
-
*/
|
|
1888
|
-
async moveTocEntryByLineIndex(sourceTocLineIndex, target) {
|
|
1889
|
-
const lines = await this.readTocLines();
|
|
1890
|
-
const sourceParsed = _chunk3R7QSABBcjs.parseTocLine.call(void 0, lines[sourceTocLineIndex]);
|
|
1891
|
-
if (!sourceParsed.isMatch) {
|
|
1892
|
-
throw new Error(`\u65E0\u6548\u7684 TOC \u884C\u7D22\u5F15: ${sourceTocLineIndex}`);
|
|
1893
|
-
}
|
|
1894
|
-
const { start, end } = _chunk3R7QSABBcjs.getTocEntrySubtreeRange.call(void 0, lines, sourceTocLineIndex);
|
|
1895
|
-
const resolvedTargetIndex = this.resolveMoveTargetLineIndex(lines, target);
|
|
1896
|
-
if (resolvedTargetIndex >= start && resolvedTargetIndex < end) {
|
|
1897
|
-
throw new Error("\u4E0D\u80FD\u79FB\u52A8\u5230\u81EA\u8EAB\u6216\u5B50\u6811\u5185");
|
|
1898
|
-
}
|
|
1899
|
-
const movingLines = lines.splice(start, end - start);
|
|
1900
|
-
if (movingLines.length === 0) {
|
|
1901
|
-
throw new Error(`\u65E0\u6CD5\u79FB\u52A8\u7A7A\u5B50\u6811: \u884C ${sourceTocLineIndex}`);
|
|
1902
|
-
}
|
|
1903
|
-
const targetLineIndex = _chunk3R7QSABBcjs.adjustTocLineIndexAfterSubtreeRemoval.call(void 0,
|
|
1904
|
-
resolvedTargetIndex,
|
|
1905
|
-
start,
|
|
1906
|
-
end
|
|
1907
|
-
);
|
|
1908
|
-
const targetParsed = _chunk3R7QSABBcjs.parseTocLine.call(void 0, lines[targetLineIndex]);
|
|
1909
|
-
if (!targetParsed.isMatch) {
|
|
1910
|
-
throw new Error(`\u65E0\u6548\u7684\u76EE\u6807 TOC \u884C\u7D22\u5F15: ${targetLineIndex}`);
|
|
1911
|
-
}
|
|
1912
|
-
let insertIndex;
|
|
1913
|
-
let newIndent;
|
|
1914
|
-
if (target.placement === "inside") {
|
|
1915
|
-
insertIndex = targetLineIndex + 1;
|
|
1916
|
-
newIndent = targetParsed.indentLevel + 1;
|
|
1917
|
-
} else if (target.placement === "before") {
|
|
1918
|
-
insertIndex = targetLineIndex;
|
|
1919
|
-
newIndent = targetParsed.indentLevel;
|
|
1920
|
-
} else {
|
|
1921
|
-
insertIndex = _chunk3R7QSABBcjs.getTocEntrySubtreeRange.call(void 0, lines, targetLineIndex).end;
|
|
1922
|
-
newIndent = targetParsed.indentLevel;
|
|
1923
|
-
}
|
|
1924
|
-
const oldBaseIndent = _chunk3R7QSABBcjs.parseTocLine.call(void 0, movingLines[0]).indentLevel;
|
|
1925
|
-
const indentDelta = newIndent - oldBaseIndent;
|
|
1926
|
-
const adjustedLines = this.adjustSubtreeIndent(movingLines, indentDelta);
|
|
1927
|
-
const maxDepth = this.getSidebarMaxDepth();
|
|
1928
|
-
if (maxDepth > 0) {
|
|
1929
|
-
const maxIndent = this.getMaxSubtreeIndent(adjustedLines);
|
|
1930
|
-
const maxAllowedIndent = maxDepth - 1;
|
|
1931
|
-
if (maxIndent > maxAllowedIndent) {
|
|
1932
|
-
throw new Error(`\u79FB\u52A8\u540E\u5C06\u8D85\u51FA\u76EE\u5F55\u6700\u5927\u5C42\u7EA7\uFF08${maxDepth} \u5C42\uFF09`);
|
|
1933
|
-
}
|
|
1934
|
-
}
|
|
1935
|
-
lines.splice(insertIndex, 0, ...adjustedLines);
|
|
1936
|
-
await this.writeTocLines(lines);
|
|
1937
|
-
logger.info(
|
|
1938
|
-
`TOC.md \u79FB\u52A8\u884C ${sourceTocLineIndex} -> \u884C ${targetLineIndex} (${target.placement})`
|
|
1939
|
-
);
|
|
1940
|
-
}
|
|
1941
|
-
/**
|
|
1942
|
-
* 语雀式移动:成为 target 的下一同级
|
|
1943
|
-
*/
|
|
1944
|
-
async moveAfterByNodeId(sourceNodeId, targetNodeId) {
|
|
1945
|
-
const lines = await this.readTocLines();
|
|
1946
|
-
const sourceIndex = this.resolveNodeIdToTocLineIndex(lines, sourceNodeId);
|
|
1947
|
-
const targetIndex = this.resolveNodeIdToTocLineIndex(lines, targetNodeId);
|
|
1948
|
-
await this.moveTocEntryByLineIndex(sourceIndex, {
|
|
1949
|
-
targetTocLineIndex: targetIndex,
|
|
1950
|
-
placement: "after"
|
|
1951
|
-
});
|
|
1952
|
-
}
|
|
1953
|
-
/**
|
|
1954
|
-
* 语雀式:prepend 到侧栏列表顶(无 target_uuid,book 即容器)
|
|
1955
|
-
*/
|
|
1956
|
-
async prependToRootByNodeId(sourceNodeId) {
|
|
1957
|
-
const lines = await this.readTocLines();
|
|
1958
|
-
const sourceIndex = this.resolveNodeIdToTocLineIndex(lines, sourceNodeId);
|
|
1959
|
-
let targetLineIndex = 0;
|
|
1960
|
-
while (targetLineIndex < lines.length && !_chunk3R7QSABBcjs.parseTocLine.call(void 0, lines[targetLineIndex]).isMatch) {
|
|
1961
|
-
targetLineIndex++;
|
|
1962
|
-
}
|
|
1963
|
-
if (targetLineIndex >= lines.length) {
|
|
1964
|
-
throw new Error("TOC.md \u4E3A\u7A7A\uFF0C\u65E0\u6CD5\u79FB\u52A8\u5230\u9876\u90E8");
|
|
1965
|
-
}
|
|
1966
|
-
await this.moveTocEntryByLineIndex(sourceIndex, {
|
|
1967
|
-
targetTocLineIndex: targetLineIndex,
|
|
1968
|
-
placement: "before"
|
|
1969
|
-
});
|
|
1970
|
-
}
|
|
1971
|
-
/**
|
|
1972
|
-
* 语雀式移动:成为 target 的第一个子项
|
|
1973
|
-
*/
|
|
1974
|
-
async prependChildByNodeId(sourceNodeId, targetNodeId) {
|
|
1975
|
-
const lines = await this.readTocLines();
|
|
1976
|
-
const sourceIndex = this.resolveNodeIdToTocLineIndex(lines, sourceNodeId);
|
|
1977
|
-
const targetIndex = this.resolveNodeIdToTocLineIndex(lines, targetNodeId);
|
|
1978
|
-
await this.moveTocEntryByLineIndex(sourceIndex, {
|
|
1979
|
-
targetTocLineIndex: targetIndex,
|
|
1980
|
-
placement: "inside"
|
|
1981
|
-
});
|
|
1982
|
-
}
|
|
1983
|
-
resolveNodeIdToTocLineIndex(lines, nodeId) {
|
|
1984
|
-
const parsed = _chunk3R7QSABBcjs.parseNodeId.call(void 0, nodeId);
|
|
1985
|
-
if (parsed.kind === "note" && parsed.noteIndex) {
|
|
1986
|
-
return _chunk3R7QSABBcjs.findTocLineIndex.call(void 0, lines, parsed.noteIndex);
|
|
1987
|
-
}
|
|
1988
|
-
if (parsed.kind === "line" && parsed.tocLineIndex !== void 0) {
|
|
1989
|
-
return parsed.tocLineIndex;
|
|
1990
|
-
}
|
|
1991
|
-
if (parsed.kind === "folder" && parsed.folderPath) {
|
|
1992
|
-
return _chunk3R7QSABBcjs.findFolderLineIndex.call(void 0, lines, parsed.folderPath);
|
|
1993
|
-
}
|
|
1994
|
-
throw new Error(`\u65E0\u6CD5\u89E3\u6790 nodeId: ${nodeId}`);
|
|
1995
|
-
}
|
|
1996
|
-
/**
|
|
1997
|
-
* 重命名 TOC 目录行
|
|
1998
|
-
*/
|
|
1999
|
-
async renameFolderInToc(tocLineIndex, newTitle) {
|
|
2000
|
-
const lines = await this.readTocLines();
|
|
2001
|
-
const updated = _chunk3R7QSABBcjs.renameFolderLine.call(void 0, lines, tocLineIndex, newTitle);
|
|
2002
|
-
await this.writeTocLines(updated);
|
|
2003
|
-
logger.info(`TOC.md \u91CD\u547D\u540D\u76EE\u5F55\u884C ${tocLineIndex}: ${newTitle.trim()}`);
|
|
2004
|
-
}
|
|
2005
|
-
/**
|
|
2006
|
-
* 删除子树前获取回退笔记(子树之前的最后一篇笔记)
|
|
2007
|
-
*/
|
|
2008
|
-
async getPreviousNoteIndexBeforeEntryDelete(tocLineIndex) {
|
|
2009
|
-
const lines = await this.readTocLines();
|
|
2010
|
-
return _chunk3R7QSABBcjs.getPreviousNoteIndexOutsideSubtree.call(void 0, lines, tocLineIndex);
|
|
2011
|
-
}
|
|
2012
|
-
/**
|
|
2013
|
-
* 判断 noteIndex 是否在指定 TOC 行子树内
|
|
2014
|
-
*/
|
|
2015
|
-
async isNoteInTocEntrySubtree(tocLineIndex, noteIndex) {
|
|
2016
|
-
const lines = await this.readTocLines();
|
|
2017
|
-
return _chunk3R7QSABBcjs.isNoteIndexInSubtree.call(void 0, lines, tocLineIndex, noteIndex);
|
|
2018
|
-
}
|
|
2019
|
-
/**
|
|
2020
|
-
* 级联删除 TOC 子树,并删除子树内所有笔记磁盘目录
|
|
2021
|
-
*/
|
|
2022
|
-
async deleteTocEntryCascade(tocLineIndex) {
|
|
2023
|
-
if (!_fs.existsSync.call(void 0, ROOT_TOC_PATH)) return [];
|
|
2024
|
-
const lines = await this.readTocLines();
|
|
2025
|
-
const noteIndexes = _chunk3R7QSABBcjs.collectNoteIndexesInSubtree.call(void 0, lines, tocLineIndex);
|
|
2026
|
-
const { start, end } = _chunk3R7QSABBcjs.getTocEntrySubtreeRange.call(void 0, lines, tocLineIndex);
|
|
2027
|
-
lines.splice(start, end - start);
|
|
2028
|
-
await this.writeTocLines(lines);
|
|
2029
|
-
const noteService = NoteService.getInstance();
|
|
2030
|
-
for (const noteIndex of noteIndexes) {
|
|
2031
|
-
await noteService.deleteNote(noteIndex);
|
|
2032
|
-
}
|
|
2033
|
-
logger.info(
|
|
2034
|
-
`\u7EA7\u8054\u5220\u9664 TOC \u884C ${tocLineIndex}\uFF08${end - start} \u884C\uFF0C${noteIndexes.length} \u7BC7\u7B14\u8BB0\uFF09`
|
|
2035
|
-
);
|
|
2036
|
-
return noteIndexes;
|
|
2037
|
-
}
|
|
2038
|
-
/**
|
|
2039
|
-
* 在指定 TOC 行(folder 或 note)子树末尾插入笔记
|
|
2040
|
-
*/
|
|
2041
|
-
async insertNotesUnderTocLine(parentTocLineIndex, notesToInsert) {
|
|
2042
|
-
if (notesToInsert.length === 0) return;
|
|
2043
|
-
const lines = await this.readTocLines();
|
|
2044
|
-
const parentParsed = _chunk3R7QSABBcjs.parseTocLine.call(void 0, lines[parentTocLineIndex]);
|
|
2045
|
-
if (!parentParsed.isMatch) {
|
|
2046
|
-
throw new Error(`\u65E0\u6548\u7684 TOC \u884C\u7D22\u5F15: ${parentTocLineIndex}`);
|
|
2047
|
-
}
|
|
2048
|
-
const childIndent = parentParsed.indentLevel + 1;
|
|
2049
|
-
const { end } = _chunk3R7QSABBcjs.getTocEntrySubtreeRange.call(void 0, lines, parentTocLineIndex);
|
|
2050
|
-
const noteLines = notesToInsert.map(
|
|
2051
|
-
(note) => _chunk3R7QSABBcjs.buildTocLine.call(void 0, note, childIndent, _chunk3R7QSABBcjs.getTocLineCompleted.call(void 0, note))
|
|
2052
|
-
);
|
|
2053
|
-
lines.splice(end, 0, ...noteLines);
|
|
2054
|
-
await this.writeTocLines(lines);
|
|
2055
|
-
logger.info(
|
|
2056
|
-
`\u5728 TOC \u884C ${parentTocLineIndex} \u4E0B\u63D2\u5165 ${notesToInsert.length} \u7BC7\u7B14\u8BB0`
|
|
2057
|
-
);
|
|
2058
|
-
}
|
|
2059
|
-
/**
|
|
2060
|
-
* 在指定 TOC 行(folder 或 note)子树末尾插入子目录
|
|
2061
|
-
*/
|
|
2062
|
-
async insertFolderUnderParent(parentTocLineIndex, title) {
|
|
2063
|
-
const trimmed = title.trim();
|
|
2064
|
-
if (!trimmed) {
|
|
2065
|
-
throw new Error("\u76EE\u5F55\u6807\u9898\u4E0D\u80FD\u4E3A\u7A7A");
|
|
2066
|
-
}
|
|
2067
|
-
const lines = await this.readTocLines();
|
|
2068
|
-
const parentParsed = _chunk3R7QSABBcjs.parseTocLine.call(void 0, lines[parentTocLineIndex]);
|
|
2069
|
-
if (!parentParsed.isMatch) {
|
|
2070
|
-
throw new Error(`\u65E0\u6548\u7684 TOC \u884C\u7D22\u5F15: ${parentTocLineIndex}`);
|
|
2071
|
-
}
|
|
2072
|
-
const childIndent = parentParsed.indentLevel + 1;
|
|
2073
|
-
const { end } = _chunk3R7QSABBcjs.getTocEntrySubtreeRange.call(void 0, lines, parentTocLineIndex);
|
|
2074
|
-
lines.splice(end, 0, _chunk3R7QSABBcjs.buildFolderTocLine.call(void 0, trimmed, childIndent));
|
|
2075
|
-
await this.writeTocLines(lines);
|
|
2076
|
-
logger.info(`\u5728 TOC \u884C ${parentTocLineIndex} \u4E0B\u63D2\u5165\u76EE\u5F55: ${trimmed}`);
|
|
2077
|
-
}
|
|
2078
|
-
/**
|
|
2079
|
-
* 在指定笔记上方或下方插入笔记
|
|
2080
|
-
*/
|
|
2081
|
-
async insertNotesAroundNote(targetNoteIndex, notesToInsert, placement) {
|
|
2082
|
-
if (notesToInsert.length === 0) return;
|
|
2083
|
-
const lines = await this.readTocLines();
|
|
2084
|
-
const targetIndex = _chunk3R7QSABBcjs.findTocLineIndex.call(void 0, lines, targetNoteIndex);
|
|
2085
|
-
const targetParsed = _chunk3R7QSABBcjs.parseTocLine.call(void 0, lines[targetIndex]);
|
|
2086
|
-
const indent = targetParsed.indentLevel;
|
|
2087
|
-
const noteLines = notesToInsert.map(
|
|
2088
|
-
(note) => _chunk3R7QSABBcjs.buildTocLine.call(void 0, note, indent, _chunk3R7QSABBcjs.getTocLineCompleted.call(void 0, note))
|
|
2089
|
-
);
|
|
2090
|
-
const insertIndex = placement === "before" ? targetIndex : _chunk3R7QSABBcjs.getTocEntrySubtreeRange.call(void 0, lines, targetIndex).end;
|
|
2091
|
-
lines.splice(insertIndex, 0, ...noteLines);
|
|
2092
|
-
await this.writeTocLines(lines);
|
|
2093
|
-
logger.info(
|
|
2094
|
-
`\u5728\u7B14\u8BB0 ${targetNoteIndex} ${placement === "before" ? "\u4E0A\u65B9" : "\u4E0B\u65B9"}\u63D2\u5165 ${notesToInsert.length} \u7BC7\u7B14\u8BB0`
|
|
2095
|
-
);
|
|
2096
|
-
}
|
|
2097
|
-
/**
|
|
2098
|
-
* 在目录子树末尾插入笔记
|
|
2099
|
-
*/
|
|
2100
|
-
async insertNotesUnderFolder(folderPath, notesToInsert) {
|
|
2101
|
-
if (notesToInsert.length === 0) return;
|
|
2102
|
-
const lines = await this.readTocLines();
|
|
2103
|
-
const folderIndex = _chunk3R7QSABBcjs.findFolderLineIndex.call(void 0, lines, folderPath);
|
|
2104
|
-
await this.insertNotesUnderTocLine(folderIndex, notesToInsert);
|
|
2105
|
-
}
|
|
2106
|
-
async insertNotesUnderParent(parentNoteIndex, notesToInsert) {
|
|
2107
|
-
if (notesToInsert.length === 0) return;
|
|
2108
|
-
const lines = await this.readTocLines();
|
|
2109
|
-
const parentIndex = _chunk3R7QSABBcjs.findTocLineIndex.call(void 0, lines, parentNoteIndex);
|
|
2110
|
-
await this.insertNotesUnderTocLine(parentIndex, notesToInsert);
|
|
2111
|
-
}
|
|
2112
|
-
/**
|
|
2113
|
-
* 规范化 TOC 并刷新 sidebar
|
|
2114
|
-
*/
|
|
2115
|
-
async refreshTocAndSidebar(notes) {
|
|
2116
|
-
const allNotes = _nullishCoalesce(notes, () => ( (this.noteIndexCache.isInitialized() ? this.noteIndexCache.toNoteInfoList() : this.noteManager.scanNotes())));
|
|
2117
|
-
await this.normalizeToc(allNotes);
|
|
2118
|
-
await this.regenerateSidebar(allNotes);
|
|
2119
|
-
}
|
|
2120
|
-
resolveMoveTargetLineIndex(lines, target) {
|
|
2121
|
-
if ("targetTocLineIndex" in target) {
|
|
2122
|
-
return target.targetTocLineIndex;
|
|
2123
|
-
}
|
|
2124
|
-
if (target.targetType === "folder") {
|
|
2125
|
-
return _chunk3R7QSABBcjs.findFolderLineIndex.call(void 0, lines, target.targetFolderPath);
|
|
2126
|
-
}
|
|
2127
|
-
return _chunk3R7QSABBcjs.findTocLineIndex.call(void 0, lines, target.targetNoteIndex);
|
|
2128
|
-
}
|
|
2129
|
-
getSidebarMaxDepth() {
|
|
2130
|
-
const config2 = this.configManager.getAll();
|
|
2131
|
-
const depth = _nullishCoalesce(config2.sidebarMaxDepth, () => ( 0));
|
|
2132
|
-
return depth > 0 ? depth : 0;
|
|
2133
|
-
}
|
|
2134
|
-
getMaxSubtreeIndent(lines) {
|
|
2135
|
-
let max = 0;
|
|
2136
|
-
for (const line of lines) {
|
|
2137
|
-
const parsed = _chunk3R7QSABBcjs.parseTocLine.call(void 0, line);
|
|
2138
|
-
if (parsed.isMatch) {
|
|
2139
|
-
max = Math.max(max, parsed.indentLevel);
|
|
2140
|
-
}
|
|
2141
|
-
}
|
|
2142
|
-
return max;
|
|
2143
|
-
}
|
|
2144
|
-
adjustSubtreeIndent(lines, delta) {
|
|
2145
|
-
if (delta === 0) return lines;
|
|
2146
|
-
return lines.map((line) => {
|
|
2147
|
-
const parsed = _chunk3R7QSABBcjs.parseTocLine.call(void 0, line);
|
|
2148
|
-
if (!parsed.isMatch) return line;
|
|
2149
|
-
const newIndent = Math.max(0, parsed.indentLevel + delta);
|
|
2150
|
-
const withoutIndent = line.trimStart();
|
|
2151
|
-
return `${" ".repeat(newIndent * _chunk3R7QSABBcjs.TOC_INDENT_SPACES)}${withoutIndent}`;
|
|
2152
|
-
});
|
|
2153
|
-
}
|
|
2154
|
-
async readTocLines() {
|
|
2155
|
-
this.ensureTocExists();
|
|
2156
|
-
const content = await _fs.promises.readFile(ROOT_TOC_PATH, "utf-8");
|
|
2157
|
-
return content.split("\n");
|
|
2158
|
-
}
|
|
2159
|
-
async writeTocLines(lines) {
|
|
2160
|
-
const content = _chunk3R7QSABBcjs.processTocEmptyLines.call(void 0, lines).join("\n");
|
|
2161
|
-
await _fs.promises.writeFile(ROOT_TOC_PATH, content, "utf-8");
|
|
2162
|
-
}
|
|
2163
|
-
};
|
|
2164
|
-
|
|
2165
1292
|
// services/file-watcher/service.ts
|
|
2166
1293
|
var _http = require('http');
|
|
2167
1294
|
|
|
@@ -2335,6 +1462,17 @@ async function safeExecute(label, fn, logger2) {
|
|
|
2335
1462
|
}
|
|
2336
1463
|
}
|
|
2337
1464
|
|
|
1465
|
+
// services/reconcileToc.ts
|
|
1466
|
+
var workspaces = /* @__PURE__ */ new Map();
|
|
1467
|
+
async function reconcileTocFromFiles(repoRoot) {
|
|
1468
|
+
let workspace = workspaces.get(repoRoot);
|
|
1469
|
+
if (!workspace) {
|
|
1470
|
+
workspace = _chunkAGVER5MXcjs.createWorkspace.call(void 0, { rootPath: repoRoot });
|
|
1471
|
+
workspaces.set(repoRoot, workspace);
|
|
1472
|
+
}
|
|
1473
|
+
await workspace.toc.reconcileFromFiles();
|
|
1474
|
+
}
|
|
1475
|
+
|
|
2338
1476
|
// services/file-watcher/folderChangeHandler.ts
|
|
2339
1477
|
var RENAME_REVERT_DELAY_MS = 2e3;
|
|
2340
1478
|
var DELETE_REINIT_DELAY_MS = 1e3;
|
|
@@ -2364,7 +1502,7 @@ var FolderChangeHandler = class {
|
|
|
2364
1502
|
this.activeTimers.add(timer);
|
|
2365
1503
|
}
|
|
2366
1504
|
async handleFolderDeletion(deletedFolderName) {
|
|
2367
|
-
const { scheduler, watchState, noteIndexCache,
|
|
1505
|
+
const { scheduler, watchState, noteIndexCache, logger: logger2, notesDir } = this.config;
|
|
2368
1506
|
if (scheduler.getUpdating()) return;
|
|
2369
1507
|
scheduler.setUpdating(true);
|
|
2370
1508
|
try {
|
|
@@ -2377,9 +1515,8 @@ var FolderChangeHandler = class {
|
|
|
2377
1515
|
await safeExecute(
|
|
2378
1516
|
`\u5220\u9664\u7B14\u8BB0 ${noteIndex}`,
|
|
2379
1517
|
async () => {
|
|
2380
|
-
await
|
|
2381
|
-
|
|
2382
|
-
_optionalChain([this, 'access', _15 => _15.config, 'access', _16 => _16.onNoteStructureChanged, 'optionalCall', _17 => _17(`watcher:delete:${noteIndex}`)]);
|
|
1518
|
+
await reconcileTocFromFiles(_path.dirname.call(void 0, notesDir));
|
|
1519
|
+
_optionalChain([this, 'access', _11 => _11.config, 'access', _12 => _12.onNoteStructureChanged, 'optionalCall', _13 => _13(`watcher:delete:${noteIndex}`)]);
|
|
2383
1520
|
},
|
|
2384
1521
|
logger2
|
|
2385
1522
|
);
|
|
@@ -2414,7 +1551,7 @@ var FolderChangeHandler = class {
|
|
|
2414
1551
|
logger2
|
|
2415
1552
|
);
|
|
2416
1553
|
}
|
|
2417
|
-
_optionalChain([this, 'access',
|
|
1554
|
+
_optionalChain([this, 'access', _14 => _14.config, 'access', _15 => _15.onRenameSuccess, 'optionalCall', _16 => _16({
|
|
2418
1555
|
oldFolder: oldName,
|
|
2419
1556
|
newFolder: newName,
|
|
2420
1557
|
noteIndex: newNoteIndex
|
|
@@ -2447,7 +1584,7 @@ var FolderChangeHandler = class {
|
|
|
2447
1584
|
return { oldNoteIndex, newNoteIndex };
|
|
2448
1585
|
}
|
|
2449
1586
|
async handleTitleOnlyRename(noteIndex, newName) {
|
|
2450
|
-
const { noteIndexCache,
|
|
1587
|
+
const { noteIndexCache, logger: logger2, notesDir } = this.config;
|
|
2451
1588
|
logger2.info(`\u7B14\u8BB0\u7D22\u5F15\u672A\u53D8 (${noteIndex})\uFF0C\u53EA\u66F4\u65B0\u6807\u9898`);
|
|
2452
1589
|
noteIndexCache.updateFolderName(noteIndex, newName);
|
|
2453
1590
|
await safeExecute(
|
|
@@ -2455,9 +1592,12 @@ var FolderChangeHandler = class {
|
|
|
2455
1592
|
() => this.rewriteNoteReadmeH1(notesDir, newName, noteIndex),
|
|
2456
1593
|
logger2
|
|
2457
1594
|
);
|
|
2458
|
-
await
|
|
2459
|
-
|
|
2460
|
-
|
|
1595
|
+
await safeExecute(
|
|
1596
|
+
`\u6807\u9898\u91CD\u547D\u540D\u540C\u6B65\u76EE\u5F55 ${noteIndex}`,
|
|
1597
|
+
() => reconcileTocFromFiles(_path.dirname.call(void 0, notesDir)),
|
|
1598
|
+
logger2
|
|
1599
|
+
);
|
|
1600
|
+
_optionalChain([this, 'access', _17 => _17.config, 'access', _18 => _18.onNoteStructureChanged, 'optionalCall', _19 => _19(`watcher:rename-title:${noteIndex}`)]);
|
|
2461
1601
|
logger2.success(`\u6807\u9898\u66F4\u65B0\u5B8C\u6210`);
|
|
2462
1602
|
}
|
|
2463
1603
|
/**
|
|
@@ -2486,22 +1626,24 @@ var FolderChangeHandler = class {
|
|
|
2486
1626
|
);
|
|
2487
1627
|
return;
|
|
2488
1628
|
}
|
|
2489
|
-
const newH1 =
|
|
1629
|
+
const newH1 = _chunkAGVER5MXcjs.generateNoteTitle.call(void 0, noteIndex, newTitle, REPO_NOTES_URL);
|
|
2490
1630
|
if (lines[h1Index] === newH1) return;
|
|
2491
1631
|
lines[h1Index] = newH1;
|
|
2492
1632
|
await _fs.promises.writeFile(readmePath, lines.join("\n"), "utf-8");
|
|
2493
1633
|
}
|
|
2494
1634
|
async handleIndexChangedRename(oldNoteIndex, newNoteIndex) {
|
|
2495
|
-
const { noteService, noteIndexCache,
|
|
1635
|
+
const { noteService, noteIndexCache, logger: logger2, notesDir } = this.config;
|
|
2496
1636
|
logger2.info(`\u7B14\u8BB0\u7D22\u5F15\u53D8\u66F4: ${oldNoteIndex} \u2192 ${newNoteIndex}`);
|
|
2497
|
-
await
|
|
1637
|
+
await safeExecute(
|
|
1638
|
+
`\u7D22\u5F15\u53D8\u66F4\u540C\u6B65\u76EE\u5F55 ${oldNoteIndex}\u2192${newNoteIndex}`,
|
|
1639
|
+
() => reconcileTocFromFiles(_path.dirname.call(void 0, notesDir)),
|
|
1640
|
+
logger2
|
|
1641
|
+
);
|
|
2498
1642
|
const newNote = noteService.getNoteByIndex(newNoteIndex);
|
|
2499
1643
|
if (newNote) {
|
|
2500
1644
|
noteIndexCache.delete(oldNoteIndex);
|
|
2501
1645
|
noteIndexCache.add(newNote);
|
|
2502
|
-
|
|
2503
|
-
await tocService.regenerateSidebar();
|
|
2504
|
-
_optionalChain([this, 'access', _24 => _24.config, 'access', _25 => _25.onNoteStructureChanged, 'optionalCall', _26 => _26(
|
|
1646
|
+
_optionalChain([this, 'access', _20 => _20.config, 'access', _21 => _21.onNoteStructureChanged, 'optionalCall', _22 => _22(
|
|
2505
1647
|
`watcher:rename-index:${oldNoteIndex}->${newNoteIndex}`
|
|
2506
1648
|
)]);
|
|
2507
1649
|
logger2.success(`\u7B14\u8BB0\u7D22\u5F15\u53D8\u66F4\u5904\u7406\u5B8C\u6210`);
|
|
@@ -2528,7 +1670,7 @@ var FolderChangeHandler = class {
|
|
|
2528
1670
|
}
|
|
2529
1671
|
}
|
|
2530
1672
|
extractNoteIndexOrWarn(name) {
|
|
2531
|
-
const noteIndex = _optionalChain([name, 'access',
|
|
1673
|
+
const noteIndex = _optionalChain([name, 'access', _23 => _23.match, 'call', _24 => _24(/^(\d{4})/), 'optionalAccess', _25 => _25[1]]) || null;
|
|
2532
1674
|
if (!noteIndex) {
|
|
2533
1675
|
this.config.logger.warn(`\u65E0\u6CD5\u4ECE\u6587\u4EF6\u5939\u540D\u79F0\u63D0\u53D6\u7B14\u8BB0\u7D22\u5F15: ${name}`);
|
|
2534
1676
|
}
|
|
@@ -2608,29 +1750,21 @@ var FsWatcherAdapter = class {
|
|
|
2608
1750
|
};
|
|
2609
1751
|
|
|
2610
1752
|
// services/file-watcher/globalUpdateCoordinator.ts
|
|
1753
|
+
|
|
2611
1754
|
var GlobalUpdateCoordinator = class {
|
|
2612
1755
|
constructor(config2) {
|
|
2613
1756
|
this.config = config2;
|
|
2614
1757
|
}
|
|
2615
1758
|
async applyConfigUpdates(changedNoteIndexes) {
|
|
2616
1759
|
if (changedNoteIndexes.length === 0) return;
|
|
2617
|
-
const {
|
|
2618
|
-
logger2.info("\u68C0\u6D4B\u5230\u7B14\u8BB0\u72B6\u6001\u53D8\u5316\uFF0C\
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
noteIndex,
|
|
2626
|
-
_optionalChain([item, 'optionalAccess', _30 => _30.noteConfig]) || {}
|
|
2627
|
-
);
|
|
2628
|
-
logger2.info(`\u589E\u91CF\u66F4\u65B0 TOC.md \u4E2D\u7684\u7B14\u8BB0: ${noteIndex}`);
|
|
2629
|
-
},
|
|
2630
|
-
logger2
|
|
2631
|
-
);
|
|
2632
|
-
}
|
|
2633
|
-
await tocService.regenerateSidebar();
|
|
1760
|
+
const { logger: logger2, notesDir } = this.config;
|
|
1761
|
+
logger2.info("\u68C0\u6D4B\u5230\u7B14\u8BB0\u72B6\u6001\u53D8\u5316\uFF0C\u540C\u6B65\u5168\u5C40\u6587\u4EF6...");
|
|
1762
|
+
await safeExecute(
|
|
1763
|
+
"\u914D\u7F6E\u53D8\u66F4\u540C\u6B65\u76EE\u5F55",
|
|
1764
|
+
() => reconcileTocFromFiles(_path.dirname.call(void 0, notesDir)),
|
|
1765
|
+
logger2
|
|
1766
|
+
);
|
|
1767
|
+
logger2.info(`\u5DF2\u540C\u6B65\u914D\u7F6E\u53D8\u66F4\u7684\u7B14\u8BB0: ${changedNoteIndexes.join(", ")}`);
|
|
2634
1768
|
}
|
|
2635
1769
|
async updateNoteReadmesOnly(events) {
|
|
2636
1770
|
const noteIndexesToUpdate = [...new Set(events.map((c) => c.noteIndex))];
|
|
@@ -2751,7 +1885,7 @@ var WatchState = class {
|
|
|
2751
1885
|
const content = _fs.readFileSync.call(void 0, filePath, "utf-8");
|
|
2752
1886
|
if (content.length === 0) return null;
|
|
2753
1887
|
return _crypto.createHash.call(void 0, "md5").update(content).digest("hex");
|
|
2754
|
-
} catch (
|
|
1888
|
+
} catch (e3) {
|
|
2755
1889
|
return null;
|
|
2756
1890
|
}
|
|
2757
1891
|
}
|
|
@@ -2887,6 +2021,257 @@ var WatchState = class {
|
|
|
2887
2021
|
}
|
|
2888
2022
|
};
|
|
2889
2023
|
|
|
2024
|
+
// services/note/service.ts
|
|
2025
|
+
|
|
2026
|
+
|
|
2027
|
+
var _uuid = require('uuid');
|
|
2028
|
+
var NoteService = class _NoteService {
|
|
2029
|
+
constructor() {
|
|
2030
|
+
this.ignoredConfigPaths = /* @__PURE__ */ new Set();
|
|
2031
|
+
this.noteManager = NoteManager.getInstance();
|
|
2032
|
+
this.noteIndexCache = NoteIndexCache.getInstance();
|
|
2033
|
+
}
|
|
2034
|
+
static getInstance() {
|
|
2035
|
+
if (!_NoteService.instance) {
|
|
2036
|
+
_NoteService.instance = new _NoteService();
|
|
2037
|
+
}
|
|
2038
|
+
return _NoteService.instance;
|
|
2039
|
+
}
|
|
2040
|
+
/**
|
|
2041
|
+
* 标记配置文件在下次变更时被忽略(防止 API 写入触发文件监听循环)
|
|
2042
|
+
* @param configPath - 配置文件路径
|
|
2043
|
+
*/
|
|
2044
|
+
ignoreNextConfigChange(configPath) {
|
|
2045
|
+
this.ignoredConfigPaths.add(configPath);
|
|
2046
|
+
}
|
|
2047
|
+
/**
|
|
2048
|
+
* 检查配置文件是否应该被忽略
|
|
2049
|
+
* @param configPath - 配置文件路径
|
|
2050
|
+
* @returns 是否应该忽略
|
|
2051
|
+
*/
|
|
2052
|
+
shouldIgnoreConfigChange(configPath) {
|
|
2053
|
+
if (this.ignoredConfigPaths.has(configPath)) {
|
|
2054
|
+
this.ignoredConfigPaths.delete(configPath);
|
|
2055
|
+
return true;
|
|
2056
|
+
}
|
|
2057
|
+
return false;
|
|
2058
|
+
}
|
|
2059
|
+
/**
|
|
2060
|
+
* 获取所有笔记
|
|
2061
|
+
* dev 模式下(缓存已初始化)从内存读取,其他模式回退到文件扫描
|
|
2062
|
+
* @returns 笔记信息数组
|
|
2063
|
+
*/
|
|
2064
|
+
getAllNotes() {
|
|
2065
|
+
if (this.noteIndexCache.isInitialized()) {
|
|
2066
|
+
return this.noteIndexCache.toNoteInfoList();
|
|
2067
|
+
}
|
|
2068
|
+
return this.noteManager.scanNotes();
|
|
2069
|
+
}
|
|
2070
|
+
/**
|
|
2071
|
+
* 获取笔记(通过索引)
|
|
2072
|
+
* @param noteIndex - 笔记索引(文件夹前 4 位数字)
|
|
2073
|
+
* @returns 笔记信息,未找到时返回 undefined
|
|
2074
|
+
*/
|
|
2075
|
+
getNoteByIndex(noteIndex) {
|
|
2076
|
+
return this.noteManager.getNoteByIndex(noteIndex);
|
|
2077
|
+
}
|
|
2078
|
+
/**
|
|
2079
|
+
* 创建新笔记
|
|
2080
|
+
* @param options - 创建选项
|
|
2081
|
+
* @returns 新创建的笔记信息
|
|
2082
|
+
*/
|
|
2083
|
+
async createNote(options = {}) {
|
|
2084
|
+
const {
|
|
2085
|
+
title = "new",
|
|
2086
|
+
category,
|
|
2087
|
+
enableDiscussions = false,
|
|
2088
|
+
configId,
|
|
2089
|
+
usedIndexes
|
|
2090
|
+
} = options;
|
|
2091
|
+
const noteIndex = this.generateNextNoteIndex(usedIndexes);
|
|
2092
|
+
const dirName = `${noteIndex}. ${title}`;
|
|
2093
|
+
const notePath = _path.join.call(void 0, NOTES_PATH, dirName);
|
|
2094
|
+
await ensureDirectory(notePath);
|
|
2095
|
+
const readmePath = _path.join.call(void 0, notePath, "README.md");
|
|
2096
|
+
const noteTitle = _chunkAGVER5MXcjs.generateNoteTitle.call(void 0, noteIndex, title, REPO_NOTES_URL);
|
|
2097
|
+
const readmeContent = noteTitle + "\n" + _chunkAGVER5MXcjs.getNewNoteReadmeBody.call(void 0, );
|
|
2098
|
+
_fs.writeFileSync.call(void 0, readmePath, readmeContent, "utf-8");
|
|
2099
|
+
const configPath = _path.join.call(void 0, notePath, ".tnotes.json");
|
|
2100
|
+
const config2 = {
|
|
2101
|
+
id: configId || _uuid.v4.call(void 0, ),
|
|
2102
|
+
// 配置 ID 使用 UUID(跨知识库唯一)
|
|
2103
|
+
bilibili: [],
|
|
2104
|
+
tnotes: [],
|
|
2105
|
+
yuque: [],
|
|
2106
|
+
done: false,
|
|
2107
|
+
category,
|
|
2108
|
+
enableDiscussions
|
|
2109
|
+
};
|
|
2110
|
+
this.noteManager.writeNoteConfig(configPath, config2);
|
|
2111
|
+
const noteInfo = {
|
|
2112
|
+
index: noteIndex,
|
|
2113
|
+
// 返回的 id 是笔记索引(目录前缀)
|
|
2114
|
+
path: notePath,
|
|
2115
|
+
dirName,
|
|
2116
|
+
readmePath,
|
|
2117
|
+
configPath,
|
|
2118
|
+
config: config2
|
|
2119
|
+
};
|
|
2120
|
+
if (this.noteIndexCache.isInitialized()) {
|
|
2121
|
+
this.noteIndexCache.add(noteInfo);
|
|
2122
|
+
}
|
|
2123
|
+
logger.info(`Created new note: ${dirName}`);
|
|
2124
|
+
return noteInfo;
|
|
2125
|
+
}
|
|
2126
|
+
/**
|
|
2127
|
+
* 删除笔记文件夹
|
|
2128
|
+
* @param noteIndex - 笔记索引
|
|
2129
|
+
* @returns 被删除的笔记信息
|
|
2130
|
+
*/
|
|
2131
|
+
async deleteNote(noteIndex) {
|
|
2132
|
+
const note = this.getNoteByIndex(noteIndex);
|
|
2133
|
+
if (!note) {
|
|
2134
|
+
throw new Error(`\u7B14\u8BB0\u672A\u627E\u5230: ${noteIndex}`);
|
|
2135
|
+
}
|
|
2136
|
+
await _fs.promises.rm(note.path, { recursive: true, force: true });
|
|
2137
|
+
if (this.noteIndexCache.isInitialized()) {
|
|
2138
|
+
this.noteIndexCache.delete(noteIndex);
|
|
2139
|
+
}
|
|
2140
|
+
logger.info(`Deleted note: ${note.dirName}`);
|
|
2141
|
+
return note;
|
|
2142
|
+
}
|
|
2143
|
+
/**
|
|
2144
|
+
* 生成下一个笔记索引(填充空缺)
|
|
2145
|
+
* @param usedIndexes - 可选的已使用编号集合,不传则内部扫描
|
|
2146
|
+
* @returns 新的笔记索引(4位数字字符串,从 0001 到 9999)
|
|
2147
|
+
*/
|
|
2148
|
+
generateNextNoteIndex(usedIndexes) {
|
|
2149
|
+
if (!usedIndexes) {
|
|
2150
|
+
const notes = this.getAllNotes();
|
|
2151
|
+
usedIndexes = /* @__PURE__ */ new Set();
|
|
2152
|
+
for (const note of notes) {
|
|
2153
|
+
const id = parseInt(note.index, 10);
|
|
2154
|
+
if (!isNaN(id) && id >= 1 && id <= 9999) {
|
|
2155
|
+
usedIndexes.add(id);
|
|
2156
|
+
}
|
|
2157
|
+
}
|
|
2158
|
+
}
|
|
2159
|
+
if (usedIndexes.size === 0) {
|
|
2160
|
+
return "0001";
|
|
2161
|
+
}
|
|
2162
|
+
for (let i = 1; i <= 9999; i++) {
|
|
2163
|
+
if (!usedIndexes.has(i)) {
|
|
2164
|
+
return i.toString().padStart(CONSTANTS.NOTE_INDEX_LENGTH, "0");
|
|
2165
|
+
}
|
|
2166
|
+
}
|
|
2167
|
+
throw new Error("\u6240\u6709\u7B14\u8BB0\u7F16\u53F7 (0001-9999) \u5DF2\u88AB\u5360\u7528\uFF0C\u65E0\u6CD5\u521B\u5EFA\u65B0\u7B14\u8BB0");
|
|
2168
|
+
}
|
|
2169
|
+
/**
|
|
2170
|
+
* 更新笔记配置
|
|
2171
|
+
* @param noteIndex - 笔记索引
|
|
2172
|
+
* @param updates - 配置更新
|
|
2173
|
+
*/
|
|
2174
|
+
async updateNoteConfig(noteIndex, updates) {
|
|
2175
|
+
const note = this.getNoteByIndex(noteIndex);
|
|
2176
|
+
if (!note || !note.config) {
|
|
2177
|
+
throw new Error(`Note not found or no config: ${noteIndex}`);
|
|
2178
|
+
}
|
|
2179
|
+
const oldConfig = { ...note.config };
|
|
2180
|
+
const updatedConfig = {
|
|
2181
|
+
...note.config,
|
|
2182
|
+
...updates
|
|
2183
|
+
};
|
|
2184
|
+
this.ignoreNextConfigChange(note.configPath);
|
|
2185
|
+
this.noteManager.updateNoteConfig(note, updatedConfig);
|
|
2186
|
+
this.noteIndexCache.updateConfig(noteIndex, updatedConfig);
|
|
2187
|
+
const needsGlobalUpdate = this.checkNeedsGlobalUpdate(
|
|
2188
|
+
oldConfig,
|
|
2189
|
+
updatedConfig
|
|
2190
|
+
);
|
|
2191
|
+
if (needsGlobalUpdate) {
|
|
2192
|
+
logger.info(`\u68C0\u6D4B\u5230\u5168\u5C40\u5B57\u6BB5\u53D8\u66F4 (${noteIndex})\uFF0C\u6B63\u5728\u589E\u91CF\u66F4\u65B0\u5168\u5C40\u6587\u4EF6...`);
|
|
2193
|
+
await reconcileTocFromFiles(ROOT_DIR_PATH);
|
|
2194
|
+
logger.info(`\u5168\u5C40\u6587\u4EF6\u589E\u91CF\u66F4\u65B0\u5B8C\u6210 (${noteIndex})`);
|
|
2195
|
+
} else {
|
|
2196
|
+
logger.debug(`\u914D\u7F6E\u66F4\u65B0\u4E0D\u5F71\u54CD\u5168\u5C40\u6587\u4EF6 (${noteIndex})`);
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2199
|
+
/**
|
|
2200
|
+
* 检查配置更新是否需要触发全局更新
|
|
2201
|
+
* @param oldConfig - 旧配置
|
|
2202
|
+
* @param newConfig - 新配置
|
|
2203
|
+
* @returns 是否需要全局更新
|
|
2204
|
+
*/
|
|
2205
|
+
checkNeedsGlobalUpdate(oldConfig, newConfig) {
|
|
2206
|
+
const globalFields = ["done"];
|
|
2207
|
+
for (const field of globalFields) {
|
|
2208
|
+
if (oldConfig[field] !== newConfig[field]) {
|
|
2209
|
+
return true;
|
|
2210
|
+
}
|
|
2211
|
+
}
|
|
2212
|
+
return false;
|
|
2213
|
+
}
|
|
2214
|
+
/**
|
|
2215
|
+
* 修正笔记标题
|
|
2216
|
+
* @param noteInfo - 笔记信息
|
|
2217
|
+
* @returns 是否进行了修正
|
|
2218
|
+
*/
|
|
2219
|
+
async fixNoteTitle(noteInfo) {
|
|
2220
|
+
try {
|
|
2221
|
+
const readmeContent = _fs.readFileSync.call(void 0, noteInfo.readmePath, "utf-8");
|
|
2222
|
+
if (readmeContent.length === 0) return false;
|
|
2223
|
+
const lines = readmeContent.split("\n");
|
|
2224
|
+
const match = noteInfo.dirName.match(/^\d{4}\.\s+(.+)$/);
|
|
2225
|
+
if (!match) {
|
|
2226
|
+
logger.warn(`\u68C0\u6D4B\u5230\u9519\u8BEF\u7684\u7B14\u8BB0\u76EE\u5F55\u540D\u79F0\uFF1A${noteInfo.dirName}`);
|
|
2227
|
+
return false;
|
|
2228
|
+
}
|
|
2229
|
+
const expectedTitle = match[1];
|
|
2230
|
+
const expectedH1 = _chunkAGVER5MXcjs.generateNoteTitle.call(void 0,
|
|
2231
|
+
noteInfo.index,
|
|
2232
|
+
expectedTitle,
|
|
2233
|
+
REPO_NOTES_URL
|
|
2234
|
+
);
|
|
2235
|
+
const firstLine = lines[0].trim();
|
|
2236
|
+
if (!firstLine.startsWith("# ")) {
|
|
2237
|
+
lines.unshift(expectedH1);
|
|
2238
|
+
_fs.writeFileSync.call(void 0, noteInfo.readmePath, lines.join("\n"), "utf-8");
|
|
2239
|
+
logger.info(`Added title to: ${noteInfo.dirName}`);
|
|
2240
|
+
return true;
|
|
2241
|
+
}
|
|
2242
|
+
if (firstLine !== expectedH1) {
|
|
2243
|
+
lines[0] = expectedH1;
|
|
2244
|
+
_fs.writeFileSync.call(void 0, noteInfo.readmePath, lines.join("\n"), "utf-8");
|
|
2245
|
+
logger.info(`Fixed title for: ${noteInfo.dirName}`);
|
|
2246
|
+
return true;
|
|
2247
|
+
}
|
|
2248
|
+
return false;
|
|
2249
|
+
} catch (error) {
|
|
2250
|
+
logger.error(`Failed to fix title for: ${noteInfo.dirName}`, error);
|
|
2251
|
+
return false;
|
|
2252
|
+
}
|
|
2253
|
+
}
|
|
2254
|
+
/**
|
|
2255
|
+
* 修正所有笔记的标题
|
|
2256
|
+
* @param providedNotes - 可选的笔记列表,不传则内部扫描
|
|
2257
|
+
* @returns 修正的笔记数量
|
|
2258
|
+
*/
|
|
2259
|
+
async fixAllNoteTitles(providedNotes) {
|
|
2260
|
+
const notes = _nullishCoalesce(providedNotes, () => ( this.getAllNotes()));
|
|
2261
|
+
let fixedCount = 0;
|
|
2262
|
+
for (const note of notes) {
|
|
2263
|
+
const fixed = await this.fixNoteTitle(note);
|
|
2264
|
+
if (fixed) {
|
|
2265
|
+
fixedCount++;
|
|
2266
|
+
}
|
|
2267
|
+
}
|
|
2268
|
+
if (fixedCount > 0) {
|
|
2269
|
+
logger.info(`Fixed ${fixedCount} note titles`);
|
|
2270
|
+
}
|
|
2271
|
+
return fixedCount;
|
|
2272
|
+
}
|
|
2273
|
+
};
|
|
2274
|
+
|
|
2890
2275
|
// services/readme/service.ts
|
|
2891
2276
|
|
|
2892
2277
|
|
|
@@ -3190,7 +2575,6 @@ var ReadmeService = class _ReadmeService {
|
|
|
3190
2575
|
this.readmeGenerator = new ReadmeGenerator();
|
|
3191
2576
|
this.configManager = _chunkMZIXIY2Ycjs.ConfigManager.getInstance();
|
|
3192
2577
|
this.noteIndexCache = NoteIndexCache.getInstance();
|
|
3193
|
-
this.tocService = TocService.getInstance();
|
|
3194
2578
|
}
|
|
3195
2579
|
static getInstance() {
|
|
3196
2580
|
if (!_ReadmeService.instance) {
|
|
@@ -3230,8 +2614,7 @@ var ReadmeService = class _ReadmeService {
|
|
|
3230
2614
|
await this.updateHomeReadme(notes);
|
|
3231
2615
|
}
|
|
3232
2616
|
if (updateSidebar) {
|
|
3233
|
-
await
|
|
3234
|
-
await this.tocService.regenerateSidebar(notes);
|
|
2617
|
+
await reconcileTocFromFiles(ROOT_DIR_PATH);
|
|
3235
2618
|
}
|
|
3236
2619
|
logger.info("\u77E5\u8BC6\u5E93\u66F4\u65B0\u5B8C\u6210\uFF01");
|
|
3237
2620
|
}
|
|
@@ -3342,7 +2725,7 @@ var ReadmeService = class _ReadmeService {
|
|
|
3342
2725
|
continue;
|
|
3343
2726
|
}
|
|
3344
2727
|
let statusEmoji = "\u23F0 ";
|
|
3345
|
-
if (_optionalChain([note, 'optionalAccess',
|
|
2728
|
+
if (_optionalChain([note, 'optionalAccess', _26 => _26.config])) {
|
|
3346
2729
|
if (note.config.done) {
|
|
3347
2730
|
statusEmoji = "\u2705 ";
|
|
3348
2731
|
}
|
|
@@ -3604,17 +2987,15 @@ var ReadmeService = class _ReadmeService {
|
|
|
3604
2987
|
/**
|
|
3605
2988
|
* 更新 TOC.md 和 sidebar,不重写每篇笔记 README
|
|
3606
2989
|
*/
|
|
3607
|
-
async refreshHomeReadmeAndSidebar(
|
|
3608
|
-
|
|
3609
|
-
await this.tocService.normalizeToc(allNotes);
|
|
3610
|
-
await this.tocService.regenerateSidebar(allNotes);
|
|
2990
|
+
async refreshHomeReadmeAndSidebar(_notes) {
|
|
2991
|
+
await reconcileTocFromFiles(ROOT_DIR_PATH);
|
|
3611
2992
|
}
|
|
3612
2993
|
/**
|
|
3613
2994
|
* 重新生成 sidebar.json(基于当前 TOC.md)
|
|
3614
2995
|
* @param notes - 可选的笔记列表,不传则内部扫描
|
|
3615
2996
|
*/
|
|
3616
|
-
async regenerateSidebar(
|
|
3617
|
-
await
|
|
2997
|
+
async regenerateSidebar(_notes) {
|
|
2998
|
+
await reconcileTocFromFiles(ROOT_DIR_PATH);
|
|
3618
2999
|
logger.info("\u91CD\u65B0\u751F\u6210 sidebar.json");
|
|
3619
3000
|
}
|
|
3620
3001
|
async readHomeReadmeLines() {
|
|
@@ -3731,7 +3112,6 @@ var FileWatcherService = class _FileWatcherService {
|
|
|
3731
3112
|
init() {
|
|
3732
3113
|
this.noteService = NoteService.getInstance();
|
|
3733
3114
|
this.readmeService = ReadmeService.getInstance();
|
|
3734
|
-
this.tocService = TocService.getInstance();
|
|
3735
3115
|
this.noteIndexCache = NoteIndexCache.getInstance();
|
|
3736
3116
|
this.watchState = this.initWatchState();
|
|
3737
3117
|
this.scheduler = this.initScheduler();
|
|
@@ -3762,7 +3142,6 @@ var FileWatcherService = class _FileWatcherService {
|
|
|
3762
3142
|
scheduler: this.scheduler,
|
|
3763
3143
|
noteService: this.noteService,
|
|
3764
3144
|
readmeService: this.readmeService,
|
|
3765
|
-
tocService: this.tocService,
|
|
3766
3145
|
noteIndexCache: this.noteIndexCache,
|
|
3767
3146
|
logger,
|
|
3768
3147
|
onRenameSuccess: (payload) => {
|
|
@@ -3864,9 +3243,8 @@ var FileWatcherService = class _FileWatcherService {
|
|
|
3864
3243
|
}
|
|
3865
3244
|
initCoordinator() {
|
|
3866
3245
|
return new GlobalUpdateCoordinator({
|
|
3246
|
+
notesDir: this.notesDir,
|
|
3867
3247
|
readmeService: this.readmeService,
|
|
3868
|
-
tocService: this.tocService,
|
|
3869
|
-
noteIndexCache: this.noteIndexCache,
|
|
3870
3248
|
logger
|
|
3871
3249
|
});
|
|
3872
3250
|
}
|
|
@@ -3974,7 +3352,7 @@ var FileWatcherService = class _FileWatcherService {
|
|
|
3974
3352
|
var GitManager = class {
|
|
3975
3353
|
constructor(dir, logger2) {
|
|
3976
3354
|
this.dir = dir;
|
|
3977
|
-
this.logger = _optionalChain([logger2, 'optionalAccess',
|
|
3355
|
+
this.logger = _optionalChain([logger2, 'optionalAccess', _27 => _27.child, 'call', _28 => _28("git")]) || new Logger({ prefix: "git" });
|
|
3978
3356
|
}
|
|
3979
3357
|
/**
|
|
3980
3358
|
* 检查是否为有效的 Git 仓库
|
|
@@ -3986,7 +3364,7 @@ var GitManager = class {
|
|
|
3986
3364
|
this.dir
|
|
3987
3365
|
);
|
|
3988
3366
|
return result.trim() === "true";
|
|
3989
|
-
} catch (
|
|
3367
|
+
} catch (e4) {
|
|
3990
3368
|
return false;
|
|
3991
3369
|
}
|
|
3992
3370
|
}
|
|
@@ -4036,7 +3414,7 @@ var GitManager = class {
|
|
|
4036
3414
|
const [behindStr, aheadStr] = aheadBehind.trim().split(" ");
|
|
4037
3415
|
behind = parseInt(behindStr) || 0;
|
|
4038
3416
|
ahead = parseInt(aheadStr) || 0;
|
|
4039
|
-
} catch (
|
|
3417
|
+
} catch (e5) {
|
|
4040
3418
|
}
|
|
4041
3419
|
return {
|
|
4042
3420
|
hasChanges: lines.length > 0,
|
|
@@ -4083,7 +3461,7 @@ var GitManager = class {
|
|
|
4083
3461
|
};
|
|
4084
3462
|
}
|
|
4085
3463
|
return { url, type: "unknown" };
|
|
4086
|
-
} catch (
|
|
3464
|
+
} catch (e6) {
|
|
4087
3465
|
return null;
|
|
4088
3466
|
}
|
|
4089
3467
|
}
|
|
@@ -4155,7 +3533,7 @@ var GitManager = class {
|
|
|
4155
3533
|
});
|
|
4156
3534
|
}
|
|
4157
3535
|
this.logger.success(`\u62C9\u53D6\u6210\u529F: ${changedFiles.length} \u4E2A\u6587\u4EF6\u5DF2\u66F4\u65B0`);
|
|
4158
|
-
} catch (
|
|
3536
|
+
} catch (e7) {
|
|
4159
3537
|
this.logger.success("\u62C9\u53D6\u6210\u529F");
|
|
4160
3538
|
}
|
|
4161
3539
|
} else {
|
|
@@ -4242,7 +3620,7 @@ var GitManager = class {
|
|
|
4242
3620
|
const message = commitMessage || `update: ${status.changedFiles} files modified`;
|
|
4243
3621
|
await runCommand(`git commit -m "${message}"`, this.dir);
|
|
4244
3622
|
let cmd = "git push";
|
|
4245
|
-
if (_optionalChain([options, 'optionalAccess',
|
|
3623
|
+
if (_optionalChain([options, 'optionalAccess', _29 => _29.force])) cmd += " --force";
|
|
4246
3624
|
await runCommand(cmd, this.dir);
|
|
4247
3625
|
const remoteInfo = await this.getRemoteInfo();
|
|
4248
3626
|
if (remoteInfo) {
|
|
@@ -4423,7 +3801,7 @@ var ProcessManager = class {
|
|
|
4423
3801
|
if (!processInfo) return false;
|
|
4424
3802
|
try {
|
|
4425
3803
|
return process.kill(processInfo.pid, 0);
|
|
4426
|
-
} catch (
|
|
3804
|
+
} catch (e8) {
|
|
4427
3805
|
return false;
|
|
4428
3806
|
}
|
|
4429
3807
|
}
|
|
@@ -4620,8 +3998,8 @@ var VitepressService = class _VitepressService {
|
|
|
4620
3998
|
}
|
|
4621
3999
|
const elapsed = Date.now() - startTime;
|
|
4622
4000
|
const seconds = (elapsed / 1e3).toFixed(0);
|
|
4623
|
-
_optionalChain([process, 'access',
|
|
4624
|
-
_optionalChain([process, 'access',
|
|
4001
|
+
_optionalChain([process, 'access', _30 => _30.stderr, 'access', _31 => _31.clearLine, 'optionalCall', _32 => _32(0)]);
|
|
4002
|
+
_optionalChain([process, 'access', _33 => _33.stderr, 'access', _34 => _34.cursorTo, 'optionalCall', _35 => _35(0)]);
|
|
4625
4003
|
process.stderr.write(`\u23F3 \u542F\u52A8\u4E2D: \u5DF2\u7528 ${seconds}s...`);
|
|
4626
4004
|
}, _VitepressService.SERVER_STATUS_LINE_INTERVAL);
|
|
4627
4005
|
const handleOutput = (data) => {
|
|
@@ -4633,16 +4011,16 @@ var VitepressService = class _VitepressService {
|
|
|
4633
4011
|
if (!serverReady && (text.includes("Local:") || text.includes("http://localhost") || text.includes("\u279C") && text.includes("Local"))) {
|
|
4634
4012
|
serverReady = true;
|
|
4635
4013
|
clearInterval(statusTimer);
|
|
4636
|
-
_optionalChain([process, 'access',
|
|
4637
|
-
_optionalChain([process, 'access',
|
|
4014
|
+
_optionalChain([process, 'access', _36 => _36.stderr, 'access', _37 => _37.clearLine, 'optionalCall', _38 => _38(0)]);
|
|
4015
|
+
_optionalChain([process, 'access', _39 => _39.stderr, 'access', _40 => _40.cursorTo, 'optionalCall', _41 => _41(0)]);
|
|
4638
4016
|
const elapsed = Date.now() - startTime;
|
|
4639
4017
|
setTimeout(() => resolve4({ version, elapsed }), 200);
|
|
4640
4018
|
return;
|
|
4641
4019
|
}
|
|
4642
4020
|
if (!serverReady) {
|
|
4643
4021
|
if (text.includes("error") || text.includes("Error") || text.includes("Port") && text.includes("is in use")) {
|
|
4644
|
-
_optionalChain([process, 'access',
|
|
4645
|
-
_optionalChain([process, 'access',
|
|
4022
|
+
_optionalChain([process, 'access', _42 => _42.stderr, 'access', _43 => _43.clearLine, 'optionalCall', _44 => _44(0)]);
|
|
4023
|
+
_optionalChain([process, 'access', _45 => _45.stderr, 'access', _46 => _46.cursorTo, 'optionalCall', _47 => _47(0)]);
|
|
4646
4024
|
process.stdout.write(data);
|
|
4647
4025
|
}
|
|
4648
4026
|
}
|
|
@@ -4659,8 +4037,8 @@ var VitepressService = class _VitepressService {
|
|
|
4659
4037
|
if (!serverReady) {
|
|
4660
4038
|
serverReady = true;
|
|
4661
4039
|
clearInterval(statusTimer);
|
|
4662
|
-
_optionalChain([process, 'access',
|
|
4663
|
-
_optionalChain([process, 'access',
|
|
4040
|
+
_optionalChain([process, 'access', _48 => _48.stderr, 'access', _49 => _49.clearLine, 'optionalCall', _50 => _50(0)]);
|
|
4041
|
+
_optionalChain([process, 'access', _51 => _51.stderr, 'access', _52 => _52.cursorTo, 'optionalCall', _53 => _53(0)]);
|
|
4664
4042
|
logger.warn("\u542F\u52A8\u8D85\u65F6\uFF0C\u8BF7\u68C0\u67E5 VitePress \u8F93\u51FA");
|
|
4665
4043
|
resolve4({ version, elapsed: _VitepressService.SERVER_STARTUP_TIMEOUT });
|
|
4666
4044
|
}
|
|
@@ -4694,8 +4072,8 @@ var VitepressService = class _VitepressService {
|
|
|
4694
4072
|
return;
|
|
4695
4073
|
}
|
|
4696
4074
|
};
|
|
4697
|
-
_optionalChain([child, 'access',
|
|
4698
|
-
_optionalChain([child, 'access',
|
|
4075
|
+
_optionalChain([child, 'access', _54 => _54.stdout, 'optionalAccess', _55 => _55.on, 'call', _56 => _56("data", filterOutput)]);
|
|
4076
|
+
_optionalChain([child, 'access', _57 => _57.stderr, 'optionalAccess', _58 => _58.on, 'call', _59 => _59("data", filterOutput)]);
|
|
4699
4077
|
child.on("error", (err) => {
|
|
4700
4078
|
reject(err);
|
|
4701
4079
|
});
|
|
@@ -4842,13 +4220,13 @@ function buildRepoNotesUrl(repoName2) {
|
|
|
4842
4220
|
return `https://github.com/${GITHUB_ORG}/${repoName2}/tree/main/notes`;
|
|
4843
4221
|
}
|
|
4844
4222
|
function renderFirstNoteReadme(ctx) {
|
|
4845
|
-
const noteTitle =
|
|
4223
|
+
const noteTitle = _chunkAGVER5MXcjs.generateNoteTitle.call(void 0,
|
|
4846
4224
|
"0001",
|
|
4847
4225
|
ctx.noteTitle,
|
|
4848
4226
|
buildRepoNotesUrl(ctx.repoName)
|
|
4849
4227
|
);
|
|
4850
4228
|
return `${noteTitle}
|
|
4851
|
-
${
|
|
4229
|
+
${_chunkAGVER5MXcjs.getNewNoteReadmeBody.call(void 0, )}`;
|
|
4852
4230
|
}
|
|
4853
4231
|
function renderIndexMd(ctx) {
|
|
4854
4232
|
return `---
|
|
@@ -5134,7 +4512,6 @@ var RenameNoteCommand = class extends BaseCommand {
|
|
|
5134
4512
|
constructor() {
|
|
5135
4513
|
super("rename-note");
|
|
5136
4514
|
this.noteService = NoteService.getInstance();
|
|
5137
|
-
this.tocService = TocService.getInstance();
|
|
5138
4515
|
}
|
|
5139
4516
|
async run() {
|
|
5140
4517
|
const noteIndex = process.env.NOTE_ID;
|
|
@@ -5196,7 +4573,7 @@ var RenameNoteCommand = class extends BaseCommand {
|
|
|
5196
4573
|
}
|
|
5197
4574
|
}
|
|
5198
4575
|
if (h1Index !== -1) {
|
|
5199
|
-
const newH1 =
|
|
4576
|
+
const newH1 = _chunkAGVER5MXcjs.generateNoteTitle.call(void 0,
|
|
5200
4577
|
noteIndex,
|
|
5201
4578
|
newTitle.trim(),
|
|
5202
4579
|
REPO_NOTES_URL
|
|
@@ -5215,8 +4592,7 @@ var RenameNoteCommand = class extends BaseCommand {
|
|
|
5215
4592
|
}
|
|
5216
4593
|
try {
|
|
5217
4594
|
this.logger.info("\u6B63\u5728\u66F4\u65B0 TOC.md \u548C sidebar.json...");
|
|
5218
|
-
await
|
|
5219
|
-
await this.tocService.regenerateSidebar();
|
|
4595
|
+
await reconcileTocFromFiles(ROOT_DIR_PATH);
|
|
5220
4596
|
this.logger.success("\u2705 \u5168\u5C40\u6587\u4EF6\u5DF2\u66F4\u65B0");
|
|
5221
4597
|
} catch (error) {
|
|
5222
4598
|
this.logger.warn("\u26A0\uFE0F \u6587\u4EF6\u5939\u91CD\u547D\u540D\u6210\u529F,\u4F46\u66F4\u65B0\u5168\u5C40\u6587\u4EF6\u65F6\u51FA\u9519:", error);
|
|
@@ -5259,6 +4635,4 @@ var RenameNoteCommand = class extends BaseCommand {
|
|
|
5259
4635
|
|
|
5260
4636
|
|
|
5261
4637
|
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
exports.ROOT_DIR_PATH = ROOT_DIR_PATH; exports.ROOT_README_PATH = ROOT_README_PATH; exports.ROOT_TOC_PATH = ROOT_TOC_PATH; exports.ROOT_CONFIG_PATH = ROOT_CONFIG_PATH; exports.handleError = handleError; exports.logger = logger; exports.createLogger = createLogger; exports.parseArgs = parseArgs; exports.parseReadmeCompletedNotes = parseReadmeCompletedNotes; exports.migrateReadmeToToc = migrateReadmeToToc; exports.runCommand = runCommand; exports.NoteManager = NoteManager; exports.NoteIndexCache = NoteIndexCache; exports.TocService = TocService; exports.NoteService = NoteService; exports.ReadmeService = ReadmeService; exports.FileWatcherService = FileWatcherService; exports.GitManager = GitManager; exports.GitService = GitService; exports.VitepressService = VitepressService; exports.DEFAULT_PORT = DEFAULT_PORT; exports.DEFAULT_DESCRIPTION = DEFAULT_DESCRIPTION; exports.defaultDisplayName = defaultDisplayName; exports.validateTopic = validateTopic; exports.validatePort = validatePort; exports.buildInitContext = buildInitContext; exports.isAlreadyInitialized = isAlreadyInitialized; exports.getInitializedConfigPath = getInitializedConfigPath; exports.buildManualSteps = buildManualSteps; exports.InitSubRepoService = InitSubRepoService; exports.COMMAND_NAMES = COMMAND_NAMES; exports.COMMAND_DESCRIPTIONS = COMMAND_DESCRIPTIONS; exports.COMMAND_OPTIONS = COMMAND_OPTIONS; exports.BaseCommand = BaseCommand; exports.UpdateNoteConfigCommand = UpdateNoteConfigCommand; exports.RenameNoteCommand = RenameNoteCommand;
|
|
4638
|
+
exports.ROOT_DIR_PATH = ROOT_DIR_PATH; exports.ROOT_TOC_PATH = ROOT_TOC_PATH; exports.ROOT_CONFIG_PATH = ROOT_CONFIG_PATH; exports.reconcileTocFromFiles = reconcileTocFromFiles; exports.handleError = handleError; exports.logger = logger; exports.createLogger = createLogger; exports.parseArgs = parseArgs; exports.parseReadmeCompletedNotes = parseReadmeCompletedNotes; exports.runCommand = runCommand; exports.NoteManager = NoteManager; exports.NoteIndexCache = NoteIndexCache; exports.NoteService = NoteService; exports.ReadmeService = ReadmeService; exports.FileWatcherService = FileWatcherService; exports.GitManager = GitManager; exports.GitService = GitService; exports.VitepressService = VitepressService; exports.DEFAULT_PORT = DEFAULT_PORT; exports.DEFAULT_DESCRIPTION = DEFAULT_DESCRIPTION; exports.defaultDisplayName = defaultDisplayName; exports.validateTopic = validateTopic; exports.validatePort = validatePort; exports.buildInitContext = buildInitContext; exports.isAlreadyInitialized = isAlreadyInitialized; exports.getInitializedConfigPath = getInitializedConfigPath; exports.buildManualSteps = buildManualSteps; exports.InitSubRepoService = InitSubRepoService; exports.COMMAND_NAMES = COMMAND_NAMES; exports.COMMAND_DESCRIPTIONS = COMMAND_DESCRIPTIONS; exports.COMMAND_OPTIONS = COMMAND_OPTIONS; exports.BaseCommand = BaseCommand; exports.UpdateNoteConfigCommand = UpdateNoteConfigCommand; exports.RenameNoteCommand = RenameNoteCommand;
|