fastify 3.27.3 → 4.0.0-alpha.2

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 (164) hide show
  1. package/.taprc +3 -0
  2. package/README.md +7 -7
  3. package/build/build-error-serializer.js +27 -0
  4. package/build/build-validation.js +47 -35
  5. package/docs/Guides/Database.md +320 -0
  6. package/docs/Guides/Getting-Started.md +7 -7
  7. package/docs/Guides/Plugins-Guide.md +1 -1
  8. package/docs/Guides/Serverless.md +3 -3
  9. package/docs/Guides/Testing.md +2 -2
  10. package/docs/Migration-Guide-V4.md +12 -0
  11. package/docs/Reference/ContentTypeParser.md +4 -0
  12. package/docs/Reference/Decorators.md +2 -2
  13. package/docs/Reference/Encapsulation.md +2 -2
  14. package/docs/Reference/Errors.md +51 -6
  15. package/docs/Reference/HTTP2.md +3 -3
  16. package/docs/Reference/Hooks.md +4 -7
  17. package/docs/Reference/LTS.md +5 -4
  18. package/docs/Reference/Plugins.md +3 -3
  19. package/docs/Reference/Reply.md +23 -22
  20. package/docs/Reference/Request.md +1 -3
  21. package/docs/Reference/Routes.md +22 -15
  22. package/docs/Reference/Server.md +69 -119
  23. package/docs/Reference/TypeScript.md +20 -22
  24. package/docs/Reference/Validation-and-Serialization.md +30 -55
  25. package/docs/Type-Providers.md +257 -0
  26. package/examples/asyncawait.js +1 -1
  27. package/examples/benchmark/hooks-benchmark-async-await.js +1 -1
  28. package/examples/benchmark/hooks-benchmark.js +1 -1
  29. package/examples/benchmark/simple.js +1 -1
  30. package/examples/hooks.js +2 -2
  31. package/examples/http2.js +1 -1
  32. package/examples/https.js +1 -1
  33. package/examples/parser.js +1 -1
  34. package/examples/route-prefix.js +1 -1
  35. package/examples/shared-schema.js +1 -1
  36. package/examples/simple-stream.js +18 -0
  37. package/examples/simple.js +1 -1
  38. package/examples/simple.mjs +1 -1
  39. package/examples/typescript-server.ts +1 -1
  40. package/examples/use-plugin.js +1 -1
  41. package/fastify.d.ts +34 -22
  42. package/fastify.js +40 -36
  43. package/lib/configValidator.js +902 -1023
  44. package/lib/contentTypeParser.js +6 -16
  45. package/lib/context.js +36 -10
  46. package/lib/decorate.js +3 -1
  47. package/lib/error-handler.js +158 -0
  48. package/lib/error-serializer.js +257 -0
  49. package/lib/errors.js +43 -9
  50. package/lib/fourOhFour.js +31 -20
  51. package/lib/handleRequest.js +10 -13
  52. package/lib/hooks.js +14 -9
  53. package/lib/pluginOverride.js +0 -3
  54. package/lib/pluginUtils.js +3 -2
  55. package/lib/reply.js +29 -158
  56. package/lib/request.js +13 -10
  57. package/lib/route.js +131 -138
  58. package/lib/schema-controller.js +2 -2
  59. package/lib/schemas.js +27 -1
  60. package/lib/server.js +241 -116
  61. package/lib/symbols.js +4 -3
  62. package/lib/validation.js +2 -1
  63. package/lib/warnings.js +4 -12
  64. package/lib/wrapThenable.js +4 -11
  65. package/package.json +37 -39
  66. package/test/404s.test.js +258 -125
  67. package/test/500s.test.js +3 -3
  68. package/test/als.test.js +1 -1
  69. package/test/async-await.test.js +20 -76
  70. package/test/bodyLimit.test.js +1 -1
  71. package/test/build-certificate.js +6 -7
  72. package/test/case-insensitive.test.js +4 -4
  73. package/test/close-pipelining.test.js +2 -2
  74. package/test/close.test.js +11 -11
  75. package/test/content-parser.test.js +32 -0
  76. package/test/context-config.test.js +52 -0
  77. package/test/custom-http-server.test.js +14 -7
  78. package/test/custom-parser-async.test.js +1 -66
  79. package/test/custom-parser.test.js +92 -159
  80. package/test/custom-querystring-parser.test.js +3 -3
  81. package/test/decorator.test.js +11 -13
  82. package/test/delete.test.js +6 -6
  83. package/test/encapsulated-error-handler.test.js +50 -0
  84. package/test/esm/index.test.js +0 -14
  85. package/test/fastify-instance.test.js +4 -4
  86. package/test/fluent-schema.test.js +4 -4
  87. package/test/genReqId.test.js +1 -1
  88. package/test/get.test.js +4 -4
  89. package/test/handler-context.test.js +2 -2
  90. package/test/head.test.js +1 -1
  91. package/test/helper.js +19 -4
  92. package/test/hooks-async.test.js +15 -48
  93. package/test/hooks.on-ready.test.js +10 -5
  94. package/test/hooks.test.js +78 -119
  95. package/test/http2/closing.test.js +10 -16
  96. package/test/http2/constraint.test.js +1 -1
  97. package/test/http2/head.test.js +1 -1
  98. package/test/http2/plain.test.js +1 -1
  99. package/test/http2/secure-with-fallback.test.js +1 -1
  100. package/test/http2/secure.test.js +1 -1
  101. package/test/http2/unknown-http-method.test.js +4 -10
  102. package/test/https/custom-https-server.test.js +12 -6
  103. package/test/https/https.test.js +1 -1
  104. package/test/input-validation.js +3 -3
  105. package/test/internals/handleRequest.test.js +6 -43
  106. package/test/internals/initialConfig.test.js +41 -12
  107. package/test/internals/logger.test.js +2 -2
  108. package/test/internals/reply.test.js +281 -40
  109. package/test/internals/request.test.js +13 -7
  110. package/test/internals/server.test.js +88 -0
  111. package/test/listen.deprecated.test.js +202 -0
  112. package/test/listen.test.js +118 -150
  113. package/test/logger.test.js +82 -42
  114. package/test/maxRequestsPerSocket.test.js +8 -6
  115. package/test/middleware.test.js +2 -25
  116. package/test/nullable-validation.test.js +53 -16
  117. package/test/output-validation.test.js +1 -1
  118. package/test/plugin.test.js +47 -21
  119. package/test/pretty-print.test.js +22 -10
  120. package/test/promises.test.js +1 -1
  121. package/test/proto-poisoning.test.js +6 -6
  122. package/test/register.test.js +3 -3
  123. package/test/reply-error.test.js +126 -15
  124. package/test/request-error.test.js +3 -6
  125. package/test/route-hooks.test.js +18 -18
  126. package/test/route-prefix.test.js +2 -1
  127. package/test/route.test.js +206 -22
  128. package/test/router-options.test.js +2 -2
  129. package/test/schema-examples.test.js +11 -5
  130. package/test/schema-feature.test.js +25 -20
  131. package/test/schema-serialization.test.js +9 -9
  132. package/test/schema-special-usage.test.js +5 -153
  133. package/test/schema-validation.test.js +9 -9
  134. package/test/skip-reply-send.test.js +2 -2
  135. package/test/stream.test.js +82 -23
  136. package/test/throw.test.js +8 -5
  137. package/test/trust-proxy.test.js +6 -6
  138. package/test/type-provider.test.js +20 -0
  139. package/test/types/fastify.test-d.ts +10 -18
  140. package/test/types/import.js +2 -0
  141. package/test/types/import.ts +1 -0
  142. package/test/types/instance.test-d.ts +68 -17
  143. package/test/types/logger.test-d.ts +44 -15
  144. package/test/types/reply.test-d.ts +2 -1
  145. package/test/types/route.test-d.ts +8 -2
  146. package/test/types/schema.test-d.ts +2 -39
  147. package/test/types/type-provider.test-d.ts +417 -0
  148. package/test/url-rewriting.test.js +3 -3
  149. package/test/validation-error-handling.test.js +8 -8
  150. package/test/versioned-routes.test.js +30 -18
  151. package/test/wrapThenable.test.js +7 -6
  152. package/types/content-type-parser.d.ts +17 -8
  153. package/types/hooks.d.ts +102 -59
  154. package/types/instance.d.ts +244 -118
  155. package/types/logger.d.ts +18 -104
  156. package/types/plugin.d.ts +10 -4
  157. package/types/reply.d.ts +18 -12
  158. package/types/request.d.ts +10 -5
  159. package/types/route.d.ts +42 -31
  160. package/types/schema.d.ts +1 -1
  161. package/types/type-provider.d.ts +99 -0
  162. package/types/utils.d.ts +1 -1
  163. package/lib/schema-compilers.js +0 -12
  164. package/test/emit-warning.test.js +0 -166
@@ -24,7 +24,7 @@ test('Custom querystring parser', t => {
24
24
  reply.send({ hello: 'world' })
25
25
  })
26
26
 
27
- fastify.listen(0, (err, address) => {
27
+ fastify.listen({ port: 0 }, (err, address) => {
28
28
  t.error(err)
29
29
  t.teardown(() => fastify.close())
30
30
 
@@ -61,7 +61,7 @@ test('Custom querystring parser should be called also if there is nothing to par
61
61
  reply.send({ hello: 'world' })
62
62
  })
63
63
 
64
- fastify.listen(0, (err, address) => {
64
+ fastify.listen({ port: 0 }, (err, address) => {
65
65
  t.error(err)
66
66
  t.teardown(() => fastify.close())
67
67
 
@@ -98,7 +98,7 @@ test('Querystring without value', t => {
98
98
  reply.send({ hello: 'world' })
99
99
  })
100
100
 
101
- fastify.listen(0, (err, address) => {
101
+ fastify.listen({ port: 0 }, (err, address) => {
102
102
  t.error(err)
103
103
  t.teardown(() => fastify.close())
104
104
 
@@ -132,7 +132,7 @@ test('decorateReply inside register', t => {
132
132
  reply.send({ hello: 'world' })
133
133
  })
134
134
 
135
- fastify.listen(0, err => {
135
+ fastify.listen({ port: 0 }, err => {
136
136
  t.error(err)
137
137
  fastify.server.unref()
138
138
 
@@ -180,7 +180,7 @@ test('decorateReply as plugin (inside .after)', t => {
180
180
  reply.send({ hello: 'world' })
181
181
  })
182
182
 
183
- fastify.listen(0, err => {
183
+ fastify.listen({ port: 0 }, err => {
184
184
  t.error(err)
185
185
  fastify.server.unref()
186
186
 
@@ -228,7 +228,7 @@ test('decorateReply as plugin (outside .after)', t => {
228
228
  reply.send({ hello: 'world' })
229
229
  })
230
230
 
231
- fastify.listen(0, err => {
231
+ fastify.listen({ port: 0 }, err => {
232
232
  t.error(err)
233
233
  fastify.server.unref()
234
234
 
@@ -274,7 +274,7 @@ test('decorateRequest inside register', t => {
274
274
  reply.send({ hello: 'world' })
275
275
  })
276
276
 
277
- fastify.listen(0, err => {
277
+ fastify.listen({ port: 0 }, err => {
278
278
  t.error(err)
279
279
  fastify.server.unref()
280
280
 
@@ -322,7 +322,7 @@ test('decorateRequest as plugin (inside .after)', t => {
322
322
  reply.send({ hello: 'world' })
323
323
  })
324
324
 
325
- fastify.listen(0, err => {
325
+ fastify.listen({ port: 0 }, err => {
326
326
  t.error(err)
327
327
  fastify.server.unref()
328
328
 
@@ -370,7 +370,7 @@ test('decorateRequest as plugin (outside .after)', t => {
370
370
  reply.send({ hello: 'world' })
371
371
  })
372
372
 
373
- fastify.listen(0, err => {
373
+ fastify.listen({ port: 0 }, err => {
374
374
  t.error(err)
375
375
  fastify.server.unref()
376
376
 
@@ -764,7 +764,7 @@ test('decorate* should throw if called after ready', async t => {
764
764
  })
765
765
  })
766
766
 
767
- await fastify.listen(0)
767
+ await fastify.listen({ port: 0 })
768
768
  try {
769
769
  fastify.decorate('test', true)
770
770
  t.fail('should not decorate')
@@ -913,8 +913,7 @@ test('plugin required decorators', async t => {
913
913
  })
914
914
  },
915
915
  {
916
- name: 'custom-plugin-one',
917
- fastify: '3.x'
916
+ name: 'custom-plugin-one'
918
917
  }
919
918
  )
920
919
 
@@ -924,7 +923,6 @@ test('plugin required decorators', async t => {
924
923
  },
925
924
  {
926
925
  name: 'custom-plugin-two',
927
- fastify: '3.x',
928
926
  dependencies: ['custom-plugin-one'],
929
927
  decorators: {
930
928
  request: ['someThing']
@@ -951,7 +949,7 @@ test('decorateRequest/decorateReply empty string', t => {
951
949
  })
952
950
  t.teardown(fastify.close.bind(fastify))
953
951
 
954
- fastify.listen(0, err => {
952
+ fastify.listen({ port: 0 }, err => {
955
953
  t.error(err)
956
954
  fastify.server.unref()
957
955
 
@@ -980,7 +978,7 @@ test('decorateRequest/decorateReply is undefined', t => {
980
978
  })
981
979
  t.teardown(fastify.close.bind(fastify))
982
980
 
983
- fastify.listen(0, err => {
981
+ fastify.listen({ port: 0 }, err => {
984
982
  t.error(err)
985
983
  fastify.server.unref()
986
984
 
@@ -1009,7 +1007,7 @@ test('decorateRequest/decorateReply is not set to a value', t => {
1009
1007
  })
1010
1008
  t.teardown(fastify.close.bind(fastify))
1011
1009
 
1012
- fastify.listen(0, err => {
1010
+ fastify.listen({ port: 0 }, err => {
1013
1011
  t.error(err)
1014
1012
  fastify.server.unref()
1015
1013
 
@@ -157,7 +157,7 @@ test('body - delete', t => {
157
157
  }
158
158
  })
159
159
 
160
- fastify.listen(0, err => {
160
+ fastify.listen({ port: 0 }, err => {
161
161
  t.error(err)
162
162
  fastify.server.unref()
163
163
 
@@ -197,7 +197,7 @@ fastify.listen(0, err => {
197
197
  t.equal(response.statusCode, 400)
198
198
  t.same(JSON.parse(body), {
199
199
  error: 'Bad Request',
200
- message: 'params.test should be integer',
200
+ message: 'params/test must be integer',
201
201
  statusCode: 400
202
202
  })
203
203
  })
@@ -232,7 +232,7 @@ fastify.listen(0, err => {
232
232
  t.equal(response.statusCode, 400)
233
233
  t.same(JSON.parse(body), {
234
234
  error: 'Bad Request',
235
- message: "headers['x-test'] should be number",
235
+ message: 'headers/x-test must be number',
236
236
  statusCode: 400
237
237
  })
238
238
  })
@@ -261,7 +261,7 @@ fastify.listen(0, err => {
261
261
  t.equal(response.statusCode, 400)
262
262
  t.same(JSON.parse(body), {
263
263
  error: 'Bad Request',
264
- message: 'querystring.hello should be integer',
264
+ message: 'querystring/hello must be integer',
265
265
  statusCode: 400
266
266
  })
267
267
  })
@@ -302,7 +302,7 @@ test('shorthand - delete with application/json Content-Type header and without b
302
302
  t.plan(4)
303
303
  const fastify = require('..')()
304
304
  fastify.delete('/', {}, (req, reply) => {
305
- t.equal(req.body, null)
305
+ t.equal(req.body, undefined)
306
306
  reply.send(req.body)
307
307
  })
308
308
  fastify.inject({
@@ -313,6 +313,6 @@ test('shorthand - delete with application/json Content-Type header and without b
313
313
  }, (err, response) => {
314
314
  t.error(err)
315
315
  t.equal(response.statusCode, 200)
316
- t.same(JSON.parse(response.payload), null)
316
+ t.same(response.payload.toString(), '')
317
317
  })
318
318
  })
@@ -0,0 +1,50 @@
1
+ 'use strict'
2
+
3
+ const { test } = require('tap')
4
+ const Fastify = require('..')
5
+
6
+ test('encapuslates an error handler', async t => {
7
+ t.plan(3)
8
+
9
+ const fastify = Fastify()
10
+ fastify.register(async function (fastify) {
11
+ fastify.setErrorHandler(async function a (err) {
12
+ t.equal(err.message, 'kaboom')
13
+ throw new Error('caught')
14
+ })
15
+ fastify.get('/encapsulated', async () => { throw new Error('kaboom') })
16
+ })
17
+
18
+ fastify.setErrorHandler(async function b (err) {
19
+ t.equal(err.message, 'caught')
20
+ throw new Error('wrapped')
21
+ })
22
+
23
+ const res = await fastify.inject('/encapsulated')
24
+ t.equal(res.json().message, 'wrapped')
25
+ })
26
+
27
+ test('onError hook nested', async t => {
28
+ t.plan(4)
29
+
30
+ const fastify = Fastify()
31
+ fastify.register(async function (fastify) {
32
+ fastify.setErrorHandler(async function a (err) {
33
+ t.equal(err.message, 'kaboom')
34
+ throw new Error('caught')
35
+ })
36
+ fastify.get('/encapsulated', async () => { throw new Error('kaboom') })
37
+ })
38
+
39
+ fastify.setErrorHandler(async function b (err) {
40
+ t.equal(err.message, 'caught')
41
+ throw new Error('wrapped')
42
+ })
43
+
44
+ fastify.addHook('onError', async function (request, reply, err) {
45
+ t.equal(err.message, 'kaboom')
46
+ })
47
+
48
+ const res = await fastify.inject('/encapsulated')
49
+ t.equal(res.json().message, 'wrapped')
50
+ })
@@ -3,20 +3,6 @@
3
3
  const t = require('tap')
4
4
  const semver = require('semver')
5
5
 
6
- if (semver.lt(process.versions.node, '13.3.0')) {
7
- t.skip('Skip esm because Node version <= 13.3.0')
8
- } else {
9
- // Node v8 throw a `SyntaxError: Unexpected token import`
10
- // even if this branch is never touch in the code,
11
- // by using `eval` we can avoid this issue.
12
- // eslint-disable-next-line
13
- new Function('module', 'return import(module)')('./esm.mjs').catch((err) => {
14
- process.nextTick(() => {
15
- throw err
16
- })
17
- })
18
- }
19
-
20
6
  if (semver.lt(process.versions.node, '14.13.0')) {
21
7
  t.skip('Skip named exports because Node version < 14.13.0')
22
8
  } else {
@@ -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
@@ -17,7 +17,7 @@ test('Should accept a custom genReqId function', t => {
17
17
  reply.send({ id: req.id })
18
18
  })
19
19
 
20
- fastify.listen(0, err => {
20
+ fastify.listen({ port: 0 }, err => {
21
21
  t.error(err)
22
22
  fastify.inject({
23
23
  method: 'GET',
package/test/get.test.js CHANGED
@@ -203,7 +203,7 @@ test('send a falsy boolean', t => {
203
203
  }
204
204
  })
205
205
 
206
- fastify.listen(0, err => {
206
+ fastify.listen({ port: 0 }, err => {
207
207
  t.error(err)
208
208
  fastify.server.unref()
209
209
 
@@ -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
  })
@@ -32,7 +32,7 @@ test('handlers receive correct `this` context', (t) => {
32
32
  reply.send()
33
33
  })
34
34
 
35
- instance.listen(0, (err) => {
35
+ instance.listen({ port: 0 }, (err) => {
36
36
  instance.server.unref()
37
37
  if (err) t.threw(err)
38
38
  t.ok(instance.foo)
@@ -55,7 +55,7 @@ test('handlers have access to the internal context', (t) => {
55
55
  reply.send()
56
56
  })
57
57
 
58
- instance.listen(0, (err) => {
58
+ instance.listen({ port: 0 }, (err) => {
59
59
  instance.server.unref()
60
60
  if (err) t.threw(err)
61
61
  http.get(getUrl(instance), () => {}).on('error', t.threw)
package/test/head.test.js CHANGED
@@ -92,7 +92,7 @@ test('missing schema - head', t => {
92
92
  }
93
93
  })
94
94
 
95
- fastify.listen(0, err => {
95
+ fastify.listen({ port: 0 }, err => {
96
96
  t.error(err)
97
97
  fastify.server.unref()
98
98
 
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')
@@ -91,7 +92,7 @@ module.exports.payloadMethod = function (method, t, isSetErrorHandler = false) {
91
92
  }
92
93
  })
93
94
 
94
- fastify.listen(0, function (err) {
95
+ fastify.listen({ port: 0 }, function (err) {
95
96
  if (err) {
96
97
  t.error(err)
97
98
  return
@@ -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'
@@ -56,7 +56,7 @@ test('async hooks', t => {
56
56
  reply.code(200).send({ hello: 'world' })
57
57
  })
58
58
 
59
- fastify.listen(0, err => {
59
+ fastify.listen({ port: 0 }, err => {
60
60
  t.error(err)
61
61
  fastify.server.unref()
62
62
 
@@ -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) => {
@@ -112,7 +112,7 @@ t.test('listen and onReady order', async t => {
112
112
 
113
113
  await fastify.ready()
114
114
  t.pass('trigger the onReady')
115
- await fastify.listen(0)
115
+ await fastify.listen({ port: 0 })
116
116
  t.pass('do not trigger the onReady')
117
117
 
118
118
  await fastify.close()
@@ -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