fastify 5.3.2 → 5.3.3
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/.vscode/settings.json +22 -0
- package/docs/Guides/Ecosystem.md +7 -2
- package/docs/Guides/Serverless.md +28 -69
- package/docs/Reference/Errors.md +0 -2
- package/docs/Reference/Server.md +17 -1
- package/eslint.config.js +17 -9
- package/fastify.js +6 -2
- package/lib/decorate.js +2 -2
- package/lib/errors.js +0 -8
- package/lib/logger-factory.js +1 -1
- package/lib/logger-pino.js +2 -2
- package/lib/reply.js +2 -2
- package/lib/request.js +1 -1
- package/lib/server.js +30 -51
- package/package.json +4 -4
- package/test/close-pipelining.test.js +5 -4
- package/test/decorator.test.js +422 -341
- package/test/helper.js +107 -69
- package/test/hooks.on-listen.test.js +255 -239
- package/test/hooks.on-ready.test.js +110 -92
- package/test/inject.test.js +114 -97
- package/test/input-validation.js +63 -53
- package/test/internals/errors.test.js +1 -11
- package/test/internals/hooks.test.js +17 -0
- package/test/issue-4959.test.js +2 -2
- package/test/logger/response.test.js +19 -20
- package/test/options.error-handler.test.js +1 -1
- package/test/options.test.js +1 -1
- package/test/output-validation.test.js +49 -70
- package/test/patch.error-handler.test.js +1 -1
- package/test/patch.test.js +1 -1
- package/test/plugin.1.test.js +71 -60
- package/test/promises.test.js +36 -30
- package/test/put.error-handler.test.js +1 -1
- package/test/put.test.js +1 -1
- package/test/reply-error.test.js +169 -148
- package/test/reply-trailers.test.js +119 -108
- package/test/schema-feature.test.js +309 -238
- package/test/schema-validation.test.js +44 -2
- package/test/stream.1.test.js +30 -27
- package/test/stream.2.test.js +20 -10
- package/test/stream.3.test.js +37 -31
- package/test/types/errors.test-d.ts +0 -1
- package/test/types/plugin.test-d.ts +1 -1
- package/test/types/register.test-d.ts +1 -1
- package/test/use-semicolon-delimiter.test.js +1 -1
- package/types/errors.d.ts +0 -1
- package/test/http2/missing-http2-module.test.js +0 -17
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"workbench.colorCustomizations": {
|
|
3
|
+
"[GitHub Dark]": {
|
|
4
|
+
"tab.activeBackground": "#0d0d0d",
|
|
5
|
+
"tab.activeBorder": "#ffff00"
|
|
6
|
+
},
|
|
7
|
+
"activityBar.background": "#7AC6C8",
|
|
8
|
+
"activityBar.foreground": "#0B2A34",
|
|
9
|
+
"activityBar.inactiveForeground": "#1e2021",
|
|
10
|
+
"activityBar.activeBorder": "#853937",
|
|
11
|
+
"activityBar.activeBackground": "#3F7F81",
|
|
12
|
+
"activityBar.border": "#3F7F81",
|
|
13
|
+
"titleBar.activeBackground": "#549B9D",
|
|
14
|
+
"titleBar.activeForeground": "#0B2A34",
|
|
15
|
+
"titleBar.inactiveBackground": "#727f7f",
|
|
16
|
+
"titleBar.inactiveForeground": "#1e2021",
|
|
17
|
+
"titleBar.border": "#3F7F81",
|
|
18
|
+
"statusBar.background": "#71ACAD",
|
|
19
|
+
"statusBar.foreground": "#0B2A34",
|
|
20
|
+
"statusBar.border": "#3F7F81"
|
|
21
|
+
}
|
|
22
|
+
}
|
package/docs/Guides/Ecosystem.md
CHANGED
|
@@ -40,8 +40,6 @@ section.
|
|
|
40
40
|
plugin for adding
|
|
41
41
|
[CSRF](https://en.wikipedia.org/wiki/Cross-site_request_forgery) protection to
|
|
42
42
|
Fastify.
|
|
43
|
-
- [`@fastify/diagnostics-channel`](https://github.com/fastify/fastify-diagnostics-channel)
|
|
44
|
-
Plugin to deal with `diagnostics_channel` on Fastify.
|
|
45
43
|
- [`@fastify/elasticsearch`](https://github.com/fastify/fastify-elasticsearch)
|
|
46
44
|
Plugin to share the same ES client.
|
|
47
45
|
- [`@fastify/env`](https://github.com/fastify/fastify-env) Load and check
|
|
@@ -200,6 +198,9 @@ section.
|
|
|
200
198
|
to go!
|
|
201
199
|
A plugin to implement [Lyra](https://github.com/nearform/lyra) search engine
|
|
202
200
|
on Fastify
|
|
201
|
+
- [`@inaiat/fastify-papr`](https://github.com/inaiat/fastify-papr)
|
|
202
|
+
A plugin to integrate [Papr](https://github.com/plexinc/papr),
|
|
203
|
+
the MongoDB ORM for TypeScript & MongoDB, with Fastify.
|
|
203
204
|
- [`@jerome1337/fastify-enforce-routes-pattern`](https://github.com/Jerome1337/fastify-enforce-routes-pattern)
|
|
204
205
|
A Fastify plugin that enforces naming pattern for routes path.
|
|
205
206
|
- [`@joggr/fastify-prisma`](https://github.com/joggrdocs/fastify-prisma)
|
|
@@ -737,9 +738,13 @@ middlewares into Fastify plugins
|
|
|
737
738
|
generator by directory structure.
|
|
738
739
|
- [`fastify-flux`](https://github.com/Jnig/fastify-flux) Tool for building
|
|
739
740
|
Fastify APIs using decorators and convert Typescript interface to JSON Schema.
|
|
741
|
+
- [`jeasx`](https://www.jeasx.dev)
|
|
742
|
+
A flexible server-rendering framework built on Fastify
|
|
743
|
+
that leverages asynchronous JSX to simplify web development.
|
|
740
744
|
- [`simple-tjscli`](https://github.com/imjuni/simple-tjscli) CLI tool to
|
|
741
745
|
generate JSON Schema from TypeScript interfaces.
|
|
742
746
|
- [`vite-plugin-fastify`](https://github.com/Vanilla-IceCream/vite-plugin-fastify)
|
|
743
747
|
Fastify plugin for Vite with Hot-module Replacement.
|
|
744
748
|
- [`vite-plugin-fastify-routes`](https://github.com/Vanilla-IceCream/vite-plugin-fastify-routes)
|
|
745
749
|
File-based routing for Fastify applications using Vite.
|
|
750
|
+
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
<h1 align="center">Serverless</h1>
|
|
2
2
|
|
|
3
3
|
Run serverless applications and REST APIs using your existing Fastify
|
|
4
|
-
application.
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
application. You may need to make code changes to work on your
|
|
5
|
+
serverless platform of choice. This document contains a small guide
|
|
6
|
+
for the most popular serverless providers and how to use
|
|
7
7
|
Fastify with them.
|
|
8
8
|
|
|
9
9
|
#### Should you use Fastify in a serverless platform?
|
|
10
10
|
|
|
11
|
-
That is up to you! Keep in mind
|
|
11
|
+
That is up to you! Keep in mind, functions as a service should always use
|
|
12
12
|
small and focused functions, but you can also run an entire web application with
|
|
13
13
|
them. It is important to remember that the bigger the application the slower the
|
|
14
14
|
initial boot will be. The best way to run Fastify applications in serverless
|
|
15
|
-
environments is to use platforms like Google Cloud Run, AWS Fargate,
|
|
16
|
-
Container Instances, where the server can handle multiple requests
|
|
17
|
-
time and make full use of Fastify's features.
|
|
15
|
+
environments is to use platforms like Google Cloud Run, AWS Fargate, Azure
|
|
16
|
+
Container Instances, and Vercel where the server can handle multiple requests
|
|
17
|
+
at the same time and make full use of Fastify's features.
|
|
18
18
|
|
|
19
19
|
One of the best features of using Fastify in serverless applications is the ease
|
|
20
20
|
of development. In your local environment, you will always run the Fastify
|
|
@@ -136,7 +136,6 @@ of serverless applications to the cloud.
|
|
|
136
136
|
|
|
137
137
|
[Genezio has a dedicated guide for deploying a Fastify application.](https://genezio.com/docs/frameworks/fastify/)
|
|
138
138
|
|
|
139
|
-
|
|
140
139
|
## Google Cloud Functions
|
|
141
140
|
|
|
142
141
|
### Creation of Fastify instance
|
|
@@ -238,14 +237,13 @@ npx @google-cloud/functions-framework --target=fastifyFunction
|
|
|
238
237
|
Or add this command to your `package.json` scripts:
|
|
239
238
|
```json
|
|
240
239
|
"scripts": {
|
|
241
|
-
...
|
|
242
|
-
"dev": "npx @google-cloud/functions-framework --target=fastifyFunction"
|
|
243
|
-
...
|
|
240
|
+
...
|
|
241
|
+
"dev": "npx @google-cloud/functions-framework --target=fastifyFunction"
|
|
242
|
+
...
|
|
244
243
|
}
|
|
245
244
|
```
|
|
246
245
|
and run it with `npm run dev`.
|
|
247
246
|
|
|
248
|
-
|
|
249
247
|
### Deploy
|
|
250
248
|
```bash
|
|
251
249
|
gcloud functions deploy fastifyFunction \
|
|
@@ -326,7 +324,7 @@ async function registerRoutes (fastify) {
|
|
|
326
324
|
})
|
|
327
325
|
|
|
328
326
|
// define your endpoints here...
|
|
329
|
-
fastify.post("/some-route-here", async (request, reply) => {}
|
|
327
|
+
fastify.post("/some-route-here", async (request, reply) => {})
|
|
330
328
|
|
|
331
329
|
fastify.get('/', async (request, reply) => {
|
|
332
330
|
reply.send({message: 'Hello World!'})
|
|
@@ -377,7 +375,6 @@ firebase functions:log
|
|
|
377
375
|
- [Fastify on Firebase Functions](https://github.com/lirantal/lemon-squeezy-firebase-webhook-fastify/blob/main/package.json)
|
|
378
376
|
- [An article about HTTP webhooks on Firebase Functions and Fastify: A Practical Case Study with Lemon Squeezy](https://lirantal.com/blog/http-webhooks-firebase-functions-fastify-practical-case-study-lemon-squeezy)
|
|
379
377
|
|
|
380
|
-
|
|
381
378
|
## Google Cloud Run
|
|
382
379
|
|
|
383
380
|
Unlike AWS Lambda or Google Cloud Functions, Google Cloud Run is a serverless
|
|
@@ -463,7 +460,7 @@ CMD [ "npm", "start" ]
|
|
|
463
460
|
To keep build artifacts out of your container (which keeps it small and improves
|
|
464
461
|
build times) add a `.dockerignore` file like the one below:
|
|
465
462
|
|
|
466
|
-
|
|
463
|
+
```dockerignore
|
|
467
464
|
Dockerfile
|
|
468
465
|
README.md
|
|
469
466
|
node_modules
|
|
@@ -490,12 +487,11 @@ gcloud beta run deploy --image gcr.io/PROJECT-ID/APP-NAME --platform managed
|
|
|
490
487
|
|
|
491
488
|
Your app will be accessible from the URL GCP provides.
|
|
492
489
|
|
|
493
|
-
|
|
494
490
|
## netlify-lambda
|
|
495
491
|
|
|
496
492
|
First, please perform all preparation steps related to **AWS Lambda**.
|
|
497
493
|
|
|
498
|
-
Create a folder called `functions`,
|
|
494
|
+
Create a folder called `functions`, then create `server.js` (and your endpoint
|
|
499
495
|
path will be `server.js`) inside the `functions` folder.
|
|
500
496
|
|
|
501
497
|
### functions/server.js
|
|
@@ -564,9 +560,9 @@ Add this command to your `package.json` *scripts*
|
|
|
564
560
|
|
|
565
561
|
```json
|
|
566
562
|
"scripts": {
|
|
567
|
-
...
|
|
568
|
-
"build:functions": "netlify-lambda build functions --config ./webpack.config.netlify.js"
|
|
569
|
-
...
|
|
563
|
+
...
|
|
564
|
+
"build:functions": "netlify-lambda build functions --config ./webpack.config.netlify.js"
|
|
565
|
+
...
|
|
570
566
|
}
|
|
571
567
|
```
|
|
572
568
|
|
|
@@ -574,54 +570,17 @@ Then it should work fine.
|
|
|
574
570
|
|
|
575
571
|
## Vercel
|
|
576
572
|
|
|
577
|
-
[Vercel](https://vercel.com)
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
{
|
|
583
|
-
"rewrites": [
|
|
584
|
-
{
|
|
585
|
-
"source": "/(.*)",
|
|
586
|
-
"destination": "/api/serverless.js"
|
|
587
|
-
}
|
|
588
|
-
]
|
|
589
|
-
}
|
|
590
|
-
```
|
|
591
|
-
|
|
592
|
-
Then, write `api/serverless.js` like so:
|
|
593
|
-
|
|
594
|
-
```js
|
|
595
|
-
"use strict";
|
|
596
|
-
|
|
597
|
-
// Read the .env file.
|
|
598
|
-
import * as dotenv from "dotenv";
|
|
599
|
-
dotenv.config();
|
|
573
|
+
[Vercel](https://vercel.com) fully supports deploying Fastify applications.
|
|
574
|
+
Additionally, with Vercel's
|
|
575
|
+
[Fluid compute](https://vercel.com/docs/functions/fluid-compute), you can combine
|
|
576
|
+
server-like concurrency with the autoscaling properties of traditional
|
|
577
|
+
serverless functions.
|
|
600
578
|
|
|
601
|
-
|
|
602
|
-
|
|
579
|
+
Get started with the
|
|
580
|
+
[Fastify Node.js template on Vercel](
|
|
581
|
+
https://vercel.com/templates/other/fastify-serverless-function).
|
|
603
582
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
// Register your application as a normal plugin.
|
|
610
|
-
app.register(import("../src/app.js"));
|
|
611
|
-
|
|
612
|
-
export default async (req, res) => {
|
|
613
|
-
await app.ready();
|
|
614
|
-
app.server.emit('request', req, res);
|
|
615
|
-
}
|
|
616
|
-
```
|
|
617
|
-
|
|
618
|
-
In `src/app.js` define the plugin.
|
|
619
|
-
```js
|
|
620
|
-
async function routes (fastify, options) {
|
|
621
|
-
fastify.get('/', async (request, reply) => {
|
|
622
|
-
return { hello: 'world' }
|
|
623
|
-
})
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
export default routes;
|
|
627
|
-
```
|
|
583
|
+
[Fluid compute](https://vercel.com/docs/functions/fluid-compute) currently
|
|
584
|
+
requires an explicit opt-in. Learn more about enabling Fluid compute
|
|
585
|
+
[here](
|
|
586
|
+
https://vercel.com/docs/functions/fluid-compute#how-to-enable-fluid-compute).
|
package/docs/Reference/Errors.md
CHANGED
|
@@ -69,7 +69,6 @@
|
|
|
69
69
|
- [FST_ERR_SCH_VALIDATION_BUILD](#fst_err_sch_validation_build)
|
|
70
70
|
- [FST_ERR_SCH_SERIALIZATION_BUILD](#fst_err_sch_serialization_build)
|
|
71
71
|
- [FST_ERR_SCH_RESPONSE_SCHEMA_NOT_NESTED_2XX](#fst_err_sch_response_schema_not_nested_2xx)
|
|
72
|
-
- [FST_ERR_HTTP2_INVALID_VERSION](#fst_err_http2_invalid_version)
|
|
73
72
|
- [FST_ERR_INIT_OPTS_INVALID](#fst_err_init_opts_invalid)
|
|
74
73
|
- [FST_ERR_FORCE_CLOSE_CONNECTIONS_IDLE_NOT_AVAILABLE](#fst_err_force_close_connections_idle_not_available)
|
|
75
74
|
- [FST_ERR_DUPLICATED_ROUTE](#fst_err_duplicated_route)
|
|
@@ -340,7 +339,6 @@ Below is a table with all the error codes used by Fastify.
|
|
|
340
339
|
| <a id="fst_err_sch_validation_build">FST_ERR_SCH_VALIDATION_BUILD</a> | The JSON schema provided for validation to a route is not valid. | Fix the JSON schema. | [#2023](https://github.com/fastify/fastify/pull/2023) |
|
|
341
340
|
| <a id="fst_err_sch_serialization_build">FST_ERR_SCH_SERIALIZATION_BUILD</a> | The JSON schema provided for serialization of a route response is not valid. | Fix the JSON schema. | [#2023](https://github.com/fastify/fastify/pull/2023) |
|
|
342
341
|
| <a id="fst_err_sch_response_schema_not_nested_2xx">FST_ERR_SCH_RESPONSE_SCHEMA_NOT_NESTED_2XX</a> | Response schemas should be nested under a valid status code (2XX). | Use a valid status code. | [#4554](https://github.com/fastify/fastify/pull/4554) |
|
|
343
|
-
| <a id="fst_err_http2_invalid_version">FST_ERR_HTTP2_INVALID_VERSION</a> | HTTP2 is available only from node >= 8.8.1. | Use a higher version of node. | [#1346](https://github.com/fastify/fastify/pull/1346) |
|
|
344
342
|
| <a id="fst_err_init_opts_invalid">FST_ERR_INIT_OPTS_INVALID</a> | Invalid initialization options. | Use valid initialization options. | [#1471](https://github.com/fastify/fastify/pull/1471) |
|
|
345
343
|
| <a id="fst_err_force_close_connections_idle_not_available">FST_ERR_FORCE_CLOSE_CONNECTIONS_IDLE_NOT_AVAILABLE</a> | Cannot set forceCloseConnections to `idle` as your HTTP server does not support `closeIdleConnections` method. | Use a different value for `forceCloseConnections`. | [#3925](https://github.com/fastify/fastify/pull/3925) |
|
|
346
344
|
| <a id="fst_err_duplicated_route">FST_ERR_DUPLICATED_ROUTE</a> | The HTTP method already has a registered controller for that URL. | Use a different URL or register the controller for another HTTP method. | [#2954](https://github.com/fastify/fastify/pull/2954) |
|
package/docs/Reference/Server.md
CHANGED
|
@@ -1529,7 +1529,7 @@ plugins.
|
|
|
1529
1529
|
> 🛈 Note:
|
|
1530
1530
|
> Some config properties from the request object will be
|
|
1531
1531
|
> undefined inside the custom not found handler. E.g.:
|
|
1532
|
-
> `request.
|
|
1532
|
+
> `request.routeOptions.url`, `routeOptions.method` and `routeOptions.config`.
|
|
1533
1533
|
> This method design goal is to allow calling the common not found route.
|
|
1534
1534
|
> To return a per-route customized 404 response, you can do it in
|
|
1535
1535
|
> the response itself.
|
|
@@ -1574,6 +1574,22 @@ if (statusCode >= 500) {
|
|
|
1574
1574
|
log.error(error)
|
|
1575
1575
|
}
|
|
1576
1576
|
```
|
|
1577
|
+
|
|
1578
|
+
> ⚠ Warning:
|
|
1579
|
+
> Avoid calling setErrorHandler multiple times in the same scope.
|
|
1580
|
+
> Only the last handler will take effect, and previous ones will be silently overridden.
|
|
1581
|
+
>
|
|
1582
|
+
> Incorrect usage:
|
|
1583
|
+
> ```js
|
|
1584
|
+
> app.setErrorHandler(function freeSomeResources () {
|
|
1585
|
+
> // Never executed, memory leaks
|
|
1586
|
+
> })
|
|
1587
|
+
>
|
|
1588
|
+
> app.setErrorHandler(function anotherErrorHandler () {
|
|
1589
|
+
> // Overrides the previous handler
|
|
1590
|
+
> })
|
|
1591
|
+
> ```
|
|
1592
|
+
|
|
1577
1593
|
#### setChildLoggerFactory
|
|
1578
1594
|
<a id="set-child-logger-factory"></a>
|
|
1579
1595
|
|
package/eslint.config.js
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
+
const neostandard = require('neostandard')
|
|
2
3
|
|
|
3
|
-
module.exports =
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
module.exports = [
|
|
5
|
+
...neostandard({
|
|
6
|
+
ignores: [
|
|
7
|
+
'lib/configValidator.js',
|
|
8
|
+
'lib/error-serializer.js',
|
|
9
|
+
'test/same-shape.test.js',
|
|
10
|
+
'test/types/import.js'
|
|
11
|
+
],
|
|
12
|
+
ts: true
|
|
13
|
+
}),
|
|
14
|
+
{
|
|
15
|
+
rules: {
|
|
16
|
+
'comma-dangle': ['error', 'never']
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
]
|
package/fastify.js
CHANGED
|
@@ -681,8 +681,12 @@ function fastify (options) {
|
|
|
681
681
|
this[kHooks].add(name, fn)
|
|
682
682
|
} else {
|
|
683
683
|
this.after((err, done) => {
|
|
684
|
-
|
|
685
|
-
|
|
684
|
+
try {
|
|
685
|
+
_addHook.call(this, name, fn)
|
|
686
|
+
done(err)
|
|
687
|
+
} catch (err) {
|
|
688
|
+
done(err)
|
|
689
|
+
}
|
|
686
690
|
})
|
|
687
691
|
}
|
|
688
692
|
return this
|
package/lib/decorate.js
CHANGED
|
@@ -4,7 +4,7 @@ const {
|
|
|
4
4
|
kReply,
|
|
5
5
|
kRequest,
|
|
6
6
|
kState,
|
|
7
|
-
kHasBeenDecorated
|
|
7
|
+
kHasBeenDecorated
|
|
8
8
|
} = require('./symbols.js')
|
|
9
9
|
|
|
10
10
|
const {
|
|
@@ -13,7 +13,7 @@ const {
|
|
|
13
13
|
FST_ERR_DEC_AFTER_START,
|
|
14
14
|
FST_ERR_DEC_REFERENCE_TYPE,
|
|
15
15
|
FST_ERR_DEC_DEPENDENCY_INVALID_TYPE,
|
|
16
|
-
FST_ERR_DEC_UNDECLARED
|
|
16
|
+
FST_ERR_DEC_UNDECLARED
|
|
17
17
|
} = require('./errors')
|
|
18
18
|
|
|
19
19
|
function decorate (instance, name, fn, dependencies) {
|
package/lib/errors.js
CHANGED
|
@@ -328,14 +328,6 @@ const codes = {
|
|
|
328
328
|
'response schemas should be nested under a valid status code, e.g { 2xx: { type: "object" } }'
|
|
329
329
|
),
|
|
330
330
|
|
|
331
|
-
/**
|
|
332
|
-
* http2
|
|
333
|
-
*/
|
|
334
|
-
FST_ERR_HTTP2_INVALID_VERSION: createError(
|
|
335
|
-
'FST_ERR_HTTP2_INVALID_VERSION',
|
|
336
|
-
'HTTP2 is available only from node >= 8.8.1'
|
|
337
|
-
),
|
|
338
|
-
|
|
339
331
|
/**
|
|
340
332
|
* initialConfig
|
|
341
333
|
*/
|
package/lib/logger-factory.js
CHANGED
package/lib/logger-pino.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
const pino = require('pino')
|
|
10
10
|
const { serializersSym } = pino.symbols
|
|
11
11
|
const {
|
|
12
|
-
FST_ERR_LOG_INVALID_DESTINATION
|
|
12
|
+
FST_ERR_LOG_INVALID_DESTINATION
|
|
13
13
|
} = require('./errors')
|
|
14
14
|
|
|
15
15
|
function createPinoLogger (opts) {
|
|
@@ -64,5 +64,5 @@ const serializers = {
|
|
|
64
64
|
|
|
65
65
|
module.exports = {
|
|
66
66
|
serializers,
|
|
67
|
-
createPinoLogger
|
|
67
|
+
createPinoLogger
|
|
68
68
|
}
|
package/lib/reply.js
CHANGED
|
@@ -22,7 +22,7 @@ const {
|
|
|
22
22
|
kReplyCacheSerializeFns,
|
|
23
23
|
kSchemaController,
|
|
24
24
|
kOptions,
|
|
25
|
-
kRouteContext
|
|
25
|
+
kRouteContext
|
|
26
26
|
} = require('./symbols.js')
|
|
27
27
|
const {
|
|
28
28
|
onSendHookRunner,
|
|
@@ -53,7 +53,7 @@ const {
|
|
|
53
53
|
FST_ERR_BAD_TRAILER_VALUE,
|
|
54
54
|
FST_ERR_MISSING_SERIALIZATION_FN,
|
|
55
55
|
FST_ERR_MISSING_CONTENTTYPE_SERIALIZATION_FN,
|
|
56
|
-
FST_ERR_DEC_UNDECLARED
|
|
56
|
+
FST_ERR_DEC_UNDECLARED
|
|
57
57
|
} = require('./errors')
|
|
58
58
|
const decorators = require('./decorate')
|
|
59
59
|
|
package/lib/request.js
CHANGED
|
@@ -11,7 +11,7 @@ const {
|
|
|
11
11
|
kOptions,
|
|
12
12
|
kRequestCacheValidateFns,
|
|
13
13
|
kRouteContext,
|
|
14
|
-
kRequestOriginalUrl
|
|
14
|
+
kRequestOriginalUrl
|
|
15
15
|
} = require('./symbols')
|
|
16
16
|
const { FST_ERR_REQ_INVALID_VALIDATION_INVOCATION, FST_ERR_DEC_UNDECLARED } = require('./errors')
|
|
17
17
|
const decorators = require('./decorate')
|
package/lib/server.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const http = require('node:http')
|
|
4
4
|
const https = require('node:https')
|
|
5
|
+
const http2 = require('node:http2')
|
|
5
6
|
const dns = require('node:dns')
|
|
6
7
|
const os = require('node:os')
|
|
7
8
|
|
|
@@ -9,7 +10,6 @@ const { kState, kOptions, kServerBindings } = require('./symbols')
|
|
|
9
10
|
const { FSTWRN003 } = require('./warnings')
|
|
10
11
|
const { onListenHookRunner } = require('./hooks')
|
|
11
12
|
const {
|
|
12
|
-
FST_ERR_HTTP2_INVALID_VERSION,
|
|
13
13
|
FST_ERR_REOPENED_CLOSE_SERVER,
|
|
14
14
|
FST_ERR_REOPENED_SERVER,
|
|
15
15
|
FST_ERR_LISTEN_OPTIONS_INVALID
|
|
@@ -98,7 +98,6 @@ function createServer (options, httpHandler) {
|
|
|
98
98
|
|
|
99
99
|
if (cb === undefined) {
|
|
100
100
|
const listening = listenPromise.call(this, server, listenOptions)
|
|
101
|
-
/* istanbul ignore else */
|
|
102
101
|
return listening.then(address => {
|
|
103
102
|
return new Promise((resolve, reject) => {
|
|
104
103
|
if (host === 'localhost') {
|
|
@@ -192,7 +191,6 @@ function multipleBindings (mainServer, httpHandler, serverOpts, listenOptions, o
|
|
|
192
191
|
// to the secondary servers. It is valid only when the user is
|
|
193
192
|
// listening on localhost
|
|
194
193
|
const originUnref = mainServer.unref
|
|
195
|
-
/* c8 ignore next 4 */
|
|
196
194
|
mainServer.unref = function () {
|
|
197
195
|
originUnref.call(mainServer)
|
|
198
196
|
mainServer.emit('unref')
|
|
@@ -218,7 +216,8 @@ function listenCallback (server, listenOptions) {
|
|
|
218
216
|
|
|
219
217
|
if (this[kState].listening && this[kState].closing) {
|
|
220
218
|
return listenOptions.cb(new FST_ERR_REOPENED_CLOSE_SERVER(), null)
|
|
221
|
-
}
|
|
219
|
+
}
|
|
220
|
+
if (this[kState].listening) {
|
|
222
221
|
return listenOptions.cb(new FST_ERR_REOPENED_SERVER(), null)
|
|
223
222
|
}
|
|
224
223
|
|
|
@@ -234,7 +233,8 @@ function listenCallback (server, listenOptions) {
|
|
|
234
233
|
function listenPromise (server, listenOptions) {
|
|
235
234
|
if (this[kState].listening && this[kState].closing) {
|
|
236
235
|
return Promise.reject(new FST_ERR_REOPENED_CLOSE_SERVER())
|
|
237
|
-
}
|
|
236
|
+
}
|
|
237
|
+
if (this[kState].listening) {
|
|
238
238
|
return Promise.reject(new FST_ERR_REOPENED_SERVER())
|
|
239
239
|
}
|
|
240
240
|
|
|
@@ -272,41 +272,38 @@ function listenPromise (server, listenOptions) {
|
|
|
272
272
|
}
|
|
273
273
|
|
|
274
274
|
function getServerInstance (options, httpHandler) {
|
|
275
|
-
let server = null
|
|
276
|
-
// node@20 do not accepts options as boolean
|
|
277
|
-
// we need to provide proper https option
|
|
278
|
-
const httpsOptions = options.https === true ? {} : options.https
|
|
279
275
|
if (options.serverFactory) {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
if (typeof httpsOptions === 'object') {
|
|
283
|
-
server = http2().createSecureServer(httpsOptions, httpHandler)
|
|
284
|
-
} else {
|
|
285
|
-
server = http2().createServer(httpHandler)
|
|
286
|
-
}
|
|
287
|
-
server.on('session', sessionTimeout(options.http2SessionTimeout))
|
|
288
|
-
} else {
|
|
289
|
-
// this is http1
|
|
290
|
-
if (httpsOptions) {
|
|
291
|
-
server = https.createServer(httpsOptions, httpHandler)
|
|
292
|
-
} else {
|
|
293
|
-
server = http.createServer(options.http, httpHandler)
|
|
294
|
-
}
|
|
295
|
-
server.keepAliveTimeout = options.keepAliveTimeout
|
|
296
|
-
server.requestTimeout = options.requestTimeout
|
|
297
|
-
// we treat zero as null
|
|
298
|
-
// and null is the default setting from nodejs
|
|
299
|
-
// so we do not pass the option to server
|
|
300
|
-
if (options.maxRequestsPerSocket > 0) {
|
|
301
|
-
server.maxRequestsPerSocket = options.maxRequestsPerSocket
|
|
302
|
-
}
|
|
276
|
+
// User provided server instance
|
|
277
|
+
return options.serverFactory(httpHandler, options)
|
|
303
278
|
}
|
|
304
279
|
|
|
305
|
-
|
|
280
|
+
// We have accepted true as a valid way to init https but node requires an options obj
|
|
281
|
+
const httpsOptions = options.https === true ? {} : options.https
|
|
282
|
+
|
|
283
|
+
if (options.http2) {
|
|
284
|
+
const server = typeof httpsOptions === 'object' ? http2.createSecureServer(httpsOptions, httpHandler) : http2.createServer(options.http, httpHandler)
|
|
285
|
+
server.on('session', (session) => session.setTimeout(options.http2SessionTimeout, function closeSession () {
|
|
286
|
+
this.close()
|
|
287
|
+
}))
|
|
288
|
+
|
|
306
289
|
server.setTimeout(options.connectionTimeout)
|
|
290
|
+
|
|
291
|
+
return server
|
|
307
292
|
}
|
|
293
|
+
|
|
294
|
+
// HTTP1 server instance
|
|
295
|
+
const server = httpsOptions ? https.createServer(httpsOptions, httpHandler) : http.createServer(options.http, httpHandler)
|
|
296
|
+
server.keepAliveTimeout = options.keepAliveTimeout
|
|
297
|
+
server.requestTimeout = options.requestTimeout
|
|
298
|
+
server.setTimeout(options.connectionTimeout)
|
|
299
|
+
// We treat zero as null(node default) so we do not pass zero to the server instance
|
|
300
|
+
if (options.maxRequestsPerSocket > 0) {
|
|
301
|
+
server.maxRequestsPerSocket = options.maxRequestsPerSocket
|
|
302
|
+
}
|
|
303
|
+
|
|
308
304
|
return server
|
|
309
305
|
}
|
|
306
|
+
|
|
310
307
|
/**
|
|
311
308
|
* Inspects the provided `server.address` object and returns a
|
|
312
309
|
* normalized list of IP address strings. Normalization in this
|
|
@@ -355,21 +352,3 @@ function logServerAddress (server, listenTextResolver) {
|
|
|
355
352
|
}
|
|
356
353
|
return addresses[0]
|
|
357
354
|
}
|
|
358
|
-
|
|
359
|
-
function http2 () {
|
|
360
|
-
try {
|
|
361
|
-
return require('node:http2')
|
|
362
|
-
} catch (err) {
|
|
363
|
-
throw new FST_ERR_HTTP2_INVALID_VERSION()
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
function sessionTimeout (timeout) {
|
|
368
|
-
return function (session) {
|
|
369
|
-
session.setTimeout(timeout, close)
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
function close () {
|
|
374
|
-
this.close()
|
|
375
|
-
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fastify",
|
|
3
|
-
"version": "5.3.
|
|
3
|
+
"version": "5.3.3",
|
|
4
4
|
"description": "Fast and low overhead web framework, for Node.js",
|
|
5
5
|
"main": "fastify.js",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -172,14 +172,14 @@
|
|
|
172
172
|
"ajv-i18n": "^4.2.0",
|
|
173
173
|
"ajv-merge-patch": "^5.0.1",
|
|
174
174
|
"autocannon": "^8.0.0",
|
|
175
|
-
"borp": "^0.
|
|
175
|
+
"borp": "^0.20.0",
|
|
176
176
|
"branch-comparer": "^1.1.0",
|
|
177
177
|
"concurrently": "^9.1.2",
|
|
178
178
|
"cross-env": "^7.0.3",
|
|
179
179
|
"eslint": "^9.0.0",
|
|
180
180
|
"fast-json-body": "^1.1.0",
|
|
181
181
|
"fastify-plugin": "^5.0.0",
|
|
182
|
-
"fluent-json-schema": "^
|
|
182
|
+
"fluent-json-schema": "^6.0.0",
|
|
183
183
|
"h2url": "^0.2.0",
|
|
184
184
|
"http-errors": "^2.0.0",
|
|
185
185
|
"joi": "^17.12.3",
|
|
@@ -192,7 +192,7 @@
|
|
|
192
192
|
"simple-get": "^4.0.1",
|
|
193
193
|
"split2": "^4.2.0",
|
|
194
194
|
"tap": "^21.0.0",
|
|
195
|
-
"tsd": "^0.
|
|
195
|
+
"tsd": "^0.32.0",
|
|
196
196
|
"typescript": "~5.8.2",
|
|
197
197
|
"undici": "^6.13.0",
|
|
198
198
|
"vary": "^1.1.2",
|
|
@@ -59,10 +59,11 @@ test('Should close the socket abruptly - pipelining - return503OnClosing: false'
|
|
|
59
59
|
instance.request({ path: '/', method: 'GET' })
|
|
60
60
|
])
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
t.assert.strictEqual(
|
|
62
|
+
const fulfilled = responses.filter(r => r.status === 'fulfilled')
|
|
63
|
+
const rejected = responses.filter(r => r.status === 'rejected')
|
|
64
|
+
|
|
65
|
+
t.assert.strictEqual(fulfilled.length, 2)
|
|
66
|
+
t.assert.strictEqual(rejected.length, 2)
|
|
66
67
|
|
|
67
68
|
await instance.close()
|
|
68
69
|
})
|