All files / src/dashboard handler.ts

100% Statements 18/18
100% Branches 10/10
100% Functions 3/3
100% Lines 18/18

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71                  17x 17x 17x                       18x     18x 6x       12x                       17x 10x 10x   9x         9x 6x   3x     1x 1x               17x 1x    
/**
 * Dashboard HTTP Handler
 *
 * Handles GET / requests and returns:
 * - HTML dashboard when Accept header includes text/html or wildcard
 * - JSON metrics when Accept header is application/json
 */
 
import { Request, Response } from "express";
import { collectMetrics, DashboardMetrics } from "./metrics.js";
import { renderDashboard } from "./html-template.js";
import { logDebug, logError } from "../logger.js";
 
// Determine if request prefers HTML response
//
// Returns true for:
// - Accept: text/html
// - Accept: */* (browser default)
// - No Accept header (treat as browser)
//
// Returns false for:
// - Accept: application/json
function prefersHtml(req: Request): boolean {
  const accept = req.headers.accept ?? "*/*";
 
  // Explicit JSON request
  if (accept.includes("application/json") && !accept.includes("text/html")) {
    return false;
  }
 
  // HTML or wildcard (browser default)
  return accept.includes("text/html") || accept.includes("*/*");
}
 
/**
 * Dashboard endpoint handler
 *
 * Returns server health dashboard as HTML or JSON based on Accept header.
 * Safe for MCP clients - they use POST /mcp or SSE endpoints, not GET /.
 *
 * @param req - Express request
 * @param res - Express response
 */
export function dashboardHandler(req: Request, res: Response): void {
  try {
    const metrics = collectMetrics();
 
    logDebug("Dashboard request", {
      accept: req.headers.accept,
      prefersHtml: prefersHtml(req),
    });
 
    if (prefersHtml(req)) {
      res.type("text/html").send(renderDashboard(metrics));
    } else {
      res.json(metrics);
    }
  } catch (error) {
    logError("Dashboard error", { err: error });
    res.status(500).json({ error: "Failed to generate dashboard" });
  }
}
 
/**
 * Get dashboard metrics without rendering
 * Useful for programmatic access or testing
 */
export function getMetrics(): DashboardMetrics {
  return collectMetrics();
}