mirror of
https://github.com/nestjs/nest.git
synced 2026-02-24 00:02:56 +00:00
Compare commits
405 Commits
nean-updat
...
v7.6.13
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4a2b06205 | ||
|
|
7cb7b1dc8a | ||
|
|
e7fa96022e | ||
|
|
de4a90cc65 | ||
|
|
dfb03e17ef | ||
|
|
87b6951143 | ||
|
|
1e644bd95b | ||
|
|
29cc923de8 | ||
|
|
d570a79a3b | ||
|
|
7ad0f61bf4 | ||
|
|
513d2c91aa | ||
|
|
c19f6267d4 | ||
|
|
c1c7f00f85 | ||
|
|
6ac26cba50 | ||
|
|
a9d16961af | ||
|
|
49e2c4dc7d | ||
|
|
9518f6448f | ||
|
|
2882764a45 | ||
|
|
38cfd1b445 | ||
|
|
aa47eb99be | ||
|
|
ffa1ead4a2 | ||
|
|
5385337dfc | ||
|
|
89c454b996 | ||
|
|
f95d37f542 | ||
|
|
a47c2d8ddc | ||
|
|
e86a66c794 | ||
|
|
b39ae98514 | ||
|
|
3d40ae3f3c | ||
|
|
6b4f830e30 | ||
|
|
7809ec8d45 | ||
|
|
2eff8bb355 | ||
|
|
9a12e7bf35 | ||
|
|
bbf9e693b6 | ||
|
|
47b2ed07ed | ||
|
|
59319e93d9 | ||
|
|
45866e26ab | ||
|
|
544633f4ad | ||
|
|
c8de663f40 | ||
|
|
801dd7a882 | ||
|
|
14a2415070 | ||
|
|
c429576c07 | ||
|
|
0a287c8817 | ||
|
|
cc445332a3 | ||
|
|
fcb31ab7bb | ||
|
|
bc6dda9992 | ||
|
|
99059148d4 | ||
|
|
1848755d21 | ||
|
|
d450111f06 | ||
|
|
db73a25a1d | ||
|
|
e20758036e | ||
|
|
9922cae666 | ||
|
|
8f270c4129 | ||
|
|
147cd417b5 | ||
|
|
cbbc01fe43 | ||
|
|
a5a05fa5b0 | ||
|
|
23001620eb | ||
|
|
55d113c250 | ||
|
|
45345cfb6a | ||
|
|
97d0aee4e1 | ||
|
|
5cd3c3c0c9 | ||
|
|
4fa1564288 | ||
|
|
a5a8bc80c3 | ||
|
|
50b7c7103e | ||
|
|
c25abbfda4 | ||
|
|
60bae3d5f0 | ||
|
|
14969285ea | ||
|
|
e9e2f8e884 | ||
|
|
151562673a | ||
|
|
36027564bd | ||
|
|
78fe4989ca | ||
|
|
517df3ce9e | ||
|
|
f26163df3e | ||
|
|
4e19e959f2 | ||
|
|
ceb5de6479 | ||
|
|
e6772683ce | ||
|
|
60aafc591b | ||
|
|
78fa9b4e64 | ||
|
|
40b1a7c106 | ||
|
|
af420c44e9 | ||
|
|
e95c6e7456 | ||
|
|
fac59d5530 | ||
|
|
f7d0e94a0e | ||
|
|
00995d0ff3 | ||
|
|
c3806a557a | ||
|
|
b3e0568245 | ||
|
|
5fe60d707b | ||
|
|
6c44abedc8 | ||
|
|
6d625b91b4 | ||
|
|
51c091e8eb | ||
|
|
597b6c514a | ||
|
|
8be6777d6b | ||
|
|
4b73018de0 | ||
|
|
b4907b36ae | ||
|
|
2dc8b572a1 | ||
|
|
1e916fbc6a | ||
|
|
59c917e30a | ||
|
|
6421d6b04a | ||
|
|
0257245554 | ||
|
|
47525d26d8 | ||
|
|
954fbb693f | ||
|
|
fbe04f2db4 | ||
|
|
e088e113b7 | ||
|
|
d478e22723 | ||
|
|
d513fdf408 | ||
|
|
a7df4d6d55 | ||
|
|
b32817aeed | ||
|
|
c349d92bea | ||
|
|
f4a8f493bc | ||
|
|
a60491d9bc | ||
|
|
80edd1002b | ||
|
|
527f8ccfbb | ||
|
|
7a7ccb7c45 | ||
|
|
8e999a7665 | ||
|
|
1a8eefebfd | ||
|
|
cf5cd331ec | ||
|
|
b8078d7d05 | ||
|
|
34adb6d90b | ||
|
|
bff8609b98 | ||
|
|
29847d265c | ||
|
|
38a2b106c4 | ||
|
|
0a8eb9cbbe | ||
|
|
40ec0aee09 | ||
|
|
5fcda32a88 | ||
|
|
c4778047ca | ||
|
|
10164b6770 | ||
|
|
0312224383 | ||
|
|
a8e19c0514 | ||
|
|
ccfb512992 | ||
|
|
fa3b744e46 | ||
|
|
86870636a2 | ||
|
|
b9d39b973d | ||
|
|
5b07b2432f | ||
|
|
2ceddd61c0 | ||
|
|
1ac11d1b06 | ||
|
|
8503d62e4e | ||
|
|
6e8547bd94 | ||
|
|
7009884378 | ||
|
|
170f574bef | ||
|
|
124afbbdc7 | ||
|
|
bee7ab584f | ||
|
|
97fe2dde38 | ||
|
|
52483414d6 | ||
|
|
3323283a1d | ||
|
|
4b3f1a43ae | ||
|
|
b5006c958f | ||
|
|
36757d4056 | ||
|
|
989a66a2ec | ||
|
|
38baa94eee | ||
|
|
b4bad009d9 | ||
|
|
6aa9c131ac | ||
|
|
58cdb78acc | ||
|
|
fd7286476b | ||
|
|
d5c51c144b | ||
|
|
6c65300078 | ||
|
|
3e196c1376 | ||
|
|
462da30ecd | ||
|
|
ddcd840fb8 | ||
|
|
025689f022 | ||
|
|
d449a70a49 | ||
|
|
fd094c19c9 | ||
|
|
28d1ab655e | ||
|
|
4feca70016 | ||
|
|
59476d8aa5 | ||
|
|
8f6ee6ec82 | ||
|
|
7a224d6ce9 | ||
|
|
5657412a55 | ||
|
|
e4d6695c15 | ||
|
|
ee92aecddf | ||
|
|
2deced39c8 | ||
|
|
095bce2687 | ||
|
|
c190ccb5cd | ||
|
|
71fb7c68b2 | ||
|
|
0e16450a64 | ||
|
|
2ee0e7f840 | ||
|
|
b365aa5fba | ||
|
|
a423ca8c31 | ||
|
|
e0816c91a1 | ||
|
|
8cd06e9bb5 | ||
|
|
b21af5ef47 | ||
|
|
7b95db1a5b | ||
|
|
1823b46607 | ||
|
|
f6715dae15 | ||
|
|
da2935cc0f | ||
|
|
65e1cca493 | ||
|
|
6bf271aa10 | ||
|
|
e22c6019e9 | ||
|
|
054bae48a1 | ||
|
|
0ba2658ab4 | ||
|
|
dcf8788262 | ||
|
|
c8f739ced0 | ||
|
|
eb233d9fb3 | ||
|
|
b8e552b229 | ||
|
|
a96b08465e | ||
|
|
c47c45b6ff | ||
|
|
93b5598a33 | ||
|
|
29497d61af | ||
|
|
f37e23c5ea | ||
|
|
07cab6a468 | ||
|
|
fa0e011b03 | ||
|
|
d034e62ff0 | ||
|
|
396fe779e6 | ||
|
|
5728578e10 | ||
|
|
0db1b041ef | ||
|
|
821574cee9 | ||
|
|
4f96cadb7e | ||
|
|
90d64d085d | ||
|
|
6db30813de | ||
|
|
b336fd172c | ||
|
|
3123ad3f19 | ||
|
|
fc5f3c91af | ||
|
|
e51ab047d2 | ||
|
|
2ba2b99325 | ||
|
|
ba37eee5b0 | ||
|
|
4804f32472 | ||
|
|
40a0678fbf | ||
|
|
a11d167130 | ||
|
|
6b119c3579 | ||
|
|
f22d3370f3 | ||
|
|
c12100c3c6 | ||
|
|
8cf29c9172 | ||
|
|
12ac1108a7 | ||
|
|
c150deefbd | ||
|
|
68b5d2a8e2 | ||
|
|
4d87dd6b1e | ||
|
|
e0b825121b | ||
|
|
dc8b1d5c72 | ||
|
|
832b3bc90c | ||
|
|
8180e5905c | ||
|
|
2307373bfe | ||
|
|
71255392c9 | ||
|
|
07c8cdc80b | ||
|
|
f9e5272e2b | ||
|
|
b842a7e817 | ||
|
|
8df890a8ac | ||
|
|
060befe22e | ||
|
|
06bddccb5c | ||
|
|
4f88c3d147 | ||
|
|
dd7c176df3 | ||
|
|
c43fb62322 | ||
|
|
8c4fb929b7 | ||
|
|
1130edc150 | ||
|
|
6417c5477a | ||
|
|
149483a852 | ||
|
|
27d9202108 | ||
|
|
950e3697c7 | ||
|
|
df5a7c3a48 | ||
|
|
25b7ad5805 | ||
|
|
0f668075fb | ||
|
|
b74f80fb1c | ||
|
|
a0d08f049c | ||
|
|
c88db600a0 | ||
|
|
91be6a6a55 | ||
|
|
e196f51608 | ||
|
|
f4c45f8d88 | ||
|
|
4baea48cfa | ||
|
|
275e71f89a | ||
|
|
4a1074a793 | ||
|
|
e9d1735688 | ||
|
|
3b93861706 | ||
|
|
6d1c02be01 | ||
|
|
1e5f60ed17 | ||
|
|
6379162871 | ||
|
|
fddc980b1d | ||
|
|
6027001b4e | ||
|
|
0cd83570a2 | ||
|
|
48d91c9646 | ||
|
|
9b9b3564a4 | ||
|
|
25526070a1 | ||
|
|
6df1712b0d | ||
|
|
8aa0f75c8c | ||
|
|
c0babd6cfd | ||
|
|
6448d17f43 | ||
|
|
6a9c9100f5 | ||
|
|
55c7051787 | ||
|
|
db6a555d29 | ||
|
|
7c722c3d0b | ||
|
|
e7011e3b4f | ||
|
|
0fb8e1a025 | ||
|
|
459458bbb4 | ||
|
|
9e96e76e1a | ||
|
|
a63db1b8aa | ||
|
|
477b6d0d5c | ||
|
|
90aa625bf8 | ||
|
|
e8541185f0 | ||
|
|
c48e2bcfdb | ||
|
|
667df81eb5 | ||
|
|
fb5117c241 | ||
|
|
ec9727093d | ||
|
|
d2e6616115 | ||
|
|
9f3614042f | ||
|
|
2bc2c8adfa | ||
|
|
e4c5d17df2 | ||
|
|
bf420cd91d | ||
|
|
5d48691713 | ||
|
|
454d519c67 | ||
|
|
60f256ecdf | ||
|
|
df4c2eb318 | ||
|
|
843116eea9 | ||
|
|
3af5404401 | ||
|
|
9a6610cb07 | ||
|
|
a76a6e4a30 | ||
|
|
d063c4772d | ||
|
|
64d78a9c80 | ||
|
|
efe4884c27 | ||
|
|
5ebd3353b1 | ||
|
|
5d2fa36556 | ||
|
|
1440ccaa4b | ||
|
|
42262df197 | ||
|
|
6f119c843c | ||
|
|
cb0564d77a | ||
|
|
d28c25618d | ||
|
|
4a57915f5a | ||
|
|
3188b801bd | ||
|
|
b7e46f45d4 | ||
|
|
993e5f4a91 | ||
|
|
bc394eabb2 | ||
|
|
0b874e7dfc | ||
|
|
a65fcd1472 | ||
|
|
159cdce1f1 | ||
|
|
b298b8bc92 | ||
|
|
53226211f7 | ||
|
|
d4bb87c5eb | ||
|
|
fa4642f70f | ||
|
|
c4c1b7c6a5 | ||
|
|
2be4c4cd70 | ||
|
|
76289893d7 | ||
|
|
b3e654e84d | ||
|
|
668d781b6c | ||
|
|
fb45437621 | ||
|
|
0c7bf92086 | ||
|
|
091d09fde2 | ||
|
|
653f0a4281 | ||
|
|
48d899d025 | ||
|
|
81f3161f7c | ||
|
|
0f29446c65 | ||
|
|
1b31a744a8 | ||
|
|
0fe31b9bc8 | ||
|
|
5da5a4ad58 | ||
|
|
2abb9b2154 | ||
|
|
43f053ab21 | ||
|
|
a74725d585 | ||
|
|
51f5de8333 | ||
|
|
0c8b004bf9 | ||
|
|
3ce92c7883 | ||
|
|
3bbde4c26c | ||
|
|
a48107ef92 | ||
|
|
b7990aa5b1 | ||
|
|
07737aa371 | ||
|
|
ca7b79532f | ||
|
|
ad6ce62f0e | ||
|
|
4c814a2d85 | ||
|
|
1dbb8ff3db | ||
|
|
c6780a3a91 | ||
|
|
1945f8d24a | ||
|
|
ccd4fdae58 | ||
|
|
817d9f45e0 | ||
|
|
9362db8042 | ||
|
|
2fb5f4dd16 | ||
|
|
a400be366b | ||
|
|
7267409d91 | ||
|
|
fa494041c8 | ||
|
|
af4f041d6a | ||
|
|
562b2bb175 | ||
|
|
36c2a35614 | ||
|
|
fb4cc36c75 | ||
|
|
7386204da6 | ||
|
|
d99370bb1d | ||
|
|
90fcd3599e | ||
|
|
e3a66d1902 | ||
|
|
71cab143e6 | ||
|
|
3357fe0349 | ||
|
|
be0cdfe7e6 | ||
|
|
c9c92b47de | ||
|
|
6fb25e93e2 | ||
|
|
6957b52afe | ||
|
|
5b7eae83e0 | ||
|
|
52546cc62e | ||
|
|
d43c4d7510 | ||
|
|
b4c24cc17e | ||
|
|
119190ad75 | ||
|
|
3361cfd236 | ||
|
|
0cf4409869 | ||
|
|
5028393d57 | ||
|
|
05b771a9c2 | ||
|
|
d972d9ad8f | ||
|
|
668968faa9 | ||
|
|
d588b8bc68 | ||
|
|
1a0922a58b | ||
|
|
cd04a8d58a | ||
|
|
ff935dac06 | ||
|
|
ba2f5ae63a | ||
|
|
0d67f823d5 | ||
|
|
f001a9ab83 | ||
|
|
8bc4e92d21 | ||
|
|
e6e11b9cf1 | ||
|
|
766218aad1 | ||
|
|
d6b2266615 | ||
|
|
86051702b8 | ||
|
|
dd51cf8f51 | ||
|
|
525ef91307 | ||
|
|
7dad2e479b | ||
|
|
530274e2c8 | ||
|
|
d24d0381a2 | ||
|
|
85dcf72508 | ||
|
|
f4df4d9a9e |
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2017-2020 Kamil Mysliwiec <https://kamilmysliwiec.com>
|
||||
Copyright (c) 2017-2021 Kamil Mysliwiec <https://kamilmysliwiec.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
||||
18
Readme.md
18
Readme.md
@@ -56,16 +56,21 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
||||
|
||||
#### Principal Sponsors
|
||||
<table style="text-align:center;"><tr><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><td>
|
||||
<a href="https://valor-software.com/" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/valor-software.png" width="180" valign="middle" /></a></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>
|
||||
<td>
|
||||
<a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="200" valign="middle" /></a></td>
|
||||
</tr></table>
|
||||
|
||||
#### Gold Sponsors
|
||||
|
||||
<table style="text-align:center;"><tr><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></tr></table>
|
||||
|
||||
#### Silver Sponsors
|
||||
|
||||
<table style="text-align:center;"><tr><td>
|
||||
<a href="https://neoteric.eu/" target="_blank"><img src="https://nestjs.com/img/neoteric-cut.png" width="120" valign="middle" /></a> </td><td>
|
||||
<a href="http://gojob.com" target="_blank"><img src="http://nestjs.com/img/gojob-logo.png" valign="middle" width="100" /></a> </td><td>
|
||||
<a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="170" valign="middle" /></a> </td><td>
|
||||
<a href="http://www.leogistics.com" target="_blank"><img src="https://nestjs.com/img/leogistics-logo.jpeg" width="150" valign="middle" /></td><td>
|
||||
<a href="http://www.meetdandy.com" target="_blank"><img src="https://nestjs.com/img/dandy-wide-logo.png" width="150" valign="middle" /></td></tr></table>
|
||||
|
||||
@@ -90,6 +95,13 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://genuinebee.com/" target="_blank"><img src="https://nestjs.com/img/genuinebee.svg" width="97" valign="middle" /></a> </td>
|
||||
<td align="center" valign="middle"><a href="https://sanyodigital.com/" target="_blank"><img src="https://nestjs.com/img/sanyo-digital.png" width="130" valign="middle" /></a></td></tr><tr><td align="center" valign="middle"><a href="https://vpn-review.com/vpn-for-torrenting" target="_blank"><img src="https://nestjs.com/img/vpn-review-logo.png" width="85" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://lambda-it.ch/" target="_blank"><img src="https://nestjs.com/img/lambda-it-logo.svg" width="115" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://pickwriters.com/top-10-translation-services" target="_blank"><img src="https://nestjs.com/img/pickwriters-logo.png" width="40" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://thewordpoint.com/services/localization" target="_blank"><img src="https://nestjs.com/img/thewordpoint-logo.png" width="40" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://streamat.se/" target="_blank"><img src="https://nestjs.com/img/streamat-logo.png" width="120" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://filmen.nu/" target="_blank"><img src="https://nestjs.com/img/filmen-logo.png" width="120" valign="middle" /></a></td></tr><tr>
|
||||
<td align="center" valign="middle"><a href="https://meercode.io/" target="_blank"><img src="https://nestjs.com/img/meercode-logo.png" width="60" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://www.najlepszeplatformyforex.pl/blog/broker-xtb/" target="_blank"><img src="https://nestjs.com/img/npf-logo.jpg" width="200" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://thestandarddaily.com/" target="_blank"><img src="https://nestjs.com/img/the-standard-daily-logo.png" width="180" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://houseofangular.io/" target="_blank"><img src="https://nestjs.com/img/house-of-angular.png" width="100" valign="middle" /></a></td>
|
||||
<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/rocketech-logo.svg" width="110" valign="middle" /></a></td>
|
||||
</tr></table>
|
||||
|
||||
## Backers
|
||||
|
||||
@@ -2,47 +2,87 @@
|
||||
express
|
||||
-----------------------
|
||||
Running 10s test @ http://localhost:3000
|
||||
8 threads and 1024 connections
|
||||
Thread Stats Avg Stdev Max +/- Stdev
|
||||
Latency 47.78ms 19.09ms 212.47ms 66.94%
|
||||
Req/Sec 1.31k 268.90 2.07k 72.38%
|
||||
104687 requests in 10.02s, 21.47MB read
|
||||
Socket errors: connect 0, read 877, write 0, timeout 0
|
||||
Requests/sec: 10444.24
|
||||
Transfer/sec: 2.14MB
|
||||
1024 connections
|
||||
|
||||
┌─────────┬───────┬───────┬───────┬────────┬──────────┬──────────┬────────┐
|
||||
│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
|
||||
├─────────┼───────┼───────┼───────┼────────┼──────────┼──────────┼────────┤
|
||||
│ Latency │ 55 ms │ 58 ms │ 91 ms │ 138 ms │ 61.88 ms │ 23.95 ms │ 747 ms │
|
||||
└─────────┴───────┴───────┴───────┴────────┴──────────┴──────────┴────────┘
|
||||
┌───────────┬─────────┬─────────┬─────────┬─────────┬──────────┬─────────┬─────────┐
|
||||
│ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
|
||||
├───────────┼─────────┼─────────┼─────────┼─────────┼──────────┼─────────┼─────────┤
|
||||
│ Req/Sec │ 8407 │ 8407 │ 17407 │ 17743 │ 16454.41 │ 2716.94 │ 8402 │
|
||||
├───────────┼─────────┼─────────┼─────────┼─────────┼──────────┼─────────┼─────────┤
|
||||
│ Bytes/Sec │ 1.81 MB │ 1.81 MB │ 3.74 MB │ 3.81 MB │ 3.54 MB │ 584 kB │ 1.81 MB │
|
||||
└───────────┴─────────┴─────────┴─────────┴─────────┴──────────┴─────────┴─────────┘
|
||||
|
||||
Req/Bytes counts sampled once per second.
|
||||
|
||||
165k requests in 10.17s, 35.4 MB read
|
||||
-----------------------
|
||||
nest (with "@nestjs/platform-express")
|
||||
-----------------------
|
||||
Running 10s test @ http://localhost:3000
|
||||
1024 connections
|
||||
|
||||
┌─────────┬───────┬───────┬───────┬───────┬──────────┬──────────┬────────┐
|
||||
│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
|
||||
├─────────┼───────┼───────┼───────┼───────┼──────────┼──────────┼────────┤
|
||||
│ Latency │ 61 ms │ 64 ms │ 71 ms │ 94 ms │ 65.44 ms │ 17.35 ms │ 325 ms │
|
||||
└─────────┴───────┴───────┴───────┴───────┴──────────┴──────────┴────────┘
|
||||
┌───────────┬─────────┬─────────┬─────────┬─────────┬─────────┬────────┬─────────┐
|
||||
│ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
|
||||
├───────────┼─────────┼─────────┼─────────┼─────────┼─────────┼────────┼─────────┤
|
||||
│ Req/Sec │ 14183 │ 14183 │ 15767 │ 15991 │ 15640 │ 501.13 │ 14182 │
|
||||
├───────────┼─────────┼─────────┼─────────┼─────────┼─────────┼────────┼─────────┤
|
||||
│ Bytes/Sec │ 3.06 MB │ 3.06 MB │ 3.41 MB │ 3.45 MB │ 3.38 MB │ 108 kB │ 3.06 MB │
|
||||
└───────────┴─────────┴─────────┴─────────┴─────────┴─────────┴────────┴─────────┘
|
||||
|
||||
Req/Bytes counts sampled once per second.
|
||||
|
||||
156k requests in 10.24s, 33.8 MB read
|
||||
-----------------------
|
||||
fastify
|
||||
-----------------------
|
||||
Running 10s test @ http://localhost:3000
|
||||
8 threads and 1024 connections
|
||||
Thread Stats Avg Stdev Max +/- Stdev
|
||||
Latency 21.80ms 8.73ms 78.12ms 55.78%
|
||||
Req/Sec 2.99k 0.92k 5.67k 68.88%
|
||||
238550 requests in 10.02s, 31.17MB read
|
||||
Socket errors: connect 0, read 862, write 0, timeout 0
|
||||
Requests/sec: 23795.79
|
||||
Transfer/sec: 3.11MB
|
||||
1024 connections
|
||||
|
||||
┌─────────┬───────┬───────┬───────┬───────┬──────────┬──────────┬─────────┐
|
||||
│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
|
||||
├─────────┼───────┼───────┼───────┼───────┼──────────┼──────────┼─────────┤
|
||||
│ Latency │ 27 ms │ 30 ms │ 39 ms │ 78 ms │ 31.62 ms │ 26.59 ms │ 1232 ms │
|
||||
└─────────┴───────┴───────┴───────┴───────┴──────────┴──────────┴─────────┘
|
||||
┌───────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┐
|
||||
│ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
|
||||
├───────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
|
||||
│ Req/Sec │ 19935 │ 19935 │ 33247 │ 34111 │ 32030.4 │ 4103.84 │ 19931 │
|
||||
├───────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
|
||||
│ Bytes/Sec │ 3.03 MB │ 3.03 MB │ 5.05 MB │ 5.19 MB │ 4.87 MB │ 624 kB │ 3.03 MB │
|
||||
└───────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┘
|
||||
|
||||
Req/Bytes counts sampled once per second.
|
||||
|
||||
320k requests in 10.18s, 48.7 MB read
|
||||
-----------------------
|
||||
nest
|
||||
nest (with "@nestjs/platform-fastify")
|
||||
-----------------------
|
||||
Running 10s test @ http://localhost:3000
|
||||
8 threads and 1024 connections
|
||||
Thread Stats Avg Stdev Max +/- Stdev
|
||||
Latency 54.00ms 22.33ms 200.25ms 62.23%
|
||||
Req/Sec 1.15k 338.60 1.88k 66.12%
|
||||
91348 requests in 10.05s, 18.82MB read
|
||||
Socket errors: connect 0, read 983, write 0, timeout 0
|
||||
Requests/sec: 9093.64
|
||||
Transfer/sec: 1.87MB
|
||||
-----------------------
|
||||
nest-fastify
|
||||
-----------------------
|
||||
Running 10s test @ http://localhost:3000
|
||||
8 threads and 1024 connections
|
||||
Thread Stats Avg Stdev Max +/- Stdev
|
||||
Latency 29.31ms 11.71ms 101.96ms 70.03%
|
||||
Req/Sec 2.17k 0.93k 4.12k 63.13%
|
||||
173241 requests in 10.05s, 22.80MB read
|
||||
Socket errors: connect 0, read 934, write 0, timeout 0
|
||||
Requests/sec: 17233.87
|
||||
Transfer/sec: 2.27MB
|
||||
1024 connections
|
||||
|
||||
┌─────────┬───────┬───────┬───────┬───────┬──────────┬──────────┬────────┐
|
||||
│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
|
||||
├─────────┼───────┼───────┼───────┼───────┼──────────┼──────────┼────────┤
|
||||
│ Latency │ 31 ms │ 33 ms │ 38 ms │ 52 ms │ 34.41 ms │ 11.73 ms │ 245 ms │
|
||||
└─────────┴───────┴───────┴───────┴───────┴──────────┴──────────┴────────┘
|
||||
┌───────────┬─────────┬─────────┬────────┬─────────┬─────────┬─────────┬─────────┐
|
||||
│ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
|
||||
├───────────┼─────────┼─────────┼────────┼─────────┼─────────┼─────────┼─────────┤
|
||||
│ Req/Sec │ 24911 │ 24911 │ 30031 │ 30335 │ 29470.4 │ 1564.48 │ 24907 │
|
||||
├───────────┼─────────┼─────────┼────────┼─────────┼─────────┼─────────┼─────────┤
|
||||
│ Bytes/Sec │ 3.81 MB │ 3.81 MB │ 4.6 MB │ 4.64 MB │ 4.51 MB │ 239 kB │ 3.81 MB │
|
||||
└───────────┴─────────┴─────────┴────────┴─────────┴─────────┴─────────┴─────────┘
|
||||
|
||||
Req/Bytes counts sampled once per second.
|
||||
|
||||
295k requests in 10.17s, 45.1 MB read
|
||||
177
integration/cors/e2e/express.spec.ts
Normal file
177
integration/cors/e2e/express.spec.ts
Normal file
@@ -0,0 +1,177 @@
|
||||
import { NestFastifyApplication } from '@nestjs/platform-fastify';
|
||||
import { Test } from '@nestjs/testing';
|
||||
import * as request from 'supertest';
|
||||
import { AppModule } from '../src/app.module';
|
||||
|
||||
describe('Express Cors', () => {
|
||||
let app: NestFastifyApplication;
|
||||
const configs = [
|
||||
{
|
||||
origin: 'example.com',
|
||||
methods: 'GET',
|
||||
credentials: true,
|
||||
exposedHeaders: ['foo', 'bar'],
|
||||
allowedHeaders: ['baz', 'woo'],
|
||||
maxAge: 123,
|
||||
},
|
||||
{
|
||||
origin: 'sample.com',
|
||||
methods: 'GET',
|
||||
credentials: true,
|
||||
exposedHeaders: ['zoo', 'bar'],
|
||||
allowedHeaders: ['baz', 'foo'],
|
||||
maxAge: 321,
|
||||
},
|
||||
];
|
||||
describe('Dynamic config', () => {
|
||||
describe('enableCors', () => {
|
||||
before(async () => {
|
||||
const module = await Test.createTestingModule({
|
||||
imports: [AppModule],
|
||||
}).compile();
|
||||
|
||||
app = module.createNestApplication<NestFastifyApplication>();
|
||||
|
||||
let requestId = 0;
|
||||
const configDelegation = function (req, cb) {
|
||||
const config = configs[requestId];
|
||||
requestId++;
|
||||
cb(null, config);
|
||||
};
|
||||
app.enableCors(configDelegation);
|
||||
|
||||
await app.init();
|
||||
});
|
||||
|
||||
it(`Should add cors headers based on the first config`, async () => {
|
||||
return request(app.getHttpServer())
|
||||
.get('/')
|
||||
.expect('access-control-allow-origin', 'example.com')
|
||||
.expect('vary', 'Origin')
|
||||
.expect('access-control-allow-credentials', 'true')
|
||||
.expect('access-control-expose-headers', 'foo,bar')
|
||||
.expect('content-length', '0');
|
||||
});
|
||||
|
||||
it(`Should add cors headers based on the second config`, async () => {
|
||||
return request(app.getHttpServer())
|
||||
.options('/')
|
||||
.expect('access-control-allow-origin', 'sample.com')
|
||||
.expect('vary', 'Origin')
|
||||
.expect('access-control-allow-credentials', 'true')
|
||||
.expect('access-control-expose-headers', 'zoo,bar')
|
||||
.expect('access-control-allow-methods', 'GET')
|
||||
.expect('access-control-allow-headers', 'baz,foo')
|
||||
.expect('access-control-max-age', '321')
|
||||
.expect('content-length', '0');
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await app.close();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Application Options', () => {
|
||||
before(async () => {
|
||||
const module = await Test.createTestingModule({
|
||||
imports: [AppModule],
|
||||
}).compile();
|
||||
|
||||
let requestId = 0;
|
||||
const configDelegation = function (req, cb) {
|
||||
const config = configs[requestId];
|
||||
requestId++;
|
||||
cb(null, config);
|
||||
};
|
||||
|
||||
app = module.createNestApplication<NestFastifyApplication>(null, {
|
||||
cors: configDelegation,
|
||||
});
|
||||
|
||||
await app.init();
|
||||
});
|
||||
|
||||
it(`Should add cors headers based on the first config`, async () => {
|
||||
return request(app.getHttpServer())
|
||||
.get('/')
|
||||
.expect('access-control-allow-origin', 'example.com')
|
||||
.expect('vary', 'Origin')
|
||||
.expect('access-control-allow-credentials', 'true')
|
||||
.expect('access-control-expose-headers', 'foo,bar')
|
||||
.expect('content-length', '0');
|
||||
});
|
||||
|
||||
it(`Should add cors headers based on the second config`, async () => {
|
||||
return request(app.getHttpServer())
|
||||
.options('/')
|
||||
.expect('access-control-allow-origin', 'sample.com')
|
||||
.expect('vary', 'Origin')
|
||||
.expect('access-control-allow-credentials', 'true')
|
||||
.expect('access-control-expose-headers', 'zoo,bar')
|
||||
.expect('access-control-allow-methods', 'GET')
|
||||
.expect('access-control-allow-headers', 'baz,foo')
|
||||
.expect('access-control-max-age', '321')
|
||||
.expect('content-length', '0');
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await app.close();
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('Static config', () => {
|
||||
describe('enableCors', () => {
|
||||
before(async () => {
|
||||
const module = await Test.createTestingModule({
|
||||
imports: [AppModule],
|
||||
}).compile();
|
||||
|
||||
app = module.createNestApplication<NestFastifyApplication>();
|
||||
app.enableCors(configs[0]);
|
||||
|
||||
await app.init();
|
||||
});
|
||||
|
||||
it(`CORS headers`, async () => {
|
||||
return request(app.getHttpServer())
|
||||
.get('/')
|
||||
.expect('access-control-allow-origin', 'example.com')
|
||||
.expect('vary', 'Origin')
|
||||
.expect('access-control-allow-credentials', 'true')
|
||||
.expect('access-control-expose-headers', 'foo,bar')
|
||||
.expect('content-length', '0');
|
||||
});
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await app.close();
|
||||
});
|
||||
|
||||
describe('Application Options', () => {
|
||||
before(async () => {
|
||||
const module = await Test.createTestingModule({
|
||||
imports: [AppModule],
|
||||
}).compile();
|
||||
|
||||
app = module.createNestApplication<NestFastifyApplication>(null, {
|
||||
cors: configs[0],
|
||||
});
|
||||
await app.init();
|
||||
});
|
||||
|
||||
it(`CORS headers`, async () => {
|
||||
return request(app.getHttpServer())
|
||||
.get('/')
|
||||
.expect('access-control-allow-origin', 'example.com')
|
||||
.expect('vary', 'Origin')
|
||||
.expect('access-control-allow-credentials', 'true')
|
||||
.expect('access-control-expose-headers', 'foo,bar')
|
||||
.expect('content-length', '0');
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await app.close();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
177
integration/cors/e2e/fastify.spec.ts
Normal file
177
integration/cors/e2e/fastify.spec.ts
Normal file
@@ -0,0 +1,177 @@
|
||||
import { NestFastifyApplication } from '@nestjs/platform-fastify';
|
||||
import { Test } from '@nestjs/testing';
|
||||
import * as request from 'supertest';
|
||||
import { AppModule } from '../src/app.module';
|
||||
|
||||
describe('Fastify Cors', () => {
|
||||
let app: NestFastifyApplication;
|
||||
const configs = [
|
||||
{
|
||||
origin: 'example.com',
|
||||
methods: 'GET',
|
||||
credentials: true,
|
||||
exposedHeaders: ['foo', 'bar'],
|
||||
allowedHeaders: ['baz', 'woo'],
|
||||
maxAge: 123,
|
||||
},
|
||||
{
|
||||
origin: 'sample.com',
|
||||
methods: 'GET',
|
||||
credentials: true,
|
||||
exposedHeaders: ['zoo', 'bar'],
|
||||
allowedHeaders: ['baz', 'foo'],
|
||||
maxAge: 321,
|
||||
},
|
||||
];
|
||||
describe('Dynamic config', () => {
|
||||
describe('enableCors', () => {
|
||||
before(async () => {
|
||||
const module = await Test.createTestingModule({
|
||||
imports: [AppModule],
|
||||
}).compile();
|
||||
|
||||
app = module.createNestApplication<NestFastifyApplication>();
|
||||
|
||||
let requestId = 0;
|
||||
const configDelegation = function (req, cb) {
|
||||
const config = configs[requestId];
|
||||
requestId++;
|
||||
cb(null, config);
|
||||
};
|
||||
app.enableCors(configDelegation);
|
||||
|
||||
await app.init();
|
||||
});
|
||||
|
||||
it(`Should add cors headers based on the first config`, async () => {
|
||||
return request(app.getHttpServer())
|
||||
.get('/')
|
||||
.expect('access-control-allow-origin', 'example.com')
|
||||
.expect('vary', 'Origin')
|
||||
.expect('access-control-allow-credentials', 'true')
|
||||
.expect('access-control-expose-headers', 'foo,bar')
|
||||
.expect('content-length', '0');
|
||||
});
|
||||
|
||||
it(`Should add cors headers based on the second config`, async () => {
|
||||
return request(app.getHttpServer())
|
||||
.options('/')
|
||||
.expect('access-control-allow-origin', 'sample.com')
|
||||
.expect('vary', 'Origin')
|
||||
.expect('access-control-allow-credentials', 'true')
|
||||
.expect('access-control-expose-headers', 'zoo,bar')
|
||||
.expect('access-control-allow-methods', 'GET')
|
||||
.expect('access-control-allow-headers', 'baz,foo')
|
||||
.expect('access-control-max-age', '321')
|
||||
.expect('content-length', '0');
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await app.close();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Application Options', () => {
|
||||
before(async () => {
|
||||
const module = await Test.createTestingModule({
|
||||
imports: [AppModule],
|
||||
}).compile();
|
||||
|
||||
let requestId = 0;
|
||||
const configDelegation = function (req, cb) {
|
||||
const config = configs[requestId];
|
||||
requestId++;
|
||||
cb(null, config);
|
||||
};
|
||||
|
||||
app = module.createNestApplication<NestFastifyApplication>(null, {
|
||||
cors: configDelegation,
|
||||
});
|
||||
|
||||
await app.init();
|
||||
});
|
||||
|
||||
it(`Should add cors headers based on the first config`, async () => {
|
||||
return request(app.getHttpServer())
|
||||
.get('/')
|
||||
.expect('access-control-allow-origin', 'example.com')
|
||||
.expect('vary', 'Origin')
|
||||
.expect('access-control-allow-credentials', 'true')
|
||||
.expect('access-control-expose-headers', 'foo,bar')
|
||||
.expect('content-length', '0');
|
||||
});
|
||||
|
||||
it(`Should add cors headers based on the second config`, async () => {
|
||||
return request(app.getHttpServer())
|
||||
.options('/')
|
||||
.expect('access-control-allow-origin', 'sample.com')
|
||||
.expect('vary', 'Origin')
|
||||
.expect('access-control-allow-credentials', 'true')
|
||||
.expect('access-control-expose-headers', 'zoo,bar')
|
||||
.expect('access-control-allow-methods', 'GET')
|
||||
.expect('access-control-allow-headers', 'baz,foo')
|
||||
.expect('access-control-max-age', '321')
|
||||
.expect('content-length', '0');
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await app.close();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Static config', () => {
|
||||
describe('enableCors', () => {
|
||||
before(async () => {
|
||||
const module = await Test.createTestingModule({
|
||||
imports: [AppModule],
|
||||
}).compile();
|
||||
|
||||
app = module.createNestApplication<NestFastifyApplication>();
|
||||
app.enableCors(configs[0]);
|
||||
|
||||
await app.init();
|
||||
});
|
||||
|
||||
it(`CORS headers`, async () => {
|
||||
return request(app.getHttpServer())
|
||||
.get('/')
|
||||
.expect('access-control-allow-origin', 'example.com')
|
||||
.expect('vary', 'Origin')
|
||||
.expect('access-control-allow-credentials', 'true')
|
||||
.expect('access-control-expose-headers', 'foo,bar')
|
||||
.expect('content-length', '0');
|
||||
});
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await app.close();
|
||||
});
|
||||
describe('Application Options', () => {
|
||||
before(async () => {
|
||||
const module = await Test.createTestingModule({
|
||||
imports: [AppModule],
|
||||
}).compile();
|
||||
|
||||
app = module.createNestApplication<NestFastifyApplication>(null, {
|
||||
cors: configs[0],
|
||||
});
|
||||
await app.init();
|
||||
});
|
||||
|
||||
it(`CORS headers`, async () => {
|
||||
return request(app.getHttpServer())
|
||||
.get('/')
|
||||
.expect('access-control-allow-origin', 'example.com')
|
||||
.expect('vary', 'Origin')
|
||||
.expect('access-control-allow-credentials', 'true')
|
||||
.expect('access-control-expose-headers', 'foo,bar')
|
||||
.expect('content-length', '0');
|
||||
});
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await app.close();
|
||||
});
|
||||
});
|
||||
});
|
||||
9
integration/cors/src/app.controller.ts
Normal file
9
integration/cors/src/app.controller.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { Controller, Get } from '@nestjs/common';
|
||||
|
||||
@Controller()
|
||||
export class AppController {
|
||||
@Get()
|
||||
getGlobals() {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
7
integration/cors/src/app.module.ts
Normal file
7
integration/cors/src/app.module.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { AppController } from './app.controller';
|
||||
|
||||
@Module({
|
||||
controllers: [AppController],
|
||||
})
|
||||
export class AppModule {}
|
||||
22
integration/cors/tsconfig.json
Normal file
22
integration/cors/tsconfig.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"declaration": false,
|
||||
"noImplicitAny": false,
|
||||
"removeComments": true,
|
||||
"noLib": false,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"target": "es6",
|
||||
"sourceMap": true,
|
||||
"allowJs": true,
|
||||
"outDir": "./dist"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"e2e/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
]
|
||||
}
|
||||
@@ -23,7 +23,7 @@ services:
|
||||
- "9001:9001"
|
||||
restart: always
|
||||
mysql:
|
||||
image: mysql:5.7.32
|
||||
image: mysql:5.7.33
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: root
|
||||
MYSQL_DATABASE: test
|
||||
|
||||
@@ -63,6 +63,22 @@ describe('Hello world (fastify adapter)', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it(`/GET { host: [":tenant.example1.com", ":tenant.example2.com"] } not matched`, () => {
|
||||
return app
|
||||
.inject({
|
||||
method: 'GET',
|
||||
url: '/host-array',
|
||||
})
|
||||
.then(({ payload }) => {
|
||||
expect(JSON.parse(payload)).to.be.eql({
|
||||
error: 'Internal Server Error',
|
||||
message:
|
||||
'HTTP adapter does not support filtering on hosts: [":tenant.example1.com", ":tenant.example2.com"]',
|
||||
statusCode: 500,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it(`/GET inject with LightMyRequest chaining API`, () => {
|
||||
return app
|
||||
.inject()
|
||||
|
||||
@@ -28,6 +28,16 @@ describe('Hello world (default adapter)', () => {
|
||||
path: '/host',
|
||||
greeting: 'Host Greeting! tenant=acme',
|
||||
},
|
||||
{
|
||||
host: 'acme.example1.com',
|
||||
path: '/host-array',
|
||||
greeting: 'Host Greeting! tenant=acme',
|
||||
},
|
||||
{
|
||||
host: 'acme.example2.com',
|
||||
path: '/host-array',
|
||||
greeting: 'Host Greeting! tenant=acme',
|
||||
},
|
||||
].forEach(({ host, path, greeting }) => {
|
||||
describe(`host=${host}`, () => {
|
||||
describe('/GET', () => {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { HelloModule } from './hello/hello.module';
|
||||
import { HostArrayModule } from './host-array/host-array.module';
|
||||
import { HostModule } from './host/host.module';
|
||||
|
||||
@Module({
|
||||
imports: [HelloModule, HostModule],
|
||||
imports: [HelloModule, HostModule, HostArrayModule],
|
||||
})
|
||||
export class ApplicationModule {}
|
||||
|
||||
10
integration/hello-world/src/host-array/dto/test.dto.ts
Normal file
10
integration/hello-world/src/host-array/dto/test.dto.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { IsString, IsNotEmpty, IsNumber } from 'class-validator';
|
||||
|
||||
export class TestDto {
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
string: string;
|
||||
|
||||
@IsNumber()
|
||||
number: number;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import { Controller, Get, Header, HostParam, Param } from '@nestjs/common';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { HostArrayService } from './host-array.service';
|
||||
import { UserByIdPipe } from './users/user-by-id.pipe';
|
||||
|
||||
@Controller({
|
||||
path: 'host-array',
|
||||
host: [':tenant.example1.com', ':tenant.example2.com'],
|
||||
})
|
||||
export class HostArrayController {
|
||||
constructor(private readonly hostService: HostArrayService) {}
|
||||
|
||||
@Get()
|
||||
@Header('Authorization', 'Bearer')
|
||||
greeting(@HostParam('tenant') tenant: string): string {
|
||||
return `${this.hostService.greeting()} tenant=${tenant}`;
|
||||
}
|
||||
|
||||
@Get('async')
|
||||
async asyncGreeting(@HostParam('tenant') tenant: string): Promise<string> {
|
||||
return `${await this.hostService.greeting()} tenant=${tenant}`;
|
||||
}
|
||||
|
||||
@Get('stream')
|
||||
streamGreeting(@HostParam('tenant') tenant: string): Observable<string> {
|
||||
return of(`${this.hostService.greeting()} tenant=${tenant}`);
|
||||
}
|
||||
|
||||
@Get('local-pipe/:id')
|
||||
localPipe(
|
||||
@Param('id', UserByIdPipe)
|
||||
user: any,
|
||||
@HostParam('tenant') tenant: string,
|
||||
): any {
|
||||
return { ...user, tenant };
|
||||
}
|
||||
}
|
||||
10
integration/hello-world/src/host-array/host-array.module.ts
Normal file
10
integration/hello-world/src/host-array/host-array.module.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { HostArrayController } from './host-array.controller';
|
||||
import { HostArrayService } from './host-array.service';
|
||||
import { UsersService } from './users/users.service';
|
||||
|
||||
@Module({
|
||||
controllers: [HostArrayController],
|
||||
providers: [HostArrayService, UsersService],
|
||||
})
|
||||
export class HostArrayModule {}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
@Injectable()
|
||||
export class HostArrayService {
|
||||
greeting(): string {
|
||||
return 'Host Greeting!';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';
|
||||
import { UsersService } from './users.service';
|
||||
|
||||
@Injectable()
|
||||
export class UserByIdPipe implements PipeTransform<string> {
|
||||
constructor(private readonly usersService: UsersService) {}
|
||||
|
||||
transform(value: string, metadata: ArgumentMetadata) {
|
||||
return this.usersService.findById(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
@Injectable()
|
||||
export class UsersService {
|
||||
findById(id: string) {
|
||||
return { id, host: true };
|
||||
}
|
||||
}
|
||||
@@ -113,6 +113,5 @@ describe('GRPC transport', () => {
|
||||
|
||||
after(async () => {
|
||||
await app.close();
|
||||
client.close();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -105,6 +105,22 @@ describe('RPC transport', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('/POST (custom client)', () => {
|
||||
return request(server)
|
||||
.post('/error?client=custom')
|
||||
.send({})
|
||||
.expect(200)
|
||||
.expect('true');
|
||||
});
|
||||
|
||||
it('/POST (standard client)', () => {
|
||||
return request(server)
|
||||
.post('/error?client=standard')
|
||||
.send({})
|
||||
.expect(200)
|
||||
.expect('false');
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await app.close();
|
||||
});
|
||||
|
||||
@@ -12,15 +12,17 @@ import {
|
||||
EventPattern,
|
||||
MessagePattern,
|
||||
Transport,
|
||||
RpcException,
|
||||
} from '@nestjs/microservices';
|
||||
import { from, Observable, of } from 'rxjs';
|
||||
import { scan } from 'rxjs/operators';
|
||||
import { from, Observable, of, throwError } from 'rxjs';
|
||||
import { catchError, scan } from 'rxjs/operators';
|
||||
|
||||
@Controller()
|
||||
export class AppController {
|
||||
constructor(
|
||||
@Inject('USE_CLASS_CLIENT') private useClassClient: ClientProxy,
|
||||
@Inject('USE_FACTORY_CLIENT') private useFactoryClient: ClientProxy,
|
||||
@Inject('CUSTOM_PROXY_CLIENT') private customClient: ClientProxy,
|
||||
) {}
|
||||
static IS_NOTIFIED = false;
|
||||
|
||||
@@ -75,6 +77,17 @@ export class AppController {
|
||||
.reduce(async (a, b) => (await a) && b);
|
||||
}
|
||||
|
||||
@Post('error')
|
||||
@HttpCode(200)
|
||||
serializeError(@Query('client') query: 'custom' | 'standard' = 'standard', @Body() body: Record<string, any>): Observable<boolean> {
|
||||
const client = query === 'custom' ? this.customClient : this.client;
|
||||
return client.send({ cmd: 'err' }, {}).pipe(
|
||||
catchError((err) => {
|
||||
return of(err instanceof RpcException);
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
@MessagePattern({ cmd: 'sum' })
|
||||
sum(data: number[]): number {
|
||||
return (data || []).reduce((a, b) => a + b);
|
||||
@@ -95,6 +108,11 @@ export class AppController {
|
||||
return from(data);
|
||||
}
|
||||
|
||||
@MessagePattern({ cmd: 'err' })
|
||||
throwAnError() {
|
||||
return throwError(new Error('err'));
|
||||
}
|
||||
|
||||
@Post('notify')
|
||||
async sendNotification(): Promise<any> {
|
||||
return this.client.emit<number>('notification', true);
|
||||
|
||||
@@ -5,8 +5,16 @@ import {
|
||||
Transport,
|
||||
ClientsModuleOptionsFactory,
|
||||
ClientOptions,
|
||||
ClientTCP,
|
||||
RpcException,
|
||||
} from '@nestjs/microservices';
|
||||
|
||||
class ErrorHandlingProxy extends ClientTCP {
|
||||
serializeError(err) {
|
||||
return new RpcException(err);
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
class ConfigService {
|
||||
private readonly config = {
|
||||
@@ -51,7 +59,14 @@ class ClientOptionService implements ClientsModuleOptionsFactory {
|
||||
name: 'USE_CLASS_CLIENT',
|
||||
useClass: ClientOptionService,
|
||||
inject: [ConfigService],
|
||||
},
|
||||
}, {
|
||||
imports: [ConfigModule],
|
||||
inject: [ConfigService],
|
||||
name: 'CUSTOM_PROXY_CLIENT',
|
||||
useFactory: (config: ConfigService) => ({
|
||||
customClass: ErrorHandlingProxy
|
||||
})
|
||||
}
|
||||
]),
|
||||
],
|
||||
controllers: [AppController],
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
import { Body, Controller, HttpCode, OnModuleInit, Post, OnModuleDestroy } from '@nestjs/common';
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
HttpCode,
|
||||
OnModuleInit,
|
||||
Post,
|
||||
OnModuleDestroy,
|
||||
} from '@nestjs/common';
|
||||
import { Logger } from '@nestjs/common/services/logger.service';
|
||||
import { Client, ClientKafka, Transport } from '@nestjs/microservices';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
"packages": [
|
||||
"packages/*"
|
||||
],
|
||||
"version": "7.6.5"
|
||||
"version": "7.6.13"
|
||||
}
|
||||
|
||||
5216
package-lock.json
generated
5216
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
89
package.json
89
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nestjs/core",
|
||||
"version": "7.5.3",
|
||||
"version": "7.6.8",
|
||||
"description": "Modern, fast, powerful node.js web framework",
|
||||
"homepage": "https://nestjs.com",
|
||||
"repository": {
|
||||
@@ -29,9 +29,10 @@
|
||||
"test:docker:up": "docker-compose -f integration/docker-compose.yml up -d",
|
||||
"test:docker:down": "docker-compose -f integration/docker-compose.yml down",
|
||||
"lint": "concurrently 'npm run lint:packages' 'npm run lint:integration' 'npm run lint:spec'",
|
||||
"lint:integration": "eslint 'integration/*/{,!(node_modules)/**/}/*.ts' -c '.eslintrc.spec.js' --fix",
|
||||
"lint:packages": "eslint 'packages/**/**.ts' --fix --ignore-pattern 'packages/**/*.spec.ts'",
|
||||
"lint:spec": "eslint 'packages/**/**.spec.ts' -c '.eslintrc.spec.js' --fix",
|
||||
"lint:fix": "concurrently 'npm run lint:packages -- --fix' 'npm run lint:integration -- --fix' 'npm run lint:spec -- --fix'",
|
||||
"lint:integration": "eslint 'integration/*/{,!(node_modules)/**/}/*.ts' -c '.eslintrc.spec.js'",
|
||||
"lint:packages": "eslint 'packages/**/**.ts' --ignore-pattern 'packages/**/*.spec.ts'",
|
||||
"lint:spec": "eslint 'packages/**/**.spec.ts' -c '.eslintrc.spec.js'",
|
||||
"prerelease": "gulp copy-misc && gulp build --dist node_modules/@nestjs",
|
||||
"publish": "npm run prerelease && npm run build:prod && ./node_modules/.bin/lerna publish --force-publish --access public --exact -m \"chore(@nestjs) publish %s release\"",
|
||||
"publish:beta": "npm run prerelease && npm run build:prod && ./node_modules/.bin/lerna publish --npm-tag=beta --access public -m \"chore(@nestjs) publish %s release\"",
|
||||
@@ -53,12 +54,12 @@
|
||||
"dependencies": {
|
||||
"@nuxtjs/opencollective": "0.3.2",
|
||||
"axios": "0.21.1",
|
||||
"class-transformer": "0.3.1",
|
||||
"class-validator": "0.12.2",
|
||||
"class-transformer": "0.4.0",
|
||||
"class-validator": "0.13.1",
|
||||
"cli-color": "2.0.0",
|
||||
"cors": "2.8.5",
|
||||
"express": "4.17.1",
|
||||
"fast-json-stringify": "2.3.1",
|
||||
"fast-json-stringify": "2.4.2",
|
||||
"fast-safe-stringify": "2.0.7",
|
||||
"iterare": "1.2.1",
|
||||
"object-hash": "2.1.1",
|
||||
@@ -73,98 +74,98 @@
|
||||
"@codechecks/client": "0.1.10",
|
||||
"@commitlint/cli": "11.0.0",
|
||||
"@commitlint/config-angular": "11.0.0",
|
||||
"@grpc/proto-loader": "0.5.5",
|
||||
"@nestjs/graphql": "7.9.4",
|
||||
"@nestjs/mongoose": "7.2.1",
|
||||
"@grpc/proto-loader": "0.5.6",
|
||||
"@nestjs/graphql": "7.9.9",
|
||||
"@nestjs/mongoose": "7.2.3",
|
||||
"@nestjs/typeorm": "7.1.5",
|
||||
"@types/amqplib": "0.5.17",
|
||||
"@types/bytes": "3.1.0",
|
||||
"@types/cache-manager": "2.10.3",
|
||||
"@types/chai": "4.2.14",
|
||||
"@types/cache-manager": "3.4.0",
|
||||
"@types/chai": "4.2.15",
|
||||
"@types/chai-as-promised": "7.1.3",
|
||||
"@types/cors": "2.8.9",
|
||||
"@types/cors": "2.8.10",
|
||||
"@types/express": "4.17.11",
|
||||
"@types/gulp": "4.0.8",
|
||||
"@types/mocha": "8.2.0",
|
||||
"@types/mocha": "8.2.1",
|
||||
"@types/mongoose": "5.10.3",
|
||||
"@types/node": "14.14.20",
|
||||
"@types/node": "14.14.31",
|
||||
"@types/redis": "2.8.28",
|
||||
"@types/reflect-metadata": "0.1.0",
|
||||
"@types/sinon": "9.0.10",
|
||||
"@types/socket.io": "2.1.12",
|
||||
"@types/socket.io": "2.1.13",
|
||||
"@types/ws": "7.4.0",
|
||||
"@typescript-eslint/eslint-plugin": "4.13.0",
|
||||
"@typescript-eslint/parser": "4.13.0",
|
||||
"amqp-connection-manager": "3.2.1",
|
||||
"@typescript-eslint/eslint-plugin": "4.15.1",
|
||||
"@typescript-eslint/parser": "4.15.1",
|
||||
"amqp-connection-manager": "3.2.2",
|
||||
"amqplib": "0.6.0",
|
||||
"apollo-server-express": "2.19.1",
|
||||
"apollo-server-express": "2.21.0",
|
||||
"artillery": "1.6.1",
|
||||
"awesome-typescript-loader": "5.2.1",
|
||||
"body-parser": "1.19.0",
|
||||
"bytes": "3.1.0",
|
||||
"cache-manager": "3.4.0",
|
||||
"chai": "4.2.0",
|
||||
"chai": "4.3.0",
|
||||
"chai-as-promised": "7.1.1",
|
||||
"clang-format": "1.5.0",
|
||||
"commitlint-circle": "1.0.0",
|
||||
"concurrently": "5.3.0",
|
||||
"concurrently": "6.0.0",
|
||||
"conventional-changelog": "3.1.24",
|
||||
"core-js": "3.8.2",
|
||||
"core-js": "3.9.0",
|
||||
"coveralls": "3.1.0",
|
||||
"delete-empty": "3.0.0",
|
||||
"engine.io-client": "4.0.6",
|
||||
"eslint": "7.17.0",
|
||||
"eslint-config-prettier": "7.1.0",
|
||||
"engine.io-client": "4.1.1",
|
||||
"eslint": "7.20.0",
|
||||
"eslint-config-prettier": "7.2.0",
|
||||
"eslint-plugin-import": "2.22.1",
|
||||
"eventsource": "1.0.7",
|
||||
"fancy-log": "1.3.3",
|
||||
"fastify": "3.9.2",
|
||||
"fastify-cors": "5.1.0",
|
||||
"fastify": "3.12.0",
|
||||
"fastify-cors": "5.2.0",
|
||||
"fastify-formbody": "5.0.0",
|
||||
"fastify-multipart": "3.3.1",
|
||||
"fastify-static": "3.3.1",
|
||||
"graphql": "15.4.0",
|
||||
"graphql-tools": "7.0.2",
|
||||
"grpc": "1.24.4",
|
||||
"fastify-multipart": "4.0.0",
|
||||
"fastify-static": "4.0.0",
|
||||
"graphql": "15.5.0",
|
||||
"graphql-tools": "7.0.4",
|
||||
"grpc": "1.24.5",
|
||||
"gulp": "4.0.2",
|
||||
"gulp-clang-format": "1.0.27",
|
||||
"gulp-clean": "0.4.0",
|
||||
"gulp-sourcemaps": "3.0.0",
|
||||
"gulp-typescript": "5.0.1",
|
||||
"gulp-watch": "5.0.1",
|
||||
"husky": "4.3.7",
|
||||
"imports-loader": "1.2.0",
|
||||
"husky": "5.1.0",
|
||||
"imports-loader": "2.0.0",
|
||||
"json-loader": "0.5.7",
|
||||
"kafkajs": "1.15.0",
|
||||
"lerna": "2.11.0",
|
||||
"light-my-request": "4.4.1",
|
||||
"lint-staged": "10.5.3",
|
||||
"lint-staged": "10.5.4",
|
||||
"markdown-table": "2.0.0",
|
||||
"merge-graphql-schemas": "1.7.8",
|
||||
"middie": "5.2.0",
|
||||
"mocha": "8.2.1",
|
||||
"mongoose": "5.11.11",
|
||||
"mocha": "8.3.0",
|
||||
"mongoose": "5.11.17",
|
||||
"mqtt": "4.2.6",
|
||||
"multer": "1.4.2",
|
||||
"mysql": "2.18.1",
|
||||
"nats": "1.4.12",
|
||||
"nodemon": "2.0.7",
|
||||
"nyc": "15.1.0",
|
||||
"point-of-view": "4.8.0",
|
||||
"point-of-view": "4.13.0",
|
||||
"prettier": "2.2.1",
|
||||
"redis": "3.0.2",
|
||||
"rxjs-compat": "6.6.3",
|
||||
"sinon": "9.2.3",
|
||||
"sinon": "9.2.4",
|
||||
"sinon-chai": "3.5.0",
|
||||
"socket.io-client": "2.4.0",
|
||||
"subscriptions-transport-ws": "0.9.18",
|
||||
"supertest": "6.0.1",
|
||||
"supertest": "6.1.3",
|
||||
"ts-morph": "9.1.0",
|
||||
"ts-node": "9.1.1",
|
||||
"typeorm": "0.2.30",
|
||||
"typescript": "4.1.3",
|
||||
"typeorm": "0.2.31",
|
||||
"typescript": "4.1.5",
|
||||
"wrk": "1.2.1",
|
||||
"ws": "7.4.2"
|
||||
"ws": "7.4.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.13.0"
|
||||
|
||||
@@ -56,16 +56,21 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
||||
|
||||
#### Principal Sponsors
|
||||
<table style="text-align:center;"><tr><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><td>
|
||||
<a href="https://valor-software.com/" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/valor-software.png" width="180" valign="middle" /></a></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>
|
||||
<td>
|
||||
<a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="200" valign="middle" /></a></td>
|
||||
</tr></table>
|
||||
|
||||
#### Gold Sponsors
|
||||
|
||||
<table style="text-align:center;"><tr><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></tr></table>
|
||||
|
||||
#### Silver Sponsors
|
||||
|
||||
<table style="text-align:center;"><tr><td>
|
||||
<a href="https://neoteric.eu/" target="_blank"><img src="https://nestjs.com/img/neoteric-cut.png" width="120" valign="middle" /></a> </td><td>
|
||||
<a href="http://gojob.com" target="_blank"><img src="http://nestjs.com/img/gojob-logo.png" valign="middle" width="100" /></a> </td><td>
|
||||
<a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="170" valign="middle" /></a> </td><td>
|
||||
<a href="http://www.leogistics.com" target="_blank"><img src="https://nestjs.com/img/leogistics-logo.jpeg" width="150" valign="middle" /></td><td>
|
||||
<a href="http://www.meetdandy.com" target="_blank"><img src="https://nestjs.com/img/dandy-wide-logo.png" width="150" valign="middle" /></td></tr></table>
|
||||
|
||||
@@ -90,6 +95,11 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://genuinebee.com/" target="_blank"><img src="https://nestjs.com/img/genuinebee.svg" width="97" valign="middle" /></a> </td>
|
||||
<td align="center" valign="middle"><a href="https://sanyodigital.com/" target="_blank"><img src="https://nestjs.com/img/sanyo-digital.png" width="130" valign="middle" /></a></td></tr><tr><td align="center" valign="middle"><a href="https://vpn-review.com/vpn-for-torrenting" target="_blank"><img src="https://nestjs.com/img/vpn-review-logo.png" width="85" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://lambda-it.ch/" target="_blank"><img src="https://nestjs.com/img/lambda-it-logo.svg" width="115" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://pickwriters.com/top-10-translation-services" target="_blank"><img src="https://nestjs.com/img/pickwriters-logo.png" width="40" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://thewordpoint.com/services/localization" target="_blank"><img src="https://nestjs.com/img/thewordpoint-logo.png" width="40" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://streamat.se/" target="_blank"><img src="https://nestjs.com/img/streamat-logo.png" width="120" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://filmen.nu/" target="_blank"><img src="https://nestjs.com/img/filmen-logo.png" width="120" valign="middle" /></a></td></tr><tr>
|
||||
<td align="center" valign="middle"><a href="https://meercode.io/" target="_blank"><img src="https://nestjs.com/img/meercode-logo.png" width="60" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://www.najlepszeplatformyforex.pl/blog/broker-xtb/" target="_blank"><img src="https://nestjs.com/img/npf-logo.jpg" width="200" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://thestandarddaily.com/" target="_blank"><img src="https://nestjs.com/img/the-standard-daily-logo.png" width="180" valign="middle" /></a></td>
|
||||
</tr></table>
|
||||
|
||||
## Backers
|
||||
|
||||
@@ -27,7 +27,7 @@ export interface ControllerOptions extends ScopeOptions {
|
||||
*
|
||||
* @see [Routing](https://docs.nestjs.com/controllers#routing)
|
||||
*/
|
||||
host?: string;
|
||||
host?: string | string[];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -167,7 +167,7 @@ export const Session: () => ParameterDecorator = createRouteParamDecorator(
|
||||
* Route handler parameter decorator. Extracts the `file` object
|
||||
* and populates the decorated parameter with the value of `file`.
|
||||
* Used in conjunction with
|
||||
* [multer middleware](https://github.com/expressjs/multer).
|
||||
* [multer middleware](https://github.com/expressjs/multer) for Express-based applications.
|
||||
*
|
||||
* For example:
|
||||
* ```typescript
|
||||
@@ -179,15 +179,78 @@ export const Session: () => ParameterDecorator = createRouteParamDecorator(
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
export const UploadedFile: (
|
||||
export function UploadedFile(): ParameterDecorator;
|
||||
/**
|
||||
* Route handler parameter decorator. Extracts the `file` object
|
||||
* and populates the decorated parameter with the value of `file`.
|
||||
* Used in conjunction with
|
||||
* [multer middleware](https://github.com/expressjs/multer) for Express-based applications.
|
||||
*
|
||||
* For example:
|
||||
* ```typescript
|
||||
* uploadFile(@UploadedFile() file) {
|
||||
* console.log(file);
|
||||
* }
|
||||
* ```
|
||||
* @see [Request object](https://docs.nestjs.com/techniques/file-upload)
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
export function UploadedFile(
|
||||
...pipes: (Type<PipeTransform> | PipeTransform)[]
|
||||
): ParameterDecorator;
|
||||
|
||||
/**
|
||||
* Route handler parameter decorator. Extracts the `file` object
|
||||
* and populates the decorated parameter with the value of `file`.
|
||||
* Used in conjunction with
|
||||
* [multer middleware](https://github.com/expressjs/multer) for Express-based applications.
|
||||
*
|
||||
* For example:
|
||||
* ```typescript
|
||||
* uploadFile(@UploadedFile() file) {
|
||||
* console.log(file);
|
||||
* }
|
||||
* ```
|
||||
* @see [Request object](https://docs.nestjs.com/techniques/file-upload)
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
export function UploadedFile(
|
||||
fileKey?: string,
|
||||
) => ParameterDecorator = createRouteParamDecorator(RouteParamtypes.FILE);
|
||||
...pipes: (Type<PipeTransform> | PipeTransform)[]
|
||||
): ParameterDecorator;
|
||||
/**
|
||||
* Route handler parameter decorator. Extracts the `file` object
|
||||
* and populates the decorated parameter with the value of `file`.
|
||||
* Used in conjunction with
|
||||
* [multer middleware](https://github.com/expressjs/multer) for Express-based applications.
|
||||
*
|
||||
* For example:
|
||||
* ```typescript
|
||||
* uploadFile(@UploadedFile() file) {
|
||||
* console.log(file);
|
||||
* }
|
||||
* ```
|
||||
* @see [Request object](https://docs.nestjs.com/techniques/file-upload)
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
export function UploadedFile(
|
||||
fileKey?: string | (Type<PipeTransform> | PipeTransform),
|
||||
...pipes: (Type<PipeTransform> | PipeTransform)[]
|
||||
): ParameterDecorator {
|
||||
return createPipesRouteParamDecorator(RouteParamtypes.FILE)(
|
||||
fileKey,
|
||||
...pipes,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Route handler parameter decorator. Extracts the `files` object
|
||||
* and populates the decorated parameter with the value of `files`.
|
||||
* Used in conjunction with
|
||||
* [multer middleware](https://github.com/expressjs/multer).
|
||||
* [multer middleware](https://github.com/expressjs/multer) for Express-based applications.
|
||||
*
|
||||
* For example:
|
||||
* ```typescript
|
||||
@@ -199,9 +262,51 @@ export const UploadedFile: (
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
export const UploadedFiles: () => ParameterDecorator = createRouteParamDecorator(
|
||||
RouteParamtypes.FILES,
|
||||
);
|
||||
export function UploadedFiles(): ParameterDecorator;
|
||||
/**
|
||||
* Route handler parameter decorator. Extracts the `files` object
|
||||
* and populates the decorated parameter with the value of `files`.
|
||||
* Used in conjunction with
|
||||
* [multer middleware](https://github.com/expressjs/multer) for Express-based applications.
|
||||
*
|
||||
* For example:
|
||||
* ```typescript
|
||||
* uploadFile(@UploadedFiles() files) {
|
||||
* console.log(files);
|
||||
* }
|
||||
* ```
|
||||
* @see [Request object](https://docs.nestjs.com/techniques/file-upload)
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
export function UploadedFiles(
|
||||
...pipes: (Type<PipeTransform> | PipeTransform)[]
|
||||
): ParameterDecorator;
|
||||
/**
|
||||
* Route handler parameter decorator. Extracts the `files` object
|
||||
* and populates the decorated parameter with the value of `files`.
|
||||
* Used in conjunction with
|
||||
* [multer middleware](https://github.com/expressjs/multer) for Express-based applications.
|
||||
*
|
||||
* For example:
|
||||
* ```typescript
|
||||
* uploadFile(@UploadedFiles() files) {
|
||||
* console.log(files);
|
||||
* }
|
||||
* ```
|
||||
* @see [Request object](https://docs.nestjs.com/techniques/file-upload)
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
export function UploadedFiles(
|
||||
...pipes: (Type<PipeTransform> | PipeTransform)[]
|
||||
): ParameterDecorator {
|
||||
return createPipesRouteParamDecorator(RouteParamtypes.FILES)(
|
||||
undefined,
|
||||
...pipes,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Route handler parameter decorator. Extracts the `headers`
|
||||
* property from the `req` object and populates the decorated
|
||||
|
||||
@@ -78,4 +78,3 @@ export class HttpException extends Error {
|
||||
: { statusCode, message: objectOrError, error: description };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,4 +50,9 @@ export interface ClassTransformOptions {
|
||||
* and exposing all class properties (with undefined, if nothing else is given)
|
||||
*/
|
||||
excludeExtraneousValues?: boolean;
|
||||
/**
|
||||
* If set to true then class transformer will take default values for unprovided fields.
|
||||
* This is useful when you convert a plain object to a class and have an optional field with a default value.
|
||||
*/
|
||||
exposeDefaultValues?: boolean;
|
||||
}
|
||||
|
||||
@@ -52,3 +52,10 @@ export interface CorsOptions {
|
||||
*/
|
||||
optionsSuccessStatus?: number;
|
||||
}
|
||||
|
||||
export interface CorsOptionsCallback {
|
||||
(error: Error, options: CorsOptions): void;
|
||||
}
|
||||
export interface CorsOptionsDelegate<T> {
|
||||
(req: T, cb: CorsOptionsCallback): void;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { RequestMethod } from '../../enums';
|
||||
import { CorsOptions } from '../../interfaces/external/cors-options.interface';
|
||||
import {
|
||||
CorsOptions,
|
||||
CorsOptionsDelegate,
|
||||
} from '../../interfaces/external/cors-options.interface';
|
||||
import { NestApplicationOptions } from '../../interfaces/nest-application-options.interface';
|
||||
|
||||
export type ErrorHandler<TRequest = any, TResponse = any> = (
|
||||
@@ -59,10 +62,10 @@ export interface HttpServer<TRequest = any, TResponse = any> {
|
||||
| Promise<(path: string, callback: Function) => any>;
|
||||
getRequestHostname?(request: TRequest): string;
|
||||
getRequestMethod?(request: TRequest): string;
|
||||
getRequestUrl?(request: TResponse): string;
|
||||
getRequestUrl?(request: TRequest): string;
|
||||
getInstance(): any;
|
||||
registerParserMiddleware(): any;
|
||||
enableCors(options: CorsOptions): any;
|
||||
enableCors(options: CorsOptions | CorsOptionsDelegate<TRequest>): any;
|
||||
getHttpServer(): any;
|
||||
initHttpServer(options: NestApplicationOptions): void;
|
||||
close(): any;
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { CorsOptions } from './external/cors-options.interface';
|
||||
import {
|
||||
CorsOptions,
|
||||
CorsOptionsDelegate,
|
||||
} from './external/cors-options.interface';
|
||||
import { HttpsOptions } from './external/https-options.interface';
|
||||
import { NestApplicationContextOptions } from './nest-application-context-options.interface';
|
||||
|
||||
@@ -9,7 +12,7 @@ export interface NestApplicationOptions extends NestApplicationContextOptions {
|
||||
/**
|
||||
* CORS options from [CORS package](https://github.com/expressjs/cors#configuration-options)
|
||||
*/
|
||||
cors?: boolean | CorsOptions;
|
||||
cors?: boolean | CorsOptions | CorsOptionsDelegate<any>;
|
||||
/**
|
||||
* Whether to use underlying platform body parser.
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { CorsOptions } from './external/cors-options.interface';
|
||||
import {
|
||||
CorsOptions,
|
||||
CorsOptionsDelegate,
|
||||
} from './external/cors-options.interface';
|
||||
import { CanActivate } from './features/can-activate.interface';
|
||||
import { NestInterceptor } from './features/nest-interceptor.interface';
|
||||
import { HttpServer } from './http/http-server.interface';
|
||||
@@ -30,7 +33,7 @@ export interface INestApplication extends INestApplicationContext {
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
enableCors(options?: CorsOptions): void;
|
||||
enableCors(options?: CorsOptions | CorsOptionsDelegate<any>): void;
|
||||
|
||||
/**
|
||||
* Starts the application.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nestjs/common",
|
||||
"version": "7.6.5",
|
||||
"version": "7.6.13",
|
||||
"description": "Nest - modern, fast, powerful node.js web framework (@common)",
|
||||
"author": "Kamil Mysliwiec",
|
||||
"homepage": "https://nestjs.com",
|
||||
|
||||
@@ -86,7 +86,39 @@ export class ParseArrayPipe implements PipeTransform {
|
||||
} catch {}
|
||||
return this.validationPipe.transform(item, validationMetadata);
|
||||
};
|
||||
value = await Promise.all(value.map(toClassInstance));
|
||||
if (this.options.stopAtFirstError === false) {
|
||||
// strict compare to "false" to make sure
|
||||
// that this option is disabled by default
|
||||
let errors = [];
|
||||
|
||||
const targetArray = value as Array<unknown>;
|
||||
for (let i = 0; i < targetArray.length; i++) {
|
||||
try {
|
||||
targetArray[i] = await toClassInstance(targetArray[i]);
|
||||
} catch (err) {
|
||||
let message: string[] | unknown;
|
||||
if (err.getResponse) {
|
||||
const response = err.getResponse();
|
||||
if (Array.isArray(response.message)) {
|
||||
message = response.message.map(
|
||||
(item: string) => `[${i}] ${item}`,
|
||||
);
|
||||
} else {
|
||||
message = `[${i}] ${response.message}`;
|
||||
}
|
||||
} else {
|
||||
message = err;
|
||||
}
|
||||
errors = errors.concat(message);
|
||||
}
|
||||
}
|
||||
if (errors.length > 0) {
|
||||
throw this.exceptionFactory(errors as any);
|
||||
}
|
||||
return targetArray;
|
||||
} else {
|
||||
value = await Promise.all(value.map(toClassInstance));
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Injectable } from '../decorators/core/injectable.decorator';
|
||||
import { Optional } from '../decorators/core/optional.decorator';
|
||||
import { clc, yellow } from '../utils/cli-colors.util';
|
||||
import { isObject } from '../utils/shared.utils';
|
||||
import { isObject, isPlainObject } from '../utils/shared.utils';
|
||||
|
||||
declare const process: any;
|
||||
|
||||
@@ -146,7 +146,7 @@ export class Logger implements LoggerService {
|
||||
isTimeDiffEnabled?: boolean,
|
||||
writeStreamType?: 'stdout' | 'stderr',
|
||||
) {
|
||||
const output = isObject(message)
|
||||
const output = isPlainObject(message)
|
||||
? `${color('Object:')}\n${JSON.stringify(message, null, 2)}\n`
|
||||
: color(message);
|
||||
|
||||
@@ -154,7 +154,10 @@ export class Logger implements LoggerService {
|
||||
const contextMessage = context ? yellow(`[${context}] `) : '';
|
||||
const timestampDiff = this.updateAndGetTimestampDiff(isTimeDiffEnabled);
|
||||
const instance = (this.instance as typeof Logger) ?? Logger;
|
||||
const computedMessage = `${pidMessage}${instance.getTimestamp()} ${contextMessage}${output}${timestampDiff}\n`;
|
||||
const timestamp = instance.getTimestamp
|
||||
? instance.getTimestamp()
|
||||
: Logger.getTimestamp?.();
|
||||
const computedMessage = `${pidMessage}${timestamp} ${contextMessage}${output}${timestampDiff}\n`;
|
||||
|
||||
process[writeStreamType ?? 'stdout'].write(computedMessage);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Controller } from '../../decorators/core/controller.decorator';
|
||||
describe('@Controller', () => {
|
||||
const reflectedPath = 'test';
|
||||
const reflectedHost = 'api.example.com';
|
||||
const reflectedHostArray = ['api1.example.com', 'api2.example.com'];
|
||||
|
||||
@Controller(reflectedPath)
|
||||
class Test {}
|
||||
@@ -14,6 +15,9 @@ describe('@Controller', () => {
|
||||
@Controller({ path: reflectedPath, host: reflectedHost })
|
||||
class PathAndHostDecorator {}
|
||||
|
||||
@Controller({ path: reflectedPath, host: reflectedHostArray })
|
||||
class PathAndHostArrayDecorator {}
|
||||
|
||||
@Controller({ host: reflectedHost })
|
||||
class HostOnlyDecorator {}
|
||||
|
||||
@@ -29,6 +33,8 @@ describe('@Controller', () => {
|
||||
expect(host).to.be.eql(reflectedHost);
|
||||
const host2 = Reflect.getMetadata('host', HostOnlyDecorator);
|
||||
expect(host2).to.be.eql(reflectedHost);
|
||||
const host3 = Reflect.getMetadata('host', PathAndHostArrayDecorator);
|
||||
expect(host3).to.be.eql(reflectedHostArray);
|
||||
});
|
||||
|
||||
it('should set default path when no object passed as param', () => {
|
||||
|
||||
@@ -1,7 +1,19 @@
|
||||
import * as chai from 'chai';
|
||||
import { expect } from 'chai';
|
||||
import * as chaiAsPromised from 'chai-as-promised';
|
||||
import { Type } from 'class-transformer';
|
||||
import {
|
||||
IsBoolean,
|
||||
IsDate,
|
||||
IsDefined,
|
||||
IsNumber,
|
||||
IsString,
|
||||
ValidateNested,
|
||||
} from 'class-validator';
|
||||
import { BadRequestException } from '../../exceptions';
|
||||
import { ArgumentMetadata } from '../../interfaces/features/pipe-transform.interface';
|
||||
import { ParseArrayPipe } from '../../pipes/parse-array.pipe';
|
||||
chai.use(chaiAsPromised);
|
||||
|
||||
describe('ParseArrayPipe', () => {
|
||||
let target: ParseArrayPipe;
|
||||
@@ -102,6 +114,153 @@ describe('ParseArrayPipe', () => {
|
||||
expect(item).to.be.instanceOf(ArrItem);
|
||||
});
|
||||
});
|
||||
describe('when "stopAtFirstError" is explicitly turned off', () => {
|
||||
it('should validate each item and concat errors', async () => {
|
||||
class ArrItemWithProp {
|
||||
@IsNumber()
|
||||
number: number;
|
||||
}
|
||||
const pipe = new ParseArrayPipe({
|
||||
items: ArrItemWithProp,
|
||||
stopAtFirstError: false,
|
||||
});
|
||||
try {
|
||||
await pipe.transform(
|
||||
[
|
||||
{ number: '1' },
|
||||
{ number: '1' },
|
||||
{ number: 1 },
|
||||
] as ArrItemWithProp[],
|
||||
{} as ArgumentMetadata,
|
||||
);
|
||||
} catch (err) {
|
||||
expect(err).to.be.instanceOf(BadRequestException);
|
||||
expect(err.getResponse().message).to.deep.equal([
|
||||
'[0] number must be a number conforming to the specified constraints',
|
||||
'[1] number must be a number conforming to the specified constraints',
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
it('should validate each nested object and concat errors', async () => {
|
||||
class RandomObject {
|
||||
@IsDefined()
|
||||
@IsBoolean()
|
||||
isEnabled: boolean;
|
||||
|
||||
@IsString()
|
||||
title: string;
|
||||
|
||||
@IsDate()
|
||||
createdAt: Date;
|
||||
|
||||
constructor(partial: Partial<any>) {
|
||||
Object.assign(this, partial);
|
||||
}
|
||||
}
|
||||
class ArrItemObject {
|
||||
@ValidateNested()
|
||||
random: RandomObject;
|
||||
}
|
||||
const pipe = new ParseArrayPipe({
|
||||
items: ArrItemObject,
|
||||
stopAtFirstError: false,
|
||||
});
|
||||
try {
|
||||
await pipe.transform(
|
||||
[
|
||||
{
|
||||
random: new RandomObject({
|
||||
isEnabled: true,
|
||||
title: true,
|
||||
createdAt: new Date(),
|
||||
}),
|
||||
},
|
||||
{
|
||||
random: new RandomObject({
|
||||
title: 'ok',
|
||||
createdAt: false,
|
||||
}),
|
||||
},
|
||||
] as any[],
|
||||
{} as ArgumentMetadata,
|
||||
);
|
||||
} catch (err) {
|
||||
expect(err).to.be.instanceOf(BadRequestException);
|
||||
expect(err.getResponse().message).to.deep.equal([
|
||||
'[0] random.title must be a string',
|
||||
'[1] random.isEnabled should not be null or undefined',
|
||||
'[1] random.isEnabled must be a boolean value',
|
||||
'[1] random.createdAt must be a Date instance',
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
it('should validate each nested array and concat errors', async () => {
|
||||
class RandomObject {
|
||||
@IsDefined()
|
||||
@IsBoolean()
|
||||
isEnabled: boolean;
|
||||
|
||||
@IsString()
|
||||
title: string;
|
||||
|
||||
@IsDate()
|
||||
createdAt: Date;
|
||||
|
||||
constructor(partial: Partial<any>) {
|
||||
Object.assign(this, partial);
|
||||
}
|
||||
}
|
||||
class ArrItemObject {
|
||||
@Type(() => RandomObject)
|
||||
@ValidateNested({ each: true })
|
||||
random: RandomObject[];
|
||||
}
|
||||
const pipe = new ParseArrayPipe({
|
||||
items: ArrItemObject,
|
||||
stopAtFirstError: false,
|
||||
});
|
||||
try {
|
||||
await pipe.transform(
|
||||
[
|
||||
{
|
||||
random: [
|
||||
new RandomObject({
|
||||
isEnabled: true,
|
||||
title: true,
|
||||
createdAt: new Date(),
|
||||
}),
|
||||
new RandomObject({
|
||||
isEnabled: true,
|
||||
title: true,
|
||||
createdAt: new Date(),
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
random: [
|
||||
new RandomObject({
|
||||
title: 'ok',
|
||||
createdAt: false,
|
||||
}),
|
||||
],
|
||||
},
|
||||
] as any[],
|
||||
{} as ArgumentMetadata,
|
||||
);
|
||||
} catch (err) {
|
||||
expect(err).to.be.instanceOf(BadRequestException);
|
||||
expect(err.getResponse().message).to.deep.equal([
|
||||
'[0] random.0.title must be a string',
|
||||
'[0] random.1.title must be a string',
|
||||
'[1] random.0.isEnabled should not be null or undefined',
|
||||
'[1] random.0.isEnabled must be a boolean value',
|
||||
'[1] random.0.createdAt must be a Date instance',
|
||||
]);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -56,16 +56,21 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
||||
|
||||
#### Principal Sponsors
|
||||
<table style="text-align:center;"><tr><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><td>
|
||||
<a href="https://valor-software.com/" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/valor-software.png" width="180" valign="middle" /></a></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>
|
||||
<td>
|
||||
<a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="200" valign="middle" /></a></td>
|
||||
</tr></table>
|
||||
|
||||
#### Gold Sponsors
|
||||
|
||||
<table style="text-align:center;"><tr><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></tr></table>
|
||||
|
||||
#### Silver Sponsors
|
||||
|
||||
<table style="text-align:center;"><tr><td>
|
||||
<a href="https://neoteric.eu/" target="_blank"><img src="https://nestjs.com/img/neoteric-cut.png" width="120" valign="middle" /></a> </td><td>
|
||||
<a href="http://gojob.com" target="_blank"><img src="http://nestjs.com/img/gojob-logo.png" valign="middle" width="100" /></a> </td><td>
|
||||
<a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="170" valign="middle" /></a> </td><td>
|
||||
<a href="http://www.leogistics.com" target="_blank"><img src="https://nestjs.com/img/leogistics-logo.jpeg" width="150" valign="middle" /></td><td>
|
||||
<a href="http://www.meetdandy.com" target="_blank"><img src="https://nestjs.com/img/dandy-wide-logo.png" width="150" valign="middle" /></td></tr></table>
|
||||
|
||||
@@ -90,6 +95,11 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://genuinebee.com/" target="_blank"><img src="https://nestjs.com/img/genuinebee.svg" width="97" valign="middle" /></a> </td>
|
||||
<td align="center" valign="middle"><a href="https://sanyodigital.com/" target="_blank"><img src="https://nestjs.com/img/sanyo-digital.png" width="130" valign="middle" /></a></td></tr><tr><td align="center" valign="middle"><a href="https://vpn-review.com/vpn-for-torrenting" target="_blank"><img src="https://nestjs.com/img/vpn-review-logo.png" width="85" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://lambda-it.ch/" target="_blank"><img src="https://nestjs.com/img/lambda-it-logo.svg" width="115" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://pickwriters.com/top-10-translation-services" target="_blank"><img src="https://nestjs.com/img/pickwriters-logo.png" width="40" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://thewordpoint.com/services/localization" target="_blank"><img src="https://nestjs.com/img/thewordpoint-logo.png" width="40" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://streamat.se/" target="_blank"><img src="https://nestjs.com/img/streamat-logo.png" width="120" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://filmen.nu/" target="_blank"><img src="https://nestjs.com/img/filmen-logo.png" width="120" valign="middle" /></a></td></tr><tr>
|
||||
<td align="center" valign="middle"><a href="https://meercode.io/" target="_blank"><img src="https://nestjs.com/img/meercode-logo.png" width="60" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://www.najlepszeplatformyforex.pl/blog/broker-xtb/" target="_blank"><img src="https://nestjs.com/img/npf-logo.jpg" width="200" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://thestandarddaily.com/" target="_blank"><img src="https://nestjs.com/img/the-standard-daily-logo.png" width="180" valign="middle" /></a></td>
|
||||
</tr></table>
|
||||
|
||||
## Backers
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { HttpServer, RequestMethod } from '@nestjs/common';
|
||||
import { RequestHandler } from '@nestjs/common/interfaces';
|
||||
import { CorsOptions } from '@nestjs/common/interfaces/external/cors-options.interface';
|
||||
import {
|
||||
CorsOptions,
|
||||
CorsOptionsDelegate,
|
||||
} from '@nestjs/common/interfaces/external/cors-options.interface';
|
||||
import { NestApplicationOptions } from '@nestjs/common/interfaces/nest-application-options.interface';
|
||||
|
||||
/**
|
||||
@@ -14,6 +17,14 @@ export abstract class AbstractHttpAdapter<
|
||||
protected httpServer: TServer;
|
||||
|
||||
constructor(protected readonly instance: any) {}
|
||||
all(path: string, handler: RequestHandler<TRequest, TResponse>);
|
||||
all(handler: RequestHandler<TRequest, TResponse>);
|
||||
all(path: any, handler?: any) {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
setBaseViewsDir?(path: string | string[]): this {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
public async init() {}
|
||||
@@ -97,7 +108,10 @@ export abstract class AbstractHttpAdapter<
|
||||
abstract setNotFoundHandler(handler: Function, prefix?: string);
|
||||
abstract setHeader(response, name: string, value: string);
|
||||
abstract registerParserMiddleware(prefix?: string);
|
||||
abstract enableCors(options: CorsOptions, prefix?: string);
|
||||
abstract enableCors(
|
||||
options: CorsOptions | CorsOptionsDelegate<TRequest>,
|
||||
prefix?: string,
|
||||
);
|
||||
abstract createMiddlewareFactory(
|
||||
requestMethod: RequestMethod,
|
||||
):
|
||||
|
||||
@@ -14,12 +14,8 @@ export class ApplicationConfig {
|
||||
private globalInterceptors: NestInterceptor[] = [];
|
||||
private globalGuards: CanActivate[] = [];
|
||||
private readonly globalRequestPipes: InstanceWrapper<PipeTransform>[] = [];
|
||||
private readonly globalRequestFilters: InstanceWrapper<
|
||||
ExceptionFilter
|
||||
>[] = [];
|
||||
private readonly globalRequestInterceptors: InstanceWrapper<
|
||||
NestInterceptor
|
||||
>[] = [];
|
||||
private readonly globalRequestFilters: InstanceWrapper<ExceptionFilter>[] = [];
|
||||
private readonly globalRequestInterceptors: InstanceWrapper<NestInterceptor>[] = [];
|
||||
private readonly globalRequestGuards: InstanceWrapper<CanActivate>[] = [];
|
||||
|
||||
constructor(private ioAdapter: WebSocketAdapter | null = null) {}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Type } from '@nestjs/common';
|
||||
import { ForwardReference, Type } from '@nestjs/common';
|
||||
import { isNil, isSymbol } from '@nestjs/common/utils/shared.utils';
|
||||
import {
|
||||
InjectorDependency,
|
||||
@@ -10,8 +10,12 @@ import { Module } from '../injector/module';
|
||||
* Returns the name of an instance
|
||||
* @param instance The instance which should get the name from
|
||||
*/
|
||||
const getInstanceName = (instance: unknown): string =>
|
||||
instance && (instance as Type<any>).name;
|
||||
const getInstanceName = (instance: unknown): string => {
|
||||
if ((instance as ForwardReference)?.forwardRef) {
|
||||
return (instance as ForwardReference).forwardRef()?.name;
|
||||
}
|
||||
return (instance as Type<any>)?.name;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the name of the dependency
|
||||
|
||||
@@ -38,9 +38,7 @@ export interface ExternalContextOptions {
|
||||
export class ExternalContextCreator {
|
||||
private readonly contextUtils = new ContextUtils();
|
||||
private readonly externalErrorProxy = new ExternalErrorProxy();
|
||||
private readonly handlerMetadataStorage = new HandlerMetadataStorage<
|
||||
ExternalHandlerMetadata
|
||||
>();
|
||||
private readonly handlerMetadataStorage = new HandlerMetadataStorage<ExternalHandlerMetadata>();
|
||||
private container: NestContainer;
|
||||
|
||||
constructor(
|
||||
|
||||
@@ -28,8 +28,11 @@ export class RoutesMapper {
|
||||
},
|
||||
];
|
||||
}
|
||||
const routePath: string = Reflect.getMetadata(PATH_METADATA, route);
|
||||
if (this.isRouteInfo(routePath, route)) {
|
||||
const routePathOrPaths: string | string[] = Reflect.getMetadata(
|
||||
PATH_METADATA,
|
||||
route,
|
||||
);
|
||||
if (this.isRouteInfo(routePathOrPaths, route)) {
|
||||
return [
|
||||
{
|
||||
path: this.validateRoutePath(route.path),
|
||||
@@ -43,21 +46,28 @@ export class RoutesMapper {
|
||||
);
|
||||
const concatPaths = <T>(acc: T[], currentValue: T[]) =>
|
||||
acc.concat(currentValue);
|
||||
return paths
|
||||
.map(
|
||||
item =>
|
||||
item.path &&
|
||||
item.path.map(p => ({
|
||||
path:
|
||||
this.validateGlobalPath(routePath) + this.validateRoutePath(p),
|
||||
method: item.requestMethod,
|
||||
})),
|
||||
|
||||
return []
|
||||
.concat(routePathOrPaths)
|
||||
.map(routePath =>
|
||||
paths
|
||||
.map(
|
||||
item =>
|
||||
item.path &&
|
||||
item.path.map(p => ({
|
||||
path:
|
||||
this.validateGlobalPath(routePath) +
|
||||
this.validateRoutePath(p),
|
||||
method: item.requestMethod,
|
||||
})),
|
||||
)
|
||||
.reduce(concatPaths, []),
|
||||
)
|
||||
.reduce(concatPaths, []);
|
||||
}
|
||||
|
||||
private isRouteInfo(
|
||||
path: string | undefined,
|
||||
path: string | string[] | undefined,
|
||||
objectOrClass: Function | RouteInfo,
|
||||
): objectOrClass is RouteInfo {
|
||||
return isUndefined(path);
|
||||
|
||||
@@ -9,7 +9,10 @@ import {
|
||||
PipeTransform,
|
||||
WebSocketAdapter,
|
||||
} from '@nestjs/common';
|
||||
import { CorsOptions } from '@nestjs/common/interfaces/external/cors-options.interface';
|
||||
import {
|
||||
CorsOptions,
|
||||
CorsOptionsDelegate,
|
||||
} from '@nestjs/common/interfaces/external/cors-options.interface';
|
||||
import { NestApplicationOptions } from '@nestjs/common/interfaces/nest-application-options.interface';
|
||||
import { Logger } from '@nestjs/common/services/logger.service';
|
||||
import { loadPackage } from '@nestjs/common/utils/load-package.util';
|
||||
@@ -76,6 +79,7 @@ export class NestApplication
|
||||
|
||||
protected async dispose(): Promise<void> {
|
||||
this.socketModule && (await this.socketModule.close());
|
||||
this.microservicesModule && (await this.microservicesModule.close());
|
||||
this.httpAdapter && (await this.httpAdapter.close());
|
||||
|
||||
await Promise.all(
|
||||
@@ -102,11 +106,15 @@ export class NestApplication
|
||||
if (!this.appOptions || !this.appOptions.cors) {
|
||||
return undefined;
|
||||
}
|
||||
const isCorsOptionsObj = isObject(this.appOptions.cors);
|
||||
if (!isCorsOptionsObj) {
|
||||
const passCustomOptions =
|
||||
isObject(this.appOptions.cors) ||
|
||||
typeof this.appOptions.cors === 'function';
|
||||
if (!passCustomOptions) {
|
||||
return this.enableCors();
|
||||
}
|
||||
return this.enableCors(this.appOptions.cors as CorsOptions);
|
||||
return this.enableCors(
|
||||
this.appOptions.cors as CorsOptions | CorsOptionsDelegate<any>,
|
||||
);
|
||||
}
|
||||
|
||||
public createServer<T = any>(): T {
|
||||
@@ -224,7 +232,7 @@ export class NestApplication
|
||||
return this;
|
||||
}
|
||||
|
||||
public enableCors(options?: CorsOptions): void {
|
||||
public enableCors(options?: CorsOptions | CorsOptionsDelegate<any>): void {
|
||||
this.httpAdapter.enableCors(options);
|
||||
}
|
||||
|
||||
|
||||
@@ -248,14 +248,29 @@ export class NestFactoryStatic {
|
||||
}
|
||||
|
||||
private createAdapterProxy<T>(app: NestApplication, adapter: HttpServer): T {
|
||||
return (new Proxy(app, {
|
||||
const proxy = new Proxy(app, {
|
||||
get: (receiver: Record<string, any>, prop: string) => {
|
||||
if (!(prop in receiver) && prop in adapter) {
|
||||
return this.createExceptionZone(adapter, prop);
|
||||
return (...args: unknown[]) => {
|
||||
this.createExceptionZone(adapter, prop)(...args);
|
||||
return proxy;
|
||||
};
|
||||
}
|
||||
if (isFunction(receiver[prop])) {
|
||||
const mapToProxy = (result: unknown) =>
|
||||
result instanceof NestApplication ? proxy : result;
|
||||
|
||||
return (...args: unknown[]) => {
|
||||
const result = receiver[prop](...args);
|
||||
return result instanceof Promise
|
||||
? result.then(mapToProxy)
|
||||
: mapToProxy(result);
|
||||
};
|
||||
}
|
||||
return receiver[prop];
|
||||
},
|
||||
}) as unknown) as T;
|
||||
});
|
||||
return (proxy as unknown) as T;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nestjs/core",
|
||||
"version": "7.6.5",
|
||||
"version": "7.6.13",
|
||||
"description": "Nest - modern, fast, powerful node.js web framework (@core)",
|
||||
"author": "Kamil Mysliwiec",
|
||||
"license": "MIT",
|
||||
@@ -36,7 +36,7 @@
|
||||
"uuid": "8.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nestjs/common": "7.6.5"
|
||||
"@nestjs/common": "7.6.13"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@nestjs/common": "^7.0.0",
|
||||
|
||||
@@ -413,7 +413,11 @@ export class RouterExecutionContext {
|
||||
const renderTemplate = this.reflectRenderTemplate(callback);
|
||||
if (renderTemplate) {
|
||||
return async <TResult, TResponse>(result: TResult, res: TResponse) => {
|
||||
await this.responseController.render(result, res, renderTemplate);
|
||||
return await this.responseController.render(
|
||||
result,
|
||||
res,
|
||||
renderTemplate,
|
||||
);
|
||||
};
|
||||
}
|
||||
if (redirectResponse && typeof redirectResponse.url === 'string') {
|
||||
|
||||
@@ -73,7 +73,7 @@ export class RouterExplorer {
|
||||
module: string,
|
||||
applicationRef: T,
|
||||
basePath: string,
|
||||
host: string,
|
||||
host: string | string[],
|
||||
) {
|
||||
const { instance } = instanceWrapper;
|
||||
const routerPaths = this.scanForPaths(instance);
|
||||
@@ -150,7 +150,7 @@ export class RouterExplorer {
|
||||
instanceWrapper: InstanceWrapper,
|
||||
moduleKey: string,
|
||||
basePath: string,
|
||||
host: string,
|
||||
host: string | string[],
|
||||
) {
|
||||
(routePaths || []).forEach(pathProperties => {
|
||||
const { path, requestMethod } = pathProperties;
|
||||
@@ -179,7 +179,7 @@ export class RouterExplorer {
|
||||
instanceWrapper: InstanceWrapper,
|
||||
moduleKey: string,
|
||||
basePath: string,
|
||||
host: string,
|
||||
host: string | string[],
|
||||
) {
|
||||
const {
|
||||
path: paths,
|
||||
@@ -216,14 +216,24 @@ export class RouterExplorer {
|
||||
});
|
||||
}
|
||||
|
||||
private applyHostFilter(host: string, handler: Function) {
|
||||
private applyHostFilter(host: string | string[], handler: Function) {
|
||||
if (!host) {
|
||||
return handler;
|
||||
}
|
||||
|
||||
const httpAdapterRef = this.container.getHttpAdapterRef();
|
||||
const keys = [];
|
||||
const re = pathToRegexp(host, keys);
|
||||
const hosts = Array.isArray(host) ? host : [host];
|
||||
const hostRegExps = hosts.map((host: string) => {
|
||||
const keys = [];
|
||||
const regexp = pathToRegexp(host, keys);
|
||||
return { regexp, keys };
|
||||
});
|
||||
|
||||
const unsupportedFilteringErrorMessage = Array.isArray(host)
|
||||
? `HTTP adapter does not support filtering on hosts: ["${host.join(
|
||||
'", "',
|
||||
)}"]`
|
||||
: `HTTP adapter does not support filtering on host: "${host}"`;
|
||||
|
||||
return <TRequest extends Record<string, any> = any, TResponse = any>(
|
||||
req: TRequest,
|
||||
@@ -232,14 +242,17 @@ export class RouterExplorer {
|
||||
) => {
|
||||
(req as Record<string, any>).hosts = {};
|
||||
const hostname = httpAdapterRef.getRequestHostname(req) || '';
|
||||
const match = hostname.match(re);
|
||||
if (match) {
|
||||
keys.forEach((key, i) => (req.hosts[key.name] = match[i + 1]));
|
||||
return handler(req, res, next);
|
||||
|
||||
for (const exp of hostRegExps) {
|
||||
const match = hostname.match(exp.regexp);
|
||||
if (match) {
|
||||
exp.keys.forEach((key, i) => (req.hosts[key.name] = match[i + 1]));
|
||||
return handler(req, res, next);
|
||||
}
|
||||
}
|
||||
if (!next) {
|
||||
throw new InternalServerErrorException(
|
||||
`HTTP adapter does not support filtering on host: "${host}"`,
|
||||
unsupportedFilteringErrorMessage,
|
||||
);
|
||||
}
|
||||
return next();
|
||||
|
||||
@@ -48,7 +48,7 @@ export class RouterResponseController {
|
||||
template: string,
|
||||
) {
|
||||
const result = await this.transformToResult(resultOrDeferred);
|
||||
this.applicationRef.render(response, template, result);
|
||||
return this.applicationRef.render(response, template, result);
|
||||
}
|
||||
|
||||
public async transformToResult(resultOrDeferred: any) {
|
||||
|
||||
@@ -132,7 +132,7 @@ export class RoutesResolver implements Resolver {
|
||||
|
||||
private getHostMetadata(
|
||||
metatype: Type<unknown> | Function,
|
||||
): string | undefined {
|
||||
): string | string[] | undefined {
|
||||
return Reflect.getMetadata(HOST_METADATA, metatype);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,4 +34,32 @@ describe('RoutesMapper', () => {
|
||||
{ path: '/test/another', method: RequestMethod.DELETE },
|
||||
]);
|
||||
});
|
||||
@Controller(['test', 'test2'])
|
||||
class TestRouteWithMultiplePaths {
|
||||
@RequestMapping({ path: 'test' })
|
||||
public getTest() {}
|
||||
|
||||
@RequestMapping({ path: 'another', method: RequestMethod.DELETE })
|
||||
public getAnother() {}
|
||||
}
|
||||
|
||||
it('should map a controller with multiple paths to "ControllerMetadata" in forRoutes', () => {
|
||||
const config = {
|
||||
middleware: 'Test',
|
||||
forRoutes: [
|
||||
{ path: 'test', method: RequestMethod.GET },
|
||||
TestRouteWithMultiplePaths,
|
||||
],
|
||||
};
|
||||
|
||||
expect(mapper.mapRouteToRouteInfo(config.forRoutes[0])).to.deep.equal([
|
||||
{ path: '/test', method: RequestMethod.GET },
|
||||
]);
|
||||
expect(mapper.mapRouteToRouteInfo(config.forRoutes[1])).to.deep.equal([
|
||||
{ path: '/test/test', method: RequestMethod.GET },
|
||||
{ path: '/test/another', method: RequestMethod.DELETE },
|
||||
{ path: '/test2/test', method: RequestMethod.GET },
|
||||
{ path: '/test2/another', method: RequestMethod.DELETE },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -56,16 +56,21 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
||||
|
||||
#### Principal Sponsors
|
||||
<table style="text-align:center;"><tr><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><td>
|
||||
<a href="https://valor-software.com/" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/valor-software.png" width="180" valign="middle" /></a></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>
|
||||
<td>
|
||||
<a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="200" valign="middle" /></a></td>
|
||||
</tr></table>
|
||||
|
||||
#### Gold Sponsors
|
||||
|
||||
<table style="text-align:center;"><tr><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></tr></table>
|
||||
|
||||
#### Silver Sponsors
|
||||
|
||||
<table style="text-align:center;"><tr><td>
|
||||
<a href="https://neoteric.eu/" target="_blank"><img src="https://nestjs.com/img/neoteric-cut.png" width="120" valign="middle" /></a> </td><td>
|
||||
<a href="http://gojob.com" target="_blank"><img src="http://nestjs.com/img/gojob-logo.png" valign="middle" width="100" /></a> </td><td>
|
||||
<a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="170" valign="middle" /></a> </td><td>
|
||||
<a href="http://www.leogistics.com" target="_blank"><img src="https://nestjs.com/img/leogistics-logo.jpeg" width="150" valign="middle" /></td><td>
|
||||
<a href="http://www.meetdandy.com" target="_blank"><img src="https://nestjs.com/img/dandy-wide-logo.png" width="150" valign="middle" /></td></tr></table>
|
||||
|
||||
@@ -90,6 +95,11 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://genuinebee.com/" target="_blank"><img src="https://nestjs.com/img/genuinebee.svg" width="97" valign="middle" /></a> </td>
|
||||
<td align="center" valign="middle"><a href="https://sanyodigital.com/" target="_blank"><img src="https://nestjs.com/img/sanyo-digital.png" width="130" valign="middle" /></a></td></tr><tr><td align="center" valign="middle"><a href="https://vpn-review.com/vpn-for-torrenting" target="_blank"><img src="https://nestjs.com/img/vpn-review-logo.png" width="85" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://lambda-it.ch/" target="_blank"><img src="https://nestjs.com/img/lambda-it-logo.svg" width="115" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://pickwriters.com/top-10-translation-services" target="_blank"><img src="https://nestjs.com/img/pickwriters-logo.png" width="40" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://thewordpoint.com/services/localization" target="_blank"><img src="https://nestjs.com/img/thewordpoint-logo.png" width="40" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://streamat.se/" target="_blank"><img src="https://nestjs.com/img/streamat-logo.png" width="120" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://filmen.nu/" target="_blank"><img src="https://nestjs.com/img/filmen-logo.png" width="120" valign="middle" /></a></td></tr><tr>
|
||||
<td align="center" valign="middle"><a href="https://meercode.io/" target="_blank"><img src="https://nestjs.com/img/meercode-logo.png" width="60" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://www.najlepszeplatformyforex.pl/blog/broker-xtb/" target="_blank"><img src="https://nestjs.com/img/npf-logo.jpg" width="200" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://thestandarddaily.com/" target="_blank"><img src="https://nestjs.com/img/the-standard-daily-logo.png" width="180" valign="middle" /></a></td>
|
||||
</tr></table>
|
||||
|
||||
## Backers
|
||||
|
||||
@@ -305,7 +305,9 @@ export class ClientGrpcProxy extends ClientProxy implements ClientGrpc {
|
||||
}
|
||||
|
||||
public close() {
|
||||
this.grpcClients.forEach(client => client.close());
|
||||
this.grpcClients
|
||||
.filter(client => client && isFunction(client.close))
|
||||
.forEach(client => client.close());
|
||||
this.grpcClients = [];
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Transport } from '../enums/transport.enum';
|
||||
import {
|
||||
ClientOptions,
|
||||
CustomClientOptions,
|
||||
TcpClientOptions,
|
||||
} from '../interfaces/client-metadata.interface';
|
||||
import { Closeable } from '../interfaces/closeable.interface';
|
||||
@@ -30,7 +31,16 @@ export class ClientProxyFactory {
|
||||
clientOptions: { transport: Transport.GRPC } & ClientOptions,
|
||||
): ClientGrpcProxy;
|
||||
public static create(clientOptions: ClientOptions): ClientProxy & Closeable;
|
||||
public static create(clientOptions: ClientOptions): ClientProxy & Closeable {
|
||||
public static create(
|
||||
clientOptions: CustomClientOptions,
|
||||
): ClientProxy & Closeable;
|
||||
public static create(
|
||||
clientOptions: ClientOptions | CustomClientOptions,
|
||||
): ClientProxy & Closeable {
|
||||
if (this.isCustomClientOptions(clientOptions)) {
|
||||
const { customClass, options } = clientOptions;
|
||||
return new customClass(options);
|
||||
}
|
||||
const { transport, options } = clientOptions;
|
||||
switch (transport) {
|
||||
case Transport.REDIS:
|
||||
@@ -49,4 +59,10 @@ export class ClientProxyFactory {
|
||||
return new ClientTCP(options as TcpClientOptions['options']);
|
||||
}
|
||||
}
|
||||
|
||||
private static isCustomClientOptions(
|
||||
options: ClientOptions | CustomClientOptions,
|
||||
): options is CustomClientOptions {
|
||||
return !!(options as CustomClientOptions).customClass;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,17 +84,25 @@ export abstract class ClientProxy {
|
||||
): (packet: WritePacket) => void {
|
||||
return ({ err, response, isDisposed }: WritePacket) => {
|
||||
if (err) {
|
||||
return observer.error(err);
|
||||
return observer.error(this.serializeError(err));
|
||||
} else if (response !== undefined && isDisposed) {
|
||||
observer.next(response);
|
||||
observer.next(this.serializeResponse(response));
|
||||
return observer.complete();
|
||||
} else if (isDisposed) {
|
||||
return observer.complete();
|
||||
}
|
||||
observer.next(response);
|
||||
observer.next(this.serializeResponse(response));
|
||||
};
|
||||
}
|
||||
|
||||
protected serializeError(err: any): any {
|
||||
return err;
|
||||
}
|
||||
|
||||
protected serializeResponse(response: any): any {
|
||||
return response;
|
||||
}
|
||||
|
||||
protected assignPacketId(packet: ReadPacket): ReadPacket & PacketId {
|
||||
const id = randomStringGenerator();
|
||||
return Object.assign(packet, { id });
|
||||
|
||||
@@ -41,9 +41,7 @@ export interface RpcHandlerMetadata {
|
||||
export class RpcContextCreator {
|
||||
private readonly contextUtils = new ContextUtils();
|
||||
private readonly rpcParamsFactory = new RpcParamsFactory();
|
||||
private readonly handlerMetadataStorage = new HandlerMetadataStorage<
|
||||
RpcHandlerMetadata
|
||||
>();
|
||||
private readonly handlerMetadataStorage = new HandlerMetadataStorage<RpcHandlerMetadata>();
|
||||
|
||||
constructor(
|
||||
private readonly rpcProxy: RpcProxy,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { Type } from '@nestjs/common';
|
||||
import { ClientProxy } from '../client';
|
||||
import { Transport } from '../enums/transport.enum';
|
||||
import { Deserializer } from './deserializer.interface';
|
||||
import {
|
||||
@@ -19,6 +21,11 @@ export type ClientOptions =
|
||||
| TcpClientOptions
|
||||
| RmqOptions;
|
||||
|
||||
export interface CustomClientOptions {
|
||||
customClass: Type<ClientProxy>;
|
||||
options?: Record<string, any>;
|
||||
}
|
||||
|
||||
export interface TcpClientOptions {
|
||||
transport: Transport.TCP;
|
||||
options?: {
|
||||
|
||||
@@ -39,11 +39,13 @@ export class MicroservicesModule {
|
||||
new InterceptorsContextCreator(container, config),
|
||||
new InterceptorsConsumer(),
|
||||
);
|
||||
|
||||
const injector = new Injector();
|
||||
this.listenersController = new ListenersController(
|
||||
this.clientsContainer,
|
||||
contextCreator,
|
||||
container,
|
||||
new Injector(),
|
||||
injector,
|
||||
ClientProxyFactory,
|
||||
exceptionFiltersContext,
|
||||
);
|
||||
@@ -90,9 +92,9 @@ export class MicroservicesModule {
|
||||
});
|
||||
}
|
||||
|
||||
public close() {
|
||||
public async close() {
|
||||
const clients = this.clientsContainer.getAllClients();
|
||||
clients.forEach(client => client.close());
|
||||
await Promise.all(clients.map(client => client.close()));
|
||||
this.clientsContainer.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import { DynamicModule, Module, Provider } from '@nestjs/common';
|
||||
import { ClientProxyFactory } from '../client';
|
||||
import {
|
||||
DynamicModule,
|
||||
Module,
|
||||
OnApplicationShutdown,
|
||||
Provider,
|
||||
} from '@nestjs/common';
|
||||
import { ClientProxy, ClientProxyFactory } from '../client';
|
||||
import { Closeable } from '../interfaces';
|
||||
import {
|
||||
ClientsModuleAsyncOptions,
|
||||
ClientsModuleOptions,
|
||||
@@ -12,7 +18,7 @@ export class ClientsModule {
|
||||
static register(options: ClientsModuleOptions): DynamicModule {
|
||||
const clients = (options || []).map(item => ({
|
||||
provide: item.name,
|
||||
useValue: ClientProxyFactory.create(item),
|
||||
useValue: this.assignOnAppShutdownHook(ClientProxyFactory.create(item)),
|
||||
}));
|
||||
return {
|
||||
module: ClientsModule,
|
||||
@@ -84,7 +90,14 @@ export class ClientsModule {
|
||||
) {
|
||||
return async (...args: any[]) => {
|
||||
const clientOptions = await useFactory(...args);
|
||||
return ClientProxyFactory.create(clientOptions);
|
||||
const clientProxyRef = ClientProxyFactory.create(clientOptions);
|
||||
return this.assignOnAppShutdownHook(clientProxyRef);
|
||||
};
|
||||
}
|
||||
|
||||
private static assignOnAppShutdownHook(client: ClientProxy & Closeable) {
|
||||
((client as unknown) as OnApplicationShutdown).onApplicationShutdown =
|
||||
client.close;
|
||||
return client;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,23 @@
|
||||
import { ClientOptions } from '../../interfaces';
|
||||
import { ClientOptions, CustomClientOptions } from '../../interfaces';
|
||||
import { Type, Provider, ModuleMetadata } from '@nestjs/common/interfaces';
|
||||
|
||||
export type ClientProviderOptions = ClientOptions & {
|
||||
export type ClientProvider = ClientOptions | CustomClientOptions;
|
||||
|
||||
export type ClientProviderOptions = ClientProvider & {
|
||||
name: string | symbol;
|
||||
};
|
||||
|
||||
export type ClientsModuleOptions = Array<ClientProviderOptions>;
|
||||
|
||||
export interface ClientsModuleOptionsFactory {
|
||||
createClientOptions(): Promise<ClientOptions> | ClientOptions;
|
||||
createClientOptions(): Promise<ClientProvider> | ClientProvider;
|
||||
}
|
||||
|
||||
export interface ClientsProviderAsyncOptions
|
||||
extends Pick<ModuleMetadata, 'imports'> {
|
||||
useExisting?: Type<ClientsModuleOptionsFactory>;
|
||||
useClass?: Type<ClientsModuleOptionsFactory>;
|
||||
useFactory?: (...args: any[]) => Promise<ClientOptions> | ClientOptions;
|
||||
useFactory?: (...args: any[]) => Promise<ClientProvider> | ClientProvider;
|
||||
inject?: any[];
|
||||
extraProviders?: Provider[];
|
||||
name: string | symbol;
|
||||
|
||||
@@ -149,6 +149,8 @@ export class NestMicroservice
|
||||
|
||||
protected async closeApplication(): Promise<any> {
|
||||
this.socketModule && (await this.socketModule.close());
|
||||
this.microservicesModule && (await this.microservicesModule.close());
|
||||
|
||||
await super.close();
|
||||
this.setIsTerminated(true);
|
||||
}
|
||||
@@ -159,5 +161,6 @@ export class NestMicroservice
|
||||
return;
|
||||
}
|
||||
this.socketModule && (await this.socketModule.close());
|
||||
this.microservicesModule && (await this.microservicesModule.close());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nestjs/microservices",
|
||||
"version": "7.6.5",
|
||||
"version": "7.6.13",
|
||||
"description": "Nest - modern, fast, powerful node.js web framework (@microservices)",
|
||||
"author": "Kamil Mysliwiec",
|
||||
"license": "MIT",
|
||||
@@ -22,8 +22,8 @@
|
||||
"tslib": "2.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nestjs/common": "7.6.5",
|
||||
"@nestjs/core": "7.6.5"
|
||||
"@nestjs/common": "7.6.13",
|
||||
"@nestjs/core": "7.6.13"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@nestjs/common": "^7.0.0",
|
||||
|
||||
@@ -124,7 +124,7 @@ describe('ClientMqtt', () => {
|
||||
subscription = client.createResponseCallback();
|
||||
|
||||
client['routingMap'].set(responseMessage.id, callback);
|
||||
subscription('channel', new Buffer(JSON.stringify(responseMessage)));
|
||||
subscription('channel', Buffer.from(JSON.stringify(responseMessage)));
|
||||
});
|
||||
it('should call callback with expected arguments', () => {
|
||||
expect(
|
||||
@@ -143,7 +143,7 @@ describe('ClientMqtt', () => {
|
||||
client['routingMap'].set(responseMessage.id, callback);
|
||||
subscription(
|
||||
'channel',
|
||||
new Buffer(
|
||||
Buffer.from(
|
||||
JSON.stringify({
|
||||
...responseMessage,
|
||||
isDisposed: true,
|
||||
@@ -169,7 +169,7 @@ describe('ClientMqtt', () => {
|
||||
subscription = client.createResponseCallback();
|
||||
|
||||
client['routingMap'].set('3', callback);
|
||||
subscription('channel', new Buffer(JSON.stringify(responseMessage)));
|
||||
subscription('channel', Buffer.from(JSON.stringify(responseMessage)));
|
||||
});
|
||||
|
||||
it('should not call callback', () => {
|
||||
|
||||
@@ -128,7 +128,7 @@ describe('ClientRedis', () => {
|
||||
|
||||
subscription = client.createResponseCallback();
|
||||
client['routingMap'].set(responseMessage.id, callback);
|
||||
subscription('channel', new Buffer(JSON.stringify(responseMessage)));
|
||||
subscription('channel', Buffer.from(JSON.stringify(responseMessage)));
|
||||
});
|
||||
it('should call callback with expected arguments', () => {
|
||||
expect(
|
||||
@@ -146,7 +146,7 @@ describe('ClientRedis', () => {
|
||||
client['routingMap'].set(responseMessage.id, callback);
|
||||
subscription(
|
||||
'channel',
|
||||
new Buffer(
|
||||
Buffer.from(
|
||||
JSON.stringify({
|
||||
...responseMessage,
|
||||
isDisposed: responseMessage.response,
|
||||
@@ -170,7 +170,7 @@ describe('ClientRedis', () => {
|
||||
beforeEach(() => {
|
||||
callback = sinon.spy();
|
||||
subscription = client.createResponseCallback();
|
||||
subscription('channel', new Buffer(JSON.stringify(responseMessage)));
|
||||
subscription('channel', Buffer.from(JSON.stringify(responseMessage)));
|
||||
});
|
||||
|
||||
it('should not call callback', () => {
|
||||
@@ -336,4 +336,4 @@ describe('ClientRedis', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -2,9 +2,9 @@ import { DynamicModule, FactoryProvider, Injectable } from '@nestjs/common';
|
||||
import { expect } from 'chai';
|
||||
import * as sinon from 'sinon';
|
||||
import { ClientProxyFactory } from '../../client';
|
||||
import { ClientsModule, ClientsModuleOptionsFactory } from '../../module';
|
||||
import { ClientOptions } from '../../interfaces';
|
||||
import { Transport } from '../../enums';
|
||||
import { ClientOptions } from '../../interfaces';
|
||||
import { ClientsModule, ClientsModuleOptionsFactory } from '../../module';
|
||||
|
||||
describe('ClientsModule', () => {
|
||||
let dynamicModule: DynamicModule;
|
||||
@@ -24,7 +24,9 @@ describe('ClientsModule', () => {
|
||||
expect(dynamicModule.providers).to.be.deep.eq([
|
||||
{
|
||||
provide: 'test',
|
||||
useValue: ClientProxyFactory.create({}),
|
||||
useValue: ClientsModule['assignOnAppShutdownHook'](
|
||||
ClientProxyFactory.create({}),
|
||||
),
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -56,16 +56,21 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
||||
|
||||
#### Principal Sponsors
|
||||
<table style="text-align:center;"><tr><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><td>
|
||||
<a href="https://valor-software.com/" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/valor-software.png" width="180" valign="middle" /></a></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>
|
||||
<td>
|
||||
<a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="200" valign="middle" /></a></td>
|
||||
</tr></table>
|
||||
|
||||
#### Gold Sponsors
|
||||
|
||||
<table style="text-align:center;"><tr><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></tr></table>
|
||||
|
||||
#### Silver Sponsors
|
||||
|
||||
<table style="text-align:center;"><tr><td>
|
||||
<a href="https://neoteric.eu/" target="_blank"><img src="https://nestjs.com/img/neoteric-cut.png" width="120" valign="middle" /></a> </td><td>
|
||||
<a href="http://gojob.com" target="_blank"><img src="http://nestjs.com/img/gojob-logo.png" valign="middle" width="100" /></a> </td><td>
|
||||
<a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="170" valign="middle" /></a> </td><td>
|
||||
<a href="http://www.leogistics.com" target="_blank"><img src="https://nestjs.com/img/leogistics-logo.jpeg" width="150" valign="middle" /></td><td>
|
||||
<a href="http://www.meetdandy.com" target="_blank"><img src="https://nestjs.com/img/dandy-wide-logo.png" width="150" valign="middle" /></td></tr></table>
|
||||
|
||||
@@ -90,6 +95,11 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://genuinebee.com/" target="_blank"><img src="https://nestjs.com/img/genuinebee.svg" width="97" valign="middle" /></a> </td>
|
||||
<td align="center" valign="middle"><a href="https://sanyodigital.com/" target="_blank"><img src="https://nestjs.com/img/sanyo-digital.png" width="130" valign="middle" /></a></td></tr><tr><td align="center" valign="middle"><a href="https://vpn-review.com/vpn-for-torrenting" target="_blank"><img src="https://nestjs.com/img/vpn-review-logo.png" width="85" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://lambda-it.ch/" target="_blank"><img src="https://nestjs.com/img/lambda-it-logo.svg" width="115" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://pickwriters.com/top-10-translation-services" target="_blank"><img src="https://nestjs.com/img/pickwriters-logo.png" width="40" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://thewordpoint.com/services/localization" target="_blank"><img src="https://nestjs.com/img/thewordpoint-logo.png" width="40" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://streamat.se/" target="_blank"><img src="https://nestjs.com/img/streamat-logo.png" width="120" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://filmen.nu/" target="_blank"><img src="https://nestjs.com/img/filmen-logo.png" width="120" valign="middle" /></a></td></tr><tr>
|
||||
<td align="center" valign="middle"><a href="https://meercode.io/" target="_blank"><img src="https://nestjs.com/img/meercode-logo.png" width="60" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://www.najlepszeplatformyforex.pl/blog/broker-xtb/" target="_blank"><img src="https://nestjs.com/img/npf-logo.jpg" width="200" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://thestandarddaily.com/" target="_blank"><img src="https://nestjs.com/img/the-standard-daily-logo.png" width="180" valign="middle" /></a></td>
|
||||
</tr></table>
|
||||
|
||||
## Backers
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { RequestMethod } from '@nestjs/common';
|
||||
import { CorsOptions } from '@nestjs/common/interfaces/external/cors-options.interface';
|
||||
import {
|
||||
CorsOptions,
|
||||
CorsOptionsDelegate,
|
||||
} from '@nestjs/common/interfaces/external/cors-options.interface';
|
||||
import { NestApplicationOptions } from '@nestjs/common/interfaces/nest-application-options.interface';
|
||||
import { isFunction, isNil, isObject } from '@nestjs/common/utils/shared.utils';
|
||||
import { AbstractHttpAdapter } from '@nestjs/core/adapters/http-adapter';
|
||||
@@ -108,7 +111,7 @@ export class ExpressAdapter extends AbstractHttpAdapter {
|
||||
return request.originalUrl;
|
||||
}
|
||||
|
||||
public enableCors(options: CorsOptions) {
|
||||
public enableCors(options: CorsOptions | CorsOptionsDelegate<any>) {
|
||||
return this.use(cors(options));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nestjs/platform-express",
|
||||
"version": "7.6.5",
|
||||
"version": "7.6.13",
|
||||
"description": "Nest - modern, fast, powerful node.js web framework (@platform-express)",
|
||||
"author": "Kamil Mysliwiec",
|
||||
"license": "MIT",
|
||||
@@ -24,8 +24,8 @@
|
||||
"tslib": "2.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nestjs/common": "7.6.5",
|
||||
"@nestjs/core": "7.6.5"
|
||||
"@nestjs/common": "7.6.13",
|
||||
"@nestjs/core": "7.6.13"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@nestjs/common": "^7.0.0",
|
||||
|
||||
@@ -56,16 +56,21 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
||||
|
||||
#### Principal Sponsors
|
||||
<table style="text-align:center;"><tr><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><td>
|
||||
<a href="https://valor-software.com/" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/valor-software.png" width="180" valign="middle" /></a></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>
|
||||
<td>
|
||||
<a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="200" valign="middle" /></a></td>
|
||||
</tr></table>
|
||||
|
||||
#### Gold Sponsors
|
||||
|
||||
<table style="text-align:center;"><tr><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></tr></table>
|
||||
|
||||
#### Silver Sponsors
|
||||
|
||||
<table style="text-align:center;"><tr><td>
|
||||
<a href="https://neoteric.eu/" target="_blank"><img src="https://nestjs.com/img/neoteric-cut.png" width="120" valign="middle" /></a> </td><td>
|
||||
<a href="http://gojob.com" target="_blank"><img src="http://nestjs.com/img/gojob-logo.png" valign="middle" width="100" /></a> </td><td>
|
||||
<a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="170" valign="middle" /></a> </td><td>
|
||||
<a href="http://www.leogistics.com" target="_blank"><img src="https://nestjs.com/img/leogistics-logo.jpeg" width="150" valign="middle" /></td><td>
|
||||
<a href="http://www.meetdandy.com" target="_blank"><img src="https://nestjs.com/img/dandy-wide-logo.png" width="150" valign="middle" /></td></tr></table>
|
||||
|
||||
@@ -90,6 +95,11 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://genuinebee.com/" target="_blank"><img src="https://nestjs.com/img/genuinebee.svg" width="97" valign="middle" /></a> </td>
|
||||
<td align="center" valign="middle"><a href="https://sanyodigital.com/" target="_blank"><img src="https://nestjs.com/img/sanyo-digital.png" width="130" valign="middle" /></a></td></tr><tr><td align="center" valign="middle"><a href="https://vpn-review.com/vpn-for-torrenting" target="_blank"><img src="https://nestjs.com/img/vpn-review-logo.png" width="85" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://lambda-it.ch/" target="_blank"><img src="https://nestjs.com/img/lambda-it-logo.svg" width="115" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://pickwriters.com/top-10-translation-services" target="_blank"><img src="https://nestjs.com/img/pickwriters-logo.png" width="40" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://thewordpoint.com/services/localization" target="_blank"><img src="https://nestjs.com/img/thewordpoint-logo.png" width="40" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://streamat.se/" target="_blank"><img src="https://nestjs.com/img/streamat-logo.png" width="120" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://filmen.nu/" target="_blank"><img src="https://nestjs.com/img/filmen-logo.png" width="120" valign="middle" /></a></td></tr><tr>
|
||||
<td align="center" valign="middle"><a href="https://meercode.io/" target="_blank"><img src="https://nestjs.com/img/meercode-logo.png" width="60" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://www.najlepszeplatformyforex.pl/blog/broker-xtb/" target="_blank"><img src="https://nestjs.com/img/npf-logo.jpg" width="200" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://thestandarddaily.com/" target="_blank"><img src="https://nestjs.com/img/the-standard-daily-logo.png" width="180" valign="middle" /></a></td>
|
||||
</tr></table>
|
||||
|
||||
## Backers
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
import { HttpStatus, Logger, RequestMethod } from '@nestjs/common';
|
||||
import { CorsOptions } from '@nestjs/common/interfaces/external/cors-options.interface';
|
||||
import {
|
||||
CorsOptions,
|
||||
CorsOptionsDelegate,
|
||||
} from '@nestjs/common/interfaces/external/cors-options.interface';
|
||||
import { loadPackage } from '@nestjs/common/utils/load-package.util';
|
||||
import { AbstractHttpAdapter } from '@nestjs/core/adapters/http-adapter';
|
||||
import {
|
||||
@@ -257,8 +260,18 @@ export class FastifyAdapter<
|
||||
return request.raw ? request.raw.url : request.url;
|
||||
}
|
||||
|
||||
public enableCors(options: CorsOptions) {
|
||||
this.register(require('fastify-cors'), options);
|
||||
public enableCors(
|
||||
options:
|
||||
| CorsOptions
|
||||
| CorsOptionsDelegate<
|
||||
FastifyRequest<RequestGenericInterface, TServer, TRawRequest>
|
||||
>,
|
||||
) {
|
||||
if (typeof options === 'function') {
|
||||
this.register(require('fastify-cors'), () => options);
|
||||
} else {
|
||||
this.register(require('fastify-cors'), options);
|
||||
}
|
||||
}
|
||||
|
||||
public registerParserMiddleware() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nestjs/platform-fastify",
|
||||
"version": "7.6.5",
|
||||
"version": "7.6.13",
|
||||
"description": "Nest - modern, fast, powerful node.js web framework (@platform-fastify)",
|
||||
"author": "Kamil Mysliwiec",
|
||||
"license": "MIT",
|
||||
@@ -17,8 +17,8 @@
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"fastify": "3.9.2",
|
||||
"fastify-cors": "5.1.0",
|
||||
"fastify": "3.12.0",
|
||||
"fastify-cors": "5.2.0",
|
||||
"fastify-formbody": "5.0.0",
|
||||
"light-my-request": "4.4.1",
|
||||
"middie": "5.2.0",
|
||||
|
||||
@@ -56,16 +56,21 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
||||
|
||||
#### Principal Sponsors
|
||||
<table style="text-align:center;"><tr><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><td>
|
||||
<a href="https://valor-software.com/" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/valor-software.png" width="180" valign="middle" /></a></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>
|
||||
<td>
|
||||
<a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="200" valign="middle" /></a></td>
|
||||
</tr></table>
|
||||
|
||||
#### Gold Sponsors
|
||||
|
||||
<table style="text-align:center;"><tr><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></tr></table>
|
||||
|
||||
#### Silver Sponsors
|
||||
|
||||
<table style="text-align:center;"><tr><td>
|
||||
<a href="https://neoteric.eu/" target="_blank"><img src="https://nestjs.com/img/neoteric-cut.png" width="120" valign="middle" /></a> </td><td>
|
||||
<a href="http://gojob.com" target="_blank"><img src="http://nestjs.com/img/gojob-logo.png" valign="middle" width="100" /></a> </td><td>
|
||||
<a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="170" valign="middle" /></a> </td><td>
|
||||
<a href="http://www.leogistics.com" target="_blank"><img src="https://nestjs.com/img/leogistics-logo.jpeg" width="150" valign="middle" /></td><td>
|
||||
<a href="http://www.meetdandy.com" target="_blank"><img src="https://nestjs.com/img/dandy-wide-logo.png" width="150" valign="middle" /></td></tr></table>
|
||||
|
||||
@@ -90,6 +95,11 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://genuinebee.com/" target="_blank"><img src="https://nestjs.com/img/genuinebee.svg" width="97" valign="middle" /></a> </td>
|
||||
<td align="center" valign="middle"><a href="https://sanyodigital.com/" target="_blank"><img src="https://nestjs.com/img/sanyo-digital.png" width="130" valign="middle" /></a></td></tr><tr><td align="center" valign="middle"><a href="https://vpn-review.com/vpn-for-torrenting" target="_blank"><img src="https://nestjs.com/img/vpn-review-logo.png" width="85" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://lambda-it.ch/" target="_blank"><img src="https://nestjs.com/img/lambda-it-logo.svg" width="115" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://pickwriters.com/top-10-translation-services" target="_blank"><img src="https://nestjs.com/img/pickwriters-logo.png" width="40" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://thewordpoint.com/services/localization" target="_blank"><img src="https://nestjs.com/img/thewordpoint-logo.png" width="40" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://streamat.se/" target="_blank"><img src="https://nestjs.com/img/streamat-logo.png" width="120" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://filmen.nu/" target="_blank"><img src="https://nestjs.com/img/filmen-logo.png" width="120" valign="middle" /></a></td></tr><tr>
|
||||
<td align="center" valign="middle"><a href="https://meercode.io/" target="_blank"><img src="https://nestjs.com/img/meercode-logo.png" width="60" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://www.najlepszeplatformyforex.pl/blog/broker-xtb/" target="_blank"><img src="https://nestjs.com/img/npf-logo.jpg" width="200" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://thestandarddaily.com/" target="_blank"><img src="https://nestjs.com/img/the-standard-daily-logo.png" width="180" valign="middle" /></a></td>
|
||||
</tr></table>
|
||||
|
||||
## Backers
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nestjs/platform-socket.io",
|
||||
"version": "7.6.5",
|
||||
"version": "7.6.13",
|
||||
"description": "Nest - modern, fast, powerful node.js web framework (@platform-socket.io)",
|
||||
"author": "Kamil Mysliwiec",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -56,16 +56,21 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
||||
|
||||
#### Principal Sponsors
|
||||
<table style="text-align:center;"><tr><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><td>
|
||||
<a href="https://valor-software.com/" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/valor-software.png" width="180" valign="middle" /></a></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>
|
||||
<td>
|
||||
<a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="200" valign="middle" /></a></td>
|
||||
</tr></table>
|
||||
|
||||
#### Gold Sponsors
|
||||
|
||||
<table style="text-align:center;"><tr><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></tr></table>
|
||||
|
||||
#### Silver Sponsors
|
||||
|
||||
<table style="text-align:center;"><tr><td>
|
||||
<a href="https://neoteric.eu/" target="_blank"><img src="https://nestjs.com/img/neoteric-cut.png" width="120" valign="middle" /></a> </td><td>
|
||||
<a href="http://gojob.com" target="_blank"><img src="http://nestjs.com/img/gojob-logo.png" valign="middle" width="100" /></a> </td><td>
|
||||
<a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="170" valign="middle" /></a> </td><td>
|
||||
<a href="http://www.leogistics.com" target="_blank"><img src="https://nestjs.com/img/leogistics-logo.jpeg" width="150" valign="middle" /></td><td>
|
||||
<a href="http://www.meetdandy.com" target="_blank"><img src="https://nestjs.com/img/dandy-wide-logo.png" width="150" valign="middle" /></td></tr></table>
|
||||
|
||||
@@ -90,6 +95,11 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://genuinebee.com/" target="_blank"><img src="https://nestjs.com/img/genuinebee.svg" width="97" valign="middle" /></a> </td>
|
||||
<td align="center" valign="middle"><a href="https://sanyodigital.com/" target="_blank"><img src="https://nestjs.com/img/sanyo-digital.png" width="130" valign="middle" /></a></td></tr><tr><td align="center" valign="middle"><a href="https://vpn-review.com/vpn-for-torrenting" target="_blank"><img src="https://nestjs.com/img/vpn-review-logo.png" width="85" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://lambda-it.ch/" target="_blank"><img src="https://nestjs.com/img/lambda-it-logo.svg" width="115" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://pickwriters.com/top-10-translation-services" target="_blank"><img src="https://nestjs.com/img/pickwriters-logo.png" width="40" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://thewordpoint.com/services/localization" target="_blank"><img src="https://nestjs.com/img/thewordpoint-logo.png" width="40" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://streamat.se/" target="_blank"><img src="https://nestjs.com/img/streamat-logo.png" width="120" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://filmen.nu/" target="_blank"><img src="https://nestjs.com/img/filmen-logo.png" width="120" valign="middle" /></a></td></tr><tr>
|
||||
<td align="center" valign="middle"><a href="https://meercode.io/" target="_blank"><img src="https://nestjs.com/img/meercode-logo.png" width="60" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://www.najlepszeplatformyforex.pl/blog/broker-xtb/" target="_blank"><img src="https://nestjs.com/img/npf-logo.jpg" width="200" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://thestandarddaily.com/" target="_blank"><img src="https://nestjs.com/img/the-standard-daily-logo.png" width="180" valign="middle" /></a></td>
|
||||
</tr></table>
|
||||
|
||||
## Backers
|
||||
|
||||
@@ -32,6 +32,13 @@ export class WsAdapter extends AbstractWsAdapter {
|
||||
options?: any & { namespace?: string; server?: any },
|
||||
): any {
|
||||
const { server, ...wsOptions } = options;
|
||||
if (wsOptions?.namespace) {
|
||||
const error = new Error(
|
||||
'"WsAdapter" does not support namespaces. If you need namespaces in your project, consider using the "@nestjs/platform-socket.io" package instead.',
|
||||
);
|
||||
this.logger.error(error);
|
||||
throw error;
|
||||
}
|
||||
if (port === 0 && this.httpServer) {
|
||||
return this.bindErrorHandler(
|
||||
new wsPackage.Server({
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nestjs/platform-ws",
|
||||
"version": "7.6.5",
|
||||
"version": "7.6.13",
|
||||
"description": "Nest - modern, fast, powerful node.js web framework (@platform-ws)",
|
||||
"author": "Kamil Mysliwiec",
|
||||
"license": "MIT",
|
||||
@@ -18,7 +18,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": "2.1.0",
|
||||
"ws": "7.4.2"
|
||||
"ws": "7.4.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@nestjs/common": "^7.0.0",
|
||||
|
||||
@@ -56,16 +56,21 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
||||
|
||||
#### Principal Sponsors
|
||||
<table style="text-align:center;"><tr><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><td>
|
||||
<a href="https://valor-software.com/" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/valor-software.png" width="180" valign="middle" /></a></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>
|
||||
<td>
|
||||
<a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="200" valign="middle" /></a></td>
|
||||
</tr></table>
|
||||
|
||||
#### Gold Sponsors
|
||||
|
||||
<table style="text-align:center;"><tr><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></tr></table>
|
||||
|
||||
#### Silver Sponsors
|
||||
|
||||
<table style="text-align:center;"><tr><td>
|
||||
<a href="https://neoteric.eu/" target="_blank"><img src="https://nestjs.com/img/neoteric-cut.png" width="120" valign="middle" /></a> </td><td>
|
||||
<a href="http://gojob.com" target="_blank"><img src="http://nestjs.com/img/gojob-logo.png" valign="middle" width="100" /></a> </td><td>
|
||||
<a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="170" valign="middle" /></a> </td><td>
|
||||
<a href="http://www.leogistics.com" target="_blank"><img src="https://nestjs.com/img/leogistics-logo.jpeg" width="150" valign="middle" /></td><td>
|
||||
<a href="http://www.meetdandy.com" target="_blank"><img src="https://nestjs.com/img/dandy-wide-logo.png" width="150" valign="middle" /></td></tr></table>
|
||||
|
||||
@@ -90,6 +95,11 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://genuinebee.com/" target="_blank"><img src="https://nestjs.com/img/genuinebee.svg" width="97" valign="middle" /></a> </td>
|
||||
<td align="center" valign="middle"><a href="https://sanyodigital.com/" target="_blank"><img src="https://nestjs.com/img/sanyo-digital.png" width="130" valign="middle" /></a></td></tr><tr><td align="center" valign="middle"><a href="https://vpn-review.com/vpn-for-torrenting" target="_blank"><img src="https://nestjs.com/img/vpn-review-logo.png" width="85" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://lambda-it.ch/" target="_blank"><img src="https://nestjs.com/img/lambda-it-logo.svg" width="115" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://pickwriters.com/top-10-translation-services" target="_blank"><img src="https://nestjs.com/img/pickwriters-logo.png" width="40" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://thewordpoint.com/services/localization" target="_blank"><img src="https://nestjs.com/img/thewordpoint-logo.png" width="40" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://streamat.se/" target="_blank"><img src="https://nestjs.com/img/streamat-logo.png" width="120" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://filmen.nu/" target="_blank"><img src="https://nestjs.com/img/filmen-logo.png" width="120" valign="middle" /></a></td></tr><tr>
|
||||
<td align="center" valign="middle"><a href="https://meercode.io/" target="_blank"><img src="https://nestjs.com/img/meercode-logo.png" width="60" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://www.najlepszeplatformyforex.pl/blog/broker-xtb/" target="_blank"><img src="https://nestjs.com/img/npf-logo.jpg" width="200" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://thestandarddaily.com/" target="_blank"><img src="https://nestjs.com/img/the-standard-daily-logo.png" width="180" valign="middle" /></a></td>
|
||||
</tr></table>
|
||||
|
||||
## Backers
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nestjs/testing",
|
||||
"version": "7.6.5",
|
||||
"version": "7.6.13",
|
||||
"description": "Nest - modern, fast, powerful node.js web framework (@testing)",
|
||||
"author": "Kamil Mysliwiec",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Logger, Module } from '@nestjs/common';
|
||||
import { Logger, LoggerService, Module } from '@nestjs/common';
|
||||
import { ModuleMetadata } from '@nestjs/common/interfaces';
|
||||
import { ApplicationConfig } from '@nestjs/core/application-config';
|
||||
import { NestContainer } from '@nestjs/core/injector/container';
|
||||
@@ -16,6 +16,7 @@ export class TestingModuleBuilder {
|
||||
private readonly scanner: DependenciesScanner;
|
||||
private readonly instanceLoader = new InstanceLoader(this.container);
|
||||
private readonly module: any;
|
||||
private testingLogger: LoggerService;
|
||||
|
||||
constructor(metadataScanner: MetadataScanner, metadata: ModuleMetadata) {
|
||||
this.scanner = new DependenciesScanner(
|
||||
@@ -26,6 +27,11 @@ export class TestingModuleBuilder {
|
||||
this.module = this.createModule(metadata);
|
||||
}
|
||||
|
||||
public setLogger(testingLogger: LoggerService) {
|
||||
this.testingLogger = testingLogger;
|
||||
return this;
|
||||
}
|
||||
|
||||
public overridePipe<T = any>(typeOrToken: T): OverrideBy {
|
||||
return this.override(typeOrToken, false);
|
||||
}
|
||||
@@ -98,6 +104,6 @@ export class TestingModuleBuilder {
|
||||
}
|
||||
|
||||
private applyLogger() {
|
||||
Logger.overrideLogger(new TestingLogger());
|
||||
Logger.overrideLogger(this.testingLogger || new TestingLogger());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,16 +56,21 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
||||
|
||||
#### Principal Sponsors
|
||||
<table style="text-align:center;"><tr><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><td>
|
||||
<a href="https://valor-software.com/" target="_blank"><img src="https://docs.nestjs.com/assets/sponsors/valor-software.png" width="180" valign="middle" /></a></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>
|
||||
<td>
|
||||
<a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="200" valign="middle" /></a></td>
|
||||
</tr></table>
|
||||
|
||||
#### Gold Sponsors
|
||||
|
||||
<table style="text-align:center;"><tr><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></tr></table>
|
||||
|
||||
#### Silver Sponsors
|
||||
|
||||
<table style="text-align:center;"><tr><td>
|
||||
<a href="https://neoteric.eu/" target="_blank"><img src="https://nestjs.com/img/neoteric-cut.png" width="120" valign="middle" /></a> </td><td>
|
||||
<a href="http://gojob.com" target="_blank"><img src="http://nestjs.com/img/gojob-logo.png" valign="middle" width="100" /></a> </td><td>
|
||||
<a href="https://trilon.io" target="_blank"><img src="https://nestjs.com/img/trilon.svg" width="170" valign="middle" /></a> </td><td>
|
||||
<a href="http://www.leogistics.com" target="_blank"><img src="https://nestjs.com/img/leogistics-logo.jpeg" width="150" valign="middle" /></td><td>
|
||||
<a href="http://www.meetdandy.com" target="_blank"><img src="https://nestjs.com/img/dandy-wide-logo.png" width="150" valign="middle" /></td></tr></table>
|
||||
|
||||
@@ -90,6 +95,11 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://genuinebee.com/" target="_blank"><img src="https://nestjs.com/img/genuinebee.svg" width="97" valign="middle" /></a> </td>
|
||||
<td align="center" valign="middle"><a href="https://sanyodigital.com/" target="_blank"><img src="https://nestjs.com/img/sanyo-digital.png" width="130" valign="middle" /></a></td></tr><tr><td align="center" valign="middle"><a href="https://vpn-review.com/vpn-for-torrenting" target="_blank"><img src="https://nestjs.com/img/vpn-review-logo.png" width="85" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://lambda-it.ch/" target="_blank"><img src="https://nestjs.com/img/lambda-it-logo.svg" width="115" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://pickwriters.com/top-10-translation-services" target="_blank"><img src="https://nestjs.com/img/pickwriters-logo.png" width="40" valign="middle" /></a></td><td align="center" valign="middle"><a href="https://thewordpoint.com/services/localization" target="_blank"><img src="https://nestjs.com/img/thewordpoint-logo.png" width="40" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://streamat.se/" target="_blank"><img src="https://nestjs.com/img/streamat-logo.png" width="120" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://filmen.nu/" target="_blank"><img src="https://nestjs.com/img/filmen-logo.png" width="120" valign="middle" /></a></td></tr><tr>
|
||||
<td align="center" valign="middle"><a href="https://meercode.io/" target="_blank"><img src="https://nestjs.com/img/meercode-logo.png" width="60" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://www.najlepszeplatformyforex.pl/blog/broker-xtb/" target="_blank"><img src="https://nestjs.com/img/npf-logo.jpg" width="200" valign="middle" /></a></td>
|
||||
<td align="center" valign="middle"><a href="https://thestandarddaily.com/" target="_blank"><img src="https://nestjs.com/img/the-standard-daily-logo.png" width="180" valign="middle" /></a></td>
|
||||
</tr></table>
|
||||
|
||||
## Backers
|
||||
|
||||
@@ -39,9 +39,7 @@ export interface WsHandlerMetadata {
|
||||
export class WsContextCreator {
|
||||
private readonly contextUtils = new ContextUtils();
|
||||
private readonly wsParamsFactory = new WsParamsFactory();
|
||||
private readonly handlerMetadataStorage = new HandlerMetadataStorage<
|
||||
WsHandlerMetadata
|
||||
>();
|
||||
private readonly handlerMetadataStorage = new HandlerMetadataStorage<WsHandlerMetadata>();
|
||||
|
||||
constructor(
|
||||
private readonly wsProxy: WsProxy,
|
||||
|
||||
@@ -31,7 +31,7 @@ export interface GatewayMetadata {
|
||||
* Accepted origins
|
||||
* @default '*:*'
|
||||
*/
|
||||
origins?: string;
|
||||
origins?: string | string[];
|
||||
|
||||
parser?: any;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nestjs/websockets",
|
||||
"version": "7.6.5",
|
||||
"version": "7.6.13",
|
||||
"description": "Nest - modern, fast, powerful node.js web framework (@websockets)",
|
||||
"author": "Kamil Mysliwiec",
|
||||
"license": "MIT",
|
||||
@@ -16,8 +16,8 @@
|
||||
"tslib": "2.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nestjs/common": "7.6.5",
|
||||
"@nestjs/core": "7.6.5"
|
||||
"@nestjs/common": "7.6.13",
|
||||
"@nestjs/core": "7.6.13"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@nestjs/common": "^7.0.0",
|
||||
|
||||
@@ -46,20 +46,20 @@ export class SocketModule<HttpServer = any> {
|
||||
);
|
||||
const modules = container.getModules();
|
||||
modules.forEach(({ providers }, moduleName: string) =>
|
||||
this.combineAllGateways(providers, moduleName),
|
||||
this.connectAllGateways(providers, moduleName),
|
||||
);
|
||||
}
|
||||
|
||||
public combineAllGateways(
|
||||
public connectAllGateways(
|
||||
providers: Map<string, InstanceWrapper<Injectable>>,
|
||||
moduleName: string,
|
||||
) {
|
||||
iterate(providers.values())
|
||||
.filter(wrapper => wrapper && !wrapper.isNotMetatype)
|
||||
.forEach(wrapper => this.combineGatewayAndServer(wrapper, moduleName));
|
||||
.forEach(wrapper => this.connectGatewayToServer(wrapper, moduleName));
|
||||
}
|
||||
|
||||
public combineGatewayAndServer(
|
||||
public connectGatewayToServer(
|
||||
wrapper: InstanceWrapper<Injectable>,
|
||||
moduleName: string,
|
||||
) {
|
||||
@@ -71,7 +71,7 @@ export class SocketModule<HttpServer = any> {
|
||||
if (!this.isAdapterInitialized) {
|
||||
this.initializeAdapter();
|
||||
}
|
||||
this.webSocketsController.mergeGatewayAndServer(
|
||||
this.webSocketsController.connectGatewayToServer(
|
||||
instance as NestGateway,
|
||||
metatype,
|
||||
moduleName,
|
||||
|
||||
@@ -50,7 +50,7 @@ describe('WebSocketsController', () => {
|
||||
contextCreator as any,
|
||||
);
|
||||
});
|
||||
describe('mergeGatewayAndServer', () => {
|
||||
describe('connectGatewayToServer', () => {
|
||||
let subscribeToServerEvents: sinon.SinonSpy;
|
||||
|
||||
@WebSocketGateway('test' as any)
|
||||
@@ -66,7 +66,7 @@ describe('WebSocketsController', () => {
|
||||
it('should throws "InvalidSocketPortException" when port is not a number', () => {
|
||||
Reflect.defineMetadata(PORT_METADATA, 'test', InvalidGateway);
|
||||
expect(() =>
|
||||
instance.mergeGatewayAndServer(
|
||||
instance.connectGatewayToServer(
|
||||
new InvalidGateway(),
|
||||
InvalidGateway,
|
||||
'',
|
||||
@@ -75,12 +75,12 @@ describe('WebSocketsController', () => {
|
||||
});
|
||||
it('should call "subscribeToServerEvents" with default values when metadata is empty', () => {
|
||||
const gateway = new DefaultGateway();
|
||||
instance.mergeGatewayAndServer(gateway, DefaultGateway, '');
|
||||
instance.connectGatewayToServer(gateway, DefaultGateway, '');
|
||||
expect(subscribeToServerEvents.calledWith(gateway, {}, 0, '')).to.be.true;
|
||||
});
|
||||
it('should call "subscribeToServerEvents" when metadata is valid', () => {
|
||||
const gateway = new Test();
|
||||
instance.mergeGatewayAndServer(gateway, Test, '');
|
||||
instance.connectGatewayToServer(gateway, Test, '');
|
||||
expect(
|
||||
subscribeToServerEvents.calledWith(gateway, { namespace }, port, ''),
|
||||
).to.be.true;
|
||||
@@ -370,4 +370,4 @@ describe('WebSocketsController', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -28,7 +28,7 @@ export class WebSocketsController {
|
||||
private readonly contextCreator: WsContextCreator,
|
||||
) {}
|
||||
|
||||
public mergeGatewayAndServer(
|
||||
public connectGatewayToServer(
|
||||
instance: NestGateway,
|
||||
metatype: Type<unknown> | Function,
|
||||
moduleKey: string,
|
||||
|
||||
70
readme_jp.md
Normal file
70
readme_jp.md
Normal file
@@ -0,0 +1,70 @@
|
||||
<p align="center">
|
||||
<a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo-small.svg" width="120" alt="Nest Logo" /></a>
|
||||
</p>
|
||||
|
||||
[circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456
|
||||
[circleci-url]: https://circleci.com/gh/nestjs/nest
|
||||
|
||||
<p align="center">すばやくスケーラブルなサーバーサイドアプリケーションを構築するための革新的な<a href="http://nodejs.org" target="_blank">Node.js</a>フレームワークです。</p>
|
||||
<p align="center">
|
||||
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a>
|
||||
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/l/@nestjs/core.svg" alt="Package License" /></a>
|
||||
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/dm/@nestjs/common.svg" alt="NPM Downloads" /></a>
|
||||
<a href="https://circleci.com/gh/nestjs/nest" target="_blank"><img src="https://img.shields.io/circleci/build/github/nestjs/nest/master" alt="CircleCI" /></a>
|
||||
<a href="https://coveralls.io/github/nestjs/nest?branch=master" target="_blank"><img src="https://coveralls.io/repos/github/nestjs/nest/badge.svg?branch=master#9" alt="Coverage" /></a>
|
||||
<a href="https://discord.gg/G7Qnnhy" target="_blank"><img src="https://img.shields.io/badge/discord-online-brightgreen.svg" alt="Discord"/></a>
|
||||
<a href="https://opencollective.com/nest#backer" target="_blank"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a>
|
||||
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a>
|
||||
<a href="https://paypal.me/kamilmysliwiec" target="_blank"><img src="https://img.shields.io/badge/Donate-PayPal-ff3f59.svg"/></a>
|
||||
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://img.shields.io/badge/Support%20us-Open%20Collective-41B883.svg" alt="Support us"></a>
|
||||
<a href="https://twitter.com/nestframework" target="_blank"><img src="https://img.shields.io/twitter/follow/nestframework.svg?style=social&label=Follow"></a>
|
||||
</p>
|
||||
<!--[](https://opencollective.com/nest#backer)
|
||||
[](https://opencollective.com/nest#sponsor)-->
|
||||
|
||||
## Description
|
||||
|
||||
すばやくスケーラブルなサーバーサイドアプリケーションを構築するための革新的な<a href="http://nodejs.org" target="_blank">Node.js</a>フレームワークです。最新のJavaScriptを使用し、<a href="http://www.typescriptlang.org" target="_blank">TypeScript</a>(JavaScriptを拡張したスーパーセット)で構築され 、OOP(オブジェクト指向プログラミング)、FP(関数型プログラミング)、およびFRP(関数型リアクティブプログラミング)の要素を取り入れています。
|
||||
|
||||
<p>Nestは<a href="https://expressjs.com/" target="_blank">Express</a>(デフォルト)や<a href="https://github.com/fastify/fastify" target="_blank">Fastify</a>などのさまざまなライブラリとの互換性を提供することで、たくさんのサードパーティプラグインを簡単に使用することができます。
|
||||
</p>
|
||||
|
||||
## Philosophy
|
||||
|
||||
<p>
|
||||
近年、Node.jsの発展によって、JavaScriptはフロントエンドとバックエンドの両方でWebの「共通言語」になりました。そしてフロントエンドでは、<a href="https://angular.io/" target="_blank">Angular</a>、<a href="https://github.com/facebook/react" target="_blank">React</a>、<a href="https://github.com/vuejs/vue" target="_blank">Vue</a>などの素晴らしいプロジェクトが生まれ、開発効率が飛躍的に向上しました。一方で、サーバーサイドでは、Node.jsエコシステム上に優れたライブラリ、ヘルパー、ツールがたくさんありますが、それらのどれもが主要な問題であるアーキテクチャを効果的に解決するものではありませんでした。
|
||||
</p>
|
||||
|
||||
<p>Nestは、実用的なアーキテクチャをすぐに構築できることを目的としています。具体的には、テストフレンドリーで、スケーラブルで、疎結合で、運用にやさしいアプリケーションを構築できるようになっています。また、アーキテクチャはAngularにインスパイアされています。</p>
|
||||
|
||||
## Getting started
|
||||
|
||||
* To check out the [guide](https://docs.nestjs.com), visit [docs.nestjs.com](https://docs.nestjs.com). :books:
|
||||
* 要查看中文 [指南](readme_zh.md), 请访问 [docs.nestjs.cn](https://docs.nestjs.cn). :books:
|
||||
* 日本語ガイドは現在準備中です。 :books:
|
||||
|
||||
## Questions
|
||||
|
||||
質問やサポートについては、公式の[Discordチャンネル](https://discord.gg/G7Qnnhy)を使用してください。また、このリポジトリのissueリストは、バグレポートと機能リクエスト **専用** です。
|
||||
|
||||
## Issues
|
||||
|
||||
issueを開く前に、必ず[Issue Reporting Checklist](https://github.com/nestjs/nest/blob/master/CONTRIBUTING.md#-submitting-an-issue)をお読みください。ガイドラインに準拠していないissueは、クローズされる場合があります。
|
||||
|
||||
## Consulting
|
||||
|
||||
公式サポートを利用することで、Nestコアチームからのテクニカルサポート、移行戦略、ベストプラクティスの提供、アーキテクチャの相談、PRレビュー、メンタリングを受けることができます。詳しくは[こちら](https://enterprise.nestjs.com)をご覧ください。
|
||||
|
||||
## Support
|
||||
|
||||
Nestは、MITライセンスのオープンソースプロジェクトです。スポンサーと支援者による素晴らしいサポートによって、その発展を支えられています。参加したい場合は[こちら](https://docs.nestjs.com/support)をご覧ください。
|
||||
|
||||
## Stay in touch
|
||||
|
||||
* Author - [Kamil Myśliwiec](https://twitter.com/kammysliwiec)
|
||||
* Website - [https://nestjs.com](https://nestjs.com/)
|
||||
* Twitter - [@nestframework](https://twitter.com/nestframework)
|
||||
|
||||
## License
|
||||
|
||||
Nest is [MIT licensed](LICENSE).
|
||||
@@ -1,5 +1,12 @@
|
||||
{
|
||||
"extends": [
|
||||
"config:base"
|
||||
],
|
||||
"labels": ["dependencies"],
|
||||
"packageRules": [
|
||||
{
|
||||
"matchDepTypes": ["devDependencies"],
|
||||
"automerge": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
11834
sample/01-cats-app/package-lock.json
generated
11834
sample/01-cats-app/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -19,36 +19,36 @@
|
||||
"test:e2e": "jest --config ./e2e/jest-e2e.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nestjs/common": "7.6.5",
|
||||
"@nestjs/core": "7.6.5",
|
||||
"@nestjs/platform-express": "7.6.5",
|
||||
"class-transformer": "0.3.1",
|
||||
"class-validator": "0.12.2",
|
||||
"@nestjs/common": "7.6.12",
|
||||
"@nestjs/core": "7.6.12",
|
||||
"@nestjs/platform-express": "7.6.12",
|
||||
"class-transformer": "0.4.0",
|
||||
"class-validator": "0.13.1",
|
||||
"reflect-metadata": "0.1.13",
|
||||
"rimraf": "3.0.2",
|
||||
"rxjs": "6.6.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nestjs/cli": "7.5.4",
|
||||
"@nestjs/schematics": "7.2.6",
|
||||
"@nestjs/testing": "7.6.5",
|
||||
"@nestjs/cli": "7.5.5",
|
||||
"@nestjs/schematics": "7.2.7",
|
||||
"@nestjs/testing": "7.6.12",
|
||||
"@types/express": "4.17.11",
|
||||
"@types/jest": "26.0.20",
|
||||
"@types/node": "14.14.20",
|
||||
"@types/node": "14.14.31",
|
||||
"@types/supertest": "2.0.10",
|
||||
"jest": "26.6.3",
|
||||
"prettier": "2.2.1",
|
||||
"supertest": "6.0.1",
|
||||
"ts-jest": "26.4.4",
|
||||
"ts-loader": "8.0.14",
|
||||
"supertest": "6.1.3",
|
||||
"ts-jest": "26.5.1",
|
||||
"ts-loader": "8.0.17",
|
||||
"ts-node": "9.1.1",
|
||||
"tsconfig-paths": "3.9.0",
|
||||
"@typescript-eslint/eslint-plugin": "4.13.0",
|
||||
"@typescript-eslint/parser": "4.13.0",
|
||||
"eslint": "7.17.0",
|
||||
"eslint-config-prettier": "7.1.0",
|
||||
"@typescript-eslint/eslint-plugin": "4.15.1",
|
||||
"@typescript-eslint/parser": "4.15.1",
|
||||
"eslint": "7.20.0",
|
||||
"eslint-config-prettier": "7.2.0",
|
||||
"eslint-plugin-import": "2.22.1",
|
||||
"typescript": "4.1.3"
|
||||
"typescript": "4.1.5"
|
||||
},
|
||||
"jest": {
|
||||
"moduleFileExtensions": [
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export interface Cat {
|
||||
readonly name: string;
|
||||
readonly age: number;
|
||||
readonly breed: string;
|
||||
name: string;
|
||||
age: number;
|
||||
breed: string;
|
||||
}
|
||||
|
||||
12530
sample/02-gateways/package-lock.json
generated
12530
sample/02-gateways/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -19,40 +19,40 @@
|
||||
"test:e2e": "echo 'No e2e tests implemented yet.'"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nestjs/common": "7.6.5",
|
||||
"@nestjs/core": "7.6.5",
|
||||
"@nestjs/platform-express": "7.6.5",
|
||||
"@nestjs/platform-socket.io": "7.6.5",
|
||||
"@nestjs/websockets": "7.6.5",
|
||||
"class-transformer": "0.3.1",
|
||||
"class-validator": "0.12.2",
|
||||
"@nestjs/common": "7.6.12",
|
||||
"@nestjs/core": "7.6.12",
|
||||
"@nestjs/platform-express": "7.6.12",
|
||||
"@nestjs/platform-socket.io": "7.6.12",
|
||||
"@nestjs/websockets": "7.6.12",
|
||||
"class-transformer": "0.4.0",
|
||||
"class-validator": "0.13.1",
|
||||
"reflect-metadata": "0.1.13",
|
||||
"rimraf": "3.0.2",
|
||||
"rxjs": "6.6.3",
|
||||
"socket.io-redis": "5.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/socket.io": "2.1.12",
|
||||
"@types/socket.io-redis": "1.0.26",
|
||||
"@types/socket.io": "2.1.13",
|
||||
"@types/socket.io-redis": "1.0.27",
|
||||
"@types/ws": "7.4.0",
|
||||
"@nestjs/cli": "7.5.4",
|
||||
"@nestjs/schematics": "7.2.6",
|
||||
"@nestjs/testing": "7.6.5",
|
||||
"@nestjs/cli": "7.5.5",
|
||||
"@nestjs/schematics": "7.2.7",
|
||||
"@nestjs/testing": "7.6.12",
|
||||
"@types/express": "4.17.11",
|
||||
"@types/node": "14.14.20",
|
||||
"@types/node": "14.14.31",
|
||||
"@types/supertest": "2.0.10",
|
||||
"jest": "26.6.3",
|
||||
"prettier": "2.2.1",
|
||||
"supertest": "6.0.1",
|
||||
"ts-jest": "26.4.4",
|
||||
"ts-loader": "8.0.14",
|
||||
"supertest": "6.1.3",
|
||||
"ts-jest": "26.5.1",
|
||||
"ts-loader": "8.0.17",
|
||||
"ts-node": "9.1.1",
|
||||
"tsconfig-paths": "3.9.0",
|
||||
"@typescript-eslint/eslint-plugin": "4.13.0",
|
||||
"@typescript-eslint/parser": "4.13.0",
|
||||
"eslint": "7.17.0",
|
||||
"eslint-config-prettier": "7.1.0",
|
||||
"@typescript-eslint/eslint-plugin": "4.15.1",
|
||||
"@typescript-eslint/parser": "4.15.1",
|
||||
"eslint": "7.20.0",
|
||||
"eslint-config-prettier": "7.2.0",
|
||||
"eslint-plugin-import": "2.22.1",
|
||||
"typescript": "4.1.3"
|
||||
"typescript": "4.1.5"
|
||||
}
|
||||
}
|
||||
|
||||
11873
sample/03-microservices/package-lock.json
generated
11873
sample/03-microservices/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -19,36 +19,36 @@
|
||||
"test:e2e": "echo 'No e2e tests implemented yet.'"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nestjs/common": "7.6.5",
|
||||
"@nestjs/core": "7.6.5",
|
||||
"@nestjs/microservices": "7.6.5",
|
||||
"@nestjs/platform-express": "7.6.5",
|
||||
"class-transformer": "0.3.1",
|
||||
"class-validator": "0.12.2",
|
||||
"@nestjs/common": "7.6.12",
|
||||
"@nestjs/core": "7.6.12",
|
||||
"@nestjs/microservices": "7.6.12",
|
||||
"@nestjs/platform-express": "7.6.12",
|
||||
"class-transformer": "0.4.0",
|
||||
"class-validator": "0.13.1",
|
||||
"reflect-metadata": "0.1.13",
|
||||
"rimraf": "3.0.2",
|
||||
"rxjs": "6.6.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nestjs/cli": "7.5.4",
|
||||
"@nestjs/schematics": "7.2.6",
|
||||
"@nestjs/testing": "7.6.5",
|
||||
"@nestjs/cli": "7.5.5",
|
||||
"@nestjs/schematics": "7.2.7",
|
||||
"@nestjs/testing": "7.6.12",
|
||||
"@types/amqplib": "0.5.17",
|
||||
"@types/express": "4.17.11",
|
||||
"@types/node": "14.14.20",
|
||||
"@types/node": "14.14.31",
|
||||
"@types/supertest": "2.0.10",
|
||||
"jest": "26.6.3",
|
||||
"prettier": "2.2.1",
|
||||
"supertest": "6.0.1",
|
||||
"ts-jest": "26.4.4",
|
||||
"ts-loader": "8.0.14",
|
||||
"supertest": "6.1.3",
|
||||
"ts-jest": "26.5.1",
|
||||
"ts-loader": "8.0.17",
|
||||
"ts-node": "9.1.1",
|
||||
"tsconfig-paths": "3.9.0",
|
||||
"@typescript-eslint/eslint-plugin": "4.13.0",
|
||||
"@typescript-eslint/parser": "4.13.0",
|
||||
"eslint": "7.17.0",
|
||||
"eslint-config-prettier": "7.1.0",
|
||||
"@typescript-eslint/eslint-plugin": "4.15.1",
|
||||
"@typescript-eslint/parser": "4.15.1",
|
||||
"eslint": "7.20.0",
|
||||
"eslint-config-prettier": "7.2.0",
|
||||
"eslint-plugin-import": "2.22.1",
|
||||
"typescript": "4.1.3"
|
||||
"typescript": "4.1.5"
|
||||
}
|
||||
}
|
||||
|
||||
12205
sample/04-grpc/package-lock.json
generated
12205
sample/04-grpc/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -19,37 +19,37 @@
|
||||
"test:e2e": "echo 'No e2e tests implemented yet.'"
|
||||
},
|
||||
"dependencies": {
|
||||
"@grpc/proto-loader": "0.5.5",
|
||||
"@nestjs/common": "7.6.5",
|
||||
"@nestjs/core": "7.6.5",
|
||||
"@nestjs/microservices": "7.6.5",
|
||||
"class-transformer": "0.3.1",
|
||||
"class-validator": "0.12.2",
|
||||
"grpc": "1.24.4",
|
||||
"@grpc/proto-loader": "0.5.6",
|
||||
"@nestjs/common": "7.6.12",
|
||||
"@nestjs/core": "7.6.12",
|
||||
"@nestjs/microservices": "7.6.12",
|
||||
"class-transformer": "0.4.0",
|
||||
"class-validator": "0.13.1",
|
||||
"grpc": "1.24.5",
|
||||
"reflect-metadata": "0.1.13",
|
||||
"rimraf": "3.0.2",
|
||||
"rxjs": "6.6.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nestjs/cli": "7.5.4",
|
||||
"@nestjs/schematics": "7.2.6",
|
||||
"@nestjs/testing": "7.6.5",
|
||||
"@nestjs/cli": "7.5.5",
|
||||
"@nestjs/schematics": "7.2.7",
|
||||
"@nestjs/testing": "7.6.12",
|
||||
"@types/express": "4.17.11",
|
||||
"@types/node": "14.14.20",
|
||||
"@types/node": "14.14.31",
|
||||
"@types/supertest": "2.0.10",
|
||||
"@types/ws": "7.4.0",
|
||||
"jest": "26.6.3",
|
||||
"prettier": "2.2.1",
|
||||
"supertest": "6.0.1",
|
||||
"ts-jest": "26.4.4",
|
||||
"ts-loader": "8.0.14",
|
||||
"supertest": "6.1.3",
|
||||
"ts-jest": "26.5.1",
|
||||
"ts-loader": "8.0.17",
|
||||
"ts-node": "9.1.1",
|
||||
"tsconfig-paths": "3.9.0",
|
||||
"@typescript-eslint/eslint-plugin": "4.13.0",
|
||||
"@typescript-eslint/parser": "4.13.0",
|
||||
"eslint": "7.17.0",
|
||||
"eslint-config-prettier": "7.1.0",
|
||||
"@typescript-eslint/eslint-plugin": "4.15.1",
|
||||
"@typescript-eslint/parser": "4.15.1",
|
||||
"eslint": "7.20.0",
|
||||
"eslint-config-prettier": "7.2.0",
|
||||
"eslint-plugin-import": "2.22.1",
|
||||
"typescript": "4.1.3"
|
||||
"typescript": "4.1.5"
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user