Add support for regex matching routes
This commit is contained in:
parent
7611c1b2bf
commit
194fa476ca
1
TODO.txt
1
TODO.txt
@ -1,4 +1,3 @@
|
|||||||
deepmatch route, regex match route
|
|
||||||
static assets
|
static assets
|
||||||
middleware
|
middleware
|
||||||
view engine
|
view engine
|
||||||
|
57
lib/src/http/routing/RegExRoute.ts
Normal file
57
lib/src/http/routing/RegExRoute.ts
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import {Route, RouteParameters} from './Route.ts'
|
||||||
|
import {Logging} from '../../service/logging/Logging.ts'
|
||||||
|
import {make} from '../../../../di/src/global.ts'
|
||||||
|
|
||||||
|
export class RegExRoute extends Route {
|
||||||
|
protected key_regex: RegExp
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
protected base: string,
|
||||||
|
protected key: string,
|
||||||
|
) {
|
||||||
|
super(base)
|
||||||
|
this.key_regex = this.build_regex(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
public get route() {
|
||||||
|
return this.base + this.key
|
||||||
|
}
|
||||||
|
|
||||||
|
public match(incoming: string): boolean {
|
||||||
|
if ( !incoming.toLowerCase().startsWith(this.base) ) return false
|
||||||
|
incoming = incoming.substr(this.base.length)
|
||||||
|
|
||||||
|
const success = this.key_regex.test(incoming)
|
||||||
|
|
||||||
|
if ( !success ) {
|
||||||
|
make(Logging).debug(`RegExRoute match failed. (Testing: ${incoming}, Key: ${this.key}, Rex: ${this.key_regex})`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return success
|
||||||
|
}
|
||||||
|
|
||||||
|
public build_parameters(incoming: string): RouteParameters {
|
||||||
|
if ( incoming.toLowerCase().startsWith(this.base) ) incoming = incoming.substr(this.base.length)
|
||||||
|
|
||||||
|
const results = this.key_regex.exec(incoming.toLowerCase())
|
||||||
|
if ( !results ) return {}
|
||||||
|
|
||||||
|
const [match, ...wildcards] = results
|
||||||
|
const params: RouteParameters = {}
|
||||||
|
let current_wildcard: number = 1
|
||||||
|
|
||||||
|
for ( const wild of wildcards ) {
|
||||||
|
params[`$${current_wildcard}`] = wild
|
||||||
|
current_wildcard += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
|
protected build_regex(key: string) {
|
||||||
|
if ( !key.startsWith('rex ') ) {
|
||||||
|
throw new TypeError(`Invalid regular expression route pattern: ${key}`)
|
||||||
|
}
|
||||||
|
return new RegExp(key.substr(4))
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,7 @@ import {Logging} from '../service/logging/Logging.ts'
|
|||||||
import {Canon} from './Canon.ts'
|
import {Canon} from './Canon.ts'
|
||||||
import {isBindable} from '../lifecycle/AppClass.ts'
|
import {isBindable} from '../lifecycle/AppClass.ts'
|
||||||
import {DeepmatchRoute} from "../http/routing/DeepmatchRoute.ts";
|
import {DeepmatchRoute} from "../http/routing/DeepmatchRoute.ts";
|
||||||
|
import {RegExRoute} from "../http/routing/RegExRoute.ts";
|
||||||
|
|
||||||
export type RouteHandler = (request: Request) => Request | Promise<Request> | ResponseFactory | Promise<ResponseFactory> | void | Promise<void>
|
export type RouteHandler = (request: Request) => Request | Promise<Request> | ResponseFactory | Promise<ResponseFactory> | void | Promise<void>
|
||||||
export type RouteHandlers = RouteHandler[]
|
export type RouteHandlers = RouteHandler[]
|
||||||
@ -74,7 +75,7 @@ export default class Routing extends LifecycleUnit {
|
|||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
this.definitions[base][verb] = this.build_handler(handlers)
|
this.definitions[base][verb] = this.build_handler(handlers)
|
||||||
this.instances.push(this.build_route(base))
|
this.instances.push(this.build_route(base, key))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,8 +137,10 @@ export default class Routing extends LifecycleUnit {
|
|||||||
return `/${joined}`.toLowerCase()
|
return `/${joined}`.toLowerCase()
|
||||||
}
|
}
|
||||||
|
|
||||||
public build_route(base: string): Route {
|
public build_route(base: string, key: string): Route {
|
||||||
if ( !base.includes(':') && !base.includes('*') ) {
|
if ( key.startsWith('rex ') ) {
|
||||||
|
return new RegExRoute(base.split(key)[0], key)
|
||||||
|
} else if ( !base.includes(':') && !base.includes('*') ) {
|
||||||
return new SimpleRoute(base)
|
return new SimpleRoute(base)
|
||||||
} else if ( base.includes('**') ) {
|
} else if ( base.includes('**') ) {
|
||||||
return new DeepmatchRoute(base)
|
return new DeepmatchRoute(base)
|
||||||
|
Loading…
Reference in New Issue
Block a user