UNPKG

locadot

Version:

Secure your local development environment with HTTPS and custom domains like dev.localhost.

140 lines (139 loc) 5.9 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const http_proxy_1 = __importDefault(require("http-proxy")); const certs_1 = require("./utils/certs"); const https_1 = __importDefault(require("https")); const http_1 = __importDefault(require("http")); const locadot_file_1 = __importDefault(require("./lib/locadot-file")); const child_process_1 = require("child_process"); const file_1 = __importDefault(require("./utils/file")); const logger_1 = __importDefault(require("./utils/logger")); const http_2 = __importDefault(require("./lib/http")); class ProxyHandler { async startCentralProxy() { try { let domainMap = await locadot_file_1.default.getRegistry(); const proxy = http_proxy_1.default.createProxyServer({}); const defaultCert = await (0, certs_1.createSSL)("localhost"); const watcher = await locadot_file_1.default.watchRegistry(async () => { logger_1.default.info("🔄 Updated domain mapping"); domainMap = await locadot_file_1.default.getRegistry(); }); process.on("SIGINT", async (err) => { logger_1.default.error("🛑 Proxy stopped. Proxy soft destroyed as process SIGINT", err); await locadot_file_1.default.softDestroy(watcher); }); process.on("SIGTERM", async (err) => { logger_1.default.error("🛑 Proxy stopped. Proxy soft destroyed as process SIGTERM", err); await locadot_file_1.default.softDestroy(watcher); }); // process.on("exit", (code: string, signal: string) => { // logger.error(`Process exited with error ${code} and signal ${signal}`); // locadotFile.softDestroy(watcher); // }); const httpsServer = https_1.default.createServer(defaultCert, (req, res) => { http_2.default.requestHandler(req, res, proxy, domainMap); }); const httpServer = http_1.default.createServer((req, res) => { http_2.default.requestHandler(req, res, proxy, domainMap); }); httpsServer.listen(443, () => { logger_1.default.info("🛜 HTTPS proxy running on port 443"); }); httpsServer.on("upgrade", (req, res, head) => { http_2.default.requestUpgrade(req, res, head, proxy, domainMap); }); httpServer.listen(80, () => { logger_1.default.info("🛜 HTTP proxy running on port 80"); }); httpServer.on("upgrade", (req, socket, head) => { http_2.default.requestUpgrade(req, socket, head, proxy, domainMap); }); } catch (error) { logger_1.default.error("Failed to start central proxy", error); } } static async isProxyRunning() { try { const pid = Number(await locadot_file_1.default.getProcessId()); if (!pid || isNaN(pid)) { return false; } process.kill(pid, 0); return true; } catch (error) { return false; } } async startProxy() { try { if (await ProxyHandler.isProxyRunning()) { logger_1.default.error("Proxy is already running"); return; } const command = locadot_file_1.default.getStartProxyFile(); const proxyProcess = (0, child_process_1.spawn)(command.command, command.path, { detached: true, stdio: ["ignore", "ignore", "pipe"], }); const logStream = file_1.default.writeFileStream("LOGS", true); proxyProcess.stderr.pipe(logStream); proxyProcess.on("error", (err) => { console.error("Failed to start child process:", err); }); if (!proxyProcess.pid) { logger_1.default.error("❌ Central proxy failed to start"); process.exit(1); } else { locadot_file_1.default.createLockFile(proxyProcess.pid?.toString()); } proxyProcess.unref(); logger_1.default.info("🚀 Central proxy started in background."); } catch (error) { logger_1.default.error("Failed to start central proxy", error); } } async addProxy(domain, port) { if (!(await ProxyHandler.isProxyRunning())) { await this.startProxy(); } let registry = await locadot_file_1.default.getRegistry(); if (registry[domain]) { console.error(`❌ ${domain} already mapped to port ${registry[domain]} use update instead.`); process.exit(1); } await locadot_file_1.default.addRegistry(domain, port); logger_1.default.info(`✅ ${domain} => http://localhost:${port}`); } async removeProxy(domain) { if (!(await ProxyHandler.isProxyRunning())) { await this.startProxy(); } await locadot_file_1.default.deleteRegistry(domain); } async updateProxy(domain, port) { if (!(await ProxyHandler.isProxyRunning())) { await this.startProxy(); } await locadot_file_1.default.updateRegistry(domain, port); } async stopProxy() { await locadot_file_1.default.softDestroy(); } async killProxy() { await locadot_file_1.default.destroy(); } async restartProxy() { await locadot_file_1.default.softDestroy(); await this.startProxy(); } } const locadotProxy = new ProxyHandler(); exports.default = locadotProxy;