import os from "node:os"; import path from "node:path"; export const SERVICE_NAME = "triggershell"; export interface UnitOptions { execPath: string; binPath: string; configPath: string; configDir: string; port?: number; host?: string; scope: "user" | "system"; } export function renderUnit(opts: UnitOptions): string { const args = ["start", "--config", opts.configPath, "--no-browser"]; if (opts.port !== undefined) args.push("--port", String(opts.port)); if (opts.host !== undefined) args.push("--host", opts.host); const execStart = [opts.execPath, opts.binPath, ...args] .map((part) => (part.includes(" ") ? `"${part}"` : part)) .join(" "); const wantedBy = opts.scope === "user" ? "default.target" : "multi-user.target"; return `[Unit] Description=TriggerShell - self-hosted script runner After=network.target [Service] Type=simple ExecStart=${execStart} WorkingDirectory=${opts.configDir} Restart=on-failure RestartSec=2 Environment=NODE_ENV=production [Install] WantedBy=${wantedBy} `; } export function userUnitPath(): string { return path.join( os.homedir(), ".config", "systemd", "user", `${SERVICE_NAME}.service`, ); } export function systemUnitPath(): string { return path.join("/etc", "systemd", "system", `${SERVICE_NAME}.service`); } export function isRoot(): boolean { return process.getuid?.() === 0; }