fastify 5.3.3 → 5.5.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/.vscode/settings.json +15 -15
- package/LICENSE +1 -1
- package/README.md +2 -0
- package/SECURITY.md +158 -2
- package/build/build-validation.js +20 -1
- package/docs/Guides/Delay-Accepting-Requests.md +8 -5
- package/docs/Guides/Ecosystem.md +20 -5
- package/docs/Guides/Migration-Guide-V5.md +6 -10
- package/docs/Guides/Recommendations.md +1 -1
- package/docs/Reference/ContentTypeParser.md +1 -1
- package/docs/Reference/Errors.md +5 -3
- package/docs/Reference/Hooks.md +16 -20
- package/docs/Reference/Lifecycle.md +2 -2
- package/docs/Reference/Logging.md +3 -3
- package/docs/Reference/Middleware.md +1 -1
- package/docs/Reference/Reply.md +8 -8
- package/docs/Reference/Request.md +2 -2
- package/docs/Reference/Routes.md +7 -6
- package/docs/Reference/Server.md +341 -200
- package/docs/Reference/TypeScript.md +1 -3
- package/docs/Reference/Validation-and-Serialization.md +56 -4
- package/docs/Reference/Warnings.md +2 -1
- package/fastify.d.ts +4 -3
- package/fastify.js +47 -34
- package/lib/configValidator.js +196 -28
- package/lib/contentTypeParser.js +41 -48
- package/lib/error-handler.js +3 -3
- package/lib/errors.js +11 -0
- package/lib/handleRequest.js +13 -17
- package/lib/pluginOverride.js +3 -1
- package/lib/promise.js +23 -0
- package/lib/reply.js +24 -30
- package/lib/request.js +3 -10
- package/lib/route.js +37 -3
- package/lib/server.js +36 -35
- package/lib/symbols.js +1 -0
- package/lib/warnings.js +19 -1
- package/package.json +14 -10
- package/test/404s.test.js +226 -325
- package/test/allow-unsafe-regex.test.js +19 -48
- package/test/als.test.js +28 -40
- package/test/async-await.test.js +84 -128
- package/test/async_hooks.test.js +18 -37
- package/test/body-limit.test.js +90 -63
- package/test/buffer.test.js +22 -0
- package/test/build-certificate.js +1 -1
- package/test/case-insensitive.test.js +44 -65
- package/test/check.test.js +17 -21
- package/test/close-pipelining.test.js +24 -15
- package/test/constrained-routes.test.js +231 -0
- package/test/custom-http-server.test.js +7 -15
- package/test/custom-parser-async.test.js +17 -22
- package/test/custom-parser.0.test.js +267 -348
- package/test/custom-parser.1.test.js +141 -191
- package/test/custom-parser.2.test.js +34 -44
- package/test/custom-parser.3.test.js +56 -104
- package/test/custom-parser.4.test.js +106 -144
- package/test/custom-parser.5.test.js +56 -75
- package/test/custom-querystring-parser.test.js +51 -77
- package/test/decorator-namespace.test._js_ +3 -4
- package/test/decorator.test.js +76 -259
- package/test/delete.test.js +101 -110
- package/test/diagnostics-channel/404.test.js +7 -15
- package/test/diagnostics-channel/async-delay-request.test.js +7 -16
- package/test/diagnostics-channel/async-request.test.js +8 -16
- package/test/diagnostics-channel/error-request.test.js +7 -15
- package/test/diagnostics-channel/sync-delay-request.test.js +7 -16
- package/test/diagnostics-channel/sync-request-reply.test.js +9 -16
- package/test/diagnostics-channel/sync-request.test.js +9 -16
- package/test/fastify-instance.test.js +1 -1
- package/test/header-overflow.test.js +18 -29
- package/test/helper.js +139 -135
- package/test/hooks-async.test.js +259 -235
- package/test/hooks.test.js +951 -996
- package/test/http-methods/copy.test.js +14 -19
- package/test/http-methods/get.test.js +131 -143
- package/test/http-methods/head.test.js +53 -84
- package/test/http-methods/lock.test.js +31 -31
- package/test/http-methods/mkcalendar.test.js +45 -72
- package/test/http-methods/mkcol.test.js +5 -9
- package/test/http-methods/move.test.js +6 -10
- package/test/http-methods/propfind.test.js +34 -44
- package/test/http-methods/proppatch.test.js +23 -29
- package/test/http-methods/report.test.js +44 -69
- package/test/http-methods/search.test.js +67 -82
- package/test/http-methods/unlock.test.js +5 -9
- package/test/http2/closing.test.js +38 -20
- package/test/http2/secure-with-fallback.test.js +31 -28
- package/test/https/custom-https-server.test.js +9 -13
- package/test/https/https.test.js +56 -53
- package/test/input-validation.js +139 -150
- package/test/internals/errors.test.js +50 -1
- package/test/internals/handle-request.test.js +72 -65
- package/test/internals/promise.test.js +63 -0
- package/test/internals/reply.test.js +277 -496
- package/test/issue-4959.test.js +12 -3
- package/test/listen.4.test.js +31 -43
- package/test/nullable-validation.test.js +33 -46
- package/test/output-validation.test.js +24 -26
- package/test/plugin.1.test.js +40 -68
- package/test/plugin.2.test.js +108 -120
- package/test/plugin.3.test.js +50 -72
- package/test/plugin.4.test.js +124 -119
- package/test/promises.test.js +42 -63
- package/test/proto-poisoning.test.js +78 -97
- package/test/register.test.js +8 -18
- package/test/request-error.test.js +57 -146
- package/test/request-id.test.js +30 -49
- package/test/route-hooks.test.js +117 -101
- package/test/route-prefix.test.js +194 -133
- package/test/route-shorthand.test.js +9 -27
- package/test/route.1.test.js +74 -131
- package/test/route.8.test.js +9 -17
- package/test/router-options.test.js +450 -0
- package/test/schema-serialization.test.js +177 -154
- package/test/schema-special-usage.test.js +165 -132
- package/test/schema-validation.test.js +254 -218
- package/test/server.test.js +143 -5
- package/test/set-error-handler.test.js +58 -1
- package/test/skip-reply-send.test.js +64 -69
- package/test/stream.1.test.js +33 -50
- package/test/stream.4.test.js +18 -28
- package/test/stream.5.test.js +11 -19
- package/test/trust-proxy.test.js +32 -58
- package/test/types/errors.test-d.ts +13 -1
- package/test/types/fastify.test-d.ts +3 -0
- package/test/types/request.test-d.ts +1 -0
- package/test/types/type-provider.test-d.ts +55 -0
- package/test/url-rewriting.test.js +45 -62
- package/test/use-semicolon-delimiter.test.js +117 -59
- package/test/versioned-routes.test.js +39 -56
- package/types/errors.d.ts +11 -1
- package/types/hooks.d.ts +1 -1
- package/types/instance.d.ts +1 -1
- package/types/reply.d.ts +2 -2
- package/types/request.d.ts +1 -0
- package/.taprc +0 -7
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
const { test } = require('node:test')
|
|
4
4
|
const Fastify = require('..')
|
|
5
|
-
const sget = require('simple-get').concat
|
|
6
5
|
|
|
7
|
-
test('Should rewrite url',
|
|
8
|
-
t.plan(
|
|
6
|
+
test('Should rewrite url', async t => {
|
|
7
|
+
t.plan(4)
|
|
9
8
|
const fastify = Fastify({
|
|
10
9
|
rewriteUrl (req) {
|
|
11
10
|
t.assert.strictEqual(req.url, '/this-would-404-without-url-rewrite')
|
|
@@ -22,24 +21,19 @@ test('Should rewrite url', (t, done) => {
|
|
|
22
21
|
}
|
|
23
22
|
})
|
|
24
23
|
|
|
25
|
-
fastify.listen({ port: 0 }
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
t.assert.deepStrictEqual(JSON.parse(body), { hello: 'world' })
|
|
35
|
-
t.assert.strictEqual(response.statusCode, 200)
|
|
36
|
-
done()
|
|
37
|
-
})
|
|
38
|
-
})
|
|
24
|
+
const fastifyServer = await fastify.listen({ port: 0 })
|
|
25
|
+
|
|
26
|
+
t.after(() => fastify.close())
|
|
27
|
+
|
|
28
|
+
const result = await fetch(`${fastifyServer}/this-would-404-without-url-rewrite`)
|
|
29
|
+
|
|
30
|
+
t.assert.ok(result.ok)
|
|
31
|
+
t.assert.strictEqual(result.status, 200)
|
|
32
|
+
t.assert.deepStrictEqual(await result.json(), { hello: 'world' })
|
|
39
33
|
})
|
|
40
34
|
|
|
41
|
-
test('Should not rewrite if the url is the same',
|
|
42
|
-
t.plan(
|
|
35
|
+
test('Should not rewrite if the url is the same', async t => {
|
|
36
|
+
t.plan(3)
|
|
43
37
|
const fastify = Fastify({
|
|
44
38
|
rewriteUrl (req) {
|
|
45
39
|
t.assert.strictEqual(req.url, '/this-would-404-without-url-rewrite')
|
|
@@ -56,22 +50,18 @@ test('Should not rewrite if the url is the same', (t, done) => {
|
|
|
56
50
|
}
|
|
57
51
|
})
|
|
58
52
|
|
|
59
|
-
fastify.listen({ port: 0 }
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
t.assert.strictEqual(response.statusCode, 404)
|
|
68
|
-
done()
|
|
69
|
-
})
|
|
70
|
-
})
|
|
53
|
+
const fastifyServer = await fastify.listen({ port: 0 })
|
|
54
|
+
|
|
55
|
+
t.after(() => fastify.close())
|
|
56
|
+
|
|
57
|
+
const result = await fetch(`${fastifyServer}/this-would-404-without-url-rewrite`)
|
|
58
|
+
|
|
59
|
+
t.assert.ok(!result.ok)
|
|
60
|
+
t.assert.strictEqual(result.status, 404)
|
|
71
61
|
})
|
|
72
62
|
|
|
73
|
-
test('Should throw an error',
|
|
74
|
-
t.plan(
|
|
63
|
+
test('Should throw an error', async t => {
|
|
64
|
+
t.plan(2)
|
|
75
65
|
const fastify = Fastify({
|
|
76
66
|
rewriteUrl (req) {
|
|
77
67
|
t.assert.strictEqual(req.url, '/this-would-404-without-url-rewrite')
|
|
@@ -88,23 +78,20 @@ test('Should throw an error', (t, done) => {
|
|
|
88
78
|
}
|
|
89
79
|
})
|
|
90
80
|
|
|
91
|
-
fastify.listen({ port: 0 }
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
done()
|
|
102
|
-
})
|
|
103
|
-
})
|
|
81
|
+
const fastifyServer = await fastify.listen({ port: 0 })
|
|
82
|
+
|
|
83
|
+
t.after(() => fastify.close())
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
await fetch(`${fastifyServer}/this-would-404-without-url-rewrite`)
|
|
87
|
+
t.assert.fail('Expected fetch to throw an error')
|
|
88
|
+
} catch (err) {
|
|
89
|
+
t.assert.ok(err instanceof Error)
|
|
90
|
+
}
|
|
104
91
|
})
|
|
105
92
|
|
|
106
|
-
test('Should rewrite url but keep originalUrl unchanged',
|
|
107
|
-
t.plan(
|
|
93
|
+
test('Should rewrite url but keep originalUrl unchanged', async t => {
|
|
94
|
+
t.plan(6)
|
|
108
95
|
const fastify = Fastify({
|
|
109
96
|
rewriteUrl (req) {
|
|
110
97
|
t.assert.strictEqual(req.url, '/this-would-404-without-url-rewrite')
|
|
@@ -122,18 +109,14 @@ test('Should rewrite url but keep originalUrl unchanged', (t, done) => {
|
|
|
122
109
|
}
|
|
123
110
|
})
|
|
124
111
|
|
|
125
|
-
fastify.listen({ port: 0 }
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
t.assert.strictEqual(response.statusCode, 200)
|
|
136
|
-
done()
|
|
137
|
-
})
|
|
138
|
-
})
|
|
112
|
+
await fastify.listen({ port: 0 })
|
|
113
|
+
const port = fastify.server.address().port
|
|
114
|
+
|
|
115
|
+
t.after(() => fastify.close())
|
|
116
|
+
|
|
117
|
+
const result = await fetch(`http://localhost:${port}/this-would-404-without-url-rewrite`)
|
|
118
|
+
|
|
119
|
+
t.assert.ok(result.ok)
|
|
120
|
+
t.assert.strictEqual(result.status, 200)
|
|
121
|
+
t.assert.deepStrictEqual(await result.json(), { hello: 'world', hostname: 'localhost', port })
|
|
139
122
|
})
|
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
const { test } = require('node:test')
|
|
4
4
|
const Fastify = require('..')
|
|
5
|
-
const sget = require('simple-get').concat
|
|
6
5
|
|
|
7
|
-
test('use semicolon delimiter default false', (t
|
|
8
|
-
t.plan(
|
|
6
|
+
test('use semicolon delimiter default false', async (t) => {
|
|
7
|
+
t.plan(2)
|
|
9
8
|
|
|
10
9
|
const fastify = Fastify()
|
|
11
10
|
|
|
@@ -13,23 +12,19 @@ test('use semicolon delimiter default false', (t, done) => {
|
|
|
13
12
|
reply.send(req.query)
|
|
14
13
|
})
|
|
15
14
|
|
|
16
|
-
fastify.listen({ port: 0 }
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}, (err, response, body) => {
|
|
22
|
-
t.assert.ifError(err)
|
|
23
|
-
t.assert.strictEqual(response.statusCode, 200)
|
|
24
|
-
t.assert.deepStrictEqual(JSON.parse(body), {})
|
|
25
|
-
fastify.close()
|
|
26
|
-
done()
|
|
27
|
-
})
|
|
15
|
+
const fastifyServer = await fastify.listen({ port: 0 })
|
|
16
|
+
t.after(() => { fastify.close() })
|
|
17
|
+
|
|
18
|
+
const result = await fetch(fastifyServer + '/1234;foo=bar', {
|
|
19
|
+
method: 'GET'
|
|
28
20
|
})
|
|
21
|
+
t.assert.strictEqual(result.status, 200)
|
|
22
|
+
const body = await result.json()
|
|
23
|
+
t.assert.deepStrictEqual(body, {})
|
|
29
24
|
})
|
|
30
25
|
|
|
31
|
-
test('use semicolon delimiter set to true', (t
|
|
32
|
-
t.plan(
|
|
26
|
+
test('use semicolon delimiter set to true', async (t) => {
|
|
27
|
+
t.plan(3)
|
|
33
28
|
const fastify = Fastify({
|
|
34
29
|
useSemicolonDelimiter: true
|
|
35
30
|
})
|
|
@@ -38,26 +33,19 @@ test('use semicolon delimiter set to true', (t, done) => {
|
|
|
38
33
|
reply.send(req.query)
|
|
39
34
|
})
|
|
40
35
|
|
|
41
|
-
fastify.listen({ port: 0 }
|
|
42
|
-
|
|
36
|
+
const fastifyServer = await fastify.listen({ port: 0 })
|
|
37
|
+
t.after(() => { fastify.close() })
|
|
43
38
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
t.assert.strictEqual(response.statusCode, 200)
|
|
50
|
-
t.assert.deepStrictEqual(JSON.parse(body), {
|
|
51
|
-
foo: 'bar'
|
|
52
|
-
})
|
|
53
|
-
fastify.close()
|
|
54
|
-
done()
|
|
55
|
-
})
|
|
39
|
+
const result = await fetch(fastifyServer + '/1234;foo=bar')
|
|
40
|
+
t.assert.ok(result.ok)
|
|
41
|
+
t.assert.strictEqual(result.status, 200)
|
|
42
|
+
t.assert.deepStrictEqual(await result.json(), {
|
|
43
|
+
foo: 'bar'
|
|
56
44
|
})
|
|
57
45
|
})
|
|
58
46
|
|
|
59
|
-
test('use semicolon delimiter set to false', (t
|
|
60
|
-
t.plan(
|
|
47
|
+
test('use semicolon delimiter set to false', async (t) => {
|
|
48
|
+
t.plan(3)
|
|
61
49
|
|
|
62
50
|
const fastify = Fastify({
|
|
63
51
|
useSemicolonDelimiter: false
|
|
@@ -67,24 +55,17 @@ test('use semicolon delimiter set to false', (t, done) => {
|
|
|
67
55
|
reply.send(req.query)
|
|
68
56
|
})
|
|
69
57
|
|
|
70
|
-
fastify.listen({ port: 0 }
|
|
71
|
-
|
|
58
|
+
const fastifyServer = await fastify.listen({ port: 0 })
|
|
59
|
+
t.after(() => { fastify.close() })
|
|
72
60
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
t.assert.ifError(err)
|
|
78
|
-
t.assert.strictEqual(response.statusCode, 200)
|
|
79
|
-
t.assert.deepStrictEqual(JSON.parse(body), {})
|
|
80
|
-
fastify.close()
|
|
81
|
-
done()
|
|
82
|
-
})
|
|
83
|
-
})
|
|
61
|
+
const result = await fetch(fastifyServer + '/1234;foo=bar')
|
|
62
|
+
t.assert.ok(result.ok)
|
|
63
|
+
t.assert.strictEqual(result.status, 200)
|
|
64
|
+
t.assert.deepStrictEqual(await result.json(), {})
|
|
84
65
|
})
|
|
85
66
|
|
|
86
|
-
test('use semicolon delimiter set to false return 404', (t
|
|
87
|
-
t.plan(
|
|
67
|
+
test('use semicolon delimiter set to false return 404', async (t) => {
|
|
68
|
+
t.plan(2)
|
|
88
69
|
|
|
89
70
|
const fastify = Fastify({
|
|
90
71
|
useSemicolonDelimiter: false
|
|
@@ -94,17 +75,94 @@ test('use semicolon delimiter set to false return 404', (t, done) => {
|
|
|
94
75
|
reply.send(req.query)
|
|
95
76
|
})
|
|
96
77
|
|
|
97
|
-
fastify.listen({ port: 0 }
|
|
98
|
-
|
|
78
|
+
const fastifyServer = await fastify.listen({ port: 0 })
|
|
79
|
+
t.after(() => { fastify.close() })
|
|
80
|
+
|
|
81
|
+
const result = await fetch(fastifyServer + '/1234;foo=bar')
|
|
82
|
+
t.assert.ok(!result.ok)
|
|
83
|
+
t.assert.strictEqual(result.status, 404)
|
|
84
|
+
})
|
|
99
85
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
done()
|
|
108
|
-
})
|
|
86
|
+
test('use routerOptions semicolon delimiter default false', async t => {
|
|
87
|
+
t.plan(3)
|
|
88
|
+
|
|
89
|
+
const fastify = Fastify()
|
|
90
|
+
|
|
91
|
+
fastify.get('/1234;foo=bar', (req, reply) => {
|
|
92
|
+
reply.send(req.query)
|
|
109
93
|
})
|
|
94
|
+
|
|
95
|
+
const fastifyServer = await fastify.listen({ port: 0 })
|
|
96
|
+
t.after(() => { fastify.close() })
|
|
97
|
+
|
|
98
|
+
const result = await fetch(fastifyServer + '/1234;foo=bar')
|
|
99
|
+
t.assert.ok(result.ok)
|
|
100
|
+
t.assert.strictEqual(result.status, 200)
|
|
101
|
+
t.assert.deepStrictEqual(await result.json(), {})
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
test('use routerOptions semicolon delimiter set to true', async t => {
|
|
105
|
+
t.plan(3)
|
|
106
|
+
const fastify = Fastify({
|
|
107
|
+
routerOptions: {
|
|
108
|
+
useSemicolonDelimiter: true
|
|
109
|
+
}
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
fastify.get('/1234', async (req, reply) => {
|
|
113
|
+
reply.send(req.query)
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
const fastifyServer = await fastify.listen({ port: 0 })
|
|
117
|
+
t.after(() => { fastify.close() })
|
|
118
|
+
|
|
119
|
+
const result = await fetch(fastifyServer + '/1234;foo=bar')
|
|
120
|
+
t.assert.ok(result.ok)
|
|
121
|
+
t.assert.strictEqual(result.status, 200)
|
|
122
|
+
t.assert.deepStrictEqual(await result.json(), {
|
|
123
|
+
foo: 'bar'
|
|
124
|
+
})
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
test('use routerOptions semicolon delimiter set to false', async t => {
|
|
128
|
+
t.plan(3)
|
|
129
|
+
|
|
130
|
+
const fastify = Fastify({
|
|
131
|
+
routerOptions: {
|
|
132
|
+
useSemicolonDelimiter: false
|
|
133
|
+
}
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
fastify.get('/1234;foo=bar', (req, reply) => {
|
|
137
|
+
reply.send(req.query)
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
const fastifyServer = await fastify.listen({ port: 0 })
|
|
141
|
+
t.after(() => { fastify.close() })
|
|
142
|
+
|
|
143
|
+
const result = await fetch(fastifyServer + '/1234;foo=bar')
|
|
144
|
+
t.assert.ok(result.ok)
|
|
145
|
+
t.assert.strictEqual(result.status, 200)
|
|
146
|
+
t.assert.deepStrictEqual(await result.json(), {})
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
test('use routerOptions semicolon delimiter set to false return 404', async t => {
|
|
150
|
+
t.plan(2)
|
|
151
|
+
|
|
152
|
+
const fastify = Fastify({
|
|
153
|
+
routerOptions: {
|
|
154
|
+
useSemicolonDelimiter: false
|
|
155
|
+
}
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
fastify.get('/1234', (req, reply) => {
|
|
159
|
+
reply.send(req.query)
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
const fastifyServer = await fastify.listen({ port: 0 })
|
|
163
|
+
t.after(() => { fastify.close() })
|
|
164
|
+
|
|
165
|
+
const result = await fetch(fastifyServer + '/1234;foo=bar')
|
|
166
|
+
t.assert.ok(!result.ok)
|
|
167
|
+
t.assert.strictEqual(result.status, 404)
|
|
110
168
|
})
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
const { test, before } = require('node:test')
|
|
4
4
|
const helper = require('./helper')
|
|
5
5
|
const Fastify = require('..')
|
|
6
|
-
const sget = require('simple-get').concat
|
|
7
6
|
const http = require('node:http')
|
|
8
7
|
const split = require('split2')
|
|
9
8
|
const append = require('vary').append
|
|
@@ -233,8 +232,8 @@ test('Versioned route but not version header should return a 404', (t, done) =>
|
|
|
233
232
|
})
|
|
234
233
|
})
|
|
235
234
|
|
|
236
|
-
test('Should register a versioned route (server)',
|
|
237
|
-
t.plan(
|
|
235
|
+
test('Should register a versioned route (server)', async t => {
|
|
236
|
+
t.plan(5)
|
|
238
237
|
const fastify = Fastify()
|
|
239
238
|
|
|
240
239
|
fastify.route({
|
|
@@ -246,34 +245,27 @@ test('Should register a versioned route (server)', (t, done) => {
|
|
|
246
245
|
}
|
|
247
246
|
})
|
|
248
247
|
|
|
249
|
-
fastify.listen({ port: 0 }
|
|
250
|
-
|
|
251
|
-
t.after(() => { fastify.close() })
|
|
248
|
+
const fastifyServer = await fastify.listen({ port: 0 })
|
|
249
|
+
t.after(() => { fastify.close() })
|
|
252
250
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
headers: {
|
|
268
|
-
'Accept-Version': '2.x'
|
|
269
|
-
}
|
|
270
|
-
}, (err, response, body) => {
|
|
271
|
-
t.assert.ifError(err)
|
|
272
|
-
t.assert.strictEqual(response.statusCode, 404)
|
|
273
|
-
done()
|
|
274
|
-
})
|
|
275
|
-
})
|
|
251
|
+
const result1 = await fetch(fastifyServer, {
|
|
252
|
+
headers: {
|
|
253
|
+
'Accept-Version': '1.x'
|
|
254
|
+
}
|
|
255
|
+
})
|
|
256
|
+
t.assert.ok(result1.ok)
|
|
257
|
+
t.assert.strictEqual(result1.status, 200)
|
|
258
|
+
const body1 = await result1.json()
|
|
259
|
+
t.assert.deepStrictEqual(body1, { hello: 'world' })
|
|
260
|
+
|
|
261
|
+
const result2 = await fetch(fastifyServer, {
|
|
262
|
+
headers: {
|
|
263
|
+
'Accept-Version': '2.x'
|
|
264
|
+
}
|
|
276
265
|
})
|
|
266
|
+
|
|
267
|
+
t.assert.ok(!result2.ok)
|
|
268
|
+
t.assert.strictEqual(result2.status, 404)
|
|
277
269
|
})
|
|
278
270
|
|
|
279
271
|
test('Shorthand route declaration', (t, done) => {
|
|
@@ -402,8 +394,8 @@ test('Bad accept version (inject)', (t, done) => {
|
|
|
402
394
|
})
|
|
403
395
|
})
|
|
404
396
|
|
|
405
|
-
test('Bad accept version (server)',
|
|
406
|
-
t.plan(
|
|
397
|
+
test('Bad accept version (server)', async t => {
|
|
398
|
+
t.plan(4)
|
|
407
399
|
const fastify = Fastify()
|
|
408
400
|
|
|
409
401
|
fastify.route({
|
|
@@ -415,33 +407,24 @@ test('Bad accept version (server)', (t, done) => {
|
|
|
415
407
|
}
|
|
416
408
|
})
|
|
417
409
|
|
|
418
|
-
fastify.listen({ port: 0 }
|
|
419
|
-
|
|
420
|
-
t.after(() => { fastify.close() })
|
|
410
|
+
const fastifyServer = await fastify.listen({ port: 0 })
|
|
411
|
+
t.after(() => { fastify.close() })
|
|
421
412
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
url: 'http://localhost:' + fastify.server.address().port,
|
|
435
|
-
headers: {
|
|
436
|
-
'Accept-Version': 12
|
|
437
|
-
}
|
|
438
|
-
}, (err, response, body) => {
|
|
439
|
-
t.assert.ifError(err)
|
|
440
|
-
t.assert.strictEqual(response.statusCode, 404)
|
|
441
|
-
done()
|
|
442
|
-
})
|
|
443
|
-
})
|
|
413
|
+
const result1 = await fetch(fastifyServer, {
|
|
414
|
+
headers: {
|
|
415
|
+
'Accept-Version': 'a.b.c'
|
|
416
|
+
}
|
|
417
|
+
})
|
|
418
|
+
t.assert.ok(!result1.ok)
|
|
419
|
+
t.assert.strictEqual(result1.status, 404)
|
|
420
|
+
|
|
421
|
+
const result2 = await fetch(fastifyServer, {
|
|
422
|
+
headers: {
|
|
423
|
+
'Accept-Version': '12'
|
|
424
|
+
}
|
|
444
425
|
})
|
|
426
|
+
t.assert.ok(!result2.ok)
|
|
427
|
+
t.assert.strictEqual(result2.status, 404)
|
|
445
428
|
})
|
|
446
429
|
|
|
447
430
|
test('test log stream', (t, done) => {
|
package/types/errors.d.ts
CHANGED
|
@@ -9,6 +9,9 @@ export type FastifyErrorCodes = Record<
|
|
|
9
9
|
'FST_ERR_AJV_CUSTOM_OPTIONS_OPT_NOT_OBJ' |
|
|
10
10
|
'FST_ERR_AJV_CUSTOM_OPTIONS_OPT_NOT_ARR' |
|
|
11
11
|
'FST_ERR_VALIDATION' |
|
|
12
|
+
'FST_ERR_LISTEN_OPTIONS_INVALID' |
|
|
13
|
+
'FST_ERR_ERROR_HANDLER_NOT_FN' |
|
|
14
|
+
'FST_ERR_ERROR_HANDLER_ALREADY_SET' |
|
|
12
15
|
'FST_ERR_CTP_ALREADY_PRESENT' |
|
|
13
16
|
'FST_ERR_CTP_INVALID_TYPE' |
|
|
14
17
|
'FST_ERR_CTP_EMPTY_TYPE' |
|
|
@@ -18,12 +21,14 @@ export type FastifyErrorCodes = Record<
|
|
|
18
21
|
'FST_ERR_CTP_INVALID_MEDIA_TYPE' |
|
|
19
22
|
'FST_ERR_CTP_INVALID_CONTENT_LENGTH' |
|
|
20
23
|
'FST_ERR_CTP_EMPTY_JSON_BODY' |
|
|
24
|
+
'FST_ERR_CTP_INVALID_JSON_BODY' |
|
|
21
25
|
'FST_ERR_CTP_INSTANCE_ALREADY_STARTED' |
|
|
22
26
|
'FST_ERR_DEC_ALREADY_PRESENT' |
|
|
23
27
|
'FST_ERR_DEC_DEPENDENCY_INVALID_TYPE' |
|
|
24
28
|
'FST_ERR_DEC_MISSING_DEPENDENCY' |
|
|
25
29
|
'FST_ERR_DEC_AFTER_START' |
|
|
26
30
|
'FST_ERR_DEC_REFERENCE_TYPE' |
|
|
31
|
+
'FST_ERR_DEC_UNDECLARED' |
|
|
27
32
|
'FST_ERR_HOOK_INVALID_TYPE' |
|
|
28
33
|
'FST_ERR_HOOK_INVALID_HANDLER' |
|
|
29
34
|
'FST_ERR_HOOK_INVALID_ASYNC_HANDLER' |
|
|
@@ -32,7 +37,12 @@ export type FastifyErrorCodes = Record<
|
|
|
32
37
|
'FST_ERR_HOOK_TIMEOUT' |
|
|
33
38
|
'FST_ERR_LOG_INVALID_DESTINATION' |
|
|
34
39
|
'FST_ERR_LOG_INVALID_LOGGER' |
|
|
40
|
+
'FST_ERR_LOG_INVALID_LOGGER_INSTANCE' |
|
|
41
|
+
'FST_ERR_LOG_INVALID_LOGGER_CONFIG' |
|
|
42
|
+
'FST_ERR_LOG_LOGGER_AND_LOGGER_INSTANCE_PROVIDED' |
|
|
35
43
|
'FST_ERR_REP_INVALID_PAYLOAD_TYPE' |
|
|
44
|
+
'FST_ERR_REP_RESPONSE_BODY_CONSUMED' |
|
|
45
|
+
'FST_ERR_REP_READABLE_STREAM_LOCKED' |
|
|
36
46
|
'FST_ERR_REP_ALREADY_SENT' |
|
|
37
47
|
'FST_ERR_REP_SENT_VALUE' |
|
|
38
48
|
'FST_ERR_SEND_INSIDE_ONERR' |
|
|
@@ -56,7 +66,6 @@ export type FastifyErrorCodes = Record<
|
|
|
56
66
|
'FST_ERR_DUPLICATED_ROUTE' |
|
|
57
67
|
'FST_ERR_BAD_URL' |
|
|
58
68
|
'FST_ERR_ASYNC_CONSTRAINT' |
|
|
59
|
-
'FST_ERR_DEFAULT_ROUTE_INVALID_TYPE' |
|
|
60
69
|
'FST_ERR_INVALID_URL' |
|
|
61
70
|
'FST_ERR_ROUTE_OPTIONS_NOT_OBJ' |
|
|
62
71
|
'FST_ERR_ROUTE_DUPLICATED_HANDLER' |
|
|
@@ -72,6 +81,7 @@ export type FastifyErrorCodes = Record<
|
|
|
72
81
|
'FST_ERR_INSTANCE_ALREADY_LISTENING' |
|
|
73
82
|
'FST_ERR_PLUGIN_VERSION_MISMATCH' |
|
|
74
83
|
'FST_ERR_PLUGIN_NOT_PRESENT_IN_INSTANCE' |
|
|
84
|
+
'FST_ERR_PLUGIN_INVALID_ASYNC_HANDLER' |
|
|
75
85
|
'FST_ERR_PLUGIN_CALLBACK_NOT_FN' |
|
|
76
86
|
'FST_ERR_PLUGIN_NOT_VALID' |
|
|
77
87
|
'FST_ERR_ROOT_PLG_BOOTED' |
|
package/types/hooks.d.ts
CHANGED
|
@@ -498,7 +498,7 @@ export type onTimeoutMetaHookHandler<
|
|
|
498
498
|
/**
|
|
499
499
|
* This hook is useful if you need to do some custom error logging or add some specific header in case of error.
|
|
500
500
|
* It is not intended for changing the error, and calling reply.send will throw an exception.
|
|
501
|
-
* This hook will be executed
|
|
501
|
+
* This hook will be executed before the customErrorHandler.
|
|
502
502
|
* Notice: unlike the other hooks, pass an error to the done function is not supported.
|
|
503
503
|
*/
|
|
504
504
|
export interface onErrorHookHandler<
|
package/types/instance.d.ts
CHANGED
|
@@ -466,7 +466,7 @@ export interface FastifyInstance<
|
|
|
466
466
|
errorHandler: (error: FastifyError, request: FastifyRequest, reply: FastifyReply) => void;
|
|
467
467
|
|
|
468
468
|
/**
|
|
469
|
-
* Set a function that will be
|
|
469
|
+
* Set a function that will be invoked whenever an exception is thrown during the request lifecycle.
|
|
470
470
|
*/
|
|
471
471
|
setErrorHandler<TError extends Error = FastifyError, RouteGeneric extends RouteGenericInterface = RouteGenericInterface, SchemaCompiler extends FastifySchema = FastifySchema, TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault>(
|
|
472
472
|
handler: (this: FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>, error: TError, request: FastifyRequest<RouteGeneric, RawServer, RawRequest, SchemaCompiler, TypeProvider>, reply: FastifyReply<RouteGeneric, RawServer, RawRequest, RawReply, ContextConfigDefault, SchemaCompiler, TypeProvider>) => any | Promise<any>
|
package/types/reply.d.ts
CHANGED
|
@@ -46,8 +46,8 @@ export interface FastifyReply<
|
|
|
46
46
|
log: FastifyBaseLogger;
|
|
47
47
|
request: FastifyRequest<RouteGeneric, RawServer, RawRequest, SchemaCompiler, TypeProvider>;
|
|
48
48
|
server: FastifyInstance;
|
|
49
|
-
code<Code extends ReplyKeysToCodes<keyof RouteGeneric['Reply']>>(statusCode: Code): FastifyReply<RouteGeneric, RawServer, RawRequest, RawReply, ContextConfig, SchemaCompiler, TypeProvider, ResolveReplyTypeWithRouteGeneric<RouteGeneric['Reply'], Code, SchemaCompiler, TypeProvider>>;
|
|
50
|
-
status<Code extends ReplyKeysToCodes<keyof RouteGeneric['Reply']>>(statusCode: Code): FastifyReply<RouteGeneric, RawServer, RawRequest, RawReply, ContextConfig, SchemaCompiler, TypeProvider, ResolveReplyTypeWithRouteGeneric<RouteGeneric['Reply'], Code, SchemaCompiler, TypeProvider>>;
|
|
49
|
+
code<Code extends keyof SchemaCompiler['response'] extends never ? ReplyKeysToCodes<keyof RouteGeneric['Reply']> : keyof SchemaCompiler['response'] extends ReplyKeysToCodes<keyof RouteGeneric['Reply']> ? keyof SchemaCompiler['response'] : ReplyKeysToCodes<keyof RouteGeneric['Reply']>>(statusCode: Code): FastifyReply<RouteGeneric, RawServer, RawRequest, RawReply, ContextConfig, SchemaCompiler, TypeProvider, ResolveReplyTypeWithRouteGeneric<RouteGeneric['Reply'], Code, SchemaCompiler, TypeProvider>>;
|
|
50
|
+
status<Code extends keyof SchemaCompiler['response'] extends never ? ReplyKeysToCodes<keyof RouteGeneric['Reply']> : keyof SchemaCompiler['response'] extends ReplyKeysToCodes<keyof RouteGeneric['Reply']> ? keyof SchemaCompiler['response'] : ReplyKeysToCodes<keyof RouteGeneric['Reply']>>(statusCode: Code): FastifyReply<RouteGeneric, RawServer, RawRequest, RawReply, ContextConfig, SchemaCompiler, TypeProvider, ResolveReplyTypeWithRouteGeneric<RouteGeneric['Reply'], Code, SchemaCompiler, TypeProvider>>;
|
|
51
51
|
statusCode: number;
|
|
52
52
|
sent: boolean;
|
|
53
53
|
send(payload?: ReplyType): FastifyReply<RouteGeneric, RawServer, RawRequest, RawReply, ContextConfig, SchemaCompiler, TypeProvider>;
|
package/types/request.d.ts
CHANGED
|
@@ -32,6 +32,7 @@ export interface RequestRouteOptions<ContextConfig = ContextConfigDefault, Schem
|
|
|
32
32
|
config: FastifyContextConfig & FastifyRouteConfig & ContextConfig;
|
|
33
33
|
schema?: SchemaCompiler; // it is empty for 404 requests
|
|
34
34
|
handler: RouteHandlerMethod;
|
|
35
|
+
version?: string;
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
/**
|