1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.NestApplication = void 0;
|
4 | const common_1 = require("@nestjs/common");
|
5 | const logger_service_1 = require("@nestjs/common/services/logger.service");
|
6 | const load_package_util_1 = require("@nestjs/common/utils/load-package.util");
|
7 | const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
|
8 | const iterare_1 = require("iterare");
|
9 | const os_1 = require("os");
|
10 | const pathToRegexp = require("path-to-regexp");
|
11 | const application_config_1 = require("./application-config");
|
12 | const constants_1 = require("./constants");
|
13 | const optional_require_1 = require("./helpers/optional-require");
|
14 | const container_1 = require("./middleware/container");
|
15 | const middleware_module_1 = require("./middleware/middleware-module");
|
16 | const nest_application_context_1 = require("./nest-application-context");
|
17 | const route_path_factory_1 = require("./router/route-path-factory");
|
18 | const routes_resolver_1 = require("./router/routes-resolver");
|
19 | const { SocketModule } = (0, optional_require_1.optionalRequire)('@nestjs/websockets/socket-module', () => require('@nestjs/websockets/socket-module'));
|
20 | const { MicroservicesModule } = (0, optional_require_1.optionalRequire)('@nestjs/microservices/microservices-module', () => require('@nestjs/microservices/microservices-module'));
|
21 |
|
22 |
|
23 |
|
24 | class NestApplication extends nest_application_context_1.NestApplicationContext {
|
25 | constructor(container, httpAdapter, config, appOptions = {}) {
|
26 | super(container);
|
27 | this.httpAdapter = httpAdapter;
|
28 | this.config = config;
|
29 | this.appOptions = appOptions;
|
30 | this.logger = new logger_service_1.Logger(NestApplication.name, {
|
31 | timestamp: true,
|
32 | });
|
33 | this.middlewareContainer = new container_1.MiddlewareContainer(this.container);
|
34 | this.microservicesModule = MicroservicesModule && new MicroservicesModule();
|
35 | this.socketModule = SocketModule && new SocketModule();
|
36 | this.microservices = [];
|
37 | this.isListening = false;
|
38 | this.selectContextModule();
|
39 | this.registerHttpServer();
|
40 | this.middlewareModule = new middleware_module_1.MiddlewareModule(new route_path_factory_1.RoutePathFactory(config));
|
41 | this.routesResolver = new routes_resolver_1.RoutesResolver(this.container, this.config, this.injector);
|
42 | }
|
43 | async dispose() {
|
44 | this.socketModule && (await this.socketModule.close());
|
45 | this.microservicesModule && (await this.microservicesModule.close());
|
46 | this.httpAdapter && (await this.httpAdapter.close());
|
47 | await Promise.all((0, iterare_1.iterate)(this.microservices).map(async (microservice) => {
|
48 | microservice.setIsTerminated(true);
|
49 | await microservice.close();
|
50 | }));
|
51 | }
|
52 | getHttpAdapter() {
|
53 | return this.httpAdapter;
|
54 | }
|
55 | registerHttpServer() {
|
56 | this.httpServer = this.createServer();
|
57 | }
|
58 | getUnderlyingHttpServer() {
|
59 | return this.httpAdapter.getHttpServer();
|
60 | }
|
61 | applyOptions() {
|
62 | if (!this.appOptions || !this.appOptions.cors) {
|
63 | return undefined;
|
64 | }
|
65 | const passCustomOptions = (0, shared_utils_1.isObject)(this.appOptions.cors) || (0, shared_utils_1.isFunction)(this.appOptions.cors);
|
66 | if (!passCustomOptions) {
|
67 | return this.enableCors();
|
68 | }
|
69 | return this.enableCors(this.appOptions.cors);
|
70 | }
|
71 | createServer() {
|
72 | this.httpAdapter.initHttpServer(this.appOptions);
|
73 | return this.httpAdapter.getHttpServer();
|
74 | }
|
75 | async registerModules() {
|
76 | this.registerWsModule();
|
77 | if (this.microservicesModule) {
|
78 | this.microservicesModule.register(this.container, this.config);
|
79 | this.microservicesModule.setupClients(this.container);
|
80 | }
|
81 | await this.middlewareModule.register(this.middlewareContainer, this.container, this.config, this.injector, this.httpAdapter);
|
82 | }
|
83 | registerWsModule() {
|
84 | if (!this.socketModule) {
|
85 | return;
|
86 | }
|
87 | this.socketModule.register(this.container, this.config, this.httpServer);
|
88 | }
|
89 | async init() {
|
90 | var _a;
|
91 | this.applyOptions();
|
92 | await ((_a = this.httpAdapter) === null || _a === void 0 ? void 0 : _a.init());
|
93 | const useBodyParser = this.appOptions && this.appOptions.bodyParser !== false;
|
94 | useBodyParser && this.registerParserMiddleware();
|
95 | await this.registerModules();
|
96 | await this.registerRouter();
|
97 | await this.callInitHook();
|
98 | await this.registerRouterHooks();
|
99 | await this.callBootstrapHook();
|
100 | this.isInitialized = true;
|
101 | this.logger.log(constants_1.MESSAGES.APPLICATION_READY);
|
102 | return this;
|
103 | }
|
104 | registerParserMiddleware() {
|
105 | var _a;
|
106 | const prefix = this.config.getGlobalPrefix();
|
107 | const rawBody = !!((_a = this.appOptions) === null || _a === void 0 ? void 0 : _a.rawBody);
|
108 | this.httpAdapter.registerParserMiddleware(prefix, rawBody);
|
109 | }
|
110 | async registerRouter() {
|
111 | await this.registerMiddleware(this.httpAdapter);
|
112 | const prefix = this.config.getGlobalPrefix();
|
113 | const basePath = (0, shared_utils_1.addLeadingSlash)(prefix);
|
114 | this.routesResolver.resolve(this.httpAdapter, basePath);
|
115 | }
|
116 | async registerRouterHooks() {
|
117 | this.routesResolver.registerNotFoundHandler();
|
118 | this.routesResolver.registerExceptionHandler();
|
119 | }
|
120 | connectMicroservice(microserviceOptions, hybridAppOptions = {}) {
|
121 | const { NestMicroservice } = (0, load_package_util_1.loadPackage)('@nestjs/microservices', 'NestFactory', () => require('@nestjs/microservices'));
|
122 | const { inheritAppConfig } = hybridAppOptions;
|
123 | const applicationConfig = inheritAppConfig
|
124 | ? this.config
|
125 | : new application_config_1.ApplicationConfig();
|
126 | const instance = new NestMicroservice(this.container, microserviceOptions, applicationConfig);
|
127 | instance.registerListeners();
|
128 | instance.setIsInitialized(true);
|
129 | instance.setIsInitHookCalled(true);
|
130 | this.microservices.push(instance);
|
131 | return instance;
|
132 | }
|
133 | getMicroservices() {
|
134 | return this.microservices;
|
135 | }
|
136 | getHttpServer() {
|
137 | return this.httpServer;
|
138 | }
|
139 | async startAllMicroservices() {
|
140 | await Promise.all(this.microservices.map(msvc => msvc.listen()));
|
141 | return this;
|
142 | }
|
143 | use(...args) {
|
144 | this.httpAdapter.use(...args);
|
145 | return this;
|
146 | }
|
147 | enableCors(options) {
|
148 | this.httpAdapter.enableCors(options);
|
149 | }
|
150 | enableVersioning(options = { type: common_1.VersioningType.URI }) {
|
151 | this.config.enableVersioning(options);
|
152 | return this;
|
153 | }
|
154 | async listen(port, ...args) {
|
155 | !this.isInitialized && (await this.init());
|
156 | return new Promise((resolve, reject) => {
|
157 | const errorHandler = (e) => {
|
158 | var _a;
|
159 | this.logger.error((_a = e === null || e === void 0 ? void 0 : e.toString) === null || _a === void 0 ? void 0 : _a.call(e));
|
160 | reject(e);
|
161 | };
|
162 | this.httpServer.once('error', errorHandler);
|
163 | const isCallbackInOriginalArgs = (0, shared_utils_1.isFunction)(args[args.length - 1]);
|
164 | const listenFnArgs = isCallbackInOriginalArgs
|
165 | ? args.slice(0, args.length - 1)
|
166 | : args;
|
167 | this.httpAdapter.listen(port, ...listenFnArgs, (...originalCallbackArgs) => {
|
168 | var _a, _b;
|
169 | if ((_b = (_a = this.appOptions) === null || _a === void 0 ? void 0 : _a.autoFlushLogs) !== null && _b !== void 0 ? _b : true) {
|
170 | this.flushLogs();
|
171 | }
|
172 | if (originalCallbackArgs[0] instanceof Error) {
|
173 | return reject(originalCallbackArgs[0]);
|
174 | }
|
175 | const address = this.httpServer.address();
|
176 | if (address) {
|
177 | this.httpServer.removeListener('error', errorHandler);
|
178 | this.isListening = true;
|
179 | resolve(this.httpServer);
|
180 | }
|
181 | if (isCallbackInOriginalArgs) {
|
182 | args[args.length - 1](...originalCallbackArgs);
|
183 | }
|
184 | });
|
185 | });
|
186 | }
|
187 | async getUrl() {
|
188 | return new Promise((resolve, reject) => {
|
189 | if (!this.isListening) {
|
190 | this.logger.error(constants_1.MESSAGES.CALL_LISTEN_FIRST);
|
191 | reject(constants_1.MESSAGES.CALL_LISTEN_FIRST);
|
192 | return;
|
193 | }
|
194 | const address = this.httpServer.address();
|
195 | resolve(this.formatAddress(address));
|
196 | });
|
197 | }
|
198 | formatAddress(address) {
|
199 | if ((0, shared_utils_1.isString)(address)) {
|
200 | if ((0, os_1.platform)() === 'win32') {
|
201 | return address;
|
202 | }
|
203 | const basePath = encodeURIComponent(address);
|
204 | return `${this.getProtocol()}+unix://${basePath}`;
|
205 | }
|
206 | let host = this.host();
|
207 | if (address && address.family === 'IPv6') {
|
208 | if (host === '::') {
|
209 | host = '[::1]';
|
210 | }
|
211 | else {
|
212 | host = `[${host}]`;
|
213 | }
|
214 | }
|
215 | else if (host === '0.0.0.0') {
|
216 | host = '127.0.0.1';
|
217 | }
|
218 | return `${this.getProtocol()}://${host}:${address.port}`;
|
219 | }
|
220 | setGlobalPrefix(prefix, options) {
|
221 | this.config.setGlobalPrefix(prefix);
|
222 | if (options) {
|
223 | const exclude = options === null || options === void 0 ? void 0 : options.exclude.map((route) => {
|
224 | if ((0, shared_utils_1.isString)(route)) {
|
225 | return {
|
226 | requestMethod: common_1.RequestMethod.ALL,
|
227 | pathRegex: pathToRegexp((0, shared_utils_1.addLeadingSlash)(route)),
|
228 | };
|
229 | }
|
230 | return {
|
231 | requestMethod: route.method,
|
232 | pathRegex: pathToRegexp((0, shared_utils_1.addLeadingSlash)(route.path)),
|
233 | };
|
234 | });
|
235 | this.config.setGlobalPrefixOptions(Object.assign(Object.assign({}, options), { exclude }));
|
236 | }
|
237 | return this;
|
238 | }
|
239 | useWebSocketAdapter(adapter) {
|
240 | this.config.setIoAdapter(adapter);
|
241 | return this;
|
242 | }
|
243 | useGlobalFilters(...filters) {
|
244 | this.config.useGlobalFilters(...filters);
|
245 | return this;
|
246 | }
|
247 | useGlobalPipes(...pipes) {
|
248 | this.config.useGlobalPipes(...pipes);
|
249 | return this;
|
250 | }
|
251 | useGlobalInterceptors(...interceptors) {
|
252 | this.config.useGlobalInterceptors(...interceptors);
|
253 | return this;
|
254 | }
|
255 | useGlobalGuards(...guards) {
|
256 | this.config.useGlobalGuards(...guards);
|
257 | return this;
|
258 | }
|
259 | useStaticAssets(pathOrOptions, options) {
|
260 | this.httpAdapter.useStaticAssets &&
|
261 | this.httpAdapter.useStaticAssets(pathOrOptions, options);
|
262 | return this;
|
263 | }
|
264 | setBaseViewsDir(path) {
|
265 | this.httpAdapter.setBaseViewsDir && this.httpAdapter.setBaseViewsDir(path);
|
266 | return this;
|
267 | }
|
268 | setViewEngine(engineOrOptions) {
|
269 | this.httpAdapter.setViewEngine &&
|
270 | this.httpAdapter.setViewEngine(engineOrOptions);
|
271 | return this;
|
272 | }
|
273 | host() {
|
274 | const address = this.httpServer.address();
|
275 | if ((0, shared_utils_1.isString)(address)) {
|
276 | return undefined;
|
277 | }
|
278 | return address && address.address;
|
279 | }
|
280 | getProtocol() {
|
281 | return this.appOptions && this.appOptions.httpsOptions ? 'https' : 'http';
|
282 | }
|
283 | async registerMiddleware(instance) {
|
284 | await this.middlewareModule.registerMiddleware(this.middlewareContainer, instance);
|
285 | }
|
286 | }
|
287 | exports.NestApplication = NestApplication;
|