fastify 4.0.0-rc.5 → 4.0.2

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 (41) hide show
  1. package/.markdownlint-cli2.yaml +22 -0
  2. package/GOVERNANCE.md +30 -20
  3. package/PROJECT_CHARTER.md +48 -17
  4. package/README.md +164 -77
  5. package/SECURITY.md +55 -44
  6. package/build/build-error-serializer.js +12 -7
  7. package/docs/Guides/Benchmarking.md +2 -0
  8. package/docs/Guides/Delay-Accepting-Requests.md +98 -90
  9. package/docs/Guides/Ecosystem.md +48 -38
  10. package/docs/Guides/Index.md +2 -0
  11. package/docs/Guides/Migration-Guide-V3.md +1 -1
  12. package/docs/Guides/Migration-Guide-V4.md +55 -0
  13. package/docs/Guides/Plugins-Guide.md +3 -3
  14. package/docs/Guides/Prototype-Poisoning.md +1 -1
  15. package/docs/Guides/Recommendations.md +2 -2
  16. package/docs/Guides/Serverless.md +17 -16
  17. package/docs/Guides/Write-Plugin.md +3 -3
  18. package/docs/Reference/ContentTypeParser.md +17 -13
  19. package/docs/Reference/Errors.md +6 -5
  20. package/docs/Reference/Middleware.md +3 -3
  21. package/docs/Reference/Plugins.md +8 -6
  22. package/docs/Reference/Reply.md +30 -16
  23. package/docs/Reference/Request.md +3 -3
  24. package/docs/Reference/Routes.md +113 -38
  25. package/docs/Reference/Server.md +109 -72
  26. package/docs/Reference/Type-Providers.md +28 -8
  27. package/docs/Reference/TypeScript.md +12 -6
  28. package/docs/Reference/Validation-and-Serialization.md +47 -35
  29. package/fastify.js +1 -1
  30. package/lib/error-serializer.js +32 -204
  31. package/lib/pluginUtils.js +10 -0
  32. package/lib/reply.js +1 -1
  33. package/lib/schemas.js +3 -0
  34. package/lib/validation.js +1 -1
  35. package/package.json +6 -4
  36. package/test/build/error-serializer.test.js +28 -0
  37. package/test/{internals → build}/version.test.js +1 -1
  38. package/test/plugin.test.js +32 -0
  39. package/test/reply-error.test.js +7 -1
  40. package/test/schema-serialization.test.js +30 -0
  41. package/docs/Migration-Guide-V4.md +0 -12
@@ -6,10 +6,12 @@ recommend using [JSON Schema](https://json-schema.org/) to validate your routes
6
6
  and serialize your outputs. Internally, Fastify compiles the schema into a
7
7
  highly performant function.
8
8
 
9
- Validation will only be attempted if the content type is `application-json`,
10
- as described in the documentation for the [content type parser](./ContentTypeParser.md).
9
+ Validation will only be attempted if the content type is `application-json`, as
10
+ described in the documentation for the [content type
11
+ parser](./ContentTypeParser.md).
11
12
 
12
- All the examples in this section are using the [JSON Schema Draft 7](https://json-schema.org/specification-links.html#draft-7) specification.
13
+ All the examples in this section are using the [JSON Schema Draft
14
+ 7](https://json-schema.org/specification-links.html#draft-7) specification.
13
15
 
14
16
  > ## ⚠ Security Notice
15
17
  > Treat the schema definition as application code. Validation and serialization
@@ -147,10 +149,9 @@ fastify.register((instance, opts, done) => {
147
149
 
148
150
 
149
151
  ### Validation
150
- The route validation internally relies upon
151
- [Ajv v8](https://www.npmjs.com/package/ajv) which is a high-performance
152
- JSON Schema validator.
153
- Validating the input is very easy: just add the fields that you need
152
+ The route validation internally relies upon [Ajv
153
+ v8](https://www.npmjs.com/package/ajv) which is a high-performance JSON Schema
154
+ validator. Validating the input is very easy: just add the fields that you need
154
155
  inside the route schema, and you are done!
155
156
 
156
157
  The supported validations are:
@@ -233,13 +234,12 @@ const schema = {
233
234
  fastify.post('/the/url', { schema }, handler)
234
235
  ```
235
236
 
236
- *Note that Ajv will try to [coerce](https://ajv.js.org/coercion.html) the values to
237
- the types specified in your schema `type` keywords, both to pass the validation
238
- and to use the correctly typed data afterwards.*
237
+ *Note that Ajv will try to [coerce](https://ajv.js.org/coercion.html) the values
238
+ to the types specified in your schema `type` keywords, both to pass the
239
+ validation and to use the correctly typed data afterwards.*
239
240
 
240
- The Ajv default configuration in Fastify supports coercing array
241
- parameters in `querystring`.
242
- Example:
241
+ The Ajv default configuration in Fastify supports coercing array parameters in
242
+ `querystring`. Example:
243
243
 
244
244
  ```js
245
245
  const opts = {
@@ -318,8 +318,9 @@ For further information see [here](https://ajv.js.org/coercion.html)
318
318
  #### Ajv Plugins
319
319
  <a id="ajv-plugins"></a>
320
320
 
321
- You can provide a list of plugins you want to use with the default `ajv` instance.
322
- Note that the plugin must be **compatible with the Ajv version shipped within Fastify**.
321
+ You can provide a list of plugins you want to use with the default `ajv`
322
+ instance. Note that the plugin must be **compatible with the Ajv version shipped
323
+ within Fastify**.
323
324
 
324
325
  > Refer to [`ajv options`](./Server.md#ajv) to check plugins format
325
326
 
@@ -388,7 +389,8 @@ body, URL parameters, headers, and query string. The default
388
389
  [ajv](https://ajv.js.org/) validation interface. Fastify uses it internally to
389
390
  speed the validation up.
390
391
 
391
- Fastify's [baseline ajv configuration](https://github.com/fastify/ajv-compiler#ajv-configuration) is:
392
+ Fastify's [baseline ajv
393
+ configuration](https://github.com/fastify/ajv-compiler#ajv-configuration) is:
392
394
 
393
395
  ```js
394
396
  {
@@ -469,7 +471,8 @@ fastify.post('/the/url', {
469
471
  },
470
472
  validatorCompiler: ({ schema, method, url, httpPart }) => {
471
473
  return function (data) {
472
- // with option strict = false, yup `validateSync` function returns the coerced value if validation was successful, or throws if validation failed
474
+ // with option strict = false, yup `validateSync` function returns the
475
+ // coerced value if validation was successful, or throws if validation failed
473
476
  try {
474
477
  const result = schema.validateSync(data, yupOptions)
475
478
  return { value: result }
@@ -487,15 +490,15 @@ fastify.post('/the/url', {
487
490
  Fastify's validation error messages are tightly coupled to the default
488
491
  validation engine: errors returned from `ajv` are eventually run through the
489
492
  `schemaErrorFormatter` function which is responsible for building human-friendly
490
- error messages. However, the `schemaErrorFormatter` function is written with `ajv`
491
- in mind. As a result, you may run into odd or incomplete error messages when
492
- using other validation libraries.
493
+ error messages. However, the `schemaErrorFormatter` function is written with
494
+ `ajv` in mind. As a result, you may run into odd or incomplete error messages
495
+ when using other validation libraries.
493
496
 
494
497
  To circumvent this issue, you have 2 main options :
495
498
 
496
499
  1. make sure your validation function (returned by your custom `schemaCompiler`)
497
- returns errors in the same structure and format as `ajv` (although this
498
- could prove to be difficult and tricky due to differences between validation
500
+ returns errors in the same structure and format as `ajv` (although this could
501
+ prove to be difficult and tricky due to differences between validation
499
502
  engines)
500
503
  2. or use a custom `errorHandler` to intercept and format your 'custom'
501
504
  validation errors
@@ -503,8 +506,8 @@ To circumvent this issue, you have 2 main options :
503
506
  To help you in writing a custom `errorHandler`, Fastify adds 2 properties to all
504
507
  validation errors:
505
508
 
506
- * `validation`: the content of the `error` property of the object returned by the
507
- validation function (returned by your custom `schemaCompiler`)
509
+ * `validation`: the content of the `error` property of the object returned by
510
+ the validation function (returned by your custom `schemaCompiler`)
508
511
  * `validationContext`: the 'context' (body, params, query, headers) where the
509
512
  validation error occurred
510
513
 
@@ -567,10 +570,20 @@ fastify.post('/the/url', { schema }, handler)
567
570
  ```
568
571
 
569
572
  As you can see, the response schema is based on the status code. If you want to
570
- use the same schema for multiple status codes, you can use `'2xx'`, for example:
573
+ use the same schema for multiple status codes, you can use `'2xx'` or `default`,
574
+ for example:
571
575
  ```js
572
576
  const schema = {
573
577
  response: {
578
+ default: {
579
+ type: 'object',
580
+ properties: {
581
+ error: {
582
+ type: 'boolean',
583
+ default: true
584
+ }
585
+ }
586
+ },
574
587
  '2xx': {
575
588
  type: 'object',
576
589
  properties: {
@@ -689,9 +702,8 @@ fastify.setSchemaErrorFormatter(function (errors, dataVar) {
689
702
  })
690
703
  ```
691
704
 
692
- You can also use
693
- [setErrorHandler](./Server.md#seterrorhandler) to
694
- define a custom response for validation errors such as
705
+ You can also use [setErrorHandler](./Server.md#seterrorhandler) to define a
706
+ custom response for validation errors such as
695
707
 
696
708
  ```js
697
709
  fastify.setErrorHandler(function (error, request, reply) {
@@ -701,9 +713,9 @@ fastify.setErrorHandler(function (error, request, reply) {
701
713
  })
702
714
  ```
703
715
 
704
- If you want a custom error response in the schema without headaches, and quickly, take a
705
- look at [`ajv-errors`](https://github.com/epoberezkin/ajv-errors).
706
- Check out the
716
+ If you want a custom error response in the schema without headaches, and
717
+ quickly, take a look at
718
+ [`ajv-errors`](https://github.com/epoberezkin/ajv-errors). Check out the
707
719
  [example](https://github.com/fastify/example/blob/HEAD/validation-messages/custom-errors-messages.js)
708
720
  usage.
709
721
  > Make sure to install version 1.0.1 of `ajv-errors`, because later versions of
@@ -719,7 +731,8 @@ const fastify = Fastify({
719
731
  ajv: {
720
732
  customOptions: {
721
733
  jsonPointers: true,
722
- allErrors: true // Warning: Enabling this option may lead to this security issue https://www.cvedetails.com/cve/CVE-2020-8192/
734
+ // Warning: Enabling this option may lead to this security issue https://www.cvedetails.com/cve/CVE-2020-8192/
735
+ allErrors: true
723
736
  },
724
737
  plugins: [
725
738
  require('ajv-errors')
@@ -797,9 +810,8 @@ fastify.setErrorHandler(function (error, request, reply) {
797
810
 
798
811
  ### JSON Schema support
799
812
 
800
- JSON Schema provides utilities to optimize your schemas that,
801
- in conjunction with Fastify's shared schema, let you reuse all your schemas
802
- easily.
813
+ JSON Schema provides utilities to optimize your schemas that, in conjunction
814
+ with Fastify's shared schema, let you reuse all your schemas easily.
803
815
 
804
816
  | Use Case | Validator | Serializer |
805
817
  |-----------------------------------|-----------|------------|
package/fastify.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const VERSION = '4.0.0-rc.5'
3
+ const VERSION = '4.0.2'
4
4
 
5
5
  const Avvio = require('avvio')
6
6
  const http = require('http')
@@ -1,195 +1,23 @@
1
1
  // This file is autogenerated by build/build-error-serializer.js, do not edit
2
2
  /* istanbul ignore file */
3
- module.exports = $main
4
- 'use strict'
5
-
6
-
7
- function $pad2Zeros (num) {
8
- const s = '00' + num
9
- return s[s.length - 2] + s[s.length - 1]
10
- }
11
-
12
- function $asAny (i) {
13
- return JSON.stringify(i)
14
- }
15
-
16
- function $asNull () {
17
- return 'null'
18
- }
19
-
20
- function $asInteger (i) {
21
- if (typeof i === 'bigint') {
22
- return i.toString()
23
- } else if (Number.isInteger(i)) {
24
- return $asNumber(i)
25
- } else {
26
- /* eslint no-undef: "off" */
27
- return $asNumber(parseInteger(i))
28
- }
29
- }
30
-
31
- function $asIntegerNullable (i) {
32
- return i === null ? null : $asInteger(i)
33
- }
34
-
35
- function $asNumber (i) {
36
- const num = Number(i)
37
- if (isNaN(num)) {
38
- return 'null'
39
- } else {
40
- return '' + num
41
- }
42
- }
43
-
44
- function $asNumberNullable (i) {
45
- return i === null ? null : $asNumber(i)
46
- }
47
-
48
- function $asBoolean (bool) {
49
- return bool && 'true' || 'false' // eslint-disable-line
50
- }
51
3
 
52
- function $asBooleanNullable (bool) {
53
- return bool === null ? null : $asBoolean(bool)
54
- }
4
+ 'use strict'
55
5
 
56
- function $asDatetime (date, skipQuotes) {
57
- const quotes = skipQuotes === true ? '' : '"'
58
- if (date instanceof Date) {
59
- return quotes + date.toISOString() + quotes
60
- } else if (date && typeof date.toISOString === 'function') {
61
- return quotes + date.toISOString() + quotes
62
- } else {
63
- return $asString(date, skipQuotes)
64
- }
65
- }
6
+ const Serializer = require('fast-json-stringify/serializer')
7
+ const buildAjv = require('fast-json-stringify/ajv')
66
8
 
67
- function $asDate (date, skipQuotes) {
68
- const quotes = skipQuotes === true ? '' : '"'
69
- if (date instanceof Date) {
70
- return quotes + new Date(date.getTime() - (date.getTimezoneOffset() * 60000 )).toISOString().slice(0, 10) + quotes
71
- } else if (date && typeof date.format === 'function') {
72
- return quotes + date.format('YYYY-MM-DD') + quotes
73
- } else {
74
- return $asString(date, skipQuotes)
75
- }
76
- }
77
-
78
- function $asTime (date, skipQuotes) {
79
- const quotes = skipQuotes === true ? '' : '"'
80
- if (date instanceof Date) {
81
- const hour = new Intl.DateTimeFormat('en', { hour: 'numeric', hour12: false }).format(date)
82
- const minute = new Intl.DateTimeFormat('en', { minute: 'numeric' }).format(date)
83
- const second = new Intl.DateTimeFormat('en', { second: 'numeric' }).format(date)
84
- return quotes + $pad2Zeros(hour) + ':' + $pad2Zeros(minute) + ':' + $pad2Zeros(second) + quotes
85
- } else if (date && typeof date.format === 'function') {
86
- return quotes + date.format('HH:mm:ss') + quotes
87
- } else {
88
- return $asString(date, skipQuotes)
89
- }
90
- }
91
-
92
- function $asString (str, skipQuotes) {
93
- const quotes = skipQuotes === true ? '' : '"'
94
- if (str instanceof Date) {
95
- return quotes + str.toISOString() + quotes
96
- } else if (str === null) {
97
- return quotes + quotes
98
- } else if (str instanceof RegExp) {
99
- str = str.source
100
- } else if (typeof str !== 'string') {
101
- str = str.toString()
102
- }
103
- // If we skipQuotes it means that we are using it as test
104
- // no need to test the string length for the render
105
- if (skipQuotes) {
106
- return str
107
- }
108
-
109
- if (str.length < 42) {
110
- return $asStringSmall(str)
111
- } else {
112
- return JSON.stringify(str)
113
- }
114
- }
9
+ const serializer = new Serializer({"mode":"standalone"})
10
+ const ajv = buildAjv({})
115
11
 
116
- function $asStringNullable (str) {
117
- return str === null ? null : $asString(str)
118
- }
119
12
 
120
- // magically escape strings for json
121
- // relying on their charCodeAt
122
- // everything below 32 needs JSON.stringify()
123
- // every string that contain surrogate needs JSON.stringify()
124
- // 34 and 92 happens all the time, so we
125
- // have a fast case for them
126
- function $asStringSmall (str) {
127
- const l = str.length
128
- let result = ''
129
- let last = 0
130
- let found = false
131
- let surrogateFound = false
132
- let point = 255
133
- // eslint-disable-next-line
134
- for (var i = 0; i < l && point >= 32; i++) {
135
- point = str.charCodeAt(i)
136
- if (point >= 0xD800 && point <= 0xDFFF) {
137
- // The current character is a surrogate.
138
- surrogateFound = true
139
- }
140
- if (point === 34 || point === 92) {
141
- result += str.slice(last, i) + '\\'
142
- last = i
143
- found = true
13
+ function main (input) {
14
+ let json = ''
15
+ json += anonymous0(input)
16
+ return json
144
17
  }
145
- }
146
-
147
- if (!found) {
148
- result = str
149
- } else {
150
- result += str.slice(last)
151
- }
152
- return ((point < 32) || (surrogateFound === true)) ? JSON.stringify(str) : '"' + result + '"'
153
- }
154
-
155
-
156
-
157
- /**
158
- * Used by schemas that are dependant on calling 'ajv.validate' during runtime,
159
- * it stores the value of the '$id' property of the schema (if it has it) inside
160
- * a cache which is used to figure out if the schema was compiled into a validator
161
- * by ajv on a previous call, if it was then the '$id' string will be used to
162
- * invoke 'ajv.validate', this allows:
163
- *
164
- * 1. Schemas that depend on ajv.validate calls to leverage ajv caching system.
165
- * 2. To avoid errors, since directly invoking 'ajv.validate' with the same
166
- * schema (that contains an '$id' property) twice will throw an error.
167
- */
168
- const $validateWithAjv = (function() {
169
- const cache = new Set()
170
-
171
- return function (schema, target) {
172
- const id = schema.$id
173
-
174
- if (!id) {
175
- return ajv.validate(schema, target)
176
- }
177
-
178
- const cached = cache.has(id)
179
-
180
- if (cached) {
181
- return ajv.validate(id, target)
182
- } else {
183
- cache.add(id)
184
- return ajv.validate(schema, target)
185
- }
186
- }
187
- })()
188
-
189
-
190
- function parseInteger(int) { return Math.trunc(int) }
191
18
 
192
- function $main (input) {
19
+ function anonymous0 (input) {
20
+ // main
193
21
 
194
22
  var obj = (input && typeof input.toJSON === 'function')
195
23
  ? input.toJSON()
@@ -198,60 +26,60 @@ function $asStringSmall (str) {
198
26
  var json = '{'
199
27
  var addComma = false
200
28
 
201
- var t = Number(obj["statusCode"])
202
- if (!isNaN(t)) {
203
-
29
+ if (obj["statusCode"] !== undefined) {
30
+
204
31
  if (addComma) {
205
32
  json += ','
206
33
  } else {
207
34
  addComma = true
208
35
  }
209
36
 
210
- json += "\"statusCode\"" + ':' + t
211
-
37
+ json += "\"statusCode\"" + ':'
38
+ json += serializer.asNumber.bind(serializer)(obj["statusCode"])
212
39
  }
213
40
 
214
- if (obj["code"] !== undefined) {
215
-
41
+ if (obj["code"] !== undefined) {
42
+
216
43
  if (addComma) {
217
44
  json += ','
218
45
  } else {
219
46
  addComma = true
220
47
  }
221
48
 
222
- json += "\"code\"" + ':'
223
- json += $asString(obj["code"])
49
+ json += "\"code\"" + ':'
50
+ json += serializer.asString.bind(serializer)(obj["code"])
224
51
  }
225
52
 
226
- if (obj["error"] !== undefined) {
227
-
53
+ if (obj["error"] !== undefined) {
54
+
228
55
  if (addComma) {
229
56
  json += ','
230
57
  } else {
231
58
  addComma = true
232
59
  }
233
60
 
234
- json += "\"error\"" + ':'
235
- json += $asString(obj["error"])
61
+ json += "\"error\"" + ':'
62
+ json += serializer.asString.bind(serializer)(obj["error"])
236
63
  }
237
64
 
238
- if (obj["message"] !== undefined) {
239
-
65
+ if (obj["message"] !== undefined) {
66
+
240
67
  if (addComma) {
241
68
  json += ','
242
69
  } else {
243
70
  addComma = true
244
71
  }
245
72
 
246
- json += "\"message\"" + ':'
247
- json += $asString(obj["message"])
73
+ json += "\"message\"" + ':'
74
+ json += serializer.asString.bind(serializer)(obj["message"])
248
75
  }
249
76
 
250
77
  json += '}'
251
78
  return json
252
79
  }
253
-
254
-
255
- ;
256
- return $main
257
80
 
81
+
82
+
83
+
84
+ module.exports = main
85
+
@@ -104,7 +104,17 @@ function checkVersion (fn) {
104
104
  const requiredVersion = meta.fastify
105
105
 
106
106
  const fastifyRc = /-rc.+$/.test(this.version)
107
+ if (fastifyRc === true && semver.gt(this.version, semver.coerce(requiredVersion)) === true) {
108
+ // A Fastify release candidate phase is taking place. In order to reduce
109
+ // the effort needed to test plugins with the RC, we allow plugins targeting
110
+ // the prior Fastify release to be loaded.
111
+ return
112
+ }
107
113
  if (requiredVersion && semver.satisfies(this.version, requiredVersion, { includePrerelease: fastifyRc }) === false) {
114
+ // We are not in a release candidate phase. Thus, we must honor the semver
115
+ // ranges defined by the plugin's metadata. Which is to say, if the plugin
116
+ // expects an older version of Fastify than the _current_ version, we will
117
+ // throw an error.
108
118
  throw new FST_ERR_PLUGIN_VERSION_MISMATCH(meta.name, requiredVersion, this.version)
109
119
  }
110
120
  }
package/lib/reply.js CHANGED
@@ -291,7 +291,7 @@ Reply.prototype.removeTrailer = function (key) {
291
291
 
292
292
  Reply.prototype.code = function (code) {
293
293
  const intValue = parseInt(code)
294
- if (isNaN(intValue) || intValue < 100 || intValue > 600) {
294
+ if (isNaN(intValue) || intValue < 100 || intValue > 599) {
295
295
  throw new FST_ERR_BAD_STATUS_CODE(code || String(code))
296
296
  }
297
297
 
package/lib/schemas.js CHANGED
@@ -143,6 +143,9 @@ function getSchemaSerializer (context, statusCode) {
143
143
  if (responseSchemaDef[fallbackStatusCode]) {
144
144
  return responseSchemaDef[fallbackStatusCode]
145
145
  }
146
+ if (responseSchemaDef.default) {
147
+ return responseSchemaDef.default
148
+ }
146
149
  return false
147
150
  }
148
151
 
package/lib/validation.js CHANGED
@@ -7,7 +7,7 @@ const {
7
7
  kSchemaBody: bodySchema,
8
8
  kSchemaResponse: responseSchema
9
9
  } = require('./symbols')
10
- const scChecker = /^[1-5]{1}[0-9]{2}$|^[1-5]xx$/
10
+ const scChecker = /^[1-5]{1}[0-9]{2}$|^[1-5]xx$|^default$/
11
11
 
12
12
  function compileSchemasForSerialization (context, compile) {
13
13
  if (!context.schema || !context.schema.response) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fastify",
3
- "version": "4.0.0-rc.5",
3
+ "version": "4.0.2",
4
4
  "description": "Fast and low overhead web framework, for Node.js",
5
5
  "main": "fastify.js",
6
6
  "type": "commonjs",
@@ -12,11 +12,12 @@
12
12
  "coverage:ci": "npm run unit -- --cov --coverage-report=html --no-browser --no-check-coverage -R terse",
13
13
  "coverage:ci-check-coverage": "nyc check-coverage --branches 100 --functions 100 --lines 100 --statements 100",
14
14
  "license-checker": "license-checker --production --onlyAllow=\"MIT;ISC;BSD-3-Clause;BSD-2-Clause\"",
15
- "lint": "npm run lint:standard && npm run lint:typescript",
15
+ "lint": "npm run lint:standard && npm run lint:typescript && npm run lint:markdown",
16
16
  "lint:fix": "standard --fix",
17
+ "lint:markdown": "markdownlint-cli2",
17
18
  "lint:standard": "standard | snazzy",
18
19
  "lint:typescript": "eslint -c types/.eslintrc.json types/**/*.d.ts test/types/**/*.test-d.ts",
19
- "prepublishOnly": "tap --no-check-coverage test/internals/version.test.js",
20
+ "prepublishOnly": "tap --no-check-coverage test/build/**.test.js",
20
21
  "test": "npm run lint && npm run unit && npm run test:typescript",
21
22
  "test:ci": "npm run unit -- -R terse --cov --coverage-report=lcovonly && npm run test:typescript",
22
23
  "test:report": "npm run lint && npm run unit:report && npm run test:typescript",
@@ -145,7 +146,6 @@
145
146
  "eslint-plugin-n": "^15.2.0",
146
147
  "eslint-plugin-promise": "^6.0.0",
147
148
  "fast-json-body": "^1.1.0",
148
- "fast-json-stringify": "^4.0.0",
149
149
  "fastify-plugin": "^3.0.1",
150
150
  "fluent-json-schema": "^3.1.0",
151
151
  "form-data": "^4.0.0",
@@ -158,6 +158,7 @@
158
158
  "json-schema-to-ts": "^2.5.3",
159
159
  "JSONStream": "^1.3.5",
160
160
  "license-checker": "^25.0.1",
161
+ "markdownlint-cli2": "^0.4.0",
161
162
  "proxyquire": "^2.1.3",
162
163
  "pump": "^3.0.0",
163
164
  "self-cert": "^2.0.0",
@@ -180,6 +181,7 @@
180
181
  "@fastify/fast-json-stringify-compiler": "^3.0.0",
181
182
  "abstract-logging": "^2.0.1",
182
183
  "avvio": "^8.1.3",
184
+ "fast-json-stringify": "^4.1.0",
183
185
  "find-my-way": "^6.3.0",
184
186
  "light-my-request": "^5.0.0",
185
187
  "pino": "^8.0.0",
@@ -0,0 +1,28 @@
1
+ 'use strict'
2
+
3
+ const t = require('tap')
4
+ const test = t.test
5
+ const fs = require('fs')
6
+ const path = require('path')
7
+
8
+ const { code } = require('../../build/build-error-serializer')
9
+
10
+ test('check generated code syntax', async (t) => {
11
+ t.plan(1)
12
+
13
+ // standard is a esm, we import it like this
14
+ const { default: standard } = await import('standard')
15
+ const result = await standard.lintText(code)
16
+
17
+ // if there are any invalid syntax
18
+ // fatal count will be greater than 0
19
+ t.equal(result[0].fatalErrorCount, 0)
20
+ })
21
+
22
+ test('ensure the current error serializer is latest', async (t) => {
23
+ t.plan(1)
24
+
25
+ const current = await fs.promises.readFile(path.resolve('lib/error-serializer.js'))
26
+
27
+ t.equal(current.toString(), code)
28
+ })
@@ -4,7 +4,7 @@ const fs = require('fs')
4
4
  const path = require('path')
5
5
  const t = require('tap')
6
6
  const test = t.test
7
- const fastify = require('../..')()
7
+ const fastify = require('../../fastify')()
8
8
 
9
9
  test('should be the same as package.json', t => {
10
10
  t.plan(1)
@@ -1057,6 +1057,38 @@ test('plugin metadata - release candidate', t => {
1057
1057
  }
1058
1058
  })
1059
1059
 
1060
+ test('fastify-rc loads prior version plugins', t => {
1061
+ t.plan(2)
1062
+ const fastify = Fastify()
1063
+ Object.defineProperty(fastify, 'version', {
1064
+ value: '99.0.0-rc.1'
1065
+ })
1066
+
1067
+ plugin[Symbol.for('plugin-meta')] = {
1068
+ name: 'plugin',
1069
+ fastify: '^98.1.0'
1070
+ }
1071
+ plugin2[Symbol.for('plugin-meta')] = {
1072
+ name: 'plugin2',
1073
+ fastify: '98.x'
1074
+ }
1075
+
1076
+ fastify.register(plugin)
1077
+
1078
+ fastify.ready((err) => {
1079
+ t.error(err)
1080
+ t.pass('everything right')
1081
+ })
1082
+
1083
+ function plugin (instance, opts, done) {
1084
+ done()
1085
+ }
1086
+
1087
+ function plugin2 (instance, opts, done) {
1088
+ done()
1089
+ }
1090
+ })
1091
+
1060
1092
  test('hasPlugin method exists as a function', t => {
1061
1093
  t.plan(1)
1062
1094
 
@@ -520,7 +520,13 @@ const invalidErrorCodes = [
520
520
  undefined,
521
521
  null,
522
522
  'error_code',
523
- 700 // out of the 100-600 range
523
+
524
+ // out of the 100-599 range:
525
+ 0,
526
+ 1,
527
+ 99,
528
+ 600,
529
+ 700
524
530
  ]
525
531
  invalidErrorCodes.forEach((invalidCode) => {
526
532
  test(`should throw error if error code is ${invalidCode}`, t => {