A fast pattern router.
A subset of URLPattern API patterns are supported.
import { router_init, router_set, router_remove } from '@mapl/pattern-router';
import { router_compile_to_matcher } from '@mapl/pattern-router/match';
const router = router_init<(req: Request) => Response | Promise<Response>>();
router_set(router, 'GET', '/', (req) => new Response('Hi'));
router_set(router, 'GET', '/user/:id(\\d+)', (req, params) => new Response(`user id: ${params.id}`));
router_set(router, 'PUT', '/post/:id(\\d+)', (req, params) => updatePost(req, params.id));
router_remove(router, 'GET', '/user/:id(\\d+)');
const matcher = router_compile_to_matcher(router);
matcher.match('GET', '/'); // [(req) => new Response('Hi')]
matcher.match('GET', '/user/001'); // undefined
matcher.match('PUT', '/post/001'); // [(req, params) => updatePost(req, params.id), { id: '001' }]
matcher.match('PUT', '/post/a01'); // undefinedWildcards and unnamed capture groups don't capture. Use named capture groups instead:
router_set(router, 'GET', '/(\\d+)', ...);
// change to
router_set(router, 'GET', '/:id(\\d+)', ...);
// or without automatic group prefixing
router_set(router, 'GET', '{/:id(\\d+)}', ...);Named groups only capture the last matched value in group delimiters with + and * modifier.
router_set(router, 'GET', '/post{/:id}+', ...); // '/post/a/b' -> { id: 'b' }To wrap compiled code pieces with routing code:
import { router_init, router_set, router_remove } from '@mapl/pattern-router';
import { router_compile_to_code } from '@mapl/pattern-router/jit';
const router = router_init<string>();
router_set(router, 'GET', '/', 'return "Home"');
router_set(router, 'POST', '/forum/:forum+', 'return "Posting to " + matchedResult.groups.forum'); // access matched params
const match = (0, eval)(`(method, path) => {${router_compile_to_code(router, 'matchedResult', 'path', 'method')}}`);
match('GET', '/'); // "Home"
match('GET', '/about'); // undefined
match('POST', '/forum/@mapl/pattern-router'); // "Posting to @mapl/pattern-router"To infer parameters types of a pattern:
import type { InferParams } from '@mapl/pattern-router/tree/utils';
type T = InferParams<'/:id'>; // { id: string }
type T = InferParams<'/user/:id?'>; // { id: string | undefined }
type T = InferParams<'/book{s/:id}?'>; // { id: string | undefined }This library requires RegExp.escape() and duplicate named capture groups in different disjunction feature support.