npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@fastify/sensible

v6.0.1

Published

Defaults for Fastify that everyone can agree on

Downloads

478,406

Readme

@fastify/sensible

CI NPM version js-standard-style

Defaults for Fastify that everyone can agree on™. This plugin adds some useful utilities to your Fastify instance, see the API section to learn more.

Why are these APIs here and not included with Fastify? Because Fastify aims to be as small and focused as possible, every utility that is not essential should be shipped as a standalone plugin.

Install

npm i @fastify/sensible

Compatibility

| Plugin version | Fastify version | | -------------- |---------------- | | ^5.0.0 | ^4.0.0 | | ^4.0.0 | ^3.0.0 | | ^2.0.0 | ^2.0.0 | | ^1.0.0 | ^1.0.0 |

Please note that if a Fastify version is out of support, then so are the corresponding version(s) of this plugin in the table above. See Fastify's LTS policy for more details.

Usage

const fastify = require('fastify')()
fastify.register(require('@fastify/sensible'))

fastify.get('/', (req, reply) => {
  reply.notFound()
})

fastify.get('/async', async (req, reply) => {
  throw fastify.httpErrors.notFound()
})

fastify.get('/async-return', async (req, reply) => {
  return reply.notFound()
})

fastify.listen({ port: 3000 })

Shared JSON Schema for HTTP errors

If you set the sharedSchemaId option, a shared JSON Schema is added and can be used in your routes.

const fastify = require('fastify')()
fastify.register(require('@fastify/sensible'), {
  sharedSchemaId: 'HttpError'
})

fastify.get('/async', {
  schema: {
    response: {
      404: { $ref: 'HttpError' }
    }
  },
  handler: async (req, reply) => {
    return reply.notFound()
  }
})

fastify.listen({ port: 3000 })

API

fastify.httpErrors

Object that exposes createError and all of the 4xx and 5xx error constructors.

Use of 4xx and 5xx error constructors follows the same structure as new createError[code || name]([msg])) in http-errors:

 // the custom message is optional
const notFoundErr = fastify.httpErrors.notFound('custom message')

4xx

  • fastify.httpErrors.badRequest()
  • fastify.httpErrors.unauthorized()
  • fastify.httpErrors.paymentRequired()
  • fastify.httpErrors.forbidden()
  • fastify.httpErrors.notFound()
  • fastify.httpErrors.methodNotAllowed()
  • fastify.httpErrors.notAcceptable()
  • fastify.httpErrors.proxyAuthenticationRequired()
  • fastify.httpErrors.requestTimeout()
  • fastify.httpErrors.conflict()
  • fastify.httpErrors.gone()
  • fastify.httpErrors.lengthRequired()
  • fastify.httpErrors.preconditionFailed()
  • fastify.httpErrors.payloadTooLarge()
  • fastify.httpErrors.uriTooLong()
  • fastify.httpErrors.unsupportedMediaType()
  • fastify.httpErrors.rangeNotSatisfiable()
  • fastify.httpErrors.expectationFailed()
  • fastify.httpErrors.imateapot()
  • fastify.httpErrors.misdirectedRequest()
  • fastify.httpErrors.unprocessableEntity()
  • fastify.httpErrors.locked()
  • fastify.httpErrors.failedDependency()
  • fastify.httpErrors.tooEarly()
  • fastify.httpErrors.upgradeRequired()
  • fastify.httpErrors.preconditionRequired()
  • fastify.httpErrors.tooManyRequests()
  • fastify.httpErrors.requestHeaderFieldsTooLarge()
  • fastify.httpErrors.unavailableForLegalReasons()

5xx

  • fastify.httpErrors.internalServerError()
  • fastify.httpErrors.notImplemented()
  • fastify.httpErrors.badGateway()
  • fastify.httpErrors.serviceUnavailable()
  • fastify.httpErrors.gatewayTimeout()
  • fastify.httpErrors.httpVersionNotSupported()
  • fastify.httpErrors.variantAlsoNegotiates()
  • fastify.httpErrors.insufficientStorage()
  • fastify.httpErrors.loopDetected()
  • fastify.httpErrors.bandwidthLimitExceeded()
  • fastify.httpErrors.notExtended()
  • fastify.httpErrors.networkAuthenticationRequired()

createError

Use of createError follows the same structure as createError([status], [message], [properties]) in http-errors:

var err = fastify.httpErrors.createError(404, 'This video does not exist!')

reply.[httpError]

The reply interface is decorated with all of the functions declared above, using it is easy:

fastify.get('/', (req, reply) => {
  reply.notFound()
})

reply.vary

The reply interface is decorated with jshttp/vary, the API is the same, but you do not need to pass the res object.

fastify.get('/', (req, reply) => {
  reply.vary('Accept')
  reply.send('ok')
})

reply.cacheControl

The reply interface is decorated an helper to configure cache control response headers.

// configure a single type
fastify.get('/', (req, reply) => {
  reply.cacheControl('public')
  reply.send('ok')
})

// configure multiple types
fastify.get('/', (req, reply) => {
  reply.cacheControl('public')
  reply.cacheControl('immutable')
  reply.send('ok')
})

// configure a type time
fastify.get('/', (req, reply) => {
  reply.cacheControl('max-age', 42)
  reply.send('ok')
})

// the time can be defined as string
fastify.get('/', (req, reply) => {
  // all the formats of github.com/vercel/ms are supported
  reply.cacheControl('max-age', '1d') // will set to 'max-age=86400'
  reply.send('ok')
})

reply.preventCache

The reply interface is decorated with a helper to set the cache control header to a no caching configuration.

fastify.get('/', (req, reply) => {
  // will set cache-control to 'no-store, max-age=0, private'
  // and for HTTP/1.0 compatibility
  // will set pragma to 'no-cache' and expires to 0
  reply.preventCache()
  reply.send('ok')
})

reply.revalidate

The reply interface is decorated with a helper to set the cache control header to a no caching configuration.

fastify.get('/', (req, reply) => {
  reply.revalidate() // will set to 'max-age=0, must-revalidate'
  reply.send('ok')
})

reply.staticCache

The reply interface is decorated with a helper to set the cache control header to a public and immutable configuration.

fastify.get('/', (req, reply) => {
  // the time can be defined as a string
  reply.staticCache(42) // will set to 'public, max-age=42, immutable'
  reply.send('ok')
})

reply.stale

The reply interface is decorated with a helper to set the cache control header for stale content.

fastify.get('/', (req, reply) => {
  // the time can be defined as a string
  reply.stale('while-revalidate', 42)
  reply.stale('if-error', 1)
  reply.send('ok')
})

reply.maxAge

The reply interface is decorated with a helper to set max age of the response. It can be used in conjunction with reply.stale, see here.

fastify.get('/', (req, reply) => {
  // the time can be defined as a string
  reply.maxAge(86400)
  reply.stale('while-revalidate', 42)
  reply.send('ok')
})

request.forwarded

The request interface is decorated with jshttp/forwarded, the API is the same, but you do not need to pass the request object:

fastify.get('/', (req, reply) => {
  reply.send(req.forwarded())
})

request.is

The request interface is decorated with jshttp/type-is, the API is the same, but you do not need to pass the request object:

fastify.get('/', (req, reply) => {
  reply.send(req.is(['html', 'json']))
})

assert

Verify if a given condition is true, if not it throws the specified http error. Useful if you work with async routes:

// the custom message is optional
fastify.assert(
  req.headers.authorization, 400, 'Missing authorization header'
)

The assert API also exposes the following methods:

  • fastify.assert.ok()
  • fastify.assert.equal()
  • fastify.assert.notEqual()
  • fastify.assert.strictEqual()
  • fastify.assert.notStrictEqual()
  • fastify.assert.deepEqual()
  • fastify.assert.notDeepEqual()

to

Async await wrapper for easy error handling without try-catch, inspired by await-to-js:

const [err, user] = await fastify.to(
  db.findOne({ user: 'tyrion' })
)

Contributing

Do you feel there is some utility that everyone can agree on which is not present? Open an issue and let's discuss it! Even better a pull request!

Acknowledgements

The project name is inspired by vim-sensible, an awesome package that if you use vim you should use too.

License

MIT Copyright © Tomas Della Vedova & Fastify collaborators