@reflet/express
Version:
Well-defined and well-typed express decorators
1,026 lines (958 loc) • 28.5 kB
TypeScript
import * as express from "express";
import * as core from "express-serve-static-core";
import { RequestHeader } from "@reflet/http";
/**
* Main method to register routers into an express application.
* @param app - express application.
* @param routers - decorated classes or instances.
*
* @example
* ```ts
* class Foo {
* @Get('/some')
* get() {}
* }
* const app = express()
* register(app, [Foo])
* app.listen(3000)
*
* // ------
* // or with instantiation:
* register(app, [new Foo()])
* ```
* ------
* @public
*/
export declare function register(app: express.Application, routers: Registration[]): express.Application;
/**
* Defines a class type. Does the opposite of built-in `InstanceType`.
* @public
*/
type ClassType = new (...args: any[]) => any;
/**
* @public
*/
type IsAny<T> = 0 extends 1 & T ? true : false;
/**
* Attaches an express Router to a class.
*
* The routes will be attached to the router at its root `path`.
*
* @param path - root path of the router.
* @param options - specifies router behavior.
*
* @see https://expressjs.com/en/4x/api.html#router
* @example
* ```ts
* @Router('/things')
* class Foo {
* @Get()
* list(req: Request, res: Response, next: NextFunction) {}
*
* @Get('/:id')
* getOne(req: Request, res: Response, next: NextFunction) {}
* }
* ```
* ------
*
* @public
*/
export declare function Router(path: string | RegExp, options?: express.RouterOptions): Router.Decorator;
export declare namespace Router {
/**
* Attaches children routers to a parent router, to have nested routers.
*
* @param register - function that should return an array of routers.
*
* @example
* ```ts
* @Router('/foo')
* @Router.Children(() => [NestedRouter])
* class ParentRouter {}
*
* @Router('/bar')
* class NestedRouter {}
* ```
* ------
* @public
*/
function Children<T extends ClassType = any>(register: (...deps: IsAny<T> extends true ? unknown[] : ConstructorParameters<T>) => Registration[]): Router.Children.Decorator;
namespace Children {
/**
* Equivalent to `ClassDecorator`.
* @public
*/
type Decorator = ClassDecorator & {
__expressRouterChildren?: never;
};
}
/**
* Attaches an express Router to a class, without defining a root path.
* The root path must be defined at registration.
*
* Useful for dynamic nested routers.
*
* @example
* ```ts
* @Router.Dynamic()
* class Items {
* @Get()
* list(req: Request, res: Response, next: NextFunction) {}
* }
*
* @Router('/foo')
* class Foo {
* constructor() {
* register(this, [['/items', Items]])
* }
* }
*
* @Router('/bar')
* class Bar {
* constructor() {
* register(this, [['/elements', Items]])
* }
* }
* ```
* ------
* @public
*/
function Dynamic(options?: express.RouterOptions): Router.Decorator;
/**
* Equivalent to `ClassDecorator`.
* @public
*/
type Decorator = ClassDecorator & {
__expressRouter?: never;
};
}
/**
* Middlewares applied to the router will be scoped to its own routes, independently of its path.
*
* @remarks
* Express isolates routers by their path, so if two routers share the same path, they will share middlewares.
* This decorator prevents this by applying middlewares directly to the routes instead of the router.
*
* @example
* ```ts
* @Router('/foo')
* @ScopedMiddlewares
* @Use(authenticate)
* class FooSecret {
* @Get()
* getSecret(req: Request, res: Response, next: NextFunction) {}
* }
*
* @Router('/foo')
* class FooPublic {
* @Get()
* getPublic(req: Request, res: Response, next: NextFunction) {}
* }
* ```
* ------
* @public
*/
export declare function ScopedMiddlewares(): ScopedMiddlewares.Decorator;
export declare function ScopedMiddlewares(...args: Parameters<ScopedMiddlewares.Decorator>): void;
export declare namespace ScopedMiddlewares {
/**
* Remove `ScopedMiddlewares` behavior on a specific router, when applied globally to the app.
*/
function Dont(): ScopedMiddlewares.Dont.Decorator;
function Dont(...args: Parameters<ScopedMiddlewares.Dont.Decorator>): void;
namespace Dont {
/**
* Equivalent to `ClassDecorator`.
* @public
*/
type Decorator = ClassDecorator & {
__expressScopedMiddlewaresDont?: never;
};
}
/**
* Equivalent to `ClassDecorator`.
* @public
*/
type Decorator = ClassDecorator & {
__expressScopedMiddlewares?: never;
};
}
/**
* @public
*/
type PropertyOrMethodDecorator = (target: Object, propertyKey: string | symbol, descriptor?: TypedPropertyDescriptor<any>) => any;
/**
* Routes an HTTP request.
* @param method - HTTP method of the request, in lowercase.
* @param path - path for which the decorated class method is invoked.
* @see https://expressjs.com/en/4x/api.html#app.METHOD
* @public
*/
export declare function Route(method: Route.Method | Route.Method[], path: string | RegExp): Route.Decorator;
export declare namespace Route {
function Get(path?: string | RegExp): Route.Decorator;
function Post(path?: string | RegExp): Route.Decorator;
function Put(path?: string | RegExp): Route.Decorator;
function Patch(path?: string | RegExp): Route.Decorator;
function Delete(path?: string | RegExp): Route.Decorator;
function Head(path?: string | RegExp): Route.Decorator;
function Options(path?: string | RegExp): Route.Decorator;
function Trace(path?: string | RegExp): Route.Decorator;
function Notify(path?: string | RegExp): Route.Decorator;
function Subscribe(path?: string | RegExp): Route.Decorator;
function Unsubscribe(path?: string | RegExp): Route.Decorator;
function Purge(path?: string | RegExp): Route.Decorator;
function Checkout(path?: string | RegExp): Route.Decorator;
function Move(path?: string | RegExp): Route.Decorator;
function Copy(path?: string | RegExp): Route.Decorator;
function Merge(path?: string | RegExp): Route.Decorator;
function Report(path?: string | RegExp): Route.Decorator;
function MSearch(path?: string | RegExp): Route.Decorator;
function Mkactivity(path?: string | RegExp): Route.Decorator;
function Mkcol(path?: string | RegExp): Route.Decorator;
function Search(path?: string | RegExp): Route.Decorator;
function Lock(path?: string | RegExp): Route.Decorator;
function Unlock(path?: string | RegExp): Route.Decorator;
function All(path?: string | RegExp): Route.Decorator;
/**
* @see http://expressjs.com/en/4x/api.html#routing-methods
* @public
*/
type Method = 'checkout' | 'copy' | 'delete' | 'get' | 'head' | 'lock' | 'merge' | 'mkactivity' | 'mkcol' | 'move' | 'm-search' | 'notify' | 'options' | 'patch' | 'post' | 'purge' | 'put' | 'report' | 'search' | 'subscribe' | 'trace' | 'unlock' | 'unsubscribe' | 'all' | 'CHECKOUT' | 'COPY' | 'DELETE' | 'GET' | 'HEAD' | 'LOCK' | 'MERGE' | 'MKACTIVITY' | 'MKCOL' | 'MOVE' | 'M-SEARCH' | 'NOTIFY' | 'OPTIONS' | 'PATCH' | 'POST' | 'PURGE' | 'PUT' | 'REPORT' | 'SEARCH' | 'SUBSCRIBE' | 'TRACE' | 'UNLOCK' | 'UNSUBSCRIBE' | 'ALL';
/**
* Equivalent to an union of `MethodDecorator` and `ProperyDecorator`.
* @public
*/
type Decorator = PropertyOrMethodDecorator & {
__expressRoute?: never;
};
}
/**
* Routes HTTP `GET` requests.
* @param path - path for which the decorated class method is invoked.
* @see https://expressjs.com/en/4x/api.html#app.get.method
* @example
* ```ts
* class Foo {
* @Get('/things/:id')
* get(req: Request, res: Response, next: NextFunction) {}
* }
* ```
* ------
* @public
*/
export declare function Get(path?: string | RegExp): Route.Decorator;
/**
* Routes HTTP `POST` requests.
* @param path - path for which the decorated class method is invoked.
* @see https://expressjs.com/en/4x/api.html#app.post.method
* @example
* ```ts
* class Foo {
* @Post('/things')
* create(req: Request, res: Response, next: NextFunction) {}
* }
* ```
* ------
* @public
*/
export declare function Post(path?: string | RegExp): Route.Decorator;
/**
* Routes HTTP `PUT` requests.
* @param path - path for which the decorated class method is invoked.
* @see https://expressjs.com/en/4x/api.html#app.put.method
* @example
* ```ts
* class Foo {
* @Put('/things/:id')
* replace(req: Request, res: Response, next: NextFunction) {}
* }
* ```
* ------
* @public
*/
export declare function Put(path?: string | RegExp): Route.Decorator;
/**
* Routes HTTP `PATCH` requests.
* @param path - path for which the decorated class method is invoked.
* @see https://expressjs.com/en/4x/api.html#app.METHOD
* @example
* ```ts
* class Foo {
* @Patch('/things/:id')
* update(req: Request, res: Response, next: NextFunction) {}
* }
* ```
* ------
* @public
*/
export declare function Patch(path?: string | RegExp): Route.Decorator;
/**
* Routes HTTP `DELETE` requests.
* @param path - path for which the decorated class method is invoked.
* @see https://expressjs.com/en/4x/api.html#app.delete.method
* @example
* ```ts
* class Foo {
* @Delete('/things/:id')
* remove(req: Request, res: Response, next: NextFunction) {}
* }
* ```
* ------
* @public
*/
export declare function Delete(path?: string | RegExp): Route.Decorator;
/**
* @public
*/
interface Handler<Req extends {} = {}> {
(req: keyof Req extends undefined ? express.Request : express.Request<Req extends {
params: infer P;
} ? P : core.ParamsDictionary, any, Req extends {
body: infer B;
} ? B : any, Req extends {
query: infer Q;
} ? Q : core.Query> & Req, res: express.Response, next: express.NextFunction): any;
}
/**
* @public
*/
type ClassOrMethodDecorator = <TFunction extends Function>(target: TFunction | Object, propertyKey?: string | symbol, descriptor?: TypedPropertyDescriptor<any>) => any;
/**
* Applies middlewares on a single route when applied to a method, or on multipe routes when applied to a class.
* @see https://expressjs.com/en/4x/api.html#app.use
*
* @remarks
* You can specify as much middlewares as you want inside a single `Use` decorator,
* and apply as many `Use` decorators as you want.
* Middlewares are applied on the routes in the order they are written.
*
* ------
* @example
* ```ts
* @Use(express.json(), express.urlencoded())
* class Foo {
* @Use<{ bar?: number }>((req, res, next) => {
* req.bar = 1
* next()
* })
* @Post('/some')
* create(req: Request & { bar: number }, res: Response, next: NextFunction) {}
* }
* ```
* ------
* @public
*/
export declare function Use<Req extends {}>(...middlewares: Handler<Req>[]): Use.Decorator;
export declare namespace Use {
/**
* Equivalent to a union of `ClassDecorator` and `MethodDecorator`.
* @public
*/
type Decorator = ClassOrMethodDecorator & {
__expressUse?: never;
};
}
/**
* Attaches an error handler on a single route when applied to a method, or on multipe routes when applied to a router class.
* @see http://expressjs.com/en/guide/error-handling.html
*
* @remarks
* You can apply as many `Catch` decorators as you want.
* Error handlers are applied on the routes in the order they are written.
*
* @example
* ```ts
* @Catch(someDefaultErrorHandler)
* class Foo {
* @Catch((err, req, res, next) => {
* res.status(400).send(err.message)
* })
* @Get('/some')
* get(req: Request, res: Response, next: NextFunction) {
* throw Error('Nope')
* }
* }
* ```
* ------
* @public
*/
export declare function Catch<T = any>(errorHandler: (err: T, req: express.Request, res: express.Response, next: express.NextFunction) => any): Catch.Decorator;
export declare namespace Catch {
/**
* Used for `@Catch` decorator.
* Equivalent to a union of `ClassDecorator` and `MethodDecorator`.
* @public
*/
type Decorator = ClassOrMethodDecorator & {
__expressCatch?: never;
};
}
/**
* Injects Request object in the method's parameters.
* @see https://expressjs.com/en/4x/api.html#req
* @example
* ```ts
* // Without invokation:
* @Get('/some')
* get(@Req req: Req) {}
*
* // With invokation:
* @Post('/some')
* create(@Req() req: Req) {}
* ```
* ------
* @public
*/
export declare function Req(): Req.Decorator;
export declare function Req(...args: Parameters<Req.Decorator>): void;
export type Req<P = core.ParamsDictionary, ResBody = any, ReqBody = any, ReqQuery = core.Query, Locals extends Record<string, any> = Record<string, any>> = express.Request<P, ResBody, ReqBody, ReqQuery, Locals>;
export declare namespace Req {
/**
* Equivalent to `ParameterDecorator`.
* @public
*/
type Decorator = ParameterDecorator & {
__expressReq?: never;
__expressHandlerParameter?: never;
};
}
/**
* Inject Response object in the method's parameters.
* @see https://expressjs.com/en/4x/api.html#res
* @example
* ```ts
* // Without invokation:
* @Get('/some')
* get(@Res res: Res) {}
*
* // With invokation:
* @Post('/some')
* create(@Res() res: Res) {}
* ```
* ------
* @public
*/
export declare function Res(): Res.Decorator;
export declare function Res(...args: Parameters<Res.Decorator>): void;
export type Res<ResBody = any, Locals extends Record<string, any> = Record<string, any>> = express.Response<ResBody, Locals>;
export declare namespace Res {
/**
* Equivalent to `ParameterDecorator`.
* @public
*/
type Decorator = ParameterDecorator & {
__expressRes?: never;
__expressHandlerParameter?: never;
};
}
/**
* Injects `next` callback function in the method's parameters.
* @see https://expressjs.com/en/guide/writing-middleware.html
* @example
* ```ts
* // Without invokation:
* @Get('/some')
* get(@Next next: Next) {}
*
* // With invokation:
* @Post('/some')
* create(@Next() next: Next) {}
* ```
* ------
* @public
*/
export declare function Next(): Next.Decorator;
export declare function Next(...args: Parameters<Next.Decorator>): void;
export type Next = express.NextFunction;
export declare namespace Next {
/**
* Equivalent to `ParameterDecorator`.
* @public
*/
type Decorator = ParameterDecorator & {
__expressNext?: never;
__expressHandlerParameter?: never;
};
}
/**
* Injects request body in the method's parameters.
* @param key - directly injects a body property.
* @see https://expressjs.com/en/4x/api.html#req.body
* @example
* ```ts
* // Whole body without invokation:
* @Post('/some')
* create(@Body body: object) {}
*
* // Whole body with invokation:
* @Put('/some')
* replace(@Body() body: object) {}
*
* // Sub property:
* @Patch('/some')
* update(@Body<User>('email') email: string) {}
* ```
* ------
* @public
*/
export declare function Body<T extends object>(key?: keyof T): Body.Decorator;
export declare function Body(...args: Parameters<Body.Decorator>): void;
export declare namespace Body {
/**
* Equivalent to `ParameterDecorator`.
* @public
*/
type Decorator = ParameterDecorator & {
__expressBody?: never;
__expressHandlerParameter?: never;
};
}
/**
* Injects named route parameters in the method's parameters.
* @param name - directly injects a single route parameter.
* @see https://expressjs.com/en/4x/api.html#req.params
* @example
* ```ts
* // Route parameters object without invokation:
* @Get('/:col/:id')
* get(@Params params: Params<'col' | 'id'>) {}
*
* // Route parameters object with invokation:
* @Get('/:col/:id')
* get(@Params() params: Params<'col' | 'id'>) {}
*
* // Single route parameter:
* @Get('/:col/:id')
* get(@Params('col') col: string, @Params('id') id: string) {}
* ```
* ------
* @public
*/
export declare function Params(name?: string): Params.Decorator;
export declare function Params(...args: Parameters<Params.Decorator>): void;
export type Params<P extends string = string> = Record<P, string>;
export declare namespace Params {
/**
* Equivalent to `ParameterDecorator`.
* @public
*/
type Decorator = ParameterDecorator & {
__expressParams?: never;
__expressHandlerParameter?: never;
};
}
/**
* Injects query string parameters in the method's parameters.
* @param field - directly injects a value.
* @see https://expressjs.com/en/4x/api.html#req.query
* @example
* ```ts
* // Query string parameters object without invokation:
* @Get('/search')
* search(@Query query: Query) {}
*
* // Query string parameters object with invokation:
* @Get('/search')
* search(@Query() query: Query) {}
*
* // Single query string parameter:
* @Get('/search')
* search(@Query('name') name: string, @Query('sort') sort: string) {}
* ```
* ------
* @public
*/
export declare function Query(field?: string): Query.Decorator;
export declare function Query(...args: Parameters<Query.Decorator>): void;
export type Query = {
[key: string]: undefined | string | string[] | Query | Query[];
};
export declare namespace Query {
/**
* Equivalent to `ParameterDecorator`.
* @public
*/
type Decorator = ParameterDecorator & {
__expressQuery?: never;
__expressHandlerParameter?: never;
};
}
/**
* Injects request headers object in the method's parameters.
* @param headerName - directly injects a specific header.
* @see https://nodejs.org/api/http.html#http_message_headers
* @example
* ```ts
* // Request headers object without invokation:
* @Get('/some')
* get(@Headers headers: Headers) {}
*
* // Request headers object with invokation:
* @Get('/some')
* get(@Headers() headers: Headers) {}
*
* // Single request header:
* @Get('/some')
* get(@Headers('user-agent') userAgent: string) {}
* ```
* ------
* @public
*/
export declare function Headers(headerName?: RequestHeader): Headers.Decorator;
export declare function Headers(...args: Parameters<Headers.Decorator>): void;
export type Headers = RequestHeader.Record;
export declare namespace Headers {
/**
* Equivalent to `ParameterDecorator`.
* @public
*/
type Decorator = ParameterDecorator & {
__expressHeaders?: never;
__expressHandlerParameter?: never;
};
}
/**
* @public
*/
declare type Middleware = express.RequestHandler | {
handler: express.RequestHandler;
dedupe?: boolean | 'by-name' | 'by-reference';
};
/**
* Creates a parameter decorator, to inject anything we want in decorated routes.
*
* @param mapper - function that should return the thing we want to inject from the Request object.
* @param use - adds middlewares to the route if the mapper needs them (_e.g. we need body-parser middlewares to retrieve `req.body`_). You can pass options to deduplicate middlewares based on the handler function reference or name (_e.g. if 'jsonParser' is already in use locally or globally, it won't be added again_).
*
* @remarks
* We can create decorators with or without options.
* Simple decorators without options are applied without being invoked.
*
* ------
* @example
* ```ts
* // Simple decorator:
* const CurrentUser = createParamDecorator((req) => req.user)
* class Foo {
* @Get('/me')
* get(@CurrentUser user: User) {}
* }
* ```
* ------
* @example
* ```ts
* // Advanced decorator (with option and middleware):
* const BodyTrimmed = (key: string) => createParamDecorator(
* (req) => req.body[key].trim(),
* [{ handler: express.json(), dedupe: true }]
* )
* class Foo {
* @Post('/message')
* create(@BodyTrimmed('text') text: string) {}
* }
* ```
* ------
* @public
*/
export declare function createParamDecorator<T = any>(mapper: (req: express.Request, res: express.Response) => T, use?: createParamDecorator.Middleware[]): createParamDecorator.Decorator;
export declare namespace createParamDecorator {
/**
* @public
*/
type Options = {
readonly mapper: (req: express.Request, res: express.Response, next?: express.NextFunction) => any;
readonly use?: Middleware[];
};
/**
* @public
*/
type Middleware = express.RequestHandler | {
handler: express.RequestHandler;
dedupe?: boolean | 'by-name' | 'by-reference';
};
/**
* Equivalent to `ParameterDecorator`.
* @public
*/
type Decorator = ParameterDecorator & {
__expressHandlerParameter?: never;
};
}
/**
* {@linkcode TypedPropertyDescriptor}
* @public
*/
interface MethodDescriptorReturn<T> {
value?: (...args: any[]) => T;
}
/**
* @public
*/
type ClassOrTypedMethodDecorator<T> = <TFunction extends Function>(target: Object | TFunction, propertyKey?: string | symbol, descriptor?: MethodDescriptorReturn<T>) => TFunction extends Function ? any : MethodDescriptorReturn<T> | void;
/**
* Tells express to handle the method's return value and send it.
*
* @param options - Force json response type.
* Return value will be sent with [`res.send`](https://expressjs.com/en/4x/api.html#res.send) by default.
* Switch `json` option to `true` to send it with [`res.json`](https://expressjs.com/en/4x/api.html#res.json)
*
* ------
* @example
* ```ts
* class Foo {
* @Send({ json: true })
* @Get('/some')
* get() {
* return 'bar' // content-type: application-json
* }
* }
* ```
* ------
* @public
*/
export declare function Send(options?: Send.Options): Send.Decorator;
/**
* Handle the method's return value with a custom handler.
*
* ------
* @example
* ```ts
* class Foo {
* @Send<string>((data, { res }) => {
* res.json({ hello: data })
* })
* @Get('/some')
* get() {
* return 'world'
* }
* }
* ```
* ------
* @public
*/
export declare function Send<T>(handler?: Send.Handler<T>): Send.Decorator<T>;
export declare namespace Send {
/**
* Options for `@Send` decorator.
* @public
*/
type Options = {
/** Forces using express `res.json` method to send response */
json?: boolean;
};
/**
* @public
*/
type Handler<T> = (data: Awaited<T>, context: {
req: express.Request;
res: express.Response;
next: express.NextFunction;
}) => void | Promise<void>;
/**
* Equivalent to a union of `ClassDecorator` and `MethodDecorator`.
* @public
*/
type Decorator<T = any> = ClassOrTypedMethodDecorator<T> & {
__expressSend?: never;
};
/**
* Prevents a method from having its return value being sent,
* if a `@Send` decorator is applied to its class.
*
* @example
* ```ts
* @Send()
* class Foo {
* @Get('/some')
* get() {
* return 'hi'
* }
*
* @Send.Dont()
* @Put('/some')
* replace(req: Request, res: Response, next: NextFunction) {
* res.send('hi')
* }
* }
* ```
* ------
* @public
*/
function Dont(): Send.Dont.Decorator;
function Dont(...args: Parameters<Send.Dont.Decorator>): void;
namespace Dont {
/**
* Equivalent to a union of `ClassDecorator` and `MethodDecorator`.
* @public
*/
type Decorator = ClassOrMethodDecorator & {
__expressSendDont?: never;
};
}
}
export interface Application extends express.Application {
}
/**
* Express application class to extend, to apply the decorators with a global behavior.
*
* _Constructor simply returns an express application, augmented with `register` method._
*
* @example
* ```ts
* @Send({ json: true })
* @Use(express.json())
* class App extends Application {
* @Get('/healthcheck')
* healthcheck() {
* return { success: true }
* }
* }
*
* @Router('/foo')
* class FooRouter {
* @Get()
* list() {
* return db.collection('foo').find({})
* }
* }
*
* const app = new App()
* app.register([FooRouter])
* app.listen(3000)
* ```
* ------
* @public
*/
export declare class Application {
constructor();
register(routers?: Registration[]): this;
}
/**
* @public
*/
declare type NotFunction = {
bind?(): never;
} | {
call?(): never;
} | {
apply?(): never;
};
/**
* @public
*/
declare type NotArray = {
push?(): never;
} | {
pop?(): never;
} | {
shift?(): never;
} | {
unshift?(): never;
};
/**
* @example
* ```ts
* const routers: Registration[] = [
* ['/foo', Foo],
* ['/bar', Bar],
* new Baz(),
* ]
* register(app, routers)
* ```
* ------
* @public
*/
export type Registration = Registration.Class | Registration.Instance | Registration.Tuple;
export declare namespace Registration {
/**
* @public
*/
type Class = new () => any;
/**
* @public
*/
type Instance = object & NotFunction & NotArray;
/**
* @public
*/
type Tuple = [path: string | RegExp, router: Registration.Class | Registration.Instance | express.IRouter];
}
/**
* Only readonly properties and methods from response.
* @public
*/
type ResponseReadonly = Pick<express.Response, 'statusCode' | 'statusMessage' | 'locals' | 'charset' | 'headersSent' | 'getHeader' | 'getHeaders' | 'getHeaderNames' | 'hasHeader' | 'finished' | 'writableEnded' | 'writableFinished'>;
/**
* Final error handler to apply globally on the app, to be able to send errors as `json`.
*
* @example
* ```ts
* app.use(finalHandler({
* json: true,
* expose: ['name', 'message'],
* log: '5xx',
* notFoundHandler: true,
* }))
* ```
* ------
* @public
*/
export declare function finalHandler(options: finalHandler.Options): express.ErrorRequestHandler;
export declare namespace finalHandler {
/**
* @public
*/
interface Options {
/**
* Specifies behavior to use `res.json` to send errors:
*
* - `true`: always send as json.
* - `false`: pass directly the error to `next`.
* - `'from-response-type'`: looks for a json compatible `Content-Type` on the response (or else pass to `next`)
* - `'from-response-type-or-request'`: if the response doesn't have a `Content-type` header, it looks for `X-Requested-With` or `Accept` headers on the request (or else pass to `next`)
*/
json: boolean | 'from-response-type' | 'from-response-type-or-request';
/**
* Exposes error properties to client:
*
* - `true`: exposes all properties (stack included, beware of information leakage !).
* - `false`: exposes nothing (empty object).
* - `string[]`: whitelists specific error properties.
* - `(status) => boolean | string[]`: flexible whitelisting.
*
* You can pass a function with the status code as parameter for more conditional whitelisting.
*/
expose: boolean | finalHandler.ErrorProps[] | finalHandler.Exposer;
/**
* log error:
*
* - `true`: every error
* - `false`: none
* - `'5xx'`: only server errors
* - `(err, req, res) => void`: flexible logging
*/
log?: boolean | '5xx' | finalHandler.Logger;
/**
* Defines the handler when the route is not found:
*
* - switch to `true` to apply a basic handler throwing a `404` error.
* - switch to a number to apply the same basic handler with a custom status code.
* - or declare your own handler.
*/
notFoundHandler?: boolean | number | express.RequestHandler;
}
/**
* @public
*/
type Exposer = (statusCode: number) => boolean | finalHandler.ErrorProps[];
/**
* @public
*/
type Logger = (err: any, req: express.Request, readonlyRes: ResponseReadonly) => void;
/**
* @public
*/
type ErrorProps = 'name' | 'message' | 'stack' | (string & Record<never, never>);
}
export {}