@nestjs/core 10.1.3 → 10.2.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 CHANGED
@@ -23,7 +23,7 @@
23
23
 
24
24
  ## Description
25
25
 
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).
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
 
@@ -34,10 +34,10 @@ Nest is a framework for building efficient, scalable <a href="https://nodejs.org
34
34
 
35
35
  ## Getting started
36
36
 
37
- * To check out the [guide](https://docs.nestjs.com), visit [docs.nestjs.com](https://docs.nestjs.com). :books:
38
- * 要查看中文 [指南](readme_zh.md), 请访问 [docs.nestjs.cn](https://docs.nestjs.cn). :books:
39
- * [가이드](readme_kr.md) 문서는 [docs.nestjs.com](https://docs.nestjs.com)에서 확인하실 수 있습니다. :books:
40
- * [ガイド](readme_jp.md)は [docs.nestjs.com](https://docs.nestjs.com)でご確認ください。 :books:
37
+ - To check out the [guide](https://docs.nestjs.com), visit [docs.nestjs.com](https://docs.nestjs.com). :books:
38
+ - 要查看中文 [指南](readme_zh.md), 请访问 [docs.nestjs.cn](https://docs.nestjs.cn). :books:
39
+ - [가이드](readme_kr.md) 문서는 [docs.nestjs.com](https://docs.nestjs.com)에서 확인하실 수 있습니다. :books:
40
+ - [ガイド](readme_jp.md)は [docs.nestjs.com](https://docs.nestjs.com)でご確認ください。 :books:
41
41
 
42
42
  ## Questions
43
43
 
@@ -56,10 +56,13 @@ With official support, you can get expert help straight from Nest core team. We
56
56
  Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support from the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
57
57
 
58
58
  #### Principal Sponsors
59
+
59
60
  <table style="text-align:center;"><tr>
60
61
  <td><a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="200" valign="middle" /></a></td>
61
62
  <td>
62
63
  <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>
64
+ <td>
65
+ <a href="https://amplication.com/" target="_blank"><img src="https://nestjs.com/img/amplication-logo.svg" width="190" valign="middle" /></a></td>
63
66
  </tr></table>
64
67
 
65
68
  #### Gold Sponsors
@@ -69,8 +72,7 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
69
72
  <td>
70
73
  <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
74
  <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>
75
+ <a href="https://nx.dev" target="_blank"><img src="https://nestjs.com/img/nx-logo.png" height="45" valign="middle" /></a></td>
74
76
  <td>
75
77
  <a href="https://weld.app/" target="_blank"><img src="https://nestjs.com/img/weld-logo.svg" width="140" valign="middle" /></a></td>
76
78
  <td>
@@ -86,7 +88,8 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
86
88
  #### Silver Sponsors
87
89
 
88
90
  <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>
91
+ <td><a href="https://n.inc" target="_blank"><img src="https://nestjs.com/img/n-inc-logo.svg" width="120" valign="middle" /></td>
92
+ <td><a href="https://twistag.com/" target="_blank"><img src="https://nestjs.com/img/twistag-logo.png" width="120" valign="middle" /></td></tr>
90
93
  </table>
91
94
 
92
95
  #### Sponsors
@@ -121,9 +124,9 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
121
124
 
122
125
  ## Stay in touch
123
126
 
124
- * Author - [Kamil Myśliwiec](https://twitter.com/kammysliwiec)
125
- * Website - [https://nestjs.com](https://nestjs.com/)
126
- * Twitter - [@nestframework](https://twitter.com/nestframework)
127
+ - Author - [Kamil Myśliwiec](https://twitter.com/kammysliwiec)
128
+ - Website - [https://nestjs.com](https://nestjs.com/)
129
+ - Twitter - [@nestframework](https://twitter.com/nestframework)
127
130
 
128
131
  ## License
129
132
 
@@ -0,0 +1,46 @@
1
+ import { Type } from '@nestjs/common';
2
+ import { InstanceWrapper } from '../injector/instance-wrapper';
3
+ import { ModulesContainer } from '../injector/modules-container';
4
+ export declare class DiscoverableMetaHostCollection {
5
+ /**
6
+ * A map of class references to metadata keys.
7
+ */
8
+ static readonly metaHostLinks: Map<Function | Type<any>, string>;
9
+ /**
10
+ * A map of metadata keys to instance wrappers (providers) with the corresponding metadata key.
11
+ * The map is weakly referenced by the modules container (unique per application).
12
+ */
13
+ private static readonly providersByMetaKey;
14
+ /**
15
+ * A map of metadata keys to instance wrappers (controllers) with the corresponding metadata key.
16
+ * The map is weakly referenced by the modules container (unique per application).
17
+ */
18
+ private static readonly controllersByMetaKey;
19
+ /**
20
+ * Adds a link between a class reference and a metadata key.
21
+ * @param target The class reference.
22
+ * @param metadataKey The metadata key.
23
+ */
24
+ static addClassMetaHostLink(target: Type | Function, metadataKey: string): void;
25
+ /**
26
+ * Inspects a provider instance wrapper and adds it to the collection of providers
27
+ * if it has a metadata key.
28
+ * @param hostContainerRef A reference to the modules container.
29
+ * @param instanceWrapper A provider instance wrapper.
30
+ * @returns void
31
+ */
32
+ static inspectProvider(hostContainerRef: ModulesContainer, instanceWrapper: InstanceWrapper): void;
33
+ /**
34
+ * Inspects a controller instance wrapper and adds it to the collection of controllers
35
+ * if it has a metadata key.
36
+ * @param hostContainerRef A reference to the modules container.
37
+ * @param instanceWrapper A controller's instance wrapper.
38
+ * @returns void
39
+ */
40
+ static inspectController(hostContainerRef: ModulesContainer, instanceWrapper: InstanceWrapper): void;
41
+ static insertByMetaKey(metaKey: string, instanceWrapper: InstanceWrapper, collection: Map<string, Set<InstanceWrapper>>): void;
42
+ static getProvidersByMetaKey(hostContainerRef: ModulesContainer, metaKey: string): Set<InstanceWrapper>;
43
+ static getControllersByMetaKey(hostContainerRef: ModulesContainer, metaKey: string): Set<InstanceWrapper>;
44
+ private static inspectInstanceWrapper;
45
+ private static getMetaKeyByInstanceWrapper;
46
+ }
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DiscoverableMetaHostCollection = void 0;
4
+ class DiscoverableMetaHostCollection {
5
+ /**
6
+ * Adds a link between a class reference and a metadata key.
7
+ * @param target The class reference.
8
+ * @param metadataKey The metadata key.
9
+ */
10
+ static addClassMetaHostLink(target, metadataKey) {
11
+ this.metaHostLinks.set(target, metadataKey);
12
+ }
13
+ /**
14
+ * Inspects a provider instance wrapper and adds it to the collection of providers
15
+ * if it has a metadata key.
16
+ * @param hostContainerRef A reference to the modules container.
17
+ * @param instanceWrapper A provider instance wrapper.
18
+ * @returns void
19
+ */
20
+ static inspectProvider(hostContainerRef, instanceWrapper) {
21
+ return this.inspectInstanceWrapper(hostContainerRef, instanceWrapper, this.providersByMetaKey);
22
+ }
23
+ /**
24
+ * Inspects a controller instance wrapper and adds it to the collection of controllers
25
+ * if it has a metadata key.
26
+ * @param hostContainerRef A reference to the modules container.
27
+ * @param instanceWrapper A controller's instance wrapper.
28
+ * @returns void
29
+ */
30
+ static inspectController(hostContainerRef, instanceWrapper) {
31
+ return this.inspectInstanceWrapper(hostContainerRef, instanceWrapper, this.controllersByMetaKey);
32
+ }
33
+ static insertByMetaKey(metaKey, instanceWrapper, collection) {
34
+ if (collection.has(metaKey)) {
35
+ const wrappers = collection.get(metaKey);
36
+ wrappers.add(instanceWrapper);
37
+ }
38
+ else {
39
+ const wrappers = new Set();
40
+ wrappers.add(instanceWrapper);
41
+ collection.set(metaKey, wrappers);
42
+ }
43
+ }
44
+ static getProvidersByMetaKey(hostContainerRef, metaKey) {
45
+ const wrappersByMetaKey = this.providersByMetaKey.get(hostContainerRef);
46
+ return wrappersByMetaKey.get(metaKey);
47
+ }
48
+ static getControllersByMetaKey(hostContainerRef, metaKey) {
49
+ const wrappersByMetaKey = this.controllersByMetaKey.get(hostContainerRef);
50
+ return wrappersByMetaKey.get(metaKey);
51
+ }
52
+ static inspectInstanceWrapper(hostContainerRef, instanceWrapper, wrapperByMetaKeyMap) {
53
+ const metaKey = DiscoverableMetaHostCollection.getMetaKeyByInstanceWrapper(instanceWrapper);
54
+ if (!metaKey) {
55
+ return;
56
+ }
57
+ let collection;
58
+ if (wrapperByMetaKeyMap.has(hostContainerRef)) {
59
+ collection = wrapperByMetaKeyMap.get(hostContainerRef);
60
+ }
61
+ else {
62
+ collection = new Map();
63
+ wrapperByMetaKeyMap.set(hostContainerRef, collection);
64
+ }
65
+ this.insertByMetaKey(metaKey, instanceWrapper, collection);
66
+ }
67
+ static getMetaKeyByInstanceWrapper(instanceWrapper) {
68
+ return this.metaHostLinks.get(
69
+ // NOTE: Regarding the ternary statement below,
70
+ // - The condition `!wrapper.metatype` is needed because when we use `useValue`
71
+ // the value of `wrapper.metatype` will be `null`.
72
+ // - The condition `wrapper.inject` is needed here because when we use
73
+ // `useFactory`, the value of `wrapper.metatype` will be the supplied
74
+ // factory function.
75
+ // For both cases, we should use `wrapper.instance.constructor` instead
76
+ // of `wrapper.metatype` to resolve processor's class properly.
77
+ // But since calling `wrapper.instance` could degrade overall performance
78
+ // we must defer it as much we can.
79
+ instanceWrapper.metatype || instanceWrapper.inject
80
+ ? instanceWrapper.instance?.constructor ?? instanceWrapper.metatype
81
+ : instanceWrapper.metatype);
82
+ }
83
+ }
84
+ exports.DiscoverableMetaHostCollection = DiscoverableMetaHostCollection;
85
+ /**
86
+ * A map of class references to metadata keys.
87
+ */
88
+ DiscoverableMetaHostCollection.metaHostLinks = new Map();
89
+ /**
90
+ * A map of metadata keys to instance wrappers (providers) with the corresponding metadata key.
91
+ * The map is weakly referenced by the modules container (unique per application).
92
+ */
93
+ DiscoverableMetaHostCollection.providersByMetaKey = new WeakMap();
94
+ /**
95
+ * A map of metadata keys to instance wrappers (controllers) with the corresponding metadata key.
96
+ * The map is weakly referenced by the modules container (unique per application).
97
+ */
98
+ DiscoverableMetaHostCollection.controllersByMetaKey = new WeakMap();
@@ -1,20 +1,76 @@
1
+ import { CustomDecorator } from '@nestjs/common';
1
2
  import { InstanceWrapper } from '../injector/instance-wrapper';
2
3
  import { Module } from '../injector/module';
3
4
  import { ModulesContainer } from '../injector/modules-container';
4
5
  /**
5
6
  * @publicApi
6
7
  */
7
- export interface DiscoveryOptions {
8
+ export interface FilterByInclude {
9
+ /**
10
+ * List of modules to include (whitelist) into the discovery process.
11
+ */
8
12
  include?: Function[];
9
13
  }
14
+ /**
15
+ * @publicApi
16
+ */
17
+ export interface FilterByMetadataKey {
18
+ /**
19
+ * A key to filter controllers and providers by.
20
+ * Only instance wrappers with the specified metadata key will be returned.
21
+ */
22
+ metadataKey?: string;
23
+ }
24
+ /**
25
+ * @publicApi
26
+ */
27
+ export type DiscoveryOptions = FilterByInclude | FilterByMetadataKey;
28
+ /**
29
+ * @publicApi
30
+ */
31
+ export type DiscoverableDecorator<T> = ((opts?: T) => CustomDecorator) & {
32
+ KEY: string;
33
+ };
10
34
  /**
11
35
  * @publicApi
12
36
  */
13
37
  export declare class DiscoveryService {
14
38
  private readonly modulesContainer;
15
39
  constructor(modulesContainer: ModulesContainer);
40
+ /**
41
+ * Creates a decorator that can be used to decorate classes and methods with metadata.
42
+ * The decorator will also add the class to the collection of discoverable classes (by metadata key).
43
+ * Decorated classes can be discovered using the `getProviders` and `getControllers` methods.
44
+ * @returns A decorator function.
45
+ */
46
+ static createDecorator<T>(): DiscoverableDecorator<T>;
47
+ /**
48
+ * Returns an array of instance wrappers (providers).
49
+ * Depending on the options, the array will contain either all providers or only providers with the specified metadata key.
50
+ * @param options Discovery options.
51
+ * @param modules A list of modules to filter by.
52
+ * @returns An array of instance wrappers (providers).
53
+ */
16
54
  getProviders(options?: DiscoveryOptions, modules?: Module[]): InstanceWrapper[];
55
+ /**
56
+ * Returns an array of instance wrappers (controllers).
57
+ * Depending on the options, the array will contain either all controllers or only controllers with the specified metadata key.
58
+ * @param options Discovery options.
59
+ * @param modules A list of modules to filter by.
60
+ * @returns An array of instance wrappers (controllers).
61
+ */
17
62
  getControllers(options?: DiscoveryOptions, modules?: Module[]): InstanceWrapper[];
63
+ /**
64
+ * Retrieves metadata from the specified instance wrapper.
65
+ * @param decorator The decorator to retrieve metadata of.
66
+ * @param instanceWrapper Reference to the instance wrapper.
67
+ * @param methodKey An optional method key to retrieve metadata from.
68
+ * @returns Discovered metadata.
69
+ */
70
+ getMetadataByDecorator<T extends DiscoverableDecorator<any>>(decorator: T, instanceWrapper: InstanceWrapper, methodKey?: string): T extends DiscoverableDecorator<infer R> ? R | undefined : T | undefined;
71
+ /**
72
+ * Returns a list of modules to be used for discovery.
73
+ */
18
74
  protected getModules(options?: DiscoveryOptions): Module[];
19
75
  private includeWhitelisted;
20
76
  }
@@ -3,7 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DiscoveryService = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const common_1 = require("@nestjs/common");
6
+ const uid_1 = require("uid");
6
7
  const modules_container_1 = require("../injector/modules-container");
8
+ const discoverable_meta_host_collection_1 = require("./discoverable-meta-host-collection");
7
9
  /**
8
10
  * @publicApi
9
11
  */
@@ -11,16 +13,73 @@ let DiscoveryService = exports.DiscoveryService = class DiscoveryService {
11
13
  constructor(modulesContainer) {
12
14
  this.modulesContainer = modulesContainer;
13
15
  }
16
+ /**
17
+ * Creates a decorator that can be used to decorate classes and methods with metadata.
18
+ * The decorator will also add the class to the collection of discoverable classes (by metadata key).
19
+ * Decorated classes can be discovered using the `getProviders` and `getControllers` methods.
20
+ * @returns A decorator function.
21
+ */
22
+ static createDecorator() {
23
+ const metadataKey = (0, uid_1.uid)(21);
24
+ const decoratorFn = (opts) => (target, key, descriptor) => {
25
+ if (!descriptor) {
26
+ discoverable_meta_host_collection_1.DiscoverableMetaHostCollection.addClassMetaHostLink(target, metadataKey);
27
+ }
28
+ (0, common_1.SetMetadata)(metadataKey, opts ?? {})(target, key, descriptor);
29
+ };
30
+ decoratorFn.KEY = metadataKey;
31
+ return decoratorFn;
32
+ }
33
+ /**
34
+ * Returns an array of instance wrappers (providers).
35
+ * Depending on the options, the array will contain either all providers or only providers with the specified metadata key.
36
+ * @param options Discovery options.
37
+ * @param modules A list of modules to filter by.
38
+ * @returns An array of instance wrappers (providers).
39
+ */
14
40
  getProviders(options = {}, modules = this.getModules(options)) {
41
+ if ('metadataKey' in options) {
42
+ const providers = discoverable_meta_host_collection_1.DiscoverableMetaHostCollection.getProvidersByMetaKey(this.modulesContainer, options.metadataKey);
43
+ return Array.from(providers);
44
+ }
15
45
  const providers = modules.map(item => [...item.providers.values()]);
16
46
  return (0, common_1.flatten)(providers);
17
47
  }
48
+ /**
49
+ * Returns an array of instance wrappers (controllers).
50
+ * Depending on the options, the array will contain either all controllers or only controllers with the specified metadata key.
51
+ * @param options Discovery options.
52
+ * @param modules A list of modules to filter by.
53
+ * @returns An array of instance wrappers (controllers).
54
+ */
18
55
  getControllers(options = {}, modules = this.getModules(options)) {
56
+ if ('metadataKey' in options) {
57
+ const controllers = discoverable_meta_host_collection_1.DiscoverableMetaHostCollection.getControllersByMetaKey(this.modulesContainer, options.metadataKey);
58
+ return Array.from(controllers);
59
+ }
19
60
  const controllers = modules.map(item => [...item.controllers.values()]);
20
61
  return (0, common_1.flatten)(controllers);
21
62
  }
63
+ /**
64
+ * Retrieves metadata from the specified instance wrapper.
65
+ * @param decorator The decorator to retrieve metadata of.
66
+ * @param instanceWrapper Reference to the instance wrapper.
67
+ * @param methodKey An optional method key to retrieve metadata from.
68
+ * @returns Discovered metadata.
69
+ */
70
+ getMetadataByDecorator(decorator, instanceWrapper, methodKey) {
71
+ if (methodKey) {
72
+ return Reflect.getMetadata(decorator.KEY, instanceWrapper.instance[methodKey]);
73
+ }
74
+ const clsRef = instanceWrapper.instance?.constructor ?? instanceWrapper.metatype;
75
+ return Reflect.getMetadata(decorator.KEY, clsRef);
76
+ }
77
+ /**
78
+ * Returns a list of modules to be used for discovery.
79
+ */
22
80
  getModules(options = {}) {
23
- if (!options.include) {
81
+ const includeInOpts = 'include' in options;
82
+ if (!includeInOpts) {
24
83
  const moduleRefs = [...this.modulesContainer.values()];
25
84
  return moduleRefs;
26
85
  }
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NestContainer = void 0;
4
4
  const constants_1 = require("@nestjs/common/constants");
5
+ const discoverable_meta_host_collection_1 = require("../discovery/discoverable-meta-host-collection");
5
6
  const exceptions_1 = require("../errors/exceptions");
6
7
  const initialize_on_preview_allowlist_1 = require("../inspector/initialize-on-preview.allowlist");
7
8
  const serialized_graph_1 = require("../inspector/serialized-graph");
@@ -137,7 +138,7 @@ class NestContainer {
137
138
  const moduleRef = this.modules.get(token);
138
139
  const { token: relatedModuleToken } = await this.moduleCompiler.compile(relatedModule);
139
140
  const related = this.modules.get(relatedModuleToken);
140
- moduleRef.addRelatedModule(related);
141
+ moduleRef.addImport(related);
141
142
  }
142
143
  addProvider(provider, token, enhancerSubtype) {
143
144
  const moduleRef = this.modules.get(token);
@@ -147,7 +148,10 @@ class NestContainer {
147
148
  if (!moduleRef) {
148
149
  throw new exceptions_1.UnknownModuleException();
149
150
  }
150
- return moduleRef.addProvider(provider, enhancerSubtype);
151
+ const providerKey = moduleRef.addProvider(provider, enhancerSubtype);
152
+ const providerRef = moduleRef.getProviderByKey(providerKey);
153
+ discoverable_meta_host_collection_1.DiscoverableMetaHostCollection.inspectProvider(this.modules, providerRef);
154
+ return providerKey;
151
155
  }
152
156
  addInjectable(injectable, token, enhancerSubtype, host) {
153
157
  if (!this.modules.has(token)) {
@@ -169,6 +173,8 @@ class NestContainer {
169
173
  }
170
174
  const moduleRef = this.modules.get(token);
171
175
  moduleRef.addController(controller);
176
+ const controllerRef = moduleRef.controllers.get(controller);
177
+ discoverable_meta_host_collection_1.DiscoverableMetaHostCollection.inspectController(this.modules, controllerRef);
172
178
  }
173
179
  clear() {
174
180
  this.modules.clear();
@@ -186,7 +192,7 @@ class NestContainer {
186
192
  if (target === globalModule || target === this.internalCoreModule) {
187
193
  return;
188
194
  }
189
- target.addRelatedModule(globalModule);
195
+ target.addImport(globalModule);
190
196
  }
191
197
  getDynamicMetadataByToken(token, metadataKey) {
192
198
  const metadata = this.dynamicModulesMetadata.get(token);
@@ -5,5 +5,6 @@ export declare class SilentLogger extends Logger {
5
5
  warn: () => void;
6
6
  debug: () => void;
7
7
  verbose: () => void;
8
+ fatal: () => void;
8
9
  setLogLevels: () => void;
9
10
  }
@@ -12,6 +12,7 @@ class SilentLogger extends common_1.Logger {
12
12
  this.warn = noop;
13
13
  this.debug = noop;
14
14
  this.verbose = noop;
15
+ this.fatal = noop;
15
16
  this.setLogLevels = noop;
16
17
  }
17
18
  }
@@ -43,8 +43,8 @@ export declare class Module {
43
43
  addModuleAsProvider(): void;
44
44
  addApplicationConfig(): void;
45
45
  addInjectable<T extends Injectable>(injectable: Provider, enhancerSubtype: EnhancerSubtype, host?: Type<T>): string | symbol | Function | InstanceWrapper<unknown>;
46
- addProvider(provider: Provider): Provider | InjectionToken;
47
- addProvider(provider: Provider, enhancerSubtype: EnhancerSubtype): Provider | InjectionToken;
46
+ addProvider(provider: Provider): InjectionToken;
47
+ addProvider(provider: Provider, enhancerSubtype: EnhancerSubtype): InjectionToken;
48
48
  isCustomProvider(provider: Provider): provider is ClassProvider | FactoryProvider | ValueProvider | ExistingProvider;
49
49
  addCustomProvider(provider: ClassProvider | FactoryProvider | ValueProvider | ExistingProvider, collection: Map<Function | string | symbol, any>, enhancerSubtype?: EnhancerSubtype): InjectionToken;
50
50
  isCustomClass(provider: any): provider is ClassProvider;
@@ -61,6 +61,10 @@ export declare class Module {
61
61
  validateExportedProvider(token: InjectionToken): InjectionToken;
62
62
  addController(controller: Type<Controller>): void;
63
63
  assignControllerUniqueId(controller: Type<Controller>): void;
64
+ addImport(moduleRef: Module): void;
65
+ /**
66
+ * @deprecated
67
+ */
64
68
  addRelatedModule(module: Module): void;
65
69
  replace(toReplace: InjectionToken, options: any): void;
66
70
  hasProvider(token: InjectionToken): boolean;
@@ -330,6 +330,12 @@ class Module {
330
330
  value: (0, random_string_generator_util_1.randomStringGenerator)(),
331
331
  });
332
332
  }
333
+ addImport(moduleRef) {
334
+ this._imports.add(moduleRef);
335
+ }
336
+ /**
337
+ * @deprecated
338
+ */
333
339
  addRelatedModule(module) {
334
340
  this._imports.add(module);
335
341
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nestjs/core",
3
- "version": "10.1.3",
3
+ "version": "10.2.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.1.3"
39
+ "@nestjs/common": "10.2.1"
40
40
  },
41
41
  "peerDependencies": {
42
42
  "@nestjs/common": "^10.0.0",
@@ -43,4 +43,5 @@ export declare class RouterExplorer {
43
43
  private createCallbackProxy;
44
44
  createRequestScopedHandler(instanceWrapper: InstanceWrapper, requestMethod: RequestMethod, moduleRef: Module, moduleKey: string, methodName: string): <TRequest extends Record<any, any>, TResponse>(req: TRequest, res: TResponse, next: () => void) => Promise<void>;
45
45
  private getContextId;
46
+ private copyMetadataToCallback;
46
47
  }
@@ -101,6 +101,7 @@ class RouterExplorer {
101
101
  controllerVersion: routePathMetadata.controllerVersion,
102
102
  },
103
103
  };
104
+ this.copyMetadataToCallback(targetCallback, routeHandler);
104
105
  routerMethodRef(path, routeHandler);
105
106
  this.graphInspector.insertEntrypointDefinition(entrypointDefinition, instanceWrapper.id);
106
107
  });
@@ -200,5 +201,10 @@ class RouterExplorer {
200
201
  }
201
202
  return contextId;
202
203
  }
204
+ copyMetadataToCallback(originalCallback, targetCallback) {
205
+ for (const key of Reflect.getMetadataKeys(originalCallback)) {
206
+ Reflect.defineMetadata(key, Reflect.getMetadata(key, originalCallback), targetCallback);
207
+ }
208
+ }
203
209
  }
204
210
  exports.RouterExplorer = RouterExplorer;
@@ -1,4 +1,25 @@
1
- import { Type } from '@nestjs/common';
1
+ import { CustomDecorator, Type } from '@nestjs/common';
2
+ /**
3
+ * @publicApi
4
+ */
5
+ export interface CreateDecoratorOptions<T = any> {
6
+ /**
7
+ * The key for the metadata.
8
+ * @default uid(21)
9
+ */
10
+ key?: string;
11
+ /**
12
+ * The transform function to apply to the metadata value.
13
+ * @default value => value
14
+ */
15
+ transform?: (value: T) => T;
16
+ }
17
+ /**
18
+ * @publicApi
19
+ */
20
+ export type ReflectableDecorator<T> = ((opts?: T) => CustomDecorator) & {
21
+ KEY: string;
22
+ };
2
23
  /**
3
24
  * Helper class providing Nest reflection capabilities.
4
25
  *
@@ -7,6 +28,24 @@ import { Type } from '@nestjs/common';
7
28
  * @publicApi
8
29
  */
9
30
  export declare class Reflector {
31
+ /**
32
+ * Creates a decorator that can be used to decorate classes and methods with metadata.
33
+ * Can be used as a strongly-typed alternative to `@SetMetadata`.
34
+ * @param options Decorator options.
35
+ * @returns A decorator function.
36
+ */
37
+ static createDecorator<T>(options?: CreateDecoratorOptions): ReflectableDecorator<T>;
38
+ /**
39
+ * Retrieve metadata for a reflectable decorator for a specified target.
40
+ *
41
+ * @example
42
+ * `const roles = this.reflector.get(Roles, context.getHandler());`
43
+ *
44
+ * @param decorator reflectable decorator created through `Reflector.createDecorator`
45
+ * @param target context (decorated object) to retrieve metadata from
46
+ *
47
+ */
48
+ get<T extends ReflectableDecorator<any>>(decorator: T, target: Type<any> | Function): T extends ReflectableDecorator<infer R> ? R : unknown;
10
49
  /**
11
50
  * Retrieve metadata for a specified key for a specified target.
12
51
  *
@@ -18,6 +57,14 @@ export declare class Reflector {
18
57
  *
19
58
  */
20
59
  get<TResult = any, TKey = any>(metadataKey: TKey, target: Type<any> | Function): TResult;
60
+ /**
61
+ * Retrieve metadata for a specified decorator for a specified set of targets.
62
+ *
63
+ * @param decorator lookup decorator for metadata to retrieve
64
+ * @param targets context (decorated objects) to retrieve metadata from
65
+ *
66
+ */
67
+ getAll<T extends ReflectableDecorator<any>>(decorator: T, targets: (Type<any> | Function)[]): T extends ReflectableDecorator<infer R> ? R extends Array<any> ? R : R[] : unknown;
21
68
  /**
22
69
  * Retrieve metadata for a specified key for a specified set of targets.
23
70
  *
@@ -26,6 +73,14 @@ export declare class Reflector {
26
73
  *
27
74
  */
28
75
  getAll<TResult extends any[] = any[], TKey = any>(metadataKey: TKey, targets: (Type<any> | Function)[]): TResult;
76
+ /**
77
+ * Retrieve metadata for a specified decorator for a specified set of targets and merge results.
78
+ *
79
+ * @param decorator lookup decorator for metadata to retrieve
80
+ * @param targets context (decorated objects) to retrieve metadata from
81
+ *
82
+ */
83
+ getAllAndMerge<T extends ReflectableDecorator<any>>(decorator: T, targets: (Type<any> | Function)[]): T extends ReflectableDecorator<infer R> ? R : unknown;
29
84
  /**
30
85
  * Retrieve metadata for a specified key for a specified set of targets and merge results.
31
86
  *
@@ -33,7 +88,15 @@ export declare class Reflector {
33
88
  * @param targets context (decorated objects) to retrieve metadata from
34
89
  *
35
90
  */
36
- getAllAndMerge<TResult extends any[] = any[], TKey = any>(metadataKey: TKey, targets: (Type<any> | Function)[]): TResult;
91
+ getAllAndMerge<TResult extends any[] | object = any[], TKey = any>(metadataKey: TKey, targets: (Type<any> | Function)[]): TResult;
92
+ /**
93
+ * Retrieve metadata for a specified decorator for a specified set of targets and return a first not undefined value.
94
+ *
95
+ * @param decorator lookup decorator for metadata to retrieve
96
+ * @param targets context (decorated objects) to retrieve metadata from
97
+ *
98
+ */
99
+ getAllAndOverride<T extends ReflectableDecorator<any>>(decorator: T, targets: (Type<any> | Function)[]): T extends ReflectableDecorator<infer R> ? R : unknown;
37
100
  /**
38
101
  * Retrieve metadata for a specified key for a specified set of targets and return a first not undefined value.
39
102
  *
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Reflector = void 0;
4
+ const common_1 = require("@nestjs/common");
4
5
  const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
6
+ const uid_1 = require("uid");
5
7
  /**
6
8
  * Helper class providing Nest reflection capabilities.
7
9
  *
@@ -11,37 +13,56 @@ const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
11
13
  */
12
14
  class Reflector {
13
15
  /**
14
- * Retrieve metadata for a specified key for a specified target.
16
+ * Creates a decorator that can be used to decorate classes and methods with metadata.
17
+ * Can be used as a strongly-typed alternative to `@SetMetadata`.
18
+ * @param options Decorator options.
19
+ * @returns A decorator function.
20
+ */
21
+ static createDecorator(options = {}) {
22
+ const metadataKey = options.key ?? (0, uid_1.uid)(21);
23
+ const decoratorFn = (metadataValue) => (target, key, descriptor) => {
24
+ const value = options.transform
25
+ ? options.transform(metadataValue)
26
+ : metadataValue;
27
+ (0, common_1.SetMetadata)(metadataKey, value ?? {})(target, key, descriptor);
28
+ };
29
+ decoratorFn.KEY = metadataKey;
30
+ return decoratorFn;
31
+ }
32
+ /**
33
+ * Retrieve metadata for a specified key or decorator for a specified target.
15
34
  *
16
35
  * @example
17
36
  * `const roles = this.reflector.get<string[]>('roles', context.getHandler());`
18
37
  *
19
- * @param metadataKey lookup key for metadata to retrieve
38
+ * @param metadataKey lookup key or decorator for metadata to retrieve
20
39
  * @param target context (decorated object) to retrieve metadata from
21
40
  *
22
41
  */
23
- get(metadataKey, target) {
42
+ get(metadataKeyOrDecorator, target) {
43
+ const metadataKey = metadataKeyOrDecorator.KEY ??
44
+ metadataKeyOrDecorator;
24
45
  return Reflect.getMetadata(metadataKey, target);
25
46
  }
26
47
  /**
27
- * Retrieve metadata for a specified key for a specified set of targets.
48
+ * Retrieve metadata for a specified key or decorator for a specified set of targets.
28
49
  *
29
- * @param metadataKey lookup key for metadata to retrieve
50
+ * @param metadataKeyOrDecorator lookup key or decorator for metadata to retrieve
30
51
  * @param targets context (decorated objects) to retrieve metadata from
31
52
  *
32
53
  */
33
- getAll(metadataKey, targets) {
34
- return (targets || []).map(target => this.get(metadataKey, target));
54
+ getAll(metadataKeyOrDecorator, targets) {
55
+ return (targets || []).map(target => this.get(metadataKeyOrDecorator, target));
35
56
  }
36
57
  /**
37
- * Retrieve metadata for a specified key for a specified set of targets and merge results.
58
+ * Retrieve metadata for a specified key or decorator for a specified set of targets and merge results.
38
59
  *
39
- * @param metadataKey lookup key for metadata to retrieve
60
+ * @param metadataKeyOrDecorator lookup key for metadata to retrieve
40
61
  * @param targets context (decorated objects) to retrieve metadata from
41
62
  *
42
63
  */
43
- getAllAndMerge(metadataKey, targets) {
44
- const metadataCollection = this.getAll(metadataKey, targets).filter(item => item !== undefined);
64
+ getAllAndMerge(metadataKeyOrDecorator, targets) {
65
+ const metadataCollection = this.getAll(metadataKeyOrDecorator, targets).filter(item => item !== undefined);
45
66
  if ((0, shared_utils_1.isEmpty)(metadataCollection)) {
46
67
  return metadataCollection;
47
68
  }
@@ -59,15 +80,15 @@ class Reflector {
59
80
  });
60
81
  }
61
82
  /**
62
- * Retrieve metadata for a specified key for a specified set of targets and return a first not undefined value.
83
+ * Retrieve metadata for a specified key or decorator for a specified set of targets and return a first not undefined value.
63
84
  *
64
- * @param metadataKey lookup key for metadata to retrieve
85
+ * @param metadataKeyOrDecorator lookup key or metadata for metadata to retrieve
65
86
  * @param targets context (decorated objects) to retrieve metadata from
66
87
  *
67
88
  */
68
- getAllAndOverride(metadataKey, targets) {
89
+ getAllAndOverride(metadataKeyOrDecorator, targets) {
69
90
  for (const target of targets) {
70
- const result = this.get(metadataKey, target);
91
+ const result = this.get(metadataKeyOrDecorator, target);
71
92
  if (result !== undefined) {
72
93
  return result;
73
94
  }