Muyue aa0a3863b6 Refactor: Complete internationalization and modernization to v2.0.0
Major Changes:
  - Remove all emojis from UI, code, and documentation for professional appearance
  - Translate entire codebase from French to English (code, comments, strings, UI)
  - Simplify template system: 18 templates → single default template
  - Rename "Mode Liberté Total" to "Enhanced Mode" throughout
  - Add comprehensive English README with installation and usage guides
  - Add MIT License (open source, no attribution required)
  - Update package.json with proper metadata and keywords

  Breaking Changes:
  - Template API endpoint changed from /api/templates/:domain/:level to /api/templates/default
  - All French UI text and notifications replaced with English
  - Template directory structure simplified

  Technical Improvements:
  - Cleaner, more maintainable codebase
  - Improved internationalization
  - Better developer experience with English documentation
  - Professional appearance suitable for production use
2025-10-14 15:05:39 +02:00

214 lines
6.2 KiB
JavaScript

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;