fastify 4.25.2 → 4.26.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 (55) hide show
  1. package/EXPENSE_POLICY.md +105 -0
  2. package/GOVERNANCE.md +2 -103
  3. package/LICENSE +1 -1
  4. package/README.md +13 -9
  5. package/SECURITY.md +2 -157
  6. package/SPONSORS.md +20 -0
  7. package/build/build-validation.js +3 -1
  8. package/docs/Guides/Ecosystem.md +29 -9
  9. package/docs/Guides/Getting-Started.md +16 -3
  10. package/docs/Guides/Style-Guide.md +7 -7
  11. package/docs/Reference/Decorators.md +1 -1
  12. package/docs/Reference/Errors.md +63 -1
  13. package/docs/Reference/Hooks.md +1 -1
  14. package/docs/Reference/Logging.md +3 -3
  15. package/docs/Reference/Reply.md +70 -1
  16. package/docs/Reference/Server.md +90 -0
  17. package/docs/Reference/Warnings.md +17 -2
  18. package/fastify.d.ts +3 -2
  19. package/fastify.js +25 -7
  20. package/lib/configValidator.js +62 -33
  21. package/lib/contentTypeParser.js +9 -2
  22. package/lib/error-handler.js +1 -1
  23. package/lib/error-serializer.js +30 -29
  24. package/lib/errors.js +6 -1
  25. package/lib/fourOhFour.js +4 -3
  26. package/lib/hooks.js +1 -5
  27. package/lib/reply.js +68 -10
  28. package/lib/reqIdGenFactory.js +5 -0
  29. package/lib/route.js +22 -6
  30. package/lib/schema-controller.js +37 -4
  31. package/lib/symbols.js +1 -0
  32. package/lib/warnings.js +6 -0
  33. package/package.json +18 -6
  34. package/test/async_hooks.test.js +69 -0
  35. package/test/findRoute.test.js +135 -0
  36. package/test/genReqId.test.js +392 -0
  37. package/test/hooks.on-listen.test.js +66 -14
  38. package/test/hooks.on-ready.test.js +1 -1
  39. package/test/internals/errors.test.js +17 -7
  40. package/test/internals/initialConfig.test.js +7 -3
  41. package/test/internals/reply.test.js +80 -5
  42. package/test/plugin.4.test.js +3 -3
  43. package/test/pretty-print.test.js +1 -1
  44. package/test/schema-serialization.test.js +41 -0
  45. package/test/schema-validation.test.js +115 -6
  46. package/test/serialize-response.test.js +187 -0
  47. package/test/types/instance.test-d.ts +14 -1
  48. package/test/types/reply.test-d.ts +4 -2
  49. package/test/types/request.test-d.ts +1 -1
  50. package/test/types/route.test-d.ts +15 -1
  51. package/test/useSemicolonDelimiter.test.js +113 -0
  52. package/test/web-api.test.js +208 -0
  53. package/types/instance.d.ts +23 -10
  54. package/types/reply.d.ts +4 -0
  55. package/types/request.d.ts +5 -4
@@ -19,7 +19,7 @@ const {
19
19
  } = require('../../lib/symbols')
20
20
  const fs = require('node:fs')
21
21
  const path = require('node:path')
22
- const { FSTDEP019, FSTDEP010 } = require('../../lib/warnings')
22
+ const { FSTDEP010, FSTDEP019, FSTDEP020 } = require('../../lib/warnings')
23
23
 
24
24
  const agent = new http.Agent({ keepAlive: false })
25
25
 
@@ -1598,7 +1598,40 @@ test('reply.getResponseTime() should return a number greater than 0 after the ti
1598
1598
  fastify.inject({ method: 'GET', url: '/' })
1599
1599
  })
1600
1600
 
1601
- test('reply.getResponseTime() should return the time since a request started while inflight', t => {
1601
+ test('should emit deprecation warning when trying to use reply.getResponseTime() and should return the time since a request started while inflight', t => {
1602
+ t.plan(5)
1603
+ const fastify = Fastify()
1604
+ fastify.route({
1605
+ method: 'GET',
1606
+ url: '/',
1607
+ handler: (req, reply) => {
1608
+ reply.send('hello world')
1609
+ }
1610
+ })
1611
+
1612
+ process.removeAllListeners('warning')
1613
+ process.on('warning', onWarning)
1614
+ function onWarning (warning) {
1615
+ t.equal(warning.name, 'DeprecationWarning')
1616
+ t.equal(warning.code, FSTDEP020.code)
1617
+ }
1618
+
1619
+ fastify.addHook('preValidation', (req, reply, done) => {
1620
+ t.equal(reply.getResponseTime(), reply.getResponseTime())
1621
+ done()
1622
+ })
1623
+
1624
+ fastify.inject({ method: 'GET', url: '/' }, (err, res) => {
1625
+ t.error(err)
1626
+ t.pass()
1627
+
1628
+ process.removeListener('warning', onWarning)
1629
+ })
1630
+
1631
+ FSTDEP020.emitted = false
1632
+ })
1633
+
1634
+ test('reply.getResponseTime() should return the same value after a request is finished', t => {
1602
1635
  t.plan(1)
1603
1636
  const fastify = Fastify()
1604
1637
  fastify.route({
@@ -1609,19 +1642,61 @@ test('reply.getResponseTime() should return the time since a request started whi
1609
1642
  }
1610
1643
  })
1611
1644
 
1645
+ fastify.addHook('onResponse', (req, reply) => {
1646
+ t.equal(reply.getResponseTime(), reply.getResponseTime())
1647
+ t.end()
1648
+ })
1649
+
1650
+ fastify.inject({ method: 'GET', url: '/' })
1651
+ })
1652
+
1653
+ test('reply.elapsedTime should return a number greater than 0 after the timer is initialised on the reply by setting up response listeners', t => {
1654
+ t.plan(1)
1655
+ const fastify = Fastify()
1656
+ fastify.route({
1657
+ method: 'GET',
1658
+ url: '/',
1659
+ handler: (req, reply) => {
1660
+ reply.send('hello world')
1661
+ }
1662
+ })
1663
+
1664
+ fastify.addHook('onResponse', (req, reply) => {
1665
+ t.ok(reply.elapsedTime > 0)
1666
+ t.end()
1667
+ })
1668
+
1669
+ fastify.inject({ method: 'GET', url: '/' })
1670
+ })
1671
+
1672
+ test('reply.elapsedTime should return the time since a request started while inflight', t => {
1673
+ t.plan(1)
1674
+ const fastify = Fastify()
1675
+ fastify.route({
1676
+ method: 'GET',
1677
+ url: '/',
1678
+ handler: (req, reply) => {
1679
+ reply.send('hello world')
1680
+ }
1681
+ })
1682
+
1683
+ let preValidationElapsedTime
1684
+
1612
1685
  fastify.addHook('preValidation', (req, reply, done) => {
1613
- t.not(reply.getResponseTime(), reply.getResponseTime())
1686
+ preValidationElapsedTime = reply.elapsedTime
1687
+
1614
1688
  done()
1615
1689
  })
1616
1690
 
1617
1691
  fastify.addHook('onResponse', (req, reply) => {
1692
+ t.ok(reply.elapsedTime > preValidationElapsedTime)
1618
1693
  t.end()
1619
1694
  })
1620
1695
 
1621
1696
  fastify.inject({ method: 'GET', url: '/' })
1622
1697
  })
1623
1698
 
1624
- test('reply.getResponseTime() should return the same value after a request is finished', t => {
1699
+ test('reply.elapsedTime should return the same value after a request is finished', t => {
1625
1700
  t.plan(1)
1626
1701
  const fastify = Fastify()
1627
1702
  fastify.route({
@@ -1633,7 +1708,7 @@ test('reply.getResponseTime() should return the same value after a request is fi
1633
1708
  })
1634
1709
 
1635
1710
  fastify.addHook('onResponse', (req, reply) => {
1636
- t.equal(reply.getResponseTime(), reply.getResponseTime())
1711
+ t.equal(reply.elapsedTime, reply.elapsedTime)
1637
1712
  t.end()
1638
1713
  })
1639
1714
 
@@ -22,7 +22,7 @@ test('pluginTimeout', t => {
22
22
  "fastify-plugin: Plugin did not start in time: 'function (app, opts, done) { -- // to no call done on purpose'. You may have forgotten to call 'done' function or to resolve a Promise")
23
23
  t.equal(err.code, 'FST_ERR_PLUGIN_TIMEOUT')
24
24
  t.ok(err.cause)
25
- t.equal(err.cause.code, 'AVV_ERR_READY_TIMEOUT')
25
+ t.equal(err.cause.code, 'AVV_ERR_PLUGIN_EXEC_TIMEOUT')
26
26
  })
27
27
  })
28
28
 
@@ -40,7 +40,7 @@ test('pluginTimeout - named function', t => {
40
40
  "fastify-plugin: Plugin did not start in time: 'nameFunction'. You may have forgotten to call 'done' function or to resolve a Promise")
41
41
  t.equal(err.code, 'FST_ERR_PLUGIN_TIMEOUT')
42
42
  t.ok(err.cause)
43
- t.equal(err.cause.code, 'AVV_ERR_READY_TIMEOUT')
43
+ t.equal(err.cause.code, 'AVV_ERR_PLUGIN_EXEC_TIMEOUT')
44
44
  })
45
45
  })
46
46
 
@@ -60,7 +60,7 @@ test('pluginTimeout default', t => {
60
60
  "fastify-plugin: Plugin did not start in time: 'function (app, opts, done) { -- // default time elapsed without calling done'. You may have forgotten to call 'done' function or to resolve a Promise")
61
61
  t.equal(err.code, 'FST_ERR_PLUGIN_TIMEOUT')
62
62
  t.ok(err.cause)
63
- t.equal(err.cause.code, 'AVV_ERR_READY_TIMEOUT')
63
+ t.equal(err.cause.code, 'AVV_ERR_PLUGIN_EXEC_TIMEOUT')
64
64
  })
65
65
 
66
66
  t.teardown(clock.uninstall)
@@ -220,7 +220,7 @@ test('pretty print - empty plugins', t => {
220
220
  fastify.ready(() => {
221
221
  const tree = fastify.printPlugins()
222
222
  t.equal(typeof tree, 'string')
223
- t.match(tree, 'bound root')
223
+ t.match(tree, /root \d+ ms\n└── bound _after \d+ ms/m)
224
224
  })
225
225
  })
226
226
 
@@ -593,6 +593,47 @@ test('Custom setSerializerCompiler returns bad serialized output', t => {
593
593
  })
594
594
  })
595
595
 
596
+ test('Custom setSerializerCompiler with addSchema', t => {
597
+ t.plan(6)
598
+ const fastify = Fastify({ exposeHeadRoutes: false })
599
+
600
+ const outSchema = {
601
+ $id: 'test',
602
+ type: 'object',
603
+ whatever: 'need to be parsed by the custom serializer'
604
+ }
605
+
606
+ fastify.setSerializerCompiler(({ schema, method, url, httpStatus }) => {
607
+ t.equal(method, 'GET')
608
+ t.equal(url, '/foo/:id')
609
+ t.equal(httpStatus, '200')
610
+ t.same(schema, outSchema)
611
+ return _data => JSON.stringify({ id: 2 })
612
+ })
613
+
614
+ // provoke re-creation of serialization compiler in setupSerializer
615
+ fastify.addSchema({ $id: 'dummy', type: 'object' })
616
+
617
+ fastify.get('/foo/:id', {
618
+ handler (_req, reply) {
619
+ reply.send({ id: 1 })
620
+ },
621
+ schema: {
622
+ response: {
623
+ 200: outSchema
624
+ }
625
+ }
626
+ })
627
+
628
+ fastify.inject({
629
+ method: 'GET',
630
+ url: '/foo/123'
631
+ }, (err, res) => {
632
+ t.error(err)
633
+ t.equal(res.payload, JSON.stringify({ id: 2 }))
634
+ })
635
+ })
636
+
596
637
  test('Custom serializer per route', async t => {
597
638
  const fastify = Fastify()
598
639
 
@@ -106,7 +106,7 @@ test('Basic validation test', t => {
106
106
  })
107
107
 
108
108
  test('External AJV instance', t => {
109
- t.plan(4)
109
+ t.plan(5)
110
110
 
111
111
  const fastify = Fastify()
112
112
  const ajv = new AJV()
@@ -118,6 +118,7 @@ test('External AJV instance', t => {
118
118
  fastify.addSchema(schemaBRefToA)
119
119
 
120
120
  fastify.setValidatorCompiler(({ schema, method, url, httpPart }) => {
121
+ t.pass('custom validator compiler called')
121
122
  return ajv.compile(schema)
122
123
  })
123
124
 
@@ -151,7 +152,7 @@ test('External AJV instance', t => {
151
152
  })
152
153
 
153
154
  test('Encapsulation', t => {
154
- t.plan(19)
155
+ t.plan(21)
155
156
 
156
157
  const fastify = Fastify()
157
158
  const ajv = new AJV()
@@ -164,6 +165,7 @@ test('Encapsulation', t => {
164
165
 
165
166
  fastify.register((instance, opts, done) => {
166
167
  const validator = ({ schema, method, url, httpPart }) => {
168
+ t.pass('custom validator compiler called')
167
169
  return ajv.compile(schema)
168
170
  }
169
171
  instance.setValidatorCompiler(validator)
@@ -271,7 +273,7 @@ test('Encapsulation', t => {
271
273
  })
272
274
 
273
275
  test('Triple $ref with a simple $id', t => {
274
- t.plan(6)
276
+ t.plan(7)
275
277
 
276
278
  const fastify = Fastify()
277
279
  const ajv = new AJV()
@@ -285,6 +287,7 @@ test('Triple $ref with a simple $id', t => {
285
287
  fastify.addSchema(schemaCRefToB)
286
288
 
287
289
  fastify.setValidatorCompiler(({ schema, method, url, httpPart }) => {
290
+ t.pass('custom validator compiler called')
288
291
  return ajv.compile(schema)
289
292
  })
290
293
 
@@ -1024,19 +1027,125 @@ test("The same $id in route's schema must not overwrite others", t => {
1024
1027
 
1025
1028
  test('Custom validator compiler should not mutate schema', async t => {
1026
1029
  t.plan(2)
1027
- class Headers {}
1030
+ class Headers { }
1028
1031
  const fastify = Fastify()
1029
1032
 
1030
1033
  fastify.setValidatorCompiler(({ schema, method, url, httpPart }) => {
1031
1034
  t.type(schema, Headers)
1032
- return () => {}
1035
+ return () => { }
1033
1036
  })
1034
1037
 
1035
1038
  fastify.get('/', {
1036
1039
  schema: {
1037
1040
  headers: new Headers()
1038
1041
  }
1039
- }, () => {})
1042
+ }, () => { })
1043
+
1044
+ await fastify.ready()
1045
+ })
1046
+
1047
+ test('Custom validator builder override by custom validator compiler', async t => {
1048
+ t.plan(3)
1049
+ const ajvDefaults = {
1050
+ removeAdditional: true,
1051
+ coerceTypes: true,
1052
+ allErrors: true
1053
+ }
1054
+ const ajv1 = new AJV(ajvDefaults).addKeyword({ keyword: 'extended_one', type: 'object', validator: () => true })
1055
+ const ajv2 = new AJV(ajvDefaults).addKeyword({ keyword: 'extended_two', type: 'object', validator: () => true })
1056
+ const fastify = Fastify({ schemaController: { compilersFactory: { buildValidator: () => (routeSchemaDef) => ajv1.compile(routeSchemaDef.schema) } } })
1057
+
1058
+ fastify.setValidatorCompiler((routeSchemaDef) => ajv2.compile(routeSchemaDef.schema))
1059
+
1060
+ fastify.post('/two/:id', {
1061
+ schema: {
1062
+ params: {
1063
+ type: 'object',
1064
+ extended_two: true,
1065
+ properties: {
1066
+ id: { type: 'number' }
1067
+ },
1068
+ required: ['id']
1069
+ }
1070
+ },
1071
+ handler: (req, _reply) => {
1072
+ t.same(typeof req.params.id, 'number')
1073
+ t.same(req.params.id, 43)
1074
+ return 'ok'
1075
+ }
1076
+ })
1040
1077
 
1041
1078
  await fastify.ready()
1079
+
1080
+ const two = await fastify.inject({
1081
+ method: 'POST',
1082
+ url: '/two/43'
1083
+ })
1084
+ t.equal(two.statusCode, 200)
1085
+ })
1086
+
1087
+ test('Custom validator builder override by custom validator compiler in child instance', async t => {
1088
+ t.plan(6)
1089
+ const ajvDefaults = {
1090
+ removeAdditional: true,
1091
+ coerceTypes: true,
1092
+ allErrors: true
1093
+ }
1094
+ const ajv1 = new AJV(ajvDefaults).addKeyword({ keyword: 'extended_one', type: 'object', validator: () => true })
1095
+ const ajv2 = new AJV(ajvDefaults).addKeyword({ keyword: 'extended_two', type: 'object', validator: () => true })
1096
+ const fastify = Fastify({ schemaController: { compilersFactory: { buildValidator: () => (routeSchemaDef) => ajv1.compile(routeSchemaDef.schema) } } })
1097
+
1098
+ fastify.register((embedded, _opts, done) => {
1099
+ embedded.setValidatorCompiler((routeSchemaDef) => ajv2.compile(routeSchemaDef.schema))
1100
+ embedded.post('/two/:id', {
1101
+ schema: {
1102
+ params: {
1103
+ type: 'object',
1104
+ extended_two: true,
1105
+ properties: {
1106
+ id: { type: 'number' }
1107
+ },
1108
+ required: ['id']
1109
+ }
1110
+ },
1111
+ handler: (req, _reply) => {
1112
+ t.same(typeof req.params.id, 'number')
1113
+ t.same(req.params.id, 43)
1114
+ return 'ok'
1115
+ }
1116
+ })
1117
+ done()
1118
+ })
1119
+
1120
+ fastify.post('/one/:id', {
1121
+ schema: {
1122
+ params: {
1123
+ type: 'object',
1124
+ extended_one: true,
1125
+ properties: {
1126
+ id: { type: 'number' }
1127
+ },
1128
+ required: ['id']
1129
+ }
1130
+ },
1131
+ handler: (req, _reply) => {
1132
+ t.same(typeof req.params.id, 'number')
1133
+ t.same(req.params.id, 42)
1134
+ return 'ok'
1135
+ }
1136
+ })
1137
+
1138
+ await fastify.ready()
1139
+
1140
+ const one = await fastify.inject({
1141
+ method: 'POST',
1142
+ url: '/one/42'
1143
+ })
1144
+ t.equal(one.statusCode, 200)
1145
+
1146
+ const two = await fastify.inject({
1147
+ method: 'POST',
1148
+ url: '/two/43'
1149
+ })
1150
+ t.equal(two.statusCode, 200)
1042
1151
  })
@@ -0,0 +1,187 @@
1
+ 'use strict'
2
+
3
+ const t = require('tap')
4
+ const test = t.test
5
+ const { S } = require('fluent-json-schema')
6
+ const Fastify = require('../fastify')
7
+ const sjson = require('secure-json-parse')
8
+
9
+ const BadRequestSchema = S.object()
10
+ .prop('statusCode', S.number())
11
+ .prop('error', S.string())
12
+ .prop('message', S.string())
13
+
14
+ const InternalServerErrorSchema = S.object()
15
+ .prop('statusCode', S.number())
16
+ .prop('error', S.string())
17
+ .prop('message', S.string())
18
+
19
+ const NotFoundSchema = S.object()
20
+ .prop('statusCode', S.number())
21
+ .prop('error', S.string())
22
+ .prop('message', S.string())
23
+
24
+ const options = {
25
+ schema: {
26
+ body: {
27
+ type: 'object',
28
+ properties: {
29
+ id: { type: 'string' }
30
+ }
31
+ },
32
+ response: {
33
+ 200: {
34
+ type: 'object',
35
+ properties: {
36
+ id: { type: 'string' }
37
+ }
38
+ },
39
+ 400: {
40
+ description: 'Bad Request',
41
+ content: {
42
+ 'application/json': {
43
+ schema: BadRequestSchema.valueOf()
44
+ }
45
+ }
46
+ },
47
+ 404: {
48
+ description: 'Resource not found',
49
+ content: {
50
+ 'application/json': {
51
+ schema: NotFoundSchema.valueOf(),
52
+ example: {
53
+ statusCode: 404,
54
+ error: 'Not Found',
55
+ message: 'Not Found'
56
+ }
57
+ }
58
+ }
59
+ },
60
+ 500: {
61
+ description: 'Internal Server Error',
62
+ content: {
63
+ 'application/json': {
64
+ schema: InternalServerErrorSchema.valueOf(),
65
+ example: {
66
+ message: 'Internal Server Error'
67
+ }
68
+ }
69
+ }
70
+ }
71
+ }
72
+ }
73
+ }
74
+
75
+ const handler = (request, reply) => {
76
+ if (request.body.id === '400') {
77
+ return reply.status(400).send({
78
+ statusCode: 400,
79
+ error: 'Bad Request',
80
+ message: 'Custom message',
81
+ extra: 'This should not be in the response'
82
+ })
83
+ }
84
+
85
+ if (request.body.id === '404') {
86
+ return reply.status(404).send({
87
+ statusCode: 404,
88
+ error: 'Not Found',
89
+ message: 'Custom Not Found',
90
+ extra: 'This should not be in the response'
91
+ })
92
+ }
93
+
94
+ if (request.body.id === '500') {
95
+ reply.status(500).send({
96
+ statusCode: 500,
97
+ error: 'Internal Server Error',
98
+ message: 'Custom Internal Server Error',
99
+ extra: 'This should not be in the response'
100
+ })
101
+ }
102
+
103
+ reply.send({
104
+ id: request.body.id,
105
+ extra: 'This should not be in the response'
106
+ })
107
+ }
108
+
109
+ test('serialize the response for a Bad Request error, as defined on the schema', async t => {
110
+ t.plan(2)
111
+
112
+ const fastify = Fastify({})
113
+
114
+ fastify.post('/', options, handler)
115
+ const response = await fastify.inject({
116
+ method: 'POST',
117
+ url: '/'
118
+ })
119
+
120
+ t.equal(response.statusCode, 400)
121
+ t.same(sjson(response.body), {
122
+ statusCode: 400,
123
+ error: 'Bad Request',
124
+ message: 'body must be object'
125
+ })
126
+ })
127
+
128
+ test('serialize the response for a Not Found error, as defined on the schema', async t => {
129
+ t.plan(2)
130
+
131
+ const fastify = Fastify({})
132
+
133
+ fastify.post('/', options, handler)
134
+
135
+ const response = await fastify.inject({
136
+ method: 'POST',
137
+ url: '/',
138
+ body: { id: '404' }
139
+ })
140
+
141
+ t.equal(response.statusCode, 404)
142
+ t.same(sjson(response.body), {
143
+ statusCode: 404,
144
+ error: 'Not Found',
145
+ message: 'Custom Not Found'
146
+ })
147
+ })
148
+
149
+ test('serialize the response for a Internal Server Error error, as defined on the schema', async t => {
150
+ t.plan(2)
151
+
152
+ const fastify = Fastify({})
153
+
154
+ fastify.post('/', options, handler)
155
+
156
+ const response = await fastify.inject({
157
+ method: 'POST',
158
+ url: '/',
159
+ body: { id: '500' }
160
+ })
161
+
162
+ t.equal(response.statusCode, 500)
163
+ t.same(sjson(response.body), {
164
+ statusCode: 500,
165
+ error: 'Internal Server Error',
166
+ message: 'Custom Internal Server Error'
167
+ })
168
+ })
169
+
170
+ test('serialize the success response, as defined on the schema', async t => {
171
+ t.plan(2)
172
+
173
+ const fastify = Fastify({})
174
+
175
+ fastify.post('/', options, handler)
176
+
177
+ const response = await fastify.inject({
178
+ method: 'POST',
179
+ url: '/',
180
+ body: { id: 'test' }
181
+ })
182
+
183
+ t.equal(response.statusCode, 200)
184
+ t.same(sjson(response.body), {
185
+ id: 'test'
186
+ })
187
+ })
@@ -51,6 +51,18 @@ expectAssignable<FastifyInstance>(
51
51
  })
52
52
  )
53
53
 
54
+ expectAssignable<FastifyInstance>(
55
+ server.setGenReqId(function (req) {
56
+ expectType<RawRequestDefaultExpression>(req)
57
+ return 'foo'
58
+ })
59
+ )
60
+
61
+ function fastifySetGenReqId (req: RawRequestDefaultExpression) {
62
+ return 'foo'
63
+ }
64
+ server.setGenReqId(fastifySetGenReqId)
65
+
54
66
  function fastifyErrorHandler (this: FastifyInstance, error: FastifyError) {}
55
67
  server.setErrorHandler(fastifyErrorHandler)
56
68
 
@@ -330,7 +342,8 @@ type InitialConfig = Readonly<{
330
342
  pluginTimeout?: number,
331
343
  requestIdHeader?: string | false,
332
344
  requestIdLogLabel?: string,
333
- http2SessionTimeout?: number
345
+ http2SessionTimeout?: number,
346
+ useSemicolonDelimiter?: boolean
334
347
  }>
335
348
 
336
349
  expectType<InitialConfig>(fastify().initialConfig)
@@ -1,5 +1,5 @@
1
1
  import { Buffer } from 'buffer'
2
- import { expectAssignable, expectError, expectType } from 'tsd'
2
+ import { expectAssignable, expectDeprecated, expectError, expectType } from 'tsd'
3
3
  import fastify, { FastifyReplyContext, FastifyReply, FastifyRequest, FastifySchema, FastifySchemaCompiler, FastifyTypeProviderDefault, RawRequestDefaultExpression, RouteHandler, RouteHandlerMethod } from '../../fastify'
4
4
  import { FastifyInstance } from '../../types/instance'
5
5
  import { FastifyLoggerInstance } from '../../types/logger'
@@ -19,6 +19,7 @@ const getHandler: RouteHandlerMethod = function (_request, reply) {
19
19
  expectType<<Code extends number>(statusCode: Code) => DefaultFastifyReplyWithCode<Code>>(reply.code)
20
20
  expectType<<Code extends number>(statusCode: Code) => DefaultFastifyReplyWithCode<Code>>(reply.status)
21
21
  expectType<(payload?: unknown) => FastifyReply>(reply.code(100 as number).send)
22
+ expectType<number>(reply.elapsedTime)
22
23
  expectType<number>(reply.statusCode)
23
24
  expectType<boolean>(reply.sent)
24
25
  expectType<((payload?: unknown) => FastifyReply)>(reply.send)
@@ -31,7 +32,8 @@ const getHandler: RouteHandlerMethod = function (_request, reply) {
31
32
  expectType<{(statusCode: number, url: string): FastifyReply; (url: string): FastifyReply }>(reply.redirect)
32
33
  expectType<() => FastifyReply>(reply.hijack)
33
34
  expectType<() => void>(reply.callNotFound)
34
- expectType<() => number>(reply.getResponseTime)
35
+ // Test reply.getResponseTime() deprecation
36
+ expectDeprecated(reply.getResponseTime)
35
37
  expectType<(contentType: string) => FastifyReply>(reply.type)
36
38
  expectType<(fn: (payload: any) => string) => FastifyReply>(reply.serializer)
37
39
  expectType<(payload: any) => string | ArrayBuffer | Buffer>(reply.serialize)
@@ -1,4 +1,3 @@
1
- import pino from 'pino'
2
1
  import { expectAssignable, expectType } from 'tsd'
3
2
  import fastify, {
4
3
  ContextConfigDefault,
@@ -83,6 +82,7 @@ const getHandler: RouteHandler = function (request, _reply) {
83
82
  expectType<FastifySchema>(request.routeSchema)
84
83
  expectType<FastifySchema>(request.routeOptions.schema)
85
84
  expectType<RouteHandlerMethod>(request.routeOptions.handler)
85
+ expectType<string | undefined>(request.routeOptions.url)
86
86
 
87
87
  expectType<RequestHeadersDefault & RawRequestDefaultExpression['headers']>(request.headers)
88
88
  request.headers = {}
@@ -3,7 +3,8 @@ import * as http from 'http'
3
3
  import { expectAssignable, expectError, expectType } from 'tsd'
4
4
  import fastify, { FastifyInstance, FastifyReply, FastifyRequest, RouteHandlerMethod } from '../../fastify'
5
5
  import { RequestPayload } from '../../types/hooks'
6
- import { HTTPMethods } from '../../types/utils'
6
+ import { FindMyWayFindResult } from '../../types/instance'
7
+ import { HTTPMethods, RawServerDefault } from '../../types/utils'
7
8
 
8
9
  /*
9
10
  * Testing Fastify HTTP Routes and Route Shorthands.
@@ -453,6 +454,19 @@ expectType<boolean>(fastify().hasRoute({
453
454
  }
454
455
  }))
455
456
 
457
+ expectType<Omit<FindMyWayFindResult<RawServerDefault>, 'store'>>(
458
+ fastify().findRoute({
459
+ url: '/',
460
+ method: 'get'
461
+ })
462
+ )
463
+
464
+ // we should not expose store
465
+ expectError(fastify().findRoute({
466
+ url: '/',
467
+ method: 'get'
468
+ }).store)
469
+
456
470
  expectType<FastifyInstance>(fastify().route({
457
471
  url: '/',
458
472
  method: 'get',