@nestjs/core 11.1.3 → 11.1.4

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.
@@ -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;
@@ -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
  */
@@ -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>>;
@@ -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) {
@@ -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
- resolveComponentInstance<T>(moduleRef: Module, token: InjectionToken, dependencyContext: InjectorDependencyContext, wrapper: InstanceWrapper<T>, contextId?: ContextId, inquirer?: InstanceWrapper, keyOrIndex?: symbol | string | number): Promise<InstanceWrapper>;
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>;
@@ -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
- const instanceHost = paramWrapper.getInstanceByContextId(this.getContextId(contextId, paramWrapper), inquirerId);
131
- if (!instanceHost.isResolved && !paramWrapper.forwardRef) {
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.resolveComponentInstance(moduleRef, token, dependencyContext, wrapper, contextId, inquirer, keyOrIndex);
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 resolveComponentInstance(moduleRef, token, dependencyContext, wrapper, contextId = constants_2.STATIC_CONTEXT, inquirer, keyOrIndex) {
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
- const instanceWrapper = await this.lookupComponent(providers, moduleRef, { ...dependencyContext, name: token }, wrapper, contextId, inquirer, keyOrIndex);
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
- if (!paramWrapper) {
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 = paramWrapper.getInstanceByContextId(this.getContextId(contextId, paramWrapper), inquirerId);
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
  };
@@ -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);
@@ -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;
@@ -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;
@@ -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({ preview: this.appOptions.preview });
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({ preview: options.preview });
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",
3
+ "version": "11.1.4",
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.3"
42
+ "@nestjs/common": "11.1.4"
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;
@@ -1,5 +1,5 @@
1
1
  export * from './help-repl-fn';
2
- export * from './get-relp-fn';
2
+ export * from './get-repl-fn';
3
3
  export * from './resolve-repl-fn';
4
4
  export * from './select-relp-fn';
5
5
  export * from './debug-repl-fn';
@@ -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-relp-fn"), exports);
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, applicationRef: T, host: string | RegExp | Array<string | RegExp>, routePathMetadata: RoutePathMetadata): void;
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, applicationRef, host, routePathMetadata) {
46
+ explore(instanceWrapper, moduleKey, httpAdapterRef, host, routePathMetadata) {
47
47
  const { instance } = instanceWrapper;
48
48
  const routerPaths = this.pathsExplorer.scanForPaths(instance);
49
- this.applyPathsToRouterProxy(applicationRef, routerPaths, instanceWrapper, moduleKey, routePathMetadata, host);
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
- routerMethodRef(normalizedPath, routeHandler);
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 {