From dd2e98ccd9cecf2a9b57ccf1ce5e8cec3bb22423 Mon Sep 17 00:00:00 2001 From: Andy Burke Date: Sun, 22 Jun 2025 13:36:44 -0700 Subject: [PATCH 01/10] fix: try to address issues running serverus from jsr.io --- deno.json | 2 +- server.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/deno.json b/deno.json index 1cec2b7..c6db87d 100644 --- a/deno.json +++ b/deno.json @@ -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.0.4", + "version": "0.0.5", "license": "MIT", "exports": { ".": "./serverus.ts", diff --git a/server.ts b/server.ts index aa25279..c3bfcd5 100644 --- a/server.ts +++ b/server.ts @@ -7,7 +7,7 @@ import * as colors from '@std/fmt/colors'; import * as fs from '@std/fs'; import * as path from '@std/path'; -const DEFAULT_HANDLER_DIRECTORIES = [path.resolve(path.join(path.dirname(path.fromFileUrl(import.meta.url)), 'handlers'))]; +const DEFAULT_HANDLER_DIRECTORIES = [path.join(import.meta.dirname ?? '.', 'handlers')]; /** A `HANDLER` must take a `Request` and return a `Response` if it can handle it. */ type HANDLER = (request: Request) => Promise | Response | null | undefined; From c1ccfa70cf334a6ade8388f124387514731ce17d Mon Sep 17 00:00:00 2001 From: Andy Burke Date: Sun, 22 Jun 2025 13:45:02 -0700 Subject: [PATCH 02/10] fix: try to use fs.walk to avoid issues with jsr.io --- server.ts | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/server.ts b/server.ts index c3bfcd5..48982fa 100644 --- a/server.ts +++ b/server.ts @@ -6,6 +6,7 @@ import * as colors from '@std/fmt/colors'; import * as fs from '@std/fs'; import * as path from '@std/path'; +import { walk } from '@std/fs'; const DEFAULT_HANDLER_DIRECTORIES = [path.join(import.meta.dirname ?? '.', 'handlers')]; @@ -108,16 +109,22 @@ export class SERVER { DEFAULT_HANDLER_DIRECTORIES; for (const handler_directory of HANDLERS_DIRECTORIES) { - const resolved_handler_directory_glob = path.resolve(path.join(handler_directory, '*.ts')); - for await (const globbed_record of fs.expandGlob(resolved_handler_directory_glob)) { - if (!globbed_record.isFile) { + const root_directory = path.resolve(handler_directory); + + for await ( + const entry of walk(root_directory, { + exts: ['.ts'], + skip: [/\.test\.ts$/] + }) + ) { + if (!entry.isFile) { continue; } - const import_path = new URL('file://' + globbed_record.path, import.meta.url).toString(); + const import_path = new URL('file://' + entry.path, import.meta.url).toString(); const handler_module: HANDLER_MODULE = await import(import_path); if (typeof handler_module.default !== 'function') { - console.warn(`Could not load handler, no default exported function: ${globbed_record.path}`); + console.warn(`Could not load handler, no default exported function: ${entry.path}`); continue; } From e1d914a28bf61cc805c61ebd75b39dbda28d7870 Mon Sep 17 00:00:00 2001 From: Andy Burke Date: Sun, 22 Jun 2025 13:46:04 -0700 Subject: [PATCH 03/10] chore: increment version --- deno.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deno.json b/deno.json index c6db87d..1c3ffc5 100644 --- a/deno.json +++ b/deno.json @@ -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.0.5", + "version": "0.0.6", "license": "MIT", "exports": { ".": "./serverus.ts", From 9bbece2601866d994f7c747ed6c06d7c99ddfa8e Mon Sep 17 00:00:00 2001 From: Andy Burke Date: Sun, 22 Jun 2025 13:51:40 -0700 Subject: [PATCH 04/10] fix: let's try yet another way to try to do this --- deno.json | 2 +- server.ts | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/deno.json b/deno.json index 1c3ffc5..c5f8a39 100644 --- a/deno.json +++ b/deno.json @@ -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.0.6", + "version": "0.0.7", "license": "MIT", "exports": { ".": "./serverus.ts", diff --git a/server.ts b/server.ts index 48982fa..7445356 100644 --- a/server.ts +++ b/server.ts @@ -121,8 +121,7 @@ export class SERVER { continue; } - const import_path = new URL('file://' + entry.path, import.meta.url).toString(); - const handler_module: HANDLER_MODULE = await import(import_path); + const handler_module: HANDLER_MODULE = await import(entry.path); if (typeof handler_module.default !== 'function') { console.warn(`Could not load handler, no default exported function: ${entry.path}`); continue; From b3a399cf7a345e05481980eeeefbd410def095b0 Mon Sep 17 00:00:00 2001 From: Andy Burke Date: Sun, 22 Jun 2025 14:10:37 -0700 Subject: [PATCH 05/10] fix: let's just force the handlers dir to have an index --- deno.json | 2 +- server.ts | 36 +++++++++++++++++++++--------------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/deno.json b/deno.json index c5f8a39..b3e304d 100644 --- a/deno.json +++ b/deno.json @@ -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.0.7", + "version": "0.0.8", "license": "MIT", "exports": { ".": "./serverus.ts", diff --git a/server.ts b/server.ts index 7445356..8a2e358 100644 --- a/server.ts +++ b/server.ts @@ -110,24 +110,30 @@ export class SERVER { for (const handler_directory of HANDLERS_DIRECTORIES) { const root_directory = path.resolve(handler_directory); + const index_file = path.join(root_directory, 'index.ts'); - for await ( - const entry of walk(root_directory, { - exts: ['.ts'], - skip: [/\.test\.ts$/] - }) - ) { - if (!entry.isFile) { + try { + const handlers_index = await import(index_file); + console.dir({ + root_directory, + index_file, + handlers_index + }); + for (const handler_name of Object.keys(handlers_index.default)) { + const handler_module: HANDLER_MODULE = handlers_index.default[handler_name]; + if (typeof handler_module?.default !== 'function') { + console.warn(`Could not load handler "${handler_name}" - no default exported function`); + continue; + } + + this.handlers.push(handler_module); + } + } catch (error) { + if (error instanceof Deno.errors.NotFound) { + console.warn(`Could not load handler index from: ${index_file}`); continue; } - - const handler_module: HANDLER_MODULE = await import(entry.path); - if (typeof handler_module.default !== 'function') { - console.warn(`Could not load handler, no default exported function: ${entry.path}`); - continue; - } - - this.handlers.push(handler_module); + throw error; } } From c45d0a46586065d7b90cb65cd36a59ddbaa083f4 Mon Sep 17 00:00:00 2001 From: Andy Burke Date: Sun, 22 Jun 2025 14:11:11 -0700 Subject: [PATCH 06/10] fix: add handler indexes --- handlers/index.ts | 9 +++++++++ tests/handlers/index.ts | 5 +++++ 2 files changed, 14 insertions(+) create mode 100644 handlers/index.ts create mode 100644 tests/handlers/index.ts diff --git a/handlers/index.ts b/handlers/index.ts new file mode 100644 index 0000000..410f0fb --- /dev/null +++ b/handlers/index.ts @@ -0,0 +1,9 @@ +import * as markdown from './markdown.ts'; +import * as static_files from './static.ts'; +import * as typescript from './typescript.ts'; + +export default { + markdown, + static: static_files, + typescript +}; diff --git a/tests/handlers/index.ts b/tests/handlers/index.ts new file mode 100644 index 0000000..f04292b --- /dev/null +++ b/tests/handlers/index.ts @@ -0,0 +1,5 @@ +import * as foo from './foo.ts'; + +export default { + foo +}; From ea3f379b1bd76cbc0f0832d282c75c9ef2408522 Mon Sep 17 00:00:00 2001 From: Andy Burke Date: Sun, 22 Jun 2025 14:14:59 -0700 Subject: [PATCH 07/10] fix: let's just have some debugging --- deno.json | 2 +- server.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/deno.json b/deno.json index b3e304d..31c6025 100644 --- a/deno.json +++ b/deno.json @@ -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.0.8", + "version": "0.0.9", "license": "MIT", "exports": { ".": "./serverus.ts", diff --git a/server.ts b/server.ts index 8a2e358..b4ce180 100644 --- a/server.ts +++ b/server.ts @@ -4,12 +4,12 @@ */ import * as colors from '@std/fmt/colors'; -import * as fs from '@std/fs'; import * as path from '@std/path'; -import { walk } from '@std/fs'; const DEFAULT_HANDLER_DIRECTORIES = [path.join(import.meta.dirname ?? '.', 'handlers')]; - +console.dir({ + meta: import.meta +}); /** A `HANDLER` must take a `Request` and return a `Response` if it can handle it. */ type HANDLER = (request: Request) => Promise | Response | null | undefined; From 3fc77f009dc0de87c1f2ce2bf4241344349e47bd Mon Sep 17 00:00:00 2001 From: Andy Burke Date: Sun, 22 Jun 2025 14:19:16 -0700 Subject: [PATCH 08/10] fix: debugging this problem --- deno.json | 2 +- server.ts | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/deno.json b/deno.json index 31c6025..535aca2 100644 --- a/deno.json +++ b/deno.json @@ -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.0.9", + "version": "0.0.10", "license": "MIT", "exports": { ".": "./serverus.ts", diff --git a/server.ts b/server.ts index b4ce180..0e4a3be 100644 --- a/server.ts +++ b/server.ts @@ -6,9 +6,10 @@ import * as colors from '@std/fmt/colors'; import * as path from '@std/path'; -const DEFAULT_HANDLER_DIRECTORIES = [path.join(import.meta.dirname ?? '.', 'handlers')]; +const DEFAULT_HANDLER_DIRECTORIES = [import.meta.resolve('./handlers')]; console.dir({ - meta: import.meta + meta: import.meta, + DEFAULT_HANDLER_DIRECTORIES }); /** A `HANDLER` must take a `Request` and return a `Response` if it can handle it. */ type HANDLER = (request: Request) => Promise | Response | null | undefined; @@ -109,13 +110,11 @@ export class SERVER { DEFAULT_HANDLER_DIRECTORIES; for (const handler_directory of HANDLERS_DIRECTORIES) { - const root_directory = path.resolve(handler_directory); - const index_file = path.join(root_directory, 'index.ts'); + const index_file = path.join(handler_directory, 'index.ts'); try { const handlers_index = await import(index_file); console.dir({ - root_directory, index_file, handlers_index }); From 5d25afc329ae402380759f4e47a85cb89297f9f7 Mon Sep 17 00:00:00 2001 From: Andy Burke Date: Sun, 22 Jun 2025 14:22:23 -0700 Subject: [PATCH 09/10] fix: remove debugging for path issues fix: resolve handlers via an index --- deno.json | 2 +- server.ts | 10 ++-------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/deno.json b/deno.json index 535aca2..f845be0 100644 --- a/deno.json +++ b/deno.json @@ -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.0.10", + "version": "0.0.11", "license": "MIT", "exports": { ".": "./serverus.ts", diff --git a/server.ts b/server.ts index 0e4a3be..648a951 100644 --- a/server.ts +++ b/server.ts @@ -7,10 +7,7 @@ import * as colors from '@std/fmt/colors'; import * as path from '@std/path'; const DEFAULT_HANDLER_DIRECTORIES = [import.meta.resolve('./handlers')]; -console.dir({ - meta: import.meta, - DEFAULT_HANDLER_DIRECTORIES -}); + /** A `HANDLER` must take a `Request` and return a `Response` if it can handle it. */ type HANDLER = (request: Request) => Promise | Response | null | undefined; @@ -114,10 +111,7 @@ export class SERVER { try { const handlers_index = await import(index_file); - console.dir({ - index_file, - handlers_index - }); + for (const handler_name of Object.keys(handlers_index.default)) { const handler_module: HANDLER_MODULE = handlers_index.default[handler_name]; if (typeof handler_module?.default !== 'function') { From 5ee654f28033b03a3227dfc0f1226b6b5f698a25 Mon Sep 17 00:00:00 2001 From: Andy Burke Date: Tue, 24 Jun 2025 12:06:09 -0700 Subject: [PATCH 10/10] fix: try to better handle directories and loading handlers both locally and remotely --- deno.json | 2 +- server.ts | 9 ++++++--- tests/04_test_overriding_handlers.test.ts | 7 +++---- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/deno.json b/deno.json index f845be0..656b882 100644 --- a/deno.json +++ b/deno.json @@ -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.0.11", + "version": "0.0.12", "license": "MIT", "exports": { ".": "./serverus.ts", diff --git a/server.ts b/server.ts index 648a951..a20ac66 100644 --- a/server.ts +++ b/server.ts @@ -102,9 +102,12 @@ export class SERVER { this.controller = new AbortController(); const { signal } = this.controller; - const HANDLERS_DIRECTORIES: string[] = - Deno.env.get('SERVERUS_HANDLERS')?.split(/[;:]/g)?.filter((dir) => dir.length > 0)?.map((dir) => path.resolve(dir)) ?? - DEFAULT_HANDLER_DIRECTORIES; + const HANDLERS_DIRECTORIES: string[] = Deno.env.get('SERVERUS_HANDLERS') + ?.split(/[;]/g) + ?.filter((dir) => dir.length > 0) + ?.map((dir) => { + return dir.includes('://') ? dir : path.resolve(dir); + }) ?? DEFAULT_HANDLER_DIRECTORIES; for (const handler_directory of HANDLERS_DIRECTORIES) { const index_file = path.join(handler_directory, 'index.ts'); diff --git a/tests/04_test_overriding_handlers.test.ts b/tests/04_test_overriding_handlers.test.ts index 90b7a04..43c806e 100644 --- a/tests/04_test_overriding_handlers.test.ts +++ b/tests/04_test_overriding_handlers.test.ts @@ -16,13 +16,12 @@ Deno.test({ const old_handlers: string | undefined = Deno.env.get('SERVERUS_HANDLERS'); try { - Deno.chdir('./tests/www'); Deno.env.set( 'SERVERUS_HANDLERS', - `${path.join(path.dirname(path.resolve(path.fromFileUrl(import.meta.url))), 'handlers')}${ - old_handlers ? (';' + old_handlers) : '' - }` + `${import.meta.resolve('./handlers')}${old_handlers ? (';' + old_handlers) : ''}` ); + + Deno.chdir('./tests/www'); test_server_info = await get_ephemeral_listen_server(); const response = await fetch(`http://${test_server_info.hostname}:${test_server_info.port}/echo/hello_world.foo`, {