metatron-open-seo/src/server/lib/dataforseoLighthouse.ts
Ben Senescu 638f5a6602 refactor: move lighthouse audits to dataforseo (#43)
* refactor: move lighthouse audits to dataforseo

* chore: remove obsolete audit settings modal

* refactor: rename psi flows to lighthouse

* save

* refactor: simplify audit lighthouse storage flow

* fix: separate lighthouse metrics from actionable audits

* refactor: remove redundant audit project inputs

* feat: redesign lighthouse issues screen with score gauges and table layout

Replace flat score cards with circular SVG gauges, condense metrics into
a compact grid, and switch issue list from cards to an expandable table
with fixed column widths.

* test: harden lighthouse regression coverage

* fix: restore project-scoped audit inputs

* refactor: simplify lighthouse payload handling

* refactor: inline lighthouse server handlers

* refactor: share audit workflow types

* refactor: simplify lighthouse payload flows

* save

* refactor: drop project pagespeed api key

* fix: restore lighthouse issues loading with resilient project context

* fix: restore audit issues back navigation

* refactor: simplify project context and lighthouse error handling

* fix: tolerate DataForSEO lighthouse payload drift

* refactor: route audit lighthouse through dataforseo client
2026-03-26 20:25:27 -04:00

61 lines
1.7 KiB
TypeScript

import { env } from "cloudflare:workers";
import {
parseDataforseoLighthousePayload,
requestCategories,
type LighthouseStrategy,
} from "@/server/lib/dataforseoLighthousePayload";
import type { DataforseoApiResponse } from "@/server/lib/dataforseoCost";
import type { StoredLighthousePayload } from "@/server/lib/lighthouseStoredPayload";
const DATAFORSEO_LIGHTHOUSE_ENDPOINT =
"https://api.dataforseo.com/v3/on_page/lighthouse/live/json";
export async function fetchDataforseoLighthouseResultRaw(input: {
url: string;
strategy: LighthouseStrategy;
}): Promise<DataforseoApiResponse<StoredLighthousePayload>> {
const response = await fetch(DATAFORSEO_LIGHTHOUSE_ENDPOINT, {
method: "POST",
headers: {
Authorization: `Basic ${env.DATAFORSEO_API_KEY?.trim() ?? ""}`,
"Content-Type": "application/json",
},
body: JSON.stringify([
{
url: input.url,
for_mobile: input.strategy === "mobile",
categories: requestCategories,
},
]),
signal: AbortSignal.timeout(60_000),
});
const rawText = await response.text();
if (!response.ok) {
throw new Error(
`DataForSEO Lighthouse request failed (${response.status}): ${rawText}`,
);
}
let payload: unknown;
try {
payload = JSON.parse(rawText);
} catch {
throw new Error(
`DataForSEO Lighthouse returned non-JSON content (content-type: ${response.headers.get("content-type") ?? "unknown"}): ${rawText}`,
);
}
const data = parseDataforseoLighthousePayload(payload, input);
return {
data,
billing: {
path: ["v3", "on_page", "lighthouse", "live", "json"],
costUsd: data.metadata.cost ?? 0,
resultCount: 1,
},
};
}