const fs = require("fs"); const path = require("path"); const root = path.join(__dirname, ".."); const allowedChecks = new Set(["system_health", "update_state", "plugins", "recent_errors", "benchmark"]); const check = String(process.argv[2] || "system_health").trim(); if (!allowedChecks.has(check)) { console.error(`Choose one of: ${Array.from(allowedChecks).join(", ")}`); process.exit(2); } const configPath = path.resolve(process.env.LUMI_DIAGNOSTICS_CONFIG || path.join(root, ".secrets", "production-diagnostics.json")); let fileConfig = {}; try { fileConfig = JSON.parse(fs.readFileSync(configPath, "utf8")); } catch (error) { if (!process.env.LUMI_DIAGNOSTICS_URL || !process.env.LUMI_DIAGNOSTICS_KEY) { console.error(`Diagnostics configuration was not found or is invalid: ${configPath}`); process.exit(2); } } const baseUrl = String(process.env.LUMI_DIAGNOSTICS_URL || fileConfig.base_url || "").trim(); const key = String(process.env.LUMI_DIAGNOSTICS_KEY || fileConfig.key || "").trim(); let endpoint; try { const parsed = new URL(baseUrl); const isLoopback = ["localhost", "127.0.0.1", "::1", "[::1]"].includes(parsed.hostname); if (parsed.protocol !== "https:" && !(parsed.protocol === "http:" && isLoopback)) { throw new Error("Production diagnostics require HTTPS (HTTP is allowed only for loopback)."); } if (parsed.username || parsed.password) throw new Error("Do not put credentials in the diagnostics URL."); endpoint = new URL("/api/diagnostics/v1/run", parsed); } catch (error) { console.error(error.message || "Configure a valid production diagnostics URL."); process.exit(2); } if (!key.startsWith("lumi_diag_")) { console.error("The production diagnostics key is missing or invalid."); process.exit(2); } const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), 15000); fetch(endpoint, { method: "POST", headers: { authorization: `Bearer ${key}`, "content-type": "application/json", accept: "application/json" }, body: JSON.stringify({ check }), signal: controller.signal }) .then(async (response) => { const body = await response.json().catch(() => null); if (!response.ok || body?.ok !== true) { throw new Error(body?.error || `Diagnostics request failed with HTTP ${response.status}.`); } console.log(JSON.stringify(body, null, 2)); }) .catch((error) => { console.error(error.name === "AbortError" ? "Diagnostics request timed out." : error.message); process.exitCode = 1; }) .finally(() => clearTimeout(timeout));