fastify 4.2.0 → 4.2.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/README.md +13 -14
- package/docs/Guides/Database.md +2 -2
- package/docs/Guides/Ecosystem.md +21 -18
- package/docs/Guides/Migration-Guide-V4.md +29 -0
- package/docs/Guides/Plugins-Guide.md +5 -0
- package/docs/Reference/Type-Providers.md +1 -15
- package/docs/Reference/TypeScript.md +27 -3
- package/fastify.js +1 -1
- package/lib/error-serializer.js +12 -12
- package/lib/reply.js +21 -22
- package/package.json +6 -6
- package/test/build/error-serializer.test.js +3 -1
- package/test/schema-validation.test.js +71 -0
- package/test/types/fastify.test-d.ts +12 -1
- package/test/types/instance.test-d.ts +4 -1
- package/test/validation-error-handling.test.js +6 -1
- package/types/instance.d.ts +59 -91
- package/types/schema.d.ts +4 -1
package/README.md
CHANGED
|
@@ -38,18 +38,18 @@ resources of your server, knowing that you are serving the highest number of
|
|
|
38
38
|
requests as possible, without sacrificing security validations and handy
|
|
39
39
|
development?
|
|
40
40
|
|
|
41
|
-
- [Quick start](
|
|
42
|
-
- [Install](
|
|
43
|
-
- [Example](
|
|
44
|
-
- [Fastify v1.x and v2.x](
|
|
45
|
-
- [Core features](
|
|
46
|
-
- [Benchmarks](
|
|
47
|
-
- [Documentation](
|
|
48
|
-
- [Ecosystem](
|
|
49
|
-
- [Support](
|
|
50
|
-
- [Team](
|
|
51
|
-
- [Hosted by](
|
|
52
|
-
- [License](
|
|
41
|
+
- [Quick start](#quick-start)
|
|
42
|
+
- [Install](#install)
|
|
43
|
+
- [Example](#example)
|
|
44
|
+
- [Fastify v1.x and v2.x](#fastify-v1x-and-v2x)
|
|
45
|
+
- [Core features](#core-features)
|
|
46
|
+
- [Benchmarks](#benchmarks)
|
|
47
|
+
- [Documentation](#documentation)
|
|
48
|
+
- [Ecosystem](#ecosystem)
|
|
49
|
+
- [Support](#support)
|
|
50
|
+
- [Team](#team)
|
|
51
|
+
- [Hosted by](#hosted-by)
|
|
52
|
+
- [License](#license)
|
|
53
53
|
|
|
54
54
|
Enter Fastify. Fastify is a web framework highly focused on providing the best
|
|
55
55
|
developer experience with the least overhead and a powerful plugin architecture.
|
|
@@ -99,8 +99,7 @@ generate functionality of [Fastify CLI](https://github.com/fastify/fastify-cli).
|
|
|
99
99
|
|
|
100
100
|
### Install
|
|
101
101
|
|
|
102
|
-
|
|
103
|
-
project as a dependency:
|
|
102
|
+
To install Fastify in an existing project as a dependency:
|
|
104
103
|
|
|
105
104
|
Install with npm:
|
|
106
105
|
```sh
|
package/docs/Guides/Database.md
CHANGED
|
@@ -204,7 +204,7 @@ function knexPlugin(fastify, options, done) {
|
|
|
204
204
|
done()
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
-
export default fp(
|
|
207
|
+
export default fp(knexPlugin, { name: 'fastify-knex-example' })
|
|
208
208
|
```
|
|
209
209
|
|
|
210
210
|
### Writing a plugin for a database engine
|
|
@@ -213,7 +213,7 @@ In this example, we will create a basic Fastify MySQL plugin from scratch (it is
|
|
|
213
213
|
a stripped-down example, please use the official plugin in production).
|
|
214
214
|
|
|
215
215
|
```javascript
|
|
216
|
-
const fp = require('
|
|
216
|
+
const fp = require('fastify-plugin')
|
|
217
217
|
const mysql = require('mysql2/promise')
|
|
218
218
|
|
|
219
219
|
function fastifyMysql(fastify, options, done) {
|
package/docs/Guides/Ecosystem.md
CHANGED
|
@@ -138,8 +138,8 @@ section.
|
|
|
138
138
|
Tiny (~5k), Fast, KISS, and dependency-free Node.JS library to make your
|
|
139
139
|
Fastify API graceful.
|
|
140
140
|
- [`@h4ad/serverless-adapter`](https://github.com/H4ad/serverless-adapter)
|
|
141
|
-
Run REST APIs and other web applications using your existing Node.js
|
|
142
|
-
application framework (Express, Koa, Hapi and Fastify), on top of AWS Lambda,
|
|
141
|
+
Run REST APIs and other web applications using your existing Node.js
|
|
142
|
+
application framework (Express, Koa, Hapi and Fastify), on top of AWS Lambda,
|
|
143
143
|
Huawei and many other clouds.
|
|
144
144
|
- [`@immobiliarelabs/fastify-metrics`](https://github.com/immobiliare/fastify-metrics)
|
|
145
145
|
Minimalistic and opinionated plugin that collects usage/process metrics and
|
|
@@ -151,12 +151,12 @@ section.
|
|
|
151
151
|
A plugin to close the server gracefully
|
|
152
152
|
- [`@mgcrea/fastify-request-logger`](https://github.com/mgcrea/fastify-request-logger)
|
|
153
153
|
A plugin to enable compact request logging for Fastify
|
|
154
|
+
- [`@mgcrea/fastify-session`](https://github.com/mgcrea/fastify-session) Session
|
|
155
|
+
plugin for Fastify that supports both stateless and stateful sessions
|
|
154
156
|
- [`@mgcrea/fastify-session-redis-store`](https://github.com/mgcrea/fastify-session-redis-store)
|
|
155
157
|
Redis store for @mgcrea/fastify-session using ioredis
|
|
156
158
|
- [`@mgcrea/fastify-session-sodium-crypto`](https://github.com/mgcrea/fastify-session-sodium-crypto)
|
|
157
159
|
Fast sodium-based crypto for @mgcrea/fastify-session
|
|
158
|
-
- [`@mgcrea/fastify-session`](https://github.com/mgcrea/fastify-session) Session
|
|
159
|
-
plugin for Fastify that supports both stateless and stateful sessions
|
|
160
160
|
- [`@mgcrea/pino-pretty-compact`](https://github.com/mgcrea/pino-pretty-compact)
|
|
161
161
|
A custom compact pino-base prettifier
|
|
162
162
|
- [`@trubavuong/fastify-seaweedfs`](https://github.com/trubavuong/fastify-seaweedfs)
|
|
@@ -169,6 +169,8 @@ section.
|
|
|
169
169
|
- [`cls-rtracer`](https://github.com/puzpuzpuz/cls-rtracer) Fastify middleware
|
|
170
170
|
for CLS-based request ID generation. An out-of-the-box solution for adding
|
|
171
171
|
request IDs into your logs.
|
|
172
|
+
- [`fast-water`](https://github.com/tswayne/fast-water) A Fastify plugin for
|
|
173
|
+
waterline. Decorates Fastify with waterline models.
|
|
172
174
|
- [`fastify-405`](https://github.com/Eomm/fastify-405) Fastify plugin that adds
|
|
173
175
|
405 HTTP status to your routes
|
|
174
176
|
- [`fastify-allow`](https://github.com/mattbishop/fastify-allow) Fastify plugin
|
|
@@ -287,13 +289,13 @@ section.
|
|
|
287
289
|
good Fastify sessions plugin focused on speed.
|
|
288
290
|
- [`fastify-google-cloud-storage`](https://github.com/carlozamagni/fastify-google-cloud-storage)
|
|
289
291
|
Fastify plugin that exposes a GCP Cloud Storage client instance.
|
|
292
|
+
- [`fastify-graceful-shutdown`](https://github.com/hemerajs/fastify-graceful-shutdown)
|
|
293
|
+
Shutdown Fastify gracefully and asynchronously.
|
|
290
294
|
- [`fastify-grant`](https://github.com/simov/fastify-grant)
|
|
291
295
|
Authentication/Authorization plugin for Fastify that supports 200+ OAuth
|
|
292
296
|
Providers.
|
|
293
297
|
- [`fastify-guard`](https://github.com/hsynlms/fastify-guard) A Fastify plugin
|
|
294
298
|
that protects endpoints by checking authenticated user roles and/or scopes.
|
|
295
|
-
- [`fastify-graceful-shutdown`](https://github.com/hemerajs/fastify-graceful-shutdown)
|
|
296
|
-
Shutdown Fastify gracefully and asynchronously.
|
|
297
299
|
- [`fastify-hasura`](https://github.com/ManUtopiK/fastify-hasura) A Fastify
|
|
298
300
|
plugin to have fun with [Hasura](https://github.com/hasura/graphql-engine).
|
|
299
301
|
- [`fastify-healthcheck`](https://github.com/smartiniOnGitHub/fastify-healthcheck)
|
|
@@ -301,20 +303,19 @@ section.
|
|
|
301
303
|
- [`fastify-hemera`](https://github.com/hemerajs/fastify-hemera) Fastify Hemera
|
|
302
304
|
plugin, for writing reliable & fault-tolerant microservices with
|
|
303
305
|
[nats.io](https://nats.io/).
|
|
306
|
+
- [`fastify-http-client`](https://github.com/kenuyx/fastify-http-client) Plugin
|
|
307
|
+
to send HTTP(s) requests. Built upon [urllib](https://github.com/node-modules/urllib).
|
|
304
308
|
- [`fastify-http-context`](https://github.com/thorough-developer/fastify-http-context)
|
|
305
309
|
Fastify plugin for "simulating" a thread of execution to allow for true HTTP
|
|
306
310
|
context to take place per API call within the Fastify lifecycle of calls.
|
|
311
|
+
- [`fastify-http-errors-enhanced`](https://github.com/ShogunPanda/fastify-http-errors-enhanced)
|
|
312
|
+
An error handling plugin for Fastify that uses enhanced HTTP errors.
|
|
307
313
|
- [`fastify-http2https`](https://github.com/lolo32/fastify-http2https) Redirect
|
|
308
314
|
HTTP requests to HTTPS, both using the same port number, or different response
|
|
309
315
|
on HTTP and HTTPS.
|
|
310
|
-
- [`fastify-http-client`](https://github.com/kenuyx/fastify-http-client) Plugin
|
|
311
|
-
to send HTTP(s) requests. Built upon
|
|
312
|
-
[urllib](https://github.com/node-modules/urllib).
|
|
313
|
-
- [`fastify-http-errors-enhanced`](https://github.com/ShogunPanda/fastify-http-errors-enhanced)
|
|
314
|
-
An error handling plugin for Fastify that uses enhanced HTTP errors.
|
|
315
316
|
- [`fastify-https-redirect`](https://github.com/tomsvogel/fastify-https-redirect)
|
|
316
317
|
Fastify plugin for auto-redirect from HTTP to HTTPS.
|
|
317
|
-
- [`
|
|
318
|
+
- [`fastify-impressions`](https://github.com/manju4ever/fastify-impressions)
|
|
318
319
|
Fastify plugin to track impressions of all the routes.
|
|
319
320
|
- [`fastify-influxdb`](https://github.com/alex-ppg/fastify-influxdb) Fastify
|
|
320
321
|
InfluxDB plugin connecting to an InfluxDB instance via the Influx default
|
|
@@ -408,10 +409,10 @@ section.
|
|
|
408
409
|
- [`fastify-orientdb`](https://github.com/mahmed8003/fastify-orientdb) Fastify
|
|
409
410
|
OrientDB connection plugin, with which you can share the OrientDB connection
|
|
410
411
|
across every part of your server.
|
|
411
|
-
- [`fastify-piscina`](https://github.com/piscinajs/fastify-piscina) A worker
|
|
412
|
-
thread pool plugin using [Piscina](https://github.com/piscinajs/piscina).
|
|
413
412
|
- [`fastify-peekaboo`](https://github.com/simone-sanfratello/fastify-peekaboo)
|
|
414
413
|
Fastify plugin for memoize responses by expressive settings.
|
|
414
|
+
- [`fastify-piscina`](https://github.com/piscinajs/fastify-piscina) A worker
|
|
415
|
+
thread pool plugin using [Piscina](https://github.com/piscinajs/piscina).
|
|
415
416
|
- [`fastify-polyglot`](https://github.com/heply/fastify-polyglot) A plugin to
|
|
416
417
|
handle i18n using
|
|
417
418
|
[node-polyglot](https://www.npmjs.com/package/node-polyglot).
|
|
@@ -444,10 +445,10 @@ section.
|
|
|
444
445
|
- [`fastify-register-routes`](https://github.com/israeleriston/fastify-register-routes)
|
|
445
446
|
Plugin to automatically load routes from a specified path and optionally limit
|
|
446
447
|
loaded file names by a regular expression.
|
|
447
|
-
- [`fastify-response-time`](https://github.com/lolo32/fastify-response-time) Add
|
|
448
|
-
`X-Response-Time` header at each request for Fastify, in milliseconds.
|
|
449
448
|
- [`fastify-response-caching`](https://github.com/codeaholicguy/fastify-response-caching)
|
|
450
449
|
A Fastify plugin for caching the response.
|
|
450
|
+
- [`fastify-response-time`](https://github.com/lolo32/fastify-response-time) Add
|
|
451
|
+
`X-Response-Time` header at each request for Fastify, in milliseconds.
|
|
451
452
|
- [`fastify-resty`](https://github.com/FastifyResty/fastify-resty) Fastify-based
|
|
452
453
|
web framework with REST API routes auto-generation for TypeORM entities using
|
|
453
454
|
DI and decorators.
|
|
@@ -518,8 +519,6 @@ section.
|
|
|
518
519
|
should use.
|
|
519
520
|
- [`fastify-wamp-router`](https://github.com/lependu/fastify-wamp-router) Web
|
|
520
521
|
Application Messaging Protocol router for Fastify.
|
|
521
|
-
- [`fast-water`](https://github.com/tswayne/fast-water) A Fastify plugin for
|
|
522
|
-
waterline. Decorates Fastify with waterline models.
|
|
523
522
|
- [`fastify-webpack-hmr`](https://github.com/lependu/fastify-webpack-hmr)
|
|
524
523
|
Webpack hot module reloading plugin for Fastify.
|
|
525
524
|
- [`fastify-webpack-hot`](https://github.com/gajus/fastify-webpack-hot) Webpack
|
|
@@ -552,7 +551,11 @@ section.
|
|
|
552
551
|
Fastify.
|
|
553
552
|
- [`sequelize-fastify`](https://github.com/hsynlms/sequelize-fastify) A simple
|
|
554
553
|
and lightweight Sequelize plugin for Fastify.
|
|
554
|
+
- [`typeorm-fastify-plugin`](https://github.com/jclemens24/fastify-typeorm) A simple
|
|
555
|
+
and updated Typeorm plugin for use with Fastify.
|
|
555
556
|
|
|
556
557
|
#### [Community Tools](#community-tools)
|
|
557
558
|
- [`fast-maker`](https://github.com/imjuni/fast-maker) route configuration
|
|
558
559
|
generator by directory structure.
|
|
560
|
+
- [`simple-tjscli`](https://github.com/imjuni/simple-tjscli) CLI tool to
|
|
561
|
+
generate JSON Schema from TypeScript interfaces.
|
|
@@ -65,6 +65,35 @@ Starting from v4, all the `GET` routes will create a sibling `HEAD` route.
|
|
|
65
65
|
You can revert this behaviour by setting the server's option `exposeHeadRoutes`
|
|
66
66
|
to `false`.
|
|
67
67
|
|
|
68
|
+
### Synchronous route definitions
|
|
69
|
+
|
|
70
|
+
The route registration has been made synchronous from v4.
|
|
71
|
+
This change was done to provide better error reporting for route definition.
|
|
72
|
+
As a result if you specify an `onRoute` hook in a plugin you should either:
|
|
73
|
+
* wrap your routes in a plugin (recommended)
|
|
74
|
+
* use `await register(...)`
|
|
75
|
+
|
|
76
|
+
For example refactor this:
|
|
77
|
+
```
|
|
78
|
+
fastify.register((instance, opts, done) => {
|
|
79
|
+
instance.addHook('onRoute', (routeOptions) => {
|
|
80
|
+
const { path, method } = routeOptions;
|
|
81
|
+
console.log({ path, method });
|
|
82
|
+
});
|
|
83
|
+
done();
|
|
84
|
+
});
|
|
85
|
+
```
|
|
86
|
+
Into this:
|
|
87
|
+
```
|
|
88
|
+
await fastify.register((instance, opts, done) => {
|
|
89
|
+
instance.addHook('onRoute', (routeOptions) => {
|
|
90
|
+
const { path, method } = routeOptions;
|
|
91
|
+
console.log({ path, method });
|
|
92
|
+
});
|
|
93
|
+
done();
|
|
94
|
+
});
|
|
95
|
+
```
|
|
96
|
+
|
|
68
97
|
## Non Breaking Changes
|
|
69
98
|
|
|
70
99
|
### Change of schema for multiple types
|
|
@@ -196,6 +196,11 @@ fastify.get('/html', (request, reply) => {
|
|
|
196
196
|
reply.html({ hello: 'world' })
|
|
197
197
|
})
|
|
198
198
|
```
|
|
199
|
+
Reminder that the `this` keyword is not available on *arrow functions*,
|
|
200
|
+
so when passing functions in *`decorateReply`* and *`decorateRequest`* as
|
|
201
|
+
a utility that also needs access to the `request` and `reply` instance,
|
|
202
|
+
a function that is defined using the `function` keyword is needed instead
|
|
203
|
+
of an *arrow function expression*.
|
|
199
204
|
|
|
200
205
|
In the same way you can do this for the `request` object:
|
|
201
206
|
```js
|
|
@@ -70,14 +70,7 @@ import { Type } from '@sinclair/typebox'
|
|
|
70
70
|
|
|
71
71
|
import fastify from 'fastify'
|
|
72
72
|
|
|
73
|
-
const server = fastify(
|
|
74
|
-
ajv: {
|
|
75
|
-
customOptions: {
|
|
76
|
-
strict: 'log',
|
|
77
|
-
keywords: ['kind', 'modifier'],
|
|
78
|
-
},
|
|
79
|
-
},
|
|
80
|
-
}).withTypeProvider<TypeBoxTypeProvider>()
|
|
73
|
+
const server = fastify().withTypeProvider<TypeBoxTypeProvider>()
|
|
81
74
|
|
|
82
75
|
server.get('/route', {
|
|
83
76
|
schema: {
|
|
@@ -94,13 +87,6 @@ server.get('/route', {
|
|
|
94
87
|
})
|
|
95
88
|
```
|
|
96
89
|
|
|
97
|
-
TypeBox uses the properties `kind` and `modifier` internally. These properties
|
|
98
|
-
are not strictly valid JSON schema which will cause `AJV@7` and newer versions
|
|
99
|
-
to throw an invalid schema error. To remove the error it's either necessary to
|
|
100
|
-
omit the properties by using
|
|
101
|
-
[`Type.Strict()`](https://github.com/sinclairzx81/typebox#strict) or use the AJV
|
|
102
|
-
options for adding custom keywords.
|
|
103
|
-
|
|
104
90
|
See also the [TypeBox
|
|
105
91
|
documentation](https://github.com/sinclairzx81/typebox#validation) on how to set
|
|
106
92
|
up AJV to work with TypeBox.
|
|
@@ -143,7 +143,7 @@ route-level `request` object.
|
|
|
143
143
|
curl localhost:8080/auth?username=admin&password=Password123!
|
|
144
144
|
```
|
|
145
145
|
And it should return back `logged in!`
|
|
146
|
-
6. But wait
|
|
146
|
+
6. But wait there's more! The generic interfaces are also available inside route
|
|
147
147
|
level hook methods. Modify the previous route by adding a `preValidation`
|
|
148
148
|
hook:
|
|
149
149
|
```typescript
|
|
@@ -403,7 +403,7 @@ definitions.
|
|
|
403
403
|
#### json-schema-to-ts
|
|
404
404
|
|
|
405
405
|
If you do not want to generate types from your schemas, but want to use them
|
|
406
|
-
|
|
406
|
+
directly from your code, you can use the package
|
|
407
407
|
[json-schema-to-ts](https://www.npmjs.com/package/json-schema-to-ts).
|
|
408
408
|
|
|
409
409
|
You can install it as dev-dependency.
|
|
@@ -661,6 +661,30 @@ However, there are a couple of suggestions to help improve this experience:
|
|
|
661
661
|
[npm-check](https://www.npmjs.com/package/npm-check) to verify plugin
|
|
662
662
|
dependencies are being used somewhere in your project.
|
|
663
663
|
|
|
664
|
+
Note that using `require` will not load the type definitions properly and may
|
|
665
|
+
cause type errors.
|
|
666
|
+
TypeScript can only identify the types that are directly imported into code,
|
|
667
|
+
which means that you can use require inline with import on top. For example:
|
|
668
|
+
|
|
669
|
+
```typescript
|
|
670
|
+
import 'plugin' // here will trigger the type augmentation.
|
|
671
|
+
|
|
672
|
+
fastify.register(require('plugin'))
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
```typescript
|
|
676
|
+
import plugin from 'plugin' // here will trigger the type augmentation.
|
|
677
|
+
|
|
678
|
+
fastify.register(plugin)
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
Or even explicit config on tsconfig
|
|
682
|
+
```jsonc
|
|
683
|
+
{
|
|
684
|
+
"types": ["plugin"] // we force TypeScript to import the types
|
|
685
|
+
}
|
|
686
|
+
```
|
|
687
|
+
|
|
664
688
|
## Code Completion In Vanilla JavaScript
|
|
665
689
|
|
|
666
690
|
Vanilla JavaScript can use the published types to provide code completion (e.g.
|
|
@@ -1378,7 +1402,7 @@ FastifyError is a custom error object that includes status code and validation
|
|
|
1378
1402
|
results.
|
|
1379
1403
|
|
|
1380
1404
|
It extends the Node.js `Error` type, and adds two additional, optional
|
|
1381
|
-
properties: `statusCode: number` and `validation:
|
|
1405
|
+
properties: `statusCode: number` and `validation: ValidationResult[]`.
|
|
1382
1406
|
|
|
1383
1407
|
##### fastify.ValidationResult
|
|
1384
1408
|
|
package/fastify.js
CHANGED
package/lib/error-serializer.js
CHANGED
|
@@ -74,24 +74,24 @@ class Serializer {
|
|
|
74
74
|
return bool === null ? 'null' : this.asBoolean(bool)
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
asDateTime (date) {
|
|
78
|
+
if (date === null) return '""'
|
|
79
79
|
if (date instanceof Date) {
|
|
80
|
-
return
|
|
80
|
+
return '"' + date.toISOString() + '"'
|
|
81
81
|
}
|
|
82
|
-
|
|
82
|
+
throw new Error(`The value "${date}" cannot be converted to a date-time.`)
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
|
|
86
|
-
return date === null ? 'null' : this.
|
|
85
|
+
asDateTimeNullable (date) {
|
|
86
|
+
return date === null ? 'null' : this.asDateTime(date)
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
asDate (date) {
|
|
90
|
-
|
|
90
|
+
if (date === null) return '""'
|
|
91
91
|
if (date instanceof Date) {
|
|
92
|
-
return
|
|
92
|
+
return '"' + new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString().slice(0, 10) + '"'
|
|
93
93
|
}
|
|
94
|
-
|
|
94
|
+
throw new Error(`The value "${date}" cannot be converted to a date.`)
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
asDateNullable (date) {
|
|
@@ -99,11 +99,11 @@ class Serializer {
|
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
asTime (date) {
|
|
102
|
-
|
|
102
|
+
if (date === null) return '""'
|
|
103
103
|
if (date instanceof Date) {
|
|
104
|
-
return
|
|
104
|
+
return '"' + new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString().slice(11, 19) + '"'
|
|
105
105
|
}
|
|
106
|
-
|
|
106
|
+
throw new Error(`The value "${date}" cannot be converted to a time.`)
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
asTimeNullable (date) {
|
package/lib/reply.js
CHANGED
|
@@ -203,10 +203,8 @@ Reply.prototype.getHeaders = function () {
|
|
|
203
203
|
|
|
204
204
|
Reply.prototype.hasHeader = function (key) {
|
|
205
205
|
key = key.toLowerCase()
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
}
|
|
209
|
-
return this.raw.hasHeader(key)
|
|
206
|
+
|
|
207
|
+
return this[kReplyHeaders][key] !== undefined || this.raw.hasHeader(key)
|
|
210
208
|
}
|
|
211
209
|
|
|
212
210
|
Reply.prototype.removeHeader = function (key) {
|
|
@@ -216,25 +214,24 @@ Reply.prototype.removeHeader = function (key) {
|
|
|
216
214
|
return this
|
|
217
215
|
}
|
|
218
216
|
|
|
219
|
-
Reply.prototype.header = function (key, value) {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
// default the value to ''
|
|
223
|
-
value = value === undefined ? '' : value
|
|
217
|
+
Reply.prototype.header = function (key, value = '') {
|
|
218
|
+
key = key.toLowerCase()
|
|
224
219
|
|
|
225
|
-
if (this[kReplyHeaders][
|
|
220
|
+
if (this[kReplyHeaders][key] && key === 'set-cookie') {
|
|
226
221
|
// https://tools.ietf.org/html/rfc7230#section-3.2.2
|
|
227
|
-
if (typeof this[kReplyHeaders][
|
|
228
|
-
this[kReplyHeaders][
|
|
222
|
+
if (typeof this[kReplyHeaders][key] === 'string') {
|
|
223
|
+
this[kReplyHeaders][key] = [this[kReplyHeaders][key]]
|
|
229
224
|
}
|
|
225
|
+
|
|
230
226
|
if (Array.isArray(value)) {
|
|
231
|
-
|
|
227
|
+
this[kReplyHeaders][key].push(...value)
|
|
232
228
|
} else {
|
|
233
|
-
this[kReplyHeaders][
|
|
229
|
+
this[kReplyHeaders][key].push(value)
|
|
234
230
|
}
|
|
235
231
|
} else {
|
|
236
|
-
this[kReplyHeaders][
|
|
232
|
+
this[kReplyHeaders][key] = value
|
|
237
233
|
}
|
|
234
|
+
|
|
238
235
|
return this
|
|
239
236
|
}
|
|
240
237
|
|
|
@@ -245,6 +242,7 @@ Reply.prototype.headers = function (headers) {
|
|
|
245
242
|
const key = keys[i]
|
|
246
243
|
this.header(key, headers[key])
|
|
247
244
|
}
|
|
245
|
+
|
|
248
246
|
return this
|
|
249
247
|
}
|
|
250
248
|
|
|
@@ -279,8 +277,7 @@ Reply.prototype.trailer = function (key, fn) {
|
|
|
279
277
|
}
|
|
280
278
|
|
|
281
279
|
Reply.prototype.hasTrailer = function (key) {
|
|
282
|
-
|
|
283
|
-
return this[kReplyTrailers][key.toLowerCase()] !== undefined
|
|
280
|
+
return this[kReplyTrailers]?.[key.toLowerCase()] !== undefined
|
|
284
281
|
}
|
|
285
282
|
|
|
286
283
|
Reply.prototype.removeTrailer = function (key) {
|
|
@@ -330,8 +327,7 @@ Reply.prototype.redirect = function (code, url) {
|
|
|
330
327
|
code = this[kReplyHasStatusCode] ? this.raw.statusCode : 302
|
|
331
328
|
}
|
|
332
329
|
|
|
333
|
-
this.header('location', url).code(code).send()
|
|
334
|
-
return this
|
|
330
|
+
return this.header('location', url).code(code).send()
|
|
335
331
|
}
|
|
336
332
|
|
|
337
333
|
Reply.prototype.callNotFound = function () {
|
|
@@ -485,9 +481,12 @@ function onSendEnd (reply, payload) {
|
|
|
485
481
|
}
|
|
486
482
|
|
|
487
483
|
if (reply[kReplyTrailers] === null) {
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
484
|
+
const contentLength = reply[kReplyHeaders]['content-length']
|
|
485
|
+
if (!contentLength ||
|
|
486
|
+
(req.raw.method !== 'HEAD' &&
|
|
487
|
+
parseInt(contentLength, 10) !== Buffer.byteLength(payload)
|
|
488
|
+
)
|
|
489
|
+
) {
|
|
491
490
|
reply[kReplyHeaders]['content-length'] = '' + Buffer.byteLength(payload)
|
|
492
491
|
}
|
|
493
492
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fastify",
|
|
3
|
-
"version": "4.2.
|
|
3
|
+
"version": "4.2.1",
|
|
4
4
|
"description": "Fast and low overhead web framework, for Node.js",
|
|
5
5
|
"main": "fastify.js",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"lint:markdown": "markdownlint-cli2",
|
|
18
18
|
"lint:standard": "standard | snazzy",
|
|
19
19
|
"lint:typescript": "eslint -c types/.eslintrc.json types/**/*.d.ts test/types/**/*.test-d.ts",
|
|
20
|
-
"prepublishOnly": "tap --no-check-coverage test/build/**.test.js",
|
|
20
|
+
"prepublishOnly": "PREPUBLISH=true tap --no-check-coverage test/build/**.test.js",
|
|
21
21
|
"test": "npm run lint && npm run unit && npm run test:typescript",
|
|
22
22
|
"test:ci": "npm run unit -- -R terse --cov --coverage-report=lcovonly && npm run test:typescript",
|
|
23
23
|
"test:report": "npm run lint && npm run unit:report && npm run test:typescript",
|
|
@@ -126,7 +126,7 @@
|
|
|
126
126
|
"homepage": "https://www.fastify.io/",
|
|
127
127
|
"devDependencies": {
|
|
128
128
|
"@fastify/pre-commit": "^2.0.2",
|
|
129
|
-
"@sinclair/typebox": "^0.
|
|
129
|
+
"@sinclair/typebox": "^0.24.9",
|
|
130
130
|
"@sinonjs/fake-timers": "^9.1.2",
|
|
131
131
|
"@types/node": "^18.0.0",
|
|
132
132
|
"@typescript-eslint/eslint-plugin": "^5.27.0",
|
|
@@ -147,7 +147,7 @@
|
|
|
147
147
|
"eslint-plugin-promise": "^6.0.0",
|
|
148
148
|
"fast-json-body": "^1.1.0",
|
|
149
149
|
"fast-json-stringify": "^5.0.0",
|
|
150
|
-
"fastify-plugin": "^
|
|
150
|
+
"fastify-plugin": "^4.0.0",
|
|
151
151
|
"fluent-json-schema": "^3.1.0",
|
|
152
152
|
"form-data": "^4.0.0",
|
|
153
153
|
"frameguard": "^4.0.0",
|
|
@@ -170,14 +170,14 @@
|
|
|
170
170
|
"split2": "^4.1.0",
|
|
171
171
|
"standard": "^17.0.0-2",
|
|
172
172
|
"tap": "^16.2.0",
|
|
173
|
-
"tsd": "^0.
|
|
173
|
+
"tsd": "^0.22.0",
|
|
174
174
|
"typescript": "^4.7.2",
|
|
175
175
|
"undici": "^5.4.0",
|
|
176
176
|
"x-xss-protection": "^2.0.0",
|
|
177
177
|
"yup": "^0.32.11"
|
|
178
178
|
},
|
|
179
179
|
"dependencies": {
|
|
180
|
-
"@fastify/ajv-compiler": "^3.1.
|
|
180
|
+
"@fastify/ajv-compiler": "^3.1.1",
|
|
181
181
|
"@fastify/error": "^3.0.0",
|
|
182
182
|
"@fastify/fast-json-stringify-compiler": "^4.0.0",
|
|
183
183
|
"abstract-logging": "^2.0.1",
|
|
@@ -23,7 +23,9 @@ test('check generated code syntax', async (t) => {
|
|
|
23
23
|
t.equal(result[0].fatalErrorCount, 0)
|
|
24
24
|
})
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
const isPrebublish = !!process.env.PREPUBLISH
|
|
27
|
+
|
|
28
|
+
test('ensure the current error serializer is latest', { skip: !isPrebublish }, async (t) => {
|
|
27
29
|
t.plan(1)
|
|
28
30
|
|
|
29
31
|
const current = await fs.promises.readFile(path.resolve('lib/error-serializer.js'))
|
|
@@ -4,6 +4,7 @@ const { test } = require('tap')
|
|
|
4
4
|
const Fastify = require('..')
|
|
5
5
|
|
|
6
6
|
const AJV = require('ajv')
|
|
7
|
+
const Schema = require('fluent-json-schema')
|
|
7
8
|
|
|
8
9
|
const customSchemaCompilers = {
|
|
9
10
|
body: new AJV({
|
|
@@ -946,3 +947,73 @@ test('Custom AJV settings on different parameters - pt2', t => {
|
|
|
946
947
|
}
|
|
947
948
|
})
|
|
948
949
|
})
|
|
950
|
+
|
|
951
|
+
test("The same $id in route's schema must not overwrite others", t => {
|
|
952
|
+
t.plan(4)
|
|
953
|
+
const fastify = Fastify()
|
|
954
|
+
|
|
955
|
+
const UserSchema = Schema.object()
|
|
956
|
+
.id('http://mydomain.com/user')
|
|
957
|
+
.title('User schema')
|
|
958
|
+
.description('Contains all user fields')
|
|
959
|
+
.prop('id', Schema.integer())
|
|
960
|
+
.prop('username', Schema.string().minLength(4))
|
|
961
|
+
.prop('firstName', Schema.string().minLength(1))
|
|
962
|
+
.prop('lastName', Schema.string().minLength(1))
|
|
963
|
+
.prop('fullName', Schema.string().minLength(1))
|
|
964
|
+
.prop('email', Schema.string())
|
|
965
|
+
.prop('password', Schema.string().minLength(6))
|
|
966
|
+
.prop('bio', Schema.string())
|
|
967
|
+
|
|
968
|
+
const userCreateSchema = UserSchema.only([
|
|
969
|
+
'username',
|
|
970
|
+
'firstName',
|
|
971
|
+
'lastName',
|
|
972
|
+
'email',
|
|
973
|
+
'bio',
|
|
974
|
+
'password',
|
|
975
|
+
'password_confirm'
|
|
976
|
+
])
|
|
977
|
+
.required([
|
|
978
|
+
'username',
|
|
979
|
+
'firstName',
|
|
980
|
+
'lastName',
|
|
981
|
+
'email',
|
|
982
|
+
'bio',
|
|
983
|
+
'password'
|
|
984
|
+
])
|
|
985
|
+
|
|
986
|
+
const userPatchSchema = UserSchema.only([
|
|
987
|
+
'firstName',
|
|
988
|
+
'lastName',
|
|
989
|
+
'bio'
|
|
990
|
+
])
|
|
991
|
+
|
|
992
|
+
fastify
|
|
993
|
+
.patch('/user/:id', {
|
|
994
|
+
schema: { body: userPatchSchema },
|
|
995
|
+
handler: () => { return 'ok' }
|
|
996
|
+
})
|
|
997
|
+
.post('/user', {
|
|
998
|
+
schema: { body: userCreateSchema },
|
|
999
|
+
handler: () => { return 'ok' }
|
|
1000
|
+
})
|
|
1001
|
+
|
|
1002
|
+
fastify.inject({
|
|
1003
|
+
method: 'POST',
|
|
1004
|
+
url: '/user',
|
|
1005
|
+
body: {}
|
|
1006
|
+
}, (err, res) => {
|
|
1007
|
+
t.error(err)
|
|
1008
|
+
t.same(res.json().message, "body must have required property 'username'")
|
|
1009
|
+
})
|
|
1010
|
+
|
|
1011
|
+
fastify.inject({
|
|
1012
|
+
url: '/user/1',
|
|
1013
|
+
method: 'PATCH',
|
|
1014
|
+
body: {}
|
|
1015
|
+
}, (err, res) => {
|
|
1016
|
+
t.error(err)
|
|
1017
|
+
t.same(res.payload, 'ok')
|
|
1018
|
+
})
|
|
1019
|
+
})
|
|
@@ -194,7 +194,18 @@ expectAssignable<FastifyInstance>(fastify({ frameworkErrors: () => { } }))
|
|
|
194
194
|
expectAssignable<FastifyInstance>(fastify({
|
|
195
195
|
rewriteUrl: (req) => req.url === '/hi' ? '/hello' : req.url!
|
|
196
196
|
}))
|
|
197
|
-
expectAssignable<FastifyInstance>(fastify({
|
|
197
|
+
expectAssignable<FastifyInstance>(fastify({
|
|
198
|
+
schemaErrorFormatter: (errors, dataVar) => {
|
|
199
|
+
console.log(
|
|
200
|
+
errors[0].keyword.toLowerCase(),
|
|
201
|
+
errors[0].message?.toLowerCase(),
|
|
202
|
+
errors[0].params,
|
|
203
|
+
errors[0].instancePath.toLowerCase(),
|
|
204
|
+
errors[0].schemaPath.toLowerCase()
|
|
205
|
+
)
|
|
206
|
+
return new Error()
|
|
207
|
+
}
|
|
208
|
+
}))
|
|
198
209
|
expectAssignable<FastifyInstance>(fastify({
|
|
199
210
|
clientErrorHandler: (err, socket) => {
|
|
200
211
|
expectType<ConnectionError>(err)
|
|
@@ -11,7 +11,7 @@ import { HookHandlerDoneFunction } from '../../types/hooks'
|
|
|
11
11
|
import { FastifyReply } from '../../types/reply'
|
|
12
12
|
import { FastifyRequest } from '../../types/request'
|
|
13
13
|
import { DefaultRoute } from '../../types/route'
|
|
14
|
-
import { FastifySchemaControllerOptions } from '../../types/schema'
|
|
14
|
+
import { FastifySchemaControllerOptions, FastifySchemaCompiler, FastifySerializerCompiler } from '../../types/schema'
|
|
15
15
|
|
|
16
16
|
const server = fastify()
|
|
17
17
|
|
|
@@ -325,3 +325,6 @@ expectType<void>(server.addConstraintStrategy(versionConstraintStrategy))
|
|
|
325
325
|
expectType<boolean>(server.hasConstraintStrategy(versionConstraintStrategy.name))
|
|
326
326
|
|
|
327
327
|
expectAssignable<DefaultRoute<RawRequestDefaultExpression, RawReplyDefaultExpression>>(server.getDefaultRoute())
|
|
328
|
+
|
|
329
|
+
expectType<FastifySchemaCompiler<any> | undefined>(server.validatorCompiler)
|
|
330
|
+
expectType<FastifySerializerCompiler<any> | undefined>(server.serializerCompiler)
|
|
@@ -494,12 +494,17 @@ test('the custom error formatter context must be the server instance in options'
|
|
|
494
494
|
})
|
|
495
495
|
|
|
496
496
|
test('should call custom error formatter', t => {
|
|
497
|
-
t.plan(
|
|
497
|
+
t.plan(9)
|
|
498
498
|
|
|
499
499
|
const fastify = Fastify({
|
|
500
500
|
schemaErrorFormatter: (errors, dataVar) => {
|
|
501
501
|
t.equal(errors.length, 1)
|
|
502
502
|
t.equal(errors[0].message, "must have required property 'name'")
|
|
503
|
+
t.equal(errors[0].keyword, 'required')
|
|
504
|
+
t.equal(errors[0].schemaPath, '#/required')
|
|
505
|
+
t.same(errors[0].params, {
|
|
506
|
+
missingProperty: 'name'
|
|
507
|
+
})
|
|
503
508
|
t.equal(dataVar, 'body')
|
|
504
509
|
return new Error('my error')
|
|
505
510
|
}
|
package/types/instance.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as http from 'http'
|
|
2
1
|
import { FastifyError } from '@fastify/error'
|
|
3
2
|
import { ConstraintStrategy, HTTPVersion } from 'find-my-way'
|
|
3
|
+
import * as http from 'http'
|
|
4
4
|
import { CallbackFunc as LightMyRequestCallback, Chain as LightMyRequestChain, InjectOptions, Response as LightMyRequestResponse } from 'light-my-request'
|
|
5
5
|
import { AddContentTypeParser, ConstructorAction, FastifyBodyParser, getDefaultJsonParser, hasContentTypeParser, ProtoAction, removeAllContentTypeParsers, removeContentTypeParser } from './content-type-parser'
|
|
6
6
|
import { onCloseAsyncHookHandler, onCloseHookHandler, onErrorAsyncHookHandler, onErrorHookHandler, onReadyAsyncHookHandler, onReadyHookHandler, onRegisterHookHandler, onRequestAsyncHookHandler, onRequestHookHandler, onResponseAsyncHookHandler, onResponseHookHandler, onRouteHookHandler, onSendAsyncHookHandler, onSendHookHandler, onTimeoutAsyncHookHandler, onTimeoutHookHandler, preHandlerAsyncHookHandler, preHandlerHookHandler, preParsingAsyncHookHandler, preParsingHookHandler, preSerializationAsyncHookHandler, preSerializationHookHandler, preValidationAsyncHookHandler, preValidationHookHandler } from './hooks'
|
|
@@ -30,6 +30,52 @@ export interface PrintRoutesOptions {
|
|
|
30
30
|
includeHooks?: boolean
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
export interface FastifyListenOptions {
|
|
34
|
+
/**
|
|
35
|
+
* Default to `0` (picks the first available open port).
|
|
36
|
+
*/
|
|
37
|
+
port?: number;
|
|
38
|
+
/**
|
|
39
|
+
* Default to `localhost`.
|
|
40
|
+
*/
|
|
41
|
+
host?: string;
|
|
42
|
+
/**
|
|
43
|
+
* Will be ignored if `port` is specified.
|
|
44
|
+
* @see [Identifying paths for IPC connections](https://nodejs.org/api/net.html#identifying-paths-for-ipc-connections).
|
|
45
|
+
*/
|
|
46
|
+
path?: string;
|
|
47
|
+
/**
|
|
48
|
+
* Specify the maximum length of the queue of pending connections.
|
|
49
|
+
* The actual length will be determined by the OS through sysctl settings such as `tcp_max_syn_backlog` and `somaxconn` on Linux.
|
|
50
|
+
* Default to `511`.
|
|
51
|
+
*/
|
|
52
|
+
backlog?: number;
|
|
53
|
+
/**
|
|
54
|
+
* Default to `false`.
|
|
55
|
+
*/
|
|
56
|
+
exclusive?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* For IPC servers makes the pipe readable for all users.
|
|
59
|
+
* Default to `false`.
|
|
60
|
+
*/
|
|
61
|
+
readableAll?: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* For IPC servers makes the pipe writable for all users.
|
|
64
|
+
* Default to `false`.
|
|
65
|
+
*/
|
|
66
|
+
writableAll?: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* For TCP servers, setting `ipv6Only` to `true` will disable dual-stack support, i.e., binding to host `::` won't make `0.0.0.0` be bound.
|
|
69
|
+
* Default to `false`.
|
|
70
|
+
*/
|
|
71
|
+
ipv6Only?: boolean;
|
|
72
|
+
/**
|
|
73
|
+
* An AbortSignal that may be used to close a listening server.
|
|
74
|
+
* @since This option is available only in Node.js v15.6.0 and greater
|
|
75
|
+
*/
|
|
76
|
+
signal?: AbortSignal;
|
|
77
|
+
}
|
|
78
|
+
|
|
33
79
|
type NotInInterface<Key, _Interface> = Key extends keyof _Interface ? never : Key
|
|
34
80
|
type FindMyWayVersion<RawServer extends RawServerBase> = RawServer extends http.Server ? HTTPVersion.V1 : HTTPVersion.V2
|
|
35
81
|
|
|
@@ -93,96 +139,8 @@ export interface FastifyInstance<
|
|
|
93
139
|
inject(opts: InjectOptions | string): Promise<LightMyRequestResponse>;
|
|
94
140
|
inject(): LightMyRequestChain;
|
|
95
141
|
|
|
96
|
-
listen(opts:
|
|
97
|
-
|
|
98
|
-
* Default to `0` (picks the first available open port).
|
|
99
|
-
*/
|
|
100
|
-
port?: number;
|
|
101
|
-
/**
|
|
102
|
-
* Default to `localhost`.
|
|
103
|
-
*/
|
|
104
|
-
host?: string;
|
|
105
|
-
/**
|
|
106
|
-
* Will be ignored if `port` is specified.
|
|
107
|
-
* @see [Identifying paths for IPC connections](https://nodejs.org/api/net.html#identifying-paths-for-ipc-connections).
|
|
108
|
-
*/
|
|
109
|
-
path?: string;
|
|
110
|
-
/**
|
|
111
|
-
* Specify the maximum length of the queue of pending connections.
|
|
112
|
-
* The actual length will be determined by the OS through sysctl settings such as `tcp_max_syn_backlog` and `somaxconn` on Linux.
|
|
113
|
-
* Default to `511`.
|
|
114
|
-
*/
|
|
115
|
-
backlog?: number;
|
|
116
|
-
/**
|
|
117
|
-
* Default to `false`.
|
|
118
|
-
*/
|
|
119
|
-
exclusive?: boolean;
|
|
120
|
-
/**
|
|
121
|
-
* For IPC servers makes the pipe readable for all users.
|
|
122
|
-
* Default to `false`.
|
|
123
|
-
*/
|
|
124
|
-
readableAll?: boolean;
|
|
125
|
-
/**
|
|
126
|
-
* For IPC servers makes the pipe writable for all users.
|
|
127
|
-
* Default to `false`.
|
|
128
|
-
*/
|
|
129
|
-
writableAll?: boolean;
|
|
130
|
-
/**
|
|
131
|
-
* For TCP servers, setting `ipv6Only` to `true` will disable dual-stack support, i.e., binding to host `::` won't make `0.0.0.0` be bound.
|
|
132
|
-
* Default to `false`.
|
|
133
|
-
*/
|
|
134
|
-
ipv6Only?: boolean;
|
|
135
|
-
/**
|
|
136
|
-
* An AbortSignal that may be used to close a listening server.
|
|
137
|
-
* @since This option is available only in Node.js v15.6.0 and greater
|
|
138
|
-
*/
|
|
139
|
-
signal?: AbortSignal;
|
|
140
|
-
}, callback: (err: Error|null, address: string) => void): void;
|
|
141
|
-
listen(opts?: {
|
|
142
|
-
/**
|
|
143
|
-
* Default to `0` (picks the first available open port).
|
|
144
|
-
*/
|
|
145
|
-
port?: number;
|
|
146
|
-
/**
|
|
147
|
-
* Default to `localhost`.
|
|
148
|
-
*/
|
|
149
|
-
host?: string;
|
|
150
|
-
/**
|
|
151
|
-
* Will be ignored if `port` is specified.
|
|
152
|
-
* @see [Identifying paths for IPC connections](https://nodejs.org/api/net.html#identifying-paths-for-ipc-connections).
|
|
153
|
-
*/
|
|
154
|
-
path?: string;
|
|
155
|
-
/**
|
|
156
|
-
* Specify the maximum length of the queue of pending connections.
|
|
157
|
-
* The actual length will be determined by the OS through sysctl settings such as `tcp_max_syn_backlog` and `somaxconn` on Linux.
|
|
158
|
-
* Default to `511`.
|
|
159
|
-
*/
|
|
160
|
-
backlog?: number;
|
|
161
|
-
/**
|
|
162
|
-
* Default to `false`.
|
|
163
|
-
*/
|
|
164
|
-
exclusive?: boolean;
|
|
165
|
-
/**
|
|
166
|
-
* For IPC servers makes the pipe readable for all users.
|
|
167
|
-
* Default to `false`.
|
|
168
|
-
*/
|
|
169
|
-
readableAll?: boolean;
|
|
170
|
-
/**
|
|
171
|
-
* For IPC servers makes the pipe writable for all users.
|
|
172
|
-
* Default to `false`.
|
|
173
|
-
*/
|
|
174
|
-
writableAll?: boolean;
|
|
175
|
-
/**
|
|
176
|
-
* For TCP servers, setting `ipv6Only` to `true` will disable dual-stack support, i.e., binding to host `::` won't make `0.0.0.0` be bound.
|
|
177
|
-
* Default to `false`.
|
|
178
|
-
*/
|
|
179
|
-
ipv6Only?: boolean;
|
|
180
|
-
/**
|
|
181
|
-
* An AbortSignal that may be used to close a listening server.
|
|
182
|
-
* @since This option is available only in Node.js v15.6.0 and greater
|
|
183
|
-
*/
|
|
184
|
-
signal?: AbortSignal;
|
|
185
|
-
}): Promise<string>;
|
|
142
|
+
listen(opts: FastifyListenOptions, callback: (err: Error | null, address: string) => void): void;
|
|
143
|
+
listen(opts?: FastifyListenOptions): Promise<string>;
|
|
186
144
|
listen(callback: (err: Error | null, address: string) => void): void;
|
|
187
145
|
|
|
188
146
|
/**
|
|
@@ -550,11 +508,21 @@ export interface FastifyInstance<
|
|
|
550
508
|
handler: (this: FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>, error: TError, request: FastifyRequest<RouteGeneric, RawServer, RawRequest, SchemaCompiler, TypeProvider>, reply: FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfigDefault, SchemaCompiler, TypeProvider>) => any | Promise<any>
|
|
551
509
|
): FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>;
|
|
552
510
|
|
|
511
|
+
/**
|
|
512
|
+
* Fastify schema validator for all routes.
|
|
513
|
+
*/
|
|
514
|
+
validatorCompiler: FastifySchemaCompiler<any> | undefined;
|
|
515
|
+
|
|
553
516
|
/**
|
|
554
517
|
* Set the schema validator for all routes.
|
|
555
518
|
*/
|
|
556
519
|
setValidatorCompiler<T = FastifySchema>(schemaCompiler: FastifySchemaCompiler<T>): FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>;
|
|
557
520
|
|
|
521
|
+
/**
|
|
522
|
+
* Fastify schema serializer for all routes.
|
|
523
|
+
*/
|
|
524
|
+
serializerCompiler: FastifySerializerCompiler<any> | undefined;
|
|
525
|
+
|
|
558
526
|
/**
|
|
559
527
|
* Set the schema serializer for all routes.
|
|
560
528
|
*/
|
package/types/schema.d.ts
CHANGED
|
@@ -23,8 +23,11 @@ export interface FastifyRouteSchemaDef<T> {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
export interface FastifySchemaValidationError {
|
|
26
|
-
|
|
26
|
+
keyword: string;
|
|
27
27
|
instancePath: string;
|
|
28
|
+
schemaPath: string;
|
|
29
|
+
params: Record<string, string | string[]>;
|
|
30
|
+
message?: string;
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
export interface FastifyValidationResult {
|