64 lines
1.7 KiB
TypeScript
64 lines
1.7 KiB
TypeScript
import { existsSync, readFileSync, rmSync } from "node:fs";
|
|
import { EMULATE_PID_FILE, START_EMULATE_SH } from "../constants.ts";
|
|
import { portlessHttpsUrl } from "./ports.ts";
|
|
import { log, sh } from "./shell.ts";
|
|
|
|
function emulateReachable(): boolean {
|
|
const healthUrl = `${portlessHttpsUrl("google.emulate.localhost")}/.well-known/openid-configuration`;
|
|
const res = sh("curl", [
|
|
"-sf",
|
|
"-o",
|
|
"/dev/null",
|
|
"--max-time",
|
|
"1",
|
|
healthUrl,
|
|
]);
|
|
return res.code === 0;
|
|
}
|
|
|
|
export function ensureEmulateRunning(): void {
|
|
if (emulateReachable()) return;
|
|
log("emulate.dev not reachable, spawning daemon");
|
|
const res = sh("bash", [START_EMULATE_SH]);
|
|
if (res.code !== 0) {
|
|
console.error(
|
|
`[dw] failed to start emulate daemon:\n${res.stdout}\n${res.stderr}`,
|
|
);
|
|
}
|
|
}
|
|
|
|
export function killPidFromFile(file: string): boolean {
|
|
if (!existsSync(file)) return false;
|
|
const pid = Number(readFileSync(file, "utf-8").trim());
|
|
if (!pid || Number.isNaN(pid)) return false;
|
|
try {
|
|
process.kill(pid, "SIGTERM");
|
|
} catch {}
|
|
rmSync(file, { force: true });
|
|
return true;
|
|
}
|
|
|
|
export function killHostProcessByName(name: string): boolean {
|
|
const res = sh("pgrep", ["-f", name]);
|
|
const pids = res.stdout
|
|
.split("\n")
|
|
.map((s) => s.trim())
|
|
.filter(Boolean)
|
|
.filter((s) => /^\d+$/.test(s));
|
|
if (pids.length === 0) return false;
|
|
for (const pid of pids) {
|
|
try {
|
|
process.kill(Number(pid), "SIGTERM");
|
|
} catch {}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
export function stopEmulateAndPortless(): void {
|
|
const fromPid = killPidFromFile(EMULATE_PID_FILE);
|
|
const fromScan = killHostProcessByName("emulate --portless");
|
|
if (fromPid || fromScan) log("stopped emulate.dev");
|
|
const stop = sh("portless", ["proxy", "stop"]);
|
|
if (stop.code === 0) log("stopped portless proxy");
|
|
}
|