nralcm
Version:
This is a framework based on NodeJs to manage rest api request lifecycle
147 lines (146 loc) • 7.52 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const __1 = require("..");
const common_1 = require("../../common");
/**
* ModelValidationHandler class to handler validation of params, querystring and request body
*/
class ModelValidationHandler {
/**
* Validates params, query string and request body
* @param context HttpContext Object
* @param routeDescriptor RouteDescriptor Object
* @returns Array of ModelError
*/
validate(context, routeDescriptor) {
const modelErrorArray = this.validateParamsAndQueryWithMethodParameters(context, routeDescriptor);
const existingmodelErrorArray = Reflect.getMetadata(__1.Constants.metadata.errorMessages, context.controllerObject) || [];
return [...modelErrorArray, ...existingmodelErrorArray];
}
/**
*
* @param context HttpContext Object
* @param routeDescriptor meta data of routes
* @returns ModelError array
*/
validateParamsAndQueryWithMethodParameters(context, routeDescriptor) {
let modelErrorArray = [];
const methodParameters = common_1.getMethodParameters(context.controller, routeDescriptor.methodName);
if (methodParameters.length) {
const methodParameterTypes = Reflect.getMetadata("design:paramtypes", context.controllerObject, routeDescriptor.methodName);
const validationMetaData = Reflect.getMetadata(__1.Constants.metadata.validation, context.controllerObject, routeDescriptor.methodName);
const paramMetaData = Reflect.getMetadata(__1.Constants.metadata.routeParams, context.controllerObject, routeDescriptor.methodName) || [];
const queryStringMetaData = Reflect.getMetadata(__1.Constants.metadata.queryString, context.controllerObject, routeDescriptor.methodName);
let optionalParameters = [];
if (validationMetaData && validationMetaData.length) {
optionalParameters = validationMetaData.filter(m => m.validator === "Optional");
}
const args = new Array(methodParameters.length);
methodParameters.forEach((par, index) => {
let isFound = false;
const param = paramMetaData.find(p => p.paramName === par);
if (param) {
isFound = true;
if (!common_1.isValidType(methodParameterTypes[index], param.paramValue)) {
const modelError = {
propertyName: param.paramName,
errorMessage: `Param ${param.paramName} of type ${methodParameterTypes[index].name} is not valid`,
isTypeError: true,
typeOfProperty: methodParameterTypes[index],
errorType: "Param"
};
modelErrorArray.push(modelError);
}
else {
args[index] = param.paramValue;
}
}
else {
const queryString = queryStringMetaData ? queryStringMetaData.find(q => q.name === par) : undefined;
if (queryString) {
isFound = true;
if (!common_1.isValidType(methodParameterTypes[index], queryString.value)) {
const modelError = {
propertyName: queryString.name,
errorMessage: `Parameter ${queryString.name} of type ${methodParameterTypes[index].name} is not valid`,
isTypeError: true,
typeOfProperty: methodParameterTypes[index],
errorType: "QueryString"
};
modelErrorArray.push(modelError);
}
else {
args[index] = queryString.value;
}
}
else {
const optionalParameter = optionalParameters ? optionalParameters.find(o => o.parameterIndex === index) : undefined;
if (optionalParameter) {
isFound = true;
}
}
}
if (!isFound) {
if (routeDescriptor.httpMethod === common_1.HttpMethod.GET) {
const modelError = {
propertyName: par,
errorMessage: `Parameter ${par} is missing in request`,
isTypeError: false,
typeOfProperty: undefined,
errorType: "Param"
};
modelErrorArray.push(modelError);
}
else {
if (methodParameterTypes[index].name === "Number" || methodParameterTypes[index].name === "String"
|| methodParameterTypes[index].name === "Boolean") {
const modelError = {
propertyName: par,
errorMessage: `Parameter ${par} is missing in request`,
isTypeError: false,
typeOfProperty: undefined,
errorType: "Param"
};
modelErrorArray.push(modelError);
}
else {
if (methodParameterTypes[index].name !== "Object") {
const result = this.validateRequestBody(context, methodParameterTypes[index]);
modelErrorArray = [...modelErrorArray, ...result];
}
args[index] = context.request.body;
}
}
}
});
if (modelErrorArray.length === 0) {
Reflect.defineMetadata(__1.Constants.metadata.args, args, context.controllerObject);
}
}
return modelErrorArray;
}
/**
* Method to validate body of request
* @param context HttpContext Object
* @param paramtype Type of Request body
*/
validateRequestBody(context, paramtype) {
const instance = new paramtype();
const validatorDataArr = Reflect.getMetadata(__1.Constants.metadata.validation, instance);
const modelErrorArray = [];
if (validatorDataArr && validatorDataArr.length) {
const objectKeys = Object.keys(context.request.body);
validatorDataArr.forEach((validatorData) => {
const keyIndex = objectKeys.findIndex(key => key === validatorData.propertyKey);
if (validatorData.validate) {
const validationResult = validatorData.validate(keyIndex !== -1 ? context.request.body[objectKeys[keyIndex]] : undefined, validatorData, instance);
if (typeof validationResult !== "boolean" && validationResult) {
modelErrorArray.push(validationResult);
}
}
});
}
return modelErrorArray;
}
}
exports.ModelValidationHandler = ModelValidationHandler;