import pathToRegexp from 'path-to-regexp' ; import * as _ from './util' ; import { Route , IntactRoute , Matcher , Params , ControllerConstructor , LoadController } from './type' ; export interface CreateMatcher { ( routes ) : Matcher ; } export interface CreateRoute { ( route ) : IntactRoute ; } export interface GetParams { ( strMatches , keys ) : Params ; } export interface CleanPath { ( path ) : string ; } const createMatcher = ( routes ) => { const finalRoutes = routes . map ( createRoute ) ; const routeLength = finalRoutes . length ; const matcher = ( pathname ) => { let finalPathname = cleanPath ( pathname ) ; for ( let i = 0 ; i < routeLength ; i ++ ) { let route = finalRoutes [ i ] ; let strMatches = route . regexp . exec ( finalPathname ) ; if ( ! strMatches ) { continue ; } let params = getParams ( strMatches , route . keys ) ; let controller = route . controller ; return { path : route . path , params , controller } ; } return null ; } ; return matcher ; } ; export default createMatcher ; const createRoute = ( route ) => { let finalRoute = Object . assign ( { } , route ) ; finalRoute . keys = [ ] ; let keys = finalRoute . keys ; let regexp = pathToRegexp ( finalRoute . path , keys ) ; let intactRoute = Object . assign ( { keys , regexp } , finalRoute ) ; return intactRoute ; } ; const getParams = ( matches , keys ) => { let params = { } ; for ( let i = 1 , len = matches . length ; i < len ; i ++ ) { let key = keys [ i - 1 ] ; if ( key ) { if ( typeof matches [ i ] === 'string' ) { params [ key . name ] = decodeURIComponent ( matches [ i ] ) ; } else { params [ key . name ] = matches [ i ] ; } } } return params ; } ; const cleanPath = ( path ) => { return path . replace ( /\/\//g , '/' ) ; } ;