@tnotesjs/core 0.6.1 → 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.
Files changed (42) hide show
  1. package/config/templates.ts +0 -5
  2. package/dist/{chunk-5F5RJ2HV.cjs → chunk-7FEANCT6.cjs} +16 -7
  3. package/dist/chunk-AGVER5MX.cjs +1746 -0
  4. package/dist/{chunk-TJ4527KA.cjs → chunk-BL22KD4V.cjs} +324 -950
  5. package/dist/{chunk-56PKXCOX.js → chunk-GWG75A5M.js} +13 -4
  6. package/dist/{chunk-DUTS75WQ.js → chunk-XNO3PCEH.js} +374 -1000
  7. package/dist/chunk-ZEQS64PE.js +1746 -0
  8. package/dist/cli/index.cjs +76 -155
  9. package/dist/cli/index.js +10 -89
  10. package/dist/markdown/index.cjs +2 -3
  11. package/dist/markdown/index.d.cts +1 -1
  12. package/dist/markdown/index.d.ts +1 -1
  13. package/dist/markdown/index.js +1 -2
  14. package/dist/{types-CwBWwNVv.d.ts → types-C_d0fFeD.d.ts} +8 -1
  15. package/dist/{types-CpsEy8lA.d.cts → types-MRBGgJTX.d.cts} +8 -1
  16. package/dist/vitepress/config/index.cjs +200 -132
  17. package/dist/vitepress/config/index.js +187 -119
  18. package/dist/workspace/index.cjs +4 -1202
  19. package/dist/workspace/index.d.cts +2 -2
  20. package/dist/workspace/index.d.ts +2 -2
  21. package/dist/workspace/index.js +4 -1202
  22. package/package.json +1 -1
  23. package/services/file-watcher/folderChangeHandler.ts +19 -15
  24. package/services/file-watcher/globalUpdateCoordinator.ts +21 -27
  25. package/services/file-watcher/service.ts +1 -6
  26. package/services/index.ts +0 -1
  27. package/services/note/service.ts +4 -6
  28. package/services/readme/service.ts +11 -18
  29. package/services/reconcileToc.ts +20 -0
  30. package/utils/index.ts +0 -9
  31. package/{services/toc → utils}/moveTocInside.test.ts +1 -1
  32. package/vitepress/components/constants.ts +2 -2
  33. package/vitepress/components/sidebar.data.ts +8 -5
  34. package/vitepress/plugins/sidebarStructurePlugin.ts +242 -145
  35. package/dist/chunk-3R7QSABB.cjs +0 -502
  36. package/dist/chunk-CZXRQPFJ.js +0 -11
  37. package/dist/chunk-HXED7KVT.cjs +0 -11
  38. package/dist/chunk-U6IBLREL.js +0 -502
  39. package/services/toc/index.ts +0 -5
  40. package/services/toc/service.ts +0 -759
  41. package/utils/migrateReadmeToToc.test.ts +0 -111
  42. package/utils/migrateReadmeToToc.ts +0 -135
@@ -1,1207 +1,9 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
- var _chunk5F5RJ2HVcjs = require('../chunk-5F5RJ2HV.cjs');
4
3
 
4
+ var _chunkAGVER5MXcjs = require('../chunk-AGVER5MX.cjs');
5
+ require('../chunk-7FEANCT6.cjs');
5
6
 
6
7
 
7
8
 
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
- var _chunk3R7QSABBcjs = require('../chunk-3R7QSABB.cjs');
20
- require('../chunk-HXED7KVT.cjs');
21
-
22
- // workspace/workspace.ts
23
- var _crypto = require('crypto');
24
- var _promises = require('fs/promises'); var _promises2 = _interopRequireDefault(_promises);
25
- var _path = require('path'); var _path2 = _interopRequireDefault(_path);
26
-
27
- // workspace/atomic.ts
28
-
29
- var _fs = require('fs');
30
-
31
-
32
-
33
- // workspace/errors.ts
34
- var WorkspaceError = class extends Error {
35
- constructor(code, message, details) {
36
- super(message);
37
- this.name = "WorkspaceError";
38
- this.code = code;
39
- this.details = details;
40
- }
41
- };
42
-
43
- // workspace/atomic.ts
44
- async function pathExists(filePath) {
45
- try {
46
- await _promises2.default.access(filePath, _fs.constants.F_OK);
47
- return true;
48
- } catch (e) {
49
- return false;
50
- }
51
- }
52
- async function stageWrite(write) {
53
- await _promises2.default.mkdir(_path2.default.dirname(write.path), { recursive: true });
54
- const temporaryPath = _path2.default.join(
55
- _path2.default.dirname(write.path),
56
- `.${_path2.default.basename(write.path)}.${_crypto.randomUUID.call(void 0, )}.tmp`
57
- );
58
- const handle = await _promises2.default.open(temporaryPath, "wx");
59
- try {
60
- await handle.writeFile(write.data);
61
- await handle.sync();
62
- } finally {
63
- await handle.close();
64
- }
65
- return temporaryPath;
66
- }
67
- async function restoreOriginals(originals) {
68
- for (const original of originals) {
69
- if (original.existed && original.data) {
70
- const restorePath = await stageWrite({
71
- path: original.path,
72
- data: original.data
73
- });
74
- await _promises2.default.rename(restorePath, original.path);
75
- } else {
76
- await _promises2.default.rm(original.path, { force: true });
77
- }
78
- }
79
- }
80
- async function writeFilesAtomically(writes) {
81
- const uniqueWrites = /* @__PURE__ */ new Map();
82
- for (const write of writes) uniqueWrites.set(write.path, write);
83
- const normalizedWrites = [...uniqueWrites.values()];
84
- const originals = [];
85
- const staged = [];
86
- try {
87
- for (const write of normalizedWrites) {
88
- const existed = await pathExists(write.path);
89
- originals.push({
90
- path: write.path,
91
- existed,
92
- data: existed ? await _promises2.default.readFile(write.path) : void 0
93
- });
94
- staged.push({
95
- target: write.path,
96
- temporary: await stageWrite(write)
97
- });
98
- }
99
- for (const item of staged) {
100
- await _promises2.default.rename(item.temporary, item.target);
101
- }
102
- } catch (error) {
103
- await Promise.allSettled(
104
- staged.map((item) => _promises2.default.rm(item.temporary, { force: true }))
105
- );
106
- try {
107
- await restoreOriginals(originals);
108
- } catch (restoreError) {
109
- throw new WorkspaceError(
110
- "FILESYSTEM_ERROR",
111
- "\u5199\u5165\u5931\u8D25\uFF0C\u5E76\u4E14\u65E0\u6CD5\u5B8C\u6574\u6062\u590D\u539F\u6587\u4EF6",
112
- {
113
- cause: error instanceof Error ? error.message : String(error),
114
- restoreCause: restoreError instanceof Error ? restoreError.message : String(restoreError)
115
- }
116
- );
117
- }
118
- throw new WorkspaceError("FILESYSTEM_ERROR", "\u65E0\u6CD5\u539F\u5B50\u5199\u5165\u77E5\u8BC6\u5E93\u6587\u4EF6", {
119
- cause: error instanceof Error ? error.message : String(error)
120
- });
121
- }
122
- }
123
-
124
- // workspace/mutationQueue.ts
125
- var MutationQueue = class {
126
- constructor() {
127
- this.tail = Promise.resolve();
128
- this.disposed = false;
129
- }
130
- async run(operation) {
131
- if (this.disposed) {
132
- throw new Error("Mutation queue has been disposed");
133
- }
134
- const previous = this.tail;
135
- let release;
136
- this.tail = new Promise((resolve) => {
137
- release = resolve;
138
- });
139
- await previous;
140
- try {
141
- return await operation();
142
- } finally {
143
- release();
144
- }
145
- }
146
- async dispose() {
147
- this.disposed = true;
148
- await this.tail;
149
- }
150
- };
151
-
152
- // workspace/paths.ts
153
-
154
- function createWorkspacePaths(rootPath) {
155
- if (!rootPath || !_path2.default.isAbsolute(rootPath)) {
156
- throw new WorkspaceError(
157
- "INVALID_PATH",
158
- "\u77E5\u8BC6\u5E93\u8DEF\u5F84\u5FC5\u987B\u662F\u975E\u7A7A\u7684\u7EDD\u5BF9\u8DEF\u5F84",
159
- { rootPath }
160
- );
161
- }
162
- const root = _path2.default.normalize(_path2.default.resolve(rootPath));
163
- return {
164
- root,
165
- config: _path2.default.join(root, ".tnotes.json"),
166
- toc: _path2.default.join(root, "TOC.md"),
167
- notes: _path2.default.join(root, "notes"),
168
- sidebar: _path2.default.join(root, "sidebar.json"),
169
- packageJson: _path2.default.join(root, "package.json")
170
- };
171
- }
172
- function assertPathInside(parent, target) {
173
- const relative = _path2.default.relative(parent, target);
174
- if (relative === "" || !relative.startsWith(`..${_path2.default.sep}`) && relative !== ".." && !_path2.default.isAbsolute(relative)) {
175
- return;
176
- }
177
- throw new WorkspaceError("INVALID_PATH", "\u76EE\u6807\u8DEF\u5F84\u8D85\u51FA\u5141\u8BB8\u8303\u56F4", {
178
- parent,
179
- target
180
- });
181
- }
182
- function sanitizeFileName(fileName) {
183
- const value = fileName.trim();
184
- if (!value || value === "." || value === ".." || value.includes("/") || value.includes("\\") || value.includes("\0")) {
185
- throw new WorkspaceError("INVALID_PATH", "\u9644\u4EF6\u6587\u4EF6\u540D\u4E0D\u5408\u6CD5", {
186
- fileName
187
- });
188
- }
189
- return value;
190
- }
191
-
192
- // workspace/scanner.ts
193
-
194
-
195
-
196
- var NOTE_DIRECTORY_PATTERN = /^(\d{4})\.\s*(.+)$/;
197
- var CURRENT_SCHEMA_VERSION = 1;
198
- function digest(...values) {
199
- const hash = _crypto.createHash.call(void 0, "sha256");
200
- for (const value of values) {
201
- hash.update(value);
202
- hash.update("\0");
203
- }
204
- return hash.digest("hex");
205
- }
206
- async function readText(filePath) {
207
- try {
208
- return await _promises2.default.readFile(filePath, "utf8");
209
- } catch (e2) {
210
- return null;
211
- }
212
- }
213
- function parseJsonObject(content) {
214
- try {
215
- const value = JSON.parse(content);
216
- return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
217
- } catch (e3) {
218
- return null;
219
- }
220
- }
221
- function noteInfoFromSummary(note) {
222
- return {
223
- index: note.index,
224
- path: note.directoryPath,
225
- dirName: note.dirName,
226
- readmePath: note.readmePath,
227
- configPath: note.configPath,
228
- config: note.config
229
- };
230
- }
231
- async function scanWorkspace(paths) {
232
- const diagnostics = [];
233
- let rootIsDirectory = false;
234
- try {
235
- rootIsDirectory = (await _promises2.default.stat(paths.root)).isDirectory();
236
- } catch (e4) {
237
- }
238
- if (!rootIsDirectory) {
239
- diagnostics.push({
240
- code: "ROOT_NOT_DIRECTORY",
241
- message: "\u77E5\u8BC6\u5E93\u6839\u76EE\u5F55\u4E0D\u5B58\u5728\u6216\u4E0D\u662F\u76EE\u5F55",
242
- severity: "error",
243
- path: paths.root
244
- });
245
- }
246
- const configText = await readText(paths.config);
247
- let config = null;
248
- if (configText === null) {
249
- diagnostics.push({
250
- code: "CONFIG_MISSING",
251
- message: "\u7F3A\u5C11\u77E5\u8BC6\u5E93\u914D\u7F6E .tnotes.json",
252
- severity: "error",
253
- path: paths.config
254
- });
255
- } else {
256
- config = parseJsonObject(configText);
257
- if (!config) {
258
- diagnostics.push({
259
- code: "CONFIG_INVALID_JSON",
260
- message: "\u77E5\u8BC6\u5E93\u914D\u7F6E\u4E0D\u662F\u6709\u6548\u7684 JSON \u5BF9\u8C61",
261
- severity: "error",
262
- path: paths.config
263
- });
264
- } else {
265
- if (typeof config.id !== "string" || !config.id.trim()) {
266
- diagnostics.push({
267
- code: "CONFIG_ID_MISSING",
268
- message: "\u77E5\u8BC6\u5E93\u914D\u7F6E\u7F3A\u5C11\u7A33\u5B9A\u7684 id",
269
- severity: "error",
270
- path: paths.config
271
- });
272
- }
273
- if (typeof config.repoName !== "string" || !config.repoName.trim()) {
274
- diagnostics.push({
275
- code: "CONFIG_REPO_NAME_MISSING",
276
- message: "\u77E5\u8BC6\u5E93\u914D\u7F6E\u7F3A\u5C11 repoName",
277
- severity: "error",
278
- path: paths.config
279
- });
280
- }
281
- }
282
- }
283
- let notesDirectoryExists = false;
284
- try {
285
- notesDirectoryExists = (await _promises2.default.stat(paths.notes)).isDirectory();
286
- } catch (e5) {
287
- }
288
- if (!notesDirectoryExists) {
289
- diagnostics.push({
290
- code: "NOTES_DIRECTORY_MISSING",
291
- message: "\u7F3A\u5C11 notes \u76EE\u5F55",
292
- severity: "error",
293
- path: paths.notes
294
- });
295
- }
296
- const tocText = await readText(paths.toc);
297
- if (tocText === null) {
298
- diagnostics.push({
299
- code: "TOC_MISSING",
300
- message: "\u7F3A\u5C11\u76EE\u5F55\u771F\u76F8\u6E90 TOC.md",
301
- severity: "error",
302
- path: paths.toc
303
- });
304
- }
305
- const notes = [];
306
- const usedIndexes = /* @__PURE__ */ new Map();
307
- const usedIds = /* @__PURE__ */ new Map();
308
- if (notesDirectoryExists) {
309
- const entries = await _promises2.default.readdir(paths.notes, { withFileTypes: true });
310
- entries.sort((left, right) => left.name.localeCompare(right.name));
311
- for (const entry of entries) {
312
- if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
313
- const match = NOTE_DIRECTORY_PATTERN.exec(entry.name);
314
- if (!match) continue;
315
- const [, index, rawTitle] = match;
316
- const title = rawTitle.trim();
317
- const directoryPath = _path2.default.join(paths.notes, entry.name);
318
- const readmePath = _path2.default.join(directoryPath, "README.md");
319
- const configPath = _path2.default.join(directoryPath, ".tnotes.json");
320
- const readme = await readText(readmePath);
321
- const noteConfigText = await readText(configPath);
322
- if (readme === null) {
323
- diagnostics.push({
324
- code: "NOTE_README_MISSING",
325
- message: `\u7B14\u8BB0 ${entry.name} \u7F3A\u5C11 README.md`,
326
- severity: "error",
327
- path: readmePath
328
- });
329
- continue;
330
- }
331
- if (noteConfigText === null) {
332
- diagnostics.push({
333
- code: "NOTE_CONFIG_MISSING",
334
- message: `\u7B14\u8BB0 ${entry.name} \u7F3A\u5C11 .tnotes.json`,
335
- severity: "error",
336
- path: configPath
337
- });
338
- continue;
339
- }
340
- const noteConfig = parseJsonObject(noteConfigText);
341
- if (!noteConfig || typeof noteConfig.id !== "string" || !noteConfig.id) {
342
- diagnostics.push({
343
- code: "NOTE_CONFIG_INVALID",
344
- message: `\u7B14\u8BB0 ${entry.name} \u7684\u914D\u7F6E\u65E0\u6CD5\u89E3\u6790\u6216\u7F3A\u5C11 id`,
345
- severity: "error",
346
- path: configPath
347
- });
348
- continue;
349
- }
350
- const existingIndex = usedIndexes.get(index);
351
- if (existingIndex) {
352
- diagnostics.push({
353
- code: "NOTE_INDEX_DUPLICATE",
354
- message: `\u7B14\u8BB0\u7F16\u53F7 ${index} \u91CD\u590D\uFF1A${existingIndex}\u3001${entry.name}`,
355
- severity: "error",
356
- path: directoryPath
357
- });
358
- } else {
359
- usedIndexes.set(index, entry.name);
360
- }
361
- const existingId = usedIds.get(noteConfig.id);
362
- if (existingId) {
363
- diagnostics.push({
364
- code: "NOTE_ID_DUPLICATE",
365
- message: `\u7B14\u8BB0 id ${noteConfig.id} \u91CD\u590D\uFF1A${existingId}\u3001${entry.name}`,
366
- severity: "error",
367
- path: configPath
368
- });
369
- } else {
370
- usedIds.set(noteConfig.id, entry.name);
371
- }
372
- notes.push({
373
- uuid: noteConfig.id,
374
- index,
375
- title,
376
- dirName: entry.name,
377
- directoryPath,
378
- readmePath,
379
- configPath,
380
- config: noteConfig,
381
- revision: digest(entry.name, readme, noteConfigText)
382
- });
383
- }
384
- }
385
- const noteInfos = notes.map(noteInfoFromSummary);
386
- const toc = tocText ? _chunk3R7QSABBcjs.parseTocToTree.call(void 0, tocText.split("\n"), noteInfos) : [];
387
- const sidebar = _chunk3R7QSABBcjs.buildSidebarFromTocTree.call(void 0, toc, noteInfos, {
388
- sidebarShowNoteId: _nullishCoalesce(_optionalChain([config, 'optionalAccess', _ => _.sidebarShowNoteId]), () => ( true)),
389
- sidebarIsCollapsed: true
390
- });
391
- const schemaVersion = _optionalChain([config, 'optionalAccess', _2 => _2.schemaVersion]);
392
- const futureSchema = typeof schemaVersion === "number" && schemaVersion > CURRENT_SCHEMA_VERSION;
393
- if (futureSchema) {
394
- diagnostics.push({
395
- code: "FUTURE_SCHEMA",
396
- message: `\u77E5\u8BC6\u5E93 schemaVersion ${schemaVersion} \u9AD8\u4E8E\u5F53\u524D\u652F\u6301\u7248\u672C ${CURRENT_SCHEMA_VERSION}`,
397
- severity: "error",
398
- path: paths.config
399
- });
400
- }
401
- const health = futureSchema ? { status: "future-schema", diagnostics } : diagnostics.some((diagnostic) => diagnostic.severity === "error") ? { status: "invalid", diagnostics } : { status: "ready", diagnostics };
402
- const id = config && typeof config.id === "string" && config.id.trim() ? config.id : `path-${digest(paths.root).slice(0, 24)}`;
403
- const revision = digest(
404
- paths.root,
405
- _nullishCoalesce(configText, () => ( "")),
406
- _nullishCoalesce(tocText, () => ( "")),
407
- ...notes.map((note) => `${note.uuid}:${note.revision}`)
408
- );
409
- return {
410
- snapshot: {
411
- id,
412
- rootPath: paths.root,
413
- config,
414
- health,
415
- toc,
416
- sidebar,
417
- notes,
418
- revision
419
- },
420
- configText,
421
- tocText
422
- };
423
- }
424
- function toNoteInfo(note) {
425
- return noteInfoFromSummary(note);
426
- }
427
-
428
- // workspace/workspace.ts
429
- var NOTE_CONFIG_FIELD_ORDER = [
430
- "bilibili",
431
- "tnotes",
432
- "yuque",
433
- "done",
434
- "category",
435
- "enableDiscussions",
436
- "description",
437
- "id"
438
- ];
439
- function validateTitle(title) {
440
- const value = title.trim();
441
- if (!value || /[\\/\0\r\n]/.test(value) || /[. ]$/.test(value) || /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\.|$)/i.test(value)) {
442
- throw new WorkspaceError("INVALID_TITLE", "\u7B14\u8BB0\u6216\u5206\u7EC4\u6807\u9898\u4E0D\u5408\u6CD5", {
443
- title
444
- });
445
- }
446
- return value;
447
- }
448
- function serializeNoteConfig(config) {
449
- const record = config;
450
- const sorted = {};
451
- for (const field of NOTE_CONFIG_FIELD_ORDER) {
452
- if (field in record) sorted[field] = record[field];
453
- }
454
- for (const [key, value] of Object.entries(record)) {
455
- if (!(key in sorted)) sorted[key] = value;
456
- }
457
- return `${JSON.stringify(sorted, null, 2)}
458
- `;
459
- }
460
- function normalizeTocContent(lines) {
461
- const content = _chunk3R7QSABBcjs.processTocEmptyLines.call(void 0, lines).join("\n");
462
- return content.endsWith("\n") ? content : `${content}
463
- `;
464
- }
465
- function toNoteInfos(notes) {
466
- return notes.map(toNoteInfo);
467
- }
468
- function sidebarContent(tocLines, notes, config) {
469
- const noteInfos = toNoteInfos(notes);
470
- const tree = _chunk3R7QSABBcjs.parseTocToTree.call(void 0, tocLines, noteInfos);
471
- return JSON.stringify(
472
- _chunk3R7QSABBcjs.buildSidebarFromTocTree.call(void 0, tree, noteInfos, {
473
- sidebarShowNoteId: _nullishCoalesce(config.sidebarShowNoteId, () => ( true)),
474
- sidebarIsCollapsed: true
475
- }),
476
- null,
477
- 2
478
- );
479
- }
480
- function requireConfig(snapshot) {
481
- if (snapshot.health.status === "future-schema") {
482
- throw new WorkspaceError(
483
- "WORKSPACE_READ_ONLY",
484
- "\u77E5\u8BC6\u5E93\u7531\u66F4\u65B0\u7248\u672C\u7684 Core \u521B\u5EFA\uFF0C\u5F53\u524D\u7248\u672C\u53EA\u5141\u8BB8\u8BFB\u53D6"
485
- );
486
- }
487
- if (snapshot.health.status !== "ready" || !snapshot.config) {
488
- throw new WorkspaceError("WORKSPACE_INVALID", "\u77E5\u8BC6\u5E93\u914D\u7F6E\u5F02\u5E38\uFF0C\u7981\u6B62\u4FEE\u6539", {
489
- diagnostics: snapshot.health.diagnostics
490
- });
491
- }
492
- return snapshot.config;
493
- }
494
- function findNote(snapshot, noteUuid) {
495
- const note = snapshot.notes.find((item) => item.uuid === noteUuid);
496
- if (!note) {
497
- throw new WorkspaceError("NOTE_NOT_FOUND", `\u672A\u627E\u5230\u7B14\u8BB0\uFF1A${noteUuid}`, {
498
- noteUuid
499
- });
500
- }
501
- return note;
502
- }
503
- function assertRevision(actual, expected, subject) {
504
- if (actual !== expected) {
505
- throw new WorkspaceError(
506
- "REVISION_CONFLICT",
507
- `${subject} \u5DF2\u88AB\u5176\u4ED6\u7A0B\u5E8F\u4FEE\u6539\uFF0C\u8BF7\u5148\u5904\u7406\u5916\u90E8\u53D8\u66F4`,
508
- { actual, expected }
509
- );
510
- }
511
- }
512
- function allocateNoteIndex(notes) {
513
- const used = new Set(
514
- notes.map((note) => Number.parseInt(note.index, 10)).filter((value) => Number.isInteger(value) && value >= 1 && value <= 9999)
515
- );
516
- for (let index = 1; index <= 9999; index++) {
517
- if (!used.has(index)) return String(index).padStart(4, "0");
518
- }
519
- throw new WorkspaceError(
520
- "NOTE_INDEX_EXHAUSTED",
521
- "\u6240\u6709\u7B14\u8BB0\u7F16\u53F7\uFF080001-9999\uFF09\u5747\u5DF2\u4F7F\u7528"
522
- );
523
- }
524
- function resolveEntryLine(lines, snapshot, entry) {
525
- if (entry.type === "line") {
526
- if (entry.tocLineIndex < 0 || entry.tocLineIndex >= lines.length) {
527
- throw new WorkspaceError("INVALID_TOC_ENTRY", "TOC \u884C\u7D22\u5F15\u65E0\u6548", {
528
- tocLineIndex: entry.tocLineIndex
529
- });
530
- }
531
- return entry.tocLineIndex;
532
- }
533
- if (entry.type === "folder") {
534
- try {
535
- return _chunk3R7QSABBcjs.findFolderLineIndex.call(void 0, lines, entry.folderPath);
536
- } catch (error) {
537
- throw new WorkspaceError("INVALID_TOC_ENTRY", "\u672A\u627E\u5230 TOC \u5206\u7EC4", {
538
- folderPath: entry.folderPath,
539
- cause: error instanceof Error ? error.message : String(error)
540
- });
541
- }
542
- }
543
- const note = findNote(snapshot, entry.noteUuid);
544
- try {
545
- return _chunk3R7QSABBcjs.findTocLineIndex.call(void 0, lines, note.index);
546
- } catch (error) {
547
- throw new WorkspaceError("INVALID_TOC_ENTRY", "\u672A\u5728 TOC \u4E2D\u627E\u5230\u7B14\u8BB0", {
548
- noteUuid: entry.noteUuid,
549
- cause: error instanceof Error ? error.message : String(error)
550
- });
551
- }
552
- }
553
- function placementTargetLine(lines, snapshot, placement) {
554
- if (placement.type === "note") {
555
- return resolveEntryLine(lines, snapshot, {
556
- type: "note",
557
- noteUuid: placement.targetNoteUuid
558
- });
559
- }
560
- return resolveEntryLine(lines, snapshot, {
561
- type: "folder",
562
- folderPath: placement.folderPath
563
- });
564
- }
565
- function insertLineAtPlacement(lines, snapshot, placement, buildLine) {
566
- const resolvedPlacement = _nullishCoalesce(placement, () => ( { type: "root", placement: "end" }));
567
- if (resolvedPlacement.type === "root") {
568
- if (resolvedPlacement.placement === "start") {
569
- const firstContent = lines.findIndex((line) => _chunk3R7QSABBcjs.parseTocLine.call(void 0, line).isMatch);
570
- lines.splice(firstContent >= 0 ? firstContent : lines.length, 0, buildLine(0));
571
- } else {
572
- let insertAt = lines.length;
573
- while (insertAt > 0 && lines[insertAt - 1] === "") insertAt--;
574
- lines.splice(insertAt, 0, buildLine(0));
575
- }
576
- return;
577
- }
578
- const targetLine = placementTargetLine(lines, snapshot, resolvedPlacement);
579
- const target = _chunk3R7QSABBcjs.parseTocLine.call(void 0, lines[targetLine]);
580
- if (!target.isMatch) {
581
- throw new WorkspaceError("INVALID_TOC_ENTRY", "\u76EE\u6807 TOC \u6761\u76EE\u65E0\u6548");
582
- }
583
- if (resolvedPlacement.placement === "inside") {
584
- const range = _chunk3R7QSABBcjs.getTocEntrySubtreeRange.call(void 0, lines, targetLine);
585
- lines.splice(range.end, 0, buildLine(target.indentLevel + 1));
586
- } else if (resolvedPlacement.placement === "before") {
587
- lines.splice(targetLine, 0, buildLine(target.indentLevel));
588
- } else {
589
- const range = _chunk3R7QSABBcjs.getTocEntrySubtreeRange.call(void 0, lines, targetLine);
590
- lines.splice(range.end, 0, buildLine(target.indentLevel));
591
- }
592
- }
593
- function adjustIndent(lines, delta) {
594
- return lines.map((line) => {
595
- const parsed = _chunk3R7QSABBcjs.parseTocLine.call(void 0, line);
596
- if (!parsed.isMatch) return line;
597
- const indent = Math.max(0, parsed.indentLevel + delta);
598
- return `${" ".repeat(indent * _chunk3R7QSABBcjs.TOC_INDENT_SPACES)}${line.trimStart()}`;
599
- });
600
- }
601
- async function listFilesRecursively(directoryPath) {
602
- const result = [];
603
- const entries = await _promises2.default.readdir(directoryPath, { withFileTypes: true });
604
- for (const entry of entries) {
605
- const entryPath = _path2.default.join(directoryPath, entry.name);
606
- if (entry.isDirectory()) {
607
- result.push(...await listFilesRecursively(entryPath));
608
- } else {
609
- result.push(entryPath);
610
- }
611
- }
612
- return result;
613
- }
614
- var Workspace = class {
615
- constructor(options) {
616
- this.queue = new MutationQueue();
617
- this.disposed = false;
618
- this.paths = createWorkspacePaths(options.rootPath);
619
- this.logger = _nullishCoalesce(options.logger, () => ( {}));
620
- this.prettierByDefault = _nullishCoalesce(_optionalChain([options, 'access', _3 => _3.format, 'optionalAccess', _4 => _4.prettier]), () => ( true));
621
- this.notes = {
622
- read: (noteUuid) => this.readNote(noteUuid),
623
- save: (input) => this.saveNote(input),
624
- create: (input) => this.createNote(input),
625
- rename: (input) => this.renameNote(input),
626
- updateConfig: (input) => this.updateNoteConfig(input)
627
- };
628
- this.toc = {
629
- move: (input) => this.moveTocEntry(input),
630
- createGroup: (input) => this.createTocGroup(input),
631
- renameGroup: (input) => this.renameTocGroup(input),
632
- previewDelete: (entry) => this.previewDelete(entry),
633
- deleteEntry: (input) => this.deleteTocEntry(input),
634
- setDone: (input) => this.updateNoteConfig(input)
635
- };
636
- this.attachments = {
637
- writeLocal: (input) => this.writeLocalAttachment(input)
638
- };
639
- }
640
- async inspect() {
641
- this.assertActive();
642
- return (await scanWorkspace(this.paths)).snapshot;
643
- }
644
- async refresh() {
645
- return this.inspect();
646
- }
647
- async reconcileTocCompletion() {
648
- return this.queue.run(async () => {
649
- const scanned = await this.scanReady();
650
- const { snapshot, tocText } = scanned;
651
- const config = requireConfig(snapshot);
652
- const lines = (_nullishCoalesce(tocText, () => ( ""))).split("\n");
653
- const completedByIndex = /* @__PURE__ */ new Map();
654
- for (const line of lines) {
655
- const parsed = _chunk3R7QSABBcjs.parseTocLine.call(void 0, line);
656
- if (parsed.noteIndex && !completedByIndex.has(parsed.noteIndex)) {
657
- completedByIndex.set(parsed.noteIndex, parsed.completed);
658
- }
659
- }
660
- const changedFiles = [];
661
- const writes = [];
662
- const updatedNotes = snapshot.notes.map((note) => {
663
- const completed = completedByIndex.get(note.index);
664
- if (completed === void 0 || completed === note.config.done) return note;
665
- const updatedConfig = { ...note.config, done: completed };
666
- writes.push({ path: note.configPath, data: serializeNoteConfig(updatedConfig) });
667
- changedFiles.push({ path: note.configPath, kind: "updated" });
668
- return { ...note, config: updatedConfig };
669
- });
670
- if (writes.length > 0) {
671
- writes.push({
672
- path: this.paths.sidebar,
673
- data: sidebarContent(lines, updatedNotes, config)
674
- });
675
- changedFiles.push({ path: this.paths.sidebar, kind: "updated" });
676
- await writeFilesAtomically(writes);
677
- }
678
- const value = await this.inspect();
679
- return { value, changedFiles, snapshotRevision: value.revision };
680
- });
681
- }
682
- async dispose() {
683
- if (this.disposed) return;
684
- this.disposed = true;
685
- await this.queue.dispose();
686
- }
687
- assertActive() {
688
- if (this.disposed) {
689
- throw new WorkspaceError("WORKSPACE_DISPOSED", "\u5DE5\u4F5C\u533A\u5B9E\u4F8B\u5DF2\u7ECF\u91CA\u653E");
690
- }
691
- }
692
- async scanReady() {
693
- this.assertActive();
694
- const scanned = await scanWorkspace(this.paths);
695
- requireConfig(scanned.snapshot);
696
- return scanned;
697
- }
698
- async readNote(noteUuid) {
699
- const snapshot = await this.inspect();
700
- const note = findNote(snapshot, noteUuid);
701
- return { ...note, content: await _promises2.default.readFile(note.readmePath, "utf8") };
702
- }
703
- async saveNote(input) {
704
- return this.queue.run(async () => {
705
- const { snapshot } = await this.scanReady();
706
- const config = requireConfig(snapshot);
707
- const note = findNote(snapshot, input.noteUuid);
708
- assertRevision(note.revision, input.expectedRevision, "\u7B14\u8BB0");
709
- const formatted = await _chunk5F5RJ2HVcjs.formatTNotesNote.call(void 0, {
710
- content: input.content,
711
- noteIndex: note.index,
712
- title: note.title,
713
- repoOwner: config.author,
714
- repoName: config.repoName,
715
- noteConfig: note.config,
716
- prettier: _nullishCoalesce(input.prettier, () => ( this.prettierByDefault))
717
- });
718
- const current = await _promises2.default.readFile(note.readmePath, "utf8");
719
- const changedFiles = [];
720
- if (formatted.content !== current) {
721
- await writeFilesAtomically([
722
- { path: note.readmePath, data: formatted.content }
723
- ]);
724
- changedFiles.push({ path: note.readmePath, kind: "updated" });
725
- }
726
- const value = await this.readNote(input.noteUuid);
727
- const refreshed = await this.inspect();
728
- return { value, changedFiles, snapshotRevision: refreshed.revision };
729
- });
730
- }
731
- async createNote(input) {
732
- return this.queue.run(async () => {
733
- const { snapshot, tocText } = await this.scanReady();
734
- const config = requireConfig(snapshot);
735
- if (input.expectedSnapshotRevision) {
736
- assertRevision(
737
- snapshot.revision,
738
- input.expectedSnapshotRevision,
739
- "\u77E5\u8BC6\u5E93\u76EE\u5F55"
740
- );
741
- }
742
- const title = validateTitle(input.title);
743
- const index = allocateNoteIndex(snapshot.notes);
744
- const dirName = `${index}. ${title}`;
745
- const directoryPath = _path2.default.join(this.paths.notes, dirName);
746
- assertPathInside(this.paths.notes, directoryPath);
747
- try {
748
- await _promises2.default.mkdir(directoryPath);
749
- } catch (error) {
750
- throw new WorkspaceError("FILESYSTEM_ERROR", "\u65E0\u6CD5\u521B\u5EFA\u7B14\u8BB0\u76EE\u5F55", {
751
- directoryPath,
752
- cause: error instanceof Error ? error.message : String(error)
753
- });
754
- }
755
- const noteConfig = {
756
- bilibili: [],
757
- tnotes: [],
758
- yuque: [],
759
- done: false,
760
- enableDiscussions: _nullishCoalesce(_optionalChain([input, 'access', _5 => _5.config, 'optionalAccess', _6 => _6.enableDiscussions]), () => ( false)),
761
- description: _nullishCoalesce(_optionalChain([input, 'access', _7 => _7.config, 'optionalAccess', _8 => _8.description]), () => ( "")),
762
- id: _crypto.randomUUID.call(void 0, )
763
- };
764
- const readmePath = _path2.default.join(directoryPath, "README.md");
765
- const configPath = _path2.default.join(directoryPath, ".tnotes.json");
766
- const formatted = await _chunk5F5RJ2HVcjs.formatTNotesNote.call(void 0, {
767
- content: _chunk3R7QSABBcjs.getNewNoteReadmeBody.call(void 0, ),
768
- noteIndex: index,
769
- title,
770
- repoOwner: config.author,
771
- repoName: config.repoName,
772
- noteConfig,
773
- prettier: this.prettierByDefault
774
- });
775
- const newNote = {
776
- uuid: noteConfig.id,
777
- index,
778
- title,
779
- dirName,
780
- directoryPath,
781
- readmePath,
782
- configPath,
783
- config: noteConfig,
784
- revision: ""
785
- };
786
- const tocLines = (_nullishCoalesce(tocText, () => ( ""))).split("\n");
787
- insertLineAtPlacement(
788
- tocLines,
789
- snapshot,
790
- input.placement,
791
- (indent) => _chunk3R7QSABBcjs.buildTocLine.call(void 0, toNoteInfo(newNote), indent, false)
792
- );
793
- const updatedNotes = [...snapshot.notes, newNote];
794
- const normalizedToc = normalizeTocContent(tocLines);
795
- const normalizedLines = normalizedToc.split("\n");
796
- try {
797
- await writeFilesAtomically([
798
- { path: readmePath, data: formatted.content },
799
- { path: configPath, data: serializeNoteConfig(noteConfig) },
800
- { path: this.paths.toc, data: normalizedToc },
801
- {
802
- path: this.paths.sidebar,
803
- data: sidebarContent(normalizedLines, updatedNotes, config)
804
- }
805
- ]);
806
- } catch (error) {
807
- await _promises2.default.rm(directoryPath, { recursive: true, force: true });
808
- throw error;
809
- }
810
- const value = await this.readNote(noteConfig.id);
811
- const refreshed = await this.inspect();
812
- return {
813
- value,
814
- changedFiles: [
815
- { path: directoryPath, kind: "created" },
816
- { path: readmePath, kind: "created" },
817
- { path: configPath, kind: "created" },
818
- { path: this.paths.toc, kind: "updated" },
819
- { path: this.paths.sidebar, kind: "updated" }
820
- ],
821
- snapshotRevision: refreshed.revision
822
- };
823
- });
824
- }
825
- async renameNote(input) {
826
- return this.queue.run(async () => {
827
- const { snapshot, tocText } = await this.scanReady();
828
- const config = requireConfig(snapshot);
829
- const note = findNote(snapshot, input.noteUuid);
830
- assertRevision(note.revision, input.expectedRevision, "\u7B14\u8BB0");
831
- const title = validateTitle(input.title);
832
- const newDirName = `${note.index}. ${title}`;
833
- if (newDirName === note.dirName) {
834
- const value2 = await this.readNote(note.uuid);
835
- return { value: value2, changedFiles: [], snapshotRevision: snapshot.revision };
836
- }
837
- const newDirectoryPath = _path2.default.join(this.paths.notes, newDirName);
838
- assertPathInside(this.paths.notes, newDirectoryPath);
839
- try {
840
- await _promises2.default.access(newDirectoryPath);
841
- throw new WorkspaceError("INVALID_TITLE", "\u76EE\u6807\u7B14\u8BB0\u76EE\u5F55\u5DF2\u7ECF\u5B58\u5728", {
842
- newDirectoryPath
843
- });
844
- } catch (error) {
845
- if (error instanceof WorkspaceError) throw error;
846
- }
847
- const currentContent = await _promises2.default.readFile(note.readmePath, "utf8");
848
- const formatted = await _chunk5F5RJ2HVcjs.formatTNotesNote.call(void 0, {
849
- content: currentContent,
850
- noteIndex: note.index,
851
- title,
852
- repoOwner: config.author,
853
- repoName: config.repoName,
854
- noteConfig: note.config,
855
- prettier: this.prettierByDefault
856
- });
857
- const renamedNote = {
858
- ...note,
859
- title,
860
- dirName: newDirName,
861
- directoryPath: newDirectoryPath,
862
- readmePath: _path2.default.join(newDirectoryPath, "README.md"),
863
- configPath: _path2.default.join(newDirectoryPath, ".tnotes.json")
864
- };
865
- const tocLines = (_nullishCoalesce(tocText, () => ( ""))).split("\n");
866
- for (let index = 0; index < tocLines.length; index++) {
867
- const parsed = _chunk3R7QSABBcjs.parseTocLine.call(void 0, tocLines[index]);
868
- if (parsed.noteIndex === note.index) {
869
- tocLines[index] = _chunk3R7QSABBcjs.buildTocLine.call(void 0,
870
- toNoteInfo(renamedNote),
871
- parsed.indentLevel,
872
- parsed.completed
873
- );
874
- }
875
- }
876
- const normalizedToc = normalizeTocContent(tocLines);
877
- const updatedNotes = snapshot.notes.map(
878
- (item) => item.uuid === note.uuid ? renamedNote : item
879
- );
880
- await _promises2.default.rename(note.directoryPath, newDirectoryPath);
881
- try {
882
- await writeFilesAtomically([
883
- { path: renamedNote.readmePath, data: formatted.content },
884
- { path: this.paths.toc, data: normalizedToc },
885
- {
886
- path: this.paths.sidebar,
887
- data: sidebarContent(normalizedToc.split("\n"), updatedNotes, config)
888
- }
889
- ]);
890
- } catch (error) {
891
- await _promises2.default.rename(newDirectoryPath, note.directoryPath);
892
- throw error;
893
- }
894
- const value = await this.readNote(note.uuid);
895
- const refreshed = await this.inspect();
896
- return {
897
- value,
898
- changedFiles: [
899
- {
900
- path: newDirectoryPath,
901
- previousPath: note.directoryPath,
902
- kind: "renamed"
903
- },
904
- { path: renamedNote.readmePath, kind: "updated" },
905
- { path: this.paths.toc, kind: "updated" },
906
- { path: this.paths.sidebar, kind: "updated" }
907
- ],
908
- snapshotRevision: refreshed.revision
909
- };
910
- });
911
- }
912
- async updateNoteConfig(input) {
913
- return this.queue.run(async () => {
914
- const { snapshot, tocText } = await this.scanReady();
915
- const config = requireConfig(snapshot);
916
- const note = findNote(snapshot, input.noteUuid);
917
- assertRevision(note.revision, input.expectedRevision, "\u7B14\u8BB0");
918
- const updatedConfig = { ...note.config, ...input.updates };
919
- const writes = [
920
- { path: note.configPath, data: serializeNoteConfig(updatedConfig) }
921
- ];
922
- const changedFiles = [
923
- { path: note.configPath, kind: "updated" }
924
- ];
925
- if (typeof input.updates.done === "boolean") {
926
- const lines = (_nullishCoalesce(tocText, () => ( ""))).split("\n");
927
- let updated = false;
928
- const tempNote = { ...note, config: updatedConfig };
929
- for (let index = 0; index < lines.length; index++) {
930
- const parsed = _chunk3R7QSABBcjs.parseTocLine.call(void 0, lines[index]);
931
- if (parsed.noteIndex === note.index) {
932
- lines[index] = _chunk3R7QSABBcjs.buildTocLine.call(void 0,
933
- toNoteInfo(tempNote),
934
- parsed.indentLevel,
935
- input.updates.done
936
- );
937
- updated = true;
938
- }
939
- }
940
- if (updated) {
941
- const normalizedToc = normalizeTocContent(lines);
942
- const updatedNotes = snapshot.notes.map(
943
- (item) => item.uuid === note.uuid ? tempNote : item
944
- );
945
- writes.push(
946
- { path: this.paths.toc, data: normalizedToc },
947
- {
948
- path: this.paths.sidebar,
949
- data: sidebarContent(normalizedToc.split("\n"), updatedNotes, config)
950
- }
951
- );
952
- changedFiles.push(
953
- { path: this.paths.toc, kind: "updated" },
954
- { path: this.paths.sidebar, kind: "updated" }
955
- );
956
- }
957
- }
958
- await writeFilesAtomically(writes);
959
- const value = await this.readNote(note.uuid);
960
- const refreshed = await this.inspect();
961
- return { value, changedFiles, snapshotRevision: refreshed.revision };
962
- });
963
- }
964
- async moveTocEntry(input) {
965
- return this.queue.run(async () => {
966
- const { snapshot, tocText } = await this.scanReady();
967
- const config = requireConfig(snapshot);
968
- assertRevision(snapshot.revision, input.expectedSnapshotRevision, "\u77E5\u8BC6\u5E93\u76EE\u5F55");
969
- const lines = (_nullishCoalesce(tocText, () => ( ""))).split("\n");
970
- const sourceLine = resolveEntryLine(lines, snapshot, input.source);
971
- const targetLine = resolveEntryLine(lines, snapshot, input.target);
972
- const sourceRange = _chunk3R7QSABBcjs.getTocEntrySubtreeRange.call(void 0, lines, sourceLine);
973
- if (targetLine >= sourceRange.start && targetLine < sourceRange.end) {
974
- throw new WorkspaceError(
975
- "INVALID_TOC_ENTRY",
976
- "\u4E0D\u80FD\u628A\u76EE\u5F55\u6761\u76EE\u79FB\u52A8\u5230\u81EA\u8EAB\u6216\u81EA\u8EAB\u5B50\u6811\u5185"
977
- );
978
- }
979
- const moving = lines.splice(
980
- sourceRange.start,
981
- sourceRange.end - sourceRange.start
982
- );
983
- const adjustedTarget = _chunk3R7QSABBcjs.adjustTocLineIndexAfterSubtreeRemoval.call(void 0,
984
- targetLine,
985
- sourceRange.start,
986
- sourceRange.end
987
- );
988
- const target = _chunk3R7QSABBcjs.parseTocLine.call(void 0, lines[adjustedTarget]);
989
- if (!target.isMatch) {
990
- throw new WorkspaceError("INVALID_TOC_ENTRY", "\u79FB\u52A8\u76EE\u6807\u65E0\u6548");
991
- }
992
- let insertAt;
993
- let indent;
994
- if (input.placement === "inside") {
995
- insertAt = _chunk3R7QSABBcjs.getTocEntrySubtreeRange.call(void 0, lines, adjustedTarget).end;
996
- indent = target.indentLevel + 1;
997
- } else if (input.placement === "before") {
998
- insertAt = adjustedTarget;
999
- indent = target.indentLevel;
1000
- } else {
1001
- insertAt = _chunk3R7QSABBcjs.getTocEntrySubtreeRange.call(void 0, lines, adjustedTarget).end;
1002
- indent = target.indentLevel;
1003
- }
1004
- const oldIndent = _chunk3R7QSABBcjs.parseTocLine.call(void 0, moving[0]).indentLevel;
1005
- lines.splice(insertAt, 0, ...adjustIndent(moving, indent - oldIndent));
1006
- const normalizedToc = normalizeTocContent(lines);
1007
- await writeFilesAtomically([
1008
- { path: this.paths.toc, data: normalizedToc },
1009
- {
1010
- path: this.paths.sidebar,
1011
- data: sidebarContent(normalizedToc.split("\n"), snapshot.notes, config)
1012
- }
1013
- ]);
1014
- const value = await this.inspect();
1015
- return {
1016
- value,
1017
- changedFiles: [
1018
- { path: this.paths.toc, kind: "updated" },
1019
- { path: this.paths.sidebar, kind: "updated" }
1020
- ],
1021
- snapshotRevision: value.revision
1022
- };
1023
- });
1024
- }
1025
- async createTocGroup(input) {
1026
- return this.queue.run(async () => {
1027
- const { snapshot, tocText } = await this.scanReady();
1028
- const config = requireConfig(snapshot);
1029
- assertRevision(snapshot.revision, input.expectedSnapshotRevision, "\u77E5\u8BC6\u5E93\u76EE\u5F55");
1030
- const title = validateTitle(input.title);
1031
- const lines = (_nullishCoalesce(tocText, () => ( ""))).split("\n");
1032
- insertLineAtPlacement(
1033
- lines,
1034
- snapshot,
1035
- input.placement,
1036
- (indent) => _chunk3R7QSABBcjs.buildFolderTocLine.call(void 0, title, indent)
1037
- );
1038
- const normalizedToc = normalizeTocContent(lines);
1039
- await writeFilesAtomically([
1040
- { path: this.paths.toc, data: normalizedToc },
1041
- {
1042
- path: this.paths.sidebar,
1043
- data: sidebarContent(normalizedToc.split("\n"), snapshot.notes, config)
1044
- }
1045
- ]);
1046
- const value = await this.inspect();
1047
- return {
1048
- value,
1049
- changedFiles: [
1050
- { path: this.paths.toc, kind: "updated" },
1051
- { path: this.paths.sidebar, kind: "updated" }
1052
- ],
1053
- snapshotRevision: value.revision
1054
- };
1055
- });
1056
- }
1057
- async renameTocGroup(input) {
1058
- return this.queue.run(async () => {
1059
- const { snapshot, tocText } = await this.scanReady();
1060
- const config = requireConfig(snapshot);
1061
- assertRevision(snapshot.revision, input.expectedSnapshotRevision, "\u77E5\u8BC6\u5E93\u76EE\u5F55");
1062
- const lines = (_nullishCoalesce(tocText, () => ( ""))).split("\n");
1063
- const lineIndex = resolveEntryLine(lines, snapshot, {
1064
- type: "folder",
1065
- folderPath: input.folderPath
1066
- });
1067
- const updatedLines = _chunk3R7QSABBcjs.renameFolderLine.call(void 0, lines, lineIndex, validateTitle(input.title));
1068
- const normalizedToc = normalizeTocContent(updatedLines);
1069
- await writeFilesAtomically([
1070
- { path: this.paths.toc, data: normalizedToc },
1071
- {
1072
- path: this.paths.sidebar,
1073
- data: sidebarContent(normalizedToc.split("\n"), snapshot.notes, config)
1074
- }
1075
- ]);
1076
- const value = await this.inspect();
1077
- return {
1078
- value,
1079
- changedFiles: [
1080
- { path: this.paths.toc, kind: "updated" },
1081
- { path: this.paths.sidebar, kind: "updated" }
1082
- ],
1083
- snapshotRevision: value.revision
1084
- };
1085
- });
1086
- }
1087
- async previewDelete(entry) {
1088
- const { snapshot, tocText } = await this.scanReady();
1089
- const lines = (_nullishCoalesce(tocText, () => ( ""))).split("\n");
1090
- const lineIndex = resolveEntryLine(lines, snapshot, entry);
1091
- const indexes = _chunk3R7QSABBcjs.collectNoteIndexesInSubtree.call(void 0, lines, lineIndex);
1092
- const notes = indexes.map((index) => snapshot.notes.find((note) => note.index === index)).filter((note) => Boolean(note));
1093
- const filePaths = (await Promise.all(notes.map((note) => listFilesRecursively(note.directoryPath)))).flat();
1094
- return {
1095
- entry,
1096
- notes: notes.map((note) => ({
1097
- noteUuid: note.uuid,
1098
- index: note.index,
1099
- title: note.title,
1100
- directoryPath: note.directoryPath
1101
- })),
1102
- filePaths,
1103
- directoryPaths: notes.map((note) => note.directoryPath),
1104
- snapshotRevision: snapshot.revision
1105
- };
1106
- }
1107
- async deleteTocEntry(input) {
1108
- return this.queue.run(async () => {
1109
- const { snapshot, tocText } = await this.scanReady();
1110
- const config = requireConfig(snapshot);
1111
- assertRevision(snapshot.revision, input.expectedSnapshotRevision, "\u77E5\u8BC6\u5E93\u76EE\u5F55");
1112
- const lines = (_nullishCoalesce(tocText, () => ( ""))).split("\n");
1113
- const lineIndex = resolveEntryLine(lines, snapshot, input.entry);
1114
- const range = _chunk3R7QSABBcjs.getTocEntrySubtreeRange.call(void 0, lines, lineIndex);
1115
- const indexes = _chunk3R7QSABBcjs.collectNoteIndexesInSubtree.call(void 0, lines, lineIndex);
1116
- const notes = indexes.map((index) => snapshot.notes.find((note) => note.index === index)).filter((note) => Boolean(note));
1117
- lines.splice(range.start, range.end - range.start);
1118
- const remainingNotes = snapshot.notes.filter(
1119
- (note) => !indexes.includes(note.index)
1120
- );
1121
- const normalizedToc = normalizeTocContent(lines);
1122
- const movedDirectories = [];
1123
- try {
1124
- for (const note of notes) {
1125
- const temporary = _path2.default.join(
1126
- this.paths.notes,
1127
- `.${_path2.default.basename(note.directoryPath)}.desk-delete-${_crypto.randomUUID.call(void 0, )}`
1128
- );
1129
- await _promises2.default.rename(note.directoryPath, temporary);
1130
- movedDirectories.push({ original: note.directoryPath, temporary });
1131
- }
1132
- await writeFilesAtomically([
1133
- { path: this.paths.toc, data: normalizedToc },
1134
- {
1135
- path: this.paths.sidebar,
1136
- data: sidebarContent(normalizedToc.split("\n"), remainingNotes, config)
1137
- }
1138
- ]);
1139
- } catch (error) {
1140
- for (const moved of movedDirectories.reverse()) {
1141
- await _promises2.default.rename(moved.temporary, moved.original);
1142
- }
1143
- throw error;
1144
- }
1145
- for (const moved of movedDirectories) {
1146
- await _promises2.default.rm(moved.temporary, { recursive: true, force: true });
1147
- }
1148
- const value = await this.inspect();
1149
- return {
1150
- value,
1151
- changedFiles: [
1152
- ...notes.map((note) => ({
1153
- path: note.directoryPath,
1154
- kind: "deleted"
1155
- })),
1156
- { path: this.paths.toc, kind: "updated" },
1157
- { path: this.paths.sidebar, kind: "updated" }
1158
- ],
1159
- snapshotRevision: value.revision
1160
- };
1161
- });
1162
- }
1163
- async writeLocalAttachment(input) {
1164
- return this.queue.run(async () => {
1165
- const { snapshot } = await this.scanReady();
1166
- const note = findNote(snapshot, input.noteUuid);
1167
- const assetsPath = _path2.default.join(note.directoryPath, "assets");
1168
- assertPathInside(note.directoryPath, assetsPath);
1169
- const requestedName = sanitizeFileName(input.fileName);
1170
- const extension = _path2.default.extname(requestedName);
1171
- const base = _path2.default.basename(requestedName, extension);
1172
- let candidate = requestedName;
1173
- let suffix = 1;
1174
- while (true) {
1175
- try {
1176
- await _promises2.default.access(_path2.default.join(assetsPath, candidate));
1177
- candidate = `${base}-${suffix}${extension}`;
1178
- suffix++;
1179
- } catch (e6) {
1180
- break;
1181
- }
1182
- }
1183
- const absolutePath = _path2.default.join(assetsPath, candidate);
1184
- assertPathInside(assetsPath, absolutePath);
1185
- await writeFilesAtomically([{ path: absolutePath, data: input.data }]);
1186
- const value = {
1187
- absolutePath,
1188
- markdownPath: `./assets/${candidate}`
1189
- };
1190
- const refreshed = await this.inspect();
1191
- return {
1192
- value,
1193
- changedFiles: [{ path: absolutePath, kind: "created" }],
1194
- snapshotRevision: refreshed.revision
1195
- };
1196
- });
1197
- }
1198
- };
1199
-
1200
- // workspace/index.ts
1201
- function createWorkspace(options) {
1202
- return new Workspace(options);
1203
- }
1204
-
1205
-
1206
-
1207
- exports.WorkspaceError = WorkspaceError; exports.createWorkspace = createWorkspace;
9
+ exports.WorkspaceError = _chunkAGVER5MXcjs.WorkspaceError; exports.createWorkspace = _chunkAGVER5MXcjs.createWorkspace;