UNPKG

@kitmi/jacaranda

Version:

JavaScript application framework

128 lines (107 loc) 3.82 kB
import { url as urlUtil, naming, text, eachAsync_, batchAsync_, get as _get } from '@kitmi/utils'; import { InvalidConfiguration } from '@kitmi/types'; import { supportedMethods } from '../helpers'; import { loadController_ } from '../helpers/loadModuleFrom_'; /** * Module router for mounting a specific controller. * @module Router_Module */ /** * Create a module-based router. * @param {Routable} app * @param {string} baseRoute * @param {*} options * @example * '<base path>': { * module: { * $controllerPath: * $middlewares: * $urlDasherize: false * '/': [ 'controller', ... ] * } * } * * '<base path>': { * module: "controller" * } */ async function moduleRouter(app, baseRoute, options) { if (typeof options === 'string') { // [ 'controllerName' ] options = { '/': [options], }; } let controllerPath = options.$controllerPath ?? 'modules'; const kebabify = options.$urlDasherize; let router = app.router.createRouter(baseRoute); if (options.$middlewares) { //module-wide middlewares await app.useMiddlewares_(router, options.$middlewares); } await eachAsync_(options, async (controllers, subBaseRoute) => { if (subBaseRoute[0] === '$') { return; } if (!Array.isArray(controllers)) { controllers = [controllers]; } await batchAsync_(controllers, async (moduleController) => { let controller = await loadController_( app, options.$source, controllerPath, moduleController, options.$packageName ); if (controller == null) { throw new InvalidConfiguration( `Module controller "${moduleController}" not found.`, app, `routing.${baseRoute}.module[${subBaseRoute}]` ); } let isController = false; if (typeof controller === 'function') { controller = new controller(app); isController = true; } for (let actionName in controller) { let action = controller[actionName]; if (typeof action !== 'function' || !action.__metaHttpMethod) continue; // only marked httpMethod should be mounted const method = action.__metaHttpMethod; const subRoute = text.ensureStartsWith( urlUtil.join( subBaseRoute, text.dropIfStartsWith( action.__metaRoute || (kebabify ? naming.kebabCase(actionName) : actionName), '/' ) ), '/' ); let bindAction; if (isController) { bindAction = action.bind(controller); } else { bindAction = action; } if (!supportedMethods.has(method)) { throw new InvalidConfiguration( 'Unsupported http method: ' + method, app, `routing[${baseRoute}].module.subBaseRoute[${moduleController}.${actionName}]` ); } await app.addRoute_( router, method, subRoute, action.__metaMiddlewares ? action.__metaMiddlewares.concat([bindAction]) : bindAction ); } }); }); app.addRouter(router); } export default moduleRouter;