ts-api-core
Version:
Nodejs api framework core
180 lines • 8.99 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateif = exports.MethodValidateDecorator = exports.validate = exports.Validate = void 0;
/* eslint-disable @typescript-eslint/no-extraneous-class */
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
/* eslint-disable prefer-rest-params */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
/* eslint-disable @typescript-eslint/no-unsafe-call */
require("reflect-metadata");
const express_decorator_1 = require("../express.decorator");
const mvc_error_1 = require("./mvc.error");
/**
* 参数校验器
*/
class Validate {
static getTargetMetaDataMapKey(target) {
var _a, _b;
return (_a = target.name) !== null && _a !== void 0 ? _a : (_b = target.constructor) === null || _b === void 0 ? void 0 : _b.name;
}
static putMetadataKey(target, metadataKey, type, field) {
const mapKey = this.getTargetMetaDataMapKey(target);
let items = this.validMetadataKeyMap.get(mapKey);
if (!items) {
items = [];
this.validMetadataKeyMap.set(mapKey, items);
}
items.push([metadataKey, type, field]);
}
static getMetadataInfo(target) {
const mapKey = this.getTargetMetaDataMapKey(target);
return this.validMetadataKeyMap.get(mapKey);
}
static mergeMetadataField(target, keys) {
const metaData = this.getMetadataInfo(target);
metaData === null || metaData === void 0 ? void 0 : metaData.forEach((row) => {
if (row[1] === 1 && row[2]) {
const ss = row[2].toLowerCase();
const i = keys.findIndex(v => v.toLowerCase() === ss);
if (i < 0) {
keys.push(row[2]);
}
}
});
}
static validateDTO(target, data) {
const keys = Object.keys(data);
const keyLen = keys.length;
keys.forEach((ee, idx) => {
this.validateProperty(target, data, keyLen, `${data.constructor.name}.${idx}`, ee, false);
});
}
static validateProperty(target, data, dataLength, propertyName, propertyKey, dataIsArray) {
try {
const targetMetaMapKey = this.getTargetMetaDataMapKey(target);
const validMetadataKeyList = this.validMetadataKeyMap.get(targetMetaMapKey);
validMetadataKeyList === null || validMetadataKeyList === void 0 ? void 0 : validMetadataKeyList.forEach((validMetaData) => {
var _a, _b, _c, _d, _e, _f;
// 验证方法参数
const isProperty = validMetaData[1] === 0;
const validParameters = Reflect.getOwnMetadata(validMetaData[0], target, isProperty ? propertyName : propertyKey);
if (validParameters) {
for (const parameterIndex of validParameters.paramsIndex) {
const dataValue = dataIsArray
? parameterIndex >= dataLength
? undefined
: data[parameterIndex]
: data[propertyKey];
if (parameterIndex >= dataLength
|| dataValue === undefined
|| dataValue === ''
|| Number.isNaN(dataValue)) {
const defaultValue = parameterIndex >= dataLength
? undefined
: (_a = validParameters === null || validParameters === void 0 ? void 0 : validParameters.validator) === null || _a === void 0 ? void 0 : _a.getDefaultValue();
if (defaultValue === undefined
&& validParameters.validator.isMust()) {
if (!dataIsArray) {
throw new mvc_error_1.ParamError(propertyKey + '参数为空或不存在');
}
const meta = (_b = target.$Meta) !== null && _b !== void 0 ? _b : (_c = target.prototype) === null || _c === void 0 ? void 0 : _c.$Meta;
const { params } = meta.routes[propertyName];
for (const pp of params) {
if (pp.index === parameterIndex) {
throw new mvc_error_1.ParamError(pp.name + '参数为空或不存在');
}
}
}
else if (dataIsArray) {
data[parameterIndex] = defaultValue;
}
else {
data[propertyKey] = defaultValue;
}
}
else if (!validParameters.validator.valid(dataValue, (vv) => {
if (dataIsArray) {
data[parameterIndex] = vv;
}
else {
data[propertyKey] = vv;
}
})) {
if (!dataIsArray) {
const text = (_d = validParameters === null || validParameters === void 0 ? void 0 : validParameters.validator) === null || _d === void 0 ? void 0 : _d.getMessage();
throw new mvc_error_1.ParamError(propertyKey + text);
}
const meta = (_e = target.$Meta) !== null && _e !== void 0 ? _e : (_f = target.prototype) === null || _f === void 0 ? void 0 : _f.$Meta;
const { params } = meta.routes[propertyName];
const t1 = params[parameterIndex].name;
const t2 = validParameters.validator.getMessage();
throw new mvc_error_1.ParamError(t1 + t2);
}
}
}
});
}
catch (ex) {
console.error(ex);
mvc_error_1.BaseError.throwError(ex, '处理参数校验', ex.message);
}
}
}
exports.Validate = Validate;
Validate.validMetadataKeyMap = new Map();
Validate.classMap = new Map();
/** 参数或字段校验(注意:对象字段校验暂不支持继承) */
function validate(target, propertyName,
// eslint-disable-next-line @typescript-eslint/ban-types
descriptor) {
if (!descriptor) {
// 装饰器在类名上
if (target.name) {
// console.log(target.name);
Validate.classMap.set(target.name, target);
}
return;
}
const method = descriptor.value;
if (!method) {
return;
}
descriptor.value = function () {
var _a;
Validate.validateProperty((_a = target.constructor) !== null && _a !== void 0 ? _a : target, arguments, arguments.length, propertyName !== null && propertyName !== void 0 ? propertyName : '', propertyName !== null && propertyName !== void 0 ? propertyName : '', true);
return method.apply(this, arguments);
};
}
exports.validate = validate;
class MethodValidateDecorator {
static getValidatorDecorator(metadataKey, abstractValidator) {
return function (target, propertyKey, parameterIndex = 0) {
const type = propertyKey ? 1 : 0;
const _target = target.name ? target : target.constructor;
// console.log(target.name ?? target.constructor?.name);
Validate.putMetadataKey(_target, metadataKey, type, typeof propertyKey === 'string' ? propertyKey : undefined);
const key = propertyKey !== null && propertyKey !== void 0 ? propertyKey : `${_target.name}.${parameterIndex}`;
const validParameters = Reflect.getOwnMetadata(metadataKey, _target, key) || [];
validParameters.push(parameterIndex);
const data = {
paramsIndex: validParameters,
validator: abstractValidator,
};
Reflect.defineMetadata(metadataKey, data, _target, key);
};
}
}
exports.MethodValidateDecorator = MethodValidateDecorator;
/**
* 参数校验条件 (是否需要校验其它参数)
* @param callBack 检测回调函数,返回 true 时继续执行校验
* @returns
*/
function validateif(callBack) {
return function (target) {
const meta = (0, express_decorator_1.getClazz)(target.prototype);
meta.validateif = callBack;
};
}
exports.validateif = validateif;
//# sourceMappingURL=method.validate.decorator.js.map