UNPKG

yml-mvc-router

Version:

A configurable, Express-compatible routing module that maps routes from YAML to controllers following the MVC pattern

106 lines (90 loc) 3.02 kB
const express = require('express'); const path = require('path'); const fs = require('fs'); const yaml = require('js-yaml'); const chokidar = require('chokidar'); const Parser = require('./parser'); const Builder = require('./builder'); const Resolver = require('./resolver'); const Executor = require('./executor'); const Assets = require('./assets'); const Inspector = require('./inspector'); /** * Creates yml-mvc-router middleware * @param {Object} options - Configuration options * @returns {Function} Express middleware function */ function ymlRouter(options = {}) { const config = { routes: './routes/routes.yml', controllers: './controllers', middlewares: './middlewares', views: './views', assets: './public', engine: 'ejs', watch: process.env.NODE_ENV !== 'production', devInspector: process.env.NODE_ENV !== 'production', controllerExt: ['.js'], resolveController: null, plugins: [], ...options }; // Resolve absolute paths config.routes = path.resolve(config.routes); config.controllers = path.resolve(config.controllers); config.middlewares = path.resolve(config.middlewares); config.views = path.resolve(config.views); config.assets = path.resolve(config.assets); const parser = new Parser(config); const resolver = new Resolver(config); const executor = new Executor(config); const assets = new Assets(config); const inspector = new Inspector(config); let router = express.Router(); let routesMeta = []; // Load and build routes initially function buildRoutes() { try { if (!fs.existsSync(config.routes)) { throw new Error(`Routes file not found: ${config.routes}`); } const yamlContent = fs.readFileSync(config.routes, 'utf8'); const parsedRoutes = parser.parse(yamlContent); const builder = new Builder(config, resolver, executor, assets); const result = builder.build(parsedRoutes); router = result.router; routesMeta = result.meta; } catch (error) { throw error; } } // Initial build buildRoutes(); // Watch for changes in development if (config.watch) { const watcher = chokidar.watch(config.routes); watcher.on('change', () => { console.log('[yml-mvc-router] Routes file changed, reloading...'); try { buildRoutes(); console.log('[yml-mvc-router] Routes reloaded successfully'); } catch (error) { console.error('[yml-mvc-router] Failed to reload routes:', error.message); } }); } // Main middleware function function middleware(req, res, next) { // Add dev inspector route if (config.devInspector && req.path === '/routes' && req.method === 'GET') { return inspector.handle(req, res, routesMeta); } // Execute router router(req, res, next); } // Attach metadata for debugging middleware.getMeta = () => routesMeta; middleware.getConfig = () => config; return middleware; } module.exports = ymlRouter;