const express = require('express'); const router = express.Router(); const fs = require('fs'); const path = require('path'); const { v4: uuidv4 } = require('uuid'); // Import export module const exportRouter = require('./export'); function modifMd(id, modifications) { if (id === undefined) throw new Error('id required'); if (!Array.isArray(modifications) || modifications.length === 0) throw new Error('modifications required'); const dataDir = path.resolve(__dirname, '../data'); const mapPath = path.join(dataDir, 'uuid_map.json'); if (!fs.existsSync(mapPath)) throw new Error('uuid_map.json does not exist'); const map = JSON.parse(fs.readFileSync(mapPath, 'utf8')); const uuid = map[id]; if (!uuid) throw new Error(`No file for id ${id}`); const mdPath = path.join(dataDir, `${uuid}.md`); if (!fs.existsSync(mdPath)) throw new Error('Markdown file does not exist'); let lignes = fs.readFileSync(mdPath, 'utf8').split('\n'); modifications = modifications.slice().sort((a, b) => a.debut - b.debut); let offset = 0; for (let m of modifications) { let debut = m.debut + offset; let fin = m.fin + offset; const remplacement = Array.isArray(m.contenu) ? m.contenu : m.contenu.split('\n'); if (debut < 0 || fin >= lignes.length || debut > fin) throw new Error('Invalid range (start/end) for a modification'); const avant = lignes.slice(0, debut); const apres = lignes.slice(fin + 1); lignes = [...avant, ...remplacement, ...apres]; offset += remplacement.length - (fin - debut + 1); } const nouveau = lignes.join('\n'); fs.writeFileSync(mdPath, nouveau, { encoding: 'utf8', flag: 'w' }); return { id, uuid, path: mdPath, modifications }; } function createMd(markdownContent = "# Title\nContent...") { const uuid = uuidv4(); const dataDir = path.resolve(__dirname, '../data'); const mdPath = path.join(dataDir, `${uuid}.md`); const mapPath = path.join(dataDir, 'uuid_map.json'); fs.writeFileSync(mdPath, markdownContent, { encoding: 'utf8', flag: 'w' }); let map = {}; if (fs.existsSync(mapPath)) { map = JSON.parse(fs.readFileSync(mapPath, 'utf8')); } let id = Object.keys(map).at(-1); if (id == undefined){ map[0] = uuid; } else { id = +id+1 map[id] = uuid; } fs.writeFileSync(mapPath, JSON.stringify(map, null, 2), 'utf8'); return { id, uuid, path: mdPath, markdownContent}; } function readMd(id = undefined) { const dataDir = path.resolve(__dirname, '../data'); const mapPath = path.join(dataDir, 'uuid_map.json'); let map = {}; if (fs.existsSync(mapPath)) { map = JSON.parse(fs.readFileSync(mapPath, 'utf8')); } if (id !== undefined) { const uuid = map[id]; if (!uuid) { throw new Error(`No file found for id ${id}`); } const mdPath = path.join(dataDir, `${uuid}.md`); if (!fs.existsSync(mdPath)) { throw new Error(`File ${mdPath} does not exist`); } const markdownContent = fs.readFileSync(mdPath, 'utf8'); return [{ id, uuid, path: mdPath, markdownContent }]; } else { const results = []; for (const [curId, uuid] of Object.entries(map)) { const mdPath = path.join(dataDir, `${uuid}.md`); if (fs.existsSync(mdPath)) { const markdownContent = fs.readFileSync(mdPath, 'utf8'); results.push({ id: curId, uuid, path: mdPath, markdownContent }); } } return results; } } function updateMd(id, newMarkdownContent) { if (id === undefined) throw new Error('id required'); const dataDir = path.resolve(__dirname, '../data'); const mapPath = path.join(dataDir, 'uuid_map.json'); if (!fs.existsSync(mapPath)) throw new Error('uuid_map.json does not exist'); let map = JSON.parse(fs.readFileSync(mapPath, 'utf8')); const uuid = map[id]; if (!uuid) throw new Error(`No file found for id ${id}`); const mdPath = path.join(dataDir, `${uuid}.md`); if (!fs.existsSync(mdPath)) throw new Error('Markdown file does not exist'); fs.writeFileSync(mdPath, newMarkdownContent, { encoding: 'utf8', flag: 'w' }); return { id, uuid, path: mdPath, newMarkdownContent }; } function deteMd(id) { if (id === undefined) throw new Error('id required'); const dataDir = path.resolve(__dirname, '../data'); const mapPath = path.join(dataDir, 'uuid_map.json'); if (!fs.existsSync(mapPath)) throw new Error('uuid_map.json does not exist'); let map = JSON.parse(fs.readFileSync(mapPath, 'utf8')); const uuid = map[id]; if (!uuid) throw new Error(`No file found for id ${id}`); const mdPath = path.join(dataDir, `${uuid}.md`); if (fs.existsSync(mdPath)) fs.unlinkSync(mdPath); delete map[id]; fs.writeFileSync(mapPath, JSON.stringify(map, null, 2), 'utf8'); return { id, deleted: true }; } // GET /api/journals - Get all journals router.get('/journals', (req, res) => { res.json({ success: true, data: readMd() }); }); // POST /api/journals - Create a new journal router.post('/journals', (req, res) => { const { content } = req.body; res.status(201).json({ success: true, data: createMd(content) }); }); // GET /api/journals/:id - Get a specific journal router.get('/journals/:id', (req, res) => { const { id } = req.params; res.json({ success: true, data: readMd(id) }); }); // PUT /api/journals/:id - Update a journal router.put('/journals/:id', (req, res) => { const { id } = req.params; const { content, modifications } = req.body; try { let result; if (content) { // Complete content update result = updateMd(id, content); } else if (modifications) { // Partial modifications (for future compatibility) result = modifMd(id, modifications); } else { return res.status(400).json({ success: false, error: 'Content or modifications required' }); } res.json({ success: true, data: result }); } catch (error) { res.status(500).json({ success: false, error: error.message }); } }); // DELETE /api/journals/:id - Delete a journal router.delete('/journals/:id', (req, res) => { const { id } = req.params; res.json({ success: true, data: deteMd(id) }); }); // Integrate export routes router.use('/export', exportRouter); module.exports = router;