fastify 4.23.2 → 4.24.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.
- package/README.md +1 -1
- package/docs/Guides/Ecosystem.md +6 -0
- package/docs/Reference/Hooks.md +1 -0
- package/docs/Reference/Plugins.md +1 -1
- package/docs/Reference/Reply.md +4 -3
- package/docs/Reference/Request.md +3 -2
- package/docs/Reference/Server.md +31 -3
- package/docs/Reference/Type-Providers.md +2 -2
- package/docs/Reference/TypeScript.md +21 -7
- package/fastify.d.ts +2 -2
- package/fastify.js +8 -1
- package/lib/contentTypeParser.js +1 -1
- package/lib/reply.js +20 -3
- package/lib/reqIdGenFactory.js +15 -9
- package/lib/request.js +1 -1
- package/lib/route.js +18 -3
- package/lib/schemas.js +3 -3
- package/lib/warnings.js +3 -1
- package/package.json +2 -2
- package/test/async-dispose.test.js +21 -0
- package/test/constrained-routes.test.js +127 -3
- package/test/hooks-async.test.js +160 -10
- package/test/input-validation.js +3 -3
- package/test/internals/reply.test.js +33 -4
- package/test/logger/instantiation.test.js +338 -0
- package/test/logger/logger-test-utils.js +47 -0
- package/test/logger/logging.test.js +406 -0
- package/test/logger/options.test.js +500 -0
- package/test/logger/request.test.js +292 -0
- package/test/logger/response.test.js +184 -0
- package/test/reply-code.test.js +64 -0
- package/test/types/reply.test-d.ts +3 -3
- package/test/types/request.test-d.ts +9 -9
- package/test/types/type-provider.test-d.ts +89 -0
- package/test/types/using.test-d.ts +14 -0
- package/types/context.d.ts +9 -2
- package/types/instance.d.ts +4 -1
- package/types/plugin.d.ts +2 -1
- package/types/reply.d.ts +2 -2
- package/types/request.d.ts +3 -3
- package/types/route.d.ts +5 -5
- package/test/serial/logger.0.test.js +0 -866
- package/test/serial/logger.1.test.js +0 -862
- /package/test/{serial → logger}/tap-parallel-not-ok +0 -0
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const stream = require('node:stream')
|
|
4
|
+
|
|
5
|
+
const t = require('tap')
|
|
6
|
+
const split = require('split2')
|
|
7
|
+
|
|
8
|
+
const Fastify = require('../../fastify')
|
|
9
|
+
const helper = require('../helper')
|
|
10
|
+
const { on } = stream
|
|
11
|
+
const { request } = require('./logger-test-utils')
|
|
12
|
+
|
|
13
|
+
t.test('request', (t) => {
|
|
14
|
+
t.setTimeout(60000)
|
|
15
|
+
|
|
16
|
+
let localhost
|
|
17
|
+
|
|
18
|
+
t.plan(7)
|
|
19
|
+
t.before(async function () {
|
|
20
|
+
[localhost] = await helper.getLoopbackHost()
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
t.test('The request id header key can be customized', async (t) => {
|
|
24
|
+
const lines = ['incoming request', 'some log message', 'request completed']
|
|
25
|
+
t.plan(lines.length * 2 + 2)
|
|
26
|
+
const REQUEST_ID = '42'
|
|
27
|
+
|
|
28
|
+
const stream = split(JSON.parse)
|
|
29
|
+
const fastify = Fastify({
|
|
30
|
+
logger: { stream, level: 'info' },
|
|
31
|
+
requestIdHeader: 'my-custom-request-id'
|
|
32
|
+
})
|
|
33
|
+
t.teardown(fastify.close.bind(fastify))
|
|
34
|
+
|
|
35
|
+
fastify.get('/', (req, reply) => {
|
|
36
|
+
t.equal(req.id, REQUEST_ID)
|
|
37
|
+
req.log.info('some log message')
|
|
38
|
+
reply.send({ id: req.id })
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
const response = await fastify.inject({ method: 'GET', url: '/', headers: { 'my-custom-request-id': REQUEST_ID } })
|
|
42
|
+
const body = await response.json()
|
|
43
|
+
t.equal(body.id, REQUEST_ID)
|
|
44
|
+
|
|
45
|
+
for await (const [line] of on(stream, 'data')) {
|
|
46
|
+
t.equal(line.reqId, REQUEST_ID)
|
|
47
|
+
t.equal(line.msg, lines.shift(), 'message is set')
|
|
48
|
+
if (lines.length === 0) break
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
t.test('The request id header key can be ignored', async (t) => {
|
|
53
|
+
const lines = ['incoming request', 'some log message', 'request completed']
|
|
54
|
+
t.plan(lines.length * 2 + 2)
|
|
55
|
+
const REQUEST_ID = 'ignore-me'
|
|
56
|
+
|
|
57
|
+
const stream = split(JSON.parse)
|
|
58
|
+
const fastify = Fastify({
|
|
59
|
+
logger: { stream, level: 'info' },
|
|
60
|
+
requestIdHeader: false
|
|
61
|
+
})
|
|
62
|
+
t.teardown(fastify.close.bind(fastify))
|
|
63
|
+
|
|
64
|
+
fastify.get('/', (req, reply) => {
|
|
65
|
+
t.equal(req.id, 'req-1')
|
|
66
|
+
req.log.info('some log message')
|
|
67
|
+
reply.send({ id: req.id })
|
|
68
|
+
})
|
|
69
|
+
const response = await fastify.inject({ method: 'GET', url: '/', headers: { 'request-id': REQUEST_ID } })
|
|
70
|
+
const body = await response.json()
|
|
71
|
+
t.equal(body.id, 'req-1')
|
|
72
|
+
|
|
73
|
+
for await (const [line] of on(stream, 'data')) {
|
|
74
|
+
t.equal(line.reqId, 'req-1')
|
|
75
|
+
t.equal(line.msg, lines.shift(), 'message is set')
|
|
76
|
+
if (lines.length === 0) break
|
|
77
|
+
}
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
t.test('The request id header key can be customized along with a custom id generator', async (t) => {
|
|
81
|
+
const REQUEST_ID = '42'
|
|
82
|
+
const matches = [
|
|
83
|
+
{ reqId: REQUEST_ID, msg: /incoming request/ },
|
|
84
|
+
{ reqId: REQUEST_ID, msg: /some log message/ },
|
|
85
|
+
{ reqId: REQUEST_ID, msg: /request completed/ },
|
|
86
|
+
{ reqId: 'foo', msg: /incoming request/ },
|
|
87
|
+
{ reqId: 'foo', msg: /some log message 2/ },
|
|
88
|
+
{ reqId: 'foo', msg: /request completed/ }
|
|
89
|
+
]
|
|
90
|
+
t.plan(matches.length + 4)
|
|
91
|
+
|
|
92
|
+
const stream = split(JSON.parse)
|
|
93
|
+
const fastify = Fastify({
|
|
94
|
+
logger: { stream, level: 'info' },
|
|
95
|
+
requestIdHeader: 'my-custom-request-id',
|
|
96
|
+
genReqId (req) {
|
|
97
|
+
return 'foo'
|
|
98
|
+
}
|
|
99
|
+
})
|
|
100
|
+
t.teardown(fastify.close.bind(fastify))
|
|
101
|
+
|
|
102
|
+
fastify.get('/one', (req, reply) => {
|
|
103
|
+
t.equal(req.id, REQUEST_ID)
|
|
104
|
+
req.log.info('some log message')
|
|
105
|
+
reply.send({ id: req.id })
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
fastify.get('/two', (req, reply) => {
|
|
109
|
+
t.equal(req.id, 'foo')
|
|
110
|
+
req.log.info('some log message 2')
|
|
111
|
+
reply.send({ id: req.id })
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
{
|
|
115
|
+
const response = await fastify.inject({ method: 'GET', url: '/one', headers: { 'my-custom-request-id': REQUEST_ID } })
|
|
116
|
+
const body = await response.json()
|
|
117
|
+
t.equal(body.id, REQUEST_ID)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
{
|
|
121
|
+
const response = await fastify.inject({ method: 'GET', url: '/two' })
|
|
122
|
+
const body = await response.json()
|
|
123
|
+
t.equal(body.id, 'foo')
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
for await (const [line] of on(stream, 'data')) {
|
|
127
|
+
t.match(line, matches.shift())
|
|
128
|
+
if (matches.length === 0) break
|
|
129
|
+
}
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
t.test('The request id header key can be ignored along with a custom id generator', async (t) => {
|
|
133
|
+
const REQUEST_ID = 'ignore-me'
|
|
134
|
+
const matches = [
|
|
135
|
+
{ reqId: 'foo', msg: /incoming request/ },
|
|
136
|
+
{ reqId: 'foo', msg: /some log message/ },
|
|
137
|
+
{ reqId: 'foo', msg: /request completed/ },
|
|
138
|
+
{ reqId: 'foo', msg: /incoming request/ },
|
|
139
|
+
{ reqId: 'foo', msg: /some log message 2/ },
|
|
140
|
+
{ reqId: 'foo', msg: /request completed/ }
|
|
141
|
+
]
|
|
142
|
+
t.plan(matches.length + 4)
|
|
143
|
+
|
|
144
|
+
const stream = split(JSON.parse)
|
|
145
|
+
const fastify = Fastify({
|
|
146
|
+
logger: { stream, level: 'info' },
|
|
147
|
+
requestIdHeader: false,
|
|
148
|
+
genReqId (req) {
|
|
149
|
+
return 'foo'
|
|
150
|
+
}
|
|
151
|
+
})
|
|
152
|
+
t.teardown(fastify.close.bind(fastify))
|
|
153
|
+
|
|
154
|
+
fastify.get('/one', (req, reply) => {
|
|
155
|
+
t.equal(req.id, 'foo')
|
|
156
|
+
req.log.info('some log message')
|
|
157
|
+
reply.send({ id: req.id })
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
fastify.get('/two', (req, reply) => {
|
|
161
|
+
t.equal(req.id, 'foo')
|
|
162
|
+
req.log.info('some log message 2')
|
|
163
|
+
reply.send({ id: req.id })
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
{
|
|
167
|
+
const response = await fastify.inject({ method: 'GET', url: '/one', headers: { 'request-id': REQUEST_ID } })
|
|
168
|
+
const body = await response.json()
|
|
169
|
+
t.equal(body.id, 'foo')
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
{
|
|
173
|
+
const response = await fastify.inject({ method: 'GET', url: '/two' })
|
|
174
|
+
const body = await response.json()
|
|
175
|
+
t.equal(body.id, 'foo')
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
for await (const [line] of on(stream, 'data')) {
|
|
179
|
+
t.match(line, matches.shift())
|
|
180
|
+
if (matches.length === 0) break
|
|
181
|
+
}
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
t.test('The request id log label can be changed', async (t) => {
|
|
185
|
+
const REQUEST_ID = '42'
|
|
186
|
+
const matches = [
|
|
187
|
+
{ traceId: REQUEST_ID, msg: /incoming request/ },
|
|
188
|
+
{ traceId: REQUEST_ID, msg: /some log message/ },
|
|
189
|
+
{ traceId: REQUEST_ID, msg: /request completed/ }
|
|
190
|
+
]
|
|
191
|
+
t.plan(matches.length + 2)
|
|
192
|
+
|
|
193
|
+
const stream = split(JSON.parse)
|
|
194
|
+
const fastify = Fastify({
|
|
195
|
+
logger: { stream, level: 'info' },
|
|
196
|
+
requestIdHeader: 'my-custom-request-id',
|
|
197
|
+
requestIdLogLabel: 'traceId'
|
|
198
|
+
})
|
|
199
|
+
t.teardown(fastify.close.bind(fastify))
|
|
200
|
+
|
|
201
|
+
fastify.get('/one', (req, reply) => {
|
|
202
|
+
t.equal(req.id, REQUEST_ID)
|
|
203
|
+
req.log.info('some log message')
|
|
204
|
+
reply.send({ id: req.id })
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
{
|
|
208
|
+
const response = await fastify.inject({ method: 'GET', url: '/one', headers: { 'my-custom-request-id': REQUEST_ID } })
|
|
209
|
+
const body = await response.json()
|
|
210
|
+
t.equal(body.id, REQUEST_ID)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
for await (const [line] of on(stream, 'data')) {
|
|
214
|
+
t.match(line, matches.shift())
|
|
215
|
+
if (matches.length === 0) break
|
|
216
|
+
}
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
t.test('should redact the authorization header if so specified', async (t) => {
|
|
220
|
+
const lines = [
|
|
221
|
+
{ msg: /Server listening at/ },
|
|
222
|
+
{ req: { headers: { authorization: '[Redacted]' } }, msg: 'incoming request' },
|
|
223
|
+
{ res: { statusCode: 200 }, msg: 'request completed' }
|
|
224
|
+
]
|
|
225
|
+
t.plan(lines.length + 3)
|
|
226
|
+
const stream = split(JSON.parse)
|
|
227
|
+
const fastify = Fastify({
|
|
228
|
+
logger: {
|
|
229
|
+
stream,
|
|
230
|
+
redact: ['req.headers.authorization'],
|
|
231
|
+
level: 'info',
|
|
232
|
+
serializers: {
|
|
233
|
+
req (req) {
|
|
234
|
+
return {
|
|
235
|
+
method: req.method,
|
|
236
|
+
url: req.url,
|
|
237
|
+
headers: req.headers,
|
|
238
|
+
hostname: req.hostname,
|
|
239
|
+
remoteAddress: req.ip,
|
|
240
|
+
remotePort: req.socket.remotePort
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
})
|
|
246
|
+
t.teardown(fastify.close.bind(fastify))
|
|
247
|
+
|
|
248
|
+
fastify.get('/', function (req, reply) {
|
|
249
|
+
t.same(req.headers.authorization, 'Bearer abcde')
|
|
250
|
+
reply.send({ hello: 'world' })
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
await fastify.ready()
|
|
254
|
+
await fastify.listen({ port: 0, host: localhost })
|
|
255
|
+
|
|
256
|
+
await request({
|
|
257
|
+
method: 'GET',
|
|
258
|
+
path: '/',
|
|
259
|
+
host: localhost,
|
|
260
|
+
port: fastify.server.address().port,
|
|
261
|
+
headers: {
|
|
262
|
+
authorization: 'Bearer abcde'
|
|
263
|
+
}
|
|
264
|
+
}, function (response, body) {
|
|
265
|
+
t.equal(response.statusCode, 200)
|
|
266
|
+
t.same(body, JSON.stringify({ hello: 'world' }))
|
|
267
|
+
})
|
|
268
|
+
|
|
269
|
+
for await (const [line] of on(stream, 'data')) {
|
|
270
|
+
t.match(line, lines.shift())
|
|
271
|
+
if (lines.length === 0) break
|
|
272
|
+
}
|
|
273
|
+
})
|
|
274
|
+
|
|
275
|
+
t.test('should not throw error when serializing custom req', (t) => {
|
|
276
|
+
t.plan(1)
|
|
277
|
+
|
|
278
|
+
const lines = []
|
|
279
|
+
const dest = new stream.Writable({
|
|
280
|
+
write: function (chunk, enc, cb) {
|
|
281
|
+
lines.push(JSON.parse(chunk))
|
|
282
|
+
cb()
|
|
283
|
+
}
|
|
284
|
+
})
|
|
285
|
+
const fastify = Fastify({ logger: { level: 'info', stream: dest } })
|
|
286
|
+
t.teardown(fastify.close.bind(fastify))
|
|
287
|
+
|
|
288
|
+
fastify.log.info({ req: {} })
|
|
289
|
+
|
|
290
|
+
t.same(lines[0].req, {})
|
|
291
|
+
})
|
|
292
|
+
})
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const stream = require('node:stream')
|
|
4
|
+
|
|
5
|
+
const t = require('tap')
|
|
6
|
+
const split = require('split2')
|
|
7
|
+
const pino = require('pino')
|
|
8
|
+
|
|
9
|
+
const Fastify = require('../../fastify')
|
|
10
|
+
const { on } = stream
|
|
11
|
+
|
|
12
|
+
t.test('response serialization', (t) => {
|
|
13
|
+
t.setTimeout(60000)
|
|
14
|
+
|
|
15
|
+
t.plan(4)
|
|
16
|
+
|
|
17
|
+
t.test('Should use serializers from plugin and route', async (t) => {
|
|
18
|
+
const lines = [
|
|
19
|
+
{ msg: 'incoming request' },
|
|
20
|
+
{ test: 'XHello', test2: 'ZHello' },
|
|
21
|
+
{ msg: 'request completed' }
|
|
22
|
+
]
|
|
23
|
+
t.plan(lines.length + 1)
|
|
24
|
+
|
|
25
|
+
const stream = split(JSON.parse)
|
|
26
|
+
|
|
27
|
+
const logger = pino({ level: 'info' }, stream)
|
|
28
|
+
const fastify = Fastify({
|
|
29
|
+
logger
|
|
30
|
+
})
|
|
31
|
+
t.teardown(fastify.close.bind(fastify))
|
|
32
|
+
|
|
33
|
+
fastify.register(context1, {
|
|
34
|
+
logSerializers: { test: value => 'X' + value }
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
function context1 (instance, opts, done) {
|
|
38
|
+
instance.get('/', {
|
|
39
|
+
logSerializers: {
|
|
40
|
+
test2: value => 'Z' + value
|
|
41
|
+
}
|
|
42
|
+
}, (req, reply) => {
|
|
43
|
+
req.log.info({ test: 'Hello', test2: 'Hello' }) // { test: 'XHello', test2: 'ZHello' }
|
|
44
|
+
reply.send({ hello: 'world' })
|
|
45
|
+
})
|
|
46
|
+
done()
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
await fastify.ready()
|
|
50
|
+
|
|
51
|
+
{
|
|
52
|
+
const response = await fastify.inject({ method: 'GET', url: '/' })
|
|
53
|
+
const body = await response.json()
|
|
54
|
+
t.same(body, { hello: 'world' })
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
for await (const [line] of on(stream, 'data')) {
|
|
58
|
+
t.match(line, lines.shift())
|
|
59
|
+
if (lines.length === 0) break
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
t.test('Should use serializers from instance fastify and route', async (t) => {
|
|
64
|
+
const lines = [
|
|
65
|
+
{ msg: 'incoming request' },
|
|
66
|
+
{ test: 'XHello', test2: 'ZHello' },
|
|
67
|
+
{ msg: 'request completed' }
|
|
68
|
+
]
|
|
69
|
+
t.plan(lines.length + 1)
|
|
70
|
+
|
|
71
|
+
const stream = split(JSON.parse)
|
|
72
|
+
|
|
73
|
+
const logger = pino({
|
|
74
|
+
level: 'info',
|
|
75
|
+
serializers: {
|
|
76
|
+
test: value => 'X' + value,
|
|
77
|
+
test2: value => 'This should be override - ' + value
|
|
78
|
+
}
|
|
79
|
+
}, stream)
|
|
80
|
+
const fastify = Fastify({
|
|
81
|
+
logger
|
|
82
|
+
})
|
|
83
|
+
t.teardown(fastify.close.bind(fastify))
|
|
84
|
+
|
|
85
|
+
fastify.get('/', {
|
|
86
|
+
logSerializers: {
|
|
87
|
+
test2: value => 'Z' + value
|
|
88
|
+
}
|
|
89
|
+
}, (req, reply) => {
|
|
90
|
+
req.log.info({ test: 'Hello', test2: 'Hello' }) // { test: 'XHello', test2: 'ZHello' }
|
|
91
|
+
reply.send({ hello: 'world' })
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
await fastify.ready()
|
|
95
|
+
|
|
96
|
+
{
|
|
97
|
+
const response = await fastify.inject({ method: 'GET', url: '/' })
|
|
98
|
+
const body = await response.json()
|
|
99
|
+
t.same(body, { hello: 'world' })
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
for await (const [line] of on(stream, 'data')) {
|
|
103
|
+
t.match(line, lines.shift())
|
|
104
|
+
if (lines.length === 0) break
|
|
105
|
+
}
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
t.test('Should use serializers inherit from contexts', async (t) => {
|
|
109
|
+
const lines = [
|
|
110
|
+
{ msg: 'incoming request' },
|
|
111
|
+
{ test: 'XHello', test2: 'YHello', test3: 'ZHello' },
|
|
112
|
+
{ msg: 'request completed' }
|
|
113
|
+
]
|
|
114
|
+
t.plan(lines.length + 1)
|
|
115
|
+
|
|
116
|
+
const stream = split(JSON.parse)
|
|
117
|
+
|
|
118
|
+
const logger = pino({
|
|
119
|
+
level: 'info',
|
|
120
|
+
serializers: {
|
|
121
|
+
test: value => 'X' + value
|
|
122
|
+
}
|
|
123
|
+
}, stream)
|
|
124
|
+
|
|
125
|
+
const fastify = Fastify({ logger })
|
|
126
|
+
t.teardown(fastify.close.bind(fastify))
|
|
127
|
+
|
|
128
|
+
fastify.register(context1, { logSerializers: { test2: value => 'Y' + value } })
|
|
129
|
+
|
|
130
|
+
function context1 (instance, opts, done) {
|
|
131
|
+
instance.get('/', {
|
|
132
|
+
logSerializers: {
|
|
133
|
+
test3: value => 'Z' + value
|
|
134
|
+
}
|
|
135
|
+
}, (req, reply) => {
|
|
136
|
+
req.log.info({ test: 'Hello', test2: 'Hello', test3: 'Hello' }) // { test: 'XHello', test2: 'YHello', test3: 'ZHello' }
|
|
137
|
+
reply.send({ hello: 'world' })
|
|
138
|
+
})
|
|
139
|
+
done()
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
await fastify.ready()
|
|
143
|
+
|
|
144
|
+
{
|
|
145
|
+
const response = await fastify.inject({ method: 'GET', url: '/' })
|
|
146
|
+
const body = await response.json()
|
|
147
|
+
t.same(body, { hello: 'world' })
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
for await (const [line] of on(stream, 'data')) {
|
|
151
|
+
t.match(line, lines.shift())
|
|
152
|
+
if (lines.length === 0) break
|
|
153
|
+
}
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
t.test('should serialize request and response', async (t) => {
|
|
157
|
+
const lines = [
|
|
158
|
+
{ req: { method: 'GET', url: '/500' }, msg: 'incoming request' },
|
|
159
|
+
{ req: { method: 'GET', url: '/500' }, msg: '500 error' },
|
|
160
|
+
{ msg: 'request completed' }
|
|
161
|
+
]
|
|
162
|
+
t.plan(lines.length + 1)
|
|
163
|
+
|
|
164
|
+
const stream = split(JSON.parse)
|
|
165
|
+
const fastify = Fastify({ logger: { level: 'info', stream } })
|
|
166
|
+
t.teardown(fastify.close.bind(fastify))
|
|
167
|
+
|
|
168
|
+
fastify.get('/500', (req, reply) => {
|
|
169
|
+
reply.code(500).send(Error('500 error'))
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
await fastify.ready()
|
|
173
|
+
|
|
174
|
+
{
|
|
175
|
+
const response = await fastify.inject({ method: 'GET', url: '/500' })
|
|
176
|
+
t.equal(response.statusCode, 500)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
for await (const [line] of on(stream, 'data')) {
|
|
180
|
+
t.match(line, lines.shift())
|
|
181
|
+
if (lines.length === 0) break
|
|
182
|
+
}
|
|
183
|
+
})
|
|
184
|
+
})
|
package/test/reply-code.test.js
CHANGED
|
@@ -57,3 +57,67 @@ test('code should handle null/undefined/float', t => {
|
|
|
57
57
|
t.equal(res.statusCode, 404)
|
|
58
58
|
})
|
|
59
59
|
})
|
|
60
|
+
|
|
61
|
+
test('code should handle 204', t => {
|
|
62
|
+
t.plan(8)
|
|
63
|
+
|
|
64
|
+
const fastify = Fastify()
|
|
65
|
+
|
|
66
|
+
fastify.get('/204', function (request, reply) {
|
|
67
|
+
reply.status(204)
|
|
68
|
+
return null
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
fastify.get('/undefined/204', function (request, reply) {
|
|
72
|
+
reply.status(204).send({ message: 'hello' })
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
fastify.inject({
|
|
76
|
+
method: 'GET',
|
|
77
|
+
url: '/204'
|
|
78
|
+
}, (error, res) => {
|
|
79
|
+
t.error(error)
|
|
80
|
+
t.equal(res.statusCode, 204)
|
|
81
|
+
t.equal(res.payload, '')
|
|
82
|
+
t.equal(res.headers['content-length'], undefined)
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
fastify.inject({
|
|
86
|
+
method: 'GET',
|
|
87
|
+
url: '/undefined/204'
|
|
88
|
+
}, (error, res) => {
|
|
89
|
+
t.error(error)
|
|
90
|
+
t.equal(res.statusCode, 204)
|
|
91
|
+
t.equal(res.payload, '')
|
|
92
|
+
t.equal(res.headers['content-length'], undefined)
|
|
93
|
+
})
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
test('code should handle onSend hook on 204', t => {
|
|
97
|
+
t.plan(5)
|
|
98
|
+
|
|
99
|
+
const fastify = Fastify()
|
|
100
|
+
fastify.addHook('onSend', async function (request, reply, payload) {
|
|
101
|
+
return {
|
|
102
|
+
...payload,
|
|
103
|
+
world: 'hello'
|
|
104
|
+
}
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
fastify.get('/204', function (request, reply) {
|
|
108
|
+
reply.status(204).send({
|
|
109
|
+
hello: 'world'
|
|
110
|
+
})
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
fastify.inject({
|
|
114
|
+
method: 'GET',
|
|
115
|
+
url: '/204'
|
|
116
|
+
}, (error, res) => {
|
|
117
|
+
t.error(error)
|
|
118
|
+
t.equal(res.statusCode, 204)
|
|
119
|
+
t.equal(res.payload, '')
|
|
120
|
+
t.equal(res.headers['content-length'], undefined)
|
|
121
|
+
t.equal(res.headers['content-type'], undefined)
|
|
122
|
+
})
|
|
123
|
+
})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Buffer } from 'buffer'
|
|
2
2
|
import { expectAssignable, expectError, expectType } from 'tsd'
|
|
3
|
-
import fastify, {
|
|
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'
|
|
6
6
|
import { ResolveReplyTypeWithRouteGeneric } from '../../types/reply'
|
|
@@ -12,8 +12,8 @@ type DefaultFastifyReplyWithCode<Code extends number> = FastifyReply<RawServerDe
|
|
|
12
12
|
|
|
13
13
|
const getHandler: RouteHandlerMethod = function (_request, reply) {
|
|
14
14
|
expectType<RawReplyDefaultExpression>(reply.raw)
|
|
15
|
-
expectType<
|
|
16
|
-
expectType<
|
|
15
|
+
expectType<FastifyReplyContext<ContextConfigDefault>>(reply.context)
|
|
16
|
+
expectType<FastifyReplyContext<ContextConfigDefault>['config']>(reply.context.config)
|
|
17
17
|
expectType<FastifyLoggerInstance>(reply.log)
|
|
18
18
|
expectType<FastifyRequest<RouteGenericInterface, RawServerDefault, RawRequestDefaultExpression>>(reply.request)
|
|
19
19
|
expectType<<Code extends number>(statusCode: Code) => DefaultFastifyReplyWithCode<Code>>(reply.code)
|
|
@@ -2,7 +2,7 @@ import pino from 'pino'
|
|
|
2
2
|
import { expectAssignable, expectType } from 'tsd'
|
|
3
3
|
import fastify, {
|
|
4
4
|
ContextConfigDefault,
|
|
5
|
-
|
|
5
|
+
FastifyRequestContext,
|
|
6
6
|
FastifyContextConfig,
|
|
7
7
|
FastifyLogFn,
|
|
8
8
|
FastifySchema,
|
|
@@ -75,10 +75,10 @@ const getHandler: RouteHandler = function (request, _reply) {
|
|
|
75
75
|
expectType<RawRequestDefaultExpression>(request.raw)
|
|
76
76
|
expectType<RequestBodyDefault>(request.body)
|
|
77
77
|
expectType<RequestParamsDefault>(request.params)
|
|
78
|
-
expectType<
|
|
79
|
-
expectType<
|
|
80
|
-
expectType<
|
|
81
|
-
expectType<
|
|
78
|
+
expectType<FastifyRequestContext<ContextConfigDefault>>(request.context)
|
|
79
|
+
expectType<FastifyRequestContext<ContextConfigDefault>['config']>(request.context.config)
|
|
80
|
+
expectType<FastifyRequestContext<ContextConfigDefault>['config']>(request.routeConfig)
|
|
81
|
+
expectType<FastifyRequestContext<ContextConfigDefault>['config']>(request.routeOptions.config)
|
|
82
82
|
expectType<ContextConfigDefault & FastifyRouteConfig & FastifyContextConfig>(request.routeOptions.config)
|
|
83
83
|
expectType<FastifySchema>(request.routeSchema)
|
|
84
84
|
expectType<FastifySchema>(request.routeOptions.schema)
|
|
@@ -112,8 +112,8 @@ const postHandler: Handler = function (request) {
|
|
|
112
112
|
expectType<number>(request.params.id)
|
|
113
113
|
expectType<string>(request.headers['x-foobar'])
|
|
114
114
|
expectType<FastifyInstance>(request.server)
|
|
115
|
-
expectType<
|
|
116
|
-
expectType<
|
|
115
|
+
expectType<FastifyRequestContext<ContextConfigDefault>>(request.context)
|
|
116
|
+
expectType<FastifyRequestContext<ContextConfigDefault>['config']>(request.context.config)
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
function putHandler (request: CustomRequest, reply: FastifyReply) {
|
|
@@ -130,8 +130,8 @@ function putHandler (request: CustomRequest, reply: FastifyReply) {
|
|
|
130
130
|
expectType<number>(request.params.id)
|
|
131
131
|
expectType<string>(request.headers['x-foobar'])
|
|
132
132
|
expectType<FastifyInstance>(request.server)
|
|
133
|
-
expectType<
|
|
134
|
-
expectType<
|
|
133
|
+
expectType<FastifyRequestContext<ContextConfigDefault>>(request.context)
|
|
134
|
+
expectType<FastifyRequestContext<ContextConfigDefault>['config']>(request.context.config)
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
const server = fastify()
|