import pathToRegexp , { Key } from 'path-to-regexp' ; import { RequestMethods } from '../Server' ; import { RegisteredRouteInterface } from './RegisteredRouteInterface' ; import { RouteInterface } from './RouteInterface' ; import { RouterConfigInterface } from '../Config' ; import { AbstractActionController } from '../Controller' ; export class RouterService { private routes : RegisteredRouteInterface [ ] = [ ] ; private config : RouterConfigInterface ; constructor ( config ) { this . config = config ; this . registerRoutes ( this . config . routes ) ; } public resolve ( method , target ) { for ( let i = 0 ; i < this . routes . length ; i ++ ) { const route = this . routes [ i ] ; if ( method !== route . method ) { continue ; } const parameters = this . match ( target , route ) ; if ( parameters ) { return { route , parameters } ; } } return null ; } public match ( target , route ) { const { regex , keys } = route ; const result = regex . exec ( target ) ; if ( ! result ) { return null ; } result . splice ( 0 , 1 ) ; return this . buildParameters ( keys , result ) ; } public registerRoutes ( routes ) { routes . forEach ( newRoute => { if ( Array . isArray ( newRoute ) ) { return this . registerRoutes ( newRoute ) ; } const { method , route , action , controller } = newRoute ; this . registerRoute ( method , route , controller , action ) ; } ) ; return this ; } public registerRoute ( method , route , controller , action ) { const keys = [ ] ; const regex = pathToRegexp ( route , keys ) ; const routeIndex = this . routes . findIndex ( target => target . route === route && target . method === method ) ; if ( routeIndex > - 1 ) { this . routes . splice ( routeIndex , 1 ) ; } this . routes . push ( { regex , controller , action , keys , method , route } ) ; return this ; } public getRegisteredRoutes ( ) { return this . routes ; } public buildParameters ( from , result ) { return result . reduce ( ( params , match , index ) : { } => { return Object . assign ( params , { [ from [ index ] . name ] : match } ) ; } , { } ) ; } }