diff --git a/src/bun.js/api/server.zig b/src/bun.js/api/server.zig index db0ff33a2f..5214d1fad0 100644 --- a/src/bun.js/api/server.zig +++ b/src/bun.js/api/server.zig @@ -1210,6 +1210,19 @@ pub const ServerConfig = struct { } }; + fn getRoutesObject(global: *JSC.JSGlobalObject, arg: JSC.JSValue) bun.JSError!?JSC.JSValue { + inline for (.{ "routes", "static" }) |key| { + if (try arg.get(global, key)) |routes| { + // https://github.com/oven-sh/bun/issues/17568 + if (routes.isArray()) { + return null; + } + return routes; + } + } + return null; + } + pub const FromJSOptions = struct { allow_bake_config: bool = true, is_fetch_required: bool = true, @@ -1309,7 +1322,7 @@ pub const ServerConfig = struct { } if (global.hasException()) return error.JSError; - if ((try arg.get(global, "routes")) orelse (try arg.get(global, "static"))) |static| { + if (try getRoutesObject(global, arg)) |static| { if (!static.isObject()) { return global.throwInvalidArguments( \\Bun.serve() expects 'routes' to be an object shaped like: diff --git a/test/bun.lock b/test/bun.lock index 3ae0e6ec8c..978fa00516 100644 --- a/test/bun.lock +++ b/test/bun.lock @@ -33,6 +33,7 @@ "fast-glob": "3.3.1", "filenamify": "6.0.0", "happy-dom": "17.0.3", + "hono": "4.7.2", "http2-wrapper": "2.2.1", "https-proxy-agent": "7.0.5", "iconv-lite": "0.6.3", @@ -1248,6 +1249,8 @@ "highlight.js": ["highlight.js@10.7.3", "", {}, "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A=="], + "hono": ["hono@4.7.2", "", {}, "sha512-8V5XxoOF6SI12jkHkzX/6aLBMU5GEF5g387EjVSQipS0DlxWgWGSMeEayY3CRBjtTUQYwLHx9JYouWqKzy2Vng=="], + "html-encoding-sniffer": ["html-encoding-sniffer@4.0.0", "", { "dependencies": { "whatwg-encoding": "^3.1.1" } }, "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ=="], "http-cache-semantics": ["http-cache-semantics@4.1.1", "", {}, "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ=="], diff --git a/test/js/third_party/hono/hello-world-fixture.test.ts b/test/js/third_party/hono/hello-world-fixture.test.ts new file mode 100644 index 0000000000..e38c32be2b --- /dev/null +++ b/test/js/third_party/hono/hello-world-fixture.test.ts @@ -0,0 +1,39 @@ +import { expect, test } from "bun:test"; +import { bunEnv, bunExe } from "harness"; +import { join } from "path"; + +test("Hono app export bug", async () => { + await using process = Bun.spawn({ + cmd: [bunExe(), join(import.meta.dir, "hello-world.fixture.ts")], + env: { + ...bunEnv, + "BUN_PORT": "0", + }, + stdout: "pipe", + stderr: "inherit", + }); + + // Wait for server to start and get its URL + const reader = process.stdout.getReader(); + let serverUrl = ""; + while (!serverUrl && !process.exitCode) { + const { value, done } = await reader.read(); + if (done) break; + const output = new TextDecoder().decode(value); + const match = output.match(/http:\/\/[^:]+:(\d+)/); + if (match) { + serverUrl = match[0]; + break; + } + } + + expect(serverUrl).toBeTruthy(); + + // Make a request to verify the server works + const response = await fetch(serverUrl); + expect(response.status).toBe(200); + expect(await response.text()).toBe('The message is "Hono is cool!"'); + + // Kill the server process + process.kill(); +}); diff --git a/test/js/third_party/hono/hello-world.fixture.ts b/test/js/third_party/hono/hello-world.fixture.ts new file mode 100644 index 0000000000..3838002c48 --- /dev/null +++ b/test/js/third_party/hono/hello-world.fixture.ts @@ -0,0 +1,19 @@ +import { Hono } from "hono"; + +type Variables = { + message: string; +}; + +const app = new Hono<{ Variables: Variables }>(); + +app.use(async (c, next) => { + c.set("message", "Hono is cool!"); + await next(); +}); + +app.get("/", c => { + const message = c.get("message"); + return c.text(`The message is "${message}"`); +}); + +export default app; diff --git a/test/js/third_party/hono/hello-world.test.ts b/test/js/third_party/hono/hello-world.test.ts new file mode 100644 index 0000000000..ae390dbd0e --- /dev/null +++ b/test/js/third_party/hono/hello-world.test.ts @@ -0,0 +1,18 @@ +import { describe, expect, it } from "bun:test"; +import { Hono } from "hono"; + +describe("Hono Hello World", () => { + it("should respond with hello world", async () => { + const app = new Hono(); + app.get("/", c => c.text("Hello World!")); + + using server = Bun.serve({ + fetch: app.fetch, + port: 0, + }); + + const response = await fetch(server.url); + expect(response.status).toBe(200); + expect(await response.text()).toBe("Hello World!"); + }); +}); diff --git a/test/package.json b/test/package.json index 0c373dceb8..55ffcfb3c9 100644 --- a/test/package.json +++ b/test/package.json @@ -38,6 +38,7 @@ "fast-glob": "3.3.1", "filenamify": "6.0.0", "happy-dom": "17.0.3", + "hono": "4.7.2", "http2-wrapper": "2.2.1", "https-proxy-agent": "7.0.5", "iconv-lite": "0.6.3",