fastify 3.27.3 → 4.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/.taprc +3 -0
  2. package/README.md +7 -7
  3. package/build/build-error-serializer.js +27 -0
  4. package/build/build-validation.js +47 -35
  5. package/docs/Guides/Database.md +320 -0
  6. package/docs/Guides/Getting-Started.md +7 -7
  7. package/docs/Guides/Plugins-Guide.md +1 -1
  8. package/docs/Guides/Serverless.md +3 -3
  9. package/docs/Guides/Testing.md +2 -2
  10. package/docs/Migration-Guide-V4.md +12 -0
  11. package/docs/Reference/ContentTypeParser.md +4 -0
  12. package/docs/Reference/Decorators.md +2 -2
  13. package/docs/Reference/Encapsulation.md +2 -2
  14. package/docs/Reference/Errors.md +51 -6
  15. package/docs/Reference/HTTP2.md +3 -3
  16. package/docs/Reference/Hooks.md +4 -7
  17. package/docs/Reference/LTS.md +5 -4
  18. package/docs/Reference/Plugins.md +3 -3
  19. package/docs/Reference/Reply.md +23 -22
  20. package/docs/Reference/Request.md +1 -3
  21. package/docs/Reference/Routes.md +22 -15
  22. package/docs/Reference/Server.md +69 -119
  23. package/docs/Reference/TypeScript.md +20 -22
  24. package/docs/Reference/Validation-and-Serialization.md +30 -55
  25. package/docs/Type-Providers.md +257 -0
  26. package/examples/asyncawait.js +1 -1
  27. package/examples/benchmark/hooks-benchmark-async-await.js +1 -1
  28. package/examples/benchmark/hooks-benchmark.js +1 -1
  29. package/examples/benchmark/simple.js +1 -1
  30. package/examples/hooks.js +2 -2
  31. package/examples/http2.js +1 -1
  32. package/examples/https.js +1 -1
  33. package/examples/parser.js +1 -1
  34. package/examples/route-prefix.js +1 -1
  35. package/examples/shared-schema.js +1 -1
  36. package/examples/simple-stream.js +18 -0
  37. package/examples/simple.js +1 -1
  38. package/examples/simple.mjs +1 -1
  39. package/examples/typescript-server.ts +1 -1
  40. package/examples/use-plugin.js +1 -1
  41. package/fastify.d.ts +34 -22
  42. package/fastify.js +40 -36
  43. package/lib/configValidator.js +902 -1023
  44. package/lib/contentTypeParser.js +6 -16
  45. package/lib/context.js +36 -10
  46. package/lib/decorate.js +3 -1
  47. package/lib/error-handler.js +158 -0
  48. package/lib/error-serializer.js +257 -0
  49. package/lib/errors.js +43 -9
  50. package/lib/fourOhFour.js +31 -20
  51. package/lib/handleRequest.js +10 -13
  52. package/lib/hooks.js +14 -9
  53. package/lib/pluginOverride.js +0 -3
  54. package/lib/pluginUtils.js +3 -2
  55. package/lib/reply.js +29 -158
  56. package/lib/request.js +13 -10
  57. package/lib/route.js +131 -138
  58. package/lib/schema-controller.js +2 -2
  59. package/lib/schemas.js +27 -1
  60. package/lib/server.js +241 -116
  61. package/lib/symbols.js +4 -3
  62. package/lib/validation.js +2 -1
  63. package/lib/warnings.js +4 -12
  64. package/lib/wrapThenable.js +4 -11
  65. package/package.json +37 -39
  66. package/test/404s.test.js +258 -125
  67. package/test/500s.test.js +3 -3
  68. package/test/als.test.js +1 -1
  69. package/test/async-await.test.js +20 -76
  70. package/test/bodyLimit.test.js +1 -1
  71. package/test/build-certificate.js +6 -7
  72. package/test/case-insensitive.test.js +4 -4
  73. package/test/close-pipelining.test.js +2 -2
  74. package/test/close.test.js +11 -11
  75. package/test/content-parser.test.js +32 -0
  76. package/test/context-config.test.js +52 -0
  77. package/test/custom-http-server.test.js +14 -7
  78. package/test/custom-parser-async.test.js +1 -66
  79. package/test/custom-parser.test.js +92 -159
  80. package/test/custom-querystring-parser.test.js +3 -3
  81. package/test/decorator.test.js +11 -13
  82. package/test/delete.test.js +6 -6
  83. package/test/encapsulated-error-handler.test.js +50 -0
  84. package/test/esm/index.test.js +0 -14
  85. package/test/fastify-instance.test.js +4 -4
  86. package/test/fluent-schema.test.js +4 -4
  87. package/test/genReqId.test.js +1 -1
  88. package/test/get.test.js +4 -4
  89. package/test/handler-context.test.js +2 -2
  90. package/test/head.test.js +1 -1
  91. package/test/helper.js +19 -4
  92. package/test/hooks-async.test.js +15 -48
  93. package/test/hooks.on-ready.test.js +10 -5
  94. package/test/hooks.test.js +78 -119
  95. package/test/http2/closing.test.js +10 -16
  96. package/test/http2/constraint.test.js +1 -1
  97. package/test/http2/head.test.js +1 -1
  98. package/test/http2/plain.test.js +1 -1
  99. package/test/http2/secure-with-fallback.test.js +1 -1
  100. package/test/http2/secure.test.js +1 -1
  101. package/test/http2/unknown-http-method.test.js +4 -10
  102. package/test/https/custom-https-server.test.js +12 -6
  103. package/test/https/https.test.js +1 -1
  104. package/test/input-validation.js +3 -3
  105. package/test/internals/handleRequest.test.js +6 -43
  106. package/test/internals/initialConfig.test.js +41 -12
  107. package/test/internals/logger.test.js +2 -2
  108. package/test/internals/reply.test.js +281 -40
  109. package/test/internals/request.test.js +13 -7
  110. package/test/internals/server.test.js +88 -0
  111. package/test/listen.deprecated.test.js +202 -0
  112. package/test/listen.test.js +118 -150
  113. package/test/logger.test.js +82 -42
  114. package/test/maxRequestsPerSocket.test.js +8 -6
  115. package/test/middleware.test.js +2 -25
  116. package/test/nullable-validation.test.js +53 -16
  117. package/test/output-validation.test.js +1 -1
  118. package/test/plugin.test.js +47 -21
  119. package/test/pretty-print.test.js +22 -10
  120. package/test/promises.test.js +1 -1
  121. package/test/proto-poisoning.test.js +6 -6
  122. package/test/register.test.js +3 -3
  123. package/test/reply-error.test.js +126 -15
  124. package/test/request-error.test.js +3 -6
  125. package/test/route-hooks.test.js +18 -18
  126. package/test/route-prefix.test.js +2 -1
  127. package/test/route.test.js +206 -22
  128. package/test/router-options.test.js +2 -2
  129. package/test/schema-examples.test.js +11 -5
  130. package/test/schema-feature.test.js +25 -20
  131. package/test/schema-serialization.test.js +9 -9
  132. package/test/schema-special-usage.test.js +5 -153
  133. package/test/schema-validation.test.js +9 -9
  134. package/test/skip-reply-send.test.js +2 -2
  135. package/test/stream.test.js +82 -23
  136. package/test/throw.test.js +8 -5
  137. package/test/trust-proxy.test.js +6 -6
  138. package/test/type-provider.test.js +20 -0
  139. package/test/types/fastify.test-d.ts +10 -18
  140. package/test/types/import.js +2 -0
  141. package/test/types/import.ts +1 -0
  142. package/test/types/instance.test-d.ts +68 -17
  143. package/test/types/logger.test-d.ts +44 -15
  144. package/test/types/reply.test-d.ts +2 -1
  145. package/test/types/route.test-d.ts +8 -2
  146. package/test/types/schema.test-d.ts +2 -39
  147. package/test/types/type-provider.test-d.ts +417 -0
  148. package/test/url-rewriting.test.js +3 -3
  149. package/test/validation-error-handling.test.js +8 -8
  150. package/test/versioned-routes.test.js +30 -18
  151. package/test/wrapThenable.test.js +7 -6
  152. package/types/content-type-parser.d.ts +17 -8
  153. package/types/hooks.d.ts +102 -59
  154. package/types/instance.d.ts +244 -118
  155. package/types/logger.d.ts +18 -104
  156. package/types/plugin.d.ts +10 -4
  157. package/types/reply.d.ts +18 -12
  158. package/types/request.d.ts +10 -5
  159. package/types/route.d.ts +42 -31
  160. package/types/schema.d.ts +1 -1
  161. package/types/type-provider.d.ts +99 -0
  162. package/types/utils.d.ts +1 -1
  163. package/lib/schema-compilers.js +0 -12
  164. package/test/emit-warning.test.js +0 -166
package/fastify.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const VERSION = '3.27.3'
3
+ const VERSION = '4.0.0-alpha.2'
4
4
 
5
5
  const Avvio = require('avvio')
6
6
  const http = require('http')
@@ -10,6 +10,7 @@ let lightMyRequest
10
10
  const {
11
11
  kAvvioBoot,
12
12
  kChildren,
13
+ kServerBindings,
13
14
  kBodyLimit,
14
15
  kRoutePrefix,
15
16
  kLogLevel,
@@ -31,7 +32,7 @@ const {
31
32
  kFourOhFourContext
32
33
  } = require('./lib/symbols.js')
33
34
 
34
- const { createServer } = require('./lib/server')
35
+ const createServer = require('./lib/server')
35
36
  const Reply = require('./lib/reply')
36
37
  const Request = require('./lib/request')
37
38
  const supportedMethods = ['DELETE', 'GET', 'HEAD', 'PATCH', 'POST', 'PUT', 'OPTIONS']
@@ -52,9 +53,12 @@ const { defaultInitOptions } = getSecuredInitialConfig
52
53
 
53
54
  const {
54
55
  FST_ERR_BAD_URL,
55
- FST_ERR_MISSING_MIDDLEWARE
56
+ AVVIO_ERRORS_MAP,
57
+ appendStackTrace
56
58
  } = require('./lib/errors')
57
59
 
60
+ const { buildErrorHandler } = require('./lib/error-handler.js')
61
+
58
62
  const onBadUrlContext = {
59
63
  config: {
60
64
  },
@@ -76,21 +80,6 @@ function defaultBuildPrettyMeta (route) {
76
80
  return Object.assign({}, cleanKeys)
77
81
  }
78
82
 
79
- function defaultErrorHandler (error, request, reply) {
80
- if (reply.statusCode < 500) {
81
- reply.log.info(
82
- { res: reply, err: error },
83
- error && error.message
84
- )
85
- } else {
86
- reply.log.error(
87
- { req: request, res: reply, err: error },
88
- error && error.message
89
- )
90
- }
91
- reply.send(error)
92
- }
93
-
94
83
  function fastify (options) {
95
84
  // Options validations
96
85
  options = options || {}
@@ -115,7 +104,6 @@ function fastify (options) {
115
104
  const requestIdLogLabel = options.requestIdLogLabel || 'reqId'
116
105
  const bodyLimit = options.bodyLimit || defaultInitOptions.bodyLimit
117
106
  const disableRequestLogging = options.disableRequestLogging || false
118
- const exposeHeadRoutes = options.exposeHeadRoutes != null ? options.exposeHeadRoutes : false
119
107
 
120
108
  const ajvOptions = Object.assign({
121
109
  customOptions: {},
@@ -148,11 +136,13 @@ function fastify (options) {
148
136
  options.disableRequestLogging = disableRequestLogging
149
137
  options.ajv = ajvOptions
150
138
  options.clientErrorHandler = options.clientErrorHandler || defaultClientErrorHandler
151
- options.exposeHeadRoutes = exposeHeadRoutes
152
139
 
153
140
  const initialConfig = getSecuredInitialConfig(options)
154
141
  const keepAliveConnections = options.forceCloseConnections === true ? new Set() : noopSet()
155
142
 
143
+ // exposeHeadRoutes have its defult set from the validatorfrom the validatorfrom the validatorfrom the validator
144
+ options.exposeHeadRoutes = initialConfig.exposeHeadRoutes
145
+
156
146
  let constraints = options.constraints
157
147
  if (options.versioning) {
158
148
  warning.emit('FSTDEP009')
@@ -210,6 +200,7 @@ function fastify (options) {
210
200
  [kKeepAliveConnections]: keepAliveConnections,
211
201
  [kOptions]: options,
212
202
  [kChildren]: [],
203
+ [kServerBindings]: [],
213
204
  [kBodyLimit]: bodyLimit,
214
205
  [kRoutePrefix]: '',
215
206
  [kLogLevel]: '',
@@ -217,7 +208,7 @@ function fastify (options) {
217
208
  [kHooks]: new Hooks(),
218
209
  [kSchemaController]: schemaController,
219
210
  [kSchemaErrorFormatter]: null,
220
- [kErrorHandler]: defaultErrorHandler,
211
+ [kErrorHandler]: buildErrorHandler(),
221
212
  [kReplySerializerDefault]: null,
222
213
  [kContentTypeParser]: new ContentTypeParser(
223
214
  bodyLimit,
@@ -267,6 +258,8 @@ function fastify (options) {
267
258
  },
268
259
  // expose logger instance
269
260
  log: logger,
261
+ // type provider
262
+ withTypeProvider,
270
263
  // hooks
271
264
  addHook,
272
265
  // schemas
@@ -295,6 +288,12 @@ function fastify (options) {
295
288
  // http server
296
289
  listen,
297
290
  server,
291
+ addresses: function () {
292
+ /* istanbul ignore next */
293
+ const binded = this[kServerBindings].map(b => b.address())
294
+ binded.push(this.server.address())
295
+ return binded.filter(adr => adr)
296
+ },
298
297
  // extend fastify objects
299
298
  decorate: decorator.add,
300
299
  hasDecorator: decorator.exist,
@@ -313,9 +312,6 @@ function fastify (options) {
313
312
  initialConfig
314
313
  }
315
314
 
316
- fastify[kReply].prototype.server = fastify
317
- fastify[kRequest].prototype.server = fastify
318
-
319
315
  Object.defineProperties(fastify, {
320
316
  pluginName: {
321
317
  get () {
@@ -339,16 +335,11 @@ function fastify (options) {
339
335
  },
340
336
  errorHandler: {
341
337
  get () {
342
- return this[kErrorHandler]
338
+ return this[kErrorHandler].func
343
339
  }
344
340
  }
345
341
  })
346
342
 
347
- // We are adding `use` to the fastify prototype so the user
348
- // can still access it (and get the expected error), but `decorate`
349
- // will not detect it, and allow the user to override it.
350
- Object.setPrototypeOf(fastify, { use })
351
-
352
343
  if (options.schemaErrorFormatter) {
353
344
  validateSchemaErrorFormatter(options.schemaErrorFormatter)
354
345
  fastify[kSchemaErrorFormatter] = options.schemaErrorFormatter.bind(fastify)
@@ -361,9 +352,11 @@ function fastify (options) {
361
352
  // - ready
362
353
  // - onClose
363
354
  // - close
355
+
356
+ const avvioPluginTimeout = Number(options.pluginTimeout)
364
357
  const avvio = Avvio(fastify, {
365
358
  autostart: false,
366
- timeout: Number(options.pluginTimeout) || defaultInitOptions.pluginTimeout,
359
+ timeout: isNaN(avvioPluginTimeout) === false ? avvioPluginTimeout : defaultInitOptions.pluginTimeout,
367
360
  expose: {
368
361
  use: 'register'
369
362
  }
@@ -500,6 +493,13 @@ function fastify (options) {
500
493
  }
501
494
 
502
495
  function manageErr (err) {
496
+ // If the error comes out of Avvio's Error codes
497
+ // We create a make and preserve the previous error
498
+ // as cause
499
+ err = err != null && AVVIO_ERRORS_MAP[err.code] != null
500
+ ? appendStackTrace(err, new AVVIO_ERRORS_MAP[err.code](err.message))
501
+ : err
502
+
503
503
  if (cb) {
504
504
  if (err) {
505
505
  cb(err)
@@ -515,15 +515,16 @@ function fastify (options) {
515
515
  }
516
516
  }
517
517
 
518
- function use () {
519
- throw new FST_ERR_MISSING_MIDDLEWARE()
518
+ // Used exclusively in TypeScript contexts to enable auto type inference from JSON schema.
519
+ function withTypeProvider () {
520
+ return this
520
521
  }
521
522
 
522
523
  // wrapper that we expose to the user for hooks handling
523
524
  function addHook (name, fn) {
524
525
  throwIfAlreadyStarted('Cannot call "addHook" when fastify instance is already started!')
525
526
 
526
- if (name === 'onSend' || name === 'preSerialization' || name === 'onError') {
527
+ if (name === 'onSend' || name === 'preSerialization' || name === 'onError' || name === 'preParsing') {
527
528
  if (fn.constructor.name === 'AsyncFunction' && fn.length === 4) {
528
529
  throw new Error('Async function has too many arguments. Async hooks should not use the \'done\' argument.')
529
530
  }
@@ -531,7 +532,7 @@ function fastify (options) {
531
532
  if (fn.constructor.name === 'AsyncFunction' && fn.length !== 0) {
532
533
  throw new Error('Async function has too many arguments. Async hooks should not use the \'done\' argument.')
533
534
  }
534
- } else if (name !== 'preParsing') {
535
+ } else {
535
536
  if (fn.constructor.name === 'AsyncFunction' && fn.length === 3) {
536
537
  throw new Error('Async function has too many arguments. Async hooks should not use the \'done\' argument.')
537
538
  }
@@ -541,6 +542,9 @@ function fastify (options) {
541
542
  this.onClose(fn)
542
543
  } else if (name === 'onReady') {
543
544
  this[kHooks].add(name, fn)
545
+ } else if (name === 'onRoute') {
546
+ this[kHooks].validate(name, fn)
547
+ this[kHooks].add(name, fn)
544
548
  } else {
545
549
  this.after((err, done) => {
546
550
  _addHook.call(this, name, fn)
@@ -669,7 +673,7 @@ function fastify (options) {
669
673
  function setErrorHandler (func) {
670
674
  throwIfAlreadyStarted('Cannot call "setErrorHandler" when fastify instance is already started!')
671
675
 
672
- this[kErrorHandler] = func.bind(this)
676
+ this[kErrorHandler] = buildErrorHandler(this[kErrorHandler], func.bind(this))
673
677
  return this
674
678
  }
675
679