fastify 3.27.1 → 3.27.4
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 +2 -1
- package/docs/Reference/ContentTypeParser.md +4 -1
- package/docs/Reference/Server.md +36 -0
- package/docs/Reference/Validation-and-Serialization.md +4 -1
- package/fastify.d.ts +1 -0
- package/fastify.js +20 -18
- package/lib/decorate.js +2 -2
- package/lib/errors.js +1 -1
- package/lib/reply.js +5 -5
- package/lib/schema-controller.js +1 -1
- package/lib/server.js +1 -1
- package/package.json +12 -13
- package/test/404s.test.js +24 -0
- package/test/async-await.test.js +3 -3
- package/test/close.test.js +1 -1
- package/test/context-config.test.js +4 -4
- 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/internals/reply.test.js +13 -14
- package/test/logger.test.js +18 -18
- package/test/maxRequestsPerSocket.test.js +2 -2
- package/test/skip-reply-send.test.js +7 -7
- package/test/trust-proxy.test.js +1 -1
- package/test/types/fastify.test-d.ts +1 -0
- package/test/types/hooks.test-d.ts +7 -3
- package/test/types/instance.test-d.ts +1 -1
- package/test/validation-error-handling.test.js +1 -1
- package/test/versioned-routes.test.js +1 -1
- package/types/.eslintrc.json +4 -2
- package/types/hooks.d.ts +5 -1
- package/types/register.d.ts +1 -1
package/docs/Guides/Ecosystem.md
CHANGED
|
@@ -59,7 +59,7 @@ section.
|
|
|
59
59
|
- [`fastify-http-proxy`](https://github.com/fastify/fastify-http-proxy) Proxy
|
|
60
60
|
your HTTP requests to another server, with hooks.
|
|
61
61
|
- [`fastify-jwt`](https://github.com/fastify/fastify-jwt) JWT utils for Fastify,
|
|
62
|
-
internally uses [
|
|
62
|
+
internally uses [fast-jwt](https://github.com/nearform/fast-jwt).
|
|
63
63
|
- [`fastify-leveldb`](https://github.com/fastify/fastify-leveldb) Plugin to
|
|
64
64
|
share a common LevelDB connection across Fastify.
|
|
65
65
|
- [`fastify-mongodb`](https://github.com/fastify/fastify-mongodb) Fastify
|
|
@@ -130,6 +130,7 @@ section.
|
|
|
130
130
|
- [`@immobiliarelabs/fastify-metrics`](https://github.com/immobiliare/fastify-metrics)
|
|
131
131
|
Minimalistic and opinionated plugin that collects usage/process metrics and
|
|
132
132
|
dispatches to [statsd](https://github.com/statsd/statsd).
|
|
133
|
+
- [`@immobiliarelabs/fastify-sentry`](https://github.com/immobiliare/fastify-sentry) Sentry errors handler that just works! Install, add your DSN and you're good to go!
|
|
133
134
|
- [`@mgcrea/fastify-graceful-exit`](https://github.com/mgcrea/fastify-graceful-exit)
|
|
134
135
|
A plugin to close the server gracefully
|
|
135
136
|
- [`@mgcrea/fastify-request-logger`](https://github.com/mgcrea/fastify-request-logger)
|
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
## `Content-Type` Parser
|
|
4
4
|
Natively, Fastify only supports `'application/json'` and `'text/plain'` content
|
|
5
|
-
types.
|
|
5
|
+
types. If the content type is not one of these, a `FST_ERR_CTP_INVALID_MEDIA_TYPE`
|
|
6
|
+
error will be thrown.
|
|
7
|
+
|
|
8
|
+
The default charset is `utf-8`. If you need to support different content
|
|
6
9
|
types, you can use the `addContentTypeParser` API. *The default JSON and/or
|
|
7
10
|
plain text parser can be changed or removed.*
|
|
8
11
|
|
package/docs/Reference/Server.md
CHANGED
|
@@ -77,6 +77,9 @@ describes the properties available in that options object.
|
|
|
77
77
|
- [printRoutes](#printroutes)
|
|
78
78
|
- [printPlugins](#printplugins)
|
|
79
79
|
- [addContentTypeParser](#addcontenttypeparser)
|
|
80
|
+
- [hasContentTypeParser](#hasContentTypeParser)
|
|
81
|
+
- [removeContentTypeParser](#removeContentTypeParser)
|
|
82
|
+
- [removeAllContentTypeParsers](#removeAllContentTypeParsers)
|
|
80
83
|
- [getDefaultJsonParser](#getdefaultjsonparser)
|
|
81
84
|
- [defaultTextParser](#defaulttextparser)
|
|
82
85
|
- [errorHandler](#errorhandler)
|
|
@@ -1479,6 +1482,39 @@ content types, e.g. `text/json, application/vnd.oasis.opendocument.text`.
|
|
|
1479
1482
|
fastify.addContentTypeParser('text/json', { asString: true }, fastify.getDefaultJsonParser('ignore', 'ignore'))
|
|
1480
1483
|
```
|
|
1481
1484
|
|
|
1485
|
+
#### hasContentTypeParser
|
|
1486
|
+
<a id="hasContentTypeParser"></a>
|
|
1487
|
+
|
|
1488
|
+
`fastify.hasContentTypeParser(contentType)` is used to check whether there is a content type parser in the current
|
|
1489
|
+
context for the specified content type.
|
|
1490
|
+
|
|
1491
|
+
```js
|
|
1492
|
+
fastify.hasContentTypeParser('text/json')
|
|
1493
|
+
|
|
1494
|
+
fastify.hasContentTypeParser(/^.+\/json$/)
|
|
1495
|
+
```
|
|
1496
|
+
|
|
1497
|
+
#### removeContentTypeParser
|
|
1498
|
+
<a id="removeContentTypeParser"></a>
|
|
1499
|
+
|
|
1500
|
+
`fastify.removeContentTypeParser(contentType)` is used to remove content type parsers in the current context. This
|
|
1501
|
+
method allows for example to remove the both built-in parsers for `application/json` and `text/plain`.
|
|
1502
|
+
|
|
1503
|
+
```js
|
|
1504
|
+
fastify.removeContentTypeParser('application/json')
|
|
1505
|
+
|
|
1506
|
+
fastify.removeContentTypeParser(['application/json', 'text/plain'])
|
|
1507
|
+
```
|
|
1508
|
+
|
|
1509
|
+
#### removeAllContentTypeParsers
|
|
1510
|
+
<a id="removeAllContentTypeParsers"></a>
|
|
1511
|
+
|
|
1512
|
+
The `fastify.removeAllContentTypeParsers()` method allows all content type parsers in the current context to be removed.
|
|
1513
|
+
A use case of this method is the implementation of catch-all content type parser. Before adding this parser with
|
|
1514
|
+
`fastify.addContentTypeParser()` one could call the `removeAllContentTypeParsers` method.
|
|
1515
|
+
|
|
1516
|
+
For more details about the usage of the different content type parser APIs see [here](./ContentTypeParser.md#usage).
|
|
1517
|
+
|
|
1482
1518
|
#### getDefaultJsonParser
|
|
1483
1519
|
<a id="getDefaultJsonParser"></a>
|
|
1484
1520
|
|
|
@@ -4,7 +4,10 @@
|
|
|
4
4
|
Fastify uses a schema-based approach, and even if it is not mandatory we
|
|
5
5
|
recommend using [JSON Schema](https://json-schema.org/) to validate your routes
|
|
6
6
|
and serialize your outputs. Internally, Fastify compiles the schema into a
|
|
7
|
-
highly performant function.
|
|
7
|
+
highly performant function.
|
|
8
|
+
|
|
9
|
+
Validation will only be attempted if the content type is `application-json`,
|
|
10
|
+
as described in the documentation for the [content type parser](./ContentTypeParser.md).
|
|
8
11
|
|
|
9
12
|
> ## ⚠ Security Notice
|
|
10
13
|
> Treat the schema definition as application code. Validation and serialization
|
package/fastify.d.ts
CHANGED
|
@@ -113,6 +113,7 @@ export type FastifyServerOptions<
|
|
|
113
113
|
caseSensitive?: boolean,
|
|
114
114
|
requestIdHeader?: string,
|
|
115
115
|
requestIdLogLabel?: string;
|
|
116
|
+
jsonShorthand?: boolean;
|
|
116
117
|
genReqId?: <RequestGeneric extends RequestGenericInterface = RequestGenericInterface>(req: FastifyRequest<RequestGeneric, RawServer, RawRequestDefaultExpression<RawServer>>) => string,
|
|
117
118
|
trustProxy?: boolean | string | string[] | number | TrustProxyFunction,
|
|
118
119
|
querystringParser?: (str: string) => { [key: string]: unknown },
|
package/fastify.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const VERSION = '3.27.
|
|
3
|
+
const VERSION = '3.27.4'
|
|
4
4
|
|
|
5
5
|
const Avvio = require('avvio')
|
|
6
6
|
const http = require('http')
|
|
@@ -27,7 +27,8 @@ const {
|
|
|
27
27
|
kPluginNameChain,
|
|
28
28
|
kSchemaErrorFormatter,
|
|
29
29
|
kErrorHandler,
|
|
30
|
-
kKeepAliveConnections
|
|
30
|
+
kKeepAliveConnections,
|
|
31
|
+
kFourOhFourContext
|
|
31
32
|
} = require('./lib/symbols.js')
|
|
32
33
|
|
|
33
34
|
const { createServer } = require('./lib/server')
|
|
@@ -58,7 +59,8 @@ const onBadUrlContext = {
|
|
|
58
59
|
config: {
|
|
59
60
|
},
|
|
60
61
|
onSend: [],
|
|
61
|
-
onError: []
|
|
62
|
+
onError: [],
|
|
63
|
+
[kFourOhFourContext]: null
|
|
62
64
|
}
|
|
63
65
|
|
|
64
66
|
function defaultBuildPrettyMeta (route) {
|
|
@@ -173,9 +175,9 @@ function fastify (options) {
|
|
|
173
175
|
// Default router
|
|
174
176
|
const router = buildRouting({
|
|
175
177
|
config: {
|
|
176
|
-
defaultRoute
|
|
177
|
-
onBadUrl
|
|
178
|
-
constraints
|
|
178
|
+
defaultRoute,
|
|
179
|
+
onBadUrl,
|
|
180
|
+
constraints,
|
|
179
181
|
ignoreTrailingSlash: options.ignoreTrailingSlash || defaultInitOptions.ignoreTrailingSlash,
|
|
180
182
|
maxParamLength: options.maxParamLength || defaultInitOptions.maxParamLength,
|
|
181
183
|
caseSensitive: options.caseSensitive,
|
|
@@ -266,16 +268,16 @@ function fastify (options) {
|
|
|
266
268
|
// expose logger instance
|
|
267
269
|
log: logger,
|
|
268
270
|
// hooks
|
|
269
|
-
addHook
|
|
271
|
+
addHook,
|
|
270
272
|
// schemas
|
|
271
|
-
addSchema
|
|
273
|
+
addSchema,
|
|
272
274
|
getSchema: schemaController.getSchema.bind(schemaController),
|
|
273
275
|
getSchemas: schemaController.getSchemas.bind(schemaController),
|
|
274
|
-
setValidatorCompiler
|
|
275
|
-
setSerializerCompiler
|
|
276
|
-
setSchemaController
|
|
277
|
-
setReplySerializer
|
|
278
|
-
setSchemaErrorFormatter
|
|
276
|
+
setValidatorCompiler,
|
|
277
|
+
setSerializerCompiler,
|
|
278
|
+
setSchemaController,
|
|
279
|
+
setReplySerializer,
|
|
280
|
+
setSchemaErrorFormatter,
|
|
279
281
|
// custom parsers
|
|
280
282
|
addContentTypeParser: ContentTypeParser.helpers.addContentTypeParser,
|
|
281
283
|
hasContentTypeParser: ContentTypeParser.helpers.hasContentTypeParser,
|
|
@@ -291,8 +293,8 @@ function fastify (options) {
|
|
|
291
293
|
close: null,
|
|
292
294
|
printPlugins: null,
|
|
293
295
|
// http server
|
|
294
|
-
listen
|
|
295
|
-
server
|
|
296
|
+
listen,
|
|
297
|
+
server,
|
|
296
298
|
// extend fastify objects
|
|
297
299
|
decorate: decorator.add,
|
|
298
300
|
hasDecorator: decorator.exist,
|
|
@@ -301,12 +303,12 @@ function fastify (options) {
|
|
|
301
303
|
hasRequestDecorator: decorator.existRequest,
|
|
302
304
|
hasReplyDecorator: decorator.existReply,
|
|
303
305
|
// fake http injection
|
|
304
|
-
inject
|
|
306
|
+
inject,
|
|
305
307
|
// pretty print of the registered routes
|
|
306
308
|
printRoutes,
|
|
307
309
|
// custom error handling
|
|
308
|
-
setNotFoundHandler
|
|
309
|
-
setErrorHandler
|
|
310
|
+
setNotFoundHandler,
|
|
311
|
+
setErrorHandler,
|
|
310
312
|
// Set fastify initial configuration options read-only object
|
|
311
313
|
initialConfig
|
|
312
314
|
}
|
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
|
|
package/lib/reply.js
CHANGED
|
@@ -579,11 +579,11 @@ function handleError (reply, error, cb) {
|
|
|
579
579
|
const serializerFn = getSchemaSerializer(reply.context, statusCode)
|
|
580
580
|
payload = (serializerFn === false)
|
|
581
581
|
? serializeError({
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
582
|
+
error: statusCodes[statusCode + ''],
|
|
583
|
+
code: error.code,
|
|
584
|
+
message: error.message || '',
|
|
585
|
+
statusCode
|
|
586
|
+
})
|
|
587
587
|
: serializerFn(Object.create(error, {
|
|
588
588
|
error: { value: statusCodes[statusCode + ''] },
|
|
589
589
|
message: { value: error.message || '' },
|
package/lib/schema-controller.js
CHANGED
package/lib/server.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fastify",
|
|
3
|
-
"version": "3.27.
|
|
3
|
+
"version": "3.27.4",
|
|
4
4
|
"description": "Fast and low overhead web framework, for Node.js",
|
|
5
5
|
"main": "fastify.js",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -12,7 +12,7 @@
|
|
|
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",
|
|
@@ -124,11 +124,11 @@
|
|
|
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
132
|
"JSONStream": "^1.3.5",
|
|
133
133
|
"ajv": "^6.0.0",
|
|
134
134
|
"ajv-errors": "^1.0.1",
|
|
@@ -140,13 +140,12 @@
|
|
|
140
140
|
"cors": "^2.8.5",
|
|
141
141
|
"coveralls": "^3.1.0",
|
|
142
142
|
"dns-prefetch-control": "^0.3.0",
|
|
143
|
-
"eslint": "^
|
|
144
|
-
"eslint-config-standard": "^
|
|
143
|
+
"eslint": "^8.0.1",
|
|
144
|
+
"eslint-config-standard": "^17.0.0-1",
|
|
145
145
|
"eslint-import-resolver-node": "^0.3.2",
|
|
146
|
-
"eslint-plugin-import": "^2.
|
|
147
|
-
"eslint-plugin-
|
|
148
|
-
"eslint-plugin-promise": "^
|
|
149
|
-
"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",
|
|
150
149
|
"fast-json-body": "^1.1.0",
|
|
151
150
|
"fastify-plugin": "^3.0.0",
|
|
152
151
|
"fluent-json-schema": "^3.0.0",
|
|
@@ -167,7 +166,7 @@
|
|
|
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",
|
|
@@ -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
|
@@ -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
|
})
|
package/test/close.test.js
CHANGED
|
@@ -215,7 +215,7 @@ t.test('Current opened connection should continue to work after closing and retu
|
|
|
215
215
|
t.error(err)
|
|
216
216
|
|
|
217
217
|
const port = fastify.server.address().port
|
|
218
|
-
const client = net.createConnection({ port
|
|
218
|
+
const client = net.createConnection({ port }, () => {
|
|
219
219
|
client.write('GET / HTTP/1.1\r\n\r\n')
|
|
220
220
|
|
|
221
221
|
client.once('data', data => {
|
|
@@ -29,7 +29,7 @@ test('config', t => {
|
|
|
29
29
|
method: 'GET',
|
|
30
30
|
url: '/route',
|
|
31
31
|
schema: schema.schema,
|
|
32
|
-
handler
|
|
32
|
+
handler,
|
|
33
33
|
config: Object.assign({}, schema.config)
|
|
34
34
|
})
|
|
35
35
|
|
|
@@ -37,7 +37,7 @@ test('config', t => {
|
|
|
37
37
|
method: 'GET',
|
|
38
38
|
url: '/no-config',
|
|
39
39
|
schema: schema.schema,
|
|
40
|
-
handler
|
|
40
|
+
handler
|
|
41
41
|
})
|
|
42
42
|
|
|
43
43
|
fastify.inject({
|
|
@@ -81,7 +81,7 @@ test('config with exposeHeadRoutes', t => {
|
|
|
81
81
|
method: 'GET',
|
|
82
82
|
url: '/route',
|
|
83
83
|
schema: schema.schema,
|
|
84
|
-
handler
|
|
84
|
+
handler,
|
|
85
85
|
config: Object.assign({}, schema.config)
|
|
86
86
|
})
|
|
87
87
|
|
|
@@ -89,7 +89,7 @@ test('config with exposeHeadRoutes', t => {
|
|
|
89
89
|
method: 'GET',
|
|
90
90
|
url: '/no-config',
|
|
91
91
|
schema: schema.schema,
|
|
92
|
-
handler
|
|
92
|
+
handler
|
|
93
93
|
})
|
|
94
94
|
|
|
95
95
|
fastify.inject({
|
package/test/inject.test.js
CHANGED
|
@@ -19,7 +19,7 @@ test('fastify.all should add all the methods to the same url', t => {
|
|
|
19
19
|
function injectRequest (method) {
|
|
20
20
|
const options = {
|
|
21
21
|
url: '/',
|
|
22
|
-
method
|
|
22
|
+
method
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
if (method === 'POST' || method === 'PUT' || method === 'PATCH') {
|
|
@@ -29,7 +29,7 @@ test('fastify.all should add all the methods to the same url', t => {
|
|
|
29
29
|
fastify.inject(options, (err, res) => {
|
|
30
30
|
t.error(err)
|
|
31
31
|
const payload = JSON.parse(res.payload)
|
|
32
|
-
t.same(payload, { method
|
|
32
|
+
t.same(payload, { method })
|
|
33
33
|
})
|
|
34
34
|
}
|
|
35
35
|
})
|
|
@@ -32,8 +32,8 @@ test('rawBody function', t => {
|
|
|
32
32
|
|
|
33
33
|
res.log = { error: () => { }, info: () => { } }
|
|
34
34
|
const context = {
|
|
35
|
-
Reply
|
|
36
|
-
Request
|
|
35
|
+
Reply,
|
|
36
|
+
Request,
|
|
37
37
|
preHandler: [],
|
|
38
38
|
onSend: [],
|
|
39
39
|
_parserOptions: {
|
|
@@ -85,8 +85,8 @@ test('Should support Webpack and faux modules', t => {
|
|
|
85
85
|
|
|
86
86
|
res.log = { error: () => { }, info: () => { } }
|
|
87
87
|
const context = {
|
|
88
|
-
Reply
|
|
89
|
-
Request
|
|
88
|
+
Reply,
|
|
89
|
+
Request,
|
|
90
90
|
preHandler: [],
|
|
91
91
|
onSend: [],
|
|
92
92
|
_parserOptions: {
|
|
@@ -62,8 +62,8 @@ test('handler function - invalid schema', t => {
|
|
|
62
62
|
}
|
|
63
63
|
},
|
|
64
64
|
handler: () => {},
|
|
65
|
-
Reply
|
|
66
|
-
Request
|
|
65
|
+
Reply,
|
|
66
|
+
Request,
|
|
67
67
|
preValidation: [],
|
|
68
68
|
preHandler: [],
|
|
69
69
|
onSend: [],
|
|
@@ -93,8 +93,8 @@ test('handler function - reply', t => {
|
|
|
93
93
|
reply.code(204)
|
|
94
94
|
reply.send(undefined)
|
|
95
95
|
},
|
|
96
|
-
Reply
|
|
97
|
-
Request
|
|
96
|
+
Reply,
|
|
97
|
+
Request,
|
|
98
98
|
preValidation: [],
|
|
99
99
|
preHandler: [],
|
|
100
100
|
onSend: [],
|
|
@@ -123,8 +123,8 @@ test('handler function - preValidationCallback with finished response', t => {
|
|
|
123
123
|
t.fail()
|
|
124
124
|
reply.send(undefined)
|
|
125
125
|
},
|
|
126
|
-
Reply
|
|
127
|
-
Request
|
|
126
|
+
Reply,
|
|
127
|
+
Request,
|
|
128
128
|
preValidation: null,
|
|
129
129
|
preHandler: [],
|
|
130
130
|
onSend: [],
|
|
@@ -150,8 +150,8 @@ test('handler function - preValidationCallback with finished response (< v12.9.0
|
|
|
150
150
|
t.fail()
|
|
151
151
|
reply.send(undefined)
|
|
152
152
|
},
|
|
153
|
-
Reply
|
|
154
|
-
Request
|
|
153
|
+
Reply,
|
|
154
|
+
Request,
|
|
155
155
|
preValidation: null,
|
|
156
156
|
preHandler: [],
|
|
157
157
|
onSend: [],
|
|
@@ -5,9 +5,8 @@ const test = t.test
|
|
|
5
5
|
const sget = require('simple-get').concat
|
|
6
6
|
const http = require('http')
|
|
7
7
|
const NotFound = require('http-errors').NotFound
|
|
8
|
-
const EventEmitter = require('events').EventEmitter
|
|
9
8
|
const Reply = require('../../lib/reply')
|
|
10
|
-
const { Writable } = require('stream')
|
|
9
|
+
const { Readable, Writable } = require('stream')
|
|
11
10
|
const {
|
|
12
11
|
kReplyErrorHandlerCalled,
|
|
13
12
|
kReplyHeaders,
|
|
@@ -40,30 +39,30 @@ test('Once called, Reply should return an object with methods', t => {
|
|
|
40
39
|
test('reply.send will logStream error and destroy the stream', { only: true }, t => {
|
|
41
40
|
t.plan(1)
|
|
42
41
|
let destroyCalled
|
|
43
|
-
const payload = new
|
|
42
|
+
const payload = new Readable({
|
|
43
|
+
read () {},
|
|
44
|
+
destroy (err, cb) {
|
|
45
|
+
destroyCalled = true
|
|
46
|
+
cb(err)
|
|
47
|
+
}
|
|
48
|
+
})
|
|
44
49
|
|
|
45
|
-
const response =
|
|
50
|
+
const response = new Writable()
|
|
51
|
+
Object.assign(response, {
|
|
46
52
|
setHeader: () => {},
|
|
47
53
|
hasHeader: () => false,
|
|
48
54
|
getHeader: () => undefined,
|
|
49
55
|
writeHead: () => {},
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
destroy: () => (destroyCalled = true),
|
|
53
|
-
on: () => {}
|
|
54
|
-
}
|
|
56
|
+
headersSent: true
|
|
57
|
+
})
|
|
55
58
|
|
|
56
59
|
const log = {
|
|
57
60
|
warn: () => {}
|
|
58
61
|
}
|
|
59
62
|
|
|
60
|
-
Object.assign(payload, {
|
|
61
|
-
pipe: () => {},
|
|
62
|
-
destroy: () => {}
|
|
63
|
-
})
|
|
64
63
|
const reply = new Reply(response, { context: { onSend: null } }, log)
|
|
65
64
|
reply.send(payload)
|
|
66
|
-
payload.
|
|
65
|
+
payload.destroy(new Error('stream error'))
|
|
67
66
|
|
|
68
67
|
t.equal(destroyCalled, true, 'Error not logged and not streamed')
|
|
69
68
|
})
|
package/test/logger.test.js
CHANGED
|
@@ -37,7 +37,7 @@ test('defaults to info level', t => {
|
|
|
37
37
|
try {
|
|
38
38
|
fastify = Fastify({
|
|
39
39
|
logger: {
|
|
40
|
-
stream
|
|
40
|
+
stream
|
|
41
41
|
}
|
|
42
42
|
})
|
|
43
43
|
} catch (e) {
|
|
@@ -85,7 +85,7 @@ test('test log stream', t => {
|
|
|
85
85
|
try {
|
|
86
86
|
fastify = Fastify({
|
|
87
87
|
logger: {
|
|
88
|
-
stream
|
|
88
|
+
stream,
|
|
89
89
|
level: 'info'
|
|
90
90
|
}
|
|
91
91
|
})
|
|
@@ -132,7 +132,7 @@ test('test error log stream', t => {
|
|
|
132
132
|
try {
|
|
133
133
|
fastify = Fastify({
|
|
134
134
|
logger: {
|
|
135
|
-
stream
|
|
135
|
+
stream,
|
|
136
136
|
level: 'info'
|
|
137
137
|
}
|
|
138
138
|
})
|
|
@@ -182,7 +182,7 @@ test('can use external logger instance', t => {
|
|
|
182
182
|
|
|
183
183
|
const logger = require('pino')(splitStream)
|
|
184
184
|
|
|
185
|
-
const localFastify = Fastify({ logger
|
|
185
|
+
const localFastify = Fastify({ logger })
|
|
186
186
|
|
|
187
187
|
localFastify.get('/foo', function (req, reply) {
|
|
188
188
|
t.ok(req.log)
|
|
@@ -226,7 +226,7 @@ test('can use external logger instance with custom serializer', t => {
|
|
|
226
226
|
}, splitStream)
|
|
227
227
|
|
|
228
228
|
const localFastify = Fastify({
|
|
229
|
-
logger
|
|
229
|
+
logger
|
|
230
230
|
})
|
|
231
231
|
|
|
232
232
|
localFastify.get('/foo', function (req, reply) {
|
|
@@ -253,7 +253,7 @@ test('expose the logger', t => {
|
|
|
253
253
|
try {
|
|
254
254
|
fastify = Fastify({
|
|
255
255
|
logger: {
|
|
256
|
-
stream
|
|
256
|
+
stream,
|
|
257
257
|
level: 'info'
|
|
258
258
|
}
|
|
259
259
|
})
|
|
@@ -271,7 +271,7 @@ test('The request id header key can be customized', t => {
|
|
|
271
271
|
|
|
272
272
|
const stream = split(JSON.parse)
|
|
273
273
|
const fastify = Fastify({
|
|
274
|
-
logger: { stream
|
|
274
|
+
logger: { stream, level: 'info' },
|
|
275
275
|
requestIdHeader: 'my-custom-request-id'
|
|
276
276
|
})
|
|
277
277
|
t.teardown(() => fastify.close())
|
|
@@ -316,7 +316,7 @@ test('The request id header key can be customized along with a custom id generat
|
|
|
316
316
|
|
|
317
317
|
const stream = split(JSON.parse)
|
|
318
318
|
const fastify = Fastify({
|
|
319
|
-
logger: { stream
|
|
319
|
+
logger: { stream, level: 'info' },
|
|
320
320
|
requestIdHeader: 'my-custom-request-id',
|
|
321
321
|
genReqId (req) {
|
|
322
322
|
return 'foo'
|
|
@@ -379,7 +379,7 @@ test('The request id log label can be changed', t => {
|
|
|
379
379
|
|
|
380
380
|
const stream = split(JSON.parse)
|
|
381
381
|
const fastify = Fastify({
|
|
382
|
-
logger: { stream
|
|
382
|
+
logger: { stream, level: 'info' },
|
|
383
383
|
requestIdHeader: 'my-custom-request-id',
|
|
384
384
|
requestIdLogLabel: 'traceId'
|
|
385
385
|
})
|
|
@@ -422,7 +422,7 @@ test('The logger should accept custom serializer', t => {
|
|
|
422
422
|
const stream = split(JSON.parse)
|
|
423
423
|
const fastify = Fastify({
|
|
424
424
|
logger: {
|
|
425
|
-
stream
|
|
425
|
+
stream,
|
|
426
426
|
level: 'info',
|
|
427
427
|
serializers: {
|
|
428
428
|
req: function (req) {
|
|
@@ -1151,7 +1151,7 @@ test('should serialize request and response', t => {
|
|
|
1151
1151
|
const stream = split(JSON.parse)
|
|
1152
1152
|
const fastify = Fastify({
|
|
1153
1153
|
logger: {
|
|
1154
|
-
stream
|
|
1154
|
+
stream,
|
|
1155
1155
|
level: 'info'
|
|
1156
1156
|
}
|
|
1157
1157
|
})
|
|
@@ -1173,7 +1173,7 @@ test('Do not wrap IPv4 address', t => {
|
|
|
1173
1173
|
const stream = split(JSON.parse)
|
|
1174
1174
|
const fastify = Fastify({
|
|
1175
1175
|
logger: {
|
|
1176
|
-
stream
|
|
1176
|
+
stream,
|
|
1177
1177
|
level: 'info'
|
|
1178
1178
|
}
|
|
1179
1179
|
})
|
|
@@ -1241,7 +1241,7 @@ test('should log the error if no error handler is defined', t => {
|
|
|
1241
1241
|
const stream = split(JSON.parse)
|
|
1242
1242
|
const fastify = Fastify({
|
|
1243
1243
|
logger: {
|
|
1244
|
-
stream
|
|
1244
|
+
stream,
|
|
1245
1245
|
level: 'info'
|
|
1246
1246
|
}
|
|
1247
1247
|
})
|
|
@@ -1275,7 +1275,7 @@ test('should log as info if error status code >= 400 and < 500 if no error handl
|
|
|
1275
1275
|
const stream = split(JSON.parse)
|
|
1276
1276
|
const fastify = Fastify({
|
|
1277
1277
|
logger: {
|
|
1278
|
-
stream
|
|
1278
|
+
stream,
|
|
1279
1279
|
level: 'info'
|
|
1280
1280
|
}
|
|
1281
1281
|
})
|
|
@@ -1313,7 +1313,7 @@ test('should log as error if error status code >= 500 if no error handler is def
|
|
|
1313
1313
|
const stream = split(JSON.parse)
|
|
1314
1314
|
const fastify = Fastify({
|
|
1315
1315
|
logger: {
|
|
1316
|
-
stream
|
|
1316
|
+
stream,
|
|
1317
1317
|
level: 'info'
|
|
1318
1318
|
}
|
|
1319
1319
|
})
|
|
@@ -1347,7 +1347,7 @@ test('should not log the error if error handler is defined', t => {
|
|
|
1347
1347
|
const stream = split(JSON.parse)
|
|
1348
1348
|
const fastify = Fastify({
|
|
1349
1349
|
logger: {
|
|
1350
|
-
stream
|
|
1350
|
+
stream,
|
|
1351
1351
|
level: 'info'
|
|
1352
1352
|
}
|
|
1353
1353
|
})
|
|
@@ -1381,7 +1381,7 @@ test('should not rely on raw request to log errors', t => {
|
|
|
1381
1381
|
const stream = split(JSON.parse)
|
|
1382
1382
|
const fastify = Fastify({
|
|
1383
1383
|
logger: {
|
|
1384
|
-
stream
|
|
1384
|
+
stream,
|
|
1385
1385
|
level: 'info'
|
|
1386
1386
|
}
|
|
1387
1387
|
})
|
|
@@ -1412,7 +1412,7 @@ test('should redact the authorization header if so specified', t => {
|
|
|
1412
1412
|
const stream = split(JSON.parse)
|
|
1413
1413
|
const fastify = Fastify({
|
|
1414
1414
|
logger: {
|
|
1415
|
-
stream
|
|
1415
|
+
stream,
|
|
1416
1416
|
redact: ['req.headers.authorization'],
|
|
1417
1417
|
level: 'info',
|
|
1418
1418
|
serializers: {
|
|
@@ -21,7 +21,7 @@ test('maxRequestsPerSocket on node version >= 16.10.0', { skip }, t => {
|
|
|
21
21
|
t.error(err)
|
|
22
22
|
|
|
23
23
|
const port = fastify.server.address().port
|
|
24
|
-
const client = net.createConnection({ port
|
|
24
|
+
const client = net.createConnection({ port }, () => {
|
|
25
25
|
client.write('GET / HTTP/1.1\r\n\r\n')
|
|
26
26
|
|
|
27
27
|
client.once('data', data => {
|
|
@@ -61,7 +61,7 @@ test('maxRequestsPerSocket zero should behave same as null', { skip }, t => {
|
|
|
61
61
|
t.error(err)
|
|
62
62
|
|
|
63
63
|
const port = fastify.server.address().port
|
|
64
|
-
const client = net.createConnection({ port
|
|
64
|
+
const client = net.createConnection({ port }, () => {
|
|
65
65
|
client.write('GET / HTTP/1.1\r\n\r\n')
|
|
66
66
|
|
|
67
67
|
client.once('data', data => {
|
|
@@ -23,7 +23,7 @@ test('skip automatic reply.send() with reply.sent = true and a body', (t) => {
|
|
|
23
23
|
const stream = split(JSON.parse)
|
|
24
24
|
const app = Fastify({
|
|
25
25
|
logger: {
|
|
26
|
-
stream
|
|
26
|
+
stream
|
|
27
27
|
}
|
|
28
28
|
})
|
|
29
29
|
|
|
@@ -52,7 +52,7 @@ test('skip automatic reply.send() with reply.sent = true and no body', (t) => {
|
|
|
52
52
|
const stream = split(JSON.parse)
|
|
53
53
|
const app = Fastify({
|
|
54
54
|
logger: {
|
|
55
|
-
stream
|
|
55
|
+
stream
|
|
56
56
|
}
|
|
57
57
|
})
|
|
58
58
|
|
|
@@ -81,7 +81,7 @@ test('skip automatic reply.send() with reply.sent = true and an error', (t) => {
|
|
|
81
81
|
const stream = split(JSON.parse)
|
|
82
82
|
const app = Fastify({
|
|
83
83
|
logger: {
|
|
84
|
-
stream
|
|
84
|
+
stream
|
|
85
85
|
}
|
|
86
86
|
})
|
|
87
87
|
|
|
@@ -125,7 +125,7 @@ function testHandlerOrBeforeHandlerHook (test, hookOrHandler) {
|
|
|
125
125
|
const stream = split(JSON.parse)
|
|
126
126
|
const app = Fastify({
|
|
127
127
|
logger: {
|
|
128
|
-
stream
|
|
128
|
+
stream
|
|
129
129
|
}
|
|
130
130
|
})
|
|
131
131
|
|
|
@@ -170,7 +170,7 @@ function testHandlerOrBeforeHandlerHook (test, hookOrHandler) {
|
|
|
170
170
|
const stream = split(JSON.parse)
|
|
171
171
|
const app = Fastify({
|
|
172
172
|
logger: {
|
|
173
|
-
stream
|
|
173
|
+
stream
|
|
174
174
|
}
|
|
175
175
|
})
|
|
176
176
|
t.teardown(() => app.close())
|
|
@@ -224,7 +224,7 @@ function testHandlerOrBeforeHandlerHook (test, hookOrHandler) {
|
|
|
224
224
|
const stream = split(JSON.parse)
|
|
225
225
|
const app = Fastify({
|
|
226
226
|
logger: {
|
|
227
|
-
stream
|
|
227
|
+
stream
|
|
228
228
|
}
|
|
229
229
|
})
|
|
230
230
|
t.teardown(() => app.close())
|
|
@@ -274,7 +274,7 @@ function testHandlerOrBeforeHandlerHook (test, hookOrHandler) {
|
|
|
274
274
|
const stream = split(JSON.parse)
|
|
275
275
|
const app = Fastify({
|
|
276
276
|
logger: {
|
|
277
|
-
stream
|
|
277
|
+
stream
|
|
278
278
|
}
|
|
279
279
|
})
|
|
280
280
|
|
package/test/trust-proxy.test.js
CHANGED
|
@@ -206,6 +206,7 @@ expectAssignable<FastifyInstance>(fastify({
|
|
|
206
206
|
expectType<Socket>(socket)
|
|
207
207
|
}
|
|
208
208
|
}))
|
|
209
|
+
expectAssignable<FastifyInstance>(fastify({ jsonShorthand: true }))
|
|
209
210
|
|
|
210
211
|
// Thenable
|
|
211
212
|
expectAssignable<PromiseLike<FastifyInstance>>(fastify({ return503OnClosing: true }))
|
|
@@ -7,7 +7,9 @@ import fastify, {
|
|
|
7
7
|
RawReplyDefaultExpression,
|
|
8
8
|
RawRequestDefaultExpression,
|
|
9
9
|
RawServerBase,
|
|
10
|
-
RouteOptions
|
|
10
|
+
RouteOptions,
|
|
11
|
+
RegisterOptions,
|
|
12
|
+
FastifyPluginOptions
|
|
11
13
|
} from '../../fastify'
|
|
12
14
|
import { preHandlerAsyncHookHandler, RequestPayload } from '../../types/hooks'
|
|
13
15
|
|
|
@@ -113,8 +115,9 @@ server.addHook('onRoute', function (opts) {
|
|
|
113
115
|
expectType<RouteOptions & { routePath: string; path: string; prefix: string}>(opts)
|
|
114
116
|
})
|
|
115
117
|
|
|
116
|
-
server.addHook('onRegister', (instance, done) => {
|
|
118
|
+
server.addHook('onRegister', (instance, opts, done) => {
|
|
117
119
|
expectType<FastifyInstance>(instance)
|
|
120
|
+
expectType<RegisterOptions & FastifyPluginOptions>(opts)
|
|
118
121
|
expectAssignable<(err?: FastifyError) => void>(done)
|
|
119
122
|
expectAssignable<(err?: NodeJS.ErrnoException) => void>(done)
|
|
120
123
|
expectType<void>(done(new Error()))
|
|
@@ -194,8 +197,9 @@ server.addHook('onError', async function (request, reply, error) {
|
|
|
194
197
|
expectType<FastifyError>(error)
|
|
195
198
|
})
|
|
196
199
|
|
|
197
|
-
server.addHook('onRegister', async (instance) => {
|
|
200
|
+
server.addHook('onRegister', async (instance, opts) => {
|
|
198
201
|
expectType<FastifyInstance>(instance)
|
|
202
|
+
expectType<RegisterOptions & FastifyPluginOptions>(opts)
|
|
199
203
|
})
|
|
200
204
|
|
|
201
205
|
server.addHook('onReady', async function () {
|
|
@@ -140,7 +140,7 @@ test('error inside custom error handler should have validationContext if specifi
|
|
|
140
140
|
return function (data) {
|
|
141
141
|
const error = new Error('this failed')
|
|
142
142
|
error.validationContext = 'customContext'
|
|
143
|
-
return { error
|
|
143
|
+
return { error }
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
}, function (req, reply) {
|
package/types/.eslintrc.json
CHANGED
|
@@ -31,12 +31,14 @@
|
|
|
31
31
|
"files": ["*.test-d.ts"],
|
|
32
32
|
"rules": {
|
|
33
33
|
"no-unused-vars": "off",
|
|
34
|
-
"
|
|
34
|
+
"n/handle-callback-err": "off",
|
|
35
35
|
"@typescript-eslint/no-empty-function": "off",
|
|
36
36
|
"@typescript-eslint/explicit-function-return-type": "off",
|
|
37
37
|
"@typescript-eslint/no-unused-vars": "off",
|
|
38
38
|
"@typescript-eslint/no-non-null-assertion": "off",
|
|
39
|
-
"@typescript-eslint/no-misused-promises": ["error"
|
|
39
|
+
"@typescript-eslint/no-misused-promises": ["error", {
|
|
40
|
+
"checksVoidReturn": false
|
|
41
|
+
}]
|
|
40
42
|
},
|
|
41
43
|
"globals": {
|
|
42
44
|
"NodeJS": "readonly"
|
package/types/hooks.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ import { FastifyRequest } from './request'
|
|
|
6
6
|
import { FastifyReply } from './reply'
|
|
7
7
|
import { FastifyError } from 'fastify-error'
|
|
8
8
|
import { FastifyLoggerInstance } from './logger'
|
|
9
|
+
import { RegisterOptions } from './register'
|
|
10
|
+
import { FastifyPluginOptions } from './plugin'
|
|
9
11
|
|
|
10
12
|
type HookHandlerDoneFunction = <TError extends Error = FastifyError>(err?: TError) => void
|
|
11
13
|
|
|
@@ -360,10 +362,12 @@ export interface onRegisterHookHandler<
|
|
|
360
362
|
RawServer extends RawServerBase = RawServerDefault,
|
|
361
363
|
RawRequest extends RawRequestDefaultExpression<RawServer> = RawRequestDefaultExpression<RawServer>,
|
|
362
364
|
RawReply extends RawReplyDefaultExpression<RawServer> = RawReplyDefaultExpression<RawServer>,
|
|
363
|
-
Logger = FastifyLoggerInstance
|
|
365
|
+
Logger = FastifyLoggerInstance,
|
|
366
|
+
Options extends FastifyPluginOptions = FastifyPluginOptions
|
|
364
367
|
> {
|
|
365
368
|
(
|
|
366
369
|
instance: FastifyInstance<RawServer, RawRequest, RawReply, Logger>,
|
|
370
|
+
opts: RegisterOptions & Options,
|
|
367
371
|
done: HookHandlerDoneFunction
|
|
368
372
|
): Promise<unknown> | void; // documentation is missing the `done` method
|
|
369
373
|
}
|
package/types/register.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { FastifyPluginOptions, FastifyPluginCallback, FastifyPluginAsync } from
|
|
|
2
2
|
import { LogLevel } from './logger'
|
|
3
3
|
import { FastifyInstance } from './instance'
|
|
4
4
|
|
|
5
|
-
interface RegisterOptions {
|
|
5
|
+
export interface RegisterOptions {
|
|
6
6
|
prefix?: string;
|
|
7
7
|
logLevel?: LogLevel;
|
|
8
8
|
logSerializers?: Record<string, (value: any) => string>;
|