Problem
Routes registered via app.route() / app.get() are matched in registration order, not by specificity. This means if a user registers a catch-all before a specific route, the specific route is silently shadowed:
app.route("/blog/[...rest]", handlerA); // registered first → matched first
app.route("/blog/[id]", handlerB); // NEVER reached
File-system routes are protected from this by sortRoutePaths() in fs_crawl.ts, which sorts before insertion. But programmatic routes bypass sorting entirely — commands go into this.#commands in registration order → applyCommandsInner processes them in that order → router.add() inserts them in that order → UrlPatternRouter matches first-wins.
Steps to reproduce
const app = new App();
app.route("/api/[...rest]", () => new Response("catch-all"));
app.route("/api/health", () => new Response("health"));
// GET /api/health → returns "catch-all" (WRONG)
Proposed fix
Apply the same sortRoutePaths sorting to programmatic routes. In applyCommandsInner, sort the Route and Handler command groups before processing, or sort #dynamicArr in UrlPatternRouter.add() when a new pattern is inserted.
The sorting criteria should match sortRoutePaths semantics: static segments > dynamic params [id] > catch-all [...rest].
Problem
Routes registered via
app.route()/app.get()are matched in registration order, not by specificity. This means if a user registers a catch-all before a specific route, the specific route is silently shadowed:File-system routes are protected from this by
sortRoutePaths()infs_crawl.ts, which sorts before insertion. But programmatic routes bypass sorting entirely — commands go intothis.#commandsin registration order →applyCommandsInnerprocesses them in that order →router.add()inserts them in that order →UrlPatternRoutermatches first-wins.Steps to reproduce
Proposed fix
Apply the same
sortRoutePathssorting to programmatic routes. InapplyCommandsInner, sort theRouteandHandlercommand groups before processing, or sort#dynamicArrinUrlPatternRouter.add()when a new pattern is inserted.The sorting criteria should match
sortRoutePathssemantics: static segments > dynamic params[id]> catch-all[...rest].