-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwatcher.js
More file actions
94 lines (84 loc) · 2.57 KB
/
watcher.js
File metadata and controls
94 lines (84 loc) · 2.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
const chokidar = require('chokidar');
const fs = require('fs');
const path = require('path');
const POSTS_DIR = path.join(__dirname, 'blog', 'posts');
const POSTS_JSON = path.join(__dirname, 'blog', 'posts.json');
function parseMeta(md) {
let meta = {};
if (md.startsWith('---')) {
const end = md.indexOf('---', 3);
if (end !== -1) {
const metaBlock = md.slice(3, end).trim();
metaBlock.split(/\r?\n/).forEach(line => {
const [k, ...rest] = line.split(':');
if (k && rest.length) meta[k.trim()] = rest.join(':').trim();
});
}
} else if (md.startsWith('title:')) {
const lines = md.split(/\r?\n/);
let metaLines = [];
let i = 0;
for (; i < lines.length; i++) {
if (!lines[i].trim()) break;
metaLines.push(lines[i]);
}
metaLines.forEach(line => {
const [k, ...rest] = line.split(':');
if (k && rest.length) meta[k.trim()] = rest.join(':').trim();
});
}
return meta;
}
function loadPostsJson() {
if (!fs.existsSync(POSTS_JSON)) return [];
try {
return JSON.parse(fs.readFileSync(POSTS_JSON, 'utf8'));
} catch (e) {
return [];
}
}
function savePostsJson(posts) {
fs.writeFileSync(POSTS_JSON, JSON.stringify(posts, null, 2));
}
function updatePostEntry(file) {
const posts = loadPostsJson();
const fileName = path.basename(file);
if (!fs.existsSync(file)) {
// Remove entry if file deleted
const newPosts = posts.filter(p => p.file !== fileName);
savePostsJson(newPosts);
console.log(`[watcher] Removed ${fileName} from posts.json`);
return;
}
// Add or update entry
const md = fs.readFileSync(file, 'utf8');
const meta = parseMeta(md);
let found = false;
const newPosts = posts.map(p => {
if (p.file === fileName) {
found = true;
return { file: fileName, meta };
}
return p;
});
if (!found) newPosts.push({ file: fileName, meta });
savePostsJson(newPosts);
console.log(`[watcher] Updated ${fileName} in posts.json`);
}
function resyncAll() {
const files = fs.readdirSync(POSTS_DIR).filter(f => f.endsWith('.md'));
const posts = files.map(f => {
const md = fs.readFileSync(path.join(POSTS_DIR, f), 'utf8');
return { file: f, meta: parseMeta(md) };
});
savePostsJson(posts);
console.log('[watcher] Resynced all posts.');
}
// Initial sync
resyncAll();
const watcher = chokidar.watch(path.join(POSTS_DIR, '*.md'), { ignoreInitial: true });
watcher
.on('add', updatePostEntry)
.on('change', updatePostEntry)
.on('unlink', updatePostEntry);
console.log('[watcher] Watching for changes in blog/posts/*.md');