diff --git a/packages/route-pattern/src/index.ts b/packages/route-pattern/src/index.ts index 92d8ee5604d..5162b56c327 100644 --- a/packages/route-pattern/src/index.ts +++ b/packages/route-pattern/src/index.ts @@ -1,4 +1,5 @@ -export { RoutePattern } from './lib/route-pattern.ts' +export { RoutePattern,urlpat } from './lib/route-pattern.ts' +export { createRouter } from './lib/router.ts' export type { RoutePatternOptions, RouteMatch } from './lib/route-pattern.ts' export { MissingParamError, createHrefBuilder } from './lib/href.ts' export type { HrefBuilder, HrefBuilderOptions } from './lib/href.ts' diff --git a/packages/route-pattern/src/lib/route-pattern.ts b/packages/route-pattern/src/lib/route-pattern.ts index 56a9b4a4b5e..d6436685b97 100644 --- a/packages/route-pattern/src/lib/route-pattern.ts +++ b/packages/route-pattern/src/lib/route-pattern.ts @@ -222,3 +222,32 @@ function matchSearch(search: string, constraints: SearchConstraints): boolean { return true } +/** + // Anative URLPattern for pathname-only patterns (variables, wildcards) + //eturns null if not supported or pattern uses enums or optionals or origin/search.... + **/ + + +export function urlpat(input:string|RoutePattern):URLPattern|null{ + let Ctor =(globalThis as any).URLPattern + if (!Ctor) return null; + let src=typeof input==='string' ? input:input.source + let {protocol,hostname,port,pathname,search}=parse(src) + if(protocol||hostname||port|| search) return null + if(!pathname) return new Ctor({pathname: '/'}) + let path=token(pathname) + if (path==null) return null + if(!path.startsWith('/')) path='/'+path + return new Ctor({pathname: path}) +} +function token(tokens: TokenList): string|null{ + let o='' + for (let i=0;i=(req:Request,params:Params

)=>Response | Promise +type Route ={method:Method; pattern:RoutePattern; up?:URLPattern; handler:Handler} + +export function createRouter(){ + const routes:Route[]=[] + const api={ + get

(pattern:P,handler:Handler

){add('GET',pattern,handler);return api}, + all

(pattern:P,handler:Handler

){add('*',pattern,handler);return api}, + async handle(req:Request):Promise{ + const url=new URL(req.url) + const method=(req.method||'GET').toUpperCase() + for(const r of routes){ + if(r.method!=='*'&&r.method!==method) continue + if(r.up&&!r.up.test(url)) continue + const m=r.pattern.match(url) + if(m) return r.handler(req,m.params as any) + } + return undefined + } + } + function add(method:Method, src:string, handler:Handler) { + const rp=new RoutePattern(src) + const up=urlpat(rp)||undefined + routes.push({method,pattern:rp,up,handler}) + } + return api +}