UNPKG

nralcm

Version:

This is a framework based on NodeJs to manage rest api request lifecycle

147 lines (146 loc) 7.52 kB
"use strict"; 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;