Skip to content

Instantly share code, notes, and snippets.

@skunkworker
Created August 10, 2019 03:56
Show Gist options
  • Save skunkworker/0b11fcde7a8a2c46746ba413742cf04b to your computer and use it in GitHub Desktop.
Save skunkworker/0b11fcde7a8a2c46746ba413742cf04b to your computer and use it in GitHub Desktop.
basic typescript route matcher
export interface StringTMap<T> { [key: string]: T; };
export interface NumberTMap<T> { [key: number]: T; };
export interface StringAnyMap extends StringTMap<any> {};
export interface NumberAnyMap extends NumberTMap<any> {};
export interface StringStringMap extends StringTMap<string> {};
export interface NumberStringMap extends NumberTMap<string> {};
export interface StringNumberMap extends StringTMap<number> {};
export interface NumberNumberMap extends NumberTMap<number> {};
export interface StringBooleanMap extends StringTMap<boolean> {};
export interface NumberBooleanMap extends NumberTMap<boolean> {};
export namespace RouteMatcher {
// inspired from https://stackoverflow.com/questions/37737499/simple-javascript-url-routing-regex/40739605#40739605
export class RouteMatcher {
routes: Array<StringTMap<any>>;
constructor(initialRoutes: StringTMap<any>) {
// parse and recreate config for use
this.routes = Object.keys(initialRoutes)
// sort longest path first
.sort(function(a,b){ return b.length - a.length; })
// convert into more usable format
.map(function(path) {
// clean up the formats from rails
var cleanedPath = path.replace("(.:format)","")
return {
// create regex
path: new RegExp("^" + cleanedPath.replace(/:[^\s/]+/g, '([\\w-]+)') + "$"),
module: initialRoutes[path]
};
});
// == [{ path: /^\/about\/team\//:([\w-]+)$/, module: "aboutMember" }, ...]
}
matchRoute(url: string) {
let routes = this.routes
// loop through all routes, longest first
for (var i = 0, l = routes.length; i < l; i++) {
// parse if possible
var found = url.match(routes[i].path);
if (found) { // parsed successfully
// console.log("module: " + routes[i].module); // module to load
// console.log("args:", found.slice(1)); // arguments for module
return {module: routes[i].module, args: found.slice(1)}
break; // ignore the rest of the paths
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment