fix(cli): resolve tray runtime import to a file:// URL so --tray works on Windows (#11332)

Merged via consolidated batch validation. Fixes omniroute server --tray on Windows: absolute paths passed to dynamic import() are parsed as URLs, and a Windows drive letter (C:) isn't a supported URL scheme. Resolves via pathToFileURL. Own regression test passes.
This commit is contained in:
Paco Cartones
2026-08-24 17:11:49 +02:00
committed by GitHub
parent 9df3f8923d
commit 644dd32d3f
2 changed files with 60 additions and 2 deletions

View File

@@ -2,6 +2,7 @@ import { existsSync, mkdirSync, writeFileSync, chmodSync } from "node:fs";
import { join } from "node:path";
import { homedir } from "node:os";
import { execSync } from "node:child_process";
import { pathToFileURL } from "node:url";
const RUNTIME_DIR = join(homedir(), ".omniroute", "runtime");
// systray2 is a maintained fork with prebuilt binaries — installed lazily at runtime,
@@ -16,6 +17,16 @@ export const SYSTRAY_PACKAGE = "systray2";
export const SYSTRAY_VERSION = "2.1.4";
const SYSTRAY_SPEC = `${SYSTRAY_PACKAGE}@${SYSTRAY_VERSION}`;
// Dynamic `import()` resolves its specifier as a URL, not a filesystem path.
// On Windows the lazily-installed systray2 lives at an absolute path whose
// leading drive letter the ESM loader parses as an unsupported URL scheme
// (e.g. `c:`) and rejects. Build a file:// URL so the tray import works on
// Windows too. Same defect fixed for the CLI db-fallback imports in #11238,
// missed at this call site.
export function systrayModuleSpecifier(runtimeDir: string): string {
return pathToFileURL(join(runtimeDir, "node_modules", SYSTRAY_PACKAGE)).href;
}
export function resolveSystrayBinName(platform: NodeJS.Platform): string | null {
if (platform === "win32") return "tray_windows_release.exe";
if (platform === "darwin") return "tray_darwin_release";
@@ -60,8 +71,7 @@ export async function loadSystray(): Promise<(new (...args: unknown[]) => unknow
// drop the +x bit on extraction (observed on macOS).
chmodSystrayBinAt(RUNTIME_DIR, process.platform);
try {
const modPath = join(RUNTIME_DIR, "node_modules", SYSTRAY_PACKAGE);
const mod = await import(modPath);
const mod = await import(systrayModuleSpecifier(RUNTIME_DIR));
return (mod.default ?? mod.SysTray ?? mod) as (new (...args: unknown[]) => unknown) | null;
} catch (err) {
console.warn(`[omniroute] tray runtime import failed: ${(err as Error).message}`);