Skip to content

Commit d1c04c0

Browse files
feat(deno): migrate mvt/ Bun → Deno (Class A, standards#253 longtail) (#53)
## Summary Class A — pure-Deno port. The only Bun-specific code was `mvt/src/server.js` (35 lines, `Bun.serve` + `Bun.file` + `Bun.env`) plus the `mvt/package.json` Bun-runner scripts. ## Changes 1. **`mvt/deno.json`** (new) — Deno-native tasks for `test`/`test:watch`/`serve`/`dev` + fmt/lint config. 2. **`mvt/src/server.js`** — Bun → Deno API port: - `Bun.env.PORT` → `Deno.env.get("PORT")` - `Bun.serve({port, fetch})` → `Deno.serve({port}, fetch)` - `Bun.file(url).exists() + new Response(file)` → `await Deno.readFile(url)` with `Deno.errors.NotFound` catch (idiomatic Deno file-serve) 3. **`mvt/package.json`** (deleted) — was Bun-only, no deps; just `bun test` + `bun src/server.js` scripts. Tests use `node:test` + `node:assert/strict`, both supported by Deno natively without flags — no test-file changes needed. The path-traversal guard (`fileUrl.pathname.startsWith(root.pathname)`) is preserved unchanged. ## Test plan - [ ] `deno task test` runs the public-goods kernel test suite (uses `node:test` which Deno supports natively) - [ ] `deno task serve` starts the static server on port 5173 (default) or `$PORT` - [ ] `curl http://localhost:5173/` returns the UI index.html - [ ] `curl http://localhost:5173/../etc/passwd` returns 403 (path-traversal guard intact) Per per-repo follow-up tracker for standards#253 (campaign closed 2026-05-31, longtail tracked in `project_estate_npm_to_deno_2026_05_28.md`). Refs hyperpolymath/standards#253. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 6905e26 commit d1c04c0

3 files changed

Lines changed: 38 additions & 25 deletions

File tree

mvt/deno.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"$schema": "https://deno.land/x/deno/cli/schemas/config-file.v1.json",
3+
"name": "@hyperpolymath/econosphere-mvt",
4+
"version": "0.1.0",
5+
"license": "MPL-2.0",
6+
"tasks": {
7+
"test": "deno test --allow-read tests/kernel/",
8+
"test:watch": "deno test --watch --allow-read tests/kernel/",
9+
"serve": "deno run --allow-net --allow-read --allow-env src/server.js",
10+
"dev": "deno run --watch --allow-net --allow-read --allow-env src/server.js"
11+
},
12+
"fmt": {
13+
"useTabs": false,
14+
"lineWidth": 100,
15+
"indentWidth": 2,
16+
"singleQuote": false
17+
},
18+
"lint": {
19+
"rules": {
20+
"tags": ["recommended"]
21+
}
22+
}
23+
}

mvt/package.json

Lines changed: 0 additions & 10 deletions
This file was deleted.

mvt/src/server.js

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const port = Number(Bun.env.PORT ?? 5173);
1+
const port = Number(Deno.env.get("PORT") ?? 5173);
22
const root = new URL("../", import.meta.url);
33

44
const contentTypes = {
@@ -9,26 +9,26 @@ const contentTypes = {
99
".md": "text/markdown; charset=utf-8"
1010
};
1111

12-
Bun.serve({
13-
port,
14-
async fetch(request) {
15-
const url = new URL(request.url);
16-
const pathname = url.pathname === "/" ? "/src/ui/index.html" : url.pathname;
17-
const fileUrl = new URL(`.${pathname}`, root);
12+
Deno.serve({ port }, async (request) => {
13+
const url = new URL(request.url);
14+
const pathname = url.pathname === "/" ? "/src/ui/index.html" : url.pathname;
15+
const fileUrl = new URL(`.${pathname}`, root);
1816

19-
if (!fileUrl.pathname.startsWith(root.pathname)) {
20-
return new Response("Forbidden", { status: 403 });
21-
}
22-
23-
const file = Bun.file(fileUrl);
24-
if (!(await file.exists())) {
25-
return new Response("Not found", { status: 404 });
26-
}
17+
if (!fileUrl.pathname.startsWith(root.pathname)) {
18+
return new Response("Forbidden", { status: 403 });
19+
}
2720

21+
try {
22+
const file = await Deno.readFile(fileUrl);
2823
const extension = fileUrl.pathname.slice(fileUrl.pathname.lastIndexOf("."));
2924
return new Response(file, {
3025
headers: { "content-type": contentTypes[extension] ?? "application/octet-stream" }
3126
});
27+
} catch (err) {
28+
if (err instanceof Deno.errors.NotFound) {
29+
return new Response("Not found", { status: 404 });
30+
}
31+
throw err;
3232
}
3333
});
3434

0 commit comments

Comments
 (0)