import { fileURLToPath } from "node:url"; import path from "node:path"; import { loadConfig } from "./config.js"; import log4js from "log4js"; import { createElectronWindow } from "./electron/window.js"; import { setupIPC } from "./electron/ipc.js"; import { LocalServer } from "./localserver/localserver.js"; import { SocketClient } from "./socket/socketclient.js"; import { authenticateWithOtp, checkRunning, createCliLogger, isHeadless, isInfo, otpCode, printAuthCommand, printerHostInfo, startWaiting, stopWaiting, } from "./commandlineutils.js"; if (!process.env.NODE_ENV) { process.env.NODE_ENV = "production"; } const config = loadConfig(); const logger = log4js.getLogger("App"); logger.level = config.logLevel; const cli = createCliLogger(logger); export async function init(options = {}) { const headless = options.headless ?? isHeadless; cli.blank(); startWaiting("Checking if Farm Control Server is running...", logger); let runningServer; try { runningServer = await checkRunning(); } catch (err) { await stopWaiting(); throw err; } if (otpCode != undefined || isInfo == true) { cli.success("Farm Control Server is running."); } if (isInfo) { const buildNumber = runningServer.buildNumber ?? runningServer.build ?? "n/a"; cli.blank(); cli.sectionHeader("FarmControl Server"); cli.label( "Version:", runningServer.version ? `v${runningServer.version}` : "n/a", ); cli.label("Build:", buildNumber === "dev" ? "dev" : `b${buildNumber}`); cli.label("Authenticated:", cli.yesNo(runningServer.authenticated == true)); cli.sectionFooter(); cli.blank(); if (runningServer.authenticated == false) { cli.sectionHeader("Authenticate"); printAuthCommand(cli); cli.sectionFooter(); } else { cli.sectionHeader("Host"); printerHostInfo(runningServer.host, cli); cli.sectionFooter(); } cli.blank(); return runningServer; } if (otpCode != undefined) { cli.blank(); startWaiting("Authenticating with OTP...", logger); let authenticatedServer; try { authenticatedServer = await authenticateWithOtp(otpCode); await stopWaiting(); } catch (err) { await stopWaiting(); throw err; } if (authenticatedServer.valid == false) { cli.failure("Failed to authenticate!"); cli.failure(authenticatedServer.error); } else { cli.success("Authenticated with OTP."); cli.blank(); cli.sectionHeader("Host"); printerHostInfo(authenticatedServer.host, cli); cli.sectionFooter(); cli.blank(); return authenticatedServer; } cli.blank(); return authenticatedServer; } if (runningServer != false) { cli.warn("✘ Farm Control Server is already running."); cli.blank(); return runningServer; } if (!headless) { startWaiting("Creating electron window...", logger); try { await createElectronWindow().catch((err) => { cli.warn("Failed to create Electron window:", err); }); await stopWaiting(); } catch (err) { await stopWaiting(); throw err; } setupIPC().catch((err) => { cli.warn("Failed to setup IPC:", err); }); } else { cli.info("Running in headless mode. Skipping window creation."); } const socketClient = new SocketClient(); global.socketClient = socketClient; const localServer = new LocalServer(socketClient); await localServer.start(); socketClient.connect(); process.on("SIGINT", async () => { startWaiting("Shutting down...", logger); cli.blank(); socketClient.disconnect(); localServer.stop(); await stopWaiting(); process.exit(0); }); } const isMainModule = process.argv[1] && fileURLToPath(import.meta.url) === path.resolve(process.argv[1]); if (isMainModule && !process.env.FC_HEADLESS_ENTRY) { init().catch((err) => { logger.error(err.message); cli.blank(); process.exit(1); }); }