fastify 4.5.2 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/Guides/Ecosystem.md +27 -12
- package/docs/Guides/Migration-Guide-V4.md +97 -48
- package/docs/Guides/Write-Plugin.md +1 -1
- package/docs/Reference/Logging.md +16 -13
- package/docs/Reference/Server.md +24 -2
- package/docs/Reference/Type-Providers.md +2 -16
- package/docs/Reference/TypeScript.md +7 -14
- package/examples/typescript-server.ts +1 -1
- package/fastify.d.ts +2 -2
- package/fastify.js +4 -1
- package/lib/decorate.js +2 -2
- package/lib/error-serializer.js +13 -40
- package/lib/route.js +9 -0
- package/lib/schemas.js +1 -0
- package/lib/server.js +6 -1
- package/package.json +3 -3
- package/test/404s.test.js +1 -1
- package/test/async-await.test.js +22 -0
- package/test/decorator.test.js +1 -1
- package/test/has-route.test.js +77 -0
- package/test/internals/decorator.test.js +2 -2
- package/test/listen.deprecated.test.js +33 -0
- package/test/schema-special-usage.test.js +29 -0
- package/test/types/fastify.test-d.ts +9 -0
- package/test/types/route.test-d.ts +11 -0
- package/test/unsupported-httpversion.test.js +0 -26
- package/types/hooks.d.ts +25 -25
- package/types/instance.d.ts +28 -22
- package/types/logger.d.ts +1 -1
- package/types/plugin.d.ts +3 -3
- package/types/reply.d.ts +2 -2
- package/types/request.d.ts +2 -2
- package/types/route.d.ts +12 -12
package/lib/error-serializer.js
CHANGED
|
@@ -23,14 +23,6 @@ class Serializer {
|
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
asAny (i) {
|
|
27
|
-
return JSON.stringify(i)
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
asNull () {
|
|
31
|
-
return 'null'
|
|
32
|
-
}
|
|
33
|
-
|
|
34
26
|
asInteger (i) {
|
|
35
27
|
if (typeof i === 'bigint') {
|
|
36
28
|
return i.toString()
|
|
@@ -47,10 +39,6 @@ class Serializer {
|
|
|
47
39
|
}
|
|
48
40
|
}
|
|
49
41
|
|
|
50
|
-
asIntegerNullable (i) {
|
|
51
|
-
return i === null ? 'null' : this.asInteger(i)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
42
|
asNumber (i) {
|
|
55
43
|
const num = Number(i)
|
|
56
44
|
if (Number.isNaN(num)) {
|
|
@@ -62,54 +50,43 @@ class Serializer {
|
|
|
62
50
|
}
|
|
63
51
|
}
|
|
64
52
|
|
|
65
|
-
asNumberNullable (i) {
|
|
66
|
-
return i === null ? 'null' : this.asNumber(i)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
53
|
asBoolean (bool) {
|
|
70
54
|
return bool && 'true' || 'false' // eslint-disable-line
|
|
71
55
|
}
|
|
72
56
|
|
|
73
|
-
asBooleanNullable (bool) {
|
|
74
|
-
return bool === null ? 'null' : this.asBoolean(bool)
|
|
75
|
-
}
|
|
76
|
-
|
|
77
57
|
asDateTime (date) {
|
|
78
58
|
if (date === null) return '""'
|
|
79
59
|
if (date instanceof Date) {
|
|
80
60
|
return '"' + date.toISOString() + '"'
|
|
81
61
|
}
|
|
62
|
+
if (typeof date === 'string') {
|
|
63
|
+
return '"' + date + '"'
|
|
64
|
+
}
|
|
82
65
|
throw new Error(`The value "${date}" cannot be converted to a date-time.`)
|
|
83
66
|
}
|
|
84
67
|
|
|
85
|
-
asDateTimeNullable (date) {
|
|
86
|
-
return date === null ? 'null' : this.asDateTime(date)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
68
|
asDate (date) {
|
|
90
69
|
if (date === null) return '""'
|
|
91
70
|
if (date instanceof Date) {
|
|
92
71
|
return '"' + new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString().slice(0, 10) + '"'
|
|
93
72
|
}
|
|
73
|
+
if (typeof date === 'string') {
|
|
74
|
+
return '"' + date + '"'
|
|
75
|
+
}
|
|
94
76
|
throw new Error(`The value "${date}" cannot be converted to a date.`)
|
|
95
77
|
}
|
|
96
78
|
|
|
97
|
-
asDateNullable (date) {
|
|
98
|
-
return date === null ? 'null' : this.asDate(date)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
79
|
asTime (date) {
|
|
102
80
|
if (date === null) return '""'
|
|
103
81
|
if (date instanceof Date) {
|
|
104
82
|
return '"' + new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString().slice(11, 19) + '"'
|
|
105
83
|
}
|
|
84
|
+
if (typeof date === 'string') {
|
|
85
|
+
return '"' + date + '"'
|
|
86
|
+
}
|
|
106
87
|
throw new Error(`The value "${date}" cannot be converted to a time.`)
|
|
107
88
|
}
|
|
108
89
|
|
|
109
|
-
asTimeNullable (date) {
|
|
110
|
-
return date === null ? 'null' : this.asTime(date)
|
|
111
|
-
}
|
|
112
|
-
|
|
113
90
|
asString (str) {
|
|
114
91
|
const quotes = '"'
|
|
115
92
|
if (str instanceof Date) {
|
|
@@ -129,10 +106,6 @@ class Serializer {
|
|
|
129
106
|
}
|
|
130
107
|
}
|
|
131
108
|
|
|
132
|
-
asStringNullable (str) {
|
|
133
|
-
return str === null ? 'null' : this.asString(str)
|
|
134
|
-
}
|
|
135
|
-
|
|
136
109
|
// magically escape strings for json
|
|
137
110
|
// relying on their charCodeAt
|
|
138
111
|
// everything below 32 needs JSON.stringify()
|
|
@@ -200,7 +173,7 @@ class Serializer {
|
|
|
200
173
|
}
|
|
201
174
|
|
|
202
175
|
json += "\"statusCode\"" + ':'
|
|
203
|
-
json += serializer.asNumber
|
|
176
|
+
json += serializer.asNumber(obj["statusCode"])
|
|
204
177
|
}
|
|
205
178
|
|
|
206
179
|
if (obj["code"] !== undefined) {
|
|
@@ -212,7 +185,7 @@ class Serializer {
|
|
|
212
185
|
}
|
|
213
186
|
|
|
214
187
|
json += "\"code\"" + ':'
|
|
215
|
-
json += serializer.asString
|
|
188
|
+
json += serializer.asString(obj["code"])
|
|
216
189
|
}
|
|
217
190
|
|
|
218
191
|
if (obj["error"] !== undefined) {
|
|
@@ -224,7 +197,7 @@ class Serializer {
|
|
|
224
197
|
}
|
|
225
198
|
|
|
226
199
|
json += "\"error\"" + ':'
|
|
227
|
-
json += serializer.asString
|
|
200
|
+
json += serializer.asString(obj["error"])
|
|
228
201
|
}
|
|
229
202
|
|
|
230
203
|
if (obj["message"] !== undefined) {
|
|
@@ -236,7 +209,7 @@ class Serializer {
|
|
|
236
209
|
}
|
|
237
210
|
|
|
238
211
|
json += "\"message\"" + ':'
|
|
239
|
-
json += serializer.asString
|
|
212
|
+
json += serializer.asString(obj["message"])
|
|
240
213
|
}
|
|
241
214
|
|
|
242
215
|
json += '}'
|
package/lib/route.js
CHANGED
|
@@ -83,6 +83,7 @@ function buildRouting (options) {
|
|
|
83
83
|
},
|
|
84
84
|
routing: router.lookup.bind(router), // router func to find the right handler to call
|
|
85
85
|
route, // configure a route in the fastify instance
|
|
86
|
+
hasRoute,
|
|
86
87
|
prepareRoute,
|
|
87
88
|
getDefaultRoute: function () {
|
|
88
89
|
return router.defaultRoute
|
|
@@ -141,6 +142,14 @@ function buildRouting (options) {
|
|
|
141
142
|
return route.call(this, { options, isFastify })
|
|
142
143
|
}
|
|
143
144
|
|
|
145
|
+
function hasRoute ({ options }) {
|
|
146
|
+
return router.find(
|
|
147
|
+
options.method,
|
|
148
|
+
options.url || '',
|
|
149
|
+
options.constraints
|
|
150
|
+
) !== null
|
|
151
|
+
}
|
|
152
|
+
|
|
144
153
|
// Route management
|
|
145
154
|
function route ({ options, isFastify }) {
|
|
146
155
|
// Since we are mutating/assigning only top level props, it is fine to have a shallow copy using the spread operator
|
package/lib/schemas.js
CHANGED
|
@@ -62,6 +62,7 @@ function normalizeSchema (routeSchemas, serverOptions) {
|
|
|
62
62
|
// let's check if our schemas have a custom prototype
|
|
63
63
|
for (const key of ['headers', 'querystring', 'params', 'body']) {
|
|
64
64
|
if (typeof routeSchemas[key] === 'object' && Object.getPrototypeOf(routeSchemas[key]) !== Object.prototype) {
|
|
65
|
+
routeSchemas[kSchemaVisited] = true
|
|
65
66
|
return routeSchemas
|
|
66
67
|
}
|
|
67
68
|
}
|
package/lib/server.js
CHANGED
|
@@ -319,7 +319,7 @@ function normalizeListenArgs (args) {
|
|
|
319
319
|
options.backlog = argsLength > 1 ? lastArg : undefined
|
|
320
320
|
} else {
|
|
321
321
|
/* Deal with listen ([port[, host[, backlog]]]) */
|
|
322
|
-
options.port = argsLength >= 1 && Number.isInteger(firstArg) ? firstArg :
|
|
322
|
+
options.port = argsLength >= 1 && Number.isInteger(firstArg) ? firstArg : normalizePort(firstArg)
|
|
323
323
|
// This will listen to what localhost is.
|
|
324
324
|
// It can be 127.0.0.1 or ::1, depending on the operating system.
|
|
325
325
|
// Fixes https://github.com/fastify/fastify/issues/1022.
|
|
@@ -330,6 +330,11 @@ function normalizeListenArgs (args) {
|
|
|
330
330
|
return options
|
|
331
331
|
}
|
|
332
332
|
|
|
333
|
+
function normalizePort (firstArg) {
|
|
334
|
+
const port = parseInt(firstArg, 10)
|
|
335
|
+
return port >= 0 && !Number.isNaN(port) ? port : 0
|
|
336
|
+
}
|
|
337
|
+
|
|
333
338
|
function logServerAddress (server) {
|
|
334
339
|
let address = server.address()
|
|
335
340
|
const isUnixSocket = typeof address === 'string'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fastify",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.6.0",
|
|
4
4
|
"description": "Fast and low overhead web framework, for Node.js",
|
|
5
5
|
"main": "fastify.js",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -164,7 +164,7 @@
|
|
|
164
164
|
"split2": "^4.1.0",
|
|
165
165
|
"standard": "^17.0.0-2",
|
|
166
166
|
"tap": "^16.2.0",
|
|
167
|
-
"tsd": "^0.
|
|
167
|
+
"tsd": "^0.23.0",
|
|
168
168
|
"typescript": "^4.7.2",
|
|
169
169
|
"undici": "^5.4.0",
|
|
170
170
|
"vary": "^1.1.2",
|
|
@@ -177,7 +177,7 @@
|
|
|
177
177
|
"abstract-logging": "^2.0.1",
|
|
178
178
|
"avvio": "^8.1.3",
|
|
179
179
|
"find-my-way": "^7.0.0",
|
|
180
|
-
"light-my-request": "^5.
|
|
180
|
+
"light-my-request": "^5.5.1",
|
|
181
181
|
"pino": "^8.0.0",
|
|
182
182
|
"process-warning": "^2.0.0",
|
|
183
183
|
"proxy-addr": "^2.0.7",
|
package/test/404s.test.js
CHANGED
|
@@ -1945,7 +1945,7 @@ test('Send 404 when frameworkError calls reply.callNotFound', t => {
|
|
|
1945
1945
|
t.end()
|
|
1946
1946
|
})
|
|
1947
1947
|
|
|
1948
|
-
test('hooks are applied to not found handlers', async ({ equal }) => {
|
|
1948
|
+
test('hooks are applied to not found handlers /1', async ({ equal }) => {
|
|
1949
1949
|
const fastify = Fastify()
|
|
1950
1950
|
|
|
1951
1951
|
// adding await here is fundamental for this test
|
package/test/async-await.test.js
CHANGED
|
@@ -423,6 +423,28 @@ test('promise was fulfilled with undefined', t => {
|
|
|
423
423
|
})
|
|
424
424
|
})
|
|
425
425
|
|
|
426
|
+
test('promise was fulfilled with undefined using inject', async (t) => {
|
|
427
|
+
const stream = split(JSON.parse)
|
|
428
|
+
const fastify = Fastify({
|
|
429
|
+
logger: {
|
|
430
|
+
stream,
|
|
431
|
+
level: 'error'
|
|
432
|
+
}
|
|
433
|
+
})
|
|
434
|
+
|
|
435
|
+
fastify.get('/', async (req, reply) => {
|
|
436
|
+
})
|
|
437
|
+
|
|
438
|
+
stream.once('data', line => {
|
|
439
|
+
t.fail('should not log an error')
|
|
440
|
+
})
|
|
441
|
+
|
|
442
|
+
const res = await fastify.inject('/')
|
|
443
|
+
|
|
444
|
+
t.equal(res.body, '')
|
|
445
|
+
t.equal(res.statusCode, 200)
|
|
446
|
+
})
|
|
447
|
+
|
|
426
448
|
test('error is not logged because promise was fulfilled with undefined but response was sent before promise resolution', t => {
|
|
427
449
|
t.plan(4)
|
|
428
450
|
|
package/test/decorator.test.js
CHANGED
|
@@ -642,7 +642,7 @@ test('should register empty values', t => {
|
|
|
642
642
|
|
|
643
643
|
fastify.register((instance, opts, done) => {
|
|
644
644
|
instance.decorate('test', null)
|
|
645
|
-
t.ok(
|
|
645
|
+
t.ok(Object.prototype.hasOwnProperty.call(instance, 'test'))
|
|
646
646
|
done()
|
|
647
647
|
})
|
|
648
648
|
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const t = require('tap')
|
|
4
|
+
const test = t.test
|
|
5
|
+
const Fastify = require('../fastify')
|
|
6
|
+
|
|
7
|
+
test('hasRoute', t => {
|
|
8
|
+
t.plan(4)
|
|
9
|
+
const test = t.test
|
|
10
|
+
const fastify = Fastify()
|
|
11
|
+
|
|
12
|
+
test('hasRoute - invalid options', t => {
|
|
13
|
+
t.plan(3)
|
|
14
|
+
|
|
15
|
+
t.equal(fastify.hasRoute({ }), false)
|
|
16
|
+
|
|
17
|
+
t.equal(fastify.hasRoute({ method: 'GET' }), false)
|
|
18
|
+
|
|
19
|
+
t.equal(fastify.hasRoute({ constraints: [] }), false)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
test('hasRoute - primitive method', t => {
|
|
23
|
+
t.plan(2)
|
|
24
|
+
fastify.route({
|
|
25
|
+
method: 'GET',
|
|
26
|
+
url: '/',
|
|
27
|
+
handler: function (req, reply) {
|
|
28
|
+
reply.send({ hello: 'world' })
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
t.equal(fastify.hasRoute({
|
|
33
|
+
method: 'GET',
|
|
34
|
+
url: '/'
|
|
35
|
+
}), true)
|
|
36
|
+
|
|
37
|
+
t.equal(fastify.hasRoute({
|
|
38
|
+
method: 'POST',
|
|
39
|
+
url: '/'
|
|
40
|
+
}), false)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
test('hasRoute - with constraints', t => {
|
|
44
|
+
t.plan(2)
|
|
45
|
+
fastify.route({
|
|
46
|
+
method: 'GET',
|
|
47
|
+
url: '/',
|
|
48
|
+
constraints: { version: '1.2.0' },
|
|
49
|
+
handler: (req, reply) => {
|
|
50
|
+
reply.send({ hello: 'world' })
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
t.equal(fastify.hasRoute({
|
|
55
|
+
method: 'GET',
|
|
56
|
+
url: '/',
|
|
57
|
+
constraints: { version: '1.2.0' }
|
|
58
|
+
}), true)
|
|
59
|
+
|
|
60
|
+
t.equal(fastify.hasRoute({
|
|
61
|
+
method: 'GET',
|
|
62
|
+
url: '/',
|
|
63
|
+
constraints: { version: '1.3.0' }
|
|
64
|
+
}), false)
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
test('hasRoute - parametric route regexp with constraints', t => {
|
|
68
|
+
t.plan(1)
|
|
69
|
+
// parametric with regexp
|
|
70
|
+
fastify.get('/example/:file(^\\d+).png', function (request, reply) { })
|
|
71
|
+
|
|
72
|
+
t.equal(fastify.hasRoute({
|
|
73
|
+
method: 'GET',
|
|
74
|
+
url: '/example/12345.png'
|
|
75
|
+
}), true)
|
|
76
|
+
})
|
|
77
|
+
})
|
|
@@ -138,7 +138,7 @@ test('decorate should recognize getter/setter objects', t => {
|
|
|
138
138
|
this._a = val
|
|
139
139
|
}
|
|
140
140
|
})
|
|
141
|
-
t.equal(
|
|
141
|
+
t.equal(Object.prototype.hasOwnProperty.call(one, 'foo'), true)
|
|
142
142
|
t.equal(one.foo, undefined)
|
|
143
143
|
one.foo = 'a'
|
|
144
144
|
t.equal(one.foo, 'a')
|
|
@@ -154,6 +154,6 @@ test('decorate should recognize getter/setter objects', t => {
|
|
|
154
154
|
decorator.add.call(two, 'foo', {
|
|
155
155
|
getter: () => 'a getter'
|
|
156
156
|
})
|
|
157
|
-
t.equal(
|
|
157
|
+
t.equal(Object.prototype.hasOwnProperty.call(two, 'foo'), true)
|
|
158
158
|
t.equal(two.foo, 'a getter')
|
|
159
159
|
})
|
|
@@ -200,3 +200,36 @@ test('listen when firstArg is { path: string(pipe) } and with backlog and callba
|
|
|
200
200
|
t.equal(address, '\\\\.\\pipe\\testPipe3')
|
|
201
201
|
})
|
|
202
202
|
})
|
|
203
|
+
|
|
204
|
+
test('listen accepts a port as string, and callback', t => {
|
|
205
|
+
t.plan(2)
|
|
206
|
+
const fastify = Fastify()
|
|
207
|
+
t.teardown(fastify.close.bind(fastify))
|
|
208
|
+
const port = 3000
|
|
209
|
+
fastify.listen(port.toString(), localhost, (err) => {
|
|
210
|
+
t.equal(fastify.server.address().port, port)
|
|
211
|
+
t.error(err)
|
|
212
|
+
})
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
test('listen accepts a port as string, address and callback', t => {
|
|
216
|
+
t.plan(3)
|
|
217
|
+
const fastify = Fastify()
|
|
218
|
+
t.teardown(fastify.close.bind(fastify))
|
|
219
|
+
const port = 3000
|
|
220
|
+
fastify.listen(port.toString(), localhost, (err) => {
|
|
221
|
+
t.equal(fastify.server.address().port, port)
|
|
222
|
+
t.equal(fastify.server.address().address, localhost)
|
|
223
|
+
t.error(err)
|
|
224
|
+
})
|
|
225
|
+
})
|
|
226
|
+
|
|
227
|
+
test('listen with invalid port string without callback with (address)', t => {
|
|
228
|
+
t.plan(1)
|
|
229
|
+
const fastify = Fastify()
|
|
230
|
+
t.teardown(fastify.close.bind(fastify))
|
|
231
|
+
fastify.listen('-1')
|
|
232
|
+
.then(address => {
|
|
233
|
+
t.equal(address, `http://${localhostForURL}:${fastify.server.address().port}`)
|
|
234
|
+
})
|
|
235
|
+
})
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const { test } = require('tap')
|
|
4
4
|
const Joi = require('joi')
|
|
5
|
+
const yup = require('yup')
|
|
5
6
|
const AJV = require('ajv')
|
|
6
7
|
const S = require('fluent-json-schema')
|
|
7
8
|
const Fastify = require('..')
|
|
@@ -673,3 +674,31 @@ test('JOI validation overwrite request headers', t => {
|
|
|
673
674
|
})
|
|
674
675
|
})
|
|
675
676
|
})
|
|
677
|
+
|
|
678
|
+
test('Custom schema object should not trigger FST_ERR_SCH_DUPLICATE', async t => {
|
|
679
|
+
const fastify = Fastify()
|
|
680
|
+
const handler = () => { }
|
|
681
|
+
|
|
682
|
+
fastify.get('/the/url', {
|
|
683
|
+
schema: {
|
|
684
|
+
query: yup.object({
|
|
685
|
+
foo: yup.string()
|
|
686
|
+
})
|
|
687
|
+
},
|
|
688
|
+
validatorCompiler: ({ schema, method, url, httpPart }) => {
|
|
689
|
+
return function (data) {
|
|
690
|
+
// with option strict = false, yup `validateSync` function returns the coerced value if validation was successful, or throws if validation failed
|
|
691
|
+
try {
|
|
692
|
+
const result = schema.validateSync(data, {})
|
|
693
|
+
return { value: result }
|
|
694
|
+
} catch (e) {
|
|
695
|
+
return { error: e }
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
},
|
|
699
|
+
handler
|
|
700
|
+
})
|
|
701
|
+
|
|
702
|
+
await fastify.ready()
|
|
703
|
+
t.pass('fastify is ready')
|
|
704
|
+
})
|
|
@@ -8,6 +8,7 @@ import fastify, {
|
|
|
8
8
|
LightMyRequestResponse,
|
|
9
9
|
LightMyRequestCallback,
|
|
10
10
|
InjectOptions, FastifyBaseLogger,
|
|
11
|
+
RouteGenericInterface,
|
|
11
12
|
ValidationResult
|
|
12
13
|
} from '../../fastify'
|
|
13
14
|
import { ErrorObject as AjvErrorObject } from 'ajv'
|
|
@@ -24,6 +25,7 @@ expectType<FastifyInstance<http.Server, http.IncomingMessage, http.ServerRespons
|
|
|
24
25
|
expectType<FastifyInstance<http.Server, http.IncomingMessage, http.ServerResponse> & PromiseLike<FastifyInstance<http.Server, http.IncomingMessage, http.ServerResponse>>>(fastify({}))
|
|
25
26
|
// https server
|
|
26
27
|
expectType<FastifyInstance<https.Server, http.IncomingMessage, http.ServerResponse> & PromiseLike<FastifyInstance<https.Server, http.IncomingMessage, http.ServerResponse>>>(fastify({ https: {} }))
|
|
28
|
+
expectType<FastifyInstance<https.Server, http.IncomingMessage, http.ServerResponse> & PromiseLike<FastifyInstance<https.Server, http.IncomingMessage, http.ServerResponse>>>(fastify({ https: null }))
|
|
27
29
|
// http2 server
|
|
28
30
|
expectType<FastifyInstance<http2.Http2Server, http2.Http2ServerRequest, http2.Http2ServerResponse> & PromiseLike<FastifyInstance<http2.Http2Server, http2.Http2ServerRequest, http2.Http2ServerResponse>>>(fastify({ http2: true, http2SessionTimeout: 1000 }))
|
|
29
31
|
expectType<FastifyInstance<http2.Http2SecureServer, http2.Http2ServerRequest, http2.Http2ServerResponse> & PromiseLike<FastifyInstance<http2.Http2SecureServer, http2.Http2ServerRequest, http2.Http2ServerResponse>>>(fastify({ http2: true, https: {}, http2SessionTimeout: 1000 }))
|
|
@@ -231,3 +233,10 @@ const ajvErrorObject: AjvErrorObject = {
|
|
|
231
233
|
message: ''
|
|
232
234
|
}
|
|
233
235
|
expectAssignable<ValidationResult>(ajvErrorObject)
|
|
236
|
+
|
|
237
|
+
const routeGeneric: RouteGenericInterface = {}
|
|
238
|
+
expectType<unknown>(routeGeneric.Body)
|
|
239
|
+
expectType<unknown>(routeGeneric.Headers)
|
|
240
|
+
expectType<unknown>(routeGeneric.Params)
|
|
241
|
+
expectType<unknown>(routeGeneric.Querystring)
|
|
242
|
+
expectType<unknown>(routeGeneric.Reply)
|
|
@@ -230,3 +230,14 @@ expectType<FastifyInstance>(fastify().route({
|
|
|
230
230
|
method: 'GET',
|
|
231
231
|
handler: routeHandlerWithReturnValue
|
|
232
232
|
}))
|
|
233
|
+
|
|
234
|
+
expectType<boolean>(fastify().hasRoute({
|
|
235
|
+
url: '/',
|
|
236
|
+
method: 'GET'
|
|
237
|
+
}))
|
|
238
|
+
|
|
239
|
+
expectType<boolean>(fastify().hasRoute({
|
|
240
|
+
url: '/',
|
|
241
|
+
method: 'GET',
|
|
242
|
+
constraints: { version: '1.2.0' }
|
|
243
|
+
}))
|
|
@@ -4,32 +4,6 @@ const net = require('net')
|
|
|
4
4
|
const t = require('tap')
|
|
5
5
|
const Fastify = require('../fastify')
|
|
6
6
|
|
|
7
|
-
t.test('Will return 505 HTTP error if HTTP version (default) is not supported', t => {
|
|
8
|
-
const fastify = Fastify()
|
|
9
|
-
|
|
10
|
-
t.teardown(fastify.close.bind(fastify))
|
|
11
|
-
|
|
12
|
-
fastify.get('/', (req, reply) => {
|
|
13
|
-
reply.send({ hello: 'world' })
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
fastify.listen({ port: 0 }, err => {
|
|
17
|
-
t.error(err)
|
|
18
|
-
|
|
19
|
-
const port = fastify.server.address().port
|
|
20
|
-
const client = net.createConnection({ port }, () => {
|
|
21
|
-
client.write('GET / HTTP/5.1\r\n\r\n')
|
|
22
|
-
|
|
23
|
-
client.once('data', data => {
|
|
24
|
-
t.match(data.toString(), /505 HTTP Version Not Supported/i)
|
|
25
|
-
client.end(() => {
|
|
26
|
-
t.end()
|
|
27
|
-
})
|
|
28
|
-
})
|
|
29
|
-
})
|
|
30
|
-
})
|
|
31
|
-
})
|
|
32
|
-
|
|
33
7
|
t.test('Will return 505 HTTP error if HTTP version (2.0 when server is 1.1) is not supported', t => {
|
|
34
8
|
const fastify = Fastify()
|
|
35
9
|
|