@fastify/sensible
Advanced tools
Comparing version 5.2.0 to 5.3.0
23
index.js
@@ -34,4 +34,6 @@ 'use strict' | ||
// TODO: benchmark if this closure causes some performance drop | ||
Object.keys(httpErrors).forEach(httpError => { | ||
const httpErrorsKeys = Object.keys(httpErrors) | ||
for (let i = 0; i < httpErrorsKeys.length; ++i) { | ||
const httpError = httpErrorsKeys[i] | ||
switch (httpError) { | ||
@@ -53,4 +55,19 @@ case 'HttpError': | ||
} | ||
}) | ||
} | ||
if (opts?.sharedSchemaId) { | ||
// The schema must be the same as: | ||
// https://github.com/fastify/fastify/blob/c08b67e0bfedc9935b51c787ae4cd6b250ad303c/build/build-error-serializer.js#L8-L16 | ||
fastify.addSchema({ | ||
$id: opts.sharedSchemaId, | ||
type: 'object', | ||
properties: { | ||
statusCode: { type: 'number' }, | ||
code: { type: 'string' }, | ||
error: { type: 'string' }, | ||
message: { type: 'string' } | ||
} | ||
}) | ||
} | ||
function to (promise) { | ||
@@ -57,0 +74,0 @@ return promise.then(data => [null, data], err => [err, undefined]) |
@@ -11,4 +11,4 @@ 'use strict' | ||
const assert = require('assert') | ||
const ms = require('ms') | ||
const assert = require('node:assert') | ||
const ms = require('@lukeed/ms').parse | ||
@@ -15,0 +15,0 @@ const validSingletimes = [ |
@@ -102,5 +102,1 @@ interface HttpError extends Error { | ||
} & Record<HttpErrorNames, (msg?: string) => HttpError>; | ||
export type HttpErrorReplys = { | ||
getHttpError: (code: HttpErrorCodes, message?: string) => void; | ||
} & Record<HttpErrorNames, (msg?: string) => void>; |
'use strict' | ||
const createError = require('http-errors') | ||
const statusCodes = require('http').STATUS_CODES | ||
const statusCodes = require('node:http').STATUS_CODES | ||
@@ -6,0 +6,0 @@ const statusCodesMap = Object.assign({}, statusCodes) |
{ | ||
"name": "@fastify/sensible", | ||
"version": "5.2.0", | ||
"version": "5.3.0", | ||
"description": "Defaults for Fastify that everyone can agree on", | ||
@@ -9,2 +9,3 @@ "main": "index.js", | ||
"lint": "standard", | ||
"lint:fix": "standard --fix", | ||
"test": "npm run test:unit && npm run test:typescript", | ||
@@ -31,9 +32,11 @@ "test:typescript": "tsd", | ||
"devDependencies": { | ||
"@types/node": "^18.0.0", | ||
"@fastify/pre-commit": "^2.0.2", | ||
"@types/node": "^20.1.0", | ||
"fastify": "^4.0.0-rc.2", | ||
"standard": "^17.0.0", | ||
"tap": "^16.0.0", | ||
"tsd": "^0.25.0" | ||
"tsd": "^0.29.0" | ||
}, | ||
"dependencies": { | ||
"@lukeed/ms": "^2.0.1", | ||
"fast-deep-equal": "^3.1.1", | ||
@@ -43,3 +46,2 @@ "fastify-plugin": "^4.0.0", | ||
"http-errors": "^2.0.0", | ||
"ms": "^2.1.3", | ||
"type-is": "^1.6.18", | ||
@@ -46,0 +48,0 @@ "vary": "^1.1.2" |
@@ -10,9 +10,4 @@ # @fastify/sensible | ||
Supports Fastify versions `4.x`. | ||
Please refer to [this branch](https://github.com/fastify/fastify-sensible/tree/4.x) and related versions for Fastify `3.x` compatibility. | ||
Please refer to [this branch](https://github.com/fastify/fastify-sensible/tree/2.x) and related versions for Fastify `2.x` compatibility. | ||
Please refer to [this branch](https://github.com/fastify/fastify-sensible/tree/1.x) and related versions for Fastify `1.x` compatibility. | ||
*Why are these APIs here and not included with Fastify?<br> | ||
Because Fastify aims to be as small and focused as possible, every utility that is not essential should be shipped as standalone plugin.* | ||
Because Fastify aims to be as small and focused as possible, every utility that is not essential should be shipped as a standalone plugin.* | ||
@@ -24,2 +19,16 @@ ## Install | ||
### 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](https://github.com/fastify/fastify/blob/main/docs/Reference/LTS.md) for more details. | ||
## Usage | ||
@@ -44,7 +53,30 @@ ```js | ||
``` | ||
## 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. | ||
```js | ||
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 the `4xx` and `5xx` error constructors. | ||
Object that exposes `createError` and all of the `4xx` and `5xx` error constructors. | ||
Usage of `4xx` and `5xx` error constructors follows the same structure as [`new createError[code || name]([msg]))`](https://github.com/jshttp/http-errors#new-createerrorcode--namemsg) in [http-errors](https://github.com/jshttp/http-errors): | ||
Use of `4xx` and `5xx` error constructors follows the same structure as [`new createError[code || name]([msg]))`](https://github.com/jshttp/http-errors#new-createerrorcode--namemsg) in [http-errors](https://github.com/jshttp/http-errors): | ||
@@ -103,3 +135,3 @@ ```js | ||
Usage of `createError` follows the same structure as [`createError([status], [message], [properties])`](https://github.com/jshttp/http-errors#createerrorstatus-message-properties) in [http-errors](https://github.com/jshttp/http-errors): | ||
Use of `createError` follows the same structure as [`createError([status], [message], [properties])`](https://github.com/jshttp/http-errors#createerrorstatus-message-properties) in [http-errors](https://github.com/jshttp/http-errors): | ||
@@ -111,3 +143,3 @@ ```js | ||
#### `reply.[httpError]` | ||
The `reply` interface is decorated with all the functions declared above, using it is very easy: | ||
The `reply` interface is decorated with all of the functions declared above, using it is easy: | ||
```js | ||
@@ -159,3 +191,3 @@ fastify.get('/', (req, reply) => { | ||
#### `reply.preventCache` | ||
The `reply` interface is decorated an helper to set the cache control header to a no caching configuration. | ||
The `reply` interface is decorated with a helper to set the cache control header to a no caching configuration. | ||
```js | ||
@@ -172,3 +204,3 @@ fastify.get('/', (req, reply) => { | ||
#### `reply.revalidate` | ||
The `reply` interface is decorated an helper to set the cache control header to a no caching configuration. | ||
The `reply` interface is decorated with a helper to set the cache control header to a no caching configuration. | ||
```js | ||
@@ -182,3 +214,3 @@ fastify.get('/', (req, reply) => { | ||
#### `reply.staticCache` | ||
The `reply` interface is decorated an helper to set the cache control header to a no caching configuration. | ||
The `reply` interface is decorated with a helper to set the cache control header to a public and immutable configuration. | ||
```js | ||
@@ -193,3 +225,3 @@ fastify.get('/', (req, reply) => { | ||
#### `reply.stale` | ||
The `reply` interface is decorated an helper to set the cache control header for [stale content](https://tools.ietf.org/html/rfc5861). | ||
The `reply` interface is decorated with a helper to set the cache control header for [stale content](https://tools.ietf.org/html/rfc5861). | ||
```js | ||
@@ -205,3 +237,3 @@ fastify.get('/', (req, reply) => { | ||
#### `reply.maxAge` | ||
The `reply` interface is decorated an helper to set max age of the response. It can be used in conjunction with `reply.stale`, see [here](https://web.dev/stale-while-revalidate/). | ||
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](https://web.dev/stale-while-revalidate/). | ||
```js | ||
@@ -233,3 +265,3 @@ fastify.get('/', (req, reply) => { | ||
#### `assert` | ||
Verify if a given condition is true, if not it throws the specified http error.<br> Very useful if you work with *async* routes: | ||
Verify if a given condition is true, if not it throws the specified http error.<br> Useful if you work with *async* routes: | ||
```js | ||
@@ -241,3 +273,3 @@ // the custom message is optional | ||
``` | ||
The `assert` API exposes also the following methods: | ||
The `assert` API also exposes the following methods: | ||
- <code>fastify.assert.<b>ok()</b></code> | ||
@@ -244,0 +276,0 @@ - <code>fastify.assert.<b>equal()</b></code> |
@@ -72,3 +72,3 @@ 'use strict' | ||
t.equal(res.headers.pragma, 'no-cache') | ||
t.equal(res.headers.expires, 0) | ||
t.equal(res.headers.expires, '0') | ||
t.equal(res.payload, 'ok') | ||
@@ -75,0 +75,0 @@ }) |
@@ -5,3 +5,3 @@ 'use strict' | ||
const createError = require('http-errors') | ||
const statusCodes = require('http').STATUS_CODES | ||
const statusCodes = require('node:http').STATUS_CODES | ||
const Fastify = require('fastify') | ||
@@ -8,0 +8,0 @@ const Sensible = require('../index') |
'use strict' | ||
const { test } = require('tap') | ||
const statusCodes = require('http').STATUS_CODES | ||
const statusCodes = require('node:http').STATUS_CODES | ||
const Fastify = require('fastify') | ||
@@ -6,0 +6,0 @@ const Sensible = require('../index') |
@@ -1,3 +0,3 @@ | ||
import { FastifyPluginCallback } from 'fastify' | ||
import { HttpErrors, HttpErrorReplys } from "../lib/httpError" | ||
import { FastifyPluginCallback, FastifyReply } from 'fastify' | ||
import { HttpErrors, HttpErrorCodes, HttpErrorNames } from "../lib/httpError" | ||
@@ -22,2 +22,6 @@ type FastifySensible = FastifyPluginCallback<fastifySensible.SensibleOptions> | ||
type HttpErrorReplys = { | ||
getHttpError: (code: HttpErrorCodes, message?: string) => FastifyReply; | ||
} & Record<HttpErrorNames, (msg?: string) => FastifyReply>; | ||
declare module 'fastify' { | ||
@@ -24,0 +28,0 @@ namespace SensibleTypes { |
@@ -10,45 +10,45 @@ import { expectType, expectAssignable, expectError } from 'tsd' | ||
app.get('/', (req, reply) => { | ||
expectAssignable<void>(reply.badRequest()) | ||
expectAssignable<void>(reply.unauthorized()) | ||
expectAssignable<void>(reply.paymentRequired()) | ||
expectAssignable<void>(reply.forbidden()) | ||
expectAssignable<void>(reply.notFound()) | ||
expectAssignable<void>(reply.methodNotAllowed()) | ||
expectAssignable<void>(reply.notAcceptable()) | ||
expectAssignable<void>(reply.proxyAuthenticationRequired()) | ||
expectAssignable<void>(reply.requestTimeout()) | ||
expectAssignable<void>(reply.gone()) | ||
expectAssignable<void>(reply.lengthRequired()) | ||
expectAssignable<void>(reply.preconditionFailed()) | ||
expectAssignable<void>(reply.payloadTooLarge()) | ||
expectAssignable<void>(reply.uriTooLong()) | ||
expectAssignable<void>(reply.unsupportedMediaType()) | ||
expectAssignable<void>(reply.rangeNotSatisfiable()) | ||
expectAssignable<void>(reply.expectationFailed()) | ||
expectAssignable<void>(reply.imateapot()) | ||
expectAssignable<void>(reply.unprocessableEntity()) | ||
expectAssignable<void>(reply.locked()) | ||
expectAssignable<void>(reply.failedDependency()) | ||
expectAssignable<void>(reply.tooEarly()) | ||
expectAssignable<void>(reply.upgradeRequired()) | ||
expectAssignable<void>(reply.preconditionFailed()) | ||
expectAssignable<void>(reply.tooManyRequests()) | ||
expectAssignable<void>(reply.requestHeaderFieldsTooLarge()) | ||
expectAssignable<void>(reply.unavailableForLegalReasons()) | ||
expectAssignable<void>(reply.internalServerError()) | ||
expectAssignable<void>(reply.notImplemented()) | ||
expectAssignable<void>(reply.badGateway()) | ||
expectAssignable<void>(reply.serviceUnavailable()) | ||
expectAssignable<void>(reply.gatewayTimeout()) | ||
expectAssignable<void>(reply.httpVersionNotSupported()) | ||
expectAssignable<void>(reply.variantAlsoNegotiates()) | ||
expectAssignable<void>(reply.insufficientStorage()) | ||
expectAssignable<void>(reply.loopDetected()) | ||
expectAssignable<void>(reply.bandwidthLimitExceeded()) | ||
expectAssignable<void>(reply.notExtended()) | ||
expectAssignable<void>(reply.networkAuthenticationRequired()) | ||
expectAssignable<typeof reply>(reply.badRequest()) | ||
expectAssignable<typeof reply>(reply.unauthorized()) | ||
expectAssignable<typeof reply>(reply.paymentRequired()) | ||
expectAssignable<typeof reply>(reply.forbidden()) | ||
expectAssignable<typeof reply>(reply.notFound()) | ||
expectAssignable<typeof reply>(reply.methodNotAllowed()) | ||
expectAssignable<typeof reply>(reply.notAcceptable()) | ||
expectAssignable<typeof reply>(reply.proxyAuthenticationRequired()) | ||
expectAssignable<typeof reply>(reply.requestTimeout()) | ||
expectAssignable<typeof reply>(reply.gone()) | ||
expectAssignable<typeof reply>(reply.lengthRequired()) | ||
expectAssignable<typeof reply>(reply.preconditionFailed()) | ||
expectAssignable<typeof reply>(reply.payloadTooLarge()) | ||
expectAssignable<typeof reply>(reply.uriTooLong()) | ||
expectAssignable<typeof reply>(reply.unsupportedMediaType()) | ||
expectAssignable<typeof reply>(reply.rangeNotSatisfiable()) | ||
expectAssignable<typeof reply>(reply.expectationFailed()) | ||
expectAssignable<typeof reply>(reply.imateapot()) | ||
expectAssignable<typeof reply>(reply.unprocessableEntity()) | ||
expectAssignable<typeof reply>(reply.locked()) | ||
expectAssignable<typeof reply>(reply.failedDependency()) | ||
expectAssignable<typeof reply>(reply.tooEarly()) | ||
expectAssignable<typeof reply>(reply.upgradeRequired()) | ||
expectAssignable<typeof reply>(reply.preconditionFailed()) | ||
expectAssignable<typeof reply>(reply.tooManyRequests()) | ||
expectAssignable<typeof reply>(reply.requestHeaderFieldsTooLarge()) | ||
expectAssignable<typeof reply>(reply.unavailableForLegalReasons()) | ||
expectAssignable<typeof reply>(reply.internalServerError()) | ||
expectAssignable<typeof reply>(reply.notImplemented()) | ||
expectAssignable<typeof reply>(reply.badGateway()) | ||
expectAssignable<typeof reply>(reply.serviceUnavailable()) | ||
expectAssignable<typeof reply>(reply.gatewayTimeout()) | ||
expectAssignable<typeof reply>(reply.httpVersionNotSupported()) | ||
expectAssignable<typeof reply>(reply.variantAlsoNegotiates()) | ||
expectAssignable<typeof reply>(reply.insufficientStorage()) | ||
expectAssignable<typeof reply>(reply.loopDetected()) | ||
expectAssignable<typeof reply>(reply.bandwidthLimitExceeded()) | ||
expectAssignable<typeof reply>(reply.notExtended()) | ||
expectAssignable<typeof reply>(reply.networkAuthenticationRequired()) | ||
}) | ||
app.get('/', (req, reply) => { | ||
expectAssignable<void>(reply.getHttpError(405, 'Method Not Allowed')) | ||
expectAssignable<typeof reply>(reply.getHttpError(405, 'Method Not Allowed')) | ||
}) | ||
@@ -55,0 +55,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
60364
25
1483
292
3
6
+ Added@lukeed/ms@^2.0.1
+ Added@lukeed/ms@2.0.2(transitive)
- Removedms@^2.1.3
- Removedms@2.1.3(transitive)