import { Endpoint , EndpointConfig , GenericEndpoint , toEndpoint , EndpointWithConfigure } from "./endpoint/mod.ts" ; import { Util , Log , TrueFunction } from "../util/mod.ts" ; import { rgb24 } from "https://deno.land/std/fmt/colors.ts" ; import { MiddlewareConfig , Middleware , MiddleWareWithConfigure } from "./middleware/mod.ts" ; import { EnlaceServer } from "./server.ts" ; import { isController , getEndpointsInController } from "../controller.ts" ; import { Adaptor } from "./adaptor/mod.ts" ; type RouterHolder = EnlaceServer | Adaptor ; type RouteItem = GenericEndpoint | Object ; /**
 * Function module that guides network requests to the correct Endpoint.
 */ export class Router { /**
     * The owner of the Router. It's might be an instance of EnlceServer
     * or Adaptor.
     */ public readonly holder : RouterHolder ; constructor ( holder ) { this . holder = holder ; } /**
     * A boolean value indicates whether the router is on the EnlceServer
     * instance.
     */ public get isRootRouter ( ) : boolean { return this . holder instanceof EnlaceServer ; } /**
     * A map table store the relationship between endpoint configure and regisetered endpoint.
     */ protected configureToEndpoint : Map < EndpointConfig , Endpoint > = new Map ( ) ; /**
     * A list value store the relationship between endpoint configure and registered middle ware.
     */ protected middlewareWithConfigure : Array < MiddleWareWithConfigure > = new Array ( ) ; /**
     * A list value indicates all the registered endpoints in the Router.
     */ public get endpoints ( ) : Endpoint [ ] { return [ ... this . configureToEndpoint . values ( ) ] ; } /**
     * A list value indicates all the registered middlewares in the Router.
     */ public get middleware ( ) : Middleware [ ] { return this . middlewareWithConfigure . map ( i => i . middleWare ) ; } param path param middleWare public useMiddlewareOn ( path , middleware ) { const configure = { expectedPath : path } ; this . addMiddleWareAndConfigure ( middleware , configure ) ; } see Router . useEndpoint param path param endpoint public useEndpointOn ( path , endpoint ) { return this . useEndpoint ( endpoint , { expectedPath : path , selectAdaptor : TrueFunction } ) ; } param endpoint param configure public useEndpoint ( endpoint , configure ? ) { if ( isController ( endpoint ) ) { const endpoints = getEndpointsInController ( endpoint ) ; for ( const { endpoint , configure } of endpoints ) { this . addEndpointWithConfigure ( toEndpoint ( endpoint ) , configure ) ; } } else { this . addEndpointWithConfigure ( toEndpoint ( endpoint as GenericEndpoint ) , configure ! ) ; } return this ; } param path public matchMiddleWareWithPath ( path ) { let matched = [ ] ; for ( const { configure , middleWare } of this . middlewareWithConfigure ) { if ( Util . matchPath ( path , configure . expectedPath ) ) { matched . push ( { configure , middleWare } ) ; } } return matched ; } param path public matchEndpointWithPath ( path ) { let matched = null ; for ( const [ configure , endpoint ] of this . configureToEndpoint ) { if ( Util . matchPath ( path , configure . expectedPath ) ) { if ( configure . expectedPath . length > ( matched ?. configure . expectedPath . length ?? 0 ) ) { matched = { configure , endpoint } ; } } } return matched ; } param endpoint param config protected addEndpointWithConfigure ( endpoint , config ) { Log . info ( `register ${ rgb24 ( config . expectedPath , 0xffc42e ) } on endpoint` , 'Router' ) ; this . configureToEndpoint . set ( config , endpoint ) ; } param middleware param configure protected addMiddleWareAndConfigure ( middleware , configure ) { this . middlewareWithConfigure . push ( { configure , middleWare : middleware } ) ; } }