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.
Files changed (45) hide show
  1. package/build/build-validation.js +1 -1
  2. package/docs/Guides/Ecosystem.md +23 -0
  3. package/docs/Reference/Hooks.md +4 -1
  4. package/docs/Reference/Logging.md +1 -1
  5. package/docs/Reference/Reply.md +1 -0
  6. package/docs/Reference/Routes.md +6 -3
  7. package/docs/Reference/Server.md +20 -7
  8. package/docs/Reference/Validation-and-Serialization.md +1 -1
  9. package/fastify.d.ts +1 -1
  10. package/fastify.js +4 -4
  11. package/lib/configValidator.js +68 -19
  12. package/lib/context.js +1 -0
  13. package/lib/handleRequest.js +2 -2
  14. package/lib/httpMethods.js +22 -0
  15. package/lib/reqIdGenFactory.js +13 -2
  16. package/lib/route.js +2 -4
  17. package/lib/server.js +1 -0
  18. package/package.json +3 -9
  19. package/test/copy.test.js +41 -0
  20. package/test/hooks-async.test.js +43 -0
  21. package/test/internals/all.test.js +8 -2
  22. package/test/internals/reply.test.js +4 -1
  23. package/test/lock.test.js +73 -0
  24. package/test/logger.test.js +108 -0
  25. package/test/mkcol.test.js +38 -0
  26. package/test/move.test.js +45 -0
  27. package/test/propfind.test.js +108 -0
  28. package/test/proppatch.test.js +78 -0
  29. package/test/schema-examples.test.js +54 -0
  30. package/test/search.test.js +100 -0
  31. package/test/trace.test.js +21 -0
  32. package/test/types/fastify.test-d.ts +1 -0
  33. package/test/types/instance.test-d.ts +1 -1
  34. package/test/types/logger.test-d.ts +4 -5
  35. package/test/types/reply.test-d.ts +44 -3
  36. package/test/types/request.test-d.ts +9 -28
  37. package/test/types/type-provider.test-d.ts +3 -1
  38. package/test/unlock.test.js +41 -0
  39. package/test/upgrade.test.js +53 -0
  40. package/types/instance.d.ts +1 -1
  41. package/types/logger.d.ts +7 -4
  42. package/types/reply.d.ts +7 -6
  43. package/types/request.d.ts +2 -2
  44. package/types/type-provider.d.ts +1 -14
  45. 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 },
@@ -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
@@ -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('onResponse', async (request, reply) => {
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
 
@@ -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) {
@@ -32,8 +32,10 @@ fastify.route(options)
32
32
  ### Routes options
33
33
  <a id="options"></a>
34
34
 
35
- *`method`: currently it supports `'DELETE'`, `'GET'`, `'HEAD'`, `'PATCH'`,
36
- `'POST'`, `'PUT'` and `'OPTIONS'`. It could also be an array of methods.
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', async (req, reply) => {
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
 
@@ -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\*](#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 know the request-id. See [the
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][https://nodejs.org/api/net.html#serverlistenoptions-callback] parameter
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
- three ways to define a name (in order).
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 you `module.exports` a plugin the filename is used.
1120
- 3. If you use a regular [function
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":{"hello":["1"]}}
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.0'
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 = ['DELETE', 'GET', 'HEAD', 'PATCH', 'POST', 'PUT', 'OPTIONS']
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 || reqIdGenFactory()
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
@@ -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
- validate10.errors = [{instancePath:instancePath+"/requestIdHeader",schemaPath:"#/properties/requestIdHeader/type",keyword:"type",params:{type: "string"},message:"must be string"}];
852
- return false;
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 _errs59 = errors;
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 = _errs59 === errors;
937
+ var valid0 = _errs62 === errors;
889
938
  if(valid0){
890
939
  let data21 = data.http2SessionTimeout;
891
- const _errs61 = errors;
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 = _errs61 === errors;
961
+ var valid0 = _errs64 === errors;
913
962
  if(valid0){
914
963
  let data22 = data.exposeHeadRoutes;
915
- const _errs63 = errors;
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 = _errs63 === errors;
986
+ var valid0 = _errs66 === errors;
938
987
  if(valid0){
939
988
  if(data.versioning !== undefined){
940
989
  let data23 = data.versioning;
941
- const _errs65 = errors;
942
- if(errors === _errs65){
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 = _errs65 === errors;
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 _errs68 = errors;
964
- if(errors === _errs68){
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 _errs71 = errors;
969
- if(errors === _errs71){
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 valid6 = _errs71 === errors;
1010
- if(!valid6){
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 = _errs68 === errors;
1069
+ var valid0 = _errs71 === errors;
1021
1070
  }
1022
1071
  else {
1023
1072
  var valid0 = true;
package/lib/context.js CHANGED
@@ -44,6 +44,7 @@ function Context ({
44
44
  this.onTimeout = null
45
45
  this.preHandler = null
46
46
  this.onResponse = null
47
+ this.preSerialization = null
47
48
  this.config = config
48
49
  this.errorHandler = errorHandler || server[kErrorHandler]
49
50
  this._middie = null
@@ -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
+ }
@@ -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
- return function genReqId (req) {
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 = ['DELETE', 'GET', 'HEAD', 'PATCH', 'POST', 'PUT', 'OPTIONS']
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 = req.headers[requestIdHeader] || genReqId(req)
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.0",
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.4.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
- "x-xss-protection": "^2.0.0",
170
+ "vary": "^1.1.2",
177
171
  "yup": "^0.32.11"
178
172
  },
179
173
  "dependencies": {