import {IRoutes, IRoute, IMethod} from '../../common/REST' import express, {NextFunction} from 'express' export interface IRequest extends express.Request { body: T['body'] params: T['params'] query: T['query'] } export type IHandler = (req: IRequest, res: express.Response, next: NextFunction) => Promise export class AsyncRouter { readonly router: express.Router readonly use: express.IRouterHandler & express.IRouterMatcher constructor(router?: express.Application | express.Router) { this.router = router ? router : express.Router() this.use = this.router.use.bind(this.router) as any } protected addRoute( method: M, path: P, handler: IHandler, ) { const addRoute = this.router[method].bind(this.router) addRoute(path, this.wrapHandler(handler)) } protected wrapHandler( handler: IHandler, ): express.RequestHandler { return (req, res, next) => { handler(req, res, next) .then(response => { res.json(response) }) .catch(next) } } get

(path: P, handler: IHandler) { this.addRoute('get', path, handler) } post

(path: P, handler: IHandler) { this.addRoute('post', path, handler) } put

(path: P, handler: IHandler) { this.addRoute('put', path, handler) } delete

( path: P, handler: IHandler) { this.addRoute('delete', path, handler) } head

(path: P, handler: IHandler) { this.addRoute('head', path, handler) } options

( path: P, handler: IHandler) { this.addRoute('options', path, handler) } patch

( path: P, handler: IHandler) { this.addRoute('patch', path, handler) } }