import { collectDns } from "./dns"; import { evaluateDiagnostics } from "./diagnostics"; import { collectTls } from "./tls"; import { collectHttp } from "./http"; import { normalizeHost, validateResolvedAddresses } from "./policy"; import { score } from "./score"; import type { Category, CollectorStatus, InspectionResult } from "./types"; function collectorStatus(value: Record): CollectorStatus { const meta = value._meta; if (!meta || typeof meta !== "object" || typeof (meta as Record).status !== "string") return "failed"; const status = String((meta as Record).status); return status === "ok" || status === "partial" || status === "failed" ? status : "failed"; } export function buildCompleteness(dns: Record, tls: Record, http: Record) { const collectors: Record = { dns: collectorStatus(dns), tls: collectorStatus(tls), http: collectorStatus(http), }; const statuses = Object.values(collectors); const complete = statuses.filter((status) => status === "ok").length; const issues = [dns, tls, http].flatMap((collector) => { const errors = collector._meta && typeof collector._meta === "object" ? (collector._meta as Record).errors : []; return Array.isArray(errors) ? errors.map((error) => typeof error === "object" && error !== null && "message" in error ? String((error as { message?: unknown }).message) : String(error)) : []; }); return { status: complete === statuses.length ? "complete" as const : complete === 0 ? "failed" as const : "partial" as const, complete, total: statuses.length, collectors, issues: [...new Set(issues)], }; } export async function inspectHost(rawHost: string): Promise { const host = normalizeHost(rawHost); const dns = await collectDns(host); const addresses = validateResolvedAddresses([ ...(Array.isArray(dns.a) ? dns.a.filter((value): value is string => typeof value === "string") : []), ...(Array.isArray(dns.aaaa) ? dns.aaaa.filter((value): value is string => typeof value === "string") : []), ]); const [tls, http] = await Promise.all([collectTls(host, addresses), collectHttp(host)]); const findings = evaluateDiagnostics(dns, tls, http); return { host, inspectedAt: new Date().toISOString(), addresses, completeness: buildCompleteness(dns, tls, http), dns, tls, http, findings, score: score(findings) }; }