fastify 5.6.1 → 5.7.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 (97) hide show
  1. package/.claude/settings.local.json +11 -0
  2. package/README.md +34 -33
  3. package/SECURITY.md +45 -7
  4. package/SPONSORS.md +1 -1
  5. package/build/build-validation.js +2 -3
  6. package/docs/Guides/Detecting-When-Clients-Abort.md +1 -1
  7. package/docs/Guides/Ecosystem.md +17 -15
  8. package/docs/Guides/Fluent-Schema.md +2 -2
  9. package/docs/Guides/Migration-Guide-V4.md +2 -1
  10. package/docs/Guides/Migration-Guide-V5.md +9 -0
  11. package/docs/Guides/Serverless.md +25 -7
  12. package/docs/Guides/Testing.md +2 -2
  13. package/docs/Reference/Decorators.md +4 -3
  14. package/docs/Reference/Encapsulation.md +5 -1
  15. package/docs/Reference/Logging.md +4 -0
  16. package/docs/Reference/Plugins.md +13 -4
  17. package/docs/Reference/Principles.md +2 -2
  18. package/docs/Reference/Reply.md +6 -2
  19. package/docs/Reference/Server.md +67 -4
  20. package/docs/Reference/Type-Providers.md +2 -2
  21. package/docs/Reference/TypeScript.md +2 -1
  22. package/docs/Reference/Validation-and-Serialization.md +7 -1
  23. package/docs/fastify-fastify-pr-6425-run-20528050272-Lint_Docs.log +180 -0
  24. package/docs/fastify-fastify-pr-6425-run-20528054188-PR_#6425.log +4006 -0
  25. package/docs/fastify-fastify-pr-6425-run-20528054403-Pull_Request_Labeler.log +42 -0
  26. package/docs/fastify-fastify-pr-6425-run-20528054421-Lint_Docs.log +196 -0
  27. package/docs/fastify-fastify-pr-6425-run-20528054423-Internal_Links_Check.log +1864 -0
  28. package/docs/fastify-fastify-pr-6425-run-20528054430-Test_compare.log +5 -0
  29. package/docs/fastify-fastify-pr-6425-run-20528054438-pull_request_title_check.log +41 -0
  30. package/eslint.config.js +18 -2
  31. package/examples/benchmark/webstream.js +27 -0
  32. package/fastify.d.ts +17 -22
  33. package/fastify.js +192 -177
  34. package/lib/{configValidator.js → config-validator.js} +189 -223
  35. package/lib/{contentTypeParser.js → content-type-parser.js} +2 -1
  36. package/lib/error-handler.js +3 -6
  37. package/lib/error-status.js +14 -0
  38. package/lib/{fourOhFour.js → four-oh-four.js} +6 -3
  39. package/lib/{handleRequest.js → handle-request.js} +7 -2
  40. package/lib/{headRoute.js → head-route.js} +13 -1
  41. package/lib/{initialConfigValidation.js → initial-config-validation.js} +1 -1
  42. package/lib/{pluginOverride.js → plugin-override.js} +2 -2
  43. package/lib/{pluginUtils.js → plugin-utils.js} +2 -2
  44. package/lib/reply.js +58 -6
  45. package/lib/request.js +5 -0
  46. package/lib/route.js +39 -14
  47. package/lib/schema-controller.js +2 -2
  48. package/lib/server.js +38 -5
  49. package/lib/validation.js +9 -1
  50. package/lib/{wrapThenable.js → wrap-thenable.js} +3 -0
  51. package/package.json +11 -11
  52. package/test/404s.test.js +69 -0
  53. package/test/500s.test.js +191 -0
  54. package/test/child-logger-factory.test.js +3 -3
  55. package/test/content-parser.test.js +2 -1
  56. package/test/diagnostics-channel/error-before-handler.test.js +1 -1
  57. package/test/diagnostics-channel/error-status.test.js +84 -0
  58. package/test/internals/content-type-parser.test.js +2 -2
  59. package/test/internals/handle-request.test.js +2 -2
  60. package/test/internals/initial-config.test.js +1 -1
  61. package/test/internals/plugin.test.js +2 -2
  62. package/test/internals/reply.test.js +22 -3
  63. package/test/internals/req-id-gen-factory.test.js +1 -1
  64. package/test/internals/schema-controller-perf.test.js +40 -0
  65. package/test/issue-4959.test.js +34 -9
  66. package/test/listen.1.test.js +9 -1
  67. package/test/logger/logging.test.js +38 -1
  68. package/test/promises.test.js +3 -3
  69. package/test/reply-web-stream-locked.test.js +37 -0
  70. package/test/request-error.test.js +116 -0
  71. package/test/route.6.test.js +20 -1
  72. package/test/route.7.test.js +49 -0
  73. package/test/router-options.test.js +169 -0
  74. package/test/schema-validation.test.js +27 -4
  75. package/test/server.test.js +25 -4
  76. package/test/stream.5.test.js +3 -3
  77. package/test/types/fastify.test-d.ts +94 -21
  78. package/test/types/hooks.test-d.ts +6 -1
  79. package/test/types/instance.test-d.ts +64 -36
  80. package/test/types/logger.test-d.ts +18 -6
  81. package/test/types/plugin.test-d.ts +24 -6
  82. package/test/types/register.test-d.ts +108 -33
  83. package/test/types/reply.test-d.ts +78 -10
  84. package/test/types/request.test-d.ts +25 -6
  85. package/test/types/route.test-d.ts +10 -1
  86. package/test/types/type-provider.test-d.ts +6 -6
  87. package/test/validation-error-handling.test.js +68 -1
  88. package/test/web-api.test.js +136 -0
  89. package/test/wrap-thenable.test.js +1 -1
  90. package/types/instance.d.ts +3 -3
  91. package/types/reply.d.ts +2 -2
  92. package/types/type-provider.d.ts +16 -0
  93. package/.vscode/settings.json +0 -22
  94. package/test/check.test.js +0 -219
  95. package/test/decorator-namespace.test._js_ +0 -30
  96. /package/lib/{reqIdGenFactory.js → req-id-gen-factory.js} +0 -0
  97. /package/types/{serverFactory.d.ts → server-factory.d.ts} +0 -0
@@ -0,0 +1,11 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "WebFetch(domain:github.com)",
5
+ "Bash(curl -sI https://github.com/nucleode/arecibo)",
6
+ "Bash(curl:*)"
7
+ ],
8
+ "deny": [],
9
+ "ask": []
10
+ }
11
+ }
package/README.md CHANGED
@@ -260,7 +260,8 @@ application. You should __always__ benchmark if performance matters to you.
260
260
  Please visit [Fastify help](https://github.com/fastify/help) to view prior
261
261
  support issues and to ask new support questions.
262
262
 
263
- Version 3 of Fastify and lower are EOL and will not receive any security or bug fixes.
263
+ Version 3 of Fastify and lower are EOL and will not receive any security or bug
264
+ fixes.
264
265
 
265
266
  Fastify's partner, HeroDevs, provides commercial security fixes for all
266
267
  unsupported versions at [https://herodevs.com/support/fastify-nes][hd-link].
@@ -280,70 +281,70 @@ listed in alphabetical order.
280
281
 
281
282
  **Lead Maintainers:**
282
283
  * [__Matteo Collina__](https://github.com/mcollina),
283
- <https://twitter.com/matteocollina>, <https://www.npmjs.com/~matteo.collina>
284
+ <https://x.com/matteocollina>, <https://www.npmjs.com/~matteo.collina>
284
285
  * [__Tomas Della Vedova__](https://github.com/delvedor),
285
- <https://twitter.com/delvedor>, <https://www.npmjs.com/~delvedor>
286
+ <https://x.com/delvedor>, <https://www.npmjs.com/~delvedor>
286
287
  * [__KaKa Ng__](https://github.com/climba03003),
287
288
  <https://www.npmjs.com/~climba03003>
288
289
  * [__Manuel Spigolon__](https://github.com/eomm),
289
- <https://twitter.com/manueomm>, <https://www.npmjs.com/~eomm>
290
+ <https://x.com/manueomm>, <https://www.npmjs.com/~eomm>
290
291
  * [__James Sumners__](https://github.com/jsumners),
291
- <https://twitter.com/jsumners79>, <https://www.npmjs.com/~jsumners>
292
+ <https://x.com/jsumners79>, <https://www.npmjs.com/~jsumners>
292
293
 
293
294
  ### Fastify Core team
294
295
  * [__Aras Abbasi__](https://github.com/uzlopak),
295
296
  <https://www.npmjs.com/~uzlopak>
296
297
  * [__Harry Brundage__](https://github.com/airhorns/),
297
- <https://twitter.com/harrybrundage>, <https://www.npmjs.com/~airhorns>
298
+ <https://x.com/harrybrundage>, <https://www.npmjs.com/~airhorns>
298
299
  * [__Matteo Collina__](https://github.com/mcollina),
299
- <https://twitter.com/matteocollina>, <https://www.npmjs.com/~matteo.collina>
300
+ <https://x.com/matteocollina>, <https://www.npmjs.com/~matteo.collina>
300
301
  * [__Gürgün Dayıoğlu__](https://github.com/gurgunday),
301
302
  <https://www.npmjs.com/~gurgunday>
302
303
  * [__Tomas Della Vedova__](https://github.com/delvedor),
303
- <https://twitter.com/delvedor>, <https://www.npmjs.com/~delvedor>
304
+ <https://x.com/delvedor>, <https://www.npmjs.com/~delvedor>
304
305
  * [__Carlos Fuentes__](https://github.com/metcoder95),
305
- <https://twitter.com/metcoder95>, <https://www.npmjs.com/~metcoder95>
306
+ <https://x.com/metcoder95>, <https://www.npmjs.com/~metcoder95>
306
307
  * [__Vincent Le Goff__](https://github.com/zekth)
307
308
  * [__Luciano Mammino__](https://github.com/lmammino),
308
- <https://twitter.com/loige>, <https://www.npmjs.com/~lmammino>
309
+ <https://x.com/loige>, <https://www.npmjs.com/~lmammino>
309
310
  * [__Jean Michelet__](https://github.com/jean-michelet),
310
311
  <https://www.npmjs.com/~jean-michelet>
311
312
  * [__KaKa Ng__](https://github.com/climba03003),
312
313
  <https://www.npmjs.com/~climba03003>
313
314
  * [__Luis Orbaiceta__](https://github.com/luisorbaiceta),
314
- <https://twitter.com/luisorbai>, <https://www.npmjs.com/~luisorbaiceta>
315
+ <https://x.com/luisorbai>, <https://www.npmjs.com/~luisorbaiceta>
315
316
  * [__Maksim Sinik__](https://github.com/fox1t),
316
- <https://twitter.com/maksimsinik>, <https://www.npmjs.com/~fox1t>
317
+ <https://x.com/maksimsinik>, <https://www.npmjs.com/~fox1t>
317
318
  * [__Manuel Spigolon__](https://github.com/eomm),
318
- <https://twitter.com/manueomm>, <https://www.npmjs.com/~eomm>
319
+ <https://x.com/manueomm>, <https://www.npmjs.com/~eomm>
319
320
  * [__James Sumners__](https://github.com/jsumners),
320
- <https://twitter.com/jsumners79>, <https://www.npmjs.com/~jsumners>
321
+ <https://x.com/jsumners79>, <https://www.npmjs.com/~jsumners>
321
322
 
322
323
  ### Fastify Plugins team
323
324
  * [__Harry Brundage__](https://github.com/airhorns/),
324
- <https://twitter.com/harrybrundage>, <https://www.npmjs.com/~airhorns>
325
+ <https://x.com/harrybrundage>, <https://www.npmjs.com/~airhorns>
325
326
  * [__Simone Busoli__](https://github.com/simoneb),
326
- <https://twitter.com/simonebu>, <https://www.npmjs.com/~simoneb>
327
+ <https://x.com/simonebu>, <https://www.npmjs.com/~simoneb>
327
328
  * [__Dan Castillo__](https://github.com/dancastillo),
328
329
  <https://www.npmjs.com/~dancastillo>
329
330
  * [__Matteo Collina__](https://github.com/mcollina),
330
- <https://twitter.com/matteocollina>, <https://www.npmjs.com/~matteo.collina>
331
+ <https://x.com/matteocollina>, <https://www.npmjs.com/~matteo.collina>
331
332
  * [__Gürgün Dayıoğlu__](https://github.com/gurgunday),
332
333
  <https://www.npmjs.com/~gurgunday>
333
334
  * [__Tomas Della Vedova__](https://github.com/delvedor),
334
- <https://twitter.com/delvedor>, <https://www.npmjs.com/~delvedor>
335
+ <https://x.com/delvedor>, <https://www.npmjs.com/~delvedor>
335
336
  * [__Carlos Fuentes__](https://github.com/metcoder95),
336
- <https://twitter.com/metcoder95>, <https://www.npmjs.com/~metcoder95>
337
+ <https://x.com/metcoder95>, <https://www.npmjs.com/~metcoder95>
337
338
  * [__Vincent Le Goff__](https://github.com/zekth)
338
339
  * [__Jean Michelet__](https://github.com/jean-michelet),
339
340
  <https://www.npmjs.com/~jean-michelet>
340
341
  * [__KaKa Ng__](https://github.com/climba03003),
341
342
  <https://www.npmjs.com/~climba03003>
342
343
  * [__Maksim Sinik__](https://github.com/fox1t),
343
- <https://twitter.com/maksimsinik>, <https://www.npmjs.com/~fox1t>
344
+ <https://x.com/maksimsinik>, <https://www.npmjs.com/~fox1t>
344
345
  * [__Frazer Smith__](https://github.com/Fdawgs), <https://www.npmjs.com/~fdawgs>
345
346
  * [__Manuel Spigolon__](https://github.com/eomm),
346
- <https://twitter.com/manueomm>, <https://www.npmjs.com/~eomm>
347
+ <https://x.com/manueomm>, <https://www.npmjs.com/~eomm>
347
348
 
348
349
  ### Emeritus Contributors
349
350
  Great contributors to a specific area of the Fastify ecosystem will be invited
@@ -351,32 +352,32 @@ to join this group by Lead Maintainers when they decide to step down from the
351
352
  active contributor's group.
352
353
 
353
354
  * [__Tommaso Allevi__](https://github.com/allevo),
354
- <https://twitter.com/allevitommaso>, <https://www.npmjs.com/~allevo>
355
+ <https://x.com/allevitommaso>, <https://www.npmjs.com/~allevo>
355
356
  * [__Ethan Arrowood__](https://github.com/Ethan-Arrowood/),
356
- <https://twitter.com/arrowoodtech>, <https://www.npmjs.com/~ethan_arrowood>
357
+ <https://x.com/arrowoodtech>, <https://www.npmjs.com/~ethan_arrowood>
357
358
  * [__Çağatay Çalı__](https://github.com/cagataycali),
358
- <https://twitter.com/cagataycali>, <https://www.npmjs.com/~cagataycali>
359
+ <https://x.com/cagataycali>, <https://www.npmjs.com/~cagataycali>
359
360
  * [__David Mark Clements__](https://github.com/davidmarkclements),
360
- <https://twitter.com/davidmarkclem>,
361
+ <https://x.com/davidmarkclem>,
361
362
  <https://www.npmjs.com/~davidmarkclements>
362
- * [__dalisoft__](https://github.com/dalisoft), <https://twitter.com/dalisoft>,
363
+ * [__dalisoft__](https://github.com/dalisoft), <https://x.com/dalisoft>,
363
364
  <https://www.npmjs.com/~dalisoft>
364
365
  * [__Dustin Deus__](https://github.com/StarpTech),
365
- <https://twitter.com/dustindeus>, <https://www.npmjs.com/~starptech>
366
+ <https://x.com/dustindeus>, <https://www.npmjs.com/~starptech>
366
367
  * [__Denis Fäcke__](https://github.com/SerayaEryn),
367
- <https://twitter.com/serayaeryn>, <https://www.npmjs.com/~serayaeryn>
368
+ <https://x.com/serayaeryn>, <https://www.npmjs.com/~serayaeryn>
368
369
  * [__Rafael Gonzaga__](https://github.com/rafaelgss),
369
- <https://twitter.com/_rafaelgss>, <https://www.npmjs.com/~rafaelgss>
370
+ <https://x.com/_rafaelgss>, <https://www.npmjs.com/~rafaelgss>
370
371
  * [__Trivikram Kamat__](https://github.com/trivikr),
371
- <https://twitter.com/trivikram>, <https://www.npmjs.com/~trivikr>
372
+ <https://x.com/trivikram>, <https://www.npmjs.com/~trivikr>
372
373
  * [__Ayoub El Khattabi__](https://github.com/AyoubElk),
373
- <https://twitter.com/ayoubelkh>, <https://www.npmjs.com/~ayoubelk>
374
+ <https://x.com/ayoubelkh>, <https://www.npmjs.com/~ayoubelk>
374
375
  * [__Cemre Mengu__](https://github.com/cemremengu),
375
- <https://twitter.com/cemremengu>, <https://www.npmjs.com/~cemremengu>
376
+ <https://x.com/cemremengu>, <https://www.npmjs.com/~cemremengu>
376
377
  * [__Salman Mitha__](https://github.com/salmanm),
377
378
  <https://www.npmjs.com/~salmanm>
378
379
  * [__Nathan Woltman__](https://github.com/nwoltman),
379
- <https://twitter.com/NathanWoltman>, <https://www.npmjs.com/~nwoltman>
380
+ <https://x.com/NathanWoltman>, <https://www.npmjs.com/~nwoltman>
380
381
 
381
382
  ## Hosted by
382
383
 
package/SECURITY.md CHANGED
@@ -3,6 +3,46 @@
3
3
  This document describes the management of vulnerabilities for the Fastify
4
4
  project and its official plugins.
5
5
 
6
+ ## Threat Model
7
+
8
+ Fastify's threat model extends the
9
+ [Node.js threat model](https://github.com/nodejs/node/blob/main/SECURITY.md#the-nodejs-threat-model).
10
+
11
+ **Trusted:** Application code (plugins, handlers, hooks, schemas), configuration,
12
+ and the runtime environment.
13
+
14
+ **Untrusted:** All network input (HTTP headers, body, query strings, URL
15
+ parameters).
16
+
17
+ ### Examples of Vulnerabilities
18
+
19
+ - Parsing flaws that bypass validation or security controls
20
+ - DoS through malformed input to Fastify's core
21
+ - Bypasses of built-in protections (prototype poisoning, schema validation)
22
+
23
+ ### Examples of Non-Vulnerabilities
24
+
25
+ The following are **not** considered vulnerabilities in Fastify:
26
+
27
+ - **Application code vulnerabilities**: XSS, SQL injection, or other flaws in
28
+ user-written route handlers, hooks, or plugins
29
+ - **Malicious application code**: Issues caused by intentionally malicious
30
+ plugins or handlers (application code is trusted)
31
+ - **Validation schema issues**: Weak or incorrect schemas provided by developers
32
+ (schemas are trusted)
33
+ - **ReDoS in user patterns**: Regular expression DoS in user-provided regex
34
+ patterns for routes or validation
35
+ - **Missing security features**: Lack of rate limiting, authentication, or
36
+ authorization (these are application-level concerns)
37
+ - **Configuration mistakes**: Security issues arising from developer
38
+ misconfiguration (configuration is trusted)
39
+ - **Third-party dependencies**: Vulnerabilities in npm packages used by the
40
+ application (not Fastify core dependencies)
41
+ - **Resource exhaustion from handlers**: DoS caused by expensive operations in
42
+ user route handlers
43
+ - **Information disclosure by design**: Exposing error details or stack traces
44
+ explicitly enabled via configuration options
45
+
6
46
  ## Reporting vulnerabilities
7
47
 
8
48
  Individuals who find potential vulnerabilities in Fastify are invited to
@@ -137,13 +177,13 @@ work as a member of the Fastify Core team.
137
177
  ### Members
138
178
 
139
179
  * [__Matteo Collina__](https://github.com/mcollina),
140
- <https://twitter.com/matteocollina>, <https://www.npmjs.com/~matteo.collina>
180
+ <https://x.com/matteocollina>, <https://www.npmjs.com/~matteo.collina>
141
181
  * [__Tomas Della Vedova__](https://github.com/delvedor),
142
- <https://twitter.com/delvedor>, <https://www.npmjs.com/~delvedor>
182
+ <https://x.com/delvedor>, <https://www.npmjs.com/~delvedor>
143
183
  * [__Vincent Le Goff__](https://github.com/zekth)
144
184
  * [__KaKa Ng__](https://github.com/climba03003)
145
185
  * [__James Sumners__](https://github.com/jsumners),
146
- <https://twitter.com/jsumners79>, <https://www.npmjs.com/~jsumners>
186
+ <https://x.com/jsumners79>, <https://www.npmjs.com/~jsumners>
147
187
 
148
188
  ## OpenSSF CII Best Practices
149
189
 
@@ -155,11 +195,9 @@ There are three “tiers”: passing, silver, and gold.
155
195
  We meet 100% of the “passing” criteria.
156
196
 
157
197
  ### Silver
158
- We meet 87% of the silver criteria. The gaps are as follows:
198
+ We meet 87% of the "silver" criteria. The gaps are as follows:
159
199
  - we do not have a DCO or a CLA process for contributions.
160
- - we do not currently document
161
- “what the user can and cannot expect in terms of security” for our project.
162
- - we do not currently document ”the architecture (aka high-level design)”
200
+ - we do not currently document "the architecture (aka high-level design)"
163
201
  for our project.
164
202
 
165
203
  ### Gold
package/SPONSORS.md CHANGED
@@ -9,7 +9,7 @@ or [GitHub Sponsors](https://github.com/sponsors/fastify)!
9
9
 
10
10
  ## Tier 4
11
11
 
12
- _Be the first!_
12
+ - [SerpApi](http://serpapi.com/)
13
13
 
14
14
  ## Tier 3
15
15
 
@@ -16,7 +16,7 @@ module.exports.defaultInitOptions = ${JSON.stringify(defaultInitOptions)}
16
16
  /* c8 ignore stop */
17
17
  `
18
18
 
19
- const file = path.join(__dirname, '..', 'lib', 'configValidator.js')
19
+ const file = path.join(__dirname, '..', 'lib', 'config-validator.js')
20
20
  fs.writeFileSync(file, moduleCode)
21
21
  console.log(`Saved ${file} file successfully`)
22
22
  }
@@ -98,7 +98,6 @@ const schema = {
98
98
  ignoreTrailingSlash: { type: 'boolean', default: defaultInitOptions.ignoreTrailingSlash },
99
99
  ignoreDuplicateSlashes: { type: 'boolean', default: defaultInitOptions.ignoreDuplicateSlashes },
100
100
  disableRequestLogging: {
101
- type: 'boolean',
102
101
  default: false
103
102
  },
104
103
  maxParamLength: { type: 'integer', default: defaultInitOptions.maxParamLength },
@@ -112,7 +111,7 @@ const schema = {
112
111
  useSemicolonDelimiter: { type: 'boolean', default: defaultInitOptions.useSemicolonDelimiter },
113
112
  routerOptions: {
114
113
  type: 'object',
115
- additionalProperties: false,
114
+ additionalProperties: true,
116
115
  properties: {
117
116
  ignoreTrailingSlash: { type: 'boolean', default: defaultInitOptions.routerOptions.ignoreTrailingSlash },
118
117
  ignoreDuplicateSlashes: { type: 'boolean', default: defaultInitOptions.routerOptions.ignoreDuplicateSlashes },
@@ -81,7 +81,7 @@ start()
81
81
  Our code is setting up a Fastify server which includes the following
82
82
  functionality:
83
83
 
84
- - Accepting requests at http://localhost:3000, with a 3 second delayed response
84
+ - Accepting requests at `http://localhost:3000`, with a 3 second delayed response
85
85
  of `{ ok: true }`.
86
86
  - An onRequest hook that triggers when every request is received.
87
87
  - Logic that triggers in the hook when the request is closed.
@@ -119,6 +119,8 @@ section.
119
119
  HTTP errors and assertions, but also more request and reply methods.
120
120
  - [`@fastify/session`](https://github.com/fastify/session) a session plugin for
121
121
  Fastify.
122
+ - [`@fastify/sse`](https://github.com/fastify/sse) Plugin for Server-Sent Events
123
+ (SSE) support in Fastify.
122
124
  - [`@fastify/static`](https://github.com/fastify/fastify-static) Plugin for
123
125
  serving static files as fast as possible.
124
126
  - [`@fastify/swagger`](https://github.com/fastify/fastify-swagger) Plugin for
@@ -165,6 +167,9 @@ section.
165
167
  A simple way to add a crud in your fastify project.
166
168
  - [`@applicazza/fastify-nextjs`](https://github.com/applicazza/fastify-nextjs)
167
169
  Alternate Fastify and Next.js integration.
170
+ - [`@attaryz/fastify-devtools`](https://github.com/attaryz/fastify-devtools)
171
+ Development tools plugin for Fastify with live request dashboard, replay
172
+ capabilities, and metrics tracking.
168
173
  - [`@blastorg/fastify-aws-dynamodb-cache`](https://github.com/blastorg/fastify-aws-dynamodb-cache)
169
174
  A plugin to help with caching API responses using AWS DynamoDB.
170
175
  - [`@clerk/fastify`](https://github.com/clerkinc/javascript/tree/main/packages/fastify)
@@ -177,13 +182,8 @@ section.
177
182
  close the server gracefully on `SIGINT` and `SIGTERM` signals.
178
183
  - [`@eropple/fastify-openapi3`](https://github.com/eropple/fastify-openapi3) Provides
179
184
  easy, developer-friendly OpenAPI 3.1 specs + doc explorer based on your routes.
180
- - [`@ethicdevs/fastify-custom-session`](https://github.com/EthicDevs/fastify-custom-session)
181
- A plugin lets you use session and decide only where to load/save from/to. Has
182
- great TypeScript support + built-in adapters for common ORMs/databases (Firebase,
183
- Prisma Client, Postgres (wip), InMemory) and you can easily make your own adapter!
184
- - [`@ethicdevs/fastify-git-server`](https://github.com/EthicDevs/fastify-git-server)
185
- A plugin to easily create git server and make one/many Git repositories available
186
- for clone/fetch/push through the standard `git` (over http) commands.
185
+
186
+
187
187
  - [`@exortek/fastify-mongo-sanitize`](https://github.com/ExorTek/fastify-mongo-sanitize)
188
188
  A Fastify plugin that protects against No(n)SQL injection by sanitizing data.
189
189
  - [`@exortek/remix-fastify`](https://github.com/ExorTek/remix-fastify)
@@ -241,6 +241,9 @@ section.
241
241
  request IDs into your logs.
242
242
  - [`electron-server`](https://github.com/anonrig/electron-server) A plugin for
243
243
  using Fastify without the need of consuming a port on Electron apps.
244
+ - [`elements-fastify`](https://github.com/rohitsoni007/elements-fastify) Fastify
245
+ Plugin for Stoplight Elements API Documentation using
246
+ openapi swagger json yml.
244
247
  - [`fast-water`](https://github.com/tswayne/fast-water) A Fastify plugin for
245
248
  waterline. Decorates Fastify with waterline models.
246
249
  - [`fastify-204`](https://github.com/Shiva127/fastify-204) Fastify plugin that
@@ -368,7 +371,7 @@ section.
368
371
  - [`fastify-feature-flags`](https://gitlab.com/m03geek/fastify-feature-flags)
369
372
  Fastify feature flags plugin with multiple providers support (e.g. env,
370
373
  [config](https://lorenwest.github.io/node-config/),
371
- [unleash](https://unleash.github.io/)).
374
+ [unleash](https://github.com/Unleash/unleash)).
372
375
  - [`fastify-file-routes`](https://github.com/spa5k/fastify-file-routes) Get
373
376
  Next.js based file system routing into fastify.
374
377
  - [`fastify-file-upload`](https://github.com/huangang/fastify-file-upload)
@@ -519,10 +522,7 @@ middlewares into Fastify plugins
519
522
  Add `additionalProperties: false` by default to your JSON Schemas.
520
523
  - [`fastify-no-icon`](https://github.com/jsumners/fastify-no-icon) Plugin to
521
524
  eliminate thrown errors for `/favicon.ico` requests.
522
- - [`fastify-normalize-request-reply`](https://github.com/ericrglass/fastify-normalize-request-reply)
523
- Plugin to normalize the request and reply to the Express version 4.x request
524
- and response, which allows use of middleware, like swagger-stats, that was
525
- originally written for Express.
525
+
526
526
  - [`fastify-now`](https://github.com/yonathan06/fastify-now) Structure your
527
527
  endpoints in a folder and load them dynamically with Fastify.
528
528
  - [`fastify-nuxtjs`](https://github.com/gomah/fastify-nuxtjs) Vue server-side
@@ -566,8 +566,8 @@ middlewares into Fastify plugins
566
566
  custom permission checks.
567
567
  - [`fastify-piscina`](https://github.com/piscinajs/fastify-piscina) A worker
568
568
  thread pool plugin using [Piscina](https://github.com/piscinajs/piscina).
569
- - [`fastify-polyglot`](https://github.com/beliven-it/fastify-polyglot) A plugin to
570
- handle i18n using
569
+ - [`fastify-polyglot`](https://github.com/beliven-it/fastify-polyglot) A plugin
570
+ to handle i18n using
571
571
  [node-polyglot](https://www.npmjs.com/package/node-polyglot).
572
572
  - [`fastify-postgraphile`](https://github.com/alemagio/fastify-postgraphile)
573
573
  Plugin to integrate [PostGraphile](https://www.graphile.org/postgraphile/) in
@@ -641,6 +641,8 @@ middlewares into Fastify plugins
641
641
  - [`fastify-server-session`](https://github.com/jsumners/fastify-server-session)
642
642
  A session plugin with support for arbitrary backing caches via
643
643
  `fastify-caching`.
644
+ - [`fastify-ses-mailer`](https://github.com/KaranHotwani/fastify-ses-mailer) A
645
+ Fastify plugin for sending emails via AWS SES using AWS SDK v3.
644
646
  - [`fastify-shared-schema`](https://github.com/Adibla/fastify-shared-schema) Plugin
645
647
  for sharing schemas between different routes.
646
648
  - [`fastify-slonik`](https://github.com/Unbuttun/fastify-slonik) Fastify Slonik
@@ -682,7 +684,7 @@ middlewares into Fastify plugins
682
684
  - [`fastify-type-provider-effect-schema`](https://github.com/daotl/fastify-type-provider-effect-schema)
683
685
  Fastify
684
686
  [type provider](https://fastify.dev/docs/latest/Reference/Type-Providers/)
685
- for [@effect/schema](https://github.com/effect-ts/schema).
687
+ for [@effect/schema](https://github.com/Effect-TS/effect).
686
688
  - [`fastify-type-provider-zod`](https://github.com/turkerdev/fastify-type-provider-zod)
687
689
  Fastify
688
690
  [type provider](https://fastify.dev/docs/latest/Reference/Type-Providers/)
@@ -122,5 +122,5 @@ const schema = { body: bodyJsonSchema }
122
122
  fastify.post('/the/url', { schema }, handler)
123
123
  ```
124
124
 
125
- NB You can mix up the `$ref-way` and the `replace-way` when using
126
- `fastify.addSchema`.
125
+ > ℹ️ Note: You can mix up the `$ref-way` and the `replace-way`
126
+ > when using `fastify.addSchema`.
@@ -109,7 +109,8 @@ argument from your router handler.
109
109
  ### `exposeHeadRoutes` true by default
110
110
 
111
111
  Starting with v4, every `GET` route will create a sibling `HEAD` route.
112
- You can revert this behavior by setting `exposeHeadRoutes: false` in the server options.
112
+ You can revert this behavior by setting `exposeHeadRoutes: false` in the server
113
+ options.
113
114
 
114
115
  ### Synchronous route definitions ([#2954](https://github.com/fastify/fastify/pull/2954))
115
116
 
@@ -545,6 +545,15 @@ for more information.
545
545
  This was already deprecated in v4 as `FSTDEP014`,
546
546
  so you should have already updated your code.
547
547
 
548
+ ### `time` and `date-time` formats enforce timezone
549
+
550
+ The updated AJV compiler updates `ajv-formats` which now
551
+ enforce the use of timezone in `time` and `date-time` format.
552
+ A workaround is to use `iso-time` and `iso-date-time` formats
553
+ which support an optional timezone for backwards compatibility.
554
+ See the
555
+ [full discussion](https://github.com/fastify/fluent-json-schema/issues/267).
556
+
548
557
  ## New Features
549
558
 
550
559
  ### Diagnostic Channel support
@@ -303,10 +303,10 @@ const fastifyApp = async (request, reply) => {
303
303
 
304
304
  ### Add Custom `contentTypeParser` to Fastify instance and define endpoints
305
305
 
306
- Firebase Function's HTTP layer already parses the request
307
- and makes a JSON payload available. It also provides access
308
- to the raw body, unparsed, which is useful for calculating
309
- request signatures to validate HTTP webhooks.
306
+ Firebase Function's HTTP layer already parses the request and makes a JSON
307
+ payload available through the property `payload.body` below. It also provides
308
+ access to the raw body, unparsed, which is useful for calculating request
309
+ signatures to validate HTTP webhooks.
310
310
 
311
311
  Add as follows to the `registerRoutes()` function:
312
312
 
@@ -332,6 +332,24 @@ async function registerRoutes (fastify) {
332
332
  }
333
333
  ```
334
334
 
335
+ **Failing to add this `ContentTypeParser` may lead to the Fastify process
336
+ remaining stuck and not processing any other requests after receiving one with
337
+ the Content-Type `application/json`.**
338
+
339
+ When using Typescript, since the type of `payload` is a native `IncomingMessage`
340
+ that gets modified by Firebase, it won't be able to find the property
341
+ `payload.body`.
342
+
343
+ In order to suppress the error, you can use the following signature:
344
+
345
+ ```ts
346
+ declare module 'http' {
347
+ interface IncomingMessage {
348
+ body?: unknown;
349
+ }
350
+ }
351
+ ```
352
+
335
353
  ### Export the function using Firebase onRequest
336
354
 
337
355
  Final step is to export the Fastify app instance to Firebase's own
@@ -577,10 +595,10 @@ server-like concurrency with the autoscaling properties of traditional
577
595
  serverless functions.
578
596
 
579
597
  Get started with the
580
- [Fastify Node.js template on Vercel](
581
- https://vercel.com/templates/other/fastify-serverless-function).
598
+ [Fastify template on Vercel](
599
+ https://vercel.com/templates/backend/fastify-on-vercel).
582
600
 
583
601
  [Fluid compute](https://vercel.com/docs/functions/fluid-compute) currently
584
602
  requires an explicit opt-in. Learn more about enabling Fluid compute
585
603
  [here](
586
- https://vercel.com/docs/functions/fluid-compute#how-to-enable-fluid-compute).
604
+ https://vercel.com/docs/functions/fluid-compute#how-to-enable-fluid-compute).
@@ -353,8 +353,8 @@ Now you should be able to step through your test file (and the rest of
353
353
 
354
354
 
355
355
  ## Plugins
356
- Let's `cd` into a fresh directory called 'testing-plugin-example' and type `npm init
357
- -y` in our terminal.
356
+ Let's `cd` into a fresh directory called 'testing-plugin-example' and type
357
+ `npm init -y` in our terminal.
358
358
 
359
359
  Run `npm i fastify fastify-plugin`
360
360
 
@@ -369,7 +369,8 @@ console.log(fastify.foo) // 'a getter'
369
369
  #### `getDecorator(name)`
370
370
  <a id="get-decorator"></a>
371
371
 
372
- Used to retrieve an existing decorator from the Fastify instance, `Request`, or `Reply`.
372
+ Used to retrieve an existing decorator from the Fastify instance, `Request`,
373
+ or `Reply`.
373
374
  If the decorator is not defined, an `FST_ERR_DEC_UNDECLARED` error is thrown.
374
375
 
375
376
  ```js
@@ -399,7 +400,7 @@ fastify.register(async function (fastify) {
399
400
  ```
400
401
 
401
402
  > ℹ️ Note: For TypeScript users, `getDecorator` supports generic type parameters.
402
- > See the [TypeScript documentation](/docs/latest/Reference/TypeScript/) for
403
+ > See the [TypeScript documentation](/docs/Reference/TypeScript.md) for
403
404
  > advanced typing examples.
404
405
 
405
406
  #### `setDecorator(name, value)`
@@ -429,5 +430,5 @@ fastify.addHook('preHandler', async (req, reply) => {
429
430
  ```
430
431
 
431
432
  > ℹ️ Note: For TypeScript users, see the
432
- > [TypeScript documentation](/docs/latest/Reference/TypeScript/) for advanced
433
+ > [TypeScript documentation](/docs/Reference/TypeScript.md) for advanced
433
434
  > typing examples using `setDecorator<T>`.
@@ -27,7 +27,11 @@ registered within its _grandchild context_.
27
27
 
28
28
  Given that everything in Fastify is a [plugin](./Plugins.md) except for the
29
29
  _root context_, every "context" and "plugin" in this example is a plugin
30
- that can consist of decorators, hooks, plugins, and routes. To put this
30
+ that can consist of decorators, hooks, plugins, and routes. As plugins, they
31
+ must still signal completion either by returning a Promise (e.g., using `async`
32
+ functions) or by calling the `done` function if using the callback style.
33
+
34
+ To put this
31
35
  example into concrete terms, consider a basic scenario of a REST API server
32
36
  with three routes: the first route (`/one`) requires authentication, the
33
37
  second route (`/two`) does not, and the third route (`/three`) has access to
@@ -107,6 +107,10 @@ value is used; otherwise, a new incremental ID is generated. See Fastify Factory
107
107
  [`requestIdHeader`](./Server.md#factory-request-id-header) and Fastify Factory
108
108
  [`genReqId`](./Server.md#genreqid) for customization options.
109
109
 
110
+ > ⚠ Warning: enabling `requestIdHeader` allows any callers to set `reqId` to a
111
+ > value of their choosing.
112
+ > No validation is performed on `requestIdHeader`.
113
+
110
114
  #### Serializers
111
115
  The default logger uses standard serializers for objects with `req`, `res`, and
112
116
  `err` properties. The `req` object is the Fastify [`Request`](./Request.md)
@@ -79,8 +79,8 @@ the Fastify instance by a preceding plugin, such as utilizing an existing databa
79
79
  connection.
80
80
 
81
81
  Keep in mind that the Fastify instance passed to the function is the same as the
82
- one passed into the plugin, a copy of the external Fastify instance rather than a
83
- reference. Any usage of the instance will behave the same as it would if called
82
+ one passed into the plugin, a copy of the external Fastify instance rather than
83
+ a reference. Any usage of the instance will behave the same as it would if called
84
84
  within the plugin's function. For example, if `decorate` is called, the decorated
85
85
  variables will be available within the plugin's function unless it was wrapped
86
86
  with [`fastify-plugin`](https://github.com/fastify/fastify-plugin).
@@ -171,18 +171,27 @@ export default plugin
171
171
  <a id="create-plugin"></a>
172
172
 
173
173
  Creating a plugin is easy. Create a function that takes three parameters: the
174
- `fastify` instance, an `options` object, and the `done` callback.
174
+ `fastify` instance, an `options` object, and the `done` callback. Alternatively,
175
+ use an `async` function and omit the `done` callback.
175
176
 
176
177
  Example:
177
178
  ```js
178
- module.exports = function (fastify, opts, done) {
179
+ module.exports = function callbackPlugin (fastify, opts, done) {
179
180
  fastify.decorate('utility', function () {})
180
181
 
181
182
  fastify.get('/', handler)
182
183
 
183
184
  done()
184
185
  }
186
+
187
+ // Or using async
188
+ module.exports = async function asyncPlugin (fastify, opts) {
189
+ fastify.decorate('utility', function () {})
190
+
191
+ fastify.get('/', handler)
192
+ }
185
193
  ```
194
+
186
195
  `register` can also be used inside another `register`:
187
196
  ```js
188
197
  module.exports = function (fastify, opts, done) {
@@ -64,8 +64,8 @@ frameworks do this; Fastify does not.
64
64
 
65
65
  ## Semantic Versioning and Long Term Support
66
66
 
67
- A clear [Long Term Support strategy is provided](./LTS.md) to inform developers when
68
- to upgrade.
67
+ A clear [Long Term Support strategy is provided](./LTS.md) to inform developers
68
+ when to upgrade.
69
69
 
70
70
  ## Specification adherence
71
71
 
@@ -70,8 +70,9 @@ since the request was received by Fastify.
70
70
  - `.serialize(payload)` - Serializes the specified payload using the default
71
71
  JSON serializer or using the custom serializer (if one is set) and returns the
72
72
  serialized payload.
73
- - `.getSerializationFunction(schema | httpStatus, [contentType])` - Returns the serialization
74
- function for the specified schema or http status, if any of either are set.
73
+ - `.getSerializationFunction(schema | httpStatus, [contentType])` - Returns the
74
+ serialization function for the specified schema or http status, if any of
75
+ either are set.
75
76
  - `.compileSerializationSchema(schema, [httpStatus], [contentType])` - Compiles
76
77
  the specified schema and returns a serialization function using the default
77
78
  (or customized) `SerializerCompiler`. The optional `httpStatus` is forwarded
@@ -688,6 +689,9 @@ If you are sending a stream and you have not set a `'Content-Type'` header,
688
689
  As noted above, streams are considered to be pre-serialized, so they will be
689
690
  sent unmodified without response validation.
690
691
 
692
+ See special note about error handling for streams in
693
+ [`setErrorHandler`](./Server.md#seterrorhandler).
694
+
691
695
  ```js
692
696
  const fs = require('node:fs')
693
697