fastify 4.3.0 → 4.5.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/build/build-validation.js +1 -1
- package/docs/Guides/Ecosystem.md +23 -0
- package/docs/Reference/Hooks.md +4 -1
- package/docs/Reference/Logging.md +1 -1
- package/docs/Reference/Reply.md +1 -0
- package/docs/Reference/Routes.md +6 -3
- package/docs/Reference/Server.md +20 -7
- package/docs/Reference/Validation-and-Serialization.md +1 -1
- package/fastify.d.ts +1 -1
- package/fastify.js +4 -4
- package/lib/configValidator.js +68 -19
- package/lib/context.js +1 -0
- package/lib/handleRequest.js +2 -2
- package/lib/httpMethods.js +22 -0
- package/lib/reqIdGenFactory.js +13 -2
- package/lib/route.js +2 -4
- package/lib/server.js +1 -0
- package/package.json +3 -9
- package/test/copy.test.js +41 -0
- package/test/hooks-async.test.js +43 -0
- package/test/internals/all.test.js +8 -2
- package/test/internals/reply.test.js +4 -1
- package/test/lock.test.js +73 -0
- package/test/logger.test.js +108 -0
- package/test/mkcol.test.js +38 -0
- package/test/move.test.js +45 -0
- package/test/propfind.test.js +108 -0
- package/test/proppatch.test.js +78 -0
- package/test/schema-examples.test.js +54 -0
- package/test/search.test.js +100 -0
- package/test/trace.test.js +21 -0
- package/test/types/fastify.test-d.ts +1 -0
- package/test/types/instance.test-d.ts +1 -1
- package/test/types/logger.test-d.ts +4 -5
- package/test/types/reply.test-d.ts +44 -3
- package/test/types/request.test-d.ts +9 -28
- package/test/types/type-provider.test-d.ts +3 -1
- package/test/unlock.test.js +41 -0
- package/test/upgrade.test.js +53 -0
- package/types/instance.d.ts +1 -1
- package/types/logger.d.ts +7 -4
- package/types/reply.d.ts +7 -6
- package/types/request.d.ts +2 -2
- package/types/type-provider.d.ts +1 -14
- package/types/utils.d.ts +2 -1
|
@@ -97,7 +97,7 @@ const schema = {
|
|
|
97
97
|
onProtoPoisoning: { type: 'string', default: defaultInitOptions.onProtoPoisoning },
|
|
98
98
|
onConstructorPoisoning: { type: 'string', default: defaultInitOptions.onConstructorPoisoning },
|
|
99
99
|
pluginTimeout: { type: 'integer', default: defaultInitOptions.pluginTimeout },
|
|
100
|
-
requestIdHeader: { type: 'string', default: defaultInitOptions.requestIdHeader },
|
|
100
|
+
requestIdHeader: { anyOf: [{ enum: [false] }, { type: 'string' }], default: defaultInitOptions.requestIdHeader },
|
|
101
101
|
requestIdLogLabel: { type: 'string', default: defaultInitOptions.requestIdLogLabel },
|
|
102
102
|
http2SessionTimeout: { type: 'integer', default: defaultInitOptions.http2SessionTimeout },
|
|
103
103
|
exposeHeadRoutes: { type: 'boolean', default: defaultInitOptions.exposeHeadRoutes },
|
package/docs/Guides/Ecosystem.md
CHANGED
|
@@ -112,6 +112,14 @@ section.
|
|
|
112
112
|
- [`@fastify/swagger`](https://github.com/fastify/fastify-swagger) Plugin for
|
|
113
113
|
serving Swagger/OpenAPI documentation for Fastify, supporting dynamic
|
|
114
114
|
generation.
|
|
115
|
+
- [`@fastify/type-provider-json-schema-to-ts`](https://github.com/fastify/fastify-type-provider-json-schema-to-ts)
|
|
116
|
+
Fastify
|
|
117
|
+
[type provider](https://www.fastify.io/docs/latest/Reference/Type-Providers/)
|
|
118
|
+
for [json-schema-to-ts](https://github.com/ThomasAribart/json-schema-to-ts).
|
|
119
|
+
- [`@fastify/type-provider-typebox`](https://github.com/fastify/fastify-type-provider-typebox)
|
|
120
|
+
Fastify
|
|
121
|
+
[type provider](https://www.fastify.io/docs/latest/Reference/Type-Providers/)
|
|
122
|
+
for [Typebox](https://github.com/sinclairzx81/typebox).
|
|
115
123
|
- [`@fastify/under-pressure`](https://github.com/fastify/under-pressure) Measure
|
|
116
124
|
process load with automatic handling of _"Service Unavailable"_ plugin for
|
|
117
125
|
Fastify.
|
|
@@ -147,6 +155,9 @@ section.
|
|
|
147
155
|
- [`@immobiliarelabs/fastify-sentry`](https://github.com/immobiliare/fastify-sentry)
|
|
148
156
|
Sentry errors handler that just works! Install, add your DSN and you're good
|
|
149
157
|
to go!
|
|
158
|
+
- [`@mateonunez/fastify-lyra`](https://github.com/mateonunez/fastify-lyra)
|
|
159
|
+
A plugin to implement [Lyra](https://github.com/nearform/lyra) search engine
|
|
160
|
+
on Fastify
|
|
150
161
|
- [`@mgcrea/fastify-graceful-exit`](https://github.com/mgcrea/fastify-graceful-exit)
|
|
151
162
|
A plugin to close the server gracefully
|
|
152
163
|
- [`@mgcrea/fastify-request-logger`](https://github.com/mgcrea/fastify-request-logger)
|
|
@@ -215,6 +226,8 @@ section.
|
|
|
215
226
|
to add [boom](https://github.com/hapijs/boom) support.
|
|
216
227
|
- [`fastify-bree`](https://github.com/climba03003/fastify-bree) Fastify plugin
|
|
217
228
|
to add [bree](https://github.com/breejs/bree) support.
|
|
229
|
+
- [`fastify-bugsnag`](https://github.com/ZigaStrgar/fastify-bugsnag) Fastify plugin
|
|
230
|
+
to add support for [Bugsnag](https://www.bugsnag.com/) error reporting.
|
|
218
231
|
- [`fastify-casbin`](https://github.com/nearform/fastify-casbin) Casbin support
|
|
219
232
|
for Fastify.
|
|
220
233
|
- [`fastify-casbin-rest`](https://github.com/nearform/fastify-casbin-rest)
|
|
@@ -315,6 +328,8 @@ section.
|
|
|
315
328
|
- [`fastify-http2https`](https://github.com/lolo32/fastify-http2https) Redirect
|
|
316
329
|
HTTP requests to HTTPS, both using the same port number, or different response
|
|
317
330
|
on HTTP and HTTPS.
|
|
331
|
+
- [`fastify-https-always`](https://github.com/mattbishop/fastify-https-always)
|
|
332
|
+
Lightweight, proxy-aware redirect plugin from HTTP to HTTPS.
|
|
318
333
|
- [`fastify-https-redirect`](https://github.com/tomsvogel/fastify-https-redirect)
|
|
319
334
|
Fastify plugin for auto-redirect from HTTP to HTTPS.
|
|
320
335
|
- [`fastify-impressions`](https://github.com/manju4ever/fastify-impressions)
|
|
@@ -328,6 +343,8 @@ section.
|
|
|
328
343
|
authentication for Fastify-based web apps.
|
|
329
344
|
- [`fastify-kafkajs`](https://github.com/kffl/fastify-kafkajs) Fastify plugin
|
|
330
345
|
that adds support for KafkaJS - a modern Apache Kafka client library.
|
|
346
|
+
- [`fastify-keycloak-adapter`](https://github.com/yubinTW/fastify-keycloak-adapter)
|
|
347
|
+
A keycloak adapter for a Fastify app.
|
|
331
348
|
- [`fastify-knexjs`](https://github.com/chapuletta/fastify-knexjs) Fastify
|
|
332
349
|
plugin for support KnexJS Query Builder.
|
|
333
350
|
- [`fastify-knexjs-mock`](https://github.com/chapuletta/fastify-knexjs-mock)
|
|
@@ -411,6 +428,8 @@ section.
|
|
|
411
428
|
- [`fastify-orientdb`](https://github.com/mahmed8003/fastify-orientdb) Fastify
|
|
412
429
|
OrientDB connection plugin, with which you can share the OrientDB connection
|
|
413
430
|
across every part of your server.
|
|
431
|
+
- [`fastify-osm`](https://github.com/gzileni/fastify-osm) Fastify
|
|
432
|
+
OSM plugin to run overpass queries by OpenStreetMap.
|
|
414
433
|
- [`fastify-peekaboo`](https://github.com/simone-sanfratello/fastify-peekaboo)
|
|
415
434
|
Fastify plugin for memoize responses by expressive settings.
|
|
416
435
|
- [`fastify-piscina`](https://github.com/piscinajs/fastify-piscina) A worker
|
|
@@ -508,6 +527,10 @@ section.
|
|
|
508
527
|
TOTP (e.g. for 2FA).
|
|
509
528
|
- [`fastify-twitch-ebs-tools`](https://github.com/lukemnet/fastify-twitch-ebs-tools)
|
|
510
529
|
Useful functions for Twitch Extension Backend Services (EBS).
|
|
530
|
+
- [`fastify-type-provider-zod`](https://github.com/turkerdev/fastify-type-provider-zod)
|
|
531
|
+
Fastify
|
|
532
|
+
[type provider](https://www.fastify.io/docs/latest/Reference/Type-Providers/)
|
|
533
|
+
for [zod](https://github.com/colinhacks/zod).
|
|
511
534
|
- [`fastify-typeorm-plugin`](https://github.com/inthepocket/fastify-typeorm-plugin)
|
|
512
535
|
Fastify plugin to work with TypeORM.
|
|
513
536
|
- [`fastify-vhost`](https://github.com/patrickpissurno/fastify-vhost) Proxy
|
package/docs/Reference/Hooks.md
CHANGED
|
@@ -244,6 +244,9 @@ The `onResponse` hook is executed when a response has been sent, so you will not
|
|
|
244
244
|
be able to send more data to the client. It can however be useful for sending
|
|
245
245
|
data to external services, for example, to gather statistics.
|
|
246
246
|
|
|
247
|
+
**Note:** setting `disableRequestLogging` to `true` will disable any error log
|
|
248
|
+
inside the `onResponse` hook. In this case use `try - catch` to log errors.
|
|
249
|
+
|
|
247
250
|
### onTimeout
|
|
248
251
|
|
|
249
252
|
```js
|
|
@@ -287,7 +290,7 @@ fastify.addHook('preHandler', (request, reply, done) => {
|
|
|
287
290
|
|
|
288
291
|
Or if you're using `async/await` you can just throw an error:
|
|
289
292
|
```js
|
|
290
|
-
fastify.addHook('
|
|
293
|
+
fastify.addHook('onRequest', async (request, reply) => {
|
|
291
294
|
throw new Error('Some error')
|
|
292
295
|
})
|
|
293
296
|
```
|
|
@@ -170,7 +170,7 @@ app.addHook('preHandler', function (req, reply, done) {
|
|
|
170
170
|
You can also supply your own logger instance. Instead of passing configuration
|
|
171
171
|
options, pass the instance. The logger you supply must conform to the Pino
|
|
172
172
|
interface; that is, it must have the following methods: `info`, `error`,
|
|
173
|
-
`debug`, `fatal`, `warn`, `trace`, `child`.
|
|
173
|
+
`debug`, `fatal`, `warn`, `trace`, `silent`, `child` and a string property `level`.
|
|
174
174
|
|
|
175
175
|
Example:
|
|
176
176
|
|
package/docs/Reference/Reply.md
CHANGED
|
@@ -767,6 +767,7 @@ Fastify natively handles promises and supports async-await.
|
|
|
767
767
|
|
|
768
768
|
*Note that in the following examples we are not using reply.send.*
|
|
769
769
|
```js
|
|
770
|
+
const { promisify } = require('util')
|
|
770
771
|
const delay = promisify(setTimeout)
|
|
771
772
|
|
|
772
773
|
fastify.get('/promises', options, function (request, reply) {
|
package/docs/Reference/Routes.md
CHANGED
|
@@ -32,8 +32,10 @@ fastify.route(options)
|
|
|
32
32
|
### Routes options
|
|
33
33
|
<a id="options"></a>
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
`'POST'`, `'PUT'
|
|
35
|
+
* `method`: currently it supports `'DELETE'`, `'GET'`, `'HEAD'`, `'PATCH'`,
|
|
36
|
+
`'POST'`, `'PUT'`, `'OPTIONS'`, `'SEARCH'`, `'TRACE'`, `'PROPFIND'`,
|
|
37
|
+
`'PROPPATCH'`, `'MKCOL'`, `'COPY'`, `'MOVE'`, `'LOCK'` and `'UNLOCK'`.
|
|
38
|
+
It could also be an array of methods.
|
|
37
39
|
* `url`: the path of the URL to match this route (alias: `path`).
|
|
38
40
|
* `schema`: an object containing the schemas for the request and response. They
|
|
39
41
|
need to be in [JSON Schema](https://json-schema.org/) format, check
|
|
@@ -656,7 +658,7 @@ fastify.inject({
|
|
|
656
658
|
>
|
|
657
659
|
> ```js
|
|
658
660
|
> const append = require('vary').append
|
|
659
|
-
> fastify.addHook('onSend',
|
|
661
|
+
> fastify.addHook('onSend', (req, reply, payload, done) => {
|
|
660
662
|
> if (req.headers['accept-version']) { // or the custom header you are using
|
|
661
663
|
> let value = reply.getHeader('Vary') || ''
|
|
662
664
|
> const header = Array.isArray(value) ? value.join(', ') : String(value)
|
|
@@ -664,6 +666,7 @@ fastify.inject({
|
|
|
664
666
|
> reply.header('Vary', value)
|
|
665
667
|
> }
|
|
666
668
|
> }
|
|
669
|
+
> done()
|
|
667
670
|
> })
|
|
668
671
|
> ```
|
|
669
672
|
|
package/docs/Reference/Server.md
CHANGED
|
@@ -55,7 +55,7 @@ describes the properties available in that options object.
|
|
|
55
55
|
- [routing](#routing)
|
|
56
56
|
- [route](#route)
|
|
57
57
|
- [close](#close)
|
|
58
|
-
- [decorate
|
|
58
|
+
- [decorate*](#decorate)
|
|
59
59
|
- [register](#register)
|
|
60
60
|
- [addHook](#addhook)
|
|
61
61
|
- [prefix](#prefix)
|
|
@@ -488,11 +488,18 @@ about safe regexp: [Safe-regex2](https://www.npmjs.com/package/safe-regex2)
|
|
|
488
488
|
### `requestIdHeader`
|
|
489
489
|
<a id="factory-request-id-header"></a>
|
|
490
490
|
|
|
491
|
-
The header name used to
|
|
491
|
+
The header name used to set the request-id. See [the
|
|
492
492
|
request-id](./Logging.md#logging-request-id) section.
|
|
493
|
+
Setting `requestIdHeader` to `false` will always use [genReqId](#genreqid)
|
|
493
494
|
|
|
494
495
|
+ Default: `'request-id'`
|
|
495
|
-
|
|
496
|
+
|
|
497
|
+
```js
|
|
498
|
+
const fastify = require('fastify')({
|
|
499
|
+
requestIdHeader: 'x-custom-id', // -> use 'X-Custom-Id' header if available
|
|
500
|
+
//requestIdHeader: false, // -> always use genReqId
|
|
501
|
+
})
|
|
502
|
+
```
|
|
496
503
|
### `requestIdLogLabel`
|
|
497
504
|
<a id="factory-request-id-log-label"></a>
|
|
498
505
|
|
|
@@ -890,7 +897,7 @@ fastify.ready().then(() => {
|
|
|
890
897
|
Starts the server and internally waits for the `.ready()` event. The signature
|
|
891
898
|
is `.listen([options][, callback])`. Both the `options` object and the
|
|
892
899
|
`callback` parameters follow the [Node.js
|
|
893
|
-
core]
|
|
900
|
+
core](https://nodejs.org/api/net.html#serverlistenoptions-callback) parameter
|
|
894
901
|
definitions.
|
|
895
902
|
|
|
896
903
|
By default, the server will listen on the address(es) resolved by `localhost`
|
|
@@ -1112,12 +1119,15 @@ fastify.register(function (instance, opts, done) {
|
|
|
1112
1119
|
<a id="pluginName"></a>
|
|
1113
1120
|
|
|
1114
1121
|
Name of the current plugin. The root plugin is called `'fastify'`. There are
|
|
1115
|
-
|
|
1122
|
+
different ways to define a name (in order).
|
|
1116
1123
|
|
|
1117
1124
|
1. If you use [fastify-plugin](https://github.com/fastify/fastify-plugin) the
|
|
1118
1125
|
metadata `name` is used.
|
|
1119
|
-
2. If
|
|
1120
|
-
|
|
1126
|
+
2. If the exported plugin has the `Symbol.for('fastify.display-name')` property,
|
|
1127
|
+
then the value of that property is used.
|
|
1128
|
+
Example: `pluginFn[Symbol.for('fastify.display-name')] = "Custom Name"`
|
|
1129
|
+
3. If you `module.exports` a plugin the filename is used.
|
|
1130
|
+
4. If you use a regular [function
|
|
1121
1131
|
declaration](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions#Defining_functions)
|
|
1122
1132
|
the function name is used.
|
|
1123
1133
|
|
|
@@ -1402,6 +1412,9 @@ handlers. *async-await* is supported as well.
|
|
|
1402
1412
|
*Note: If the error `statusCode` is less than 400, Fastify will automatically
|
|
1403
1413
|
set it at 500 before calling the error handler.*
|
|
1404
1414
|
|
|
1415
|
+
*Also note* that `setErrorHandler` will ***not*** catch any error inside
|
|
1416
|
+
an `onResponse` hook because the response has already been sent to the client.
|
|
1417
|
+
|
|
1405
1418
|
```js
|
|
1406
1419
|
fastify.setErrorHandler(function (error, request, reply) {
|
|
1407
1420
|
// Log error
|
|
@@ -268,7 +268,7 @@ fastify.listen({ port: 3000 }, (err) => {
|
|
|
268
268
|
```sh
|
|
269
269
|
curl -X GET "http://localhost:3000/?ids=1
|
|
270
270
|
|
|
271
|
-
{"params":{"
|
|
271
|
+
{"params":{"ids":["1"]}}
|
|
272
272
|
```
|
|
273
273
|
|
|
274
274
|
You can also specify a custom schema validator for each parameter type (body,
|
package/fastify.d.ts
CHANGED
|
@@ -123,7 +123,7 @@ export type FastifyServerOptions<
|
|
|
123
123
|
serializerOpts?: FJSOptions | Record<string, unknown>,
|
|
124
124
|
serverFactory?: FastifyServerFactory<RawServer>,
|
|
125
125
|
caseSensitive?: boolean,
|
|
126
|
-
requestIdHeader?: string,
|
|
126
|
+
requestIdHeader?: string | false,
|
|
127
127
|
requestIdLogLabel?: string;
|
|
128
128
|
jsonShorthand?: boolean;
|
|
129
129
|
genReqId?: <RequestGeneric extends RequestGenericInterface = RequestGenericInterface, TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault>(req: FastifyRequest<RequestGeneric, RawServer, RawRequestDefaultExpression<RawServer>, FastifySchema, TypeProvider>) => string,
|
package/fastify.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const VERSION = '4.
|
|
3
|
+
const VERSION = '4.5.1'
|
|
4
4
|
|
|
5
5
|
const Avvio = require('avvio')
|
|
6
6
|
const http = require('http')
|
|
@@ -34,7 +34,7 @@ const {
|
|
|
34
34
|
const { createServer, compileValidateHTTPVersion } = require('./lib/server')
|
|
35
35
|
const Reply = require('./lib/reply')
|
|
36
36
|
const Request = require('./lib/request')
|
|
37
|
-
const supportedMethods =
|
|
37
|
+
const { supportedMethods } = require('./lib/httpMethods')
|
|
38
38
|
const decorator = require('./lib/decorate')
|
|
39
39
|
const ContentTypeParser = require('./lib/contentTypeParser')
|
|
40
40
|
const SchemaController = require('./lib/schema-controller')
|
|
@@ -98,8 +98,8 @@ function fastify (options) {
|
|
|
98
98
|
|
|
99
99
|
validateBodyLimitOption(options.bodyLimit)
|
|
100
100
|
|
|
101
|
-
const requestIdHeader = options.requestIdHeader || defaultInitOptions.requestIdHeader
|
|
102
|
-
const genReqId = options.genReqId
|
|
101
|
+
const requestIdHeader = (options.requestIdHeader === false) ? false : (options.requestIdHeader || defaultInitOptions.requestIdHeader)
|
|
102
|
+
const genReqId = reqIdGenFactory(requestIdHeader, options.genReqId)
|
|
103
103
|
const requestIdLogLabel = options.requestIdLogLabel || 'reqId'
|
|
104
104
|
const bodyLimit = options.bodyLimit || defaultInitOptions.bodyLimit
|
|
105
105
|
const disableRequestLogging = options.disableRequestLogging || false
|
package/lib/configValidator.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"use strict";
|
|
4
4
|
module.exports = validate10;
|
|
5
5
|
module.exports.default = validate10;
|
|
6
|
-
const schema11 = {"type":"object","additionalProperties":false,"properties":{"connectionTimeout":{"type":"integer","default":0},"keepAliveTimeout":{"type":"integer","default":72000},"forceCloseConnections":{"oneOf":[{"type":"string","pattern":"idle"},{"type":"boolean"}]},"maxRequestsPerSocket":{"type":"integer","default":0,"nullable":true},"requestTimeout":{"type":"integer","default":0},"bodyLimit":{"type":"integer","default":1048576},"caseSensitive":{"type":"boolean","default":true},"allowUnsafeRegex":{"type":"boolean","default":false},"http2":{"type":"boolean"},"https":{"if":{"not":{"oneOf":[{"type":"boolean"},{"type":"null"},{"type":"object","additionalProperties":false,"required":["allowHTTP1"],"properties":{"allowHTTP1":{"type":"boolean"}}}]}},"then":{"setDefaultValue":true}},"ignoreTrailingSlash":{"type":"boolean","default":false},"ignoreDuplicateSlashes":{"type":"boolean","default":false},"disableRequestLogging":{"type":"boolean","default":false},"jsonShorthand":{"type":"boolean","default":true},"maxParamLength":{"type":"integer","default":100},"onProtoPoisoning":{"type":"string","default":"error"},"onConstructorPoisoning":{"type":"string","default":"error"},"pluginTimeout":{"type":"integer","default":10000},"requestIdHeader":{"type":"string","default":"request-id"},"requestIdLogLabel":{"type":"string","default":"reqId"},"http2SessionTimeout":{"type":"integer","default":72000},"exposeHeadRoutes":{"type":"boolean","default":true},"versioning":{"type":"object","additionalProperties":true,"required":["storage","deriveVersion"],"properties":{"storage":{},"deriveVersion":{}}},"constraints":{"type":"object","additionalProperties":{"type":"object","required":["name","storage","validate","deriveConstraint"],"additionalProperties":true,"properties":{"name":{"type":"string"},"storage":{},"validate":{},"deriveConstraint":{}}}}}};
|
|
6
|
+
const schema11 = {"type":"object","additionalProperties":false,"properties":{"connectionTimeout":{"type":"integer","default":0},"keepAliveTimeout":{"type":"integer","default":72000},"forceCloseConnections":{"oneOf":[{"type":"string","pattern":"idle"},{"type":"boolean"}]},"maxRequestsPerSocket":{"type":"integer","default":0,"nullable":true},"requestTimeout":{"type":"integer","default":0},"bodyLimit":{"type":"integer","default":1048576},"caseSensitive":{"type":"boolean","default":true},"allowUnsafeRegex":{"type":"boolean","default":false},"http2":{"type":"boolean"},"https":{"if":{"not":{"oneOf":[{"type":"boolean"},{"type":"null"},{"type":"object","additionalProperties":false,"required":["allowHTTP1"],"properties":{"allowHTTP1":{"type":"boolean"}}}]}},"then":{"setDefaultValue":true}},"ignoreTrailingSlash":{"type":"boolean","default":false},"ignoreDuplicateSlashes":{"type":"boolean","default":false},"disableRequestLogging":{"type":"boolean","default":false},"jsonShorthand":{"type":"boolean","default":true},"maxParamLength":{"type":"integer","default":100},"onProtoPoisoning":{"type":"string","default":"error"},"onConstructorPoisoning":{"type":"string","default":"error"},"pluginTimeout":{"type":"integer","default":10000},"requestIdHeader":{"anyOf":[{"enum":[false]},{"type":"string"}],"default":"request-id"},"requestIdLogLabel":{"type":"string","default":"reqId"},"http2SessionTimeout":{"type":"integer","default":72000},"exposeHeadRoutes":{"type":"boolean","default":true},"versioning":{"type":"object","additionalProperties":true,"required":["storage","deriveVersion"],"properties":{"storage":{},"deriveVersion":{}}},"constraints":{"type":"object","additionalProperties":{"type":"object","required":["name","storage","validate","deriveConstraint"],"additionalProperties":true,"properties":{"name":{"type":"string"},"storage":{},"validate":{},"deriveConstraint":{}}}}}};
|
|
7
7
|
const func2 = Object.prototype.hasOwnProperty;
|
|
8
8
|
const pattern0 = new RegExp("idle", "u");
|
|
9
9
|
|
|
@@ -837,6 +837,23 @@ var valid0 = _errs55 === errors;
|
|
|
837
837
|
if(valid0){
|
|
838
838
|
let data19 = data.requestIdHeader;
|
|
839
839
|
const _errs57 = errors;
|
|
840
|
+
const _errs58 = errors;
|
|
841
|
+
let valid6 = false;
|
|
842
|
+
const _errs59 = errors;
|
|
843
|
+
if(!(data19 === false)){
|
|
844
|
+
const err12 = {instancePath:instancePath+"/requestIdHeader",schemaPath:"#/properties/requestIdHeader/anyOf/0/enum",keyword:"enum",params:{allowedValues: schema11.properties.requestIdHeader.anyOf[0].enum},message:"must be equal to one of the allowed values"};
|
|
845
|
+
if(vErrors === null){
|
|
846
|
+
vErrors = [err12];
|
|
847
|
+
}
|
|
848
|
+
else {
|
|
849
|
+
vErrors.push(err12);
|
|
850
|
+
}
|
|
851
|
+
errors++;
|
|
852
|
+
}
|
|
853
|
+
var _valid3 = _errs59 === errors;
|
|
854
|
+
valid6 = valid6 || _valid3;
|
|
855
|
+
if(!valid6){
|
|
856
|
+
const _errs60 = errors;
|
|
840
857
|
if(typeof data19 !== "string"){
|
|
841
858
|
let dataType21 = typeof data19;
|
|
842
859
|
let coerced21 = undefined;
|
|
@@ -848,8 +865,14 @@ else if(data19 === null){
|
|
|
848
865
|
coerced21 = "";
|
|
849
866
|
}
|
|
850
867
|
else {
|
|
851
|
-
|
|
852
|
-
|
|
868
|
+
const err13 = {instancePath:instancePath+"/requestIdHeader",schemaPath:"#/properties/requestIdHeader/anyOf/1/type",keyword:"type",params:{type: "string"},message:"must be string"};
|
|
869
|
+
if(vErrors === null){
|
|
870
|
+
vErrors = [err13];
|
|
871
|
+
}
|
|
872
|
+
else {
|
|
873
|
+
vErrors.push(err13);
|
|
874
|
+
}
|
|
875
|
+
errors++;
|
|
853
876
|
}
|
|
854
877
|
}
|
|
855
878
|
if(coerced21 !== undefined){
|
|
@@ -859,10 +882,36 @@ data["requestIdHeader"] = coerced21;
|
|
|
859
882
|
}
|
|
860
883
|
}
|
|
861
884
|
}
|
|
885
|
+
var _valid3 = _errs60 === errors;
|
|
886
|
+
valid6 = valid6 || _valid3;
|
|
887
|
+
}
|
|
888
|
+
if(!valid6){
|
|
889
|
+
const err14 = {instancePath:instancePath+"/requestIdHeader",schemaPath:"#/properties/requestIdHeader/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};
|
|
890
|
+
if(vErrors === null){
|
|
891
|
+
vErrors = [err14];
|
|
892
|
+
}
|
|
893
|
+
else {
|
|
894
|
+
vErrors.push(err14);
|
|
895
|
+
}
|
|
896
|
+
errors++;
|
|
897
|
+
validate10.errors = vErrors;
|
|
898
|
+
return false;
|
|
899
|
+
}
|
|
900
|
+
else {
|
|
901
|
+
errors = _errs58;
|
|
902
|
+
if(vErrors !== null){
|
|
903
|
+
if(_errs58){
|
|
904
|
+
vErrors.length = _errs58;
|
|
905
|
+
}
|
|
906
|
+
else {
|
|
907
|
+
vErrors = null;
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
}
|
|
862
911
|
var valid0 = _errs57 === errors;
|
|
863
912
|
if(valid0){
|
|
864
913
|
let data20 = data.requestIdLogLabel;
|
|
865
|
-
const
|
|
914
|
+
const _errs62 = errors;
|
|
866
915
|
if(typeof data20 !== "string"){
|
|
867
916
|
let dataType22 = typeof data20;
|
|
868
917
|
let coerced22 = undefined;
|
|
@@ -885,10 +934,10 @@ data["requestIdLogLabel"] = coerced22;
|
|
|
885
934
|
}
|
|
886
935
|
}
|
|
887
936
|
}
|
|
888
|
-
var valid0 =
|
|
937
|
+
var valid0 = _errs62 === errors;
|
|
889
938
|
if(valid0){
|
|
890
939
|
let data21 = data.http2SessionTimeout;
|
|
891
|
-
const
|
|
940
|
+
const _errs64 = errors;
|
|
892
941
|
if(!(((typeof data21 == "number") && (!(data21 % 1) && !isNaN(data21))) && (isFinite(data21)))){
|
|
893
942
|
let dataType23 = typeof data21;
|
|
894
943
|
let coerced23 = undefined;
|
|
@@ -909,10 +958,10 @@ data["http2SessionTimeout"] = coerced23;
|
|
|
909
958
|
}
|
|
910
959
|
}
|
|
911
960
|
}
|
|
912
|
-
var valid0 =
|
|
961
|
+
var valid0 = _errs64 === errors;
|
|
913
962
|
if(valid0){
|
|
914
963
|
let data22 = data.exposeHeadRoutes;
|
|
915
|
-
const
|
|
964
|
+
const _errs66 = errors;
|
|
916
965
|
if(typeof data22 !== "boolean"){
|
|
917
966
|
let coerced24 = undefined;
|
|
918
967
|
if(!(coerced24 !== undefined)){
|
|
@@ -934,12 +983,12 @@ data["exposeHeadRoutes"] = coerced24;
|
|
|
934
983
|
}
|
|
935
984
|
}
|
|
936
985
|
}
|
|
937
|
-
var valid0 =
|
|
986
|
+
var valid0 = _errs66 === errors;
|
|
938
987
|
if(valid0){
|
|
939
988
|
if(data.versioning !== undefined){
|
|
940
989
|
let data23 = data.versioning;
|
|
941
|
-
const
|
|
942
|
-
if(errors ===
|
|
990
|
+
const _errs68 = errors;
|
|
991
|
+
if(errors === _errs68){
|
|
943
992
|
if(data23 && typeof data23 == "object" && !Array.isArray(data23)){
|
|
944
993
|
let missing1;
|
|
945
994
|
if(((data23.storage === undefined) && (missing1 = "storage")) || ((data23.deriveVersion === undefined) && (missing1 = "deriveVersion"))){
|
|
@@ -952,7 +1001,7 @@ validate10.errors = [{instancePath:instancePath+"/versioning",schemaPath:"#/prop
|
|
|
952
1001
|
return false;
|
|
953
1002
|
}
|
|
954
1003
|
}
|
|
955
|
-
var valid0 =
|
|
1004
|
+
var valid0 = _errs68 === errors;
|
|
956
1005
|
}
|
|
957
1006
|
else {
|
|
958
1007
|
var valid0 = true;
|
|
@@ -960,13 +1009,13 @@ var valid0 = true;
|
|
|
960
1009
|
if(valid0){
|
|
961
1010
|
if(data.constraints !== undefined){
|
|
962
1011
|
let data24 = data.constraints;
|
|
963
|
-
const
|
|
964
|
-
if(errors ===
|
|
1012
|
+
const _errs71 = errors;
|
|
1013
|
+
if(errors === _errs71){
|
|
965
1014
|
if(data24 && typeof data24 == "object" && !Array.isArray(data24)){
|
|
966
1015
|
for(const key2 in data24){
|
|
967
1016
|
let data25 = data24[key2];
|
|
968
|
-
const
|
|
969
|
-
if(errors ===
|
|
1017
|
+
const _errs74 = errors;
|
|
1018
|
+
if(errors === _errs74){
|
|
970
1019
|
if(data25 && typeof data25 == "object" && !Array.isArray(data25)){
|
|
971
1020
|
let missing2;
|
|
972
1021
|
if(((((data25.name === undefined) && (missing2 = "name")) || ((data25.storage === undefined) && (missing2 = "storage"))) || ((data25.validate === undefined) && (missing2 = "validate"))) || ((data25.deriveConstraint === undefined) && (missing2 = "deriveConstraint"))){
|
|
@@ -1006,8 +1055,8 @@ validate10.errors = [{instancePath:instancePath+"/constraints/" + key2.replace(/
|
|
|
1006
1055
|
return false;
|
|
1007
1056
|
}
|
|
1008
1057
|
}
|
|
1009
|
-
var
|
|
1010
|
-
if(!
|
|
1058
|
+
var valid7 = _errs74 === errors;
|
|
1059
|
+
if(!valid7){
|
|
1011
1060
|
break;
|
|
1012
1061
|
}
|
|
1013
1062
|
}
|
|
@@ -1017,7 +1066,7 @@ validate10.errors = [{instancePath:instancePath+"/constraints",schemaPath:"#/pro
|
|
|
1017
1066
|
return false;
|
|
1018
1067
|
}
|
|
1019
1068
|
}
|
|
1020
|
-
var valid0 =
|
|
1069
|
+
var valid0 = _errs71 === errors;
|
|
1021
1070
|
}
|
|
1022
1071
|
else {
|
|
1023
1072
|
var valid0 = true;
|
package/lib/context.js
CHANGED
package/lib/handleRequest.js
CHANGED
|
@@ -18,14 +18,14 @@ function handleRequest (err, request, reply) {
|
|
|
18
18
|
const method = request.raw.method
|
|
19
19
|
const headers = request.headers
|
|
20
20
|
|
|
21
|
-
if (method === 'GET' || method === 'HEAD') {
|
|
21
|
+
if (method === 'GET' || method === 'HEAD' || method === 'SEARCH') {
|
|
22
22
|
handler(request, reply)
|
|
23
23
|
return
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
const contentType = headers['content-type']
|
|
27
27
|
|
|
28
|
-
if (method === 'POST' || method === 'PUT' || method === 'PATCH') {
|
|
28
|
+
if (method === 'POST' || method === 'PUT' || method === 'PATCH' || method === 'TRACE') {
|
|
29
29
|
if (contentType === undefined) {
|
|
30
30
|
if (
|
|
31
31
|
headers['transfer-encoding'] === undefined &&
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
supportedMethods: [
|
|
5
|
+
'DELETE',
|
|
6
|
+
'GET',
|
|
7
|
+
'HEAD',
|
|
8
|
+
'PATCH',
|
|
9
|
+
'POST',
|
|
10
|
+
'PUT',
|
|
11
|
+
'OPTIONS',
|
|
12
|
+
'PROPFIND',
|
|
13
|
+
'PROPPATCH',
|
|
14
|
+
'MKCOL',
|
|
15
|
+
'COPY',
|
|
16
|
+
'MOVE',
|
|
17
|
+
'LOCK',
|
|
18
|
+
'UNLOCK',
|
|
19
|
+
'TRACE',
|
|
20
|
+
'SEARCH'
|
|
21
|
+
]
|
|
22
|
+
}
|
package/lib/reqIdGenFactory.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
module.exports = function () {
|
|
3
|
+
module.exports = function (requestIdHeader, optGenReqId) {
|
|
4
4
|
// 2,147,483,647 (2^31 − 1) stands for max SMI value (an internal optimization of V8).
|
|
5
5
|
// With this upper bound, if you'll be generating 1k ids/sec, you're going to hit it in ~25 days.
|
|
6
6
|
// This is very likely to happen in real-world applications, hence the limit is enforced.
|
|
@@ -8,8 +8,19 @@ module.exports = function () {
|
|
|
8
8
|
// In the worst cases, it will become a float, losing accuracy.
|
|
9
9
|
const maxInt = 2147483647
|
|
10
10
|
let nextReqId = 0
|
|
11
|
-
|
|
11
|
+
function defaultGenReqId (req) {
|
|
12
12
|
nextReqId = (nextReqId + 1) & maxInt
|
|
13
13
|
return `req-${nextReqId.toString(36)}`
|
|
14
14
|
}
|
|
15
|
+
|
|
16
|
+
const genReqId = optGenReqId || defaultGenReqId
|
|
17
|
+
|
|
18
|
+
if (requestIdHeader) {
|
|
19
|
+
// requestIdHeader = typeof requestIdHeader === 'string' ? requestIdHeader : 'request-id'
|
|
20
|
+
return function (req) {
|
|
21
|
+
return req.headers[requestIdHeader] || genReqId(req)
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return genReqId
|
|
15
26
|
}
|
package/lib/route.js
CHANGED
|
@@ -4,7 +4,7 @@ const FindMyWay = require('find-my-way')
|
|
|
4
4
|
const Context = require('./context')
|
|
5
5
|
const handleRequest = require('./handleRequest')
|
|
6
6
|
const { hookRunner, hookIterator, lifecycleHooks } = require('./hooks')
|
|
7
|
-
const supportedMethods =
|
|
7
|
+
const { supportedMethods } = require('./httpMethods')
|
|
8
8
|
const { normalizeSchema } = require('./schemas')
|
|
9
9
|
const { parseHeadOnSendHandlers } = require('./headRoute')
|
|
10
10
|
const warning = require('./warnings')
|
|
@@ -46,7 +46,6 @@ function buildRouting (options) {
|
|
|
46
46
|
|
|
47
47
|
let avvio
|
|
48
48
|
let fourOhFour
|
|
49
|
-
let requestIdHeader
|
|
50
49
|
let requestIdLogLabel
|
|
51
50
|
let logger
|
|
52
51
|
let hasLogger
|
|
@@ -74,7 +73,6 @@ function buildRouting (options) {
|
|
|
74
73
|
validateHTTPVersion = fastifyArgs.validateHTTPVersion
|
|
75
74
|
|
|
76
75
|
globalExposeHeadRoutes = options.exposeHeadRoutes
|
|
77
|
-
requestIdHeader = options.requestIdHeader
|
|
78
76
|
requestIdLogLabel = options.requestIdLogLabel
|
|
79
77
|
genReqId = options.genReqId
|
|
80
78
|
disableRequestLogging = options.disableRequestLogging
|
|
@@ -397,7 +395,7 @@ function buildRouting (options) {
|
|
|
397
395
|
req.headers[kRequestAcceptVersion] = undefined
|
|
398
396
|
}
|
|
399
397
|
|
|
400
|
-
const id =
|
|
398
|
+
const id = genReqId(req)
|
|
401
399
|
|
|
402
400
|
const loggerBinding = {
|
|
403
401
|
[requestIdLogLabel]: id
|
package/lib/server.js
CHANGED
|
@@ -132,6 +132,7 @@ function multipleBindings (mainServer, httpHandler, serverOpts, listenOptions, o
|
|
|
132
132
|
|
|
133
133
|
const secondaryServer = getServerInstance(serverOpts, httpHandler)
|
|
134
134
|
const closeSecondary = () => { secondaryServer.close(() => {}) }
|
|
135
|
+
secondaryServer.on('upgrade', mainServer.emit.bind(mainServer, 'upgrade'))
|
|
135
136
|
mainServer.on('unref', closeSecondary)
|
|
136
137
|
mainServer.on('close', closeSecondary)
|
|
137
138
|
mainServer.on('error', closeSecondary)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fastify",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.5.1",
|
|
4
4
|
"description": "Fast and low overhead web framework, for Node.js",
|
|
5
5
|
"main": "fastify.js",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -137,8 +137,6 @@
|
|
|
137
137
|
"ajv-i18n": "^4.2.0",
|
|
138
138
|
"ajv-merge-patch": "^5.0.1",
|
|
139
139
|
"branch-comparer": "^1.1.0",
|
|
140
|
-
"cors": "^2.8.5",
|
|
141
|
-
"dns-prefetch-control": "^0.3.0",
|
|
142
140
|
"eslint": "^8.16.0",
|
|
143
141
|
"eslint-config-standard": "^17.0.0-1",
|
|
144
142
|
"eslint-import-resolver-node": "^0.3.6",
|
|
@@ -150,21 +148,17 @@
|
|
|
150
148
|
"fastify-plugin": "^4.0.0",
|
|
151
149
|
"fluent-json-schema": "^3.1.0",
|
|
152
150
|
"form-data": "^4.0.0",
|
|
153
|
-
"frameguard": "^4.0.0",
|
|
154
151
|
"h2url": "^0.2.0",
|
|
155
|
-
"helmet": "^5.1.0",
|
|
156
|
-
"hide-powered-by": "^1.1.0",
|
|
157
152
|
"http-errors": "^2.0.0",
|
|
158
153
|
"joi": "^17.6.0",
|
|
159
154
|
"json-schema-to-ts": "^2.5.3",
|
|
160
155
|
"JSONStream": "^1.3.5",
|
|
161
156
|
"license-checker": "^25.0.1",
|
|
162
|
-
"markdownlint-cli2": "^0.
|
|
157
|
+
"markdownlint-cli2": "^0.5.0",
|
|
163
158
|
"proxyquire": "^2.1.3",
|
|
164
159
|
"pump": "^3.0.0",
|
|
165
160
|
"self-cert": "^2.0.0",
|
|
166
161
|
"send": "^0.18.0",
|
|
167
|
-
"serve-static": "^1.15.0",
|
|
168
162
|
"simple-get": "^4.0.1",
|
|
169
163
|
"snazzy": "^9.0.0",
|
|
170
164
|
"split2": "^4.1.0",
|
|
@@ -173,7 +167,7 @@
|
|
|
173
167
|
"tsd": "^0.22.0",
|
|
174
168
|
"typescript": "^4.7.2",
|
|
175
169
|
"undici": "^5.4.0",
|
|
176
|
-
"
|
|
170
|
+
"vary": "^1.1.2",
|
|
177
171
|
"yup": "^0.32.11"
|
|
178
172
|
},
|
|
179
173
|
"dependencies": {
|