UNPKG

nralcm

Version:

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

118 lines (117 loc) 5.76 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); require("reflect-metadata"); const __1 = require(".."); const exceptions_1 = require("../../exceptions"); /** * Maps current request with api method of controller * @param context HttpContext object * @returns RouteDescriptor object, If not found throws NotFoundException */ function ApiMethodMapper(context, restApiConfiguration) { const urlParts = getUrlParts(context.request.url); const url = urlParts.slice(1).join("/"); // try to find route without param const routeDescriptors = Reflect.getMetadata("routes", context.controllerObject); const routeDescriptor = routeDescriptors.find(routeDescriptor => { return context.request.method.toLowerCase() === routeDescriptor.httpMethod.toLowerCase() && (!url ? (routeDescriptor.methodName.toUpperCase() === context.request.method.toUpperCase()) : routeDescriptor.route === url); }); if (routeDescriptor) { mapQueryString(context, routeDescriptor); return routeDescriptor; } // find route with param const paramMapResult = mapParams(context, routeDescriptors, url); if (paramMapResult !== null) { mapQueryString(context, paramMapResult); return paramMapResult; } throw new exceptions_1.NotFoundException(); } exports.ApiMethodMapper = ApiMethodMapper; /** * get url parts after api * @param url request url * @returns Array of url parts */ function getUrlParts(url) { url = url.substring(url.indexOf("api") + 3); url = url.startsWith("/") ? url.substring(1) : url; const queryStringIndex = url.indexOf("?"); if (queryStringIndex > 0) { url = url.substring(0, url.indexOf("?")); } return url ? url.split("/") : []; } /** * Maps params of url with route and saves in meta data of controller object * @param context HttpContext Object * @param routeDescriptors All RouteDescriptor data of controller * @param url compact url like compact url of 'api/product/getproduct' will be getproduct */ function mapParams(context, routeDescriptors, url) { for (let index = 0; index < routeDescriptors.length; index++) { const routeDescriptor = routeDescriptors[index]; routeDescriptor.route = routeDescriptor.route || "/"; const routeParts = routeDescriptor.route.startsWith("/") ? routeDescriptor.route.substring(1).split("/") : routeDescriptor.route.split("/"); const urlParts = url.startsWith("/") ? url.substring(1).split("/") : url.split("/"); if (routeParts.length === urlParts.length && routeDescriptor.route.indexOf("{") >= 0 && routeDescriptor.route.indexOf("}") >= 0) { const nonParamsRouteParts = routeParts.filter(route => route.indexOf("{") === -1 || route.indexOf("}") === -1); let isMatched = false; nonParamsRouteParts.forEach((routePart) => { if (urlParts.find(urlPart => urlPart === routePart)) { isMatched = true; } else { isMatched = false; } }); if (isMatched || nonParamsRouteParts.length === 0) { isMatched = true; routeParts.forEach((route, i) => { const openCurlyBraceIndex = route.indexOf("{"); const closeCurlyBraceIndex = route.indexOf("}"); if (openCurlyBraceIndex >= 0 && closeCurlyBraceIndex >= 0) { if (urlParts[i]) { const paramData = { paramName: route.substring(openCurlyBraceIndex + 1, closeCurlyBraceIndex), paramValue: urlParts[i] }; const paramMetaDataArr = Reflect.getMetadata(__1.Constants.metadata.routeParams, context.controllerObject, routeDescriptors[index].methodName) || []; paramMetaDataArr.push(paramData); Reflect.defineMetadata(__1.Constants.metadata.routeParams, paramMetaDataArr, context.controllerObject, routeDescriptors[index].methodName); } else { const existingErrorMessages = Reflect.getMetadata(__1.Constants.metadata.emptyRouteParams, context.controllerObject) || []; existingErrorMessages.push(`Parametr ${route.substring(openCurlyBraceIndex + 1, closeCurlyBraceIndex)} is missing`); Reflect.defineMetadata(__1.Constants.metadata.emptyRouteParams, existingErrorMessages, context.controllerObject); } } }); return routeDescriptors[index]; } } } // tslint:disable-next-line:no-null-keyword throw new exceptions_1.NotFoundException(); } /** * Gets query string from request and saves query string in metatdata of controller object * @param context HttpContext Object * @param routeDescriptor RouteDescriptor object that holds metadata of api method */ function mapQueryString(context, routeDescriptor) { if (context.request.query) { const existingQueryStrings = Reflect.getMetadata(__1.Constants.metadata.queryString, context.controllerObject, routeDescriptor.methodName) || []; Object.keys(context.request.query).forEach(qs => { existingQueryStrings.push({ name: qs, value: context.request.query[qs] }); }); Reflect.defineMetadata(__1.Constants.metadata.queryString, existingQueryStrings, context.controllerObject, routeDescriptor.methodName); } }