fastify 4.2.0 → 4.4.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 (63) hide show
  1. package/README.md +13 -14
  2. package/docs/Guides/Database.md +2 -2
  3. package/docs/Guides/Ecosystem.md +42 -18
  4. package/docs/Guides/Migration-Guide-V4.md +29 -0
  5. package/docs/Guides/Plugins-Guide.md +5 -0
  6. package/docs/Reference/HTTP2.md +1 -3
  7. package/docs/Reference/Hooks.md +4 -1
  8. package/docs/Reference/Logging.md +1 -1
  9. package/docs/Reference/Reply.md +177 -0
  10. package/docs/Reference/Request.md +171 -0
  11. package/docs/Reference/Routes.md +4 -2
  12. package/docs/Reference/Server.md +4 -1
  13. package/docs/Reference/Type-Providers.md +1 -15
  14. package/docs/Reference/TypeScript.md +27 -3
  15. package/fastify.d.ts +1 -1
  16. package/fastify.js +3 -3
  17. package/lib/contentTypeParser.js +10 -2
  18. package/lib/context.js +10 -1
  19. package/lib/error-serializer.js +12 -12
  20. package/lib/errors.js +8 -0
  21. package/lib/handleRequest.js +2 -2
  22. package/lib/httpMethods.js +22 -0
  23. package/lib/reply.js +101 -24
  24. package/lib/request.js +97 -1
  25. package/lib/route.js +3 -1
  26. package/lib/symbols.js +15 -9
  27. package/package.json +7 -7
  28. package/test/build/error-serializer.test.js +3 -1
  29. package/test/content-parser.test.js +15 -0
  30. package/test/copy.test.js +41 -0
  31. package/test/internals/all.test.js +8 -2
  32. package/test/internals/reply-serialize.test.js +583 -0
  33. package/test/internals/reply.test.js +4 -1
  34. package/test/internals/request-validate.test.js +1269 -0
  35. package/test/internals/request.test.js +11 -2
  36. package/test/lock.test.js +73 -0
  37. package/test/mkcol.test.js +38 -0
  38. package/test/move.test.js +45 -0
  39. package/test/propfind.test.js +108 -0
  40. package/test/proppatch.test.js +78 -0
  41. package/test/request-error.test.js +44 -1
  42. package/test/schema-validation.test.js +71 -0
  43. package/test/search.test.js +100 -0
  44. package/test/trace.test.js +21 -0
  45. package/test/types/fastify.test-d.ts +12 -1
  46. package/test/types/hooks.test-d.ts +1 -2
  47. package/test/types/import.ts +1 -1
  48. package/test/types/instance.test-d.ts +4 -1
  49. package/test/types/logger.test-d.ts +4 -5
  50. package/test/types/reply.test-d.ts +44 -3
  51. package/test/types/request.test-d.ts +10 -29
  52. package/test/types/type-provider.test-d.ts +79 -7
  53. package/test/unlock.test.js +41 -0
  54. package/test/validation-error-handling.test.js +6 -1
  55. package/types/hooks.d.ts +19 -39
  56. package/types/instance.d.ts +78 -130
  57. package/types/logger.d.ts +7 -4
  58. package/types/reply.d.ts +7 -1
  59. package/types/request.d.ts +16 -3
  60. package/types/route.d.ts +23 -29
  61. package/types/schema.d.ts +4 -1
  62. package/types/type-provider.d.ts +8 -20
  63. package/types/utils.d.ts +2 -1
@@ -19,6 +19,9 @@ test('Regular request', t => {
19
19
  req.connection = req.socket
20
20
  const request = new Request('id', 'params', req, 'query', 'log')
21
21
  t.type(request, Request)
22
+ t.type(request.validateInput, Function)
23
+ t.type(request.getValidationFunction, Function)
24
+ t.type(request.compileValidationSchema, Function)
22
25
  t.equal(request.id, 'id')
23
26
  t.equal(request.params, 'params')
24
27
  t.equal(request.raw, req)
@@ -74,7 +77,7 @@ test('Regular request - host header has precedence over authority', t => {
74
77
  })
75
78
 
76
79
  test('Request with trust proxy', t => {
77
- t.plan(15)
80
+ t.plan(18)
78
81
  const headers = {
79
82
  'x-forwarded-for': '2.2.2.2, 1.1.1.1',
80
83
  'x-forwarded-host': 'example.com'
@@ -103,6 +106,9 @@ test('Request with trust proxy', t => {
103
106
  t.equal(request.url, '/')
104
107
  t.equal(request.socket, req.socket)
105
108
  t.equal(request.protocol, 'http')
109
+ t.type(request.validateInput, Function)
110
+ t.type(request.getValidationFunction, Function)
111
+ t.type(request.compileValidationSchema, Function)
106
112
  })
107
113
 
108
114
  test('Request with trust proxy, encrypted', t => {
@@ -221,7 +227,7 @@ test('Request with trust proxy - plain', t => {
221
227
  })
222
228
 
223
229
  test('Request with undefined socket', t => {
224
- t.plan(15)
230
+ t.plan(18)
225
231
  const headers = {
226
232
  host: 'hostname'
227
233
  }
@@ -247,6 +253,9 @@ test('Request with undefined socket', t => {
247
253
  t.equal(request.url, '/')
248
254
  t.equal(request.protocol, undefined)
249
255
  t.same(request.socket, req.socket)
256
+ t.type(request.validateInput, Function)
257
+ t.type(request.getValidationFunction, Function)
258
+ t.type(request.compileValidationSchema, Function)
250
259
  })
251
260
 
252
261
  test('Request with trust proxy and undefined socket', t => {
@@ -0,0 +1,73 @@
1
+ 'use strict'
2
+
3
+ const t = require('tap')
4
+ const test = t.test
5
+ const sget = require('simple-get').concat
6
+ const fastify = require('..')()
7
+
8
+ test('can be created - lock', t => {
9
+ t.plan(1)
10
+ try {
11
+ fastify.route({
12
+ method: 'LOCK',
13
+ url: '*',
14
+ handler: function (req, reply) {
15
+ reply
16
+ .code(200)
17
+ .send(`<?xml version="1.0" encoding="utf-8" ?>
18
+ <D:prop xmlns:D="DAV:">
19
+ <D:lockdiscovery>
20
+ <D:activelock>
21
+ <D:locktype>
22
+ <D:write/>
23
+ </D:locktype>
24
+ <D:lockscope>
25
+ <D:exclusive/>
26
+ </D:lockscope>
27
+ <D:depth>infinity</D:depth>
28
+ <D:owner>
29
+ <D:href>http://example.org/~ejw/contact.html</D:href>
30
+ </D:owner>
31
+ <D:timeout>Second-604800</D:timeout>
32
+ <D:locktoken>
33
+ <D:href>urn:uuid:e71d4fae-5dec-22d6-fea5-00a0c91e6be4</:href>
34
+ </D:locktoken>
35
+ <D:lockroot>
36
+ <D:href>http://example.com/workspace/webdav/proposal.oc</D:href>
37
+ </D:lockroot>
38
+ </D:activelock>
39
+ </D:lockdiscovery>
40
+ </D:prop>`
41
+ )
42
+ }
43
+ })
44
+ t.pass()
45
+ } catch (e) {
46
+ t.fail()
47
+ }
48
+ })
49
+
50
+ fastify.listen({ port: 0 }, err => {
51
+ t.error(err)
52
+ t.teardown(() => { fastify.close() })
53
+
54
+ test('request - lock', t => {
55
+ t.plan(3)
56
+ sget({
57
+ url: `http://localhost:${fastify.server.address().port}/test/a.txt`,
58
+ body: `<?xml version="1.0" encoding="utf-8" ?>
59
+ <D:lockinfo xmlns:D='DAV:'>
60
+ <D:lockscope> <D:exclusive/> </D:lockscope>
61
+ <D:locktype> <D:write/> </D:locktype>
62
+ <D:owner>
63
+ <D:href>http://example.org/~ejw/contact.html</D:href>
64
+ </D:owner>
65
+ </D:lockinfo> `,
66
+ method: 'LOCK'
67
+ }, (err, response, body) => {
68
+ t.error(err)
69
+ t.equal(response.statusCode, 200)
70
+ t.equal(response.headers['content-length'], '' + body.length)
71
+ })
72
+ })
73
+ })
@@ -0,0 +1,38 @@
1
+ 'use strict'
2
+
3
+ const t = require('tap')
4
+ const test = t.test
5
+ const sget = require('simple-get').concat
6
+ const fastify = require('..')()
7
+
8
+ test('can be created - mkcol', t => {
9
+ t.plan(1)
10
+ try {
11
+ fastify.route({
12
+ method: 'MKCOL',
13
+ url: '*',
14
+ handler: function (req, reply) {
15
+ reply.code(201).send()
16
+ }
17
+ })
18
+ t.pass()
19
+ } catch (e) {
20
+ t.fail()
21
+ }
22
+ })
23
+
24
+ fastify.listen({ port: 0 }, err => {
25
+ t.error(err)
26
+ t.teardown(() => { fastify.close() })
27
+
28
+ test('request - mkcol', t => {
29
+ t.plan(2)
30
+ sget({
31
+ url: `http://localhost:${fastify.server.address().port}/test/`,
32
+ method: 'MKCOL'
33
+ }, (err, response, body) => {
34
+ t.error(err)
35
+ t.equal(response.statusCode, 201)
36
+ })
37
+ })
38
+ })
@@ -0,0 +1,45 @@
1
+ 'use strict'
2
+
3
+ const t = require('tap')
4
+ const test = t.test
5
+ const sget = require('simple-get').concat
6
+ const fastify = require('..')()
7
+
8
+ test('shorthand - move', t => {
9
+ t.plan(1)
10
+ try {
11
+ fastify.route({
12
+ method: 'MOVE',
13
+ url: '*',
14
+ handler: function (req, reply) {
15
+ const destination = req.headers.destination
16
+ reply.code(201)
17
+ .header('location', destination)
18
+ .send()
19
+ }
20
+ })
21
+ t.pass()
22
+ } catch (e) {
23
+ t.fail()
24
+ }
25
+ })
26
+
27
+ fastify.listen({ port: 0 }, err => {
28
+ t.error(err)
29
+ t.teardown(() => { fastify.close() })
30
+
31
+ test('request - move', t => {
32
+ t.plan(3)
33
+ sget({
34
+ url: `http://localhost:${fastify.server.address().port}/test.txt`,
35
+ method: 'MOVE',
36
+ headers: {
37
+ Destination: '/test2.txt'
38
+ }
39
+ }, (err, response, body) => {
40
+ t.error(err)
41
+ t.equal(response.statusCode, 201)
42
+ t.equal(response.headers.location, '/test2.txt')
43
+ })
44
+ })
45
+ })
@@ -0,0 +1,108 @@
1
+ 'use strict'
2
+
3
+ const t = require('tap')
4
+ const test = t.test
5
+ const sget = require('simple-get').concat
6
+ const fastify = require('..')()
7
+
8
+ test('can be created - propfind', t => {
9
+ t.plan(1)
10
+ try {
11
+ fastify.route({
12
+ method: 'PROPFIND',
13
+ url: '*',
14
+ handler: function (req, reply) {
15
+ return reply.code(207)
16
+ .send(`<?xml version="1.0" encoding="utf-8"?>
17
+ <D:multistatus xmlns:D="DAV:">
18
+ <D:response xmlns:lp1="DAV:">
19
+ <D:href>/</D:href>
20
+ <D:propstat>
21
+ <D:prop>
22
+ <lp1:resourcetype>
23
+ <D:collection/>
24
+ </lp1:resourcetype>
25
+ <lp1:creationdate>2022-04-13T12:35:30Z</lp1:creationdate>
26
+ <lp1:getlastmodified>Wed, 13 Apr 2022 12:35:30 GMT</lp1:getlastmodified>
27
+ <lp1:getetag>"e0-5dc8869b53ef1"</lp1:getetag>
28
+ <D:supportedlock>
29
+ <D:lockentry>
30
+ <D:lockscope>
31
+ <D:exclusive/>
32
+ </D:lockscope>
33
+ <D:locktype>
34
+ <D:write/>
35
+ </D:locktype>
36
+ </D:lockentry>
37
+ <D:lockentry>
38
+ <D:lockscope>
39
+ <D:shared/>
40
+ </D:lockscope>
41
+ <D:locktype>
42
+ <D:write/>
43
+ </D:locktype>
44
+ </D:lockentry>
45
+ </D:supportedlock>
46
+ <D:lockdiscovery/>
47
+ <D:getcontenttype>httpd/unix-directory</D:getcontenttype>
48
+ </D:prop>
49
+ <D:status>HTTP/1.1 200 OK</D:status>
50
+ </D:propstat>
51
+ </D:response>
52
+ </D:multistatus>`
53
+ )
54
+ }
55
+ })
56
+ t.pass()
57
+ } catch (e) {
58
+ t.fail()
59
+ }
60
+ })
61
+
62
+ fastify.listen({ port: 0 }, err => {
63
+ t.error(err)
64
+ t.teardown(() => { fastify.close() })
65
+
66
+ test('request - propfind', t => {
67
+ t.plan(3)
68
+ sget({
69
+ url: `http://localhost:${fastify.server.address().port}/`,
70
+ method: 'PROPFIND'
71
+ }, (err, response, body) => {
72
+ t.error(err)
73
+ t.equal(response.statusCode, 207)
74
+ t.equal(response.headers['content-length'], '' + body.length)
75
+ })
76
+ })
77
+
78
+ test('request with other path - propfind', t => {
79
+ t.plan(3)
80
+ sget({
81
+ url: `http://localhost:${fastify.server.address().port}/test`,
82
+ method: 'PROPFIND'
83
+ }, (err, response, body) => {
84
+ t.error(err)
85
+ t.equal(response.statusCode, 207)
86
+ t.equal(response.headers['content-length'], '' + body.length)
87
+ })
88
+ })
89
+
90
+ test('request with body - propfind', t => {
91
+ t.plan(3)
92
+ sget({
93
+ url: `http://localhost:${fastify.server.address().port}/test`,
94
+ body: `<?xml version="1.0" encoding="utf-8" ?>
95
+ <D:propfind xmlns:D="DAV:">
96
+ <D:prop xmlns:R="http://ns.example.com/boxschema/">
97
+ <R:bigbox/> <R:author/> <R:DingALing/> <R:Random/>
98
+ </D:prop>
99
+ </D:propfind>
100
+ `,
101
+ method: 'PROPFIND'
102
+ }, (err, response, body) => {
103
+ t.error(err)
104
+ t.equal(response.statusCode, 207)
105
+ t.equal(response.headers['content-length'], '' + body.length)
106
+ })
107
+ })
108
+ })
@@ -0,0 +1,78 @@
1
+ 'use strict'
2
+
3
+ const t = require('tap')
4
+ const test = t.test
5
+ const sget = require('simple-get').concat
6
+ const fastify = require('..')()
7
+
8
+ test('shorthand - proppatch', t => {
9
+ t.plan(1)
10
+ try {
11
+ fastify.route({
12
+ method: 'PROPPATCH',
13
+ url: '*',
14
+ handler: function (req, reply) {
15
+ reply
16
+ .code(207)
17
+ .send(`<?xml version="1.0" encoding="utf-8" ?>
18
+ <D:multistatus xmlns:D="DAV:"
19
+ xmlns:Z="http://ns.example.com/standards/z39.50/">
20
+ <D:response>
21
+ <D:href>http://www.example.com/bar.html</D:href>
22
+ <D:propstat>
23
+ <D:prop>
24
+ <Z:Authors/>
25
+ </D:prop>
26
+ <D:status>HTTP/1.1 424 Failed Dependency</D:status>
27
+ </D:propstat>
28
+ <D:propstat>
29
+ <D:prop>
30
+ <Z:Copyright-Owner/>
31
+ </D:prop>
32
+ <D:status>HTTP/1.1 409 Conflict</D:status>
33
+ </D:propstat>
34
+ <D:responsedescription> Copyright Owner cannot be deleted or altered.</D:responsedescription>
35
+ </D:response>
36
+ </D:multistatus>`
37
+ )
38
+ }
39
+ })
40
+ t.pass()
41
+ } catch (e) {
42
+ t.fail()
43
+ }
44
+ })
45
+
46
+ fastify.listen({ port: 0 }, err => {
47
+ t.error(err)
48
+ t.teardown(() => { fastify.close() })
49
+
50
+ test('request - proppatch', t => {
51
+ t.plan(3)
52
+ sget({
53
+ url: `http://localhost:${fastify.server.address().port}/test/a.txt`,
54
+ body: `<?xml version="1.0" encoding="utf-8" ?>
55
+ <D:propertyupdate xmlns:D="DAV:"
56
+ xmlns:Z="http://ns.example.com/standards/z39.50/">
57
+ <D:set>
58
+ <D:prop>
59
+ <Z:Authors>
60
+ <Z:Author>Jim Whitehead</Z:Author>
61
+ <Z:Author>Roy Fielding</Z:Author>
62
+ </Z:Authors>
63
+ </D:prop>
64
+ </D:set>
65
+ <D:remove>
66
+ <D:prop>
67
+ <Z:Copyright-Owner/>
68
+ </D:prop>
69
+ </D:remove>
70
+ </D:propertyupdate>`,
71
+ method: 'PROPPATCH'
72
+ }, (err, response, body) => {
73
+ t.error(err)
74
+ t.equal(response.statusCode, 207)
75
+ t.equal(response.headers['content-length'], '' + body.length)
76
+ })
77
+ })
78
+ })
@@ -150,7 +150,7 @@ test('default clientError handler ignores sockets in destroyed state', t => {
150
150
  })
151
151
 
152
152
  test('default clientError handler destroys sockets in writable state', t => {
153
- t.plan(1)
153
+ t.plan(2)
154
154
 
155
155
  const fastify = Fastify({
156
156
  bodyLimit: 1,
@@ -166,6 +166,9 @@ test('default clientError handler destroys sockets in writable state', t => {
166
166
  },
167
167
  destroy () {
168
168
  t.pass('destroy should be called')
169
+ },
170
+ write (response) {
171
+ t.match(response, /^HTTP\/1.1 400 Bad Request/)
169
172
  }
170
173
  })
171
174
  })
@@ -186,6 +189,9 @@ test('default clientError handler destroys http sockets in non-writable state',
186
189
  },
187
190
  destroy () {
188
191
  t.pass('destroy should be called')
192
+ },
193
+ write (response) {
194
+ t.fail('write should not be called')
189
195
  }
190
196
  })
191
197
  })
@@ -270,3 +276,40 @@ test('encapsulated error handler binding', t => {
270
276
  t.equal(fastify.hello, undefined)
271
277
  })
272
278
  })
279
+
280
+ test('default clientError replies with bad request on reused keep-alive connection', t => {
281
+ t.plan(2)
282
+
283
+ let response = ''
284
+
285
+ const fastify = Fastify({
286
+ bodyLimit: 1,
287
+ keepAliveTimeout: 100
288
+ })
289
+
290
+ fastify.get('/', (request, reply) => {
291
+ reply.send('OK\n')
292
+ })
293
+
294
+ fastify.listen({ port: 0 }, function (err) {
295
+ t.error(err)
296
+ fastify.server.unref()
297
+
298
+ const client = connect(fastify.server.address().port)
299
+
300
+ client.on('data', chunk => {
301
+ response += chunk.toString('utf-8')
302
+ })
303
+
304
+ client.on('end', () => {
305
+ t.match(response, /^HTTP\/1.1 200 OK.*HTTP\/1.1 400 Bad Request/s)
306
+ })
307
+
308
+ client.resume()
309
+ client.write('GET / HTTP/1.1\r\n')
310
+ client.write('\r\n\r\n')
311
+ client.write('GET /?a b HTTP/1.1\r\n')
312
+ client.write('Connection: close\r\n')
313
+ client.write('\r\n\r\n')
314
+ })
315
+ })
@@ -4,6 +4,7 @@ const { test } = require('tap')
4
4
  const Fastify = require('..')
5
5
 
6
6
  const AJV = require('ajv')
7
+ const Schema = require('fluent-json-schema')
7
8
 
8
9
  const customSchemaCompilers = {
9
10
  body: new AJV({
@@ -946,3 +947,73 @@ test('Custom AJV settings on different parameters - pt2', t => {
946
947
  }
947
948
  })
948
949
  })
950
+
951
+ test("The same $id in route's schema must not overwrite others", t => {
952
+ t.plan(4)
953
+ const fastify = Fastify()
954
+
955
+ const UserSchema = Schema.object()
956
+ .id('http://mydomain.com/user')
957
+ .title('User schema')
958
+ .description('Contains all user fields')
959
+ .prop('id', Schema.integer())
960
+ .prop('username', Schema.string().minLength(4))
961
+ .prop('firstName', Schema.string().minLength(1))
962
+ .prop('lastName', Schema.string().minLength(1))
963
+ .prop('fullName', Schema.string().minLength(1))
964
+ .prop('email', Schema.string())
965
+ .prop('password', Schema.string().minLength(6))
966
+ .prop('bio', Schema.string())
967
+
968
+ const userCreateSchema = UserSchema.only([
969
+ 'username',
970
+ 'firstName',
971
+ 'lastName',
972
+ 'email',
973
+ 'bio',
974
+ 'password',
975
+ 'password_confirm'
976
+ ])
977
+ .required([
978
+ 'username',
979
+ 'firstName',
980
+ 'lastName',
981
+ 'email',
982
+ 'bio',
983
+ 'password'
984
+ ])
985
+
986
+ const userPatchSchema = UserSchema.only([
987
+ 'firstName',
988
+ 'lastName',
989
+ 'bio'
990
+ ])
991
+
992
+ fastify
993
+ .patch('/user/:id', {
994
+ schema: { body: userPatchSchema },
995
+ handler: () => { return 'ok' }
996
+ })
997
+ .post('/user', {
998
+ schema: { body: userCreateSchema },
999
+ handler: () => { return 'ok' }
1000
+ })
1001
+
1002
+ fastify.inject({
1003
+ method: 'POST',
1004
+ url: '/user',
1005
+ body: {}
1006
+ }, (err, res) => {
1007
+ t.error(err)
1008
+ t.same(res.json().message, "body must have required property 'username'")
1009
+ })
1010
+
1011
+ fastify.inject({
1012
+ url: '/user/1',
1013
+ method: 'PATCH',
1014
+ body: {}
1015
+ }, (err, res) => {
1016
+ t.error(err)
1017
+ t.same(res.payload, 'ok')
1018
+ })
1019
+ })
@@ -0,0 +1,100 @@
1
+ 'use strict'
2
+
3
+ const t = require('tap')
4
+ const test = t.test
5
+ const fastify = require('..')()
6
+
7
+ const schema = {
8
+ schema: {
9
+ response: {
10
+ '2xx': {
11
+ type: 'object',
12
+ properties: {
13
+ hello: {
14
+ type: 'string'
15
+ }
16
+ }
17
+ }
18
+ }
19
+ }
20
+ }
21
+
22
+ const querySchema = {
23
+ schema: {
24
+ querystring: {
25
+ type: 'object',
26
+ properties: {
27
+ hello: {
28
+ type: 'integer'
29
+ }
30
+ }
31
+ }
32
+ }
33
+ }
34
+
35
+ const paramsSchema = {
36
+ schema: {
37
+ params: {
38
+ type: 'object',
39
+ properties: {
40
+ foo: {
41
+ type: 'string'
42
+ },
43
+ test: {
44
+ type: 'integer'
45
+ }
46
+ }
47
+ }
48
+ }
49
+ }
50
+
51
+ test('shorthand - search', t => {
52
+ t.plan(1)
53
+ try {
54
+ fastify.route({
55
+ method: 'SEARCH',
56
+ url: '/',
57
+ schema,
58
+ handler: function (request, reply) {
59
+ reply.code(200).send({ hello: 'world' })
60
+ }
61
+ })
62
+ t.pass()
63
+ } catch (e) {
64
+ t.fail()
65
+ }
66
+ })
67
+
68
+ test('shorthand - search params', t => {
69
+ t.plan(1)
70
+ try {
71
+ fastify.route({
72
+ method: 'SEARCH',
73
+ url: '/params/:foo/:test',
74
+ paramsSchema,
75
+ handler: function (request, reply) {
76
+ reply.code(200).send(request.params)
77
+ }
78
+ })
79
+ t.pass()
80
+ } catch (e) {
81
+ t.fail()
82
+ }
83
+ })
84
+
85
+ test('shorthand - get, querystring schema', t => {
86
+ t.plan(1)
87
+ try {
88
+ fastify.route({
89
+ method: 'SEARCH',
90
+ url: '/query',
91
+ querySchema,
92
+ handler: function (request, reply) {
93
+ reply.code(200).send(request.query)
94
+ }
95
+ })
96
+ t.pass()
97
+ } catch (e) {
98
+ t.fail()
99
+ }
100
+ })
@@ -0,0 +1,21 @@
1
+ 'use strict'
2
+
3
+ const t = require('tap')
4
+ const test = t.test
5
+ const fastify = require('..')()
6
+
7
+ test('shorthand - trace', t => {
8
+ t.plan(1)
9
+ try {
10
+ fastify.route({
11
+ method: 'TRACE',
12
+ url: '/',
13
+ handler: function (request, reply) {
14
+ reply.code(200).send('TRACE OK')
15
+ }
16
+ })
17
+ t.pass()
18
+ } catch (e) {
19
+ t.fail()
20
+ }
21
+ })
@@ -194,7 +194,18 @@ expectAssignable<FastifyInstance>(fastify({ frameworkErrors: () => { } }))
194
194
  expectAssignable<FastifyInstance>(fastify({
195
195
  rewriteUrl: (req) => req.url === '/hi' ? '/hello' : req.url!
196
196
  }))
197
- expectAssignable<FastifyInstance>(fastify({ schemaErrorFormatter: (errors, dataVar) => new Error() }))
197
+ expectAssignable<FastifyInstance>(fastify({
198
+ schemaErrorFormatter: (errors, dataVar) => {
199
+ console.log(
200
+ errors[0].keyword.toLowerCase(),
201
+ errors[0].message?.toLowerCase(),
202
+ errors[0].params,
203
+ errors[0].instancePath.toLowerCase(),
204
+ errors[0].schemaPath.toLowerCase()
205
+ )
206
+ return new Error()
207
+ }
208
+ }))
198
209
  expectAssignable<FastifyInstance>(fastify({
199
210
  clientErrorHandler: (err, socket) => {
200
211
  expectType<ConnectionError>(err)
@@ -223,8 +223,7 @@ RawReplyDefaultExpression,
223
223
  RouteGenericInterface,
224
224
  ContextConfigDefault,
225
225
  FastifySchema,
226
- FastifyTypeProviderDefault,
227
- ResolveFastifyRequestType<FastifyTypeProviderDefault, FastifySchema, RouteGenericInterface>
226
+ FastifyTypeProviderDefault
228
227
  > = async function (request, reply): Promise<void> {
229
228
  expectType<FastifyInstance>(this)
230
229
  expectAssignable<FastifyRequest>(request)
@@ -1 +1 @@
1
- import { FastifyLogFn } from '../../fastify'
1
+ import { FastifyListenOptions, FastifyLogFn } from '../../fastify'