fastify 2.7.1 → 2.11.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 (72) hide show
  1. package/README.md +15 -4
  2. package/build/build-validation.js +8 -0
  3. package/docs/Benchmarking.md +2 -2
  4. package/docs/ContentTypeParser.md +12 -10
  5. package/docs/Decorators.md +14 -14
  6. package/docs/Ecosystem.md +7 -1
  7. package/docs/Errors.md +13 -8
  8. package/docs/Fluent-Schema.md +9 -12
  9. package/docs/Getting-Started.md +29 -25
  10. package/docs/HTTP2.md +1 -1
  11. package/docs/Hooks.md +201 -186
  12. package/docs/LTS.md +6 -7
  13. package/docs/Logging.md +10 -10
  14. package/docs/Middleware.md +59 -0
  15. package/docs/Plugins-Guide.md +52 -52
  16. package/docs/Plugins.md +3 -0
  17. package/docs/Reply.md +47 -3
  18. package/docs/Routes.md +120 -8
  19. package/docs/Server.md +69 -3
  20. package/docs/Serverless.md +76 -4
  21. package/docs/TypeScript.md +33 -10
  22. package/docs/Validation-and-Serialization.md +137 -1
  23. package/examples/typescript-server.ts +1 -1
  24. package/fastify.d.ts +52 -13
  25. package/fastify.js +68 -7
  26. package/lib/configValidator.js +99 -52
  27. package/lib/contentTypeParser.js +4 -4
  28. package/lib/context.js +2 -1
  29. package/lib/errors.js +21 -18
  30. package/lib/fourOhFour.js +10 -10
  31. package/lib/handleRequest.js +1 -2
  32. package/lib/logger.js +2 -2
  33. package/lib/pluginUtils.js +32 -0
  34. package/lib/reply.js +41 -6
  35. package/lib/route.js +37 -9
  36. package/lib/schemas.js +23 -12
  37. package/lib/symbols.js +4 -1
  38. package/lib/validation.js +15 -9
  39. package/lib/wrapThenable.js +1 -1
  40. package/package.json +34 -26
  41. package/test/404s.test.js +41 -1
  42. package/test/async-await.js +66 -0
  43. package/test/custom-parser.test.js +1 -1
  44. package/test/custom-querystring-parser.test.js +1 -1
  45. package/test/decorator.test.js +48 -0
  46. package/test/emit-warning.test.js +3 -3
  47. package/test/fastify-instance.test.js +29 -0
  48. package/test/helper.js +7 -7
  49. package/test/hooks-async.js +4 -3
  50. package/test/hooks.test.js +27 -8
  51. package/test/input-validation.test.js +126 -0
  52. package/test/internals/errors.test.js +9 -1
  53. package/test/internals/initialConfig.test.js +4 -2
  54. package/test/internals/plugin.test.js +4 -4
  55. package/test/internals/reply.test.js +78 -6
  56. package/test/internals/schemas.test.js +30 -0
  57. package/test/internals/validation.test.js +18 -0
  58. package/test/listen.test.js +1 -1
  59. package/test/logger.test.js +314 -1
  60. package/test/plugin.test.js +171 -0
  61. package/test/promises.test.js +55 -0
  62. package/test/proto-poisoning.test.js +76 -0
  63. package/test/route-hooks.test.js +109 -91
  64. package/test/route-prefix.test.js +1 -1
  65. package/test/schemas.test.js +450 -0
  66. package/test/shared-schemas.test.js +2 -2
  67. package/test/stream.test.js +10 -6
  68. package/test/throw.test.js +48 -2
  69. package/test/types/index.ts +86 -1
  70. package/test/validation-error-handling.test.js +3 -3
  71. package/test/versioned-routes.test.js +1 -1
  72. package/docs/Middlewares.md +0 -59
package/docs/Routes.md CHANGED
@@ -1,14 +1,34 @@
1
1
  <h1 align="center">Fastify</h1>
2
2
 
3
3
  ## Routes
4
- You have two ways to declare a route with Fastify, the shorthand method and the full declaration. Let's start with the second one:
4
+
5
+ The routes methods will configure the endpoints of your application.
6
+ You have two ways to declare a route with Fastify, the shorthand method and the full declaration.
7
+
8
+ - [Full Declaration](#full-declaration)
9
+ - [Route Options](#options)
10
+ - [Shorthand Declaration](#shorthand-declaration)
11
+ - [URL Parameters](#url-building)
12
+ - [Use `async`/`await`](#async-await)
13
+ - [Promise resolution](#promise-resolution)
14
+ - [Route Prefixing](#route-prefixing)
15
+ - Logs
16
+ - [Custom Log Level](#custom-log-level)
17
+ - [Custom Log Serializer](#custom-log-serializer)
18
+ - [Route handler configuration](#routes-config)
19
+ - [Route's Versioning](#version)
20
+
5
21
  <a name="full-declaration"></a>
6
22
  ### Full declaration
23
+
7
24
  ```js
8
25
  fastify.route(options)
9
26
  ```
10
- * `method`: currently it supports `'DELETE'`, `'GET'`, `'HEAD'`, `'PATCH'`, `'POST'`, `'PUT'` and `'OPTIONS'`. It could also be an array of methods.
11
27
 
28
+ <a name="options"></a>
29
+ ### Routes option
30
+
31
+ * `method`: currently it supports `'DELETE'`, `'GET'`, `'HEAD'`, `'PATCH'`, `'POST'`, `'PUT'` and `'OPTIONS'`. It could also be an array of methods.
12
32
  * `url`: the path of the url to match this route (alias: `path`).
13
33
  * `schema`: an object containing the schemas for the request and response.
14
34
  They need to be in
@@ -23,14 +43,18 @@ They need to be in
23
43
  * `response`: filter and generate a schema for the response, setting a
24
44
  schema allows us to have 10-20% more throughput.
25
45
  * `attachValidation`: attach `validationError` to request, if there is a schema validation error, instead of sending the error to the error handler.
26
- * `onRequest(request, reply, done)`: a [function](https://github.com/fastify/fastify/blob/master/docs/Hooks.md#route-hooks) as soon that a request is received, it could also be an array of functions.
27
- * `preValidation(request, reply, done)`: a [function](https://github.com/fastify/fastify/blob/master/docs/Hooks.md#route-hooks) called after the shared `preValidation` hooks, useful if you need to perform authentication at route level for example, it could also be an array of functions.
28
- * `preHandler(request, reply, done)`: a [function](https://github.com/fastify/fastify/blob/master/docs/Hooks.md#route-hooks) called just before the request handler, it could also be an array of functions.
29
- * `preSerialization(request, reply, payload, done)`: a [function](https://github.com/fastify/fastify/blob/master/docs/Hooks.md#route-hooks) called just before the serialization, it could also be an array of functions.
46
+ * `onRequest(request, reply, done)`: a [function](https://github.com/fastify/fastify/blob/master/docs/Hooks.md#onrequest) as soon that a request is received, it could also be an array of functions.
47
+ * `preParsing(request, reply, done)`: a [function](https://github.com/fastify/fastify/blob/master/docs/Hooks.md#preparsing) called before parsing the request, it could also be an array of functions.
48
+ * `preValidation(request, reply, done)`: a [function](https://github.com/fastify/fastify/blob/master/docs/Hooks.md#prevalidation) called after the shared `preValidation` hooks, useful if you need to perform authentication at route level for example, it could also be an array of functions.
49
+ * `preHandler(request, reply, done)`: a [function](https://github.com/fastify/fastify/blob/master/docs/Hooks.md#prehandler) called just before the request handler, it could also be an array of functions.
50
+ * `preSerialization(request, reply, payload, done)`: a [function](https://github.com/fastify/fastify/blob/master/docs/Hooks.md#preserialization) called just before the serialization, it could also be an array of functions.
51
+ * `onSend(request, reply, payload, done)`: a [function](https://github.com/fastify/fastify/blob/master/docs/Hooks.md#route-hooks) called right before a response is sent, it could also be an array of functions.
52
+ * `onResponse(request, reply, payload, done)`: a [function](https://github.com/fastify/fastify/blob/master/docs/Hooks.md#onresponse) called when a response has been sent, so you will not be able to send more data to the client. It could also be an array of functions.
30
53
  * `handler(request, reply)`: the function that will handle this request.
31
54
  * `schemaCompiler(schema)`: the function that build the schema for the validations. See [here](https://github.com/fastify/fastify/blob/master/docs/Validation-and-Serialization.md#schema-compiler)
32
55
  * `bodyLimit`: prevents the default JSON body parser from parsing request bodies larger than this number of bytes. Must be an integer. You may also set this option globally when first creating the Fastify instance with `fastify(options)`. Defaults to `1048576` (1 MiB).
33
56
  * `logLevel`: set log level for this route. See below.
57
+ * `logSerializers`: set serializers to log for this route.
34
58
  * `config`: object used to store custom configuration.
35
59
  * `version`: a [semver](http://semver.org/) compatible string that defined the version of the endpoint. [Example](https://github.com/fastify/fastify/blob/master/docs/Routes.md#version).
36
60
  * `prefixTrailingSlash`: string used to determine how to handle passing `/` as a route with a prefix.
@@ -168,7 +192,6 @@ fastify.get('/', options, async function (request, reply) {
168
192
  return processed
169
193
  })
170
194
  ```
171
- **Warning:** You can't return `undefined`. For more details read [promise-resolution](#promise-resolution).
172
195
 
173
196
  As you can see we are not calling `reply.send` to send back the data to the user. You just need to return the body and you are done!
174
197
 
@@ -180,8 +203,32 @@ fastify.get('/', options, async function (request, reply) {
180
203
  reply.send(processed)
181
204
  })
182
205
  ```
206
+
207
+ If the route is wrapping a callback-based API that will call
208
+ `reply.send()` outside of the promise chain, it is possible to `await reply`:
209
+
210
+ ```js
211
+ fastify.get('/', options, async function (request, reply) {
212
+ setImmediate(() => {
213
+ reply.send({ hello: 'world' })
214
+ })
215
+ await reply
216
+ })
217
+ ```
218
+
219
+ Returning reply also works:
220
+
221
+ ```js
222
+ fastify.get('/', options, async function (request, reply) {
223
+ setImmediate(() => {
224
+ reply.send({ hello: 'world' })
225
+ })
226
+ return reply
227
+ })
228
+ ```
229
+
183
230
  **Warning:**
184
- * If you use `return` and `reply.send` at the same time, the first one that happens takes precedence, the second value will be discarded, a *warn* log will also be emitted because you tried to send a response twice.
231
+ * When using both `return value` and `reply.send(value)` at the same time, the first one that happens takes precedence, the second value will be discarded, and a *warn* log will also be emitted because you tried to send a response twice.
185
232
  * You can't return `undefined`. For more details read [promise-resolution](#promise-resolution).
186
233
 
187
234
  <a name="promise-resolution"></a>
@@ -214,6 +261,7 @@ fastify.register(require('./routes/v2/users'), { prefix: '/v2' })
214
261
 
215
262
  fastify.listen(3000)
216
263
  ```
264
+
217
265
  ```js
218
266
  // routes/v1/users.js
219
267
  module.exports = function (fastify, opts, done) {
@@ -221,6 +269,7 @@ module.exports = function (fastify, opts, done) {
221
269
  done()
222
270
  }
223
271
  ```
272
+
224
273
  ```js
225
274
  // routes/v2/users.js
226
275
  module.exports = function (fastify, opts, done) {
@@ -263,6 +312,7 @@ fastify.register(require('./routes/events'), { logLevel: 'debug' })
263
312
 
264
313
  fastify.listen(3000)
265
314
  ```
315
+
266
316
  Or you can directly pass it to a route:
267
317
  ```js
268
318
  fastify.get('/', { logLevel: 'warn' }, (request, reply) => {
@@ -271,6 +321,64 @@ fastify.get('/', { logLevel: 'warn' }, (request, reply) => {
271
321
  ```
272
322
  *Remember that the custom log level is applied only to the routes, and not to the global Fastify Logger, accessible with `fastify.log`*
273
323
 
324
+ <a name="custom-log-serializer"></a>
325
+ ### Custom Log Serializer
326
+
327
+ In some context, you may need to log a large object but it could be a waste of resources for some routes. In this case, you can define some [`serializer`](https://github.com/pinojs/pino/blob/master/docs/api.md#bindingsserializers-object) and attach them in the right context!
328
+
329
+ ```js
330
+ const fastify = require('fastify')({ logger: true })
331
+
332
+ fastify.register(require('./routes/user'), {
333
+ logSerializers: {
334
+ user: (value) => `My serializer one - ${value.name}`
335
+ }
336
+ })
337
+ fastify.register(require('./routes/events'), {
338
+ logSerializers: {
339
+ user: (value) => `My serializer two - ${value.name} ${value.surname}`
340
+ }
341
+ })
342
+
343
+ fastify.listen(3000)
344
+ ```
345
+
346
+ You can inherit serializers by context:
347
+
348
+ ```js
349
+ const fastify = Fastify({
350
+ logger: {
351
+ level: 'info',
352
+ serializers: {
353
+ user (req) {
354
+ return {
355
+ method: req.method,
356
+ url: req.url,
357
+ headers: req.headers,
358
+ hostname: req.hostname,
359
+ remoteAddress: req.ip,
360
+ remotePort: req.connection.remotePort
361
+ }
362
+ }
363
+ }
364
+ }
365
+ })
366
+
367
+ fastify.register(context1, {
368
+ logSerializers: {
369
+ user: value => `My serializer father - ${value}`
370
+ }
371
+ })
372
+
373
+ async function context1 (fastify, opts) {
374
+ fastify.get('/', (req, reply) => {
375
+ req.log.info({ user: 'call father serializer', key: 'another key' }) // shows: { user: 'My serializer father - call father serializer', key: 'another key' }
376
+ reply.send({})
377
+ })
378
+ }
379
+
380
+ fastify.listen(3000)
381
+ ```
274
382
 
275
383
  <a name="routes-config"></a>
276
384
  ### Config
@@ -292,10 +400,12 @@ fastify.listen(3000)
292
400
 
293
401
  <a name="version"></a>
294
402
  ### Version
403
+
295
404
  #### Default
296
405
  If needed you can provide a version option, which will allow you to declare multiple versions of the same route. The versioning should follow the [semver](http://semver.org/) specification.<br/>
297
406
  Fastify will automatically detect the `Accept-Version` header and route the request accordingly (advanced ranges and pre-releases currently are not supported).<br/>
298
407
  *Be aware that using this feature will cause a degradation of the overall performances of the router.*
408
+
299
409
  ```js
300
410
  fastify.route({
301
411
  method: 'GET',
@@ -316,7 +426,9 @@ fastify.inject({
316
426
  // { hello: 'world' }
317
427
  })
318
428
  ```
429
+
319
430
  If you declare multiple versions with the same major or minor, Fastify will always choose the highest compatible with the `Accept-Version` header value.<br/>
320
431
  If the request will not have the `Accept-Version` header, a 404 error will be returned.
432
+
321
433
  #### Custom
322
434
  It's possible to define a custom versioning logic. This can be done through the [`versioning`](https://github.com/fastify/fastify/blob/master/docs/Server.md#versioning) configuration, when creating a fastify server instance.
package/docs/Server.md CHANGED
@@ -75,7 +75,7 @@ Defines the maximum payload, in bytes, the server is allowed to accept.
75
75
 
76
76
  Defines what action the framework must take when parsing a JSON object
77
77
  with `__proto__`. This functionality is provided by
78
- [bourne](https://github.com/hapijs/bourne).
78
+ [secure-json-parse](https://github.com/fastify/secure-json-parse).
79
79
  See https://hueniverse.com/a-tale-of-prototype-poisoning-2610fa170061
80
80
  for more details about prototype poisoning attacks.
81
81
 
@@ -83,6 +83,19 @@ Possible values are `'error'`, `'remove'` and `'ignore'`.
83
83
 
84
84
  + Default: `'error'`
85
85
 
86
+ <a name="factory-on-constructor-poisoning"></a>
87
+ ### `onConstructorPoisoning`
88
+
89
+ Defines what action the framework must take when parsing a JSON object
90
+ with `constructor`. This functionality is provided by
91
+ [secure-json-parse](https://github.com/fastify/secure-json-parse).
92
+ See https://hueniverse.com/a-tale-of-prototype-poisoning-2610fa170061
93
+ for more details about prototype poisoning attacks.
94
+
95
+ Possible values are `'error'`, `'remove'` and `'ignore'`.
96
+
97
+ + Default: `'ignore'`
98
+
86
99
  <a name="factory-logger"></a>
87
100
  ### `logger`
88
101
 
@@ -104,7 +117,7 @@ are not present on the object, they will be added accordingly:
104
117
  for incoming requests. The default function generates sequential identifiers.
105
118
  * `level`: the minimum logging level. If not set, it will be set to `'info'`.
106
119
  * `serializers`: a hash of serialization functions. By default, serializers
107
- are added for `req` (incoming request objects), `res` (outgoing repsonse
120
+ are added for `req` (incoming request objects), `res` (outgoing response
108
121
  objets), and `err` (standard `Error` objects). When a log method receives
109
122
  an object with any of these properties then the respective serializer will
110
123
  be used for that property. For example:
@@ -360,6 +373,42 @@ If `false`, the server routes the incoming request as usual.
360
373
 
361
374
  + Default: `true`
362
375
 
376
+ <a name="factory-ajv"></a>
377
+ ### `ajv`
378
+
379
+ Configure the ajv instance used by Fastify without providing a custom one.
380
+
381
+ + Default:
382
+
383
+ ```js
384
+ {
385
+ customOptions: {
386
+ removeAdditional: true,
387
+ useDefaults: true,
388
+ coerceTypes: true,
389
+ allErrors: true,
390
+ nullable: true
391
+ },
392
+ plugins: []
393
+ }
394
+ ```
395
+
396
+ ```js
397
+ const fastify = require('fastify')({
398
+ ajv: {
399
+ customOptions: {
400
+ nullable: false // Refer to [ajv options](https://ajv.js.org/#options)
401
+ },
402
+ plugins: [
403
+ require('ajv-merge-patch')
404
+ [require('ajv-keywords'), 'instanceof'];
405
+ // Usage: [plugin, pluginOptions] - Plugin with options
406
+ // Usage: plugin - Plugin without options
407
+ ]
408
+ }
409
+ })
410
+ ```
411
+
363
412
  ## Instance
364
413
 
365
414
  ### Server Methods
@@ -547,7 +596,7 @@ A plugin can be a set of routes, a server decorator or whatever, check [here](ht
547
596
 
548
597
  <a name="use"></a>
549
598
  #### use
550
- Function to add middlewares to Fastify, check [here](https://github.com/fastify/fastify/blob/master/docs/Middlewares.md).
599
+ Function to add middlewares to Fastify, check [here](https://github.com/fastify/fastify/blob/master/docs/Middleware.md).
551
600
 
552
601
  <a name="addHook"></a>
553
602
  #### addHook
@@ -581,6 +630,18 @@ fastify.register(function (instance, opts, done) {
581
630
  }, { prefix: '/v1' })
582
631
  ```
583
632
 
633
+ <a name="pluginName"></a>
634
+ #### pluginName
635
+ Name of the current plugin. There are three ways to define a name (in order).
636
+
637
+ 1. If you use [fastify-plugin](https://github.com/fastify/fastify-plugin) the metadata `name` is used.
638
+ 2. If you `module.exports` a plugin the filename is used.
639
+ 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.
640
+
641
+ *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.
642
+
643
+ 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`.
644
+
584
645
  <a name="log"></a>
585
646
  #### log
586
647
  The logger instance, check [here](https://github.com/fastify/fastify/blob/master/docs/Logging.md).
@@ -610,6 +671,11 @@ fastify.setReplySerializer(function (payload, statusCode){
610
671
  #### setSchemaCompiler
611
672
  Set the schema compiler for all routes [here](https://github.com/fastify/fastify/blob/master/docs/Validation-and-Serialization.md#schema-compiler).
612
673
 
674
+ <a name="set-schema-resolver"></a>
675
+ #### setSchemaResolver
676
+ Set the schema `$ref` resolver for all routes [here](https://github.com/fastify/fastify/blob/master/docs/Validation-and-Serialization.md#schema-resolver).
677
+
678
+
613
679
  <a name="schema-compiler"></a>
614
680
  #### schemaCompiler
615
681
  This property can be used to set the schema compiler, it is a shortcut for the `setSchemaCompiler` method, and get the schema compiler back for all routes.
@@ -6,6 +6,7 @@ Run serverless applications and REST APIs using your existing Fastify applicatio
6
6
 
7
7
  - [AWS Lambda](#aws-lambda)
8
8
  - [Google Cloud Run](#google-cloud-run)
9
+ - [Zeit Now](#zeit-now)
9
10
 
10
11
  ### Attention Readers:
11
12
  > Fastify is not designed to run on serverless environments.
@@ -35,7 +36,7 @@ function init() {
35
36
  return app;
36
37
  }
37
38
 
38
- if (require.main !== module) {
39
+ if (require.main === module) {
39
40
  // called directly i.e. "node app"
40
41
  init().listen(3000, (err) => {
41
42
  if (err) console.error(err);
@@ -93,9 +94,9 @@ An example deployable with [claudia.js](https://claudiajs.com/tutorials/serverle
93
94
 
94
95
  ## Google Cloud Run
95
96
 
96
- Unlike AWS Lambda or Google Cloud Functions, Google Cloud Run is a serverless **container** environment. It's primary purpose is to provide an infrastucture-abstracted environment to run arbitrary containers. As a result, Fastify can be deployed to Google Cloud Run with little-to-no code changes from the way you would write your Fastify app normally.
97
+ Unlike AWS Lambda or Google Cloud Functions, Google Cloud Run is a serverless **container** environment. It's primary purpose is to provide an infrastructure-abstracted environment to run arbitrary containers. As a result, Fastify can be deployed to Google Cloud Run with little-to-no code changes from the way you would write your Fastify app normally.
97
98
 
98
- *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)*
99
+ *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)*.
99
100
 
100
101
  ### Adjust Fastfiy server
101
102
 
@@ -175,7 +176,7 @@ npm-debug.log
175
176
 
176
177
  ### Submit build
177
178
 
178
- Next, submit your app to be built into a Docker image by running the following command (replacing `PROJECT-ID` and `APP-NAME` with your GCP project id and an app name:
179
+ Next, submit your app to be built into a Docker image by running the following command (replacing `PROJECT-ID` and `APP-NAME` with your GCP project id and an app name):
179
180
 
180
181
  ```bash
181
182
  gcloud builds submit --tag gcr.io/PROJECT-ID/APP-NAME
@@ -190,3 +191,74 @@ gcloud beta run deploy --image gcr.io/PROJECT-ID/APP-NAME --platform managed
190
191
  ```
191
192
 
192
193
  Your app will be accessible from the URL GCP provides.
194
+
195
+ ## Zeit Now
196
+
197
+ [now](https://zeit.co/home) provides zero configuration deployment for
198
+ Node.js applications. In order to use now, it is as simple as
199
+ configuring your `now.json` file like the following:
200
+
201
+ ```json
202
+ {
203
+ "version": 2,
204
+ "builds": [
205
+ {
206
+ "src": "api/serverless.js",
207
+ "use": "@now/node",
208
+ "config": {
209
+ "helpers": false
210
+ }
211
+ }
212
+ ],
213
+ "routes": [
214
+ { "src": "/.*", "dest": "/api/serverless.js"}
215
+ ]
216
+ }
217
+ ```
218
+
219
+ Then, write a `api/serverless.js` like so:
220
+
221
+ ```js
222
+ 'use strict'
223
+
224
+ const build = require('./index')
225
+
226
+ const app = build()
227
+
228
+ module.exports = async function (req, res) {
229
+ await app.ready()
230
+ app.server.emit('request', req, res)
231
+ }
232
+ ```
233
+
234
+ And a `api/index.js` file:
235
+
236
+ ```js
237
+ 'use strict'
238
+
239
+ const fastify = require('fastify')
240
+
241
+ function build () {
242
+ const app = fastify({
243
+ logger: true
244
+ })
245
+
246
+ app.get('/', async (req, res) => {
247
+ const { name = 'World' } = req.query
248
+ req.log.info({ name }, 'hello world!')
249
+ return `Hello ${name}!`
250
+ })
251
+
252
+ return app
253
+ }
254
+
255
+ module.exports = build
256
+ ```
257
+
258
+ Note that you'll need to use Node 10 by setting it in `package.json`:
259
+
260
+ ```js
261
+ "engines": {
262
+ "node": "10.x"
263
+ },
264
+ ```
@@ -7,7 +7,7 @@ Fastify is shipped with a typings file, but you may need to install `@types/node
7
7
  ## Types support
8
8
  We do care about the TypeScript community, and one of our core team members is currently reworking all types.
9
9
  We do our best to have the typings updated with the latest version of the API, but *it can happen* that the typings are not in sync.<br/>
10
- Luckly this is Open Source and you can contribute to fix them, we will be very happy to accept the fix and release it as soon as possible as a patch release. Checkout the [contributing](#contributing) rules!
10
+ Luckily this is Open Source and you can contribute to fix them, we will be very happy to accept the fix and release it as soon as possible as a patch release. Checkout the [contributing](#contributing) rules!
11
11
 
12
12
  Plugins may or may not include typings. See [Plugin Types](#plugin-types) for more information.
13
13
 
@@ -21,6 +21,7 @@ import { Server, IncomingMessage, ServerResponse } from 'http'
21
21
  // Create a http server. We pass the relevant typings for our http version used.
22
22
  // By passing types we get correctly typed access to the underlying http objects in routes.
23
23
  // If using http2 we'd pass <http2.Http2Server, http2.Http2ServerRequest, http2.Http2ServerResponse>
24
+ // For https pass http2.Http2SecureServer or http.SecureServer instead of Server.
24
25
  const server: fastify.FastifyInstance<Server, IncomingMessage, ServerResponse> = fastify({})
25
26
 
26
27
  const opts: fastify.RouteShorthandOptions = {
@@ -106,7 +107,7 @@ const opts: fastify.RouteShorthandOptions = {
106
107
  }
107
108
  }
108
109
 
109
- server.get<Query, Params, Body, Headers>('/ping/:bar', opts, (request, reply) => {
110
+ server.get<Query, Params, Headers, Body>('/ping/:bar', opts, (request, reply) => {
110
111
  console.log(request.query) // this is of type Query!
111
112
  console.log(request.params) // this is of type Params!
112
113
  console.log(request.body) // this is of type Body!
@@ -204,7 +205,7 @@ When updating core types you should make a PR to this repository. Ensure you:
204
205
  <a id="plugin-types"></a>
205
206
  ### Plugin Types
206
207
 
207
- Plugins maintained by and orginized under the fastify organization on GitHub should ship with typings just like fastify itself does.
208
+ Plugins maintained by and organized under the fastify organization on GitHub should ship with typings just like fastify itself does.
208
209
  Some plugins already include typings but many do not. We are happy to accept contributions to those plugins without any typings, see [fastify-cors](https://github.com/fastify/fastify-cors) for an example of a plugin that comes with it's own typings.
209
210
 
210
211
  Typings for third-party-plugins may either be included with the plugin or hosted on DefinitelyTyped. Remember, if you author a plugin to either include typings or publish them on DefinitelyTyped! Information of how to install typings from DefinitelyTyped can be found [here](https://github.com/DefinitelyTyped/DefinitelyTyped#npm).
@@ -218,26 +219,43 @@ Typings for many plugins that extend the `FastifyRequest`, `FastifyReply` or `Fa
218
219
  This code shows the typings for the `fastify-static` plugin.
219
220
 
220
221
  ```ts
222
+ /// <reference types="node" />
223
+
221
224
  // require fastify typings
222
- import fastify = require("fastify");
223
- // require necessary http typings
225
+ import * as fastify from 'fastify';
226
+
227
+ // require necessary http, http2, https typings
224
228
  import { Server, IncomingMessage, ServerResponse } from "http";
229
+ import { Http2SecureServer, Http2Server, Http2ServerRequest, Http2ServerResponse } from "http2";
230
+ import * as https from "https";
231
+
232
+ type HttpServer = Server | Http2Server | Http2SecureServer | https.Server;
233
+ type HttpRequest = IncomingMessage | Http2ServerRequest;
234
+ type HttpResponse = ServerResponse | Http2ServerResponse;
225
235
 
226
236
  // extend fastify typings
227
237
  declare module "fastify" {
228
- interface FastifyReply<HttpResponse> {
229
- sendFile(filename: string): FastifyReply<HttpResponse>;
230
- }
238
+ interface FastifyReply<HttpResponse> {
239
+ sendFile(filename: string): FastifyReply<HttpResponse>;
240
+ }
231
241
  }
232
242
 
233
243
  // declare plugin type using fastify.Plugin
234
- declare const fastifyStatic: fastify.Plugin<Server, IncomingMessage, ServerResponse, {
244
+ declare function fastifyStatic(): fastify.Plugin<
245
+ Server,
246
+ IncomingMessage,
247
+ ServerResponse,
248
+ {
235
249
  root: string;
236
250
  prefix?: string;
237
251
  serve?: boolean;
238
252
  decorateReply?: boolean;
239
253
  schemaHide?: boolean;
240
254
  setHeaders?: (...args: any[]) => void;
255
+ redirect?: boolean;
256
+ wildcard?: boolean | string;
257
+
258
+ // Passed on to `send`
241
259
  acceptRanges?: boolean;
242
260
  cacheControl?: boolean;
243
261
  dotfiles?: boolean;
@@ -247,7 +265,12 @@ declare const fastifyStatic: fastify.Plugin<Server, IncomingMessage, ServerRespo
247
265
  index?: string[];
248
266
  lastModified?: boolean;
249
267
  maxAge?: string | number;
250
- }>;
268
+ }
269
+ >;
270
+
271
+ declare namespace fastifyStatic {
272
+ interface FastifyStaticOptions {}
273
+ }
251
274
 
252
275
  // export plugin type
253
276
  export = fastifyStatic;