/
githubmirror
/
nest
Обзор
Документация
Войти
/
githubmirror
/
nest
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
packages/core/middleware/utils.ts
135 строк
4 KB
Kamil Myśliwiec
feat: add legacy route converter, update tests
28 ноя 2024, 13:28
Не верифицирован
28 ноя 2024, 13:28
7f142e9
Код
Авторство
О чём код?
import { RequestMethod } from '@nestjs/common'; import { HttpServer, RouteInfo, Type } from '@nestjs/common/interfaces'; import { addLeadingSlash, isFunction, isString, } from '@nestjs/common/utils/shared.utils'; import { iterate } from 'iterare'; import { pathToRegexp } from 'path-to-regexp'; import { uid } from 'uid'; import { ExcludeRouteMetadata } from '../router/interfaces/exclude-route-metadata.interface'; import { LegacyRouteConverter } from '../router/legacy-route-converter'; import { isRouteExcluded } from '../router/utils'; export const mapToExcludeRoute = ( routes: (string | RouteInfo)[], ): ExcludeRouteMetadata[] => { return routes.map(route => { const originalPath = isString(route) ? route : route.path; const path = LegacyRouteConverter.tryConvert(originalPath); try { if (isString(route)) { return { path, requestMethod: RequestMethod.ALL, pathRegex: pathToRegexp(addLeadingSlash(path)).regexp, }; } return { path, requestMethod: route.method, pathRegex: pathToRegexp(addLeadingSlash(path)).regexp, }; } catch (e) { if (e instanceof TypeError) { LegacyRouteConverter.printError(originalPath); } throw e; } }); }; export const filterMiddleware = <T extends Function | Type<any> = any>( middleware: T[], routes: RouteInfo[], httpAdapter: HttpServer, ) => { const excludedRoutes = mapToExcludeRoute(routes); return iterate([]) .concat(middleware) .filter(isFunction) .map((item: T) => mapToClass(item, excludedRoutes, httpAdapter)) .toArray(); }; export const mapToClass = <T extends Function | Type<any>>( middleware: T, excludedRoutes: ExcludeRouteMetadata[], httpAdapter: HttpServer, ) => { if (isMiddlewareClass(middleware)) { if (excludedRoutes.length <= 0) { return middleware; } const MiddlewareHost = class extends middleware { use(...params: unknown[]) { const [req, _, next] = params as [Record<string, any>, any, Function]; const isExcluded = isMiddlewareRouteExcluded( req, excludedRoutes, httpAdapter, ); if (isExcluded) { return next(); } return super.use(...params); } }; return assignToken(MiddlewareHost, middleware.name); } return assignToken( class { use = (...params: unknown[]) => { const [req, _, next] = params as [Record<string, any>, any, Function]; const isExcluded = isMiddlewareRouteExcluded( req, excludedRoutes, httpAdapter, ); if (isExcluded) { return next(); } return (middleware as Function)(...params); }; }, ); }; export function isMiddlewareClass(middleware: any): middleware is Type<any> { const middlewareStr = middleware.toString(); if (middlewareStr.substring(0, 5) === 'class') { return true; } const middlewareArr = middlewareStr.split(' '); return ( middlewareArr[0] === 'function' && /[A-Z]/.test(middlewareArr[1]?.[0]) && isFunction(middleware.prototype?.use) ); } export function assignToken(metatype: Type<any>, token = uid(21)): Type<any> { Object.defineProperty(metatype, 'name', { value: token }); return metatype; } export function isMiddlewareRouteExcluded( req: Record<string, any>, excludedRoutes: ExcludeRouteMetadata[], httpAdapter: HttpServer, ): boolean { if (excludedRoutes.length <= 0) { return false; } const reqMethod = httpAdapter.getRequestMethod!(req); const originalUrl = httpAdapter.getRequestUrl!(req); const queryParamsIndex = originalUrl ? originalUrl.indexOf('?') : -1; const pathname = queryParamsIndex >= 0 ? originalUrl.slice(0, queryParamsIndex) : originalUrl; return isRouteExcluded(excludedRoutes, pathname, RequestMethod[reqMethod]); }