From b713be161431729305701f80b3b6f53d2f07f62a Mon Sep 17 00:00:00 2001 From: ertopogo Date: Fri, 20 Feb 2026 19:36:00 +0100 Subject: Initial commit: schemas infrastructure Arauco avec serveur web --- server/server.js | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 server/server.js (limited to 'server/server.js') diff --git a/server/server.js b/server/server.js new file mode 100644 index 0000000..cc685d1 --- /dev/null +++ b/server/server.js @@ -0,0 +1,94 @@ +const express = require('express'); +const path = require('path'); +const fs = require('fs'); +const { WebSocketServer } = require('ws'); +const chokidar = require('chokidar'); + +const PORT = process.env.PORT || 3030; +const SCHEMAS_ROOT = path.resolve(__dirname, '..'); + +const app = express(); +app.use(express.static(path.join(__dirname, 'public'))); + +function scanSchemas() { + const schemas = []; + + function walk(dir, category) { + if (!fs.existsSync(dir)) return; + for (const file of fs.readdirSync(dir)) { + const fullPath = path.join(dir, file); + if (fs.statSync(fullPath).isDirectory()) { + walk(fullPath, file); + } else if (file.endsWith('.mmd')) { + const relativePath = path.relative(SCHEMAS_ROOT, fullPath).replace(/\\/g, '/'); + schemas.push({ + name: file.replace('.mmd', ''), + category: category || 'root', + path: relativePath, + fullPath + }); + } + } + } + + walk(path.join(SCHEMAS_ROOT, 'macro'), 'macro'); + walk(path.join(SCHEMAS_ROOT, 'micro'), null); + return schemas; +} + +app.get('/api/schemas', (req, res) => { + const schemas = scanSchemas(); + const grouped = {}; + for (const s of schemas) { + if (!grouped[s.category]) grouped[s.category] = []; + grouped[s.category].push({ name: s.name, path: s.path }); + } + res.json(grouped); +}); + +app.get('/api/schema/:encodedPath', (req, res) => { + const schemaPath = decodeURIComponent(req.params.encodedPath); + const fullPath = path.join(SCHEMAS_ROOT, schemaPath); + const resolved = path.resolve(fullPath); + + if (!resolved.startsWith(SCHEMAS_ROOT)) { + return res.status(403).json({ error: 'Acces interdit' }); + } + if (!fs.existsSync(resolved)) { + return res.status(404).json({ error: 'Schema introuvable' }); + } + + const content = fs.readFileSync(resolved, 'utf-8'); + res.json({ path: schemaPath, content }); +}); + +const server = app.listen(PORT, () => { + console.log(`\n Araucaria Schemas Viewer`); + console.log(` -> http://localhost:${PORT}\n`); + console.log(` Schemas root: ${SCHEMAS_ROOT}`); + console.log(` Watching for .mmd changes...\n`); +}); + +const wss = new WebSocketServer({ server }); + +const watcher = chokidar.watch( + [path.join(SCHEMAS_ROOT, 'macro'), path.join(SCHEMAS_ROOT, 'micro')], + { ignoreInitial: true, persistent: true } +); + +watcher.on('all', (event, filePath) => { + if (!filePath.endsWith('.mmd')) return; + const relativePath = path.relative(SCHEMAS_ROOT, filePath).replace(/\\/g, '/'); + console.log(` [${event}] ${relativePath}`); + + const message = JSON.stringify({ type: 'reload', event, path: relativePath }); + for (const client of wss.clients) { + if (client.readyState === 1) client.send(message); + } +}); + +process.on('SIGINT', () => { + watcher.close(); + server.close(); + process.exit(0); +}); -- cgit v1.2.3