fastify 3.25.3 → 3.27.2
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/build/build-validation.js +2 -0
- package/docs/Guides/Ecosystem.md +2 -1
- package/docs/Guides/Index.md +2 -0
- package/docs/Guides/Prototype-Poisoning.md +391 -0
- package/docs/Guides/Recommendations.md +1 -1
- package/docs/Reference/ContentTypeParser.md +4 -1
- package/docs/Reference/Plugins.md +4 -4
- package/docs/Reference/Request.md +3 -0
- package/docs/Reference/Server.md +52 -2
- package/docs/Reference/TypeScript.md +1 -1
- package/docs/Reference/Validation-and-Serialization.md +4 -1
- package/fastify.d.ts +3 -1
- package/fastify.js +41 -21
- package/lib/decorate.js +2 -2
- package/lib/errors.js +6 -1
- package/lib/noop-set.js +10 -0
- package/lib/pluginUtils.js +5 -0
- package/lib/reply.js +21 -11
- package/lib/route.js +34 -1
- package/lib/schema-controller.js +1 -1
- package/lib/server.js +1 -1
- package/lib/symbols.js +3 -1
- package/package.json +16 -17
- package/test/404s.test.js +25 -1
- package/test/async-await.test.js +3 -3
- package/test/bundler/esbuild/bundler-test.js +31 -0
- package/test/bundler/esbuild/package.json +10 -0
- package/test/bundler/esbuild/src/fail-plugin-version.js +12 -0
- package/test/bundler/esbuild/src/index.js +7 -0
- package/test/bundler/webpack/bundler-test.js +15 -4
- package/test/bundler/webpack/src/fail-plugin-version.js +1 -3
- package/test/bundler/webpack/src/index.js +1 -3
- package/test/close.test.js +39 -1
- package/test/context-config.test.js +4 -4
- package/test/custom-parser.test.js +30 -31
- package/test/inject.test.js +1 -1
- package/test/internals/all.test.js +2 -2
- package/test/internals/contentTypeParser.test.js +4 -4
- package/test/internals/handleRequest.test.js +8 -8
- package/test/internals/logger.test.js +1 -1
- package/test/logger.test.js +18 -18
- package/test/maxRequestsPerSocket.test.js +2 -2
- package/test/noop-set.test.js +19 -0
- package/test/plugin.name.display.js +10 -0
- package/test/plugin.test.js +18 -0
- package/test/route.test.js +12 -0
- package/test/schema-serialization.test.js +41 -0
- package/test/skip-reply-send.test.js +7 -7
- package/test/trust-proxy.test.js +1 -1
- package/test/types/fastify.test-d.ts +18 -0
- package/test/types/hooks.test-d.ts +34 -6
- package/test/types/instance.test-d.ts +26 -1
- package/test/validation-error-handling.test.js +1 -1
- package/test/versioned-routes.test.js +28 -4
- package/types/.eslintrc.json +1 -1
- package/types/hooks.d.ts +24 -20
- package/types/instance.d.ts +13 -1
- package/types/register.d.ts +1 -1
- package/types/schema.d.ts +14 -0
package/fastify.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const VERSION = '3.
|
|
3
|
+
const VERSION = '3.27.2'
|
|
4
4
|
|
|
5
5
|
const Avvio = require('avvio')
|
|
6
6
|
const http = require('http')
|
|
@@ -16,6 +16,7 @@ const {
|
|
|
16
16
|
kLogSerializers,
|
|
17
17
|
kHooks,
|
|
18
18
|
kSchemaController,
|
|
19
|
+
kRequestAcceptVersion,
|
|
19
20
|
kReplySerializerDefault,
|
|
20
21
|
kContentTypeParser,
|
|
21
22
|
kReply,
|
|
@@ -25,7 +26,9 @@ const {
|
|
|
25
26
|
kOptions,
|
|
26
27
|
kPluginNameChain,
|
|
27
28
|
kSchemaErrorFormatter,
|
|
28
|
-
kErrorHandler
|
|
29
|
+
kErrorHandler,
|
|
30
|
+
kKeepAliveConnections,
|
|
31
|
+
kFourOhFourContext
|
|
29
32
|
} = require('./lib/symbols.js')
|
|
30
33
|
|
|
31
34
|
const { createServer } = require('./lib/server')
|
|
@@ -44,6 +47,7 @@ const build404 = require('./lib/fourOhFour')
|
|
|
44
47
|
const getSecuredInitialConfig = require('./lib/initialConfigValidation')
|
|
45
48
|
const override = require('./lib/pluginOverride')
|
|
46
49
|
const warning = require('./lib/warnings')
|
|
50
|
+
const noopSet = require('./lib/noop-set')
|
|
47
51
|
const { defaultInitOptions } = getSecuredInitialConfig
|
|
48
52
|
|
|
49
53
|
const {
|
|
@@ -55,7 +59,8 @@ const onBadUrlContext = {
|
|
|
55
59
|
config: {
|
|
56
60
|
},
|
|
57
61
|
onSend: [],
|
|
58
|
-
onError: []
|
|
62
|
+
onError: [],
|
|
63
|
+
[kFourOhFourContext]: null
|
|
59
64
|
}
|
|
60
65
|
|
|
61
66
|
function defaultBuildPrettyMeta (route) {
|
|
@@ -132,6 +137,7 @@ function fastify (options) {
|
|
|
132
137
|
// Update the options with the fixed values
|
|
133
138
|
options.connectionTimeout = options.connectionTimeout || defaultInitOptions.connectionTimeout
|
|
134
139
|
options.keepAliveTimeout = options.keepAliveTimeout || defaultInitOptions.keepAliveTimeout
|
|
140
|
+
options.forceCloseConnections = typeof options.forceCloseConnections === 'boolean' ? options.forceCloseConnections : defaultInitOptions.forceCloseConnections
|
|
135
141
|
options.maxRequestsPerSocket = options.maxRequestsPerSocket || defaultInitOptions.maxRequestsPerSocket
|
|
136
142
|
options.requestTimeout = options.requestTimeout || defaultInitOptions.requestTimeout
|
|
137
143
|
options.logger = logger
|
|
@@ -145,6 +151,7 @@ function fastify (options) {
|
|
|
145
151
|
options.exposeHeadRoutes = exposeHeadRoutes
|
|
146
152
|
|
|
147
153
|
const initialConfig = getSecuredInitialConfig(options)
|
|
154
|
+
const keepAliveConnections = options.forceCloseConnections === true ? new Set() : noopSet()
|
|
148
155
|
|
|
149
156
|
let constraints = options.constraints
|
|
150
157
|
if (options.versioning) {
|
|
@@ -168,14 +175,15 @@ function fastify (options) {
|
|
|
168
175
|
// Default router
|
|
169
176
|
const router = buildRouting({
|
|
170
177
|
config: {
|
|
171
|
-
defaultRoute
|
|
172
|
-
onBadUrl
|
|
173
|
-
constraints
|
|
178
|
+
defaultRoute,
|
|
179
|
+
onBadUrl,
|
|
180
|
+
constraints,
|
|
174
181
|
ignoreTrailingSlash: options.ignoreTrailingSlash || defaultInitOptions.ignoreTrailingSlash,
|
|
175
182
|
maxParamLength: options.maxParamLength || defaultInitOptions.maxParamLength,
|
|
176
183
|
caseSensitive: options.caseSensitive,
|
|
177
184
|
buildPrettyMeta: defaultBuildPrettyMeta
|
|
178
|
-
}
|
|
185
|
+
},
|
|
186
|
+
keepAliveConnections
|
|
179
187
|
})
|
|
180
188
|
|
|
181
189
|
// 404 router, used for handling encapsulated 404 handlers
|
|
@@ -199,6 +207,7 @@ function fastify (options) {
|
|
|
199
207
|
closing: false,
|
|
200
208
|
started: false
|
|
201
209
|
},
|
|
210
|
+
[kKeepAliveConnections]: keepAliveConnections,
|
|
202
211
|
[kOptions]: options,
|
|
203
212
|
[kChildren]: [],
|
|
204
213
|
[kBodyLimit]: bodyLimit,
|
|
@@ -259,16 +268,16 @@ function fastify (options) {
|
|
|
259
268
|
// expose logger instance
|
|
260
269
|
log: logger,
|
|
261
270
|
// hooks
|
|
262
|
-
addHook
|
|
271
|
+
addHook,
|
|
263
272
|
// schemas
|
|
264
|
-
addSchema
|
|
273
|
+
addSchema,
|
|
265
274
|
getSchema: schemaController.getSchema.bind(schemaController),
|
|
266
275
|
getSchemas: schemaController.getSchemas.bind(schemaController),
|
|
267
|
-
setValidatorCompiler
|
|
268
|
-
setSerializerCompiler
|
|
269
|
-
setSchemaController
|
|
270
|
-
setReplySerializer
|
|
271
|
-
setSchemaErrorFormatter
|
|
276
|
+
setValidatorCompiler,
|
|
277
|
+
setSerializerCompiler,
|
|
278
|
+
setSchemaController,
|
|
279
|
+
setReplySerializer,
|
|
280
|
+
setSchemaErrorFormatter,
|
|
272
281
|
// custom parsers
|
|
273
282
|
addContentTypeParser: ContentTypeParser.helpers.addContentTypeParser,
|
|
274
283
|
hasContentTypeParser: ContentTypeParser.helpers.hasContentTypeParser,
|
|
@@ -284,8 +293,8 @@ function fastify (options) {
|
|
|
284
293
|
close: null,
|
|
285
294
|
printPlugins: null,
|
|
286
295
|
// http server
|
|
287
|
-
listen
|
|
288
|
-
server
|
|
296
|
+
listen,
|
|
297
|
+
server,
|
|
289
298
|
// extend fastify objects
|
|
290
299
|
decorate: decorator.add,
|
|
291
300
|
hasDecorator: decorator.exist,
|
|
@@ -294,12 +303,12 @@ function fastify (options) {
|
|
|
294
303
|
hasRequestDecorator: decorator.existRequest,
|
|
295
304
|
hasReplyDecorator: decorator.existReply,
|
|
296
305
|
// fake http injection
|
|
297
|
-
inject
|
|
306
|
+
inject,
|
|
298
307
|
// pretty print of the registered routes
|
|
299
308
|
printRoutes,
|
|
300
309
|
// custom error handling
|
|
301
|
-
setNotFoundHandler
|
|
302
|
-
setErrorHandler
|
|
310
|
+
setNotFoundHandler,
|
|
311
|
+
setErrorHandler,
|
|
303
312
|
// Set fastify initial configuration options read-only object
|
|
304
313
|
initialConfig
|
|
305
314
|
}
|
|
@@ -374,6 +383,15 @@ function fastify (options) {
|
|
|
374
383
|
if (fastify[kState].listening) {
|
|
375
384
|
// No new TCP connections are accepted
|
|
376
385
|
instance.server.close(done)
|
|
386
|
+
|
|
387
|
+
for (const conn of fastify[kKeepAliveConnections]) {
|
|
388
|
+
// We must invoke the destroy method instead of merely unreffing
|
|
389
|
+
// the sockets. If we only unref, then the callback passed to
|
|
390
|
+
// `fastify.close` will never be invoked; nor will any of the
|
|
391
|
+
// registered `onClose` hooks.
|
|
392
|
+
conn.destroy()
|
|
393
|
+
fastify[kKeepAliveConnections].delete(conn)
|
|
394
|
+
}
|
|
377
395
|
} else {
|
|
378
396
|
done(null)
|
|
379
397
|
}
|
|
@@ -520,10 +538,8 @@ function fastify (options) {
|
|
|
520
538
|
}
|
|
521
539
|
|
|
522
540
|
if (name === 'onClose') {
|
|
523
|
-
this[kHooks].validate(name, fn)
|
|
524
541
|
this.onClose(fn)
|
|
525
542
|
} else if (name === 'onReady') {
|
|
526
|
-
this[kHooks].validate(name, fn)
|
|
527
543
|
this[kHooks].add(name, fn)
|
|
528
544
|
} else {
|
|
529
545
|
this.after((err, done) => {
|
|
@@ -578,6 +594,10 @@ function fastify (options) {
|
|
|
578
594
|
// req and res are Node.js core objects
|
|
579
595
|
function defaultRoute (req, res) {
|
|
580
596
|
if (req.headers['accept-version'] !== undefined) {
|
|
597
|
+
// we remove the accept-version header for performance result
|
|
598
|
+
// because we do not want to go through the constraint checking
|
|
599
|
+
// the usage of symbol here to prevent any colision on custom header name
|
|
600
|
+
req.headers[kRequestAcceptVersion] = req.headers['accept-version']
|
|
581
601
|
req.headers['accept-version'] = undefined
|
|
582
602
|
}
|
|
583
603
|
fourOhFour.router.lookup(req, res)
|
package/lib/decorate.js
CHANGED
package/lib/errors.js
CHANGED
|
@@ -106,7 +106,7 @@ const codes = {
|
|
|
106
106
|
*/
|
|
107
107
|
FST_ERR_MISSING_MIDDLEWARE: createError(
|
|
108
108
|
'FST_ERR_MISSING_MIDDLEWARE',
|
|
109
|
-
'You must register a plugin for handling middlewares, visit fastify.io/docs/latest/Middleware/ for more info.',
|
|
109
|
+
'You must register a plugin for handling middlewares, visit fastify.io/docs/latest/Reference/Middleware/ for more info.',
|
|
110
110
|
500
|
|
111
111
|
),
|
|
112
112
|
|
|
@@ -210,6 +210,11 @@ const codes = {
|
|
|
210
210
|
500,
|
|
211
211
|
TypeError
|
|
212
212
|
),
|
|
213
|
+
FST_ERR_INVALID_URL: createError(
|
|
214
|
+
'FST_ERR_INVALID_URL',
|
|
215
|
+
"URL must be a string. Received '%s'",
|
|
216
|
+
400
|
|
217
|
+
),
|
|
213
218
|
|
|
214
219
|
/**
|
|
215
220
|
* again listen when close server
|
package/lib/noop-set.js
ADDED
package/lib/pluginUtils.js
CHANGED
|
@@ -14,6 +14,11 @@ function getMeta (fn) {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
function getPluginName (func) {
|
|
17
|
+
const display = getDisplayName(func)
|
|
18
|
+
if (display) {
|
|
19
|
+
return display
|
|
20
|
+
}
|
|
21
|
+
|
|
17
22
|
// let's see if this is a file, and in that case use that
|
|
18
23
|
// this is common for plugins
|
|
19
24
|
const cache = require.cache
|
package/lib/reply.js
CHANGED
|
@@ -365,12 +365,18 @@ function preserializeHookEnd (err, request, reply, payload) {
|
|
|
365
365
|
return
|
|
366
366
|
}
|
|
367
367
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
368
|
+
try {
|
|
369
|
+
if (reply[kReplySerializer] !== null) {
|
|
370
|
+
payload = reply[kReplySerializer](payload)
|
|
371
|
+
} else if (reply.context && reply.context[kReplySerializerDefault]) {
|
|
372
|
+
payload = reply.context[kReplySerializerDefault](payload, reply.raw.statusCode)
|
|
373
|
+
} else {
|
|
374
|
+
payload = serialize(reply.context, payload, reply.raw.statusCode)
|
|
375
|
+
}
|
|
376
|
+
} catch (e) {
|
|
377
|
+
wrapSeralizationError(e, reply)
|
|
378
|
+
onErrorHook(reply, e)
|
|
379
|
+
return
|
|
374
380
|
}
|
|
375
381
|
|
|
376
382
|
flatstr(payload)
|
|
@@ -378,6 +384,10 @@ function preserializeHookEnd (err, request, reply, payload) {
|
|
|
378
384
|
onSendHook(reply, payload)
|
|
379
385
|
}
|
|
380
386
|
|
|
387
|
+
function wrapSeralizationError (error, reply) {
|
|
388
|
+
error.serialization = reply.context.config
|
|
389
|
+
}
|
|
390
|
+
|
|
381
391
|
function onSendHook (reply, payload) {
|
|
382
392
|
if (reply.context.onSend !== null) {
|
|
383
393
|
reply[kReplySent] = true
|
|
@@ -569,11 +579,11 @@ function handleError (reply, error, cb) {
|
|
|
569
579
|
const serializerFn = getSchemaSerializer(reply.context, statusCode)
|
|
570
580
|
payload = (serializerFn === false)
|
|
571
581
|
? serializeError({
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
582
|
+
error: statusCodes[statusCode + ''],
|
|
583
|
+
code: error.code,
|
|
584
|
+
message: error.message || '',
|
|
585
|
+
statusCode
|
|
586
|
+
})
|
|
577
587
|
: serializerFn(Object.create(error, {
|
|
578
588
|
error: { value: statusCodes[statusCode + ''] },
|
|
579
589
|
message: { value: error.message || '' },
|
package/lib/route.js
CHANGED
|
@@ -8,6 +8,7 @@ const supportedMethods = ['DELETE', 'GET', 'HEAD', 'PATCH', 'POST', 'PUT', 'OPTI
|
|
|
8
8
|
const { normalizeSchema } = require('./schemas')
|
|
9
9
|
const { parseHeadOnSendHandlers } = require('./headRoute')
|
|
10
10
|
const warning = require('./warnings')
|
|
11
|
+
const { kRequestAcceptVersion } = require('./symbols')
|
|
11
12
|
|
|
12
13
|
const {
|
|
13
14
|
compileSchemasForValidation,
|
|
@@ -17,7 +18,8 @@ const {
|
|
|
17
18
|
const {
|
|
18
19
|
FST_ERR_SCH_VALIDATION_BUILD,
|
|
19
20
|
FST_ERR_SCH_SERIALIZATION_BUILD,
|
|
20
|
-
FST_ERR_DEFAULT_ROUTE_INVALID_TYPE
|
|
21
|
+
FST_ERR_DEFAULT_ROUTE_INVALID_TYPE,
|
|
22
|
+
FST_ERR_INVALID_URL
|
|
21
23
|
} = require('./errors')
|
|
22
24
|
|
|
23
25
|
const {
|
|
@@ -40,6 +42,7 @@ const {
|
|
|
40
42
|
} = require('./symbols.js')
|
|
41
43
|
|
|
42
44
|
function buildRouting (options) {
|
|
45
|
+
const { keepAliveConnections } = options
|
|
43
46
|
const router = FindMyWay(options.config)
|
|
44
47
|
|
|
45
48
|
let avvio
|
|
@@ -97,6 +100,10 @@ function buildRouting (options) {
|
|
|
97
100
|
|
|
98
101
|
// Convert shorthand to extended route declaration
|
|
99
102
|
function prepareRoute (method, url, options, handler) {
|
|
103
|
+
if (typeof url !== 'string') {
|
|
104
|
+
throw new FST_ERR_INVALID_URL(typeof url)
|
|
105
|
+
}
|
|
106
|
+
|
|
100
107
|
if (!handler && typeof options === 'function') {
|
|
101
108
|
handler = options // for support over direct function calls such as fastify.get() options are reused as the handler
|
|
102
109
|
options = {}
|
|
@@ -344,6 +351,23 @@ function buildRouting (options) {
|
|
|
344
351
|
}
|
|
345
352
|
}
|
|
346
353
|
|
|
354
|
+
// When server.forceCloseConnections is true, we will collect any requests
|
|
355
|
+
// that have indicated they want persistence so that they can be reaped
|
|
356
|
+
// on server close. Otherwise, the container is a noop container.
|
|
357
|
+
const connHeader = String.prototype.toLowerCase.call(req.headers.connection || '')
|
|
358
|
+
if (connHeader === 'keep-alive') {
|
|
359
|
+
if (keepAliveConnections.has(req.socket) === false) {
|
|
360
|
+
keepAliveConnections.add(req.socket)
|
|
361
|
+
req.socket.on('close', removeTrackedSocket.bind({ keepAliveConnections, socket: req.socket }))
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// we revert the changes in defaultRoute
|
|
366
|
+
if (req.headers[kRequestAcceptVersion] !== undefined) {
|
|
367
|
+
req.headers['accept-version'] = req.headers[kRequestAcceptVersion]
|
|
368
|
+
req.headers[kRequestAcceptVersion] = undefined
|
|
369
|
+
}
|
|
370
|
+
|
|
347
371
|
const id = req.headers[requestIdHeader] || genReqId(req)
|
|
348
372
|
|
|
349
373
|
const loggerBinding = {
|
|
@@ -478,6 +502,15 @@ function preParsingHookRunner (functions, request, reply, cb) {
|
|
|
478
502
|
next(null, request[kRequestPayloadStream])
|
|
479
503
|
}
|
|
480
504
|
|
|
505
|
+
/**
|
|
506
|
+
* Used within the route handler as a `net.Socket.close` event handler.
|
|
507
|
+
* The purpose is to remove a socket from the tracked sockets collection when
|
|
508
|
+
* the socket has naturally timed out.
|
|
509
|
+
*/
|
|
510
|
+
function removeTrackedSocket () {
|
|
511
|
+
this.keepAliveConnections.delete(this.socket)
|
|
512
|
+
}
|
|
513
|
+
|
|
481
514
|
function noop () { }
|
|
482
515
|
|
|
483
516
|
module.exports = { buildRouting, validateBodyLimitOption }
|
package/lib/schema-controller.js
CHANGED
package/lib/server.js
CHANGED
package/lib/symbols.js
CHANGED
|
@@ -21,6 +21,7 @@ const keys = {
|
|
|
21
21
|
kReply: Symbol('fastify.Reply'),
|
|
22
22
|
kRequest: Symbol('fastify.Request'),
|
|
23
23
|
kRequestPayloadStream: Symbol('fastify.RequestPayloadStream'),
|
|
24
|
+
kRequestAcceptVersion: Symbol('fastify.RequestAcceptVersion'),
|
|
24
25
|
kCanSetNotFoundHandler: Symbol('fastify.canSetNotFoundHandler'),
|
|
25
26
|
kFourOhFour: Symbol('fastify.404'),
|
|
26
27
|
kFourOhFourLevelInstance: Symbol('fastify.404LogLevelInstance'),
|
|
@@ -43,7 +44,8 @@ const keys = {
|
|
|
43
44
|
kPluginNameChain: Symbol('fastify.pluginNameChain'),
|
|
44
45
|
// This symbol is only meant to be used for fastify tests and should not be used for any other purpose
|
|
45
46
|
kTestInternals: Symbol('fastify.testInternals'),
|
|
46
|
-
kErrorHandler: Symbol('fastify.errorHandler')
|
|
47
|
+
kErrorHandler: Symbol('fastify.errorHandler'),
|
|
48
|
+
kKeepAliveConnections: Symbol('fastify.keepAliveConnections')
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
module.exports = keys
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fastify",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.27.2",
|
|
4
4
|
"description": "Fast and low overhead web framework, for Node.js",
|
|
5
5
|
"main": "fastify.js",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -12,11 +12,11 @@
|
|
|
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",
|
|
14
14
|
"lint:fix": "standard --fix",
|
|
15
|
-
"lint:standard": "standard
|
|
15
|
+
"lint:standard": "standard | snazzy",
|
|
16
16
|
"lint:typescript": "eslint -c types/.eslintrc.json types/**/*.d.ts test/types/**/*.test-d.ts",
|
|
17
17
|
"prepublishOnly": "tap --no-check-coverage test/internals/version.test.js",
|
|
18
18
|
"test": "npm run lint && npm run unit && npm run test:typescript",
|
|
19
|
-
"test:ci": "npm run
|
|
19
|
+
"test:ci": "npm run unit -- -R terse --cov --coverage-report=lcovonly && npm run test:typescript",
|
|
20
20
|
"test:report": "npm run lint && npm run unit:report && npm run test:typescript",
|
|
21
21
|
"test:typescript": "tsd",
|
|
22
22
|
"unit": "tap -J test/*.test.js test/*/*.test.js",
|
|
@@ -124,11 +124,12 @@
|
|
|
124
124
|
"@fastify/ajv-compiler-8": "npm:@fastify/ajv-compiler@^2.0.0",
|
|
125
125
|
"@fastify/pre-commit": "^2.0.1",
|
|
126
126
|
"@hapi/joi": "^17.1.1",
|
|
127
|
-
"@sinonjs/fake-timers": "^
|
|
127
|
+
"@sinonjs/fake-timers": "^9.1.0",
|
|
128
128
|
"@types/node": "^16.0.0",
|
|
129
129
|
"@types/pino": "^6.0.1",
|
|
130
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
131
|
-
"@typescript-eslint/parser": "^
|
|
130
|
+
"@typescript-eslint/eslint-plugin": "^5.0.0",
|
|
131
|
+
"@typescript-eslint/parser": "^5.0.0",
|
|
132
|
+
"JSONStream": "^1.3.5",
|
|
132
133
|
"ajv": "^6.0.0",
|
|
133
134
|
"ajv-errors": "^1.0.1",
|
|
134
135
|
"ajv-formats": "^2.1.1",
|
|
@@ -139,25 +140,23 @@
|
|
|
139
140
|
"cors": "^2.8.5",
|
|
140
141
|
"coveralls": "^3.1.0",
|
|
141
142
|
"dns-prefetch-control": "^0.3.0",
|
|
142
|
-
"eslint": "^
|
|
143
|
-
"eslint-config-standard": "^
|
|
143
|
+
"eslint": "^8.0.1",
|
|
144
|
+
"eslint-config-standard": "^17.0.0-1",
|
|
144
145
|
"eslint-import-resolver-node": "^0.3.2",
|
|
145
|
-
"eslint-plugin-import": "^2.
|
|
146
|
-
"eslint-plugin-
|
|
147
|
-
"eslint-plugin-promise": "^
|
|
148
|
-
"eslint-plugin-standard": "^5.0.0",
|
|
146
|
+
"eslint-plugin-import": "^2.25.4",
|
|
147
|
+
"eslint-plugin-n": "^14.0.0",
|
|
148
|
+
"eslint-plugin-promise": "^6.0.0",
|
|
149
149
|
"fast-json-body": "^1.1.0",
|
|
150
150
|
"fastify-plugin": "^3.0.0",
|
|
151
151
|
"fluent-json-schema": "^3.0.0",
|
|
152
152
|
"form-data": "^4.0.0",
|
|
153
153
|
"frameguard": "^4.0.0",
|
|
154
154
|
"h2url": "^0.2.0",
|
|
155
|
-
"helmet": "^
|
|
155
|
+
"helmet": "^5.0.1",
|
|
156
156
|
"hide-powered-by": "^1.1.0",
|
|
157
157
|
"hsts": "^2.2.0",
|
|
158
158
|
"http-errors": "^2.0.0",
|
|
159
159
|
"ienoopen": "^1.1.0",
|
|
160
|
-
"JSONStream": "^1.3.5",
|
|
161
160
|
"license-checker": "^25.0.1",
|
|
162
161
|
"pem": "^1.14.4",
|
|
163
162
|
"proxyquire": "^2.1.3",
|
|
@@ -167,13 +166,13 @@
|
|
|
167
166
|
"simple-get": "^4.0.0",
|
|
168
167
|
"snazzy": "^9.0.0",
|
|
169
168
|
"split2": "^4.1.0",
|
|
170
|
-
"standard": "^
|
|
169
|
+
"standard": "^17.0.0-2",
|
|
171
170
|
"tap": "^15.1.1",
|
|
172
171
|
"tap-mocha-reporter": "^5.0.1",
|
|
173
172
|
"then-sleep": "^1.0.1",
|
|
174
173
|
"tsd": "^0.19.0",
|
|
175
174
|
"typescript": "^4.0.2",
|
|
176
|
-
"undici": "^3.3.
|
|
175
|
+
"undici": "^3.3.6",
|
|
177
176
|
"x-xss-protection": "^2.0.0",
|
|
178
177
|
"yup": "^0.32.0"
|
|
179
178
|
},
|
|
@@ -192,7 +191,7 @@
|
|
|
192
191
|
"rfdc": "^1.1.4",
|
|
193
192
|
"secure-json-parse": "^2.0.0",
|
|
194
193
|
"semver": "^7.3.2",
|
|
195
|
-
"tiny-lru": "^
|
|
194
|
+
"tiny-lru": "^8.0.1"
|
|
196
195
|
},
|
|
197
196
|
"standard": {
|
|
198
197
|
"ignore": [
|
package/test/404s.test.js
CHANGED
|
@@ -1221,7 +1221,7 @@ test('preHandler option for setNotFoundHandler', t => {
|
|
|
1221
1221
|
})
|
|
1222
1222
|
|
|
1223
1223
|
// https://github.com/fastify/fastify/issues/2229
|
|
1224
|
-
t.test('preHandler hook in setNotFoundHandler should be called when callNotFound', t => {
|
|
1224
|
+
t.test('preHandler hook in setNotFoundHandler should be called when callNotFound', { timeout: 40000 }, t => {
|
|
1225
1225
|
t.plan(2)
|
|
1226
1226
|
const fastify = Fastify()
|
|
1227
1227
|
|
|
@@ -1772,3 +1772,27 @@ test('setNotFoundHandler should be chaining fastify instance', t => {
|
|
|
1772
1772
|
|
|
1773
1773
|
t.end()
|
|
1774
1774
|
})
|
|
1775
|
+
|
|
1776
|
+
test('Send 404 when frameworkError calls reply.callNotFound', t => {
|
|
1777
|
+
t.test('Dynamic route', t => {
|
|
1778
|
+
t.plan(4)
|
|
1779
|
+
const fastify = Fastify({
|
|
1780
|
+
logger: true,
|
|
1781
|
+
frameworkErrors: (error, req, reply) => {
|
|
1782
|
+
t.equal(error.message, "'%world' is not a valid url component")
|
|
1783
|
+
return reply.callNotFound()
|
|
1784
|
+
}
|
|
1785
|
+
})
|
|
1786
|
+
fastify.get('/hello/:id', () => t.fail('we should not be here'))
|
|
1787
|
+
fastify.inject({
|
|
1788
|
+
url: '/hello/%world',
|
|
1789
|
+
method: 'GET'
|
|
1790
|
+
}, (err, response) => {
|
|
1791
|
+
t.error(err)
|
|
1792
|
+
t.equal(response.statusCode, 404)
|
|
1793
|
+
t.equal(response.payload, '404 Not Found')
|
|
1794
|
+
})
|
|
1795
|
+
})
|
|
1796
|
+
|
|
1797
|
+
t.end()
|
|
1798
|
+
})
|
package/test/async-await.test.js
CHANGED
|
@@ -407,7 +407,7 @@ test('error is logged because promise was fulfilled with undefined', t => {
|
|
|
407
407
|
try {
|
|
408
408
|
fastify = Fastify({
|
|
409
409
|
logger: {
|
|
410
|
-
stream
|
|
410
|
+
stream,
|
|
411
411
|
level: 'error'
|
|
412
412
|
}
|
|
413
413
|
})
|
|
@@ -447,7 +447,7 @@ test('error is not logged because promise was fulfilled with undefined but statu
|
|
|
447
447
|
try {
|
|
448
448
|
fastify = Fastify({
|
|
449
449
|
logger: {
|
|
450
|
-
stream
|
|
450
|
+
stream,
|
|
451
451
|
level: 'error'
|
|
452
452
|
}
|
|
453
453
|
})
|
|
@@ -488,7 +488,7 @@ test('error is not logged because promise was fulfilled with undefined but respo
|
|
|
488
488
|
try {
|
|
489
489
|
fastify = Fastify({
|
|
490
490
|
logger: {
|
|
491
|
-
stream
|
|
491
|
+
stream,
|
|
492
492
|
level: 'error'
|
|
493
493
|
}
|
|
494
494
|
})
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const t = require('tap')
|
|
4
|
+
const test = t.test
|
|
5
|
+
const fastifySuccess = require('./dist/success')
|
|
6
|
+
const fastifyFailPlugin = require('./dist/failPlugin')
|
|
7
|
+
|
|
8
|
+
test('Bundled package should work', (t) => {
|
|
9
|
+
t.plan(4)
|
|
10
|
+
fastifySuccess.ready((err) => {
|
|
11
|
+
t.error(err)
|
|
12
|
+
fastifySuccess.inject(
|
|
13
|
+
{
|
|
14
|
+
method: 'GET',
|
|
15
|
+
url: '/'
|
|
16
|
+
},
|
|
17
|
+
(error, res) => {
|
|
18
|
+
t.error(error)
|
|
19
|
+
t.equal(res.statusCode, 200)
|
|
20
|
+
t.same(res.json(), { hello: 'world' })
|
|
21
|
+
}
|
|
22
|
+
)
|
|
23
|
+
})
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
test('Bundled package should not work with bad plugin version', (t) => {
|
|
27
|
+
t.plan(1)
|
|
28
|
+
fastifyFailPlugin.ready((err) => {
|
|
29
|
+
t.match(err.message, /expected '9.x' fastify version/i)
|
|
30
|
+
})
|
|
31
|
+
})
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "0.0.1",
|
|
3
|
+
"scripts": {
|
|
4
|
+
"bundle": "esbuild success=src/index.js failPlugin=src/fail-plugin-version.js --bundle --outdir=dist --platform=node",
|
|
5
|
+
"test": "npm run bundle && node bundler-test.js"
|
|
6
|
+
},
|
|
7
|
+
"devDependencies": {
|
|
8
|
+
"esbuild": "^0.14.11"
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const fp = require('fastify-plugin')
|
|
2
|
+
const fastify = require('../../../../')()
|
|
3
|
+
|
|
4
|
+
fastify.get('/', function (request, reply) {
|
|
5
|
+
reply.send({ hello: 'world' })
|
|
6
|
+
})
|
|
7
|
+
|
|
8
|
+
fastify.register(fp((instance, opts, done) => {
|
|
9
|
+
done()
|
|
10
|
+
}, { fastify: '9.x' }))
|
|
11
|
+
|
|
12
|
+
module.exports = fastify
|
|
@@ -5,16 +5,27 @@ const test = t.test
|
|
|
5
5
|
const fastifySuccess = require('./dist/success')
|
|
6
6
|
const fastifyFailPlugin = require('./dist/failPlugin')
|
|
7
7
|
|
|
8
|
-
test('Bundled package should work', t => {
|
|
9
|
-
t.plan(
|
|
8
|
+
test('Bundled package should work', (t) => {
|
|
9
|
+
t.plan(4)
|
|
10
10
|
fastifySuccess.ready((err) => {
|
|
11
11
|
t.error(err)
|
|
12
|
+
fastifySuccess.inject(
|
|
13
|
+
{
|
|
14
|
+
method: 'GET',
|
|
15
|
+
url: '/'
|
|
16
|
+
},
|
|
17
|
+
(error, res) => {
|
|
18
|
+
t.error(error)
|
|
19
|
+
t.equal(res.statusCode, 200)
|
|
20
|
+
t.same(res.json(), { hello: 'world' })
|
|
21
|
+
}
|
|
22
|
+
)
|
|
12
23
|
})
|
|
13
24
|
})
|
|
14
25
|
|
|
15
|
-
test('Bundled package should not work with bad plugin version', t => {
|
|
26
|
+
test('Bundled package should not work with bad plugin version', (t) => {
|
|
16
27
|
t.plan(1)
|
|
17
28
|
fastifyFailPlugin.ready((err) => {
|
|
18
|
-
t.
|
|
29
|
+
t.match(err.message, /expected '9.x' fastify version/i)
|
|
19
30
|
})
|
|
20
31
|
})
|