fastify 5.0.0 → 5.2.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/.borp.yaml +3 -0
- package/.vscode/settings.json +22 -0
- package/README.md +12 -7
- package/docs/Guides/Database.md +15 -15
- package/docs/Guides/Detecting-When-Clients-Abort.md +28 -28
- package/docs/Guides/Ecosystem.md +14 -15
- package/docs/Guides/Index.md +1 -1
- package/docs/Guides/Migration-Guide-V4.md +11 -11
- package/docs/Guides/Migration-Guide-V5.md +133 -9
- package/docs/Guides/Plugins-Guide.md +1 -1
- package/docs/Guides/Prototype-Poisoning.md +3 -3
- package/docs/Guides/Recommendations.md +9 -9
- package/docs/Guides/Serverless.md +5 -5
- package/docs/Guides/Testing.md +58 -57
- package/docs/Guides/Write-Plugin.md +2 -2
- package/docs/Guides/Write-Type-Provider.md +3 -3
- package/docs/Reference/ContentTypeParser.md +4 -4
- package/docs/Reference/Decorators.md +2 -2
- package/docs/Reference/Errors.md +3 -3
- package/docs/Reference/Hooks.md +7 -7
- package/docs/Reference/LTS.md +8 -0
- package/docs/Reference/Logging.md +5 -4
- package/docs/Reference/Reply.md +55 -58
- package/docs/Reference/Request.md +49 -42
- package/docs/Reference/Routes.md +16 -13
- package/docs/Reference/Server.md +32 -28
- package/docs/Reference/TypeScript.md +9 -9
- package/docs/Reference/Validation-and-Serialization.md +5 -5
- package/examples/typescript-server.ts +1 -1
- package/fastify.d.ts +14 -5
- package/fastify.js +8 -6
- package/lib/contentTypeParser.js +9 -7
- package/lib/context.js +1 -2
- package/lib/error-handler.js +9 -9
- package/lib/errors.js +1 -1
- package/lib/fourOhFour.js +1 -1
- package/lib/hooks.js +4 -1
- package/lib/{logger.js → logger-factory.js} +70 -122
- package/lib/logger-pino.js +68 -0
- package/lib/pluginOverride.js +1 -1
- package/lib/pluginUtils.js +2 -2
- package/lib/reply.js +4 -5
- package/lib/request.js +16 -9
- package/lib/route.js +23 -22
- package/lib/validation.js +2 -2
- package/package.json +13 -15
- package/test/404s.test.js +675 -629
- package/test/500s.test.js +72 -63
- package/test/{allowUnsafeRegex.test.js → allow-unsafe-regex.test.js} +30 -26
- package/test/als.test.js +48 -45
- package/test/async-await.test.js +148 -134
- package/test/async-dispose.test.js +4 -5
- package/test/async_hooks.test.js +30 -28
- package/test/{bodyLimit.test.js → body-limit.test.js} +61 -58
- package/test/buffer.test.js +9 -10
- package/test/build/error-serializer.test.js +3 -4
- package/test/build/version.test.js +2 -3
- package/test/build-certificate.js +1 -1
- package/test/bundler/README.md +5 -5
- package/test/bundler/esbuild/bundler-test.js +10 -9
- package/test/bundler/webpack/bundler-test.js +10 -9
- package/test/case-insensitive.test.js +31 -28
- package/test/chainable.test.js +4 -5
- package/test/check.test.js +8 -10
- package/test/{childLoggerFactory.test.js → child-logger-factory.test.js} +56 -19
- package/test/client-timeout.test.js +5 -5
- package/test/close-pipelining.test.js +6 -8
- package/test/conditional-pino.test.js +47 -0
- package/test/{connectionTimeout.test.js → connection-timeout.test.js} +10 -11
- package/test/constrained-routes.test.js +243 -236
- package/test/content-length.test.js +53 -68
- package/test/content-parser.test.js +186 -158
- package/test/content-type.test.js +8 -9
- package/test/context-config.test.js +44 -54
- package/test/custom-http-server.test.js +16 -20
- package/test/custom-parser.5.test.js +32 -32
- package/test/diagnostics-channel/404.test.js +15 -15
- package/test/diagnostics-channel/async-delay-request.test.js +25 -25
- package/test/diagnostics-channel/async-request.test.js +24 -24
- package/test/diagnostics-channel/error-before-handler.test.js +4 -5
- package/test/diagnostics-channel/error-request.test.js +19 -19
- package/test/diagnostics-channel/error-status.test.js +8 -8
- package/test/diagnostics-channel/init.test.js +6 -7
- package/test/diagnostics-channel/sync-delay-request.test.js +16 -16
- package/test/diagnostics-channel/sync-request-reply.test.js +16 -16
- package/test/diagnostics-channel/sync-request.test.js +19 -19
- package/test/encapsulated-child-logger-factory.test.js +8 -8
- package/test/encapsulated-error-handler.test.js +20 -20
- package/test/esm/errorCodes.test.mjs +5 -5
- package/test/esm/esm.test.mjs +3 -3
- package/test/esm/named-exports.mjs +3 -3
- package/test/esm/other.mjs +2 -2
- package/test/fastify-instance.test.js +33 -34
- package/test/{findRoute.test.js → find-route.test.js} +11 -10
- package/test/fluent-schema.test.js +33 -36
- package/test/handler-context.test.js +11 -11
- package/test/has-route.test.js +12 -15
- package/test/header-overflow.test.js +13 -12
- package/test/hooks.on-ready.test.js +2 -2
- package/test/hooks.test.js +25 -25
- package/test/http-methods/copy.test.js +22 -24
- package/test/http-methods/custom-http-methods.test.js +24 -21
- package/test/http-methods/get.test.js +97 -84
- package/test/http-methods/head.test.js +63 -57
- package/test/http-methods/lock.test.js +21 -20
- package/test/http-methods/mkcalendar.test.js +31 -27
- package/test/http-methods/mkcol.test.js +10 -10
- package/test/http-methods/move.test.js +11 -11
- package/test/http-methods/propfind.test.js +32 -27
- package/test/http-methods/proppatch.test.js +21 -19
- package/test/http-methods/report.test.js +32 -27
- package/test/http-methods/search.test.js +52 -47
- package/test/http-methods/trace.test.js +3 -4
- package/test/http-methods/unlock.test.js +10 -10
- package/test/http2/closing.test.js +50 -58
- package/test/http2/constraint.test.js +47 -50
- package/test/http2/head.test.js +18 -19
- package/test/http2/missing-http2-module.test.js +4 -5
- package/test/http2/plain.test.js +31 -31
- package/test/http2/secure-with-fallback.test.js +61 -61
- package/test/http2/secure.test.js +28 -31
- package/test/http2/unknown-http-method.test.js +13 -14
- package/test/https/custom-https-server.test.js +6 -7
- package/test/https/https.test.js +78 -78
- package/test/imports.test.js +5 -6
- package/test/internals/all.test.js +8 -11
- package/test/internals/{contentTypeParser.test.js → content-type-parser.test.js} +5 -6
- package/test/internals/context.test.js +9 -11
- package/test/internals/decorator.test.js +20 -21
- package/test/internals/errors.test.js +427 -427
- package/test/internals/{handleRequest.test.js → handle-request.test.js} +53 -42
- package/test/internals/{hookRunner.test.js → hook-runner.test.js} +99 -100
- package/test/internals/hooks.test.js +31 -35
- package/test/internals/{initialConfig.test.js → initial-config.test.js} +92 -80
- package/test/internals/logger.test.js +28 -28
- package/test/internals/plugin.test.js +17 -18
- package/test/internals/reply-serialize.test.js +106 -106
- package/test/internals/reply.test.js +620 -585
- package/test/internals/{reqIdGenFactory.test.js → req-id-gen-factory.test.js} +31 -31
- package/test/internals/request-validate.test.js +218 -221
- package/test/internals/request.test.js +225 -107
- package/test/internals/server.test.js +15 -12
- package/test/internals/validation.test.js +35 -36
- package/test/{keepAliveTimeout.test.js → keep-alive-timeout.test.js} +9 -10
- package/test/listen.5.test.js +9 -9
- package/test/{maxRequestsPerSocket.test.js → max-requests-per-socket.test.js} +30 -30
- package/test/middleware.test.js +4 -5
- package/test/noop-set.test.js +5 -5
- package/test/post-empty-body.test.js +18 -11
- package/test/pretty-print.test.js +59 -49
- package/test/proto-poisoning.test.js +42 -37
- package/test/reply-code.test.js +34 -32
- package/test/{reply-earlyHints.test.js → reply-early-hints.test.js} +21 -19
- package/test/request-error.test.js +122 -0
- package/test/request-header-host.test.js +339 -0
- package/test/request-id.test.js +31 -25
- package/test/{requestTimeout.test.js → request-timeout.test.js} +11 -11
- package/test/route.1.test.js +79 -72
- package/test/route.2.test.js +17 -16
- package/test/route.3.test.js +32 -27
- package/test/route.4.test.js +21 -25
- package/test/route.5.test.js +45 -64
- package/test/route.6.test.js +70 -89
- package/test/route.7.test.js +61 -65
- package/test/route.8.test.js +80 -18
- package/test/router-options.test.js +80 -77
- package/test/same-shape.test.js +5 -5
- package/test/schema-examples.test.js +72 -38
- package/test/serialize-response.test.js +9 -10
- package/test/server.test.js +75 -78
- package/test/set-error-handler.test.js +2 -3
- package/test/stream-serializers.test.js +10 -7
- package/test/sync-routes.test.js +18 -18
- package/test/test-reporter.mjs +68 -0
- package/test/trust-proxy.test.js +51 -45
- package/test/type-provider.test.js +8 -6
- package/test/types/content-type-parser.test-d.ts +1 -1
- package/test/types/fastify.test-d.ts +16 -4
- package/test/types/hooks.test-d.ts +2 -1
- package/test/types/instance.test-d.ts +13 -13
- package/test/types/logger.test-d.ts +2 -2
- package/test/types/plugin.test-d.ts +17 -9
- package/test/types/register.test-d.ts +22 -6
- package/test/types/reply.test-d.ts +1 -1
- package/test/types/route.test-d.ts +34 -4
- package/test/types/serverFactory.test-d.ts +1 -1
- package/test/types/type-provider.test-d.ts +1 -1
- package/test/url-rewriting.test.js +35 -38
- package/test/{useSemicolonDelimiter.test.js → use-semicolon-delimiter.test.js} +30 -30
- package/test/validation-error-handling.test.js +259 -285
- package/test/versioned-routes.test.js +126 -113
- package/test/web-api.test.js +48 -37
- package/test/{wrapThenable.test.js → wrap-thenable.test.js} +10 -9
- package/types/hooks.d.ts +2 -1
- package/types/instance.d.ts +9 -2
- package/types/register.d.ts +12 -3
- package/types/reply.d.ts +1 -1
- package/types/request.d.ts +2 -6
- package/types/serverFactory.d.ts +3 -3
- package/types/utils.d.ts +13 -5
- package/test/types/import.js +0 -2
package/test/route.7.test.js
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
const stream = require('node:stream')
|
|
4
4
|
const split = require('split2')
|
|
5
|
-
const
|
|
6
|
-
const test = t.test
|
|
5
|
+
const { test } = require('node:test')
|
|
7
6
|
const Fastify = require('..')
|
|
7
|
+
const createError = require('@fastify/error')
|
|
8
8
|
|
|
9
|
-
test("HEAD route should handle stream.on('error')", t => {
|
|
9
|
+
test("HEAD route should handle stream.on('error')", (t, done) => {
|
|
10
10
|
t.plan(6)
|
|
11
11
|
|
|
12
12
|
const resStream = stream.Readable.from('Hello with error!')
|
|
@@ -31,23 +31,24 @@ test("HEAD route should handle stream.on('error')", t => {
|
|
|
31
31
|
|
|
32
32
|
logStream.once('data', line => {
|
|
33
33
|
const { message, stack } = expectedError
|
|
34
|
-
t.
|
|
35
|
-
t.
|
|
36
|
-
t.
|
|
34
|
+
t.assert.deepStrictEqual(line.err, { type: 'Error', message, stack })
|
|
35
|
+
t.assert.strictEqual(line.msg, 'Error on Stream found for HEAD route')
|
|
36
|
+
t.assert.strictEqual(line.level, 50)
|
|
37
37
|
})
|
|
38
38
|
|
|
39
39
|
fastify.inject({
|
|
40
40
|
method: 'HEAD',
|
|
41
41
|
url: '/more-coffee'
|
|
42
42
|
}, (error, res) => {
|
|
43
|
-
t.
|
|
44
|
-
t.
|
|
45
|
-
t.
|
|
43
|
+
t.assert.ifError(error)
|
|
44
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
45
|
+
t.assert.strictEqual(res.headers['content-type'], undefined)
|
|
46
|
+
done()
|
|
46
47
|
})
|
|
47
48
|
})
|
|
48
49
|
|
|
49
|
-
test('HEAD route should be exposed by default', t => {
|
|
50
|
-
t.plan(
|
|
50
|
+
test('HEAD route should be exposed by default', async t => {
|
|
51
|
+
t.plan(5)
|
|
51
52
|
|
|
52
53
|
const resStream = stream.Readable.from('Hello with error!')
|
|
53
54
|
const resJson = { hello: 'world' }
|
|
@@ -70,28 +71,24 @@ test('HEAD route should be exposed by default', t => {
|
|
|
70
71
|
}
|
|
71
72
|
})
|
|
72
73
|
|
|
73
|
-
fastify.inject({
|
|
74
|
+
let res = await fastify.inject({
|
|
74
75
|
method: 'HEAD',
|
|
75
76
|
url: '/without-flag'
|
|
76
|
-
}, (error, res) => {
|
|
77
|
-
t.error(error)
|
|
78
|
-
t.equal(res.statusCode, 200)
|
|
79
77
|
})
|
|
78
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
80
79
|
|
|
81
|
-
fastify.inject({
|
|
80
|
+
res = await fastify.inject({
|
|
82
81
|
method: 'HEAD',
|
|
83
82
|
url: '/with-flag'
|
|
84
|
-
}, (error, res) => {
|
|
85
|
-
t.error(error)
|
|
86
|
-
t.equal(res.statusCode, 200)
|
|
87
|
-
t.equal(res.headers['content-type'], 'application/json; charset=utf-8')
|
|
88
|
-
t.equal(res.headers['content-length'], `${Buffer.byteLength(JSON.stringify(resJson))}`)
|
|
89
|
-
t.equal(res.body, '')
|
|
90
83
|
})
|
|
84
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
85
|
+
t.assert.strictEqual(res.headers['content-type'], 'application/json; charset=utf-8')
|
|
86
|
+
t.assert.strictEqual(res.headers['content-length'], `${Buffer.byteLength(JSON.stringify(resJson))}`)
|
|
87
|
+
t.assert.strictEqual(res.body, '')
|
|
91
88
|
})
|
|
92
89
|
|
|
93
|
-
test('HEAD route should be exposed if route exposeHeadRoute is set', t => {
|
|
94
|
-
t.plan(
|
|
90
|
+
test('HEAD route should be exposed if route exposeHeadRoute is set', async t => {
|
|
91
|
+
t.plan(5)
|
|
95
92
|
|
|
96
93
|
const resBuffer = Buffer.from('I am a coffee!')
|
|
97
94
|
const resJson = { hello: 'world' }
|
|
@@ -114,27 +111,23 @@ test('HEAD route should be exposed if route exposeHeadRoute is set', t => {
|
|
|
114
111
|
}
|
|
115
112
|
})
|
|
116
113
|
|
|
117
|
-
fastify.inject({
|
|
114
|
+
let res = await fastify.inject({
|
|
118
115
|
method: 'HEAD',
|
|
119
116
|
url: '/one'
|
|
120
|
-
}, (error, res) => {
|
|
121
|
-
t.error(error)
|
|
122
|
-
t.equal(res.statusCode, 200)
|
|
123
|
-
t.equal(res.headers['content-type'], 'application/octet-stream')
|
|
124
|
-
t.equal(res.headers['content-length'], `${resBuffer.byteLength}`)
|
|
125
|
-
t.equal(res.body, '')
|
|
126
117
|
})
|
|
118
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
119
|
+
t.assert.strictEqual(res.headers['content-type'], 'application/octet-stream')
|
|
120
|
+
t.assert.strictEqual(res.headers['content-length'], `${resBuffer.byteLength}`)
|
|
121
|
+
t.assert.strictEqual(res.body, '')
|
|
127
122
|
|
|
128
|
-
fastify.inject({
|
|
123
|
+
res = await fastify.inject({
|
|
129
124
|
method: 'HEAD',
|
|
130
125
|
url: '/two'
|
|
131
|
-
}, (error, res) => {
|
|
132
|
-
t.error(error)
|
|
133
|
-
t.equal(res.statusCode, 404)
|
|
134
126
|
})
|
|
127
|
+
t.assert.strictEqual(res.statusCode, 404)
|
|
135
128
|
})
|
|
136
129
|
|
|
137
|
-
test('Set a custom HEAD route before GET one without disabling exposeHeadRoutes (global)', t => {
|
|
130
|
+
test('Set a custom HEAD route before GET one without disabling exposeHeadRoutes (global)', (t, done) => {
|
|
138
131
|
t.plan(6)
|
|
139
132
|
|
|
140
133
|
const resBuffer = Buffer.from('I am a coffee!')
|
|
@@ -165,16 +158,17 @@ test('Set a custom HEAD route before GET one without disabling exposeHeadRoutes
|
|
|
165
158
|
method: 'HEAD',
|
|
166
159
|
url: '/one'
|
|
167
160
|
}, (error, res) => {
|
|
168
|
-
t.
|
|
169
|
-
t.
|
|
170
|
-
t.
|
|
171
|
-
t.
|
|
172
|
-
t.
|
|
173
|
-
t.
|
|
161
|
+
t.assert.ifError(error)
|
|
162
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
163
|
+
t.assert.strictEqual(res.headers['content-type'], 'application/pdf')
|
|
164
|
+
t.assert.strictEqual(res.headers['content-length'], `${resBuffer.byteLength}`)
|
|
165
|
+
t.assert.strictEqual(res.headers['x-custom-header'], 'some-custom-header')
|
|
166
|
+
t.assert.strictEqual(res.body, '')
|
|
167
|
+
done()
|
|
174
168
|
})
|
|
175
169
|
})
|
|
176
170
|
|
|
177
|
-
test('Set a custom HEAD route before GET one without disabling exposeHeadRoutes (route)', t => {
|
|
171
|
+
test('Set a custom HEAD route before GET one without disabling exposeHeadRoutes (route)', (t, done) => {
|
|
178
172
|
t.plan(6)
|
|
179
173
|
|
|
180
174
|
const fastify = Fastify()
|
|
@@ -205,16 +199,17 @@ test('Set a custom HEAD route before GET one without disabling exposeHeadRoutes
|
|
|
205
199
|
method: 'HEAD',
|
|
206
200
|
url: '/one'
|
|
207
201
|
}, (error, res) => {
|
|
208
|
-
t.
|
|
209
|
-
t.
|
|
210
|
-
t.
|
|
211
|
-
t.
|
|
212
|
-
t.
|
|
213
|
-
t.
|
|
202
|
+
t.assert.ifError(error)
|
|
203
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
204
|
+
t.assert.strictEqual(res.headers['content-type'], 'application/pdf')
|
|
205
|
+
t.assert.strictEqual(res.headers['content-length'], `${resBuffer.byteLength}`)
|
|
206
|
+
t.assert.strictEqual(res.headers['x-custom-header'], 'some-custom-header')
|
|
207
|
+
t.assert.strictEqual(res.body, '')
|
|
208
|
+
done()
|
|
214
209
|
})
|
|
215
210
|
})
|
|
216
211
|
|
|
217
|
-
test('HEAD routes properly auto created for GET routes when prefixTrailingSlash: \'no-slash\'', t => {
|
|
212
|
+
test('HEAD routes properly auto created for GET routes when prefixTrailingSlash: \'no-slash\'', (t, done) => {
|
|
218
213
|
t.plan(2)
|
|
219
214
|
|
|
220
215
|
const fastify = Fastify()
|
|
@@ -234,8 +229,9 @@ test('HEAD routes properly auto created for GET routes when prefixTrailingSlash:
|
|
|
234
229
|
}, { prefix: '/prefix' })
|
|
235
230
|
|
|
236
231
|
fastify.inject({ url: '/prefix/prefix', method: 'HEAD' }, (err, res) => {
|
|
237
|
-
t.
|
|
238
|
-
t.
|
|
232
|
+
t.assert.ifError(err)
|
|
233
|
+
t.assert.strictEqual(res.statusCode, 404)
|
|
234
|
+
done()
|
|
239
235
|
})
|
|
240
236
|
})
|
|
241
237
|
|
|
@@ -262,9 +258,9 @@ test('HEAD routes properly auto created for GET routes when prefixTrailingSlash:
|
|
|
262
258
|
const trailingSlashReply = await fastify.inject({ url: '/prefix/', method: 'HEAD' })
|
|
263
259
|
const noneTrailingReply = await fastify.inject({ url: '/prefix', method: 'HEAD' })
|
|
264
260
|
|
|
265
|
-
t.
|
|
266
|
-
t.
|
|
267
|
-
t.
|
|
261
|
+
t.assert.strictEqual(doublePrefixReply.statusCode, 404)
|
|
262
|
+
t.assert.strictEqual(trailingSlashReply.statusCode, 200)
|
|
263
|
+
t.assert.strictEqual(noneTrailingReply.statusCode, 200)
|
|
268
264
|
})
|
|
269
265
|
|
|
270
266
|
test('GET route with body schema should throw', t => {
|
|
@@ -272,7 +268,7 @@ test('GET route with body schema should throw', t => {
|
|
|
272
268
|
|
|
273
269
|
const fastify = Fastify()
|
|
274
270
|
|
|
275
|
-
t.throws(() => {
|
|
271
|
+
t.assert.throws(() => {
|
|
276
272
|
fastify.route({
|
|
277
273
|
method: 'GET',
|
|
278
274
|
path: '/get',
|
|
@@ -283,7 +279,7 @@ test('GET route with body schema should throw', t => {
|
|
|
283
279
|
reply.send({ hello: 'world' })
|
|
284
280
|
}
|
|
285
281
|
})
|
|
286
|
-
},
|
|
282
|
+
}, createError('FST_ERR_ROUTE_BODY_VALIDATION_SCHEMA_NOT_SUPPORTED', 'Body validation schema for GET:/get route is not supported!')())
|
|
287
283
|
})
|
|
288
284
|
|
|
289
285
|
test('HEAD route with body schema should throw', t => {
|
|
@@ -291,7 +287,7 @@ test('HEAD route with body schema should throw', t => {
|
|
|
291
287
|
|
|
292
288
|
const fastify = Fastify()
|
|
293
289
|
|
|
294
|
-
t.throws(() => {
|
|
290
|
+
t.assert.throws(() => {
|
|
295
291
|
fastify.route({
|
|
296
292
|
method: 'HEAD',
|
|
297
293
|
path: '/shouldThrow',
|
|
@@ -302,7 +298,7 @@ test('HEAD route with body schema should throw', t => {
|
|
|
302
298
|
reply.send({ hello: 'world' })
|
|
303
299
|
}
|
|
304
300
|
})
|
|
305
|
-
},
|
|
301
|
+
}, createError('FST_ERR_ROUTE_BODY_VALIDATION_SCHEMA_NOT_SUPPORTED', 'Body validation schema for HEAD:/shouldThrow route is not supported!')())
|
|
306
302
|
})
|
|
307
303
|
|
|
308
304
|
test('[HEAD, GET] route with body schema should throw', t => {
|
|
@@ -310,7 +306,7 @@ test('[HEAD, GET] route with body schema should throw', t => {
|
|
|
310
306
|
|
|
311
307
|
const fastify = Fastify()
|
|
312
308
|
|
|
313
|
-
t.throws(() => {
|
|
309
|
+
t.assert.throws(() => {
|
|
314
310
|
fastify.route({
|
|
315
311
|
method: ['HEAD', 'GET'],
|
|
316
312
|
path: '/shouldThrowHead',
|
|
@@ -321,7 +317,7 @@ test('[HEAD, GET] route with body schema should throw', t => {
|
|
|
321
317
|
reply.send({ hello: 'world' })
|
|
322
318
|
}
|
|
323
319
|
})
|
|
324
|
-
},
|
|
320
|
+
}, createError('FST_ERR_ROUTE_BODY_VALIDATION_SCHEMA_NOT_SUPPORTED', 'Body validation schema for HEAD:/shouldThrowHead route is not supported!')())
|
|
325
321
|
})
|
|
326
322
|
|
|
327
323
|
test('GET route with body schema should throw - shorthand', t => {
|
|
@@ -329,7 +325,7 @@ test('GET route with body schema should throw - shorthand', t => {
|
|
|
329
325
|
|
|
330
326
|
const fastify = Fastify()
|
|
331
327
|
|
|
332
|
-
t.throws(() => {
|
|
328
|
+
t.assert.throws(() => {
|
|
333
329
|
fastify.get('/shouldThrow', {
|
|
334
330
|
schema: {
|
|
335
331
|
body: {}
|
|
@@ -339,7 +335,7 @@ test('GET route with body schema should throw - shorthand', t => {
|
|
|
339
335
|
reply.send({ hello: 'world' })
|
|
340
336
|
}
|
|
341
337
|
)
|
|
342
|
-
},
|
|
338
|
+
}, createError('FST_ERR_ROUTE_BODY_VALIDATION_SCHEMA_NOT_SUPPORTED', 'Body validation schema for GET:/shouldThrow route is not supported!')())
|
|
343
339
|
})
|
|
344
340
|
|
|
345
341
|
test('HEAD route with body schema should throw - shorthand', t => {
|
|
@@ -347,7 +343,7 @@ test('HEAD route with body schema should throw - shorthand', t => {
|
|
|
347
343
|
|
|
348
344
|
const fastify = Fastify()
|
|
349
345
|
|
|
350
|
-
t.throws(() => {
|
|
346
|
+
t.assert.throws(() => {
|
|
351
347
|
fastify.head('/shouldThrow2', {
|
|
352
348
|
schema: {
|
|
353
349
|
body: {}
|
|
@@ -357,5 +353,5 @@ test('HEAD route with body schema should throw - shorthand', t => {
|
|
|
357
353
|
reply.send({ hello: 'world' })
|
|
358
354
|
}
|
|
359
355
|
)
|
|
360
|
-
},
|
|
356
|
+
}, createError('FST_ERR_ROUTE_BODY_VALIDATION_SCHEMA_NOT_SUPPORTED', 'Body validation schema for HEAD:/shouldThrow2 route is not supported!')())
|
|
361
357
|
})
|
package/test/route.8.test.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const test = t.test
|
|
3
|
+
const { test } = require('node:test')
|
|
5
4
|
const sget = require('simple-get').concat
|
|
6
|
-
const Fastify = require('
|
|
5
|
+
const Fastify = require('..')
|
|
7
6
|
const {
|
|
8
7
|
FST_ERR_INVALID_URL
|
|
9
8
|
} = require('../lib/errors')
|
|
@@ -24,9 +23,9 @@ test('Request and Reply share the route options', async t => {
|
|
|
24
23
|
url: '/',
|
|
25
24
|
config,
|
|
26
25
|
handler: (req, reply) => {
|
|
27
|
-
t.
|
|
28
|
-
t.
|
|
29
|
-
t.match(req.routeOptions.config, config, 'there are url and method additional properties')
|
|
26
|
+
t.assert.deepStrictEqual(req.routeOptions, reply.routeOptions)
|
|
27
|
+
t.assert.deepStrictEqual(req.routeOptions.config, reply.routeOptions.config)
|
|
28
|
+
t.assert.match(req.routeOptions.config, config, 'there are url and method additional properties')
|
|
30
29
|
|
|
31
30
|
reply.send({ hello: 'world' })
|
|
32
31
|
}
|
|
@@ -62,10 +61,10 @@ test('Will not try to re-createprefixed HEAD route if it already exists and expo
|
|
|
62
61
|
|
|
63
62
|
await fastify.ready()
|
|
64
63
|
|
|
65
|
-
t.ok(true)
|
|
64
|
+
t.assert.ok(true)
|
|
66
65
|
})
|
|
67
66
|
|
|
68
|
-
test('route with non-english characters', t => {
|
|
67
|
+
test('route with non-english characters', (t, done) => {
|
|
69
68
|
t.plan(4)
|
|
70
69
|
|
|
71
70
|
const fastify = Fastify()
|
|
@@ -75,16 +74,17 @@ test('route with non-english characters', t => {
|
|
|
75
74
|
})
|
|
76
75
|
|
|
77
76
|
fastify.listen({ port: 0 }, err => {
|
|
78
|
-
t.
|
|
79
|
-
t.
|
|
77
|
+
t.assert.ifError(err)
|
|
78
|
+
t.after(() => fastify.close())
|
|
80
79
|
|
|
81
80
|
sget({
|
|
82
81
|
method: 'GET',
|
|
83
82
|
url: getServerUrl(fastify) + encodeURI('/föö')
|
|
84
83
|
}, (err, response, body) => {
|
|
85
|
-
t.
|
|
86
|
-
t.
|
|
87
|
-
t.
|
|
84
|
+
t.assert.ifError(err)
|
|
85
|
+
t.assert.strictEqual(response.statusCode, 200)
|
|
86
|
+
t.assert.strictEqual(body.toString(), 'here /föö')
|
|
87
|
+
done()
|
|
88
88
|
})
|
|
89
89
|
})
|
|
90
90
|
})
|
|
@@ -96,7 +96,7 @@ test('invalid url attribute - non string URL', t => {
|
|
|
96
96
|
try {
|
|
97
97
|
fastify.get(/^\/(donations|skills|blogs)/, () => { })
|
|
98
98
|
} catch (error) {
|
|
99
|
-
t.
|
|
99
|
+
t.assert.strictEqual(error.code, FST_ERR_INVALID_URL().code)
|
|
100
100
|
}
|
|
101
101
|
})
|
|
102
102
|
|
|
@@ -117,7 +117,7 @@ test('exposeHeadRoute should not reuse the same route option', async t => {
|
|
|
117
117
|
})
|
|
118
118
|
|
|
119
119
|
fastify.addHook('onRoute', function (routeOption) {
|
|
120
|
-
t.
|
|
120
|
+
t.assert.strictEqual(routeOption.onRequest.length, 1)
|
|
121
121
|
})
|
|
122
122
|
|
|
123
123
|
fastify.route({
|
|
@@ -140,7 +140,7 @@ test('using fastify.all when a catchall is defined does not degrade performance'
|
|
|
140
140
|
fastify.all(`/${i}`, async (_, reply) => reply.json({ ok: true }))
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
-
t.
|
|
143
|
+
t.assert.ok("fastify.all doesn't degrade performance")
|
|
144
144
|
})
|
|
145
145
|
|
|
146
146
|
test('Adding manually HEAD route after GET with the same path throws Fastify duplicated route instance error', t => {
|
|
@@ -164,8 +164,70 @@ test('Adding manually HEAD route after GET with the same path throws Fastify dup
|
|
|
164
164
|
reply.send({ hello: 'world' })
|
|
165
165
|
}
|
|
166
166
|
})
|
|
167
|
-
t.fail('Should throw fastify duplicated route declaration')
|
|
167
|
+
t.assert.fail('Should throw fastify duplicated route declaration')
|
|
168
168
|
} catch (error) {
|
|
169
|
-
t.
|
|
169
|
+
t.assert.strictEqual(error.code, 'FST_ERR_DUPLICATED_ROUTE')
|
|
170
170
|
}
|
|
171
171
|
})
|
|
172
|
+
|
|
173
|
+
test('Will pass onSend hook to HEAD method if exposeHeadRoutes is true /1', async (t) => {
|
|
174
|
+
t.plan(1)
|
|
175
|
+
|
|
176
|
+
const fastify = Fastify({ exposeHeadRoutes: true })
|
|
177
|
+
|
|
178
|
+
await fastify.register((scope, opts, next) => {
|
|
179
|
+
scope.route({
|
|
180
|
+
method: 'GET',
|
|
181
|
+
path: '/route',
|
|
182
|
+
handler: (req, reply) => {
|
|
183
|
+
reply.send({ ok: true })
|
|
184
|
+
},
|
|
185
|
+
onSend: (req, reply, payload, done) => {
|
|
186
|
+
reply.header('x-content-type', 'application/fastify')
|
|
187
|
+
done(null, payload)
|
|
188
|
+
}
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
next()
|
|
192
|
+
}, { prefix: '/prefix' })
|
|
193
|
+
|
|
194
|
+
await fastify.ready()
|
|
195
|
+
|
|
196
|
+
const result = await fastify.inject({
|
|
197
|
+
url: '/prefix/route',
|
|
198
|
+
method: 'HEAD'
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
t.assert.strictEqual(result.headers['x-content-type'], 'application/fastify')
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
test('Will pass onSend hook to HEAD method if exposeHeadRoutes is true /2', async (t) => {
|
|
205
|
+
t.plan(1)
|
|
206
|
+
|
|
207
|
+
const fastify = Fastify({ exposeHeadRoutes: true })
|
|
208
|
+
|
|
209
|
+
await fastify.register((scope, opts, next) => {
|
|
210
|
+
scope.route({
|
|
211
|
+
method: 'get',
|
|
212
|
+
path: '/route',
|
|
213
|
+
handler: (req, reply) => {
|
|
214
|
+
reply.send({ ok: true })
|
|
215
|
+
},
|
|
216
|
+
onSend: (req, reply, payload, done) => {
|
|
217
|
+
reply.header('x-content-type', 'application/fastify')
|
|
218
|
+
done(null, payload)
|
|
219
|
+
}
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
next()
|
|
223
|
+
}, { prefix: '/prefix' })
|
|
224
|
+
|
|
225
|
+
await fastify.ready()
|
|
226
|
+
|
|
227
|
+
const result = await fastify.inject({
|
|
228
|
+
url: '/prefix/route',
|
|
229
|
+
method: 'HEAD'
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
t.assert.strictEqual(result.headers['x-content-type'], 'application/fastify')
|
|
233
|
+
})
|