import express from 'express' import {IRoutes, TMethod} from '@rondo/common' import {TTypedHandler, TTypedMiddleware} from './TTypedHandler' 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, ...handlers: [TTypedHandler] | [ Array>, TTypedHandler, ] ) { const addRoute = this.router[method].bind(this.router as any) if (handlers.length === 2) { const middleware = handlers[0] const handler = handlers[1] addRoute(path, ...middleware, this.wrapHandler(handler)) } else { addRoute(path, this.wrapHandler(handlers[0])) } } protected wrapHandler( handler: TTypedHandler, ): express.RequestHandler { return (req, res, next) => { handler(req, res, next) .then(response => { res.json(response) }) .catch(next) } } get

( path: P, ...handlers: [TTypedHandler] | [ Array>, TTypedHandler, ] ): void { this.addRoute('get', path, ...handlers) } post

( path: P, ...handlers: [TTypedHandler] | [ Array>, TTypedHandler, ] ) { this.addRoute('post', path, ...handlers) } put

( path: P, ...handlers: [TTypedHandler] | [ Array>, TTypedHandler, ] ) { this.addRoute('put', path, ...handlers) } delete

( path: P, ...handlers: [TTypedHandler] | [ Array>, TTypedHandler, ] ) { this.addRoute('delete', path, ...handlers) } head

( path: P, ...handlers: [TTypedHandler] | [ Array>, TTypedHandler, ] ) { this.addRoute('head', path, ...handlers) } options

( path: P, ...handlers: [TTypedHandler] | [ Array>, TTypedHandler, ] ) { this.addRoute('options', path, ...handlers) } patch

( path: P, ...handlers: [TTypedHandler] | [ Array>, TTypedHandler, ] ) { this.addRoute('patch', path, ...handlers) } }