import type { ConcreteNetwork, GeoTarget } from "@fetcha/core"; import { executeHttp } from "./http"; import type { ProviderHealth, ProviderRequest, ProviderResponse, ProxyProvider } from "./types"; /** * Direct egress from Fetcha's own infrastructure — no upstream proxy. Cheapest possible * route ("datacenter" class), no geo control. Used as the first attempt in `auto` mode only * when the domain profile says the site tolerates it, and only when enabled via * `FETCHA_DIRECT_EGRESS=1`. Disabled by default to keep the platform's own IPs clean. */ export class DirectProvider implements ProxyProvider { readonly id = "direct" as const; readonly label = "Fetcha direct egress"; readonly networks: ConcreteNetwork[] = ["datacenter"]; private readonly enabled: boolean; constructor(env: NodeJS.ProcessEnv = process.env) { this.enabled = env.FETCHA_DIRECT_EGRESS === "1"; } isConfigured(): boolean { return this.enabled; } supportsGeo(geo: GeoTarget): boolean { return !geo.country; // cannot target geography } pricePerGb(): number { return 0.05; } estimateCost(_network: ConcreteNetwork, bytes: number): number { return (bytes / 1_073_741_824) * this.pricePerGb(); } proxyEndpoint(): null { return null; } async fetch(request: ProviderRequest): Promise { return executeHttp(this.id, null, request); } async health(network: ConcreteNetwork = "datacenter"): Promise { if (!this.enabled) return { provider: this.id, network, status: "unconfigured", latencyMs: null, checkedAt: new Date(), detail: "Direct egress disabled" }; const t0 = performance.now(); try { const res = await this.fetch({ requestId: "probe", attemptId: "probe", url: "https://www.cloudflare.com/cdn-cgi/trace", method: "GET", headers: {}, timeoutMs: 8000, network, geo: { country: null, region: null, city: null }, followRedirects: true, maxRedirects: 3, maxResponseBytes: 65536, }); const latencyMs = Math.round(performance.now() - t0); return { provider: this.id, network, status: res.status < 500 ? "healthy" : "degraded", latencyMs, checkedAt: new Date() }; } catch (e) { return { provider: this.id, network, status: "down", latencyMs: null, checkedAt: new Date(), detail: (e as Error).message }; } } }