1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const common_1 = require("@nestjs/common");
|
4 | const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
|
5 | const constants_1 = require("./constants");
|
6 | const unknown_element_exception_1 = require("./errors/exceptions/unknown-element.exception");
|
7 | const unknown_module_exception_1 = require("./errors/exceptions/unknown-module.exception");
|
8 | const helpers_1 = require("./helpers");
|
9 | const hooks_1 = require("./hooks");
|
10 | const container_scanner_1 = require("./injector/container-scanner");
|
11 | const injector_1 = require("./injector/injector");
|
12 | const iterare_1 = require("iterare");
|
13 |
|
14 |
|
15 |
|
16 | class NestApplicationContext {
|
17 | constructor(container, scope = new Array(), contextModule = null) {
|
18 | this.container = container;
|
19 | this.scope = scope;
|
20 | this.contextModule = contextModule;
|
21 | this.isInitialized = false;
|
22 | this.injector = new injector_1.Injector();
|
23 | this.activeShutdownSignals = new Array();
|
24 | this.containerScanner = new container_scanner_1.ContainerScanner(container);
|
25 | }
|
26 | selectContextModule() {
|
27 | const modules = this.container.getModules().values();
|
28 | this.contextModule = modules.next().value;
|
29 | }
|
30 | select(moduleType) {
|
31 | const modules = this.container.getModules();
|
32 | const moduleMetatype = this.contextModule.metatype;
|
33 | const scope = this.scope.concat(moduleMetatype);
|
34 | const moduleTokenFactory = this.container.getModuleTokenFactory();
|
35 | const token = moduleTokenFactory.create(moduleType);
|
36 | const selectedModule = modules.get(token);
|
37 | if (!selectedModule) {
|
38 | throw new unknown_module_exception_1.UnknownModuleException();
|
39 | }
|
40 | return new NestApplicationContext(this.container, scope, selectedModule);
|
41 | }
|
42 | get(typeOrToken, options = { strict: false }) {
|
43 | if (!(options && options.strict)) {
|
44 | return this.find(typeOrToken);
|
45 | }
|
46 | return this.findInstanceByToken(typeOrToken, this.contextModule);
|
47 | }
|
48 | resolve(typeOrToken, contextId = helpers_1.createContextId(), options = { strict: false }) {
|
49 | return this.resolvePerContext(typeOrToken, this.contextModule, contextId, options);
|
50 | }
|
51 | |
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 | async init() {
|
58 | if (this.isInitialized) {
|
59 | return this;
|
60 | }
|
61 | await this.callInitHook();
|
62 | await this.callBootstrapHook();
|
63 | this.isInitialized = true;
|
64 | return this;
|
65 | }
|
66 | async close() {
|
67 | await this.callDestroyHook();
|
68 | await this.callBeforeShutdownHook();
|
69 | await this.dispose();
|
70 | await this.callShutdownHook();
|
71 | await this.unsubscribeFromProcessSignals();
|
72 | }
|
73 | useLogger(logger) {
|
74 | common_1.Logger.overrideLogger(logger);
|
75 | }
|
76 | |
77 |
|
78 |
|
79 |
|
80 |
|
81 |
|
82 |
|
83 |
|
84 |
|
85 | enableShutdownHooks(signals = []) {
|
86 | if (shared_utils_1.isEmpty(signals)) {
|
87 | signals = Object.keys(common_1.ShutdownSignal).map((key) => common_1.ShutdownSignal[key]);
|
88 | }
|
89 | else {
|
90 |
|
91 |
|
92 | signals = Array.from(new Set(signals));
|
93 | }
|
94 | signals = iterare_1.iterate(signals)
|
95 | .map((signal) => signal
|
96 | .toString()
|
97 | .toUpperCase()
|
98 | .trim())
|
99 |
|
100 | .filter(signal => !this.activeShutdownSignals.includes(signal))
|
101 | .toArray();
|
102 | this.listenToShutdownSignals(signals);
|
103 | return this;
|
104 | }
|
105 | async dispose() {
|
106 |
|
107 |
|
108 | return Promise.resolve();
|
109 | }
|
110 | |
111 |
|
112 |
|
113 |
|
114 |
|
115 |
|
116 | listenToShutdownSignals(signals) {
|
117 | const cleanup = async (signal) => {
|
118 | try {
|
119 | signals.forEach(sig => process.removeListener(sig, cleanup));
|
120 | await this.callDestroyHook();
|
121 | await this.callBeforeShutdownHook(signal);
|
122 | await this.dispose();
|
123 | await this.callShutdownHook(signal);
|
124 | process.kill(process.pid, signal);
|
125 | }
|
126 | catch (err) {
|
127 | common_1.Logger.error(constants_1.MESSAGES.ERROR_DURING_SHUTDOWN, err.stack, NestApplicationContext.name);
|
128 | process.exit(1);
|
129 | }
|
130 | };
|
131 | this.shutdownCleanupRef = cleanup;
|
132 | signals.forEach((signal) => {
|
133 | this.activeShutdownSignals.push(signal);
|
134 | process.on(signal, cleanup);
|
135 | });
|
136 | }
|
137 | |
138 |
|
139 |
|
140 | unsubscribeFromProcessSignals() {
|
141 | if (!this.shutdownCleanupRef) {
|
142 | return;
|
143 | }
|
144 | this.activeShutdownSignals.forEach(signal => {
|
145 | process.removeListener(signal, this.shutdownCleanupRef);
|
146 | });
|
147 | }
|
148 | |
149 |
|
150 |
|
151 |
|
152 | async callInitHook() {
|
153 | const modulesContainer = this.container.getModules();
|
154 | for (const module of [...modulesContainer.values()].reverse()) {
|
155 | await hooks_1.callModuleInitHook(module);
|
156 | }
|
157 | }
|
158 | |
159 |
|
160 |
|
161 |
|
162 | async callDestroyHook() {
|
163 | const modulesContainer = this.container.getModules();
|
164 | for (const module of modulesContainer.values()) {
|
165 | await hooks_1.callModuleDestroyHook(module);
|
166 | }
|
167 | }
|
168 | |
169 |
|
170 |
|
171 |
|
172 | async callBootstrapHook() {
|
173 | const modulesContainer = this.container.getModules();
|
174 | for (const module of [...modulesContainer.values()].reverse()) {
|
175 | await hooks_1.callModuleBootstrapHook(module);
|
176 | }
|
177 | }
|
178 | |
179 |
|
180 |
|
181 |
|
182 | async callShutdownHook(signal) {
|
183 | const modulesContainer = this.container.getModules();
|
184 | for (const module of [...modulesContainer.values()].reverse()) {
|
185 | await hooks_1.callAppShutdownHook(module, signal);
|
186 | }
|
187 | }
|
188 | |
189 |
|
190 |
|
191 |
|
192 | async callBeforeShutdownHook(signal) {
|
193 | const modulesContainer = this.container.getModules();
|
194 | for (const module of [...modulesContainer.values()].reverse()) {
|
195 | await hooks_1.callBeforeAppShutdownHook(module, signal);
|
196 | }
|
197 | }
|
198 | find(typeOrToken) {
|
199 | return this.containerScanner.find(typeOrToken);
|
200 | }
|
201 | findInstanceByToken(metatypeOrToken, contextModule) {
|
202 | return this.containerScanner.findInstanceByToken(metatypeOrToken, contextModule);
|
203 | }
|
204 | async resolvePerContext(typeOrToken, contextModule, contextId, options) {
|
205 | let wrapper, collection;
|
206 | if (!(options && options.strict)) {
|
207 | [wrapper, collection] = this.containerScanner.getWrapperCollectionPair(typeOrToken);
|
208 | }
|
209 | else {
|
210 | [
|
211 | wrapper,
|
212 | collection,
|
213 | ] = this.containerScanner.getWrapperCollectionPairByHost(typeOrToken, contextModule);
|
214 | }
|
215 | const instance = await this.injector.loadPerContext(wrapper.instance, wrapper.host, collection, contextId);
|
216 | if (!instance) {
|
217 | throw new unknown_element_exception_1.UnknownElementException();
|
218 | }
|
219 | return instance;
|
220 | }
|
221 | }
|
222 | exports.NestApplicationContext = NestApplicationContext;
|