From c92ef0688b40da94d13782bbf1e262fa2e51184e Mon Sep 17 00:00:00 2001 From: Andy Burke Date: Wed, 25 Jun 2025 17:06:05 -0700 Subject: [PATCH] feature: SERVERUS_ROOT environment variable --- README.md | 5 ++++ deno.json | 2 +- server.ts | 13 ++++++++++ tests/01_get_static_file.test.ts | 1 + tests/06_test_overriding_root.test.ts | 35 +++++++++++++++++++++++++++ 5 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 tests/06_test_overriding_root.test.ts diff --git a/README.md b/README.md index 51b116f..9973c60 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,11 @@ The default handlers are: You just start serverus in a directory (or specify a root) and it tells you where it's listening. +## Environment Variables + + - `SERVERUS_ROOT`: set the root, aka --root on the command line + - `SERVERUS_HANDLERS`: a list of ;-separated directories to look for handlers in + ### Typescript Handling These types and interface define the default serverus Typescript handler's expected diff --git a/deno.json b/deno.json index e5b7b88..eb034a6 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.2.0", + "version": "0.3.0", "license": "MIT", "exports": { ".": "./serverus.ts", diff --git a/server.ts b/server.ts index 3cf7648..5a59dd3 100644 --- a/server.ts +++ b/server.ts @@ -31,6 +31,7 @@ export type SERVER_OPTIONS = { hostname?: string; port?: number; logging?: boolean | LOGGER; + root?: string; watch?: boolean; }; @@ -78,6 +79,7 @@ export class SERVER { private controller: AbortController | undefined; private shutdown_binding: (() => void) | undefined; private handlers: HANDLER_MODULE[]; + private original_directory: string | undefined; /** * @param {SERVER_OPTIONS} (optional) options to configure the server @@ -100,6 +102,12 @@ export class SERVER { * @returns {Promise} */ public async start(): Promise { + const root = this.options.root ?? Deno.env.get('SERVERUS_ROOT'); + if (typeof root === 'string') { + this.original_directory = Deno.cwd(); + Deno.chdir(path.resolve(root)); + } + this.controller = new AbortController(); const { signal } = this.controller; @@ -197,9 +205,14 @@ export class SERVER { } } + if (this.original_directory) { + Deno.chdir(this.original_directory); + } + this.controller = undefined; this.server = undefined; this.shutdown_binding = undefined; + this.original_directory = undefined; for (const handler_module of this.handlers) { if (typeof handler_module.unload === 'function') { diff --git a/tests/01_get_static_file.test.ts b/tests/01_get_static_file.test.ts index c1babef..53812e3 100644 --- a/tests/01_get_static_file.test.ts +++ b/tests/01_get_static_file.test.ts @@ -25,6 +25,7 @@ Deno.test({ asserts.assert(response.ok); asserts.assert(body); + asserts.assertEquals(body, 'this is a test\n'); } finally { Deno.chdir(cwd); if (test_server_info) { diff --git a/tests/06_test_overriding_root.test.ts b/tests/06_test_overriding_root.test.ts new file mode 100644 index 0000000..45b0645 --- /dev/null +++ b/tests/06_test_overriding_root.test.ts @@ -0,0 +1,35 @@ +import * as asserts from '@std/assert'; +import { EPHEMERAL_SERVER, get_ephemeral_listen_server } from './helpers.ts'; + +Deno.test({ + name: 'override the default root', + permissions: { + env: true, + read: true, + write: true, + net: true + }, + fn: async () => { + let test_server_info: EPHEMERAL_SERVER | null = null; + + try { + 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}/test.txt`, { + method: 'GET' + }); + + const body = await response.text(); + + asserts.assert(response.ok); + asserts.assert(body); + asserts.assertEquals(body, 'this is a test\n'); + } finally { + Deno.env.delete('SERVERUS_ROOT'); + if (test_server_info) { + await test_server_info?.server?.stop(); + } + } + } +});