fastify 5.6.1 → 5.6.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 (61) hide show
  1. package/build/build-validation.js +1 -1
  2. package/build/sync-version.js +1 -0
  3. package/docs/Guides/Ecosystem.md +5 -0
  4. package/docs/Guides/Fluent-Schema.md +2 -2
  5. package/docs/Reference/Encapsulation.md +5 -1
  6. package/docs/Reference/Plugins.md +11 -2
  7. package/docs/Reference/Reply.md +3 -0
  8. package/docs/Reference/Server.md +32 -0
  9. package/docs/Reference/Type-Providers.md +2 -2
  10. package/eslint.config.js +18 -2
  11. package/fastify.d.ts +1 -1
  12. package/fastify.js +179 -169
  13. package/lib/{contentTypeParser.js → content-type-parser.js} +2 -1
  14. package/lib/error-handler.js +2 -2
  15. package/lib/{fourOhFour.js → four-oh-four.js} +4 -2
  16. package/lib/{handleRequest.js → handle-request.js} +1 -1
  17. package/lib/{headRoute.js → head-route.js} +13 -1
  18. package/lib/{initialConfigValidation.js → initial-config-validation.js} +1 -1
  19. package/lib/{pluginOverride.js → plugin-override.js} +2 -2
  20. package/lib/{pluginUtils.js → plugin-utils.js} +2 -2
  21. package/lib/reply.js +5 -3
  22. package/lib/request.js +5 -0
  23. package/lib/route.js +20 -9
  24. package/lib/server.js +38 -5
  25. package/lib/validation.js +9 -1
  26. package/package.json +8 -8
  27. package/test/500s.test.js +191 -0
  28. package/test/child-logger-factory.test.js +3 -3
  29. package/test/content-parser.test.js +2 -1
  30. package/test/diagnostics-channel/error-before-handler.test.js +1 -1
  31. package/test/internals/content-type-parser.test.js +2 -2
  32. package/test/internals/handle-request.test.js +2 -2
  33. package/test/internals/initial-config.test.js +1 -1
  34. package/test/internals/plugin.test.js +2 -2
  35. package/test/internals/reply.test.js +22 -3
  36. package/test/internals/req-id-gen-factory.test.js +1 -1
  37. package/test/promises.test.js +3 -3
  38. package/test/reply-web-stream-locked.test.js +37 -0
  39. package/test/request-error.test.js +116 -0
  40. package/test/route.6.test.js +20 -1
  41. package/test/route.7.test.js +49 -0
  42. package/test/schema-validation.test.js +27 -4
  43. package/test/server.test.js +22 -4
  44. package/test/stream.5.test.js +3 -3
  45. package/test/types/fastify.test-d.ts +70 -18
  46. package/test/types/hooks.test-d.ts +6 -1
  47. package/test/types/instance.test-d.ts +35 -15
  48. package/test/types/logger.test-d.ts +18 -6
  49. package/test/types/plugin.test-d.ts +24 -6
  50. package/test/types/register.test-d.ts +108 -33
  51. package/test/types/reply.test-d.ts +23 -6
  52. package/test/types/request.test-d.ts +25 -6
  53. package/test/types/route.test-d.ts +10 -1
  54. package/test/validation-error-handling.test.js +68 -1
  55. package/test/wrap-thenable.test.js +1 -1
  56. package/types/instance.d.ts +2 -2
  57. package/test/check.test.js +0 -219
  58. /package/lib/{configValidator.js → config-validator.js} +0 -0
  59. /package/lib/{reqIdGenFactory.js → req-id-gen-factory.js} +0 -0
  60. /package/lib/{wrapThenable.js → wrap-thenable.js} +0 -0
  61. /package/types/{serverFactory.d.ts → server-factory.d.ts} +0 -0
@@ -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
  }
@@ -9,3 +9,4 @@ const { version } = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'packa
9
9
  const fastifyJs = path.join(__dirname, '..', 'fastify.js')
10
10
 
11
11
  fs.writeFileSync(fastifyJs, fs.readFileSync(fastifyJs).toString('utf8').replace(/const\s*VERSION\s*=.*/, `const VERSION = '${version}'`))
12
+ console.log(`Synchronized fastify.js VERSION to ${version}`)
@@ -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)
@@ -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`.
@@ -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` functions)
32
+ 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
@@ -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) {
@@ -688,6 +688,9 @@ If you are sending a stream and you have not set a `'Content-Type'` header,
688
688
  As noted above, streams are considered to be pre-serialized, so they will be
689
689
  sent unmodified without response validation.
690
690
 
691
+ See special note about error handling for streams in
692
+ [`setErrorHandler`](./Server.md#seterrorhandler).
693
+
691
694
  ```js
692
695
  const fs = require('node:fs')
693
696
 
@@ -1442,6 +1442,8 @@ fastify.mkcol('/', (req, reply) => {
1442
1442
  })
1443
1443
  ```
1444
1444
 
1445
+ > ⚠ Warning:
1446
+ > `addHttpMethod` overrides existing methods.
1445
1447
 
1446
1448
  #### addSchema
1447
1449
  <a id="add-schema"></a>
@@ -1693,6 +1695,9 @@ set it to 500 before calling the error handler.
1693
1695
  sent to the client. Use the `onSend` hook instead.
1694
1696
  - not found (404) errors. Use [`setNotFoundHandler`](#set-not-found-handler)
1695
1697
  instead.
1698
+ - Stream errors thrown during piping into the response socket, as
1699
+ headers/response were already sent to the client.
1700
+ Use custom in-stream data to signal such errors.
1696
1701
 
1697
1702
  ```js
1698
1703
  fastify.setErrorHandler(function (error, request, reply) {
@@ -1722,6 +1727,33 @@ if (statusCode >= 500) {
1722
1727
  > Avoid calling setErrorHandler multiple times in the same scope.
1723
1728
  > See [`allowErrorHandlerOverride`](#allowerrorhandleroverride).
1724
1729
 
1730
+ ##### Custom error handler for stream replies
1731
+ <a id="set-error-handler-stream-replies"></a>
1732
+
1733
+ If `Content-Type` differs between the endpoint and error handler, explicitly
1734
+ define it in both. For example, if the endpoint returns an `application/text`
1735
+ stream and the error handler responds with `application/json`, the error handler
1736
+ must explicitly set `Content-Type`. Otherwise, it will fail serialization with
1737
+ a `500` status code. Alternatively, always respond with serialized data in the
1738
+ error handler by manually calling a serialization method (e.g.,
1739
+ `JSON.stringify`).
1740
+
1741
+ ```js
1742
+ fastify.setErrorHandler((err, req, reply) => {
1743
+ reply
1744
+ .code(400)
1745
+ .type('application/json')
1746
+ .send({ error: err.message })
1747
+ })
1748
+ ```
1749
+
1750
+ ```js
1751
+ fastify.setErrorHandler((err, req, reply) => {
1752
+ reply
1753
+ .code(400)
1754
+ .send(JSON.stringify({ error: err.message }))
1755
+ })
1756
+ ```
1725
1757
 
1726
1758
  #### setChildLoggerFactory
1727
1759
  <a id="set-child-logger-factory"></a>
@@ -88,8 +88,8 @@ server.get('/route', {
88
88
  ```
89
89
 
90
90
  See the [TypeBox
91
- documentation](https://github.com/sinclairzx81/typebox#validation)
92
- for setting up AJV to work with TypeBox.
91
+ documentation](https://sinclairzx81.github.io/typebox/#/docs/overview/2_setup)
92
+ for setting-up AJV to work with TypeBox.
93
93
 
94
94
  ### Zod
95
95
 
package/eslint.config.js CHANGED
@@ -4,7 +4,7 @@ const neostandard = require('neostandard')
4
4
  module.exports = [
5
5
  ...neostandard({
6
6
  ignores: [
7
- 'lib/configValidator.js',
7
+ 'lib/config-validator.js',
8
8
  'lib/error-serializer.js',
9
9
  'test/same-shape.test.js',
10
10
  'test/types/import.js'
@@ -13,7 +13,23 @@ module.exports = [
13
13
  }),
14
14
  {
15
15
  rules: {
16
- 'comma-dangle': ['error', 'never']
16
+ 'comma-dangle': ['error', 'never'],
17
+ 'max-len': ['error', {
18
+ code: 120,
19
+ tabWidth: 2,
20
+ ignoreUrls: true,
21
+ ignoreStrings: true,
22
+ ignoreTemplateLiterals: true,
23
+ ignoreRegExpLiterals: true,
24
+ ignoreComments: true,
25
+ ignoreTrailingComments: true
26
+ }]
27
+ }
28
+ },
29
+ {
30
+ files: ['**/*.d.ts'],
31
+ rules: {
32
+ 'max-len': 'off'
17
33
  }
18
34
  }
19
35
  ]
package/fastify.d.ts CHANGED
@@ -29,7 +29,7 @@ import { FastifyReply } from './types/reply'
29
29
  import { FastifyRequest, RequestGenericInterface } from './types/request'
30
30
  import { RouteGenericInterface, RouteHandler, RouteHandlerMethod, RouteOptions, RouteShorthandMethod, RouteShorthandOptions, RouteShorthandOptionsWithHandler } from './types/route'
31
31
  import { FastifySchema, FastifySchemaValidationError, FastifySchemaCompiler, FastifySerializerCompiler, SchemaErrorDataVar, SchemaErrorFormatter } from './types/schema'
32
- import { FastifyServerFactory, FastifyServerFactoryHandler } from './types/serverFactory'
32
+ import { FastifyServerFactory, FastifyServerFactoryHandler } from './types/server-factory'
33
33
  import { FastifyTypeProvider, FastifyTypeProviderDefault, SafePromiseLike } from './types/type-provider'
34
34
  import { ContextConfigDefault, HTTPMethods, RawReplyDefaultExpression, RawRequestDefaultExpression, RawServerBase, RawServerDefault, RequestBodyDefault, RequestHeadersDefault, RequestParamsDefault, RequestQuerystringDefault } from './types/utils'
35
35