fastify 5.3.2 → 5.4.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 +2 -0
- package/build/build-validation.js +2 -1
- package/docs/Guides/Delay-Accepting-Requests.md +3 -3
- package/docs/Guides/Ecosystem.md +16 -7
- package/docs/Guides/Serverless.md +28 -69
- package/docs/Reference/ContentTypeParser.md +1 -1
- package/docs/Reference/Errors.md +2 -4
- package/docs/Reference/Hooks.md +14 -14
- 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 +1 -1
- package/docs/Reference/Routes.md +3 -3
- package/docs/Reference/Server.md +40 -10
- package/docs/Reference/Validation-and-Serialization.md +1 -1
- package/eslint.config.js +17 -9
- package/fastify.d.ts +2 -1
- package/fastify.js +20 -4
- package/lib/configValidator.js +1 -1
- package/lib/decorate.js +2 -2
- package/lib/errors.js +6 -8
- package/lib/logger-factory.js +1 -1
- package/lib/logger-pino.js +2 -2
- package/lib/pluginOverride.js +3 -1
- package/lib/reply.js +9 -13
- package/lib/request.js +4 -11
- package/lib/server.js +30 -51
- package/lib/symbols.js +1 -0
- package/lib/warnings.js +8 -0
- package/package.json +11 -7
- 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 +11 -2
- package/test/body-limit.test.js +41 -65
- package/test/build-certificate.js +1 -1
- package/test/close-pipelining.test.js +5 -4
- package/test/custom-parser-async.test.js +17 -22
- package/test/decorator-namespace.test._js_ +3 -4
- package/test/decorator.test.js +422 -341
- package/test/diagnostics-channel/async-delay-request.test.js +7 -16
- package/test/diagnostics-channel/sync-delay-request.test.js +7 -16
- package/test/helper.js +108 -70
- package/test/hooks-async.test.js +248 -218
- package/test/hooks.on-listen.test.js +255 -239
- package/test/hooks.on-ready.test.js +110 -92
- package/test/hooks.test.js +910 -769
- package/test/http-methods/lock.test.js +31 -31
- package/test/http-methods/mkcol.test.js +5 -9
- 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/http2/closing.test.js +38 -20
- package/test/http2/secure-with-fallback.test.js +28 -27
- package/test/https/https.test.js +56 -53
- package/test/inject.test.js +114 -97
- package/test/input-validation.js +63 -53
- package/test/internals/errors.test.js +0 -10
- package/test/internals/handle-request.test.js +49 -66
- package/test/internals/hooks.test.js +17 -0
- package/test/issue-4959.test.js +14 -5
- package/test/listen.4.test.js +31 -43
- package/test/logger/response.test.js +19 -20
- package/test/nullable-validation.test.js +33 -46
- package/test/options.error-handler.test.js +1 -1
- package/test/options.test.js +1 -1
- package/test/output-validation.test.js +49 -72
- package/test/patch.error-handler.test.js +1 -1
- package/test/patch.test.js +1 -1
- package/test/plugin.1.test.js +71 -60
- package/test/plugin.2.test.js +104 -86
- package/test/plugin.3.test.js +56 -35
- package/test/plugin.4.test.js +124 -119
- package/test/promises.test.js +36 -30
- package/test/proto-poisoning.test.js +78 -97
- package/test/put.error-handler.test.js +1 -1
- package/test/put.test.js +1 -1
- package/test/reply-error.test.js +169 -148
- package/test/reply-trailers.test.js +119 -108
- package/test/request-error.test.js +0 -46
- package/test/route-hooks.test.js +112 -92
- package/test/route-prefix.test.js +194 -133
- package/test/schema-feature.test.js +309 -238
- package/test/schema-serialization.test.js +177 -154
- package/test/schema-special-usage.test.js +165 -132
- package/test/schema-validation.test.js +278 -199
- package/test/set-error-handler.test.js +58 -1
- package/test/skip-reply-send.test.js +64 -69
- package/test/stream.1.test.js +30 -27
- package/test/stream.2.test.js +20 -10
- package/test/stream.3.test.js +37 -31
- package/test/trust-proxy.test.js +32 -58
- package/test/types/errors.test-d.ts +0 -1
- package/test/types/fastify.test-d.ts +3 -0
- package/test/types/plugin.test-d.ts +1 -1
- package/test/types/register.test-d.ts +1 -1
- package/test/types/request.test-d.ts +1 -0
- package/test/url-rewriting.test.js +45 -62
- package/test/use-semicolon-delimiter.test.js +1 -1
- package/types/errors.d.ts +0 -1
- package/types/request.d.ts +1 -0
- package/.taprc +0 -7
- package/test/http2/missing-http2-module.test.js +0 -17
package/test/stream.3.test.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const test = t.test
|
|
3
|
+
const { test } = require('node:test')
|
|
5
4
|
const split = require('split2')
|
|
6
5
|
const Fastify = require('..')
|
|
7
6
|
|
|
8
|
-
test('Destroying streams prematurely', t => {
|
|
7
|
+
test('Destroying streams prematurely', (t, testDone) => {
|
|
9
8
|
t.plan(6)
|
|
10
9
|
|
|
11
10
|
let fastify = null
|
|
@@ -18,7 +17,7 @@ test('Destroying streams prematurely', t => {
|
|
|
18
17
|
}
|
|
19
18
|
})
|
|
20
19
|
} catch (e) {
|
|
21
|
-
t.fail()
|
|
20
|
+
t.assert.fail()
|
|
22
21
|
}
|
|
23
22
|
const stream = require('node:stream')
|
|
24
23
|
const http = require('node:http')
|
|
@@ -26,13 +25,14 @@ test('Destroying streams prematurely', t => {
|
|
|
26
25
|
// Test that "premature close" errors are logged with level warn
|
|
27
26
|
logStream.on('data', line => {
|
|
28
27
|
if (line.res) {
|
|
29
|
-
t.
|
|
30
|
-
t.
|
|
28
|
+
t.assert.strictEqual(line.msg, 'stream closed prematurely')
|
|
29
|
+
t.assert.strictEqual(line.level, 30)
|
|
30
|
+
testDone()
|
|
31
31
|
}
|
|
32
32
|
})
|
|
33
33
|
|
|
34
34
|
fastify.get('/', function (request, reply) {
|
|
35
|
-
t.
|
|
35
|
+
t.assert.ok('Received request')
|
|
36
36
|
|
|
37
37
|
let sent = false
|
|
38
38
|
const reallyLongStream = new stream.Readable({
|
|
@@ -48,26 +48,26 @@ test('Destroying streams prematurely', t => {
|
|
|
48
48
|
})
|
|
49
49
|
|
|
50
50
|
fastify.listen({ port: 0 }, err => {
|
|
51
|
-
t.
|
|
52
|
-
t.
|
|
51
|
+
t.assert.ifError(err)
|
|
52
|
+
t.after(() => fastify.close())
|
|
53
53
|
|
|
54
54
|
const port = fastify.server.address().port
|
|
55
55
|
|
|
56
56
|
http.get(`http://localhost:${port}`, function (response) {
|
|
57
|
-
t.
|
|
57
|
+
t.assert.strictEqual(response.statusCode, 200)
|
|
58
58
|
response.on('readable', function () {
|
|
59
59
|
response.destroy()
|
|
60
60
|
})
|
|
61
61
|
|
|
62
62
|
// Node bug? Node never emits 'close' here.
|
|
63
63
|
response.on('aborted', function () {
|
|
64
|
-
t.
|
|
64
|
+
t.assert.ok('Response closed')
|
|
65
65
|
})
|
|
66
66
|
})
|
|
67
67
|
})
|
|
68
68
|
})
|
|
69
69
|
|
|
70
|
-
test('Destroying streams prematurely should call close method', t => {
|
|
70
|
+
test('Destroying streams prematurely should call close method', (t, testDone) => {
|
|
71
71
|
t.plan(7)
|
|
72
72
|
|
|
73
73
|
let fastify = null
|
|
@@ -80,7 +80,7 @@ test('Destroying streams prematurely should call close method', t => {
|
|
|
80
80
|
}
|
|
81
81
|
})
|
|
82
82
|
} catch (e) {
|
|
83
|
-
t.fail()
|
|
83
|
+
t.assert.fail()
|
|
84
84
|
}
|
|
85
85
|
const stream = require('node:stream')
|
|
86
86
|
const http = require('node:http')
|
|
@@ -88,13 +88,13 @@ test('Destroying streams prematurely should call close method', t => {
|
|
|
88
88
|
// Test that "premature close" errors are logged with level warn
|
|
89
89
|
logStream.on('data', line => {
|
|
90
90
|
if (line.res) {
|
|
91
|
-
t.
|
|
92
|
-
t.
|
|
91
|
+
t.assert.strictEqual(line.msg, 'stream closed prematurely')
|
|
92
|
+
t.assert.strictEqual(line.level, 30)
|
|
93
93
|
}
|
|
94
94
|
})
|
|
95
95
|
|
|
96
96
|
fastify.get('/', function (request, reply) {
|
|
97
|
-
t.
|
|
97
|
+
t.assert.ok('Received request')
|
|
98
98
|
|
|
99
99
|
let sent = false
|
|
100
100
|
const reallyLongStream = new stream.Readable({
|
|
@@ -106,30 +106,33 @@ test('Destroying streams prematurely should call close method', t => {
|
|
|
106
106
|
}
|
|
107
107
|
})
|
|
108
108
|
reallyLongStream.destroy = undefined
|
|
109
|
-
reallyLongStream.close = () =>
|
|
109
|
+
reallyLongStream.close = () => {
|
|
110
|
+
t.assert.ok('called')
|
|
111
|
+
testDone()
|
|
112
|
+
}
|
|
110
113
|
reply.send(reallyLongStream)
|
|
111
114
|
})
|
|
112
115
|
|
|
113
116
|
fastify.listen({ port: 0 }, err => {
|
|
114
|
-
t.
|
|
115
|
-
t.
|
|
117
|
+
t.assert.ifError(err)
|
|
118
|
+
t.after(() => { fastify.close() })
|
|
116
119
|
|
|
117
120
|
const port = fastify.server.address().port
|
|
118
121
|
|
|
119
122
|
http.get(`http://localhost:${port}`, function (response) {
|
|
120
|
-
t.
|
|
123
|
+
t.assert.strictEqual(response.statusCode, 200)
|
|
121
124
|
response.on('readable', function () {
|
|
122
125
|
response.destroy()
|
|
123
126
|
})
|
|
124
127
|
// Node bug? Node never emits 'close' here.
|
|
125
128
|
response.on('aborted', function () {
|
|
126
|
-
t.
|
|
129
|
+
t.assert.ok('Response closed')
|
|
127
130
|
})
|
|
128
131
|
})
|
|
129
132
|
})
|
|
130
133
|
})
|
|
131
134
|
|
|
132
|
-
test('Destroying streams prematurely should call close method when destroy is not a function', t => {
|
|
135
|
+
test('Destroying streams prematurely should call close method when destroy is not a function', (t, testDone) => {
|
|
133
136
|
t.plan(7)
|
|
134
137
|
|
|
135
138
|
let fastify = null
|
|
@@ -142,7 +145,7 @@ test('Destroying streams prematurely should call close method when destroy is no
|
|
|
142
145
|
}
|
|
143
146
|
})
|
|
144
147
|
} catch (e) {
|
|
145
|
-
t.fail()
|
|
148
|
+
t.assert.fail()
|
|
146
149
|
}
|
|
147
150
|
const stream = require('node:stream')
|
|
148
151
|
const http = require('node:http')
|
|
@@ -150,13 +153,13 @@ test('Destroying streams prematurely should call close method when destroy is no
|
|
|
150
153
|
// Test that "premature close" errors are logged with level warn
|
|
151
154
|
logStream.on('data', line => {
|
|
152
155
|
if (line.res) {
|
|
153
|
-
t.
|
|
154
|
-
t.
|
|
156
|
+
t.assert.strictEqual(line.msg, 'stream closed prematurely')
|
|
157
|
+
t.assert.strictEqual(line.level, 30)
|
|
155
158
|
}
|
|
156
159
|
})
|
|
157
160
|
|
|
158
161
|
fastify.get('/', function (request, reply) {
|
|
159
|
-
t.
|
|
162
|
+
t.assert.ok('Received request')
|
|
160
163
|
|
|
161
164
|
let sent = false
|
|
162
165
|
const reallyLongStream = new stream.Readable({
|
|
@@ -168,24 +171,27 @@ test('Destroying streams prematurely should call close method when destroy is no
|
|
|
168
171
|
}
|
|
169
172
|
})
|
|
170
173
|
reallyLongStream.destroy = true
|
|
171
|
-
reallyLongStream.close = () =>
|
|
174
|
+
reallyLongStream.close = () => {
|
|
175
|
+
t.assert.ok('called')
|
|
176
|
+
testDone()
|
|
177
|
+
}
|
|
172
178
|
reply.send(reallyLongStream)
|
|
173
179
|
})
|
|
174
180
|
|
|
175
181
|
fastify.listen({ port: 0 }, err => {
|
|
176
|
-
t.
|
|
177
|
-
t.
|
|
182
|
+
t.assert.ifError(err)
|
|
183
|
+
t.after(() => { fastify.close() })
|
|
178
184
|
|
|
179
185
|
const port = fastify.server.address().port
|
|
180
186
|
|
|
181
187
|
http.get(`http://localhost:${port}`, function (response) {
|
|
182
|
-
t.
|
|
188
|
+
t.assert.strictEqual(response.statusCode, 200)
|
|
183
189
|
response.on('readable', function () {
|
|
184
190
|
response.destroy()
|
|
185
191
|
})
|
|
186
192
|
// Node bug? Node never emits 'close' here.
|
|
187
193
|
response.on('aborted', function () {
|
|
188
|
-
t.
|
|
194
|
+
t.assert.ok('Response closed')
|
|
189
195
|
})
|
|
190
196
|
})
|
|
191
197
|
})
|
package/test/trust-proxy.test.js
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { test, before } = require('node:test')
|
|
4
|
-
const sget = require('simple-get').concat
|
|
5
4
|
const fastify = require('..')
|
|
6
5
|
const helper = require('./helper')
|
|
7
|
-
const { waitForCb } = require('./toolkit')
|
|
8
6
|
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
const sgetForwardedRequest = (app, forHeader, path, protoHeader, testCaseDone) => {
|
|
7
|
+
const fetchForwardedRequest = async (fastifyServer, forHeader, path, protoHeader) => {
|
|
12
8
|
const headers = {
|
|
13
9
|
'X-Forwarded-For': forHeader,
|
|
14
10
|
'X-Forwarded-Host': 'example.com'
|
|
@@ -16,11 +12,10 @@ const sgetForwardedRequest = (app, forHeader, path, protoHeader, testCaseDone) =
|
|
|
16
12
|
if (protoHeader) {
|
|
17
13
|
headers['X-Forwarded-Proto'] = protoHeader
|
|
18
14
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
headers
|
|
22
|
-
|
|
23
|
-
}, testCaseDone || noop)
|
|
15
|
+
|
|
16
|
+
return fetch(fastifyServer + path, {
|
|
17
|
+
headers
|
|
18
|
+
})
|
|
24
19
|
}
|
|
25
20
|
|
|
26
21
|
const testRequestValues = (t, req, options) => {
|
|
@@ -52,8 +47,8 @@ before(async function () {
|
|
|
52
47
|
[localhost] = await helper.getLoopbackHost()
|
|
53
48
|
})
|
|
54
49
|
|
|
55
|
-
test('trust proxy, not add properties to node req',
|
|
56
|
-
t.plan(
|
|
50
|
+
test('trust proxy, not add properties to node req', async t => {
|
|
51
|
+
t.plan(13)
|
|
57
52
|
const app = fastify({
|
|
58
53
|
trustProxy: true
|
|
59
54
|
})
|
|
@@ -69,20 +64,14 @@ test('trust proxy, not add properties to node req', (t, done) => {
|
|
|
69
64
|
reply.code(200).send({ ip: req.ip, host: req.host })
|
|
70
65
|
})
|
|
71
66
|
|
|
72
|
-
app.listen({ port: 0 }
|
|
73
|
-
t.assert.ifError(err)
|
|
74
|
-
|
|
75
|
-
const completion = waitForCb({ steps: 2 })
|
|
76
|
-
|
|
77
|
-
sgetForwardedRequest(app, '1.1.1.1', '/trustproxy', undefined, completion.stepIn)
|
|
78
|
-
sgetForwardedRequest(app, '2.2.2.2, 1.1.1.1', '/trustproxychain', undefined, completion.stepIn)
|
|
67
|
+
const fastifyServer = await app.listen({ port: 0 })
|
|
79
68
|
|
|
80
|
-
|
|
81
|
-
|
|
69
|
+
await fetchForwardedRequest(fastifyServer, '1.1.1.1', '/trustproxy', undefined)
|
|
70
|
+
await fetchForwardedRequest(fastifyServer, '2.2.2.2, 1.1.1.1', '/trustproxychain', undefined)
|
|
82
71
|
})
|
|
83
72
|
|
|
84
|
-
test('trust proxy chain',
|
|
85
|
-
t.plan(
|
|
73
|
+
test('trust proxy chain', async t => {
|
|
74
|
+
t.plan(8)
|
|
86
75
|
const app = fastify({
|
|
87
76
|
trustProxy: [localhost, '192.168.1.1']
|
|
88
77
|
})
|
|
@@ -93,14 +82,12 @@ test('trust proxy chain', (t, done) => {
|
|
|
93
82
|
reply.code(200).send({ ip: req.ip, host: req.host })
|
|
94
83
|
})
|
|
95
84
|
|
|
96
|
-
app.listen({ port: 0 }
|
|
97
|
-
|
|
98
|
-
sgetForwardedRequest(app, '192.168.1.1, 1.1.1.1', '/trustproxychain', undefined, done)
|
|
99
|
-
})
|
|
85
|
+
const fastifyServer = await app.listen({ port: 0 })
|
|
86
|
+
await fetchForwardedRequest(fastifyServer, '192.168.1.1, 1.1.1.1', '/trustproxychain', undefined)
|
|
100
87
|
})
|
|
101
88
|
|
|
102
|
-
test('trust proxy function',
|
|
103
|
-
t.plan(
|
|
89
|
+
test('trust proxy function', async t => {
|
|
90
|
+
t.plan(8)
|
|
104
91
|
const app = fastify({
|
|
105
92
|
trustProxy: (address) => address === localhost
|
|
106
93
|
})
|
|
@@ -111,14 +98,12 @@ test('trust proxy function', (t, done) => {
|
|
|
111
98
|
reply.code(200).send({ ip: req.ip, host: req.host })
|
|
112
99
|
})
|
|
113
100
|
|
|
114
|
-
app.listen({ port: 0 }
|
|
115
|
-
|
|
116
|
-
sgetForwardedRequest(app, '1.1.1.1', '/trustproxyfunc', undefined, done)
|
|
117
|
-
})
|
|
101
|
+
const fastifyServer = await app.listen({ port: 0 })
|
|
102
|
+
await fetchForwardedRequest(fastifyServer, '1.1.1.1', '/trustproxyfunc', undefined)
|
|
118
103
|
})
|
|
119
104
|
|
|
120
|
-
test('trust proxy number',
|
|
121
|
-
t.plan(
|
|
105
|
+
test('trust proxy number', async t => {
|
|
106
|
+
t.plan(9)
|
|
122
107
|
const app = fastify({
|
|
123
108
|
trustProxy: 1
|
|
124
109
|
})
|
|
@@ -129,14 +114,12 @@ test('trust proxy number', (t, done) => {
|
|
|
129
114
|
reply.code(200).send({ ip: req.ip, host: req.host })
|
|
130
115
|
})
|
|
131
116
|
|
|
132
|
-
app.listen({ port: 0 }
|
|
133
|
-
|
|
134
|
-
sgetForwardedRequest(app, '2.2.2.2, 1.1.1.1', '/trustproxynumber', undefined, done)
|
|
135
|
-
})
|
|
117
|
+
const fastifyServer = await app.listen({ port: 0 })
|
|
118
|
+
await fetchForwardedRequest(fastifyServer, '2.2.2.2, 1.1.1.1', '/trustproxynumber', undefined)
|
|
136
119
|
})
|
|
137
120
|
|
|
138
|
-
test('trust proxy IP addresses',
|
|
139
|
-
t.plan(
|
|
121
|
+
test('trust proxy IP addresses', async t => {
|
|
122
|
+
t.plan(9)
|
|
140
123
|
const app = fastify({
|
|
141
124
|
trustProxy: `${localhost}, 2.2.2.2`
|
|
142
125
|
})
|
|
@@ -147,14 +130,12 @@ test('trust proxy IP addresses', (t, done) => {
|
|
|
147
130
|
reply.code(200).send({ ip: req.ip, host: req.host })
|
|
148
131
|
})
|
|
149
132
|
|
|
150
|
-
app.listen({ port: 0 }
|
|
151
|
-
|
|
152
|
-
sgetForwardedRequest(app, '3.3.3.3, 2.2.2.2, 1.1.1.1', '/trustproxyipaddrs', undefined, done)
|
|
153
|
-
})
|
|
133
|
+
const fastifyServer = await app.listen({ port: 0 })
|
|
134
|
+
await fetchForwardedRequest(fastifyServer, '3.3.3.3, 2.2.2.2, 1.1.1.1', '/trustproxyipaddrs', undefined)
|
|
154
135
|
})
|
|
155
136
|
|
|
156
|
-
test('trust proxy protocol',
|
|
157
|
-
t.plan(
|
|
137
|
+
test('trust proxy protocol', async t => {
|
|
138
|
+
t.plan(30)
|
|
158
139
|
const app = fastify({
|
|
159
140
|
trustProxy: true
|
|
160
141
|
})
|
|
@@ -173,16 +154,9 @@ test('trust proxy protocol', (t, done) => {
|
|
|
173
154
|
reply.code(200).send({ ip: req.ip, host: req.host })
|
|
174
155
|
})
|
|
175
156
|
|
|
176
|
-
app.listen({ port: 0 }
|
|
177
|
-
t.assert.ifError(err)
|
|
178
|
-
|
|
179
|
-
const completion = waitForCb({ steps: 3 })
|
|
180
|
-
sgetForwardedRequest(app, '1.1.1.1', '/trustproxyprotocol', 'lorem', completion.stepIn)
|
|
181
|
-
sgetForwardedRequest(app, '1.1.1.1', '/trustproxynoprotocol', undefined, completion.stepIn)
|
|
157
|
+
const fastifyServer = await app.listen({ port: 0 })
|
|
182
158
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
completion.patience.then(done)
|
|
187
|
-
})
|
|
159
|
+
await fetchForwardedRequest(fastifyServer, '1.1.1.1', '/trustproxyprotocol', 'lorem')
|
|
160
|
+
await fetchForwardedRequest(fastifyServer, '1.1.1.1', '/trustproxynoprotocol', undefined)
|
|
161
|
+
await fetchForwardedRequest(fastifyServer, '1.1.1.1', '/trustproxyprotocols', 'ipsum, dolor')
|
|
188
162
|
})
|
|
@@ -52,7 +52,6 @@ expectAssignable<FastifyErrorConstructor>(errorCodes.FST_ERR_SCH_DUPLICATE)
|
|
|
52
52
|
expectAssignable<FastifyErrorConstructor>(errorCodes.FST_ERR_SCH_VALIDATION_BUILD)
|
|
53
53
|
expectAssignable<FastifyErrorConstructor>(errorCodes.FST_ERR_SCH_SERIALIZATION_BUILD)
|
|
54
54
|
expectAssignable<FastifyErrorConstructor>(errorCodes.FST_ERR_SCH_RESPONSE_SCHEMA_NOT_NESTED_2XX)
|
|
55
|
-
expectAssignable<FastifyErrorConstructor>(errorCodes.FST_ERR_HTTP2_INVALID_VERSION)
|
|
56
55
|
expectAssignable<FastifyErrorConstructor>(errorCodes.FST_ERR_INIT_OPTS_INVALID)
|
|
57
56
|
expectAssignable<FastifyErrorConstructor>(errorCodes.FST_ERR_FORCE_CLOSE_CONNECTIONS_IDLE_NOT_AVAILABLE)
|
|
58
57
|
expectAssignable<FastifyErrorConstructor>(errorCodes.FST_ERR_DUPLICATED_ROUTE)
|
|
@@ -273,3 +273,6 @@ expectType<FastifyErrorCodes>(fastify.errorCodes)
|
|
|
273
273
|
fastify({ allowUnsafeRegex: true })
|
|
274
274
|
fastify({ allowUnsafeRegex: false })
|
|
275
275
|
expectError(fastify({ allowUnsafeRegex: 'invalid' }))
|
|
276
|
+
|
|
277
|
+
expectAssignable<FastifyInstance>(fastify({ allowErrorHandlerOverride: true }))
|
|
278
|
+
expectAssignable<FastifyInstance>(fastify({ allowErrorHandlerOverride: false }))
|
|
@@ -12,7 +12,7 @@ interface TestOptions extends FastifyPluginOptions {
|
|
|
12
12
|
}
|
|
13
13
|
const testOptions: TestOptions = {
|
|
14
14
|
option1: 'a',
|
|
15
|
-
option2: false
|
|
15
|
+
option2: false
|
|
16
16
|
}
|
|
17
17
|
const testPluginOpts: FastifyPluginCallback<TestOptions> = function (instance, opts, done) {
|
|
18
18
|
expectType<TestOptions>(opts)
|
|
@@ -50,7 +50,7 @@ const testPluginWithHttp2WithType = (instance: ServerWithHttp2, opts: FastifyPlu
|
|
|
50
50
|
const testPluginWithHttp2WithTypeAsync = async (instance: ServerWithHttp2, opts: FastifyPluginOptions) => { }
|
|
51
51
|
const testOptions: TestOptions = {
|
|
52
52
|
option1: 'a',
|
|
53
|
-
option2: false
|
|
53
|
+
option2: false
|
|
54
54
|
}
|
|
55
55
|
expectAssignable<ServerWithHttp2>(serverWithHttp2.register(testPluginCallback))
|
|
56
56
|
expectAssignable<ServerWithHttp2>(serverWithHttp2.register(testPluginAsync))
|
|
@@ -78,6 +78,7 @@ const getHandler: RouteHandler = function (request, _reply) {
|
|
|
78
78
|
expectType<FastifySchema | undefined>(request.routeOptions.schema)
|
|
79
79
|
expectType<RouteHandlerMethod>(request.routeOptions.handler)
|
|
80
80
|
expectType<string | undefined>(request.routeOptions.url)
|
|
81
|
+
expectType<string | undefined>(request.routeOptions.version)
|
|
81
82
|
|
|
82
83
|
expectType<RequestHeadersDefault & RawRequestDefaultExpression['headers']>(request.headers)
|
|
83
84
|
request.headers = {}
|
|
@@ -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
|
})
|
package/types/errors.d.ts
CHANGED
|
@@ -51,7 +51,6 @@ export type FastifyErrorCodes = Record<
|
|
|
51
51
|
'FST_ERR_SCH_VALIDATION_BUILD' |
|
|
52
52
|
'FST_ERR_SCH_SERIALIZATION_BUILD' |
|
|
53
53
|
'FST_ERR_SCH_RESPONSE_SCHEMA_NOT_NESTED_2XX' |
|
|
54
|
-
'FST_ERR_HTTP2_INVALID_VERSION' |
|
|
55
54
|
'FST_ERR_INIT_OPTS_INVALID' |
|
|
56
55
|
'FST_ERR_FORCE_CLOSE_CONNECTIONS_IDLE_NOT_AVAILABLE' |
|
|
57
56
|
'FST_ERR_DUPLICATED_ROUTE' |
|
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
|
/**
|
package/.taprc
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { test } = require('node:test')
|
|
4
|
-
const proxyquire = require('proxyquire')
|
|
5
|
-
const server = proxyquire('../../lib/server', { 'node:http2': null })
|
|
6
|
-
const Fastify = proxyquire('../..', { './lib/server.js': server })
|
|
7
|
-
|
|
8
|
-
test('should throw when http2 module cannot be found', t => {
|
|
9
|
-
t.plan(2)
|
|
10
|
-
try {
|
|
11
|
-
Fastify({ http2: true })
|
|
12
|
-
t.assert.fail('fastify did not throw expected error')
|
|
13
|
-
} catch (err) {
|
|
14
|
-
t.assert.strictEqual(err.code, 'FST_ERR_HTTP2_INVALID_VERSION')
|
|
15
|
-
t.assert.strictEqual(err.message, 'HTTP2 is available only from node >= 8.8.1')
|
|
16
|
-
}
|
|
17
|
-
})
|