fastify 3.19.0 → 3.20.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/docs/ContentTypeParser.md +56 -2
- package/docs/Decorators.md +3 -0
- package/docs/Ecosystem.md +5 -1
- package/docs/Getting-Started.md +1 -1
- package/docs/Reply.md +6 -5
- package/docs/Request.md +2 -0
- package/docs/Routes.md +3 -3
- package/docs/Server.md +7 -5
- package/docs/TypeScript.md +1 -1
- package/fastify.d.ts +4 -2
- package/fastify.js +21 -2
- package/lib/contentTypeParser.js +46 -1
- package/lib/logger.js +1 -1
- package/lib/pluginUtils.js +3 -1
- package/lib/reply.js +6 -2
- package/lib/route.js +6 -3
- package/package.json +4 -4
- package/test/async-await.test.js +73 -0
- package/test/content-parser.test.js +76 -0
- package/test/custom-parser.test.js +203 -0
- package/test/internals/version.test.js +43 -0
- package/test/route.test.js +56 -0
- package/test/types/content-type-parser.test-d.ts +8 -0
- package/test/types/fastify.test-d.ts +16 -0
- package/test/types/instance.test-d.ts +40 -2
- package/test/types/logger.test-d.ts +23 -1
- package/test/types/reply.test-d.ts +2 -0
- package/test/types/request.test-d.ts +4 -0
- package/types/content-type-parser.d.ts +4 -0
- package/types/instance.d.ts +37 -6
- package/types/logger.d.ts +1 -0
- package/types/reply.d.ts +2 -0
- package/types/request.d.ts +2 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<h1 align="center">Fastify</h1>
|
|
2
2
|
|
|
3
3
|
## `Content-Type` Parser
|
|
4
|
-
Natively, Fastify only supports `'application/json'` and `'text/plain'` content types. The default charset is `utf-8`. If you need to support different content types, you can use the `addContentTypeParser` API. *The default JSON and/or plain text parser can be changed.*
|
|
4
|
+
Natively, Fastify only supports `'application/json'` and `'text/plain'` content types. The default charset is `utf-8`. If you need to support different content types, you can use the `addContentTypeParser` API. *The default JSON and/or plain text parser can be changed or removed.*
|
|
5
5
|
|
|
6
6
|
*Note: If you decide to specify your own content type with the `Content-Type` header, UTF-8 will not be the default. Be sure to include UTF-8 like this `text/html; charset=utf-8`.*
|
|
7
7
|
|
|
@@ -56,7 +56,11 @@ fastify.addContentTypeParser('application/vnd.custom', (request, body, done) =>
|
|
|
56
56
|
fastify.addContentTypeParser('application/vnd.custom+xml', (request, body, done) => {} )
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
Besides the `addContentTypeParser` API there are further APIs that can be used. These are `hasContentTypeParser`, `removeContentTypeParser` and `removeAllContentTypeParsers`.
|
|
60
|
+
|
|
61
|
+
#### hasContentTypeParser
|
|
62
|
+
|
|
63
|
+
You can use the `hasContentTypeParser` API to find if a specific content type parser already exists.
|
|
60
64
|
|
|
61
65
|
```js
|
|
62
66
|
if (!fastify.hasContentTypeParser('application/jsoff')){
|
|
@@ -68,6 +72,40 @@ if (!fastify.hasContentTypeParser('application/jsoff')){
|
|
|
68
72
|
}
|
|
69
73
|
```
|
|
70
74
|
|
|
75
|
+
#### removeContentTypeParser
|
|
76
|
+
|
|
77
|
+
With `removeContentTypeParser` a single or an array of content types can be removed. The method supports `string` and
|
|
78
|
+
`RegExp` content types.
|
|
79
|
+
|
|
80
|
+
```js
|
|
81
|
+
fastify.addContentTypeParser('text/xml', function (request, payload, done) {
|
|
82
|
+
xmlParser(payload, function (err, body) {
|
|
83
|
+
done(err, body)
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
// Removes the both built-in content type parsers so that only the content type parser for text/html is available
|
|
88
|
+
fastiy.removeContentTypeParser(['application/json', 'text/plain'])
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
#### removeAllContentTypeParsers
|
|
92
|
+
|
|
93
|
+
In the example from just above, it is noticeable that we need to specify each content type that we want to remove.
|
|
94
|
+
To solve this problem Fastify provides the `removeAllContentTypeParsers` API. This can be used to remove all currently existing content type parsers.
|
|
95
|
+
In the example below we achieve exactly the same as in the example above except that we do not need to specify each content type to delete.
|
|
96
|
+
Just like `removeContentTypeParser`, this API supports encapsulation. The API is especially useful if you want to register a
|
|
97
|
+
[catch-all content type parser](#Catch-All) that should be executed for every content type and the built-in parsers should be ignored as well.
|
|
98
|
+
|
|
99
|
+
```js
|
|
100
|
+
fastiy.removeAllContentTypeParsers()
|
|
101
|
+
|
|
102
|
+
fastify.addContentTypeParser('text/xml', function (request, payload, done) {
|
|
103
|
+
xmlParser(payload, function (err, body) {
|
|
104
|
+
done(err, body)
|
|
105
|
+
})
|
|
106
|
+
})
|
|
107
|
+
```
|
|
108
|
+
|
|
71
109
|
**Notice**: The old syntaxes `function(req, done)` and `async function(req)` for the parser are still supported but they are deprecated.
|
|
72
110
|
|
|
73
111
|
#### Body Parser
|
|
@@ -140,3 +178,19 @@ fastify.route({
|
|
|
140
178
|
```
|
|
141
179
|
|
|
142
180
|
For piping file uploads you may want to check out [this plugin](https://github.com/fastify/fastify-multipart).
|
|
181
|
+
|
|
182
|
+
If you really want the content type parser to be executed on all content types and not only on those that don't have a
|
|
183
|
+
specific one, you should call the `removeAllContentTypeParsers` method first.
|
|
184
|
+
|
|
185
|
+
```js
|
|
186
|
+
// Without this call, the request body with the content type application/json would be processed by the built in json parser
|
|
187
|
+
fastify.removeAllContentTypeParsers()
|
|
188
|
+
|
|
189
|
+
fastify.addContentTypeParser('*', function (request, payload, done) {
|
|
190
|
+
var data = ''
|
|
191
|
+
payload.on('data', chunk => { data += chunk })
|
|
192
|
+
payload.on('end', () => {
|
|
193
|
+
done(null, data)
|
|
194
|
+
})
|
|
195
|
+
})
|
|
196
|
+
```
|
package/docs/Decorators.md
CHANGED
|
@@ -117,6 +117,9 @@ upon "greet" and "log" decorators:
|
|
|
117
117
|
fastify.decorate('utility', fn, ['greet', 'log'])
|
|
118
118
|
```
|
|
119
119
|
|
|
120
|
+
Note: using an arrow function will break the binding of `this` to the
|
|
121
|
+
`FastifyInstance`.
|
|
122
|
+
|
|
120
123
|
If a dependency is not satisfied, the `decorate` method will throw an exception.
|
|
121
124
|
The dependency check is performed before the server instance is booted. Thus,
|
|
122
125
|
it cannot occur during runtime.
|
package/docs/Ecosystem.md
CHANGED
|
@@ -102,6 +102,7 @@ Plugins maintained by the Fastify team are listed under [Core](#core) while plug
|
|
|
102
102
|
- [`fastify-file-upload`](https://github.com/huangang/fastify-file-upload) Fastify plugin for uploading files.
|
|
103
103
|
- [`fastify-firebase`](https://github.com/now-ims/fastify-firebase) Fastify plugin for [Firebase Admin SDK](https://firebase.google.com/docs/admin/setup) to Fastify so you can easily use Firebase Auth, Firestore, Cloud Storage, Cloud Messaging, and more.
|
|
104
104
|
- [`fastify-firebase-auth`](https://github.com/oxsav/fastify-firebase-auth) Firebase Authentication for Fastify supporting all of the methods relating to the authentication API.
|
|
105
|
+
- [`fastify-formidable`](https://github.com/climba03003/fastify-formidable) Handy plugin to provide multipart support and fastify-swagger integration.
|
|
105
106
|
- [`fastify-gcloud-trace`](https://github.com/mkinoshi/fastify-gcloud-trace) [Google Cloud Trace API](https://cloud.google.com/trace/docs/reference) Connector for Fastify.
|
|
106
107
|
- [`fastify-get-head`](https://github.com/MetCoder95/fastify-get-head) Small plugin to set a new HEAD route handler for each GET route previously registered in Fastify.
|
|
107
108
|
- [`fastify-good-sessions`](https://github.com/Phara0h/fastify-good-sessions) A good Fastify sessions plugin focused on speed.
|
|
@@ -161,6 +162,7 @@ Plugins maintained by the Fastify team are listed under [Core](#core) while plug
|
|
|
161
162
|
- [`fastify-qs`](https://github.com/webdevium/fastify-qs) A plugin for Fastify that adds support for parsing URL query parameters with [qs](https://github.com/ljharb/qs).
|
|
162
163
|
- [`fastify-raw-body`](https://github.com/Eomm/fastify-raw-body) Add the `request.rawBody` field.
|
|
163
164
|
- [`fastify-rbac`](https://gitlab.com/m03geek/fastify-rbac) Fastify role-based access control plugin.
|
|
165
|
+
- [`fastify-recaptcha`](https://github.com/qwertyforce/fastify-recaptcha) Fastify plugin for recaptcha verification.
|
|
164
166
|
- [`fastify-redis-channels`](https://github.com/hearit-io/fastify-redis-channels) A plugin for fast, reliable, and scalable channels implementation based on Redis streams.
|
|
165
167
|
- [`fastify-register-routes`](https://github.com/israeleriston/fastify-register-routes) Plugin to automatically load routes from a specified path and optionally limit loaded file names by a regular expression.
|
|
166
168
|
- [`fastify-response-time`](https://github.com/lolo32/fastify-response-time) Add `X-Response-Time` header at each request for Fastify, in milliseconds.
|
|
@@ -168,6 +170,7 @@ Plugins maintained by the Fastify team are listed under [Core](#core) while plug
|
|
|
168
170
|
- [`fastify-resty`](https://github.com/FastifyResty/fastify-resty) Fastify-based web framework with REST API routes auto-generation for TypeORM entities using DI and decorators.
|
|
169
171
|
- [`fastify-reverse-routes`](https://github.com/dimonnwc3/fastify-reverse-routes) Fastify reverse routes plugin, allows to defined named routes and build path using name and parameters.
|
|
170
172
|
- [`fastify-rob-config`](https://github.com/jeromemacias/fastify-rob-config) Fastify Rob-Config integration.
|
|
173
|
+
- [`fastify-route-group`](https://github.com/TakNePoidet/fastify-route-group) Convenient grouping and inheritance of routes
|
|
171
174
|
- [`fastify-schema-constraint`](https://github.com/Eomm/fastify-schema-constraint) Choose the JSON schema to use based on request parameters.
|
|
172
175
|
- [`fastify-schema-to-typescript`](https://github.com/thomasthiebaud/fastify-schema-to-typescript) Generate typescript types based on your JSON/YAML validation schemas so they are always in sync.
|
|
173
176
|
- [`fastify-secure-session`](https://github.com/mcollina/fastify-secure-session) Create a secure stateless cookie session for Fastify.
|
|
@@ -175,6 +178,7 @@ Plugins maintained by the Fastify team are listed under [Core](#core) while plug
|
|
|
175
178
|
- [`fastify-sequelize`](https://github.com/lyquocnam/fastify-sequelize) Fastify plugin work with Sequelize (adapter for NodeJS -> Sqlite, Mysql, Mssql, Postgres).
|
|
176
179
|
- [`fastify-server-session`](https://github.com/jsumners/fastify-server-session) A session plugin with support for arbitrary backing caches via `fastify-caching`.
|
|
177
180
|
- [`fastify-session`](https://github.com/SerayaEryn/fastify-session) a session plugin for Fastify.
|
|
181
|
+
- [`fastify-slonik`](https://github.com/Unbuttun/fastify-slonik) Fastify Slonik plugin, with this you can use slonik in every part of your server.
|
|
178
182
|
- [`fastify-soap-client`](https://github.com/fastify/fastify-soap-client) a SOAP client plugin for Fastify.
|
|
179
183
|
- [`fastify-socket.io`](https://github.com/alemagio/fastify-socket.io) a Socket.io plugin for Fastify.
|
|
180
184
|
- [`fastify-sse`](https://github.com/lolo32/fastify-sse) to provide Server-Sent Events with `reply.sse( … )` to Fastify.
|
|
@@ -200,4 +204,4 @@ Plugins maintained by the Fastify team are listed under [Core](#core) while plug
|
|
|
200
204
|
- [`nstats`](https://github.com/Phara0h/nstats) A fast and compact way to get all your network and process stats for your node application. Websocket, HTTP/S, and prometheus compatible!
|
|
201
205
|
- [`oas-fastify`](https://github.com/ahmadnassri/node-oas-fastify) OAS 3.x to Fastify routes automation. Automatically generates route handlers with fastify configuration and validation.
|
|
202
206
|
- [`openapi-validator-middleware`](https://github.com/PayU/openapi-validator-middleware#fastify) Swagger and OpenAPI 3.0 spec-based request validation middleware that supports Fastify.
|
|
203
|
-
- [`fastify
|
|
207
|
+
- [`sequelize-fastify`](https://github.com/hsynlms/sequelize-fastify) A simple and lightweight Sequelize plugin for Fastify.
|
package/docs/Getting-Started.md
CHANGED
|
@@ -184,7 +184,7 @@ async function routes (fastify, options) {
|
|
|
184
184
|
|
|
185
185
|
fastify.get('/animals/:animal', async (request, reply) => {
|
|
186
186
|
const result = await collection.findOne({ animal: request.params.animal })
|
|
187
|
-
if (result
|
|
187
|
+
if (!result) {
|
|
188
188
|
throw new Error('Invalid value')
|
|
189
189
|
}
|
|
190
190
|
return result
|
package/docs/Reply.md
CHANGED
|
@@ -53,10 +53,11 @@ and properties:
|
|
|
53
53
|
- `.serializer(function)` - Sets a custom serializer for the payload.
|
|
54
54
|
- `.send(payload)` - Sends the payload to the user, could be a plain text, a buffer, JSON, stream, or an Error object.
|
|
55
55
|
- `.sent` - A boolean value that you can use if you need to know if `send` has already been called.
|
|
56
|
-
- `.raw` - The [`http.ServerResponse`](https://nodejs.org/dist/latest/docs/api/http.html#http_class_http_serverresponse) from Node core.
|
|
57
|
-
- `.res` *(deprecated, use `.raw` instead)* - The [`http.ServerResponse`](https://nodejs.org/dist/latest/docs/api/http.html#http_class_http_serverresponse) from Node core.
|
|
56
|
+
- `.raw` - The [`http.ServerResponse`](https://nodejs.org/dist/latest-v14.x/docs/api/http.html#http_class_http_serverresponse) from Node core.
|
|
57
|
+
- `.res` *(deprecated, use `.raw` instead)* - The [`http.ServerResponse`](https://nodejs.org/dist/latest-v14.x/docs/api/http.html#http_class_http_serverresponse) from Node core.
|
|
58
58
|
- `.log` - The logger instance of the incoming request.
|
|
59
59
|
- `.request` - The incoming request.
|
|
60
|
+
- `.context` - Access the [Request's context](Request.md#Request) property.
|
|
60
61
|
|
|
61
62
|
```js
|
|
62
63
|
fastify.get('/', options, function (request, reply) {
|
|
@@ -108,7 +109,7 @@ fastify.get('/', async function (req, rep) {
|
|
|
108
109
|
Sets a response header. If the value is omitted or undefined, it is coerced
|
|
109
110
|
to `''`.
|
|
110
111
|
|
|
111
|
-
For more information, see [`http.ServerResponse#setHeader`](https://nodejs.org/dist/latest/docs/api/http.html#http_response_setheader_name_value).
|
|
112
|
+
For more information, see [`http.ServerResponse#setHeader`](https://nodejs.org/dist/latest-v14.x/docs/api/http.html#http_response_setheader_name_value).
|
|
112
113
|
|
|
113
114
|
<a name="headers"></a>
|
|
114
115
|
### .headers(object)
|
|
@@ -227,7 +228,7 @@ See [`.send()`](#send) for more information on sending different types of values
|
|
|
227
228
|
|
|
228
229
|
<a name="raw"></a>
|
|
229
230
|
### .raw
|
|
230
|
-
This is the [`http.ServerResponse`](https://nodejs.org/dist/latest/docs/api/http.html#http_class_http_serverresponse) from Node core. Whilst you are using the Fastify `Reply` object, the use of `Reply.raw` functions is at your own risk as you are skipping all the Fastify
|
|
231
|
+
This is the [`http.ServerResponse`](https://nodejs.org/dist/latest-v14.x/docs/api/http.html#http_class_http_serverresponse) from Node core. Whilst you are using the Fastify `Reply` object, the use of `Reply.raw` functions is at your own risk as you are skipping all the Fastify
|
|
231
232
|
logic of handling the HTTP response. e.g.:
|
|
232
233
|
|
|
233
234
|
```js
|
|
@@ -300,7 +301,7 @@ fastify.get('/json', options, function (request, reply) {
|
|
|
300
301
|
|
|
301
302
|
<a name="send-streams"></a>
|
|
302
303
|
#### Streams
|
|
303
|
-
*send* can also handle streams out of the box
|
|
304
|
+
*send* can also handle streams out of the box. If you are sending a stream and you have not set a `'Content-Type'` header, *send* will set it at `'application/octet-stream'`.
|
|
304
305
|
```js
|
|
305
306
|
fastify.get('/streams', function (request, reply) {
|
|
306
307
|
const fs = require('fs')
|
package/docs/Request.md
CHANGED
|
@@ -23,6 +23,8 @@ Request is a core Fastify object containing the following fields:
|
|
|
23
23
|
- `is404` - true if request is being handled by 404 handler, false if it is not
|
|
24
24
|
- `connection` - Deprecated, use `socket` instead. The underlying connection of the incoming request.
|
|
25
25
|
- `socket` - the underlying connection of the incoming request
|
|
26
|
+
- `context` - A Fastify internal object. You should not use it directly or modify it. It is usefull to access one special key:
|
|
27
|
+
- `context.config` - The route [`config`](Routes.md#routes-config) object.
|
|
26
28
|
|
|
27
29
|
|
|
28
30
|
```js
|
package/docs/Routes.md
CHANGED
|
@@ -427,7 +427,7 @@ Fastify will require a request `Accept-Version` header to be set if the route ha
|
|
|
427
427
|
fastify.route({
|
|
428
428
|
method: 'GET',
|
|
429
429
|
url: '/',
|
|
430
|
-
|
|
430
|
+
constraints: { version: '1.2.0' },
|
|
431
431
|
handler: function (request, reply) {
|
|
432
432
|
reply.send({ hello: 'world' })
|
|
433
433
|
}
|
|
@@ -475,7 +475,7 @@ You can provide a `host` key in the `constraints` route option for to limit that
|
|
|
475
475
|
fastify.route({
|
|
476
476
|
method: 'GET',
|
|
477
477
|
url: '/',
|
|
478
|
-
|
|
478
|
+
constraints: { host: 'auth.fastify.io' },
|
|
479
479
|
handler: function (request, reply) {
|
|
480
480
|
reply.send('hello world from auth.fastify.io')
|
|
481
481
|
}
|
|
@@ -508,7 +508,7 @@ RegExp `host` constraints can also be specified allowing constraining to hosts m
|
|
|
508
508
|
fastify.route({
|
|
509
509
|
method: 'GET',
|
|
510
510
|
url: '/',
|
|
511
|
-
|
|
511
|
+
constraints: { host: /.*\.fastify\.io/ }, // will match any subdomain of fastify.io
|
|
512
512
|
handler: function (request, reply) {
|
|
513
513
|
reply.send('hello world from ' + request.headers.host)
|
|
514
514
|
}
|
package/docs/Server.md
CHANGED
|
@@ -11,7 +11,7 @@ document describes the properties available in that options object.
|
|
|
11
11
|
<a name="factory-http2"></a>
|
|
12
12
|
### `http2`
|
|
13
13
|
|
|
14
|
-
If `true` Node.js core's [HTTP/2](https://nodejs.org/dist/latest-
|
|
14
|
+
If `true` Node.js core's [HTTP/2](https://nodejs.org/dist/latest-v14.x/docs/api/http2.html) module is used for binding the socket.
|
|
15
15
|
|
|
16
16
|
+ Default: `false`
|
|
17
17
|
|
|
@@ -20,7 +20,7 @@ If `true` Node.js core's [HTTP/2](https://nodejs.org/dist/latest-v8.x/docs/api/h
|
|
|
20
20
|
|
|
21
21
|
An object used to configure the server's listening socket for TLS. The options
|
|
22
22
|
are the same as the Node.js core
|
|
23
|
-
[`createServer` method](https://nodejs.org/dist/latest-
|
|
23
|
+
[`createServer` method](https://nodejs.org/dist/latest-v14.x/docs/api/https.html#https_https_createserver_options_requestlistener).
|
|
24
24
|
When this property is `null`, the socket will not be configured for TLS.
|
|
25
25
|
|
|
26
26
|
This option also applies when the
|
|
@@ -113,7 +113,7 @@ for more details about prototype poisoning attacks.
|
|
|
113
113
|
|
|
114
114
|
Possible values are `'error'`, `'remove'` and `'ignore'`.
|
|
115
115
|
|
|
116
|
-
+ Default: `'
|
|
116
|
+
+ Default: `'error'`
|
|
117
117
|
|
|
118
118
|
<a name="factory-logger"></a>
|
|
119
119
|
### `logger`
|
|
@@ -454,8 +454,10 @@ const fastify = require('fastify')({
|
|
|
454
454
|
Set a default
|
|
455
455
|
[timeout](https://nodejs.org/api/http2.html#http2_http2session_settimeout_msecs_callback) to every incoming HTTP/2 session. The session will be closed on the timeout. Default: `5000` ms.
|
|
456
456
|
|
|
457
|
-
Note that this is needed to offer the graceful "close" experience when
|
|
458
|
-
|
|
457
|
+
Note that this is needed to offer the graceful "close" experience when using HTTP/2.
|
|
458
|
+
The low default has been chosen to mitigate denial of service attacks.
|
|
459
|
+
When the server is behind a load balancer or can scale automatically this value can be
|
|
460
|
+
increased to fit the use case. Node core defaults this to `0`. `
|
|
459
461
|
|
|
460
462
|
<a name="framework-errors"></a>
|
|
461
463
|
### `frameworkErrors`
|
package/docs/TypeScript.md
CHANGED
|
@@ -164,7 +164,7 @@ When you want to use it for validation of some payload in a fastify route you ca
|
|
|
164
164
|
```typescript
|
|
165
165
|
const app = fastify();
|
|
166
166
|
|
|
167
|
-
app.post<{ Body: UserType;
|
|
167
|
+
app.post<{ Body: UserType; Reply: UserType }>(
|
|
168
168
|
"/",
|
|
169
169
|
{
|
|
170
170
|
schema: {
|
package/fastify.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ import { FastifyReply } from './types/reply'
|
|
|
14
14
|
import { FastifySchemaValidationError } from './types/schema'
|
|
15
15
|
import { ConstructorAction, ProtoAction } from "./types/content-type-parser";
|
|
16
16
|
import { Socket } from 'net'
|
|
17
|
+
import { Options as FJSOptions } from 'fast-json-stringify'
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* Fastify factory function for the standard fastify http, https, or http2 server instance.
|
|
@@ -102,6 +103,7 @@ export type FastifyServerOptions<
|
|
|
102
103
|
onProtoPoisoning?: ProtoAction,
|
|
103
104
|
onConstructorPoisoning?: ConstructorAction,
|
|
104
105
|
logger?: boolean | FastifyLoggerOptions<RawServer> | Logger,
|
|
106
|
+
serializerOpts?: FJSOptions | Record<string, unknown>,
|
|
105
107
|
serverFactory?: FastifyServerFactory<RawServer>,
|
|
106
108
|
caseSensitive?: boolean,
|
|
107
109
|
requestIdHeader?: string,
|
|
@@ -122,7 +124,7 @@ export type FastifyServerOptions<
|
|
|
122
124
|
deriveVersion<Context>(req: Object, ctx?: Context): string // not a fan of using Object here. Also what is Context? Can either of these be better defined?
|
|
123
125
|
},
|
|
124
126
|
constraints?: {
|
|
125
|
-
[name: string]: ConstraintStrategy<FindMyWayVersion<RawServer
|
|
127
|
+
[name: string]: ConstraintStrategy<FindMyWayVersion<RawServer>, unknown>,
|
|
126
128
|
},
|
|
127
129
|
return503OnClosing?: boolean,
|
|
128
130
|
ajv?: {
|
|
@@ -163,7 +165,7 @@ export type { Chain as LightMyRequestChain, InjectOptions, Response as LightMyRe
|
|
|
163
165
|
export { FastifyRequest, RequestGenericInterface } from './types/request'
|
|
164
166
|
export { FastifyReply } from './types/reply'
|
|
165
167
|
export { FastifyPluginCallback, FastifyPluginAsync, FastifyPluginOptions, FastifyPlugin } from './types/plugin'
|
|
166
|
-
export { FastifyInstance } from './types/instance'
|
|
168
|
+
export { FastifyInstance, PrintRoutesOptions } from './types/instance'
|
|
167
169
|
export { FastifyLoggerOptions, FastifyLoggerInstance, FastifyLogFn, LogLevel } from './types/logger'
|
|
168
170
|
export { FastifyContext, FastifyContextConfig } from './types/context'
|
|
169
171
|
export { RouteHandler, RouteHandlerMethod, RouteOptions, RouteShorthandMethod, RouteShorthandOptions, RouteShorthandOptionsWithHandler } from './types/route'
|
package/fastify.js
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
const Avvio = require('avvio')
|
|
4
4
|
const http = require('http')
|
|
5
|
-
const path = require('path')
|
|
6
5
|
const querystring = require('querystring')
|
|
7
6
|
let lightMyRequest
|
|
7
|
+
let version
|
|
8
|
+
let versionLoaded = false
|
|
8
9
|
|
|
9
|
-
const { version } = require(path.join(__dirname, 'package.json'))
|
|
10
10
|
const {
|
|
11
11
|
kAvvioBoot,
|
|
12
12
|
kChildren,
|
|
@@ -272,6 +272,8 @@ function fastify (options) {
|
|
|
272
272
|
hasContentTypeParser: ContentTypeParser.helpers.hasContentTypeParser,
|
|
273
273
|
getDefaultJsonParser: ContentTypeParser.defaultParsers.getDefaultJsonParser,
|
|
274
274
|
defaultTextParser: ContentTypeParser.defaultParsers.defaultTextParser,
|
|
275
|
+
removeContentTypeParser: ContentTypeParser.helpers.removeContentTypeParser,
|
|
276
|
+
removeAllContentTypeParsers: ContentTypeParser.helpers.removeAllContentTypeParsers,
|
|
275
277
|
// Fastify architecture methods (initialized by Avvio)
|
|
276
278
|
register: null,
|
|
277
279
|
after: null,
|
|
@@ -323,6 +325,9 @@ function fastify (options) {
|
|
|
323
325
|
},
|
|
324
326
|
version: {
|
|
325
327
|
get () {
|
|
328
|
+
if (versionLoaded === false) {
|
|
329
|
+
version = loadVersion()
|
|
330
|
+
}
|
|
326
331
|
return version
|
|
327
332
|
}
|
|
328
333
|
},
|
|
@@ -672,6 +677,20 @@ function wrapRouting (httpHandler, { rewriteUrl, logger }) {
|
|
|
672
677
|
}
|
|
673
678
|
}
|
|
674
679
|
|
|
680
|
+
function loadVersion () {
|
|
681
|
+
versionLoaded = true
|
|
682
|
+
const fs = require('fs')
|
|
683
|
+
const path = require('path')
|
|
684
|
+
try {
|
|
685
|
+
const pkgPath = path.join(__dirname, 'package.json')
|
|
686
|
+
fs.accessSync(pkgPath, fs.constants.R_OK)
|
|
687
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath))
|
|
688
|
+
return pkg.name === 'fastify' ? pkg.version : undefined
|
|
689
|
+
} catch (e) {
|
|
690
|
+
return undefined
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
|
|
675
694
|
/**
|
|
676
695
|
* These export configurations enable JS and TS developers
|
|
677
696
|
* to consumer fastify in whatever way best suits their needs.
|
package/lib/contentTypeParser.js
CHANGED
|
@@ -116,6 +116,27 @@ ContentTypeParser.prototype.getParser = function (contentType) {
|
|
|
116
116
|
return this.customParsers['']
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
ContentTypeParser.prototype.removeAll = function () {
|
|
120
|
+
this.customParsers = {}
|
|
121
|
+
this.parserRegExpList = []
|
|
122
|
+
this.parserList = []
|
|
123
|
+
this.cache = lru(100)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
ContentTypeParser.prototype.remove = function (contentType) {
|
|
127
|
+
if (!(typeof contentType === 'string' || contentType instanceof RegExp)) throw new FST_ERR_CTP_INVALID_TYPE()
|
|
128
|
+
|
|
129
|
+
delete this.customParsers[contentType]
|
|
130
|
+
|
|
131
|
+
const parsers = typeof contentType === 'string' ? this.parserList : this.parserRegExpList
|
|
132
|
+
|
|
133
|
+
const idx = parsers.findIndex(ct => ct.toString() === contentType.toString())
|
|
134
|
+
|
|
135
|
+
if (idx > -1) {
|
|
136
|
+
parsers.splice(idx, 1)
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
119
140
|
ContentTypeParser.prototype.run = function (contentType, handler, request, reply) {
|
|
120
141
|
const parser = this.cache.get(contentType) || this.getParser(contentType)
|
|
121
142
|
|
|
@@ -297,11 +318,35 @@ function hasContentTypeParser (contentType) {
|
|
|
297
318
|
return this[kContentTypeParser].hasParser(contentType)
|
|
298
319
|
}
|
|
299
320
|
|
|
321
|
+
function removeContentTypeParser (contentType) {
|
|
322
|
+
if (this[kState].started) {
|
|
323
|
+
throw new Error('Cannot call "removeContentTypeParser" when fastify instance is already started!')
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
if (Array.isArray(contentType)) {
|
|
327
|
+
for (const type of contentType) {
|
|
328
|
+
this[kContentTypeParser].remove(type)
|
|
329
|
+
}
|
|
330
|
+
} else {
|
|
331
|
+
this[kContentTypeParser].remove(contentType)
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
function removeAllContentTypeParsers () {
|
|
336
|
+
if (this[kState].started) {
|
|
337
|
+
throw new Error('Cannot call "removeAllContentTypeParsers" when fastify instance is already started!')
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
this[kContentTypeParser].removeAll()
|
|
341
|
+
}
|
|
342
|
+
|
|
300
343
|
module.exports = ContentTypeParser
|
|
301
344
|
module.exports.helpers = {
|
|
302
345
|
buildContentTypeParser,
|
|
303
346
|
addContentTypeParser,
|
|
304
|
-
hasContentTypeParser
|
|
347
|
+
hasContentTypeParser,
|
|
348
|
+
removeContentTypeParser,
|
|
349
|
+
removeAllContentTypeParsers
|
|
305
350
|
}
|
|
306
351
|
module.exports.defaultParsers = {
|
|
307
352
|
getDefaultJsonParser,
|
package/lib/logger.js
CHANGED
|
@@ -35,7 +35,7 @@ function createPinoLogger (opts, stream) {
|
|
|
35
35
|
if (prevLogger[serializersSym]) {
|
|
36
36
|
opts.serializers = Object.assign({}, opts.serializers, prevLogger[serializersSym])
|
|
37
37
|
}
|
|
38
|
-
logger = prevLogger.child(opts)
|
|
38
|
+
logger = prevLogger.child({}, opts)
|
|
39
39
|
opts.logger = prevLogger
|
|
40
40
|
opts.genReqId = prevGenReqId
|
|
41
41
|
} else {
|
package/lib/pluginUtils.js
CHANGED
|
@@ -109,7 +109,9 @@ function registerPluginName (fn) {
|
|
|
109
109
|
|
|
110
110
|
function registerPlugin (fn) {
|
|
111
111
|
registerPluginName.call(this, fn)
|
|
112
|
-
|
|
112
|
+
if (this.version !== undefined) {
|
|
113
|
+
checkVersion.call(this, fn)
|
|
114
|
+
}
|
|
113
115
|
checkDecorators.call(this, fn)
|
|
114
116
|
checkDependencies.call(this, fn)
|
|
115
117
|
return shouldSkipOverride(fn)
|
package/lib/reply.js
CHANGED
|
@@ -548,8 +548,12 @@ function handleError (reply, error, cb) {
|
|
|
548
548
|
reply[kReplyErrorHandlerCalled] = true
|
|
549
549
|
reply[kReplyHeaders]['content-length'] = undefined
|
|
550
550
|
const result = errorHandler(error, reply.request, reply)
|
|
551
|
-
if (result
|
|
552
|
-
|
|
551
|
+
if (result !== undefined) {
|
|
552
|
+
if (result !== null && typeof result.then === 'function') {
|
|
553
|
+
wrapThenable(result, reply)
|
|
554
|
+
} else {
|
|
555
|
+
reply.send(result)
|
|
556
|
+
}
|
|
553
557
|
}
|
|
554
558
|
return
|
|
555
559
|
}
|
package/lib/route.js
CHANGED
|
@@ -247,7 +247,7 @@ function buildRouting (options) {
|
|
|
247
247
|
opts.schemaErrorFormatter || this[kSchemaErrorFormatter]
|
|
248
248
|
)
|
|
249
249
|
|
|
250
|
-
const headRouteExists = router.find('HEAD',
|
|
250
|
+
const headRouteExists = router.find('HEAD', url) != null
|
|
251
251
|
|
|
252
252
|
try {
|
|
253
253
|
router.on(opts.method, opts.url, { constraints }, routeHandler, context)
|
|
@@ -345,15 +345,18 @@ function buildRouting (options) {
|
|
|
345
345
|
|
|
346
346
|
const id = req.headers[requestIdHeader] || genReqId(req)
|
|
347
347
|
|
|
348
|
+
const loggerBinding = {
|
|
349
|
+
[requestIdLogLabel]: id
|
|
350
|
+
}
|
|
351
|
+
|
|
348
352
|
const loggerOpts = {
|
|
349
|
-
[requestIdLogLabel]: id,
|
|
350
353
|
level: context.logLevel
|
|
351
354
|
}
|
|
352
355
|
|
|
353
356
|
if (context.logSerializers) {
|
|
354
357
|
loggerOpts.serializers = context.logSerializers
|
|
355
358
|
}
|
|
356
|
-
const childLogger = logger.child(loggerOpts)
|
|
359
|
+
const childLogger = logger.child(loggerBinding, loggerOpts)
|
|
357
360
|
childLogger[kDisableRequestLogging] = disableRequestLogging
|
|
358
361
|
|
|
359
362
|
const queryPrefix = req.url.indexOf('?')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fastify",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.20.1",
|
|
4
4
|
"description": "Fast and low overhead web framework, for Node.js",
|
|
5
5
|
"main": "fastify.js",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -164,7 +164,7 @@
|
|
|
164
164
|
"tap": "^15.0.5",
|
|
165
165
|
"tap-mocha-reporter": "^5.0.1",
|
|
166
166
|
"then-sleep": "^1.0.1",
|
|
167
|
-
"tsd": "^0.
|
|
167
|
+
"tsd": "^0.17.0",
|
|
168
168
|
"typescript": "^4.0.2",
|
|
169
169
|
"undici": "^3.3.5",
|
|
170
170
|
"x-xss-protection": "^2.0.0",
|
|
@@ -177,10 +177,10 @@
|
|
|
177
177
|
"fast-json-stringify": "^2.5.2",
|
|
178
178
|
"fastify-error": "^0.3.0",
|
|
179
179
|
"fastify-warning": "^0.2.0",
|
|
180
|
-
"find-my-way": "^4.
|
|
180
|
+
"find-my-way": "^4.1.0",
|
|
181
181
|
"flatstr": "^1.0.12",
|
|
182
182
|
"light-my-request": "^4.2.0",
|
|
183
|
-
"pino": "^6.
|
|
183
|
+
"pino": "^6.13.0",
|
|
184
184
|
"proxy-addr": "^2.0.7",
|
|
185
185
|
"readable-stream": "^3.4.0",
|
|
186
186
|
"rfdc": "^1.1.4",
|
package/test/async-await.test.js
CHANGED
|
@@ -646,6 +646,79 @@ test('customErrorHandler only called if reply not already sent', t => {
|
|
|
646
646
|
})
|
|
647
647
|
})
|
|
648
648
|
|
|
649
|
+
// See https://github.com/fastify/fastify/issues/3209
|
|
650
|
+
test('setNotFoundHandler should accept return value', t => {
|
|
651
|
+
t.plan(3)
|
|
652
|
+
|
|
653
|
+
const fastify = Fastify()
|
|
654
|
+
|
|
655
|
+
fastify.get('/', async () => ({ hello: 'world' }))
|
|
656
|
+
|
|
657
|
+
fastify.setNotFoundHandler((req, reply) => {
|
|
658
|
+
reply.code(404)
|
|
659
|
+
return {
|
|
660
|
+
error: statusCodes['404'],
|
|
661
|
+
message: 'lost',
|
|
662
|
+
statusCode: 404
|
|
663
|
+
}
|
|
664
|
+
})
|
|
665
|
+
|
|
666
|
+
fastify.inject({
|
|
667
|
+
method: 'GET',
|
|
668
|
+
url: '/elsewhere'
|
|
669
|
+
}, (err, res) => {
|
|
670
|
+
t.error(err)
|
|
671
|
+
t.equal(res.statusCode, 404)
|
|
672
|
+
t.same(
|
|
673
|
+
{
|
|
674
|
+
error: statusCodes['404'],
|
|
675
|
+
message: 'lost',
|
|
676
|
+
statusCode: 404
|
|
677
|
+
},
|
|
678
|
+
JSON.parse(res.payload)
|
|
679
|
+
)
|
|
680
|
+
})
|
|
681
|
+
})
|
|
682
|
+
|
|
683
|
+
// See https://github.com/fastify/fastify/issues/3209
|
|
684
|
+
test('customErrorHandler should accept return value', t => {
|
|
685
|
+
t.plan(4)
|
|
686
|
+
|
|
687
|
+
const fastify = Fastify()
|
|
688
|
+
|
|
689
|
+
fastify.get('/', async (req, reply) => {
|
|
690
|
+
const error = new Error('ouch')
|
|
691
|
+
error.statusCode = 400
|
|
692
|
+
throw error
|
|
693
|
+
})
|
|
694
|
+
|
|
695
|
+
fastify.setErrorHandler((err, req, reply) => {
|
|
696
|
+
t.equal(err.message, 'ouch')
|
|
697
|
+
reply.code(401)
|
|
698
|
+
return {
|
|
699
|
+
error: statusCodes['401'],
|
|
700
|
+
message: 'kaboom',
|
|
701
|
+
statusCode: 401
|
|
702
|
+
}
|
|
703
|
+
})
|
|
704
|
+
|
|
705
|
+
fastify.inject({
|
|
706
|
+
method: 'GET',
|
|
707
|
+
url: '/'
|
|
708
|
+
}, (err, res) => {
|
|
709
|
+
t.error(err)
|
|
710
|
+
t.equal(res.statusCode, 401)
|
|
711
|
+
t.same(
|
|
712
|
+
{
|
|
713
|
+
error: statusCodes['401'],
|
|
714
|
+
message: 'kaboom',
|
|
715
|
+
statusCode: 401
|
|
716
|
+
},
|
|
717
|
+
JSON.parse(res.payload)
|
|
718
|
+
)
|
|
719
|
+
})
|
|
720
|
+
})
|
|
721
|
+
|
|
649
722
|
test('await self', async t => {
|
|
650
723
|
const app = Fastify()
|
|
651
724
|
t.equal(await app, app)
|