fastify 5.0.0-alpha.2 → 5.0.0-alpha.4

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 (290) hide show
  1. package/README.md +2 -2
  2. package/SPONSORS.md +2 -0
  3. package/build/build-validation.js +3 -15
  4. package/docs/Guides/Ecosystem.md +4 -0
  5. package/docs/Guides/Getting-Started.md +0 -2
  6. package/docs/Guides/Migration-Guide-V4.md +48 -0
  7. package/docs/Guides/Recommendations.md +8 -6
  8. package/docs/Reference/Errors.md +0 -2
  9. package/docs/Reference/Hooks.md +5 -9
  10. package/docs/Reference/Logging.md +1 -1
  11. package/docs/Reference/Reply.md +9 -11
  12. package/docs/Reference/Request.md +0 -11
  13. package/docs/Reference/Routes.md +4 -23
  14. package/docs/Reference/Server.md +30 -40
  15. package/docs/Reference/Type-Providers.md +2 -2
  16. package/docs/Reference/TypeScript.md +16 -18
  17. package/docs/Reference/Validation-and-Serialization.md +62 -27
  18. package/docs/Reference/Warnings.md +0 -26
  19. package/eslint.config.js +9 -25
  20. package/fastify.d.ts +10 -23
  21. package/fastify.js +60 -61
  22. package/lib/configValidator.js +130 -182
  23. package/lib/context.js +1 -22
  24. package/lib/decorate.js +2 -2
  25. package/lib/errors.js +0 -6
  26. package/lib/handleRequest.js +5 -5
  27. package/lib/reply.js +34 -74
  28. package/lib/request.js +0 -45
  29. package/lib/route.js +12 -27
  30. package/lib/schemas.js +27 -22
  31. package/lib/server.js +6 -11
  32. package/lib/symbols.js +1 -1
  33. package/lib/validation.js +27 -6
  34. package/lib/warnings.js +1 -92
  35. package/lib/wrapThenable.js +1 -1
  36. package/package.json +14 -15
  37. package/test/decorator.test.js +1 -1
  38. package/test/diagnostics-channel/404.test.js +1 -1
  39. package/test/diagnostics-channel/async-delay-request.test.js +1 -1
  40. package/test/diagnostics-channel/async-request.test.js +1 -1
  41. package/test/diagnostics-channel/error-before-handler.test.js +1 -1
  42. package/test/diagnostics-channel/error-request.test.js +1 -1
  43. package/test/diagnostics-channel/error-status.test.js +1 -1
  44. package/test/diagnostics-channel/init.test.js +2 -2
  45. package/test/diagnostics-channel/sync-delay-request.test.js +1 -1
  46. package/test/diagnostics-channel/sync-request-reply.test.js +1 -1
  47. package/test/diagnostics-channel/sync-request.test.js +1 -1
  48. package/test/{copy.test.js → http-methods/copy.test.js} +2 -1
  49. package/test/http-methods/custom-http-methods.test.js +111 -0
  50. package/test/{get.test.js → http-methods/get.test.js} +1 -1
  51. package/test/{head.test.js → http-methods/head.test.js} +7 -87
  52. package/test/{lock.test.js → http-methods/lock.test.js} +2 -1
  53. package/test/{mkcalendar.test.js → http-methods/mkcalendar.test.js} +2 -1
  54. package/test/{mkcol.test.js → http-methods/mkcol.test.js} +2 -1
  55. package/test/{move.test.js → http-methods/move.test.js} +2 -1
  56. package/test/{propfind.test.js → http-methods/propfind.test.js} +2 -1
  57. package/test/{proppatch.test.js → http-methods/proppatch.test.js} +2 -1
  58. package/test/{report.test.js → http-methods/report.test.js} +2 -1
  59. package/test/{search.test.js → http-methods/search.test.js} +2 -1
  60. package/test/{trace.test.js → http-methods/trace.test.js} +2 -1
  61. package/test/{unlock.test.js → http-methods/unlock.test.js} +2 -1
  62. package/test/internals/all.test.js +3 -3
  63. package/test/internals/decorator.test.js +2 -2
  64. package/test/internals/errors.test.js +7 -17
  65. package/test/internals/initialConfig.test.js +0 -31
  66. package/test/internals/reply-serialize.test.js +25 -10
  67. package/test/internals/reply.test.js +31 -153
  68. package/test/internals/request-validate.test.js +21 -12
  69. package/test/internals/request.test.js +1 -18
  70. package/test/internals/validation.test.js +49 -56
  71. package/test/listen.1.test.js +66 -14
  72. package/test/listen.5.test.js +11 -0
  73. package/test/reply-trailers.test.js +1 -32
  74. package/test/route-shorthand.test.js +3 -1
  75. package/test/route.3.test.js +4 -1
  76. package/test/route.7.test.js +2 -12
  77. package/test/route.8.test.js +34 -5
  78. package/test/router-options.test.js +6 -3
  79. package/test/schema-examples.test.js +15 -6
  80. package/test/schema-feature.test.js +178 -35
  81. package/test/schema-serialization.test.js +125 -21
  82. package/test/schema-validation.test.js +154 -3
  83. package/test/skip-reply-send.test.js +6 -6
  84. package/test/stream-serializers.test.js +37 -0
  85. package/test/throw.test.js +2 -14
  86. package/test/types/errors.test-d.ts +1 -2
  87. package/test/types/fastify.test-d.ts +23 -34
  88. package/test/types/hooks.test-d.ts +56 -56
  89. package/test/types/instance.test-d.ts +3 -3
  90. package/test/types/reply.test-d.ts +7 -8
  91. package/test/types/request.test-d.ts +2 -12
  92. package/test/types/route.test-d.ts +158 -158
  93. package/test/types/schema.test-d.ts +22 -5
  94. package/test/versioned-routes.test.js +0 -90
  95. package/test/web-api.test.js +75 -0
  96. package/types/errors.d.ts +78 -79
  97. package/types/hooks.d.ts +18 -18
  98. package/types/instance.d.ts +1 -1
  99. package/types/logger.d.ts +7 -7
  100. package/types/reply.d.ts +18 -22
  101. package/types/request.d.ts +8 -14
  102. package/types/route.d.ts +5 -6
  103. package/types/type-provider.d.ts +1 -1
  104. package/.tap/processinfo/09002e93-10ad-430c-bc86-c0576928b0ed.json +0 -241
  105. package/.tap/processinfo/ee66c5ab-635d-48b5-8be6-3dc3ceea5bfc.json +0 -268
  106. package/.tap/test-results/test/404s.test.js.tap +0 -623
  107. package/.tap/test-results/test/500s.test.js.tap +0 -64
  108. package/.tap/test-results/test/allowUnsafeRegex.test.js.tap +0 -36
  109. package/.tap/test-results/test/als.test.js.tap +0 -15
  110. package/.tap/test-results/test/async-await.test.js.tap +0 -184
  111. package/.tap/test-results/test/async-dispose.test.js.tap +0 -8
  112. package/.tap/test-results/test/async_hooks.test.js.tap +0 -10
  113. package/.tap/test-results/test/bodyLimit.test.js.tap +0 -48
  114. package/.tap/test-results/test/buffer.test.js.tap +0 -20
  115. package/.tap/test-results/test/build/error-serializer.test.js.tap +0 -12
  116. package/.tap/test-results/test/build/version.test.js.tap +0 -7
  117. package/.tap/test-results/test/case-insensitive.test.js.tap +0 -36
  118. package/.tap/test-results/test/chainable.test.js.tap +0 -17
  119. package/.tap/test-results/test/check.test.js.tap +0 -10
  120. package/.tap/test-results/test/childLoggerFactory.test.js.tap +0 -23
  121. package/.tap/test-results/test/client-timeout.test.js.tap +0 -7
  122. package/.tap/test-results/test/close-pipelining.test.js.tap +0 -15
  123. package/.tap/test-results/test/close.test.js.tap +0 -172
  124. package/.tap/test-results/test/connectionTimeout.test.js.tap +0 -12
  125. package/.tap/test-results/test/constrained-routes.test.js.tap +0 -173
  126. package/.tap/test-results/test/content-length.test.js.tap +0 -46
  127. package/.tap/test-results/test/content-parser.test.js.tap +0 -266
  128. package/.tap/test-results/test/content-type.test.js.tap +0 -14
  129. package/.tap/test-results/test/context-config.test.js.tap +0 -41
  130. package/.tap/test-results/test/copy.test.js.tap +0 -14
  131. package/.tap/test-results/test/custom-http-server.test.js.tap +0 -30
  132. package/.tap/test-results/test/custom-parser-async.test.js.tap +0 -21
  133. package/.tap/test-results/test/custom-parser.0.test.js.tap +0 -199
  134. package/.tap/test-results/test/custom-parser.1.test.js.tap +0 -90
  135. package/.tap/test-results/test/custom-parser.2.test.js.tap +0 -22
  136. package/.tap/test-results/test/custom-parser.3.test.js.tap +0 -53
  137. package/.tap/test-results/test/custom-parser.4.test.js.tap +0 -45
  138. package/.tap/test-results/test/custom-parser.5.test.js.tap +0 -41
  139. package/.tap/test-results/test/custom-querystring-parser.test.js.tap +0 -46
  140. package/.tap/test-results/test/decorator.test.js.tap +0 -465
  141. package/.tap/test-results/test/delete.test.js.tap +0 -110
  142. package/.tap/test-results/test/diagnostics-channel/404.test.js.tap +0 -15
  143. package/.tap/test-results/test/diagnostics-channel/async-delay-request.test.js.tap +0 -25
  144. package/.tap/test-results/test/diagnostics-channel/async-request.test.js.tap +0 -24
  145. package/.tap/test-results/test/diagnostics-channel/error-before-handler.test.js.tap +0 -9
  146. package/.tap/test-results/test/diagnostics-channel/error-request.test.js.tap +0 -20
  147. package/.tap/test-results/test/diagnostics-channel/error-status.test.js.tap +0 -10
  148. package/.tap/test-results/test/diagnostics-channel/init.test.js.tap +0 -14
  149. package/.tap/test-results/test/diagnostics-channel/sync-delay-request.test.js.tap +0 -16
  150. package/.tap/test-results/test/diagnostics-channel/sync-request-reply.test.js.tap +0 -16
  151. package/.tap/test-results/test/diagnostics-channel/sync-request.test.js.tap +0 -19
  152. package/.tap/test-results/test/encapsulated-child-logger-factory.test.js.tap +0 -18
  153. package/.tap/test-results/test/encapsulated-error-handler.test.js.tap +0 -243
  154. package/.tap/test-results/test/esm/errorCodes.test.mjs.tap +0 -9
  155. package/.tap/test-results/test/esm/esm.test.mjs.tap +0 -8
  156. package/.tap/test-results/test/esm/index.test.js.tap +0 -8
  157. package/.tap/test-results/test/fastify-instance.test.js.tap +0 -114
  158. package/.tap/test-results/test/findRoute.test.js.tap +0 -37
  159. package/.tap/test-results/test/fluent-schema.test.js.tap +0 -36
  160. package/.tap/test-results/test/genReqId.test.js.tap +0 -106
  161. package/.tap/test-results/test/get.test.js.tap +0 -151
  162. package/.tap/test-results/test/handler-context.test.js.tap +0 -19
  163. package/.tap/test-results/test/has-route.test.js.tap +0 -30
  164. package/.tap/test-results/test/head.test.js.tap +0 -130
  165. package/.tap/test-results/test/header-overflow.test.js.tap +0 -16
  166. package/.tap/test-results/test/hooks-async.test.js.tap +0 -286
  167. package/.tap/test-results/test/hooks.on-listen.test.js.tap +0 -311
  168. package/.tap/test-results/test/hooks.on-ready.test.js.tap +0 -151
  169. package/.tap/test-results/test/hooks.test.js.tap +0 -966
  170. package/.tap/test-results/test/http2/closing.test.js.tap +0 -35
  171. package/.tap/test-results/test/http2/constraint.test.js.tap +0 -32
  172. package/.tap/test-results/test/http2/head.test.js.tap +0 -9
  173. package/.tap/test-results/test/http2/missing-http2-module.test.js.tap +0 -8
  174. package/.tap/test-results/test/http2/plain.test.js.tap +0 -22
  175. package/.tap/test-results/test/http2/secure-with-fallback.test.js.tap +0 -40
  176. package/.tap/test-results/test/http2/secure.test.js.tap +0 -27
  177. package/.tap/test-results/test/http2/unknown-http-method.test.js.tap +0 -9
  178. package/.tap/test-results/test/https/custom-https-server.test.js.tap +0 -10
  179. package/.tap/test-results/test/https/https.test.js.tap +0 -45
  180. package/.tap/test-results/test/imports.test.js.tap +0 -14
  181. package/.tap/test-results/test/inject.test.js.tap +0 -165
  182. package/.tap/test-results/test/internals/all.test.js.tap +0 -42
  183. package/.tap/test-results/test/internals/contentTypeParser.test.js.tap +0 -14
  184. package/.tap/test-results/test/internals/context.test.js.tap +0 -14
  185. package/.tap/test-results/test/internals/decorator.test.js.tap +0 -51
  186. package/.tap/test-results/test/internals/errors.test.js.tap +0 -1212
  187. package/.tap/test-results/test/internals/handleRequest.test.js.tap +0 -69
  188. package/.tap/test-results/test/internals/hookRunner.test.js.tap +0 -143
  189. package/.tap/test-results/test/internals/hooks.test.js.tap +0 -45
  190. package/.tap/test-results/test/internals/initialConfig.test.js.tap +0 -125
  191. package/.tap/test-results/test/internals/logger.test.js.tap +0 -71
  192. package/.tap/test-results/test/internals/plugin.test.js.tap +0 -48
  193. package/.tap/test-results/test/internals/reply-serialize.test.js.tap +0 -166
  194. package/.tap/test-results/test/internals/reply.test.js.tap +0 -688
  195. package/.tap/test-results/test/internals/reqIdGenFactory.test.js.tap +0 -74
  196. package/.tap/test-results/test/internals/request-validate.test.js.tap +0 -384
  197. package/.tap/test-results/test/internals/request.test.js.tap +0 -163
  198. package/.tap/test-results/test/internals/server.test.js.tap +0 -30
  199. package/.tap/test-results/test/internals/validation.test.js.tap +0 -121
  200. package/.tap/test-results/test/keepAliveTimeout.test.js.tap +0 -12
  201. package/.tap/test-results/test/listen.1.test.js.tap +0 -31
  202. package/.tap/test-results/test/listen.2.test.js.tap +0 -46
  203. package/.tap/test-results/test/listen.3.test.js.tap +0 -25
  204. package/.tap/test-results/test/listen.4.test.js.tap +0 -51
  205. package/.tap/test-results/test/lock.test.js.tap +0 -29
  206. package/.tap/test-results/test/logger/instantiation.test.js.tap +0 -92
  207. package/.tap/test-results/test/logger/logging.test.js.tap +0 -117
  208. package/.tap/test-results/test/logger/options.test.js.tap +0 -165
  209. package/.tap/test-results/test/logger/request.test.js.tap +0 -82
  210. package/.tap/test-results/test/logger/response.test.js.tap +0 -38
  211. package/.tap/test-results/test/maxRequestsPerSocket.test.js.tap +0 -44
  212. package/.tap/test-results/test/method-missing.test.js.tap +0 -8
  213. package/.tap/test-results/test/middleware.test.js.tap +0 -17
  214. package/.tap/test-results/test/mkcalendar.test.js.tap +0 -43
  215. package/.tap/test-results/test/mkcol.test.js.tap +0 -14
  216. package/.tap/test-results/test/move.test.js.tap +0 -15
  217. package/.tap/test-results/test/noop-set.test.js.tap +0 -8
  218. package/.tap/test-results/test/nullable-validation.test.js.tap +0 -36
  219. package/.tap/test-results/test/options.error-handler.test.js.tap +0 -186
  220. package/.tap/test-results/test/options.test.js.tap +0 -174
  221. package/.tap/test-results/test/output-validation.test.js.tap +0 -66
  222. package/.tap/test-results/test/patch.error-handler.test.js.tap +0 -206
  223. package/.tap/test-results/test/patch.test.js.tap +0 -182
  224. package/.tap/test-results/test/plugin.1.test.js.tap +0 -78
  225. package/.tap/test-results/test/plugin.2.test.js.tap +0 -102
  226. package/.tap/test-results/test/plugin.3.test.js.tap +0 -58
  227. package/.tap/test-results/test/plugin.4.test.js.tap +0 -164
  228. package/.tap/test-results/test/post-empty-body.test.js.tap +0 -8
  229. package/.tap/test-results/test/pretty-print.test.js.tap +0 -82
  230. package/.tap/test-results/test/promises.test.js.tap +0 -46
  231. package/.tap/test-results/test/propfind.test.js.tap +0 -43
  232. package/.tap/test-results/test/proppatch.test.js.tap +0 -29
  233. package/.tap/test-results/test/proto-poisoning.test.js.tap +0 -47
  234. package/.tap/test-results/test/put.error-handler.test.js.tap +0 -206
  235. package/.tap/test-results/test/put.test.js.tap +0 -182
  236. package/.tap/test-results/test/register.test.js.tap +0 -61
  237. package/.tap/test-results/test/reply-code.test.js.tap +0 -40
  238. package/.tap/test-results/test/reply-earlyHints.test.js.tap +0 -22
  239. package/.tap/test-results/test/reply-error.test.js.tap +0 -643
  240. package/.tap/test-results/test/reply-trailers.test.js.tap +0 -176
  241. package/.tap/test-results/test/report.test.js.tap +0 -43
  242. package/.tap/test-results/test/request-error.test.js.tap +0 -98
  243. package/.tap/test-results/test/request-id.test.js.tap +0 -38
  244. package/.tap/test-results/test/request.deprecated.test.js.tap +0 -13
  245. package/.tap/test-results/test/requestTimeout.test.js.tap +0 -21
  246. package/.tap/test-results/test/route-hooks.test.js.tap +0 -498
  247. package/.tap/test-results/test/route-prefix.test.js.tap +0 -195
  248. package/.tap/test-results/test/route-shorthand.test.js.tap +0 -190
  249. package/.tap/test-results/test/route.1.test.js.tap +0 -93
  250. package/.tap/test-results/test/route.2.test.js.tap +0 -28
  251. package/.tap/test-results/test/route.3.test.js.tap +0 -39
  252. package/.tap/test-results/test/route.4.test.js.tap +0 -32
  253. package/.tap/test-results/test/route.5.test.js.tap +0 -54
  254. package/.tap/test-results/test/route.6.test.js.tap +0 -81
  255. package/.tap/test-results/test/route.7.test.js.tap +0 -93
  256. package/.tap/test-results/test/route.8.test.js.tap +0 -38
  257. package/.tap/test-results/test/router-options.test.js.tap +0 -104
  258. package/.tap/test-results/test/same-shape.test.js.tap +0 -22
  259. package/.tap/test-results/test/schema-examples.test.js.tap +0 -85
  260. package/.tap/test-results/test/schema-feature.test.js.tap +0 -445
  261. package/.tap/test-results/test/schema-serialization.test.js.tap +0 -194
  262. package/.tap/test-results/test/schema-special-usage.test.js.tap +0 -186
  263. package/.tap/test-results/test/schema-validation.test.js.tap +0 -199
  264. package/.tap/test-results/test/search.test.js.tap +0 -77
  265. package/.tap/test-results/test/serialize-response.test.js.tap +0 -26
  266. package/.tap/test-results/test/server.test.js.tap +0 -65
  267. package/.tap/test-results/test/set-error-handler.test.js.tap +0 -7
  268. package/.tap/test-results/test/skip-reply-send.test.js.tap +0 -272
  269. package/.tap/test-results/test/stream.1.test.js.tap +0 -36
  270. package/.tap/test-results/test/stream.2.test.js.tap +0 -20
  271. package/.tap/test-results/test/stream.3.test.js.tap +0 -34
  272. package/.tap/test-results/test/stream.4.test.js.tap +0 -40
  273. package/.tap/test-results/test/stream.5.test.js.tap +0 -37
  274. package/.tap/test-results/test/sync-routes.test.js.tap +0 -19
  275. package/.tap/test-results/test/throw.test.js.tap +0 -116
  276. package/.tap/test-results/test/trace.test.js.tap +0 -7
  277. package/.tap/test-results/test/trust-proxy.test.js.tap +0 -109
  278. package/.tap/test-results/test/type-provider.test.js.tap +0 -12
  279. package/.tap/test-results/test/unlock.test.js.tap +0 -14
  280. package/.tap/test-results/test/upgrade.test.js.tap +0 -8
  281. package/.tap/test-results/test/url-rewriting.test.js.tap +0 -39
  282. package/.tap/test-results/test/useSemicolonDelimiter.test.js.tap +0 -33
  283. package/.tap/test-results/test/validation-error-handling.test.js.tap +0 -180
  284. package/.tap/test-results/test/versioned-routes.test.js.tap +0 -151
  285. package/.tap/test-results/test/web-api.test.js.tap +0 -51
  286. package/.tap/test-results/test/wrapThenable.test.js.tap +0 -11
  287. package/EXPENSE_POLICY.md +0 -105
  288. package/lib/httpMethods.js +0 -40
  289. package/test/method-missing.test.js +0 -24
  290. package/test/request.deprecated.test.js +0 -38
@@ -105,6 +105,142 @@ test('Basic validation test', t => {
105
105
  })
106
106
  })
107
107
 
108
+ test('Different schema per content type', t => {
109
+ t.plan(12)
110
+
111
+ const fastify = Fastify()
112
+ fastify.addContentTypeParser('application/octet-stream', {
113
+ parseAs: 'buffer'
114
+ }, async function (_, payload) {
115
+ return payload
116
+ })
117
+ fastify.post('/', {
118
+ schema: {
119
+ body: {
120
+ content: {
121
+ 'application/json': {
122
+ schema: schemaArtist
123
+ },
124
+ 'application/octet-stream': {
125
+ schema: {} // Skip validation
126
+ },
127
+ 'text/plain': {
128
+ schema: { type: 'string' }
129
+ }
130
+ }
131
+ }
132
+ }
133
+ }, async function (req, reply) {
134
+ return reply.send(req.body)
135
+ })
136
+
137
+ fastify.inject({
138
+ url: '/',
139
+ method: 'POST',
140
+ headers: { 'Content-Type': 'application/json' },
141
+ body: {
142
+ name: 'michelangelo',
143
+ work: 'sculptor, painter, architect and poet'
144
+ }
145
+ }, (err, res) => {
146
+ t.error(err)
147
+ t.same(JSON.parse(res.payload).name, 'michelangelo')
148
+ t.equal(res.statusCode, 200)
149
+ })
150
+
151
+ fastify.inject({
152
+ url: '/',
153
+ method: 'POST',
154
+ headers: { 'Content-Type': 'application/json' },
155
+ body: { name: 'michelangelo' }
156
+ }, (err, res) => {
157
+ t.error(err)
158
+ t.same(res.json(), { statusCode: 400, code: 'FST_ERR_VALIDATION', error: 'Bad Request', message: "body must have required property 'work'" })
159
+ t.equal(res.statusCode, 400)
160
+ })
161
+
162
+ fastify.inject({
163
+ url: '/',
164
+ method: 'POST',
165
+ headers: { 'Content-Type': 'application/octet-stream' },
166
+ body: Buffer.from('AAAAAAAA')
167
+ }, (err, res) => {
168
+ t.error(err)
169
+ t.same(res.payload, 'AAAAAAAA')
170
+ t.equal(res.statusCode, 200)
171
+ })
172
+
173
+ fastify.inject({
174
+ url: '/',
175
+ method: 'POST',
176
+ headers: { 'Content-Type': 'text/plain' },
177
+ body: 'AAAAAAAA'
178
+ }, (err, res) => {
179
+ t.error(err)
180
+ t.same(res.payload, 'AAAAAAAA')
181
+ t.equal(res.statusCode, 200)
182
+ })
183
+ })
184
+
185
+ test('Skip validation if no schema for content type', t => {
186
+ t.plan(3)
187
+
188
+ const fastify = Fastify()
189
+ fastify.post('/', {
190
+ schema: {
191
+ body: {
192
+ content: {
193
+ 'application/json': {
194
+ schema: schemaArtist
195
+ }
196
+ // No schema for 'text/plain'
197
+ }
198
+ }
199
+ }
200
+ }, async function (req, reply) {
201
+ return reply.send(req.body)
202
+ })
203
+
204
+ fastify.inject({
205
+ url: '/',
206
+ method: 'POST',
207
+ headers: { 'Content-Type': 'text/plain' },
208
+ body: 'AAAAAAAA'
209
+ }, (err, res) => {
210
+ t.error(err)
211
+ t.same(res.payload, 'AAAAAAAA')
212
+ t.equal(res.statusCode, 200)
213
+ })
214
+ })
215
+
216
+ test('Skip validation if no content type schemas', t => {
217
+ t.plan(3)
218
+
219
+ const fastify = Fastify()
220
+ fastify.post('/', {
221
+ schema: {
222
+ body: {
223
+ content: {
224
+ // No schemas
225
+ }
226
+ }
227
+ }
228
+ }, async function (req, reply) {
229
+ return reply.send(req.body)
230
+ })
231
+
232
+ fastify.inject({
233
+ url: '/',
234
+ method: 'POST',
235
+ headers: { 'Content-Type': 'text/plain' },
236
+ body: 'AAAAAAAA'
237
+ }, (err, res) => {
238
+ t.error(err)
239
+ t.same(res.payload, 'AAAAAAAA')
240
+ t.equal(res.statusCode, 200)
241
+ })
242
+ })
243
+
108
244
  test('External AJV instance', t => {
109
245
  t.plan(5)
110
246
 
@@ -829,7 +965,12 @@ test('Custom AJV settings - pt1', t => {
829
965
 
830
966
  fastify.post('/', {
831
967
  schema: {
832
- body: { num: { type: 'integer' } }
968
+ body: {
969
+ type: 'object',
970
+ properties: {
971
+ num: { type: 'integer' }
972
+ }
973
+ }
833
974
  },
834
975
  handler: (req, reply) => {
835
976
  t.equal(req.body.num, 12)
@@ -862,7 +1003,12 @@ test('Custom AJV settings - pt2', t => {
862
1003
 
863
1004
  fastify.post('/', {
864
1005
  schema: {
865
- body: { num: { type: 'integer' } }
1006
+ body: {
1007
+ type: 'object',
1008
+ properties: {
1009
+ num: { type: 'integer' }
1010
+ }
1011
+ }
866
1012
  },
867
1013
  handler: (req, reply) => {
868
1014
  t.fail('the handler is not called because the "12" is not coerced to number')
@@ -889,7 +1035,12 @@ test('Custom AJV settings on different parameters - pt1', t => {
889
1035
 
890
1036
  fastify.post('/api/:id', {
891
1037
  schema: {
892
- querystring: { id: { type: 'integer' } },
1038
+ querystring: {
1039
+ type: 'object',
1040
+ properties: {
1041
+ id: { type: 'integer' }
1042
+ }
1043
+ },
893
1044
  body: {
894
1045
  type: 'object',
895
1046
  properties: {
@@ -19,7 +19,7 @@ const lifecycleHooks = [
19
19
  'onError'
20
20
  ]
21
21
 
22
- test('skip automatic reply.send() with reply.sent = true and a body', (t) => {
22
+ test('skip automatic reply.send() with reply.hijack and a body', (t) => {
23
23
  const stream = split(JSON.parse)
24
24
  const app = Fastify({
25
25
  logger: {
@@ -33,7 +33,7 @@ test('skip automatic reply.send() with reply.sent = true and a body', (t) => {
33
33
  })
34
34
 
35
35
  app.get('/', (req, reply) => {
36
- reply.sent = true
36
+ reply.hijack()
37
37
  reply.raw.end('hello world')
38
38
 
39
39
  return Promise.resolve('this will be skipped')
@@ -48,7 +48,7 @@ test('skip automatic reply.send() with reply.sent = true and a body', (t) => {
48
48
  })
49
49
  })
50
50
 
51
- test('skip automatic reply.send() with reply.sent = true and no body', (t) => {
51
+ test('skip automatic reply.send() with reply.hijack and no body', (t) => {
52
52
  const stream = split(JSON.parse)
53
53
  const app = Fastify({
54
54
  logger: {
@@ -62,7 +62,7 @@ test('skip automatic reply.send() with reply.sent = true and no body', (t) => {
62
62
  })
63
63
 
64
64
  app.get('/', (req, reply) => {
65
- reply.sent = true
65
+ reply.hijack()
66
66
  reply.raw.end('hello world')
67
67
 
68
68
  return Promise.resolve()
@@ -77,7 +77,7 @@ test('skip automatic reply.send() with reply.sent = true and no body', (t) => {
77
77
  })
78
78
  })
79
79
 
80
- test('skip automatic reply.send() with reply.sent = true and an error', (t) => {
80
+ test('skip automatic reply.send() with reply.hijack and an error', (t) => {
81
81
  const stream = split(JSON.parse)
82
82
  const app = Fastify({
83
83
  logger: {
@@ -96,7 +96,7 @@ test('skip automatic reply.send() with reply.sent = true and an error', (t) => {
96
96
  })
97
97
 
98
98
  app.get('/', (req, reply) => {
99
- reply.sent = true
99
+ reply.hijack()
100
100
  reply.raw.end('hello world')
101
101
 
102
102
  return Promise.reject(new Error('kaboom'))
@@ -0,0 +1,37 @@
1
+ 'use strict'
2
+
3
+ const t = require('tap')
4
+ const test = t.test
5
+ const Fastify = require('..')
6
+ const Reply = require('../lib/reply')
7
+
8
+ test('should serialize reply when response stream is ended', t => {
9
+ t.plan(3)
10
+ const stream = require('node:stream')
11
+ const fastify = Fastify({
12
+ logger: {
13
+ serializers: {
14
+ res (reply) {
15
+ t.type(reply, Reply)
16
+ return reply
17
+ }
18
+ }
19
+ }
20
+ })
21
+
22
+ fastify.get('/error', function (req, reply) {
23
+ const reallyLongStream = new stream.Readable({
24
+ read: () => { }
25
+ })
26
+ reply.code(200).send(reallyLongStream)
27
+ reply.raw.end(Buffer.from('hello\n'))
28
+ })
29
+
30
+ fastify.inject({
31
+ url: '/error',
32
+ method: 'GET'
33
+ }, (err) => {
34
+ t.error(err)
35
+ fastify.close()
36
+ })
37
+ })
@@ -22,9 +22,9 @@ test('Fastify should throw on multiple assignment to the same route', t => {
22
22
 
23
23
  try {
24
24
  fastify.get('/', () => {})
25
- t.fail('Should throw on duplicated route declaration')
25
+ t.fail('Should throw fastify duplicated route declaration')
26
26
  } catch (error) {
27
- t.equal(error.message, "Method 'GET' already declared for route '/'")
27
+ t.equal(error.code, 'FST_ERR_DUPLICATED_ROUTE')
28
28
  }
29
29
  })
30
30
 
@@ -74,18 +74,6 @@ test('Fastify should throw for an invalid schema, printing the error route - bod
74
74
  })
75
75
  })
76
76
 
77
- test('Fastify should throw for an invalid shorthand option type', t => {
78
- t.plan(3)
79
- try {
80
- Fastify({ jsonShorthand: 'hello' })
81
- t.fail()
82
- } catch (e) {
83
- t.equal(e.code, 'FST_ERR_INIT_OPTS_INVALID')
84
- t.match(e.message, /must be boolean/)
85
- t.pass()
86
- }
87
- })
88
-
89
77
  test('Should throw on unsupported method', t => {
90
78
  t.plan(1)
91
79
  const fastify = Fastify()
@@ -1,6 +1,6 @@
1
+ import { FastifyErrorConstructor } from '@fastify/error'
1
2
  import { expectAssignable } from 'tsd'
2
3
  import { errorCodes } from '../../fastify'
3
- import { FastifyErrorConstructor } from '@fastify/error'
4
4
 
5
5
  expectAssignable<FastifyErrorConstructor>(errorCodes.FST_ERR_VALIDATION)
6
6
  expectAssignable<FastifyErrorConstructor>(errorCodes.FST_ERR_NOT_FOUND)
@@ -10,7 +10,6 @@ expectAssignable<FastifyErrorConstructor>(errorCodes.FST_ERR_SCHEMA_CONTROLLER_B
10
10
  expectAssignable<FastifyErrorConstructor>(errorCodes.FST_ERR_SCHEMA_ERROR_FORMATTER_NOT_FN)
11
11
  expectAssignable<FastifyErrorConstructor>(errorCodes.FST_ERR_AJV_CUSTOM_OPTIONS_OPT_NOT_OBJ)
12
12
  expectAssignable<FastifyErrorConstructor>(errorCodes.FST_ERR_AJV_CUSTOM_OPTIONS_OPT_NOT_ARR)
13
- expectAssignable<FastifyErrorConstructor>(errorCodes.FST_ERR_VERSION_CONSTRAINT_NOT_STR)
14
13
  expectAssignable<FastifyErrorConstructor>(errorCodes.FST_ERR_VALIDATION)
15
14
  expectAssignable<FastifyErrorConstructor>(errorCodes.FST_ERR_CTP_ALREADY_PRESENT)
16
15
  expectAssignable<FastifyErrorConstructor>(errorCodes.FST_ERR_CTP_INVALID_TYPE)
@@ -1,25 +1,26 @@
1
+ import { ErrorObject as AjvErrorObject } from 'ajv'
2
+ import * as http from 'http'
3
+ import * as http2 from 'http2'
4
+ import * as https from 'https'
5
+ import { Socket } from 'net'
6
+ import { expectAssignable, expectError, expectNotAssignable, expectType } from 'tsd'
1
7
  import fastify, {
2
8
  ConnectionError,
9
+ FastifyBaseLogger,
10
+ FastifyError,
11
+ FastifyErrorCodes,
3
12
  FastifyInstance,
4
13
  FastifyPlugin,
5
14
  FastifyPluginAsync,
6
15
  FastifyPluginCallback,
16
+ InjectOptions,
17
+ LightMyRequestCallback,
7
18
  LightMyRequestChain,
8
19
  LightMyRequestResponse,
9
- LightMyRequestCallback,
10
- InjectOptions, FastifyBaseLogger,
11
20
  RawRequestDefaultExpression,
12
21
  RouteGenericInterface,
13
- FastifyErrorCodes,
14
- FastifyError,
15
22
  SafePromiseLike
16
23
  } from '../../fastify'
17
- import { ErrorObject as AjvErrorObject } from 'ajv'
18
- import * as http from 'http'
19
- import * as https from 'https'
20
- import * as http2 from 'http2'
21
- import { expectType, expectError, expectAssignable, expectNotAssignable } from 'tsd'
22
- import { Socket } from 'net'
23
24
 
24
25
  // FastifyInstance
25
26
  // http server
@@ -80,8 +81,8 @@ expectAssignable<FastifyInstance>(fastify({ onProtoPoisoning: 'error' }))
80
81
  expectAssignable<FastifyInstance>(fastify({ onConstructorPoisoning: 'error' }))
81
82
  expectAssignable<FastifyInstance>(fastify({ serializerOpts: { rounding: 'ceil' } }))
82
83
  expectAssignable<FastifyInstance>(fastify({ serializerOpts: { ajv: { missingRefs: 'ignore' } } }))
83
- expectAssignable<FastifyInstance>(fastify({ serializerOpts: { schema: { } } }))
84
- expectAssignable<FastifyInstance>(fastify({ serializerOpts: { otherProp: { } } }))
84
+ expectAssignable<FastifyInstance>(fastify({ serializerOpts: { schema: {} } }))
85
+ expectAssignable<FastifyInstance>(fastify({ serializerOpts: { otherProp: {} } }))
85
86
  expectAssignable<FastifyInstance<http.Server, http.IncomingMessage, http.ServerResponse, FastifyBaseLogger>>(fastify({ logger: true }))
86
87
  expectAssignable<FastifyInstance<http.Server, http.IncomingMessage, http.ServerResponse, FastifyBaseLogger>>(fastify({ logger: true }))
87
88
  expectAssignable<FastifyInstance<http.Server, http.IncomingMessage, http.ServerResponse, FastifyBaseLogger>>(fastify({
@@ -139,52 +140,41 @@ expectAssignable<FastifyInstance>(fastify({ trustProxy: true }))
139
140
  expectAssignable<FastifyInstance>(fastify({ querystringParser: () => ({ foo: 'bar' }) }))
140
141
  expectAssignable<FastifyInstance>(fastify({ querystringParser: () => ({ foo: { bar: 'fuzz' } }) }))
141
142
  expectAssignable<FastifyInstance>(fastify({ querystringParser: () => ({ foo: ['bar', 'fuzz'] }) }))
142
- expectAssignable<FastifyInstance>(fastify({
143
- versioning: {
144
- storage: () => ({
145
- get: () => 'foo',
146
- set: () => { },
147
- del: () => { },
148
- empty: () => { }
149
- }),
150
- deriveVersion: () => 'foo'
151
- }
152
- }))
153
143
  expectAssignable<FastifyInstance>(fastify({ constraints: {} }))
154
144
  expectAssignable<FastifyInstance>(fastify({
155
145
  constraints: {
156
146
  version: {
157
147
  name: 'version',
158
148
  storage: () => ({
159
- get: () => () => {},
149
+ get: () => () => { },
160
150
  set: () => { },
161
151
  del: () => { },
162
152
  empty: () => { }
163
153
  }),
164
- validate () {},
154
+ validate () { },
165
155
  deriveConstraint: () => 'foo'
166
156
  },
167
157
  host: {
168
158
  name: 'host',
169
159
  storage: () => ({
170
- get: () => () => {},
160
+ get: () => () => { },
171
161
  set: () => { },
172
162
  del: () => { },
173
163
  empty: () => { }
174
164
  }),
175
- validate () {},
165
+ validate () { },
176
166
  deriveConstraint: () => 'foo'
177
167
  },
178
168
  withObjectValue: {
179
169
  name: 'withObjectValue',
180
170
  storage: () => ({
181
- get: () => () => {},
171
+ get: () => () => { },
182
172
  set: () => { },
183
173
  del: () => { },
184
174
  empty: () => { }
185
175
  }),
186
- validate () {},
187
- deriveConstraint: () => {}
176
+ validate () { },
177
+ deriveConstraint: () => { }
188
178
 
189
179
  }
190
180
  }
@@ -228,15 +218,14 @@ expectAssignable<FastifyInstance>(fastify({
228
218
  expectType<Socket>(socket)
229
219
  }
230
220
  }))
231
- expectAssignable<FastifyInstance>(fastify({ jsonShorthand: true }))
232
221
 
233
222
  // Thenable
234
223
  expectAssignable<PromiseLike<FastifyInstance>>(fastify({ return503OnClosing: true }))
235
224
  fastify().then(fastifyInstance => expectAssignable<FastifyInstance>(fastifyInstance))
236
225
 
237
- expectAssignable<FastifyPluginAsync>(async () => {})
238
- expectAssignable<FastifyPluginCallback>(() => {})
239
- expectAssignable<FastifyPlugin>(() => {})
226
+ expectAssignable<FastifyPluginAsync>(async () => { })
227
+ expectAssignable<FastifyPluginCallback>(() => { })
228
+ expectAssignable<FastifyPlugin>(() => { })
240
229
 
241
230
  const ajvErrorObject: AjvErrorObject = {
242
231
  keyword: '',
@@ -273,83 +273,83 @@ server.route<RouteGenericInterface, CustomContextConfig>({
273
273
  url: '/',
274
274
  handler: () => { },
275
275
  onRequest: (request, reply, done) => {
276
- expectType<CustomContextConfigWithDefault>(request.context.config)
277
- expectType<CustomContextConfigWithDefault>(reply.context.config)
276
+ expectType<CustomContextConfigWithDefault>(request.routeOptions.config)
277
+ expectType<CustomContextConfigWithDefault>(reply.routeOptions.config)
278
278
  },
279
279
  preParsing: (request, reply, payload, done) => {
280
- expectType<CustomContextConfigWithDefault>(request.context.config)
281
- expectType<CustomContextConfigWithDefault>(reply.context.config)
280
+ expectType<CustomContextConfigWithDefault>(request.routeOptions.config)
281
+ expectType<CustomContextConfigWithDefault>(reply.routeOptions.config)
282
282
  },
283
283
  preValidation: (request, reply, done) => {
284
- expectType<CustomContextConfigWithDefault>(request.context.config)
285
- expectType<CustomContextConfigWithDefault>(reply.context.config)
284
+ expectType<CustomContextConfigWithDefault>(request.routeOptions.config)
285
+ expectType<CustomContextConfigWithDefault>(reply.routeOptions.config)
286
286
  },
287
287
  preHandler: (request, reply, done) => {
288
- expectType<CustomContextConfigWithDefault>(request.context.config)
289
- expectType<CustomContextConfigWithDefault>(reply.context.config)
288
+ expectType<CustomContextConfigWithDefault>(request.routeOptions.config)
289
+ expectType<CustomContextConfigWithDefault>(reply.routeOptions.config)
290
290
  },
291
291
  preSerialization: (request, reply, payload, done) => {
292
- expectType<CustomContextConfigWithDefault>(request.context.config)
293
- expectType<CustomContextConfigWithDefault>(reply.context.config)
292
+ expectType<CustomContextConfigWithDefault>(request.routeOptions.config)
293
+ expectType<CustomContextConfigWithDefault>(reply.routeOptions.config)
294
294
  },
295
295
  onSend: (request, reply, payload, done) => {
296
- expectType<CustomContextConfigWithDefault>(request.context.config)
297
- expectType<CustomContextConfigWithDefault>(reply.context.config)
296
+ expectType<CustomContextConfigWithDefault>(request.routeOptions.config)
297
+ expectType<CustomContextConfigWithDefault>(reply.routeOptions.config)
298
298
  },
299
299
  onResponse: (request, reply, done) => {
300
- expectType<CustomContextConfigWithDefault>(request.context.config)
301
- expectType<CustomContextConfigWithDefault>(reply.context.config)
300
+ expectType<CustomContextConfigWithDefault>(request.routeOptions.config)
301
+ expectType<CustomContextConfigWithDefault>(reply.routeOptions.config)
302
302
  },
303
303
  onTimeout: (request, reply, done) => {
304
- expectType<CustomContextConfigWithDefault>(request.context.config)
305
- expectType<CustomContextConfigWithDefault>(reply.context.config)
304
+ expectType<CustomContextConfigWithDefault>(request.routeOptions.config)
305
+ expectType<CustomContextConfigWithDefault>(reply.routeOptions.config)
306
306
  },
307
307
  onError: (request, reply, error, done) => {
308
- expectType<CustomContextConfigWithDefault>(request.context.config)
309
- expectType<CustomContextConfigWithDefault>(reply.context.config)
308
+ expectType<CustomContextConfigWithDefault>(request.routeOptions.config)
309
+ expectType<CustomContextConfigWithDefault>(reply.routeOptions.config)
310
310
  }
311
311
  })
312
312
 
313
313
  server.get<RouteGenericInterface, CustomContextConfig>('/', {
314
314
  onRequest: async (request, reply) => {
315
- expectType<CustomContextConfigWithDefault>(request.context.config)
316
- expectType<CustomContextConfigWithDefault>(reply.context.config)
315
+ expectType<CustomContextConfigWithDefault>(request.routeOptions.config)
316
+ expectType<CustomContextConfigWithDefault>(reply.routeOptions.config)
317
317
  },
318
318
  preParsing: async (request, reply) => {
319
- expectType<CustomContextConfigWithDefault>(request.context.config)
320
- expectType<CustomContextConfigWithDefault>(reply.context.config)
319
+ expectType<CustomContextConfigWithDefault>(request.routeOptions.config)
320
+ expectType<CustomContextConfigWithDefault>(reply.routeOptions.config)
321
321
  },
322
322
  preValidation: async (request, reply) => {
323
- expectType<CustomContextConfigWithDefault>(request.context.config)
324
- expectType<CustomContextConfigWithDefault>(reply.context.config)
323
+ expectType<CustomContextConfigWithDefault>(request.routeOptions.config)
324
+ expectType<CustomContextConfigWithDefault>(reply.routeOptions.config)
325
325
  },
326
326
  preHandler: async (request, reply) => {
327
- expectType<CustomContextConfigWithDefault>(request.context.config)
328
- expectType<CustomContextConfigWithDefault>(reply.context.config)
327
+ expectType<CustomContextConfigWithDefault>(request.routeOptions.config)
328
+ expectType<CustomContextConfigWithDefault>(reply.routeOptions.config)
329
329
  },
330
330
  preSerialization: async (request, reply) => {
331
- expectType<CustomContextConfigWithDefault>(request.context.config)
332
- expectType<CustomContextConfigWithDefault>(reply.context.config)
331
+ expectType<CustomContextConfigWithDefault>(request.routeOptions.config)
332
+ expectType<CustomContextConfigWithDefault>(reply.routeOptions.config)
333
333
  },
334
334
  onSend: async (request, reply) => {
335
- expectType<CustomContextConfigWithDefault>(request.context.config)
336
- expectType<CustomContextConfigWithDefault>(reply.context.config)
335
+ expectType<CustomContextConfigWithDefault>(request.routeOptions.config)
336
+ expectType<CustomContextConfigWithDefault>(reply.routeOptions.config)
337
337
  },
338
338
  onResponse: async (request, reply) => {
339
- expectType<CustomContextConfigWithDefault>(request.context.config)
340
- expectType<CustomContextConfigWithDefault>(reply.context.config)
339
+ expectType<CustomContextConfigWithDefault>(request.routeOptions.config)
340
+ expectType<CustomContextConfigWithDefault>(reply.routeOptions.config)
341
341
  },
342
342
  onTimeout: async (request, reply) => {
343
- expectType<CustomContextConfigWithDefault>(request.context.config)
344
- expectType<CustomContextConfigWithDefault>(reply.context.config)
343
+ expectType<CustomContextConfigWithDefault>(request.routeOptions.config)
344
+ expectType<CustomContextConfigWithDefault>(reply.routeOptions.config)
345
345
  },
346
346
  onError: async (request, reply) => {
347
- expectType<CustomContextConfigWithDefault>(request.context.config)
348
- expectType<CustomContextConfigWithDefault>(reply.context.config)
347
+ expectType<CustomContextConfigWithDefault>(request.routeOptions.config)
348
+ expectType<CustomContextConfigWithDefault>(reply.routeOptions.config)
349
349
  }
350
350
  }, async (request, reply) => {
351
- expectType<CustomContextConfigWithDefault>(request.context.config)
352
- expectType<CustomContextConfigWithDefault>(reply.context.config)
351
+ expectType<CustomContextConfigWithDefault>(request.routeOptions.config)
352
+ expectType<CustomContextConfigWithDefault>(reply.routeOptions.config)
353
353
  })
354
354
 
355
355
  type CustomContextRequest = FastifyRequest<any, any, any, any, any, CustomContextConfig, any>
@@ -359,40 +359,40 @@ server.route<RouteGenericInterface, CustomContextConfig>({
359
359
  url: '/',
360
360
  handler: () => { },
361
361
  onRequest: async (request: CustomContextRequest, reply: CustomContextReply) => {
362
- expectType<CustomContextConfigWithDefault>(request.context.config)
363
- expectType<CustomContextConfigWithDefault>(reply.context.config)
362
+ expectType<CustomContextConfigWithDefault>(request.routeOptions.config)
363
+ expectType<CustomContextConfigWithDefault>(reply.routeOptions.config)
364
364
  },
365
365
  preParsing: async (request: CustomContextRequest, reply: CustomContextReply, payload: RequestPayload) => {
366
- expectType<CustomContextConfigWithDefault>(request.context.config)
367
- expectType<CustomContextConfigWithDefault>(reply.context.config)
366
+ expectType<CustomContextConfigWithDefault>(request.routeOptions.config)
367
+ expectType<CustomContextConfigWithDefault>(reply.routeOptions.config)
368
368
  },
369
369
  preValidation: async (request: CustomContextRequest, reply: CustomContextReply) => {
370
- expectType<CustomContextConfigWithDefault>(request.context.config)
371
- expectType<CustomContextConfigWithDefault>(reply.context.config)
370
+ expectType<CustomContextConfigWithDefault>(request.routeOptions.config)
371
+ expectType<CustomContextConfigWithDefault>(reply.routeOptions.config)
372
372
  },
373
373
  preHandler: async (request: CustomContextRequest, reply: CustomContextReply) => {
374
- expectType<CustomContextConfigWithDefault>(request.context.config)
375
- expectType<CustomContextConfigWithDefault>(reply.context.config)
374
+ expectType<CustomContextConfigWithDefault>(request.routeOptions.config)
375
+ expectType<CustomContextConfigWithDefault>(reply.routeOptions.config)
376
376
  },
377
377
  preSerialization: async (request: CustomContextRequest, reply: CustomContextReply, payload: any) => {
378
- expectType<CustomContextConfigWithDefault>(request.context.config)
379
- expectType<CustomContextConfigWithDefault>(reply.context.config)
378
+ expectType<CustomContextConfigWithDefault>(request.routeOptions.config)
379
+ expectType<CustomContextConfigWithDefault>(reply.routeOptions.config)
380
380
  },
381
381
  onSend: async (request: CustomContextRequest, reply: CustomContextReply, payload: any) => {
382
- expectType<CustomContextConfigWithDefault>(request.context.config)
383
- expectType<CustomContextConfigWithDefault>(reply.context.config)
382
+ expectType<CustomContextConfigWithDefault>(request.routeOptions.config)
383
+ expectType<CustomContextConfigWithDefault>(reply.routeOptions.config)
384
384
  },
385
385
  onResponse: async (request: CustomContextRequest, reply: CustomContextReply) => {
386
- expectType<CustomContextConfigWithDefault>(request.context.config)
387
- expectType<CustomContextConfigWithDefault>(reply.context.config)
386
+ expectType<CustomContextConfigWithDefault>(request.routeOptions.config)
387
+ expectType<CustomContextConfigWithDefault>(reply.routeOptions.config)
388
388
  },
389
389
  onTimeout: async (request: CustomContextRequest, reply: CustomContextReply) => {
390
- expectType<CustomContextConfigWithDefault>(request.context.config)
391
- expectType<CustomContextConfigWithDefault>(reply.context.config)
390
+ expectType<CustomContextConfigWithDefault>(request.routeOptions.config)
391
+ expectType<CustomContextConfigWithDefault>(reply.routeOptions.config)
392
392
  },
393
393
  onError: async (request: CustomContextRequest, reply: CustomContextReply, error: FastifyError) => {
394
- expectType<CustomContextConfigWithDefault>(request.context.config)
395
- expectType<CustomContextConfigWithDefault>(reply.context.config)
394
+ expectType<CustomContextConfigWithDefault>(request.routeOptions.config)
395
+ expectType<CustomContextConfigWithDefault>(reply.routeOptions.config)
396
396
  }
397
397
  })
398
398
 
@@ -89,12 +89,12 @@ interface ReplyPayload {
89
89
  // typed sync error handler
90
90
  server.setErrorHandler<CustomError, ReplyPayload>((error, request, reply) => {
91
91
  expectType<CustomError>(error)
92
- expectType<((payload?: ReplyPayload['Reply']) => FastifyReply<RawServerDefault, RawRequestDefaultExpression<RawServerDefault>, RawReplyDefaultExpression<RawServerDefault>, ReplyPayload>)>(reply.send)
92
+ expectType<((payload?: ReplyPayload['Reply']) => FastifyReply<ReplyPayload, RawServerDefault, RawRequestDefaultExpression<RawServerDefault>, RawReplyDefaultExpression<RawServerDefault>>)>(reply.send)
93
93
  })
94
94
  // typed async error handler send
95
95
  server.setErrorHandler<CustomError, ReplyPayload>(async (error, request, reply) => {
96
96
  expectType<CustomError>(error)
97
- expectType<((payload?: ReplyPayload['Reply']) => FastifyReply<RawServerDefault, RawRequestDefaultExpression<RawServerDefault>, RawReplyDefaultExpression<RawServerDefault>, ReplyPayload>)>(reply.send)
97
+ expectType<((payload?: ReplyPayload['Reply']) => FastifyReply<ReplyPayload, RawServerDefault, RawRequestDefaultExpression<RawServerDefault>, RawReplyDefaultExpression<RawServerDefault>>)>(reply.send)
98
98
  })
99
99
  // typed async error handler return
100
100
  server.setErrorHandler<CustomError, ReplyPayload>(async (error, request, reply) => {
@@ -250,7 +250,7 @@ expectType<FastifyInstance>(fastify().get<RouteGenericInterface, { contextKey: s
250
250
  errorHandler: (error, request, reply) => {
251
251
  expectAssignable<FastifyError>(error)
252
252
  expectAssignable<FastifyRequest>(request)
253
- expectAssignable<{ contextKey: string }>(request.routeConfig)
253
+ expectAssignable<{ contextKey: string }>(request.routeOptions.config)
254
254
  expectAssignable<FastifyReply>(reply)
255
255
  expectAssignable<void>(server.errorHandler(error, request, reply))
256
256
  }