fastify 5.11.0 → 5.11.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/.pi/bash-confirm-whitelist.json +180 -0
- package/docs/Reference/Server.md +18 -2
- package/docs/Reference/Validation-and-Serialization.md +13 -2
- package/docs/Reference/Warnings.md +2 -2
- package/fastify.d.ts +2 -0
- package/fastify.js +10 -3
- package/lib/warnings.js +11 -2
- package/package.json +1 -1
- package/test/close.test.js +39 -0
- package/test/http-methods/custom-http-methods.test.js +61 -0
- package/test/types/fastify.tst.ts +11 -0
- package/test/types/instance.tst.ts +2 -0
- package/test/validation-error-handling.test.js +34 -0
- package/types/instance.d.ts +4 -1
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
{
|
|
2
|
+
"entries": [
|
|
3
|
+
{
|
|
4
|
+
"type": "exact",
|
|
5
|
+
"value": "git fetch --all --prune --quiet && echo FETCH_OK || echo FETCH_FAILED",
|
|
6
|
+
"addedAt": "2026-02-07T10:03:03.909Z",
|
|
7
|
+
"note": "Always accept",
|
|
8
|
+
"source": "user"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"type": "exact",
|
|
12
|
+
"value": "npm install --ignore-scripts",
|
|
13
|
+
"addedAt": "2026-02-07T10:21:13.104Z",
|
|
14
|
+
"note": "Always accept",
|
|
15
|
+
"source": "user"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"type": "exact",
|
|
19
|
+
"value": "npm run coverage:ci-check-coverage",
|
|
20
|
+
"addedAt": "2026-02-07T15:10:08.412Z",
|
|
21
|
+
"note": "Always accept",
|
|
22
|
+
"source": "user"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"type": "exact",
|
|
26
|
+
"value": "node --test test/web-api.test.js",
|
|
27
|
+
"addedAt": "2026-02-07T15:24:46.872Z",
|
|
28
|
+
"note": "Always accept",
|
|
29
|
+
"source": "user"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"type": "exact",
|
|
33
|
+
"value": "gpg --list-secret-keys --keyid-format=long || true && git config --get user.signingkey && git config --get commit.gpgsign",
|
|
34
|
+
"addedAt": "2026-02-11T04:42:44.716Z",
|
|
35
|
+
"note": "Always accept",
|
|
36
|
+
"source": "user"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"type": "exact",
|
|
40
|
+
"value": "cd /home/matteo/repositories/fastify && npm run test:typescript",
|
|
41
|
+
"addedAt": "2026-02-19T20:22:59.298Z",
|
|
42
|
+
"note": "Always accept",
|
|
43
|
+
"source": "user"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"type": "exact",
|
|
47
|
+
"value": "cd /home/matteo/repositories/fastify && git checkout -- types/route.d.ts",
|
|
48
|
+
"addedAt": "2026-02-19T20:23:45.912Z",
|
|
49
|
+
"note": "Always accept",
|
|
50
|
+
"source": "user"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"type": "exact",
|
|
54
|
+
"value": "cd /home/matteo/repositories/fastify && git status --short && git diff -- types/route.d.ts test/types/route.test-d.ts | sed -n '1,220p'",
|
|
55
|
+
"addedAt": "2026-02-19T20:25:10.175Z",
|
|
56
|
+
"note": "Always accept",
|
|
57
|
+
"source": "user"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"type": "exact",
|
|
61
|
+
"value": "cd /home/matteo/repositories/fastify && git checkout -- types/route.d.ts test/types/route.test-d.ts && npm run test:typescript",
|
|
62
|
+
"addedAt": "2026-02-19T20:25:56.421Z",
|
|
63
|
+
"note": "Always accept",
|
|
64
|
+
"source": "user"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"type": "exact",
|
|
68
|
+
"value": "cd /home/matteo/repositories/fastify && npm run lint:eslint -- types/route.d.ts test/types/route.test-d.ts",
|
|
69
|
+
"addedAt": "2026-02-19T20:27:12.547Z",
|
|
70
|
+
"note": "Always accept",
|
|
71
|
+
"source": "user"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"type": "exact",
|
|
75
|
+
"value": "cd /home/matteo/repositories/fastify && git checkout -b fix/6513-route-hook-meta-return",
|
|
76
|
+
"addedAt": "2026-02-19T20:27:31.569Z",
|
|
77
|
+
"note": "Always accept",
|
|
78
|
+
"source": "user"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"type": "exact",
|
|
82
|
+
"value": "cd /home/matteo/repositories/fastify && git add types/route.d.ts test/types/route.test-d.ts && git commit -m \"fix(types): allow async route hooks in shorthand options\"",
|
|
83
|
+
"addedAt": "2026-02-19T20:27:35.261Z",
|
|
84
|
+
"note": "Always accept",
|
|
85
|
+
"source": "user"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"type": "exact",
|
|
89
|
+
"value": "cd /home/matteo/repositories/fastify && npx tsc /tmp/ctx-test2.ts --noEmit --strict",
|
|
90
|
+
"addedAt": "2026-02-19T20:44:45.451Z",
|
|
91
|
+
"note": "Always accept",
|
|
92
|
+
"source": "user"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"type": "exact",
|
|
96
|
+
"value": "cd /home/matteo/repositories/fastify && npx tsd --files test/types/hooks.test-d.ts",
|
|
97
|
+
"addedAt": "2026-02-19T20:47:16.815Z",
|
|
98
|
+
"note": "Always accept",
|
|
99
|
+
"source": "user"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"type": "exact",
|
|
103
|
+
"value": "cd /home/matteo/repositories/fastify && npx tsd --files test/types/route.test-d.ts",
|
|
104
|
+
"addedAt": "2026-02-19T20:47:37.607Z",
|
|
105
|
+
"note": "Always accept",
|
|
106
|
+
"source": "user"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"type": "exact",
|
|
110
|
+
"value": "cd /home/matteo/repositories/fastify && npx tsd",
|
|
111
|
+
"addedAt": "2026-02-19T20:48:17.812Z",
|
|
112
|
+
"note": "Always accept",
|
|
113
|
+
"source": "user"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"type": "exact",
|
|
117
|
+
"value": "cd /home/matteo/repositories/fastify && npm run lint:eslint -- types/route.d.ts && npx tsd --files test/types/hooks.test-d.ts && npx tsd --files test/types/route.test-d.ts",
|
|
118
|
+
"addedAt": "2026-02-19T20:51:05.173Z",
|
|
119
|
+
"note": "Always accept",
|
|
120
|
+
"source": "user"
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"type": "exact",
|
|
124
|
+
"value": "which gh && gh --version && gh auth status",
|
|
125
|
+
"addedAt": "2026-02-20T07:03:43.023Z",
|
|
126
|
+
"note": "Always accept",
|
|
127
|
+
"source": "user"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"type": "exact",
|
|
131
|
+
"value": "gh api repos/fastify/fastify/rulesets",
|
|
132
|
+
"addedAt": "2026-02-22T22:29:22.020Z",
|
|
133
|
+
"note": "Always accept",
|
|
134
|
+
"source": "user"
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"type": "exact",
|
|
138
|
+
"value": "node --test test/fastify-instance.test.js",
|
|
139
|
+
"addedAt": "2026-02-23T07:23:34.147Z",
|
|
140
|
+
"note": "Always accept",
|
|
141
|
+
"source": "user"
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"type": "exact",
|
|
145
|
+
"value": "nl -ba scripts/validate-ecosystem-links.js | sed -n '1,220p'",
|
|
146
|
+
"addedAt": "2026-02-23T07:23:55.927Z",
|
|
147
|
+
"note": "Always accept",
|
|
148
|
+
"source": "user"
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"type": "pattern",
|
|
152
|
+
"value": "^npx\\s+eslint\\s+[\\w./~-]+\\s+[\\w./~-]+\\s+[\\w./~-]+\\s+[\\w./~-]+$",
|
|
153
|
+
"addedAt": "2026-03-09T12:41:11.065Z",
|
|
154
|
+
"note": "Always accept generic",
|
|
155
|
+
"source": "ai"
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
"type": "pattern",
|
|
159
|
+
"value": "^node\\s+--test\\s+[\\w./~-]+\\s+[\\w./~-]+$",
|
|
160
|
+
"addedAt": "2026-03-09T12:41:58.425Z",
|
|
161
|
+
"note": "Always accept generic",
|
|
162
|
+
"source": "ai"
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"type": "pattern",
|
|
166
|
+
"value": "^npm\\s+run\\s+test:typescript$",
|
|
167
|
+
"addedAt": "2026-03-09T12:42:48.283Z",
|
|
168
|
+
"note": "Always accept generic",
|
|
169
|
+
"source": "ai"
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"type": "exact",
|
|
173
|
+
"value": "gh search code \"request.host org:fastify\" --limit 20 --json repository,path,url",
|
|
174
|
+
"addedAt": "2026-03-09T21:03:22.953Z",
|
|
175
|
+
"note": "Always accept exact",
|
|
176
|
+
"source": "user"
|
|
177
|
+
}
|
|
178
|
+
],
|
|
179
|
+
"version": 2
|
|
180
|
+
}
|
package/docs/Reference/Server.md
CHANGED
|
@@ -1707,6 +1707,13 @@ Fastify supports the `GET`, `HEAD`, `TRACE`, `DELETE`, `OPTIONS`,
|
|
|
1707
1707
|
The `addHttpMethod` method allows to add any non standard HTTP
|
|
1708
1708
|
methods to the server that are [supported by Node.js](https://nodejs.org/api/http.html#httpmethods).
|
|
1709
1709
|
|
|
1710
|
+
The method accepts an optional configuration object:
|
|
1711
|
+
|
|
1712
|
+
| Property | Type | Default | Description |
|
|
1713
|
+
| -------- | ---- | ------- | ----------- |
|
|
1714
|
+
| `hasBody` | `boolean` | `false` | Whether the method accepts a request body. |
|
|
1715
|
+
| `overrideExisting` | `boolean` | `false` | Whether to explicitly override an existing method. |
|
|
1716
|
+
|
|
1710
1717
|
```js
|
|
1711
1718
|
// Add a new HTTP method called 'MKCOL' that supports a request body
|
|
1712
1719
|
fastify.addHttpMethod('MKCOL', { hasBody: true, })
|
|
@@ -1725,8 +1732,17 @@ fastify.mkcol('/', (req, reply) => {
|
|
|
1725
1732
|
})
|
|
1726
1733
|
```
|
|
1727
1734
|
|
|
1728
|
-
|
|
1729
|
-
|
|
1735
|
+
Calling `addHttpMethod` for an existing method overrides its body behavior.
|
|
1736
|
+
|
|
1737
|
+
```js
|
|
1738
|
+
fastify.addHttpMethod('GET', {
|
|
1739
|
+
hasBody: true,
|
|
1740
|
+
overrideExisting: true
|
|
1741
|
+
})
|
|
1742
|
+
```
|
|
1743
|
+
|
|
1744
|
+
In Fastify v5, omitting `overrideExisting: true` emits `FSTDEP025`; in Fastify
|
|
1745
|
+
v6, it will throw an error.
|
|
1730
1746
|
|
|
1731
1747
|
#### addSchema
|
|
1732
1748
|
<a id="add-schema"></a>
|
|
@@ -876,14 +876,25 @@ with the following payload:
|
|
|
876
876
|
|
|
877
877
|
To handle errors inside the route, specify the `attachValidation` option. If
|
|
878
878
|
there is a validation error, the `validationError` property of the request will
|
|
879
|
-
contain the `Error` object
|
|
879
|
+
contain the same `Error` object Fastify would have sent on its own, so no
|
|
880
|
+
message has to be rebuilt from the raw validation result:
|
|
881
|
+
|
|
882
|
+
- `message` is the formatted message, identical to the one in the response
|
|
883
|
+
payload above (for example `body must have required property 'name'`). It is
|
|
884
|
+
produced by [`schemaErrorFormatter`](#schemaerrorformatter), so a custom
|
|
885
|
+
formatter is reflected here too.
|
|
886
|
+
- `validation` is the raw validation result, as returned by the validator.
|
|
887
|
+
- `validationContext` is the part of the request that failed validation
|
|
888
|
+
(`body`, `params`, `querystring` or `headers`).
|
|
889
|
+
- `code` is `FST_ERR_VALIDATION` and `statusCode` is `400`.
|
|
880
890
|
|
|
881
891
|
```js
|
|
882
892
|
const fastify = Fastify()
|
|
883
893
|
|
|
884
894
|
fastify.post('/', { schema, attachValidation: true }, function (req, reply) {
|
|
885
895
|
if (req.validationError) {
|
|
886
|
-
// `req.validationError.
|
|
896
|
+
// `req.validationError.message` is the formatted message
|
|
897
|
+
// `req.validationError.validation` contains the raw validation result
|
|
887
898
|
reply.code(400).send(req.validationError)
|
|
888
899
|
}
|
|
889
900
|
})
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
- [FSTDEP022](#FSTDEP022)
|
|
13
13
|
- [FSTDEP023](#FSTDEP023)
|
|
14
14
|
- [FSTDEP024](#FSTDEP024)
|
|
15
|
+
- [FSTDEP025](#FSTDEP025)
|
|
15
16
|
|
|
16
17
|
## Warnings
|
|
17
18
|
|
|
@@ -46,8 +47,6 @@ Disabling warnings is not recommended and may cause unexpected behavior.
|
|
|
46
47
|
| <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) |
|
|
47
48
|
| <a id="FSTWRN003">FSTWRN003</a> | The `%s` plugin mixes async and callback styles, which may lead to unhandled rejections. | Do not mix async and callback style. | [#6011](https://github.com/fastify/fastify/pull/6011) |
|
|
48
49
|
| <a id="FSTWRN004">FSTWRN004</a> | An `errorHandler` is being overridden in the same scope, which can lead to subtle bugs. | Avoid calling `setErrorHandler` more than once in the same scope. For more information, see [Server documentation](https://fastify.dev/docs/latest/Reference/Server/#allowerrorhandleroverride). | [#6104](https://github.com/fastify/fastify/pull/6104) |
|
|
49
|
-
|
|
50
|
-
|
|
51
50
|
### Fastify Deprecation Codes
|
|
52
51
|
|
|
53
52
|
Deprecation codes are supported by the Node.js CLI options:
|
|
@@ -62,3 +61,4 @@ Deprecation codes are supported by the Node.js CLI options:
|
|
|
62
61
|
| <a id="FSTDEP022">FSTDEP022</a> | You are trying to access the deprecated router options on top option properties. | Use `options.routerOptions`. | [#5985](https://github.com/fastify/fastify/pull/5985)
|
|
63
62
|
| <a id="FSTDEP023">FSTDEP023</a> | `disableRequestLogging` top-level option is deprecated. | Pass a `LogController` instance via the `logController` option with `disableRequestLogging` in its constructor instead. |
|
|
64
63
|
| <a id="FSTDEP024">FSTDEP024</a> | `requestIdLogLabel` top-level option is deprecated. | Pass a `LogController` instance via the `logController` option with `requestIdLogLabel` in its constructor instead. |
|
|
64
|
+
| <a id="FSTDEP025">FSTDEP025</a> | Calling `addHttpMethod` for an existing HTTP method without `{ overrideExisting: true }` is deprecated. | Pass `{ overrideExisting: true }` to make the override explicit. | [#6879](https://github.com/fastify/fastify/pull/6879) |
|
package/fastify.d.ts
CHANGED
|
@@ -69,6 +69,7 @@ declare namespace fastify {
|
|
|
69
69
|
Logger extends FastifyBaseLogger = FastifyBaseLogger
|
|
70
70
|
> = FastifyServerOptions<Server, Logger> & {
|
|
71
71
|
https: https.ServerOptions | null
|
|
72
|
+
http2?: false
|
|
72
73
|
}
|
|
73
74
|
|
|
74
75
|
export type FastifyHttpOptions<
|
|
@@ -76,6 +77,7 @@ declare namespace fastify {
|
|
|
76
77
|
Logger extends FastifyBaseLogger = FastifyBaseLogger
|
|
77
78
|
> = FastifyServerOptions<Server, Logger> & {
|
|
78
79
|
http?: http.ServerOptions | null
|
|
80
|
+
http2?: false
|
|
79
81
|
}
|
|
80
82
|
|
|
81
83
|
type FindMyWayVersion<RawServer extends RawServerBase> = RawServer extends http.Server
|
package/fastify.js
CHANGED
|
@@ -80,7 +80,7 @@ const {
|
|
|
80
80
|
} = errorCodes
|
|
81
81
|
|
|
82
82
|
const { buildErrorHandler } = require('./lib/error-handler.js')
|
|
83
|
-
const { FSTWRN004, FSTDEP023, FSTDEP024 } = require('./lib/warnings.js')
|
|
83
|
+
const { FSTWRN004, FSTDEP023, FSTDEP024, FSTDEP025 } = require('./lib/warnings.js')
|
|
84
84
|
|
|
85
85
|
const initChannel = diagnostics.channel('fastify.initialization')
|
|
86
86
|
|
|
@@ -392,7 +392,7 @@ function fastify (serverOptions) {
|
|
|
392
392
|
if (forceCloseConnections === 'idle' && options.serverFactory) {
|
|
393
393
|
instance.server.closeIdleConnections()
|
|
394
394
|
/* istanbul ignore next: Cannot test this without Node.js core support */
|
|
395
|
-
} else if (serverHasCloseAllConnections && forceCloseConnections) {
|
|
395
|
+
} else if (serverHasCloseAllConnections && forceCloseConnections === true) {
|
|
396
396
|
instance.server.closeAllConnections()
|
|
397
397
|
} else if (forceCloseConnections === true) {
|
|
398
398
|
for (const conn of fastify[kKeepAliveConnections]) {
|
|
@@ -823,11 +823,18 @@ function fastify (serverOptions) {
|
|
|
823
823
|
return this
|
|
824
824
|
}
|
|
825
825
|
|
|
826
|
-
function addHttpMethod (method, { hasBody = false } = {}) {
|
|
826
|
+
function addHttpMethod (method, { hasBody = false, overrideExisting = false } = {}) {
|
|
827
827
|
if (typeof method !== 'string' || http.METHODS.indexOf(method) === -1) {
|
|
828
828
|
throw new FST_ERR_ROUTE_METHOD_INVALID()
|
|
829
829
|
}
|
|
830
830
|
|
|
831
|
+
const alreadyExists = this[kSupportedHTTPMethods].bodyless.has(method) ||
|
|
832
|
+
this[kSupportedHTTPMethods].bodywith.has(method)
|
|
833
|
+
|
|
834
|
+
if (alreadyExists && !overrideExisting) {
|
|
835
|
+
FSTDEP025(method)
|
|
836
|
+
}
|
|
837
|
+
|
|
831
838
|
if (hasBody === true) {
|
|
832
839
|
this[kSupportedHTTPMethods].bodywith.add(method)
|
|
833
840
|
this[kSupportedHTTPMethods].bodyless.delete(method)
|
package/lib/warnings.js
CHANGED
|
@@ -9,9 +9,10 @@ const { createWarning } = require('process-warning')
|
|
|
9
9
|
* - FSTDEP022
|
|
10
10
|
* - FSTDEP023
|
|
11
11
|
* - FSTDEP024
|
|
12
|
+
* - FSTDEP025
|
|
12
13
|
*
|
|
13
14
|
* Deprecation Codes FSTDEP001 - FSTDEP021 were used by v4 and MUST NOT be reused.
|
|
14
|
-
* - FSTDEP022
|
|
15
|
+
* - FSTDEP022 - FSTDEP025 are used by v5 and MUST NOT be reused.
|
|
15
16
|
* Warning Codes FSTWRN001 - FSTWRN002 were used by v4 and MUST NOT be reused.
|
|
16
17
|
*/
|
|
17
18
|
|
|
@@ -64,6 +65,13 @@ const FSTDEP024 = createWarning({
|
|
|
64
65
|
unlimited: true
|
|
65
66
|
})
|
|
66
67
|
|
|
68
|
+
const FSTDEP025 = createWarning({
|
|
69
|
+
name: 'FastifyDeprecation',
|
|
70
|
+
code: 'FSTDEP025',
|
|
71
|
+
message: 'Calling addHttpMethod for existing method "%s" without { overrideExisting: true } is deprecated. In Fastify v6, this will throw an error.',
|
|
72
|
+
unlimited: true
|
|
73
|
+
})
|
|
74
|
+
|
|
67
75
|
module.exports = {
|
|
68
76
|
FSTWRN001,
|
|
69
77
|
FSTWRN003,
|
|
@@ -71,5 +79,6 @@ module.exports = {
|
|
|
71
79
|
FSTSEC001,
|
|
72
80
|
FSTDEP022,
|
|
73
81
|
FSTDEP023,
|
|
74
|
-
FSTDEP024
|
|
82
|
+
FSTDEP024,
|
|
83
|
+
FSTDEP025
|
|
75
84
|
}
|
package/package.json
CHANGED
package/test/close.test.js
CHANGED
|
@@ -704,3 +704,42 @@ test('preClose execution order', (t, done) => {
|
|
|
704
704
|
})
|
|
705
705
|
})
|
|
706
706
|
})
|
|
707
|
+
|
|
708
|
+
test('does not destroy connections with in-flight requests (forceCloseConnections - idle)', { skip: noSupport }, async t => {
|
|
709
|
+
const fastify = Fastify({ forceCloseConnections: 'idle' })
|
|
710
|
+
|
|
711
|
+
fastify.get('/', async () => {
|
|
712
|
+
// the server starts closing while this request is still being served
|
|
713
|
+
fastify.close()
|
|
714
|
+
await sleep(200)
|
|
715
|
+
return { hello: 'world' }
|
|
716
|
+
})
|
|
717
|
+
|
|
718
|
+
await fastify.listen({ port: 0 })
|
|
719
|
+
|
|
720
|
+
const client = new Client('http://localhost:' + fastify.server.address().port)
|
|
721
|
+
t.after(() => client.close())
|
|
722
|
+
|
|
723
|
+
const response = await client.request({ path: '/', method: 'GET' })
|
|
724
|
+
t.assert.strictEqual(response.statusCode, 200)
|
|
725
|
+
t.assert.deepStrictEqual(await response.body.json(), { hello: 'world' })
|
|
726
|
+
})
|
|
727
|
+
|
|
728
|
+
test('does not destroy connections with in-flight requests (default options)', async t => {
|
|
729
|
+
const fastify = Fastify()
|
|
730
|
+
|
|
731
|
+
fastify.get('/', async () => {
|
|
732
|
+
fastify.close()
|
|
733
|
+
await sleep(200)
|
|
734
|
+
return { hello: 'world' }
|
|
735
|
+
})
|
|
736
|
+
|
|
737
|
+
await fastify.listen({ port: 0 })
|
|
738
|
+
|
|
739
|
+
const client = new Client('http://localhost:' + fastify.server.address().port)
|
|
740
|
+
t.after(() => client.close())
|
|
741
|
+
|
|
742
|
+
const response = await client.request({ path: '/', method: 'GET' })
|
|
743
|
+
t.assert.strictEqual(response.statusCode, 200)
|
|
744
|
+
t.assert.deepStrictEqual(await response.body.json(), { hello: 'world' })
|
|
745
|
+
})
|
|
@@ -112,3 +112,64 @@ test('addHttpMethod rejects fake http method', t => {
|
|
|
112
112
|
const fastify = Fastify()
|
|
113
113
|
t.assert.throws(() => { fastify.addHttpMethod('FOOO') }, /Provided method is invalid!/)
|
|
114
114
|
})
|
|
115
|
+
|
|
116
|
+
test('addHttpMethod warns when overriding an existing method', (t, done) => {
|
|
117
|
+
const fastify = Fastify()
|
|
118
|
+
const onWarning = warning => {
|
|
119
|
+
t.assert.strictEqual(warning.name, 'FastifyDeprecation')
|
|
120
|
+
t.assert.strictEqual(warning.code, 'FSTDEP025')
|
|
121
|
+
done()
|
|
122
|
+
}
|
|
123
|
+
process.once('warning', onWarning)
|
|
124
|
+
|
|
125
|
+
t.after(() => {
|
|
126
|
+
fastify.close()
|
|
127
|
+
process.removeListener('warning', onWarning)
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
fastify.addHttpMethod('GET', { hasBody: true })
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
test('addHttpMethod does not warn when overriding an existing method explicitly', t => {
|
|
134
|
+
const doNotWarn = () => {
|
|
135
|
+
t.assert.fail('should not warn')
|
|
136
|
+
}
|
|
137
|
+
process.on('warning', doNotWarn)
|
|
138
|
+
|
|
139
|
+
const fastify = Fastify()
|
|
140
|
+
t.after(() => {
|
|
141
|
+
fastify.close()
|
|
142
|
+
process.removeListener('warning', doNotWarn)
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
fastify.addHttpMethod('POST', { overrideExisting: true })
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
test('addHttpMethod can change an existing method body behavior', async t => {
|
|
149
|
+
const fastify = Fastify()
|
|
150
|
+
|
|
151
|
+
fastify.addHttpMethod('GET', {
|
|
152
|
+
hasBody: true,
|
|
153
|
+
overrideExisting: true
|
|
154
|
+
})
|
|
155
|
+
fastify.route({
|
|
156
|
+
method: 'GET',
|
|
157
|
+
url: '/',
|
|
158
|
+
exposeHeadRoute: false,
|
|
159
|
+
schema: {
|
|
160
|
+
body: {
|
|
161
|
+
type: 'object'
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
handler: async request => request.body
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
const response = await fastify.inject({
|
|
168
|
+
method: 'GET',
|
|
169
|
+
url: '/',
|
|
170
|
+
payload: { hello: 'world' }
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
t.assert.strictEqual(response.statusCode, 200)
|
|
174
|
+
t.assert.deepStrictEqual(response.json(), { hello: 'world' })
|
|
175
|
+
})
|
|
@@ -68,6 +68,17 @@ expect(fastify({ schemaController: {} })).type.toBe<
|
|
|
68
68
|
FastifyInstance<http.Server, http.IncomingMessage, http.ServerResponse> &
|
|
69
69
|
SafePromiseLike<FastifyInstance<http.Server, http.IncomingMessage, http.ServerResponse>>
|
|
70
70
|
>()
|
|
71
|
+
|
|
72
|
+
expect(fastify({ http2: false })).type.toBe<
|
|
73
|
+
FastifyInstance<http.Server, http.IncomingMessage, http.ServerResponse> &
|
|
74
|
+
SafePromiseLike<FastifyInstance<http.Server, http.IncomingMessage, http.ServerResponse>>
|
|
75
|
+
>()
|
|
76
|
+
|
|
77
|
+
expect(fastify({ https: {}, http2: false })).type.toBe<
|
|
78
|
+
FastifyInstance<https.Server, http.IncomingMessage, http.ServerResponse> &
|
|
79
|
+
SafePromiseLike<FastifyInstance<https.Server, http.IncomingMessage, http.ServerResponse>>
|
|
80
|
+
>()
|
|
81
|
+
|
|
71
82
|
expect(
|
|
72
83
|
fastify({
|
|
73
84
|
schemaController: {
|
|
@@ -215,6 +215,8 @@ function invalidSchemaErrorFormatter (err: Error) {
|
|
|
215
215
|
server.setSchemaErrorFormatter(invalidSchemaErrorFormatter)
|
|
216
216
|
|
|
217
217
|
expect(server.addHttpMethod('SEARCH', { hasBody: true })).type.toBe<FastifyInstance>()
|
|
218
|
+
expect(server.addHttpMethod('GET', { overrideExisting: true })).type.toBe<FastifyInstance>()
|
|
219
|
+
expect(server.addHttpMethod('POST', { hasBody: true, overrideExisting: true })).type.toBe<FastifyInstance>()
|
|
218
220
|
|
|
219
221
|
// test listen opts objects
|
|
220
222
|
const options: FastifyListenOptions = {}
|
|
@@ -218,6 +218,40 @@ test('should be able to attach validation to request', async (t) => {
|
|
|
218
218
|
t.assert.strictEqual(response.statusCode, 400)
|
|
219
219
|
})
|
|
220
220
|
|
|
221
|
+
test('attached validationError exposes the same message sent by the default handler', async (t) => {
|
|
222
|
+
t.plan(4)
|
|
223
|
+
|
|
224
|
+
const fastify = Fastify()
|
|
225
|
+
|
|
226
|
+
fastify.post('/attached', { schema, attachValidation: true }, function (req, reply) {
|
|
227
|
+
reply.code(400).send({
|
|
228
|
+
message: req.validationError.message,
|
|
229
|
+
code: req.validationError.code,
|
|
230
|
+
statusCode: req.validationError.statusCode,
|
|
231
|
+
validationContext: req.validationError.validationContext
|
|
232
|
+
})
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
fastify.post('/default', { schema }, echoBody)
|
|
236
|
+
|
|
237
|
+
const payload = { hello: 'michelangelo' }
|
|
238
|
+
const attached = await fastify.inject({ method: 'POST', payload, url: '/attached' })
|
|
239
|
+
const notAttached = await fastify.inject({ method: 'POST', payload, url: '/default' })
|
|
240
|
+
|
|
241
|
+
const attachedBody = attached.json()
|
|
242
|
+
|
|
243
|
+
t.assert.deepStrictEqual(attachedBody, {
|
|
244
|
+
message: "body must have required property 'name'",
|
|
245
|
+
code: 'FST_ERR_VALIDATION',
|
|
246
|
+
statusCode: 400,
|
|
247
|
+
validationContext: 'body'
|
|
248
|
+
})
|
|
249
|
+
|
|
250
|
+
t.assert.strictEqual(attachedBody.message, notAttached.json().message)
|
|
251
|
+
t.assert.strictEqual(attached.statusCode, 400)
|
|
252
|
+
t.assert.strictEqual(notAttached.statusCode, 400)
|
|
253
|
+
})
|
|
254
|
+
|
|
221
255
|
test('should respect when attachValidation is explicitly set to false', async (t) => {
|
|
222
256
|
t.plan(2)
|
|
223
257
|
|
package/types/instance.d.ts
CHANGED
|
@@ -663,7 +663,10 @@ export interface FastifyInstance<
|
|
|
663
663
|
* Methods defined by default include `GET`, `HEAD`, `TRACE`, `DELETE`,
|
|
664
664
|
* `OPTIONS`, `PATCH`, `PUT` and `POST`
|
|
665
665
|
*/
|
|
666
|
-
addHttpMethod(method: string, methodOptions?: {
|
|
666
|
+
addHttpMethod(method: string, methodOptions?: {
|
|
667
|
+
hasBody?: boolean;
|
|
668
|
+
overrideExisting?: boolean;
|
|
669
|
+
}): FastifyInstance<RawServer, RawRequest, RawReply,
|
|
667
670
|
Logger, TypeProvider>;
|
|
668
671
|
/**
|
|
669
672
|
* Fastify default JSON parser
|