import * as express from 'express' ; import State from '../State' ; import { parseEndpoint } from '../utility' ; /** Generic wrapper for an ```express``` router. Associates _endpoint templates_ in the format ```METHOD /path/:param``` with handler functions. */ export default class Router { /** An ```express``` router */ router : Function ; transform : Function ; constructor ( transform = null ) { this . router = express . Router ( ) ; this . transform = transform || ( ( path , params , ... args ) => [ { ... args . shift ( ) , ... params } , path , ... args ] ) ; } param method param route param callback declare ( method , route , callback ) { if ( ! this . router [ method ] ) { throw new Error ( `Unkown method '${ method }'.` ) ; } const handler = callback instanceof Router ? callback . router : ( req , res ) => res . send ( callback , req . params ) ; this . router [ method ] ( route , handler ) ; } param method param route param callback async retrieve ( method , path ) { return new Promise ( ( resolve ) => { return this . router ( { method : method . toUpperCase ( ) , url : path } , { send : ( callback , params ) => resolve ( callback ) } , ( ) => resolve ( undefined ) ) ; } ) ; } param method param path param args returns async request ( method , path , ... args ) { return new Promise ( ( resolve ) => { const { method : _method } = parseEndpoint ( method ) ; if ( ! _method ) { resolve ( State . BAD_REQUEST ( ) ) ; } return this . router ( { method : _method . toUpperCase ( ) , url : path } , { send : ( callback , params ) => resolve ( callback ( ... this . transform ( path , params , ... args ) ) ) } , ( ) => resolve ( State . NOT_FOUND ( ) ) ) ; } ) ; } param path async options ( path ) { return new Promise ( ( resolve ) => { return this . router ( { method : 'OPTIONS' , url : path } , { set : ( ) => { } , send : ( options ) => resolve ( options . split ( ',' ) ) } , ( ) => resolve ( State . NOT_FOUND ( ) ) ) ; } ) ; } }