import { lunarisVersionSchema } from "@/lib/catalog/version"; import { discordWorkerHeartbeatKey, getRedisClient } from "@/lib/redis/client"; export async function checkSlip2Go(signal: AbortSignal): Promise { const configuredUrl = process.env.SLIP2GO_VERIFY_URL; if (!configuredUrl || !process.env.SLIP2GO_API_SECRET) throw new Error("Slip2Go is not configured."); const url = new URL(configuredUrl); if (url.protocol !== "https:") throw new Error("Slip2Go URL must use HTTPS."); const response = await fetch(url, { method: "HEAD", cache: "no-store", signal }); // The verification endpoint requires a real slip, so a rejected HEAD request can still prove reachability. if (!response.ok && ![400, 401, 403, 405, 415, 422].includes(response.status)) { throw new Error(`Slip2Go returned ${response.status}.`); } } export async function checkLunaris(signal: AbortSignal): Promise { const response = await fetch("https://api.lunaris.moe/data/version.json", { cache: "no-store", signal }); if (!response.ok) throw new Error(`Lunaris returned ${response.status}.`); const body: unknown = await response.json(); if (typeof body !== "object" || body === null || !("version" in body)) { throw new Error("Invalid Lunaris version response."); } lunarisVersionSchema.parse(body.version); } export async function checkDiscordBot(): Promise { const redis = await getRedisClient(); if (!(await redis.exists(discordWorkerHeartbeatKey()))) { throw new Error("Discord worker heartbeat is missing."); } }