UNPKG

koa-springboot

Version:
138 lines (137 loc) 5.73 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const errors_1 = require("./errors"); const constants_1 = require("./constants"); function prefixSlash(str) { return str.startsWith('/') ? str : `/${str}`; } function getParams(actionParams, ctx) { const ret = []; (actionParams || []).forEach(actionParam => { if (actionParam.type === 'PathVariable') { ret[actionParam.index] = ctx.params[actionParam.name]; } else if (actionParam.type === 'RequestParam') { ret[actionParam.index] = ctx.query[actionParam.name]; } else if (actionParam.type === 'RequestBody') { ret[actionParam.index] = ctx.request.body || ctx.body; } if (actionParam.defaultValue !== undefined) { ret[actionParam.index] = ret[actionParam.index] || actionParam.defaultValue; } if (actionParam.required && ret[actionParam.index] === undefined) { throw new errors_1.ParamError(`param ${actionParam.name} is required`); } }); ret.push(ctx); return ret; } function paramsMiddleWare(actionParams, responseType, responseStatus, viewPath) { return (ctx, next) => __awaiter(this, void 0, void 0, function* () { try { ctx.actionParams = getParams(actionParams, ctx); } catch (error) { if (error instanceof errors_1.ParamError) { ctx.body = JSON.stringify({ code: error.code, data: error.message }); return; } else { throw error; } } const ret = yield next(); ctx.status = responseStatus; if (ret && typeof ret === 'object') { if (responseType === 'json') { ctx.set('Content-Type', 'application/json'); ctx.body = JSON.stringify(ret); } else { yield ctx.render(viewPath, ret); } } }); } function mountSingleRoute(router, baseUrl, routerConfig, controllerInstance, baseResponseType) { const { method, action, pattern, actionParams, responseType, responseStatus } = routerConfig; let path = baseUrl === '/' ? pattern : baseUrl + pattern; if (path.length > 1) { path = path.replace(/\/$/, ''); } const rResponseType = responseType || baseResponseType; const viewPath = `${controllerInstance.constructor.name.toLowerCase()}/${action}`; router[method](path, paramsMiddleWare(actionParams, rResponseType, responseStatus || constants_1.HttpStatus.OK, viewPath), (ctx) => controllerInstance[action].call(controllerInstance, ...ctx.actionParams)); } class RouterManager { constructor() { this.config = new Map(); } setRouteConfig(controller, routeConfig) { const preRouteConfig = this.getRouteConfig(controller, routeConfig.action); routeConfig.pattern = prefixSlash(routeConfig.pattern || preRouteConfig.pattern || ''); Object.assign(preRouteConfig, routeConfig); } setParamVariable(controller, action, config) { const preRouteConfig = this.getRouteConfig(controller, action); preRouteConfig.actionParams.push(config); } setInjectModel(controller, name, propertyKey) { const preRouteConfig = this.getControllerConfig(controller); preRouteConfig.injectModels = preRouteConfig.injectModels || new Map(); preRouteConfig.injectModels.set(propertyKey, name); } setControllerConfig(controller, config) { const controllerConfig = this.getControllerConfig(controller); Object.assign(controllerConfig, config); } getControllerConfig(controller) { if (!this.config.has(controller)) { const controllerConfig = { controller, baseUrl: '', routes: [], responseType: 'template' }; this.config.set(controller, controllerConfig); } return this.config.get(controller); } getRouteConfig(controller, action) { const controllerConfig = this.getControllerConfig(controller); let ret = controllerConfig.routes.find(r => r.action === action); if (!ret) { ret = { method: constants_1.RequestMethod.ALL, action, actionParams: [] }; controllerConfig.routes.push(ret); } return ret; } mountRoutes(router, models = {}) { this.config.forEach(({ baseUrl, controller, routes, responseType, injectModels }) => { const cInstance = new controller(); if (injectModels && injectModels.size > 0) { injectModels.forEach((propName, modelName) => { cInstance[propName] = models[modelName]; }); } routes.forEach(routerConfig => mountSingleRoute(router, baseUrl, routerConfig, cInstance, responseType)); }); } } exports.default = new RouterManager();