UNPKG

yml-mvc-router

Version:

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

91 lines (82 loc) 2.93 kB
const yaml = require('js-yaml'); /** * Parses YAML routes file into normalized route objects */ class Parser { constructor(config) { this.config = config; } /** * Parse YAML content into route definitions * @param {string} yamlContent - Raw YAML content * @returns {Array} Array of normalized route objects */ parse(yamlContent) { const parsed = yaml.load(yamlContent); if (!parsed || typeof parsed !== 'object') { throw new Error('Invalid YAML: must contain route definitions'); } const routes = []; this._processRoutes(parsed, routes); return routes; } /** * Process route definitions recursively (handles groups) * @param {Object} routesDef - Route definitions from YAML * @param {Array} routes - Output array to populate * @param {string} prefix - Current route prefix * @param {Array} middlewares - Inherited middlewares */ _processRoutes(routesDef, routes, prefix = '', middlewares = []) { for (const [pattern, definition] of Object.entries(routesDef)) { if (definition.children) { // Handle route groups const groupPrefix = prefix + (definition.prefix || pattern); const groupMiddlewares = [...middlewares, ...(definition.middlewares || [])]; this._processRoutes(definition.children, routes, groupPrefix, groupMiddlewares); } else { // Handle individual routes const route = this._normalizeRoute(pattern, definition, prefix, middlewares); routes.push(route); } } } /** * Normalize a single route definition * @param {string} pattern - Route pattern * @param {Object} definition - Route definition * @param {string} prefix - Route prefix * @param {Array} inheritedMiddlewares - Inherited middlewares * @returns {Object} Normalized route object */ _normalizeRoute(pattern, definition, prefix = '', inheritedMiddlewares = []) { if (typeof definition === 'string') { // Simple string format: "/path": "ControllerName.action" definition = { controller: definition }; } const fullPath = prefix + pattern; const method = (definition.method || 'GET').toUpperCase(); const middlewares = [...inheritedMiddlewares, ...(definition.middlewares || [])]; // Parse controller.action let controllerName, actionName; if (definition.controller) { const parts = definition.controller.split('.'); controllerName = parts[0]; actionName = parts[1] || 'index'; } else { throw new Error(`Route ${fullPath} missing controller definition`); } return { path: fullPath, method, controller: controllerName, action: actionName, middlewares, assets: definition.assets || {}, name: definition.name, response: definition.response, // 'json' | 'view' | undefined (auto-detect) raw: definition }; } } module.exports = Parser;