fastify 4.9.2 → 4.10.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.
- package/README.md +7 -1
- package/docs/Guides/Ecosystem.md +4 -0
- package/docs/Guides/Plugins-Guide.md +0 -18
- package/docs/Guides/Recommendations.md +51 -0
- package/docs/Guides/Write-Type-Provider.md +32 -0
- package/docs/Reference/Decorators.md +7 -1
- package/docs/Reference/Reply.md +15 -7
- package/docs/Reference/Request.md +20 -1
- package/docs/Reference/Server.md +8 -1
- package/docs/Reference/TypeScript.md +1 -1
- package/fastify.d.ts +1 -0
- package/fastify.js +10 -5
- package/lib/contentTypeParser.js +6 -3
- package/lib/context.js +4 -0
- package/lib/errors.js +6 -0
- package/lib/hooks.js +1 -1
- package/lib/reply.js +50 -7
- package/lib/request.js +19 -0
- package/lib/route.js +9 -3
- package/lib/warnings.js +2 -0
- package/package.json +4 -4
- package/test/bodyLimit.test.js +79 -0
- package/test/close-pipelining.test.js +67 -42
- package/test/close.test.js +42 -1
- package/test/hooks-async.test.js +6 -2
- package/test/hooks.on-ready.test.js +2 -1
- package/test/hooks.test.js +20 -4
- package/test/input-validation.js +0 -1
- package/test/internals/hooks.test.js +1 -1
- package/test/reply-trailers.test.js +207 -18
- package/test/request-error.test.js +96 -0
- package/test/server.test.js +2 -3
- package/test/types/fastify.test-d.ts +8 -1
- package/test/types/logger.test-d.ts +1 -32
- package/test/types/request.test-d.ts +2 -1
- package/test/types/type-provider.test-d.ts +317 -2
- package/types/logger.d.ts +1 -1
- package/types/request.d.ts +12 -0
- package/types/type-provider.d.ts +5 -3
|
@@ -5,6 +5,8 @@ const test = t.test
|
|
|
5
5
|
const Fastify = require('..')
|
|
6
6
|
const { Readable } = require('stream')
|
|
7
7
|
const { createHash } = require('crypto')
|
|
8
|
+
const { promisify } = require('util')
|
|
9
|
+
const sleep = promisify(setTimeout)
|
|
8
10
|
|
|
9
11
|
test('send trailers when payload is empty string', t => {
|
|
10
12
|
t.plan(5)
|
|
@@ -12,8 +14,8 @@ test('send trailers when payload is empty string', t => {
|
|
|
12
14
|
const fastify = Fastify()
|
|
13
15
|
|
|
14
16
|
fastify.get('/', function (request, reply) {
|
|
15
|
-
reply.trailer('ETag', function (reply, payload) {
|
|
16
|
-
|
|
17
|
+
reply.trailer('ETag', function (reply, payload, done) {
|
|
18
|
+
done(null, 'custom-etag')
|
|
17
19
|
})
|
|
18
20
|
reply.send('')
|
|
19
21
|
})
|
|
@@ -36,8 +38,8 @@ test('send trailers when payload is empty buffer', t => {
|
|
|
36
38
|
const fastify = Fastify()
|
|
37
39
|
|
|
38
40
|
fastify.get('/', function (request, reply) {
|
|
39
|
-
reply.trailer('ETag', function (reply, payload) {
|
|
40
|
-
|
|
41
|
+
reply.trailer('ETag', function (reply, payload, done) {
|
|
42
|
+
done(null, 'custom-etag')
|
|
41
43
|
})
|
|
42
44
|
reply.send(Buffer.alloc(0))
|
|
43
45
|
})
|
|
@@ -60,8 +62,8 @@ test('send trailers when payload is undefined', t => {
|
|
|
60
62
|
const fastify = Fastify()
|
|
61
63
|
|
|
62
64
|
fastify.get('/', function (request, reply) {
|
|
63
|
-
reply.trailer('ETag', function (reply, payload) {
|
|
64
|
-
|
|
65
|
+
reply.trailer('ETag', function (reply, payload, done) {
|
|
66
|
+
done(null, 'custom-etag')
|
|
65
67
|
})
|
|
66
68
|
reply.send(undefined)
|
|
67
69
|
})
|
|
@@ -88,11 +90,11 @@ test('send trailers when payload is json', t => {
|
|
|
88
90
|
const md5 = hash.digest('hex')
|
|
89
91
|
|
|
90
92
|
fastify.get('/', function (request, reply) {
|
|
91
|
-
reply.trailer('Content-MD5', function (reply, payload) {
|
|
93
|
+
reply.trailer('Content-MD5', function (reply, payload, done) {
|
|
92
94
|
t.equal(data, payload)
|
|
93
95
|
const hash = createHash('md5')
|
|
94
96
|
hash.update(payload)
|
|
95
|
-
|
|
97
|
+
done(null, hash.digest('hex'))
|
|
96
98
|
})
|
|
97
99
|
reply.send(data)
|
|
98
100
|
})
|
|
@@ -116,9 +118,9 @@ test('send trailers when payload is stream', t => {
|
|
|
116
118
|
const fastify = Fastify()
|
|
117
119
|
|
|
118
120
|
fastify.get('/', function (request, reply) {
|
|
119
|
-
reply.trailer('ETag', function (reply, payload) {
|
|
121
|
+
reply.trailer('ETag', function (reply, payload, done) {
|
|
120
122
|
t.same(payload, null)
|
|
121
|
-
|
|
123
|
+
done(null, 'custom-etag')
|
|
122
124
|
})
|
|
123
125
|
const stream = Readable.from([JSON.stringify({ hello: 'world' })])
|
|
124
126
|
reply.send(stream)
|
|
@@ -137,6 +139,161 @@ test('send trailers when payload is stream', t => {
|
|
|
137
139
|
})
|
|
138
140
|
})
|
|
139
141
|
|
|
142
|
+
test('send trailers when using async-await', t => {
|
|
143
|
+
t.plan(5)
|
|
144
|
+
|
|
145
|
+
const fastify = Fastify()
|
|
146
|
+
|
|
147
|
+
fastify.get('/', function (request, reply) {
|
|
148
|
+
reply.trailer('ETag', async function (reply, payload) {
|
|
149
|
+
return 'custom-etag'
|
|
150
|
+
})
|
|
151
|
+
reply.send('')
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
fastify.inject({
|
|
155
|
+
method: 'GET',
|
|
156
|
+
url: '/'
|
|
157
|
+
}, (error, res) => {
|
|
158
|
+
t.error(error)
|
|
159
|
+
t.equal(res.statusCode, 200)
|
|
160
|
+
t.equal(res.headers.trailer, 'etag')
|
|
161
|
+
t.equal(res.trailers.etag, 'custom-etag')
|
|
162
|
+
t.notHas(res.headers, 'content-length')
|
|
163
|
+
})
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
test('error in trailers should be ignored', t => {
|
|
167
|
+
t.plan(5)
|
|
168
|
+
|
|
169
|
+
const fastify = Fastify()
|
|
170
|
+
|
|
171
|
+
fastify.get('/', function (request, reply) {
|
|
172
|
+
reply.trailer('ETag', function (reply, payload, done) {
|
|
173
|
+
done('error')
|
|
174
|
+
})
|
|
175
|
+
reply.send('')
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
fastify.inject({
|
|
179
|
+
method: 'GET',
|
|
180
|
+
url: '/'
|
|
181
|
+
}, (error, res) => {
|
|
182
|
+
t.error(error)
|
|
183
|
+
t.equal(res.statusCode, 200)
|
|
184
|
+
t.equal(res.headers.trailer, 'etag')
|
|
185
|
+
t.notHas(res.trailers, 'etag')
|
|
186
|
+
t.notHas(res.headers, 'content-length')
|
|
187
|
+
})
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
test('should emit deprecation warning when using direct return', t => {
|
|
191
|
+
t.plan(7)
|
|
192
|
+
|
|
193
|
+
const fastify = Fastify()
|
|
194
|
+
|
|
195
|
+
fastify.get('/', function (request, reply) {
|
|
196
|
+
reply.trailer('ETag', function (reply, payload) {
|
|
197
|
+
return 'custom-etag'
|
|
198
|
+
})
|
|
199
|
+
reply.send('')
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
process.on('warning', onWarning)
|
|
203
|
+
function onWarning (warning) {
|
|
204
|
+
t.equal(warning.name, 'FastifyDeprecation')
|
|
205
|
+
t.equal(warning.code, 'FSTDEP013')
|
|
206
|
+
}
|
|
207
|
+
t.teardown(() => process.removeListener('warning', onWarning))
|
|
208
|
+
|
|
209
|
+
fastify.inject({
|
|
210
|
+
method: 'GET',
|
|
211
|
+
url: '/'
|
|
212
|
+
}, (error, res) => {
|
|
213
|
+
t.error(error)
|
|
214
|
+
t.equal(res.statusCode, 200)
|
|
215
|
+
t.equal(res.headers.trailer, 'etag')
|
|
216
|
+
t.equal(res.trailers.etag, 'custom-etag')
|
|
217
|
+
t.notHas(res.headers, 'content-length')
|
|
218
|
+
})
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
test('trailer handler counter', t => {
|
|
222
|
+
t.plan(2)
|
|
223
|
+
|
|
224
|
+
const data = JSON.stringify({ hello: 'world' })
|
|
225
|
+
const hash = createHash('md5')
|
|
226
|
+
hash.update(data)
|
|
227
|
+
const md5 = hash.digest('hex')
|
|
228
|
+
|
|
229
|
+
t.test('callback with timeout', t => {
|
|
230
|
+
t.plan(9)
|
|
231
|
+
const fastify = Fastify()
|
|
232
|
+
|
|
233
|
+
fastify.get('/', function (request, reply) {
|
|
234
|
+
reply.trailer('Return-Early', function (reply, payload, done) {
|
|
235
|
+
t.equal(data, payload)
|
|
236
|
+
done(null, 'return')
|
|
237
|
+
})
|
|
238
|
+
reply.trailer('Content-MD5', function (reply, payload, done) {
|
|
239
|
+
t.equal(data, payload)
|
|
240
|
+
const hash = createHash('md5')
|
|
241
|
+
hash.update(payload)
|
|
242
|
+
setTimeout(() => {
|
|
243
|
+
done(null, hash.digest('hex'))
|
|
244
|
+
}, 500)
|
|
245
|
+
})
|
|
246
|
+
reply.send(data)
|
|
247
|
+
})
|
|
248
|
+
|
|
249
|
+
fastify.inject({
|
|
250
|
+
method: 'GET',
|
|
251
|
+
url: '/'
|
|
252
|
+
}, (error, res) => {
|
|
253
|
+
t.error(error)
|
|
254
|
+
t.equal(res.statusCode, 200)
|
|
255
|
+
t.equal(res.headers['transfer-encoding'], 'chunked')
|
|
256
|
+
t.equal(res.headers.trailer, 'return-early content-md5')
|
|
257
|
+
t.equal(res.trailers['return-early'], 'return')
|
|
258
|
+
t.equal(res.trailers['content-md5'], md5)
|
|
259
|
+
t.notHas(res.headers, 'content-length')
|
|
260
|
+
})
|
|
261
|
+
})
|
|
262
|
+
|
|
263
|
+
t.test('async-await', t => {
|
|
264
|
+
t.plan(9)
|
|
265
|
+
const fastify = Fastify()
|
|
266
|
+
|
|
267
|
+
fastify.get('/', function (request, reply) {
|
|
268
|
+
reply.trailer('Return-Early', async function (reply, payload) {
|
|
269
|
+
t.equal(data, payload)
|
|
270
|
+
return 'return'
|
|
271
|
+
})
|
|
272
|
+
reply.trailer('Content-MD5', async function (reply, payload) {
|
|
273
|
+
t.equal(data, payload)
|
|
274
|
+
const hash = createHash('md5')
|
|
275
|
+
hash.update(payload)
|
|
276
|
+
await sleep(500)
|
|
277
|
+
return hash.digest('hex')
|
|
278
|
+
})
|
|
279
|
+
reply.send(data)
|
|
280
|
+
})
|
|
281
|
+
|
|
282
|
+
fastify.inject({
|
|
283
|
+
method: 'GET',
|
|
284
|
+
url: '/'
|
|
285
|
+
}, (error, res) => {
|
|
286
|
+
t.error(error)
|
|
287
|
+
t.equal(res.statusCode, 200)
|
|
288
|
+
t.equal(res.headers['transfer-encoding'], 'chunked')
|
|
289
|
+
t.equal(res.headers.trailer, 'return-early content-md5')
|
|
290
|
+
t.equal(res.trailers['return-early'], 'return')
|
|
291
|
+
t.equal(res.trailers['content-md5'], md5)
|
|
292
|
+
t.notHas(res.headers, 'content-length')
|
|
293
|
+
})
|
|
294
|
+
})
|
|
295
|
+
})
|
|
296
|
+
|
|
140
297
|
test('removeTrailer', t => {
|
|
141
298
|
t.plan(6)
|
|
142
299
|
|
|
@@ -144,12 +301,12 @@ test('removeTrailer', t => {
|
|
|
144
301
|
|
|
145
302
|
fastify.get('/', function (request, reply) {
|
|
146
303
|
reply.removeTrailer('ETag') // remove nothing
|
|
147
|
-
reply.trailer('ETag', function (reply, payload) {
|
|
148
|
-
|
|
304
|
+
reply.trailer('ETag', function (reply, payload, done) {
|
|
305
|
+
done(null, 'custom-etag')
|
|
149
306
|
})
|
|
150
|
-
reply.trailer('Should-Not-Call', function (reply, payload) {
|
|
307
|
+
reply.trailer('Should-Not-Call', function (reply, payload, done) {
|
|
151
308
|
t.fail('it should not called as this trailer is removed')
|
|
152
|
-
|
|
309
|
+
done(null, 'should-not-call')
|
|
153
310
|
})
|
|
154
311
|
reply.removeTrailer('Should-Not-Call')
|
|
155
312
|
reply.send(undefined)
|
|
@@ -168,6 +325,38 @@ test('removeTrailer', t => {
|
|
|
168
325
|
})
|
|
169
326
|
})
|
|
170
327
|
|
|
328
|
+
test('remove all trailers', t => {
|
|
329
|
+
t.plan(6)
|
|
330
|
+
|
|
331
|
+
const fastify = Fastify()
|
|
332
|
+
|
|
333
|
+
fastify.get('/', function (request, reply) {
|
|
334
|
+
reply.trailer('ETag', function (reply, payload, done) {
|
|
335
|
+
t.fail('it should not called as this trailer is removed')
|
|
336
|
+
done(null, 'custom-etag')
|
|
337
|
+
})
|
|
338
|
+
reply.removeTrailer('ETag')
|
|
339
|
+
reply.trailer('Should-Not-Call', function (reply, payload, done) {
|
|
340
|
+
t.fail('it should not called as this trailer is removed')
|
|
341
|
+
done(null, 'should-not-call')
|
|
342
|
+
})
|
|
343
|
+
reply.removeTrailer('Should-Not-Call')
|
|
344
|
+
reply.send('')
|
|
345
|
+
})
|
|
346
|
+
|
|
347
|
+
fastify.inject({
|
|
348
|
+
method: 'GET',
|
|
349
|
+
url: '/'
|
|
350
|
+
}, (error, res) => {
|
|
351
|
+
t.error(error)
|
|
352
|
+
t.equal(res.statusCode, 200)
|
|
353
|
+
t.notOk(res.headers.trailer)
|
|
354
|
+
t.notOk(res.trailers.etag)
|
|
355
|
+
t.notOk(res.trailers['should-not-call'])
|
|
356
|
+
t.notHas(res.headers, 'content-length')
|
|
357
|
+
})
|
|
358
|
+
})
|
|
359
|
+
|
|
171
360
|
test('hasTrailer', t => {
|
|
172
361
|
t.plan(10)
|
|
173
362
|
|
|
@@ -175,13 +364,13 @@ test('hasTrailer', t => {
|
|
|
175
364
|
|
|
176
365
|
fastify.get('/', function (request, reply) {
|
|
177
366
|
t.equal(reply.hasTrailer('ETag'), false)
|
|
178
|
-
reply.trailer('ETag', function (reply, payload) {
|
|
179
|
-
|
|
367
|
+
reply.trailer('ETag', function (reply, payload, done) {
|
|
368
|
+
done(null, 'custom-etag')
|
|
180
369
|
})
|
|
181
370
|
t.equal(reply.hasTrailer('ETag'), true)
|
|
182
|
-
reply.trailer('Should-Not-Call', function (reply, payload) {
|
|
371
|
+
reply.trailer('Should-Not-Call', function (reply, payload, done) {
|
|
183
372
|
t.fail('it should not called as this trailer is removed')
|
|
184
|
-
|
|
373
|
+
done(null, 'should-not-call')
|
|
185
374
|
})
|
|
186
375
|
t.equal(reply.hasTrailer('Should-Not-Call'), true)
|
|
187
376
|
reply.removeTrailer('Should-Not-Call')
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { connect } = require('net')
|
|
4
|
+
const sget = require('simple-get').concat
|
|
4
5
|
const t = require('tap')
|
|
5
6
|
const test = t.test
|
|
6
7
|
const Fastify = require('..')
|
|
@@ -313,3 +314,98 @@ test('default clientError replies with bad request on reused keep-alive connecti
|
|
|
313
314
|
client.write('\r\n\r\n')
|
|
314
315
|
})
|
|
315
316
|
})
|
|
317
|
+
|
|
318
|
+
test('request.routeOptions should be immutable', t => {
|
|
319
|
+
t.plan(14)
|
|
320
|
+
const fastify = Fastify()
|
|
321
|
+
const handler = function (req, res) {
|
|
322
|
+
t.equal('POST', req.routeOptions.method)
|
|
323
|
+
t.equal('/', req.routeOptions.url)
|
|
324
|
+
t.throws(() => { req.routeOptions = null }, new TypeError('Cannot set property routeOptions of #<Request> which has only a getter'))
|
|
325
|
+
t.throws(() => { req.routeOptions.method = 'INVALID' }, new TypeError('Cannot assign to read only property \'method\' of object \'#<Object>\''))
|
|
326
|
+
t.throws(() => { req.routeOptions.url = '//' }, new TypeError('Cannot assign to read only property \'url\' of object \'#<Object>\''))
|
|
327
|
+
t.throws(() => { req.routeOptions.bodyLimit = 0xDEADBEEF }, new TypeError('Cannot assign to read only property \'bodyLimit\' of object \'#<Object>\''))
|
|
328
|
+
t.throws(() => { req.routeOptions.attachValidation = true }, new TypeError('Cannot assign to read only property \'attachValidation\' of object \'#<Object>\''))
|
|
329
|
+
t.throws(() => { req.routeOptions.logLevel = 'invalid' }, new TypeError('Cannot assign to read only property \'logLevel\' of object \'#<Object>\''))
|
|
330
|
+
t.throws(() => { req.routeOptions.version = '95.0.1' }, new TypeError('Cannot assign to read only property \'version\' of object \'#<Object>\''))
|
|
331
|
+
t.throws(() => { req.routeOptions.prefixTrailingSlash = true }, new TypeError('Cannot assign to read only property \'prefixTrailingSlash\' of object \'#<Object>\''))
|
|
332
|
+
t.throws(() => { req.routeOptions.newAttribute = {} }, new TypeError('Cannot add property newAttribute, object is not extensible'))
|
|
333
|
+
|
|
334
|
+
for (const key of Object.keys(req.routeOptions)) {
|
|
335
|
+
if (typeof req.routeOptions[key] === 'object' && req.routeOptions[key] !== null) {
|
|
336
|
+
t.fail('Object.freeze must run recursively on nested structures to ensure that routeOptions is immutable.')
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
res.send({})
|
|
341
|
+
}
|
|
342
|
+
fastify.post('/', {
|
|
343
|
+
bodyLimit: 1000,
|
|
344
|
+
handler
|
|
345
|
+
})
|
|
346
|
+
fastify.listen({ port: 0 }, function (err) {
|
|
347
|
+
t.error(err)
|
|
348
|
+
t.teardown(() => { fastify.close() })
|
|
349
|
+
|
|
350
|
+
sget({
|
|
351
|
+
method: 'POST',
|
|
352
|
+
url: 'http://localhost:' + fastify.server.address().port,
|
|
353
|
+
headers: { 'Content-Type': 'application/json' },
|
|
354
|
+
body: [],
|
|
355
|
+
json: true
|
|
356
|
+
}, (err, response, body) => {
|
|
357
|
+
t.error(err)
|
|
358
|
+
t.equal(response.statusCode, 200)
|
|
359
|
+
})
|
|
360
|
+
})
|
|
361
|
+
})
|
|
362
|
+
|
|
363
|
+
test('test request.routeOptions.version', t => {
|
|
364
|
+
t.plan(7)
|
|
365
|
+
const fastify = Fastify()
|
|
366
|
+
|
|
367
|
+
fastify.route({
|
|
368
|
+
method: 'POST',
|
|
369
|
+
url: '/version',
|
|
370
|
+
constraints: { version: '1.2.0' },
|
|
371
|
+
handler: function (request, reply) {
|
|
372
|
+
t.equal('1.2.0', request.routeOptions.version)
|
|
373
|
+
reply.send({})
|
|
374
|
+
}
|
|
375
|
+
})
|
|
376
|
+
|
|
377
|
+
fastify.route({
|
|
378
|
+
method: 'POST',
|
|
379
|
+
url: '/version-undefined',
|
|
380
|
+
handler: function (request, reply) {
|
|
381
|
+
t.equal(undefined, request.routeOptions.version)
|
|
382
|
+
reply.send({})
|
|
383
|
+
}
|
|
384
|
+
})
|
|
385
|
+
fastify.listen({ port: 0 }, function (err) {
|
|
386
|
+
t.error(err)
|
|
387
|
+
t.teardown(() => { fastify.close() })
|
|
388
|
+
|
|
389
|
+
sget({
|
|
390
|
+
method: 'POST',
|
|
391
|
+
url: 'http://localhost:' + fastify.server.address().port + '/version',
|
|
392
|
+
headers: { 'Content-Type': 'application/json', 'Accept-Version': '1.2.0' },
|
|
393
|
+
body: [],
|
|
394
|
+
json: true
|
|
395
|
+
}, (err, response, body) => {
|
|
396
|
+
t.error(err)
|
|
397
|
+
t.equal(response.statusCode, 200)
|
|
398
|
+
})
|
|
399
|
+
|
|
400
|
+
sget({
|
|
401
|
+
method: 'POST',
|
|
402
|
+
url: 'http://localhost:' + fastify.server.address().port + '/version-undefined',
|
|
403
|
+
headers: { 'Content-Type': 'application/json' },
|
|
404
|
+
body: [],
|
|
405
|
+
json: true
|
|
406
|
+
}, (err, response, body) => {
|
|
407
|
+
t.error(err)
|
|
408
|
+
t.equal(response.statusCode, 200)
|
|
409
|
+
})
|
|
410
|
+
})
|
|
411
|
+
})
|
package/test/server.test.js
CHANGED
|
@@ -36,19 +36,18 @@ test('listen should accept stringified number port', t => {
|
|
|
36
36
|
|
|
37
37
|
test('listen should reject string port', async (t) => {
|
|
38
38
|
t.plan(2)
|
|
39
|
-
|
|
40
39
|
const fastify = Fastify()
|
|
41
40
|
t.teardown(fastify.close.bind(fastify))
|
|
42
41
|
|
|
43
42
|
try {
|
|
44
43
|
await fastify.listen({ port: 'hello-world' })
|
|
45
44
|
} catch (error) {
|
|
46
|
-
t.
|
|
45
|
+
t.equal(error.code, 'ERR_SOCKET_BAD_PORT')
|
|
47
46
|
}
|
|
48
47
|
|
|
49
48
|
try {
|
|
50
49
|
await fastify.listen({ port: '1234hello' })
|
|
51
50
|
} catch (error) {
|
|
52
|
-
t.
|
|
51
|
+
t.equal(error.code, 'ERR_SOCKET_BAD_PORT')
|
|
53
52
|
}
|
|
54
53
|
})
|
|
@@ -10,7 +10,8 @@ import fastify, {
|
|
|
10
10
|
InjectOptions, FastifyBaseLogger,
|
|
11
11
|
RouteGenericInterface,
|
|
12
12
|
ValidationResult,
|
|
13
|
-
FastifyErrorCodes
|
|
13
|
+
FastifyErrorCodes,
|
|
14
|
+
FastifyError
|
|
14
15
|
} from '../../fastify'
|
|
15
16
|
import { ErrorObject as AjvErrorObject } from 'ajv'
|
|
16
17
|
import * as http from 'http'
|
|
@@ -235,6 +236,12 @@ const ajvErrorObject: AjvErrorObject = {
|
|
|
235
236
|
}
|
|
236
237
|
expectAssignable<ValidationResult>(ajvErrorObject)
|
|
237
238
|
|
|
239
|
+
expectAssignable<FastifyError['validation']>([ajvErrorObject])
|
|
240
|
+
expectAssignable<FastifyError['validationContext']>('body')
|
|
241
|
+
expectAssignable<FastifyError['validationContext']>('headers')
|
|
242
|
+
expectAssignable<FastifyError['validationContext']>('parameters')
|
|
243
|
+
expectAssignable<FastifyError['validationContext']>('querystring')
|
|
244
|
+
|
|
238
245
|
const routeGeneric: RouteGenericInterface = {}
|
|
239
246
|
expectType<unknown>(routeGeneric.Body)
|
|
240
247
|
expectType<unknown>(routeGeneric.Headers)
|
|
@@ -123,35 +123,6 @@ const serverAutoInferredFileOption = fastify({
|
|
|
123
123
|
|
|
124
124
|
expectType<FastifyBaseLogger>(serverAutoInferredFileOption.log)
|
|
125
125
|
|
|
126
|
-
const serverAutoInferredPinoPrettyBooleanOption = fastify({
|
|
127
|
-
logger: {
|
|
128
|
-
prettyPrint: true
|
|
129
|
-
}
|
|
130
|
-
})
|
|
131
|
-
|
|
132
|
-
expectType<FastifyBaseLogger>(serverAutoInferredPinoPrettyBooleanOption.log)
|
|
133
|
-
|
|
134
|
-
const serverAutoInferredPinoPrettyObjectOption = fastify({
|
|
135
|
-
logger: {
|
|
136
|
-
prettyPrint: {
|
|
137
|
-
translateTime: true,
|
|
138
|
-
levelFirst: false,
|
|
139
|
-
messageKey: 'msg',
|
|
140
|
-
timestampKey: 'time',
|
|
141
|
-
messageFormat: false,
|
|
142
|
-
colorize: true,
|
|
143
|
-
crlf: false,
|
|
144
|
-
errorLikeObjectKeys: ['err', 'error'],
|
|
145
|
-
errorProps: '',
|
|
146
|
-
search: 'foo == `bar`',
|
|
147
|
-
ignore: 'pid,hostname',
|
|
148
|
-
suppressFlushSyncWarning: true
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
})
|
|
152
|
-
|
|
153
|
-
expectType<FastifyBaseLogger>(serverAutoInferredPinoPrettyObjectOption.log)
|
|
154
|
-
|
|
155
126
|
const serverAutoInferredSerializerObjectOption = fastify({
|
|
156
127
|
logger: {
|
|
157
128
|
serializers: {
|
|
@@ -200,9 +171,6 @@ const passPinoOption = fastify({
|
|
|
200
171
|
redact: ['custom'],
|
|
201
172
|
messageKey: 'msg',
|
|
202
173
|
nestedKey: 'nested',
|
|
203
|
-
prettyPrint: {
|
|
204
|
-
|
|
205
|
-
},
|
|
206
174
|
enabled: true
|
|
207
175
|
}
|
|
208
176
|
})
|
|
@@ -215,6 +183,7 @@ expectDeprecated({} as FastifyLoggerInstance)
|
|
|
215
183
|
const childParent = fastify().log
|
|
216
184
|
// we test different option variant here
|
|
217
185
|
expectType<FastifyLoggerInstance>(childParent.child({}, { level: 'info' }))
|
|
186
|
+
expectType<FastifyLoggerInstance>(childParent.child({}, { level: 'silent' }))
|
|
218
187
|
expectType<FastifyLoggerInstance>(childParent.child({}, { redact: ['pass', 'pin'] }))
|
|
219
188
|
expectType<FastifyLoggerInstance>(childParent.child({}, { serializers: { key: () => {} } }))
|
|
220
189
|
expectType<FastifyLoggerInstance>(childParent.child({}, { level: 'info', redact: ['pass', 'pin'], serializers: { key: () => {} } }))
|
|
@@ -17,7 +17,7 @@ import fastify, {
|
|
|
17
17
|
} from '../../fastify'
|
|
18
18
|
import { RequestParamsDefault, RequestHeadersDefault, RequestQuerystringDefault } from '../../types/utils'
|
|
19
19
|
import { FastifyLoggerInstance } from '../../types/logger'
|
|
20
|
-
import { FastifyRequest } from '../../types/request'
|
|
20
|
+
import { FastifyRequest, RequestRouteOptions } from '../../types/request'
|
|
21
21
|
import { FastifyReply } from '../../types/reply'
|
|
22
22
|
import { FastifyInstance } from '../../types/instance'
|
|
23
23
|
import { RouteGenericInterface } from '../../types/route'
|
|
@@ -66,6 +66,7 @@ const getHandler: RouteHandler = function (request, _reply) {
|
|
|
66
66
|
expectType<string>(request.method)
|
|
67
67
|
expectType<string>(request.routerPath)
|
|
68
68
|
expectType<string>(request.routerMethod)
|
|
69
|
+
expectType<Readonly<RequestRouteOptions>>(request.routeOptions)
|
|
69
70
|
expectType<boolean>(request.is404)
|
|
70
71
|
expectType<string>(request.hostname)
|
|
71
72
|
expectType<string>(request.ip)
|