@nestjs/core 11.1.3 → 11.1.5
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/adapters/http-adapter.d.ts +5 -0
- package/adapters/http-adapter.js +8 -0
- package/guards/guards-consumer.js +6 -0
- package/helpers/barrier.d.ts +30 -0
- package/helpers/barrier.js +46 -0
- package/helpers/http-adapter-host.d.ts +6 -0
- package/helpers/http-adapter-host.js +10 -0
- package/injector/container.d.ts +1 -0
- package/injector/container.js +3 -0
- package/injector/injector.d.ts +9 -1
- package/injector/injector.js +50 -8
- package/injector/internal-core-module/internal-core-module-factory.js +4 -1
- package/injector/module-ref.js +4 -1
- package/injector/module.d.ts +1 -1
- package/injector/module.js +2 -1
- package/injector/modules-container.d.ts +21 -0
- package/injector/modules-container.js +25 -0
- package/nest-application.js +4 -1
- package/nest-factory.js +4 -1
- package/package.json +2 -2
- package/repl/native-functions/get-repl-fn.d.ts +7 -0
- package/repl/native-functions/get-repl-fn.js +19 -0
- package/repl/native-functions/index.d.ts +1 -1
- package/repl/native-functions/index.js +1 -1
- package/router/router-explorer.d.ts +1 -1
- package/router/router-explorer.js +13 -3
- package/router/utils/flatten-route-paths.util.js +1 -1
|
@@ -7,6 +7,7 @@ import { NestApplicationOptions } from '@nestjs/common/interfaces/nest-applicati
|
|
|
7
7
|
export declare abstract class AbstractHttpAdapter<TServer = any, TRequest = any, TResponse = any> implements HttpServer<TRequest, TResponse> {
|
|
8
8
|
protected instance?: any | undefined;
|
|
9
9
|
protected httpServer: TServer;
|
|
10
|
+
protected onRouteTriggered: ((requestMethod: RequestMethod, path: string) => void) | undefined;
|
|
10
11
|
constructor(instance?: any | undefined);
|
|
11
12
|
init(): Promise<void>;
|
|
12
13
|
use(...args: any[]): any;
|
|
@@ -49,6 +50,10 @@ export declare abstract class AbstractHttpAdapter<TServer = any, TRequest = any,
|
|
|
49
50
|
setInstance<T = any>(instance: T): void;
|
|
50
51
|
getInstance<T = any>(): T;
|
|
51
52
|
normalizePath(path: string): string;
|
|
53
|
+
setOnRouteTriggered(onRouteTriggered: (requestMethod: RequestMethod, path: string) => void): void;
|
|
54
|
+
getOnRouteTriggered(): ((requestMethod: RequestMethod, path: string) => void) | undefined;
|
|
55
|
+
setOnRequestHook(onRequestHook: Function): void;
|
|
56
|
+
setOnResponseHook(onResponseHook: Function): void;
|
|
52
57
|
abstract close(): any;
|
|
53
58
|
abstract initHttpServer(options: NestApplicationOptions): any;
|
|
54
59
|
abstract useStaticAssets(...args: any[]): any;
|
package/adapters/http-adapter.js
CHANGED
|
@@ -78,5 +78,13 @@ class AbstractHttpAdapter {
|
|
|
78
78
|
normalizePath(path) {
|
|
79
79
|
return path;
|
|
80
80
|
}
|
|
81
|
+
setOnRouteTriggered(onRouteTriggered) {
|
|
82
|
+
this.onRouteTriggered = onRouteTriggered;
|
|
83
|
+
}
|
|
84
|
+
getOnRouteTriggered() {
|
|
85
|
+
return this.onRouteTriggered;
|
|
86
|
+
}
|
|
87
|
+
setOnRequestHook(onRequestHook) { }
|
|
88
|
+
setOnResponseHook(onResponseHook) { }
|
|
81
89
|
}
|
|
82
90
|
exports.AbstractHttpAdapter = AbstractHttpAdapter;
|
|
@@ -13,6 +13,12 @@ class GuardsConsumer {
|
|
|
13
13
|
context.setType(type);
|
|
14
14
|
for (const guard of guards) {
|
|
15
15
|
const result = guard.canActivate(context);
|
|
16
|
+
if (typeof result === 'boolean') {
|
|
17
|
+
if (!result) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
16
22
|
if (await this.pickResult(result)) {
|
|
17
23
|
continue;
|
|
18
24
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A simple barrier to synchronize flow of multiple async operations.
|
|
3
|
+
*/
|
|
4
|
+
export declare class Barrier {
|
|
5
|
+
private currentCount;
|
|
6
|
+
private targetCount;
|
|
7
|
+
private promise;
|
|
8
|
+
private resolve;
|
|
9
|
+
constructor(targetCount: number);
|
|
10
|
+
/**
|
|
11
|
+
* Signal that a participant has reached the barrier.
|
|
12
|
+
*
|
|
13
|
+
* The barrier will be resolved once `targetCount` participants have reached it.
|
|
14
|
+
*/
|
|
15
|
+
signal(): void;
|
|
16
|
+
/**
|
|
17
|
+
* Wait for the barrier to be resolved.
|
|
18
|
+
*
|
|
19
|
+
* @returns A promise that resolves when the barrier is resolved.
|
|
20
|
+
*/
|
|
21
|
+
wait(): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Signal that a participant has reached the barrier and wait for the barrier to be resolved.
|
|
24
|
+
*
|
|
25
|
+
* The barrier will be resolved once `targetCount` participants have reached it.
|
|
26
|
+
*
|
|
27
|
+
* @returns A promise that resolves when the barrier is resolved.
|
|
28
|
+
*/
|
|
29
|
+
signalAndWait(): Promise<void>;
|
|
30
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Barrier = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* A simple barrier to synchronize flow of multiple async operations.
|
|
6
|
+
*/
|
|
7
|
+
class Barrier {
|
|
8
|
+
constructor(targetCount) {
|
|
9
|
+
this.currentCount = 0;
|
|
10
|
+
this.targetCount = targetCount;
|
|
11
|
+
this.promise = new Promise(resolve => {
|
|
12
|
+
this.resolve = resolve;
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Signal that a participant has reached the barrier.
|
|
17
|
+
*
|
|
18
|
+
* The barrier will be resolved once `targetCount` participants have reached it.
|
|
19
|
+
*/
|
|
20
|
+
signal() {
|
|
21
|
+
this.currentCount += 1;
|
|
22
|
+
if (this.currentCount === this.targetCount) {
|
|
23
|
+
this.resolve();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Wait for the barrier to be resolved.
|
|
28
|
+
*
|
|
29
|
+
* @returns A promise that resolves when the barrier is resolved.
|
|
30
|
+
*/
|
|
31
|
+
async wait() {
|
|
32
|
+
return this.promise;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Signal that a participant has reached the barrier and wait for the barrier to be resolved.
|
|
36
|
+
*
|
|
37
|
+
* The barrier will be resolved once `targetCount` participants have reached it.
|
|
38
|
+
*
|
|
39
|
+
* @returns A promise that resolves when the barrier is resolved.
|
|
40
|
+
*/
|
|
41
|
+
async signalAndWait() {
|
|
42
|
+
this.signal();
|
|
43
|
+
return this.wait();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
exports.Barrier = Barrier;
|
|
@@ -15,6 +15,7 @@ import { AbstractHttpAdapter } from '../adapters/http-adapter';
|
|
|
15
15
|
export declare class HttpAdapterHost<T extends AbstractHttpAdapter = AbstractHttpAdapter> {
|
|
16
16
|
private _httpAdapter?;
|
|
17
17
|
private _listen$;
|
|
18
|
+
private _init$;
|
|
18
19
|
private isListening;
|
|
19
20
|
/**
|
|
20
21
|
* Accessor for the underlying `HttpAdapter`
|
|
@@ -34,6 +35,11 @@ export declare class HttpAdapterHost<T extends AbstractHttpAdapter = AbstractHtt
|
|
|
34
35
|
* This event is emitted when the HTTP application is listening for incoming requests.
|
|
35
36
|
*/
|
|
36
37
|
get listen$(): Observable<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Observable that allows to subscribe to the `init` event.
|
|
40
|
+
* This event is emitted when the HTTP application is initialized.
|
|
41
|
+
*/
|
|
42
|
+
get init$(): Observable<void>;
|
|
37
43
|
/**
|
|
38
44
|
* Sets the listening state of the application.
|
|
39
45
|
*/
|
|
@@ -17,6 +17,7 @@ const rxjs_1 = require("rxjs");
|
|
|
17
17
|
class HttpAdapterHost {
|
|
18
18
|
constructor() {
|
|
19
19
|
this._listen$ = new rxjs_1.Subject();
|
|
20
|
+
this._init$ = new rxjs_1.ReplaySubject();
|
|
20
21
|
this.isListening = false;
|
|
21
22
|
}
|
|
22
23
|
/**
|
|
@@ -26,6 +27,8 @@ class HttpAdapterHost {
|
|
|
26
27
|
*/
|
|
27
28
|
set httpAdapter(httpAdapter) {
|
|
28
29
|
this._httpAdapter = httpAdapter;
|
|
30
|
+
this._init$.next();
|
|
31
|
+
this._init$.complete();
|
|
29
32
|
}
|
|
30
33
|
/**
|
|
31
34
|
* Accessor for the underlying `HttpAdapter`
|
|
@@ -43,6 +46,13 @@ class HttpAdapterHost {
|
|
|
43
46
|
get listen$() {
|
|
44
47
|
return this._listen$.asObservable();
|
|
45
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* Observable that allows to subscribe to the `init` event.
|
|
51
|
+
* This event is emitted when the HTTP application is initialized.
|
|
52
|
+
*/
|
|
53
|
+
get init$() {
|
|
54
|
+
return this._init$.asObservable();
|
|
55
|
+
}
|
|
46
56
|
/**
|
|
47
57
|
* Sets the listening state of the application.
|
|
48
58
|
*/
|
package/injector/container.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ export declare class NestContainer {
|
|
|
24
24
|
constructor(_applicationConfig?: ApplicationConfig | undefined, _contextOptions?: NestApplicationContextOptions | undefined);
|
|
25
25
|
get serializedGraph(): SerializedGraph;
|
|
26
26
|
get applicationConfig(): ApplicationConfig | undefined;
|
|
27
|
+
get contextOptions(): NestApplicationContextOptions | undefined;
|
|
27
28
|
setHttpAdapter(httpAdapter: any): void;
|
|
28
29
|
getHttpAdapterRef(): import("..").AbstractHttpAdapter<any, any, any>;
|
|
29
30
|
getHttpAdapterHostRef(): import("..").HttpAdapterHost<import("..").AbstractHttpAdapter<any, any, any>>;
|
package/injector/container.js
CHANGED
|
@@ -38,6 +38,9 @@ class NestContainer {
|
|
|
38
38
|
get applicationConfig() {
|
|
39
39
|
return this._applicationConfig;
|
|
40
40
|
}
|
|
41
|
+
get contextOptions() {
|
|
42
|
+
return this._contextOptions;
|
|
43
|
+
}
|
|
41
44
|
setHttpAdapter(httpAdapter) {
|
|
42
45
|
this.internalProvidersStorage.httpAdapter = httpAdapter;
|
|
43
46
|
if (!this.internalProvidersStorage.httpAdapterHost) {
|
package/injector/injector.d.ts
CHANGED
|
@@ -42,8 +42,16 @@ export interface InjectorDependencyContext {
|
|
|
42
42
|
export declare class Injector {
|
|
43
43
|
private readonly options?;
|
|
44
44
|
private logger;
|
|
45
|
+
private readonly instanceDecorator;
|
|
45
46
|
constructor(options?: {
|
|
47
|
+
/**
|
|
48
|
+
* Whether to enable preview mode.
|
|
49
|
+
*/
|
|
46
50
|
preview: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Function to decorate a freshly created instance.
|
|
53
|
+
*/
|
|
54
|
+
instanceDecorator?: (target: unknown) => unknown;
|
|
47
55
|
} | undefined);
|
|
48
56
|
loadPrototype<T>({ token }: InstanceWrapper<T>, collection: Map<InjectionToken, InstanceWrapper<T>>, contextId?: ContextId): void;
|
|
49
57
|
loadInstance<T>(wrapper: InstanceWrapper<T>, collection: Map<InjectionToken, InstanceWrapper>, moduleRef: Module, contextId?: ContextId, inquirer?: InstanceWrapper): Promise<void>;
|
|
@@ -60,7 +68,7 @@ export declare class Injector {
|
|
|
60
68
|
reflectSelfParams<T>(type: Type<T>): any[];
|
|
61
69
|
resolveSingleParam<T>(wrapper: InstanceWrapper<T>, param: Type<any> | string | symbol, dependencyContext: InjectorDependencyContext, moduleRef: Module, contextId?: ContextId, inquirer?: InstanceWrapper, keyOrIndex?: symbol | string | number): Promise<InstanceWrapper<any>>;
|
|
62
70
|
resolveParamToken<T>(wrapper: InstanceWrapper<T>, param: Type<any> | string | symbol | ForwardReference): any;
|
|
63
|
-
|
|
71
|
+
resolveComponentWrapper<T>(moduleRef: Module, token: InjectionToken, dependencyContext: InjectorDependencyContext, wrapper: InstanceWrapper<T>, contextId?: ContextId, inquirer?: InstanceWrapper, keyOrIndex?: symbol | string | number): Promise<InstanceWrapper>;
|
|
64
72
|
resolveComponentHost<T>(moduleRef: Module, instanceWrapper: InstanceWrapper<T | Promise<T>>, contextId?: ContextId, inquirer?: InstanceWrapper): Promise<InstanceWrapper>;
|
|
65
73
|
lookupComponent<T = any>(providers: Map<Function | string | symbol, InstanceWrapper>, moduleRef: Module, dependencyContext: InjectorDependencyContext, wrapper: InstanceWrapper<T>, contextId?: ContextId, inquirer?: InstanceWrapper, keyOrIndex?: symbol | string | number): Promise<InstanceWrapper<T>>;
|
|
66
74
|
lookupComponentInParentModules<T = any>(dependencyContext: InjectorDependencyContext, moduleRef: Module, wrapper: InstanceWrapper<T>, contextId?: ContextId, inquirer?: InstanceWrapper, keyOrIndex?: symbol | string | number): Promise<any>;
|
package/injector/injector.js
CHANGED
|
@@ -15,10 +15,15 @@ const constants_2 = require("./constants");
|
|
|
15
15
|
const inquirer_1 = require("./inquirer");
|
|
16
16
|
const instance_wrapper_1 = require("./instance-wrapper");
|
|
17
17
|
const settlement_signal_1 = require("./settlement-signal");
|
|
18
|
+
const barrier_1 = require("../helpers/barrier");
|
|
18
19
|
class Injector {
|
|
19
20
|
constructor(options) {
|
|
20
21
|
this.options = options;
|
|
21
22
|
this.logger = new common_1.Logger('InjectorLogger');
|
|
23
|
+
this.instanceDecorator = (target) => target;
|
|
24
|
+
if (options?.instanceDecorator) {
|
|
25
|
+
this.instanceDecorator = options.instanceDecorator;
|
|
26
|
+
}
|
|
22
27
|
}
|
|
23
28
|
loadPrototype({ token }, collection, contextId = constants_2.STATIC_CONTEXT) {
|
|
24
29
|
if (!collection) {
|
|
@@ -116,10 +121,15 @@ class Injector {
|
|
|
116
121
|
const [dependencies, optionalDependenciesIds] = isFactoryProvider
|
|
117
122
|
? this.getFactoryProviderDependencies(wrapper)
|
|
118
123
|
: this.getClassDependencies(wrapper);
|
|
124
|
+
const paramBarrier = new barrier_1.Barrier(dependencies.length);
|
|
119
125
|
let isResolved = true;
|
|
120
126
|
const resolveParam = async (param, index) => {
|
|
121
127
|
try {
|
|
122
128
|
if (this.isInquirer(param, parentInquirer)) {
|
|
129
|
+
/*
|
|
130
|
+
* Signal the barrier to make sure other dependencies do not get stuck waiting forever.
|
|
131
|
+
*/
|
|
132
|
+
paramBarrier.signal();
|
|
123
133
|
return parentInquirer && parentInquirer.instance;
|
|
124
134
|
}
|
|
125
135
|
if (inquirer?.isTransient && parentInquirer) {
|
|
@@ -127,13 +137,26 @@ class Injector {
|
|
|
127
137
|
inquirerId = this.getInquirerId(parentInquirer);
|
|
128
138
|
}
|
|
129
139
|
const paramWrapper = await this.resolveSingleParam(wrapper, param, { index, dependencies }, moduleRef, contextId, inquirer, index);
|
|
130
|
-
|
|
131
|
-
|
|
140
|
+
/*
|
|
141
|
+
* Ensure that all instance wrappers are resolved at this point before we continue.
|
|
142
|
+
* Otherwise the staticity of `wrapper`'s dependency tree may be evaluated incorrectly
|
|
143
|
+
* and result in undefined / null injection.
|
|
144
|
+
*/
|
|
145
|
+
await paramBarrier.signalAndWait();
|
|
146
|
+
const paramWrapperWithInstance = await this.resolveComponentHost(moduleRef, paramWrapper, contextId, inquirer);
|
|
147
|
+
const instanceHost = paramWrapperWithInstance.getInstanceByContextId(this.getContextId(contextId, paramWrapperWithInstance), inquirerId);
|
|
148
|
+
if (!instanceHost.isResolved && !paramWrapperWithInstance.forwardRef) {
|
|
132
149
|
isResolved = false;
|
|
133
150
|
}
|
|
134
151
|
return instanceHost?.instance;
|
|
135
152
|
}
|
|
136
153
|
catch (err) {
|
|
154
|
+
/*
|
|
155
|
+
* Signal the barrier to make sure other dependencies do not get stuck waiting forever. We
|
|
156
|
+
* do not care if this occurs after `Barrier.signalAndWait()` is called in the `try` block
|
|
157
|
+
* because the barrier will always have been resolved by then.
|
|
158
|
+
*/
|
|
159
|
+
paramBarrier.signal();
|
|
137
160
|
const isOptional = optionalDependenciesIds.includes(index);
|
|
138
161
|
if (!isOptional) {
|
|
139
162
|
throw err;
|
|
@@ -199,7 +222,7 @@ class Injector {
|
|
|
199
222
|
throw new undefined_dependency_exception_1.UndefinedDependencyException(wrapper.name, dependencyContext, moduleRef);
|
|
200
223
|
}
|
|
201
224
|
const token = this.resolveParamToken(wrapper, param);
|
|
202
|
-
return this.
|
|
225
|
+
return this.resolveComponentWrapper(moduleRef, token, dependencyContext, wrapper, contextId, inquirer, keyOrIndex);
|
|
203
226
|
}
|
|
204
227
|
resolveParamToken(wrapper, param) {
|
|
205
228
|
if (typeof param === 'object' && 'forwardRef' in param) {
|
|
@@ -208,12 +231,11 @@ class Injector {
|
|
|
208
231
|
}
|
|
209
232
|
return param;
|
|
210
233
|
}
|
|
211
|
-
async
|
|
234
|
+
async resolveComponentWrapper(moduleRef, token, dependencyContext, wrapper, contextId = constants_2.STATIC_CONTEXT, inquirer, keyOrIndex) {
|
|
212
235
|
this.printResolvingDependenciesLog(token, inquirer);
|
|
213
236
|
this.printLookingForProviderLog(token, moduleRef);
|
|
214
237
|
const providers = moduleRef.providers;
|
|
215
|
-
|
|
216
|
-
return this.resolveComponentHost(moduleRef, instanceWrapper, contextId, inquirer);
|
|
238
|
+
return this.lookupComponent(providers, moduleRef, { ...dependencyContext, name: token }, wrapper, contextId, inquirer, keyOrIndex);
|
|
217
239
|
}
|
|
218
240
|
async resolveComponentHost(moduleRef, instanceWrapper, contextId = constants_2.STATIC_CONTEXT, inquirer) {
|
|
219
241
|
const inquirerId = this.getInquirerId(inquirer);
|
|
@@ -309,6 +331,7 @@ class Injector {
|
|
|
309
331
|
return this.loadPropertiesMetadata(metadata, contextId, inquirer);
|
|
310
332
|
}
|
|
311
333
|
const properties = this.reflectProperties(wrapper.metatype);
|
|
334
|
+
const propertyBarrier = new barrier_1.Barrier(properties.length);
|
|
312
335
|
const instances = await Promise.all(properties.map(async (item) => {
|
|
313
336
|
try {
|
|
314
337
|
const dependencyContext = {
|
|
@@ -316,17 +339,34 @@ class Injector {
|
|
|
316
339
|
name: item.name,
|
|
317
340
|
};
|
|
318
341
|
if (this.isInquirer(item.name, parentInquirer)) {
|
|
342
|
+
/*
|
|
343
|
+
* Signal the barrier to make sure other dependencies do not get stuck waiting forever.
|
|
344
|
+
*/
|
|
345
|
+
propertyBarrier.signal();
|
|
319
346
|
return parentInquirer && parentInquirer.instance;
|
|
320
347
|
}
|
|
321
348
|
const paramWrapper = await this.resolveSingleParam(wrapper, item.name, dependencyContext, moduleRef, contextId, inquirer, item.key);
|
|
322
|
-
|
|
349
|
+
/*
|
|
350
|
+
* Ensure that all instance wrappers are resolved at this point before we continue.
|
|
351
|
+
* Otherwise the staticity of `wrapper`'s dependency tree may be evaluated incorrectly
|
|
352
|
+
* and result in undefined / null injection.
|
|
353
|
+
*/
|
|
354
|
+
await propertyBarrier.signalAndWait();
|
|
355
|
+
const paramWrapperWithInstance = await this.resolveComponentHost(moduleRef, paramWrapper, contextId, inquirer);
|
|
356
|
+
if (!paramWrapperWithInstance) {
|
|
323
357
|
return undefined;
|
|
324
358
|
}
|
|
325
359
|
const inquirerId = this.getInquirerId(inquirer);
|
|
326
|
-
const instanceHost =
|
|
360
|
+
const instanceHost = paramWrapperWithInstance.getInstanceByContextId(this.getContextId(contextId, paramWrapperWithInstance), inquirerId);
|
|
327
361
|
return instanceHost.instance;
|
|
328
362
|
}
|
|
329
363
|
catch (err) {
|
|
364
|
+
/*
|
|
365
|
+
* Signal the barrier to make sure other dependencies do not get stuck waiting forever. We
|
|
366
|
+
* do not care if this occurs after `Barrier.signalAndWait()` is called in the `try` block
|
|
367
|
+
* because the barrier will always have been resolved by then.
|
|
368
|
+
*/
|
|
369
|
+
propertyBarrier.signal();
|
|
330
370
|
if (!item.isOptional) {
|
|
331
371
|
throw err;
|
|
332
372
|
}
|
|
@@ -371,10 +411,12 @@ class Injector {
|
|
|
371
411
|
instanceHost.instance = wrapper.forwardRef
|
|
372
412
|
? Object.assign(instanceHost.instance, new metatype(...instances))
|
|
373
413
|
: new metatype(...instances);
|
|
414
|
+
instanceHost.instance = this.instanceDecorator(instanceHost.instance);
|
|
374
415
|
}
|
|
375
416
|
else if (isInContext) {
|
|
376
417
|
const factoryReturnValue = targetMetatype.metatype(...instances);
|
|
377
418
|
instanceHost.instance = await factoryReturnValue;
|
|
419
|
+
instanceHost.instance = this.instanceDecorator(instanceHost.instance);
|
|
378
420
|
}
|
|
379
421
|
instanceHost.isResolved = true;
|
|
380
422
|
return instanceHost.instance;
|
|
@@ -17,7 +17,10 @@ class InternalCoreModuleFactory {
|
|
|
17
17
|
const logger = new common_1.Logger(lazy_module_loader_1.LazyModuleLoader.name, {
|
|
18
18
|
timestamp: false,
|
|
19
19
|
});
|
|
20
|
-
const injector = new injector_1.Injector(
|
|
20
|
+
const injector = new injector_1.Injector({
|
|
21
|
+
preview: container.contextOptions?.preview,
|
|
22
|
+
instanceDecorator: container.contextOptions?.instrument?.instanceDecorator,
|
|
23
|
+
});
|
|
21
24
|
const instanceLoader = new instance_loader_1.InstanceLoader(container, injector, graphInspector, logger);
|
|
22
25
|
return new lazy_module_loader_1.LazyModuleLoader(scanner, instanceLoader, moduleCompiler, container.getModules(), moduleOverrides);
|
|
23
26
|
};
|
package/injector/module-ref.js
CHANGED
|
@@ -18,7 +18,10 @@ class ModuleRef extends abstract_instance_resolver_1.AbstractInstanceResolver {
|
|
|
18
18
|
constructor(container) {
|
|
19
19
|
super();
|
|
20
20
|
this.container = container;
|
|
21
|
-
this.injector = new injector_1.Injector(
|
|
21
|
+
this.injector = new injector_1.Injector({
|
|
22
|
+
preview: container.contextOptions?.preview,
|
|
23
|
+
instanceDecorator: container.contextOptions?.instrument?.instanceDecorator,
|
|
24
|
+
});
|
|
22
25
|
}
|
|
23
26
|
introspect(token) {
|
|
24
27
|
const { wrapperRef } = this.instanceLinksHost.get(token);
|
package/injector/module.d.ts
CHANGED
|
@@ -65,7 +65,7 @@ export declare class Module {
|
|
|
65
65
|
replace(toReplace: InjectionToken, options: any): void;
|
|
66
66
|
hasProvider(token: InjectionToken): boolean;
|
|
67
67
|
hasInjectable(token: InjectionToken): boolean;
|
|
68
|
-
getProviderByKey<T = any>(name: InjectionToken): InstanceWrapper<T>;
|
|
68
|
+
getProviderByKey<T = any>(name: InjectionToken<T>): InstanceWrapper<T>;
|
|
69
69
|
getProviderById<T = any>(id: string): InstanceWrapper<T> | undefined;
|
|
70
70
|
getControllerById<T = any>(id: string): InstanceWrapper<T> | undefined;
|
|
71
71
|
getInjectableById<T = any>(id: string): InstanceWrapper<T> | undefined;
|
package/injector/module.js
CHANGED
|
@@ -239,11 +239,12 @@ class Module {
|
|
|
239
239
|
}
|
|
240
240
|
addCustomValue(provider, collection, enhancerSubtype) {
|
|
241
241
|
const { useValue: value, provide: providerToken } = provider;
|
|
242
|
+
const instanceDecorator = this.container.contextOptions?.instrument?.instanceDecorator;
|
|
242
243
|
collection.set(providerToken, new instance_wrapper_1.InstanceWrapper({
|
|
243
244
|
token: providerToken,
|
|
244
245
|
name: providerToken?.name || providerToken,
|
|
245
246
|
metatype: null,
|
|
246
|
-
instance: value,
|
|
247
|
+
instance: instanceDecorator ? instanceDecorator(value) : value,
|
|
247
248
|
isResolved: true,
|
|
248
249
|
async: value instanceof Promise,
|
|
249
250
|
host: this,
|
|
@@ -1,6 +1,27 @@
|
|
|
1
|
+
import { Observable } from 'rxjs';
|
|
1
2
|
import { Module } from './module';
|
|
2
3
|
export declare class ModulesContainer extends Map<string, Module> {
|
|
3
4
|
private readonly _applicationId;
|
|
5
|
+
private readonly _rpcTargetRegistry$;
|
|
6
|
+
/**
|
|
7
|
+
* Unique identifier of the application instance.
|
|
8
|
+
*/
|
|
4
9
|
get applicationId(): string;
|
|
10
|
+
/**
|
|
11
|
+
* Retrieves a module by its identifier.
|
|
12
|
+
* @param id The identifier of the module to retrieve.
|
|
13
|
+
* @returns The module instance if found, otherwise undefined.
|
|
14
|
+
*/
|
|
5
15
|
getById(id: string): Module | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Returns the RPC target registry as an observable.
|
|
18
|
+
* This registry contains all RPC targets registered in the application.
|
|
19
|
+
* @returns An observable that emits the RPC target registry.
|
|
20
|
+
*/
|
|
21
|
+
getRpcTargetRegistry<T>(): Observable<T>;
|
|
22
|
+
/**
|
|
23
|
+
* Adds an RPC target to the registry.
|
|
24
|
+
* @param target The RPC target to add.
|
|
25
|
+
*/
|
|
26
|
+
addRpcTarget<T>(target: T): void;
|
|
6
27
|
}
|
|
@@ -1,17 +1,42 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ModulesContainer = void 0;
|
|
4
|
+
const rxjs_1 = require("rxjs");
|
|
4
5
|
const uid_1 = require("uid");
|
|
5
6
|
class ModulesContainer extends Map {
|
|
6
7
|
constructor() {
|
|
7
8
|
super(...arguments);
|
|
8
9
|
this._applicationId = (0, uid_1.uid)(21);
|
|
10
|
+
this._rpcTargetRegistry$ = new rxjs_1.ReplaySubject();
|
|
9
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Unique identifier of the application instance.
|
|
14
|
+
*/
|
|
10
15
|
get applicationId() {
|
|
11
16
|
return this._applicationId;
|
|
12
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Retrieves a module by its identifier.
|
|
20
|
+
* @param id The identifier of the module to retrieve.
|
|
21
|
+
* @returns The module instance if found, otherwise undefined.
|
|
22
|
+
*/
|
|
13
23
|
getById(id) {
|
|
14
24
|
return Array.from(this.values()).find(moduleRef => moduleRef.id === id);
|
|
15
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Returns the RPC target registry as an observable.
|
|
28
|
+
* This registry contains all RPC targets registered in the application.
|
|
29
|
+
* @returns An observable that emits the RPC target registry.
|
|
30
|
+
*/
|
|
31
|
+
getRpcTargetRegistry() {
|
|
32
|
+
return this._rpcTargetRegistry$.asObservable();
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Adds an RPC target to the registry.
|
|
36
|
+
* @param target The RPC target to add.
|
|
37
|
+
*/
|
|
38
|
+
addRpcTarget(target) {
|
|
39
|
+
this._rpcTargetRegistry$.next(target);
|
|
40
|
+
}
|
|
16
41
|
}
|
|
17
42
|
exports.ModulesContainer = ModulesContainer;
|
package/nest-application.js
CHANGED
|
@@ -37,7 +37,10 @@ class NestApplication extends nest_application_context_1.NestApplicationContext
|
|
|
37
37
|
this.isListening = false;
|
|
38
38
|
this.selectContextModule();
|
|
39
39
|
this.registerHttpServer();
|
|
40
|
-
this.injector = new injector_1.Injector({
|
|
40
|
+
this.injector = new injector_1.Injector({
|
|
41
|
+
preview: this.appOptions.preview,
|
|
42
|
+
instanceDecorator: appOptions.instrument?.instanceDecorator,
|
|
43
|
+
});
|
|
41
44
|
this.middlewareModule = new middleware_module_1.MiddlewareModule();
|
|
42
45
|
this.routesResolver = new routes_resolver_1.RoutesResolver(this.container, this.config, this.injector, this.graphInspector);
|
|
43
46
|
}
|
package/nest-factory.js
CHANGED
|
@@ -94,7 +94,10 @@ class NestFactoryStatic {
|
|
|
94
94
|
uuid_factory_1.UuidFactory.mode = options.snapshot
|
|
95
95
|
? uuid_factory_1.UuidFactoryMode.Deterministic
|
|
96
96
|
: uuid_factory_1.UuidFactoryMode.Random;
|
|
97
|
-
const injector = new injector_1.Injector({
|
|
97
|
+
const injector = new injector_1.Injector({
|
|
98
|
+
preview: options.preview,
|
|
99
|
+
instanceDecorator: options.instrument?.instanceDecorator,
|
|
100
|
+
});
|
|
98
101
|
const instanceLoader = new instance_loader_1.InstanceLoader(container, injector, graphInspector);
|
|
99
102
|
const metadataScanner = new metadata_scanner_1.MetadataScanner();
|
|
100
103
|
const dependenciesScanner = new scanner_1.DependenciesScanner(container, metadataScanner, graphInspector, config);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nestjs/core",
|
|
3
|
-
"version": "11.1.
|
|
3
|
+
"version": "11.1.5",
|
|
4
4
|
"description": "Nest - modern, fast, powerful node.js web framework (@core)",
|
|
5
5
|
"author": "Kamil Mysliwiec",
|
|
6
6
|
"license": "MIT",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"uid": "2.0.2"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@nestjs/common": "11.1.
|
|
42
|
+
"@nestjs/common": "11.1.5"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
45
|
"@nestjs/common": "^11.0.0",
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Type } from '@nestjs/common';
|
|
2
|
+
import { ReplFunction } from '../repl-function';
|
|
3
|
+
import type { ReplFnDefinition } from '../repl.interfaces';
|
|
4
|
+
export declare class GetReplFn extends ReplFunction {
|
|
5
|
+
fnDefinition: ReplFnDefinition;
|
|
6
|
+
action(token: string | symbol | Function | Type<any>): any;
|
|
7
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GetReplFn = void 0;
|
|
4
|
+
const repl_function_1 = require("../repl-function");
|
|
5
|
+
class GetReplFn extends repl_function_1.ReplFunction {
|
|
6
|
+
constructor() {
|
|
7
|
+
super(...arguments);
|
|
8
|
+
this.fnDefinition = {
|
|
9
|
+
name: 'get',
|
|
10
|
+
signature: '(token: InjectionToken) => any',
|
|
11
|
+
description: 'Retrieves an instance of either injectable or controller, otherwise, throws exception.',
|
|
12
|
+
aliases: ['$'],
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
action(token) {
|
|
16
|
+
return this.ctx.app.get(token);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.GetReplFn = GetReplFn;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
tslib_1.__exportStar(require("./help-repl-fn"), exports);
|
|
5
|
-
tslib_1.__exportStar(require("./get-
|
|
5
|
+
tslib_1.__exportStar(require("./get-repl-fn"), exports);
|
|
6
6
|
tslib_1.__exportStar(require("./resolve-repl-fn"), exports);
|
|
7
7
|
tslib_1.__exportStar(require("./select-relp-fn"), exports);
|
|
8
8
|
tslib_1.__exportStar(require("./debug-repl-fn"), exports);
|
|
@@ -34,7 +34,7 @@ export declare class RouterExplorer {
|
|
|
34
34
|
private readonly logger;
|
|
35
35
|
private readonly exceptionFiltersCache;
|
|
36
36
|
constructor(metadataScanner: MetadataScanner, container: NestContainer, injector: Injector, routerProxy: RouterProxy, exceptionsFilter: ExceptionsFilter, config: ApplicationConfig, routePathFactory: RoutePathFactory, graphInspector: GraphInspector);
|
|
37
|
-
explore<T extends HttpServer = any>(instanceWrapper: InstanceWrapper, moduleKey: string,
|
|
37
|
+
explore<T extends HttpServer = any>(instanceWrapper: InstanceWrapper, moduleKey: string, httpAdapterRef: T, host: string | RegExp | Array<string | RegExp>, routePathMetadata: RoutePathMetadata): void;
|
|
38
38
|
extractRouterPath(metatype: Type<Controller>): string[];
|
|
39
39
|
applyPathsToRouterProxy<T extends HttpServer>(router: T, routeDefinitions: RouteDefinition[], instanceWrapper: InstanceWrapper, moduleKey: string, routePathMetadata: RoutePathMetadata, host: string | RegExp | Array<string | RegExp>): void;
|
|
40
40
|
private applyCallbackToRouter;
|
|
@@ -43,10 +43,10 @@ class RouterExplorer {
|
|
|
43
43
|
const interceptorsConsumer = new interceptors_1.InterceptorsConsumer();
|
|
44
44
|
this.executionContextCreator = new router_execution_context_1.RouterExecutionContext(routeParamsFactory, pipesContextCreator, pipesConsumer, guardsContextCreator, guardsConsumer, interceptorsContextCreator, interceptorsConsumer, container.getHttpAdapterRef());
|
|
45
45
|
}
|
|
46
|
-
explore(instanceWrapper, moduleKey,
|
|
46
|
+
explore(instanceWrapper, moduleKey, httpAdapterRef, host, routePathMetadata) {
|
|
47
47
|
const { instance } = instanceWrapper;
|
|
48
48
|
const routerPaths = this.pathsExplorer.scanForPaths(instance);
|
|
49
|
-
this.applyPathsToRouterProxy(
|
|
49
|
+
this.applyPathsToRouterProxy(httpAdapterRef, routerPaths, instanceWrapper, moduleKey, routePathMetadata, host);
|
|
50
50
|
}
|
|
51
51
|
extractRouterPath(metatype) {
|
|
52
52
|
const path = Reflect.getMetadata(constants_1.PATH_METADATA, metatype);
|
|
@@ -105,7 +105,17 @@ class RouterExplorer {
|
|
|
105
105
|
const normalizedPath = router.normalizePath
|
|
106
106
|
? router.normalizePath(path)
|
|
107
107
|
: path;
|
|
108
|
-
|
|
108
|
+
const httpAdapter = this.container.getHttpAdapterRef();
|
|
109
|
+
const onRouteTriggered = httpAdapter.getOnRouteTriggered?.();
|
|
110
|
+
if (onRouteTriggered) {
|
|
111
|
+
routerMethodRef(normalizedPath, (...args) => {
|
|
112
|
+
onRouteTriggered(requestMethod, path);
|
|
113
|
+
return routeHandler(...args);
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
routerMethodRef(normalizedPath, routeHandler);
|
|
118
|
+
}
|
|
109
119
|
this.graphInspector.insertEntrypointDefinition(entrypointDefinition, instanceWrapper.id);
|
|
110
120
|
});
|
|
111
121
|
const pathsToLog = this.routePathFactory.create({
|
|
@@ -11,7 +11,7 @@ function flattenRoutePaths(routes) {
|
|
|
11
11
|
if (item.children) {
|
|
12
12
|
const childrenRef = item.children;
|
|
13
13
|
childrenRef.forEach(child => {
|
|
14
|
-
if (!(0, shared_utils_1.isString)(child) && child.path) {
|
|
14
|
+
if (!(0, shared_utils_1.isString)(child) && (0, shared_utils_1.isString)(child.path)) {
|
|
15
15
|
child.path = (0, shared_utils_1.normalizePath)((0, shared_utils_1.normalizePath)(item.path) + (0, shared_utils_1.normalizePath)(child.path));
|
|
16
16
|
}
|
|
17
17
|
else {
|