Socket
Socket
Sign inDemoInstall

fastify

Package Overview
Dependencies
Maintainers
3
Versions
288
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fastify - npm Package Compare versions

Comparing version 4.1.0 to 4.2.0

integration/server.js

2

docs/Guides/Delay-Accepting-Requests.md

@@ -51,3 +51,3 @@ <h1 align="center">Fastify</h1>

1. the mechanism for authenticating with the provider
[decorating](../Referece/Decorators.md) the `fastify` object with the
[decorating](../Reference/Decorators.md) the `fastify` object with the
authentication key (`magicKey` from here onwards)

@@ -54,0 +54,0 @@ 1. the mechanism for denying requests that would, otherwise, fail

@@ -135,5 +135,11 @@ <h1 align="center">Fastify</h1>

close the server gracefully on `SIGINT` and `SIGTERM` signals.
- [`@eropple/fastify-openapi3`](https://github.com/eropple/fastify-openapi3) Provides
easy, developer-friendly OpenAPI 3.1 specs + doc explorer based on your routes.
- [`@gquittet/graceful-server`](https://github.com/gquittet/graceful-server)
Tiny (~5k), Fast, KISS, and dependency-free Node.JS library to make your
Fastify API graceful.
- [`@h4ad/serverless-adapter`](https://github.com/H4ad/serverless-adapter)
Run REST APIs and other web applications using your existing Node.js
application framework (Express, Koa, Hapi and Fastify), on top of AWS Lambda,
Huawei and many other clouds.
- [`@immobiliarelabs/fastify-metrics`](https://github.com/immobiliare/fastify-metrics)

@@ -331,2 +337,4 @@ Minimalistic and opinionated plugin that collects usage/process metrics and

Fastify plugin to parse request language.
- [`fastify-lcache`](https://github.com/denbon05/fastify-lcache)
Lightweight cache plugin
- [`fastify-loader`](https://github.com/TheNoim/fastify-loader) Load routes from

@@ -483,2 +491,4 @@ a directory and inject the Fastify instance in each file.

Server-Sent Events using Async Iterators (supports newer versions of Fastify).
- [`fastify-ssr-vite`](https://github.com/nineohnine/fastify-ssr-vite) A simple
plugin for setting up server side rendering with vite.
- [`fastify-stripe`](https://github.com/coopflow/fastify-stripe) Plugin to

@@ -485,0 +495,0 @@ initialize and encapsulate [Stripe

@@ -11,4 +11,36 @@ # V4 Migration Guide

### Deprecation of `app.use()`
### Error handling composition ([#3261](https://github.com/fastify/fastify/pull/3261))
When an error is thrown in a async error handler function,
the upper-level error handler is executed if set.
If there is not a upper-level error handler, the default will
be executed as it was previously.
```
import Fastify from 'fastify'
const fastify = Fastify()
fastify.register(async fastify => {
fastify.setErrorHandler(async err => {
console.log(err.message) // 'kaboom'
throw new Error('caught')
})
fastify.get('/encapsulated', async () => {
throw new Error('kaboom')
})
})
fastify.setErrorHandler(async err => {
console.log(err.message) // 'caught'
throw new Error('wrapped')
})
const res = await fastify.inject('/encapsulated')
console.log(res.json().message) // 'wrapped'
```
### Deprecation of `app.use()` ([#3506](https://github.com/fastify/fastify/pull/3506))
Starting this version of Fastify, we have deprecated the use of `app.use()`. We

@@ -74,1 +106,8 @@ have decided not to support the use of middlewares. Both

```
### Add `reply.trailers` methods ([#3794](https://github.com/fastify/fastify/pull/3794))
Fastify now supports the [HTTP Trailer] response headers.
[HTTP Trailer]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Trailer

@@ -27,3 +27,3 @@ <h1 align="center">Serverless</h1>

- [AWS Lambda](#aws-lambda)
- [AWS](#aws)
- [Google Cloud Functions](#google-cloud-functions)

@@ -34,4 +34,16 @@ - [Google Cloud Run](#google-cloud-run)

## AWS Lambda
## AWS
To integrate with AWS, you have two choices of library:
- Using [@fastify/aws-lambda](https://github.com/fastify/aws-lambda-fastify)
which only adds API Gateway support but has heavy optimizations for fastify.
- Using [@h4ad/serverless-adapter](https://github.com/H4ad/serverless-adapter)
which is a little slower as it creates an HTTP request for each AWS event but
has support for more AWS services such as: AWS SQS, AWS SNS and others.
So you can decide which option is best for you, but you can test both libraries.
### Using @fastify/aws-lambda
The sample provided allows you to easily build serverless web

@@ -41,8 +53,4 @@ applications/services and RESTful APIs using Fastify on top of AWS Lambda and

*Note: Using
[@fastify/aws-lambda](https://github.com/fastify/aws-lambda-fastify) is just one
possible way.*
#### app.js
### app.js
```js

@@ -77,3 +85,3 @@ const fastify = require('fastify');

### lambda.js
#### lambda.js

@@ -106,3 +114,3 @@ ```js

### Example
#### Example

@@ -114,3 +122,2 @@ An example deployable with

### Considerations

@@ -123,2 +130,8 @@

#### Beyond API Gateway
If you need to integrate with more AWS services, take a look at
[@h4ad/serverless-adapter](https://viniciusl.com.br/serverless-adapter/docs/main/frameworks/fastify)
on Fastify to find out how to integrate.
## Google Cloud Functions

@@ -125,0 +138,0 @@

@@ -19,3 +19,3 @@ <h1 align="center">Fastify</h1>

Developers experienced with Fastify should consult the [reference
documentation](./Reference/index.md) directly to find the topic they are seeking
documentation](./Reference/Index.md) directly to find the topic they are seeking
more information about.

@@ -22,0 +22,0 @@

@@ -31,2 +31,3 @@ <h1 align="center">Fastify</h1>

- [Route level hooks](#route-level-hooks)
- [Using Hooks to Inject Custom Properties](#using-hooks-to-inject-custom-properties)
- [Diagnostics Channel Hooks](#diagnostics-channel-hooks)

@@ -653,2 +654,53 @@

## Using Hooks to Inject Custom Properties
<a id="using-hooks-to-inject-custom-properties"></a>
You can use a hook to inject custom properties into incoming requests.
This is useful for reusing processed data from hooks in controllers.
A very common use case is, for example, checking user authentication based
on their token and then storing their recovered data into
the [Request](./Request.md) instance. This way, your controllers can read it
easily with `request.authenticatedUser` or whatever you want to call it.
That's how it might look like:
```js
fastify.addHook('preParsing', async (request) => {
request.authenticatedUser = {
id: 42,
name: 'Jane Doe',
role: 'admin'
}
})
fastify.get('/me/is-admin', async function (req, reply) {
return { isAdmin: req.authenticatedUser?.role === 'admin' || false }
})
```
Note that `.authenticatedUser` could actually be any property name
choosen by yourself. Using your own custom property prevents you
from mutating existing properties, which
would be a dangerous and destructive operation. So be careful and
make sure your property is entirely new, also using this approach
only for very specific and small cases like this example.
Regarding TypeScript in this example, you'd need to update the
`FastifyRequest` core interface to include your new property typing
(for more about it, see [TypeScript](./TypeScript.md) page), like:
```ts
interface AuthenticatedUser { /* ... */ }
declare module 'fastify' {
export interface FastifyRequest {
authenticatedUser?: AuthenticatedUser;
}
}
```
Although this is a very pragmatic approach, if you're trying to do
something more complex that changes these core objects, then
consider creating a custom [Plugin](./Plugins.md) instead.
## Diagnostics Channel Hooks

@@ -655,0 +707,0 @@

@@ -16,3 +16,3 @@ <h1 align="center">Fastify</h1>

You may have already seen in the [Getting
Started]((../Guides/Getting-Started.md#your-first-plugin)) guide how easy it is
Started](../Guides/Getting-Started.md#your-first-plugin) guide how easy it is
to use this API:

@@ -19,0 +19,0 @@ ```

@@ -202,5 +202,6 @@ <h1 align="center">Fastify</h1>

A useful library for building types and a schema at once is
[typebox](https://www.npmjs.com/package/@sinclair/typebox). With typebox you
define your schema within your code and use them directly as types or schemas as
you need them.
[typebox](https://www.npmjs.com/package/@sinclair/typebox) along with
[fastify-type-provider-typebox](https://github.com/fastify/fastify-type-provider-typebox).
With typebox you define your schema within your code and use them
directly as types or schemas as you need them.

@@ -210,6 +211,6 @@ When you want to use it for validation of some payload in a fastify route you

1. Install `typebox` in your project.
1. Install `typebox` and `fastify-type-provider-typebox` in your project.
```bash
npm i @sinclair/typebox
npm i @sinclair/typebox @fastify/type-provider-typebox
```

@@ -223,7 +224,8 @@

const User = Type.Object({
export const User = Type.Object({
name: Type.String(),
mail: Type.Optional(Type.String({ format: "email" })),
});
type UserType = Static<typeof User>;
mail: Type.Optional(Type.String({ format: 'email' })),
})
export type UserType = Static<typeof User>
```

@@ -234,6 +236,10 @@

```typescript
const app = fastify();
import Fastify from 'fastify'
import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox'
// ...
app.post<{ Body: UserType; Reply: UserType }>(
"/",
const fastify = Fastify().withTypeProvider<TypeBoxTypeProvider>()
app.post<{ Body: UserType, Reply: UserType }>(
'/',
{

@@ -243,3 +249,3 @@ schema: {

response: {
200: User,
200: User
},

@@ -249,15 +255,22 @@ },

(request, reply) => {
const { body: user } = request;
/* user has type
* const user: StaticProperties<{
* name: TString;
* mail: TOptional<TString>;
* }>
*/
//...
reply.status(200).send(user);
// The `name` and `mail` types are automatically inferred
const { name, mail } = request.body;
reply.status(200).send({ name, mail });
}
);
)
```
**Note** For Ajv version 7 and above is required to use the `ajvTypeBoxPlugin`:
```typescript
import Fastify from 'fastify'
import { ajvTypeBoxPlugin, TypeBoxTypeProvider } from '@fastify/type-provider-typebox'
const fastify = Fastify({
ajv: {
plugins: [ajvTypeBoxPlugin]
}
}).withTypeProvider<TypeBoxTypeProvider>()
```
#### Schemas in JSON Files

@@ -1368,3 +1381,3 @@

[src](https://github.com/fastify/fastify/blob/main/types/error.d.ts#L17)
[src](https://github.com/fastify/fastify/blob/main/fastify.d.ts#L179)

@@ -1379,3 +1392,3 @@ FastifyError is a custom error object that includes status code and validation

[src](https://github.com/fastify/fastify/blob/main/types/error.d.ts#L4)
[src](https://github.com/fastify/fastify/blob/main/fastify.d.ts#L184)

@@ -1382,0 +1395,0 @@ The route validation internally relies upon Ajv, which is a high-performance

@@ -487,3 +487,14 @@ <h1 align="center">Fastify</h1>

##### .statusCode property
All validation errors will be added a `.statusCode` property set to `400`. This guarantees
that the default error handler will set the status code of the response to `400`.
```js
fastify.setErrorHandler(function (error, request, reply) {
request.log.error(error, `This error has status code ${error.statusCode}`)
reply.status(error.statusCode).send(error)
})
```
##### Validation messages with other validation libraries

@@ -490,0 +501,0 @@

@@ -186,6 +186,6 @@ import * as http from 'http'

keyword: string;
dataPath: string;
instancePath: string;
schemaPath: string;
params: Record<string, string | string[]>;
message: string;
message?: string;
}

@@ -192,0 +192,0 @@

'use strict'
const VERSION = '4.1.0'
const VERSION = '4.2.0'

@@ -5,0 +5,0 @@ const Avvio = require('avvio')

@@ -12,3 +12,4 @@ 'use strict'

kLogLevel,
kContentTypeParser
kContentTypeParser,
kRouteByFastify
} = require('./symbols.js')

@@ -29,3 +30,4 @@

schemaErrorFormatter,
server
server,
isFastify
}) {

@@ -55,2 +57,3 @@ this.schema = schema

this.schemaErrorFormatter = schemaErrorFormatter || server[kSchemaErrorFormatter] || defaultSchemaErrorFormatter
this[kRouteByFastify] = isFastify

@@ -57,0 +60,0 @@ this.server = server

@@ -42,3 +42,3 @@ // This file is autogenerated by build/build-error-serializer.js, do not edit

const integer = this.parseInteger(i)
if (Number.isNaN(integer)) {
if (Number.isNaN(integer) || !Number.isFinite(integer)) {
throw new Error(`The value "${i}" cannot be converted to an integer.`)

@@ -59,2 +59,4 @@ } else {

throw new Error(`The value "${i}" cannot be converted to a number.`)
} else if (!Number.isFinite(num)) {
return null
} else {

@@ -77,40 +79,40 @@ return '' + num

asDatetime (date, skipQuotes) {
const quotes = skipQuotes === true ? '' : '"'
asDatetime (date) {
const quotes = '"'
if (date instanceof Date) {
return quotes + date.toISOString() + quotes
}
return this.asString(date, skipQuotes)
return this.asString(date)
}
asDatetimeNullable (date, skipQuotes) {
return date === null ? 'null' : this.asDatetime(date, skipQuotes)
asDatetimeNullable (date) {
return date === null ? 'null' : this.asDatetime(date)
}
asDate (date, skipQuotes) {
const quotes = skipQuotes === true ? '' : '"'
asDate (date) {
const quotes = '"'
if (date instanceof Date) {
return quotes + new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString().slice(0, 10) + quotes
}
return this.asString(date, skipQuotes)
return this.asString(date)
}
asDateNullable (date, skipQuotes) {
return date === null ? 'null' : this.asDate(date, skipQuotes)
asDateNullable (date) {
return date === null ? 'null' : this.asDate(date)
}
asTime (date, skipQuotes) {
const quotes = skipQuotes === true ? '' : '"'
asTime (date) {
const quotes = '"'
if (date instanceof Date) {
return quotes + new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString().slice(11, 19) + quotes
}
return this.asString(date, skipQuotes)
return this.asString(date)
}
asTimeNullable (date, skipQuotes) {
return date === null ? 'null' : this.asTime(date, skipQuotes)
asTimeNullable (date) {
return date === null ? 'null' : this.asTime(date)
}
asString (str, skipQuotes) {
const quotes = skipQuotes === true ? '' : '"'
asString (str) {
const quotes = '"'
if (str instanceof Date) {

@@ -125,7 +127,2 @@ return quotes + str.toISOString() + quotes

}
// If we skipQuotes it means that we are using it as test
// no need to test the string length for the render
if (skipQuotes) {
return str
}

@@ -192,3 +189,3 @@ if (str.length < 42) {

function anonymous0 (input) {
// main
// #

@@ -195,0 +192,0 @@ var obj = (input && typeof input.toJSON === 'function')

@@ -93,3 +93,3 @@ 'use strict'

if (reply.context.attachValidation === false) {
reply.code(400).send(result)
reply.send(result)
return

@@ -96,0 +96,0 @@ }

@@ -11,3 +11,3 @@ 'use strict'

const warning = require('./warnings')
const { kRequestAcceptVersion } = require('./symbols')
const { kRequestAcceptVersion, kRouteByFastify } = require('./symbols')

@@ -117,3 +117,3 @@ const {

// Convert shorthand to extended route declaration
function prepareRoute ({ method, url, options, handler }) {
function prepareRoute ({ method, url, options, handler, isFastify }) {
if (typeof url !== 'string') {

@@ -145,7 +145,7 @@ throw new FST_ERR_INVALID_URL(typeof url)

return route.call(this, { options })
return route.call(this, { options, isFastify })
}
// Route management
function route ({ options }) {
function route ({ options, isFastify }) {
// Since we are mutating/assigning only top level props, it is fine to have a shallow copy using the spread operator

@@ -182,13 +182,13 @@ const opts = { ...options }

case 'slash':
addNewRoute.call(this, { path })
addNewRoute.call(this, { path, isFastify })
break
case 'no-slash':
addNewRoute.call(this, { path: '' })
addNewRoute.call(this, { path: '', isFastify })
break
case 'both':
default:
addNewRoute.call(this, { path: '' })
addNewRoute.call(this, { path: '', isFastify })
// If ignoreTrailingSlash is set to true we need to add only the '' route to prevent adding an incomplete one.
if (ignoreTrailingSlash !== true && (ignoreDuplicateSlashes !== true || !prefix.endsWith('/'))) {
addNewRoute.call(this, { path, prefixing: true })
addNewRoute.call(this, { path, prefixing: true, isFastify })
}

@@ -198,5 +198,5 @@ }

// Ensure that '/prefix/' + '/route' gets registered as '/prefix/route'
addNewRoute.call(this, { path: path.slice(1) })
addNewRoute.call(this, { path: path.slice(1), isFastify })
} else {
addNewRoute.call(this, { path })
addNewRoute.call(this, { path, isFastify })
}

@@ -207,3 +207,3 @@

function addNewRoute ({ path, prefixing = false }) {
function addNewRoute ({ path, prefixing = false, isFastify = false }) {
const url = prefix + path

@@ -250,3 +250,4 @@

replySerializer: this[kReplySerializerDefault],
server: this
server: this,
isFastify
})

@@ -259,9 +260,16 @@

const headRouteExists = opts.method === 'HEAD' && router.find(opts.method, opts.url, constraints) != null
const headHandler = router.find('HEAD', opts.url, constraints)
const hasHEADHandler = headHandler != null
// Check if the current route is not for a sibling HEAD one
if (!headRouteExists) {
try {
router.on(opts.method, opts.url, { constraints }, routeHandler, context)
} catch (error) {
// remove the head route created by fastify
if (hasHEADHandler && !context[kRouteByFastify] && headHandler.store[kRouteByFastify]) {
router.off(opts.method, opts.url, { constraints })
}
try {
router.on(opts.method, opts.url, { constraints }, routeHandler, context)
} catch (error) {
// any route insertion error created by fastify can be safely ignore
// because it only duplicate route for head
if (!context[kRouteByFastify]) {
const isDuplicatedRoute = error.message.includes(`Method '${opts.method}' already declared for route '${opts.url}'`)

@@ -331,15 +339,17 @@ if (isDuplicatedRoute) {

const { exposeHeadRoute } = opts
const hasRouteExposeHeadRouteFlag = exposeHeadRoute != null
const shouldExposeHead = hasRouteExposeHeadRouteFlag ? exposeHeadRoute : globalExposeHeadRoutes
done(notHandledErr)
})
if (shouldExposeHead && options.method === 'GET' && !headRouteExists) {
const onSendHandlers = parseHeadOnSendHandlers(opts.onSend)
prepareRoute.call(this, { method: 'HEAD', url: path, options: { ...opts, onSend: onSendHandlers } })
} else if (headRouteExists && exposeHeadRoute) {
warning.emit('FSTDEP007')
}
// register head route in sync
// we must place it after the `this.after`
const { exposeHeadRoute } = opts
const hasRouteExposeHeadRouteFlag = exposeHeadRoute != null
const shouldExposeHead = hasRouteExposeHeadRouteFlag ? exposeHeadRoute : globalExposeHeadRoutes
done(notHandledErr)
})
if (shouldExposeHead && options.method === 'GET' && !hasHEADHandler) {
const onSendHandlers = parseHeadOnSendHandlers(opts.onSend)
prepareRoute.call(this, { method: 'HEAD', url: path, options: { ...opts, onSend: onSendHandlers }, isFastify: true })
} else if (hasHEADHandler && exposeHeadRoute) {
warning.emit('FSTDEP007')
}
}

@@ -346,0 +356,0 @@ }

@@ -50,5 +50,6 @@ 'use strict'

kHasBeenDecorated: Symbol('fastify.hasBeenDecorated'),
kKeepAliveConnections: Symbol('fastify.keepAliveConnections')
kKeepAliveConnections: Symbol('fastify.keepAliveConnections'),
kRouteByFastify: Symbol('fastify.routeByFastify')
}
module.exports = keys

@@ -109,2 +109,3 @@ 'use strict'

if (result instanceof Error) {
result.statusCode = result.statusCode || 400
result.validationContext = result.validationContext || dataVar

@@ -115,2 +116,3 @@ return result

const error = schemaErrorFormatter(result, dataVar)
error.statusCode = error.statusCode || 400
error.validation = result

@@ -117,0 +119,0 @@ error.validationContext = dataVar

{
"name": "fastify",
"version": "4.1.0",
"version": "4.2.0",
"description": "Fast and low overhead web framework, for Node.js",

@@ -149,3 +149,3 @@ "main": "fastify.js",

"fast-json-body": "^1.1.0",
"fast-json-stringify": "^4.2.0",
"fast-json-stringify": "^5.0.0",
"fastify-plugin": "^3.0.1",

@@ -183,6 +183,6 @@ "fluent-json-schema": "^3.1.0",

"@fastify/error": "^3.0.0",
"@fastify/fast-json-stringify-compiler": "^3.0.1",
"@fastify/fast-json-stringify-compiler": "^4.0.0",
"abstract-logging": "^2.0.1",
"avvio": "^8.1.3",
"find-my-way": "^6.3.0",
"find-my-way": "^7.0.0",
"light-my-request": "^5.0.0",

@@ -189,0 +189,0 @@ "pino": "^8.0.0",

@@ -147,3 +147,3 @@ 'use strict'

├── helicopter (GET, HEAD)
└── hello (GET, PUT, HEAD)
└── hello (GET, HEAD, PUT)
`

@@ -204,3 +204,3 @@ t.equal(typeof radixTree, 'string')

│ • (errorHandler) "defaultErrorHandler()"
└── hello (GET, PUT, HEAD)
└── hello (GET, HEAD, PUT)
• (onTimeout) ["onTimeout()"]

@@ -215,3 +215,3 @@ • (onRequest) ["anonymous()"]

│ • (onRequest) ["anonymous()"]
└── hello (GET, PUT, HEAD)
└── hello (GET, HEAD, PUT)
• (onTimeout) ["onTimeout()"]

@@ -218,0 +218,0 @@ • (onRequest) ["anonymous()"]

@@ -327,3 +327,3 @@ 'use strict'

t.ok(Array.isArray(err.validation))
reply.send('error')
reply.code(400).send('error')
})

@@ -330,0 +330,0 @@

@@ -209,3 +209,3 @@ 'use strict'

t.equal(err.code, 'FST_ERR_SCH_SERIALIZATION_BUILD')
t.match(err.message, /^Failed building the serialization schema for GET: \/:id, due to error Cannot read propert.*/) // error from fast-json-strinfigy
t.match(err.message, /^Failed building the serialization schema for GET: \/:id, due to error Cannot find reference.*/) // error from fast-json-strinfigy
})

@@ -830,3 +830,3 @@ })

t.equal(err.validationContext, 'body')
reply.send()
reply.code(400).send()
})

@@ -833,0 +833,0 @@ fastify.post('/', {

@@ -10,4 +10,6 @@ import fastify, {

LightMyRequestCallback,
InjectOptions, FastifyBaseLogger
InjectOptions, FastifyBaseLogger,
ValidationResult
} from '../../fastify'
import { ErrorObject as AjvErrorObject } from 'ajv'
import * as http from 'http'

@@ -212,1 +214,10 @@ import * as https from 'https'

expectAssignable<FastifyPlugin>(() => {})
const ajvErrorObject: AjvErrorObject = {
keyword: '',
instancePath: '',
schemaPath: '',
params: {},
message: ''
}
expectAssignable<ValidationResult>(ajvErrorObject)

@@ -52,3 +52,3 @@ import { expectType } from 'tsd'

type CustomRequest = FastifyRequest<{
Body: RequestBody;
Body: RequestBody | undefined;
Querystring: RequestQuerystring;

@@ -89,3 +89,3 @@ Params: RequestParams;

const getHandlerWithCustomLogger: RouteHandlerMethod<RawServerDefault, RawRequestDefaultExpression, RawReplyDefaultExpression, RouteGenericInterface, ContextConfigDefault, FastifySchema, FastifyTypeProviderDefault, ResolveFastifyReplyReturnType<FastifyTypeProviderDefault, FastifySchema, RouteGenericInterface>, ResolveFastifyRequestType<FastifyTypeProviderDefault, FastifySchema, RouteGenericInterface>, CustomLoggerInterface> = function (request, _reply) {
const getHandlerWithCustomLogger: RouteHandlerMethod<RawServerDefault, RawRequestDefaultExpression, RawReplyDefaultExpression, RouteGenericInterface, ContextConfigDefault, FastifySchema, FastifyTypeProviderDefault, ResolveFastifyRequestType<FastifyTypeProviderDefault, FastifySchema, RouteGenericInterface>, CustomLoggerInterface> = function (request, _reply) {
expectType<CustomLoggerInterface>(request.log)

@@ -109,7 +109,11 @@ }

function putHandler (request: CustomRequest, reply: FastifyReply) {
expectType<RequestBody>(request.body)
expectType<RequestBody | undefined>(request.body)
expectType<RequestParams>(request.params)
expectType<RequestHeaders & RawRequestDefaultExpression['headers']>(request.headers)
expectType<RequestQuerystring>(request.query)
expectType<string>(request.body.content)
if (typeof request.body === 'undefined') {
expectType<undefined>(request.body)
} else {
expectType<string>(request.body.content)
}
expectType<string>(request.query.from)

@@ -116,0 +120,0 @@ expectType<number>(request.params.id)

@@ -301,3 +301,3 @@ import fastify, {

},
async (_, res): Promise<RouteHandlerMethod<RawServerDefault, RawRequestDefaultExpression, RawReplyDefaultExpression, RouteGenericInterface, ContextConfigDefault, FastifySchema, TypeBoxProvider>> => {
async (_, res) => {
return false

@@ -388,3 +388,3 @@ }

},
async (_, res): Promise<RouteHandlerMethod<RawServerDefault, RawRequestDefaultExpression, RawReplyDefaultExpression, RouteGenericInterface, ContextConfigDefault, FastifySchema, TypeBoxProvider>> => {
async (_, res) => {
return false

@@ -394,2 +394,11 @@ }

// https://github.com/fastify/fastify/issues/4088
expectError(server.withTypeProvider<JsonSchemaToTsProvider>().get('/', {
schema: {
response: { type: 'string' }
} as const
}, (_, res) => {
return { foo: 555 }
}))
// -------------------------------------------------------------------

@@ -396,0 +405,0 @@ // Reply Type Override

@@ -100,2 +100,34 @@ 'use strict'

test('validation error has 400 statusCode set', t => {
t.plan(3)
const fastify = Fastify()
fastify.setErrorHandler((error, request, reply) => {
const errorResponse = {
message: error.message,
statusCode: error.statusCode || 500
}
reply.code(errorResponse.statusCode).send(errorResponse)
})
fastify.post('/', { schema }, echoBody)
fastify.inject({
method: 'POST',
payload: {
hello: 'michelangelo'
},
url: '/'
}, (err, res) => {
t.error(err)
t.same(res.json(), {
statusCode: 400,
message: "body must have required property 'name'"
})
t.equal(res.statusCode, 400)
})
})
test('error inside custom error handler should have validationContext', t => {

@@ -102,0 +134,0 @@ t.plan(1)

@@ -72,3 +72,2 @@ import { FastifyInstance } from './instance'

TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault,
ReturnType = ResolveFastifyReplyReturnType<TypeProvider, SchemaCompiler, RouteGeneric>,
RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>,

@@ -80,3 +79,4 @@ Logger extends FastifyLoggerInstance = FastifyLoggerInstance

reply: FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>
) => ReturnType
// This return type used to be a generic type argument. Due to TypeScript's inference of return types, this rendered returns unchecked.
) => ResolveFastifyReplyReturnType<TypeProvider, SchemaCompiler, RouteGeneric>

@@ -94,7 +94,6 @@ /**

TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault,
ReturnType = ResolveFastifyReplyReturnType<TypeProvider, SchemaCompiler, RouteGeneric>,
RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>,
Logger extends FastifyLoggerInstance = FastifyLoggerInstance
> extends RouteShorthandOptions<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, RequestType, Logger> {
handler: RouteHandlerMethod<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, ReturnType, RequestType, Logger>;
handler: RouteHandlerMethod<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, RequestType, Logger>;
}

@@ -111,14 +110,14 @@

> {
<RouteGeneric extends RouteGenericInterface = RouteGenericInterface, ContextConfig = ContextConfigDefault, SchemaCompiler = FastifySchema, ReturnType = ResolveFastifyReplyReturnType<TypeProvider, SchemaCompiler, RouteGeneric>, RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>, Logger extends FastifyLoggerInstance = FastifyLoggerInstance>(
<RouteGeneric extends RouteGenericInterface = RouteGenericInterface, ContextConfig = ContextConfigDefault, SchemaCompiler = FastifySchema, RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>, Logger extends FastifyLoggerInstance = FastifyLoggerInstance>(
path: string,
opts: RouteShorthandOptions<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, RequestType, Logger>,
handler: RouteHandlerMethod<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, ReturnType, RequestType, Logger>
handler: RouteHandlerMethod<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, RequestType, Logger>
): FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>;
<RouteGeneric extends RouteGenericInterface = RouteGenericInterface, ContextConfig = ContextConfigDefault, SchemaCompiler = FastifySchema, ReturnType = ResolveFastifyReplyReturnType<TypeProvider, SchemaCompiler, RouteGeneric>, RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>, Logger extends FastifyLoggerInstance = FastifyLoggerInstance>(
<RouteGeneric extends RouteGenericInterface = RouteGenericInterface, ContextConfig = ContextConfigDefault, SchemaCompiler = FastifySchema, RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>, Logger extends FastifyLoggerInstance = FastifyLoggerInstance>(
path: string,
handler: RouteHandlerMethod<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, ReturnType, RequestType, Logger>
handler: RouteHandlerMethod<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, RequestType, Logger>
): FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>;
<RouteGeneric extends RouteGenericInterface = RouteGenericInterface, ContextConfig = ContextConfigDefault, SchemaCompiler = FastifySchema, ReturnType = ResolveFastifyReplyReturnType<TypeProvider, SchemaCompiler, RouteGeneric>, RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>, Logger extends FastifyLoggerInstance = FastifyLoggerInstance>(
<RouteGeneric extends RouteGenericInterface = RouteGenericInterface, ContextConfig = ContextConfigDefault, SchemaCompiler = FastifySchema, RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>, Logger extends FastifyLoggerInstance = FastifyLoggerInstance>(
path: string,
opts: RouteShorthandOptionsWithHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, ReturnType, RequestType, Logger>
opts: RouteShorthandOptionsWithHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, RequestType, Logger>
): FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>;

@@ -138,3 +137,2 @@ }

TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault,
ReturnType = ResolveFastifyReplyReturnType<TypeProvider, SchemaCompiler, RouteGeneric>,
RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>,

@@ -145,3 +143,3 @@ Logger extends FastifyLoggerInstance = FastifyLoggerInstance

url: string;
handler: RouteHandlerMethod<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, ReturnType, RequestType, Logger>;
handler: RouteHandlerMethod<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, RequestType, Logger>;
}

@@ -148,0 +146,0 @@

@@ -24,13 +24,20 @@

// Used to map undefined SchemaCompiler properties to unknown
type UndefinedToUnknown<T> = T extends undefined ? unknown : T
// Without brackets, UndefinedToUnknown<undefined | null> => unknown
type UndefinedToUnknown<T> = [T] extends [undefined] ? unknown : T
// union-aware keyof operator
// keyof ({ a: number} | { b: number}) => never
// KeysOf<{a: number} | {b: number}> => "a" | "b"
// this exists to allow users to override faulty type-provider logic.
type KeysOf<T> = T extends any ? keyof T : never
// Resolves Request types either from generic argument or Type Provider.
type ResolveRequestParams<TypeProvider extends FastifyTypeProvider, SchemaCompiler extends FastifySchema, RouteGeneric extends RouteGenericInterface> =
UndefinedToUnknown<keyof RouteGeneric['Params'] extends never ? CallTypeProvider<TypeProvider, SchemaCompiler['params']> : RouteGeneric['Params']>
UndefinedToUnknown<KeysOf<RouteGeneric['Params']> extends never ? CallTypeProvider<TypeProvider, SchemaCompiler['params']> : RouteGeneric['Params']>
type ResolveRequestQuerystring<TypeProvider extends FastifyTypeProvider, SchemaCompiler extends FastifySchema, RouteGeneric extends RouteGenericInterface> =
UndefinedToUnknown<keyof RouteGeneric['Querystring'] extends never ? CallTypeProvider<TypeProvider, SchemaCompiler['querystring']> : RouteGeneric['Querystring']>
UndefinedToUnknown<KeysOf<RouteGeneric['Querystring']> extends never ? CallTypeProvider<TypeProvider, SchemaCompiler['querystring']> : RouteGeneric['Querystring']>
type ResolveRequestHeaders<TypeProvider extends FastifyTypeProvider, SchemaCompiler extends FastifySchema, RouteGeneric extends RouteGenericInterface> =
UndefinedToUnknown<keyof RouteGeneric['Headers'] extends never ? CallTypeProvider<TypeProvider, SchemaCompiler['headers']> : RouteGeneric['Headers']>
UndefinedToUnknown<KeysOf<RouteGeneric['Headers']> extends never ? CallTypeProvider<TypeProvider, SchemaCompiler['headers']> : RouteGeneric['Headers']>
type ResolveRequestBody<TypeProvider extends FastifyTypeProvider, SchemaCompiler extends FastifySchema, RouteGeneric extends RouteGenericInterface> =
UndefinedToUnknown<keyof RouteGeneric['Body'] extends never ? CallTypeProvider<TypeProvider, SchemaCompiler['body']> : RouteGeneric['Body']>
UndefinedToUnknown<KeysOf<RouteGeneric['Body']> extends never ? CallTypeProvider<TypeProvider, SchemaCompiler['body']> : RouteGeneric['Body']>

@@ -37,0 +44,0 @@ // The target request type. This type is inferenced on fastify 'requests' via generic argument assignment

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc