@nestjs/core 11.1.21 → 11.1.23

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
@@ -129,6 +129,7 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
129
129
  <tr>
130
130
  <td align="center" valign="middle"><a href="https://solcellsforetag.se/" target="_blank"><img src="https://nestjs.com/img/logos/solcellsforetag-logo.svg" width="140" valign="middle" /></a></td>
131
131
  <td align="center" valign="middle"><a href="https://www.route4me.com/" target="_blank"><img src="https://nestjs.com/img/logos/route4me-logo.svg" width="100" valign="middle" /></a></td>
132
+ <td align="center" valign="middle"><a href="https://memory2.co/" target="_blank"><img src="https://images.opencollective.com/memory-squared/bbe37f5/avatar/256.png?height=50" width="50" valign="middle" /></a></td>
132
133
  </tr>
133
134
  </table>
134
135
 
@@ -1,4 +1,4 @@
1
1
  import { RuntimeException } from './runtime.exception';
2
2
  export declare class InvalidClassModuleException extends RuntimeException {
3
- constructor(metatypeUsedAsAModule: any, scope: any[]);
3
+ constructor(metatypeUsedAsAModule: any, scope: any[], classKind: 'provider' | 'controller' | 'filter');
4
4
  }
@@ -4,8 +4,8 @@ exports.InvalidClassModuleException = void 0;
4
4
  const messages_1 = require("../messages");
5
5
  const runtime_exception_1 = require("./runtime.exception");
6
6
  class InvalidClassModuleException extends runtime_exception_1.RuntimeException {
7
- constructor(metatypeUsedAsAModule, scope) {
8
- super((0, messages_1.USING_INVALID_CLASS_AS_A_MODULE_MESSAGE)(metatypeUsedAsAModule, scope));
7
+ constructor(metatypeUsedAsAModule, scope, classKind) {
8
+ super((0, messages_1.USING_INVALID_CLASS_AS_A_MODULE_MESSAGE)(metatypeUsedAsAModule, scope, classKind));
9
9
  }
10
10
  }
11
11
  exports.InvalidClassModuleException = InvalidClassModuleException;
@@ -1,4 +1,4 @@
1
1
  import { RuntimeException } from './runtime.exception';
2
2
  export declare class InvalidModuleException extends RuntimeException {
3
- constructor(parentModule: any, index: number, scope: any[]);
3
+ constructor(parentModule: any, index: number, scope: any[], receivedValue: unknown);
4
4
  }
@@ -4,8 +4,8 @@ exports.InvalidModuleException = void 0;
4
4
  const messages_1 = require("../messages");
5
5
  const runtime_exception_1 = require("./runtime.exception");
6
6
  class InvalidModuleException extends runtime_exception_1.RuntimeException {
7
- constructor(parentModule, index, scope) {
8
- super((0, messages_1.INVALID_MODULE_MESSAGE)(parentModule, index, scope));
7
+ constructor(parentModule, index, scope, receivedValue) {
8
+ super((0, messages_1.INVALID_MODULE_MESSAGE)(parentModule, index, scope, receivedValue));
9
9
  }
10
10
  }
11
11
  exports.InvalidModuleException = InvalidModuleException;
@@ -4,8 +4,8 @@ import { Module } from '../injector/module';
4
4
  export declare const UNKNOWN_DEPENDENCIES_MESSAGE: (type: string | symbol, unknownDependencyContext: InjectorDependencyContext, moduleRef: Module | undefined) => string;
5
5
  export declare const INVALID_MIDDLEWARE_MESSAGE: (text: TemplateStringsArray, name: string) => string;
6
6
  export declare const UNDEFINED_FORWARDREF_MESSAGE: (scope: Type<any>[]) => string;
7
- export declare const INVALID_MODULE_MESSAGE: (parentModule: any, index: number, scope: any[]) => string;
8
- export declare const USING_INVALID_CLASS_AS_A_MODULE_MESSAGE: (metatypeUsedAsAModule: Type | ForwardReference, scope: any[]) => string;
7
+ export declare const INVALID_MODULE_MESSAGE: (parentModule: any, index: number, scope: any[], receivedValue: unknown) => string;
8
+ export declare const USING_INVALID_CLASS_AS_A_MODULE_MESSAGE: (metatypeUsedAsAModule: Type | ForwardReference, scope: any[], classKind: "provider" | "controller" | "filter") => string;
9
9
  export declare const UNDEFINED_MODULE_MESSAGE: (parentModule: any, index: number, scope: any[]) => string;
10
10
  export declare const UNKNOWN_EXPORT_MESSAGE: (token: string | symbol | undefined, module: string) => string;
11
11
  export declare const INVALID_CLASS_MESSAGE: (text: TemplateStringsArray, value: any) => string;
@@ -117,18 +117,44 @@ const UNDEFINED_FORWARDREF_MESSAGE = (scope) => `Nest cannot create the module i
117
117
  Scope [${stringifyScope(scope)}]
118
118
  `;
119
119
  exports.UNDEFINED_FORWARDREF_MESSAGE = UNDEFINED_FORWARDREF_MESSAGE;
120
- const INVALID_MODULE_MESSAGE = (parentModule, index, scope) => {
120
+ const INVALID_MODULE_MESSAGE = (parentModule, index, scope, receivedValue) => {
121
121
  const parentModuleName = parentModule?.name || 'module';
122
+ let formattedValue;
123
+ let receivedType;
124
+ if (receivedValue === null) {
125
+ formattedValue = 'null';
126
+ receivedType = 'null';
127
+ }
128
+ else if (typeof receivedValue === 'string') {
129
+ formattedValue = `"${receivedValue}"`;
130
+ receivedType = 'string';
131
+ }
132
+ else {
133
+ formattedValue = String(receivedValue);
134
+ receivedType = typeof receivedValue;
135
+ }
122
136
  return `Nest cannot create the ${parentModuleName} instance.
123
137
  Received an unexpected value at index [${index}] of the ${parentModuleName} "imports" array.
138
+ The received value \`${formattedValue}\` is of type "${receivedType}".
124
139
 
125
140
  Scope [${stringifyScope(scope)}]`;
126
141
  };
127
142
  exports.INVALID_MODULE_MESSAGE = INVALID_MODULE_MESSAGE;
128
- const USING_INVALID_CLASS_AS_A_MODULE_MESSAGE = (metatypeUsedAsAModule, scope) => {
143
+ const USING_INVALID_CLASS_AS_A_MODULE_MESSAGE = (metatypeUsedAsAModule, scope, classKind) => {
129
144
  const metatypeNameQuote = `"${getInstanceName(metatypeUsedAsAModule)}"`;
130
- return `Classes annotated with @Injectable(), @Catch(), and @Controller() decorators must not appear in the "imports" array of a module.
131
- Please remove ${metatypeNameQuote} (including forwarded occurrences, if any) from all of the "imports" arrays.
145
+ let hint;
146
+ switch (classKind) {
147
+ case 'controller':
148
+ hint = `${metatypeNameQuote} is decorated with @Controller() and cannot appear in the "imports" array of a module. Please move ${metatypeNameQuote} to the "controllers" array of the importing module instead.`;
149
+ break;
150
+ case 'provider':
151
+ hint = `${metatypeNameQuote} is decorated with @Injectable() and cannot appear in the "imports" array of a module. Please move ${metatypeNameQuote} to the "providers" array of the importing module instead.`;
152
+ break;
153
+ case 'filter':
154
+ hint = `${metatypeNameQuote} is decorated with @Catch() and cannot appear in the "imports" array of a module. Please move ${metatypeNameQuote} to the "providers" array (using the APP_FILTER token to apply it globally) or apply it via @UseFilters() instead.`;
155
+ break;
156
+ }
157
+ return `${hint}
132
158
 
133
159
  Scope [${stringifyScope(scope)}]
134
160
  `;
@@ -72,9 +72,9 @@ export declare class Injector {
72
72
  resolveConstructorParams<T>(wrapper: InstanceWrapper<T>, moduleRef: Module, inject: InjectorDependency[] | undefined, callback: (args: unknown[]) => void | Promise<void>, resolutionContext?: ResolutionContext, parentInquirer?: InstanceWrapper): Promise<void>;
73
73
  getClassDependencies<T>(wrapper: InstanceWrapper<T>): [InjectorDependency[], number[]];
74
74
  getFactoryProviderDependencies<T>(wrapper: InstanceWrapper<T>): [InjectorDependency[], number[]];
75
- reflectConstructorParams<T>(type: Type<T>): any[];
76
- reflectOptionalParams<T>(type: Type<T>): any[];
77
- reflectSelfParams<T>(type: Type<T>): any[];
75
+ reflectConstructorParams(type: Type<unknown> | Function): any[];
76
+ reflectOptionalParams(type: Type<unknown> | Function): any[];
77
+ reflectSelfParams(type: Type<unknown> | Function): any[];
78
78
  resolveSingleParam<T>(wrapper: InstanceWrapper<T>, param: Type<any> | string | symbol, dependencyContext: InjectorDependencyContext, moduleRef: Module, resolutionContext?: ResolutionContext, keyOrIndex?: symbol | string | number): Promise<InstanceWrapper<any>>;
79
79
  resolveParamToken<T>(wrapper: InstanceWrapper<T>, param: Type<any> | string | symbol | ForwardReference): any;
80
80
  resolveComponentWrapper<T>(moduleRef: Module, token: InjectionToken, dependencyContext: InjectorDependencyContext, wrapper: InstanceWrapper<T>, resolutionContext?: ResolutionContext, keyOrIndex?: symbol | string | number): Promise<InstanceWrapper>;
@@ -106,6 +106,7 @@ export declare class Injector {
106
106
  private getEffectiveInquirerId;
107
107
  private getStaticTransientResolutionContext;
108
108
  private getEffectiveResolutionContext;
109
+ private hasDenseCtorMetadata;
109
110
  private resolveScopedComponentHost;
110
111
  private isInquirerRequest;
111
112
  private isInquirer;
@@ -120,7 +120,8 @@ class Injector {
120
120
  }
121
121
  async resolveConstructorParams(wrapper, moduleRef, inject, callback, resolutionContext = { contextId: constants_2.STATIC_CONTEXT }, parentInquirer) {
122
122
  const metadata = wrapper.getCtorMetadata();
123
- if (metadata && resolutionContext.contextId !== constants_2.STATIC_CONTEXT) {
123
+ if (resolutionContext.contextId !== constants_2.STATIC_CONTEXT &&
124
+ this.hasDenseCtorMetadata(wrapper, inject, metadata)) {
124
125
  const deps = await this.loadCtorMetadata(metadata, resolutionContext.contextId, resolutionContext.inquirer, parentInquirer);
125
126
  return callback(deps);
126
127
  }
@@ -503,7 +504,6 @@ class Injector {
503
504
  wrapper.isExplicitlyRequested(resolutionContext.contextId, resolutionContext.inquirer));
504
505
  }
505
506
  shouldSkipProviderLoading(wrapper, resolutionContext) {
506
- const isSnapshotGraphCompilation = !!this.options?.snapshot;
507
507
  const isStaticContext = resolutionContext.contextId === constants_2.STATIC_CONTEXT;
508
508
  const hasNoInquirer = !resolutionContext.inquirer;
509
509
  const isTopLevelStaticTransientOrRequestProvider = hasNoInquirer && (wrapper.isTransient || wrapper.scope === common_1.Scope.REQUEST);
@@ -512,7 +512,7 @@ class Injector {
512
512
  const shouldSkipForStaticBootstrap = isStaticContext &&
513
513
  (isTopLevelStaticTransientOrRequestProvider ||
514
514
  isStaticInquirerOutsideResolutionContext);
515
- return !isSnapshotGraphCompilation && shouldSkipForStaticBootstrap;
515
+ return shouldSkipForStaticBootstrap;
516
516
  }
517
517
  /**
518
518
  * For nested TRANSIENT dependencies (TRANSIENT -> TRANSIENT) in non-static contexts,
@@ -556,6 +556,28 @@ class Injector {
556
556
  getEffectiveResolutionContext(dependency, resolutionContext, parentInquirer) {
557
557
  return this.createResolutionContext(resolutionContext.contextId, this.getEffectiveInquirer(dependency, resolutionContext, parentInquirer), this.getEffectiveInquirerId(dependency, resolutionContext, parentInquirer));
558
558
  }
559
+ hasDenseCtorMetadata(wrapper, inject, metadata) {
560
+ if (!metadata) {
561
+ return false;
562
+ }
563
+ // The fast path requires a fully populated metadata array.
564
+ // While another request is still registering dependency metadata,
565
+ // sparse entries here would feed request-scoped factories `undefined`.
566
+ const expectedDepsLength = !(0, shared_utils_1.isNil)(inject)
567
+ ? inject.length
568
+ : wrapper.metatype
569
+ ? this.reflectConstructorParams(wrapper.metatype).length
570
+ : 0;
571
+ if (metadata.length !== expectedDepsLength) {
572
+ return false;
573
+ }
574
+ for (let index = 0; index < expectedDepsLength; index++) {
575
+ if (metadata[index] === undefined) {
576
+ return false;
577
+ }
578
+ }
579
+ return true;
580
+ }
559
581
  resolveScopedComponentHost(item, contextId, inquirer, parentInquirer) {
560
582
  return this.isInquirerRequest(item, parentInquirer)
561
583
  ? parentInquirer
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nestjs/core",
3
- "version": "11.1.21",
3
+ "version": "11.1.23",
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.21"
42
+ "@nestjs/common": "11.1.23"
43
43
  },
44
44
  "peerDependencies": {
45
45
  "@nestjs/common": "^11.0.0",
@@ -60,5 +60,5 @@
60
60
  "optional": true
61
61
  }
62
62
  },
63
- "gitHead": "983dd52c4927753be3421162fc43e4fde8d3fcde"
63
+ "gitHead": "b8be8c12270b2e6dcd275d435e573f08b4c79d79"
64
64
  }
package/scanner.js CHANGED
@@ -64,7 +64,7 @@ class DependenciesScanner {
64
64
  throw new undefined_module_exception_1.UndefinedModuleException(moduleDefinition, index, scope);
65
65
  }
66
66
  if (!innerModule) {
67
- throw new invalid_module_exception_1.InvalidModuleException(moduleDefinition, index, scope);
67
+ throw new invalid_module_exception_1.InvalidModuleException(moduleDefinition, index, scope, innerModule);
68
68
  }
69
69
  if (ctxRegistry.includes(innerModule)) {
70
70
  continue;
@@ -90,10 +90,14 @@ class DependenciesScanner {
90
90
  const moduleToAdd = this.isForwardReference(moduleDefinition)
91
91
  ? moduleDefinition.forwardRef()
92
92
  : moduleDefinition;
93
- if (this.isInjectable(moduleToAdd) ||
94
- this.isController(moduleToAdd) ||
95
- this.isExceptionFilter(moduleToAdd)) {
96
- throw new invalid_class_module_exception_1.InvalidClassModuleException(moduleDefinition, scope);
93
+ if (this.isInjectable(moduleToAdd)) {
94
+ throw new invalid_class_module_exception_1.InvalidClassModuleException(moduleDefinition, scope, 'provider');
95
+ }
96
+ if (this.isController(moduleToAdd)) {
97
+ throw new invalid_class_module_exception_1.InvalidClassModuleException(moduleDefinition, scope, 'controller');
98
+ }
99
+ if (this.isExceptionFilter(moduleToAdd)) {
100
+ throw new invalid_class_module_exception_1.InvalidClassModuleException(moduleDefinition, scope, 'filter');
97
101
  }
98
102
  return this.container.addModule(moduleToAdd, scope);
99
103
  }