diff --git a/pages/api/badge.ts b/pages/api/badge.ts new file mode 100644 index 0000000..9ecb35b --- /dev/null +++ b/pages/api/badge.ts @@ -0,0 +1,93 @@ +import { NextRequest } from 'next/server' + +export const runtime = 'edge' + +type DataResponse = { + up: number + down: number + updatedAt: number + monitors: Record< + string, + { + up: boolean + latency: number + location: string + message: string + } + > +} + +type BadgePayload = { + schemaVersion: 1 + label: string + message: string + color: string + isError?: boolean +} + +const jsonHeaders = { + 'Content-Type': 'application/json', + 'Cache-Control': 'no-store, max-age=0, must-revalidate', +} + +function errorBadge(label: string, message: string): BadgePayload { + return { + schemaVersion: 1, + label, + message, + color: 'lightgrey', + isError: true, + } +} + +export default async function handler(req: NextRequest): Promise { + try { + const url = new URL(req.url) + + const monitorId = url.searchParams.get('id') + const label = url.searchParams.get('label') ?? 'UptimeFlare' + + const upMsg = url.searchParams.get('up') ?? 'UP' + const downMsg = url.searchParams.get('down') ?? 'DOWN' + const colorUp = url.searchParams.get('colorUp') ?? 'brightgreen' + const colorDown = url.searchParams.get('colorDown') ?? 'red' + + const dataUrl = new URL('/api/data', url.origin) + const resp = await fetch(dataUrl, { cache: 'no-store' }) + + if (!resp.ok) { + return new Response(JSON.stringify(errorBadge(label, 'unavailable')), { + headers: jsonHeaders, + status: resp.status, + }) + } + + const payload = (await resp.json()) as DataResponse + const monitor = payload.monitors?.[monitorId] + + if (!monitor) { + return new Response(JSON.stringify(errorBadge(label, 'unknown')), { + headers: jsonHeaders, + status: 404, + }) + } + + const isUp = Boolean(monitor.up) + const badge: BadgePayload = { + schemaVersion: 1, + label, + message: isUp ? upMsg : downMsg, + color: isUp ? colorUp : colorDown, + } + + return new Response(JSON.stringify(badge), { + headers: jsonHeaders, + }) + } catch (err) { + console.error('Error rendering badge API:', err) + return new Response(JSON.stringify(errorBadge('status', 'error')), { + headers: jsonHeaders, + status: 500, + }) + } +}