Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions bin/cli/commands/dashboard.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,22 @@ export async function runDashboardCommand(opts = {}) {
return 0;
}

/**
* Resolve the command and args to open a URL in the default browser
* for a given platform. Exported for testing — callers should use openFallback().
* @param {"darwin"|"win32"|string} platform
* @param {string} url
* @returns {{ cmd: string, args: string[] }}
*/
export function resolveOpenCommand(platform, url) {
if (platform === "darwin") return { cmd: "open", args: [url] };
if (platform === "win32") return { cmd: "rundll32", args: ["url.dll,FileProtocolHandler", url] };
return { cmd: "xdg-open", args: [url] };
}

function openFallback(url) {
return new Promise((resolve) => {
const { platform } = process;
let cmd, args;

if (platform === "darwin") {
cmd = "open";
args = [url];
} else if (platform === "win32") {
cmd = "cmd";
args = ["/c", "start", "", url];
} else {
cmd = "xdg-open";
args = [url];
}

const { cmd, args } = resolveOpenCommand(process.platform, url);
execFile(cmd, args, { stdio: "ignore" }, () => resolve());
});
}
1 change: 1 addition & 0 deletions changelog.d/fixes/7844-dashboard-no-cmd-fallback.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- **fix(cli):** Windows `omniroute dashboard` browser fallback uses `rundll32` instead of `cmd.exe` to open the dashboard URL, avoiding an unnecessary shell spawn ([#7844](https://github.com/diegosouzapw/OmniRoute/pull/7842))
35 changes: 35 additions & 0 deletions tests/unit/cli-dashboard-open-fallback.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import test from "node:test";
import assert from "node:assert/strict";
import { resolveOpenCommand } from "../../bin/cli/commands/dashboard.mjs";

test("openFallback: darwin uses 'open' command", () => {
const { cmd, args } = resolveOpenCommand("darwin", "http://localhost:20128");
assert.equal(cmd, "open");
assert.deepEqual(args, ["http://localhost:20128"]);
});

test("openFallback: win32 uses 'rundll32 url.dll,FileProtocolHandler' instead of cmd.exe", () => {
const { cmd, args } = resolveOpenCommand("win32", "http://localhost:20128");
assert.equal(cmd, "rundll32");
assert.deepEqual(args, ["url.dll,FileProtocolHandler", "http://localhost:20128"]);
assert.notEqual(cmd, "cmd");
});

test("openFallback: linux/other uses 'xdg-open' command", () => {
const { cmd, args } = resolveOpenCommand("linux", "http://localhost:20128");
assert.equal(cmd, "xdg-open");
assert.deepEqual(args, ["http://localhost:20128"]);
});

test("openFallback: unknown platform falls back to xdg-open", () => {
const { cmd, args } = resolveOpenCommand("aix", "http://localhost:20128");
assert.equal(cmd, "xdg-open");
assert.deepEqual(args, ["http://localhost:20128"]);
});

test("openFallback: URL with special characters is passed through verbatim", () => {
const url = "http://localhost:20128/dashboard?q=test&filter=a+b";
const { cmd, args } = resolveOpenCommand("win32", url);
assert.equal(cmd, "rundll32");
assert.equal(args[1], url);
});