Files
OmniRoute/bin/cli/commands/dashboard.mjs
diegosouzapw 22d27ca273 feat(cli): migrar serve/stop/restart/dashboard/keys/models/combo (Fase 1.3)
Extrai 7 grupos de comandos do monolito bin/cli-commands.mjs (2853 linhas)
para módulos individuais em bin/cli/commands/, registrados via Commander.

- stop.mjs: SIGTERM/SIGKILL via process.kill(); fallback por porta usa execFile
  com array de args (evita injeção de shell / Semgrep CWE-78)
- restart.mjs: delega para runStopCommand + runServe
- dashboard.mjs: alias "open", fallback nativo por plataforma via execFile
- keys.mjs: server-first (POST /api/v1/providers/keys) → DB fallback; valida
  provider via loadAvailableProviders(); suporte a --stdin
- models.mjs: GET /api/models → fallback /api/v1/models; filtro por provider e --search
- combo.mjs: list/switch/create/delete; switch server-first → DB fallback via key_value;
  TODO(1.5) marcados para substituir SQL cru por src/lib/db/combos.ts
- serve.mjs: escreve PID via writePidFile() no spawn; limpa no shutdown; suporte daemon

utils/pid.mjs e i18n keys (en.json + pt-BR.json) já criados em iteração anterior.

Testes: cli-keys-command.test.ts atualizado para novos runners;
        cli-serve-stop-command.test.ts, cli-combo-command.test.ts,
        cli-models-command.test.ts adicionados (23 testes, 0 falhas).
2026-05-14 23:11:30 -03:00

57 lines
1.3 KiB
JavaScript

import { execFile } from "node:child_process";
import { t } from "../i18n.mjs";
export function registerDashboard(program) {
program
.command("dashboard")
.alias("open")
.description(t("dashboard.description"))
.option("--url", t("dashboard.urlOnly"))
.option("--port <port>", "Port the server is running on", "20128")
.action(async (opts) => {
const exitCode = await runDashboardCommand(opts);
if (exitCode !== 0) process.exit(exitCode);
});
}
export async function runDashboardCommand(opts = {}) {
const port = opts.port ? parseInt(String(opts.port), 10) : 20128;
const dashboardUrl = `http://localhost:${port}`;
if (opts.url) {
console.log(dashboardUrl);
return 0;
}
console.log(t("dashboard.opening", { url: dashboardUrl }));
try {
const open = await import("open");
await open.default(dashboardUrl);
} catch {
await openFallback(dashboardUrl);
}
return 0;
}
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];
}
execFile(cmd, args, { stdio: "ignore" }, () => resolve());
});
}