fastify 5.7.4 → 5.8.1
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.
- package/LICENSE +1 -1
- package/README.md +1 -1
- package/SECURITY.md +20 -20
- package/build/build-validation.js +2 -0
- package/docs/Guides/Ecosystem.md +7 -59
- package/docs/Guides/Fluent-Schema.md +2 -1
- package/docs/Guides/Migration-Guide-V4.md +9 -8
- package/docs/Guides/Migration-Guide-V5.md +1 -1
- package/docs/Guides/Serverless.md +1 -1
- package/docs/Reference/ContentTypeParser.md +2 -1
- package/docs/Reference/Decorators.md +4 -2
- package/docs/Reference/Errors.md +5 -0
- package/docs/Reference/Hooks.md +85 -23
- package/docs/Reference/LTS.md +2 -2
- package/docs/Reference/Lifecycle.md +16 -1
- package/docs/Reference/Logging.md +11 -7
- package/docs/Reference/Middleware.md +3 -2
- package/docs/Reference/Reply.md +15 -8
- package/docs/Reference/Request.md +17 -1
- package/docs/Reference/Routes.md +15 -6
- package/docs/Reference/Server.md +135 -14
- package/docs/Reference/Type-Providers.md +5 -5
- package/docs/Reference/TypeScript.md +14 -10
- package/docs/Reference/Validation-and-Serialization.md +28 -1
- package/fastify.d.ts +1 -0
- package/fastify.js +4 -2
- package/lib/config-validator.js +324 -296
- package/lib/content-type-parser.js +1 -1
- package/lib/content-type.js +9 -3
- package/lib/context.js +5 -2
- package/lib/errors.js +12 -1
- package/lib/reply.js +23 -1
- package/lib/request.js +18 -1
- package/lib/route.js +45 -4
- package/lib/symbols.js +4 -0
- package/package.json +5 -5
- package/scripts/validate-ecosystem-links.js +179 -0
- package/test/content-parser.test.js +25 -1
- package/test/content-type.test.js +38 -0
- package/test/handler-timeout.test.js +367 -0
- package/test/internals/errors.test.js +2 -2
- package/test/internals/initial-config.test.js +2 -0
- package/test/request-error.test.js +41 -0
- package/test/router-options.test.js +42 -0
- package/test/scripts/validate-ecosystem-links.test.js +339 -0
- package/test/types/dummy-plugin.ts +2 -2
- package/test/types/fastify.test-d.ts +1 -0
- package/test/types/logger.test-d.ts +17 -18
- package/test/types/register.test-d.ts +2 -2
- package/test/types/reply.test-d.ts +2 -2
- package/test/types/request.test-d.ts +4 -3
- package/test/types/route.test-d.ts +6 -0
- package/test/types/type-provider.test-d.ts +1 -1
- package/test/web-api.test.js +75 -0
- package/types/errors.d.ts +2 -0
- package/types/logger.d.ts +1 -1
- package/types/request.d.ts +2 -0
- package/types/route.d.ts +35 -21
- package/types/tsconfig.eslint.json +0 -13
package/docs/Reference/Server.md
CHANGED
|
@@ -224,6 +224,71 @@ in front.
|
|
|
224
224
|
> ℹ️ Note:
|
|
225
225
|
> At the time of writing, only node >= v14.11.0 supports this option
|
|
226
226
|
|
|
227
|
+
### `handlerTimeout`
|
|
228
|
+
<a id="factory-handler-timeout"></a>
|
|
229
|
+
|
|
230
|
+
+ Default: `0` (no timeout)
|
|
231
|
+
|
|
232
|
+
Defines the maximum number of milliseconds allowed for processing a request
|
|
233
|
+
through the entire route lifecycle (from routing through onRequest, parsing,
|
|
234
|
+
validation, handler execution, and serialization). If the response is not sent
|
|
235
|
+
within this time, a `503 Service Unavailable` error is returned and
|
|
236
|
+
`request.signal` is aborted.
|
|
237
|
+
|
|
238
|
+
Unlike `connectionTimeout` and `requestTimeout` (which operate at the socket
|
|
239
|
+
level), `handlerTimeout` is an application-level timeout that works correctly
|
|
240
|
+
with HTTP keep-alive connections. It can be overridden per-route via
|
|
241
|
+
[route options](./Routes.md#routes-options). When set at both levels, the
|
|
242
|
+
route-level value takes precedence. Routes without an explicit `handlerTimeout`
|
|
243
|
+
inherit the server default. Once a server-level timeout is set, individual
|
|
244
|
+
routes cannot opt out of it — they can only override it with a different
|
|
245
|
+
positive integer.
|
|
246
|
+
|
|
247
|
+
The timeout is **cooperative**: when it fires, Fastify sends the 503 error
|
|
248
|
+
response, but the handler's async work continues to run. Use
|
|
249
|
+
[`request.signal`](./Request.md) to detect cancellation and stop ongoing work
|
|
250
|
+
(database queries, HTTP requests, etc.). APIs that accept a `signal` option
|
|
251
|
+
(`fetch()`, database drivers, `stream.pipeline()`) will cancel automatically.
|
|
252
|
+
|
|
253
|
+
The timeout error (`FST_ERR_HANDLER_TIMEOUT`) is sent through the route's
|
|
254
|
+
[error handler](./Routes.md#routes-options), which can be customized per-route
|
|
255
|
+
to change the status code or response body.
|
|
256
|
+
|
|
257
|
+
When `reply.hijack()` is called, the timeout timer is cleared — the handler
|
|
258
|
+
takes full responsibility for the response lifecycle.
|
|
259
|
+
|
|
260
|
+
> ℹ️ Note:
|
|
261
|
+
> `handlerTimeout` does not apply to 404 handlers or custom not-found handlers
|
|
262
|
+
> set via `setNotFoundHandler()`, as they bypass the route handler lifecycle.
|
|
263
|
+
|
|
264
|
+
```js
|
|
265
|
+
const fastify = require('fastify')({
|
|
266
|
+
handlerTimeout: 10000 // 10s default for all routes
|
|
267
|
+
})
|
|
268
|
+
|
|
269
|
+
// Override per-route
|
|
270
|
+
fastify.get('/slow-report', { handlerTimeout: 120000 }, async (request) => {
|
|
271
|
+
// Use request.signal for cooperative cancellation
|
|
272
|
+
const data = await db.query(longQuery, { signal: request.signal })
|
|
273
|
+
return data
|
|
274
|
+
})
|
|
275
|
+
|
|
276
|
+
// Customize the timeout response
|
|
277
|
+
fastify.get('/custom-timeout', {
|
|
278
|
+
handlerTimeout: 5000,
|
|
279
|
+
errorHandler: (error, request, reply) => {
|
|
280
|
+
if (error.code === 'FST_ERR_HANDLER_TIMEOUT') {
|
|
281
|
+
reply.code(504).send({ error: 'Gateway Timeout' })
|
|
282
|
+
} else {
|
|
283
|
+
reply.send(error)
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}, async (request) => {
|
|
287
|
+
const result = await externalService.call({ signal: request.signal })
|
|
288
|
+
return result
|
|
289
|
+
})
|
|
290
|
+
```
|
|
291
|
+
|
|
227
292
|
### `bodyLimit`
|
|
228
293
|
<a id="factory-body-limit"></a>
|
|
229
294
|
|
|
@@ -427,7 +492,8 @@ const fastify = require('fastify')({
|
|
|
427
492
|
})
|
|
428
493
|
```
|
|
429
494
|
|
|
430
|
-
> ⚠ Warning:
|
|
495
|
+
> ⚠ Warning:
|
|
496
|
+
> Enabling this allows any callers to set `reqId` to a
|
|
431
497
|
> value of their choosing.
|
|
432
498
|
> No validation is performed on `requestIdHeader`.
|
|
433
499
|
|
|
@@ -521,8 +587,8 @@ controls [avvio](https://www.npmjs.com/package/avvio) 's `timeout` parameter.
|
|
|
521
587
|
### `querystringParser`
|
|
522
588
|
<a id="factory-querystring-parser"></a>
|
|
523
589
|
|
|
524
|
-
The default query string parser that Fastify uses is a more performant fork
|
|
525
|
-
of Node.js's core `querystring` module called
|
|
590
|
+
The default query string parser that Fastify uses is a more performant fork
|
|
591
|
+
of Node.js's core `querystring` module called
|
|
526
592
|
[`fast-querystring`](https://github.com/anonrig/fast-querystring).
|
|
527
593
|
|
|
528
594
|
You can use this option to use a custom parser, such as
|
|
@@ -566,8 +632,14 @@ define it before the `GET` route.
|
|
|
566
632
|
|
|
567
633
|
+ Default: `true`
|
|
568
634
|
|
|
569
|
-
|
|
570
|
-
|
|
635
|
+
When `true`, any request arriving after [`close`](#close) has been called will
|
|
636
|
+
receive a `503 Service Unavailable` response with `Connection: close` header
|
|
637
|
+
(HTTP/1.1). This lets load balancers detect that the server is shutting down and
|
|
638
|
+
stop routing traffic to it.
|
|
639
|
+
|
|
640
|
+
When `false`, requests arriving during the closing phase are routed and
|
|
641
|
+
processed normally. They will still receive a `Connection: close` header so that
|
|
642
|
+
clients do not attempt to reuse the connection.
|
|
571
643
|
|
|
572
644
|
### `ajv`
|
|
573
645
|
<a id="factory-ajv"></a>
|
|
@@ -745,7 +817,7 @@ function rewriteUrl (req) {
|
|
|
745
817
|
<a id="routeroptions"></a>
|
|
746
818
|
|
|
747
819
|
Fastify uses [`find-my-way`](https://github.com/delvedor/find-my-way) for its
|
|
748
|
-
HTTP router. The `routerOptions` parameter allows passing
|
|
820
|
+
HTTP router. The `routerOptions` parameter allows passing
|
|
749
821
|
[`find-my-way` options](https://github.com/delvedor/find-my-way?tab=readme-ov-file#findmywayoptions)
|
|
750
822
|
to customize the HTTP router within Fastify.
|
|
751
823
|
|
|
@@ -769,8 +841,8 @@ fastify.get('/user/:id(^([0-9]+){4}$)', (request, reply) => {
|
|
|
769
841
|
<a id="build-pretty-meta"></a>
|
|
770
842
|
|
|
771
843
|
Fastify uses [find-my-way](https://github.com/delvedor/find-my-way) which
|
|
772
|
-
supports, `buildPrettyMeta` where you can assign a `buildPrettyMeta`
|
|
773
|
-
function to sanitize a route's store object to use with the `prettyPrint`
|
|
844
|
+
supports, `buildPrettyMeta` where you can assign a `buildPrettyMeta`
|
|
845
|
+
function to sanitize a route's store object to use with the `prettyPrint`
|
|
774
846
|
functions. This function should accept a single object and return an object.
|
|
775
847
|
|
|
776
848
|
```js
|
|
@@ -865,7 +937,7 @@ const fastify = require('fastify')({
|
|
|
865
937
|
})
|
|
866
938
|
```
|
|
867
939
|
|
|
868
|
-
>
|
|
940
|
+
> ℹ️ Note:
|
|
869
941
|
> The `req` and `res` objects passed to `defaultRoute` are the raw Node.js
|
|
870
942
|
> `IncomingMessage` and `ServerResponse` instances. They do **not** expose the
|
|
871
943
|
> Fastify-specific methods available on `FastifyRequest`/`FastifyReply` (for
|
|
@@ -1029,11 +1101,12 @@ fastify.get('/dev', async (request, reply) => {
|
|
|
1029
1101
|
|
|
1030
1102
|
* **Default:** `true`
|
|
1031
1103
|
|
|
1032
|
-
> ⚠
|
|
1104
|
+
> ⚠ Warning:
|
|
1105
|
+
> This option will be set to `false` by default
|
|
1033
1106
|
> in the next major release.
|
|
1034
1107
|
|
|
1035
|
-
When set to `false`, it prevents `setErrorHandler` from being called
|
|
1036
|
-
multiple times within the same scope, ensuring that the previous error
|
|
1108
|
+
When set to `false`, it prevents `setErrorHandler` from being called
|
|
1109
|
+
multiple times within the same scope, ensuring that the previous error
|
|
1037
1110
|
handler is not unintentionally overridden.
|
|
1038
1111
|
|
|
1039
1112
|
#### Example of incorrect usage:
|
|
@@ -1331,6 +1404,53 @@ fastify.close().then(() => {
|
|
|
1331
1404
|
})
|
|
1332
1405
|
```
|
|
1333
1406
|
|
|
1407
|
+
##### Shutdown lifecycle
|
|
1408
|
+
|
|
1409
|
+
When `fastify.close()` is called, the following steps happen in order:
|
|
1410
|
+
|
|
1411
|
+
1. The server is flagged as **closing**. New incoming requests receive a
|
|
1412
|
+
`Connection: close` header (HTTP/1.1) and are handled according to
|
|
1413
|
+
[`return503OnClosing`](#factory-return-503-on-closing).
|
|
1414
|
+
2. [`preClose`](./Hooks.md#pre-close) hooks execute. The server is still
|
|
1415
|
+
processing in-flight requests at this point.
|
|
1416
|
+
3. **Connection draining** based on the
|
|
1417
|
+
[`forceCloseConnections`](#forcecloseconnections) option:
|
|
1418
|
+
- `"idle"` — idle keep-alive connections are closed; in-flight requests
|
|
1419
|
+
continue.
|
|
1420
|
+
- `true` — all persistent connections are destroyed immediately.
|
|
1421
|
+
- `false` — no forced closure; idle connections remain open until they time
|
|
1422
|
+
out naturally (see [`keepAliveTimeout`](#keepalivetimeout)).
|
|
1423
|
+
4. The HTTP server **stops accepting** new TCP connections
|
|
1424
|
+
(`server.close()`). Node.js waits for all in-flight requests to complete
|
|
1425
|
+
before invoking the callback.
|
|
1426
|
+
5. [`onClose`](./Hooks.md#on-close) hooks execute. All in-flight requests have
|
|
1427
|
+
completed and the server is no longer listening.
|
|
1428
|
+
6. The `close` callback (or the returned Promise) resolves.
|
|
1429
|
+
|
|
1430
|
+
```
|
|
1431
|
+
fastify.close() called
|
|
1432
|
+
│
|
|
1433
|
+
├─▶ closing = true (new requests receive 503)
|
|
1434
|
+
│
|
|
1435
|
+
├─▶ preClose hooks
|
|
1436
|
+
│ (in-flight requests still active)
|
|
1437
|
+
│
|
|
1438
|
+
├─▶ Connection draining (forceCloseConnections)
|
|
1439
|
+
│
|
|
1440
|
+
├─▶ server.close()
|
|
1441
|
+
│ (waits for in-flight requests to complete)
|
|
1442
|
+
│
|
|
1443
|
+
├─▶ onClose hooks
|
|
1444
|
+
│ (server stopped, all requests done)
|
|
1445
|
+
│
|
|
1446
|
+
└─▶ close callback / Promise resolves
|
|
1447
|
+
```
|
|
1448
|
+
|
|
1449
|
+
> ℹ️ Note:
|
|
1450
|
+
> Upgraded connections (such as WebSocket) are not tracked by the HTTP
|
|
1451
|
+
> server and will prevent `server.close()` from completing. Close them
|
|
1452
|
+
> explicitly in a [`preClose`](./Hooks.md#pre-close) hook.
|
|
1453
|
+
|
|
1334
1454
|
#### decorate*
|
|
1335
1455
|
<a id="decorate"></a>
|
|
1336
1456
|
|
|
@@ -1391,7 +1511,7 @@ different ways to define a name (in order).
|
|
|
1391
1511
|
Example: `pluginFn[Symbol.for('fastify.display-name')] = "Custom Name"`
|
|
1392
1512
|
3. If you `module.exports` a plugin the filename is used.
|
|
1393
1513
|
4. If you use a regular [function
|
|
1394
|
-
declaration](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions#
|
|
1514
|
+
declaration](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions#defining_functions)
|
|
1395
1515
|
the function name is used.
|
|
1396
1516
|
|
|
1397
1517
|
*Fallback*: The first two lines of your plugin will represent the plugin name.
|
|
@@ -1731,7 +1851,7 @@ set it to 500 before calling the error handler.
|
|
|
1731
1851
|
- not found (404) errors. Use [`setNotFoundHandler`](#set-not-found-handler)
|
|
1732
1852
|
instead.
|
|
1733
1853
|
- Stream errors thrown during piping into the response socket, as
|
|
1734
|
-
headers/response were already sent to the client.
|
|
1854
|
+
headers/response were already sent to the client.
|
|
1735
1855
|
Use custom in-stream data to signal such errors.
|
|
1736
1856
|
|
|
1737
1857
|
```js
|
|
@@ -2173,6 +2293,7 @@ initial options passed down by the user to the Fastify instance.
|
|
|
2173
2293
|
The properties that can currently be exposed are:
|
|
2174
2294
|
- connectionTimeout
|
|
2175
2295
|
- keepAliveTimeout
|
|
2296
|
+
- handlerTimeout
|
|
2176
2297
|
- bodyLimit
|
|
2177
2298
|
- caseSensitive
|
|
2178
2299
|
- http2
|
|
@@ -63,13 +63,13 @@ server.get('/route', {
|
|
|
63
63
|
The following sets up a TypeBox Type Provider:
|
|
64
64
|
|
|
65
65
|
```bash
|
|
66
|
-
$ npm i @fastify/type-provider-typebox
|
|
66
|
+
$ npm i typebox @fastify/type-provider-typebox
|
|
67
67
|
```
|
|
68
68
|
|
|
69
69
|
```typescript
|
|
70
70
|
import fastify from 'fastify'
|
|
71
71
|
import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox'
|
|
72
|
-
import { Type } from '
|
|
72
|
+
import { Type } from 'typebox'
|
|
73
73
|
|
|
74
74
|
const server = fastify().withTypeProvider<TypeBoxTypeProvider>()
|
|
75
75
|
|
|
@@ -109,7 +109,7 @@ Example:
|
|
|
109
109
|
import Fastify from 'fastify'
|
|
110
110
|
import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox'
|
|
111
111
|
import { JsonSchemaToTsProvider } from '@fastify/type-provider-json-schema-to-ts'
|
|
112
|
-
import { Type } from '
|
|
112
|
+
import { Type } from 'typebox'
|
|
113
113
|
|
|
114
114
|
const fastify = Fastify()
|
|
115
115
|
|
|
@@ -159,7 +159,7 @@ with several scopes, as shown below:
|
|
|
159
159
|
```ts
|
|
160
160
|
import Fastify from 'fastify'
|
|
161
161
|
import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox'
|
|
162
|
-
import { Type } from '
|
|
162
|
+
import { Type } from 'typebox'
|
|
163
163
|
|
|
164
164
|
const server = Fastify().withTypeProvider<TypeBoxTypeProvider>()
|
|
165
165
|
|
|
@@ -221,7 +221,7 @@ server.listen({ port: 3000 })
|
|
|
221
221
|
|
|
222
222
|
```ts
|
|
223
223
|
// routes.ts
|
|
224
|
-
import { Type } from '
|
|
224
|
+
import { Type } from 'typebox'
|
|
225
225
|
import {
|
|
226
226
|
FastifyInstance,
|
|
227
227
|
FastifyBaseLogger,
|
|
@@ -58,8 +58,9 @@ in a blank http Fastify server.
|
|
|
58
58
|
or use one of the [recommended
|
|
59
59
|
ones](https://github.com/tsconfig/bases#node-14-tsconfigjson).
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
> ℹ️ Note:
|
|
62
|
+
> Set `target` property in `tsconfig.json` to `es2017` or greater to avoid
|
|
63
|
+
> [FastifyDeprecation](https://github.com/fastify/fastify/issues/3284) warning.
|
|
63
64
|
|
|
64
65
|
4. Create an `index.ts` file - this will contain the server code
|
|
65
66
|
5. Add the following code block to your file:
|
|
@@ -216,7 +217,7 @@ providers.
|
|
|
216
217
|
|
|
217
218
|
#### TypeBox
|
|
218
219
|
|
|
219
|
-
A useful library for building types and a schema at once is [TypeBox](https://www.npmjs.com/package
|
|
220
|
+
A useful library for building types and a schema at once is [TypeBox](https://www.npmjs.com/package/typebox).
|
|
220
221
|
With TypeBox you define your schema within your code and use them directly as
|
|
221
222
|
types or schemas as you need them.
|
|
222
223
|
|
|
@@ -226,14 +227,14 @@ can do it as follows:
|
|
|
226
227
|
1. Install `typebox` in your project.
|
|
227
228
|
|
|
228
229
|
```bash
|
|
229
|
-
npm i
|
|
230
|
+
npm i typebox
|
|
230
231
|
```
|
|
231
232
|
|
|
232
233
|
2. Define the schema you need with `Type` and create the respective type with
|
|
233
234
|
`Static`.
|
|
234
235
|
|
|
235
236
|
```typescript
|
|
236
|
-
import { Static, Type } from '
|
|
237
|
+
import { Static, Type } from 'typebox'
|
|
237
238
|
|
|
238
239
|
export const User = Type.Object({
|
|
239
240
|
name: Type.String(),
|
|
@@ -1621,8 +1622,9 @@ previous hook was `preValidation`, the next hook will be `preSerialization`.
|
|
|
1621
1622
|
`preSerialization` is the fifth hook to be executed in the request lifecycle.
|
|
1622
1623
|
The previous hook was `preHandler`, the next hook will be `onSend`.
|
|
1623
1624
|
|
|
1624
|
-
Note:
|
|
1625
|
-
|
|
1625
|
+
> ℹ️ Note:
|
|
1626
|
+
> The hook is NOT called if the payload is a string, a Buffer,
|
|
1627
|
+
> a stream, or null.
|
|
1626
1628
|
|
|
1627
1629
|
##### fastify.onSendHookHandler< OnSendPayload, [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [RequestGeneric][FastifyRequestGenericInterface], [ContextConfig][ContextConfigGeneric]>(request: [FastifyRequest][FastifyRequest], reply: [FastifyReply][FastifyReply], payload: OnSendPayload, done: (err: [FastifyError][FastifyError] | null, res?: unknown) => void): Promise\<unknown\> | void
|
|
1628
1630
|
|
|
@@ -1632,8 +1634,9 @@ You can change the payload with the `onSend` hook. It is the sixth hook to be
|
|
|
1632
1634
|
executed in the request lifecycle. The previous hook was `preSerialization`, the
|
|
1633
1635
|
next hook will be `onResponse`.
|
|
1634
1636
|
|
|
1635
|
-
Note:
|
|
1636
|
-
|
|
1637
|
+
> ℹ️ Note:
|
|
1638
|
+
> If you change the payload, you may only change it to a string,
|
|
1639
|
+
> a Buffer, a stream, or null.
|
|
1637
1640
|
|
|
1638
1641
|
##### fastify.onResponseHookHandler< [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [RequestGeneric][FastifyRequestGenericInterface], [ContextConfig][ContextConfigGeneric]>(request: [FastifyRequest][FastifyRequest], reply: [FastifyReply][FastifyReply], done: (err?: [FastifyError][FastifyError]) => void): Promise\<unknown\> | void
|
|
1639
1642
|
|
|
@@ -1679,7 +1682,8 @@ created. The hook will be executed before the registered code.
|
|
|
1679
1682
|
This hook can be useful if you are developing a plugin that needs to know when a
|
|
1680
1683
|
plugin context is formed, and you want to operate in that specific context.
|
|
1681
1684
|
|
|
1682
|
-
Note:
|
|
1685
|
+
> ℹ️ Note:
|
|
1686
|
+
> This hook will not be called if a plugin is wrapped inside fastify-plugin.
|
|
1683
1687
|
|
|
1684
1688
|
##### fastify.onCloseHookHandler< [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [Logger][LoggerGeneric]>(instance: [FastifyInstance][FastifyInstance], done: (err?: [FastifyError][FastifyError]) => void): Promise\<unknown\> | void
|
|
1685
1689
|
|
|
@@ -329,6 +329,31 @@ server.setValidatorCompiler(req => {
|
|
|
329
329
|
})
|
|
330
330
|
```
|
|
331
331
|
|
|
332
|
+
When type coercion is enabled, using `anyOf` with nullable primitive types
|
|
333
|
+
can produce unexpected results. For example, a value of `0` or `false` may be
|
|
334
|
+
coerced to `null` because Ajv evaluates `anyOf` schemas in order and applies
|
|
335
|
+
type coercion during matching. This means the `{ "type": "null" }` branch can
|
|
336
|
+
match before the intended type:
|
|
337
|
+
|
|
338
|
+
```json
|
|
339
|
+
{
|
|
340
|
+
"anyOf": [
|
|
341
|
+
{ "type": "null" },
|
|
342
|
+
{ "type": "number" }
|
|
343
|
+
]
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
To avoid this, use the `nullable` keyword instead of `anyOf` for primitive
|
|
348
|
+
types:
|
|
349
|
+
|
|
350
|
+
```json
|
|
351
|
+
{
|
|
352
|
+
"type": "number",
|
|
353
|
+
"nullable": true
|
|
354
|
+
}
|
|
355
|
+
```
|
|
356
|
+
|
|
332
357
|
For more information, see [Ajv Coercion](https://ajv.js.org/coercion.html).
|
|
333
358
|
|
|
334
359
|
#### Ajv Plugins
|
|
@@ -439,7 +464,9 @@ fastify.setValidatorCompiler(({ schema, method, url, httpPart }) => {
|
|
|
439
464
|
return ajv.compile(schema)
|
|
440
465
|
})
|
|
441
466
|
```
|
|
442
|
-
|
|
467
|
+
|
|
468
|
+
> ℹ️ Note:
|
|
469
|
+
> When using a custom validator instance, add schemas to the validator
|
|
443
470
|
> instead of Fastify. Fastify's `addSchema` method will not recognize the custom
|
|
444
471
|
> validator.
|
|
445
472
|
|
package/fastify.d.ts
CHANGED
|
@@ -119,6 +119,7 @@ declare namespace fastify {
|
|
|
119
119
|
requestTimeout?: number,
|
|
120
120
|
pluginTimeout?: number,
|
|
121
121
|
bodyLimit?: number,
|
|
122
|
+
handlerTimeout?: number,
|
|
122
123
|
maxParamLength?: number,
|
|
123
124
|
disableRequestLogging?: boolean | ((req: FastifyRequest) => boolean),
|
|
124
125
|
exposeHeadRoutes?: boolean,
|
package/fastify.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const VERSION = '5.
|
|
3
|
+
const VERSION = '5.8.1'
|
|
4
4
|
|
|
5
5
|
const Avvio = require('avvio')
|
|
6
6
|
const http = require('node:http')
|
|
@@ -32,7 +32,8 @@ const {
|
|
|
32
32
|
kKeepAliveConnections,
|
|
33
33
|
kChildLoggerFactory,
|
|
34
34
|
kGenReqId,
|
|
35
|
-
kErrorHandlerAlreadySet
|
|
35
|
+
kErrorHandlerAlreadySet,
|
|
36
|
+
kHandlerTimeout
|
|
36
37
|
} = require('./lib/symbols.js')
|
|
37
38
|
|
|
38
39
|
const { createServer } = require('./lib/server')
|
|
@@ -147,6 +148,7 @@ function fastify (serverOptions) {
|
|
|
147
148
|
[kChildren]: [],
|
|
148
149
|
[kServerBindings]: [],
|
|
149
150
|
[kBodyLimit]: options.bodyLimit,
|
|
151
|
+
[kHandlerTimeout]: options.handlerTimeout,
|
|
150
152
|
[kRoutePrefix]: '',
|
|
151
153
|
[kLogLevel]: '',
|
|
152
154
|
[kLogSerializers]: null,
|