fastify 3.17.0 → 3.19.1
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/GOVERNANCE.md +1 -1
- package/README.md +0 -4
- package/build/build-validation.js +2 -0
- package/docs/ContentTypeParser.md +2 -0
- package/docs/Ecosystem.md +7 -1
- package/docs/Errors.md +2 -0
- package/docs/Getting-Started.md +2 -0
- package/docs/Hooks.md +1 -1
- package/docs/LTS.md +3 -2
- package/docs/Routes.md +5 -0
- package/docs/Server.md +63 -5
- package/docs/TypeScript.md +9 -1
- package/docs/Validation-and-Serialization.md +1 -1
- package/fastify.d.ts +4 -3
- package/fastify.js +24 -22
- package/lib/configValidator.js +218 -185
- package/lib/handleRequest.js +6 -0
- package/lib/hooks.js +2 -1
- package/lib/pluginUtils.js +1 -3
- package/lib/request.js +1 -1
- package/lib/route.js +2 -2
- package/lib/schemas.js +8 -8
- package/package.json +6 -11
- package/test/close.test.js +11 -14
- package/test/internals/initialConfig.test.js +2 -0
- package/test/internals/validation.test.js +21 -6
- package/test/pretty-print.test.js +89 -0
- package/test/reply-error.test.js +53 -0
- package/test/throw.test.js +12 -0
- package/test/types/fastify.test-d.ts +14 -3
- package/test/types/hooks.test-d.ts +41 -17
- package/test/types/logger.test-d.ts +7 -0
- package/test/versioned-routes.test.js +1 -1
- package/types/hooks.d.ts +23 -1
- package/types/logger.d.ts +5 -0
- package/test/internals/version.test.js +0 -43
package/lib/request.js
CHANGED
package/lib/route.js
CHANGED
|
@@ -227,7 +227,7 @@ function buildRouting (options) {
|
|
|
227
227
|
}
|
|
228
228
|
const constraints = opts.constraints || {}
|
|
229
229
|
if (opts.version) {
|
|
230
|
-
warning.emit('
|
|
230
|
+
warning.emit('FSTDEP008')
|
|
231
231
|
constraints.version = opts.version
|
|
232
232
|
}
|
|
233
233
|
|
|
@@ -296,7 +296,7 @@ function buildRouting (options) {
|
|
|
296
296
|
fourOhFour.setContext(this, context)
|
|
297
297
|
|
|
298
298
|
if (opts.schema) {
|
|
299
|
-
context.schema = normalizeSchema(context.schema)
|
|
299
|
+
context.schema = normalizeSchema(context.schema, this.initialConfig)
|
|
300
300
|
|
|
301
301
|
const schemaController = this[kSchemaController]
|
|
302
302
|
if (!opts.validatorCompiler && (opts.schema.body || opts.schema.headers || opts.schema.querystring || opts.schema.params)) {
|
package/lib/schemas.js
CHANGED
|
@@ -43,7 +43,7 @@ Schemas.prototype.getSchema = function (schemaId) {
|
|
|
43
43
|
return this.store[schemaId]
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
function normalizeSchema (routeSchemas) {
|
|
46
|
+
function normalizeSchema (routeSchemas, serverOptions) {
|
|
47
47
|
if (routeSchemas[kSchemaVisited]) {
|
|
48
48
|
return routeSchemas
|
|
49
49
|
}
|
|
@@ -67,25 +67,25 @@ function normalizeSchema (routeSchemas) {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
if (routeSchemas.body) {
|
|
70
|
-
routeSchemas.body = getSchemaAnyway(routeSchemas.body)
|
|
70
|
+
routeSchemas.body = getSchemaAnyway(routeSchemas.body, serverOptions.jsonShorthand)
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
if (routeSchemas.headers) {
|
|
74
|
-
routeSchemas.headers = getSchemaAnyway(routeSchemas.headers)
|
|
74
|
+
routeSchemas.headers = getSchemaAnyway(routeSchemas.headers, serverOptions.jsonShorthand)
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
if (routeSchemas.querystring) {
|
|
78
|
-
routeSchemas.querystring = getSchemaAnyway(routeSchemas.querystring)
|
|
78
|
+
routeSchemas.querystring = getSchemaAnyway(routeSchemas.querystring, serverOptions.jsonShorthand)
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
if (routeSchemas.params) {
|
|
82
|
-
routeSchemas.params = getSchemaAnyway(routeSchemas.params)
|
|
82
|
+
routeSchemas.params = getSchemaAnyway(routeSchemas.params, serverOptions.jsonShorthand)
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
if (routeSchemas.response) {
|
|
86
86
|
const httpCodes = Object.keys(routeSchemas.response)
|
|
87
87
|
for (const code of httpCodes) {
|
|
88
|
-
routeSchemas.response[code] = getSchemaAnyway(routeSchemas.response[code])
|
|
88
|
+
routeSchemas.response[code] = getSchemaAnyway(routeSchemas.response[code], serverOptions.jsonShorthand)
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
|
|
@@ -110,8 +110,8 @@ function generateFluentSchema (schema) {
|
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
function getSchemaAnyway (schema) {
|
|
114
|
-
if (schema.$ref || schema.oneOf || schema.allOf || schema.anyOf || schema.$merge || schema.$patch) return schema
|
|
113
|
+
function getSchemaAnyway (schema, jsonShorthand) {
|
|
114
|
+
if (!jsonShorthand || schema.$ref || schema.oneOf || schema.allOf || schema.anyOf || schema.$merge || schema.$patch) return schema
|
|
115
115
|
if (!schema.type && !schema.properties) {
|
|
116
116
|
return {
|
|
117
117
|
type: 'object',
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fastify",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.19.1",
|
|
4
4
|
"description": "Fast and low overhead web framework, for Node.js",
|
|
5
5
|
"main": "fastify.js",
|
|
6
6
|
"type": "commonjs",
|
|
7
7
|
"types": "fastify.d.ts",
|
|
8
8
|
"scripts": {
|
|
9
9
|
"bench": "branchcmp -r 2 -g -s \"npm run benchmark\"",
|
|
10
|
-
"benchmark": "npx concurrently -k -s first \"node ./examples/benchmark/simple.js\" \"npx autocannon -c 100 -d
|
|
10
|
+
"benchmark": "npx concurrently -k -s first \"node ./examples/benchmark/simple.js\" \"npx autocannon -c 100 -d 30 -p 10 localhost:3000/\"",
|
|
11
11
|
"coverage": "npm run unit -- --cov --coverage-report=html",
|
|
12
12
|
"license-checker": "license-checker --production --onlyAllow=\"MIT;ISC;BSD-3-Clause;BSD-2-Clause\"",
|
|
13
13
|
"lint": "npm run lint:standard && npm run lint:typescript",
|
|
@@ -114,25 +114,22 @@
|
|
|
114
114
|
"url": "https://github.com/fastify/fastify/issues"
|
|
115
115
|
},
|
|
116
116
|
"homepage": "https://www.fastify.io/",
|
|
117
|
-
"engines": {
|
|
118
|
-
"node": ">=10.16.0"
|
|
119
|
-
},
|
|
120
117
|
"devDependencies": {
|
|
121
118
|
"@fastify/ajv-compiler-8": "github:fastify/ajv-compiler#ajv-8",
|
|
119
|
+
"@fastify/pre-commit": "^2.0.1",
|
|
122
120
|
"@hapi/joi": "^17.1.1",
|
|
123
121
|
"@sinonjs/fake-timers": "^7.0.0",
|
|
124
|
-
"@types/node": "^
|
|
122
|
+
"@types/node": "^16.0.0",
|
|
125
123
|
"@types/pino": "^6.0.1",
|
|
126
124
|
"@typescript-eslint/eslint-plugin": "^4.5.0",
|
|
127
125
|
"@typescript-eslint/parser": "^4.5.0",
|
|
126
|
+
"JSONStream": "^1.3.5",
|
|
128
127
|
"ajv": "^6.0.0",
|
|
129
128
|
"ajv-errors": "^1.0.1",
|
|
130
129
|
"ajv-i18n": "^3.5.0",
|
|
131
130
|
"ajv-merge-patch": "^4.1.0",
|
|
132
131
|
"ajv-pack": "^0.3.1",
|
|
133
|
-
"autocannon": "^7.0.0",
|
|
134
132
|
"branch-comparer": "^1.0.2",
|
|
135
|
-
"concurrently": "^6.0.0",
|
|
136
133
|
"cors": "^2.8.5",
|
|
137
134
|
"coveralls": "^3.1.0",
|
|
138
135
|
"dns-prefetch-control": "^0.3.0",
|
|
@@ -154,10 +151,8 @@
|
|
|
154
151
|
"hsts": "^2.2.0",
|
|
155
152
|
"http-errors": "^1.7.1",
|
|
156
153
|
"ienoopen": "^1.1.0",
|
|
157
|
-
"JSONStream": "^1.3.5",
|
|
158
154
|
"license-checker": "^25.0.1",
|
|
159
155
|
"pem": "^1.14.4",
|
|
160
|
-
"pre-commit": "^1.2.2",
|
|
161
156
|
"proxyquire": "^2.1.3",
|
|
162
157
|
"pump": "^3.0.0",
|
|
163
158
|
"send": "^0.17.1",
|
|
@@ -177,7 +172,6 @@
|
|
|
177
172
|
},
|
|
178
173
|
"dependencies": {
|
|
179
174
|
"@fastify/ajv-compiler": "^1.0.0",
|
|
180
|
-
"@fastify/proxy-addr": "^3.0.0",
|
|
181
175
|
"abstract-logging": "^2.0.0",
|
|
182
176
|
"avvio": "^7.1.2",
|
|
183
177
|
"fast-json-stringify": "^2.5.2",
|
|
@@ -187,6 +181,7 @@
|
|
|
187
181
|
"flatstr": "^1.0.12",
|
|
188
182
|
"light-my-request": "^4.2.0",
|
|
189
183
|
"pino": "^6.2.1",
|
|
184
|
+
"proxy-addr": "^2.0.7",
|
|
190
185
|
"readable-stream": "^3.4.0",
|
|
191
186
|
"rfdc": "^1.1.4",
|
|
192
187
|
"secure-json-parse": "^2.0.0",
|
package/test/close.test.js
CHANGED
|
@@ -4,6 +4,7 @@ const net = require('net')
|
|
|
4
4
|
const t = require('tap')
|
|
5
5
|
const test = t.test
|
|
6
6
|
const Fastify = require('..')
|
|
7
|
+
const { Client } = require('undici')
|
|
7
8
|
|
|
8
9
|
test('close callback', t => {
|
|
9
10
|
t.plan(4)
|
|
@@ -238,27 +239,23 @@ t.test('Current opened connection should continue to work after closing and retu
|
|
|
238
239
|
})
|
|
239
240
|
|
|
240
241
|
t.test('Current opened connection should not accept new incoming connections', t => {
|
|
242
|
+
t.plan(3)
|
|
241
243
|
const fastify = Fastify()
|
|
242
|
-
|
|
243
244
|
fastify.get('/', (req, reply) => {
|
|
244
245
|
fastify.close()
|
|
245
|
-
|
|
246
|
+
setTimeout(() => {
|
|
247
|
+
reply.send({ hello: 'world' })
|
|
248
|
+
}, 250)
|
|
246
249
|
})
|
|
247
250
|
|
|
248
251
|
fastify.listen(0, err => {
|
|
249
252
|
t.error(err)
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
newConnection.on('error', err => {
|
|
257
|
-
t.ok(err)
|
|
258
|
-
t.ok(['ECONNREFUSED', 'ECONNRESET'].includes(err.code))
|
|
259
|
-
|
|
260
|
-
client.end(() => { t.end() })
|
|
261
|
-
})
|
|
253
|
+
const instance = new Client('http://localhost:' + fastify.server.address().port)
|
|
254
|
+
instance.request({ path: '/', method: 'GET' }).then(data => {
|
|
255
|
+
t.equal(data.statusCode, 200)
|
|
256
|
+
})
|
|
257
|
+
instance.request({ path: '/', method: 'GET' }).then(data => {
|
|
258
|
+
t.equal(data.statusCode, 503)
|
|
262
259
|
})
|
|
263
260
|
})
|
|
264
261
|
})
|
|
@@ -27,6 +27,7 @@ test('without options passed to Fastify, initialConfig should expose default val
|
|
|
27
27
|
bodyLimit: 1024 * 1024,
|
|
28
28
|
caseSensitive: true,
|
|
29
29
|
disableRequestLogging: false,
|
|
30
|
+
jsonShorthand: true,
|
|
30
31
|
ignoreTrailingSlash: false,
|
|
31
32
|
maxParamLength: 100,
|
|
32
33
|
onProtoPoisoning: 'error',
|
|
@@ -242,6 +243,7 @@ test('Should not have issues when passing stream options to Pino.js', t => {
|
|
|
242
243
|
bodyLimit: 1024 * 1024,
|
|
243
244
|
caseSensitive: true,
|
|
244
245
|
disableRequestLogging: false,
|
|
246
|
+
jsonShorthand: true,
|
|
245
247
|
ignoreTrailingSlash: true,
|
|
246
248
|
maxParamLength: 100,
|
|
247
249
|
onProtoPoisoning: 'error',
|
|
@@ -81,6 +81,9 @@ test('build schema - payload schema', t => {
|
|
|
81
81
|
|
|
82
82
|
test('build schema - avoid repeated normalize schema', t => {
|
|
83
83
|
t.plan(3)
|
|
84
|
+
const serverConfig = {
|
|
85
|
+
jsonShorthand: true
|
|
86
|
+
}
|
|
84
87
|
const opts = {
|
|
85
88
|
schema: {
|
|
86
89
|
query: {
|
|
@@ -91,14 +94,17 @@ test('build schema - avoid repeated normalize schema', t => {
|
|
|
91
94
|
}
|
|
92
95
|
}
|
|
93
96
|
}
|
|
94
|
-
opts.schema = normalizeSchema(opts.schema)
|
|
97
|
+
opts.schema = normalizeSchema(opts.schema, serverConfig)
|
|
95
98
|
t.not(kSchemaVisited, undefined)
|
|
96
99
|
t.equal(opts.schema[kSchemaVisited], true)
|
|
97
|
-
t.equal(opts.schema, normalizeSchema(opts.schema))
|
|
100
|
+
t.equal(opts.schema, normalizeSchema(opts.schema, serverConfig))
|
|
98
101
|
})
|
|
99
102
|
|
|
100
103
|
test('build schema - query schema', t => {
|
|
101
104
|
t.plan(2)
|
|
105
|
+
const serverConfig = {
|
|
106
|
+
jsonShorthand: true
|
|
107
|
+
}
|
|
102
108
|
const opts = {
|
|
103
109
|
schema: {
|
|
104
110
|
query: {
|
|
@@ -109,7 +115,7 @@ test('build schema - query schema', t => {
|
|
|
109
115
|
}
|
|
110
116
|
}
|
|
111
117
|
}
|
|
112
|
-
opts.schema = normalizeSchema(opts.schema)
|
|
118
|
+
opts.schema = normalizeSchema(opts.schema, serverConfig)
|
|
113
119
|
validation.compileSchemasForValidation(opts, ({ schema, method, url, httpPart }) => ajv.compile(schema))
|
|
114
120
|
t.type(opts[symbols.querystringSchema].schema.type, 'string')
|
|
115
121
|
t.equal(typeof opts[symbols.querystringSchema], 'function')
|
|
@@ -117,6 +123,9 @@ test('build schema - query schema', t => {
|
|
|
117
123
|
|
|
118
124
|
test('build schema - query schema abbreviated', t => {
|
|
119
125
|
t.plan(2)
|
|
126
|
+
const serverConfig = {
|
|
127
|
+
jsonShorthand: true
|
|
128
|
+
}
|
|
120
129
|
const opts = {
|
|
121
130
|
schema: {
|
|
122
131
|
query: {
|
|
@@ -124,7 +133,7 @@ test('build schema - query schema abbreviated', t => {
|
|
|
124
133
|
}
|
|
125
134
|
}
|
|
126
135
|
}
|
|
127
|
-
opts.schema = normalizeSchema(opts.schema)
|
|
136
|
+
opts.schema = normalizeSchema(opts.schema, serverConfig)
|
|
128
137
|
validation.compileSchemasForValidation(opts, ({ schema, method, url, httpPart }) => ajv.compile(schema))
|
|
129
138
|
t.type(opts[symbols.querystringSchema].schema.type, 'string')
|
|
130
139
|
t.equal(typeof opts[symbols.querystringSchema], 'function')
|
|
@@ -149,6 +158,9 @@ test('build schema - querystring schema', t => {
|
|
|
149
158
|
|
|
150
159
|
test('build schema - querystring schema abbreviated', t => {
|
|
151
160
|
t.plan(2)
|
|
161
|
+
const serverConfig = {
|
|
162
|
+
jsonShorthand: true
|
|
163
|
+
}
|
|
152
164
|
const opts = {
|
|
153
165
|
schema: {
|
|
154
166
|
querystring: {
|
|
@@ -156,7 +168,7 @@ test('build schema - querystring schema abbreviated', t => {
|
|
|
156
168
|
}
|
|
157
169
|
}
|
|
158
170
|
}
|
|
159
|
-
opts.schema = normalizeSchema(opts.schema)
|
|
171
|
+
opts.schema = normalizeSchema(opts.schema, serverConfig)
|
|
160
172
|
validation.compileSchemasForValidation(opts, ({ schema, method, url, httpPart }) => ajv.compile(schema))
|
|
161
173
|
t.type(opts[symbols.querystringSchema].schema.type, 'string')
|
|
162
174
|
t.equal(typeof opts[symbols.querystringSchema], 'function')
|
|
@@ -165,6 +177,9 @@ test('build schema - querystring schema abbreviated', t => {
|
|
|
165
177
|
test('build schema - must throw if querystring and query schema exist', t => {
|
|
166
178
|
t.plan(2)
|
|
167
179
|
try {
|
|
180
|
+
const serverConfig = {
|
|
181
|
+
jsonShorthand: true
|
|
182
|
+
}
|
|
168
183
|
const opts = {
|
|
169
184
|
schema: {
|
|
170
185
|
query: {
|
|
@@ -181,7 +196,7 @@ test('build schema - must throw if querystring and query schema exist', t => {
|
|
|
181
196
|
}
|
|
182
197
|
}
|
|
183
198
|
}
|
|
184
|
-
opts.schema = normalizeSchema(opts.schema)
|
|
199
|
+
opts.schema = normalizeSchema(opts.schema, serverConfig)
|
|
185
200
|
} catch (err) {
|
|
186
201
|
t.equal(err.code, 'FST_ERR_SCH_DUPLICATE')
|
|
187
202
|
t.equal(err.message, 'Schema with \'querystring\' already present!')
|
|
@@ -121,3 +121,92 @@ test('pretty print - nested plugins', t => {
|
|
|
121
121
|
t.match(tree, 'baz')
|
|
122
122
|
})
|
|
123
123
|
})
|
|
124
|
+
|
|
125
|
+
test('pretty print - commonPrefix', t => {
|
|
126
|
+
t.plan(4)
|
|
127
|
+
|
|
128
|
+
const fastify = Fastify()
|
|
129
|
+
fastify.get('/hello', () => {})
|
|
130
|
+
fastify.put('/hello', () => {})
|
|
131
|
+
fastify.get('/helicopter', () => {})
|
|
132
|
+
|
|
133
|
+
fastify.ready(() => {
|
|
134
|
+
const radixTree = fastify.printRoutes()
|
|
135
|
+
const flatTree = fastify.printRoutes({ commonPrefix: false })
|
|
136
|
+
|
|
137
|
+
const radixExpected = `└── /
|
|
138
|
+
├── hel
|
|
139
|
+
│ ├── lo (GET)
|
|
140
|
+
│ └── icopter (GET)
|
|
141
|
+
└── hello (PUT)
|
|
142
|
+
`
|
|
143
|
+
const flatExpected = `└── / (-)
|
|
144
|
+
├── helicopter (GET)
|
|
145
|
+
└── hello (GET, PUT)
|
|
146
|
+
`
|
|
147
|
+
t.equal(typeof radixTree, 'string')
|
|
148
|
+
t.equal(typeof flatTree, 'string')
|
|
149
|
+
t.equal(radixTree, radixExpected)
|
|
150
|
+
t.equal(flatTree, flatExpected)
|
|
151
|
+
})
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
test('pretty print - includeMeta, includeHooks', t => {
|
|
155
|
+
t.plan(6)
|
|
156
|
+
|
|
157
|
+
const fastify = Fastify()
|
|
158
|
+
const onTimeout = () => {}
|
|
159
|
+
fastify.get('/hello', () => {})
|
|
160
|
+
fastify.put('/hello', () => {})
|
|
161
|
+
fastify.get('/helicopter', () => {})
|
|
162
|
+
|
|
163
|
+
fastify.addHook('onRequest', () => {})
|
|
164
|
+
fastify.addHook('onTimeout', onTimeout)
|
|
165
|
+
|
|
166
|
+
fastify.ready(() => {
|
|
167
|
+
const radixTree = fastify.printRoutes({ includeHooks: true, includeMeta: ['errorHandler'] })
|
|
168
|
+
const flatTree = fastify.printRoutes({ commonPrefix: false, includeHooks: true, includeMeta: ['errorHandler'] })
|
|
169
|
+
const hooksOnly = fastify.printRoutes({ commonPrefix: false, includeHooks: true })
|
|
170
|
+
|
|
171
|
+
const radixExpected = `└── /
|
|
172
|
+
├── hel
|
|
173
|
+
│ ├── lo (GET)
|
|
174
|
+
│ │ • (onTimeout) ["onTimeout()"]
|
|
175
|
+
│ │ • (onRequest) ["anonymous()"]
|
|
176
|
+
│ │ • (errorHandler) "defaultErrorHandler()"
|
|
177
|
+
│ └── icopter (GET)
|
|
178
|
+
│ • (onTimeout) ["onTimeout()"]
|
|
179
|
+
│ • (onRequest) ["anonymous()"]
|
|
180
|
+
│ • (errorHandler) "defaultErrorHandler()"
|
|
181
|
+
└── hello (PUT)
|
|
182
|
+
• (onTimeout) ["onTimeout()"]
|
|
183
|
+
• (onRequest) ["anonymous()"]
|
|
184
|
+
• (errorHandler) "defaultErrorHandler()"
|
|
185
|
+
`
|
|
186
|
+
const flatExpected = `└── / (-)
|
|
187
|
+
├── helicopter (GET)
|
|
188
|
+
│ • (onTimeout) ["onTimeout()"]
|
|
189
|
+
│ • (onRequest) ["anonymous()"]
|
|
190
|
+
│ • (errorHandler) "defaultErrorHandler()"
|
|
191
|
+
└── hello (GET, PUT)
|
|
192
|
+
• (onTimeout) ["onTimeout()"]
|
|
193
|
+
• (onRequest) ["anonymous()"]
|
|
194
|
+
• (errorHandler) "defaultErrorHandler()"
|
|
195
|
+
`
|
|
196
|
+
|
|
197
|
+
const hooksOnlyExpected = `└── / (-)
|
|
198
|
+
├── helicopter (GET)
|
|
199
|
+
│ • (onTimeout) ["onTimeout()"]
|
|
200
|
+
│ • (onRequest) ["anonymous()"]
|
|
201
|
+
└── hello (GET, PUT)
|
|
202
|
+
• (onTimeout) ["onTimeout()"]
|
|
203
|
+
• (onRequest) ["anonymous()"]
|
|
204
|
+
`
|
|
205
|
+
t.equal(typeof radixTree, 'string')
|
|
206
|
+
t.equal(typeof flatTree, 'string')
|
|
207
|
+
t.equal(typeof hooksOnlyExpected, 'string')
|
|
208
|
+
t.equal(radixTree, radixExpected)
|
|
209
|
+
t.equal(flatTree, flatExpected)
|
|
210
|
+
t.equal(hooksOnly, hooksOnlyExpected)
|
|
211
|
+
})
|
|
212
|
+
})
|
package/test/reply-error.test.js
CHANGED
|
@@ -472,3 +472,56 @@ invalidErrorCodes.forEach((invalidCode) => {
|
|
|
472
472
|
})
|
|
473
473
|
})
|
|
474
474
|
})
|
|
475
|
+
|
|
476
|
+
test('status code should be set to 500 and return an error json payload if route handler throws any non Error object expression', async t => {
|
|
477
|
+
t.plan(2)
|
|
478
|
+
const fastify = Fastify()
|
|
479
|
+
|
|
480
|
+
fastify.get('/', () => {
|
|
481
|
+
/* eslint-disable-next-line */
|
|
482
|
+
throw { foo: 'bar' }
|
|
483
|
+
})
|
|
484
|
+
|
|
485
|
+
// ----
|
|
486
|
+
const reply = await fastify.inject({ method: 'GET', url: '/' })
|
|
487
|
+
t.equal(reply.statusCode, 500)
|
|
488
|
+
t.equal(JSON.parse(reply.body).foo, 'bar')
|
|
489
|
+
})
|
|
490
|
+
|
|
491
|
+
test('should preserve the status code set by the user if an expression is thrown in a sync route', async t => {
|
|
492
|
+
t.plan(2)
|
|
493
|
+
const fastify = Fastify()
|
|
494
|
+
|
|
495
|
+
fastify.get('/', (_, rep) => {
|
|
496
|
+
rep.status(501)
|
|
497
|
+
|
|
498
|
+
/* eslint-disable-next-line */
|
|
499
|
+
throw { foo: 'bar' }
|
|
500
|
+
})
|
|
501
|
+
|
|
502
|
+
// ----
|
|
503
|
+
const reply = await fastify.inject({ method: 'GET', url: '/' })
|
|
504
|
+
t.equal(reply.statusCode, 501)
|
|
505
|
+
t.equal(JSON.parse(reply.body).foo, 'bar')
|
|
506
|
+
})
|
|
507
|
+
|
|
508
|
+
test('should trigger error handlers if a sync route throws any non-error object', async t => {
|
|
509
|
+
t.plan(3)
|
|
510
|
+
|
|
511
|
+
const fastify = Fastify()
|
|
512
|
+
|
|
513
|
+
fastify.get('/', () => {
|
|
514
|
+
/* eslint-disable-next-line */
|
|
515
|
+
throw { foo: 'bar' }
|
|
516
|
+
})
|
|
517
|
+
|
|
518
|
+
fastify.setErrorHandler(async (error) => {
|
|
519
|
+
t.ok(error)
|
|
520
|
+
return error
|
|
521
|
+
})
|
|
522
|
+
|
|
523
|
+
// ----
|
|
524
|
+
const reply = await fastify.inject({ method: 'GET', url: '/' })
|
|
525
|
+
t.equal(reply.statusCode, 500)
|
|
526
|
+
t.equal(JSON.parse(reply.body).foo, 'bar')
|
|
527
|
+
})
|
package/test/throw.test.js
CHANGED
|
@@ -71,6 +71,18 @@ test('Fastify should throw for an invalid schema, printing the error route - bod
|
|
|
71
71
|
})
|
|
72
72
|
})
|
|
73
73
|
|
|
74
|
+
test('Fastify should throw for an invalid shorthand option type', t => {
|
|
75
|
+
t.plan(3)
|
|
76
|
+
try {
|
|
77
|
+
Fastify({ jsonShorthand: 'hello' })
|
|
78
|
+
t.fail()
|
|
79
|
+
} catch (e) {
|
|
80
|
+
t.equal(e.code, 'FST_ERR_INIT_OPTS_INVALID')
|
|
81
|
+
t.match(e.message, /should be boolean/)
|
|
82
|
+
t.pass()
|
|
83
|
+
}
|
|
84
|
+
})
|
|
85
|
+
|
|
74
86
|
test('Should throw on unsupported method', t => {
|
|
75
87
|
t.plan(1)
|
|
76
88
|
const fastify = Fastify()
|
|
@@ -3,12 +3,15 @@ import fastify, {
|
|
|
3
3
|
FastifyInstance,
|
|
4
4
|
FastifyPlugin,
|
|
5
5
|
FastifyPluginAsync,
|
|
6
|
-
FastifyPluginCallback
|
|
6
|
+
FastifyPluginCallback,
|
|
7
|
+
LightMyRequestChain,
|
|
8
|
+
LightMyRequestResponse,
|
|
9
|
+
LightMyRequestCallback,
|
|
10
|
+
InjectOptions
|
|
7
11
|
} from '../../fastify'
|
|
8
12
|
import * as http from 'http'
|
|
9
13
|
import * as https from 'https'
|
|
10
14
|
import * as http2 from 'http2'
|
|
11
|
-
import { Chain as LightMyRequestChain } from 'light-my-request'
|
|
12
15
|
import { expectType, expectError, expectAssignable } from 'tsd'
|
|
13
16
|
import { FastifyLoggerInstance } from '../../types/logger'
|
|
14
17
|
import { Socket } from 'net'
|
|
@@ -21,12 +24,20 @@ expectType<FastifyInstance<http.Server, http.IncomingMessage, http.ServerRespons
|
|
|
21
24
|
expectType<FastifyInstance<https.Server, http.IncomingMessage, http.ServerResponse> & PromiseLike<FastifyInstance<https.Server, http.IncomingMessage, http.ServerResponse>>>(fastify({ https: {} }))
|
|
22
25
|
// http2 server
|
|
23
26
|
expectType<FastifyInstance<http2.Http2Server, http2.Http2ServerRequest, http2.Http2ServerResponse> & PromiseLike<FastifyInstance<http2.Http2Server, http2.Http2ServerRequest, http2.Http2ServerResponse>>>(fastify({ http2: true, http2SessionTimeout: 1000 }))
|
|
24
|
-
expectType<FastifyInstance<http2.Http2SecureServer, http2.Http2ServerRequest, http2.Http2ServerResponse> & PromiseLike<FastifyInstance<http2.Http2SecureServer, http2.Http2ServerRequest, http2.Http2ServerResponse>>>(fastify({ http2: true, https: {} }))
|
|
27
|
+
expectType<FastifyInstance<http2.Http2SecureServer, http2.Http2ServerRequest, http2.Http2ServerResponse> & PromiseLike<FastifyInstance<http2.Http2SecureServer, http2.Http2ServerRequest, http2.Http2ServerResponse>>>(fastify({ http2: true, https: {}, http2SessionTimeout: 1000 }))
|
|
25
28
|
expectType<LightMyRequestChain>(fastify({ http2: true, https: {} }).inject())
|
|
26
29
|
|
|
27
30
|
expectError(fastify<http2.Http2Server>({ http2: false })) // http2 option must be true
|
|
28
31
|
expectError(fastify<http2.Http2SecureServer>({ http2: false })) // http2 option must be true
|
|
29
32
|
|
|
33
|
+
// light-my-request
|
|
34
|
+
expectAssignable<InjectOptions>({ query: '' })
|
|
35
|
+
fastify({ http2: true, https: {} }).inject().then((resp) => {
|
|
36
|
+
expectAssignable<LightMyRequestResponse>(resp)
|
|
37
|
+
})
|
|
38
|
+
const lightMyRequestCallback: LightMyRequestCallback = (err: Error, response: LightMyRequestResponse) => {}
|
|
39
|
+
fastify({ http2: true, https: {} }).inject({}, lightMyRequestCallback)
|
|
40
|
+
|
|
30
41
|
// server options
|
|
31
42
|
expectAssignable<FastifyInstance<http2.Http2Server, http2.Http2ServerRequest, http2.Http2ServerResponse>>(fastify({ http2: true }))
|
|
32
43
|
expectAssignable<FastifyInstance>(fastify({ ignoreTrailingSlash: true }))
|