fastify 3.27.4 → 4.0.0-alpha.3
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/.taprc +3 -0
- package/README.md +7 -7
- package/build/build-error-serializer.js +27 -0
- package/build/build-validation.js +47 -35
- package/docs/Guides/Database.md +320 -0
- package/docs/Guides/Ecosystem.md +9 -0
- package/docs/Guides/Getting-Started.md +7 -7
- package/docs/Guides/Plugins-Guide.md +1 -1
- package/docs/Guides/Serverless.md +3 -3
- package/docs/Guides/Testing.md +2 -2
- package/docs/Migration-Guide-V4.md +12 -0
- package/docs/Reference/ContentTypeParser.md +4 -0
- package/docs/Reference/Decorators.md +2 -2
- package/docs/Reference/Encapsulation.md +2 -2
- package/docs/Reference/Errors.md +51 -6
- package/docs/Reference/HTTP2.md +3 -3
- package/docs/Reference/Hooks.md +4 -7
- package/docs/Reference/LTS.md +5 -4
- package/docs/Reference/Plugins.md +3 -3
- package/docs/Reference/Reply.md +73 -22
- package/docs/Reference/Request.md +1 -3
- package/docs/Reference/Routes.md +22 -15
- package/docs/Reference/Server.md +69 -119
- package/docs/Reference/TypeScript.md +20 -22
- package/docs/Reference/Validation-and-Serialization.md +30 -55
- package/docs/Type-Providers.md +257 -0
- package/examples/asyncawait.js +1 -1
- package/examples/benchmark/hooks-benchmark-async-await.js +1 -1
- package/examples/benchmark/hooks-benchmark.js +1 -1
- package/examples/benchmark/simple.js +1 -1
- package/examples/hooks.js +2 -2
- package/examples/http2.js +1 -1
- package/examples/https.js +1 -1
- package/examples/parser.js +13 -3
- package/examples/route-prefix.js +1 -1
- package/examples/shared-schema.js +1 -1
- package/examples/simple-stream.js +18 -0
- package/examples/simple.js +1 -1
- package/examples/simple.mjs +1 -1
- package/examples/typescript-server.ts +1 -1
- package/examples/use-plugin.js +1 -1
- package/fastify.d.ts +34 -22
- package/fastify.js +40 -36
- package/lib/configValidator.js +902 -1023
- package/lib/contentTypeParser.js +6 -16
- package/lib/context.js +36 -10
- package/lib/decorate.js +3 -1
- package/lib/error-handler.js +158 -0
- package/lib/error-serializer.js +257 -0
- package/lib/errors.js +51 -9
- package/lib/fourOhFour.js +31 -20
- package/lib/handleRequest.js +10 -13
- package/lib/hooks.js +14 -9
- package/lib/pluginOverride.js +0 -3
- package/lib/pluginUtils.js +3 -2
- package/lib/reply.js +121 -175
- package/lib/request.js +13 -10
- package/lib/route.js +131 -138
- package/lib/schema-controller.js +2 -2
- package/lib/schemas.js +27 -1
- package/lib/server.js +242 -116
- package/lib/symbols.js +5 -3
- package/lib/validation.js +11 -9
- package/lib/warnings.js +4 -12
- package/lib/wrapThenable.js +4 -11
- package/package.json +37 -39
- package/test/404s.test.js +258 -125
- package/test/500s.test.js +3 -3
- package/test/als.test.js +1 -1
- package/test/async-await.test.js +20 -76
- package/test/bodyLimit.test.js +1 -1
- package/test/build-certificate.js +6 -7
- package/test/case-insensitive.test.js +4 -4
- package/test/close-pipelining.test.js +2 -2
- package/test/close.test.js +11 -11
- package/test/content-parser.test.js +32 -0
- package/test/context-config.test.js +52 -0
- package/test/custom-http-server.test.js +14 -7
- package/test/custom-parser-async.test.js +1 -66
- package/test/custom-parser.test.js +92 -159
- package/test/custom-querystring-parser.test.js +3 -3
- package/test/decorator.test.js +11 -13
- package/test/delete.test.js +6 -6
- package/test/encapsulated-error-handler.test.js +50 -0
- package/test/esm/index.test.js +0 -14
- package/test/fastify-instance.test.js +4 -4
- package/test/fluent-schema.test.js +4 -4
- package/test/genReqId.test.js +1 -1
- package/test/get.test.js +4 -4
- package/test/handler-context.test.js +2 -2
- package/test/head.test.js +1 -1
- package/test/helper.js +19 -4
- package/test/hooks-async.test.js +15 -48
- package/test/hooks.on-ready.test.js +10 -5
- package/test/hooks.test.js +78 -119
- package/test/http2/closing.test.js +10 -16
- package/test/http2/constraint.test.js +1 -1
- package/test/http2/head.test.js +1 -1
- package/test/http2/plain.test.js +1 -1
- package/test/http2/secure-with-fallback.test.js +1 -1
- package/test/http2/secure.test.js +1 -1
- package/test/http2/unknown-http-method.test.js +4 -10
- package/test/https/custom-https-server.test.js +12 -6
- package/test/https/https.test.js +1 -1
- package/test/input-validation.js +3 -3
- package/test/internals/handleRequest.test.js +6 -43
- package/test/internals/initialConfig.test.js +41 -12
- package/test/internals/logger.test.js +2 -2
- package/test/internals/reply.test.js +317 -48
- package/test/internals/request.test.js +13 -7
- package/test/internals/server.test.js +88 -0
- package/test/listen.deprecated.test.js +202 -0
- package/test/listen.test.js +140 -145
- package/test/logger.test.js +82 -42
- package/test/maxRequestsPerSocket.test.js +8 -6
- package/test/middleware.test.js +2 -25
- package/test/nullable-validation.test.js +53 -16
- package/test/output-validation.test.js +1 -1
- package/test/plugin.test.js +47 -21
- package/test/pretty-print.test.js +22 -10
- package/test/promises.test.js +1 -1
- package/test/proto-poisoning.test.js +6 -6
- package/test/register.test.js +3 -3
- package/test/reply-error.test.js +126 -15
- package/test/reply-trailers.test.js +270 -0
- package/test/request-error.test.js +3 -6
- package/test/route-hooks.test.js +18 -18
- package/test/route-prefix.test.js +2 -1
- package/test/route.test.js +206 -22
- package/test/router-options.test.js +2 -2
- package/test/schema-examples.test.js +11 -5
- package/test/schema-feature.test.js +25 -20
- package/test/schema-serialization.test.js +9 -9
- package/test/schema-special-usage.test.js +5 -153
- package/test/schema-validation.test.js +9 -9
- package/test/skip-reply-send.test.js +2 -2
- package/test/stream.test.js +82 -23
- package/test/throw.test.js +8 -5
- package/test/trust-proxy.test.js +6 -6
- package/test/type-provider.test.js +20 -0
- package/test/types/fastify.test-d.ts +10 -18
- package/test/types/hooks.test-d.ts +61 -5
- package/test/types/import.js +2 -0
- package/test/types/import.ts +1 -0
- package/test/types/instance.test-d.ts +68 -17
- package/test/types/logger.test-d.ts +44 -15
- package/test/types/reply.test-d.ts +2 -1
- package/test/types/request.test-d.ts +71 -1
- package/test/types/route.test-d.ts +8 -2
- package/test/types/schema.test-d.ts +2 -39
- package/test/types/type-provider.test-d.ts +424 -0
- package/test/url-rewriting.test.js +3 -3
- package/test/validation-error-handling.test.js +8 -8
- package/test/versioned-routes.test.js +30 -18
- package/test/wrapThenable.test.js +7 -6
- package/types/content-type-parser.d.ts +17 -8
- package/types/hooks.d.ts +182 -85
- package/types/instance.d.ts +286 -118
- package/types/logger.d.ts +18 -104
- package/types/plugin.d.ts +10 -4
- package/types/reply.d.ts +18 -12
- package/types/request.d.ts +13 -8
- package/types/route.d.ts +62 -34
- package/types/schema.d.ts +1 -1
- package/types/type-provider.d.ts +99 -0
- package/types/utils.d.ts +1 -1
- package/lib/schema-compilers.js +0 -12
- package/test/emit-warning.test.js +0 -166
package/lib/fourOhFour.js
CHANGED
|
@@ -9,21 +9,17 @@ const {
|
|
|
9
9
|
kRoutePrefix,
|
|
10
10
|
kCanSetNotFoundHandler,
|
|
11
11
|
kFourOhFourLevelInstance,
|
|
12
|
-
kReply,
|
|
13
|
-
kRequest,
|
|
14
|
-
kContentTypeParser,
|
|
15
|
-
kBodyLimit,
|
|
16
|
-
kLogLevel,
|
|
17
12
|
kFourOhFourContext,
|
|
18
|
-
kHooks
|
|
19
|
-
kErrorHandler
|
|
13
|
+
kHooks
|
|
20
14
|
} = require('./symbols.js')
|
|
21
15
|
const { lifecycleHooks } = require('./hooks')
|
|
16
|
+
const { buildErrorHandler } = require('./error-handler.js')
|
|
22
17
|
const fourOhFourContext = {
|
|
23
18
|
config: {
|
|
24
19
|
},
|
|
25
20
|
onSend: [],
|
|
26
|
-
onError: []
|
|
21
|
+
onError: [],
|
|
22
|
+
errorHandler: buildErrorHandler()
|
|
27
23
|
}
|
|
28
24
|
|
|
29
25
|
/**
|
|
@@ -34,10 +30,10 @@ const fourOhFourContext = {
|
|
|
34
30
|
* kFourOhFourContext: the context in the reply object where the handler will be executed
|
|
35
31
|
*/
|
|
36
32
|
function fourOhFour (options) {
|
|
37
|
-
const { logger, genReqId } = options
|
|
33
|
+
const { logger, genReqId, disableRequestLogging } = options
|
|
38
34
|
|
|
39
35
|
// 404 router, used for handling encapsulated 404 handlers
|
|
40
|
-
const router = FindMyWay({ defaultRoute: fourOhFourFallBack })
|
|
36
|
+
const router = FindMyWay({ onBadUrl, defaultRoute: fourOhFourFallBack })
|
|
41
37
|
|
|
42
38
|
return { router, setNotFoundHandler, setContext, arrange404 }
|
|
43
39
|
|
|
@@ -58,6 +54,26 @@ function fourOhFour (options) {
|
|
|
58
54
|
})
|
|
59
55
|
}
|
|
60
56
|
|
|
57
|
+
function onBadUrl (path, req, res) {
|
|
58
|
+
const { url, method } = req
|
|
59
|
+
const message = `Route ${method}:${url} not found`
|
|
60
|
+
const body = `{"error":"Not Found","message":"${message}","statusCode":404}`
|
|
61
|
+
|
|
62
|
+
// simulate normal route logging
|
|
63
|
+
if (!disableRequestLogging) {
|
|
64
|
+
const id = genReqId(req)
|
|
65
|
+
const childLogger = logger.child({ reqId: id })
|
|
66
|
+
childLogger.info({ req }, 'incoming request')
|
|
67
|
+
childLogger.info({ req }, message)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
res.writeHead(404, {
|
|
71
|
+
'Content-Type': 'application/json',
|
|
72
|
+
'Content-Length': body.length
|
|
73
|
+
})
|
|
74
|
+
res.end(body)
|
|
75
|
+
}
|
|
76
|
+
|
|
61
77
|
function setContext (instance, context) {
|
|
62
78
|
const _404Context = Object.assign({}, instance[kFourOhFourContext])
|
|
63
79
|
_404Context.onSend = context.onSend
|
|
@@ -118,17 +134,12 @@ function fourOhFour (options) {
|
|
|
118
134
|
}
|
|
119
135
|
|
|
120
136
|
function _setNotFoundHandler (prefix, opts, handler, avvio, routeHandler) {
|
|
121
|
-
const context = new Context(
|
|
122
|
-
opts.schema,
|
|
137
|
+
const context = new Context({
|
|
138
|
+
schema: opts.schema,
|
|
123
139
|
handler,
|
|
124
|
-
|
|
125
|
-
this
|
|
126
|
-
|
|
127
|
-
opts.config || {},
|
|
128
|
-
this[kErrorHandler],
|
|
129
|
-
this[kBodyLimit],
|
|
130
|
-
this[kLogLevel]
|
|
131
|
-
)
|
|
140
|
+
config: opts.config || {},
|
|
141
|
+
server: this
|
|
142
|
+
})
|
|
132
143
|
|
|
133
144
|
avvio.once('preReady', () => {
|
|
134
145
|
const context = this[kFourOhFourContext]
|
package/lib/handleRequest.js
CHANGED
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
const { validate: validateSchema } = require('./validation')
|
|
4
4
|
const { hookRunner, hookIterator } = require('./hooks')
|
|
5
5
|
const wrapThenable = require('./wrapThenable')
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
const {
|
|
7
|
+
kReplyIsError
|
|
8
|
+
} = require('./symbols')
|
|
8
9
|
|
|
9
10
|
function handleRequest (err, request, reply) {
|
|
10
11
|
if (reply.sent === true) return
|
|
11
12
|
if (err != null) {
|
|
13
|
+
reply[kReplyIsError] = true
|
|
12
14
|
reply.send(err)
|
|
13
15
|
return
|
|
14
16
|
}
|
|
@@ -55,7 +57,7 @@ function handleRequest (err, request, reply) {
|
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
// Return 404 instead of 405 see https://github.com/fastify/fastify/pull/862 for discussion
|
|
58
|
-
|
|
60
|
+
handler(request, reply)
|
|
59
61
|
}
|
|
60
62
|
|
|
61
63
|
function handler (request, reply) {
|
|
@@ -77,11 +79,10 @@ function handler (request, reply) {
|
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
function preValidationCallback (err, request, reply) {
|
|
80
|
-
if (reply.sent === true
|
|
81
|
-
reply.raw.writableEnded === true ||
|
|
82
|
-
reply.raw.writable === false) return
|
|
82
|
+
if (reply.sent === true) return
|
|
83
83
|
|
|
84
84
|
if (err != null) {
|
|
85
|
+
reply[kReplyIsError] = true
|
|
85
86
|
reply.send(err)
|
|
86
87
|
return
|
|
87
88
|
}
|
|
@@ -111,11 +112,10 @@ function preValidationCallback (err, request, reply) {
|
|
|
111
112
|
}
|
|
112
113
|
|
|
113
114
|
function preHandlerCallback (err, request, reply) {
|
|
114
|
-
if (reply.sent
|
|
115
|
-
reply.raw.writableEnded === true ||
|
|
116
|
-
reply.raw.writable === false) return
|
|
115
|
+
if (reply.sent) return
|
|
117
116
|
|
|
118
117
|
if (err != null) {
|
|
118
|
+
reply[kReplyIsError] = true
|
|
119
119
|
reply.send(err)
|
|
120
120
|
return
|
|
121
121
|
}
|
|
@@ -125,10 +125,7 @@ function preHandlerCallback (err, request, reply) {
|
|
|
125
125
|
try {
|
|
126
126
|
result = reply.context.handler(request, reply)
|
|
127
127
|
} catch (err) {
|
|
128
|
-
|
|
129
|
-
reply[kReplyIsError] = true
|
|
130
|
-
}
|
|
131
|
-
|
|
128
|
+
reply[kReplyIsError] = true
|
|
132
129
|
reply.send(err)
|
|
133
130
|
return
|
|
134
131
|
}
|
package/lib/hooks.js
CHANGED
|
@@ -21,11 +21,13 @@ const supportedHooks = lifecycleHooks.concat(applicationHooks)
|
|
|
21
21
|
const {
|
|
22
22
|
FST_ERR_HOOK_INVALID_TYPE,
|
|
23
23
|
FST_ERR_HOOK_INVALID_HANDLER,
|
|
24
|
-
FST_ERR_SEND_UNDEFINED_ERR
|
|
24
|
+
FST_ERR_SEND_UNDEFINED_ERR,
|
|
25
|
+
FST_ERR_HOOK_TIMEOUT,
|
|
26
|
+
AVVIO_ERRORS_MAP,
|
|
27
|
+
appendStackTrace
|
|
25
28
|
} = require('./errors')
|
|
26
29
|
|
|
27
30
|
const {
|
|
28
|
-
kReplyIsError,
|
|
29
31
|
kChildren,
|
|
30
32
|
kHooks
|
|
31
33
|
} = require('./symbols')
|
|
@@ -84,6 +86,14 @@ function hookRunnerApplication (hookName, boot, server, cb) {
|
|
|
84
86
|
|
|
85
87
|
function exit (err) {
|
|
86
88
|
if (err) {
|
|
89
|
+
if (err.code === 'AVV_ERR_READY_TIMEOUT') {
|
|
90
|
+
err = appendStackTrace(err, new FST_ERR_HOOK_TIMEOUT(hookName))
|
|
91
|
+
} else {
|
|
92
|
+
err = AVVIO_ERRORS_MAP[err.code] != null
|
|
93
|
+
? appendStackTrace(err, new AVVIO_ERRORS_MAP[err.code](err.message))
|
|
94
|
+
: err
|
|
95
|
+
}
|
|
96
|
+
|
|
87
97
|
cb(err)
|
|
88
98
|
return
|
|
89
99
|
}
|
|
@@ -178,9 +188,8 @@ function hookRunner (functions, runner, request, reply, cb) {
|
|
|
178
188
|
function handleReject (err) {
|
|
179
189
|
if (!err) {
|
|
180
190
|
err = new FST_ERR_SEND_UNDEFINED_ERR()
|
|
181
|
-
} else if (!(err instanceof Error)) {
|
|
182
|
-
reply[kReplyIsError] = true
|
|
183
191
|
}
|
|
192
|
+
|
|
184
193
|
cb(err, request, reply)
|
|
185
194
|
}
|
|
186
195
|
|
|
@@ -201,11 +210,7 @@ function onSendHookRunner (functions, request, reply, payload, cb) {
|
|
|
201
210
|
}
|
|
202
211
|
|
|
203
212
|
if (i === functions.length) {
|
|
204
|
-
|
|
205
|
-
cb(null, request, reply, payload)
|
|
206
|
-
} catch (err) {
|
|
207
|
-
handleReject(err)
|
|
208
|
-
}
|
|
213
|
+
cb(null, request, reply, payload)
|
|
209
214
|
return
|
|
210
215
|
}
|
|
211
216
|
|
package/lib/pluginOverride.js
CHANGED
|
@@ -39,10 +39,7 @@ module.exports = function override (old, fn, opts) {
|
|
|
39
39
|
instance[kChildren] = []
|
|
40
40
|
|
|
41
41
|
instance[kReply] = Reply.buildReply(instance[kReply])
|
|
42
|
-
instance[kReply].prototype.server = instance
|
|
43
|
-
|
|
44
42
|
instance[kRequest] = Request.buildRequest(instance[kRequest])
|
|
45
|
-
instance[kRequest].prototype.server = instance
|
|
46
43
|
|
|
47
44
|
instance[kContentTypeParser] = ContentTypeParser.helpers.buildContentTypeParser(instance[kContentTypeParser])
|
|
48
45
|
instance[kHooks] = buildHooks(instance[kHooks])
|
package/lib/pluginUtils.js
CHANGED
|
@@ -102,9 +102,10 @@ function checkVersion (fn) {
|
|
|
102
102
|
if (!meta) return
|
|
103
103
|
|
|
104
104
|
const requiredVersion = meta.fastify
|
|
105
|
-
if (!requiredVersion) return
|
|
106
105
|
|
|
107
|
-
if (!semver.satisfies(this.version, requiredVersion))
|
|
106
|
+
if (requiredVersion && !semver.satisfies(this.version, requiredVersion)) {
|
|
107
|
+
throw new FST_ERR_PLUGIN_VERSION_MISMATCH(meta.name, requiredVersion, this.version)
|
|
108
|
+
}
|
|
108
109
|
}
|
|
109
110
|
|
|
110
111
|
function registerPluginName (fn) {
|