UNPKG

astroboy

Version:

Astroboy(阿童木)is a Nodejs SFB(Separation of Front and Back ends) framework, built on koa2.

146 lines 5.75 kB
"use strict"; const glob = require("fast-glob"); const http_1 = require("http"); const lodash = require("lodash"); const Loader_1 = require("../core/Loader"); const Ajv = require('ajv'); const ajv = new Ajv({ coerceTypes: true, }); function check(data) { return Object.prototype.toString.call(data) === '[object Object]' && Object.keys(data).length > 0; } /** * 加载所有路由文件 */ async function loadRouters(rootPath, pattern) { let routerArr = []; try { // 如果通过 ts-node 启动会 resolve index.ts const indexFile = require.resolve(`${rootPath}/app/routers/index`); const content = require(indexFile); if (Array.isArray(content)) { routerArr = content; } } catch (_err) { const entries = await glob([`${rootPath}${pattern}`], { dot: true, }); entries.forEach(entry => { routerArr = routerArr.concat(require(entry)); }); } return routerArr; } /** * 解析老的路由写法 */ function parseOldRouter(router) { // 如果第一个参数不是 routerName,则添加空参数名 if (http_1.METHODS.indexOf(router[0].toUpperCase()) > -1) { router.unshift(''); } return { name: router[0], description: '', method: Array.isArray(router[1]) ? router[1] : [router[1]], path: Array.isArray(router[2]) ? router[2] : [router[2]], controllerName: router[3], controllerMethods: Array.isArray(router[4]) ? router[4] : [router[4]], schema: {}, middleware: [], }; } /** * 解析新的路由写法 */ function parseNewRouter(router) { const controllerMethods = router.preHandler || []; if (!router.handler) { throw new Error(`注册路由失败,handler 不能为空`); } const splitArr = router.handler.split(':'); controllerMethods.push(splitArr[1]); if (!router.method) { throw new Error(`注册路由失败,method 不能为空`); } if (!router.path) { throw new Error(`注册路由失败,path 不能为空`); } return { name: router.name, description: router.description || '', method: Array.isArray(router.method) ? router.method : [router.method], path: Array.isArray(router.path) ? router.path : [router.path], controllerName: splitArr[0], controllerMethods, schema: router.schema || {}, middleware: router.middleware || [], }; } class AstroboyRouterLoader extends Loader_1.Loader { async load() { const routerArr = await loadRouters(this.app.ROOT_PATH, this.config.pattern); const controllers = this.app.controllers; const middlewares = this.app.middlewares; const middlewareConfig = this.app.middlewareConfig; const routers = []; routerArr.forEach(item => { const router = Array.isArray(item) ? parseOldRouter(item) : parseNewRouter(item); router.controller = controllers[router.controllerName]; router.method.forEach((method) => { if (http_1.METHODS.indexOf(method.toUpperCase()) === -1) { throw new Error(`注册路由失败,请求方法 ${method} 不是一个标准的 HTTP 请求方法!`); } }); for (let i = 0; i < router.middleware.length; i++) { const middlewareKey = router.middleware[i]; if (!middlewares[middlewareKey]) { throw new Error(`注册路由失败,中间件 ${middlewareKey} 不存在`); } else { const middlewareOptions = middlewareConfig[middlewareKey] && middlewareConfig[middlewareKey].options; router.middleware[i] = middlewares[middlewareKey](middlewareOptions, this.app); } } if (!router.controller) { throw new Error(`注册路由失败,控制器 ${router.controllerName} 未找到!`); } if (!lodash.isFunction(router.controller)) { throw new Error(`注册路由失败,${router.controllerName} 必须是一个类`); } const newControllerMethods = []; if (router.controller.prototype['init']) { newControllerMethods.push('init'); } router.controllerMethods.forEach((method) => { if (!router.controller.prototype[method]) { throw new Error(`注册路由失败,控制器类 ${router.controllerName} 不存在方法名为 ${method} 的方法!`); } else { const beforeMethod = 'before' + method.slice(0, 1).toUpperCase() + method.slice(1); if (router.controller.prototype[beforeMethod]) { newControllerMethods.push(beforeMethod); } newControllerMethods.push(method); } }); router.controllerMethods = newControllerMethods; router.compiledSchema = {}; if (check(router.schema.header)) { router.compiledSchema.header = ajv.compile(router.schema.header); } if (check(router.schema.query)) { router.compiledSchema.query = ajv.compile(router.schema.query); } if (check(router.schema.body)) { router.compiledSchema.body = ajv.compile(router.schema.body); } routers.push(router); }); this.app.routers = routers; } } module.exports = AstroboyRouterLoader; //# sourceMappingURL=AstroboyRouterLoader.js.map