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
@@ -24,6 +24,7 @@ describes the properties available in that options object.
24
24
  - [`onProtoPoisoning`](#onprotopoisoning)
25
25
  - [`onConstructorPoisoning`](#onconstructorpoisoning)
26
26
  - [`logger`](#logger)
27
+ - [`loggerInstance`](#loggerInstance)
27
28
  - [`disableRequestLogging`](#disablerequestlogging)
28
29
  - [`serverFactory`](#serverfactory)
29
30
  - [`caseSensitive`](#casesensitive)
@@ -105,7 +106,7 @@ describes the properties available in that options object.
105
106
 
106
107
  An object used to configure the server's listening socket. The options
107
108
  are the same as the Node.js core [`createServer`
108
- method](https://nodejs.org/dist/latest-v14.x/docs/api/http.html#http_http_createserver_options_requestlistener).
109
+ method](https://nodejs.org/docs/latest-v20.x/api/http.html#httpcreateserveroptions-requestlistener).
109
110
 
110
111
  This option is ignored if options [`http2`](#factory-http2) or
111
112
  [`https`](#factory-https) are set.
@@ -116,7 +117,7 @@ This option is ignored if options [`http2`](#factory-http2) or
116
117
  + Default: `false`
117
118
 
118
119
  If `true` Node.js core's
119
- [HTTP/2](https://nodejs.org/dist/latest-v14.x/docs/api/http2.html) module is
120
+ [HTTP/2](https://nodejs.org/dist/latest-v20.x/docs/api/http2.html) module is
120
121
  used for binding the socket.
121
122
 
122
123
  ### `https`
@@ -126,7 +127,7 @@ used for binding the socket.
126
127
 
127
128
  An object used to configure the server's listening socket for TLS. The options
128
129
  are the same as the Node.js core [`createServer`
129
- method](https://nodejs.org/dist/latest-v14.x/docs/api/https.html#https_https_createserver_options_requestlistener).
130
+ method](https://nodejs.org/dist/latest-v20.x/docs/api/https.html#https_https_createserver_options_requestlistener).
130
131
  When this property is `null`, the socket will not be configured for TLS.
131
132
 
132
133
  This option also applies when the [`http2`](#factory-http2) option is set.
@@ -152,7 +153,7 @@ Defines the server keep-alive timeout in milliseconds. See documentation for
152
153
  [`server.keepAliveTimeout`
153
154
  property](https://nodejs.org/api/http.html#http_server_keepalivetimeout) to
154
155
  understand the effect of this option. This option only applies when HTTP/1 is in
155
- use.
156
+ use.
156
157
 
157
158
  When `serverFactory` option is specified this option is ignored.
158
159
 
@@ -203,7 +204,7 @@ ignored.
203
204
  Defines the maximum number of milliseconds for receiving the entire request from
204
205
  the client. See [`server.requestTimeout`
205
206
  property](https://nodejs.org/dist/latest/docs/api/http.html#http_server_requesttimeout)
206
- to understand the effect of this option.
207
+ to understand the effect of this option.
207
208
 
208
209
  When `serverFactory` option is specified, this option is ignored.
209
210
  It must be set to a non-zero value (e.g. 120 seconds) to protect against potential
@@ -329,9 +330,6 @@ The possible values this property may have are:
329
330
  + Default: `false`. The logger is disabled. All logging methods will point to a
330
331
  null logger [abstract-logging](https://npm.im/abstract-logging) instance.
331
332
 
332
- + `pinoInstance`: a previously instantiated instance of Pino. The internal
333
- logger will point to this instance.
334
-
335
333
  + `object`: a standard Pino [options
336
334
  object](https://github.com/pinojs/pino/blob/c77d8ec5ce/docs/API.md#constructor).
337
335
  This will be passed directly to the Pino constructor. If the following
@@ -351,9 +349,15 @@ The possible values this property may have are:
351
349
  ```
352
350
  Any user-supplied serializer will override the default serializer of the
353
351
  corresponding property.
354
- + `loggerInstance`: a custom logger instance. The logger must conform to the
355
- Pino interface by having the following methods: `info`, `error`, `debug`,
356
- `fatal`, `warn`, `trace`, `child`. For example:
352
+
353
+ ### `loggerInstance`
354
+ <a id="factory-logger-instance"></a>
355
+
356
+ + Default: `null`
357
+
358
+ A custom logger instance. The logger must be a Pino instance or conform to the
359
+ Pino interface by having the following methods: `info`, `error`, `debug`,
360
+ `fatal`, `warn`, `trace`, `child`. For example:
357
361
  ```js
358
362
  const pino = require('pino')();
359
363
 
@@ -387,12 +391,12 @@ attaching custom `onRequest` and `onResponse` hooks.
387
391
 
388
392
  The other log entries that will be disabled are:
389
393
  - an error log written by the default `onResponse` hook on reply callback errors
390
- - the error and info logs written by the `defaultErrorHandler`
394
+ - the error and info logs written by the `defaultErrorHandler`
391
395
  on error management
392
- - the info log written by the `fourOhFour` handler when a
396
+ - the info log written by the `fourOhFour` handler when a
393
397
  non existent route is requested
394
398
 
395
- Other log messages emitted by Fastify will stay enabled,
399
+ Other log messages emitted by Fastify will stay enabled,
396
400
  like deprecation warnings and messages
397
401
  emitted when requests are received while the server is closing.
398
402
 
@@ -456,7 +460,7 @@ Please note that setting this option to `false` goes against
456
460
 
457
461
  By setting `caseSensitive` to `false`, all paths will be matched as lowercase,
458
462
  but the route parameters or wildcards will maintain their original letter
459
- casing.
463
+ casing.
460
464
  This option does not affect query strings, please refer to
461
465
  [`querystringParser`](#querystringparser) to change their handling.
462
466
 
@@ -493,7 +497,7 @@ Setting `requestIdHeader` to `true` will set the `requestIdHeader` to
493
497
  Setting `requestIdHeader` to a non-empty string will use
494
498
  the specified string as the `requestIdHeader`.
495
499
  By default `requestIdHeader` is set to `false` and will immediately use [genReqId](#genreqid).
496
- Setting `requestIdHeader` to an empty String (`""`) will set the
500
+ Setting `requestIdHeader` to an empty String (`""`) will set the
497
501
  requestIdHeader to `false`.
498
502
 
499
503
  + Default: `false`
@@ -827,7 +831,7 @@ is an instance-wide configuration.
827
831
  // @param {object} req The raw Node.js HTTP request, not the `FastifyRequest` object.
828
832
  // @this Fastify The root Fastify instance (not an encapsulated instance).
829
833
  // @returns {string} The path that the request should be mapped to.
830
- function rewriteUrl (req) {
834
+ function rewriteUrl (req) {
831
835
  if (req.url === '/hi') {
832
836
  this.log.debug({ originalUrl: req.url, url: '/hello' }, 'rewrite url');
833
837
  return '/hello'
@@ -948,7 +952,7 @@ Starts the server and internally waits for the `.ready()` event. The signature
948
952
  is `.listen([options][, callback])`. Both the `options` object and the
949
953
  `callback` parameters extend the [Node.js
950
954
  core](https://nodejs.org/api/net.html#serverlistenoptions-callback) options
951
- object. Thus, all core options are available with the following additional
955
+ object. Thus, all core options are available with the following additional
952
956
  Fastify specific options:
953
957
 
954
958
  ### `listenTextResolver`
@@ -956,13 +960,13 @@ Fastify specific options:
956
960
 
957
961
  Set an optional resolver for the text to log after server has been successfully
958
962
  started.
959
- It is possible to override the default `Server listening at [address]` log
963
+ It is possible to override the default `Server listening at [address]` log
960
964
  entry using this option.
961
965
 
962
966
  ```js
963
- server.listen({
964
- port: 9080,
965
- listenTextResolver: (address) => { return `Prometheus metrics server is listening at ${address}` }
967
+ server.listen({
968
+ port: 9080,
969
+ listenTextResolver: (address) => { return `Prometheus metrics server is listening at ${address}` }
966
970
  })
967
971
  ```
968
972
 
@@ -1090,7 +1094,7 @@ Method to add routes to the server, it also has shorthand functions, check
1090
1094
  <a id="hasRoute"></a>
1091
1095
 
1092
1096
  Method to check if a route is already registered to the internal router. It
1093
- expects an object as the payload. `url` and `method` are mandatory fields. It
1097
+ expects an object as the payload. `url` and `method` are mandatory fields. It
1094
1098
  is possible to also specify `constraints`. The method returns `true` if the
1095
1099
  route is registered or `false` if not.
1096
1100
 
@@ -1110,8 +1114,8 @@ if (routeExists === false) {
1110
1114
  <a id="findRoute"></a>
1111
1115
 
1112
1116
  Method to retrieve a route already registered to the internal router. It
1113
- expects an object as the payload. `url` and `method` are mandatory fields. It
1114
- is possible to also specify `constraints`.
1117
+ expects an object as the payload. `url` and `method` are mandatory fields. It
1118
+ is possible to also specify `constraints`.
1115
1119
  The method returns a route object or `null` if the route cannot be found.
1116
1120
 
1117
1121
  ```js
@@ -1351,7 +1355,7 @@ Set the schema error formatter for all routes. See
1351
1355
  Set the schema serializer compiler for all routes. See
1352
1356
  [#schema-serializer](./Validation-and-Serialization.md#schema-serializer).
1353
1357
 
1354
- > **Note**
1358
+ > **Note**
1355
1359
  > [`setReplySerializer`](#set-reply-serializer) has priority if set!
1356
1360
 
1357
1361
  #### validatorCompiler
@@ -1559,7 +1563,7 @@ is set. It can be accessed using `fastify.errorHandler` and it logs the error
1559
1563
  with respect to its `statusCode`.
1560
1564
 
1561
1565
  ```js
1562
- var statusCode = error.statusCode
1566
+ const statusCode = error.statusCode
1563
1567
  if (statusCode >= 500) {
1564
1568
  log.error(error)
1565
1569
  } else if (statusCode >= 400) {
@@ -1966,7 +1970,7 @@ The properties that can currently be exposed are:
1966
1970
  - requestIdHeader
1967
1971
  - requestIdLogLabel
1968
1972
  - http2SessionTimeout
1969
- - useSemicolonDelimiter
1973
+ - useSemicolonDelimiter
1970
1974
 
1971
1975
  ```js
1972
1976
  const { readFileSync } = require('node:fs')
@@ -182,7 +182,7 @@ route-level `request` object.
182
182
  admin"}`
183
183
 
184
184
  🎉 Good work, now you can define interfaces for each route and have strictly
185
- typed request and reply instances. Other parts of the Fastify type system rely
185
+ typed request and reply instances. Other parts of the Fastify type system rely
186
186
  on generic properties. Make sure to reference the detailed type system
187
187
  documentation below to learn more about what is available.
188
188
 
@@ -873,11 +873,11 @@ a more detailed http server walkthrough.
873
873
 
874
874
  1. Create the following imports from `@types/node` and `fastify`
875
875
  ```typescript
876
- import fs from 'fs'
877
- import path from 'path'
876
+ import fs from 'node:fs'
877
+ import path from 'node:path'
878
878
  import fastify from 'fastify'
879
879
  ```
880
- 2. Perform the following steps before setting up a Fastify HTTPS server
880
+ 2. Perform the following steps before setting up a Fastify HTTPS server
881
881
  to create the `key.pem` and `cert.pem` files:
882
882
  ```sh
883
883
  openssl genrsa -out key.pem
@@ -935,7 +935,7 @@ specified at server instantiation, the custom type becomes available on all
935
935
  further instances of the custom type.
936
936
  ```typescript
937
937
  import fastify from 'fastify'
938
- import http from 'http'
938
+ import http from 'node:http'
939
939
 
940
940
  interface customRequest extends http.IncomingMessage {
941
941
  mySpecialProp: string
@@ -1123,8 +1123,8 @@ returns `http.IncomingMessage`, otherwise, it returns
1123
1123
  `http2.Http2ServerRequest`.
1124
1124
 
1125
1125
  ```typescript
1126
- import http from 'http'
1127
- import http2 from 'http2'
1126
+ import http from 'node:http'
1127
+ import http2 from 'node:http2'
1128
1128
  import { RawRequestDefaultExpression } from 'fastify'
1129
1129
 
1130
1130
  RawRequestDefaultExpression<http.Server> // -> http.IncomingMessage
@@ -1183,8 +1183,8 @@ returns `http.ServerResponse`, otherwise, it returns
1183
1183
  `http2.Http2ServerResponse`.
1184
1184
 
1185
1185
  ```typescript
1186
- import http from 'http'
1187
- import http2 from 'http2'
1186
+ import http from 'node:http'
1187
+ import http2 from 'node:http2'
1188
1188
  import { RawReplyDefaultExpression } from 'fastify'
1189
1189
 
1190
1190
  RawReplyDefaultExpression<http.Server> // -> http.ServerResponse
@@ -49,16 +49,16 @@ The shared schemas can be reused through the JSON Schema
49
49
  [**`$ref`**](https://tools.ietf.org/html/draft-handrews-json-schema-01#section-8)
50
50
  keyword. Here is an overview of _how_ references work:
51
51
 
52
- + `myField: { $ref: '#foo'}` will search for field with `$id: '#foo'` inside the
52
+ + `myField: { $ref: '#foo' }` will search for field with `$id: '#foo'` inside the
53
53
  current schema
54
- + `myField: { $ref: '#/definitions/foo'}` will search for field
54
+ + `myField: { $ref: '#/definitions/foo' }` will search for field
55
55
  `definitions.foo` inside the current schema
56
- + `myField: { $ref: 'http://url.com/sh.json#'}` will search for a shared schema
56
+ + `myField: { $ref: 'http://url.com/sh.json#' }` will search for a shared schema
57
57
  added with `$id: 'http://url.com/sh.json'`
58
- + `myField: { $ref: 'http://url.com/sh.json#/definitions/foo'}` will search for
58
+ + `myField: { $ref: 'http://url.com/sh.json#/definitions/foo' }` will search for
59
59
  a shared schema added with `$id: 'http://url.com/sh.json'` and will use the
60
60
  field `definitions.foo`
61
- + `myField: { $ref: 'http://url.com/sh.json#foo'}` will search for a shared
61
+ + `myField: { $ref: 'http://url.com/sh.json#foo' }` will search for a shared
62
62
  schema added with `$id: 'http://url.com/sh.json'` and it will look inside of
63
63
  it for object with `$id: '#foo'`
64
64
 
@@ -11,7 +11,7 @@
11
11
  */
12
12
 
13
13
  import fastify, { FastifyInstance, RouteShorthandOptions } from '../fastify'
14
- import { Server, IncomingMessage, ServerResponse } from 'http'
14
+ import { Server, IncomingMessage, ServerResponse } from 'node:http'
15
15
 
16
16
  // Create an http server. We pass the relevant typings for our http version used.
17
17
  // By passing types we get correctly typed access to the underlying http objects in routes.
package/fastify.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import * as http from 'http'
2
- import * as http2 from 'http2'
3
- import * as https from 'https'
4
- import { Socket } from 'net'
1
+ import * as http from 'node:http'
2
+ import * as http2 from 'node:http2'
3
+ import * as https from 'node:https'
4
+ import { Socket } from 'node:net'
5
5
 
6
6
  import { Options as AjvOptions, ValidatorFactory } from '@fastify/ajv-compiler'
7
7
  import { FastifyError } from '@fastify/error'
@@ -14,7 +14,15 @@ import { FastifyContextConfig, FastifyReplyContext, FastifyRequestContext } from
14
14
  import { FastifyErrorCodes } from './types/errors'
15
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
16
  import { FastifyInstance, FastifyListenOptions, PrintRoutesOptions } from './types/instance'
17
- import { FastifyBaseLogger, FastifyLogFn, FastifyLoggerInstance, FastifyLoggerOptions, LogLevel, PinoLoggerOptions } from './types/logger'
17
+ import {
18
+ FastifyBaseLogger,
19
+ FastifyChildLoggerFactory,
20
+ FastifyLogFn,
21
+ FastifyLoggerInstance,
22
+ FastifyLoggerOptions,
23
+ LogLevel,
24
+ PinoLoggerOptions
25
+ } from './types/logger'
18
26
  import { FastifyPlugin, FastifyPluginAsync, FastifyPluginCallback, FastifyPluginOptions } from './types/plugin'
19
27
  import { FastifyRegister, FastifyRegisterOptions, RegisterOptions } from './types/register'
20
28
  import { FastifyReply } from './types/reply'
@@ -149,6 +157,7 @@ declare namespace fastify {
149
157
  * listener to error events emitted by client connections
150
158
  */
151
159
  clientErrorHandler?: (error: ConnectionError, socket: Socket) => void,
160
+ childLoggerFactory?: FastifyChildLoggerFactory
152
161
  }
153
162
 
154
163
  /**
package/fastify.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const VERSION = '5.0.0'
3
+ const VERSION = '5.2.0'
4
4
 
5
5
  const Avvio = require('avvio')
6
6
  const http = require('node:http')
@@ -42,7 +42,7 @@ const decorator = require('./lib/decorate')
42
42
  const ContentTypeParser = require('./lib/contentTypeParser')
43
43
  const SchemaController = require('./lib/schema-controller')
44
44
  const { Hooks, hookRunnerApplication, supportedHooks } = require('./lib/hooks')
45
- const { createLogger, createChildLogger, defaultChildLoggerFactory } = require('./lib/logger')
45
+ const { createChildLogger, defaultChildLoggerFactory, createLogger } = require('./lib/logger-factory')
46
46
  const pluginUtils = require('./lib/pluginUtils')
47
47
  const { getGenReqId, reqIdGenFactory } = require('./lib/reqIdGenFactory')
48
48
  const { buildRouting, validateBodyLimitOption } = require('./lib/route')
@@ -97,10 +97,11 @@ function defaultBuildPrettyMeta (route) {
97
97
  */
98
98
  function fastify (options) {
99
99
  // Options validations
100
- options = options || {}
101
-
102
- if (typeof options !== 'object') {
100
+ if (options && typeof options !== 'object') {
103
101
  throw new FST_ERR_OPTIONS_NOT_OBJ()
102
+ } else {
103
+ // Shallow copy options object to prevent mutations outside of this function
104
+ options = Object.assign({}, options)
104
105
  }
105
106
 
106
107
  if (options.querystringParser && typeof options.querystringParser !== 'function') {
@@ -134,6 +135,7 @@ function fastify (options) {
134
135
  }
135
136
 
136
137
  // Instance Fastify components
138
+
137
139
  const { logger, hasLogger } = createLogger(options)
138
140
 
139
141
  // Update the options with the fixed values
@@ -928,7 +930,7 @@ function validateSchemaErrorFormatter (schemaErrorFormatter) {
928
930
 
929
931
  /**
930
932
  * These export configurations enable JS and TS developers
931
- * to consumer fastify in whatever way best suits their needs.
933
+ * to consume fastify in whatever way best suits their needs.
932
934
  * Some examples of supported import syntax includes:
933
935
  * - `const fastify = require('fastify')`
934
936
  * - `const { fastify } = require('fastify')`
@@ -109,16 +109,19 @@ ContentTypeParser.prototype.existingParser = function (contentType) {
109
109
  ContentTypeParser.prototype.getParser = function (contentType) {
110
110
  let parser = this.customParsers.get(contentType)
111
111
  if (parser !== undefined) return parser
112
-
113
112
  parser = this.cache.get(contentType)
114
113
  if (parser !== undefined) return parser
115
114
 
116
- // eslint-disable-next-line no-var
117
- for (var i = 0; i !== this.parserList.length; ++i) {
115
+ const caseInsensitiveContentType = contentType.toLowerCase()
116
+ for (let i = 0; i !== this.parserList.length; ++i) {
118
117
  const parserListItem = this.parserList[i]
119
118
  if (
120
- contentType.slice(0, parserListItem.length) === parserListItem &&
121
- (contentType.length === parserListItem.length || contentType.charCodeAt(parserListItem.length) === 59 /* `;` */ || contentType.charCodeAt(parserListItem.length) === 32 /* ` ` */)
119
+ caseInsensitiveContentType.slice(0, parserListItem.length) === parserListItem &&
120
+ (
121
+ caseInsensitiveContentType.length === parserListItem.length ||
122
+ caseInsensitiveContentType.charCodeAt(parserListItem.length) === 59 /* `;` */ ||
123
+ caseInsensitiveContentType.charCodeAt(parserListItem.length) === 32 /* ` ` */
124
+ )
122
125
  ) {
123
126
  parser = this.customParsers.get(parserListItem)
124
127
  this.cache.set(contentType, parser)
@@ -126,8 +129,7 @@ ContentTypeParser.prototype.getParser = function (contentType) {
126
129
  }
127
130
  }
128
131
 
129
- // eslint-disable-next-line no-var
130
- for (var j = 0; j !== this.parserRegExpList.length; ++j) {
132
+ for (let j = 0; j !== this.parserRegExpList.length; ++j) {
131
133
  const parserRegExp = this.parserRegExpList[j]
132
134
  if (parserRegExp.test(contentType)) {
133
135
  parser = this.customParsers.get(parserRegExp.toString())
package/lib/context.js CHANGED
@@ -85,8 +85,7 @@ function defaultSchemaErrorFormatter (errors, dataVar) {
85
85
  let text = ''
86
86
  const separator = ', '
87
87
 
88
- // eslint-disable-next-line no-var
89
- for (var i = 0; i !== errors.length; ++i) {
88
+ for (let i = 0; i !== errors.length; ++i) {
90
89
  const e = errors[i]
91
90
  text += dataVar + (e.instancePath || '') + ' ' + e.message + separator
92
91
  }
@@ -112,16 +112,16 @@ function fallbackErrorHandler (error, reply, cb) {
112
112
  const serializerFn = getSchemaSerializer(reply[kRouteContext], statusCode, reply[kReplyHeaders]['content-type'])
113
113
  payload = (serializerFn === false)
114
114
  ? serializeError({
115
- error: statusCodes[statusCode + ''],
116
- code: error.code,
117
- message: error.message,
118
- statusCode
119
- })
115
+ error: statusCodes[statusCode + ''],
116
+ code: error.code,
117
+ message: error.message,
118
+ statusCode
119
+ })
120
120
  : serializerFn(Object.create(error, {
121
- error: { value: statusCodes[statusCode + ''] },
122
- message: { value: error.message },
123
- statusCode: { value: statusCode }
124
- }))
121
+ error: { value: statusCodes[statusCode + ''] },
122
+ message: { value: error.message },
123
+ statusCode: { value: statusCode }
124
+ }))
125
125
  } catch (err) {
126
126
  if (!reply.log[kDisableRequestLogging]) {
127
127
  // error is always FST_ERR_SCH_SERIALIZATION_BUILD because this is called from route/compileSchemasForSerialization
package/lib/errors.js CHANGED
@@ -189,7 +189,7 @@ const codes = {
189
189
 
190
190
  FST_ERR_HOOK_TIMEOUT: createError(
191
191
  'FST_ERR_HOOK_TIMEOUT',
192
- "A callback for '%s' hook timed out. You may have forgotten to call 'done' function or to resolve a Promise"
192
+ "A callback for '%s' hook%s timed out. You may have forgotten to call 'done' function or to resolve a Promise"
193
193
  ),
194
194
 
195
195
  /**
package/lib/fourOhFour.js CHANGED
@@ -18,7 +18,7 @@ const { buildErrorHandler } = require('./error-handler.js')
18
18
  const {
19
19
  FST_ERR_NOT_FOUND
20
20
  } = require('./errors')
21
- const { createChildLogger } = require('./logger')
21
+ const { createChildLogger } = require('./logger-factory')
22
22
  const { getGenReqId } = require('./reqIdGenFactory.js')
23
23
 
24
24
  /**
package/lib/hooks.js CHANGED
@@ -98,9 +98,12 @@ function hookRunnerApplication (hookName, boot, server, cb) {
98
98
  next()
99
99
 
100
100
  function exit (err) {
101
+ const hookFnName = hooks[i - 1]?.name
102
+ const hookFnFragment = hookFnName ? ` "${hookFnName}"` : ''
103
+
101
104
  if (err) {
102
105
  if (err.code === 'AVV_ERR_READY_TIMEOUT') {
103
- err = appendStackTrace(err, new FST_ERR_HOOK_TIMEOUT(hookName))
106
+ err = appendStackTrace(err, new FST_ERR_HOOK_TIMEOUT(hookName, hookFnFragment))
104
107
  } else {
105
108
  err = AVVIO_ERRORS_MAP[err.code] != null
106
109
  ? appendStackTrace(err, new AVVIO_ERRORS_MAP[err.code](err.message))