fastify 3.9.2 → 3.12.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 (92) hide show
  1. package/GOVERNANCE.md +1 -1
  2. package/README.md +12 -8
  3. package/SECURITY.md +3 -3
  4. package/docs/ContentTypeParser.md +1 -1
  5. package/docs/Ecosystem.md +16 -6
  6. package/docs/Encapsulation.md +5 -2
  7. package/docs/Fluent-Schema.md +4 -4
  8. package/docs/Getting-Started.md +1 -1
  9. package/docs/Hooks.md +28 -1
  10. package/docs/Lifecycle.md +8 -1
  11. package/docs/Middleware.md +5 -4
  12. package/docs/Reply.md +13 -4
  13. package/docs/Routes.md +4 -3
  14. package/docs/Server.md +78 -4
  15. package/docs/Serverless.md +23 -51
  16. package/docs/TypeScript.md +35 -18
  17. package/docs/Validation-and-Serialization.md +4 -4
  18. package/docs/Write-Plugin.md +4 -4
  19. package/examples/hooks-benchmark.js +12 -12
  20. package/examples/hooks.js +16 -16
  21. package/examples/plugin.js +2 -2
  22. package/examples/route-prefix.js +4 -4
  23. package/fastify.d.ts +16 -1
  24. package/fastify.js +33 -16
  25. package/isolate-0x426d1e0-1227-v8.log +4019 -0
  26. package/isolate-0x4d4c7e0-1988-v8.log +4081 -0
  27. package/lib/errors.js +6 -0
  28. package/lib/headRoute.js +31 -0
  29. package/lib/pluginOverride.js +5 -5
  30. package/lib/pluginUtils.js +7 -6
  31. package/lib/reply.js +14 -2
  32. package/lib/reqIdGenFactory.js +5 -0
  33. package/lib/request.js +1 -1
  34. package/lib/route.js +66 -41
  35. package/lib/schema-compilers.js +5 -3
  36. package/lib/schema-controller.js +106 -0
  37. package/lib/schemas.js +14 -24
  38. package/lib/server.js +1 -0
  39. package/lib/symbols.js +1 -3
  40. package/lib/warnings.js +2 -0
  41. package/lib/wrapThenable.js +2 -1
  42. package/package.json +25 -21
  43. package/test/404s.test.js +120 -120
  44. package/test/500s.test.js +8 -8
  45. package/test/async-await.test.js +29 -1
  46. package/test/close.test.js +8 -8
  47. package/test/context-config.test.js +52 -0
  48. package/test/custom-parser.test.js +8 -8
  49. package/test/decorator.test.js +49 -49
  50. package/test/default-route.test.js +43 -0
  51. package/test/fastify-instance.test.js +2 -2
  52. package/test/fluent-schema.test.js +3 -3
  53. package/test/handler-context.test.js +2 -2
  54. package/test/hooks-async.test.js +3 -3
  55. package/test/hooks.on-ready.test.js +12 -12
  56. package/test/hooks.test.js +75 -32
  57. package/test/http2/closing.test.js +23 -1
  58. package/test/inject.test.js +6 -6
  59. package/test/input-validation.js +2 -2
  60. package/test/internals/hookRunner.test.js +50 -50
  61. package/test/internals/reply.test.js +47 -22
  62. package/test/internals/request.test.js +3 -9
  63. package/test/internals/version.test.js +2 -2
  64. package/test/logger.test.js +30 -30
  65. package/test/middleware.test.js +4 -4
  66. package/test/plugin.helper.js +2 -2
  67. package/test/plugin.test.js +154 -99
  68. package/test/register.test.js +11 -11
  69. package/test/request-error.test.js +2 -2
  70. package/test/route-hooks.test.js +24 -24
  71. package/test/route-prefix.test.js +81 -52
  72. package/test/route.test.js +568 -0
  73. package/test/schema-feature.test.js +168 -38
  74. package/test/schema-serialization.test.js +4 -4
  75. package/test/schema-special-usage.test.js +136 -0
  76. package/test/schema-validation.test.js +7 -7
  77. package/test/skip-reply-send.test.js +315 -0
  78. package/test/stream.test.js +6 -6
  79. package/test/throw.test.js +4 -4
  80. package/test/types/instance.test-d.ts +5 -3
  81. package/test/types/plugin.test-d.ts +7 -7
  82. package/test/types/reply.test-d.ts +1 -0
  83. package/test/types/schema.test-d.ts +15 -0
  84. package/test/validation-error-handling.test.js +5 -5
  85. package/test/versioned-routes.test.js +1 -1
  86. package/types/content-type-parser.d.ts +1 -1
  87. package/types/instance.d.ts +6 -3
  88. package/types/plugin.d.ts +1 -1
  89. package/types/reply.d.ts +1 -0
  90. package/types/route.d.ts +8 -2
  91. package/types/schema.d.ts +3 -0
  92. package/test/skip-reply-send.js +0 -98
package/docs/Server.md CHANGED
@@ -133,8 +133,6 @@ logger will point to this instance.
133
133
  + `object`: a standard Pino [options object](https://github.com/pinojs/pino/blob/c77d8ec5ce/docs/API.md#constructor).
134
134
  This will be passed directly to the Pino constructor. If the following properties
135
135
  are not present on the object, they will be added accordingly:
136
- * `genReqId`: a synchronous function that will be used to generate identifiers
137
- for incoming requests. The default function generates sequential identifiers.
138
136
  * `level`: the minimum logging level. If not set, it will be set to `'info'`.
139
137
  * `serializers`: a hash of serialization functions. By default, serializers
140
138
  are added for `req` (incoming request objects), `res` (outgoing response
@@ -328,6 +326,13 @@ const fastify = require('fastify')({
328
326
  })
329
327
  ```
330
328
 
329
+ <a name="exposeHeadRoutes"></a>
330
+ ### `exposeHeadRoutes`
331
+
332
+ Automatically creates a sibling `HEAD` route for each `GET` route defined. If you want a custom `HEAD` handler without disabling this option, make sure to define it before the `GET` route.
333
+
334
+ + Default: `false`
335
+
331
336
  <a name="versioning"></a>
332
337
  ### `versioning`
333
338
 
@@ -457,7 +462,7 @@ function defaultClientErrorHandler (err, socket) {
457
462
  }
458
463
  ```
459
464
 
460
- *Note: `clientErrorHandler` operates with raw socket. The handler is expected to return a properly formed HTTP response that includes a status line, HTTP headers and a message body. Before attempting to write the socket, the handler should check if the socket it's still writable as it may already have been destroyed.*
465
+ *Note: `clientErrorHandler` operates with raw socket. The handler is expected to return a properly formed HTTP response that includes a status line, HTTP headers and a message body. Before attempting to write the socket, the handler should check if the socket is still writable as it may have already been destroyed.*
461
466
 
462
467
  ```js
463
468
  const fastify = require('fastify')({
@@ -668,6 +673,34 @@ fastify.listen({
668
673
  }, (err) => {})
669
674
  ```
670
675
 
676
+ <a name="getDefaultRoute"></a>
677
+ #### getDefaultRoute
678
+ Method to get the `defaultRoute` for the server:
679
+
680
+ ```js
681
+ const defaultRoute = fastify.getDefaultRoute()
682
+ ```
683
+
684
+ <a name="setDefaultRoute"></a>
685
+ #### setDefaultRoute
686
+ Method to set the `defaultRoute` for the server:
687
+
688
+ ```js
689
+ const defaultRoute = function (req, res) {
690
+ res.end('hello world')
691
+ }
692
+
693
+ fastify.setDefaultRoute(defaultRoute)
694
+ ```
695
+
696
+ <a name="routing"></a>
697
+ #### routing
698
+ Method to access the `lookup` method of the internal router and match the request to the appropriate handler:
699
+
700
+ ```js
701
+ fastify.routing(req, res)
702
+ ```
703
+
671
704
  <a name="route"></a>
672
705
  #### route
673
706
  Method to add routes to the server, it also has shorthand functions, check [here](Routes.md).
@@ -737,7 +770,7 @@ Name of the current plugin. There are three ways to define a name (in order).
737
770
  2. If you `module.exports` a plugin the filename is used.
738
771
  3. If you use a regular [function declaration](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions#Defining_functions) the function name is used.
739
772
 
740
- *Fallback*: The first two lines of your plugin will represent the plugin name. Newlines are replaced by ` -- `. This will help to indentify the root cause when you deal with many plugins.
773
+ *Fallback*: The first two lines of your plugin will represent the plugin name. Newlines are replaced by ` -- `. This will help to identify the root cause when you deal with many plugins.
741
774
 
742
775
  Important: If you have to deal with nested plugins the name differs with the usage of the [fastify-plugin](https://github.com/fastify/fastify-plugin) because no new scope is created and therefore we have no place to attach contextual data. In that case the plugin name will represent the boot order of all involved plugins in the format of `plugin-A -> plugin-B`.
743
776
 
@@ -805,6 +838,47 @@ The input `schema` can access all the shared schemas added with [`.addSchema`](#
805
838
  #### schemaErrorFormatter
806
839
  This property can be used set a function to format errors that happen while the `validationCompiler` fails to validate the schema. See [#error-handling](Validation-and-Serialization.md#schemaerrorformatter).
807
840
 
841
+ <a name="schema-controller"></a>
842
+ #### schemaController
843
+ This property can be used to fully manage where the schemas of your application will be stored.
844
+ It can be useful when your schemas are stored in another data structure that is unknown to Fastify.
845
+ See [issue #2446](https://github.com/fastify/fastify/issues/2446) for an example of what
846
+ this property helps to resolve.
847
+
848
+ ```js
849
+ const fastify = Fastify({
850
+ schemaController: {
851
+ /**
852
+ * This factory is called whenever `fastify.register()` is called.
853
+ * It may receive as input the schemas of the parent context if some schemas has been added.
854
+ * @param {object} parentSchemas these schemas will be returned by the `getSchemas()` method function of the returned `bucket`.
855
+ */
856
+ bucket: function factory (parentSchemas) {
857
+ return {
858
+ addSchema (inputSchema) {
859
+ // This function must store the schema added by the user.
860
+ // This function is invoked when `fastify.addSchema()` is called.
861
+ },
862
+ getSchema (schema$id) {
863
+ // This function must return the raw schema requested by the `schema$id`.
864
+ // This function is invoked when `fastify.getSchema(id)` is called.
865
+ return aSchema
866
+ },
867
+ getSchemas () {
868
+ // This function must return all the schemas referenced by the routes schemas' $ref
869
+ // It must return a JSON where the property is the schema `$id` and the value is the raw JSON Schema.
870
+ const allTheSchemaStored = {
871
+ 'schema$id1': schema1,
872
+ 'schema$id2': schema2
873
+ }
874
+ return allTheSchemaStored
875
+ }
876
+ }
877
+ }
878
+ }
879
+ });
880
+ ```
881
+
808
882
  <a name="set-not-found-handler"></a>
809
883
  #### setNotFoundHandler
810
884
 
@@ -99,7 +99,7 @@ Unlike AWS Lambda or Google Cloud Functions, Google Cloud Run is a serverless **
99
99
 
100
100
  *Follow the steps below to deploy to Google Cloud Run if you are already familiar with gcloud or just follow their [quickstart](https://cloud.google.com/run/docs/quickstarts/build-and-deploy)*.
101
101
 
102
- ### Adjust Fastfiy server
102
+ ### Adjust Fastify server
103
103
 
104
104
  In order for Fastify to properly listen for requests within the container, be sure to set the correct port and address:
105
105
 
@@ -279,69 +279,41 @@ Then it should work fine
279
279
 
280
280
  [Vercel](https://vercel.com) provides zero configuration deployment for
281
281
  Node.js applications. In order to use now, it is as simple as
282
- configuring your `now.json` file like the following:
282
+ configuring your `vercel.json` file like the following:
283
283
 
284
284
  ```json
285
285
  {
286
- "version": 2,
287
- "builds": [
288
- {
289
- "src": "api/serverless.js",
290
- "use": "@now/node",
291
- "config": {
292
- "helpers": false
293
- }
294
- }
295
- ],
296
- "routes": [
297
- { "src": "/.*", "dest": "/api/serverless.js"}
298
- ]
286
+ "rewrites": [
287
+ {
288
+ "source": "/(.*)",
289
+ "destination": "/api/serverless.js"
290
+ }
291
+ ]
299
292
  }
300
293
  ```
301
294
 
302
295
  Then, write a `api/serverless.js` like so:
303
296
 
304
297
  ```js
305
- 'use strict'
298
+ "use strict";
306
299
 
307
- const build = require('./index')
300
+ // Read the .env file.
301
+ import * as dotenv from "dotenv";
302
+ dotenv.config();
308
303
 
309
- const app = build()
310
-
311
- module.exports = async function (req, res) {
312
- await app.ready()
313
- app.server.emit('request', req, res)
314
- }
315
- ```
316
-
317
- And a `api/index.js` file:
318
-
319
- ```js
320
- 'use strict'
304
+ // Require the framework
305
+ import Fastify from "fastify";
321
306
 
322
- const fastify = require('fastify')
307
+ // Instantiate Fastify with some config
308
+ const app = Fastify({
309
+ logger: true,
310
+ });
323
311
 
324
- function build () {
325
- const app = fastify({
326
- logger: true
327
- })
312
+ // Register your application as a normal plugin.
313
+ app.register(import("../src/app"));
328
314
 
329
- app.get('/', async (req, res) => {
330
- const { name = 'World' } = req.query
331
- req.log.info({ name }, 'hello world!')
332
- return `Hello ${name}!`
333
- })
334
-
335
- return app
315
+ export default async (req, res) => {
316
+ await app.ready();
317
+ app.server.emit('request', req, res);
336
318
  }
337
-
338
- module.exports = build
339
- ```
340
-
341
- Note that you'll need to use Node 10 by setting it in `package.json`:
342
-
343
- ```js
344
- "engines": {
345
- "node": "10.x"
346
- },
347
319
  ```
@@ -10,7 +10,7 @@ The type system was changed in Fastify version 3. The new type system introduces
10
10
 
11
11
  > Plugins may or may not include typings. See [Plugins](#plugins) for more information. We encourage users to send pull requests to improve typings support.
12
12
 
13
- 🚨 Don't foget to install `@types/node`
13
+ 🚨 Don't forget to install `@types/node`
14
14
 
15
15
  ## Learn By Example
16
16
 
@@ -37,7 +37,7 @@ This example will get you up and running with Fastify and TypeScript. It results
37
37
  ```
38
38
  3. Initialize a TypeScript configuration file:
39
39
  ```bash
40
- npx typescript --init
40
+ npx tsc --init
41
41
  ```
42
42
  or use one of the [recommended ones](https://github.com/tsconfig/bases#node-10-tsconfigjson).
43
43
 
@@ -82,7 +82,7 @@ The type system heavily relies on generic properties to provide the most accurat
82
82
  }
83
83
 
84
84
  interface IHeaders {
85
- 'H-Custom': string;
85
+ 'h-Custom': string;
86
86
  }
87
87
  ```
88
88
  3. Using the two interfaces, define a new API route and pass them as generics. The shorthand route methods (i.e. `.get`) accept a generic object `RequestGenericInterface` containing four named properties: `Body`, `Querystring`, `Params`, and `Headers`. The interfaces will be passed down through the route method into the route method handler `request` instance.
@@ -92,7 +92,7 @@ The type system heavily relies on generic properties to provide the most accurat
92
92
  Headers: IHeaders
93
93
  }>('/auth', async (request, reply) => {
94
94
  const { username, password } = request.query
95
- const customerHeader = request.headers['H-Custom']
95
+ const customerHeader = request.headers['h-Custom']
96
96
  // do something with request data
97
97
 
98
98
  return `logged in!`
@@ -115,7 +115,7 @@ The type system heavily relies on generic properties to provide the most accurat
115
115
  done(username !== 'admin' ? new Error('Must be admin') : undefined) // only validate `admin` account
116
116
  }
117
117
  }, async (request, reply) => {
118
- const customerHeader = request.headers['H-Custom']
118
+ const customerHeader = request.headers['h-Custom']
119
119
  // do something with request data
120
120
  return `logged in!`
121
121
  })
@@ -139,10 +139,10 @@ In the last example we used interfaces to define the types for the request query
139
139
  "title": "Headers Schema",
140
140
  "type": "object",
141
141
  "properties": {
142
- "H-Custom": { "type": "string" }
142
+ "h-Custom": { "type": "string" }
143
143
  },
144
144
  "additionalProperties": false,
145
- "required": ["H-Custom"]
145
+ "required": ["h-Custom"]
146
146
  }
147
147
  ```
148
148
  ```json
@@ -194,7 +194,7 @@ In the last example we used interfaces to define the types for the request query
194
194
  done(username !== 'admin' ? new Error('Must be admin') : undefined)
195
195
  }
196
196
  }, async (request, reply) => {
197
- const customerHeader = request.headers['H-Custom']
197
+ const customerHeader = request.headers['h-Custom']
198
198
  // do something with request data
199
199
  return `logged in!`
200
200
  })
@@ -211,11 +211,11 @@ In the last example we used interfaces to define the types for the request query
211
211
  },
212
212
  preHandler: (request, reply) => {
213
213
  const { username, password } = request.query
214
- const customerHeader = request.headers['H-Custom']
214
+ const customerHeader = request.headers['h-Custom']
215
215
  },
216
216
  handler: (request, reply) => {
217
217
  const { username, password } = request.query
218
- const customerHeader = request.headers['H-Custom']
218
+ const customerHeader = request.headers['h-Custom']
219
219
  }
220
220
  })
221
221
 
@@ -229,7 +229,7 @@ In the last example we used interfaces to define the types for the request query
229
229
  ```
230
230
  Pay special attention to the imports at the top of this file. It might seem redundant, but you need to import both the schema files and the generated interfaces.
231
231
 
232
- Great work! Now you can make use of both JSON Schemas and TypeScript definitions. If you didn't know already, defining schemas for your Fastify routes can increase their throughput! Check out the [Validation and Serialization](Validation-and-Serialization.md) documenation for more info.
232
+ Great work! Now you can make use of both JSON Schemas and TypeScript definitions. If you didn't know already, defining schemas for your Fastify routes can increase their throughput! Check out the [Validation and Serialization](Validation-and-Serialization.md) documentation for more info.
233
233
 
234
234
  Some additional notes:
235
235
  - Currently, there is no type definition support for inline JSON schemas. If you can come up with a solution please open a PR!
@@ -333,14 +333,14 @@ This plugin guide is for Fastify plugins written in JavaScript. The steps outlin
333
333
  // fastify-plugin is highly recommended for any plugin you write
334
334
  const fp = require('fastify-plugin')
335
335
 
336
- function myPlugin (instance, options, next) {
336
+ function myPlugin (instance, options, done) {
337
337
 
338
338
  // decorate the fastify instance with a custom function called myPluginFunc
339
339
  instance.decorate('myPluginFunc', (input) => {
340
340
  return input.toUpperCase()
341
341
  })
342
342
 
343
- next()
343
+ done()
344
344
  }
345
345
 
346
346
  module.exports = fp(myPlugin, {
@@ -393,6 +393,23 @@ However, there are a couple of suggestions to help improve this experience:
393
393
  - Make sure the `no-unused-vars` rule is enabled in [ESLint](https://eslint.org/docs/rules/no-unused-vars) and any imported plugin are actually being loaded.
394
394
  - Use a module such as [depcheck](https://www.npmjs.com/package/depcheck) or [npm-check](https://www.npmjs.com/package/npm-check) to verify plugin dependencies are being used somewhere in your project.
395
395
 
396
+ ## Code Completion In Vanilla JavaScript
397
+
398
+ Vanilla JavaScript can use the published types to provide code completion (e.g. [Intellisense](https://code.visualstudio.com/docs/editor/intellisense)) by following the [TypeScript JSDoc Reference](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html).
399
+
400
+ For example:
401
+
402
+ ```js
403
+ /**
404
+ * setup some routes
405
+ * @param {import("fastify").FastifyInstance} fastify
406
+ * @param {*} opts
407
+ */
408
+ module.exports = async function (fastify, opts) {
409
+ fastify.get('/look', () => 'at me');
410
+ }
411
+ ```
412
+
396
413
  ## API Type System Documentation
397
414
 
398
415
  This section is a detailed account of all the types available to you in Fastify version 3.x
@@ -588,7 +605,7 @@ server.get('/', async (request, reply) => {
588
605
 
589
606
  ###### Example 5: Specifying logger types
590
607
 
591
- Fastify uses [Pino](http://getpino.io/#/) logging library under the hood. Some of it's properties can be configured via `logger` field when constructing Fastify's instance. If properties you need aren't exposed, it's also possible to pass a preconfigured external instance of Pino (or any other compatible logger) to Fastify via the same field. This allows creating custom serializers as well, see the [Logging](Logging.md) documentation for more info.
608
+ Fastify uses [Pino](https://getpino.io/#/) logging library under the hood. Some of it's properties can be configured via `logger` field when constructing Fastify's instance. If properties you need aren't exposed, it's also possible to pass a preconfigured external instance of Pino (or any other compatible logger) to Fastify via the same field. This allows creating custom serializers as well, see the [Logging](Logging.md) documentation for more info.
592
609
 
593
610
  To use an external instance of Pino, add `@types/pino` to devDependencies and pass the instance to `logger` field:
594
611
 
@@ -839,7 +856,7 @@ const server = fastify()
839
856
  const plugin: FastifyPlugin<{
840
857
  option1: string;
841
858
  option2: boolean;
842
- }> = function (instance, opts, next) { }
859
+ }> = function (instance, opts, done) { }
843
860
 
844
861
  fastify().register(plugin, {}) // Error - options object is missing required properties
845
862
  fastify().register(plugin, { option1: '', option2: true }) // OK - options object contains required properties
@@ -862,7 +879,7 @@ Check out the [Specifying Logger Types](#example-5-specifying-logger-types) exam
862
879
 
863
880
  [src](../types/logger.d.ts#L17)
864
881
 
865
- An interface definition for the internal Fastify logger. It is emulative of the [Pino.js](http://getpino.io/#/) logger. When enabled through server options, use it following the general [logger](Logging.md) documentation.
882
+ An interface definition for the internal Fastify logger. It is emulative of the [Pino.js](https://getpino.io/#/) logger. When enabled through server options, use it following the general [logger](Logging.md) documentation.
866
883
 
867
884
  ##### fastify.FastifyLogFn
868
885
 
@@ -985,7 +1002,7 @@ This interface is passed to instance of FastifyError.
985
1002
 
986
1003
  #### Hooks
987
1004
 
988
- ##### fastify.onRequestHookhandler<[RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [RequestGeneric][FastifyRequestGenericInterface], [ContextConfig][ContextConfigGeneric]>(request: [FastifyRequest][FastifyRequest], reply: [FastifyReply][FastifyReply], done: (err?: [FastifyError][FastifyError]) => void): Promise\<unknown\> | void
1005
+ ##### fastify.onRequestHookHandler<[RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [RequestGeneric][FastifyRequestGenericInterface], [ContextConfig][ContextConfigGeneric]>(request: [FastifyRequest][FastifyRequest], reply: [FastifyReply][FastifyReply], done: (err?: [FastifyError][FastifyError]) => void): Promise\<unknown\> | void
989
1006
 
990
1007
  [src](../types/hooks.d.ts#L17)
991
1008
 
@@ -993,7 +1010,7 @@ This interface is passed to instance of FastifyError.
993
1010
 
994
1011
  Notice: in the `onRequest` hook, request.body will always be null, because the body parsing happens before the `preHandler` hook.
995
1012
 
996
- ##### fastify.preParsingHookhandler<[RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [RequestGeneric][FastifyRequestGenericInterface], [ContextConfig][ContextConfigGeneric]>(request: [FastifyRequest][FastifyRequest], reply: [FastifyReply][FastifyReply], done: (err?: [FastifyError][FastifyError]) => void): Promise\<unknown\> | void
1013
+ ##### fastify.preParsingHookHandler<[RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [RequestGeneric][FastifyRequestGenericInterface], [ContextConfig][ContextConfigGeneric]>(request: [FastifyRequest][FastifyRequest], reply: [FastifyReply][FastifyReply], done: (err?: [FastifyError][FastifyError]) => void): Promise\<unknown\> | void
997
1014
 
998
1015
  [src](../types/hooks.d.ts#L35)
999
1016
 
@@ -1,14 +1,14 @@
1
1
  <h1 align="center">Fastify</h1>
2
2
 
3
3
  ## Validation and Serialization
4
- Fastify uses a schema-based approach, and even if it is not mandatory we recommend using [JSON Schema](http://json-schema.org/) to validate your routes and serialize your outputs. Internally, Fastify compiles the schema into a highly performant function.
4
+ Fastify uses a schema-based approach, and even if it is not mandatory we recommend using [JSON Schema](https://json-schema.org/) to validate your routes and serialize your outputs. Internally, Fastify compiles the schema into a highly performant function.
5
5
 
6
6
  > ## ⚠ Security Notice
7
7
  > Treat the schema definition as application code.
8
8
  > As both validation and serialization features dynamically evaluate
9
9
  > code with `new Function()`, it is not safe to use
10
- > user-provided schemas. See [Ajv](http://npm.im/ajv) and
11
- > [fast-json-stringify](http://npm.im/fast-json-stringify) for more
10
+ > user-provided schemas. See [Ajv](https://npm.im/ajv) and
11
+ > [fast-json-stringify](https://npm.im/fast-json-stringify) for more
12
12
  > details.
13
13
 
14
14
 
@@ -731,7 +731,7 @@ const refToSharedSchemaDefinitions = {
731
731
 
732
732
  <a name="resources"></a>
733
733
  ### Resources
734
- - [JSON Schema](http://json-schema.org/)
734
+ - [JSON Schema](https://json-schema.org/)
735
735
  - [Understanding JSON Schema](https://spacetelescope.github.io/understanding-json-schema/)
736
736
  - [fast-json-stringify documentation](https://github.com/fastify/fast-json-stringify)
737
737
  - [Ajv documentation](https://github.com/epoberezkin/ajv/blob/master/README.md)
@@ -9,7 +9,7 @@ The core principles of Fastify are performance, low overhead and providing a goo
9
9
  ## Code
10
10
  Fastify uses different techniques to optimize its code, many of them are documented in our Guides. We highly recommend you read [the hitchhiker's guide to plugins](Plugins-Guide.md) to discover all the APIs you can use to build your plugin and learn how use them.
11
11
 
12
- Have you got some question or are you seeking for a suggestion? We are more than happy to help you! Just open an issue in our [help repository](https://github.com/fastify/help).
12
+ Do you have a question or need some advice? We are more than happy to help you! Just open an issue in our [help repository](https://github.com/fastify/help).
13
13
 
14
14
  Once you submit a plugin to our [ecosystem list](Ecosystem.md), we will review your code and help you improve it if necessary.
15
15
 
@@ -33,7 +33,7 @@ Always put an example file in your repository. Examples are very helpful for use
33
33
  It is extremely important that a plugin is thoroughly tested to verify that is working properly.<br>
34
34
  A plugin without tests will not be accepted to the ecosystem list. A lack of tests does not inspire trust nor guarantee that the code will continue to work among different versions of its dependencies.
35
35
 
36
- We do not enforce any testing library. We use [`tap`](http://www.node-tap.org/) since it offers out of the box parallel testing and code coverage, but it is up to you to choose your library of preference.
36
+ We do not enforce any testing library. We use [`tap`](https://www.node-tap.org/) since it offers out of the box parallel testing and code coverage, but it is up to you to choose your library of preference.
37
37
 
38
38
  ## Code Linter
39
39
  It is not mandatory, but we highly recommend you use a code linter in your plugin. It will ensure a consistent code style and help you to avoid many errors.
@@ -41,8 +41,8 @@ It is not mandatory, but we highly recommend you use a code linter in your plugi
41
41
  We use [`standard`](https://standardjs.com/) since it works without the need to configure it and is very easy integrate in a test suite.
42
42
 
43
43
  ## Continuous Integration
44
- It is not mandatory, but if you release your code as open source it helps to use Continuous Integration to ensure contributions do not break your plugin and to show that the plugin works as intended. [Travis](https://travis-ci.org/) is free for open source projects and easy to setup.<br>
45
- In addition you can enable services like [Greenkeeper](https://greenkeeper.io/), that will help you keep your dependencies up to date and discover if a new release of Fastify has some issues with your plugin.
44
+ It is not mandatory, but if you release your code as open source it helps to use Continuous Integration to ensure contributions do not break your plugin and to show that the plugin works as intended. Both [CircleCI](https://circleci.com/) and [GitHub Actions](https://github.com/features/actions) are free for open source projects and easy to setup.<br>
45
+ In addition you can enable services like [Dependabot](https://dependabot.com/) or [Snyk](https://snyk.io/), that will help you keep your dependencies up to date and discover if a new release of Fastify has some issues with your plugin.
46
46
 
47
47
  ## Let's start!
48
48
  Awesome, now you know everything you need to know about how to write a good plugin for Fastify!
@@ -18,27 +18,27 @@ const opts = {
18
18
  }
19
19
 
20
20
  fastify
21
- .addHook('onRequest', function (request, reply, next) {
22
- next()
21
+ .addHook('onRequest', function (request, reply, done) {
22
+ done()
23
23
  })
24
- .addHook('onRequest', function (request, reply, next) {
25
- next()
24
+ .addHook('onRequest', function (request, reply, done) {
25
+ done()
26
26
  })
27
27
 
28
28
  fastify
29
- .addHook('preHandler', function (request, reply, next) {
30
- next()
29
+ .addHook('preHandler', function (request, reply, done) {
30
+ done()
31
31
  })
32
- .addHook('preHandler', function (request, reply, next) {
33
- setImmediate(next)
32
+ .addHook('preHandler', function (request, reply, done) {
33
+ setImmediate(done)
34
34
  })
35
- .addHook('preHandler', function (request, reply, next) {
36
- next()
35
+ .addHook('preHandler', function (request, reply, done) {
36
+ done()
37
37
  })
38
38
 
39
39
  fastify
40
- .addHook('onSend', function (request, reply, payload, next) {
41
- next()
40
+ .addHook('onSend', function (request, reply, payload, done) {
41
+ done()
42
42
  })
43
43
 
44
44
  fastify.get('/', opts, function (request, reply) {
package/examples/hooks.js CHANGED
@@ -33,37 +33,37 @@ const optsPost = {
33
33
  }
34
34
 
35
35
  fastify
36
- .addHook('onRequest', function (request, reply, next) {
36
+ .addHook('onRequest', function (request, reply, done) {
37
37
  console.log('onRequest')
38
- next()
38
+ done()
39
39
  })
40
- .addHook('preParsing', function (request, reply, next) {
40
+ .addHook('preParsing', function (request, reply, done) {
41
41
  console.log('preParsing')
42
- next()
42
+ done()
43
43
  })
44
- .addHook('preValidation', function (request, reply, next) {
44
+ .addHook('preValidation', function (request, reply, done) {
45
45
  console.log('preValidation')
46
- next()
46
+ done()
47
47
  })
48
- .addHook('preHandler', function (request, reply, next) {
48
+ .addHook('preHandler', function (request, reply, done) {
49
49
  console.log('preHandler')
50
- next()
50
+ done()
51
51
  })
52
- .addHook('preSerialization', function (request, reply, payload, next) {
52
+ .addHook('preSerialization', function (request, reply, payload, done) {
53
53
  console.log('preSerialization', payload)
54
- next()
54
+ done()
55
55
  })
56
- .addHook('onError', function (request, reply, error, next) {
56
+ .addHook('onError', function (request, reply, error, done) {
57
57
  console.log('onError', error.message)
58
- next()
58
+ done()
59
59
  })
60
- .addHook('onSend', function (request, reply, payload, next) {
60
+ .addHook('onSend', function (request, reply, payload, done) {
61
61
  console.log('onSend', payload)
62
- next()
62
+ done()
63
63
  })
64
- .addHook('onResponse', function (request, reply, next) {
64
+ .addHook('onResponse', function (request, reply, done) {
65
65
  console.log('onResponse')
66
- next()
66
+ done()
67
67
  })
68
68
  .addHook('onRoute', function (routeOptions) {
69
69
  console.log('onRoute')
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- module.exports = function (fastify, opts, next) {
3
+ module.exports = function (fastify, opts, done) {
4
4
  fastify
5
5
  .get('/', opts, function (req, reply) {
6
6
  reply.send({ hello: 'world' })
@@ -8,5 +8,5 @@ module.exports = function (fastify, opts, next) {
8
8
  .post('/', opts, function (req, reply) {
9
9
  reply.send({ hello: 'world' })
10
10
  })
11
- next()
11
+ done()
12
12
  }
@@ -15,20 +15,20 @@ const opts = {
15
15
  }
16
16
  }
17
17
 
18
- fastify.register(function (instance, options, next) {
18
+ fastify.register(function (instance, options, done) {
19
19
  // the route will be '/english/hello'
20
20
  instance.get('/hello', opts, (req, reply) => {
21
21
  reply.send({ greet: 'hello' })
22
22
  })
23
- next()
23
+ done()
24
24
  }, { prefix: '/english' })
25
25
 
26
- fastify.register(function (instance, options, next) {
26
+ fastify.register(function (instance, options, done) {
27
27
  // the route will be '/italian/hello'
28
28
  instance.get('/hello', opts, (req, reply) => {
29
29
  reply.send({ greet: 'ciao' })
30
30
  })
31
- next()
31
+ done()
32
32
  }, { prefix: '/italian' })
33
33
 
34
34
  fastify.listen(8000, function (err) {
package/fastify.d.ts CHANGED
@@ -83,6 +83,7 @@ export type FastifyServerOptions<
83
83
  bodyLimit?: number,
84
84
  maxParamLength?: number,
85
85
  disableRequestLogging?: boolean,
86
+ exposeHeadRoutes?: boolean,
86
87
  onProtoPoisoning?: 'error' | 'remove' | 'ignore',
87
88
  onConstructorPoisoning?: 'error' | 'remove' | 'ignore',
88
89
  logger?: boolean | FastifyLoggerOptions<RawServer> | Logger,
@@ -118,6 +119,20 @@ export type FastifyServerOptions<
118
119
 
119
120
  type TrustProxyFunction = (address: string, hop: number) => boolean
120
121
 
122
+ declare module 'fastify-error' {
123
+ interface FastifyError {
124
+ validation?: ValidationResult[];
125
+ }
126
+ }
127
+
128
+ export interface ValidationResult {
129
+ keyword: string;
130
+ dataPath: string;
131
+ schemaPath: string;
132
+ params: Record<string, string | string[]>;
133
+ message: string;
134
+ }
135
+
121
136
  /* Export all additional types */
122
137
  export { FastifyRequest, RequestGenericInterface } from './types/request'
123
138
  export { FastifyReply } from './types/reply'
@@ -128,7 +143,7 @@ export { FastifyContext } from './types/context'
128
143
  export { RouteHandler, RouteHandlerMethod, RouteOptions, RouteShorthandMethod, RouteShorthandOptions, RouteShorthandOptionsWithHandler } from './types/route'
129
144
  export * from './types/register'
130
145
  export { FastifyBodyParser, FastifyContentTypeParser, AddContentTypeParser, hasContentTypeParser } from './types/content-type-parser'
131
- export { FastifyError, ValidationResult } from 'fastify-error'
146
+ export { FastifyError } from 'fastify-error'
132
147
  export { FastifySchema, FastifySchemaCompiler } from './types/schema'
133
148
  export { HTTPMethods, RawServerBase, RawRequestDefaultExpression, RawReplyDefaultExpression, RawServerDefault, ContextConfigDefault, RequestBodyDefault, RequestQuerystringDefault, RequestParamsDefault, RequestHeadersDefault } from './types/utils'
134
149
  export * from './types/hooks'