fix: ensure typescript routes are hit most to least specific

This commit is contained in:
Andy Burke 2025-06-25 20:24:51 -07:00
parent 4f68a64a88
commit 1928bfcb5e
6 changed files with 35 additions and 12 deletions

View file

@ -1,7 +1,7 @@
{
"name": "@andyburke/serverus",
"description": "A flexible HTTP server for mixed content. Throw static files, markdown, Typescript and (hopefully, eventually) more into a directory and serverus can serve it up a bit more like old-school CGI.",
"version": "0.4.0",
"version": "0.5.0",
"license": "MIT",
"exports": {
".": "./serverus.ts",
@ -14,7 +14,7 @@
"tasks": {
"lint": "deno lint",
"fmt": "deno fmt",
"test": "DENO_ENV=test DATA_STORAGE_ROOT=./tests/data/$(date --iso-8601=seconds) deno test --allow-env --allow-read --allow-write --allow-net --trace-leaks --fail-fast ./tests/",
"test": "DENO_ENV=test DATA_STORAGE_ROOT=./tests/data/$(date --iso-8601=seconds) SERVERUS_TYPESCRIPT_IMPORT_LOGGING=1 deno test --allow-env --allow-read --allow-write --allow-net --trace-leaks --fail-fast ./tests/",
"build": "deno compile --allow-env --allow-read --allow-write --allow-net --include handlers ./serverus.ts -o serverus",
"serverus": "deno --allow-env --allow-read --allow-write --allow-net ./serverus.ts"
},

1
deno.lock generated
View file

@ -17,6 +17,7 @@
"jsr:@std/fs@^1.0.17": "1.0.18",
"jsr:@std/html@^1.0.4": "1.0.4",
"jsr:@std/http@^1.0.13": "1.0.17",
"jsr:@std/internal@*": "1.0.8",
"jsr:@std/internal@^1.0.6": "1.0.8",
"jsr:@std/internal@^1.0.8": "1.0.8",
"jsr:@std/media-types@^1.1.0": "1.1.0",

View file

@ -96,7 +96,7 @@ export default async function handle_typescript(request: Request): Promise<Respo
const pattern = new URLPattern({ pathname: import_info.route_path });
if (Deno.env.get('SERVERUS_TYPESCRIPT_IMPORT_LOGGING')) {
console.log(`imported: ${import_info.import_path}`);
console.log(`${import_info.route_path} : imported: ${import_info.import_path}`);
}
routes.set(pattern, module);
@ -115,7 +115,7 @@ export default async function handle_typescript(request: Request): Promise<Respo
}
for (const [pattern, handler_module] of routes) {
const match = pattern.exec(request.url);
const match = pattern.exec(request.url.replace(/\/$/, ''));
if (match) {
const method = request.method as keyof ROUTE_HANDLER;
const method_handler: ROUTE_HANDLER_METHOD = (handler_module[method] ?? handler_module.default) as ROUTE_HANDLER_METHOD;

View file

@ -16,7 +16,15 @@ Deno.test({
Deno.env.set('SERVERUS_ROOT', './tests/www');
test_server_info = await get_ephemeral_listen_server();
const response = await fetch(`http://${test_server_info.hostname}:${test_server_info.port}/echo/hi`, {
const echoes: Record<string, string> = {
'': 'echo! .... echo. ................... echo?',
hi: 'hello',
yo: 'yo',
'whoa there': 'whoa there'
};
for await (const key of Object.keys(echoes)) {
const response = await fetch(`http://${test_server_info.hostname}:${test_server_info.port}/echo/${key}`, {
method: 'GET'
});
@ -24,7 +32,12 @@ Deno.test({
asserts.assert(response.ok);
asserts.assert(body);
asserts.assertEquals(body, 'hello');
console.dir({
body,
key
});
asserts.assertEquals(body, echoes[key]);
}
} finally {
Deno.env.delete('SERVERUS_ROOT');
if (test_server_info) {

View file

@ -1,5 +1,6 @@
export function GET(_req: Request, meta: Record<string, any>): Response {
return new Response(meta.params.input ?? '', {
const input = decodeURIComponent(meta.params.input ?? '');
return new Response(input, {
status: 200,
headers: {
'Content-Type': 'text/plain'

8
tests/www/echo/index.ts Normal file
View file

@ -0,0 +1,8 @@
export function GET(_req: Request, _meta: Record<string, any>): Response {
return new Response('echo! .... echo. ................... echo?', {
status: 200,
headers: {
'Content-Type': 'text/plain'
}
});
}