UNPKG

ts-api-core

Version:

Nodejs api framework core

217 lines 9.77 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 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) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.RegisterService = exports.extractParameters = void 0; const api_request_context_1 = require("../context/api.request.context"); const model_helper_1 = require("../utils/model.helper"); const express_decorator_1 = require("./express.decorator"); const method_validate_decorator_1 = require("./validation/method.validate.decorator"); const __1 = require(".."); const ioc_decorator_1 = require("./ioc.decorator"); /** * 从请求提取参数 */ function extractParameters(req, res, params) { if (!params) { return undefined; } const args = []; const queryMap = new Map(); for (const key in req.query) { queryMap.set(key.toLowerCase(), req.query[key]); } const bodyMap = new Map(); if (req.body) { for (const key in req.body) { bodyMap.set(key.toLowerCase(), req.body[key]); } } const paramHandlerTpe = { query: (paramName) => { return queryMap.get(paramName.toLowerCase()); }, path: (paramName) => req.params[paramName.toLowerCase()], form: (paramName) => bodyMap.get(paramName.toLowerCase()), body: () => req.body, bodyModel: (paramName) => bodyMap.get(paramName.toLowerCase()), cookie: (paramName) => req.cookies && req.cookies[paramName.toLowerCase()], header: (paramName) => req.get(paramName.toLowerCase()), request: () => req, response: () => res, }; const validateObjList = new Array(); params.forEach((param) => { // eslint-disable-next-line @typescript-eslint/ban-types const paramHandler = paramHandlerTpe[param.type]; const value = paramHandler(param.name); if (param.dataType) { if (param.dataType === "number") { args.push(parseFloat(value)); } else if (typeof param.dataType.constructor === "function") { const _constructor = param.dataType.constructor; const validateTarget = method_validate_decorator_1.Validate.classMap.has(_constructor.name) ? method_validate_decorator_1.Validate.classMap.get(_constructor.name) : undefined; // eslint-disable-next-line @typescript-eslint/no-unsafe-call const v = new _constructor(); let isInitModel = false; if (param.type === "bodyModel") { model_helper_1.ModelHelper.initModel(req.body, v, true, true); isInitModel = true; } const vKeys = Object.keys(v); if (validateTarget) { // 如果存在校验器,则将校验器对应的字段加入keys中 method_validate_decorator_1.Validate.mergeMetadataField(validateTarget, vKeys); } vKeys.forEach((k) => { if (v[k] === undefined || v[k] === null || !isInitModel) { v[k] = paramHandler(k); } }); // 处理 @src 装饰器 model_helper_1.ModelHelper.mergeClassMapField(v.constructor.name, (srcKey, destKey, src) => { if (isInitModel && src.classType && v[destKey]) { // 如果指定有目标类型,且已有值时,说明已经初始化好了 return; } const v2 = paramHandler(srcKey); if (v2 !== undefined || v[destKey] === undefined || v[destKey] === null) { if (src.convert) { const result = src.executeConvert(v, v2); if (result !== undefined) { v[destKey] = result; } } else { v[destKey] = v2; } } }); // 进行参数校验 if (validateTarget) { validateObjList.push([validateTarget, v]); } args.push(v); } else { args.push(value); } } else { args.push(value); } }); // 参数校验 const needValidate = validateObjList.find((e1) => { const meta = e1[0].prototype ? (0, express_decorator_1.getClazz)(e1[0].prototype) : undefined; if ((meta === null || meta === void 0 ? void 0 : meta.validateif) && !meta.validateif(e1[1])) { method_validate_decorator_1.Validate.validateDTO(e1[0], e1[1]); return true; } return false; }); if (!needValidate) { validateObjList.forEach(e2 => method_validate_decorator_1.Validate.validateDTO(e2[0], e2[1])); } return args; } exports.extractParameters = extractParameters; /** * 注册服务 * * ``` * RegisterService(express, [services]) * ``` */ function RegisterService(app, serviceClasses, logger) { const bodyParser = __1.PackageLoader.load('body-parser'); const Router = __1.PackageLoader.load('express'); const router = Router(); serviceClasses.forEach((ServiceClazz) => { const meta = (0, express_decorator_1.getClazz)(ServiceClazz.prototype); const { routes } = meta; for (const methodName in routes) { const methodMeta = routes[methodName]; const { httpMethod } = methodMeta; const { midwares } = methodMeta; // express router callback const fn = (req, res, next) => __awaiter(this, void 0, void 0, function* () { var _a; const context = new api_request_context_1.APIRequestContext(logger, meta.logPackage); context.req = req; context.resp = res; const args = (_a = ioc_decorator_1.IocContainer.getClassConstructorArgs(context, ServiceClazz)) !== null && _a !== void 0 ? _a : [context]; const serviceInstance = new ServiceClazz(...args); try { ioc_decorator_1.IocContainer.resolveInject(context, serviceInstance, ServiceClazz); const params = extractParameters(req, res, methodMeta.params); // eslint-disable-next-line @typescript-eslint/no-unsafe-call const result = ServiceClazz.prototype[methodName].apply(serviceInstance, params); if (result instanceof Promise) { result .then((value) => { context.release(value); !res.headersSent && res.status(200).send(value); }) .catch((err) => { context.error = err; context.release(); next(err); }); } else if (result !== undefined) { context.release(); !res.headersSent && res.status(200).send(result); } } catch (e1) { context.error = e1; context.release(); next(e1); return; } }); // eslint-disable-next-line no-console console.log("Register Router " + httpMethod + ": " + meta.baseUrl + methodMeta.subUrl); // register sub route let params = [meta.baseUrl + methodMeta.subUrl]; midwares && (params = params.concat(midwares)); params.push(fn); if (httpMethod.indexOf(",") > 0) { httpMethod.split(",").forEach((e2) => { // eslint-disable-next-line @typescript-eslint/ban-types router[e2].apply(router, params); }); } else { // eslint-disable-next-line @typescript-eslint/ban-types router[httpMethod].apply(router, params); } } // 注册主路由 // let params: any[] = [meta.baseUrl, bodyParser.json(), cookieParser()]; let params = ["/", bodyParser.json()]; meta.midwares && (params = params.concat(meta.midwares)); params.push(router); // eslint-disable-next-line @typescript-eslint/ban-types app.use.apply(app, params); }); } exports.RegisterService = RegisterService; //# sourceMappingURL=mvc.register.js.map