import express = require ( 'express' ) ; import * as common from 'typera-common' ; import { Route } from 'typera-common' ; export { RequestHandler , Route } from 'typera-common' ; import { RequestBase , getRouteParams } from './context' ; import * as Middleware from './middleware' ; import * as Parser from './parser' ; import * as Response from './response' ; import * as URL from './url' ; export { RequestBase , Middleware , Parser , Response , URL } ; export function applyMiddleware < Middleware extends Middleware . Generic [ ] > ( ... middleware ) { return common . applyMiddleware ( getRouteParams , middleware ) ; } export const route = applyMiddleware ( ) ; type GenericRoute = Route < common . Response . Generic > ; class Router { private _routes : GenericRoute [ ] ; constructor ( ... routes ) { this . _routes = routes ; } add ( ... routes ) { return new Router ( ... this . _routes . concat ( routes ) ) ; } handler ( ) { const router = express . Router ( ) ; this . _routes . forEach ( ( route ) => { router [ route . method ] ( route . path , run ( route . routeHandler ) ) ; } ) ; return router ; } } export type { Router } ; export function router ( ... routes ) { return new Router ( ... routes ) ; } function run < Response extends common . Response . Generic > ( handler ) { return async ( req , res , next ) => { let response ; try { response = await handler ( { req , res } ) ; } catch ( err ) { next ( err ) ; return ; } res . status ( response . status ) ; if ( response . headers != null ) { res . set ( response . headers ) ; } if ( response . body ) { if ( Response . isStreamingBody ( response . body ) ) { response . body . callback ( res ) ; } else { res . send ( response . body ) ; } } else { res . end ( ) ; } } ; }