fastify 5.0.0 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (201) hide show
  1. package/.borp.yaml +3 -0
  2. package/.vscode/settings.json +22 -0
  3. package/README.md +12 -7
  4. package/docs/Guides/Database.md +15 -15
  5. package/docs/Guides/Detecting-When-Clients-Abort.md +28 -28
  6. package/docs/Guides/Ecosystem.md +14 -15
  7. package/docs/Guides/Index.md +1 -1
  8. package/docs/Guides/Migration-Guide-V4.md +11 -11
  9. package/docs/Guides/Migration-Guide-V5.md +133 -9
  10. package/docs/Guides/Plugins-Guide.md +1 -1
  11. package/docs/Guides/Prototype-Poisoning.md +3 -3
  12. package/docs/Guides/Recommendations.md +9 -9
  13. package/docs/Guides/Serverless.md +5 -5
  14. package/docs/Guides/Testing.md +58 -57
  15. package/docs/Guides/Write-Plugin.md +2 -2
  16. package/docs/Guides/Write-Type-Provider.md +3 -3
  17. package/docs/Reference/ContentTypeParser.md +4 -4
  18. package/docs/Reference/Decorators.md +2 -2
  19. package/docs/Reference/Errors.md +3 -3
  20. package/docs/Reference/Hooks.md +7 -7
  21. package/docs/Reference/LTS.md +8 -0
  22. package/docs/Reference/Logging.md +5 -4
  23. package/docs/Reference/Reply.md +55 -58
  24. package/docs/Reference/Request.md +49 -42
  25. package/docs/Reference/Routes.md +16 -13
  26. package/docs/Reference/Server.md +32 -28
  27. package/docs/Reference/TypeScript.md +9 -9
  28. package/docs/Reference/Validation-and-Serialization.md +5 -5
  29. package/examples/typescript-server.ts +1 -1
  30. package/fastify.d.ts +14 -5
  31. package/fastify.js +8 -6
  32. package/lib/contentTypeParser.js +9 -7
  33. package/lib/context.js +1 -2
  34. package/lib/error-handler.js +9 -9
  35. package/lib/errors.js +1 -1
  36. package/lib/fourOhFour.js +1 -1
  37. package/lib/hooks.js +4 -1
  38. package/lib/{logger.js → logger-factory.js} +70 -122
  39. package/lib/logger-pino.js +68 -0
  40. package/lib/pluginOverride.js +1 -1
  41. package/lib/pluginUtils.js +2 -2
  42. package/lib/reply.js +4 -5
  43. package/lib/request.js +16 -9
  44. package/lib/route.js +23 -22
  45. package/lib/validation.js +2 -2
  46. package/package.json +13 -15
  47. package/test/404s.test.js +675 -629
  48. package/test/500s.test.js +72 -63
  49. package/test/{allowUnsafeRegex.test.js → allow-unsafe-regex.test.js} +30 -26
  50. package/test/als.test.js +48 -45
  51. package/test/async-await.test.js +148 -134
  52. package/test/async-dispose.test.js +4 -5
  53. package/test/async_hooks.test.js +30 -28
  54. package/test/{bodyLimit.test.js → body-limit.test.js} +61 -58
  55. package/test/buffer.test.js +9 -10
  56. package/test/build/error-serializer.test.js +3 -4
  57. package/test/build/version.test.js +2 -3
  58. package/test/build-certificate.js +1 -1
  59. package/test/bundler/README.md +5 -5
  60. package/test/bundler/esbuild/bundler-test.js +10 -9
  61. package/test/bundler/webpack/bundler-test.js +10 -9
  62. package/test/case-insensitive.test.js +31 -28
  63. package/test/chainable.test.js +4 -5
  64. package/test/check.test.js +8 -10
  65. package/test/{childLoggerFactory.test.js → child-logger-factory.test.js} +56 -19
  66. package/test/client-timeout.test.js +5 -5
  67. package/test/close-pipelining.test.js +6 -8
  68. package/test/conditional-pino.test.js +47 -0
  69. package/test/{connectionTimeout.test.js → connection-timeout.test.js} +10 -11
  70. package/test/constrained-routes.test.js +243 -236
  71. package/test/content-length.test.js +53 -68
  72. package/test/content-parser.test.js +186 -158
  73. package/test/content-type.test.js +8 -9
  74. package/test/context-config.test.js +44 -54
  75. package/test/custom-http-server.test.js +16 -20
  76. package/test/custom-parser.5.test.js +32 -32
  77. package/test/diagnostics-channel/404.test.js +15 -15
  78. package/test/diagnostics-channel/async-delay-request.test.js +25 -25
  79. package/test/diagnostics-channel/async-request.test.js +24 -24
  80. package/test/diagnostics-channel/error-before-handler.test.js +4 -5
  81. package/test/diagnostics-channel/error-request.test.js +19 -19
  82. package/test/diagnostics-channel/error-status.test.js +8 -8
  83. package/test/diagnostics-channel/init.test.js +6 -7
  84. package/test/diagnostics-channel/sync-delay-request.test.js +16 -16
  85. package/test/diagnostics-channel/sync-request-reply.test.js +16 -16
  86. package/test/diagnostics-channel/sync-request.test.js +19 -19
  87. package/test/encapsulated-child-logger-factory.test.js +8 -8
  88. package/test/encapsulated-error-handler.test.js +20 -20
  89. package/test/esm/errorCodes.test.mjs +5 -5
  90. package/test/esm/esm.test.mjs +3 -3
  91. package/test/esm/named-exports.mjs +3 -3
  92. package/test/esm/other.mjs +2 -2
  93. package/test/fastify-instance.test.js +33 -34
  94. package/test/{findRoute.test.js → find-route.test.js} +11 -10
  95. package/test/fluent-schema.test.js +33 -36
  96. package/test/handler-context.test.js +11 -11
  97. package/test/has-route.test.js +12 -15
  98. package/test/header-overflow.test.js +13 -12
  99. package/test/hooks.on-ready.test.js +2 -2
  100. package/test/hooks.test.js +25 -25
  101. package/test/http-methods/copy.test.js +22 -24
  102. package/test/http-methods/custom-http-methods.test.js +24 -21
  103. package/test/http-methods/get.test.js +97 -84
  104. package/test/http-methods/head.test.js +63 -57
  105. package/test/http-methods/lock.test.js +21 -20
  106. package/test/http-methods/mkcalendar.test.js +31 -27
  107. package/test/http-methods/mkcol.test.js +10 -10
  108. package/test/http-methods/move.test.js +11 -11
  109. package/test/http-methods/propfind.test.js +32 -27
  110. package/test/http-methods/proppatch.test.js +21 -19
  111. package/test/http-methods/report.test.js +32 -27
  112. package/test/http-methods/search.test.js +52 -47
  113. package/test/http-methods/trace.test.js +3 -4
  114. package/test/http-methods/unlock.test.js +10 -10
  115. package/test/http2/closing.test.js +50 -58
  116. package/test/http2/constraint.test.js +47 -50
  117. package/test/http2/head.test.js +18 -19
  118. package/test/http2/missing-http2-module.test.js +4 -5
  119. package/test/http2/plain.test.js +31 -31
  120. package/test/http2/secure-with-fallback.test.js +61 -61
  121. package/test/http2/secure.test.js +28 -31
  122. package/test/http2/unknown-http-method.test.js +13 -14
  123. package/test/https/custom-https-server.test.js +6 -7
  124. package/test/https/https.test.js +78 -78
  125. package/test/imports.test.js +5 -6
  126. package/test/internals/all.test.js +8 -11
  127. package/test/internals/{contentTypeParser.test.js → content-type-parser.test.js} +5 -6
  128. package/test/internals/context.test.js +9 -11
  129. package/test/internals/decorator.test.js +20 -21
  130. package/test/internals/errors.test.js +427 -427
  131. package/test/internals/{handleRequest.test.js → handle-request.test.js} +53 -42
  132. package/test/internals/{hookRunner.test.js → hook-runner.test.js} +99 -100
  133. package/test/internals/hooks.test.js +31 -35
  134. package/test/internals/{initialConfig.test.js → initial-config.test.js} +92 -80
  135. package/test/internals/logger.test.js +28 -28
  136. package/test/internals/plugin.test.js +17 -18
  137. package/test/internals/reply-serialize.test.js +106 -106
  138. package/test/internals/reply.test.js +620 -585
  139. package/test/internals/{reqIdGenFactory.test.js → req-id-gen-factory.test.js} +31 -31
  140. package/test/internals/request-validate.test.js +218 -221
  141. package/test/internals/request.test.js +225 -107
  142. package/test/internals/server.test.js +15 -12
  143. package/test/internals/validation.test.js +35 -36
  144. package/test/{keepAliveTimeout.test.js → keep-alive-timeout.test.js} +9 -10
  145. package/test/listen.5.test.js +9 -9
  146. package/test/{maxRequestsPerSocket.test.js → max-requests-per-socket.test.js} +30 -30
  147. package/test/middleware.test.js +4 -5
  148. package/test/noop-set.test.js +5 -5
  149. package/test/post-empty-body.test.js +18 -11
  150. package/test/pretty-print.test.js +59 -49
  151. package/test/proto-poisoning.test.js +42 -37
  152. package/test/reply-code.test.js +34 -32
  153. package/test/{reply-earlyHints.test.js → reply-early-hints.test.js} +21 -19
  154. package/test/request-error.test.js +122 -0
  155. package/test/request-header-host.test.js +339 -0
  156. package/test/request-id.test.js +31 -25
  157. package/test/{requestTimeout.test.js → request-timeout.test.js} +11 -11
  158. package/test/route.1.test.js +79 -72
  159. package/test/route.2.test.js +17 -16
  160. package/test/route.3.test.js +32 -27
  161. package/test/route.4.test.js +21 -25
  162. package/test/route.5.test.js +45 -64
  163. package/test/route.6.test.js +70 -89
  164. package/test/route.7.test.js +61 -65
  165. package/test/route.8.test.js +80 -18
  166. package/test/router-options.test.js +80 -77
  167. package/test/same-shape.test.js +5 -5
  168. package/test/schema-examples.test.js +72 -38
  169. package/test/serialize-response.test.js +9 -10
  170. package/test/server.test.js +75 -78
  171. package/test/set-error-handler.test.js +2 -3
  172. package/test/stream-serializers.test.js +10 -7
  173. package/test/sync-routes.test.js +18 -18
  174. package/test/test-reporter.mjs +68 -0
  175. package/test/trust-proxy.test.js +51 -45
  176. package/test/type-provider.test.js +8 -6
  177. package/test/types/content-type-parser.test-d.ts +1 -1
  178. package/test/types/fastify.test-d.ts +16 -4
  179. package/test/types/hooks.test-d.ts +2 -1
  180. package/test/types/instance.test-d.ts +13 -13
  181. package/test/types/logger.test-d.ts +2 -2
  182. package/test/types/plugin.test-d.ts +17 -9
  183. package/test/types/register.test-d.ts +22 -6
  184. package/test/types/reply.test-d.ts +1 -1
  185. package/test/types/route.test-d.ts +34 -4
  186. package/test/types/serverFactory.test-d.ts +1 -1
  187. package/test/types/type-provider.test-d.ts +1 -1
  188. package/test/url-rewriting.test.js +35 -38
  189. package/test/{useSemicolonDelimiter.test.js → use-semicolon-delimiter.test.js} +30 -30
  190. package/test/validation-error-handling.test.js +259 -285
  191. package/test/versioned-routes.test.js +126 -113
  192. package/test/web-api.test.js +48 -37
  193. package/test/{wrapThenable.test.js → wrap-thenable.test.js} +10 -9
  194. package/types/hooks.d.ts +2 -1
  195. package/types/instance.d.ts +9 -2
  196. package/types/register.d.ts +12 -3
  197. package/types/reply.d.ts +1 -1
  198. package/types/request.d.ts +2 -6
  199. package/types/serverFactory.d.ts +3 -3
  200. package/types/utils.d.ts +13 -5
  201. package/test/types/import.js +0 -2
@@ -2,11 +2,11 @@
2
2
 
3
3
  const stream = require('node:stream')
4
4
  const split = require('split2')
5
- const t = require('tap')
6
- const test = t.test
5
+ const { test } = require('node:test')
7
6
  const Fastify = require('..')
7
+ const createError = require('@fastify/error')
8
8
 
9
- test("HEAD route should handle stream.on('error')", t => {
9
+ test("HEAD route should handle stream.on('error')", (t, done) => {
10
10
  t.plan(6)
11
11
 
12
12
  const resStream = stream.Readable.from('Hello with error!')
@@ -31,23 +31,24 @@ test("HEAD route should handle stream.on('error')", t => {
31
31
 
32
32
  logStream.once('data', line => {
33
33
  const { message, stack } = expectedError
34
- t.same(line.err, { type: 'Error', message, stack })
35
- t.equal(line.msg, 'Error on Stream found for HEAD route')
36
- t.equal(line.level, 50)
34
+ t.assert.deepStrictEqual(line.err, { type: 'Error', message, stack })
35
+ t.assert.strictEqual(line.msg, 'Error on Stream found for HEAD route')
36
+ t.assert.strictEqual(line.level, 50)
37
37
  })
38
38
 
39
39
  fastify.inject({
40
40
  method: 'HEAD',
41
41
  url: '/more-coffee'
42
42
  }, (error, res) => {
43
- t.error(error)
44
- t.equal(res.statusCode, 200)
45
- t.equal(res.headers['content-type'], undefined)
43
+ t.assert.ifError(error)
44
+ t.assert.strictEqual(res.statusCode, 200)
45
+ t.assert.strictEqual(res.headers['content-type'], undefined)
46
+ done()
46
47
  })
47
48
  })
48
49
 
49
- test('HEAD route should be exposed by default', t => {
50
- t.plan(7)
50
+ test('HEAD route should be exposed by default', async t => {
51
+ t.plan(5)
51
52
 
52
53
  const resStream = stream.Readable.from('Hello with error!')
53
54
  const resJson = { hello: 'world' }
@@ -70,28 +71,24 @@ test('HEAD route should be exposed by default', t => {
70
71
  }
71
72
  })
72
73
 
73
- fastify.inject({
74
+ let res = await fastify.inject({
74
75
  method: 'HEAD',
75
76
  url: '/without-flag'
76
- }, (error, res) => {
77
- t.error(error)
78
- t.equal(res.statusCode, 200)
79
77
  })
78
+ t.assert.strictEqual(res.statusCode, 200)
80
79
 
81
- fastify.inject({
80
+ res = await fastify.inject({
82
81
  method: 'HEAD',
83
82
  url: '/with-flag'
84
- }, (error, res) => {
85
- t.error(error)
86
- t.equal(res.statusCode, 200)
87
- t.equal(res.headers['content-type'], 'application/json; charset=utf-8')
88
- t.equal(res.headers['content-length'], `${Buffer.byteLength(JSON.stringify(resJson))}`)
89
- t.equal(res.body, '')
90
83
  })
84
+ t.assert.strictEqual(res.statusCode, 200)
85
+ t.assert.strictEqual(res.headers['content-type'], 'application/json; charset=utf-8')
86
+ t.assert.strictEqual(res.headers['content-length'], `${Buffer.byteLength(JSON.stringify(resJson))}`)
87
+ t.assert.strictEqual(res.body, '')
91
88
  })
92
89
 
93
- test('HEAD route should be exposed if route exposeHeadRoute is set', t => {
94
- t.plan(7)
90
+ test('HEAD route should be exposed if route exposeHeadRoute is set', async t => {
91
+ t.plan(5)
95
92
 
96
93
  const resBuffer = Buffer.from('I am a coffee!')
97
94
  const resJson = { hello: 'world' }
@@ -114,27 +111,23 @@ test('HEAD route should be exposed if route exposeHeadRoute is set', t => {
114
111
  }
115
112
  })
116
113
 
117
- fastify.inject({
114
+ let res = await fastify.inject({
118
115
  method: 'HEAD',
119
116
  url: '/one'
120
- }, (error, res) => {
121
- t.error(error)
122
- t.equal(res.statusCode, 200)
123
- t.equal(res.headers['content-type'], 'application/octet-stream')
124
- t.equal(res.headers['content-length'], `${resBuffer.byteLength}`)
125
- t.equal(res.body, '')
126
117
  })
118
+ t.assert.strictEqual(res.statusCode, 200)
119
+ t.assert.strictEqual(res.headers['content-type'], 'application/octet-stream')
120
+ t.assert.strictEqual(res.headers['content-length'], `${resBuffer.byteLength}`)
121
+ t.assert.strictEqual(res.body, '')
127
122
 
128
- fastify.inject({
123
+ res = await fastify.inject({
129
124
  method: 'HEAD',
130
125
  url: '/two'
131
- }, (error, res) => {
132
- t.error(error)
133
- t.equal(res.statusCode, 404)
134
126
  })
127
+ t.assert.strictEqual(res.statusCode, 404)
135
128
  })
136
129
 
137
- test('Set a custom HEAD route before GET one without disabling exposeHeadRoutes (global)', t => {
130
+ test('Set a custom HEAD route before GET one without disabling exposeHeadRoutes (global)', (t, done) => {
138
131
  t.plan(6)
139
132
 
140
133
  const resBuffer = Buffer.from('I am a coffee!')
@@ -165,16 +158,17 @@ test('Set a custom HEAD route before GET one without disabling exposeHeadRoutes
165
158
  method: 'HEAD',
166
159
  url: '/one'
167
160
  }, (error, res) => {
168
- t.error(error)
169
- t.equal(res.statusCode, 200)
170
- t.equal(res.headers['content-type'], 'application/pdf')
171
- t.equal(res.headers['content-length'], `${resBuffer.byteLength}`)
172
- t.equal(res.headers['x-custom-header'], 'some-custom-header')
173
- t.equal(res.body, '')
161
+ t.assert.ifError(error)
162
+ t.assert.strictEqual(res.statusCode, 200)
163
+ t.assert.strictEqual(res.headers['content-type'], 'application/pdf')
164
+ t.assert.strictEqual(res.headers['content-length'], `${resBuffer.byteLength}`)
165
+ t.assert.strictEqual(res.headers['x-custom-header'], 'some-custom-header')
166
+ t.assert.strictEqual(res.body, '')
167
+ done()
174
168
  })
175
169
  })
176
170
 
177
- test('Set a custom HEAD route before GET one without disabling exposeHeadRoutes (route)', t => {
171
+ test('Set a custom HEAD route before GET one without disabling exposeHeadRoutes (route)', (t, done) => {
178
172
  t.plan(6)
179
173
 
180
174
  const fastify = Fastify()
@@ -205,16 +199,17 @@ test('Set a custom HEAD route before GET one without disabling exposeHeadRoutes
205
199
  method: 'HEAD',
206
200
  url: '/one'
207
201
  }, (error, res) => {
208
- t.error(error)
209
- t.equal(res.statusCode, 200)
210
- t.equal(res.headers['content-type'], 'application/pdf')
211
- t.equal(res.headers['content-length'], `${resBuffer.byteLength}`)
212
- t.equal(res.headers['x-custom-header'], 'some-custom-header')
213
- t.equal(res.body, '')
202
+ t.assert.ifError(error)
203
+ t.assert.strictEqual(res.statusCode, 200)
204
+ t.assert.strictEqual(res.headers['content-type'], 'application/pdf')
205
+ t.assert.strictEqual(res.headers['content-length'], `${resBuffer.byteLength}`)
206
+ t.assert.strictEqual(res.headers['x-custom-header'], 'some-custom-header')
207
+ t.assert.strictEqual(res.body, '')
208
+ done()
214
209
  })
215
210
  })
216
211
 
217
- test('HEAD routes properly auto created for GET routes when prefixTrailingSlash: \'no-slash\'', t => {
212
+ test('HEAD routes properly auto created for GET routes when prefixTrailingSlash: \'no-slash\'', (t, done) => {
218
213
  t.plan(2)
219
214
 
220
215
  const fastify = Fastify()
@@ -234,8 +229,9 @@ test('HEAD routes properly auto created for GET routes when prefixTrailingSlash:
234
229
  }, { prefix: '/prefix' })
235
230
 
236
231
  fastify.inject({ url: '/prefix/prefix', method: 'HEAD' }, (err, res) => {
237
- t.error(err)
238
- t.equal(res.statusCode, 404)
232
+ t.assert.ifError(err)
233
+ t.assert.strictEqual(res.statusCode, 404)
234
+ done()
239
235
  })
240
236
  })
241
237
 
@@ -262,9 +258,9 @@ test('HEAD routes properly auto created for GET routes when prefixTrailingSlash:
262
258
  const trailingSlashReply = await fastify.inject({ url: '/prefix/', method: 'HEAD' })
263
259
  const noneTrailingReply = await fastify.inject({ url: '/prefix', method: 'HEAD' })
264
260
 
265
- t.equal(doublePrefixReply.statusCode, 404)
266
- t.equal(trailingSlashReply.statusCode, 200)
267
- t.equal(noneTrailingReply.statusCode, 200)
261
+ t.assert.strictEqual(doublePrefixReply.statusCode, 404)
262
+ t.assert.strictEqual(trailingSlashReply.statusCode, 200)
263
+ t.assert.strictEqual(noneTrailingReply.statusCode, 200)
268
264
  })
269
265
 
270
266
  test('GET route with body schema should throw', t => {
@@ -272,7 +268,7 @@ test('GET route with body schema should throw', t => {
272
268
 
273
269
  const fastify = Fastify()
274
270
 
275
- t.throws(() => {
271
+ t.assert.throws(() => {
276
272
  fastify.route({
277
273
  method: 'GET',
278
274
  path: '/get',
@@ -283,7 +279,7 @@ test('GET route with body schema should throw', t => {
283
279
  reply.send({ hello: 'world' })
284
280
  }
285
281
  })
286
- }, new Error('Body validation schema for GET:/get route is not supported!'))
282
+ }, createError('FST_ERR_ROUTE_BODY_VALIDATION_SCHEMA_NOT_SUPPORTED', 'Body validation schema for GET:/get route is not supported!')())
287
283
  })
288
284
 
289
285
  test('HEAD route with body schema should throw', t => {
@@ -291,7 +287,7 @@ test('HEAD route with body schema should throw', t => {
291
287
 
292
288
  const fastify = Fastify()
293
289
 
294
- t.throws(() => {
290
+ t.assert.throws(() => {
295
291
  fastify.route({
296
292
  method: 'HEAD',
297
293
  path: '/shouldThrow',
@@ -302,7 +298,7 @@ test('HEAD route with body schema should throw', t => {
302
298
  reply.send({ hello: 'world' })
303
299
  }
304
300
  })
305
- }, new Error('Body validation schema for HEAD:/shouldThrow route is not supported!'))
301
+ }, createError('FST_ERR_ROUTE_BODY_VALIDATION_SCHEMA_NOT_SUPPORTED', 'Body validation schema for HEAD:/shouldThrow route is not supported!')())
306
302
  })
307
303
 
308
304
  test('[HEAD, GET] route with body schema should throw', t => {
@@ -310,7 +306,7 @@ test('[HEAD, GET] route with body schema should throw', t => {
310
306
 
311
307
  const fastify = Fastify()
312
308
 
313
- t.throws(() => {
309
+ t.assert.throws(() => {
314
310
  fastify.route({
315
311
  method: ['HEAD', 'GET'],
316
312
  path: '/shouldThrowHead',
@@ -321,7 +317,7 @@ test('[HEAD, GET] route with body schema should throw', t => {
321
317
  reply.send({ hello: 'world' })
322
318
  }
323
319
  })
324
- }, new Error('Body validation schema for HEAD:/shouldThrowHead route is not supported!'))
320
+ }, createError('FST_ERR_ROUTE_BODY_VALIDATION_SCHEMA_NOT_SUPPORTED', 'Body validation schema for HEAD:/shouldThrowHead route is not supported!')())
325
321
  })
326
322
 
327
323
  test('GET route with body schema should throw - shorthand', t => {
@@ -329,7 +325,7 @@ test('GET route with body schema should throw - shorthand', t => {
329
325
 
330
326
  const fastify = Fastify()
331
327
 
332
- t.throws(() => {
328
+ t.assert.throws(() => {
333
329
  fastify.get('/shouldThrow', {
334
330
  schema: {
335
331
  body: {}
@@ -339,7 +335,7 @@ test('GET route with body schema should throw - shorthand', t => {
339
335
  reply.send({ hello: 'world' })
340
336
  }
341
337
  )
342
- }, new Error('Body validation schema for GET:/shouldThrow route is not supported!'))
338
+ }, createError('FST_ERR_ROUTE_BODY_VALIDATION_SCHEMA_NOT_SUPPORTED', 'Body validation schema for GET:/shouldThrow route is not supported!')())
343
339
  })
344
340
 
345
341
  test('HEAD route with body schema should throw - shorthand', t => {
@@ -347,7 +343,7 @@ test('HEAD route with body schema should throw - shorthand', t => {
347
343
 
348
344
  const fastify = Fastify()
349
345
 
350
- t.throws(() => {
346
+ t.assert.throws(() => {
351
347
  fastify.head('/shouldThrow2', {
352
348
  schema: {
353
349
  body: {}
@@ -357,5 +353,5 @@ test('HEAD route with body schema should throw - shorthand', t => {
357
353
  reply.send({ hello: 'world' })
358
354
  }
359
355
  )
360
- }, new Error('Body validation schema for HEAD:/shouldThrow2 route is not supported!'))
356
+ }, createError('FST_ERR_ROUTE_BODY_VALIDATION_SCHEMA_NOT_SUPPORTED', 'Body validation schema for HEAD:/shouldThrow2 route is not supported!')())
361
357
  })
@@ -1,9 +1,8 @@
1
1
  'use strict'
2
2
 
3
- const t = require('tap')
4
- const test = t.test
3
+ const { test } = require('node:test')
5
4
  const sget = require('simple-get').concat
6
- const Fastify = require('../fastify')
5
+ const Fastify = require('..')
7
6
  const {
8
7
  FST_ERR_INVALID_URL
9
8
  } = require('../lib/errors')
@@ -24,9 +23,9 @@ test('Request and Reply share the route options', async t => {
24
23
  url: '/',
25
24
  config,
26
25
  handler: (req, reply) => {
27
- t.same(req.routeOptions, reply.routeOptions)
28
- t.same(req.routeOptions.config, reply.routeOptions.config)
29
- t.match(req.routeOptions.config, config, 'there are url and method additional properties')
26
+ t.assert.deepStrictEqual(req.routeOptions, reply.routeOptions)
27
+ t.assert.deepStrictEqual(req.routeOptions.config, reply.routeOptions.config)
28
+ t.assert.match(req.routeOptions.config, config, 'there are url and method additional properties')
30
29
 
31
30
  reply.send({ hello: 'world' })
32
31
  }
@@ -62,10 +61,10 @@ test('Will not try to re-createprefixed HEAD route if it already exists and expo
62
61
 
63
62
  await fastify.ready()
64
63
 
65
- t.ok(true)
64
+ t.assert.ok(true)
66
65
  })
67
66
 
68
- test('route with non-english characters', t => {
67
+ test('route with non-english characters', (t, done) => {
69
68
  t.plan(4)
70
69
 
71
70
  const fastify = Fastify()
@@ -75,16 +74,17 @@ test('route with non-english characters', t => {
75
74
  })
76
75
 
77
76
  fastify.listen({ port: 0 }, err => {
78
- t.error(err)
79
- t.teardown(() => { fastify.close() })
77
+ t.assert.ifError(err)
78
+ t.after(() => fastify.close())
80
79
 
81
80
  sget({
82
81
  method: 'GET',
83
82
  url: getServerUrl(fastify) + encodeURI('/föö')
84
83
  }, (err, response, body) => {
85
- t.error(err)
86
- t.equal(response.statusCode, 200)
87
- t.equal(body.toString(), 'here /föö')
84
+ t.assert.ifError(err)
85
+ t.assert.strictEqual(response.statusCode, 200)
86
+ t.assert.strictEqual(body.toString(), 'here /föö')
87
+ done()
88
88
  })
89
89
  })
90
90
  })
@@ -96,7 +96,7 @@ test('invalid url attribute - non string URL', t => {
96
96
  try {
97
97
  fastify.get(/^\/(donations|skills|blogs)/, () => { })
98
98
  } catch (error) {
99
- t.equal(error.code, FST_ERR_INVALID_URL().code)
99
+ t.assert.strictEqual(error.code, FST_ERR_INVALID_URL().code)
100
100
  }
101
101
  })
102
102
 
@@ -117,7 +117,7 @@ test('exposeHeadRoute should not reuse the same route option', async t => {
117
117
  })
118
118
 
119
119
  fastify.addHook('onRoute', function (routeOption) {
120
- t.equal(routeOption.onRequest.length, 1)
120
+ t.assert.strictEqual(routeOption.onRequest.length, 1)
121
121
  })
122
122
 
123
123
  fastify.route({
@@ -140,7 +140,7 @@ test('using fastify.all when a catchall is defined does not degrade performance'
140
140
  fastify.all(`/${i}`, async (_, reply) => reply.json({ ok: true }))
141
141
  }
142
142
 
143
- t.pass()
143
+ t.assert.ok("fastify.all doesn't degrade performance")
144
144
  })
145
145
 
146
146
  test('Adding manually HEAD route after GET with the same path throws Fastify duplicated route instance error', t => {
@@ -164,8 +164,70 @@ test('Adding manually HEAD route after GET with the same path throws Fastify dup
164
164
  reply.send({ hello: 'world' })
165
165
  }
166
166
  })
167
- t.fail('Should throw fastify duplicated route declaration')
167
+ t.assert.fail('Should throw fastify duplicated route declaration')
168
168
  } catch (error) {
169
- t.equal(error.code, 'FST_ERR_DUPLICATED_ROUTE')
169
+ t.assert.strictEqual(error.code, 'FST_ERR_DUPLICATED_ROUTE')
170
170
  }
171
171
  })
172
+
173
+ test('Will pass onSend hook to HEAD method if exposeHeadRoutes is true /1', async (t) => {
174
+ t.plan(1)
175
+
176
+ const fastify = Fastify({ exposeHeadRoutes: true })
177
+
178
+ await fastify.register((scope, opts, next) => {
179
+ scope.route({
180
+ method: 'GET',
181
+ path: '/route',
182
+ handler: (req, reply) => {
183
+ reply.send({ ok: true })
184
+ },
185
+ onSend: (req, reply, payload, done) => {
186
+ reply.header('x-content-type', 'application/fastify')
187
+ done(null, payload)
188
+ }
189
+ })
190
+
191
+ next()
192
+ }, { prefix: '/prefix' })
193
+
194
+ await fastify.ready()
195
+
196
+ const result = await fastify.inject({
197
+ url: '/prefix/route',
198
+ method: 'HEAD'
199
+ })
200
+
201
+ t.assert.strictEqual(result.headers['x-content-type'], 'application/fastify')
202
+ })
203
+
204
+ test('Will pass onSend hook to HEAD method if exposeHeadRoutes is true /2', async (t) => {
205
+ t.plan(1)
206
+
207
+ const fastify = Fastify({ exposeHeadRoutes: true })
208
+
209
+ await fastify.register((scope, opts, next) => {
210
+ scope.route({
211
+ method: 'get',
212
+ path: '/route',
213
+ handler: (req, reply) => {
214
+ reply.send({ ok: true })
215
+ },
216
+ onSend: (req, reply, payload, done) => {
217
+ reply.header('x-content-type', 'application/fastify')
218
+ done(null, payload)
219
+ }
220
+ })
221
+
222
+ next()
223
+ }, { prefix: '/prefix' })
224
+
225
+ await fastify.ready()
226
+
227
+ const result = await fastify.inject({
228
+ url: '/prefix/route',
229
+ method: 'HEAD'
230
+ })
231
+
232
+ t.assert.strictEqual(result.headers['x-content-type'], 'application/fastify')
233
+ })