@nestjs/core 11.1.7 → 11.1.9

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
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <a href="https://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo-small.svg" width="120" alt="Nest Logo" /></a>
2
+ <a href="https://nestjs.com/" target="_blank"><img src="https://nestjs.com/img/logo-small.svg" width="120" alt="Nest Logo" /></a>
3
3
  </p>
4
4
 
5
5
  [circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456
@@ -49,7 +49,7 @@ Please make sure to read the [Issue Reporting Checklist](https://github.com/nest
49
49
 
50
50
  ## Consulting
51
51
 
52
- With official support, you can get expert help straight from Nest core team. We provide dedicated technical support, migration strategies, advice on best practices (and design decisions), PR reviews, and team augmentation. Read more about [support here](https://enterprise.nestjs.com).
52
+ With official support, you can get expert help straight from the Nest core team. We provide dedicated technical support, migration strategies, advice on best practices (and design decisions), PR reviews, and team augmentation. Read more about [support here](https://enterprise.nestjs.com).
53
53
 
54
54
  ## Support
55
55
 
@@ -92,6 +92,8 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
92
92
  <td align="center" valign="middle"><a href="https://www.itflashcards.com/" target="_blank"><img src="https://nestjs.com/img/logos/it_flashcards-logo.png" width="170" valign="middle" /></a></td>
93
93
  <td align="center" valign="middle"><a href="https://arcjet.com/?ref=nestjs" target="_blank"><img src="https://nestjs.com/img/logos/arcjet-logo.svg" width="170" valign="middle" /></a></td>
94
94
  <td align="center" valign="middle"><a href="https://crawljobs.com" target="_blank"><img src="https://nestjs.com/img/logos/crawljobs-logo.svg" width="130" valign="middle" /></a></td>
95
+ </tr><tr>
96
+ <td align="center" valign="middle"><a href="https://pandektes.com" target="_blank"><img src="https://nestjs.com/img/logos/pandektes-logo.png" width="65" valign="middle" /></a></td>
95
97
  </tr>
96
98
  </table>
97
99
 
@@ -8,7 +8,8 @@ class AbstractInstanceResolver {
8
8
  const instanceLinkOrArray = this.instanceLinksHost.get(typeOrToken, options);
9
9
  const pluckInstance = ({ wrapperRef }) => {
10
10
  if (wrapperRef.scope === common_1.Scope.REQUEST ||
11
- wrapperRef.scope === common_1.Scope.TRANSIENT) {
11
+ wrapperRef.scope === common_1.Scope.TRANSIENT ||
12
+ !wrapperRef.isDependencyTreeStatic()) {
12
13
  throw new exceptions_1.InvalidClassScopeException(typeOrToken);
13
14
  }
14
15
  return wrapperRef.instance;
@@ -82,6 +82,14 @@ export declare class Injector {
82
82
  loadCtorMetadata(metadata: InstanceWrapper<any>[], contextId: ContextId, inquirer?: InstanceWrapper, parentInquirer?: InstanceWrapper): Promise<any[]>;
83
83
  loadPropertiesMetadata(metadata: PropertyMetadata[], contextId: ContextId, inquirer?: InstanceWrapper): Promise<PropertyDependency[]>;
84
84
  private getInquirerId;
85
+ /**
86
+ * For nested TRANSIENT dependencies (TRANSIENT -> TRANSIENT) in non-static contexts,
87
+ * returns parentInquirer to ensure each parent TRANSIENT gets its own instance.
88
+ * This is necessary because in REQUEST/DURABLE scopes, the same TRANSIENT wrapper
89
+ * can be used by multiple parents, causing nested TRANSIENTs to be shared incorrectly.
90
+ * For non-TRANSIENT -> TRANSIENT, returns inquirer (current wrapper being created).
91
+ */
92
+ private getEffectiveInquirer;
85
93
  private resolveScopedComponentHost;
86
94
  private isInquirerRequest;
87
95
  private isInquirer;
@@ -111,7 +111,6 @@ class Injector {
111
111
  return settlementSignal;
112
112
  }
113
113
  async resolveConstructorParams(wrapper, moduleRef, inject, callback, contextId = constants_2.STATIC_CONTEXT, inquirer, parentInquirer) {
114
- const inquirerId = this.getInquirerId(inquirer);
115
114
  const metadata = wrapper.getCtorMetadata();
116
115
  if (metadata && contextId !== constants_2.STATIC_CONTEXT) {
117
116
  const deps = await this.loadCtorMetadata(metadata, contextId, inquirer, parentInquirer);
@@ -145,8 +144,9 @@ class Injector {
145
144
  * and result in undefined / null injection.
146
145
  */
147
146
  await paramBarrier.signalAndWait();
148
- const paramWrapperWithInstance = await this.resolveComponentHost(moduleRef, paramWrapper, contextId, inquirer);
149
- const instanceHost = paramWrapperWithInstance.getInstanceByContextId(this.getContextId(contextId, paramWrapperWithInstance), inquirerId);
147
+ const effectiveInquirer = this.getEffectiveInquirer(paramWrapper, inquirer, parentInquirer, contextId);
148
+ const paramWrapperWithInstance = await this.resolveComponentHost(moduleRef, paramWrapper, contextId, effectiveInquirer);
149
+ const instanceHost = paramWrapperWithInstance.getInstanceByContextId(this.getContextId(contextId, paramWrapperWithInstance), this.getInquirerId(effectiveInquirer));
150
150
  if (!instanceHost.isResolved && !paramWrapperWithInstance.forwardRef) {
151
151
  isResolved = false;
152
152
  }
@@ -357,12 +357,12 @@ class Injector {
357
357
  * and result in undefined / null injection.
358
358
  */
359
359
  await propertyBarrier.signalAndWait();
360
- const paramWrapperWithInstance = await this.resolveComponentHost(moduleRef, paramWrapper, contextId, inquirer);
360
+ const effectivePropertyInquirer = this.getEffectiveInquirer(paramWrapper, inquirer, parentInquirer, contextId);
361
+ const paramWrapperWithInstance = await this.resolveComponentHost(moduleRef, paramWrapper, contextId, effectivePropertyInquirer);
361
362
  if (!paramWrapperWithInstance) {
362
363
  return undefined;
363
364
  }
364
- const inquirerId = this.getInquirerId(inquirer);
365
- const instanceHost = paramWrapperWithInstance.getInstanceByContextId(this.getContextId(contextId, paramWrapperWithInstance), inquirerId);
365
+ const instanceHost = paramWrapperWithInstance.getInstanceByContextId(this.getContextId(contextId, paramWrapperWithInstance), this.getInquirerId(effectivePropertyInquirer));
366
366
  return instanceHost.instance;
367
367
  }
368
368
  catch (err) {
@@ -448,8 +448,11 @@ class Injector {
448
448
  }
449
449
  async loadCtorMetadata(metadata, contextId, inquirer, parentInquirer) {
450
450
  const hosts = await Promise.all(metadata.map(async (item) => this.resolveScopedComponentHost(item, contextId, inquirer, parentInquirer)));
451
- const inquirerId = this.getInquirerId(inquirer);
452
- return hosts.map(item => item?.getInstanceByContextId(this.getContextId(contextId, item), inquirerId).instance);
451
+ return hosts.map((item, index) => {
452
+ const dependency = metadata[index];
453
+ const effectiveInquirer = this.getEffectiveInquirer(dependency, inquirer, parentInquirer, contextId);
454
+ return item?.getInstanceByContextId(this.getContextId(contextId, item), this.getInquirerId(effectiveInquirer)).instance;
455
+ });
453
456
  }
454
457
  async loadPropertiesMetadata(metadata, contextId, inquirer) {
455
458
  const dependenciesHosts = await Promise.all(metadata.map(async ({ wrapper: item, key }) => ({
@@ -466,10 +469,25 @@ class Injector {
466
469
  getInquirerId(inquirer) {
467
470
  return inquirer ? inquirer.id : undefined;
468
471
  }
472
+ /**
473
+ * For nested TRANSIENT dependencies (TRANSIENT -> TRANSIENT) in non-static contexts,
474
+ * returns parentInquirer to ensure each parent TRANSIENT gets its own instance.
475
+ * This is necessary because in REQUEST/DURABLE scopes, the same TRANSIENT wrapper
476
+ * can be used by multiple parents, causing nested TRANSIENTs to be shared incorrectly.
477
+ * For non-TRANSIENT -> TRANSIENT, returns inquirer (current wrapper being created).
478
+ */
479
+ getEffectiveInquirer(dependency, inquirer, parentInquirer, contextId) {
480
+ return dependency?.isTransient &&
481
+ inquirer?.isTransient &&
482
+ parentInquirer &&
483
+ contextId !== constants_2.STATIC_CONTEXT
484
+ ? parentInquirer
485
+ : inquirer;
486
+ }
469
487
  resolveScopedComponentHost(item, contextId, inquirer, parentInquirer) {
470
488
  return this.isInquirerRequest(item, parentInquirer)
471
489
  ? parentInquirer
472
- : this.resolveComponentHost(item.host, item, contextId, inquirer);
490
+ : this.resolveComponentHost(item.host, item, contextId, this.getEffectiveInquirer(item, inquirer, parentInquirer, contextId));
473
491
  }
474
492
  isInquirerRequest(item, parentInquirer) {
475
493
  return item.isTransient && item.name === inquirer_1.INQUIRER && parentInquirer;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nestjs/core",
3
- "version": "11.1.7",
3
+ "version": "11.1.9",
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.7"
42
+ "@nestjs/common": "11.1.9"
43
43
  },
44
44
  "peerDependencies": {
45
45
  "@nestjs/common": "^11.0.0",