decorator-x
Version:
decorator for entity instantiation & validation, auto-generate swagger docs & graphql schema
127 lines (109 loc) • 3.29 kB
JavaScript
// @flow
const path = require('path');
const debug = require('debug')('koa_router');
import { buildSwaggerJSON } from '../../swagger/paths';
import { swaggerJSON } from '../../swagger/template/swagger.json';
import { swaggerHTML } from '../../swagger/template/swagger.html';
const methods = [
'get',
'post',
'put',
'delete',
'head',
'options',
'del',
'all'
];
/**
* Description 将 router 对象的方法进行封装
* @param router 路由对象
* @param host API 域名
* @param basePath API 基本路径
* @param info 其他的 Swagger 基本信息
*/
export function wrappingKoaRouter(
router: Object,
host: string = 'localhost',
basePath: string = '',
info: Object = {}
) {
// 修复 SwaggerObject
if (!!info) {
for (let key of Object.keys(info)) {
swaggerJSON['info'][key] = info[key];
}
}
swaggerJSON.host = host;
swaggerJSON.basePath = basePath;
// 设置静态请求
router.get('/swagger', (ctx, next) => {
ctx.body = swaggerHTML('/swagger/api.json');
});
// 设置 api.json 的请求
router.get('/swagger/api.json', function(ctx, next) {
// 构建 SwaggerJSON 文档
buildSwaggerJSON();
ctx.body = swaggerJSON;
});
/**
* Description 扫描某个类中的所有静态方法,按照其注解将其添加到
* @param StaticClass
*/
router.scan = function(StaticClass: Function) {
let methods = Object.getOwnPropertyNames(StaticClass);
// 遍历该类中的所有方法
for (let method of methods) {
if (typeof method === 'function' && method.path) {
// 添加权限校验
router.use(
basePath + StaticClass[method].path,
validate(StaticClass[method])
);
// 使用该类中的所有方法
router.all(StaticClass[method]);
}
}
};
// Hook router 中的方法
methods.forEach((method: string) => {
const originMethod = router[method];
// Hook 原 router 对象的方法,使其能够读取到函数的配置信息
router[method] = function(
pathOrFunction: string | Function,
func: Function
) {
// 如果 pathOrFunction 为字符串,则表示为正常调用
if (pathOrFunction && typeof pathOrFunction === 'string') {
originMethod.call(router, pathOrFunction, func);
} else {
// 这里对于路径函数进行判断
if (!pathOrFunction.method || !pathOrFunction.path) {
return;
}
// 这里执行对于路由对象的注册
router[pathOrFunction.method].call(
router,
// 注意,这里仅自定义注解才添加前缀
basePath + pathOrFunction.path,
pathOrFunction
);
}
};
});
}
/**
* Description 从请求路径、请求体中剥离出参数并且进行校验
* - params 路径参数 ctx.params
* - query 查询参数 ctx.query
* - body ctx.request.body 使用 koa-body 中间件(https://github.com/dlau/koa-body)
* @param decoratedFunction 传入的经过注解的函数
*/
function validate(decoratedFunction: Function): Function {
return async (ctx, next) => {
debug(ctx.query);
debug(ctx.params);
debug(ctx.request.body);
// 进行路径参数校验
await next();
};
}