Skip to content

Commit c1dd4ef

Browse files
authored
Merge branch 'master' into chore/joi-references
2 parents 1314520 + 9a9ea49 commit c1dd4ef

File tree

97 files changed

+5060
-2962
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+5060
-2962
lines changed

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ What kind of change does this PR introduce?
1414
[ ] Code style update (formatting, local variables)
1515
[ ] Refactoring (no functional changes, no api changes)
1616
[ ] Build related changes
17+
[ ] Docs
1718
[ ] Other... Please describe:
1819
```
1920

@@ -35,4 +36,4 @@ Issue Number: N/A
3536
<!-- If this PR contains a breaking change, please describe the impact and migration path for existing applications below. -->
3637

3738

38-
## Other information
39+
## Other information

.github/workflows/lighthouse.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
runs-on: ubuntu-latest
1111

1212
steps:
13-
- uses: actions/checkout@v1
13+
- uses: actions/checkout@v2
1414
- name: Use Node.js 12.x
1515
uses: actions/setup-node@v1
1616
with:
@@ -28,7 +28,7 @@ jobs:
2828
site_name: 'docs-nestjs'
2929
max_timeout: 600
3030
- name: Run Lighthouse on urls and validate with lighthouserc
31-
uses: treosh/lighthouse-ci-action@v2
31+
uses: treosh/lighthouse-ci-action@v3
3232
with:
3333
urls: |
3434
${{ steps.wait-for-netflify-preview.outputs.url }}

.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
12.18.3
1+
12.19.1

CONTRIBUTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,10 +169,10 @@ Footer should contain a [closing reference to an issue](https://help.github.com/
169169
Samples: (even more [samples](https://github.com/nestjs/nest/commits/master))
170170
171171
```
172-
docs(changelog) update change log to beta.5
172+
docs(changelog): update change log to beta.5
173173
```
174174
```
175-
bugfix(@nestjs/core) need to depend on latest rxjs and zone.js
175+
bugfix(@nestjs/core): need to depend on latest rxjs and zone.js
176176
177177
The version in our package.json gets copied to the one we publish, and users need the latest of these.
178178
```

content/cli/usages.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,9 @@ $ nest g <schematic> <name> [options]
6969
| `module` | `mo` | Generate a module declaration. |
7070
| `pipe` | `pi` | Generate a pipe declaration. |
7171
| `provider` | `pr` | Generate a provider declaration. |
72-
| `resolver` | `r` | Generate a resolver declaration. |
73-
| `service` | `s` | Generate a service declaration. |
72+
| `resolver` | `r` | Generate a resolver declaration.
73+
| `resource` | `res` | Generate a new CRUD resource. See the [CRUD (resource) generator](/recipes/crud-generator) for more details. |
74+
| `service` | `s` | Generate a service declaration. |
7475

7576
##### Options
7677

content/controllers.md

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,18 +58,18 @@ This method will return a 200 status code and the associated response, which in
5858
<tr>
5959
<td>Library-specific</td>
6060
<td>
61-
We can use the library-specific (e.g., Express) <a href="http://expressjs.com/en/api.html#res" rel="nofollow" target="_blank">response object</a>, which can be injected using the <code>@Res()</code> decorator in the method handler signature (e.g., <code>findAll(@Res() response)</code>). With this approach, you have the ability (and the responsibility), to use the native response handling methods exposed by that object. For example, with Express, you can construct responses using code like <code>response.status(200).send()</code>
61+
We can use the library-specific (e.g., Express) <a href="https://expressjs.com/en/api.html#res" rel="nofollow" target="_blank">response object</a>, which can be injected using the <code>@Res()</code> decorator in the method handler signature (e.g., <code>findAll(@Res() response)</code>). With this approach, you have the ability to use the native response handling methods exposed by that object. For example, with Express, you can construct responses using code like <code>response.status(200).send()</code>.
6262
</td>
6363
</tr>
6464
</table>
6565

66-
> warning **Warning** You cannot use both approaches at the same time. Nest detects when the handler is using either `@Res()` or `@Next()`, indicating you have chosen the library-specific option. If both approaches are used at the same time, the Standard approach is **automatically disabled** for this single route and will no longer work as expected.
66+
> warning **Warning** Nest detects when the handler is using either `@Res()` or `@Next()`, indicating you have chosen the library-specific option. If both approaches are used at the same time, the Standard approach is **automatically disabled** for this single route and will no longer work as expected. To use both approaches at the same time (for example, by injecting the response object to only set cookies/headers but still leave the rest to the framework), you must set the `passthrough` option to `true` in the `@Res({{ '{' }} passthrough: true {{ '}' }})` decorator.
6767
6868
<app-banner-enterprise></app-banner-enterprise>
6969

7070
#### Request object
7171

72-
Handlers often need access to the client **request** details. Nest provides access to the [request object](http://expressjs.com/en/api.html#req) of the underlying platform (Express by default). We can access the request object by instructing Nest to inject it by adding the `@Req()` decorator to the handler's signature.
72+
Handlers often need access to the client **request** details. Nest provides access to the [request object](https://expressjs.com/en/api.html#req) of the underlying platform (Express by default). We can access the request object by instructing Nest to inject it by adding the `@Req()` decorator to the handler's signature.
7373

7474
```typescript
7575
@@filename(cats.controller)
@@ -98,12 +98,12 @@ export class CatsController {
9898

9999
> info **Hint** In order to take advantage of `express` typings (as in the `request: Request` parameter example above), install `@types/express` package.
100100
101-
The request object represents the HTTP request and has properties for the request query string, parameters, HTTP headers, and body (read more [here](http://expressjs.com/en/api.html#req)). In most cases, it's not necessary to grab these properties manually. We can use dedicated decorators instead, such as `@Body()` or `@Query()`, which are available out of the box. Below is a list of the provided decorators and the plain platform-specific objects they represent.
101+
The request object represents the HTTP request and has properties for the request query string, parameters, HTTP headers, and body (read more [here](https://expressjs.com/en/api.html#req)). In most cases, it's not necessary to grab these properties manually. We can use dedicated decorators instead, such as `@Body()` or `@Query()`, which are available out of the box. Below is a list of the provided decorators and the plain platform-specific objects they represent.
102102

103103
<table>
104104
<tbody>
105105
<tr>
106-
<td><code>@Request()</code></td>
106+
<td><code>@Request(), @Req()</code></td>
107107
<td><code>req</code></td></tr>
108108
<tr>
109109
<td><code>@Response(), @Res()</code><span class="table-code-asterisk">*</span></td>
@@ -137,6 +137,10 @@ The request object represents the HTTP request and has properties for the reques
137137
<td><code>@Ip()</code></td>
138138
<td><code>req.ip</code></td>
139139
</tr>
140+
<tr>
141+
<td><code>@HostParam()</code></td>
142+
<td><code>req.hosts</code></td>
143+
</tr>
140144
</tbody>
141145
</table>
142146

@@ -181,7 +185,7 @@ export class CatsController {
181185
}
182186
```
183187

184-
It's that simple. Nest provides the rest of the standard HTTP request endpoint decorators in the same fashion - `@Put()`, `@Delete()`, `@Patch()`, `@Options()`, `@Head()`, and `@All()`. Each represents its respective HTTP request method.
188+
It's that simple. Nest provides decorators for all of the standard HTTP methods: `@Get()`, `@Post()`, `@Put()`, `@Delete()`, `@Patch()`, `@Options()`, and `@Head()`. In addition, `@All()` defines an endpoint that handles all of them.
185189

186190
#### Route wildcards
187191

@@ -285,7 +289,7 @@ findOne(params) {
285289
```typescript
286290
@@filename()
287291
@Get(':id')
288-
findOne(@Param('id') id): string {
292+
findOne(@Param('id') id: string): string {
289293
return `This action returns a #${id} cat`;
290294
}
291295
@@switch
@@ -479,6 +483,8 @@ export class CatsController {
479483
}
480484
```
481485

486+
> info **Hint** Nest CLI provides a generator (schematic) that automatically generates **all the boilerplate code** to help us avoid doing all of this, and make the developer experience much simpler. Read more about this feature [here](/recipes/crud-generator).
487+
482488
#### Getting up and running
483489

484490
With the above controller fully defined, Nest still doesn't know that `CatsController` exists and as a result won't create an instance of this class.
@@ -500,9 +506,9 @@ We attached the metadata to the module class using the `@Module()` decorator, an
500506

501507
<app-banner-shop></app-banner-shop>
502508

503-
#### Appendix: Library-specific approach
509+
#### Library-specific approach
504510

505-
So far we've discussed the Nest standard way of manipulating responses. The second way of manipulating the response is to use a library-specific [response object](http://expressjs.com/en/api.html#res). In order to inject a particular response object, we need to use the `@Res()` decorator. To show the differences, let's rewrite the `CatsController` to the following:
511+
So far we've discussed the Nest standard way of manipulating responses. The second way of manipulating the response is to use a library-specific [response object](https://expressjs.com/en/api.html#res). In order to inject a particular response object, we need to use the `@Res()` decorator. To show the differences, let's rewrite the `CatsController` to the following:
506512

507513
```typescript
508514
@@filename()
@@ -540,6 +546,24 @@ export class CatsController {
540546
}
541547
```
542548
543-
Though this approach works, and does in fact allow for more flexibility in some ways by providing full control of the response object (headers manipulation, library-specific features, and so on), it should be used with care. In general, the approach is much less clear and does have some disadvantages. The main disadvantages are that you lose compatibility with Nest features that depend on Nest standard response handling, such as Interceptors and the `@HttpCode()` decorator. Also, your code can become platform-dependent (as underlying libraries may have different APIs on the response object), and harder to test (you'll have to mock the response object, etc.).
549+
Though this approach works, and does in fact allow for more flexibility in some ways by providing full control of the response object (headers manipulation, library-specific features, and so on), it should be used with care. In general, the approach is much less clear and does have some disadvantages. The main disadvantage is that your code become platform-dependent (as underlying libraries may have different APIs on the response object), and harder to test (you'll have to mock the response object, etc.).
550+
551+
Also, in the example above, you lose compatibility with Nest features that depend on Nest standard response handling, such as Interceptors and `@HttpCode()` / `@Header()` decorators. To fix this, you can set the `passthrough` option to `true`, as follows:
552+
553+
```typescript
554+
@@filename()
555+
@Get()
556+
findAll(@Res({ passthrough: true }) res: Response) {
557+
res.status(HttpStatus.OK);
558+
return [];
559+
}
560+
@@switch
561+
@Get()
562+
@Bind(Res({ passthrough: true }))
563+
findAll(res) {
564+
res.status(HttpStatus.OK);
565+
return [];
566+
}
567+
```
544568

545-
As a result, the Nest standard approach should always be preferred when possible.
569+
Now you can interact with the native response object (for example, set cookies or headers depending on certain conditions), but leave the rest to the framework.

content/custom-decorators.md

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ Nest provides a set of useful **param decorators** that you can use together wit
1515
<table>
1616
<tbody>
1717
<tr>
18-
<td><code>@Request()</code></td>
18+
<td><code>@Request(), @Req()</code></td>
1919
<td><code>req</code></td>
2020
</tr>
2121
<tr>
22-
<td><code>@Response()</code></td>
22+
<td><code>@Response(), @Res()</code></td>
2323
<td><code>res</code></td>
2424
</tr>
2525
<tr>
@@ -50,6 +50,10 @@ Nest provides a set of useful **param decorators** that you can use together wit
5050
<td><code>@Ip()</code></td>
5151
<td><code>req.ip</code></td>
5252
</tr>
53+
<tr>
54+
<td><code>@HostParam()</code></td>
55+
<td><code>req.hosts</code></td>
56+
</tr>
5357
</tbody>
5458
</table>
5559

@@ -116,7 +120,7 @@ export const User = createParamDecorator(
116120
const request = ctx.switchToHttp().getRequest();
117121
const user = request.user;
118122

119-
return data ? user && user[data] : user;
123+
return data ? user?.[data] : user;
120124
},
121125
);
122126
@@switch
@@ -157,30 +161,47 @@ Nest treats custom param decorators in the same fashion as the built-in ones (`@
157161
```typescript
158162
@@filename()
159163
@Get()
160-
async findOne(@User(new ValidationPipe()) user: UserEntity) {
164+
async findOne(
165+
@User(new ValidationPipe({ validateCustomDecorators: true }))
166+
user: UserEntity,
167+
) {
161168
console.log(user);
162169
}
163170
@@switch
164171
@Get()
165-
@Bind(User(new ValidationPipe()))
172+
@Bind(User(new ValidationPipe({ validateCustomDecorators: true })))
166173
async findOne(user) {
167174
console.log(user);
168175
}
169176
```
170177

178+
> info **Hint** Note that `validateCustomDecorators` option must be set to true. `ValidationPipe` does not validate arguments annotated with the custom decorators by default.
179+
171180
#### Decorator composition
172181

173182
Nest provides a helper method to compose multiple decorators. For example, suppose you want to combine all decorators related to authentication into a single decorator. This could be done with the following construction:
174183

175184
```typescript
185+
@@filename(auth.decorator)
176186
import { applyDecorators } from '@nestjs/common';
177187

178188
export function Auth(...roles: Role[]) {
179189
return applyDecorators(
180190
SetMetadata('roles', roles),
181191
UseGuards(AuthGuard, RolesGuard),
182192
ApiBearerAuth(),
183-
ApiUnauthorizedResponse({ description: 'Unauthorized"' }),
193+
ApiUnauthorizedResponse({ description: 'Unauthorized' }),
194+
);
195+
}
196+
@@switch
197+
import { applyDecorators } from '@nestjs/common';
198+
199+
export function Auth(...roles) {
200+
return applyDecorators(
201+
SetMetadata('roles', roles),
202+
UseGuards(AuthGuard, RolesGuard),
203+
ApiBearerAuth(),
204+
ApiUnauthorizedResponse({ description: 'Unauthorized' }),
184205
);
185206
}
186207
```

content/discover/who-uses.json

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@
115115
{
116116
"logo": "/assets/logo/dozto.png",
117117
"url": "https://www.dozto.com",
118-
"width": "130px"
118+
"width": "117px"
119119
},
120120
{
121121
"logo": "/assets/logo/qingtui.png",
@@ -171,6 +171,21 @@
171171
"logo": "/assets/logo/ottonova.png",
172172
"url": "https://www.ottonova.de",
173173
"width": "130px"
174+
},
175+
{
176+
"logo": "/assets/logo/radity.png",
177+
"url": "https://radity.com",
178+
"width": "120px"
179+
},
180+
{
181+
"logo": "/assets/logo/global-cto-forum.png",
182+
"url": "https://globalctoforum.org/",
183+
"width": "120px"
184+
},
185+
{
186+
"logo": "/assets/logo/rivvy.png",
187+
"url": "https://rivvy.app",
188+
"width": "120px"
174189
}
175190
],
176191
"Body": [
@@ -218,6 +233,12 @@
218233
"https://accerlery.be",
219234
"https://www.facile.it",
220235
"https://shopback.com",
221-
"https://www.ottonova.de"
236+
"https://www.ottonova.de",
237+
"https://www.radity.com",
238+
"https://globalctoforum.org",
239+
"https://halojasa.com",
240+
"https://hexito.com",
241+
"https://rivvy.app",
242+
"https://padfever.com/"
222243
]
223244
}

content/exception-filters.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ Nest provides a set of standard exceptions that inherit from the base `HttpExcep
126126
- `BadGatewayException`
127127
- `ServiceUnavailableException`
128128
- `GatewayTimeoutException`
129+
- `PreconditionFailedException`
129130

130131
#### Exception filters
131132

content/faq/errors.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
### Common errors
2+
3+
During your development with NestJS, you may encounter various errors as you learn the framework.
4+
5+
#### "Cannot resolve dependency" error
6+
7+
Probably the most common error message is about Nest not being able to resolve dependencies of a provider. The error message usually looks something like this:
8+
9+
```bash
10+
Nest can't resolve dependencies of the <provider> (?). Please make sure that the argument <unknown_token> at index [<index>] is available in the <module> context.
11+
12+
Potential solutions:
13+
- If <unknown_token> is a provider, is it part of the current <module>?
14+
- If <unknown_token> is exported from a separate @Module, is that module imported within <module>?
15+
@Module({
16+
imports: [ /* the Module containing <unknown_token> */ ]
17+
})
18+
```
19+
20+
21+
The most common culprit of the error, is not having the `provider` in the module's `providers` array. Please make sure that the provider is indeed in the `providers` array and following [standard NestJS provider practices](/fundamentals/custom-providers#di-fundamentals).
22+
23+
There are a few gotchas, that are common. One is putting a provider in an `imports` array. If this is the case, the error will have the provider's name where `<module>` should be.
24+
25+
If you run across this error while developing, take a look at the module mentioned in the error message and look at its `providers`. For each provider in the `providers` array, make sure the module has access to all of the dependencies. Often times, `providers` are duplicated in a "Feature Module" and a "Root Module" which means Nest will try to instantiate the provider twice. More than likely, the module containing the `provider` being duplicated should be added in the "Root Module"'s `imports` array instead.
26+
27+
#### "Circular dependency" error
28+
29+
Occasionally you'll find it difficult to avoid [circular dependencies](/fundamentals/circular-dependency) in your application. You'll need to take some steps to help Nest resolve these. Errors that arise from circular dependencies look like this:
30+
31+
```bash
32+
Nest cannot create the <module> instance.
33+
The module at index [<index>] of the <module> "imports" array is undefined.
34+
35+
Potential causes:
36+
- A circular dependency between modules. Use forwardRef() to avoid it. Read more: https://docs.nestjs.com/fundamentals/circular-dependency
37+
- The module at index [<index>] is of type "undefined". Check your import statements and the type of the module.
38+
39+
Scope [<module_import_chain>]
40+
# example chain AppModule -> FooModule
41+
```
42+
43+
Circular dependencies can arise from both providers depending on each other, or typescript files depending on each other for constants, such as exporting constants from a module file and importing them in a service file. In the latter case, it is advised to create a separate file for your constants. In the former case, please follow the guide on ciruclar dependencies and make sure that both the modules **and** the providers are marked with `forwardRef`.

0 commit comments

Comments
 (0)