fastify 5.2.1 → 5.3.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/LICENSE +1 -1
- package/PROJECT_CHARTER.md +7 -7
- package/README.md +24 -25
- package/SPONSORS.md +1 -0
- package/docs/Guides/Benchmarking.md +4 -4
- package/docs/Guides/Database.md +1 -1
- package/docs/Guides/Delay-Accepting-Requests.md +10 -10
- package/docs/Guides/Ecosystem.md +7 -1
- package/docs/Guides/Fluent-Schema.md +1 -1
- package/docs/Guides/Getting-Started.md +9 -5
- package/docs/Guides/Index.md +1 -1
- package/docs/Guides/Migration-Guide-V4.md +1 -1
- package/docs/Guides/Migration-Guide-V5.md +12 -2
- package/docs/Guides/Plugins-Guide.md +6 -6
- package/docs/Guides/Serverless.md +14 -48
- package/docs/Guides/Style-Guide.md +2 -2
- package/docs/Guides/Testing.md +2 -2
- package/docs/Guides/Write-Plugin.md +2 -3
- package/docs/Reference/ContentTypeParser.md +58 -78
- package/docs/Reference/Decorators.md +249 -60
- package/docs/Reference/Encapsulation.md +28 -33
- package/docs/Reference/Errors.md +52 -53
- package/docs/Reference/HTTP2.md +7 -7
- package/docs/Reference/Hooks.md +31 -30
- package/docs/Reference/LTS.md +10 -15
- package/docs/Reference/Lifecycle.md +19 -24
- package/docs/Reference/Logging.md +59 -56
- package/docs/Reference/Middleware.md +19 -19
- package/docs/Reference/Plugins.md +55 -71
- package/docs/Reference/Principles.md +25 -30
- package/docs/Reference/Reply.md +11 -10
- package/docs/Reference/Request.md +89 -98
- package/docs/Reference/Routes.md +108 -128
- package/docs/Reference/Server.md +18 -16
- package/docs/Reference/Type-Providers.md +19 -21
- package/docs/Reference/TypeScript.md +1 -18
- package/docs/Reference/Validation-and-Serialization.md +134 -159
- package/docs/Reference/Warnings.md +22 -25
- package/fastify.js +3 -2
- package/lib/contentTypeParser.js +7 -8
- package/lib/decorate.js +18 -3
- package/lib/error-handler.js +14 -12
- package/lib/errors.js +4 -0
- package/lib/headRoute.js +4 -2
- package/lib/pluginUtils.js +4 -2
- package/lib/reply.js +17 -2
- package/lib/request.js +28 -2
- package/lib/server.js +5 -0
- package/lib/validation.js +1 -1
- package/lib/warnings.js +9 -0
- package/lib/wrapThenable.js +8 -1
- package/package.json +12 -12
- package/test/bundler/esbuild/package.json +1 -1
- package/test/close.test.js +125 -108
- package/test/custom-parser-async.test.js +34 -36
- package/test/custom-parser.4.test.js +55 -38
- package/test/decorator.test.js +174 -4
- package/test/fastify-instance.test.js +12 -2
- package/test/genReqId.test.js +125 -174
- package/test/has-route.test.js +1 -3
- package/test/hooks.on-listen.test.js +17 -14
- package/test/internals/content-type-parser.test.js +1 -1
- package/test/internals/errors.test.js +14 -1
- package/test/issue-4959.test.js +84 -0
- package/test/listen.1.test.js +37 -34
- package/test/listen.2.test.js +50 -40
- package/test/listen.3.test.js +28 -32
- package/test/listen.4.test.js +61 -45
- package/test/listen.5.test.js +23 -0
- package/test/register.test.js +55 -50
- package/test/request-error.test.js +114 -94
- package/test/route-shorthand.test.js +36 -32
- package/test/stream.5.test.js +35 -33
- package/test/throw.test.js +87 -91
- package/test/toolkit.js +32 -0
- package/test/trust-proxy.test.js +23 -23
- package/test/types/instance.test-d.ts +4 -0
- package/test/types/reply.test-d.ts +1 -0
- package/test/types/request.test-d.ts +4 -0
- package/test/types/type-provider.test-d.ts +40 -0
- package/test/upgrade.test.js +32 -33
- package/types/instance.d.ts +6 -0
- package/types/reply.d.ts +1 -0
- package/types/request.d.ts +2 -0
- package/types/type-provider.d.ts +12 -3
package/test/trust-proxy.test.js
CHANGED
|
@@ -4,6 +4,7 @@ const { test, before } = require('node:test')
|
|
|
4
4
|
const sget = require('simple-get').concat
|
|
5
5
|
const fastify = require('..')
|
|
6
6
|
const helper = require('./helper')
|
|
7
|
+
const { waitForCb } = require('./toolkit')
|
|
7
8
|
|
|
8
9
|
const noop = () => {}
|
|
9
10
|
|
|
@@ -69,18 +70,14 @@ test('trust proxy, not add properties to node req', (t, done) => {
|
|
|
69
70
|
})
|
|
70
71
|
|
|
71
72
|
app.listen({ port: 0 }, (err) => {
|
|
72
|
-
app.server.unref()
|
|
73
73
|
t.assert.ifError(err)
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
sgetForwardedRequest(app, '2.2.2.2, 1.1.1.1', '/trustproxychain', undefined, completed)
|
|
75
|
+
const completion = waitForCb({ steps: 2 })
|
|
77
76
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
}
|
|
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)
|
|
79
|
+
|
|
80
|
+
completion.patience.then(done)
|
|
84
81
|
})
|
|
85
82
|
})
|
|
86
83
|
|
|
@@ -89,6 +86,7 @@ test('trust proxy chain', (t, done) => {
|
|
|
89
86
|
const app = fastify({
|
|
90
87
|
trustProxy: [localhost, '192.168.1.1']
|
|
91
88
|
})
|
|
89
|
+
t.after(() => app.close())
|
|
92
90
|
|
|
93
91
|
app.get('/trustproxychain', function (req, reply) {
|
|
94
92
|
testRequestValues(t, req, { ip: '1.1.1.1', host: 'example.com', port: app.server.address().port })
|
|
@@ -96,9 +94,7 @@ test('trust proxy chain', (t, done) => {
|
|
|
96
94
|
})
|
|
97
95
|
|
|
98
96
|
app.listen({ port: 0 }, (err) => {
|
|
99
|
-
app.server.unref()
|
|
100
97
|
t.assert.ifError(err)
|
|
101
|
-
t.after(() => app.close())
|
|
102
98
|
sgetForwardedRequest(app, '192.168.1.1, 1.1.1.1', '/trustproxychain', undefined, done)
|
|
103
99
|
})
|
|
104
100
|
})
|
|
@@ -108,15 +104,15 @@ test('trust proxy function', (t, done) => {
|
|
|
108
104
|
const app = fastify({
|
|
109
105
|
trustProxy: (address) => address === localhost
|
|
110
106
|
})
|
|
107
|
+
t.after(() => app.close())
|
|
108
|
+
|
|
111
109
|
app.get('/trustproxyfunc', function (req, reply) {
|
|
112
110
|
testRequestValues(t, req, { ip: '1.1.1.1', host: 'example.com', port: app.server.address().port })
|
|
113
111
|
reply.code(200).send({ ip: req.ip, host: req.host })
|
|
114
112
|
})
|
|
115
113
|
|
|
116
114
|
app.listen({ port: 0 }, (err) => {
|
|
117
|
-
app.server.unref()
|
|
118
115
|
t.assert.ifError(err)
|
|
119
|
-
t.after(() => app.close())
|
|
120
116
|
sgetForwardedRequest(app, '1.1.1.1', '/trustproxyfunc', undefined, done)
|
|
121
117
|
})
|
|
122
118
|
})
|
|
@@ -126,15 +122,15 @@ test('trust proxy number', (t, done) => {
|
|
|
126
122
|
const app = fastify({
|
|
127
123
|
trustProxy: 1
|
|
128
124
|
})
|
|
125
|
+
t.after(() => app.close())
|
|
126
|
+
|
|
129
127
|
app.get('/trustproxynumber', function (req, reply) {
|
|
130
128
|
testRequestValues(t, req, { ip: '1.1.1.1', ips: [localhost, '1.1.1.1'], host: 'example.com', port: app.server.address().port })
|
|
131
129
|
reply.code(200).send({ ip: req.ip, host: req.host })
|
|
132
130
|
})
|
|
133
131
|
|
|
134
132
|
app.listen({ port: 0 }, (err) => {
|
|
135
|
-
app.server.unref()
|
|
136
133
|
t.assert.ifError(err)
|
|
137
|
-
t.after(() => app.close())
|
|
138
134
|
sgetForwardedRequest(app, '2.2.2.2, 1.1.1.1', '/trustproxynumber', undefined, done)
|
|
139
135
|
})
|
|
140
136
|
})
|
|
@@ -144,15 +140,15 @@ test('trust proxy IP addresses', (t, done) => {
|
|
|
144
140
|
const app = fastify({
|
|
145
141
|
trustProxy: `${localhost}, 2.2.2.2`
|
|
146
142
|
})
|
|
143
|
+
t.after(() => app.close())
|
|
144
|
+
|
|
147
145
|
app.get('/trustproxyipaddrs', function (req, reply) {
|
|
148
146
|
testRequestValues(t, req, { ip: '1.1.1.1', ips: [localhost, '1.1.1.1'], host: 'example.com', port: app.server.address().port })
|
|
149
147
|
reply.code(200).send({ ip: req.ip, host: req.host })
|
|
150
148
|
})
|
|
151
149
|
|
|
152
150
|
app.listen({ port: 0 }, (err) => {
|
|
153
|
-
app.server.unref()
|
|
154
151
|
t.assert.ifError(err)
|
|
155
|
-
t.after(() => app.close())
|
|
156
152
|
sgetForwardedRequest(app, '3.3.3.3, 2.2.2.2, 1.1.1.1', '/trustproxyipaddrs', undefined, done)
|
|
157
153
|
})
|
|
158
154
|
})
|
|
@@ -162,6 +158,8 @@ test('trust proxy protocol', (t, done) => {
|
|
|
162
158
|
const app = fastify({
|
|
163
159
|
trustProxy: true
|
|
164
160
|
})
|
|
161
|
+
t.after(() => app.close())
|
|
162
|
+
|
|
165
163
|
app.get('/trustproxyprotocol', function (req, reply) {
|
|
166
164
|
testRequestValues(t, req, { ip: '1.1.1.1', protocol: 'lorem', host: 'example.com', port: app.server.address().port })
|
|
167
165
|
reply.code(200).send({ ip: req.ip, host: req.host })
|
|
@@ -175,14 +173,16 @@ test('trust proxy protocol', (t, done) => {
|
|
|
175
173
|
reply.code(200).send({ ip: req.ip, host: req.host })
|
|
176
174
|
})
|
|
177
175
|
|
|
178
|
-
t.after(() => app.close())
|
|
179
|
-
|
|
180
176
|
app.listen({ port: 0 }, (err) => {
|
|
181
|
-
app.server.unref()
|
|
182
177
|
t.assert.ifError(err)
|
|
183
|
-
|
|
184
|
-
|
|
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)
|
|
182
|
+
|
|
185
183
|
// Allow for sgetForwardedRequest requests above to finish
|
|
186
|
-
setTimeout(() => sgetForwardedRequest(app, '1.1.1.1', '/trustproxyprotocols', 'ipsum, dolor',
|
|
184
|
+
setTimeout(() => sgetForwardedRequest(app, '1.1.1.1', '/trustproxyprotocols', 'ipsum, dolor', completion.stepIn))
|
|
185
|
+
|
|
186
|
+
completion.patience.then(done)
|
|
187
187
|
})
|
|
188
188
|
})
|
|
@@ -36,6 +36,7 @@ expectType<unknown>(server.getSchema('SchemaId'))
|
|
|
36
36
|
expectType<string>(server.printRoutes())
|
|
37
37
|
expectType<string>(server.printPlugins())
|
|
38
38
|
expectType<string>(server.listeningOrigin)
|
|
39
|
+
expectType<string[]>(server.supportedMethods)
|
|
39
40
|
|
|
40
41
|
expectAssignable<FastifyInstance>(
|
|
41
42
|
server.setErrorHandler(function (error, request, reply) {
|
|
@@ -521,6 +522,9 @@ expectError(server.decorateReply('typedTestReplyMethod', async function (x) {
|
|
|
521
522
|
return 'foo'
|
|
522
523
|
}))
|
|
523
524
|
|
|
525
|
+
const foo = server.getDecorator<string>('foo')
|
|
526
|
+
expectType<string>(foo)
|
|
527
|
+
|
|
524
528
|
const versionConstraintStrategy = {
|
|
525
529
|
name: 'version',
|
|
526
530
|
storage: () => ({
|
|
@@ -45,6 +45,7 @@ const getHandler: RouteHandlerMethod = function (_request, reply) {
|
|
|
45
45
|
expectAssignable<((input: { [key: string]: unknown }, schema: { [key: string]: unknown }, httpStatus?: string) => unknown)>(reply.serializeInput)
|
|
46
46
|
expectAssignable<((input: { [key: string]: unknown }, httpStatus: string) => unknown)>(reply.serializeInput)
|
|
47
47
|
expectType<ContextConfigDefault & FastifyRouteConfig & FastifyContextConfig>(reply.routeOptions.config)
|
|
48
|
+
expectType<string>(reply.getDecorator<string>('foo'))
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
interface ReplyPayload {
|
|
@@ -92,6 +92,10 @@ const getHandler: RouteHandler = function (request, _reply) {
|
|
|
92
92
|
expectAssignable<(schema: { [key: string]: unknown }) => ExpectedGetValidationFunction>(request.getValidationFunction)
|
|
93
93
|
expectAssignable<(input: { [key: string]: unknown }, schema: { [key: string]: unknown }, httpPart?: HTTPRequestPart) => boolean>(request.validateInput)
|
|
94
94
|
expectAssignable<(input: { [key: string]: unknown }, httpPart?: HTTPRequestPart) => boolean>(request.validateInput)
|
|
95
|
+
expectType<string>(request.getDecorator<string>('foo'))
|
|
96
|
+
expectType<void>(request.setDecorator('foo', 'hello'))
|
|
97
|
+
expectType<void>(request.setDecorator<string>('foo', 'hello'))
|
|
98
|
+
expectError(request.setDecorator<string>('foo', true))
|
|
95
99
|
}
|
|
96
100
|
|
|
97
101
|
const getHandlerWithCustomLogger: RouteHandlerMethod<RawServerDefault, RawRequestDefaultExpression, RawReplyDefaultExpression, RouteGenericInterface, ContextConfigDefault, FastifySchema, FastifyTypeProviderDefault, CustomLoggerInterface> = function (request, _reply) {
|
|
@@ -1009,6 +1009,46 @@ expectAssignable(server.withTypeProvider<JsonSchemaToTsProvider>().get<{ Reply:
|
|
|
1009
1009
|
}
|
|
1010
1010
|
))
|
|
1011
1011
|
|
|
1012
|
+
// -------------------------------------------------------------------
|
|
1013
|
+
// RouteGeneric Reply Type Return (Different Status Codes)
|
|
1014
|
+
// -------------------------------------------------------------------
|
|
1015
|
+
|
|
1016
|
+
expectAssignable(server.get<{
|
|
1017
|
+
Reply: {
|
|
1018
|
+
200: string | { msg: string }
|
|
1019
|
+
400: number
|
|
1020
|
+
'5xx': { error: string }
|
|
1021
|
+
}
|
|
1022
|
+
}>(
|
|
1023
|
+
'/',
|
|
1024
|
+
async (_, res) => {
|
|
1025
|
+
const option = 1 as 1 | 2 | 3 | 4
|
|
1026
|
+
switch (option) {
|
|
1027
|
+
case 1: return 'hello'
|
|
1028
|
+
case 2: return { msg: 'hello' }
|
|
1029
|
+
case 3: return 400
|
|
1030
|
+
case 4: return { error: 'error' }
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
))
|
|
1034
|
+
|
|
1035
|
+
// -------------------------------------------------------------------
|
|
1036
|
+
// RouteGeneric Reply Type Return: Non Assignable (Different Status Codes)
|
|
1037
|
+
// -------------------------------------------------------------------
|
|
1038
|
+
|
|
1039
|
+
expectError(server.get<{
|
|
1040
|
+
Reply: {
|
|
1041
|
+
200: string | { msg: string }
|
|
1042
|
+
400: number
|
|
1043
|
+
'5xx': { error: string }
|
|
1044
|
+
}
|
|
1045
|
+
}>(
|
|
1046
|
+
'/',
|
|
1047
|
+
async (_, res) => {
|
|
1048
|
+
return true
|
|
1049
|
+
}
|
|
1050
|
+
))
|
|
1051
|
+
|
|
1012
1052
|
// -------------------------------------------------------------------
|
|
1013
1053
|
// FastifyPlugin: Auxiliary
|
|
1014
1054
|
// -------------------------------------------------------------------
|
package/test/upgrade.test.js
CHANGED
|
@@ -1,53 +1,52 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const {
|
|
3
|
+
const { describe, test } = require('node:test')
|
|
4
4
|
const Fastify = require('..')
|
|
5
5
|
const { connect } = require('node:net')
|
|
6
6
|
const { once } = require('node:events')
|
|
7
7
|
const dns = require('node:dns').promises
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
describe('upgrade to both servers', async () => {
|
|
10
10
|
const localAddresses = await dns.lookup('localhost', { all: true })
|
|
11
|
-
|
|
12
|
-
skip('requires both IPv4 and IPv6')
|
|
13
|
-
return
|
|
14
|
-
}
|
|
11
|
+
const skip = localAddresses.length === 1 && 'requires both IPv4 and IPv6'
|
|
15
12
|
|
|
16
|
-
test('upgrade
|
|
13
|
+
await test('upgrade IPv4 and IPv6', { skip }, async t => {
|
|
17
14
|
t.plan(2)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
|
|
16
|
+
const fastify = Fastify()
|
|
17
|
+
fastify.server.on('upgrade', (req, socket, head) => {
|
|
18
|
+
t.assert.ok(`upgrade event ${JSON.stringify(socket.address())}`)
|
|
21
19
|
socket.end()
|
|
22
20
|
})
|
|
23
|
-
|
|
21
|
+
|
|
22
|
+
fastify.get('/', (req, res) => {
|
|
23
|
+
res.send()
|
|
24
24
|
})
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
|
|
26
|
+
await fastify.listen()
|
|
27
|
+
t.after(() => fastify.close())
|
|
27
28
|
|
|
28
29
|
{
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
await once(
|
|
30
|
+
const clientIPv4 = connect(fastify.server.address().port, '127.0.0.1')
|
|
31
|
+
clientIPv4.write('GET / HTTP/1.1\r\n')
|
|
32
|
+
clientIPv4.write('Upgrade: websocket\r\n')
|
|
33
|
+
clientIPv4.write('Connection: Upgrade\r\n')
|
|
34
|
+
clientIPv4.write('Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\r\n')
|
|
35
|
+
clientIPv4.write('Sec-WebSocket-Protocol: com.xxx.service.v1\r\n')
|
|
36
|
+
clientIPv4.write('Sec-WebSocket-Version: 13\r\n\r\n')
|
|
37
|
+
clientIPv4.write('\r\n\r\n')
|
|
38
|
+
await once(clientIPv4, 'close')
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
{
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
await once(
|
|
42
|
+
const clientIPv6 = connect(fastify.server.address().port, '::1')
|
|
43
|
+
clientIPv6.write('GET / HTTP/1.1\r\n')
|
|
44
|
+
clientIPv6.write('Upgrade: websocket\r\n')
|
|
45
|
+
clientIPv6.write('Connection: Upgrade\r\n')
|
|
46
|
+
clientIPv6.write('Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\r\n')
|
|
47
|
+
clientIPv6.write('Sec-WebSocket-Protocol: com.xxx.service.v1\r\n')
|
|
48
|
+
clientIPv6.write('Sec-WebSocket-Version: 13\r\n\r\n')
|
|
49
|
+
await once(clientIPv6, 'close')
|
|
49
50
|
}
|
|
50
51
|
})
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
setup()
|
|
52
|
+
})
|
package/types/instance.d.ts
CHANGED
|
@@ -152,6 +152,8 @@ export interface FastifyInstance<
|
|
|
152
152
|
decorateRequest: DecorationMethod<FastifyRequest, FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>>;
|
|
153
153
|
decorateReply: DecorationMethod<FastifyReply, FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>>;
|
|
154
154
|
|
|
155
|
+
getDecorator<T>(name: string | symbol): T;
|
|
156
|
+
|
|
155
157
|
hasDecorator(decorator: string | symbol): boolean;
|
|
156
158
|
hasRequestDecorator(decorator: string | symbol): boolean;
|
|
157
159
|
hasReplyDecorator(decorator: string | symbol): boolean;
|
|
@@ -548,6 +550,10 @@ export interface FastifyInstance<
|
|
|
548
550
|
* Remove all content type parsers, including the default ones
|
|
549
551
|
*/
|
|
550
552
|
removeAllContentTypeParsers: removeAllContentTypeParsers
|
|
553
|
+
/**
|
|
554
|
+
* Returns an array of strings containing the list of supported HTTP methods
|
|
555
|
+
*/
|
|
556
|
+
supportedMethods: string[]
|
|
551
557
|
/**
|
|
552
558
|
* Add a non-standard HTTP method
|
|
553
559
|
*
|
package/types/reply.d.ts
CHANGED
|
@@ -77,4 +77,5 @@ export interface FastifyReply<
|
|
|
77
77
|
) => FastifyReply<RouteGeneric, RawServer, RawRequest, RawReply, ContextConfig, SchemaCompiler, TypeProvider>;
|
|
78
78
|
hasTrailer(key: string): boolean;
|
|
79
79
|
removeTrailer(key: string): FastifyReply<RouteGeneric, RawServer, RawRequest, RawReply, ContextConfig, SchemaCompiler, TypeProvider>;
|
|
80
|
+
getDecorator<T>(name: string | symbol): T;
|
|
80
81
|
}
|
package/types/request.d.ts
CHANGED
|
@@ -87,4 +87,6 @@ export interface FastifyRequest<RouteGeneric extends RouteGenericInterface = Rou
|
|
|
87
87
|
compileValidationSchema(schema: { [key: string]: any }, httpPart?: HTTPRequestPart): ValidationFunction
|
|
88
88
|
validateInput(input: any, schema: { [key: string]: any }, httpPart?: HTTPRequestPart): boolean
|
|
89
89
|
validateInput(input: any, httpPart?: HTTPRequestPart): boolean
|
|
90
|
+
getDecorator<T>(name: string | symbol): T;
|
|
91
|
+
setDecorator<T = unknown>(name: string | symbol, value: T): void;
|
|
90
92
|
}
|
package/types/type-provider.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { RouteGenericInterface } from './route'
|
|
2
2
|
import { FastifySchema } from './schema'
|
|
3
|
-
import { RecordKeysToLowercase } from './utils'
|
|
3
|
+
import { HttpKeys, RecordKeysToLowercase } from './utils'
|
|
4
4
|
|
|
5
5
|
// -----------------------------------------------------------------------------------------------
|
|
6
6
|
// TypeProvider
|
|
@@ -80,6 +80,11 @@ export type ResolveFastifyReplyType<TypeProvider extends FastifyTypeProvider, Sc
|
|
|
80
80
|
// FastifyReplyReturnType
|
|
81
81
|
// -----------------------------------------------------------------------------------------------
|
|
82
82
|
|
|
83
|
+
// Resolves the Reply return type by taking a union of response status codes in the generic argument
|
|
84
|
+
type ResolveReplyReturnTypeFromRouteGeneric<RouteGeneric extends RouteGenericInterface> = RouteGeneric extends { Reply: infer Return }
|
|
85
|
+
? keyof Return extends HttpKeys ? Return[keyof Return] | Return : Return
|
|
86
|
+
: unknown
|
|
87
|
+
|
|
83
88
|
// The target reply return type. This type is inferenced on fastify 'routes' via generic argument assignment
|
|
84
89
|
export type ResolveFastifyReplyReturnType<
|
|
85
90
|
TypeProvider extends FastifyTypeProvider,
|
|
@@ -89,8 +94,12 @@ export type ResolveFastifyReplyReturnType<
|
|
|
89
94
|
TypeProvider,
|
|
90
95
|
SchemaCompiler,
|
|
91
96
|
RouteGeneric
|
|
92
|
-
> extends infer
|
|
93
|
-
|
|
97
|
+
> extends infer ReplyType
|
|
98
|
+
? RouteGeneric['Reply'] extends ReplyType
|
|
99
|
+
? ResolveReplyReturnTypeFromRouteGeneric<RouteGeneric> extends infer Return
|
|
100
|
+
? Return | void | Promise<Return | void>
|
|
101
|
+
: unknown
|
|
102
|
+
: ReplyType | void | Promise<ReplyType | void>
|
|
94
103
|
// review: support both async and sync return types
|
|
95
104
|
// (Promise<Return> | Return | Promise<void> | void)
|
|
96
105
|
: unknown
|