/* ! /server/routers.js ? Dynamic Express router loader matching the action loader pattern. */ // % imports import fs from 'fs'; import path from 'path'; import { fileURLToPath, pathToFileURL } from 'url'; import express from 'express'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); // % Target directory where the actual route files reside const routersDir = path.join(__dirname, '..', 'routers'); // $ debug-output console.info('[Paths] Routers:', routersDir); export const registeredEndpoints = []; // $ recursive function to load routers and extract clean endpoints async function loadRouters(dir = routersDir, baseDir = routersDir, currentPrefix = '') { let mainRouter = express.Router(); const entries = fs.readdirSync(dir, { withFileTypes: true }); for (const entry of entries) { const fullPath = path.join(dir, entry.name); if (entry.isDirectory()) { // ~ handle subdirectory and extend prefix const subPrefix = `${currentPrefix}/${entry.name}`; const subRouter = await loadRouters(fullPath, baseDir, subPrefix); mainRouter.use(`/${entry.name}`, subRouter); } else if (entry.isFile() && entry.name !== 'index.js' && !entry.name.startsWith('.') && entry.name.endsWith('.js')) { const fileUrl = pathToFileURL(fullPath).href; const module = await import(fileUrl); const routeHandler = module.default || module; const routeName = entry.name.replace(/\.js$/, ''); const subRouter = express.Router(); // ~ pass subrouter into the handler function if (typeof routeHandler === 'function') { await routeHandler(subRouter); } const finalFolderPrefix = currentPrefix === '' ? '' : currentPrefix; const endpointPath = routeName === 'root' ? finalFolderPrefix || '/' : `${finalFolderPrefix}/${routeName}`; // ~ extract methods and paths directly from the sub-router stack subRouter.stack.forEach(layer => { if (layer.route) { const methods = Object.keys(layer.route.methods).join(', ').toUpperCase(); const subRoutePath = layer.route.path === '/' ? '' : layer.route.path; registeredEndpoints.push(`${methods} ${endpointPath}${subRoutePath}`.replace(/\/+/g, '/')); } }); if (routeName === 'root') { mainRouter.use('/', subRouter); } else { mainRouter.use(`/${routeName}`, subRouter); } } } return mainRouter; } // $ Initialize asynchronously and export the loaded routers object const routers = await loadRouters(); // $ export export default routers;