UNPKG

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