UNPKG

8.7 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.MiddlewareModule = void 0;
4const request_method_enum_1 = require("@nestjs/common/enums/request-method.enum");
5const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
6const invalid_middleware_exception_1 = require("../errors/exceptions/invalid-middleware.exception");
7const runtime_exception_1 = require("../errors/exceptions/runtime.exception");
8const context_id_factory_1 = require("../helpers/context-id-factory");
9const execution_context_host_1 = require("../helpers/execution-context-host");
10const constants_1 = require("../injector/constants");
11const request_constants_1 = require("../router/request/request-constants");
12const router_exception_filters_1 = require("../router/router-exception-filters");
13const router_proxy_1 = require("../router/router-proxy");
14const utils_1 = require("../router/utils");
15const builder_1 = require("./builder");
16const resolver_1 = require("./resolver");
17const routes_mapper_1 = require("./routes-mapper");
18class MiddlewareModule {
19 constructor() {
20 this.routerProxy = new router_proxy_1.RouterProxy();
21 this.exceptionFiltersCache = new WeakMap();
22 }
23 async register(middlewareContainer, container, config, injector, httpAdapter) {
24 const appRef = container.getHttpAdapterRef();
25 this.routerExceptionFilter = new router_exception_filters_1.RouterExceptionFilters(container, config, appRef);
26 this.routesMapper = new routes_mapper_1.RoutesMapper(container);
27 this.resolver = new resolver_1.MiddlewareResolver(middlewareContainer);
28 this.config = config;
29 this.injector = injector;
30 this.container = container;
31 this.httpAdapter = httpAdapter;
32 const modules = container.getModules();
33 await this.resolveMiddleware(middlewareContainer, modules);
34 }
35 async resolveMiddleware(middlewareContainer, modules) {
36 const moduleEntries = [...modules.entries()];
37 const loadMiddlewareConfiguration = async ([moduleName, moduleRef]) => {
38 await this.loadConfiguration(middlewareContainer, moduleRef, moduleName);
39 await this.resolver.resolveInstances(moduleRef, moduleName);
40 };
41 await Promise.all(moduleEntries.map(loadMiddlewareConfiguration));
42 }
43 async loadConfiguration(middlewareContainer, moduleRef, moduleKey) {
44 const { instance } = moduleRef;
45 if (!instance.configure) {
46 return;
47 }
48 const middlewareBuilder = new builder_1.MiddlewareBuilder(this.routesMapper, this.httpAdapter);
49 await instance.configure(middlewareBuilder);
50 if (!(middlewareBuilder instanceof builder_1.MiddlewareBuilder)) {
51 return;
52 }
53 const config = middlewareBuilder.build();
54 middlewareContainer.insertConfig(config, moduleKey);
55 }
56 async registerMiddleware(middlewareContainer, applicationRef) {
57 const configs = middlewareContainer.getConfigurations();
58 const registerAllConfigs = async (moduleKey, middlewareConfig) => {
59 for (const config of middlewareConfig) {
60 await this.registerMiddlewareConfig(middlewareContainer, config, moduleKey, applicationRef);
61 }
62 };
63 const entriesSortedByDistance = [...configs.entries()].sort(([moduleA], [moduleB]) => {
64 return (this.container.getModuleByKey(moduleA).distance -
65 this.container.getModuleByKey(moduleB).distance);
66 });
67 for (const [moduleRef, moduleConfigurations] of entriesSortedByDistance) {
68 await registerAllConfigs(moduleRef, [...moduleConfigurations]);
69 }
70 }
71 async registerMiddlewareConfig(middlewareContainer, config, moduleKey, applicationRef) {
72 const { forRoutes } = config;
73 for (const routeInfo of forRoutes) {
74 await this.registerRouteMiddleware(middlewareContainer, routeInfo, config, moduleKey, applicationRef);
75 }
76 }
77 async registerRouteMiddleware(middlewareContainer, routeInfo, config, moduleKey, applicationRef) {
78 const middlewareCollection = [].concat(config.middleware);
79 const moduleRef = this.container.getModuleByKey(moduleKey);
80 for (const metatype of middlewareCollection) {
81 const collection = middlewareContainer.getMiddlewareCollection(moduleKey);
82 const instanceWrapper = collection.get(metatype);
83 if ((0, shared_utils_1.isUndefined)(instanceWrapper)) {
84 throw new runtime_exception_1.RuntimeException();
85 }
86 if (instanceWrapper.isTransient) {
87 return;
88 }
89 await this.bindHandler(instanceWrapper, applicationRef, routeInfo.method, routeInfo.path, moduleRef, collection);
90 }
91 }
92 async bindHandler(wrapper, applicationRef, method, path, moduleRef, collection) {
93 const { instance, metatype } = wrapper;
94 if ((0, shared_utils_1.isUndefined)(instance === null || instance === void 0 ? void 0 : instance.use)) {
95 throw new invalid_middleware_exception_1.InvalidMiddlewareException(metatype.name);
96 }
97 const isStatic = wrapper.isDependencyTreeStatic();
98 if (isStatic) {
99 const proxy = await this.createProxy(instance);
100 return this.registerHandler(applicationRef, method, path, proxy);
101 }
102 await this.registerHandler(applicationRef, method, path, async (req, res, next) => {
103 try {
104 const contextId = context_id_factory_1.ContextIdFactory.getByRequest(req);
105 if (!req[request_constants_1.REQUEST_CONTEXT_ID]) {
106 Object.defineProperty(req, request_constants_1.REQUEST_CONTEXT_ID, {
107 value: contextId,
108 enumerable: false,
109 writable: false,
110 configurable: false,
111 });
112 this.container.registerRequestProvider(req, contextId);
113 }
114 const contextInstance = await this.injector.loadPerContext(instance, moduleRef, collection, contextId);
115 const proxy = await this.createProxy(contextInstance, contextId);
116 return proxy(req, res, next);
117 }
118 catch (err) {
119 let exceptionsHandler = this.exceptionFiltersCache.get(instance.use);
120 if (!exceptionsHandler) {
121 exceptionsHandler = this.routerExceptionFilter.create(instance, instance.use, undefined);
122 this.exceptionFiltersCache.set(instance.use, exceptionsHandler);
123 }
124 const host = new execution_context_host_1.ExecutionContextHost([req, res, next]);
125 exceptionsHandler.next(err, host);
126 }
127 });
128 }
129 async createProxy(instance, contextId = constants_1.STATIC_CONTEXT) {
130 const exceptionsHandler = this.routerExceptionFilter.create(instance, instance.use, undefined, contextId);
131 const middleware = instance.use.bind(instance);
132 return this.routerProxy.createProxy(middleware, exceptionsHandler);
133 }
134 async registerHandler(applicationRef, method, path, proxy) {
135 const prefix = this.config.getGlobalPrefix();
136 const excludedRoutes = this.config.getGlobalPrefixOptions().exclude;
137 if ((Array.isArray(excludedRoutes) &&
138 (0, utils_1.isRouteExcluded)(excludedRoutes, path, method)) ||
139 ['*', '/*', '(.*)', '/(.*)'].includes(path)) {
140 path = (0, shared_utils_1.addLeadingSlash)(path);
141 }
142 else {
143 const basePath = (0, shared_utils_1.addLeadingSlash)(prefix);
144 if ((basePath === null || basePath === void 0 ? void 0 : basePath.endsWith('/')) && (path === null || path === void 0 ? void 0 : path.startsWith('/'))) {
145 // strip slash when a wildcard is being used
146 // and global prefix has been set
147 path = path === null || path === void 0 ? void 0 : path.slice(1);
148 }
149 path = basePath + path;
150 }
151 const isMethodAll = (0, utils_1.isRequestMethodAll)(method);
152 const requestMethod = request_method_enum_1.RequestMethod[method];
153 const router = await applicationRef.createMiddlewareFactory(method);
154 router(path, isMethodAll
155 ? proxy
156 : (req, res, next) => {
157 if (applicationRef.getRequestMethod(req) === requestMethod) {
158 return proxy(req, res, next);
159 }
160 return next();
161 });
162 }
163}
164exports.MiddlewareModule = MiddlewareModule;