fastify 3.5.0 → 3.8.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/docs/ContentTypeParser.md +3 -0
- package/docs/Ecosystem.md +7 -2
- package/docs/Hooks.md +0 -5
- package/docs/Lifecycle.md +2 -2
- package/docs/Logging.md +1 -1
- package/docs/Recommendations.md +17 -0
- package/docs/Reply.md +2 -2
- package/docs/Request.md +4 -2
- package/docs/Routes.md +21 -3
- package/docs/Server.md +51 -3
- package/docs/Style-Guide.md +180 -0
- package/docs/TypeScript.md +359 -359
- package/docs/Validation-and-Serialization.md +11 -5
- package/examples/parser.js +1 -1
- package/fastify.d.ts +2 -2
- package/fastify.js +39 -7
- package/lib/contentTypeParser.js +16 -11
- package/lib/context.js +5 -19
- package/lib/decorate.js +1 -1
- package/lib/errors.js +2 -2
- package/lib/fourOhFour.js +8 -7
- package/lib/handleRequest.js +5 -5
- package/lib/hooks.js +4 -4
- package/lib/logger.js +7 -7
- package/lib/pluginUtils.js +4 -2
- package/lib/reply.js +27 -24
- package/lib/reqIdGenFactory.js +2 -2
- package/lib/request.js +20 -8
- package/lib/route.js +12 -10
- package/lib/schemas.js +1 -1
- package/lib/server.js +5 -5
- package/lib/symbols.js +2 -1
- package/lib/validation.js +9 -8
- package/lib/warnings.js +3 -0
- package/lib/wrapThenable.js +2 -2
- package/package.json +10 -10
- package/test/404s.test.js +15 -15
- package/test/async-await.test.js +7 -7
- package/test/custom-parser-async.test.js +2 -2
- package/test/custom-parser.test.js +38 -8
- package/test/emit-warning.test.js +31 -0
- package/test/fastify-instance.test.js +33 -1
- package/test/helper.js +1 -1
- package/test/hooks.test.js +6 -6
- package/test/http2/head.test.js +1 -1
- package/test/http2/plain.test.js +1 -1
- package/test/http2/secure-with-fallback.test.js +1 -1
- package/test/http2/secure.test.js +1 -1
- package/test/http2/unknown-http-method.test.js +1 -1
- package/test/https/https.test.js +2 -1
- package/test/inject.test.js +2 -2
- package/test/internals/all.test.js +1 -1
- package/test/internals/hookRunner.test.js +1 -1
- package/test/internals/logger.test.js +1 -1
- package/test/internals/reply.test.js +62 -7
- package/test/internals/request.test.js +31 -5
- package/test/internals/version.test.js +43 -0
- package/test/listen.test.js +12 -0
- package/test/logger.test.js +11 -11
- package/test/nullable-validation.test.js +108 -0
- package/test/pretty-print.test.js +9 -14
- package/test/reply-error.test.js +2 -2
- package/test/request-error.test.js +81 -0
- package/test/route-hooks.test.js +10 -10
- package/test/stream.test.js +11 -11
- package/test/types/fastify.test-d.ts +1 -2
- package/test/types/instance.test-d.ts +17 -3
- package/test/types/logger.test-d.ts +35 -2
- package/test/types/register.test-d.ts +16 -0
- package/test/types/request.test-d.ts +1 -1
- package/test/types/route.test-d.ts +5 -0
- package/test/validation-error-handling.test.js +66 -0
- package/test/versioned-routes.test.js +55 -0
- package/types/.eslintrc.json +4 -1
- package/types/content-type-parser.d.ts +0 -15
- package/types/hooks.d.ts +138 -16
- package/types/instance.d.ts +86 -14
- package/types/logger.d.ts +13 -11
- package/types/plugin.d.ts +5 -7
- package/types/register.d.ts +8 -7
- package/types/request.d.ts +3 -1
- package/types/route.d.ts +38 -58
- package/types/schema.d.ts +4 -4
- package/types/serverFactory.d.ts +9 -9
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const sget = require('simple-get').concat
|
|
4
4
|
const { test } = require('tap')
|
|
5
5
|
const Fastify = require('..')
|
|
6
|
+
const semver = require('semver')
|
|
6
7
|
|
|
7
8
|
process.removeAllListeners('warning')
|
|
8
9
|
|
|
@@ -129,3 +130,33 @@ test('Should emit a warning when using payload less preParsing hook', t => {
|
|
|
129
130
|
})
|
|
130
131
|
})
|
|
131
132
|
})
|
|
133
|
+
|
|
134
|
+
if (semver.gte(process.versions.node, '13.0.0')) {
|
|
135
|
+
test('Should emit a warning when accessing request.connection instead of request.socket on Node process greater than 13.0.0', t => {
|
|
136
|
+
t.plan(4)
|
|
137
|
+
|
|
138
|
+
process.on('warning', onWarning)
|
|
139
|
+
function onWarning (warning) {
|
|
140
|
+
t.strictEqual(warning.name, 'FastifyDeprecation')
|
|
141
|
+
t.strictEqual(warning.code, 'FSTDEP005')
|
|
142
|
+
t.strictEqual(warning.message, 'You are accessing the deprecated "request.connection" property. Use "request.socket" instead.')
|
|
143
|
+
|
|
144
|
+
// removed listener before light-my-request emit second warning
|
|
145
|
+
process.removeListener('warning', onWarning)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const fastify = Fastify()
|
|
149
|
+
|
|
150
|
+
fastify.get('/', (request, reply) => {
|
|
151
|
+
reply.send(request.connection)
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
fastify.inject({
|
|
155
|
+
method: 'GET',
|
|
156
|
+
path: '/'
|
|
157
|
+
}, (err, res) => {
|
|
158
|
+
t.error(err)
|
|
159
|
+
process.removeListener('warning', onWarning)
|
|
160
|
+
})
|
|
161
|
+
})
|
|
162
|
+
}
|
|
@@ -4,7 +4,8 @@ const t = require('tap')
|
|
|
4
4
|
const test = t.test
|
|
5
5
|
const Fastify = require('..')
|
|
6
6
|
const {
|
|
7
|
-
kOptions
|
|
7
|
+
kOptions,
|
|
8
|
+
kErrorHandler
|
|
8
9
|
} = require('../lib/symbols')
|
|
9
10
|
|
|
10
11
|
test('root fastify instance is an object', t => {
|
|
@@ -65,3 +66,34 @@ test('fastify instance get invalid ajv options.plugins', t => {
|
|
|
65
66
|
}
|
|
66
67
|
}))
|
|
67
68
|
})
|
|
69
|
+
|
|
70
|
+
test('fastify instance should contain default errorHandler', t => {
|
|
71
|
+
t.plan(3)
|
|
72
|
+
const fastify = Fastify()
|
|
73
|
+
t.ok(fastify[kErrorHandler] instanceof Function)
|
|
74
|
+
t.same(fastify.errorHandler, fastify[kErrorHandler])
|
|
75
|
+
t.same(Object.getOwnPropertyDescriptor(fastify, 'errorHandler').set, undefined)
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
test('errorHandler in plugin should be separate from the external one', async t => {
|
|
79
|
+
t.plan(4)
|
|
80
|
+
const fastify = Fastify()
|
|
81
|
+
|
|
82
|
+
fastify.register((instance, opts, next) => {
|
|
83
|
+
const inPluginErrHandler = (_, __, reply) => {
|
|
84
|
+
reply.send({ plugin: 'error-object' })
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
instance.setErrorHandler(inPluginErrHandler)
|
|
88
|
+
|
|
89
|
+
t.notSame(instance.errorHandler, fastify.errorHandler)
|
|
90
|
+
t.equal(instance.errorHandler.name, 'bound inPluginErrHandler')
|
|
91
|
+
|
|
92
|
+
next()
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
await fastify.ready()
|
|
96
|
+
|
|
97
|
+
t.ok(fastify[kErrorHandler] instanceof Function)
|
|
98
|
+
t.same(fastify.errorHandler, fastify[kErrorHandler])
|
|
99
|
+
})
|
package/test/helper.js
CHANGED
|
@@ -282,7 +282,7 @@ module.exports.payloadMethod = function (method, t, isSetErrorHandler = false) {
|
|
|
282
282
|
|
|
283
283
|
// Node errors for OPTIONS requests with a stream body and no Content-Length header
|
|
284
284
|
if (upMethod !== 'OPTIONS') {
|
|
285
|
-
|
|
285
|
+
let chunk = Buffer.alloc(1024 * 1024 + 1, 0)
|
|
286
286
|
const largeStream = new stream.Readable({
|
|
287
287
|
read () {
|
|
288
288
|
this.push(chunk)
|
package/test/hooks.test.js
CHANGED
|
@@ -197,7 +197,7 @@ test('onRequest hook should support encapsulation / 1', t => {
|
|
|
197
197
|
test('onRequest hook should support encapsulation / 2', t => {
|
|
198
198
|
t.plan(3)
|
|
199
199
|
const fastify = Fastify()
|
|
200
|
-
|
|
200
|
+
let pluginInstance
|
|
201
201
|
|
|
202
202
|
fastify.addHook('onRequest', () => {})
|
|
203
203
|
|
|
@@ -813,7 +813,7 @@ test('onResponse hook should support encapsulation / 1', t => {
|
|
|
813
813
|
test('onResponse hook should support encapsulation / 2', t => {
|
|
814
814
|
t.plan(3)
|
|
815
815
|
const fastify = Fastify()
|
|
816
|
-
|
|
816
|
+
let pluginInstance
|
|
817
817
|
|
|
818
818
|
fastify.addHook('onResponse', () => {})
|
|
819
819
|
|
|
@@ -890,7 +890,7 @@ test('onResponse hook should support encapsulation / 3', t => {
|
|
|
890
890
|
test('onSend hook should support encapsulation / 1', t => {
|
|
891
891
|
t.plan(3)
|
|
892
892
|
const fastify = Fastify()
|
|
893
|
-
|
|
893
|
+
let pluginInstance
|
|
894
894
|
|
|
895
895
|
fastify.addHook('onSend', () => {})
|
|
896
896
|
|
|
@@ -1015,7 +1015,7 @@ test('onSend hook is called after payload is serialized and headers are set', t
|
|
|
1015
1015
|
})
|
|
1016
1016
|
|
|
1017
1017
|
fastify.register((instance, opts, done) => {
|
|
1018
|
-
|
|
1018
|
+
let chunk = 'stream payload'
|
|
1019
1019
|
const thePayload = new stream.Readable({
|
|
1020
1020
|
read () {
|
|
1021
1021
|
this.push(chunk)
|
|
@@ -2163,7 +2163,7 @@ test('preValidation hook should support encapsulation / 1', t => {
|
|
|
2163
2163
|
test('preValidation hook should support encapsulation / 2', t => {
|
|
2164
2164
|
t.plan(3)
|
|
2165
2165
|
const fastify = Fastify()
|
|
2166
|
-
|
|
2166
|
+
let pluginInstance
|
|
2167
2167
|
|
|
2168
2168
|
fastify.addHook('preValidation', () => {})
|
|
2169
2169
|
|
|
@@ -2582,7 +2582,7 @@ test('preParsing hook should support encapsulation / 1', t => {
|
|
|
2582
2582
|
test('preParsing hook should support encapsulation / 2', t => {
|
|
2583
2583
|
t.plan(3)
|
|
2584
2584
|
const fastify = Fastify()
|
|
2585
|
-
|
|
2585
|
+
let pluginInstance
|
|
2586
2586
|
|
|
2587
2587
|
fastify.addHook('preParsing', function a () {})
|
|
2588
2588
|
|
package/test/http2/head.test.js
CHANGED
package/test/http2/plain.test.js
CHANGED
package/test/https/https.test.js
CHANGED
|
@@ -7,8 +7,9 @@ const fs = require('fs')
|
|
|
7
7
|
const path = require('path')
|
|
8
8
|
const Fastify = require('../..')
|
|
9
9
|
|
|
10
|
+
let fastify
|
|
10
11
|
try {
|
|
11
|
-
|
|
12
|
+
fastify = Fastify({
|
|
12
13
|
https: {
|
|
13
14
|
key: fs.readFileSync(path.join(__dirname, 'fastify.key')),
|
|
14
15
|
cert: fs.readFileSync(path.join(__dirname, 'fastify.cert'))
|
package/test/inject.test.js
CHANGED
|
@@ -329,7 +329,7 @@ test('inject a multipart request using form-body', t => {
|
|
|
329
329
|
const fastify = Fastify()
|
|
330
330
|
|
|
331
331
|
fastify.addContentTypeParser('*', function (req, payload, done) {
|
|
332
|
-
|
|
332
|
+
let body = ''
|
|
333
333
|
payload.on('data', d => {
|
|
334
334
|
body += d
|
|
335
335
|
})
|
|
@@ -362,7 +362,7 @@ function getStream () {
|
|
|
362
362
|
}
|
|
363
363
|
util.inherits(Read, Stream.Readable)
|
|
364
364
|
const word = '{"hello":"world"}'
|
|
365
|
-
|
|
365
|
+
let i = 0
|
|
366
366
|
|
|
367
367
|
Read.prototype._read = function (size) {
|
|
368
368
|
this.push(word[i] ? word[i++] : null)
|
|
@@ -28,7 +28,7 @@ test('fastify.all should add all the methods to the same url', t => {
|
|
|
28
28
|
|
|
29
29
|
fastify.inject(options, (err, res) => {
|
|
30
30
|
t.error(err)
|
|
31
|
-
|
|
31
|
+
const payload = JSON.parse(res.payload)
|
|
32
32
|
t.deepEqual(payload, { method: method })
|
|
33
33
|
})
|
|
34
34
|
}
|
|
@@ -139,7 +139,7 @@ test('hookRunner - In case of error should skip to done (with promises)', t => {
|
|
|
139
139
|
test('hookRunner - Be able to exit before its natural end', t => {
|
|
140
140
|
t.plan(4)
|
|
141
141
|
|
|
142
|
-
|
|
142
|
+
let shouldStop = false
|
|
143
143
|
hookRunner([fn1, fn2, fn3], iterator, 'a', 'b', done)
|
|
144
144
|
|
|
145
145
|
function iterator (fn, a, b, next) {
|
|
@@ -79,7 +79,7 @@ test('reply.send throw with circular JSON', t => {
|
|
|
79
79
|
}
|
|
80
80
|
const reply = new Reply(response, { context: { onSend: [] } })
|
|
81
81
|
t.throws(() => {
|
|
82
|
-
|
|
82
|
+
const obj = {}
|
|
83
83
|
obj.obj = obj
|
|
84
84
|
reply.send(JSON.stringify(obj))
|
|
85
85
|
}, 'Converting circular structure to JSON')
|
|
@@ -430,9 +430,9 @@ test('stream with content type should not send application/octet-stream', t => {
|
|
|
430
430
|
const fs = require('fs')
|
|
431
431
|
const path = require('path')
|
|
432
432
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
433
|
+
const streamPath = path.join(__dirname, '..', '..', 'package.json')
|
|
434
|
+
const stream = fs.createReadStream(streamPath)
|
|
435
|
+
const buf = fs.readFileSync(streamPath)
|
|
436
436
|
|
|
437
437
|
fastify.get('/', function (req, reply) {
|
|
438
438
|
reply.header('Content-Type', 'text/plain').send(stream)
|
|
@@ -459,9 +459,9 @@ test('stream using reply.raw.writeHead should return customize headers', t => {
|
|
|
459
459
|
const fs = require('fs')
|
|
460
460
|
const path = require('path')
|
|
461
461
|
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
462
|
+
const streamPath = path.join(__dirname, '..', '..', 'package.json')
|
|
463
|
+
const stream = fs.createReadStream(streamPath)
|
|
464
|
+
const buf = fs.readFileSync(streamPath)
|
|
465
465
|
|
|
466
466
|
fastify.get('/', function (req, reply) {
|
|
467
467
|
reply.log.warn = function mockWarn (message) {
|
|
@@ -781,6 +781,61 @@ test('undefined payload should be sent as-is', t => {
|
|
|
781
781
|
})
|
|
782
782
|
})
|
|
783
783
|
|
|
784
|
+
test('for HEAD method, no body should be sent but content-length should be', t => {
|
|
785
|
+
t.plan(11)
|
|
786
|
+
|
|
787
|
+
const fastify = require('../..')()
|
|
788
|
+
const contentType = 'application/json; charset=utf-8'
|
|
789
|
+
const bodySize = JSON.stringify({ foo: 'bar' }).length
|
|
790
|
+
|
|
791
|
+
fastify.head('/', {
|
|
792
|
+
onSend: function (request, reply, payload, next) {
|
|
793
|
+
t.strictEqual(payload, undefined)
|
|
794
|
+
next()
|
|
795
|
+
}
|
|
796
|
+
}, function (req, reply) {
|
|
797
|
+
reply.header('content-length', bodySize)
|
|
798
|
+
reply.header('content-type', contentType)
|
|
799
|
+
reply.code(200).send()
|
|
800
|
+
})
|
|
801
|
+
|
|
802
|
+
fastify.head('/with/null', {
|
|
803
|
+
onSend: function (request, reply, payload, next) {
|
|
804
|
+
t.strictEqual(payload, 'null')
|
|
805
|
+
next()
|
|
806
|
+
}
|
|
807
|
+
}, function (req, reply) {
|
|
808
|
+
reply.header('content-length', bodySize)
|
|
809
|
+
reply.header('content-type', contentType)
|
|
810
|
+
reply.code(200).send(null)
|
|
811
|
+
})
|
|
812
|
+
|
|
813
|
+
fastify.listen(0, err => {
|
|
814
|
+
t.error(err)
|
|
815
|
+
fastify.server.unref()
|
|
816
|
+
|
|
817
|
+
sget({
|
|
818
|
+
method: 'HEAD',
|
|
819
|
+
url: `http://localhost:${fastify.server.address().port}`
|
|
820
|
+
}, (err, response, body) => {
|
|
821
|
+
t.error(err)
|
|
822
|
+
t.strictEqual(response.headers['content-type'], contentType)
|
|
823
|
+
t.strictEqual(response.headers['content-length'], bodySize.toString())
|
|
824
|
+
t.strictEqual(body.length, 0)
|
|
825
|
+
})
|
|
826
|
+
|
|
827
|
+
sget({
|
|
828
|
+
method: 'HEAD',
|
|
829
|
+
url: `http://localhost:${fastify.server.address().port}/with/null`
|
|
830
|
+
}, (err, response, body) => {
|
|
831
|
+
t.error(err)
|
|
832
|
+
t.strictEqual(response.headers['content-type'], contentType)
|
|
833
|
+
t.strictEqual(response.headers['content-length'], bodySize.toString())
|
|
834
|
+
t.strictEqual(body.length, 0)
|
|
835
|
+
})
|
|
836
|
+
})
|
|
837
|
+
})
|
|
838
|
+
|
|
784
839
|
test('reply.send(new NotFound()) should not invoke the 404 handler', t => {
|
|
785
840
|
t.plan(9)
|
|
786
841
|
|
|
@@ -12,7 +12,7 @@ test('Regular request', t => {
|
|
|
12
12
|
const req = {
|
|
13
13
|
method: 'GET',
|
|
14
14
|
url: '/',
|
|
15
|
-
|
|
15
|
+
socket: { remoteAddress: 'ip' },
|
|
16
16
|
headers
|
|
17
17
|
}
|
|
18
18
|
const request = new Request('id', 'params', req, 'query', 'log')
|
|
@@ -29,7 +29,7 @@ test('Regular request', t => {
|
|
|
29
29
|
t.strictEqual(request.body, null)
|
|
30
30
|
t.strictEqual(request.method, 'GET')
|
|
31
31
|
t.strictEqual(request.url, '/')
|
|
32
|
-
t.deepEqual(request.
|
|
32
|
+
t.deepEqual(request.socket, req.socket)
|
|
33
33
|
})
|
|
34
34
|
|
|
35
35
|
test('Regular request - hostname from authority', t => {
|
|
@@ -40,7 +40,7 @@ test('Regular request - hostname from authority', t => {
|
|
|
40
40
|
const req = {
|
|
41
41
|
method: 'GET',
|
|
42
42
|
url: '/',
|
|
43
|
-
|
|
43
|
+
socket: { remoteAddress: 'ip' },
|
|
44
44
|
headers
|
|
45
45
|
}
|
|
46
46
|
|
|
@@ -58,7 +58,7 @@ test('Regular request - host header has precedence over authority', t => {
|
|
|
58
58
|
const req = {
|
|
59
59
|
method: 'GET',
|
|
60
60
|
url: '/',
|
|
61
|
-
|
|
61
|
+
socket: { remoteAddress: 'ip' },
|
|
62
62
|
headers
|
|
63
63
|
}
|
|
64
64
|
const request = new Request('id', 'params', req, 'query', 'log')
|
|
@@ -75,6 +75,9 @@ test('Request with trust proxy', t => {
|
|
|
75
75
|
const req = {
|
|
76
76
|
method: 'GET',
|
|
77
77
|
url: '/',
|
|
78
|
+
// Some dependencies (proxy-addr, forwarded) still depend on the deprecated
|
|
79
|
+
// .connection property, we use .socket. Include both to satisfy everyone.
|
|
80
|
+
socket: { remoteAddress: 'ip' },
|
|
78
81
|
connection: { remoteAddress: 'ip' },
|
|
79
82
|
headers
|
|
80
83
|
}
|
|
@@ -94,7 +97,7 @@ test('Request with trust proxy', t => {
|
|
|
94
97
|
t.strictEqual(request.body, null)
|
|
95
98
|
t.strictEqual(request.method, 'GET')
|
|
96
99
|
t.strictEqual(request.url, '/')
|
|
97
|
-
t.deepEqual(request.
|
|
100
|
+
t.deepEqual(request.socket, req.socket)
|
|
98
101
|
})
|
|
99
102
|
|
|
100
103
|
test('Request with trust proxy - no x-forwarded-host header', t => {
|
|
@@ -154,3 +157,26 @@ test('Request with trust proxy - x-forwarded-host header has precedence over hos
|
|
|
154
157
|
t.type(request, TpRequest)
|
|
155
158
|
t.strictEqual(request.hostname, 'example.com')
|
|
156
159
|
})
|
|
160
|
+
|
|
161
|
+
test('Request with trust proxy - handles multiple entries in x-forwarded-host/proto', t => {
|
|
162
|
+
t.plan(3)
|
|
163
|
+
const headers = {
|
|
164
|
+
'x-forwarded-host': 'example2.com, example.com',
|
|
165
|
+
'x-forwarded-proto': 'http, https'
|
|
166
|
+
}
|
|
167
|
+
const req = {
|
|
168
|
+
method: 'GET',
|
|
169
|
+
url: '/',
|
|
170
|
+
// Some dependencies (proxy-addr, forwarded) still depend on the deprecated
|
|
171
|
+
// .connection property, we use .socket. Include both to satisfy everyone.
|
|
172
|
+
socket: { remoteAddress: 'ip' },
|
|
173
|
+
connection: { remoteAddress: 'ip' },
|
|
174
|
+
headers
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const TpRequest = Request.buildRequest(Request, true)
|
|
178
|
+
const request = new TpRequest('id', 'params', req, 'query', 'log')
|
|
179
|
+
t.type(request, TpRequest)
|
|
180
|
+
t.strictEqual(request.hostname, 'example.com')
|
|
181
|
+
t.strictEqual(request.protocol, 'https')
|
|
182
|
+
})
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const t = require('tap')
|
|
4
|
+
const test = t.test
|
|
5
|
+
const proxyquire = require('proxyquire')
|
|
6
|
+
|
|
7
|
+
test('should output an undefined version in case of package.json not available', t => {
|
|
8
|
+
const Fastify = proxyquire('../..', { fs: { accessSync: () => { throw Error('error') } } })
|
|
9
|
+
t.plan(1)
|
|
10
|
+
const srv = Fastify()
|
|
11
|
+
t.is(srv.version, undefined)
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
test('should output an undefined version in case of package.json is not the fastify one', t => {
|
|
15
|
+
const Fastify = proxyquire('../..', { fs: { accessSync: () => { }, readFileSync: () => JSON.stringify({ name: 'foo', version: '6.6.6' }) } })
|
|
16
|
+
t.plan(1)
|
|
17
|
+
const srv = Fastify()
|
|
18
|
+
t.is(srv.version, undefined)
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
test('should skip the version check if the version is undefined', t => {
|
|
22
|
+
const Fastify = proxyquire('../..', { fs: { accessSync: () => { }, readFileSync: () => JSON.stringify({ name: 'foo', version: '6.6.6' }) } })
|
|
23
|
+
t.plan(3)
|
|
24
|
+
const srv = Fastify()
|
|
25
|
+
t.is(srv.version, undefined)
|
|
26
|
+
|
|
27
|
+
plugin[Symbol.for('skip-override')] = false
|
|
28
|
+
plugin[Symbol.for('plugin-meta')] = {
|
|
29
|
+
name: 'plugin',
|
|
30
|
+
fastify: '>=99.0.0'
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
srv.register(plugin)
|
|
34
|
+
|
|
35
|
+
srv.ready((err) => {
|
|
36
|
+
t.error(err)
|
|
37
|
+
t.pass('everything right')
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
function plugin (instance, opts, next) {
|
|
41
|
+
next()
|
|
42
|
+
}
|
|
43
|
+
})
|
package/test/listen.test.js
CHANGED
|
@@ -62,6 +62,18 @@ test('listen accepts options and a callback', t => {
|
|
|
62
62
|
})
|
|
63
63
|
})
|
|
64
64
|
|
|
65
|
+
test('listen accepts options, backlog and a callback', t => {
|
|
66
|
+
t.plan(1)
|
|
67
|
+
const fastify = Fastify()
|
|
68
|
+
t.tearDown(fastify.close.bind(fastify))
|
|
69
|
+
fastify.listen({
|
|
70
|
+
port: 0,
|
|
71
|
+
host: 'localhost'
|
|
72
|
+
}, 511, (err) => {
|
|
73
|
+
t.error(err)
|
|
74
|
+
})
|
|
75
|
+
})
|
|
76
|
+
|
|
65
77
|
test('listen accepts a port, address and a callback with (err, address)', t => {
|
|
66
78
|
t.plan(2)
|
|
67
79
|
const fastify = Fastify()
|
package/test/logger.test.js
CHANGED
|
@@ -32,8 +32,8 @@ tearDown(() => {
|
|
|
32
32
|
|
|
33
33
|
test('defaults to info level', t => {
|
|
34
34
|
t.plan(13)
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
let fastify = null
|
|
36
|
+
const stream = split(JSON.parse)
|
|
37
37
|
try {
|
|
38
38
|
fastify = Fastify({
|
|
39
39
|
logger: {
|
|
@@ -80,8 +80,8 @@ test('defaults to info level', t => {
|
|
|
80
80
|
|
|
81
81
|
test('test log stream', t => {
|
|
82
82
|
t.plan(12)
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
let fastify = null
|
|
84
|
+
const stream = split(JSON.parse)
|
|
85
85
|
try {
|
|
86
86
|
fastify = Fastify({
|
|
87
87
|
logger: {
|
|
@@ -127,8 +127,8 @@ test('test log stream', t => {
|
|
|
127
127
|
|
|
128
128
|
test('test error log stream', t => {
|
|
129
129
|
t.plan(11)
|
|
130
|
-
|
|
131
|
-
|
|
130
|
+
let fastify = null
|
|
131
|
+
const stream = split(JSON.parse)
|
|
132
132
|
try {
|
|
133
133
|
fastify = Fastify({
|
|
134
134
|
logger: {
|
|
@@ -248,8 +248,8 @@ test('can use external logger instance with custom serializer', t => {
|
|
|
248
248
|
|
|
249
249
|
test('expose the logger', t => {
|
|
250
250
|
t.plan(2)
|
|
251
|
-
|
|
252
|
-
|
|
251
|
+
let fastify = null
|
|
252
|
+
const stream = split(JSON.parse)
|
|
253
253
|
try {
|
|
254
254
|
fastify = Fastify({
|
|
255
255
|
logger: {
|
|
@@ -1190,8 +1190,8 @@ test('Do not wrap IPv4 address', t => {
|
|
|
1190
1190
|
|
|
1191
1191
|
test('file option', t => {
|
|
1192
1192
|
t.plan(13)
|
|
1193
|
-
|
|
1194
|
-
|
|
1193
|
+
let fastify = null
|
|
1194
|
+
const dest = file()
|
|
1195
1195
|
|
|
1196
1196
|
fastify = Fastify({
|
|
1197
1197
|
logger: {
|
|
@@ -1423,7 +1423,7 @@ test('should redact the authorization header if so specified', t => {
|
|
|
1423
1423
|
headers: req.headers,
|
|
1424
1424
|
hostname: req.hostname,
|
|
1425
1425
|
remoteAddress: req.ip,
|
|
1426
|
-
remotePort: req.
|
|
1426
|
+
remotePort: req.socket.remotePort
|
|
1427
1427
|
}
|
|
1428
1428
|
}
|
|
1429
1429
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const t = require('tap')
|
|
4
4
|
const test = t.test
|
|
5
|
+
const sget = require('simple-get').concat
|
|
5
6
|
const Fastify = require('..')
|
|
6
7
|
|
|
7
8
|
test('nullable string', t => {
|
|
@@ -50,3 +51,110 @@ test('nullable string', t => {
|
|
|
50
51
|
t.same(res.payload.hello, null)
|
|
51
52
|
})
|
|
52
53
|
})
|
|
54
|
+
|
|
55
|
+
test('object or null body', t => {
|
|
56
|
+
t.plan(5)
|
|
57
|
+
|
|
58
|
+
const fastify = Fastify()
|
|
59
|
+
|
|
60
|
+
fastify.route({
|
|
61
|
+
method: 'POST',
|
|
62
|
+
url: '/',
|
|
63
|
+
handler: (req, reply) => {
|
|
64
|
+
t.strictEqual(req.body, null)
|
|
65
|
+
reply.code(200).send({ requestBody: req.body })
|
|
66
|
+
},
|
|
67
|
+
schema: {
|
|
68
|
+
body: {
|
|
69
|
+
type: ['object', 'null'],
|
|
70
|
+
properties: {
|
|
71
|
+
hello: {
|
|
72
|
+
type: 'string',
|
|
73
|
+
format: 'email'
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
response: {
|
|
78
|
+
200: {
|
|
79
|
+
type: 'object',
|
|
80
|
+
nullable: true,
|
|
81
|
+
properties: {
|
|
82
|
+
requestBody: {
|
|
83
|
+
type: 'string',
|
|
84
|
+
format: 'email',
|
|
85
|
+
nullable: true
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
fastify.listen(0, (err) => {
|
|
94
|
+
fastify.server.unref()
|
|
95
|
+
t.error(err)
|
|
96
|
+
|
|
97
|
+
sget({
|
|
98
|
+
method: 'POST',
|
|
99
|
+
url: 'http://localhost:' + fastify.server.address().port
|
|
100
|
+
}, (err, response, body) => {
|
|
101
|
+
t.error(err)
|
|
102
|
+
t.strictEqual(response.statusCode, 200)
|
|
103
|
+
t.deepEqual(JSON.parse(body), { requestBody: null })
|
|
104
|
+
})
|
|
105
|
+
})
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
test('nullable body', t => {
|
|
109
|
+
t.plan(5)
|
|
110
|
+
|
|
111
|
+
const fastify = Fastify()
|
|
112
|
+
|
|
113
|
+
fastify.route({
|
|
114
|
+
method: 'POST',
|
|
115
|
+
url: '/',
|
|
116
|
+
handler: (req, reply) => {
|
|
117
|
+
t.strictEqual(req.body, null)
|
|
118
|
+
reply.code(200).send({ requestBody: req.body })
|
|
119
|
+
},
|
|
120
|
+
schema: {
|
|
121
|
+
body: {
|
|
122
|
+
type: 'object',
|
|
123
|
+
nullable: true,
|
|
124
|
+
properties: {
|
|
125
|
+
hello: {
|
|
126
|
+
type: 'string',
|
|
127
|
+
format: 'email'
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
response: {
|
|
132
|
+
200: {
|
|
133
|
+
type: 'object',
|
|
134
|
+
nullable: true,
|
|
135
|
+
properties: {
|
|
136
|
+
requestBody: {
|
|
137
|
+
type: 'string',
|
|
138
|
+
format: 'email',
|
|
139
|
+
nullable: true
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
fastify.listen(0, (err) => {
|
|
148
|
+
fastify.server.unref()
|
|
149
|
+
t.error(err)
|
|
150
|
+
|
|
151
|
+
sget({
|
|
152
|
+
method: 'POST',
|
|
153
|
+
url: 'http://localhost:' + fastify.server.address().port
|
|
154
|
+
}, (err, response, body) => {
|
|
155
|
+
t.error(err)
|
|
156
|
+
t.strictEqual(response.statusCode, 200)
|
|
157
|
+
t.deepEqual(JSON.parse(body), { requestBody: null })
|
|
158
|
+
})
|
|
159
|
+
})
|
|
160
|
+
})
|