type Condition = ( request : Request ) => Boolean ; type Handler = ( request : Request ) => Response | Promise < Response > ; type RegExpMatcher = string | RegExp ; /**
 * Helper functions that when passed a request will return a
 * boolean indicating if the request uses that HTTP method,
 * header, host or referrer.
 */ export const Method = ( method ) : Condition => ( request ) => request . method . toLowerCase ( ) === method . toLowerCase ( ) ; export const Connect = Method ( "connect" ) ; export const Delete = Method ( "delete" ) ; export const Get = Method ( "get" ) ; export const Head = Method ( "head" ) ; export const Options = Method ( "options" ) ; export const Patch = Method ( "patch" ) ; export const Post = Method ( "post" ) ; export const Put = Method ( "put" ) ; export const Trace = Method ( "trace" ) ; export const Header = ( header , value ) => ( request ) => request . headers . get ( header ) === value ; export const Path = ( regExp ) : Condition => ( request ) => { const url = new URL ( request . url ) ; const path = url . pathname ; const match = path . match ( regExp ) || [ ] ; return match [ 0 ] === path ; } ; type Route = { conditions : Condition [ ] | Condition ; handler : Handler ; } ; /**
 * The Router handles determines which handler is matched given the
 * conditions present for each request.
 */ export class Router { routes : Route [ ] = [ ] ; handle ( conditions , handler ) { this . routes . push ( { conditions , handler , } ) ; return this ; } connect ( url , handler ) { return this . handle ( [ Connect , Path ( url ) ] , handler ) ; } delete ( url , handler ) { return this . handle ( [ Delete , Path ( url ) ] , handler ) ; } get ( url , handler ) { return this . handle ( [ Get , Path ( url ) ] , handler ) ; } head ( url , handler ) { return this . handle ( [ Head , Path ( url ) ] , handler ) ; } options ( url , handler ) { return this . handle ( [ Options , Path ( url ) ] , handler ) ; } patch ( url , handler ) { return this . handle ( [ Patch , Path ( url ) ] , handler ) ; } post ( url , handler ) { return this . handle ( [ Post , Path ( url ) ] , handler ) ; } put ( url , handler ) { return this . handle ( [ Put , Path ( url ) ] , handler ) ; } trace ( url , handler ) { return this . handle ( [ Trace , Path ( url ) ] , handler ) ; } all ( handler ) { return this . handle ( [ ] , handler ) ; } route ( request ) { const route = this . resolve ( request ) ; if ( route ) { return route . handler ( request ) ; } return new Response ( null , { status : 404 , } ) ; } /**
     * resolve returns the matching route for a request that returns
     * true for all conditions (if any).
     */ resolve ( request ) { return this . routes . find ( ( route ) => { if ( ! route . conditions || ( Array . isArray ( route ) && ! route . conditions . length ) ) { return true ; } if ( typeof route . conditions === "function" ) { return route . conditions ( request ) ; } return route . conditions . every ( ( condition ) => condition ( request ) ) ; } ) ; } }