@nestjs/core 10.0.5 → 10.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Readme.md +22 -49
- package/errors/exceptions/circular-dependency.exception.js +1 -1
- package/injector/container.d.ts +8 -2
- package/injector/container.js +20 -11
- package/injector/injector.d.ts +2 -1
- package/injector/injector.js +18 -11
- package/injector/instance-wrapper.d.ts +3 -0
- package/injector/instance-wrapper.js +4 -2
- package/injector/lazy-module-loader/lazy-module-loader.js +1 -0
- package/injector/settlement-signal.d.ts +36 -0
- package/injector/settlement-signal.js +52 -0
- package/nest-application.js +3 -0
- package/package.json +2 -2
- package/scanner.d.ts +6 -2
- package/scanner.js +7 -2
package/Readme.md
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
## Description
|
|
25
25
|
|
|
26
|
-
Nest is a framework for building efficient, scalable <a href="
|
|
26
|
+
Nest is a framework for building efficient, scalable <a href="https://nodejs.org" target="_blank">Node.js</a> server-side applications. It uses modern JavaScript, is built with <a href="https://www.typescriptlang.org" target="_blank">TypeScript</a> (preserves compatibility with pure JavaScript) and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Reactive Programming).
|
|
27
27
|
|
|
28
28
|
<p>Under the hood, Nest makes use of <a href="https://expressjs.com/" target="_blank">Express</a>, but also, provides compatibility with a wide range of other libraries, like e.g. <a href="https://github.com/fastify/fastify" target="_blank">Fastify</a>, allowing for easy use of the myriad third-party plugins which are available.</p>
|
|
29
29
|
|
|
@@ -58,24 +58,25 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
|
|
58
58
|
#### Principal Sponsors
|
|
59
59
|
<table style="text-align:center;"><tr>
|
|
60
60
|
<td><a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="200" valign="middle" /></a></td>
|
|
61
|
-
<td><a href="https://www.redhat.com" target="_blank"><img src="https://nestjs.com/img/red-hat-logo.svg" width="200" valign="middle" /></a></td>
|
|
62
|
-
<td>
|
|
63
|
-
<a href="https://github.com/Sanofi-IADC" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/sanofi.png" width="180" valign="middle" /></a></td>
|
|
64
|
-
<td>
|
|
65
|
-
<a href="https://nx.dev" target="_blank"><img src="https://nestjs.com/img/nx-logo.png" height="45" valign="middle" /></a></td>
|
|
66
61
|
<td>
|
|
67
|
-
<a href="https://valor-software.com/" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/valor-software.png" width="170" valign="middle" /></a></td
|
|
68
|
-
<a href="https://amplication.com/" target="_blank"><img src="https://nestjs.com/img/amplication-logo.svg" width="190" valign="middle" /></a></td>
|
|
62
|
+
<a href="https://valor-software.com/" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/valor-software.png" width="170" valign="middle" /></a></td>
|
|
69
63
|
</tr></table>
|
|
70
64
|
|
|
71
65
|
#### Gold Sponsors
|
|
72
66
|
|
|
73
|
-
<table style="text-align:center;"><tr
|
|
67
|
+
<table style="text-align:center;"><tr>
|
|
68
|
+
<td><a href="https://www.redhat.com" target="_blank"><img src="https://nestjs.com/img/red-hat-logo.svg" width="200" valign="middle" /></a></td>
|
|
69
|
+
<td>
|
|
70
|
+
<a href="https://github.com/Sanofi-IADC" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/sanofi.png" width="180" valign="middle" /></a></td>
|
|
71
|
+
<td>
|
|
72
|
+
<a href="https://nx.dev" target="_blank"><img src="https://nestjs.com/img/nx-logo.png" height="45" valign="middle" /></a></td><td>
|
|
73
|
+
<a href="https://amplication.com/" target="_blank"><img src="https://nestjs.com/img/amplication-logo.svg" width="190" valign="middle" /></a></td>
|
|
74
|
+
<td>
|
|
74
75
|
<a href="https://weld.app/" target="_blank"><img src="https://nestjs.com/img/weld-logo.svg" width="140" valign="middle" /></a></td>
|
|
75
76
|
<td>
|
|
76
|
-
<a href="https://intrinsic.ventures/" target="_blank"><img src="https://nestjs.com/img/intrinisic-logo.png" width="210" valign="middle" /></a></td>
|
|
77
|
+
<a href="https://intrinsic.ventures/" target="_blank"><img src="https://nestjs.com/img/intrinisic-logo.png" width="210" valign="middle" /></a></td></tr><tr>
|
|
77
78
|
<td>
|
|
78
|
-
<a href="https://jetbrains.com/" target="_blank"><img src="https://nestjs.com/img/jetbrains-logo.svg" width="
|
|
79
|
+
<a href="https://jetbrains.com/" target="_blank"><img src="https://nestjs.com/img/jetbrains-logo.svg" width="90" valign="middle" /></a></td><td>
|
|
79
80
|
<a href="https://snyk.co/nestjs" target="_blank"><img src="https://nestjs.com/img/snyk-logo-black.png" width="185" valign="middle" /></a></td><td>
|
|
80
81
|
<a href="https://fuseautotech.com/" target="_blank"><img src="https://nestjs.com/img/fuse-logo.svg" width="105" valign="middle" /></a></td>
|
|
81
82
|
<td>
|
|
@@ -84,17 +85,8 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
|
|
84
85
|
|
|
85
86
|
#### Silver Sponsors
|
|
86
87
|
|
|
87
|
-
<table style="text-align:center;"><tr
|
|
88
|
-
<a href="https://
|
|
89
|
-
<a href="http://gojob.com" target="_blank"><img src="http://nestjs.com/img/gojob-logo.png" valign="middle" width="100" /></a> </td><td>
|
|
90
|
-
<a href="https://www.myleodsc.com/" target="_blank"><img src="https://nestjs.com/img/myleo-logo.png" width="180" valign="middle" /></td><td>
|
|
91
|
-
<a href="https://careers.meetdandy.com/?gh_src=063ba61e3us" target="_blank"><img src="https://nestjs.com/img/dandy-roles-logo.svg" width="150" valign="middle" /></td><td>
|
|
92
|
-
<a href="https://www.castlecraft.in" target="_blank"><img src="https://nestjs.com/img/castlecraft-logo.png" width="150" valign="middle" /></td>
|
|
93
|
-
<td><a href="https://www.tinystacks.com" target="_blank"><img src="https://nestjs.com/img/tinystacks-logo.png#1" width="140" valign="middle" /></td>
|
|
94
|
-
<td><a href="https://n.inc" target="_blank"><img src="https://nestjs.com/img/n-inc-logo.svg" width="120" valign="middle" /></td></tr><tr>
|
|
95
|
-
<td><a href="https://bilberrry.com/" target="_blank"><img src="https://nestjs.com/img/bilberrry-logo.svg" width="180" valign="middle" /></td>
|
|
96
|
-
<td><a href="https://ipinfo.ai/" target="_blank"><img src="https://nestjs.com/img/ipinfo-logo.png" width="130" valign="middle" /></td>
|
|
97
|
-
<td><a href="https://chax.at" target="_blank"><img src="https://nestjs.com/img/chaxat-logo.png" width="100" valign="middle" /></td></tr>
|
|
88
|
+
<table style="text-align:center;"><tr>
|
|
89
|
+
<td><a href="https://n.inc" target="_blank"><img src="https://nestjs.com/img/n-inc-logo.svg" width="120" valign="middle" /></td></tr>
|
|
98
90
|
</table>
|
|
99
91
|
|
|
100
92
|
#### Sponsors
|
|
@@ -102,41 +94,22 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
|
|
102
94
|
<table><tr><td align="center" valign="middle">
|
|
103
95
|
<a href="https://www.swingdev.io" target="_blank"><img src="https://nestjs.com/img/swingdev-logo.svg#1" width="110" valign="middle" /> </a></td><td align="center" valign="middle">
|
|
104
96
|
<a href="https://www.novologic.com/" target="_blank"><img src="https://nestjs.com/img/novologic.png" width="110" valign="middle" /></a> </td><td align="center" valign="middle">
|
|
105
|
-
<a href="https://ever.co/" target="_blank"><img src="https://nestjs.com/img/ever-logo.png" width="72" valign="middle" /></a> </td><td align="center" valign="middle">
|
|
106
|
-
<a href="https://blokt.com" target="_blank"><img src="https://nestjs.com/img/blokt-logo.png" width="120" valign="middle" /></a> </td><td align="center" valign="middle">
|
|
107
|
-
<a href="http://architectnow.net/" target="_blank"><img src="https://nestjs.com/img/architectnow.png" width="125" valign="middle" /></a> </td><td align="center" valign="middle">
|
|
108
|
-
<a href="https://quander.io/" target="_blank"><img src="https://nestjs.com/img/quander.png" width="100" valign="middle" /></a> </td></tr><tr><td align="center" valign="middle">
|
|
109
97
|
<a href="https://mantro.net/" target="_blank"><img src="https://nestjs.com/img/mantro-logo.svg" width="95" valign="middle" /></a> </td><td align="center" valign="middle">
|
|
110
98
|
<a href="https://triplebyte.com/" target="_blank"><img src="https://nestjs.com/img/triplebyte.png" width="107" valign="middle" /></a> </td><td align="center" valign="middle">
|
|
111
|
-
<a href="https://
|
|
112
|
-
<a href="https://nearpod.com/" target="_blank"><img src="https://nestjs.com/img/nearpod-logo.svg" width="100" valign="middle" /></a> </td><td align="center" valign="middle">
|
|
113
|
-
<a href="https://clay.global/" target="_blank"><img src="https://nestjs.com/img/clay-logo.svg" width="75" valign="middle" /></a> </td><td align="center" valign="middle">
|
|
114
|
-
<a href="https://firesticktricks.com" target="_blank"><img src="https://nestjs.com/img/firesticktricks-logo.png" width="120" valign="middle" /></a></td></tr><tr><td align="center" valign="middle">
|
|
115
|
-
<a href="https://www.codeguesser.co.uk" target="_blank"><img src="https://nestjs.com/img/codeguesser-logo.svg" width="120" valign="middle" /></a> </td><td align="center" valign="middle">
|
|
116
|
-
<a href="https://f-a.nz/" target="_blank"><img src="https://nestjs.com/img/franz.svg" width="80" valign="middle" /></a> </td><td align="center" valign="middle">
|
|
117
|
-
<a href="https://sparkfabrik.com/" target="_blank"><img src="https://nestjs.com/img/sparkfabrik-logo.png" width="120" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://www.thebigphonestore.co.uk/" target="_blank"><img src="https://nestjs.com/img/the-big-phone-store-logo.png" width="65" valign="middle" /></a></td>
|
|
99
|
+
<a href="https://nearpod.com/" target="_blank"><img src="https://nestjs.com/img/nearpod-logo.svg" width="100" valign="middle" /></a> </td>
|
|
118
100
|
<td align="center" valign="middle">
|
|
119
|
-
<a href="https://genuinebee.com/" target="_blank"><img src="https://nestjs.com/img/genuinebee.svg" width="97" valign="middle" /></a> </td>
|
|
120
|
-
<td align="center" valign="middle"><a href="https://sanyodigital.com/" target="_blank"><img src="https://nestjs.com/img/sanyo-digital.png" width="130" valign="middle" /></a></td
|
|
121
|
-
<td align="center" valign="middle"><a href="https://
|
|
122
|
-
<td align="center" valign="middle"><a href="https://www.najlepszeplatformyforex.pl/blog/broker-xtb/" target="_blank"><img src="https://nestjs.com/img/npf-logo.jpg" width="200" valign="middle" /></a></td></tr><tr>
|
|
123
|
-
<td align="center" valign="middle"><a href="https://thestandarddaily.com/" target="_blank"><img src="https://nestjs.com/img/the-standard-daily-logo.png" width="180" valign="middle" /></a></td>
|
|
124
|
-
<td align="center" valign="middle"><a href="https://houseofangular.io/" target="_blank"><img src="https://nestjs.com/img/house-of-angular.png" width="100" valign="middle" /></a></td>
|
|
101
|
+
<a href="https://genuinebee.com/" target="_blank"><img src="https://nestjs.com/img/genuinebee.svg" width="97" valign="middle" /></a> </td></tr><tr>
|
|
102
|
+
<td align="center" valign="middle"><a href="https://sanyodigital.com/" target="_blank"><img src="https://nestjs.com/img/sanyo-digital.png" width="130" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://vpn-review.com/vpn-for-torrenting" target="_blank"><img src="https://nestjs.com/img/vpn-review-logo.png" width="85" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://lambda-it.ch/" target="_blank"><img src="https://nestjs.com/img/lambda-it-logo.svg" width="115" valign="middle" /></a></td>
|
|
103
|
+
<td align="center" valign="middle"><a href="https://www.najlepszeplatformyforex.pl/blog/broker-xtb/" target="_blank"><img src="https://nestjs.com/img/npf-logo.jpg" width="200" valign="middle" /></a></td>
|
|
125
104
|
<td align="center" valign="middle"><a href="https://rocketech.it/cases/?utm_source=google&utm_medium=badge&utm_campaign=nestjs" target="_blank"><img src="https://nestjs.com/img/rocketech-logo.svg" width="110" valign="middle" /></a></td>
|
|
126
|
-
<td align="center" valign="middle"><a href="https://www.
|
|
127
|
-
<td align="center" valign="middle"><a href="https://studyclerk.com/pay-for-research-paper" target="_blank"><img src="https://nestjs.com/img/studyclerk-logo.png" width="125" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://xyndata.com" target="_blank"><img src="https://nestjs.com/img/xyndata-logo.png" width="125" valign="middle" /></a></td></tr><tr>
|
|
128
|
-
<td align="center" valign="middle"><a href="https://www.anonymistic.com/" target="_blank"><img src="https://nestjs.com/img/anonymistic-logo.png" width="125" valign="middle" /></a></td>
|
|
105
|
+
<td align="center" valign="middle"><a href="https://www.anonymistic.com/" target="_blank"><img src="https://nestjs.com/img/anonymistic-logo.png" width="125" valign="middle" /></a></td></tr><tr>
|
|
129
106
|
<td align="center" valign="middle"><a href="https://www.naologic.com/" target="_blank"><img src="https://nestjs.com/img/naologic-logo.svg" width="125" valign="middle" /></a></td>
|
|
130
|
-
<td align="center" valign="middle"><a href="https://messaged.com/" target="_blank"><img src="https://nestjs.com/img/messaged-logo.png" width="50" valign="middle" /></a></td>
|
|
131
107
|
<td align="center" valign="middle"><a href="https://triplecore.io" target="_blank"><img src="https://nestjs.com/img/triplecore-logo.svg" width="50" valign="middle" /></a></td>
|
|
132
|
-
<td align="center" valign="middle"><a href="https://
|
|
133
|
-
<td align="center" valign="middle"><a href="https://thecasinowizard.com/bonuses/no-deposit-bonuses/" target="_blank"><img src="https://nestjs.com/img/casinowizard-logo.png" width="120" valign="middle" /></a></td></tr><tr>
|
|
108
|
+
<td align="center" valign="middle"><a href="https://thecasinowizard.com/bonuses/no-deposit-bonuses/" target="_blank"><img src="https://nestjs.com/img/casinowizard-logo.png" width="120" valign="middle" /></a></td>
|
|
134
109
|
<td align="center" valign="middle"><a href="https://polygon-software.ch/" target="_blank"><img src="https://nestjs.com/img/polygon-logo.svg" width="120" valign="middle" /></a></td>
|
|
135
|
-
<td align="center" valign="middle"><a href="https://themobilereality.com/" target="_blank"><img src="https://nestjs.com/img/mobile-reality-logo.png" width="45" valign="middle" /></a></td>
|
|
136
110
|
<td align="center" valign="middle"><a href="https://boringowl.io/" target="_blank"><img src="https://nestjs.com/img/boringowl-logo.svg" width="120" valign="middle" /></a></td>
|
|
137
|
-
<td align="center" valign="middle"><a href="https://
|
|
138
|
-
<td align="center" valign="middle"><a href="https://
|
|
139
|
-
<td align="center" valign="middle"><a href="https://doppio.sh/" target="_blank"><img src="https://nestjs.com/img/dopiosh-logo.png" width="50" valign="middle" /></a></td></tr><tr>
|
|
111
|
+
<td align="center" valign="middle"><a href="https://nordbot.app/" target="_blank"><img src="https://nestjs.com/img/nordbot-logo.png" width="120" valign="middle" /></a></td></tr><tr>
|
|
112
|
+
<td align="center" valign="middle"><a href="https://doppio.sh/" target="_blank"><img src="https://nestjs.com/img/dopiosh-logo.png" width="50" valign="middle" /></a></td>
|
|
140
113
|
<td align="center" valign="middle"><a href="https://www.hingehealth.com/" target="_blank"><img src="https://nestjs.com/img/hinge-health-logo.svg" width="100" valign="middle" /></a></td>
|
|
141
114
|
</tr></table>
|
|
142
115
|
|
|
@@ -5,7 +5,7 @@ const runtime_exception_1 = require("./runtime.exception");
|
|
|
5
5
|
class CircularDependencyException extends runtime_exception_1.RuntimeException {
|
|
6
6
|
constructor(context) {
|
|
7
7
|
const ctx = context ? ` inside ${context}` : ``;
|
|
8
|
-
super(`A circular dependency has been detected${ctx}. Please, make sure that each side of a bidirectional relationships are decorated with "forwardRef()".`);
|
|
8
|
+
super(`A circular dependency has been detected${ctx}. Please, make sure that each side of a bidirectional relationships are decorated with "forwardRef()". Note that circular relationships between custom providers (e.g., factories) are not supported since functions cannot be called more than once.`);
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
11
|
exports.CircularDependencyException = CircularDependencyException;
|
package/injector/container.d.ts
CHANGED
|
@@ -26,8 +26,14 @@ export declare class NestContainer {
|
|
|
26
26
|
setHttpAdapter(httpAdapter: any): void;
|
|
27
27
|
getHttpAdapterRef(): import("..").AbstractHttpAdapter<any, any, any>;
|
|
28
28
|
getHttpAdapterHostRef(): import("..").HttpAdapterHost<import("..").AbstractHttpAdapter<any, any, any>>;
|
|
29
|
-
addModule(metatype: ModuleMetatype, scope: ModuleScope): Promise<
|
|
30
|
-
|
|
29
|
+
addModule(metatype: ModuleMetatype, scope: ModuleScope): Promise<{
|
|
30
|
+
moduleRef: Module;
|
|
31
|
+
inserted: boolean;
|
|
32
|
+
} | undefined>;
|
|
33
|
+
replaceModule(metatypeToReplace: ModuleMetatype, newMetatype: ModuleMetatype, scope: ModuleScope): Promise<{
|
|
34
|
+
moduleRef: Module;
|
|
35
|
+
inserted: boolean;
|
|
36
|
+
} | undefined>;
|
|
31
37
|
private setModule;
|
|
32
38
|
addDynamicMetadata(token: string, dynamicModuleMetadata: Partial<DynamicModule>, scope: Type<any>[]): Promise<void>;
|
|
33
39
|
addDynamicModules(modules: any[], scope: Type<any>[]): Promise<void>;
|
package/injector/container.js
CHANGED
|
@@ -51,13 +51,19 @@ class NestContainer {
|
|
|
51
51
|
}
|
|
52
52
|
const { type, dynamicMetadata, token } = await this.moduleCompiler.compile(metatype);
|
|
53
53
|
if (this.modules.has(token)) {
|
|
54
|
-
return
|
|
54
|
+
return {
|
|
55
|
+
moduleRef: this.modules.get(token),
|
|
56
|
+
inserted: true,
|
|
57
|
+
};
|
|
55
58
|
}
|
|
56
|
-
return
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
return {
|
|
60
|
+
moduleRef: await this.setModule({
|
|
61
|
+
token,
|
|
62
|
+
type,
|
|
63
|
+
dynamicMetadata,
|
|
64
|
+
}, scope),
|
|
65
|
+
inserted: true,
|
|
66
|
+
};
|
|
61
67
|
}
|
|
62
68
|
async replaceModule(metatypeToReplace, newMetatype, scope) {
|
|
63
69
|
// In DependenciesScanner#scanForModules we already check for undefined or invalid modules
|
|
@@ -67,11 +73,14 @@ class NestContainer {
|
|
|
67
73
|
}
|
|
68
74
|
const { token } = await this.moduleCompiler.compile(metatypeToReplace);
|
|
69
75
|
const { type, dynamicMetadata } = await this.moduleCompiler.compile(newMetatype);
|
|
70
|
-
return
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
76
|
+
return {
|
|
77
|
+
moduleRef: await this.setModule({
|
|
78
|
+
token,
|
|
79
|
+
type,
|
|
80
|
+
dynamicMetadata,
|
|
81
|
+
}, scope),
|
|
82
|
+
inserted: false,
|
|
83
|
+
};
|
|
75
84
|
}
|
|
76
85
|
async setModule({ token, dynamicMetadata, type }, scope) {
|
|
77
86
|
const moduleRef = new module_1.Module(type, this);
|
package/injector/injector.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { InjectionToken } from '@nestjs/common';
|
|
|
2
2
|
import { Controller, Injectable, Type } from '@nestjs/common/interfaces';
|
|
3
3
|
import { ContextId, InstancePerContext, InstanceWrapper, PropertyMetadata } from './instance-wrapper';
|
|
4
4
|
import { Module } from './module';
|
|
5
|
+
import { SettlementSignal } from './settlement-signal';
|
|
5
6
|
/**
|
|
6
7
|
* The type of an injectable dependency
|
|
7
8
|
*/
|
|
@@ -50,7 +51,7 @@ export declare class Injector {
|
|
|
50
51
|
loadController(wrapper: InstanceWrapper<Controller>, moduleRef: Module, contextId?: ContextId): Promise<void>;
|
|
51
52
|
loadInjectable<T = any>(wrapper: InstanceWrapper<T>, moduleRef: Module, contextId?: ContextId, inquirer?: InstanceWrapper): Promise<void>;
|
|
52
53
|
loadProvider(wrapper: InstanceWrapper<Injectable>, moduleRef: Module, contextId?: ContextId, inquirer?: InstanceWrapper): Promise<void>;
|
|
53
|
-
|
|
54
|
+
applySettlementSignal<T>(instancePerContext: InstancePerContext<T>, host: InstanceWrapper<T>): SettlementSignal;
|
|
54
55
|
resolveConstructorParams<T>(wrapper: InstanceWrapper<T>, moduleRef: Module, inject: InjectorDependency[], callback: (args: unknown[]) => void | Promise<void>, contextId?: ContextId, inquirer?: InstanceWrapper, parentInquirer?: InstanceWrapper): Promise<void>;
|
|
55
56
|
getClassDependencies<T>(wrapper: InstanceWrapper<T>): [InjectorDependency[], number[]];
|
|
56
57
|
getFactoryProviderDependencies<T>(wrapper: InstanceWrapper<T>): [InjectorDependency[], number[]];
|
package/injector/injector.js
CHANGED
|
@@ -7,12 +7,14 @@ const cli_colors_util_1 = require("@nestjs/common/utils/cli-colors.util");
|
|
|
7
7
|
const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
|
|
8
8
|
const iterare_1 = require("iterare");
|
|
9
9
|
const perf_hooks_1 = require("perf_hooks");
|
|
10
|
+
const exceptions_1 = require("../errors/exceptions");
|
|
10
11
|
const runtime_exception_1 = require("../errors/exceptions/runtime.exception");
|
|
11
12
|
const undefined_dependency_exception_1 = require("../errors/exceptions/undefined-dependency.exception");
|
|
12
13
|
const unknown_dependencies_exception_1 = require("../errors/exceptions/unknown-dependencies.exception");
|
|
13
14
|
const constants_2 = require("./constants");
|
|
14
15
|
const inquirer_1 = require("./inquirer");
|
|
15
16
|
const instance_wrapper_1 = require("./instance-wrapper");
|
|
17
|
+
const settlement_signal_1 = require("./settlement-signal");
|
|
16
18
|
class Injector {
|
|
17
19
|
constructor(options) {
|
|
18
20
|
this.options = options;
|
|
@@ -36,13 +38,17 @@ class Injector {
|
|
|
36
38
|
const inquirerId = this.getInquirerId(inquirer);
|
|
37
39
|
const instanceHost = wrapper.getInstanceByContextId(this.getContextId(contextId, wrapper), inquirerId);
|
|
38
40
|
if (instanceHost.isPending) {
|
|
41
|
+
const settlementSignal = wrapper.settlementSignal;
|
|
42
|
+
if (inquirer && settlementSignal?.isCycle(inquirer.id)) {
|
|
43
|
+
throw new exceptions_1.CircularDependencyException(`"${wrapper.name}"`);
|
|
44
|
+
}
|
|
39
45
|
return instanceHost.donePromise.then((err) => {
|
|
40
46
|
if (err) {
|
|
41
47
|
throw err;
|
|
42
48
|
}
|
|
43
49
|
});
|
|
44
50
|
}
|
|
45
|
-
const
|
|
51
|
+
const settlementSignal = this.applySettlementSignal(instanceHost, wrapper);
|
|
46
52
|
const token = wrapper.token || wrapper.name;
|
|
47
53
|
const { inject } = wrapper;
|
|
48
54
|
const targetWrapper = collection.get(token);
|
|
@@ -50,7 +56,7 @@ class Injector {
|
|
|
50
56
|
throw new runtime_exception_1.RuntimeException();
|
|
51
57
|
}
|
|
52
58
|
if (instanceHost.isResolved) {
|
|
53
|
-
return
|
|
59
|
+
return settlementSignal.complete();
|
|
54
60
|
}
|
|
55
61
|
try {
|
|
56
62
|
const t0 = this.getNowTimestamp();
|
|
@@ -59,12 +65,12 @@ class Injector {
|
|
|
59
65
|
const instance = await this.instantiateClass(instances, wrapper, targetWrapper, contextId, inquirer);
|
|
60
66
|
this.applyProperties(instance, properties);
|
|
61
67
|
wrapper.initTime = this.getNowTimestamp() - t0;
|
|
62
|
-
|
|
68
|
+
settlementSignal.complete();
|
|
63
69
|
};
|
|
64
70
|
await this.resolveConstructorParams(wrapper, moduleRef, inject, callback, contextId, wrapper, inquirer);
|
|
65
71
|
}
|
|
66
72
|
catch (err) {
|
|
67
|
-
|
|
73
|
+
settlementSignal.error(err);
|
|
68
74
|
throw err;
|
|
69
75
|
}
|
|
70
76
|
}
|
|
@@ -91,13 +97,12 @@ class Injector {
|
|
|
91
97
|
await this.loadInstance(wrapper, providers, moduleRef, contextId, inquirer);
|
|
92
98
|
await this.loadEnhancersPerContext(wrapper, contextId, wrapper);
|
|
93
99
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
return done;
|
|
100
|
+
applySettlementSignal(instancePerContext, host) {
|
|
101
|
+
const settlementSignal = new settlement_signal_1.SettlementSignal();
|
|
102
|
+
instancePerContext.donePromise = settlementSignal.asPromise();
|
|
103
|
+
instancePerContext.isPending = true;
|
|
104
|
+
host.settlementSignal = settlementSignal;
|
|
105
|
+
return settlementSignal;
|
|
101
106
|
}
|
|
102
107
|
async resolveConstructorParams(wrapper, moduleRef, inject, callback, contextId = constants_2.STATIC_CONTEXT, inquirer, parentInquirer) {
|
|
103
108
|
let inquirerId = this.getInquirerId(inquirer);
|
|
@@ -206,6 +211,7 @@ class Injector {
|
|
|
206
211
|
const inquirerId = this.getInquirerId(inquirer);
|
|
207
212
|
const instanceHost = instanceWrapper.getInstanceByContextId(this.getContextId(contextId, instanceWrapper), inquirerId);
|
|
208
213
|
if (!instanceHost.isResolved && !instanceWrapper.forwardRef) {
|
|
214
|
+
inquirer?.settlementSignal?.insertRef(instanceWrapper.id);
|
|
209
215
|
await this.loadProvider(instanceWrapper, instanceWrapper.host ?? moduleRef, contextId, inquirer);
|
|
210
216
|
}
|
|
211
217
|
else if (!instanceHost.isResolved &&
|
|
@@ -279,6 +285,7 @@ class Injector {
|
|
|
279
285
|
const inquirerId = this.getInquirerId(inquirer);
|
|
280
286
|
const instanceHost = instanceWrapperRef.getInstanceByContextId(this.getContextId(contextId, instanceWrapperRef), inquirerId);
|
|
281
287
|
if (!instanceHost.isResolved && !instanceWrapperRef.forwardRef) {
|
|
288
|
+
wrapper.settlementSignal?.insertRef(instanceWrapperRef.id);
|
|
282
289
|
await this.loadProvider(instanceWrapperRef, relatedModule, contextId, wrapper);
|
|
283
290
|
break;
|
|
284
291
|
}
|
|
@@ -2,6 +2,7 @@ import { Provider, Scope, Type } from '@nestjs/common';
|
|
|
2
2
|
import { EnhancerSubtype } from '@nestjs/common/constants';
|
|
3
3
|
import { FactoryProvider, InjectionToken } from '@nestjs/common/interfaces';
|
|
4
4
|
import { Module } from './module';
|
|
5
|
+
import { SettlementSignal } from './settlement-signal';
|
|
5
6
|
export declare const INSTANCE_METADATA_SYMBOL: unique symbol;
|
|
6
7
|
export declare const INSTANCE_ID_SYMBOL: unique symbol;
|
|
7
8
|
export interface HostComponentInfo {
|
|
@@ -42,6 +43,7 @@ export declare class InstanceWrapper<T = any> {
|
|
|
42
43
|
forwardRef?: boolean;
|
|
43
44
|
durable?: boolean;
|
|
44
45
|
initTime?: number;
|
|
46
|
+
settlementSignal?: SettlementSignal;
|
|
45
47
|
private static logger;
|
|
46
48
|
private readonly values;
|
|
47
49
|
private readonly [INSTANCE_METADATA_SYMBOL];
|
|
@@ -54,6 +56,7 @@ export declare class InstanceWrapper<T = any> {
|
|
|
54
56
|
set instance(value: T);
|
|
55
57
|
get instance(): T;
|
|
56
58
|
get isNotMetatype(): boolean;
|
|
59
|
+
get isFactory(): boolean;
|
|
57
60
|
get isTransient(): boolean;
|
|
58
61
|
getInstanceByContextId(contextId: ContextId, inquirerId?: string): InstancePerContext<T>;
|
|
59
62
|
getInstanceByInquirerId(contextId: ContextId, inquirerId: string): InstancePerContext<T>;
|
|
@@ -33,8 +33,10 @@ class InstanceWrapper {
|
|
|
33
33
|
return instancePerContext.instance;
|
|
34
34
|
}
|
|
35
35
|
get isNotMetatype() {
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
return !this.metatype || this.isFactory;
|
|
37
|
+
}
|
|
38
|
+
get isFactory() {
|
|
39
|
+
return this.metatype && !(0, shared_utils_1.isNil)(this.inject);
|
|
38
40
|
}
|
|
39
41
|
get isTransient() {
|
|
40
42
|
return this.scope === common_1.Scope.TRANSIENT;
|
|
@@ -17,6 +17,7 @@ class LazyModuleLoader {
|
|
|
17
17
|
const moduleInstances = await this.dependenciesScanner.scanForModules({
|
|
18
18
|
moduleDefinition: moduleClassOrDynamicDefinition,
|
|
19
19
|
overrides: this.moduleOverrides,
|
|
20
|
+
lazy: true,
|
|
20
21
|
});
|
|
21
22
|
if (moduleInstances.length === 0) {
|
|
22
23
|
// The module has been loaded already. In this case, we must
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SettlementSignal is used to signal the resolution of a provider/instance.
|
|
3
|
+
* Calling `complete` or `error` will resolve the promise returned by `asPromise`.
|
|
4
|
+
* Can be used to detect circular dependencies.
|
|
5
|
+
*/
|
|
6
|
+
export declare class SettlementSignal {
|
|
7
|
+
private readonly _refs;
|
|
8
|
+
private readonly settledPromise;
|
|
9
|
+
private settleFn;
|
|
10
|
+
constructor();
|
|
11
|
+
/**
|
|
12
|
+
* Resolves the promise returned by `asPromise`.
|
|
13
|
+
*/
|
|
14
|
+
complete(): void;
|
|
15
|
+
/**
|
|
16
|
+
* Rejects the promise returned by `asPromise` with the given error.
|
|
17
|
+
* @param err Error to reject the promise returned by `asPromise` with.
|
|
18
|
+
*/
|
|
19
|
+
error(err: unknown): void;
|
|
20
|
+
/**
|
|
21
|
+
* Returns a promise that will be resolved when `complete` or `error` is called.
|
|
22
|
+
* @returns Promise that will be resolved when `complete` or `error` is called.
|
|
23
|
+
*/
|
|
24
|
+
asPromise(): Promise<unknown>;
|
|
25
|
+
/**
|
|
26
|
+
* Inserts a wrapper id that the host of this signal depends on.
|
|
27
|
+
* @param wrapperId Wrapper id to insert.
|
|
28
|
+
*/
|
|
29
|
+
insertRef(wrapperId: string): void;
|
|
30
|
+
/**
|
|
31
|
+
* Check if relationship is circular.
|
|
32
|
+
* @param wrapperId Wrapper id to check.
|
|
33
|
+
* @returns True if relationship is circular, false otherwise.
|
|
34
|
+
*/
|
|
35
|
+
isCycle(wrapperId: string): boolean;
|
|
36
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SettlementSignal = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* SettlementSignal is used to signal the resolution of a provider/instance.
|
|
6
|
+
* Calling `complete` or `error` will resolve the promise returned by `asPromise`.
|
|
7
|
+
* Can be used to detect circular dependencies.
|
|
8
|
+
*/
|
|
9
|
+
class SettlementSignal {
|
|
10
|
+
constructor() {
|
|
11
|
+
this._refs = new Set();
|
|
12
|
+
this.settledPromise = new Promise(resolve => {
|
|
13
|
+
this.settleFn = resolve;
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Resolves the promise returned by `asPromise`.
|
|
18
|
+
*/
|
|
19
|
+
complete() {
|
|
20
|
+
this.settleFn();
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Rejects the promise returned by `asPromise` with the given error.
|
|
24
|
+
* @param err Error to reject the promise returned by `asPromise` with.
|
|
25
|
+
*/
|
|
26
|
+
error(err) {
|
|
27
|
+
this.settleFn(err);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Returns a promise that will be resolved when `complete` or `error` is called.
|
|
31
|
+
* @returns Promise that will be resolved when `complete` or `error` is called.
|
|
32
|
+
*/
|
|
33
|
+
asPromise() {
|
|
34
|
+
return this.settledPromise;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Inserts a wrapper id that the host of this signal depends on.
|
|
38
|
+
* @param wrapperId Wrapper id to insert.
|
|
39
|
+
*/
|
|
40
|
+
insertRef(wrapperId) {
|
|
41
|
+
this._refs.add(wrapperId);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Check if relationship is circular.
|
|
45
|
+
* @param wrapperId Wrapper id to check.
|
|
46
|
+
* @returns True if relationship is circular, false otherwise.
|
|
47
|
+
*/
|
|
48
|
+
isCycle(wrapperId) {
|
|
49
|
+
return this._refs.has(wrapperId);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.SettlementSignal = SettlementSignal;
|
package/nest-application.js
CHANGED
|
@@ -88,6 +88,9 @@ class NestApplication extends nest_application_context_1.NestApplicationContext
|
|
|
88
88
|
this.socketModule.register(this.container, this.config, this.graphInspector, this.appOptions, this.httpServer);
|
|
89
89
|
}
|
|
90
90
|
async init() {
|
|
91
|
+
if (this.isInitialized) {
|
|
92
|
+
return this;
|
|
93
|
+
}
|
|
91
94
|
this.applyOptions();
|
|
92
95
|
await this.httpAdapter?.init();
|
|
93
96
|
const useBodyParser = this.appOptions && this.appOptions.bodyParser !== false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nestjs/core",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.1.1",
|
|
4
4
|
"description": "Nest - modern, fast, powerful node.js web framework (@core)",
|
|
5
5
|
"author": "Kamil Mysliwiec",
|
|
6
6
|
"license": "MIT",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"uid": "2.0.2"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@nestjs/common": "10.
|
|
39
|
+
"@nestjs/common": "10.1.1"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"@nestjs/common": "^10.0.0",
|
package/scanner.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ interface ModulesScanParameters {
|
|
|
14
14
|
scope?: Type<unknown>[];
|
|
15
15
|
ctxRegistry?: (ForwardReference | DynamicModule | Type<unknown>)[];
|
|
16
16
|
overrides?: ModuleOverride[];
|
|
17
|
+
lazy?: boolean;
|
|
17
18
|
}
|
|
18
19
|
export declare class DependenciesScanner {
|
|
19
20
|
private readonly container;
|
|
@@ -25,8 +26,11 @@ export declare class DependenciesScanner {
|
|
|
25
26
|
scan(module: Type<any>, options?: {
|
|
26
27
|
overrides?: ModuleOverride[];
|
|
27
28
|
}): Promise<void>;
|
|
28
|
-
scanForModules({ moduleDefinition, scope, ctxRegistry, overrides, }: ModulesScanParameters): Promise<Module[]>;
|
|
29
|
-
insertModule(moduleDefinition: any, scope: Type<unknown>[]): Promise<
|
|
29
|
+
scanForModules({ moduleDefinition, lazy, scope, ctxRegistry, overrides, }: ModulesScanParameters): Promise<Module[]>;
|
|
30
|
+
insertModule(moduleDefinition: any, scope: Type<unknown>[]): Promise<{
|
|
31
|
+
moduleRef: Module;
|
|
32
|
+
inserted: boolean;
|
|
33
|
+
} | undefined>;
|
|
30
34
|
scanModulesForDependencies(modules?: Map<string, Module>): Promise<void>;
|
|
31
35
|
reflectImports(module: Type<unknown>, token: string, context: string): Promise<void>;
|
|
32
36
|
reflectProviders(module: Type<any>, token: string): void;
|
package/scanner.js
CHANGED
|
@@ -33,8 +33,9 @@ class DependenciesScanner {
|
|
|
33
33
|
this.addScopedEnhancersMetadata();
|
|
34
34
|
this.container.bindGlobalScope();
|
|
35
35
|
}
|
|
36
|
-
async scanForModules({ moduleDefinition, scope = [], ctxRegistry = [], overrides = [], }) {
|
|
37
|
-
const moduleInstance = await this.insertOrOverrideModule(moduleDefinition, overrides, scope)
|
|
36
|
+
async scanForModules({ moduleDefinition, lazy, scope = [], ctxRegistry = [], overrides = [], }) {
|
|
37
|
+
const { moduleRef: moduleInstance, inserted: moduleInserted } = (await this.insertOrOverrideModule(moduleDefinition, overrides, scope)) ??
|
|
38
|
+
{};
|
|
38
39
|
moduleDefinition =
|
|
39
40
|
this.getOverrideModuleByModule(moduleDefinition, overrides)?.newModule ??
|
|
40
41
|
moduleDefinition;
|
|
@@ -69,12 +70,16 @@ class DependenciesScanner {
|
|
|
69
70
|
scope: [].concat(scope, moduleDefinition),
|
|
70
71
|
ctxRegistry,
|
|
71
72
|
overrides,
|
|
73
|
+
lazy,
|
|
72
74
|
});
|
|
73
75
|
registeredModuleRefs = registeredModuleRefs.concat(moduleRefs);
|
|
74
76
|
}
|
|
75
77
|
if (!moduleInstance) {
|
|
76
78
|
return registeredModuleRefs;
|
|
77
79
|
}
|
|
80
|
+
if (lazy && moduleInserted) {
|
|
81
|
+
this.container.bindGlobalsToImports(moduleInstance);
|
|
82
|
+
}
|
|
78
83
|
return [moduleInstance].concat(registeredModuleRefs);
|
|
79
84
|
}
|
|
80
85
|
async insertModule(moduleDefinition, scope) {
|