fastify 4.0.2 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/.eslintrc +1 -0
  2. package/README.md +3 -3
  3. package/docs/Guides/Database.md +5 -5
  4. package/docs/Guides/Delay-Accepting-Requests.md +1 -1
  5. package/docs/Guides/Ecosystem.md +13 -0
  6. package/docs/Guides/Migration-Guide-V4.md +58 -2
  7. package/docs/Guides/Serverless.md +23 -10
  8. package/docs/Reference/Hooks.md +52 -0
  9. package/docs/Reference/LTS.md +2 -2
  10. package/docs/Reference/Plugins.md +1 -1
  11. package/docs/Reference/Server.md +1 -1
  12. package/docs/Reference/Type-Providers.md +4 -3
  13. package/docs/Reference/TypeScript.md +38 -25
  14. package/docs/Reference/Validation-and-Serialization.md +11 -0
  15. package/docs/index.md +1 -1
  16. package/fastify.d.ts +3 -3
  17. package/fastify.js +19 -19
  18. package/integration/server.js +27 -0
  19. package/integration/test.sh +23 -0
  20. package/lib/context.js +5 -2
  21. package/lib/error-serializer.js +173 -8
  22. package/lib/handleRequest.js +1 -1
  23. package/lib/reply.js +2 -0
  24. package/lib/route.js +39 -29
  25. package/lib/server.js +9 -1
  26. package/lib/symbols.js +2 -1
  27. package/lib/validation.js +2 -0
  28. package/lib/wrapThenable.js +8 -3
  29. package/package.json +6 -6
  30. package/test/404s.test.js +2 -2
  31. package/test/build/error-serializer.test.js +6 -1
  32. package/test/hooks.test.js +21 -0
  33. package/test/internals/reply.test.js +12 -0
  34. package/test/listen.test.js +16 -2
  35. package/test/pretty-print.test.js +3 -3
  36. package/test/reply-error.test.js +1 -1
  37. package/test/schema-feature.test.js +2 -2
  38. package/test/stream.test.js +73 -0
  39. package/test/types/fastify.test-d.ts +12 -1
  40. package/test/types/instance.test-d.ts +1 -1
  41. package/test/types/register.test-d.ts +77 -2
  42. package/test/types/request.test-d.ts +8 -4
  43. package/test/types/type-provider.test-d.ts +11 -2
  44. package/test/validation-error-handling.test.js +32 -0
  45. package/types/register.d.ts +9 -7
  46. package/types/route.d.ts +10 -12
  47. package/types/schema.d.ts +1 -1
  48. package/types/type-provider.d.ts +12 -5
package/.eslintrc CHANGED
@@ -1,3 +1,4 @@
1
1
  {
2
+ "root": true,
2
3
  "extends": "standard"
3
4
  }
package/README.md CHANGED
@@ -56,7 +56,7 @@ developer experience with the least overhead and a powerful plugin architecture.
56
56
  It is inspired by Hapi and Express and as far as we know, it is one of the
57
57
  fastest web frameworks in town.
58
58
 
59
- This branch refers to the upcoming Fastify v4 release. Check out the
59
+ This branch refers to the Fastify v4 release. Check out the
60
60
  [v3.x](https://github.com/fastify/fastify/tree/v3.x) branch for v3.
61
61
 
62
62
  ### Quick start
@@ -104,11 +104,11 @@ project as a dependency:
104
104
 
105
105
  Install with npm:
106
106
  ```sh
107
- npm i fastify@next
107
+ npm i fastify
108
108
  ```
109
109
  Install with yarn:
110
110
  ```sh
111
- yarn add fastify@next
111
+ yarn add fastify
112
112
  ```
113
113
 
114
114
  ### Example
@@ -37,7 +37,7 @@ fastify.get('/user/:id', function(req, reply) {
37
37
  )
38
38
  })
39
39
 
40
- fastify.listen(3000, err => {
40
+ fastify.listen({ port: 3000 }, err => {
41
41
  if (err) throw err
42
42
  console.log(`server listening on ${fastify.server.address().port}`)
43
43
  })
@@ -64,7 +64,7 @@ fastify.get('/user/:id', function (req, reply) {
64
64
  )
65
65
  })
66
66
 
67
- fastify.listen(3000, err => {
67
+ fastify.listen({ port: 3000 }, err => {
68
68
  if (err) throw err
69
69
  console.log(`server listening on ${fastify.server.address().port}`)
70
70
  })
@@ -98,7 +98,7 @@ fastify.post('/foo', function (req, reply) {
98
98
  })
99
99
  })
100
100
 
101
- fastify.listen(3000, err => {
101
+ fastify.listen({ port: 3000 }, err => {
102
102
  if (err) throw err
103
103
  console.log(`server listening on ${fastify.server.address().port}`)
104
104
  })
@@ -145,7 +145,7 @@ fastify.get('/user/:id', function (req, reply) {
145
145
  })
146
146
  })
147
147
 
148
- fastify.listen(3000, err => {
148
+ fastify.listen({ port: 3000 }, err => {
149
149
  if (err) throw err
150
150
  })
151
151
  ```
@@ -172,7 +172,7 @@ fastify.post('/foo', async function (req, reply) {
172
172
  return { status: 'ok' }
173
173
  })
174
174
 
175
- fastify.listen(3000, err => {
175
+ fastify.listen({ port: 3000 }, err => {
176
176
  if (err) throw err
177
177
  console.log(`server listening on ${fastify.server.address().port}`)
178
178
  })
@@ -48,7 +48,7 @@ server (fewer resources allocated to a bound-to-fail task) and for the client
48
48
  That will be achieved by wrapping into a custom plugin two main features:
49
49
 
50
50
  1. the mechanism for authenticating with the provider
51
- [decorating](../Referece/Decorators.md) the `fastify` object with the
51
+ [decorating](../Reference/Decorators.md) the `fastify` object with the
52
52
  authentication key (`magicKey` from here onwards)
53
53
  1. the mechanism for denying requests that would, otherwise, fail
54
54
 
@@ -132,9 +132,15 @@ section.
132
132
  sampling process metrics.
133
133
  - [`@dnlup/fastify-traps`](https://github.com/dnlup/fastify-traps) A plugin to
134
134
  close the server gracefully on `SIGINT` and `SIGTERM` signals.
135
+ - [`@eropple/fastify-openapi3`](https://github.com/eropple/fastify-openapi3) Provides
136
+ easy, developer-friendly OpenAPI 3.1 specs + doc explorer based on your routes.
135
137
  - [`@gquittet/graceful-server`](https://github.com/gquittet/graceful-server)
136
138
  Tiny (~5k), Fast, KISS, and dependency-free Node.JS library to make your
137
139
  Fastify API graceful.
140
+ - [`@h4ad/serverless-adapter`](https://github.com/H4ad/serverless-adapter)
141
+ Run REST APIs and other web applications using your existing Node.js
142
+ application framework (Express, Koa, Hapi and Fastify), on top of AWS Lambda,
143
+ Huawei and many other clouds.
138
144
  - [`@immobiliarelabs/fastify-metrics`](https://github.com/immobiliare/fastify-metrics)
139
145
  Minimalistic and opinionated plugin that collects usage/process metrics and
140
146
  dispatches to [statsd](https://github.com/statsd/statsd).
@@ -327,6 +333,8 @@ section.
327
333
  Kubernetes client plugin.
328
334
  - [`fastify-language-parser`](https://github.com/lependu/fastify-language-parser)
329
335
  Fastify plugin to parse request language.
336
+ - [`fastify-lcache`](https://github.com/denbon05/fastify-lcache)
337
+ Lightweight cache plugin
330
338
  - [`fastify-loader`](https://github.com/TheNoim/fastify-loader) Load routes from
331
339
  a directory and inject the Fastify instance in each file.
332
340
  - [`fastify-lured`](https://github.com/lependu/fastify-lured) Plugin to load lua
@@ -346,6 +354,9 @@ section.
346
354
  minification and transformation of responses.
347
355
  - [`fastify-mongo-memory`](https://github.com/chapuletta/fastify-mongo-memory)
348
356
  Fastify MongoDB in Memory Plugin for testing support.
357
+ - [`fastify-mongodb-sanitizer`](https://github.com/KlemenKozelj/fastify-mongodb-sanitizer)
358
+ Fastify plugin that sanitizes client input to prevent
359
+ potential MongoDB query injection attacks.
349
360
  - [`fastify-mongoose-api`](https://github.com/jeka-kiselyov/fastify-mongoose-api)
350
361
  Fastify plugin to create REST API methods based on Mongoose MongoDB models.
351
362
  - [`fastify-mongoose-driver`](https://github.com/alex-ppg/fastify-mongoose)
@@ -475,6 +486,8 @@ section.
475
486
  Events with `reply.sse( … )` to Fastify.
476
487
  - [`fastify-sse-v2`](https://github.com/nodefactoryio/fastify-sse-v2) to provide
477
488
  Server-Sent Events using Async Iterators (supports newer versions of Fastify).
489
+ - [`fastify-ssr-vite`](https://github.com/nineohnine/fastify-ssr-vite) A simple
490
+ plugin for setting up server side rendering with vite.
478
491
  - [`fastify-stripe`](https://github.com/coopflow/fastify-stripe) Plugin to
479
492
  initialize and encapsulate [Stripe
480
493
  Node.js](https://github.com/stripe/stripe-node) instances in Fastify.
@@ -8,7 +8,39 @@ work after upgrading.
8
8
 
9
9
  ## Breaking Changes
10
10
 
11
- ### Deprecation of `app.use()`
11
+ ### Error handling composition ([#3261](https://github.com/fastify/fastify/pull/3261))
12
+
13
+ When an error is thrown in a async error handler function,
14
+ the upper-level error handler is executed if set.
15
+ If there is not a upper-level error handler, the default will
16
+ be executed as it was previously.
17
+
18
+ ```
19
+ import Fastify from 'fastify'
20
+
21
+ const fastify = Fastify()
22
+
23
+ fastify.register(async fastify => {
24
+ fastify.setErrorHandler(async err => {
25
+ console.log(err.message) // 'kaboom'
26
+ throw new Error('caught')
27
+ })
28
+
29
+ fastify.get('/encapsulated', async () => {
30
+ throw new Error('kaboom')
31
+ })
32
+ })
33
+
34
+ fastify.setErrorHandler(async err => {
35
+ console.log(err.message) // 'caught'
36
+ throw new Error('wrapped')
37
+ })
38
+
39
+ const res = await fastify.inject('/encapsulated')
40
+ console.log(res.json().message) // 'wrapped'
41
+ ```
42
+
43
+ ### Deprecation of `app.use()` ([#3506](https://github.com/fastify/fastify/pull/3506))
12
44
 
13
45
  Starting this version of Fastify, we have deprecated the use of `app.use()`. We
14
46
  have decided not to support the use of middlewares. Both
@@ -16,12 +48,29 @@ have decided not to support the use of middlewares. Both
16
48
  [`@fastify/express`](https://github.com/fastify/fastify-express) will still be
17
49
  there and maintained. Use Fastify's [hooks](../Reference/Hooks.md) instead.
18
50
 
51
+ ### `reply.res` moved to `reply.raw`
52
+
53
+ If you previously used the `reply.res` attribute to access the underlying Request
54
+ object you'll instead need to depend on `reply.raw`.
55
+
56
+ ### Need to `return reply` to signal a "fork" of the promise chain
57
+
58
+ In some situations, like when a response is sent asynchronously or when you're
59
+ just not explicitly returning a response, you'll need to return the `reply`
60
+ argument from your router handler.
61
+
62
+ ### `exposeHeadRoutes` true by default
63
+
64
+ Starting from v4, all the `GET` routes will create a sibling `HEAD` route.
65
+ You can revert this behaviour by setting the server's option `exposeHeadRoutes`
66
+ to `false`.
67
+
19
68
  ## Non Breaking Changes
20
69
 
21
70
  ### Change of schema for multiple types
22
71
 
23
72
 
24
- Since Fastiy v4 has upgraded to Ajv v8. The "type" keywords with multiple types
73
+ Since Fastify v4 has upgraded to Ajv v8. The "type" keywords with multiple types
25
74
  (other than with "null") are prohibited. Read more
26
75
  ['here'](https://ajv.js.org/strict-mode.html#strict-types)
27
76
 
@@ -53,3 +102,10 @@ properties: {
53
102
  }
54
103
  }
55
104
  ```
105
+
106
+ ### Add `reply.trailers` methods ([#3794](https://github.com/fastify/fastify/pull/3794))
107
+
108
+ Fastify now supports the [HTTP Trailer] response headers.
109
+
110
+
111
+ [HTTP Trailer]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Trailer
@@ -24,23 +24,31 @@ snippet of code.
24
24
 
25
25
  ### Contents
26
26
 
27
- - [AWS Lambda](#aws-lambda)
27
+ - [AWS](#aws)
28
28
  - [Google Cloud Functions](#google-cloud-functions)
29
29
  - [Google Cloud Run](#google-cloud-run)
30
30
  - [Netlify Lambda](#netlify-lambda)
31
31
  - [Vercel](#vercel)
32
32
 
33
- ## AWS Lambda
33
+ ## AWS
34
+
35
+ To integrate with AWS, you have two choices of library:
36
+
37
+ - Using [@fastify/aws-lambda](https://github.com/fastify/aws-lambda-fastify)
38
+ which only adds API Gateway support but has heavy optimizations for fastify.
39
+ - Using [@h4ad/serverless-adapter](https://github.com/H4ad/serverless-adapter)
40
+ which is a little slower as it creates an HTTP request for each AWS event but
41
+ has support for more AWS services such as: AWS SQS, AWS SNS and others.
42
+
43
+ So you can decide which option is best for you, but you can test both libraries.
44
+
45
+ ### Using @fastify/aws-lambda
34
46
 
35
47
  The sample provided allows you to easily build serverless web
36
48
  applications/services and RESTful APIs using Fastify on top of AWS Lambda and
37
49
  Amazon API Gateway.
38
50
 
39
- *Note: Using
40
- [@fastify/aws-lambda](https://github.com/fastify/aws-lambda-fastify) is just one
41
- possible way.*
42
-
43
- ### app.js
51
+ #### app.js
44
52
 
45
53
  ```js
46
54
  const fastify = require('fastify');
@@ -71,7 +79,7 @@ When you execute your Fastify application like always, i.e. `node app.js` *(the
71
79
  detection for this could be `require.main === module`)*, you can normally listen
72
80
  to your port, so you can still run your Fastify function locally.
73
81
 
74
- ### lambda.js
82
+ #### lambda.js
75
83
 
76
84
  ```js
77
85
  const awsLambdaFastify = require('@fastify/aws-lambda')
@@ -99,14 +107,13 @@ signature to be used as a lambda `handler` function. This way all the incoming
99
107
  events (API Gateway requests) are passed to the `proxy` function of
100
108
  [@fastify/aws-lambda](https://github.com/fastify/aws-lambda-fastify).
101
109
 
102
- ### Example
110
+ #### Example
103
111
 
104
112
  An example deployable with
105
113
  [claudia.js](https://claudiajs.com/tutorials/serverless-express.html) can be
106
114
  found
107
115
  [here](https://github.com/claudiajs/example-projects/tree/master/fastify-app-lambda).
108
116
 
109
-
110
117
  ### Considerations
111
118
 
112
119
  - API Gateway does not support streams yet, so you are not able to handle
@@ -114,6 +121,12 @@ found
114
121
  - API Gateway has a timeout of 29 seconds, so it is important to provide a reply
115
122
  during this time.
116
123
 
124
+ #### Beyond API Gateway
125
+
126
+ If you need to integrate with more AWS services, take a look at
127
+ [@h4ad/serverless-adapter](https://viniciusl.com.br/serverless-adapter/docs/main/frameworks/fastify)
128
+ on Fastify to find out how to integrate.
129
+
117
130
  ## Google Cloud Functions
118
131
 
119
132
  ### Creation of Fastify instance
@@ -28,6 +28,7 @@ are Request/Reply hooks and application hooks:
28
28
  - [onRegister](#onregister)
29
29
  - [Scope](#scope)
30
30
  - [Route level hooks](#route-level-hooks)
31
+ - [Using Hooks to Inject Custom Properties](#using-hooks-to-inject-custom-properties)
31
32
  - [Diagnostics Channel Hooks](#diagnostics-channel-hooks)
32
33
 
33
34
  **Notice:** the `done` callback is not available when using `async`/`await` or
@@ -649,6 +650,57 @@ fastify.route({
649
650
 
650
651
  **Note**: both options also accept an array of functions.
651
652
 
653
+ ## Using Hooks to Inject Custom Properties
654
+ <a id="using-hooks-to-inject-custom-properties"></a>
655
+
656
+ You can use a hook to inject custom properties into incoming requests.
657
+ This is useful for reusing processed data from hooks in controllers.
658
+
659
+ A very common use case is, for example, checking user authentication based
660
+ on their token and then storing their recovered data into
661
+ the [Request](./Request.md) instance. This way, your controllers can read it
662
+ easily with `request.authenticatedUser` or whatever you want to call it.
663
+ That's how it might look like:
664
+
665
+ ```js
666
+ fastify.addHook('preParsing', async (request) => {
667
+ request.authenticatedUser = {
668
+ id: 42,
669
+ name: 'Jane Doe',
670
+ role: 'admin'
671
+ }
672
+ })
673
+
674
+ fastify.get('/me/is-admin', async function (req, reply) {
675
+ return { isAdmin: req.authenticatedUser?.role === 'admin' || false }
676
+ })
677
+ ```
678
+
679
+ Note that `.authenticatedUser` could actually be any property name
680
+ choosen by yourself. Using your own custom property prevents you
681
+ from mutating existing properties, which
682
+ would be a dangerous and destructive operation. So be careful and
683
+ make sure your property is entirely new, also using this approach
684
+ only for very specific and small cases like this example.
685
+
686
+ Regarding TypeScript in this example, you'd need to update the
687
+ `FastifyRequest` core interface to include your new property typing
688
+ (for more about it, see [TypeScript](./TypeScript.md) page), like:
689
+
690
+ ```ts
691
+ interface AuthenticatedUser { /* ... */ }
692
+
693
+ declare module 'fastify' {
694
+ export interface FastifyRequest {
695
+ authenticatedUser?: AuthenticatedUser;
696
+ }
697
+ }
698
+ ```
699
+
700
+ Although this is a very pragmatic approach, if you're trying to do
701
+ something more complex that changes these core objects, then
702
+ consider creating a custom [Plugin](./Plugins.md) instead.
703
+
652
704
  ## Diagnostics Channel Hooks
653
705
 
654
706
  > **Note:** The `diagnostics_channel` is currently experimental on Node.js, so
@@ -47,8 +47,8 @@ A "month" is defined as 30 consecutive days.
47
47
  | :------ | :----------- | :-------------- | :------------------- |
48
48
  | 1.0.0 | 2018-03-06 | 2019-09-01 | 6, 8, 9, 10, 11 |
49
49
  | 2.0.0 | 2019-02-25 | 2021-01-31 | 6, 8, 10, 12, 14 |
50
- | 3.0.0 | 2020-07-07 | TBD | 10, 12, 14, 16, 18 |
51
- | 4.0.0 | TBD | TBD | 14, 16, 18 |
50
+ | 3.0.0 | 2020-07-07 | 2023-06-30 | 10, 12, 14, 16, 18 |
51
+ | 4.0.0 | 2022-06-08 | TBD | 14, 16, 18 |
52
52
 
53
53
  ### CI tested operating systems
54
54
  <a id="supported-os"></a>
@@ -13,7 +13,7 @@ way we create a *directed acyclic graph* (DAG) and we will not have issues
13
13
  caused by cross dependencies.
14
14
 
15
15
  You may have already seen in the [Getting
16
- Started]((../Guides/Getting-Started.md#your-first-plugin)) guide how easy it is
16
+ Started](../Guides/Getting-Started.md#your-first-plugin) guide how easy it is
17
17
  to use this API:
18
18
  ```
19
19
  fastify.register(plugin, [options])
@@ -1278,7 +1278,7 @@ const fastify = Fastify({
1278
1278
  */
1279
1279
  bucket: function factory (parentSchemas) {
1280
1280
  return {
1281
- addSchema (inputSchema) {
1281
+ add (inputSchema) {
1282
1282
  // This function must store the schema added by the user.
1283
1283
  // This function is invoked when `fastify.addSchema()` is called.
1284
1284
  },
@@ -30,11 +30,11 @@ $ npm i @fastify/type-provider-json-schema-to-ts
30
30
  ```
31
31
 
32
32
  ```typescript
33
- import { JsonSchemaToTsTypeProvider } from '@fastify/type-provider-json-schema-to-ts'
33
+ import { JsonSchemaToTsProvider } from '@fastify/type-provider-json-schema-to-ts'
34
34
 
35
35
  import fastify from 'fastify'
36
36
 
37
- const server = fastify().withTypeProvider<JsonSchemaToTsTypeProvider>()
37
+ const server = fastify().withTypeProvider<JsonSchemaToTsProvider>()
38
38
 
39
39
  server.get('/route', {
40
40
  schema: {
@@ -65,7 +65,8 @@ $ npm i @fastify/type-provider-typebox
65
65
  ```
66
66
 
67
67
  ```typescript
68
- import { TypeBoxTypeProvider, Type } from '@fastify/type-provider-typebox'
68
+ import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox'
69
+ import { Type } from '@sinclair/typebox'
69
70
 
70
71
  import fastify from 'fastify'
71
72
 
@@ -199,17 +199,18 @@ Below is how to setup schema validation using vanilla `typebox` and
199
199
  #### typebox
200
200
 
201
201
  A useful library for building types and a schema at once is
202
- [typebox](https://www.npmjs.com/package/@sinclair/typebox). With typebox you
203
- define your schema within your code and use them directly as types or schemas as
204
- you need them.
202
+ [typebox](https://www.npmjs.com/package/@sinclair/typebox) along with
203
+ [fastify-type-provider-typebox](https://github.com/fastify/fastify-type-provider-typebox).
204
+ With typebox you define your schema within your code and use them
205
+ directly as types or schemas as you need them.
205
206
 
206
207
  When you want to use it for validation of some payload in a fastify route you
207
208
  can do it as follows:
208
209
 
209
- 1. Install `typebox` in your project.
210
+ 1. Install `typebox` and `fastify-type-provider-typebox` in your project.
210
211
 
211
212
  ```bash
212
- npm i @sinclair/typebox
213
+ npm i @sinclair/typebox @fastify/type-provider-typebox
213
214
  ```
214
215
 
215
216
  2. Define the schema you need with `Type` and create the respective type with
@@ -218,40 +219,52 @@ can do it as follows:
218
219
  ```typescript
219
220
  import { Static, Type } from '@sinclair/typebox'
220
221
 
221
- const User = Type.Object({
222
+ export const User = Type.Object({
222
223
  name: Type.String(),
223
- mail: Type.Optional(Type.String({ format: "email" })),
224
- });
225
- type UserType = Static<typeof User>;
224
+ mail: Type.Optional(Type.String({ format: 'email' })),
225
+ })
226
+
227
+ export type UserType = Static<typeof User>
226
228
  ```
227
229
 
228
230
  3. Use the defined type and schema during the definition of your route
229
231
 
230
232
  ```typescript
231
- const app = fastify();
233
+ import Fastify from 'fastify'
234
+ import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox'
235
+ // ...
236
+
237
+ const fastify = Fastify().withTypeProvider<TypeBoxTypeProvider>()
232
238
 
233
- app.post<{ Body: UserType; Reply: UserType }>(
234
- "/",
239
+ app.post<{ Body: UserType, Reply: UserType }>(
240
+ '/',
235
241
  {
236
242
  schema: {
237
243
  body: User,
238
244
  response: {
239
- 200: User,
245
+ 200: User
240
246
  },
241
247
  },
242
248
  },
243
249
  (request, reply) => {
244
- const { body: user } = request;
245
- /* user has type
246
- * const user: StaticProperties<{
247
- * name: TString;
248
- * mail: TOptional<TString>;
249
- * }>
250
- */
251
- //...
252
- reply.status(200).send(user);
250
+ // The `name` and `mail` types are automatically inferred
251
+ const { name, mail } = request.body;
252
+ reply.status(200).send({ name, mail });
253
+ }
254
+ )
255
+ ```
256
+
257
+ **Note** For Ajv version 7 and above is required to use the `ajvTypeBoxPlugin`:
258
+
259
+ ```typescript
260
+ import Fastify from 'fastify'
261
+ import { ajvTypeBoxPlugin, TypeBoxTypeProvider } from '@fastify/type-provider-typebox'
262
+
263
+ const fastify = Fastify({
264
+ ajv: {
265
+ plugins: [ajvTypeBoxPlugin]
253
266
  }
254
- );
267
+ }).withTypeProvider<TypeBoxTypeProvider>()
255
268
  ```
256
269
 
257
270
  #### Schemas in JSON Files
@@ -1359,7 +1372,7 @@ A method for checking the existence of a type parser of a certain content type
1359
1372
 
1360
1373
  ##### fastify.FastifyError
1361
1374
 
1362
- [src](https://github.com/fastify/fastify/blob/main/types/error.d.ts#L17)
1375
+ [src](https://github.com/fastify/fastify/blob/main/fastify.d.ts#L179)
1363
1376
 
1364
1377
  FastifyError is a custom error object that includes status code and validation
1365
1378
  results.
@@ -1369,7 +1382,7 @@ properties: `statusCode: number` and `validation: ValiationResult[]`.
1369
1382
 
1370
1383
  ##### fastify.ValidationResult
1371
1384
 
1372
- [src](https://github.com/fastify/fastify/blob/main/types/error.d.ts#L4)
1385
+ [src](https://github.com/fastify/fastify/blob/main/fastify.d.ts#L184)
1373
1386
 
1374
1387
  The route validation internally relies upon Ajv, which is a high-performance
1375
1388
  JSON schema validator.
@@ -484,6 +484,17 @@ fastify.post('/the/url', {
484
484
  }, handler)
485
485
  ```
486
486
 
487
+ ##### .statusCode property
488
+
489
+ All validation errors will be added a `.statusCode` property set to `400`. This guarantees
490
+ that the default error handler will set the status code of the response to `400`.
491
+
492
+ ```js
493
+ fastify.setErrorHandler(function (error, request, reply) {
494
+ request.log.error(error, `This error has status code ${error.statusCode}`)
495
+ reply.status(error.statusCode).send(error)
496
+ })
497
+ ```
487
498
 
488
499
  ##### Validation messages with other validation libraries
489
500
 
package/docs/index.md CHANGED
@@ -16,7 +16,7 @@ Complete newcomers to Fastify should first read our [Getting
16
16
  Started](./Guides/Getting-Started.md) guide.
17
17
 
18
18
  Developers experienced with Fastify should consult the [reference
19
- documentation](./Reference/index.md) directly to find the topic they are seeking
19
+ documentation](./Reference/Index.md) directly to find the topic they are seeking
20
20
  more information about.
21
21
 
22
22
  ## Additional Documentation
package/fastify.d.ts CHANGED
@@ -146,7 +146,7 @@ export type FastifyServerOptions<
146
146
  },
147
147
  schemaController?: {
148
148
  bucket?: (parentSchemas?: unknown) => {
149
- addSchema(schema: unknown): FastifyInstance;
149
+ add(schema: unknown): FastifyInstance;
150
150
  getSchema(schemaId: string): unknown;
151
151
  getSchemas(): Record<string, unknown>;
152
152
  };
@@ -183,10 +183,10 @@ declare module '@fastify/error' {
183
183
 
184
184
  export interface ValidationResult {
185
185
  keyword: string;
186
- dataPath: string;
186
+ instancePath: string;
187
187
  schemaPath: string;
188
188
  params: Record<string, string | string[]>;
189
- message: string;
189
+ message?: string;
190
190
  }
191
191
 
192
192
  /* Export all additional types */
package/fastify.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const VERSION = '4.0.2'
3
+ const VERSION = '4.2.0'
4
4
 
5
5
  const Avvio = require('avvio')
6
6
  const http = require('http')
@@ -237,35 +237,35 @@ function fastify (options) {
237
237
  getDefaultRoute: router.getDefaultRoute.bind(router),
238
238
  setDefaultRoute: router.setDefaultRoute.bind(router),
239
239
  // routes shorthand methods
240
- delete: function _delete (url, opts, handler) {
241
- return router.prepareRoute.call(this, 'DELETE', url, opts, handler)
240
+ delete: function _delete (url, options, handler) {
241
+ return router.prepareRoute.call(this, { method: 'DELETE', url, options, handler })
242
242
  },
243
- get: function _get (url, opts, handler) {
244
- return router.prepareRoute.call(this, 'GET', url, opts, handler)
243
+ get: function _get (url, options, handler) {
244
+ return router.prepareRoute.call(this, { method: 'GET', url, options, handler })
245
245
  },
246
- head: function _head (url, opts, handler) {
247
- return router.prepareRoute.call(this, 'HEAD', url, opts, handler)
246
+ head: function _head (url, options, handler) {
247
+ return router.prepareRoute.call(this, { method: 'HEAD', url, options, handler })
248
248
  },
249
- patch: function _patch (url, opts, handler) {
250
- return router.prepareRoute.call(this, 'PATCH', url, opts, handler)
249
+ patch: function _patch (url, options, handler) {
250
+ return router.prepareRoute.call(this, { method: 'PATCH', url, options, handler })
251
251
  },
252
- post: function _post (url, opts, handler) {
253
- return router.prepareRoute.call(this, 'POST', url, opts, handler)
252
+ post: function _post (url, options, handler) {
253
+ return router.prepareRoute.call(this, { method: 'POST', url, options, handler })
254
254
  },
255
- put: function _put (url, opts, handler) {
256
- return router.prepareRoute.call(this, 'PUT', url, opts, handler)
255
+ put: function _put (url, options, handler) {
256
+ return router.prepareRoute.call(this, { method: 'PUT', url, options, handler })
257
257
  },
258
- options: function _options (url, opts, handler) {
259
- return router.prepareRoute.call(this, 'OPTIONS', url, opts, handler)
258
+ options: function _options (url, options, handler) {
259
+ return router.prepareRoute.call(this, { method: 'OPTIONS', url, options, handler })
260
260
  },
261
- all: function _all (url, opts, handler) {
262
- return router.prepareRoute.call(this, supportedMethods, url, opts, handler)
261
+ all: function _all (url, options, handler) {
262
+ return router.prepareRoute.call(this, { method: supportedMethods, url, options, handler })
263
263
  },
264
264
  // extended route
265
- route: function _route (opts) {
265
+ route: function _route (options) {
266
266
  // we need the fastify object that we are producing so we apply a lazy loading of the function,
267
267
  // otherwise we should bind it after the declaration
268
- return router.route.call(this, opts)
268
+ return router.route.call(this, { options })
269
269
  },
270
270
  // expose logger instance
271
271
  log: logger,
@@ -0,0 +1,27 @@
1
+ const Fastify = require('../fastify')
2
+
3
+ const fastify = Fastify()
4
+
5
+ fastify.listen({
6
+ host: '::',
7
+ port: 3000
8
+ })
9
+
10
+ fastify.get('/', async function (request, reply) {
11
+ reply.code(200).send({ data: 'home page' })
12
+ })
13
+
14
+ fastify.post('/post/:id', async function (request, reply) {
15
+ const { id } = request.params
16
+ reply.code(201).send({ data: `${id}` })
17
+ })
18
+
19
+ fastify.put('/put/:id', async function (request, reply) {
20
+ const { id } = request.params
21
+ reply.code(200).send({ data: `${id}` })
22
+ })
23
+
24
+ fastify.delete('/delete/:id', async function (request, reply) {
25
+ const { id } = request.params
26
+ reply.code(204).send({ data: `${id}` })
27
+ })