diff --git a/apps/commandboard-api/src/contract.test.ts b/apps/commandboard-api/src/contract.test.ts index b06c298..489ad69 100644 --- a/apps/commandboard-api/src/contract.test.ts +++ b/apps/commandboard-api/src/contract.test.ts @@ -1,6 +1,6 @@ import type { Server } from "node:http"; import { afterAll, beforeAll, describe, expect, it } from "vitest"; -import { createCommandBoardServer } from "./index.js"; +import { createCommandBoardServer, readPort } from "./index.js"; let server: Server; let baseUrl: string; @@ -22,6 +22,13 @@ afterAll(async () => { }); describe("CommandBoard API contracts", () => { + it("falls back when PORT is invalid", () => { + expect(readPort("not-a-port", 4010)).toBe(4010); + expect(readPort("0", 4010)).toBe(4010); + expect(readPort("65536", 4010)).toBe(4010); + expect(readPort("4020", 4010)).toBe(4020); + }); + it("exposes root API index", async () => { const response = await fetch(`${baseUrl}/`); const body = await response.json() as { ok: boolean; service: string; endpoints: string[] }; diff --git a/apps/commandboard-api/src/index.ts b/apps/commandboard-api/src/index.ts index 3596052..5d685cf 100644 --- a/apps/commandboard-api/src/index.ts +++ b/apps/commandboard-api/src/index.ts @@ -377,7 +377,7 @@ function formattedDiscoverMatch(format: "rss" | "opml" | "atom" | "json-feed", e } } -export function startCommandBoardServer(port = Number(process.env.PORT ?? 4010)) { +export function startCommandBoardServer(port = readPort(process.env.PORT, 4010)) { const server = createCommandBoardServer(); server.listen(port, () => { console.log(`CommandBoard.run API listening on http://localhost:${port}`); @@ -385,6 +385,11 @@ export function startCommandBoardServer(port = Number(process.env.PORT ?? 4010)) return server; } +export function readPort(value: string | undefined, fallback: number) { + const parsed = Number(value ?? fallback); + return Number.isInteger(parsed) && parsed > 0 && parsed <= 65535 ? parsed : fallback; +} + if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) { startCommandBoardServer(); }