You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

73 lines
2.1 KiB

import {logger} from '../../service/logging/global.ts'
export type RouteParameters = { [key: string]: string }
export type RouteSegment = { base: string, match: string | undefined }
export type ZippedRouteSegments = RouteSegment[]
/**
* Abstract base class representing a parsed and loaded route.
*/
export abstract class Route {
constructor(
/**
* The base definition string.
* @type string
*/
protected base: string
) { }
/**
* Given an incoming route path, returns true if that route matches this route definition.
* @param {string} incoming
* @return boolean
*/
public abstract match(incoming: string): boolean
/**
* Given an incoming route path, parse the parameters and return them.
* @param {string} incoming
* @return RouteParameters
*/
public abstract build_parameters(incoming: string): RouteParameters
/**
* Get the base definition of this route.
*/
public get route() {
return this.base
}
/**
* Split the given route string into its segments by '/'.
* @param {string} incoming
* @return {Array<string>}
*/
public split(incoming: string) {
return incoming.toLowerCase().split('/')
}
/**
* Split the incoming route segment and match each segment with the corresponding segment of the definition.
* @param {string} incoming
* @return ZippedRouteSegments
*/
public zip(incoming: string) {
const incoming_parts: string[] = this.split(incoming)
const base_parts: string[] = this.split(this.base)
const zipped_parts: ZippedRouteSegments = []
if ( incoming_parts.length !== base_parts.length ) {
logger.warn(`Zipping routes with different part lengths! (Base: ${this.base}, Incoming: ${incoming}`)
}
base_parts.forEach((part, index) => {
zipped_parts.push({
base: part,
match: (index >= incoming_parts.length ? undefined : incoming_parts[index]),
})
})
return zipped_parts
}
}