fastify 3.27.2 → 4.0.0-alpha.1

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 (116) hide show
  1. package/README.md +5 -4
  2. package/build/build-error-serializer.js +27 -0
  3. package/build/build-validation.js +47 -35
  4. package/docs/Migration-Guide-V4.md +12 -0
  5. package/docs/Reference/ContentTypeParser.md +4 -0
  6. package/docs/Reference/Errors.md +51 -6
  7. package/docs/Reference/Hooks.md +4 -7
  8. package/docs/Reference/LTS.md +5 -4
  9. package/docs/Reference/Reply.md +23 -22
  10. package/docs/Reference/Request.md +1 -3
  11. package/docs/Reference/Routes.md +17 -10
  12. package/docs/Reference/Server.md +48 -63
  13. package/docs/Reference/TypeScript.md +11 -13
  14. package/docs/Reference/Validation-and-Serialization.md +28 -53
  15. package/docs/Type-Providers.md +257 -0
  16. package/examples/hooks.js +1 -1
  17. package/examples/simple-stream.js +18 -0
  18. package/fastify.d.ts +34 -22
  19. package/fastify.js +37 -35
  20. package/lib/configValidator.js +902 -1023
  21. package/lib/contentTypeParser.js +6 -16
  22. package/lib/context.js +36 -10
  23. package/lib/decorate.js +3 -1
  24. package/lib/error-handler.js +158 -0
  25. package/lib/error-serializer.js +257 -0
  26. package/lib/errors.js +43 -9
  27. package/lib/fourOhFour.js +31 -20
  28. package/lib/handleRequest.js +10 -13
  29. package/lib/hooks.js +14 -9
  30. package/lib/pluginOverride.js +0 -3
  31. package/lib/pluginUtils.js +3 -2
  32. package/lib/reply.js +28 -157
  33. package/lib/request.js +13 -10
  34. package/lib/route.js +131 -138
  35. package/lib/schema-controller.js +2 -2
  36. package/lib/schemas.js +27 -1
  37. package/lib/server.js +219 -116
  38. package/lib/symbols.js +4 -3
  39. package/lib/validation.js +2 -1
  40. package/lib/warnings.js +2 -12
  41. package/lib/wrapThenable.js +4 -11
  42. package/package.json +31 -35
  43. package/test/404s.test.js +243 -110
  44. package/test/500s.test.js +2 -2
  45. package/test/async-await.test.js +13 -69
  46. package/test/content-parser.test.js +32 -0
  47. package/test/context-config.test.js +52 -0
  48. package/test/custom-http-server.test.js +14 -7
  49. package/test/custom-parser-async.test.js +0 -65
  50. package/test/custom-parser.test.js +54 -121
  51. package/test/decorator.test.js +1 -3
  52. package/test/delete.test.js +5 -5
  53. package/test/encapsulated-error-handler.test.js +50 -0
  54. package/test/esm/index.test.js +0 -14
  55. package/test/fastify-instance.test.js +4 -4
  56. package/test/fluent-schema.test.js +4 -4
  57. package/test/get.test.js +3 -3
  58. package/test/helper.js +18 -3
  59. package/test/hooks-async.test.js +14 -47
  60. package/test/hooks.on-ready.test.js +9 -4
  61. package/test/hooks.test.js +58 -99
  62. package/test/http2/closing.test.js +5 -11
  63. package/test/http2/unknown-http-method.test.js +3 -9
  64. package/test/https/custom-https-server.test.js +12 -6
  65. package/test/input-validation.js +2 -2
  66. package/test/internals/handleRequest.test.js +3 -40
  67. package/test/internals/initialConfig.test.js +33 -12
  68. package/test/internals/reply.test.js +245 -3
  69. package/test/internals/request.test.js +13 -7
  70. package/test/internals/server.test.js +88 -0
  71. package/test/listen.test.js +84 -1
  72. package/test/logger.test.js +80 -40
  73. package/test/maxRequestsPerSocket.test.js +6 -4
  74. package/test/middleware.test.js +2 -25
  75. package/test/nullable-validation.test.js +51 -14
  76. package/test/plugin.test.js +31 -5
  77. package/test/pretty-print.test.js +22 -10
  78. package/test/reply-error.test.js +123 -12
  79. package/test/request-error.test.js +2 -5
  80. package/test/route-hooks.test.js +17 -17
  81. package/test/route-prefix.test.js +2 -1
  82. package/test/route.test.js +204 -20
  83. package/test/router-options.test.js +1 -1
  84. package/test/schema-examples.test.js +11 -5
  85. package/test/schema-feature.test.js +24 -19
  86. package/test/schema-serialization.test.js +9 -9
  87. package/test/schema-special-usage.test.js +14 -81
  88. package/test/schema-validation.test.js +9 -9
  89. package/test/skip-reply-send.test.js +1 -1
  90. package/test/stream.test.js +23 -12
  91. package/test/throw.test.js +8 -5
  92. package/test/type-provider.test.js +20 -0
  93. package/test/types/fastify.test-d.ts +10 -18
  94. package/test/types/import.js +2 -0
  95. package/test/types/import.ts +1 -0
  96. package/test/types/instance.test-d.ts +35 -14
  97. package/test/types/logger.test-d.ts +44 -15
  98. package/test/types/route.test-d.ts +8 -2
  99. package/test/types/schema.test-d.ts +2 -39
  100. package/test/types/type-provider.test-d.ts +417 -0
  101. package/test/validation-error-handling.test.js +8 -8
  102. package/test/versioned-routes.test.js +28 -16
  103. package/test/wrapThenable.test.js +7 -6
  104. package/types/content-type-parser.d.ts +17 -8
  105. package/types/hooks.d.ts +102 -59
  106. package/types/instance.d.ts +124 -104
  107. package/types/logger.d.ts +18 -104
  108. package/types/plugin.d.ts +10 -4
  109. package/types/reply.d.ts +16 -11
  110. package/types/request.d.ts +10 -5
  111. package/types/route.d.ts +42 -31
  112. package/types/schema.d.ts +1 -1
  113. package/types/type-provider.d.ts +99 -0
  114. package/types/utils.d.ts +1 -1
  115. package/lib/schema-compilers.js +0 -12
  116. package/test/emit-warning.test.js +0 -166
@@ -70,8 +70,8 @@ test('fastify instance get invalid ajv options.plugins', t => {
70
70
  test('fastify instance should contain default errorHandler', t => {
71
71
  t.plan(3)
72
72
  const fastify = Fastify()
73
- t.ok(fastify[kErrorHandler] instanceof Function)
74
- t.same(fastify.errorHandler, fastify[kErrorHandler])
73
+ t.ok(fastify[kErrorHandler].func instanceof Function)
74
+ t.same(fastify.errorHandler, fastify[kErrorHandler].func)
75
75
  t.same(Object.getOwnPropertyDescriptor(fastify, 'errorHandler').set, undefined)
76
76
  })
77
77
 
@@ -94,6 +94,6 @@ test('errorHandler in plugin should be separate from the external one', async t
94
94
 
95
95
  await fastify.ready()
96
96
 
97
- t.ok(fastify[kErrorHandler] instanceof Function)
98
- t.same(fastify.errorHandler, fastify[kErrorHandler])
97
+ t.ok(fastify[kErrorHandler].func instanceof Function)
98
+ t.same(fastify.errorHandler, fastify[kErrorHandler].func)
99
99
  })
@@ -34,7 +34,7 @@ test('use fluent-json-schema object', t => {
34
34
  }, (err, res) => {
35
35
  t.error(err)
36
36
  t.equal(res.statusCode, 400)
37
- t.same(res.json(), { statusCode: 400, error: 'Bad Request', message: 'params.id should be >= 42' })
37
+ t.same(res.json(), { statusCode: 400, error: 'Bad Request', message: 'params/id must be >= 42' })
38
38
  })
39
39
 
40
40
  // check header
@@ -47,7 +47,7 @@ test('use fluent-json-schema object', t => {
47
47
  }, (err, res) => {
48
48
  t.error(err)
49
49
  t.equal(res.statusCode, 400)
50
- t.same(res.json(), { statusCode: 400, error: 'Bad Request', message: 'headers[\'x-custom\'] should match format "email"' })
50
+ t.same(res.json(), { statusCode: 400, error: 'Bad Request', message: 'headers/x-custom must match format "email"' })
51
51
  })
52
52
 
53
53
  // check query
@@ -60,7 +60,7 @@ test('use fluent-json-schema object', t => {
60
60
  }, (err, res) => {
61
61
  t.error(err)
62
62
  t.equal(res.statusCode, 400)
63
- t.same(res.json(), { statusCode: 400, error: 'Bad Request', message: 'querystring should have required property \'surname\'' })
63
+ t.same(res.json(), { statusCode: 400, error: 'Bad Request', message: 'querystring must have required property \'surname\'' })
64
64
  })
65
65
 
66
66
  // check body
@@ -73,7 +73,7 @@ test('use fluent-json-schema object', t => {
73
73
  }, (err, res) => {
74
74
  t.error(err)
75
75
  t.equal(res.statusCode, 400)
76
- t.same(res.json(), { statusCode: 400, error: 'Bad Request', message: 'body.name should be string' })
76
+ t.same(res.json(), { statusCode: 400, error: 'Bad Request', message: 'body/name must be string' })
77
77
  })
78
78
 
79
79
  // check response
package/test/get.test.js CHANGED
@@ -243,7 +243,7 @@ fastify.listen(0, err => {
243
243
  t.equal(response.statusCode, 400)
244
244
  t.same(JSON.parse(body), {
245
245
  error: 'Bad Request',
246
- message: 'params.test should be integer',
246
+ message: 'params/test must be integer',
247
247
  statusCode: 400
248
248
  })
249
249
  })
@@ -280,7 +280,7 @@ fastify.listen(0, err => {
280
280
  t.equal(response.statusCode, 400)
281
281
  t.same(JSON.parse(body), {
282
282
  error: 'Bad Request',
283
- message: "headers['x-test'] should be number",
283
+ message: 'headers/x-test must be number',
284
284
  statusCode: 400
285
285
  })
286
286
  })
@@ -309,7 +309,7 @@ fastify.listen(0, err => {
309
309
  t.equal(response.statusCode, 400)
310
310
  t.same(JSON.parse(body), {
311
311
  error: 'Bad Request',
312
- message: 'querystring.hello should be integer',
312
+ message: 'querystring/hello must be integer',
313
313
  statusCode: 400
314
314
  })
315
315
  })
package/test/helper.js CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict'
2
2
 
3
3
  const sget = require('simple-get').concat
4
+ const dns = require('dns').promises
4
5
  const stream = require('stream')
5
6
  const symbols = require('../lib/symbols')
6
7
 
@@ -16,7 +17,7 @@ module.exports.payloadMethod = function (method, t, isSetErrorHandler = false) {
16
17
  if (isSetErrorHandler) {
17
18
  fastify.setErrorHandler(function (err, request, reply) {
18
19
  t.type(request, 'object')
19
- t.type(request, fastify[symbols.kRequest])
20
+ t.type(request, fastify[symbols.kRequest].parent)
20
21
  reply
21
22
  .code(err.statusCode)
22
23
  .type('application/json; charset=utf-8')
@@ -189,7 +190,7 @@ module.exports.payloadMethod = function (method, t, isSetErrorHandler = false) {
189
190
  }, (err, response, body) => {
190
191
  t.error(err)
191
192
  t.equal(response.statusCode, 200)
192
- t.equal(JSON.parse(body.toString()), null)
193
+ t.equal(body.toString(), '')
193
194
  })
194
195
 
195
196
  // Must use inject to make a request without a Content-Length header
@@ -199,7 +200,7 @@ module.exports.payloadMethod = function (method, t, isSetErrorHandler = false) {
199
200
  }, (err, res) => {
200
201
  t.error(err)
201
202
  t.equal(res.statusCode, 200)
202
- t.equal(JSON.parse(res.payload), null)
203
+ t.equal(res.payload.toString(), '')
203
204
  })
204
205
  })
205
206
 
@@ -419,3 +420,17 @@ module.exports.payloadMethod = function (method, t, isSetErrorHandler = false) {
419
420
  })
420
421
  })
421
422
  }
423
+
424
+ module.exports.getLoopbackHost = async () => {
425
+ let localhostForURL
426
+
427
+ const lookup = await dns.lookup('localhost')
428
+ const localhost = lookup.address
429
+ if (lookup.family === 6) {
430
+ localhostForURL = `[${lookup.address}]`
431
+ } else {
432
+ localhostForURL = localhost
433
+ }
434
+
435
+ return [localhost, localhostForURL]
436
+ }
@@ -13,7 +13,7 @@ process.removeAllListeners('warning')
13
13
  test('async hooks', t => {
14
14
  t.plan(21)
15
15
 
16
- const fastify = Fastify()
16
+ const fastify = Fastify({ exposeHeadRoutes: false })
17
17
  fastify.addHook('onRequest', async function (request, reply) {
18
18
  await sleep(1)
19
19
  request.test = 'the request is coming'
@@ -132,7 +132,7 @@ test('onRequest hooks should be able to block a request', t => {
132
132
  const fastify = Fastify()
133
133
 
134
134
  fastify.addHook('onRequest', async (req, reply) => {
135
- reply.send('hello')
135
+ await reply.send('hello')
136
136
  })
137
137
 
138
138
  fastify.addHook('onRequest', async (req, reply) => {
@@ -194,37 +194,6 @@ test('preParsing hooks should be able to modify the payload', t => {
194
194
  })
195
195
  })
196
196
 
197
- test('preParsing hooks can completely ignore the payload - deprecated syntax', t => {
198
- t.plan(5)
199
- const fastify = Fastify()
200
-
201
- process.on('warning', onWarning)
202
- function onWarning (warning) {
203
- t.equal(warning.name, 'FastifyDeprecation')
204
- t.equal(warning.code, 'FSTDEP004')
205
- }
206
-
207
- fastify.addHook('preParsing', async (req, reply) => {
208
-
209
- })
210
-
211
- fastify.post('/', function (request, reply) {
212
- reply.send(request.body)
213
- })
214
-
215
- fastify.inject({
216
- method: 'POST',
217
- url: '/',
218
- payload: { hello: 'world' }
219
- }, (err, res) => {
220
- t.error(err)
221
- t.equal(res.statusCode, 200)
222
- t.same(JSON.parse(res.payload), { hello: 'world' })
223
-
224
- process.removeListener('warning', onWarning)
225
- })
226
- })
227
-
228
197
  test('preParsing hooks should handle errors', t => {
229
198
  t.plan(3)
230
199
  const fastify = Fastify()
@@ -255,7 +224,7 @@ test('preHandler hooks should be able to block a request', t => {
255
224
  const fastify = Fastify()
256
225
 
257
226
  fastify.addHook('preHandler', async (req, reply) => {
258
- reply.send('hello')
227
+ await reply.send('hello')
259
228
  })
260
229
 
261
230
  fastify.addHook('preHandler', async (req, reply) => {
@@ -289,7 +258,7 @@ test('preValidation hooks should be able to block a request', t => {
289
258
  const fastify = Fastify()
290
259
 
291
260
  fastify.addHook('preValidation', async (req, reply) => {
292
- reply.send('hello')
261
+ await reply.send('hello')
293
262
  })
294
263
 
295
264
  fastify.addHook('preValidation', async (req, reply) => {
@@ -414,7 +383,7 @@ test('preValidation hooks should handle throwing null', t => {
414
383
 
415
384
  fastify.setErrorHandler(async (error, request, reply) => {
416
385
  t.ok(error instanceof Error)
417
- reply.send(error)
386
+ await reply.send(error)
418
387
  })
419
388
 
420
389
  fastify.addHook('preValidation', async () => {
@@ -465,7 +434,7 @@ test('onRequest hooks should be able to block a request (last hook)', t => {
465
434
  const fastify = Fastify()
466
435
 
467
436
  fastify.addHook('onRequest', async (req, reply) => {
468
- reply.send('hello')
437
+ await reply.send('hello')
469
438
  })
470
439
 
471
440
  fastify.addHook('preHandler', async (req, reply) => {
@@ -499,7 +468,7 @@ test('preHandler hooks should be able to block a request (last hook)', t => {
499
468
  const fastify = Fastify()
500
469
 
501
470
  fastify.addHook('preHandler', async (req, reply) => {
502
- reply.send('hello')
471
+ await reply.send('hello')
503
472
  })
504
473
 
505
474
  fastify.addHook('onSend', async (req, reply, payload) => {
@@ -533,8 +502,9 @@ test('onRequest respond with a stream', t => {
533
502
  const stream = fs.createReadStream(process.cwd() + '/test/stream.test.js', 'utf8')
534
503
  // stream.pipe(res)
535
504
  // res.once('finish', resolve)
536
- reply.send(stream)
537
- reply.raw.once('finish', () => resolve())
505
+ reply.send(stream).then(() => {
506
+ reply.raw.once('finish', () => resolve())
507
+ })
538
508
  })
539
509
  })
540
510
 
@@ -580,14 +550,11 @@ test('preHandler respond with a stream', t => {
580
550
  const order = [1, 2]
581
551
 
582
552
  fastify.addHook('preHandler', async (req, reply) => {
583
- return new Promise((resolve, reject) => {
584
- const stream = fs.createReadStream(process.cwd() + '/test/stream.test.js', 'utf8')
585
- reply.send(stream)
586
- reply.raw.once('finish', () => {
587
- t.equal(order.shift(), 2)
588
- resolve()
589
- })
553
+ const stream = fs.createReadStream(process.cwd() + '/test/stream.test.js', 'utf8')
554
+ reply.raw.once('finish', () => {
555
+ t.equal(order.shift(), 2)
590
556
  })
557
+ return reply.send(stream)
591
558
  })
592
559
 
593
560
  fastify.addHook('preHandler', async (req, reply) => {
@@ -268,7 +268,7 @@ t.test('onReady can not add decorators or application hooks', t => {
268
268
  })
269
269
 
270
270
  t.test('onReady cannot add lifecycle hooks', t => {
271
- t.plan(4)
271
+ t.plan(5)
272
272
  const fastify = Fastify()
273
273
 
274
274
  fastify.addHook('onReady', function (done) {
@@ -277,7 +277,9 @@ t.test('onReady cannot add lifecycle hooks', t => {
277
277
  fastify.addHook('onRequest', (request, reply, done) => {})
278
278
  } catch (error) {
279
279
  t.ok(error)
280
- t.equal(error.message, 'root plugin has already booted')
280
+ t.equal(error.message, 'Root plugin has already booted')
281
+ // TODO: look where the error pops up
282
+ t.equal(error.code, 'AVV_ERR_PLUGIN_NOT_VALID')
281
283
  done(error)
282
284
  }
283
285
  })
@@ -300,7 +302,7 @@ t.test('onReady throw loading error', t => {
300
302
  })
301
303
 
302
304
  t.test('onReady does not call done', t => {
303
- t.plan(3)
305
+ t.plan(6)
304
306
  const fastify = Fastify({ pluginTimeout: 500 })
305
307
 
306
308
  fastify.addHook('onReady', function (done) {
@@ -310,7 +312,10 @@ t.test('onReady does not call done', t => {
310
312
 
311
313
  fastify.ready(err => {
312
314
  t.ok(err)
313
- t.equal(err.code, 'ERR_AVVIO_READY_TIMEOUT')
315
+ t.equal(err.message, "A callback for 'onReady' hook timed out. You may have forgotten to call 'done' function or to resolve a Promise")
316
+ t.equal(err.code, 'FST_ERR_HOOK_TIMEOUT')
317
+ t.ok(err.cause)
318
+ t.equal(err.cause.code, 'AVV_ERR_READY_TIMEOUT')
314
319
  })
315
320
  })
316
321
 
@@ -9,14 +9,22 @@ const fp = require('fastify-plugin')
9
9
  const fs = require('fs')
10
10
  const split = require('split2')
11
11
  const symbols = require('../lib/symbols.js')
12
- const warning = require('../lib/warnings')
13
12
  const payload = { hello: 'world' }
14
13
 
15
14
  process.removeAllListeners('warning')
16
15
 
16
+ function getUrl (app) {
17
+ const { address, port } = app.server.address()
18
+ if (address === '::1') {
19
+ return `http://[${address}]:${port}`
20
+ } else {
21
+ return `http://${address}:${port}`
22
+ }
23
+ }
24
+
17
25
  test('hooks', t => {
18
26
  t.plan(43)
19
- const fastify = Fastify()
27
+ const fastify = Fastify({ exposeHeadRoutes: false })
20
28
 
21
29
  try {
22
30
  fastify.addHook('preHandler', function (request, reply, done) {
@@ -46,7 +54,7 @@ test('hooks', t => {
46
54
  }
47
55
 
48
56
  try {
49
- fastify.addHook('preParsing', function (request, reply, done) {
57
+ fastify.addHook('preParsing', function (request, reply, payload, done) {
50
58
  request.preParsing = true
51
59
  t.equal(request.test, 'the request is coming')
52
60
  t.equal(reply.test, 'the reply has come')
@@ -342,7 +350,7 @@ test('preHandler hook should support encapsulation / 5', t => {
342
350
 
343
351
  test('onRoute hook should be called / 1', t => {
344
352
  t.plan(2)
345
- const fastify = Fastify()
353
+ const fastify = Fastify({ exposeHeadRoutes: false })
346
354
 
347
355
  fastify.register((instance, opts, done) => {
348
356
  instance.addHook('onRoute', () => {
@@ -363,7 +371,7 @@ test('onRoute hook should be called / 2', t => {
363
371
  t.plan(5)
364
372
  let firstHandler = 0
365
373
  let secondHandler = 0
366
- const fastify = Fastify()
374
+ const fastify = Fastify({ exposeHeadRoutes: false })
367
375
  fastify.addHook('onRoute', (route) => {
368
376
  t.pass()
369
377
  firstHandler++
@@ -391,7 +399,7 @@ test('onRoute hook should be called / 2', t => {
391
399
 
392
400
  test('onRoute hook should be called / 3', t => {
393
401
  t.plan(5)
394
- const fastify = Fastify()
402
+ const fastify = Fastify({ exposeHeadRoutes: false })
395
403
 
396
404
  function handler (req, reply) {
397
405
  reply.send()
@@ -423,7 +431,7 @@ test('onRoute hook should be called / 3', t => {
423
431
 
424
432
  test('onRoute hook should be called (encapsulation support) / 4', t => {
425
433
  t.plan(4)
426
- const fastify = Fastify()
434
+ const fastify = Fastify({ exposeHeadRoutes: false })
427
435
 
428
436
  fastify.addHook('onRoute', () => {
429
437
  t.pass()
@@ -450,7 +458,7 @@ test('onRoute hook should be called (encapsulation support) / 4', t => {
450
458
 
451
459
  test('onRoute hook should be called (encapsulation support) / 5', t => {
452
460
  t.plan(2)
453
- const fastify = Fastify()
461
+ const fastify = Fastify({ exposeHeadRoutes: false })
454
462
 
455
463
  fastify.get('/first', function (req, reply) {
456
464
  reply.send()
@@ -477,7 +485,7 @@ test('onRoute hook should be called (encapsulation support) / 5', t => {
477
485
 
478
486
  test('onRoute hook should be called (encapsulation support) / 6', t => {
479
487
  t.plan(1)
480
- const fastify = Fastify()
488
+ const fastify = Fastify({ exposeHeadRoutes: false })
481
489
 
482
490
  fastify.get('/first', function (req, reply) {
483
491
  reply.send()
@@ -494,7 +502,7 @@ test('onRoute hook should be called (encapsulation support) / 6', t => {
494
502
 
495
503
  test('onRoute should keep the context', t => {
496
504
  t.plan(4)
497
- const fastify = Fastify()
505
+ const fastify = Fastify({ exposeHeadRoutes: false })
498
506
  fastify.register((instance, opts, done) => {
499
507
  instance.decorate('test', true)
500
508
  instance.addHook('onRoute', onRoute)
@@ -519,7 +527,7 @@ test('onRoute should keep the context', t => {
519
527
 
520
528
  test('onRoute hook should pass correct route', t => {
521
529
  t.plan(9)
522
- const fastify = Fastify()
530
+ const fastify = Fastify({ exposeHeadRoutes: false })
523
531
  fastify.addHook('onRoute', (route) => {
524
532
  t.equal(route.method, 'GET')
525
533
  t.equal(route.url, '/')
@@ -547,7 +555,7 @@ test('onRoute hook should pass correct route', t => {
547
555
 
548
556
  test('onRoute hook should pass correct route with custom prefix', t => {
549
557
  t.plan(11)
550
- const fastify = Fastify()
558
+ const fastify = Fastify({ exposeHeadRoutes: false })
551
559
  fastify.addHook('onRoute', function (route) {
552
560
  t.equal(route.method, 'GET')
553
561
  t.equal(route.url, '/v1/foo')
@@ -577,7 +585,7 @@ test('onRoute hook should pass correct route with custom prefix', t => {
577
585
 
578
586
  test('onRoute hook should pass correct route with custom options', t => {
579
587
  t.plan(6)
580
- const fastify = Fastify()
588
+ const fastify = Fastify({ exposeHeadRoutes: false })
581
589
  fastify.register((instance, opts, done) => {
582
590
  instance.addHook('onRoute', function (route) {
583
591
  t.equal(route.method, 'GET')
@@ -605,7 +613,7 @@ test('onRoute hook should pass correct route with custom options', t => {
605
613
 
606
614
  test('onRoute hook should receive any route option', t => {
607
615
  t.plan(5)
608
- const fastify = Fastify()
616
+ const fastify = Fastify({ exposeHeadRoutes: false })
609
617
  fastify.register((instance, opts, done) => {
610
618
  instance.addHook('onRoute', function (route) {
611
619
  t.equal(route.method, 'GET')
@@ -626,7 +634,7 @@ test('onRoute hook should receive any route option', t => {
626
634
 
627
635
  test('onRoute hook should preserve system route configuration', t => {
628
636
  t.plan(5)
629
- const fastify = Fastify()
637
+ const fastify = Fastify({ exposeHeadRoutes: false })
630
638
  fastify.register((instance, opts, done) => {
631
639
  instance.addHook('onRoute', function (route) {
632
640
  t.equal(route.method, 'GET')
@@ -650,7 +658,7 @@ test('onRoute hook should preserve handler function in options of shorthand rout
650
658
 
651
659
  const handler = (req, reply) => {}
652
660
 
653
- const fastify = Fastify()
661
+ const fastify = Fastify({ exposeHeadRoutes: false })
654
662
  fastify.register((instance, opts, done) => {
655
663
  instance.addHook('onRoute', function (route) {
656
664
  t.equal(route.handler, handler)
@@ -671,7 +679,7 @@ test('onRoute hook should be called once when prefixTrailingSlash', t => {
671
679
  let onRouteCalled = 0
672
680
  let routePatched = 0
673
681
 
674
- const fastify = Fastify({ ignoreTrailingSlash: false })
682
+ const fastify = Fastify({ ignoreTrailingSlash: false, exposeHeadRoutes: false })
675
683
 
676
684
  // a plugin that patches route options, similar to fastify-compress
677
685
  fastify.register(fp(function myPlugin (instance, opts, next) {
@@ -710,16 +718,16 @@ test('onRoute hook should be called once when prefixTrailingSlash', t => {
710
718
  test('onRoute hook should able to change the route url', t => {
711
719
  t.plan(5)
712
720
 
713
- const fastify = Fastify()
721
+ const fastify = Fastify({ exposeHeadRoutes: false })
714
722
 
715
723
  fastify.register((instance, opts, done) => {
716
724
  instance.addHook('onRoute', (route) => {
717
- t.equal(route.url, '/föö')
725
+ t.equal(route.url, '/foo')
718
726
  route.url = encodeURI(route.url)
719
727
  })
720
728
 
721
- instance.get('/föö', (request, reply) => {
722
- reply.send('here /föö')
729
+ instance.get('/foo', (request, reply) => {
730
+ reply.send('here /foo')
723
731
  })
724
732
 
725
733
  done()
@@ -731,37 +739,43 @@ test('onRoute hook should able to change the route url', t => {
731
739
 
732
740
  sget({
733
741
  method: 'GET',
734
- url: 'http://localhost:' + fastify.server.address().port + encodeURI('/föö')
742
+ url: getUrl(fastify) + encodeURI('/foo')
735
743
  }, (err, response, body) => {
736
744
  t.error(err)
737
745
  t.equal(response.statusCode, 200)
738
- t.equal(body.toString(), 'here /föö')
746
+ t.equal(body.toString(), 'here /foo')
739
747
  })
740
748
  })
741
749
  })
742
750
 
743
- test('onRoute hook that throws should be caught ', t => {
751
+ test('onRoute hook that throws should be caught', t => {
744
752
  t.plan(1)
745
- const fastify = Fastify()
753
+ const fastify = Fastify({ exposeHeadRoutes: false })
746
754
 
747
755
  fastify.register((instance, opts, done) => {
748
756
  instance.addHook('onRoute', () => {
749
757
  throw new Error('snap')
750
758
  })
751
- instance.get('/', opts, function (req, reply) {
752
- reply.send()
753
- })
759
+
760
+ try {
761
+ instance.get('/', opts, function (req, reply) {
762
+ reply.send()
763
+ })
764
+
765
+ t.fail('onRoute should throw sync if error')
766
+ } catch (error) {
767
+ t.ok(error)
768
+ }
769
+
754
770
  done()
755
771
  })
756
772
 
757
- fastify.ready(err => {
758
- t.ok(err)
759
- })
773
+ fastify.ready()
760
774
  })
761
775
 
762
776
  test('onRoute hook with many prefix', t => {
763
777
  t.plan(3)
764
- const fastify = Fastify()
778
+ const fastify = Fastify({ exposeHeadRoutes: false })
765
779
  const handler = (req, reply) => { reply.send({}) }
766
780
 
767
781
  const onRouteChecks = [
@@ -1073,6 +1087,7 @@ test('onSend hook is called after payload is serialized and headers are set', t
1073
1087
  })
1074
1088
 
1075
1089
  instance.get('/stream', (request, reply) => {
1090
+ reply.header('content-type', 'application/octet-stream')
1076
1091
  reply.send(thePayload)
1077
1092
  })
1078
1093
 
@@ -2213,7 +2228,7 @@ test('request in onRequest, preParsing, preValidation and onResponse', t => {
2213
2228
  const fastify = Fastify()
2214
2229
 
2215
2230
  fastify.addHook('onRequest', function (request, reply, done) {
2216
- t.same(request.body, null)
2231
+ t.same(request.body, undefined)
2217
2232
  t.same(request.query, { key: 'value' })
2218
2233
  t.same(request.params, { greeting: 'hello' })
2219
2234
  t.same(request.headers, {
@@ -2227,7 +2242,7 @@ test('request in onRequest, preParsing, preValidation and onResponse', t => {
2227
2242
  })
2228
2243
 
2229
2244
  fastify.addHook('preParsing', function (request, reply, payload, done) {
2230
- t.same(request.body, null)
2245
+ t.same(request.body, undefined)
2231
2246
  t.same(request.query, { key: 'value' })
2232
2247
  t.same(request.params, { greeting: 'hello' })
2233
2248
  t.same(request.headers, {
@@ -2469,19 +2484,20 @@ test('onError hook with setErrorHandler', t => {
2469
2484
 
2470
2485
  const fastify = Fastify()
2471
2486
 
2472
- const err = new Error('ouch')
2487
+ const external = new Error('ouch')
2488
+ const internal = new Error('kaboom')
2473
2489
 
2474
2490
  fastify.setErrorHandler((_, req, reply) => {
2475
- reply.send(err)
2491
+ reply.send(external)
2476
2492
  })
2477
2493
 
2478
2494
  fastify.addHook('onError', (request, reply, error, done) => {
2479
- t.match(error, err)
2495
+ t.match(error, internal)
2480
2496
  done()
2481
2497
  })
2482
2498
 
2483
2499
  fastify.get('/', (req, reply) => {
2484
- reply.send(new Error('kaboom'))
2500
+ reply.send(internal)
2485
2501
  })
2486
2502
 
2487
2503
  fastify.inject({
@@ -2497,34 +2513,6 @@ test('onError hook with setErrorHandler', t => {
2497
2513
  })
2498
2514
  })
2499
2515
 
2500
- t.test('Hide error', t => {
2501
- t.plan(2)
2502
-
2503
- const fastify = Fastify()
2504
-
2505
- fastify.setErrorHandler((_, req, reply) => {
2506
- reply.send({ hello: 'world' })
2507
- })
2508
-
2509
- fastify.addHook('onError', (request, reply, error, done) => {
2510
- t.fail('Should not be called')
2511
- })
2512
-
2513
- fastify.get('/', (req, reply) => {
2514
- reply.send(new Error('kaboom'))
2515
- })
2516
-
2517
- fastify.inject({
2518
- method: 'GET',
2519
- url: '/'
2520
- }, (err, res) => {
2521
- t.error(err)
2522
- t.same(
2523
- JSON.parse(res.payload),
2524
- { hello: 'world' }
2525
- )
2526
- })
2527
- })
2528
2516
  t.end()
2529
2517
  })
2530
2518
 
@@ -2566,37 +2554,6 @@ test('preParsing hook should run before parsing and be able to modify the payloa
2566
2554
  })
2567
2555
  })
2568
2556
 
2569
- test('preParsing hooks can completely ignore the payload - deprecated syntax', t => {
2570
- t.plan(5)
2571
- const fastify = Fastify()
2572
-
2573
- process.on('warning', onWarning)
2574
- warning.emitted.delete('FSTDEP004')
2575
-
2576
- function onWarning (warning) {
2577
- t.equal(warning.name, 'FastifyDeprecation')
2578
- t.equal(warning.code, 'FSTDEP004')
2579
- }
2580
-
2581
- fastify.addHook('preParsing', (req, reply, done) => {
2582
- done()
2583
- })
2584
-
2585
- fastify.post('/', function (request, reply) {
2586
- reply.send(request.body)
2587
- })
2588
-
2589
- fastify.inject({
2590
- method: 'POST',
2591
- url: '/',
2592
- payload: { hello: 'world' }
2593
- }, (err, res) => {
2594
- t.error(err)
2595
- t.equal(res.statusCode, 200)
2596
- t.same(JSON.parse(res.payload), { hello: 'world' })
2597
- })
2598
- })
2599
-
2600
2557
  test('preParsing hooks should run in the order in which they are defined', t => {
2601
2558
  t.plan(5)
2602
2559
  const fastify = Fastify()
@@ -3198,10 +3155,11 @@ test('onTimeout should be triggered', t => {
3198
3155
  })
3199
3156
 
3200
3157
  fastify.get('/', async (req, reply) => {
3201
- reply.send({ hello: 'world' })
3158
+ await reply.send({ hello: 'world' })
3202
3159
  })
3203
3160
 
3204
3161
  fastify.get('/timeout', async (req, reply) => {
3162
+ return reply
3205
3163
  })
3206
3164
 
3207
3165
  fastify.listen(0, (err, address) => {
@@ -3236,10 +3194,11 @@ test('onTimeout should be triggered and socket _meta is set', t => {
3236
3194
 
3237
3195
  fastify.get('/', async (req, reply) => {
3238
3196
  req.raw.socket._meta = {}
3239
- reply.send({ hello: 'world' })
3197
+ return reply.send({ hello: 'world' })
3240
3198
  })
3241
3199
 
3242
3200
  fastify.get('/timeout', async (req, reply) => {
3201
+ return reply
3243
3202
  })
3244
3203
 
3245
3204
  fastify.listen(0, (err, address) => {