fastify 4.24.2 → 4.25.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.
- package/README.md +7 -2
- package/SECURITY.md +27 -0
- package/docs/Guides/Ecosystem.md +18 -6
- package/docs/Guides/Getting-Started.md +3 -3
- package/docs/Guides/Plugins-Guide.md +2 -2
- package/docs/Guides/Style-Guide.md +7 -7
- package/docs/Reference/ContentTypeParser.md +2 -0
- package/docs/Reference/Errors.md +171 -397
- package/docs/Reference/Hooks.md +8 -2
- package/docs/Reference/Index.md +2 -0
- package/docs/Reference/Reply.md +16 -5
- package/docs/Reference/Request.md +1 -1
- package/docs/Reference/Routes.md +5 -5
- package/docs/Reference/TypeScript.md +1 -1
- package/docs/Reference/Warnings.md +77 -0
- package/examples/use-plugin.js +2 -0
- package/fastify.js +37 -20
- package/integration/server.js +2 -0
- package/lib/decorate.js +2 -2
- package/lib/errors.js +1 -1
- package/lib/hooks.js +1 -1
- package/lib/pluginUtils.js +10 -1
- package/lib/reply.js +5 -5
- package/lib/request.js +14 -7
- package/lib/route.js +9 -5
- package/lib/server.js +20 -27
- package/lib/validation.js +5 -5
- package/lib/warnings.js +110 -40
- package/package.json +4 -4
- package/test/buffer.test.js +2 -0
- package/test/bundler/esbuild/src/fail-plugin-version.js +2 -0
- package/test/bundler/esbuild/src/index.js +2 -0
- package/test/bundler/webpack/src/fail-plugin-version.js +2 -0
- package/test/bundler/webpack/src/index.js +2 -0
- package/test/bundler/webpack/webpack.config.js +2 -0
- package/test/close-pipelining.test.js +4 -4
- package/test/close.test.js +3 -3
- package/test/constrained-routes.test.js +24 -24
- package/test/decorator.test.js +27 -22
- package/test/default-route.test.js +7 -7
- package/test/fastify-instance.test.js +120 -0
- package/test/hooks.on-ready.test.js +16 -0
- package/test/hooks.test.js +1 -3
- package/test/http2/constraint.test.js +1 -1
- package/test/internals/errors.test.js +28 -3
- package/test/internals/reply.test.js +33 -9
- package/test/logger/instantiation.test.js +2 -1
- package/test/plugin.4.test.js +28 -0
- package/test/register.test.js +5 -5
- package/test/reply-trailers.test.js +1 -1
- package/test/route.7.test.js +7 -6
- package/test/schema-examples.test.js +2 -2
- package/test/schema-feature.test.js +11 -11
- package/test/server.test.js +51 -0
- package/test/types/hooks.test-d.ts +124 -1
- package/test/types/instance.test-d.ts +12 -0
- package/test/types/logger.test-d.ts +14 -0
- package/test/types/reply.test-d.ts +25 -6
- package/test/types/request.test-d.ts +3 -2
- package/test/types/route.test-d.ts +38 -0
- package/test/versioned-routes.test.js +7 -6
- package/types/hooks.d.ts +183 -0
- package/types/instance.d.ts +12 -12
- package/types/reply.d.ts +7 -10
- package/types/request.d.ts +2 -1
- package/types/route.d.ts +31 -26
- package/types/utils.d.ts +10 -0
package/docs/Reference/Reply.md
CHANGED
|
@@ -86,7 +86,6 @@ object that exposes the following functions and properties:
|
|
|
86
86
|
- `.log` - The logger instance of the incoming request.
|
|
87
87
|
- `.request` - The incoming request.
|
|
88
88
|
- `.context` - Deprecated, access the [Request's context](./Request.md) property.
|
|
89
|
-
- `.routeOptions` - Access the [Request's routeOptions](./Request.md) property.
|
|
90
89
|
|
|
91
90
|
```js
|
|
92
91
|
fastify.get('/', options, function (request, reply) {
|
|
@@ -666,8 +665,12 @@ fastify.get('/json', options, function (request, reply) {
|
|
|
666
665
|
#### Streams
|
|
667
666
|
<a id="send-streams"></a>
|
|
668
667
|
|
|
669
|
-
|
|
670
|
-
`'application/octet-stream'`.
|
|
668
|
+
If you are sending a stream and you have not set a `'Content-Type'` header,
|
|
669
|
+
*send* will set it to `'application/octet-stream'`.
|
|
670
|
+
|
|
671
|
+
As noted above, streams are considered to be pre-serialized, so they will be
|
|
672
|
+
sent unmodified without response validation.
|
|
673
|
+
|
|
671
674
|
```js
|
|
672
675
|
fastify.get('/streams', function (request, reply) {
|
|
673
676
|
const fs = require('node:fs')
|
|
@@ -691,6 +694,10 @@ fastify.get('/streams', async function (request, reply) {
|
|
|
691
694
|
|
|
692
695
|
If you are sending a buffer and you have not set a `'Content-Type'` header,
|
|
693
696
|
*send* will set it to `'application/octet-stream'`.
|
|
697
|
+
|
|
698
|
+
As noted above, Buffers are considered to be pre-serialized, so they will be
|
|
699
|
+
sent unmodified without response validation.
|
|
700
|
+
|
|
694
701
|
```js
|
|
695
702
|
const fs = require('node:fs')
|
|
696
703
|
fastify.get('/streams', function (request, reply) {
|
|
@@ -714,8 +721,12 @@ fastify.get('/streams', async function (request, reply) {
|
|
|
714
721
|
#### TypedArrays
|
|
715
722
|
<a id="send-typedarrays"></a>
|
|
716
723
|
|
|
717
|
-
`send` manages TypedArray and sets the `'Content-Type'
|
|
718
|
-
header if not already set.
|
|
724
|
+
`send` manages TypedArray like a Buffer, and sets the `'Content-Type'`
|
|
725
|
+
header to `'application/octet-stream'` if not already set.
|
|
726
|
+
|
|
727
|
+
As noted above, TypedArray/Buffers are considered to be pre-serialized, so they
|
|
728
|
+
will be sent unmodified without response validation.
|
|
729
|
+
|
|
719
730
|
```js
|
|
720
731
|
const fs = require('node:fs')
|
|
721
732
|
fastify.get('/streams', function (request, reply) {
|
|
@@ -161,7 +161,7 @@ for more information on how to compile validation function.
|
|
|
161
161
|
This function will compile a validation schema and
|
|
162
162
|
return a function that can be used to validate data.
|
|
163
163
|
The function returned (a.k.a. _validation function_) is compiled
|
|
164
|
-
by using the provided [`
|
|
164
|
+
by using the provided [`SchemaController#ValidationCompiler`](./Server.md#schema-controller).
|
|
165
165
|
A `WeakMap` is used to cached this, reducing compilation calls.
|
|
166
166
|
|
|
167
167
|
The optional parameter `httpPart`, if provided, is forwarded directly
|
package/docs/Reference/Routes.md
CHANGED
|
@@ -715,9 +715,9 @@ arbitrary host matching.
|
|
|
715
715
|
fastify.route({
|
|
716
716
|
method: 'GET',
|
|
717
717
|
url: '/',
|
|
718
|
-
constraints: { host: 'auth.fastify.
|
|
718
|
+
constraints: { host: 'auth.fastify.dev' },
|
|
719
719
|
handler: function (request, reply) {
|
|
720
|
-
reply.send('hello world from auth.fastify.
|
|
720
|
+
reply.send('hello world from auth.fastify.dev')
|
|
721
721
|
}
|
|
722
722
|
})
|
|
723
723
|
|
|
@@ -735,10 +735,10 @@ fastify.inject({
|
|
|
735
735
|
method: 'GET',
|
|
736
736
|
url: '/',
|
|
737
737
|
headers: {
|
|
738
|
-
'Host': 'auth.fastify.
|
|
738
|
+
'Host': 'auth.fastify.dev'
|
|
739
739
|
}
|
|
740
740
|
}, (err, res) => {
|
|
741
|
-
// => 'hello world from auth.fastify.
|
|
741
|
+
// => 'hello world from auth.fastify.dev'
|
|
742
742
|
})
|
|
743
743
|
```
|
|
744
744
|
|
|
@@ -749,7 +749,7 @@ matching wildcard subdomains (or any other pattern):
|
|
|
749
749
|
fastify.route({
|
|
750
750
|
method: 'GET',
|
|
751
751
|
url: '/',
|
|
752
|
-
constraints: { host: /.*\.fastify\.io/ }, // will match any subdomain of fastify.
|
|
752
|
+
constraints: { host: /.*\.fastify\.io/ }, // will match any subdomain of fastify.dev
|
|
753
753
|
handler: function (request, reply) {
|
|
754
754
|
reply.send('hello world from ' + request.headers.host)
|
|
755
755
|
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
|
|
2
|
+
<h1 align="center">Fastify</h1>
|
|
3
|
+
|
|
4
|
+
**Table of contents**
|
|
5
|
+
- [Warnings](#warnings)
|
|
6
|
+
- [Warnings In Fastify](#warnings-in-fastify)
|
|
7
|
+
- [Fastify Warning Codes](#fastify-warning-codes)
|
|
8
|
+
- [FSTWRN001](#FSTWRN001)
|
|
9
|
+
- [FSTWRN002](#FSTWRN002)
|
|
10
|
+
- [Fastify Deprecation Codes](#fastify-deprecation-codes)
|
|
11
|
+
- [FSTDEP005](#FSTDEP005)
|
|
12
|
+
- [FSTDEP006](#FSTDEP006)
|
|
13
|
+
- [FSTDEP007](#FSTDEP007)
|
|
14
|
+
- [FSTDEP008](#FSTDEP008)
|
|
15
|
+
- [FSTDEP009](#FSTDEP009)
|
|
16
|
+
- [FSTDEP010](#FSTDEP010)
|
|
17
|
+
- [FSTDEP011](#FSTDEP011)
|
|
18
|
+
- [FSTDEP012](#FSTDEP012)
|
|
19
|
+
- [FSTDEP013](#FSTDEP013)
|
|
20
|
+
- [FSTDEP014](#FSTDEP014)
|
|
21
|
+
- [FSTDEP015](#FSTDEP015)
|
|
22
|
+
- [FSTDEP016](#FSTDEP016)
|
|
23
|
+
- [FSTDEP017](#FSTDEP017)
|
|
24
|
+
- [FSTDEP018](#FSTDEP018)
|
|
25
|
+
- [FSTDEP019](#FSTDEP019)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
## Warnings
|
|
29
|
+
|
|
30
|
+
### Warnings In Fastify
|
|
31
|
+
Warnings are enabled by default. They can be disabled by using any
|
|
32
|
+
of the following methods:
|
|
33
|
+
|
|
34
|
+
- setting the `NODE_NO_WARNINGS` environment variable to `1`
|
|
35
|
+
- passing the `--no-warnings` flag to the node process
|
|
36
|
+
- setting 'no-warnings' in the `NODE_OPTIONS` environment variable
|
|
37
|
+
|
|
38
|
+
For more information on how to disable warnings, see [node's documentation](https://nodejs.org/api/cli.html).
|
|
39
|
+
|
|
40
|
+
However, disabling warnings is not recommended as it may cause
|
|
41
|
+
potential problems when upgrading Fastify versions.
|
|
42
|
+
Only experienced users should consider disabling warnings.
|
|
43
|
+
|
|
44
|
+
### Fastify Warning Codes
|
|
45
|
+
|
|
46
|
+
| Code | Description | How to solve | Discussion |
|
|
47
|
+
| ---- | ----------- | ------------ | ---------- |
|
|
48
|
+
| <a id="FSTWRN001">FSTWRN001</a> | The specified schema for a route is missing. This may indicate the schema is not well specified. | Check the schema for the route. | [#4647](https://github.com/fastify/fastify/pull/4647) |
|
|
49
|
+
| <a id="FSTWRN002">FSTWRN002</a> | The %s plugin being registered mixes async and callback styles, which will result in an error in `fastify@5`. | Do not mix async and callback style. | [#5139](https://github.com/fastify/fastify/pull/5139) |
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
### Fastify Deprecation Codes
|
|
53
|
+
|
|
54
|
+
Deprecation codes are further supported by the Node.js CLI options:
|
|
55
|
+
|
|
56
|
+
- [--no-deprecation](https://nodejs.org/api/cli.html#--no-deprecation)
|
|
57
|
+
- [--throw-deprecation](https://nodejs.org/api/cli.html#--throw-deprecation)
|
|
58
|
+
- [--trace-deprecation](https://nodejs.org/api/cli.html#--trace-deprecation)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
| Code | Description | How to solve | Discussion |
|
|
62
|
+
| ---- | ----------- | ------------ | ---------- |
|
|
63
|
+
| <a id="FSTDEP005">FSTDEP005</a> | You are accessing the deprecated `request.connection` property. | Use `request.socket`. | [#2594](https://github.com/fastify/fastify/pull/2594) |
|
|
64
|
+
| <a id="FSTDEP006">FSTDEP006</a> | You are decorating Request/Reply with a reference type. This reference is shared amongst all requests. | Do not use Arrays/Objects as values when decorating Request/Reply. | [#2688](https://github.com/fastify/fastify/pull/2688) |
|
|
65
|
+
| <a id="FSTDEP007">FSTDEP007</a> | You are trying to set a HEAD route using `exposeHeadRoute` route flag when a sibling route is already set. | Remove `exposeHeadRoutes` or explicitly set `exposeHeadRoutes` to `false` | [#2700](https://github.com/fastify/fastify/pull/2700) |
|
|
66
|
+
| <a id="FSTDEP008">FSTDEP008</a> | You are using route constraints via the route `{version: "..."}` option. | Use `{constraints: {version: "..."}}` option. | [#2682](https://github.com/fastify/fastify/pull/2682) |
|
|
67
|
+
| <a id="FSTDEP009">FSTDEP009</a> | You are using a custom route versioning strategy via the server `{versioning: "..."}` option. | Use `{constraints: {version: "..."}}` option. | [#2682](https://github.com/fastify/fastify/pull/2682) |
|
|
68
|
+
| <a id="FSTDEP010">FSTDEP010</a> | Modifying the `reply.sent` property is deprecated. | Use the `reply.hijack()` method. | [#3140](https://github.com/fastify/fastify/pull/3140) |
|
|
69
|
+
| <a id="FSTDEP011">FSTDEP011</a> | Variadic listen method is deprecated. | Use `.listen(optionsObject)`. | [#3712](https://github.com/fastify/fastify/pull/3712) |
|
|
70
|
+
| <a id="FSTDEP012">FSTDEP012</a> | You are trying to access the deprecated `request.context` property. | Use `request.routeOptions.config` or `request.routeOptions.schema`. | [#4216](https://github.com/fastify/fastify/pull/4216) [#5084](https://github.com/fastify/fastify/pull/5084) |
|
|
71
|
+
| <a id="FSTDEP013">FSTDEP013</a> | Direct return of "trailers" function is deprecated. | Use "callback" or "async-await" for return value. | [#4380](https://github.com/fastify/fastify/pull/4380) |
|
|
72
|
+
| <a id="FSTDEP014">FSTDEP014</a> | You are trying to set/access the default route. This property is deprecated. | Use `setNotFoundHandler` if you want to custom a 404 handler or the wildcard (`*`) to match all routes. | [#4480](https://github.com/fastify/fastify/pull/4480) |
|
|
73
|
+
| <a id="FSTDEP015">FSTDEP015</a> | You are accessing the deprecated `request.routeSchema` property. | Use `request.routeOptions.schema`. | [#4470](https://github.com/fastify/fastify/pull/4470) |
|
|
74
|
+
| <a id="FSTDEP016">FSTDEP016</a> | You are accessing the deprecated `request.routeConfig` property. | Use `request.routeOptions.config`. | [#4470](https://github.com/fastify/fastify/pull/4470) |
|
|
75
|
+
| <a id="FSTDEP017">FSTDEP017</a> | You are accessing the deprecated `request.routerPath` property. | Use `request.routeOptions.url`. | [#4470](https://github.com/fastify/fastify/pull/4470) |
|
|
76
|
+
| <a id="FSTDEP018">FSTDEP018</a> | You are accessing the deprecated `request.routerMethod` property. | Use `request.routeOptions.method`. | [#4470](https://github.com/fastify/fastify/pull/4470) |
|
|
77
|
+
| <a id="FSTDEP019">FSTDEP019</a> | You are accessing the deprecated `reply.context` property. | Use `reply.routeOptions.config` or `reply.routeOptions.schema`. | [#5032](https://github.com/fastify/fastify/pull/5032) [#5084](https://github.com/fastify/fastify/pull/5084) |
|
package/examples/use-plugin.js
CHANGED
package/fastify.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const VERSION = '4.
|
|
3
|
+
const VERSION = '4.25.0'
|
|
4
4
|
|
|
5
5
|
const Avvio = require('avvio')
|
|
6
6
|
const http = require('node:http')
|
|
@@ -47,7 +47,7 @@ const { buildRouting, validateBodyLimitOption } = require('./lib/route')
|
|
|
47
47
|
const build404 = require('./lib/fourOhFour')
|
|
48
48
|
const getSecuredInitialConfig = require('./lib/initialConfigValidation')
|
|
49
49
|
const override = require('./lib/pluginOverride')
|
|
50
|
-
const
|
|
50
|
+
const { FSTDEP009 } = require('./lib/warnings')
|
|
51
51
|
const noopSet = require('./lib/noop-set')
|
|
52
52
|
const {
|
|
53
53
|
appendStackTrace,
|
|
@@ -152,7 +152,7 @@ function fastify (options) {
|
|
|
152
152
|
|
|
153
153
|
let constraints = options.constraints
|
|
154
154
|
if (options.versioning) {
|
|
155
|
-
|
|
155
|
+
FSTDEP009()
|
|
156
156
|
constraints = {
|
|
157
157
|
...constraints,
|
|
158
158
|
version: {
|
|
@@ -217,7 +217,10 @@ function fastify (options) {
|
|
|
217
217
|
[kState]: {
|
|
218
218
|
listening: false,
|
|
219
219
|
closing: false,
|
|
220
|
-
started: false
|
|
220
|
+
started: false,
|
|
221
|
+
ready: false,
|
|
222
|
+
booting: false,
|
|
223
|
+
readyPromise: null
|
|
221
224
|
},
|
|
222
225
|
[kKeepAliveConnections]: keepAliveConnections,
|
|
223
226
|
[kOptions]: options,
|
|
@@ -562,25 +565,43 @@ function fastify (options) {
|
|
|
562
565
|
}
|
|
563
566
|
|
|
564
567
|
function ready (cb) {
|
|
568
|
+
if (this[kState].readyPromise !== null) {
|
|
569
|
+
if (cb != null) {
|
|
570
|
+
this[kState].readyPromise.then(() => cb(null, fastify), cb)
|
|
571
|
+
return
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
return this[kState].readyPromise
|
|
575
|
+
}
|
|
576
|
+
|
|
565
577
|
let resolveReady
|
|
566
578
|
let rejectReady
|
|
567
579
|
|
|
568
580
|
// run the hooks after returning the promise
|
|
569
581
|
process.nextTick(runHooks)
|
|
570
582
|
|
|
583
|
+
// Create a promise no matter what
|
|
584
|
+
// It will work as a barrier for all the .ready() calls (ensuring single hook execution)
|
|
585
|
+
// as well as a flow control mechanism to chain cbs and further
|
|
586
|
+
// promises
|
|
587
|
+
this[kState].readyPromise = new Promise(function (resolve, reject) {
|
|
588
|
+
resolveReady = resolve
|
|
589
|
+
rejectReady = reject
|
|
590
|
+
})
|
|
591
|
+
|
|
571
592
|
if (!cb) {
|
|
572
|
-
return
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
})
|
|
593
|
+
return this[kState].readyPromise
|
|
594
|
+
} else {
|
|
595
|
+
this[kState].readyPromise.then(() => cb(null, fastify), cb)
|
|
576
596
|
}
|
|
577
597
|
|
|
578
598
|
function runHooks () {
|
|
579
599
|
// start loading
|
|
580
600
|
fastify[kAvvioBoot]((err, done) => {
|
|
581
|
-
if (err || fastify[kState].started) {
|
|
601
|
+
if (err || fastify[kState].started || fastify[kState].ready || fastify[kState].booting) {
|
|
582
602
|
manageErr(err)
|
|
583
603
|
} else {
|
|
604
|
+
fastify[kState].booting = true
|
|
584
605
|
hookRunnerApplication('onReady', fastify[kAvvioBoot], fastify, manageErr)
|
|
585
606
|
}
|
|
586
607
|
done()
|
|
@@ -595,18 +616,14 @@ function fastify (options) {
|
|
|
595
616
|
? appendStackTrace(err, new AVVIO_ERRORS_MAP[err.code](err.message))
|
|
596
617
|
: err
|
|
597
618
|
|
|
598
|
-
if (
|
|
599
|
-
|
|
600
|
-
cb(err)
|
|
601
|
-
} else {
|
|
602
|
-
cb(undefined, fastify)
|
|
603
|
-
}
|
|
604
|
-
} else {
|
|
605
|
-
if (err) {
|
|
606
|
-
return rejectReady(err)
|
|
607
|
-
}
|
|
608
|
-
resolveReady(fastify)
|
|
619
|
+
if (err) {
|
|
620
|
+
return rejectReady(err)
|
|
609
621
|
}
|
|
622
|
+
|
|
623
|
+
resolveReady(fastify)
|
|
624
|
+
fastify[kState].booting = false
|
|
625
|
+
fastify[kState].ready = true
|
|
626
|
+
fastify[kState].promise = null
|
|
610
627
|
}
|
|
611
628
|
}
|
|
612
629
|
|
package/integration/server.js
CHANGED
package/lib/decorate.js
CHANGED
|
@@ -16,7 +16,7 @@ const {
|
|
|
16
16
|
FST_ERR_DEC_DEPENDENCY_INVALID_TYPE
|
|
17
17
|
} = require('./errors')
|
|
18
18
|
|
|
19
|
-
const
|
|
19
|
+
const { FSTDEP006 } = require('./warnings')
|
|
20
20
|
|
|
21
21
|
function decorate (instance, name, fn, dependencies) {
|
|
22
22
|
if (Object.prototype.hasOwnProperty.call(instance, name)) {
|
|
@@ -58,7 +58,7 @@ function decorateConstructor (konstructor, name, fn, dependencies) {
|
|
|
58
58
|
|
|
59
59
|
function checkReferenceType (name, fn) {
|
|
60
60
|
if (typeof fn === 'object' && fn && !(typeof fn.getter === 'function' || typeof fn.setter === 'function')) {
|
|
61
|
-
|
|
61
|
+
FSTDEP006(name)
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
|
package/lib/errors.js
CHANGED
|
@@ -179,7 +179,7 @@ const codes = {
|
|
|
179
179
|
*/
|
|
180
180
|
FST_ERR_MISSING_MIDDLEWARE: createError(
|
|
181
181
|
'FST_ERR_MISSING_MIDDLEWARE',
|
|
182
|
-
'You must register a plugin for handling middlewares, visit fastify.
|
|
182
|
+
'You must register a plugin for handling middlewares, visit fastify.dev/docs/latest/Reference/Middleware/ for more info.',
|
|
183
183
|
500
|
|
184
184
|
),
|
|
185
185
|
|
package/lib/hooks.js
CHANGED
package/lib/pluginUtils.js
CHANGED
|
@@ -11,6 +11,7 @@ const {
|
|
|
11
11
|
FST_ERR_PLUGIN_VERSION_MISMATCH,
|
|
12
12
|
FST_ERR_PLUGIN_NOT_PRESENT_IN_INSTANCE
|
|
13
13
|
} = require('./errors')
|
|
14
|
+
const { FSTWRN002 } = require('./warnings.js')
|
|
14
15
|
|
|
15
16
|
function getMeta (fn) {
|
|
16
17
|
return fn[Symbol.for('plugin-meta')]
|
|
@@ -132,10 +133,18 @@ function registerPluginName (fn) {
|
|
|
132
133
|
const name = meta.name
|
|
133
134
|
if (!name) return
|
|
134
135
|
this[kRegisteredPlugins].push(name)
|
|
136
|
+
return name
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function checkPluginHealthiness (fn, pluginName = 'anonymous') {
|
|
140
|
+
if (fn.constructor.name === 'AsyncFunction' && fn.length === 3) {
|
|
141
|
+
FSTWRN002(pluginName)
|
|
142
|
+
}
|
|
135
143
|
}
|
|
136
144
|
|
|
137
145
|
function registerPlugin (fn) {
|
|
138
|
-
registerPluginName.call(this, fn)
|
|
146
|
+
const pluginName = registerPluginName.call(this, fn)
|
|
147
|
+
checkPluginHealthiness.call(this, fn, pluginName)
|
|
139
148
|
checkVersion.call(this, fn)
|
|
140
149
|
checkDecorators.call(this, fn)
|
|
141
150
|
checkDependencies.call(this, fn)
|
package/lib/reply.js
CHANGED
|
@@ -53,7 +53,7 @@ const {
|
|
|
53
53
|
FST_ERR_MISSING_SERIALIZATION_FN,
|
|
54
54
|
FST_ERR_MISSING_CONTENTTYPE_SERIALIZATION_FN
|
|
55
55
|
} = require('./errors')
|
|
56
|
-
const
|
|
56
|
+
const { FSTDEP010, FSTDEP013, FSTDEP019 } = require('./warnings')
|
|
57
57
|
|
|
58
58
|
function Reply (res, request, log) {
|
|
59
59
|
this.raw = res
|
|
@@ -80,7 +80,7 @@ Object.defineProperties(Reply.prototype, {
|
|
|
80
80
|
// Is temporary to avoid constant conflicts between `next` and `main`
|
|
81
81
|
context: {
|
|
82
82
|
get () {
|
|
83
|
-
|
|
83
|
+
FSTDEP019()
|
|
84
84
|
return this.request[kRouteContext]
|
|
85
85
|
}
|
|
86
86
|
},
|
|
@@ -96,7 +96,7 @@ Object.defineProperties(Reply.prototype, {
|
|
|
96
96
|
return (this[kReplyHijacked] || this.raw.writableEnded) === true
|
|
97
97
|
},
|
|
98
98
|
set (value) {
|
|
99
|
-
|
|
99
|
+
FSTDEP010()
|
|
100
100
|
|
|
101
101
|
if (value !== true) {
|
|
102
102
|
throw new FST_ERR_REP_SENT_VALUE()
|
|
@@ -164,7 +164,7 @@ Reply.prototype.send = function (payload) {
|
|
|
164
164
|
if (hasContentType === false) {
|
|
165
165
|
this[kReplyHeaders]['content-type'] = CONTENT_TYPE.OCTET
|
|
166
166
|
}
|
|
167
|
-
const payloadToSend = Buffer.isBuffer(payload) ? payload : Buffer.from(payload.buffer)
|
|
167
|
+
const payloadToSend = Buffer.isBuffer(payload) ? payload : Buffer.from(payload.buffer, payload.byteOffset, payload.byteLength)
|
|
168
168
|
onSendHook(this, payloadToSend)
|
|
169
169
|
return this
|
|
170
170
|
}
|
|
@@ -748,7 +748,7 @@ function sendTrailer (payload, res, reply) {
|
|
|
748
748
|
result.then((v) => cb(null, v), cb)
|
|
749
749
|
} else if (result !== null && result !== undefined) {
|
|
750
750
|
// TODO: should be removed in fastify@5
|
|
751
|
-
|
|
751
|
+
FSTDEP013()
|
|
752
752
|
cb(null, result)
|
|
753
753
|
}
|
|
754
754
|
}
|
package/lib/request.js
CHANGED
|
@@ -2,7 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
const proxyAddr = require('proxy-addr')
|
|
4
4
|
const semver = require('semver')
|
|
5
|
-
const
|
|
5
|
+
const {
|
|
6
|
+
FSTDEP005,
|
|
7
|
+
FSTDEP012,
|
|
8
|
+
FSTDEP015,
|
|
9
|
+
FSTDEP016,
|
|
10
|
+
FSTDEP017,
|
|
11
|
+
FSTDEP018
|
|
12
|
+
} = require('./warnings')
|
|
6
13
|
const {
|
|
7
14
|
kHasBeenDecorated,
|
|
8
15
|
kSchemaBody,
|
|
@@ -166,13 +173,13 @@ Object.defineProperties(Request.prototype, {
|
|
|
166
173
|
},
|
|
167
174
|
context: {
|
|
168
175
|
get () {
|
|
169
|
-
|
|
176
|
+
FSTDEP012()
|
|
170
177
|
return this[kRouteContext]
|
|
171
178
|
}
|
|
172
179
|
},
|
|
173
180
|
routerPath: {
|
|
174
181
|
get () {
|
|
175
|
-
|
|
182
|
+
FSTDEP017()
|
|
176
183
|
return this[kRouteContext].config?.url
|
|
177
184
|
}
|
|
178
185
|
},
|
|
@@ -208,19 +215,19 @@ Object.defineProperties(Request.prototype, {
|
|
|
208
215
|
},
|
|
209
216
|
routerMethod: {
|
|
210
217
|
get () {
|
|
211
|
-
|
|
218
|
+
FSTDEP018()
|
|
212
219
|
return this[kRouteContext].config?.method
|
|
213
220
|
}
|
|
214
221
|
},
|
|
215
222
|
routeConfig: {
|
|
216
223
|
get () {
|
|
217
|
-
|
|
224
|
+
FSTDEP016()
|
|
218
225
|
return this[kRouteContext][kPublicRouteContext]?.config
|
|
219
226
|
}
|
|
220
227
|
},
|
|
221
228
|
routeSchema: {
|
|
222
229
|
get () {
|
|
223
|
-
|
|
230
|
+
FSTDEP015()
|
|
224
231
|
return this[kRouteContext][kPublicRouteContext].schema
|
|
225
232
|
}
|
|
226
233
|
},
|
|
@@ -233,7 +240,7 @@ Object.defineProperties(Request.prototype, {
|
|
|
233
240
|
get () {
|
|
234
241
|
/* istanbul ignore next */
|
|
235
242
|
if (semver.gte(process.versions.node, '13.0.0')) {
|
|
236
|
-
|
|
243
|
+
FSTDEP005()
|
|
237
244
|
}
|
|
238
245
|
return this.raw.connection
|
|
239
246
|
}
|
package/lib/route.js
CHANGED
|
@@ -7,7 +7,11 @@ const { onRequestAbortHookRunner, lifecycleHooks, preParsingHookRunner, onTimeou
|
|
|
7
7
|
const { supportedMethods } = require('./httpMethods')
|
|
8
8
|
const { normalizeSchema } = require('./schemas')
|
|
9
9
|
const { parseHeadOnSendHandlers } = require('./headRoute')
|
|
10
|
-
const
|
|
10
|
+
const {
|
|
11
|
+
FSTDEP007,
|
|
12
|
+
FSTDEP008,
|
|
13
|
+
FSTDEP014
|
|
14
|
+
} = require('./warnings')
|
|
11
15
|
|
|
12
16
|
const {
|
|
13
17
|
compileSchemasForValidation,
|
|
@@ -100,11 +104,11 @@ function buildRouting (options) {
|
|
|
100
104
|
hasRoute,
|
|
101
105
|
prepareRoute,
|
|
102
106
|
getDefaultRoute: function () {
|
|
103
|
-
|
|
107
|
+
FSTDEP014()
|
|
104
108
|
return router.defaultRoute
|
|
105
109
|
},
|
|
106
110
|
setDefaultRoute: function (defaultRoute) {
|
|
107
|
-
|
|
111
|
+
FSTDEP014()
|
|
108
112
|
if (typeof defaultRoute !== 'function') {
|
|
109
113
|
throw new FST_ERR_DEFAULT_ROUTE_INVALID_TYPE()
|
|
110
114
|
}
|
|
@@ -324,7 +328,7 @@ function buildRouting (options) {
|
|
|
324
328
|
})
|
|
325
329
|
|
|
326
330
|
if (opts.version) {
|
|
327
|
-
|
|
331
|
+
FSTDEP008()
|
|
328
332
|
constraints.version = opts.version
|
|
329
333
|
}
|
|
330
334
|
|
|
@@ -417,7 +421,7 @@ function buildRouting (options) {
|
|
|
417
421
|
const onSendHandlers = parseHeadOnSendHandlers(headOpts.onSend)
|
|
418
422
|
prepareRoute.call(this, { method: 'HEAD', url: path, options: { ...headOpts, onSend: onSendHandlers }, isFastify: true })
|
|
419
423
|
} else if (hasHEADHandler && exposeHeadRoute) {
|
|
420
|
-
|
|
424
|
+
FSTDEP007()
|
|
421
425
|
}
|
|
422
426
|
}
|
|
423
427
|
}
|
package/lib/server.js
CHANGED
|
@@ -4,7 +4,7 @@ const http = require('node:http')
|
|
|
4
4
|
const https = require('node:https')
|
|
5
5
|
const dns = require('node:dns')
|
|
6
6
|
|
|
7
|
-
const
|
|
7
|
+
const { FSTDEP011 } = require('./warnings')
|
|
8
8
|
const { kState, kOptions, kServerBindings } = require('./symbols')
|
|
9
9
|
const { onListenHookRunner } = require('./hooks')
|
|
10
10
|
const {
|
|
@@ -36,12 +36,12 @@ function createServer (options, httpHandler) {
|
|
|
36
36
|
if (arguments.length === 0) {
|
|
37
37
|
listenOptions = normalizeListenArgs([])
|
|
38
38
|
} else if (arguments.length > 0 && (firstArgType !== '[object Object]' && firstArgType !== '[object Function]')) {
|
|
39
|
-
|
|
39
|
+
FSTDEP011()
|
|
40
40
|
listenOptions = normalizeListenArgs(Array.from(arguments))
|
|
41
41
|
cb = listenOptions.cb
|
|
42
42
|
} else if (args.length > 1) {
|
|
43
43
|
// `.listen(obj, a, ..., n, callback )`
|
|
44
|
-
|
|
44
|
+
FSTDEP011()
|
|
45
45
|
// Deal with `.listen(port, host, backlog, [cb])`
|
|
46
46
|
const hostPath = listenOptions.path ? [listenOptions.path] : [listenOptions.port ?? 0, listenOptions.host ?? 'localhost']
|
|
47
47
|
Object.assign(listenOptions, normalizeListenArgs([...hostPath, ...args]))
|
|
@@ -163,29 +163,6 @@ function multipleBindings (mainServer, httpHandler, serverOpts, listenOptions, o
|
|
|
163
163
|
/* istanbul ignore next: the else won't be taken unless listening fails */
|
|
164
164
|
if (!_ignoreErr) {
|
|
165
165
|
this[kServerBindings].push(secondaryServer)
|
|
166
|
-
// Due to the nature of the feature is not possible to know
|
|
167
|
-
// ahead of time the number of bindings that will be made.
|
|
168
|
-
// For instance, each binding is hooked to be closed at their own
|
|
169
|
-
// pace through the `onClose` hook.
|
|
170
|
-
// It also allows them to handle possible connections already
|
|
171
|
-
// attached to them if any.
|
|
172
|
-
/* c8 ignore next 20 */
|
|
173
|
-
this.onClose((instance, done) => {
|
|
174
|
-
if (instance[kState].listening) {
|
|
175
|
-
// No new TCP connections are accepted
|
|
176
|
-
// We swallow any error from the secondary
|
|
177
|
-
// server
|
|
178
|
-
secondaryServer.close(() => done())
|
|
179
|
-
if (serverOpts.forceCloseConnections === 'idle') {
|
|
180
|
-
// Not needed in Node 19
|
|
181
|
-
secondaryServer.closeIdleConnections()
|
|
182
|
-
} else if (typeof secondaryServer.closeAllConnections === 'function' && serverOpts.forceCloseConnections) {
|
|
183
|
-
secondaryServer.closeAllConnections()
|
|
184
|
-
}
|
|
185
|
-
} else {
|
|
186
|
-
done()
|
|
187
|
-
}
|
|
188
|
-
})
|
|
189
166
|
}
|
|
190
167
|
|
|
191
168
|
if (bound === binding) {
|
|
@@ -196,7 +173,23 @@ function multipleBindings (mainServer, httpHandler, serverOpts, listenOptions, o
|
|
|
196
173
|
})
|
|
197
174
|
|
|
198
175
|
const secondaryServer = getServerInstance(serverOpts, httpHandler)
|
|
199
|
-
const closeSecondary = () => {
|
|
176
|
+
const closeSecondary = () => {
|
|
177
|
+
// To avoid fall into situations where the close of the
|
|
178
|
+
// secondary server is triggered before the preClose hook
|
|
179
|
+
// is done running, we better wait until the main server
|
|
180
|
+
// is closed.
|
|
181
|
+
// No new TCP connections are accepted
|
|
182
|
+
// We swallow any error from the secondary
|
|
183
|
+
// server
|
|
184
|
+
secondaryServer.close(() => {})
|
|
185
|
+
if (serverOpts.forceCloseConnections === 'idle') {
|
|
186
|
+
// Not needed in Node 19
|
|
187
|
+
secondaryServer.closeIdleConnections()
|
|
188
|
+
} else if (typeof secondaryServer.closeAllConnections === 'function' && serverOpts.forceCloseConnections) {
|
|
189
|
+
secondaryServer.closeAllConnections()
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
200
193
|
secondaryServer.on('upgrade', mainServer.emit.bind(mainServer, 'upgrade'))
|
|
201
194
|
mainServer.on('unref', closeSecondary)
|
|
202
195
|
mainServer.on('close', closeSecondary)
|
package/lib/validation.js
CHANGED
|
@@ -13,7 +13,7 @@ const {
|
|
|
13
13
|
FST_ERR_SCH_RESPONSE_SCHEMA_NOT_NESTED_2XX
|
|
14
14
|
} = require('./errors')
|
|
15
15
|
|
|
16
|
-
const
|
|
16
|
+
const { FSTWRN001 } = require('./warnings')
|
|
17
17
|
|
|
18
18
|
function compileSchemasForSerialization (context, compile) {
|
|
19
19
|
if (!context.schema || !context.schema.response) {
|
|
@@ -83,25 +83,25 @@ function compileSchemasForValidation (context, compile, isCustom) {
|
|
|
83
83
|
}
|
|
84
84
|
context[headersSchema] = compile({ schema: headersSchemaLowerCase, method, url, httpPart: 'headers' })
|
|
85
85
|
} else if (Object.prototype.hasOwnProperty.call(schema, 'headers')) {
|
|
86
|
-
|
|
86
|
+
FSTWRN001('headers', method, url)
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
if (schema.body) {
|
|
90
90
|
context[bodySchema] = compile({ schema: schema.body, method, url, httpPart: 'body' })
|
|
91
91
|
} else if (Object.prototype.hasOwnProperty.call(schema, 'body')) {
|
|
92
|
-
|
|
92
|
+
FSTWRN001('body', method, url)
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
if (schema.querystring) {
|
|
96
96
|
context[querystringSchema] = compile({ schema: schema.querystring, method, url, httpPart: 'querystring' })
|
|
97
97
|
} else if (Object.prototype.hasOwnProperty.call(schema, 'querystring')) {
|
|
98
|
-
|
|
98
|
+
FSTWRN001('querystring', method, url)
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
if (schema.params) {
|
|
102
102
|
context[paramsSchema] = compile({ schema: schema.params, method, url, httpPart: 'params' })
|
|
103
103
|
} else if (Object.prototype.hasOwnProperty.call(schema, 'params')) {
|
|
104
|
-
|
|
104
|
+
FSTWRN001('params', method, url)
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
|