@nestjs/core 11.1.26 → 11.1.28

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
@@ -59,11 +59,11 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
59
59
 
60
60
  <table style="text-align:center;">
61
61
  <tr>
62
- <td><a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="200" valign="middle" /></a></td>
63
- <td><a href="https://microsoft.com/" target="_blank"><img src="https://nestjs.com/img/logos/microsoft-logo.png" width="180" valign="middle" /></a></td>
64
- <td><a href="https://mojam.co" target="_blank"><img src="https://nestjs.com/img/logos/mojam-logo.png" width="80" valign="middle" /></a></td>
62
+ <td><a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/github/trilon-logo.svg" width="200" valign="middle" /></a></td>
63
+ <td><a href="https://microsoft.com/" target="_blank"><img src="https://nestjs.com/img/github/microsoft-logo.png" width="180" valign="middle" /></a></td>
64
+ <td><a href="https://mojam.co" target="_blank"><img src="https://images.opencollective.com/mojamco/981e9de/logo/256.png?height=256" width="80" valign="middle" /></a></td>
65
65
  <td><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>
66
- <td><a href="https://serpapi.com/" target="_blank"><img src="https://nestjs.com/img/logos/serpapi-logo.png" width="150" valign="middle" /></a></td>
66
+ <td><a href="https://serpapi.com/" target="_blank"><img src="https://nestjs.com/img/github/serpapi-logo.png" width="150" valign="middle" /></a></td>
67
67
  </tr>
68
68
  </table>
69
69
 
@@ -71,15 +71,15 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
71
71
 
72
72
  <table style="text-align:center;">
73
73
  <tr>
74
- <td><a href="https://www.redhat.com" target="_blank"><img src="https://nestjs.com/img/logos/red-hat-logo.svg" width="200" valign="middle" /></a></td>
75
- <td><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>
76
- <td><a href="https://nx.dev" target="_blank"><img src="https://nestjs.com/img/logos/nx-logo.png" height="45" valign="middle" /></a></td>
77
- <td><a href="https://intrinsic.ventures/" target="_blank"><img src="https://nestjs.com/img/logos/intrinisic-logo.png" width="210" valign="middle" /></a></td>
78
- <td><a href="https://jetbrains.com/" target="_blank"><img src="https://nestjs.com/img/logos/jetbrains-logo.svg" width="90" valign="middle" /></a></td>
74
+ <td><a href="https://www.redhat.com" target="_blank"><img src="https://nestjs.com/img/github/red-hat-logo.svg" width="150" valign="middle" /></a></td>
75
+ <td><a href="https://github.com/Sanofi-IADC" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/sanofi.png" width="120" valign="middle" /></a></td>
76
+ <td><a href="https://nx.dev" target="_blank"><img src="https://nestjs.com/img/github/nx-logo.png" height="45" valign="middle" /></a></td>
77
+ <td><a href="https://intrinsic.ventures/" target="_blank"><img src="https://nestjs.com/img/github/intrinisic-logo.png" width="150" valign="middle" /></a></td>
78
+ <td><a href="https://jetbrains.com/" target="_blank"><img src="https://nestjs.com/img/github/jetbrains-logo.svg" width="70" valign="middle" /></a></td>
79
79
  </tr>
80
80
  <tr>
81
- <td><a href="https://snyk.co/nestjs" target="_blank"><img src="https://nestjs.com/img/logos/snyk-logo-black.png" width="185" valign="middle" /></a></td>
82
- <td><a href="https://www.movavi.com/imovie-for-windows.html" target="_blank"><img src="https://nestjs.com/img/logos/movavi-logo.svg" width="105" valign="middle" /></a></td>
81
+ <td><a href="https://snyk.co/nestjs" target="_blank"><img src="https://nestjs.com/img/github/snyk-logo-black.png" width="125" valign="middle" /></a></td>
82
+ <td align="center"><a href="https://www.movavi.com/imovie-for-windows.html" target="_blank"><img src="https://images.opencollective.com/movavi/1fb15e5/avatar/256.png?height=256" width="60" valign="middle" /></a></td>
83
83
  </tr>
84
84
  </table>
85
85
 
@@ -87,17 +87,15 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
87
87
 
88
88
  <table style="text-align:center;">
89
89
  <tr>
90
- <td><a href="https://www.mercedes-benz.com/" target="_blank"><img src="https://nestjs.com/img/logos/mercedes-logo.png" width="100" valign="middle" /></a></td>
91
- <td><a href="https://www.dinii.jp/" target="_blank"><img src="https://nestjs.com/img/logos/dinii-logo.png" width="65" valign="middle" /></a></td>
92
- <td><a href="https://handsontable.com/docs/react-data-grid/?utm_source=NestJS_GH&utm_medium=sponsorship&utm_campaign=library_sponsorship_2024" target="_blank"><img src="https://nestjs.com/img/logos/handsontable-dark-logo.svg#2" width="150" valign="middle" /></a></td>
93
- <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>
94
- <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>
95
- <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>
90
+ <td><a href="https://www.mercedes-benz.com/" target="_blank"><img src="https://nestjs.com/img/github/mercedes-logo.png" width="100" valign="middle" /></a></td>
91
+ <td><a href="https://handsontable.com/docs/react-data-grid/?utm_source=NestJS_GH&utm_medium=sponsorship&utm_campaign=library_sponsorship_2024" target="_blank"><img src="https://nestjs.com/img/github/handsontable-dark-logo.svg#2" width="150" valign="middle" /></a></td>
92
+ <td align="center" valign="middle"><a href="https://www.itflashcards.com/" target="_blank"><img src="https://nestjs.com/img/github/it_flashcards-logo.png" width="170" valign="middle" /></a></td>
93
+ <td align="center" valign="middle"><a href="https://arcjet.com/?ref=nestjs" target="_blank"><img src="https://nestjs.com/img/github/arcjet-logo.svg" width="170" valign="middle" /></a></td>
94
+ <td align="center" valign="middle"><a href="https://pandektes.com" target="_blank"><img src="https://nestjs.com/img/github/pandektes-logo.png" width="65" valign="middle" /></a></td>
96
95
  </tr><tr>
97
- <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>
98
- <td align="center" valign="middle"><a href="https://www.fintechcrafts.com/" target="_blank"><img src="https://nestjs.com/img/logos/fintechcrafts-logo.svg" width="65" valign="middle" /></a></td>
96
+ <td align="center" valign="middle"><a href="https://www.fintechcrafts.com/" target="_blank"><img src="https://opencollective-production.s3.us-west-1.amazonaws.com/account-avatar/935813df-48a9-4b41-b923-7d70b5621c6b/2026-05-06%2010%2021%2033.png" width="65" valign="middle" /></a></td>
99
97
  <td align="center" valign="middle"><a href="https://talordata.com/?campaignid=Ya5Xpw2gmhyee6Tg&utm_source=nestjs&utm_term=nestjs" target="_blank"><img src="https://images.opencollective.com/elowen/9ccac7f/avatar/512.png" width="65" valign="middle" /></a></td>
100
- <td align="center" valign="middle"><a href="https://www.rapidproxy.io/?ref=nestjs" target="_blank"><img src="https://nestjs.com/img/logos/rapid-logo.svg" width="120" valign="middle" /></a></td>
98
+ <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="65" valign="middle" /></a></td>
101
99
  </tr>
102
100
  </table>
103
101
 
@@ -105,33 +103,12 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
105
103
 
106
104
  <table>
107
105
  <tr>
108
- <td align="center" valign="middle"><a href="https://www.swingdev.io" target="_blank"><img src="https://nestjs.com/img/logos/swingdev-logo.svg#1" width="110" valign="middle" /></a></td>
109
- <td align="center" valign="middle"><a href="https://www.novologic.com/" target="_blank"><img src="https://nestjs.com/img/logos/novologic.png" width="110" valign="middle" /></a></td>
110
- <td align="center" valign="middle"><a href="https://mantro.net/" target="_blank"><img src="https://nestjs.com/img/logos/mantro-logo.svg" width="95" valign="middle" /></a></td>
111
- <td align="center" valign="middle"><a href="https://triplebyte.com/" target="_blank"><img src="https://nestjs.com/img/logos/triplebyte.png" width="107" valign="middle" /></a></td>
112
- <td align="center" valign="middle"><a href="https://nearpod.com/" target="_blank"><img src="https://nestjs.com/img/logos/nearpod-logo.svg" width="100" valign="middle" /></a></td>
113
- <td align="center" valign="middle"><a href="https://genuinebee.com/" target="_blank"><img src="https://nestjs.com/img/logos/genuinebee.svg" width="97" valign="middle" /></a></td>
114
- </tr>
115
- <tr>
116
- <td align="center" valign="middle"><a href="https://vpn-review.com/vpn-for-torrenting" target="_blank"><img src="https://nestjs.com/img/logos/vpn-review-logo.png" width="85" valign="middle" /></a></td>
117
- <td align="center" valign="middle"><a href="https://lambda-it.ch/" target="_blank"><img src="https://nestjs.com/img/logos/lambda-it-logo.svg" width="115" valign="middle" /></a></td>
118
- <td align="center" valign="middle"><a href="https://rocketech.it/cases/?utm_source=google&utm_medium=badge&utm_campaign=nestjs" target="_blank"><img src="https://nestjs.com/img/logos/rocketech-logo.svg" width="110" valign="middle" /></a></td>
119
- <td align="center" valign="middle"><a href="https://www.anonymistic.com/" target="_blank"><img src="https://nestjs.com/img/logos/anonymistic-logo.png" width="125" valign="middle" /></a></td>
120
- <td align="center" valign="middle"><a href="https://www.naologic.com/" target="_blank"><img src="https://nestjs.com/img/logos/naologic-logo.svg" width="125" valign="middle" /></a></td>
121
- <td align="center" valign="middle"><a href="https://triplecore.io" target="_blank"><img src="https://nestjs.com/img/logos/triplecore-logo.svg" width="50" valign="middle" /></a></td>
122
- </tr>
123
- <tr>
124
- <td align="center" valign="middle"><a href="https://polygon-software.ch/" target="_blank"><img src="https://nestjs.com/img/logos/polygon-logo.svg" width="120" valign="middle" /></a></td>
125
- <td align="center" valign="middle"><a href="https://boringowl.io/" target="_blank"><img src="https://nestjs.com/img/logos/boringowl-logo.svg" width="120" valign="middle" /></a></td>
126
- <td align="center" valign="middle"><a href="https://nordbot.app/" target="_blank"><img src="https://nestjs.com/img/logos/nordbot-logo.png" width="120" valign="middle" /></a></td>
127
- <td align="center" valign="middle"><a href="https://doppio.sh/" target="_blank"><img src="https://nestjs.com/img/logos/dopiosh-logo.png" width="50" valign="middle" /></a></td>
128
- <td align="center" valign="middle"><a href="https://www.hingehealth.com/" target="_blank"><img src="https://nestjs.com/img/logos/hinge-health-logo.svg" width="100" valign="middle" /></a></td>
129
- <td align="center" valign="middle"><a href="https://www.tripoffice.com/" target="_blank"><img src="https://nestjs.com/img/logos/tripoffice-logo.png" width="140" valign="middle" /></a></td>
130
- </tr>
131
- <tr>
132
- <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>
133
- <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>
134
- <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>
106
+ <td align="center" valign="middle"><a href="https://mantro.net/" target="_blank"><img src="https://nestjs.com/img/github/mantro-logo.svg" width="95" valign="middle" /></a></td>
107
+ <td align="center" valign="middle"><a href="https://triplebyte.com/" target="_blank"><img src="https://nestjs.com/img/github/triplebyte-logo.png" width="107" valign="middle" /></a></td>
108
+ <td align="center" valign="middle"><a href="https://nearpod.com/" target="_blank"><img src="https://nestjs.com/img/github/nearpod-logo.svg" width="100" valign="middle" /></a></td>
109
+ <td align="center" valign="middle"><a href="https://www.naologic.com/" target="_blank"><img src="https://nestjs.com/img/github/naologic-logo.svg" width="125" valign="middle" /></a></td>
110
+ <td align="center" valign="middle"><a href="https://triplecore.io" target="_blank"><img src="https://nestjs.com/img/github/triplecore-logo.svg" width="50" valign="middle" /></a>
111
+ <td align="center" valign="middle"><a href="https://www.hingehealth.com/" target="_blank"><img src="https://nestjs.com/img/github/hinge-health-logo.svg" width="100" valign="middle" /></a></td>
135
112
  </tr>
136
113
  </table>
137
114
 
@@ -28,10 +28,37 @@ class InterceptorsConsumer {
28
28
  return new execution_context_host_1.ExecutionContextHost(args, instance.constructor, callback);
29
29
  }
30
30
  transformDeferred(next) {
31
- return (0, rxjs_1.from)(next()).pipe((0, operators_1.switchMap)(res => {
32
- const isDeferred = res instanceof Promise || res instanceof rxjs_1.Observable;
33
- return isDeferred ? res : Promise.resolve(res);
34
- }));
31
+ // Call next() eagerly here — this method is invoked inside
32
+ // defer(AsyncResource.bind(...)), so the async context (e.g. AsyncLocalStorage)
33
+ // is correctly inherited. Deferring next() into the subscriber function would
34
+ // lose that context because the subscriber is called outside the bound scope.
35
+ const nextPromise = next();
36
+ return new rxjs_1.Observable(subscriber => {
37
+ let innerSub;
38
+ nextPromise
39
+ .then(res => {
40
+ if (subscriber.closed) {
41
+ // The outer subscription was torn down (e.g. an SSE client disconnect)
42
+ // before the async handler resolved. Subscribe-and-immediately-unsubscribe
43
+ // so the producer Observable's teardown/cleanup logic still runs.
44
+ if (res instanceof rxjs_1.Observable) {
45
+ const sub = res.subscribe({ error: () => { } });
46
+ sub.unsubscribe();
47
+ }
48
+ return;
49
+ }
50
+ const isDeferred = res instanceof Promise || res instanceof rxjs_1.Observable;
51
+ innerSub = (0, rxjs_1.from)(isDeferred ? res : Promise.resolve(res)).subscribe(subscriber);
52
+ })
53
+ .catch(err => {
54
+ if (!subscriber.closed) {
55
+ subscriber.error(err);
56
+ }
57
+ });
58
+ return () => {
59
+ innerSub?.unsubscribe();
60
+ };
61
+ });
35
62
  }
36
63
  }
37
64
  exports.InterceptorsConsumer = InterceptorsConsumer;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nestjs/core",
3
- "version": "11.1.26",
3
+ "version": "11.1.28",
4
4
  "description": "Nest - modern, fast, powerful node.js web framework (@core)",
5
5
  "author": "Kamil Mysliwiec",
6
6
  "license": "MIT",
@@ -28,7 +28,7 @@
28
28
  "uid": "2.0.2"
29
29
  },
30
30
  "devDependencies": {
31
- "@nestjs/common": "11.1.26"
31
+ "@nestjs/common": "11.1.28"
32
32
  },
33
33
  "peerDependencies": {
34
34
  "@nestjs/common": "^11.0.0",
@@ -49,5 +49,5 @@
49
49
  "optional": true
50
50
  }
51
51
  },
52
- "gitHead": "9ff83d540f50e96eb0093b4eb0dd96191aa6a285"
52
+ "gitHead": "dfaa376170168d12d9d28bcfe137a9bacce579a3"
53
53
  }
@@ -12,5 +12,5 @@ export declare class LegacyRouteConverter {
12
12
  logs?: boolean;
13
13
  }): string;
14
14
  static printError(route: string): void;
15
- static printWarning(route: string): void;
15
+ static printWarning(route: string, convertedRoute?: string): void;
16
16
  }
@@ -23,38 +23,47 @@ class LegacyRouteConverter {
23
23
  ? this.printWarning.bind(this)
24
24
  : () => { };
25
25
  if (normalizedRoute.endsWith('/(.*)/')) {
26
+ const convertedRoute = route.replace('(.*)', '{*path}');
26
27
  // Skip printing warning for the "all" wildcard.
27
28
  if (normalizedRoute !== '/(.*)/') {
28
- printWarning(route);
29
+ printWarning(route, convertedRoute);
29
30
  }
30
- return route.replace('(.*)', '{*path}');
31
+ return convertedRoute;
31
32
  }
32
33
  if (normalizedRoute.endsWith('/*/')) {
34
+ const convertedRoute = route.replace('*', '{*path}');
33
35
  // Skip printing warning for the "all" wildcard.
34
36
  if (normalizedRoute !== '/*/') {
35
- printWarning(route);
37
+ printWarning(route, convertedRoute);
36
38
  }
37
- return route.replace('*', '{*path}');
39
+ return convertedRoute;
38
40
  }
39
41
  if (normalizedRoute.endsWith('/+/')) {
40
- printWarning(route);
41
- return route.replace('/+', '/*path');
42
+ const convertedRoute = route.replace('/+', '/*path');
43
+ printWarning(route, convertedRoute);
44
+ return convertedRoute;
42
45
  }
43
46
  // When route includes any wildcard segments in the middle.
44
47
  if (normalizedRoute.includes('/*/')) {
45
- printWarning(route);
46
48
  // Replace each /*/ segment with a named parameter using different name for each segment.
47
- return route.replaceAll('/*/', (match, offset) => {
49
+ const convertedRoute = route.replaceAll('/*/', (match, offset) => {
48
50
  return `/*path${offset}/`;
49
51
  });
52
+ printWarning(route, convertedRoute);
53
+ return convertedRoute;
50
54
  }
51
55
  return route;
52
56
  }
53
57
  static printError(route) {
54
58
  this.logger.error(UNSUPPORTED_PATH_MESSAGE `${route}`);
55
59
  }
56
- static printWarning(route) {
57
- this.logger.warn(UNSUPPORTED_PATH_MESSAGE `${route}` + ' Attempting to auto-convert...');
60
+ static printWarning(route, convertedRoute) {
61
+ // Surface the auto-converted result so users can map the flagged path to a
62
+ // concrete fix, instead of only seeing the (often prefixed) offending path.
63
+ const autoConvertMessage = convertedRoute
64
+ ? ` Attempting to auto-convert to "${convertedRoute}"...`
65
+ : ' Attempting to auto-convert...';
66
+ this.logger.warn(UNSUPPORTED_PATH_MESSAGE `${route}` + autoConvertMessage);
58
67
  }
59
68
  }
60
69
  exports.LegacyRouteConverter = LegacyRouteConverter;
@@ -59,19 +59,28 @@ class RouterResponseController {
59
59
  200;
60
60
  return new Promise((resolve, reject) => {
61
61
  let settled = false;
62
+ let closeRequested = false;
62
63
  let subscription;
63
64
  const disconnectSource = request.socket ?? response;
64
65
  const cleanup = () => disconnectSource.removeListener('close', onClose);
66
+ const endStream = () => {
67
+ if (!stream.writableEnded) {
68
+ stream.end();
69
+ }
70
+ };
65
71
  const onClose = () => {
66
- if (settled) {
72
+ if (settled || closeRequested) {
73
+ return;
74
+ }
75
+ closeRequested = true;
76
+ if (!subscription) {
77
+ cleanup();
67
78
  return;
68
79
  }
69
80
  settled = true;
70
81
  cleanup();
71
82
  subscription?.unsubscribe();
72
- if (!stream.writableEnded) {
73
- stream.end();
74
- }
83
+ endStream();
75
84
  response.end();
76
85
  resolve();
77
86
  };
@@ -82,6 +91,17 @@ class RouterResponseController {
82
91
  return;
83
92
  }
84
93
  this.assertObservable(observableResult);
94
+ if (closeRequested) {
95
+ const cleanupSubscription = observableResult.subscribe({
96
+ error: () => undefined,
97
+ });
98
+ cleanupSubscription.unsubscribe();
99
+ settled = true;
100
+ endStream();
101
+ response.end();
102
+ resolve();
103
+ return;
104
+ }
85
105
  stream.pipe(response, {
86
106
  additionalHeaders: options?.additionalHeaders,
87
107
  statusCode,
@@ -111,9 +131,7 @@ class RouterResponseController {
111
131
  }
112
132
  settled = true;
113
133
  cleanup();
114
- if (!stream.writableEnded) {
115
- stream.end();
116
- }
134
+ endStream();
117
135
  reject(err);
118
136
  },
119
137
  complete: () => {
@@ -122,9 +140,7 @@ class RouterResponseController {
122
140
  }
123
141
  settled = true;
124
142
  cleanup();
125
- if (!stream.writableEnded) {
126
- stream.end();
127
- }
143
+ endStream();
128
144
  resolve();
129
145
  },
130
146
  });
@@ -143,11 +159,16 @@ class RouterResponseController {
143
159
  if (settled) {
144
160
  return;
145
161
  }
162
+ if (closeRequested) {
163
+ settled = true;
164
+ endStream();
165
+ response.end();
166
+ resolve();
167
+ return;
168
+ }
146
169
  settled = true;
147
170
  cleanup();
148
- if (!stream.writableEnded) {
149
- stream.end();
150
- }
171
+ endStream();
151
172
  reject(err);
152
173
  });
153
174
  });