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
@@ -235,6 +235,28 @@ const schema = {
235
235
  fastify.post('/the/url', { schema }, handler)
236
236
  ```
237
237
 
238
+ For `body` schema, it is further possible to differentiate the schema per content
239
+ type by nesting the schemas inside `content` property. The schema validation
240
+ will be applied based on the `Content-Type` header in the request.
241
+
242
+ ```js
243
+ fastify.post('/the/url', {
244
+ schema: {
245
+ body: {
246
+ content: {
247
+ 'application/json': {
248
+ schema: { type: 'object' }
249
+ },
250
+ 'text/plain': {
251
+ schema: { type: 'string' }
252
+ }
253
+ // Other content types will not be validated
254
+ }
255
+ }
256
+ }
257
+ }, handler)
258
+ ```
259
+
238
260
  *Note that Ajv will try to [coerce](https://ajv.js.org/coercion.html) the values
239
261
  to the types specified in your schema `type` keywords, both to pass the
240
262
  validation and to use the correctly typed data afterwards.*
@@ -618,37 +640,47 @@ You can even have a specific response schema for different content types.
618
640
  For example:
619
641
  ```js
620
642
  const schema = {
621
- response: {
622
- 200: {
623
- description: 'Response schema that support different content types'
624
- content: {
625
- 'application/json': {
626
- schema: {
627
- name: { type: 'string' },
628
- image: { type: 'string' },
629
- address: { type: 'string' }
630
- }
631
- },
632
- 'application/vnd.v1+json': {
633
- schema: {
634
- type: 'array',
635
- items: { $ref: 'test' }
636
- }
637
- }
643
+ response: {
644
+ 200: {
645
+ description: 'Response schema that support different content types'
646
+ content: {
647
+ 'application/json': {
648
+ schema: {
649
+ name: { type: 'string' },
650
+ image: { type: 'string' },
651
+ address: { type: 'string' }
638
652
  }
639
653
  },
640
- '3xx': {
641
- content: {
642
- 'application/vnd.v2+json': {
643
- schema: {
644
- fullName: { type: 'string' },
645
- phone: { type: 'string' }
646
- }
647
- }
654
+ 'application/vnd.v1+json': {
655
+ schema: {
656
+ type: 'array',
657
+ items: { $ref: 'test' }
658
+ }
659
+ }
660
+ }
661
+ },
662
+ '3xx': {
663
+ content: {
664
+ 'application/vnd.v2+json': {
665
+ schema: {
666
+ fullName: { type: 'string' },
667
+ phone: { type: 'string' }
668
+ }
669
+ }
670
+ }
671
+ },
672
+ default: {
673
+ content: {
674
+ // */* is match-all content-type
675
+ '*/*': {
676
+ schema: {
677
+ desc: { type: 'string' }
648
678
  }
649
679
  }
650
680
  }
651
681
  }
682
+ }
683
+ }
652
684
 
653
685
  fastify.post('/url', { schema }, handler)
654
686
  ```
@@ -673,8 +705,11 @@ fastify.get('/user', {
673
705
  schema: {
674
706
  response: {
675
707
  '2xx': {
676
- id: { type: 'number' },
677
- name: { type: 'string' }
708
+ type: 'object',
709
+ properties: {
710
+ id: { type: 'number' },
711
+ name: { type: 'string' }
712
+ }
678
713
  }
679
714
  }
680
715
  }
@@ -8,19 +8,6 @@
8
8
  - [FSTWRN001](#FSTWRN001)
9
9
  - [FSTWRN002](#FSTWRN002)
10
10
  - [Fastify Deprecation Codes](#fastify-deprecation-codes)
11
- - [FSTDEP005](#FSTDEP005)
12
- - [FSTDEP007](#FSTDEP007)
13
- - [FSTDEP008](#FSTDEP008)
14
- - [FSTDEP009](#FSTDEP009)
15
- - [FSTDEP010](#FSTDEP010)
16
- - [FSTDEP012](#FSTDEP012)
17
- - [FSTDEP013](#FSTDEP013)
18
- - [FSTDEP015](#FSTDEP015)
19
- - [FSTDEP016](#FSTDEP016)
20
- - [FSTDEP017](#FSTDEP017)
21
- - [FSTDEP018](#FSTDEP018)
22
- - [FSTDEP019](#FSTDEP019)
23
- - [FSTDEP021](#FSTDEP021)
24
11
 
25
12
 
26
13
  ## Warnings
@@ -71,16 +58,3 @@ Deprecation codes are further supported by the Node.js CLI options:
71
58
 
72
59
  | Code | Description | How to solve | Discussion |
73
60
  | ---- | ----------- | ------------ | ---------- |
74
- | <a id="FSTDEP005">FSTDEP005</a> | You are accessing the deprecated `request.connection` property. | Use `request.socket`. | [#2594](https://github.com/fastify/fastify/pull/2594) |
75
- | <a id="FSTDEP007">FSTDEP007</a> | You are trying to set a HEAD route using `exposeHeadRoute` route flag when a sibling route is already set. | Remove `exposeHeadRoutes` or explicitly set `exposeHeadRoutes` to `false` | [#2700](https://github.com/fastify/fastify/pull/2700) |
76
- | <a id="FSTDEP008">FSTDEP008</a> | You are using route constraints via the route `{version: "..."}` option. | Use `{constraints: {version: "..."}}` option. | [#2682](https://github.com/fastify/fastify/pull/2682) |
77
- | <a id="FSTDEP009">FSTDEP009</a> | You are using a custom route versioning strategy via the server `{versioning: "..."}` option. | Use `{constraints: {version: "..."}}` option. | [#2682](https://github.com/fastify/fastify/pull/2682) |
78
- | <a id="FSTDEP010">FSTDEP010</a> | Modifying the `reply.sent` property is deprecated. | Use the `reply.hijack()` method. | [#3140](https://github.com/fastify/fastify/pull/3140) |
79
- | <a id="FSTDEP012">FSTDEP012</a> | You are trying to access the deprecated `request.context` property. | Use `request.routeOptions.config` or `request.routeOptions.schema`. | [#4216](https://github.com/fastify/fastify/pull/4216) [#5084](https://github.com/fastify/fastify/pull/5084) |
80
- | <a id="FSTDEP013">FSTDEP013</a> | Direct return of "trailers" function is deprecated. | Use "callback" or "async-await" for return value. | [#4380](https://github.com/fastify/fastify/pull/4380) |
81
- | <a id="FSTDEP015">FSTDEP015</a> | You are accessing the deprecated `request.routeSchema` property. | Use `request.routeOptions.schema`. | [#4470](https://github.com/fastify/fastify/pull/4470) |
82
- | <a id="FSTDEP016">FSTDEP016</a> | You are accessing the deprecated `request.routeConfig` property. | Use `request.routeOptions.config`. | [#4470](https://github.com/fastify/fastify/pull/4470) |
83
- | <a id="FSTDEP017">FSTDEP017</a> | You are accessing the deprecated `request.routerPath` property. | Use `request.routeOptions.url`. | [#4470](https://github.com/fastify/fastify/pull/4470) |
84
- | <a id="FSTDEP018">FSTDEP018</a> | You are accessing the deprecated `request.routerMethod` property. | Use `request.routeOptions.method`. | [#4470](https://github.com/fastify/fastify/pull/4470) |
85
- | <a id="FSTDEP019">FSTDEP019</a> | You are accessing the deprecated `reply.context` property. | Use `reply.routeOptions.config` or `reply.routeOptions.schema`. | [#5032](https://github.com/fastify/fastify/pull/5032) [#5084](https://github.com/fastify/fastify/pull/5084) |
86
- | <a id="FSTDEP021">FSTDEP021</a> | The `reply.redirect()` method has a new signature: `reply.redirect(url: string, code?: number)`. It will be enforced in `fastify@v5`'. | [#5483](https://github.com/fastify/fastify/pull/5483) |
package/eslint.config.js CHANGED
@@ -1,27 +1,11 @@
1
1
  'use strict'
2
2
 
3
- const neo = require('neostandard')
4
-
5
- module.exports = [
6
- {
7
- ignores: [
8
- 'lib/configValidator.js',
9
- 'lib/error-serializer.js',
10
- 'test/same-shape.test.js'
11
- ]
12
- },
13
- ...neo({
14
- ts: true
15
- }),
16
- {
17
- rules: {
18
- '@stylistic/comma-dangle': ['error', {
19
- arrays: 'never',
20
- objects: 'never',
21
- imports: 'never',
22
- exports: 'never',
23
- functions: 'never'
24
- }]
25
- }
26
- }
27
- ]
3
+ module.exports = require('neostandard')({
4
+ ignores: [
5
+ 'lib/configValidator.js',
6
+ 'lib/error-serializer.js',
7
+ 'test/same-shape.test.js',
8
+ 'test/types/import.js'
9
+ ],
10
+ ts: true
11
+ })
package/fastify.d.ts CHANGED
@@ -7,23 +7,23 @@ import { Options as AjvOptions, ValidatorFactory } from '@fastify/ajv-compiler'
7
7
  import { FastifyError } from '@fastify/error'
8
8
  import { Options as FJSOptions, SerializerFactory } from '@fastify/fast-json-stringify-compiler'
9
9
  import { ConstraintStrategy, HTTPVersion } from 'find-my-way'
10
- import { Chain as LightMyRequestChain, InjectOptions, Response as LightMyRequestResponse, CallbackFunc as LightMyRequestCallback } from 'light-my-request'
10
+ import { InjectOptions, CallbackFunc as LightMyRequestCallback, Chain as LightMyRequestChain, Response as LightMyRequestResponse } from 'light-my-request'
11
11
 
12
- import { FastifyBodyParser, FastifyContentTypeParser, AddContentTypeParser, hasContentTypeParser, getDefaultJsonParser, ProtoAction, ConstructorAction } from './types/content-type-parser'
13
- import { FastifyRequestContext, FastifyContextConfig, FastifyReplyContext } from './types/context'
12
+ import { AddContentTypeParser, ConstructorAction, FastifyBodyParser, FastifyContentTypeParser, getDefaultJsonParser, hasContentTypeParser, ProtoAction } from './types/content-type-parser'
13
+ import { FastifyContextConfig, FastifyReplyContext, FastifyRequestContext } from './types/context'
14
14
  import { FastifyErrorCodes } from './types/errors'
15
- import { DoneFuncWithErrOrRes, HookHandlerDoneFunction, RequestPayload, onCloseAsyncHookHandler, onCloseHookHandler, onErrorAsyncHookHandler, onErrorHookHandler, onReadyAsyncHookHandler, onReadyHookHandler, onListenAsyncHookHandler, onListenHookHandler, onRegisterHookHandler, onRequestAsyncHookHandler, onRequestHookHandler, onResponseAsyncHookHandler, onResponseHookHandler, onRouteHookHandler, onSendAsyncHookHandler, onSendHookHandler, onTimeoutAsyncHookHandler, onTimeoutHookHandler, preHandlerAsyncHookHandler, preHandlerHookHandler, preParsingAsyncHookHandler, preParsingHookHandler, preSerializationAsyncHookHandler, preSerializationHookHandler, preValidationAsyncHookHandler, preValidationHookHandler, onRequestAbortHookHandler, onRequestAbortAsyncHookHandler, preCloseAsyncHookHandler, preCloseHookHandler } from './types/hooks'
16
- import { FastifyListenOptions, FastifyInstance, PrintRoutesOptions } from './types/instance'
17
- import { FastifyBaseLogger, FastifyLoggerInstance, FastifyLoggerOptions, PinoLoggerOptions, FastifyLogFn, LogLevel } from './types/logger'
18
- import { FastifyPluginCallback, FastifyPluginAsync, FastifyPluginOptions, FastifyPlugin } from './types/plugin'
15
+ import { DoneFuncWithErrOrRes, HookHandlerDoneFunction, onCloseAsyncHookHandler, onCloseHookHandler, onErrorAsyncHookHandler, onErrorHookHandler, onListenAsyncHookHandler, onListenHookHandler, onReadyAsyncHookHandler, onReadyHookHandler, onRegisterHookHandler, onRequestAbortAsyncHookHandler, onRequestAbortHookHandler, onRequestAsyncHookHandler, onRequestHookHandler, onResponseAsyncHookHandler, onResponseHookHandler, onRouteHookHandler, onSendAsyncHookHandler, onSendHookHandler, onTimeoutAsyncHookHandler, onTimeoutHookHandler, preCloseAsyncHookHandler, preCloseHookHandler, preHandlerAsyncHookHandler, preHandlerHookHandler, preParsingAsyncHookHandler, preParsingHookHandler, preSerializationAsyncHookHandler, preSerializationHookHandler, preValidationAsyncHookHandler, preValidationHookHandler, RequestPayload } from './types/hooks'
16
+ import { FastifyInstance, FastifyListenOptions, PrintRoutesOptions } from './types/instance'
17
+ import { FastifyBaseLogger, FastifyLogFn, FastifyLoggerInstance, FastifyLoggerOptions, LogLevel, PinoLoggerOptions } from './types/logger'
18
+ import { FastifyPlugin, FastifyPluginAsync, FastifyPluginCallback, FastifyPluginOptions } from './types/plugin'
19
19
  import { FastifyRegister, FastifyRegisterOptions, RegisterOptions } from './types/register'
20
20
  import { FastifyReply } from './types/reply'
21
21
  import { FastifyRequest, RequestGenericInterface } from './types/request'
22
- import { RouteHandler, RouteHandlerMethod, RouteOptions, RouteShorthandMethod, RouteShorthandOptions, RouteShorthandOptionsWithHandler, RouteGenericInterface } from './types/route'
22
+ import { RouteGenericInterface, RouteHandler, RouteHandlerMethod, RouteOptions, RouteShorthandMethod, RouteShorthandOptions, RouteShorthandOptionsWithHandler } from './types/route'
23
23
  import { FastifySchema, FastifySchemaCompiler, FastifySchemaValidationError, SchemaErrorDataVar, SchemaErrorFormatter } from './types/schema'
24
24
  import { FastifyServerFactory, FastifyServerFactoryHandler } from './types/serverFactory'
25
25
  import { FastifyTypeProvider, FastifyTypeProviderDefault, SafePromiseLike } from './types/type-provider'
26
- import { HTTPMethods, RawServerBase, RawRequestDefaultExpression, RawReplyDefaultExpression, RawServerDefault, ContextConfigDefault, RequestBodyDefault, RequestQuerystringDefault, RequestParamsDefault, RequestHeadersDefault } from './types/utils'
26
+ import { ContextConfigDefault, HTTPMethods, RawReplyDefaultExpression, RawRequestDefaultExpression, RawServerBase, RawServerDefault, RequestBodyDefault, RequestHeadersDefault, RequestParamsDefault, RequestQuerystringDefault } from './types/utils'
27
27
 
28
28
  declare module '@fastify/error' {
29
29
  interface FastifyError {
@@ -111,22 +111,9 @@ declare namespace fastify {
111
111
  requestIdHeader?: string | false,
112
112
  requestIdLogLabel?: string;
113
113
  useSemicolonDelimiter?: boolean,
114
- jsonShorthand?: boolean;
115
114
  genReqId?: (req: RawRequestDefaultExpression<RawServer>) => string,
116
115
  trustProxy?: boolean | string | string[] | number | TrustProxyFunction,
117
116
  querystringParser?: (str: string) => { [key: string]: unknown },
118
- /**
119
- * @deprecated Prefer using the `constraints.version` property
120
- */
121
- versioning?: {
122
- storage(): {
123
- get(version: string): string | null,
124
- set(version: string, store: Function): void
125
- del(version: string): void,
126
- empty(): void
127
- },
128
- deriveVersion<Context>(req: Object, ctx?: Context): string // not a fan of using Object here. Also what is Context? Can either of these be better defined?
129
- },
130
117
  constraints?: {
131
118
  [name: string]: ConstraintStrategy<FindMyWayVersion<RawServer>, unknown>,
132
119
  },
@@ -149,7 +136,7 @@ declare namespace fastify {
149
136
  frameworkErrors?: <RequestGeneric extends RequestGenericInterface = RequestGenericInterface, TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault, SchemaCompiler extends FastifySchema = FastifySchema>(
150
137
  error: FastifyError,
151
138
  req: FastifyRequest<RequestGeneric, RawServer, RawRequestDefaultExpression<RawServer>, FastifySchema, TypeProvider>,
152
- res: FastifyReply<RawServer, RawRequestDefaultExpression<RawServer>, RawReplyDefaultExpression<RawServer>, RequestGeneric, FastifyContextConfig, SchemaCompiler, TypeProvider>
139
+ res: FastifyReply<RequestGeneric, RawServer, RawRequestDefaultExpression<RawServer>, RawReplyDefaultExpression<RawServer>, FastifyContextConfig, SchemaCompiler, TypeProvider>
153
140
  ) => void,
154
141
  rewriteUrl?: (
155
142
  // The RawRequestDefaultExpression, RawReplyDefaultExpression, and FastifyTypeProviderDefault parameters
package/fastify.js CHANGED
@@ -1,10 +1,10 @@
1
1
  'use strict'
2
2
 
3
- const VERSION = '5.0.0-alpha.2'
3
+ const VERSION = '5.0.0-alpha.4'
4
4
 
5
5
  const Avvio = require('avvio')
6
6
  const http = require('node:http')
7
- const diagnostics = require('dc-polyfill')
7
+ const diagnostics = require('node:diagnostics_channel')
8
8
  let lightMyRequest
9
9
 
10
10
  const {
@@ -12,6 +12,7 @@ const {
12
12
  kChildren,
13
13
  kServerBindings,
14
14
  kBodyLimit,
15
+ kSupportedHTTPMethods,
15
16
  kRoutePrefix,
16
17
  kLogLevel,
17
18
  kLogSerializers,
@@ -37,7 +38,6 @@ const { createServer } = require('./lib/server')
37
38
  const Reply = require('./lib/reply')
38
39
  const Request = require('./lib/request')
39
40
  const Context = require('./lib/context.js')
40
- const { supportedMethods } = require('./lib/httpMethods')
41
41
  const decorator = require('./lib/decorate')
42
42
  const ContentTypeParser = require('./lib/contentTypeParser')
43
43
  const SchemaController = require('./lib/schema-controller')
@@ -49,7 +49,6 @@ const { buildRouting, validateBodyLimitOption } = require('./lib/route')
49
49
  const build404 = require('./lib/fourOhFour')
50
50
  const getSecuredInitialConfig = require('./lib/initialConfigValidation')
51
51
  const override = require('./lib/pluginOverride')
52
- const { FSTDEP009 } = require('./lib/warnings')
53
52
  const noopSet = require('./lib/noop-set')
54
53
  const {
55
54
  appendStackTrace,
@@ -68,12 +67,12 @@ const {
68
67
  FST_ERR_SCHEMA_CONTROLLER_BUCKET_OPT_NOT_FN,
69
68
  FST_ERR_AJV_CUSTOM_OPTIONS_OPT_NOT_OBJ,
70
69
  FST_ERR_AJV_CUSTOM_OPTIONS_OPT_NOT_ARR,
71
- FST_ERR_VERSION_CONSTRAINT_NOT_STR,
72
70
  FST_ERR_INSTANCE_ALREADY_LISTENING,
73
71
  FST_ERR_REOPENED_CLOSE_SERVER,
74
72
  FST_ERR_ROUTE_REWRITE_NOT_STR,
75
73
  FST_ERR_SCHEMA_ERROR_FORMATTER_NOT_FN,
76
- FST_ERR_ERROR_HANDLER_NOT_FN
74
+ FST_ERR_ERROR_HANDLER_NOT_FN,
75
+ FST_ERR_ROUTE_METHOD_INVALID
77
76
  } = errorCodes
78
77
 
79
78
  const { buildErrorHandler } = require('./lib/error-handler.js')
@@ -154,31 +153,12 @@ function fastify (options) {
154
153
  // exposeHeadRoutes have its default set from the validator
155
154
  options.exposeHeadRoutes = initialConfig.exposeHeadRoutes
156
155
 
157
- let constraints = options.constraints
158
- if (options.versioning) {
159
- FSTDEP009()
160
- constraints = {
161
- ...constraints,
162
- version: {
163
- name: 'version',
164
- mustMatchWhenDerived: true,
165
- storage: options.versioning.storage,
166
- deriveConstraint: options.versioning.deriveVersion,
167
- validate (value) {
168
- if (typeof value !== 'string') {
169
- throw new FST_ERR_VERSION_CONSTRAINT_NOT_STR()
170
- }
171
- }
172
- }
173
- }
174
- }
175
-
176
156
  // Default router
177
157
  const router = buildRouting({
178
158
  config: {
179
159
  defaultRoute,
180
160
  onBadUrl,
181
- constraints,
161
+ constraints: options.constraints,
182
162
  ignoreTrailingSlash: options.ignoreTrailingSlash || defaultInitOptions.ignoreTrailingSlash,
183
163
  ignoreDuplicateSlashes: options.ignoreDuplicateSlashes || defaultInitOptions.ignoreDuplicateSlashes,
184
164
  maxParamLength: options.maxParamLength || defaultInitOptions.maxParamLength,
@@ -228,6 +208,22 @@ function fastify (options) {
228
208
  readyPromise: null
229
209
  },
230
210
  [kKeepAliveConnections]: keepAliveConnections,
211
+ [kSupportedHTTPMethods]: {
212
+ bodyless: new Set([
213
+ // Standard
214
+ 'GET',
215
+ 'HEAD',
216
+ 'TRACE'
217
+ ]),
218
+ bodywith: new Set([
219
+ // Standard
220
+ 'DELETE',
221
+ 'OPTIONS',
222
+ 'PATCH',
223
+ 'PUT',
224
+ 'POST'
225
+ ])
226
+ },
231
227
  [kOptions]: options,
232
228
  [kChildren]: [],
233
229
  [kServerBindings]: [],
@@ -265,6 +261,9 @@ function fastify (options) {
265
261
  head: function _head (url, options, handler) {
266
262
  return router.prepareRoute.call(this, { method: 'HEAD', url, options, handler })
267
263
  },
264
+ trace: function _trace (url, options, handler) {
265
+ return router.prepareRoute.call(this, { method: 'TRACE', url, options, handler })
266
+ },
268
267
  patch: function _patch (url, options, handler) {
269
268
  return router.prepareRoute.call(this, { method: 'PATCH', url, options, handler })
270
269
  },
@@ -277,41 +276,8 @@ function fastify (options) {
277
276
  options: function _options (url, options, handler) {
278
277
  return router.prepareRoute.call(this, { method: 'OPTIONS', url, options, handler })
279
278
  },
280
- propfind: function _propfind (url, options, handler) {
281
- return router.prepareRoute.call(this, { method: 'PROPFIND', url, options, handler })
282
- },
283
- proppatch: function _proppatch (url, options, handler) {
284
- return router.prepareRoute.call(this, { method: 'PROPPATCH', url, options, handler })
285
- },
286
- mkcalendar: function _mkcalendar (url, options, handler) {
287
- return router.prepareRoute.call(this, { method: 'MKCALENDAR', url, options, handler })
288
- },
289
- mkcol: function _mkcol (url, options, handler) {
290
- return router.prepareRoute.call(this, { method: 'MKCOL', url, options, handler })
291
- },
292
- copy: function _copy (url, options, handler) {
293
- return router.prepareRoute.call(this, { method: 'COPY', url, options, handler })
294
- },
295
- move: function _move (url, options, handler) {
296
- return router.prepareRoute.call(this, { method: 'MOVE', url, options, handler })
297
- },
298
- lock: function _lock (url, options, handler) {
299
- return router.prepareRoute.call(this, { method: 'LOCK', url, options, handler })
300
- },
301
- unlock: function _unlock (url, options, handler) {
302
- return router.prepareRoute.call(this, { method: 'UNLOCK', url, options, handler })
303
- },
304
- trace: function _trace (url, options, handler) {
305
- return router.prepareRoute.call(this, { method: 'TRACE', url, options, handler })
306
- },
307
- report: function _mkcalendar (url, options, handler) {
308
- return router.prepareRoute.call(this, { method: 'REPORT', url, options, handler })
309
- },
310
- search: function _search (url, options, handler) {
311
- return router.prepareRoute.call(this, { method: 'SEARCH', url, options, handler })
312
- },
313
279
  all: function _all (url, options, handler) {
314
- return router.prepareRoute.call(this, { method: supportedMethods, url, options, handler })
280
+ return router.prepareRoute.call(this, { method: this.supportedMethods, url, options, handler })
315
281
  },
316
282
  // extended route
317
283
  route: function _route (options) {
@@ -375,6 +341,7 @@ function fastify (options) {
375
341
  decorateRequest: decorator.decorateRequest,
376
342
  hasRequestDecorator: decorator.existRequest,
377
343
  hasReplyDecorator: decorator.existReply,
344
+ addHttpMethod,
378
345
  // fake http injection
379
346
  inject,
380
347
  // pretty print of the registered routes
@@ -442,6 +409,15 @@ function fastify (options) {
442
409
  genReqId: {
443
410
  configurable: true,
444
411
  get () { return this[kGenReqId] }
412
+ },
413
+ supportedMethods: {
414
+ configurable: false,
415
+ get () {
416
+ return [
417
+ ...this[kSupportedHTTPMethods].bodyless,
418
+ ...this[kSupportedHTTPMethods].bodywith
419
+ ]
420
+ }
445
421
  }
446
422
  })
447
423
 
@@ -485,7 +461,7 @@ function fastify (options) {
485
461
  if (forceCloseConnections === 'idle') {
486
462
  // Not needed in Node 19
487
463
  instance.server.closeIdleConnections()
488
- /* istanbul ignore next: Cannot test this without Node.js core support */
464
+ /* istanbul ignore next: Cannot test this without Node.js core support */
489
465
  } else if (serverHasCloseAllConnections && forceCloseConnections) {
490
466
  instance.server.closeAllConnections()
491
467
  } else if (forceCloseConnections === true) {
@@ -917,6 +893,29 @@ function fastify (options) {
917
893
  this[kGenReqId] = reqIdGenFactory(this[kOptions].requestIdHeader, func)
918
894
  return this
919
895
  }
896
+
897
+ function addHttpMethod (method, { hasBody = false } = {}) {
898
+ if (typeof method !== 'string' || http.METHODS.indexOf(method) === -1) {
899
+ throw new FST_ERR_ROUTE_METHOD_INVALID()
900
+ }
901
+
902
+ if (hasBody === true) {
903
+ this[kSupportedHTTPMethods].bodywith.add(method)
904
+ this[kSupportedHTTPMethods].bodyless.delete(method)
905
+ } else {
906
+ this[kSupportedHTTPMethods].bodywith.delete(method)
907
+ this[kSupportedHTTPMethods].bodyless.add(method)
908
+ }
909
+
910
+ const _method = method.toLowerCase()
911
+ if (!this.hasDecorator(_method)) {
912
+ this.decorate(_method, function (url, options, handler) {
913
+ return router.prepareRoute.call(this, { method, url, options, handler })
914
+ })
915
+ }
916
+
917
+ return this
918
+ }
920
919
  }
921
920
 
922
921
  function validateSchemaErrorFormatter (schemaErrorFormatter) {