fastify 3.4.1 → 3.7.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/docs/ContentTypeParser.md +3 -0
- package/docs/Decorators.md +2 -0
- package/docs/Ecosystem.md +2 -1
- package/docs/Lifecycle.md +2 -2
- package/docs/Logging.md +1 -1
- package/docs/Reply.md +18 -0
- package/docs/Request.md +5 -1
- package/docs/Routes.md +2 -2
- package/docs/Server.md +55 -4
- package/docs/TypeScript.md +2 -1
- package/docs/Validation-and-Serialization.md +11 -5
- package/examples/simple.mjs +27 -0
- package/fastify.js +55 -7
- package/lib/contentTypeParser.js +4 -0
- package/lib/context.js +1 -16
- package/lib/errors.js +10 -2
- package/lib/fourOhFour.js +4 -3
- package/lib/logger.js +1 -1
- package/lib/pluginUtils.js +15 -0
- package/lib/reply.js +3 -3
- package/lib/request.js +26 -1
- package/lib/route.js +7 -3
- package/lib/symbols.js +2 -1
- package/lib/validation.js +1 -0
- package/lib/warnings.js +3 -0
- package/lib/wrapThenable.js +2 -2
- package/package.json +5 -5
- package/test/custom-parser.test.js +30 -0
- package/test/emit-warning.test.js +31 -0
- package/test/esm/index.test.js +15 -2
- package/test/esm/named-exports.mjs +13 -0
- package/test/fastify-instance.test.js +33 -1
- package/test/http2/secure.test.js +11 -0
- package/test/https/https.test.js +26 -0
- package/test/internals/request.test.js +8 -5
- package/test/internals/version.test.js +43 -0
- package/test/listen.test.js +16 -0
- package/test/logger.test.js +1 -1
- package/test/plugin.test.js +108 -0
- package/test/request-error.test.js +81 -0
- package/test/route.test.js +27 -0
- package/test/trust-proxy.test.js +42 -5
- package/test/types/decorate-request-reply.test-d.ts +18 -0
- package/test/types/instance.test-d.ts +27 -9
- package/test/types/logger.test-d.ts +63 -1
- package/test/types/register.test-d.ts +16 -0
- package/test/types/request.test-d.ts +1 -1
- package/test/types/schema.test-d.ts +5 -0
- package/test/validation-error-handling.test.js +66 -0
- package/types/instance.d.ts +7 -13
- package/types/logger.d.ts +90 -10
- package/types/register.d.ts +1 -0
- package/types/request.d.ts +20 -11
- package/types/schema.d.ts +2 -2
|
@@ -28,6 +28,9 @@ fastify.addContentTypeParser('application/jsoff', async function (request, paylo
|
|
|
28
28
|
|
|
29
29
|
return res
|
|
30
30
|
})
|
|
31
|
+
|
|
32
|
+
// Can use default JSON/Text parser for different content Types
|
|
33
|
+
fastify.addContentTypeParser('text/json', { parseAs: 'string' }, fastify.getDefaultJsonParser('ignore', 'ignore'))
|
|
31
34
|
```
|
|
32
35
|
|
|
33
36
|
You can also use the `hasContentTypeParser` API to find if a specific content type parser already exists.
|
package/docs/Decorators.md
CHANGED
|
@@ -55,6 +55,8 @@ fastify.get('/', (req, reply) => {
|
|
|
55
55
|
})
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
+
Note that it is important to keep initial shape of decorated field as close as possible to the value intended to be set dynamically in the future. Initialize a decorator as a `''` if the intended value is a string, and as `null` if it will be an object or a function.
|
|
59
|
+
|
|
58
60
|
See
|
|
59
61
|
[JavaScript engine fundamentals: Shapes and Inline Caches](https://web.archive.org/web/20200201163000/https://mathiasbynens.be/notes/shapes-ics)
|
|
60
62
|
for more information on this topic.
|
package/docs/Ecosystem.md
CHANGED
|
@@ -17,6 +17,7 @@ Plugins maintained by the fastify team are listed under [Core](#core) while plug
|
|
|
17
17
|
- [`fastify-compress`](https://github.com/fastify/fastify-compress) Fastify compression utils.
|
|
18
18
|
- [`fastify-cookie`](https://github.com/fastify/fastify-cookie) Parse and set cookie headers.
|
|
19
19
|
- [`fastify-cors`](https://github.com/fastify/fastify-cors) Enables the use of CORS in a Fastify application.
|
|
20
|
+
- [`fastify-csrf`](https://github.com/fastify/fastify-csrf) A plugin for adding [CSRF](https://en.wikipedia.org/wiki/Cross-site_request_forgery) protection to Fastify.
|
|
20
21
|
- [`fastify-elasticsearch`](https://github.com/fastify/fastify-elasticsearch) Plugin to share the same ES client.
|
|
21
22
|
- [`fastify-env`](https://github.com/fastify/fastify-env) Load and check configuration.
|
|
22
23
|
- [`fastify-etag`](https://github.com/fastify/fastify-etag) Automatically generate etags for HTTP responses.
|
|
@@ -65,7 +66,6 @@ Plugins maintained by the fastify team are listed under [Core](#core) while plug
|
|
|
65
66
|
- [`fastify-cloudevents`](https://github.com/smartiniOnGitHub/fastify-cloudevents) Fastify plugin to generate and forward Fastify events in the Cloudevents format.
|
|
66
67
|
- [`fastify-cockroachdb`](https://github.com/alex-ppg/fastify-cockroachdb) Fastify plugin to connect to a CockroachDB PostgreSQL instance via the Sequelize ORM.
|
|
67
68
|
- [`fastify-couchdb`](https://github.com/nigelhanlon/fastify-couchdb) Fastify plugin to add CouchDB support via [nano](https://github.com/apache/nano).
|
|
68
|
-
- [`fastify-csrf`](https://github.com/Tarang11/fastify-csrf) A csrf plugin for Fastify.
|
|
69
69
|
- [`fastify-decorators`](https://github.com/L2jLiga/fastify-decorators) Fastify plugin that provides the set of TypeScript decorators.
|
|
70
70
|
- [`fastify-dynamodb`](https://github.com/matrus2/fastify-dynamodb) AWS DynamoDB plugin for Fastify. It exposes [AWS.DynamoDB.DocumentClient()](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html) object.
|
|
71
71
|
- [`fastify-dynareg`](https://github.com/greguz/fastify-dynareg) Dynamic plugin register for Fastify.
|
|
@@ -128,6 +128,7 @@ Plugins maintained by the fastify team are listed under [Core](#core) while plug
|
|
|
128
128
|
- [`fastify-rbac`](https://gitlab.com/m03geek/fastify-rbac) Fastify role-based access control plugin.
|
|
129
129
|
- [`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.
|
|
130
130
|
- [`fastify-response-time`](https://github.com/lolo32/fastify-response-time) Add `X-Response-Time` header at each request for Fastify, in milliseconds.
|
|
131
|
+
- [`fastify-response-caching`](https://github.com/codeaholicguy/fastify-response-caching) A Fastify plugin for caching the response.
|
|
131
132
|
- [`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.
|
|
132
133
|
- [`fastify-rob-config`](https://github.com/jeromemacias/fastify-rob-config) Fastify Rob-Config integration.
|
|
133
134
|
- [`fastify-schema-constraint`](https://github.com/Eomm/fastify-schema-constraint) Choose the JSON schema to use based on request parameters.
|
package/docs/Lifecycle.md
CHANGED
|
@@ -10,7 +10,7 @@ Incoming Request
|
|
|
10
10
|
│
|
|
11
11
|
└─▶ Instance Logger
|
|
12
12
|
│
|
|
13
|
-
|
|
13
|
+
4**/5** ◀─┴─▶ onRequest Hook
|
|
14
14
|
│
|
|
15
15
|
4**/5** ◀─┴─▶ preParsing Hook
|
|
16
16
|
│
|
|
@@ -20,7 +20,7 @@ Incoming Request
|
|
|
20
20
|
│
|
|
21
21
|
415 ◀─┴─▶ Validation
|
|
22
22
|
│
|
|
23
|
-
|
|
23
|
+
4**/5** ◀─┴─▶ preHandler Hook
|
|
24
24
|
│
|
|
25
25
|
4**/5** ◀─┴─▶ User Handler
|
|
26
26
|
│
|
package/docs/Logging.md
CHANGED
package/docs/Reply.md
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
- [.callNotFound()](#callnotfound)
|
|
16
16
|
- [.getResponseTime()](#getresponsetime)
|
|
17
17
|
- [.type(contentType)](#typecontenttype)
|
|
18
|
+
- [.raw](#raw)
|
|
18
19
|
- [.serializer(func)](#serializerfunc)
|
|
19
20
|
- [.sent](#sent)
|
|
20
21
|
- [.send(data)](#senddata)
|
|
@@ -207,6 +208,23 @@ reply
|
|
|
207
208
|
|
|
208
209
|
See [`.send()`](#send) for more information on sending different types of values.
|
|
209
210
|
|
|
211
|
+
<a name="raw"></a>
|
|
212
|
+
### .raw
|
|
213
|
+
This is the [`http.ServerResponse`](https://nodejs.org/dist/latest/docs/api/http.html#http_class_http_serverresponse) from Node core. While you're using the fastify `Reply` object, the use of `Reply.raw` functions is at your own risk as you're skipping all the fastify
|
|
214
|
+
logic of handling the http response. eg:
|
|
215
|
+
|
|
216
|
+
```js
|
|
217
|
+
app.get('/cookie-2', (req, reply) => {
|
|
218
|
+
reply.setCookie('session', 'value', { secure: false }) // this will not be used
|
|
219
|
+
|
|
220
|
+
// in this case we are using only the nodejs http server response object
|
|
221
|
+
reply.raw.writeHead(200, { 'Content-Type': 'text/plain' })
|
|
222
|
+
reply.raw.write('ok')
|
|
223
|
+
reply.raw.end()
|
|
224
|
+
})
|
|
225
|
+
```
|
|
226
|
+
Another example of the misuse of `Reply.raw` is explained in [Reply.md#getheaders](Reply.md#getheaders).
|
|
227
|
+
|
|
210
228
|
<a name="sent"></a>
|
|
211
229
|
### .sent
|
|
212
230
|
|
package/docs/Request.md
CHANGED
|
@@ -14,12 +14,15 @@ Request is a core Fastify object containing the following fields:
|
|
|
14
14
|
- `ip` - the IP address of the incoming request
|
|
15
15
|
- `ips` - an array of the IP addresses in the `X-Forwarded-For` header of the incoming request (only when the [`trustProxy`](Server.md#factory-trust-proxy) option is enabled)
|
|
16
16
|
- `hostname` - the hostname of the incoming request
|
|
17
|
+
- `protocol` - the protocol of the incoming request (`https` or `http`)
|
|
17
18
|
- `method` - the method of the incoming request
|
|
18
19
|
- `url` - the url of the incoming request
|
|
19
20
|
- `routerMethod` - the method defined for the router that is handling the request
|
|
20
21
|
- `routerPath` - the path pattern defined for the router that is handling the request
|
|
21
22
|
- `is404` - true if request is being handled by 404 handler, false if it is not
|
|
22
|
-
- `connection` -
|
|
23
|
+
- `connection` - Deprecated, use `socket` instead. The underlying connection of the incoming request.
|
|
24
|
+
- `socket` - the underlying connection of the incoming request
|
|
25
|
+
|
|
23
26
|
|
|
24
27
|
```js
|
|
25
28
|
fastify.post('/:params', options, function (request, reply) {
|
|
@@ -32,6 +35,7 @@ fastify.post('/:params', options, function (request, reply) {
|
|
|
32
35
|
console.log(request.ip)
|
|
33
36
|
console.log(request.ips)
|
|
34
37
|
console.log(request.hostname)
|
|
38
|
+
console.log(request.protocol)
|
|
35
39
|
request.log.info('some info')
|
|
36
40
|
})
|
|
37
41
|
```
|
package/docs/Routes.md
CHANGED
|
@@ -51,7 +51,7 @@ They need to be in
|
|
|
51
51
|
* `onSend(request, reply, payload, done)`: a [function](Hooks.md#route-hooks) called right before a response is sent, it could also be an array of functions.
|
|
52
52
|
* `onResponse(request, reply, done)`: a [function](Hooks.md#onresponse) called when a response has been sent, so you will not be able to send more data to the client. It could also be an array of functions.
|
|
53
53
|
* `handler(request, reply)`: the function that will handle this request. The [Fastify server](Server.md) will be bound to `this` when the handler is called. Note: using an arrow function will break the binding of `this`.
|
|
54
|
-
* `errorHandler(error, request, reply)`: a custom error handler for the scope of the request. Overrides the default error global handler, and anything set by [`setErrorHandler`](Server.md#setErrorHandler), for requests to the route.
|
|
54
|
+
* `errorHandler(error, request, reply)`: a custom error handler for the scope of the request. Overrides the default error global handler, and anything set by [`setErrorHandler`](Server.md#setErrorHandler), for requests to the route. To access the default handler, you can access `instance.errorHandler`. Note that this will point to fastify's default `errorHandler` only if a plugin hasn't overridden it already.
|
|
55
55
|
* `validatorCompiler({ schema, method, url, httpPart })`: function that builds schemas for request validations. See the [Validation and Serialization](Validation-and-Serialization.md#schema-validator) documentation.
|
|
56
56
|
* `serializerCompiler({ { schema, method, url, httpStatus } })`: function that builds schemas for response serialization. See the [Validation and Serialization](Validation-and-Serialization.md#schema-serializer) documentation.
|
|
57
57
|
* `schemaErrorFormatter(errors, dataVar)`: function that formats the errors from the validation compiler. See the [Validation and Serialization](Validation-and-Serialization.md#error-handling) documentation. Overrides the global schema error formatter handler, and anything set by `setSchemaErrorFormatter`, for requests to the route.
|
|
@@ -360,7 +360,7 @@ const fastify = Fastify({
|
|
|
360
360
|
headers: req.headers,
|
|
361
361
|
hostname: req.hostname,
|
|
362
362
|
remoteAddress: req.ip,
|
|
363
|
-
remotePort: req.
|
|
363
|
+
remotePort: req.socket.remotePort
|
|
364
364
|
}
|
|
365
365
|
}
|
|
366
366
|
}
|
package/docs/Server.md
CHANGED
|
@@ -293,13 +293,14 @@ const fastify = Fastify({ trustProxy: true })
|
|
|
293
293
|
|
|
294
294
|
For more examples refer to [proxy-addr](https://www.npmjs.com/package/proxy-addr) package.
|
|
295
295
|
|
|
296
|
-
You may access the `ip`, `ips`, and `
|
|
296
|
+
You may access the `ip`, `ips`, `hostname` and `protocol` values on the [`request`](Request.md) object.
|
|
297
297
|
|
|
298
298
|
```js
|
|
299
299
|
fastify.get('/', (request, reply) => {
|
|
300
300
|
console.log(request.ip)
|
|
301
301
|
console.log(request.ips)
|
|
302
302
|
console.log(request.hostname)
|
|
303
|
+
console.log(request.protocol)
|
|
303
304
|
})
|
|
304
305
|
```
|
|
305
306
|
|
|
@@ -478,7 +479,7 @@ const fastify = require('fastify')({
|
|
|
478
479
|
<a name="rewrite-url"></a>
|
|
479
480
|
### `rewriteUrl`
|
|
480
481
|
|
|
481
|
-
Set a sync callback function that must return a string that allows rewriting urls.
|
|
482
|
+
Set a sync callback function that must return a string that allows rewriting urls.
|
|
482
483
|
|
|
483
484
|
> Rewriting a url will modify the `url` property of the `req` object
|
|
484
485
|
|
|
@@ -742,6 +743,10 @@ Important: If you have to deal with nested plugins the name differs with the usa
|
|
|
742
743
|
#### log
|
|
743
744
|
The logger instance, check [here](Logging.md).
|
|
744
745
|
|
|
746
|
+
<a name="version"></a>
|
|
747
|
+
#### version
|
|
748
|
+
Fastify version of the instance. Used for plugin support. See [Plugins](Plugins.md#handle-the-scope) for information on how the version is used by plugins.
|
|
749
|
+
|
|
745
750
|
<a name="inject"></a>
|
|
746
751
|
#### inject
|
|
747
752
|
Fake http injection (for testing purposes) [here](Testing.md#inject).
|
|
@@ -833,17 +838,19 @@ fastify.register(function (instance, options, done) {
|
|
|
833
838
|
<a name="set-error-handler"></a>
|
|
834
839
|
#### setErrorHandler
|
|
835
840
|
|
|
836
|
-
`fastify.setErrorHandler(handler(error, request, reply))`: Set a function that will be called whenever an error happens. The handler is fully encapsulated, so different plugins can set different error handlers. *async-await* is supported as well.<br>
|
|
841
|
+
`fastify.setErrorHandler(handler(error, request, reply))`: Set a function that will be called whenever an error happens. The handler is bound to the Fastify instance, and is fully encapsulated, so different plugins can set different error handlers. *async-await* is supported as well.<br>
|
|
837
842
|
*Note: If the error `statusCode` is less than 400, Fastify will automatically set it at 500 before calling the error handler.*
|
|
838
843
|
|
|
839
844
|
```js
|
|
840
845
|
fastify.setErrorHandler(function (error, request, reply) {
|
|
841
846
|
// Log error
|
|
847
|
+
this.log.error(error)
|
|
842
848
|
// Send error response
|
|
849
|
+
reply.status(409).send({ ok: false })
|
|
843
850
|
})
|
|
844
851
|
```
|
|
845
852
|
|
|
846
|
-
Fastify is provided with a default function that is called if no error handler is set and
|
|
853
|
+
Fastify is provided with a default function that is called if no error handler is set. It can be accessed using `fastify.errorHandler` and it logs the error with respect to its `statusCode`.
|
|
847
854
|
|
|
848
855
|
```js
|
|
849
856
|
var statusCode = error.statusCode
|
|
@@ -876,6 +883,50 @@ fastify.ready(() => {
|
|
|
876
883
|
})
|
|
877
884
|
```
|
|
878
885
|
|
|
886
|
+
<a name="addContentTypeParser"></a>
|
|
887
|
+
#### addContentTypeParser
|
|
888
|
+
|
|
889
|
+
`fastify.addContentTypeParser(content-type, options, parser)` is used to pass custom parser for a given content type. Useful for adding parsers for custom content types, e.g. `text/json, application/vnd.oasis.opendocument.text`. `content-type` can be a string or string array.
|
|
890
|
+
|
|
891
|
+
```js
|
|
892
|
+
// The two arguments passed to getDefaultJsonParser are for ProtoType poisoning and Constructor Poisoning configuration respectively. The possible values are 'ignore', 'remove', 'error'. ignore skips all validations and it is similar to calling JSON.parse() directly. See the <a href="https://github.com/fastify/secure-json-parse#api">`secure-json-parse` documentation</a> for more information.
|
|
893
|
+
|
|
894
|
+
fastify.addContentTypeParser('text/json', { asString: true }, fastify.getDefaultJsonParser('ignore', 'ignore'))
|
|
895
|
+
```
|
|
896
|
+
|
|
897
|
+
<a name="getDefaultJsonParser"></a>
|
|
898
|
+
#### getDefaultJsonParser
|
|
899
|
+
|
|
900
|
+
`fastify.getDefaultJsonParser(onProtoPoisoning, onConstructorPoisoning)` takes two arguments. First argument is ProtoType poisoning configuration and second argument is constructor poisoning configuration. See the <a href="https://github.com/fastify/secure-json-parse#api">`secure-json-parse` documentation</a> for more information.
|
|
901
|
+
|
|
902
|
+
|
|
903
|
+
<a name="defaultTextParser"></a>
|
|
904
|
+
#### defaultTextParser
|
|
905
|
+
|
|
906
|
+
`fastify.defaultTextParser()` can be used to parse content as plain text.
|
|
907
|
+
|
|
908
|
+
```js
|
|
909
|
+
fastify.addContentTypeParser('text/json', { asString: true }, fastify.defaultTextParser())
|
|
910
|
+
```
|
|
911
|
+
|
|
912
|
+
<a name="errorHandler"></a>
|
|
913
|
+
#### errorHandler
|
|
914
|
+
|
|
915
|
+
`fastify.errorHandler` can be used to handle errors using fastify's default error handler.
|
|
916
|
+
|
|
917
|
+
```js
|
|
918
|
+
fastify.get('/', {
|
|
919
|
+
errorHandler: (error, request, reply) => {
|
|
920
|
+
if (error.code === 'SOMETHING_SPECIFIC') {
|
|
921
|
+
reply.send({ custom: 'response' })
|
|
922
|
+
return
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
fastify.errorHandler(error, request, response)
|
|
926
|
+
}
|
|
927
|
+
}, handler)
|
|
928
|
+
```
|
|
929
|
+
|
|
879
930
|
<a name="initial-config"></a>
|
|
880
931
|
#### initialConfig
|
|
881
932
|
|
package/docs/TypeScript.md
CHANGED
|
@@ -10,6 +10,7 @@ The type system was changed in Fastify version 3. The new type system introduces
|
|
|
10
10
|
|
|
11
11
|
> Plugins may or may not include typings. See [Plugins](#plugins) for more information. We encourage users to send pull requests to improve typings support.
|
|
12
12
|
|
|
13
|
+
🚨 Don't foget to install `@types/node`
|
|
13
14
|
|
|
14
15
|
## Learn By Example
|
|
15
16
|
|
|
@@ -243,7 +244,7 @@ One of Fastify's most distinguishable features is its extensive plugin ecosystem
|
|
|
243
244
|
```bash
|
|
244
245
|
npm init -y
|
|
245
246
|
npm i fastify fastify-plugin
|
|
246
|
-
npm i -D typescript
|
|
247
|
+
npm i -D typescript @types/node
|
|
247
248
|
```
|
|
248
249
|
2. Add a `build` script to the `"scripts"` section and `'index.d.ts'` to the `"types"` section of the `package.json` file:
|
|
249
250
|
```json
|
|
@@ -163,13 +163,19 @@ const bodyJsonSchema = {
|
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
const queryStringJsonSchema = {
|
|
166
|
-
|
|
167
|
-
|
|
166
|
+
type: 'object',
|
|
167
|
+
properties: {
|
|
168
|
+
name: { type: 'string' },
|
|
169
|
+
excitement: { type: 'integer' }
|
|
170
|
+
}
|
|
168
171
|
}
|
|
169
172
|
|
|
170
173
|
const paramsJsonSchema = {
|
|
171
|
-
|
|
172
|
-
|
|
174
|
+
type: 'object',
|
|
175
|
+
properties: {
|
|
176
|
+
par1: { type: 'string' },
|
|
177
|
+
par2: { type: 'number' }
|
|
178
|
+
}
|
|
173
179
|
}
|
|
174
180
|
|
|
175
181
|
const headersJsonSchema = {
|
|
@@ -198,7 +204,7 @@ fastify.post('/the/url', { schema }, handler)
|
|
|
198
204
|
|
|
199
205
|
You can provide a list of plugins you want to use with Ajv:
|
|
200
206
|
|
|
201
|
-
> Refer to [`ajv options`](Server.md#
|
|
207
|
+
> Refer to [`ajv options`](Server.md#ajv) to check plugins format
|
|
202
208
|
|
|
203
209
|
```js
|
|
204
210
|
const fastify = require('fastify')({
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// works on Node v14.13.0+
|
|
2
|
+
import { fastify } from '../fastify.js'
|
|
3
|
+
|
|
4
|
+
const app = fastify({
|
|
5
|
+
logger: false
|
|
6
|
+
})
|
|
7
|
+
|
|
8
|
+
const schema = {
|
|
9
|
+
schema: {
|
|
10
|
+
response: {
|
|
11
|
+
200: {
|
|
12
|
+
type: 'object',
|
|
13
|
+
properties: {
|
|
14
|
+
hello: {
|
|
15
|
+
type: 'string'
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
app.get('/', schema, async function (req, reply) {
|
|
24
|
+
return { hello: 'world' }
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
app.listen(3000).catch(console.error)
|
package/fastify.js
CHANGED
|
@@ -4,6 +4,8 @@ const Avvio = require('avvio')
|
|
|
4
4
|
const http = require('http')
|
|
5
5
|
const querystring = require('querystring')
|
|
6
6
|
let lightMyRequest
|
|
7
|
+
let version
|
|
8
|
+
let versionLoaded = false
|
|
7
9
|
|
|
8
10
|
const {
|
|
9
11
|
kAvvioBoot,
|
|
@@ -24,7 +26,8 @@ const {
|
|
|
24
26
|
kState,
|
|
25
27
|
kOptions,
|
|
26
28
|
kPluginNameChain,
|
|
27
|
-
kSchemaErrorFormatter
|
|
29
|
+
kSchemaErrorFormatter,
|
|
30
|
+
kErrorHandler
|
|
28
31
|
} = require('./lib/symbols.js')
|
|
29
32
|
|
|
30
33
|
const { createServer } = require('./lib/server')
|
|
@@ -56,6 +59,21 @@ const onBadUrlContext = {
|
|
|
56
59
|
onError: []
|
|
57
60
|
}
|
|
58
61
|
|
|
62
|
+
function defaultErrorHandler (error, request, reply) {
|
|
63
|
+
if (reply.statusCode >= 500) {
|
|
64
|
+
reply.log.error(
|
|
65
|
+
{ req: request, res: reply, err: error },
|
|
66
|
+
error && error.message
|
|
67
|
+
)
|
|
68
|
+
} else if (reply.statusCode >= 400) {
|
|
69
|
+
reply.log.info(
|
|
70
|
+
{ res: reply, err: error },
|
|
71
|
+
error && error.message
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
reply.send(error)
|
|
75
|
+
}
|
|
76
|
+
|
|
59
77
|
function fastify (options) {
|
|
60
78
|
// Options validations
|
|
61
79
|
options = options || {}
|
|
@@ -159,6 +177,7 @@ function fastify (options) {
|
|
|
159
177
|
[kSchemas]: schemas,
|
|
160
178
|
[kValidatorCompiler]: null,
|
|
161
179
|
[kSchemaErrorFormatter]: options.schemaErrorFormatter,
|
|
180
|
+
[kErrorHandler]: defaultErrorHandler,
|
|
162
181
|
[kSerializerCompiler]: null,
|
|
163
182
|
[kReplySerializerDefault]: null,
|
|
164
183
|
[kContentTypeParser]: new ContentTypeParser(
|
|
@@ -218,6 +237,8 @@ function fastify (options) {
|
|
|
218
237
|
// custom parsers
|
|
219
238
|
addContentTypeParser: ContentTypeParser.helpers.addContentTypeParser,
|
|
220
239
|
hasContentTypeParser: ContentTypeParser.helpers.hasContentTypeParser,
|
|
240
|
+
getDefaultJsonParser: ContentTypeParser.defaultParsers.getDefaultJsonParser,
|
|
241
|
+
defaultTextParser: ContentTypeParser.defaultParsers.defaultTextParser,
|
|
221
242
|
// Fastify architecture methods (initialized by Avvio)
|
|
222
243
|
register: null,
|
|
223
244
|
after: null,
|
|
@@ -255,13 +276,26 @@ function fastify (options) {
|
|
|
255
276
|
}
|
|
256
277
|
},
|
|
257
278
|
prefix: {
|
|
258
|
-
get
|
|
279
|
+
get () { return this[kRoutePrefix] }
|
|
259
280
|
},
|
|
260
281
|
validatorCompiler: {
|
|
261
|
-
get
|
|
282
|
+
get () { return this[kValidatorCompiler] }
|
|
262
283
|
},
|
|
263
284
|
serializerCompiler: {
|
|
264
|
-
get
|
|
285
|
+
get () { return this[kSerializerCompiler] }
|
|
286
|
+
},
|
|
287
|
+
version: {
|
|
288
|
+
get () {
|
|
289
|
+
if (versionLoaded === false) {
|
|
290
|
+
version = loadVersion()
|
|
291
|
+
}
|
|
292
|
+
return version
|
|
293
|
+
}
|
|
294
|
+
},
|
|
295
|
+
errorHandler: {
|
|
296
|
+
get () {
|
|
297
|
+
return this[kErrorHandler]
|
|
298
|
+
}
|
|
265
299
|
}
|
|
266
300
|
})
|
|
267
301
|
|
|
@@ -549,7 +583,7 @@ function fastify (options) {
|
|
|
549
583
|
function setErrorHandler (func) {
|
|
550
584
|
throwIfAlreadyStarted('Cannot call "setErrorHandler" when fastify instance is already started!')
|
|
551
585
|
|
|
552
|
-
this
|
|
586
|
+
this[kErrorHandler] = func.bind(this)
|
|
553
587
|
return this
|
|
554
588
|
}
|
|
555
589
|
}
|
|
@@ -581,6 +615,20 @@ function wrapRouting (httpHandler, { rewriteUrl, logger }) {
|
|
|
581
615
|
}
|
|
582
616
|
}
|
|
583
617
|
|
|
618
|
+
function loadVersion () {
|
|
619
|
+
versionLoaded = true
|
|
620
|
+
const fs = require('fs')
|
|
621
|
+
const path = require('path')
|
|
622
|
+
try {
|
|
623
|
+
const pkgPath = path.join(__dirname, 'package.json')
|
|
624
|
+
fs.accessSync(pkgPath, fs.constants.R_OK)
|
|
625
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath))
|
|
626
|
+
return pkg.name === 'fastify' ? pkg.version : undefined
|
|
627
|
+
} catch (e) {
|
|
628
|
+
return undefined
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
|
|
584
632
|
/**
|
|
585
633
|
* These export configurations enable JS and TS developers
|
|
586
634
|
* to consumer fastify in whatever way best suits their needs.
|
|
@@ -592,6 +640,6 @@ function wrapRouting (httpHandler, { rewriteUrl, logger }) {
|
|
|
592
640
|
* - `import fastify from 'fastify'`
|
|
593
641
|
* - `import fastify, { TSC_definition } from 'fastify'`
|
|
594
642
|
*/
|
|
595
|
-
fastify.fastify = fastify
|
|
596
|
-
fastify.default = fastify
|
|
597
643
|
module.exports = fastify
|
|
644
|
+
module.exports.fastify = fastify
|
|
645
|
+
module.exports.default = fastify
|
package/lib/contentTypeParser.js
CHANGED
package/lib/context.js
CHANGED
|
@@ -17,7 +17,7 @@ function Context (schema, handler, Reply, Request, contentTypeParser, config, er
|
|
|
17
17
|
this.preHandler = null
|
|
18
18
|
this.onResponse = null
|
|
19
19
|
this.config = config
|
|
20
|
-
this.errorHandler = errorHandler
|
|
20
|
+
this.errorHandler = errorHandler
|
|
21
21
|
this._middie = null
|
|
22
22
|
this._parserOptions = { limit: bodyLimit || null }
|
|
23
23
|
this.logLevel = logLevel
|
|
@@ -28,21 +28,6 @@ function Context (schema, handler, Reply, Request, contentTypeParser, config, er
|
|
|
28
28
|
this.schemaErrorFormatter = schemaErrorFormatter || defaultSchemaErrorFormatter
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
function defaultErrorHandler (error, request, reply) {
|
|
32
|
-
if (reply.statusCode >= 500) {
|
|
33
|
-
reply.log.error(
|
|
34
|
-
{ req: request, res: reply, err: error },
|
|
35
|
-
error && error.message
|
|
36
|
-
)
|
|
37
|
-
} else if (reply.statusCode >= 400) {
|
|
38
|
-
reply.log.info(
|
|
39
|
-
{ res: reply, err: error },
|
|
40
|
-
error && error.message
|
|
41
|
-
)
|
|
42
|
-
}
|
|
43
|
-
reply.send(error)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
31
|
function defaultSchemaErrorFormatter (errors, dataVar) {
|
|
47
32
|
var text = ''
|
|
48
33
|
var separator = ', '
|
package/lib/errors.js
CHANGED
|
@@ -171,8 +171,8 @@ const codes = {
|
|
|
171
171
|
/**
|
|
172
172
|
* wrapThenable
|
|
173
173
|
*/
|
|
174
|
-
|
|
175
|
-
'
|
|
174
|
+
FST_ERR_PROMISE_NOT_FULFILLED: createError(
|
|
175
|
+
'FST_ERR_PROMISE_NOT_FULFILLED',
|
|
176
176
|
"Promise may not be fulfilled with 'undefined' when statusCode is not 204"
|
|
177
177
|
),
|
|
178
178
|
|
|
@@ -211,6 +211,14 @@ const codes = {
|
|
|
211
211
|
FST_ERR_REOPENED_SERVER: createError(
|
|
212
212
|
'FST_ERR_REOPENED_SERVER',
|
|
213
213
|
'Fastify is already listening'
|
|
214
|
+
),
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* plugin
|
|
218
|
+
*/
|
|
219
|
+
FST_ERR_PLUGIN_VERSION_MISMATCH: createError(
|
|
220
|
+
'FST_ERR_PLUGIN_VERSION_MISMATCH',
|
|
221
|
+
"fastify-plugin: %s - expected '%s' fastify version, '%s' is installed"
|
|
214
222
|
)
|
|
215
223
|
}
|
|
216
224
|
|
package/lib/fourOhFour.js
CHANGED
|
@@ -15,7 +15,8 @@ const {
|
|
|
15
15
|
kBodyLimit,
|
|
16
16
|
kLogLevel,
|
|
17
17
|
kFourOhFourContext,
|
|
18
|
-
kHooks
|
|
18
|
+
kHooks,
|
|
19
|
+
kErrorHandler
|
|
19
20
|
} = require('./symbols.js')
|
|
20
21
|
const { lifecycleHooks } = require('./hooks')
|
|
21
22
|
const fourOhFourContext = {
|
|
@@ -28,7 +29,7 @@ const fourOhFourContext = {
|
|
|
28
29
|
/**
|
|
29
30
|
* Each fastify instance have a:
|
|
30
31
|
* kFourOhFourLevelInstance: point to a fastify instance that has the 404 handler setted
|
|
31
|
-
* kCanSetNotFoundHandler: bool to track if the 404 handler has
|
|
32
|
+
* kCanSetNotFoundHandler: bool to track if the 404 handler has already been set
|
|
32
33
|
* kFourOhFour: the singleton instance of this 404 module
|
|
33
34
|
* kFourOhFourContext: the context in the reply object where the handler will be executed
|
|
34
35
|
*/
|
|
@@ -124,7 +125,7 @@ function fourOhFour (options) {
|
|
|
124
125
|
this[kRequest],
|
|
125
126
|
this[kContentTypeParser],
|
|
126
127
|
opts.config || {},
|
|
127
|
-
this
|
|
128
|
+
this[kErrorHandler],
|
|
128
129
|
this[kBodyLimit],
|
|
129
130
|
this[kLogLevel]
|
|
130
131
|
)
|
package/lib/logger.js
CHANGED
package/lib/pluginUtils.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const semver = require('semver')
|
|
3
4
|
const assert = require('assert')
|
|
4
5
|
const registeredPlugins = Symbol.for('registered-plugin')
|
|
5
6
|
const {
|
|
@@ -7,6 +8,7 @@ const {
|
|
|
7
8
|
kRequest,
|
|
8
9
|
kTestInternals
|
|
9
10
|
} = require('./symbols.js')
|
|
11
|
+
const { FST_ERR_PLUGIN_VERSION_MISMATCH } = require('./errors')
|
|
10
12
|
|
|
11
13
|
function getMeta (fn) {
|
|
12
14
|
return fn[Symbol.for('plugin-meta')]
|
|
@@ -84,6 +86,16 @@ function _checkDecorators (instance, decorators) {
|
|
|
84
86
|
})
|
|
85
87
|
}
|
|
86
88
|
|
|
89
|
+
function checkVersion (fn) {
|
|
90
|
+
const meta = getMeta(fn)
|
|
91
|
+
if (!meta) return
|
|
92
|
+
|
|
93
|
+
const requiredVersion = meta.fastify
|
|
94
|
+
if (!requiredVersion) return
|
|
95
|
+
|
|
96
|
+
if (!semver.satisfies(this.version, requiredVersion)) throw new FST_ERR_PLUGIN_VERSION_MISMATCH(meta.name, requiredVersion, this.version)
|
|
97
|
+
}
|
|
98
|
+
|
|
87
99
|
function registerPluginName (fn) {
|
|
88
100
|
const meta = getMeta(fn)
|
|
89
101
|
if (!meta) return
|
|
@@ -95,6 +107,9 @@ function registerPluginName (fn) {
|
|
|
95
107
|
|
|
96
108
|
function registerPlugin (fn) {
|
|
97
109
|
registerPluginName.call(this, fn)
|
|
110
|
+
if (this.version !== undefined) {
|
|
111
|
+
checkVersion.call(this, fn)
|
|
112
|
+
}
|
|
98
113
|
checkDecorators.call(this, fn)
|
|
99
114
|
checkDependencies.call(this, fn)
|
|
100
115
|
return shouldSkipOverride(fn)
|
package/lib/reply.js
CHANGED
|
@@ -303,9 +303,9 @@ Reply.prototype.getResponseTime = function () {
|
|
|
303
303
|
// - https://github.com/fastify/fastify/issues/1864 for the discussions
|
|
304
304
|
// - https://promisesaplus.com/ for the definition of thenable
|
|
305
305
|
// - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then for the signature
|
|
306
|
-
Reply.prototype.then = function (
|
|
306
|
+
Reply.prototype.then = function (fulfilled, rejected) {
|
|
307
307
|
if (this.sent) {
|
|
308
|
-
|
|
308
|
+
fulfilled()
|
|
309
309
|
return
|
|
310
310
|
}
|
|
311
311
|
|
|
@@ -317,7 +317,7 @@ Reply.prototype.then = function (fullfilled, rejected) {
|
|
|
317
317
|
rejected(err)
|
|
318
318
|
}
|
|
319
319
|
} else {
|
|
320
|
-
|
|
320
|
+
fulfilled()
|
|
321
321
|
}
|
|
322
322
|
})
|
|
323
323
|
}
|