@nestjs/core 11.1.27 → 11.1.29
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 +24 -47
- package/helpers/barrier.js +4 -1
- package/injector/injector.js +6 -10
- package/injector/module-ref.js +14 -12
- package/interceptors/interceptors-consumer.js +31 -4
- package/middleware/builder.js +5 -1
- package/nest-application-context.js +4 -11
- package/nest-application.d.ts +1 -0
- package/nest-application.js +15 -1
- package/package.json +3 -3
- package/router/legacy-route-converter.d.ts +1 -1
- package/router/legacy-route-converter.js +19 -10
- package/router/sse-stream.d.ts +1 -0
- package/router/sse-stream.js +22 -11
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/
|
|
64
|
-
<td><a href="https://mojam.co" target="_blank"><img src="https://
|
|
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/
|
|
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/
|
|
75
|
-
<td><a href="https://github.com/Sanofi-IADC" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/sanofi.png" width="
|
|
76
|
-
<td><a href="https://nx.dev" target="_blank"><img src="https://nestjs.com/img/
|
|
77
|
-
<td><a href="https://intrinsic.ventures/" target="_blank"><img src="https://nestjs.com/img/
|
|
78
|
-
<td><a href="https://jetbrains.com/" target="_blank"><img src="https://nestjs.com/img/
|
|
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/
|
|
82
|
-
<td><a href="https://www.movavi.com/imovie-for-windows.html" target="_blank"><img src="https://
|
|
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/
|
|
91
|
-
<td><a href="https://
|
|
92
|
-
<td><a href="https://
|
|
93
|
-
<td align="center" valign="middle"><a href="https://
|
|
94
|
-
<td align="center" valign="middle"><a href="https://
|
|
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://
|
|
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://
|
|
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://
|
|
109
|
-
<td align="center" valign="middle"><a href="https://
|
|
110
|
-
<td align="center" valign="middle"><a href="https://
|
|
111
|
-
<td align="center" valign="middle"><a href="https://
|
|
112
|
-
<td align="center" valign="middle"><a href="https://
|
|
113
|
-
<td align="center" valign="middle"><a href="https://
|
|
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
|
|
package/helpers/barrier.js
CHANGED
|
@@ -11,6 +11,9 @@ class Barrier {
|
|
|
11
11
|
this.promise = new Promise(resolve => {
|
|
12
12
|
this.resolve = resolve;
|
|
13
13
|
});
|
|
14
|
+
if (targetCount === 0) {
|
|
15
|
+
this.resolve();
|
|
16
|
+
}
|
|
14
17
|
}
|
|
15
18
|
/**
|
|
16
19
|
* Signal that a participant has reached the barrier.
|
|
@@ -19,7 +22,7 @@ class Barrier {
|
|
|
19
22
|
*/
|
|
20
23
|
signal() {
|
|
21
24
|
this.currentCount += 1;
|
|
22
|
-
if (this.currentCount
|
|
25
|
+
if (this.currentCount >= this.targetCount) {
|
|
23
26
|
this.resolve();
|
|
24
27
|
}
|
|
25
28
|
}
|
package/injector/injector.js
CHANGED
|
@@ -328,16 +328,12 @@ class Injector {
|
|
|
328
328
|
this.printFoundInModuleLog(name, relatedModule);
|
|
329
329
|
instanceWrapperRef = providers.get(name);
|
|
330
330
|
this.addDependencyMetadata(keyOrIndex, wrapper, instanceWrapperRef);
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
* staticity of the dependency tree and lead to undefined / null injection.
|
|
338
|
-
*/
|
|
339
|
-
break;
|
|
340
|
-
}
|
|
331
|
+
/*
|
|
332
|
+
* Stop at the first direct export match. Continuing when the provider is
|
|
333
|
+
* already resolved would let a later import (e.g. a global forRoot module)
|
|
334
|
+
* override an explicit forFeature import for the same token.
|
|
335
|
+
*/
|
|
336
|
+
break;
|
|
341
337
|
}
|
|
342
338
|
return instanceWrapperRef;
|
|
343
339
|
}
|
package/injector/module-ref.js
CHANGED
|
@@ -56,9 +56,9 @@ class ModuleRef extends abstract_instance_resolver_1.AbstractInstanceResolver {
|
|
|
56
56
|
isPending: false,
|
|
57
57
|
});
|
|
58
58
|
}
|
|
59
|
-
return new Promise(
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
return new Promise((resolve, reject) => {
|
|
60
|
+
const callback = async (instances) => {
|
|
61
|
+
try {
|
|
62
62
|
const properties = await this.injector.resolveProperties(wrapper, moduleRef, undefined, {
|
|
63
63
|
contextId: contextId ?? constants_1.STATIC_CONTEXT,
|
|
64
64
|
inquirer: wrapper,
|
|
@@ -66,15 +66,17 @@ class ModuleRef extends abstract_instance_resolver_1.AbstractInstanceResolver {
|
|
|
66
66
|
const instance = new type(...instances);
|
|
67
67
|
this.injector.applyProperties(instance, properties);
|
|
68
68
|
resolve(instance);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
reject(err);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
this.injector
|
|
75
|
+
.resolveConstructorParams(wrapper, moduleRef, undefined, callback, {
|
|
76
|
+
contextId: contextId ?? constants_1.STATIC_CONTEXT,
|
|
77
|
+
inquirer: wrapper,
|
|
78
|
+
})
|
|
79
|
+
.catch(reject);
|
|
78
80
|
});
|
|
79
81
|
}
|
|
80
82
|
}
|
|
@@ -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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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/middleware/builder.js
CHANGED
|
@@ -73,7 +73,11 @@ MiddlewareBuilder.ConfigProxy = class {
|
|
|
73
73
|
.map(route => ({
|
|
74
74
|
method: route.method,
|
|
75
75
|
path: route.path,
|
|
76
|
-
|
|
76
|
+
// No `g` flag: each regex is reused across every route below, and a
|
|
77
|
+
// global regex advances `lastIndex` on a match, so the next `test()`
|
|
78
|
+
// would resume mid-string and fail the `^` anchor. The pattern is
|
|
79
|
+
// anchored and only used with `test()`, so `g` buys nothing anyway.
|
|
80
|
+
regex: new RegExp('^(' + route.path.replace(regexMatchParams, wildcard) + ')$'),
|
|
77
81
|
}));
|
|
78
82
|
return routes.filter(route => {
|
|
79
83
|
const isOverlapped = (item) => {
|
|
@@ -104,17 +104,10 @@ class NestApplicationContext extends abstract_instance_resolver_1.AbstractInstan
|
|
|
104
104
|
if (this.isInitialized) {
|
|
105
105
|
return this;
|
|
106
106
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
await this.callBootstrapHook();
|
|
112
|
-
resolve();
|
|
113
|
-
}
|
|
114
|
-
catch (err) {
|
|
115
|
-
reject(err);
|
|
116
|
-
}
|
|
117
|
-
});
|
|
107
|
+
this.initializationPromise = (async () => {
|
|
108
|
+
await this.callInitHook();
|
|
109
|
+
await this.callBootstrapHook();
|
|
110
|
+
})();
|
|
118
111
|
await this.initializationPromise;
|
|
119
112
|
this.isInitialized = true;
|
|
120
113
|
return this;
|
package/nest-application.d.ts
CHANGED
package/nest-application.js
CHANGED
|
@@ -151,7 +151,7 @@ class NestApplication extends nest_application_context_1.NestApplicationContext
|
|
|
151
151
|
return this;
|
|
152
152
|
}
|
|
153
153
|
use(...args) {
|
|
154
|
-
this.httpAdapter.use(...args);
|
|
154
|
+
this.httpAdapter.use(...this.applyFunctionDecoratorIfRegistered(args));
|
|
155
155
|
return this;
|
|
156
156
|
}
|
|
157
157
|
useBodyParser(...args) {
|
|
@@ -329,5 +329,19 @@ class NestApplication extends nest_application_context_1.NestApplicationContext
|
|
|
329
329
|
}
|
|
330
330
|
return instances;
|
|
331
331
|
}
|
|
332
|
+
applyFunctionDecoratorIfRegistered(args) {
|
|
333
|
+
if (!this.appOptions.instrument?.instanceDecorator) {
|
|
334
|
+
return args;
|
|
335
|
+
}
|
|
336
|
+
const [firstArg, secondArg] = args;
|
|
337
|
+
return [
|
|
338
|
+
(0, shared_utils_1.isFunction)(firstArg)
|
|
339
|
+
? this.appOptions.instrument.instanceDecorator(firstArg)
|
|
340
|
+
: firstArg,
|
|
341
|
+
(0, shared_utils_1.isFunction)(secondArg)
|
|
342
|
+
? this.appOptions.instrument.instanceDecorator(secondArg)
|
|
343
|
+
: secondArg,
|
|
344
|
+
];
|
|
345
|
+
}
|
|
332
346
|
}
|
|
333
347
|
exports.NestApplication = NestApplication;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nestjs/core",
|
|
3
|
-
"version": "11.1.
|
|
3
|
+
"version": "11.1.29",
|
|
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.
|
|
31
|
+
"@nestjs/common": "11.1.29"
|
|
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": "
|
|
52
|
+
"gitHead": "03587a112ebbbb53a6bc3875afb5a9205aa5a5f1"
|
|
53
53
|
}
|
|
@@ -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
|
|
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
|
|
39
|
+
return convertedRoute;
|
|
38
40
|
}
|
|
39
41
|
if (normalizedRoute.endsWith('/+/')) {
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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;
|
package/router/sse-stream.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export type HeaderStream = WritableHeaderStream & ReadHeaders;
|
|
|
22
22
|
* - type
|
|
23
23
|
* - id
|
|
24
24
|
* - retry
|
|
25
|
+
* - comment
|
|
25
26
|
*
|
|
26
27
|
* If constructed with a HTTP Request, it will optimise the socket for streaming.
|
|
27
28
|
* If this stream is piped to an HTTP Response, it will set appropriate headers.
|
package/router/sse-stream.js
CHANGED
|
@@ -3,14 +3,26 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.SseStream = void 0;
|
|
4
4
|
const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
|
|
5
5
|
const stream_1 = require("stream");
|
|
6
|
+
function serializeSseLines(value, prefix) {
|
|
7
|
+
return value
|
|
8
|
+
.split(/\r\n|\r|\n/)
|
|
9
|
+
.map(line => `${prefix}${line}\n`)
|
|
10
|
+
.join('');
|
|
11
|
+
}
|
|
6
12
|
function toDataString(data) {
|
|
7
13
|
if ((0, shared_utils_1.isObject)(data)) {
|
|
8
14
|
return toDataString(JSON.stringify(data));
|
|
9
15
|
}
|
|
10
|
-
return data
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
16
|
+
return serializeSseLines(data, 'data: ');
|
|
17
|
+
}
|
|
18
|
+
function toCommentString(comment) {
|
|
19
|
+
return serializeSseLines(comment, ': ');
|
|
20
|
+
}
|
|
21
|
+
function isCommentOnly(message) {
|
|
22
|
+
return (!(0, shared_utils_1.isNil)(message.comment) &&
|
|
23
|
+
(0, shared_utils_1.isUndefined)(message.data) &&
|
|
24
|
+
(0, shared_utils_1.isUndefined)(message.type) &&
|
|
25
|
+
(0, shared_utils_1.isUndefined)(message.retry));
|
|
14
26
|
}
|
|
15
27
|
/**
|
|
16
28
|
* Adapted from https://raw.githubusercontent.com/EventSource/node-ssestream
|
|
@@ -21,6 +33,7 @@ function toDataString(data) {
|
|
|
21
33
|
* - type
|
|
22
34
|
* - id
|
|
23
35
|
* - retry
|
|
36
|
+
* - comment
|
|
24
37
|
*
|
|
25
38
|
* If constructed with a HTTP Request, it will optimise the socket for streaming.
|
|
26
39
|
* If this stream is piped to an HTTP Response, it will set appropriate headers.
|
|
@@ -84,12 +97,10 @@ class SseStream extends stream_1.Transform {
|
|
|
84
97
|
this.commitHeaders();
|
|
85
98
|
const sanitize = (val) => String(val).replace(/[\r\n]/g, '');
|
|
86
99
|
let data = message.type ? `event: ${sanitize(message.type)}\n` : '';
|
|
87
|
-
data +=
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
data += message.retry ? `retry: ${sanitize(message.retry)}\n` : '';
|
|
92
|
-
data += message.data ? toDataString(message.data) : '';
|
|
100
|
+
data += !(0, shared_utils_1.isNil)(message.id) ? `id: ${sanitize(message.id)}\n` : '';
|
|
101
|
+
data += !(0, shared_utils_1.isNil)(message.retry) ? `retry: ${sanitize(message.retry)}\n` : '';
|
|
102
|
+
data += !(0, shared_utils_1.isNil)(message.comment) ? toCommentString(message.comment) : '';
|
|
103
|
+
data += !(0, shared_utils_1.isNil)(message.data) ? toDataString(message.data) : '';
|
|
93
104
|
data += '\n';
|
|
94
105
|
this.push(data);
|
|
95
106
|
callback();
|
|
@@ -98,7 +109,7 @@ class SseStream extends stream_1.Transform {
|
|
|
98
109
|
* Calls `.write` but handles the drain if needed
|
|
99
110
|
*/
|
|
100
111
|
writeMessage(message, cb) {
|
|
101
|
-
if (message.id
|
|
112
|
+
if ((0, shared_utils_1.isNil)(message.id) && !isCommentOnly(message)) {
|
|
102
113
|
this.lastEventId++;
|
|
103
114
|
message.id = this.lastEventId.toString();
|
|
104
115
|
}
|