ts-api-core
Version:
Nodejs api framework core
217 lines • 9.77 kB
JavaScript
;
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