fastify 3.5.0 → 3.8.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.
Files changed (84) hide show
  1. package/docs/ContentTypeParser.md +3 -0
  2. package/docs/Ecosystem.md +7 -2
  3. package/docs/Hooks.md +0 -5
  4. package/docs/Lifecycle.md +2 -2
  5. package/docs/Logging.md +1 -1
  6. package/docs/Recommendations.md +17 -0
  7. package/docs/Reply.md +2 -2
  8. package/docs/Request.md +4 -2
  9. package/docs/Routes.md +21 -3
  10. package/docs/Server.md +51 -3
  11. package/docs/Style-Guide.md +180 -0
  12. package/docs/TypeScript.md +359 -359
  13. package/docs/Validation-and-Serialization.md +11 -5
  14. package/examples/parser.js +1 -1
  15. package/fastify.d.ts +2 -2
  16. package/fastify.js +39 -7
  17. package/lib/contentTypeParser.js +16 -11
  18. package/lib/context.js +5 -19
  19. package/lib/decorate.js +1 -1
  20. package/lib/errors.js +2 -2
  21. package/lib/fourOhFour.js +8 -7
  22. package/lib/handleRequest.js +5 -5
  23. package/lib/hooks.js +4 -4
  24. package/lib/logger.js +7 -7
  25. package/lib/pluginUtils.js +4 -2
  26. package/lib/reply.js +27 -24
  27. package/lib/reqIdGenFactory.js +2 -2
  28. package/lib/request.js +20 -8
  29. package/lib/route.js +12 -10
  30. package/lib/schemas.js +1 -1
  31. package/lib/server.js +5 -5
  32. package/lib/symbols.js +2 -1
  33. package/lib/validation.js +9 -8
  34. package/lib/warnings.js +3 -0
  35. package/lib/wrapThenable.js +2 -2
  36. package/package.json +10 -10
  37. package/test/404s.test.js +15 -15
  38. package/test/async-await.test.js +7 -7
  39. package/test/custom-parser-async.test.js +2 -2
  40. package/test/custom-parser.test.js +38 -8
  41. package/test/emit-warning.test.js +31 -0
  42. package/test/fastify-instance.test.js +33 -1
  43. package/test/helper.js +1 -1
  44. package/test/hooks.test.js +6 -6
  45. package/test/http2/head.test.js +1 -1
  46. package/test/http2/plain.test.js +1 -1
  47. package/test/http2/secure-with-fallback.test.js +1 -1
  48. package/test/http2/secure.test.js +1 -1
  49. package/test/http2/unknown-http-method.test.js +1 -1
  50. package/test/https/https.test.js +2 -1
  51. package/test/inject.test.js +2 -2
  52. package/test/internals/all.test.js +1 -1
  53. package/test/internals/hookRunner.test.js +1 -1
  54. package/test/internals/logger.test.js +1 -1
  55. package/test/internals/reply.test.js +62 -7
  56. package/test/internals/request.test.js +31 -5
  57. package/test/internals/version.test.js +43 -0
  58. package/test/listen.test.js +12 -0
  59. package/test/logger.test.js +11 -11
  60. package/test/nullable-validation.test.js +108 -0
  61. package/test/pretty-print.test.js +9 -14
  62. package/test/reply-error.test.js +2 -2
  63. package/test/request-error.test.js +81 -0
  64. package/test/route-hooks.test.js +10 -10
  65. package/test/stream.test.js +11 -11
  66. package/test/types/fastify.test-d.ts +1 -2
  67. package/test/types/instance.test-d.ts +17 -3
  68. package/test/types/logger.test-d.ts +35 -2
  69. package/test/types/register.test-d.ts +16 -0
  70. package/test/types/request.test-d.ts +1 -1
  71. package/test/types/route.test-d.ts +5 -0
  72. package/test/validation-error-handling.test.js +66 -0
  73. package/test/versioned-routes.test.js +55 -0
  74. package/types/.eslintrc.json +4 -1
  75. package/types/content-type-parser.d.ts +0 -15
  76. package/types/hooks.d.ts +138 -16
  77. package/types/instance.d.ts +86 -14
  78. package/types/logger.d.ts +13 -11
  79. package/types/plugin.d.ts +5 -7
  80. package/types/register.d.ts +8 -7
  81. package/types/request.d.ts +3 -1
  82. package/types/route.d.ts +38 -58
  83. package/types/schema.d.ts +4 -4
  84. package/types/serverFactory.d.ts +9 -9
package/lib/request.js CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict'
2
2
 
3
3
  const proxyAddr = require('proxy-addr')
4
+ const semver = require('semver')
4
5
  const warning = require('./warnings')
5
6
 
6
7
  function Request (id, params, req, query, log, context) {
@@ -56,6 +57,12 @@ function buildRegularRequest (R) {
56
57
  return _Request
57
58
  }
58
59
 
60
+ function getLastEntryInMultiHeaderValue (headerValue) {
61
+ // we use the last one if the header is set more than once
62
+ const lastIndex = headerValue.lastIndexOf(',')
63
+ return lastIndex === -1 ? headerValue.trim() : headerValue.slice(lastIndex + 1).trim()
64
+ }
65
+
59
66
  function buildRequestWithTrustProxy (R, trustProxy) {
60
67
  const _Request = buildRegularRequest(R)
61
68
  const proxyFn = getTrustProxyFn(trustProxy)
@@ -74,7 +81,7 @@ function buildRequestWithTrustProxy (R, trustProxy) {
74
81
  hostname: {
75
82
  get () {
76
83
  if (this.ip !== undefined && this.headers['x-forwarded-host']) {
77
- return this.headers['x-forwarded-host']
84
+ return getLastEntryInMultiHeaderValue(this.headers['x-forwarded-host'])
78
85
  }
79
86
  return this.headers.host || this.headers[':authority']
80
87
  }
@@ -82,12 +89,9 @@ function buildRequestWithTrustProxy (R, trustProxy) {
82
89
  protocol: {
83
90
  get () {
84
91
  if (this.headers['x-forwarded-proto']) {
85
- const proto = this.headers['x-forwarded-proto']
86
- // we use the last one if the header is set more than once
87
- const lastIndex = proto.lastIndexOf(',')
88
- return lastIndex === -1 ? proto.trim() : proto.slice(lastIndex + 1).trim()
92
+ return getLastEntryInMultiHeaderValue(this.headers['x-forwarded-proto'])
89
93
  }
90
- return this.connection.encrypted ? 'https' : 'http'
94
+ return this.socket.encrypted ? 'https' : 'http'
91
95
  }
92
96
  }
93
97
  })
@@ -129,12 +133,20 @@ Object.defineProperties(Request.prototype, {
129
133
  },
130
134
  connection: {
131
135
  get () {
136
+ if (semver.gte(process.versions.node, '13.0.0')) {
137
+ warning.emit('FSTDEP005')
138
+ }
132
139
  return this.raw.connection
133
140
  }
134
141
  },
142
+ socket: {
143
+ get () {
144
+ return this.raw.socket
145
+ }
146
+ },
135
147
  ip: {
136
148
  get () {
137
- return this.connection.remoteAddress
149
+ return this.socket.remoteAddress
138
150
  }
139
151
  },
140
152
  hostname: {
@@ -144,7 +156,7 @@ Object.defineProperties(Request.prototype, {
144
156
  },
145
157
  protocol: {
146
158
  get () {
147
- return this.connection.encrypted ? 'https' : 'http'
159
+ return this.socket.encrypted ? 'https' : 'http'
148
160
  }
149
161
  },
150
162
  headers: {
package/lib/route.js CHANGED
@@ -40,7 +40,8 @@ const {
40
40
  kRequest,
41
41
  kRequestPayloadStream,
42
42
  kDisableRequestLogging,
43
- kSchemaErrorFormatter
43
+ kSchemaErrorFormatter,
44
+ kErrorHandler
44
45
  } = require('./symbols.js')
45
46
 
46
47
  function buildRouting (options) {
@@ -123,6 +124,7 @@ function buildRouting (options) {
123
124
  throwIfAlreadyStarted('Cannot add route when fastify instance is already started!')
124
125
 
125
126
  if (Array.isArray(opts.method)) {
127
+ /* eslint-disable no-var */
126
128
  for (var i = 0; i < opts.method.length; i++) {
127
129
  if (supportedMethods.indexOf(opts.method[i]) === -1) {
128
130
  throw new Error(`${opts.method[i]} method is not supported!`)
@@ -147,7 +149,7 @@ function buildRouting (options) {
147
149
  const prefix = this[kRoutePrefix]
148
150
 
149
151
  this.after((notHandledErr, done) => {
150
- var path = opts.url || opts.path
152
+ const path = opts.url || opts.path
151
153
  if (path === '/' && prefix.length > 0) {
152
154
  switch (opts.prefixTrailingSlash) {
153
155
  case 'slash':
@@ -213,7 +215,7 @@ function buildRouting (options) {
213
215
  this[kRequest],
214
216
  this[kContentTypeParser],
215
217
  config,
216
- opts.errorHandler || this._errorHandler,
218
+ opts.errorHandler || this[kErrorHandler],
217
219
  opts.bodyLimit,
218
220
  opts.logLevel,
219
221
  opts.logSerializers,
@@ -310,9 +312,9 @@ function buildRouting (options) {
310
312
  }
311
313
  }
312
314
 
313
- var id = req.headers[requestIdHeader] || genReqId(req)
315
+ const id = req.headers[requestIdHeader] || genReqId(req)
314
316
 
315
- var loggerOpts = {
317
+ const loggerOpts = {
316
318
  [requestIdLogLabel]: id,
317
319
  level: context.logLevel
318
320
  }
@@ -320,13 +322,13 @@ function buildRouting (options) {
320
322
  if (context.logSerializers) {
321
323
  loggerOpts.serializers = context.logSerializers
322
324
  }
323
- var childLogger = logger.child(loggerOpts)
325
+ const childLogger = logger.child(loggerOpts)
324
326
  childLogger[kDisableRequestLogging] = disableRequestLogging
325
327
 
326
- var queryPrefix = req.url.indexOf('?')
327
- var query = querystringParser(queryPrefix > -1 ? req.url.slice(queryPrefix + 1) : '')
328
- var request = new context.Request(id, params, req, query, childLogger, context)
329
- var reply = new context.Reply(res, request, childLogger)
328
+ const queryPrefix = req.url.indexOf('?')
329
+ const query = querystringParser(queryPrefix > -1 ? req.url.slice(queryPrefix + 1) : '')
330
+ const request = new context.Request(id, params, req, query, childLogger, context)
331
+ const reply = new context.Reply(res, request, childLogger)
330
332
 
331
333
  if (disableRequestLogging === false) {
332
334
  childLogger.info({ req: request }, 'incoming request')
package/lib/schemas.js CHANGED
@@ -16,7 +16,7 @@ function Schemas () {
16
16
  }
17
17
 
18
18
  Schemas.prototype.add = function (inputSchema) {
19
- var schema = fastClone((inputSchema.isFluentSchema || inputSchema[kFluentSchema])
19
+ const schema = fastClone((inputSchema.isFluentSchema || inputSchema[kFluentSchema])
20
20
  ? inputSchema.valueOf()
21
21
  : inputSchema
22
22
  )
package/lib/server.js CHANGED
@@ -11,7 +11,7 @@ function createServer (options, httpHandler) {
11
11
  assert(options, 'Missing options')
12
12
  assert(httpHandler, 'Missing http handler')
13
13
 
14
- var server = null
14
+ let server = null
15
15
  if (options.serverFactory) {
16
16
  server = options.serverFactory(httpHandler, options)
17
17
  } else if (options.https) {
@@ -91,15 +91,15 @@ function createServer (options, httpHandler) {
91
91
  }
92
92
 
93
93
  return this.ready().then(() => {
94
- var errEventHandler
95
- var errEvent = new Promise((resolve, reject) => {
94
+ let errEventHandler
95
+ const errEvent = new Promise((resolve, reject) => {
96
96
  errEventHandler = (err) => {
97
97
  this[kState].listening = false
98
98
  reject(err)
99
99
  }
100
100
  server.once('error', errEventHandler)
101
101
  })
102
- var listen = new Promise((resolve, reject) => {
102
+ const listen = new Promise((resolve, reject) => {
103
103
  server.listen(listenOptions, () => {
104
104
  server.removeListener('error', errEventHandler)
105
105
  resolve(logServerAddress())
@@ -116,7 +116,7 @@ function createServer (options, httpHandler) {
116
116
  }
117
117
 
118
118
  const logServerAddress = () => {
119
- var address = server.address()
119
+ let address = server.address()
120
120
  const isUnixSocket = typeof address === 'string'
121
121
  if (!isUnixSocket) {
122
122
  if (address.address.indexOf(':') === -1) {
package/lib/symbols.js CHANGED
@@ -38,7 +38,8 @@ const keys = {
38
38
  kDisableRequestLogging: Symbol('fastify.disableRequestLogging'),
39
39
  kPluginNameChain: Symbol('fastify.pluginNameChain'),
40
40
  // This symbol is only meant to be used for fastify tests and should not be used for any other purpose
41
- kTestInternals: Symbol('fastify.testInternals')
41
+ kTestInternals: Symbol('fastify.testInternals'),
42
+ kErrorHandler: Symbol('fastify.errorHandler')
42
43
  }
43
44
 
44
45
  module.exports = keys
package/lib/validation.js CHANGED
@@ -67,7 +67,7 @@ function compileSchemasForValidation (context, compile) {
67
67
  }
68
68
 
69
69
  function validateParam (validatorFunction, request, paramName) {
70
- var ret = validatorFunction && validatorFunction(request[paramName])
70
+ const ret = validatorFunction && validatorFunction(request[paramName])
71
71
  if (ret === false) return validatorFunction.errors
72
72
  if (ret && ret.error) return ret.error
73
73
  if (ret && ret.value) request[paramName] = ret.value
@@ -75,20 +75,20 @@ function validateParam (validatorFunction, request, paramName) {
75
75
  }
76
76
 
77
77
  function validate (context, request) {
78
- var params = validateParam(context[paramsSchema], request, 'params')
78
+ const params = validateParam(context[paramsSchema], request, 'params')
79
79
 
80
80
  if (params) {
81
81
  return wrapValidationError(params, 'params', context.schemaErrorFormatter)
82
82
  }
83
- var body = validateParam(context[bodySchema], request, 'body')
83
+ const body = validateParam(context[bodySchema], request, 'body')
84
84
  if (body) {
85
85
  return wrapValidationError(body, 'body', context.schemaErrorFormatter)
86
86
  }
87
- var query = validateParam(context[querystringSchema], request, 'query')
87
+ const query = validateParam(context[querystringSchema], request, 'query')
88
88
  if (query) {
89
89
  return wrapValidationError(query, 'querystring', context.schemaErrorFormatter)
90
90
  }
91
- var headers = validateParam(context[headersSchema], request, 'headers')
91
+ const headers = validateParam(context[headersSchema], request, 'headers')
92
92
  if (headers) {
93
93
  return wrapValidationError(headers, 'headers', context.schemaErrorFormatter)
94
94
  }
@@ -97,24 +97,25 @@ function validate (context, request) {
97
97
 
98
98
  function wrapValidationError (result, dataVar, schemaErrorFormatter) {
99
99
  if (result instanceof Error) {
100
+ result.validationContext = result.validationContext || dataVar
100
101
  return result
101
102
  }
102
103
 
103
- var error = schemaErrorFormatter(result, dataVar)
104
+ const error = schemaErrorFormatter(result, dataVar)
104
105
  error.validation = result
105
106
  error.validationContext = dataVar
106
107
  return error
107
108
  }
108
109
 
109
110
  function serialize (context, data, statusCode) {
110
- var responseSchemaDef = context[responseSchema]
111
+ const responseSchemaDef = context[responseSchema]
111
112
  if (!responseSchemaDef) {
112
113
  return JSON.stringify(data)
113
114
  }
114
115
  if (responseSchemaDef[statusCode]) {
115
116
  return responseSchemaDef[statusCode](data)
116
117
  }
117
- var fallbackStatusCode = (statusCode + '')[0] + 'xx'
118
+ const fallbackStatusCode = (statusCode + '')[0] + 'xx'
118
119
  if (responseSchemaDef[fallbackStatusCode]) {
119
120
  return responseSchemaDef[fallbackStatusCode](data)
120
121
  }
package/lib/warnings.js CHANGED
@@ -8,6 +8,7 @@ const warning = require('fastify-warning')()
8
8
  * - FSTDEP002
9
9
  * - FSTDEP003
10
10
  * - FSTDEP004
11
+ * - FSTDEP005
11
12
  */
12
13
 
13
14
  warning.create('FastifyDeprecation', 'FSTDEP001', 'You are accessing the Node.js core request object via "request.req", Use "request.raw" instead.')
@@ -18,4 +19,6 @@ warning.create('FastifyDeprecation', 'FSTDEP003', 'You are using the legacy Cont
18
19
 
19
20
  warning.create('FastifyDeprecation', 'FSTDEP004', 'You are using the legacy preParsing hook signature. Use the one suggested in the documentation instead.')
20
21
 
22
+ warning.create('FastifyDeprecation', 'FSTDEP005', 'You are accessing the deprecated "request.connection" property. Use "request.socket" instead.')
23
+
21
24
  module.exports = warning
@@ -6,7 +6,7 @@ const {
6
6
  kReplySentOverwritten
7
7
  } = require('./symbols')
8
8
 
9
- const { FST_ERR_PROMISE_NOT_FULLFILLED } = require('./errors')
9
+ const { FST_ERR_PROMISE_NOT_FULFILLED } = require('./errors')
10
10
 
11
11
  function wrapThenable (thenable, reply) {
12
12
  thenable.then(function (payload) {
@@ -27,7 +27,7 @@ function wrapThenable (thenable, reply) {
27
27
  reply.send(err)
28
28
  }
29
29
  } else if (reply[kReplySent] === false) {
30
- reply.log.error({ err: new FST_ERR_PROMISE_NOT_FULLFILLED() }, "Promise may not be fulfilled with 'undefined' when statusCode is not 204")
30
+ reply.log.error({ err: new FST_ERR_PROMISE_NOT_FULFILLED() }, "Promise may not be fulfilled with 'undefined' when statusCode is not 204")
31
31
  }
32
32
  }, function (err) {
33
33
  if (reply[kReplySentOverwritten] === true) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fastify",
3
- "version": "3.5.0",
3
+ "version": "3.8.0",
4
4
  "description": "Fast and low overhead web framework, for Node.js",
5
5
  "main": "fastify.js",
6
6
  "type": "commonjs",
@@ -116,8 +116,8 @@
116
116
  "@sinonjs/fake-timers": "^6.0.1",
117
117
  "@types/pino": "^6.0.1",
118
118
  "@types/node": "^14.10.3",
119
- "@typescript-eslint/eslint-plugin": "^2.29.0",
120
- "@typescript-eslint/parser": "^2.29.0",
119
+ "@typescript-eslint/eslint-plugin": "^4.5.0",
120
+ "@typescript-eslint/parser": "^4.5.0",
121
121
  "JSONStream": "^1.3.5",
122
122
  "ajv-errors": "^1.0.1",
123
123
  "ajv-i18n": "^3.5.0",
@@ -129,8 +129,8 @@
129
129
  "cors": "^2.8.5",
130
130
  "coveralls": "^3.0.14",
131
131
  "dns-prefetch-control": "^0.3.0",
132
- "eslint": "^6.8.0",
133
- "eslint-config-standard": "^14.1.1",
132
+ "eslint": "^7.11.0",
133
+ "eslint-config-standard": "^16.0.1",
134
134
  "eslint-import-resolver-node": "^0.3.2",
135
135
  "eslint-plugin-import": "^2.20.2",
136
136
  "eslint-plugin-node": "^11.1.0",
@@ -138,7 +138,7 @@
138
138
  "eslint-plugin-standard": "^4.0.1",
139
139
  "events.once": "^2.0.2",
140
140
  "fast-json-body": "^1.1.0",
141
- "fastify-plugin": "^2.1.0",
141
+ "fastify-plugin": "^3.0.0",
142
142
  "fluent-schema": "^1.0.0",
143
143
  "form-data": "^3.0.0",
144
144
  "frameguard": "^3.1.0",
@@ -155,9 +155,9 @@
155
155
  "send": "^0.17.1",
156
156
  "serve-static": "^1.14.1",
157
157
  "simple-get": "^4.0.0",
158
- "snazzy": "^8.0.0",
158
+ "snazzy": "^9.0.0",
159
159
  "split2": "^3.1.1",
160
- "standard": "^14.0.0",
160
+ "standard": "^16.0.1",
161
161
  "tap": "^14.4.1",
162
162
  "tap-mocha-reporter": "^5.0.0",
163
163
  "then-sleep": "^1.0.1",
@@ -174,9 +174,9 @@
174
174
  "fast-json-stringify": "^2.2.1",
175
175
  "fastify-error": "^0.2.0",
176
176
  "fastify-warning": "^0.2.0",
177
- "find-my-way": "^3.0.0",
177
+ "find-my-way": "^3.0.5",
178
178
  "flatstr": "^1.0.12",
179
- "light-my-request": "^4.0.2",
179
+ "light-my-request": "^4.2.0",
180
180
  "pino": "^6.2.1",
181
181
  "proxy-addr": "^2.0.5",
182
182
  "readable-stream": "^3.4.0",
package/test/404s.test.js CHANGED
@@ -1073,7 +1073,7 @@ test('404 inside onSend', t => {
1073
1073
 
1074
1074
  const fastify = Fastify()
1075
1075
 
1076
- var called = false
1076
+ let called = false
1077
1077
 
1078
1078
  fastify.get('/', function (req, reply) {
1079
1079
  reply.send({ hello: 'world' })
@@ -1215,7 +1215,7 @@ test('preHandler option for setNotFoundHandler', t => {
1215
1215
  payload: { hello: 'world' }
1216
1216
  }, (err, res) => {
1217
1217
  t.error(err)
1218
- var payload = JSON.parse(res.payload)
1218
+ const payload = JSON.parse(res.payload)
1219
1219
  t.deepEqual(payload, { preHandler: true, hello: 'world' })
1220
1220
  })
1221
1221
  })
@@ -1244,7 +1244,7 @@ test('preHandler option for setNotFoundHandler', t => {
1244
1244
  payload: { hello: 'world' }
1245
1245
  }, (err, res) => {
1246
1246
  t.error(err)
1247
- var payload = JSON.parse(res.payload)
1247
+ const payload = JSON.parse(res.payload)
1248
1248
  t.deepEqual(payload, { preHandler: true, hello: 'world' })
1249
1249
  })
1250
1250
  })
@@ -1278,7 +1278,7 @@ test('preHandler option for setNotFoundHandler', t => {
1278
1278
  payload: { hello: 'world' }
1279
1279
  }, (err, res) => {
1280
1280
  t.error(err)
1281
- var payload = JSON.parse(res.payload)
1281
+ const payload = JSON.parse(res.payload)
1282
1282
  t.deepEqual(payload, { preHandler1: true, preHandler2: true, hello: 'world' })
1283
1283
  })
1284
1284
  })
@@ -1307,7 +1307,7 @@ test('preHandler option for setNotFoundHandler', t => {
1307
1307
  payload: { hello: 'world' }
1308
1308
  }, (err, res) => {
1309
1309
  t.error(err)
1310
- var payload = JSON.parse(res.payload)
1310
+ const payload = JSON.parse(res.payload)
1311
1311
  t.deepEqual(payload, { check: 'ab', hello: 'world' })
1312
1312
  })
1313
1313
  })
@@ -1339,7 +1339,7 @@ test('preHandler option for setNotFoundHandler', t => {
1339
1339
  payload: { hello: 'world' }
1340
1340
  }, (err, res) => {
1341
1341
  t.error(err)
1342
- var payload = JSON.parse(res.payload)
1342
+ const payload = JSON.parse(res.payload)
1343
1343
  t.deepEqual(payload, { hello: 'earth' })
1344
1344
  })
1345
1345
 
@@ -1349,7 +1349,7 @@ test('preHandler option for setNotFoundHandler', t => {
1349
1349
  payload: { hello: 'world' }
1350
1350
  }, (err, res) => {
1351
1351
  t.error(err)
1352
- var payload = JSON.parse(res.payload)
1352
+ const payload = JSON.parse(res.payload)
1353
1353
  t.deepEqual(payload, { hello: 'world' })
1354
1354
  })
1355
1355
  })
@@ -1372,7 +1372,7 @@ test('preHandler option for setNotFoundHandler', t => {
1372
1372
  payload: { hello: 'world' }
1373
1373
  }, (err, res) => {
1374
1374
  t.error(err)
1375
- var payload = JSON.parse(res.payload)
1375
+ const payload = JSON.parse(res.payload)
1376
1376
  t.equal(res.statusCode, 500)
1377
1377
  t.deepEqual(payload, {
1378
1378
  message: 'kaboom',
@@ -1401,7 +1401,7 @@ test('preHandler option for setNotFoundHandler', t => {
1401
1401
  payload: { hello: 'world' }
1402
1402
  }, (err, res) => {
1403
1403
  t.error(err)
1404
- var payload = JSON.parse(res.payload)
1404
+ const payload = JSON.parse(res.payload)
1405
1405
  t.equal(res.statusCode, 401)
1406
1406
  t.deepEqual(payload, {
1407
1407
  message: 'go away',
@@ -1436,7 +1436,7 @@ test('preHandler option for setNotFoundHandler', t => {
1436
1436
  payload: { hello: 'world' }
1437
1437
  }, (err, res) => {
1438
1438
  t.error(err)
1439
- var payload = JSON.parse(res.payload)
1439
+ const payload = JSON.parse(res.payload)
1440
1440
  t.deepEqual(payload, { preHandler: 'ab', hello: 'world' })
1441
1441
  })
1442
1442
  })
@@ -1473,7 +1473,7 @@ test('preHandler option for setNotFoundHandler', t => {
1473
1473
  payload: { hello: 'world' }
1474
1474
  }, (err, res) => {
1475
1475
  t.error(err)
1476
- var payload = JSON.parse(res.payload)
1476
+ const payload = JSON.parse(res.payload)
1477
1477
  t.deepEqual(payload, { check: 'ab', hello: 'world' })
1478
1478
  })
1479
1479
 
@@ -1483,7 +1483,7 @@ test('preHandler option for setNotFoundHandler', t => {
1483
1483
  payload: { hello: 'world' }
1484
1484
  }, (err, res) => {
1485
1485
  t.error(err)
1486
- var payload = JSON.parse(res.payload)
1486
+ const payload = JSON.parse(res.payload)
1487
1487
  t.deepEqual(payload, { check: 'a', hello: 'world' })
1488
1488
  })
1489
1489
  })
@@ -1511,7 +1511,7 @@ test('preHandler option for setNotFoundHandler', t => {
1511
1511
  payload: { hello: 'world' }
1512
1512
  }, (err, res) => {
1513
1513
  t.error(err)
1514
- var payload = JSON.parse(res.payload)
1514
+ const payload = JSON.parse(res.payload)
1515
1515
  t.deepEqual(payload, { foo: 43, hello: 'world' })
1516
1516
  })
1517
1517
  })
@@ -1627,7 +1627,7 @@ test('preValidation option', t => {
1627
1627
  payload: { hello: 'world' }
1628
1628
  }, (err, res) => {
1629
1629
  t.error(err)
1630
- var payload = JSON.parse(res.payload)
1630
+ const payload = JSON.parse(res.payload)
1631
1631
  t.deepEqual(payload, { hello: 'world' })
1632
1632
  })
1633
1633
  })
@@ -1657,7 +1657,7 @@ t.test('preValidation option could accept an array of functions', t => {
1657
1657
  payload: { hello: 'world' }
1658
1658
  }, (err, res) => {
1659
1659
  t.error(err)
1660
- var payload = JSON.parse(res.payload)
1660
+ const payload = JSON.parse(res.payload)
1661
1661
  t.deepEqual(payload, { hello: 'world' })
1662
1662
  })
1663
1663
  })
@@ -402,8 +402,8 @@ test('does not call reply.send() twice if 204 reponse is already sent', t => {
402
402
  test('error is logged because promise was fulfilled with undefined', t => {
403
403
  t.plan(3)
404
404
 
405
- var fastify = null
406
- var stream = split(JSON.parse)
405
+ let fastify = null
406
+ const stream = split(JSON.parse)
407
407
  try {
408
408
  fastify = Fastify({
409
409
  logger: {
@@ -442,8 +442,8 @@ test('error is logged because promise was fulfilled with undefined', t => {
442
442
  test('error is not logged because promise was fulfilled with undefined but statusCode 204 was set', t => {
443
443
  t.plan(3)
444
444
 
445
- var fastify = null
446
- var stream = split(JSON.parse)
445
+ let fastify = null
446
+ const stream = split(JSON.parse)
447
447
  try {
448
448
  fastify = Fastify({
449
449
  logger: {
@@ -482,9 +482,9 @@ test('error is not logged because promise was fulfilled with undefined but statu
482
482
  test('error is not logged because promise was fulfilled with undefined but response was sent before promise resolution', t => {
483
483
  t.plan(4)
484
484
 
485
- var fastify = null
486
- var stream = split(JSON.parse)
487
- var payload = { hello: 'world' }
485
+ let fastify = null
486
+ const stream = split(JSON.parse)
487
+ const payload = { hello: 'world' }
488
488
  try {
489
489
  fastify = Fastify({
490
490
  logger: {
@@ -20,7 +20,7 @@ test('contentTypeParser should add a custom async parser', t => {
20
20
  })
21
21
 
22
22
  fastify.addContentTypeParser('application/jsoff', async function (req, payload) {
23
- var res = await new Promise((resolve, reject) => resolve(payload))
23
+ const res = await new Promise((resolve, reject) => resolve(payload))
24
24
  return res
25
25
  })
26
26
 
@@ -84,7 +84,7 @@ test('contentTypeParser should add a custom async parser - deprecated syntax', t
84
84
  })
85
85
 
86
86
  fastify.addContentTypeParser('application/jsoff', async function (req) {
87
- var res = await new Promise((resolve, reject) => resolve(req))
87
+ const res = await new Promise((resolve, reject) => resolve(req))
88
88
  return res
89
89
  })
90
90
 
@@ -9,7 +9,7 @@ const Fastify = require('..')
9
9
  const jsonParser = require('fast-json-body')
10
10
 
11
11
  function plainTextParser (request, callback) {
12
- var body = ''
12
+ let body = ''
13
13
  request.setEncoding('utf8')
14
14
  request.on('error', onError)
15
15
  request.on('data', onData)
@@ -436,7 +436,7 @@ test('catch all content type parser', t => {
436
436
  })
437
437
 
438
438
  fastify.addContentTypeParser('*', function (req, payload, done) {
439
- var data = ''
439
+ let data = ''
440
440
  payload.on('data', chunk => { data += chunk })
441
441
  payload.on('end', () => {
442
442
  done(null, data)
@@ -484,7 +484,7 @@ test('catch all content type parser should not interfere with other conte type p
484
484
  })
485
485
 
486
486
  fastify.addContentTypeParser('*', function (req, payload, done) {
487
- var data = ''
487
+ let data = ''
488
488
  payload.on('data', chunk => { data += chunk })
489
489
  payload.on('end', () => {
490
490
  done(null, data)
@@ -538,7 +538,7 @@ test('\'*\' catch undefined Content-Type requests', t => {
538
538
  t.tearDown(fastify.close.bind(fastify))
539
539
 
540
540
  fastify.addContentTypeParser('*', function (req, payload, done) {
541
- var data = ''
541
+ let data = ''
542
542
  payload.on('data', chunk => { data += chunk })
543
543
  payload.on('end', () => {
544
544
  done(null, data)
@@ -754,7 +754,7 @@ test('Should get the body as string', t => {
754
754
  t.ok('called')
755
755
  t.ok(typeof body === 'string')
756
756
  try {
757
- var json = JSON.parse(body)
757
+ const json = JSON.parse(body)
758
758
  done(null, json)
759
759
  } catch (err) {
760
760
  err.statusCode = 400
@@ -900,7 +900,7 @@ test('Should get the body as string', t => {
900
900
  t.ok('called')
901
901
  t.ok(typeof body === 'string')
902
902
  try {
903
- var plainText = body
903
+ const plainText = body
904
904
  done(null, plainText)
905
905
  } catch (err) {
906
906
  err.statusCode = 400
@@ -939,7 +939,7 @@ test('Should get the body as buffer', t => {
939
939
  t.ok('called')
940
940
  t.ok(body instanceof Buffer)
941
941
  try {
942
- var json = JSON.parse(body)
942
+ const json = JSON.parse(body)
943
943
  done(null, json)
944
944
  } catch (err) {
945
945
  err.statusCode = 400
@@ -978,7 +978,7 @@ test('Should get the body as buffer', t => {
978
978
  t.ok('called')
979
979
  t.ok(body instanceof Buffer)
980
980
  try {
981
- var plainText = body
981
+ const plainText = body
982
982
  done(null, plainText)
983
983
  } catch (err) {
984
984
  err.statusCode = 400
@@ -1214,3 +1214,33 @@ test('route bodyLimit should take precedence over a custom parser bodyLimit', t
1214
1214
  })
1215
1215
  })
1216
1216
  })
1217
+
1218
+ test('should be able to use default parser for extra content type', t => {
1219
+ t.plan(4)
1220
+ const fastify = Fastify()
1221
+ t.tearDown(() => fastify.close())
1222
+
1223
+ fastify.post('/', (request, reply) => {
1224
+ reply.send(request.body)
1225
+ })
1226
+
1227
+ fastify.addContentTypeParser('text/json', { parseAs: 'string' }, fastify.getDefaultJsonParser('ignore', 'ignore'))
1228
+
1229
+ fastify.listen(0, err => {
1230
+ t.error(err)
1231
+
1232
+ sget({
1233
+ method: 'POST',
1234
+ url: 'http://localhost:' + fastify.server.address().port,
1235
+ body: '{"hello":"world"}',
1236
+ headers: {
1237
+ 'Content-Type': 'text/json'
1238
+ }
1239
+ }, (err, response, body) => {
1240
+ t.error(err)
1241
+ t.strictEqual(response.statusCode, 200)
1242
+ t.strictDeepEqual(JSON.parse(body.toString()), { hello: 'world' })
1243
+ fastify.close()
1244
+ })
1245
+ })
1246
+ })