import { defineProxyService } from "@webext-core/proxy-service" interface SerializedResponse { status: number statusText: string headers: Record data: number[] ok: boolean type: ResponseType redirected: boolean url: string } function reconstructResponse(serialized: SerializedResponse): Response { const uint8Array = new Uint8Array(serialized.data) const response = new Response(uint8Array, { status: serialized.status, statusText: serialized.statusText, headers: new Headers(serialized.headers) }) Object.defineProperty(response, "ok", { get: () => serialized.ok }) Object.defineProperty(response, "type", { get: () => serialized.type }) Object.defineProperty(response, "redirected", { get: () => serialized.redirected }) Object.defineProperty(response, "url", { get: () => serialized.url }) return response } class ProxyFetch { async fetch(url: RequestInfo | URL, init?: RequestInit) { const cleanInit: RequestInit = init ? { ...init } : {} if ("signal" in cleanInit) { cleanInit.signal = undefined } if (cleanInit?.body && typeof cleanInit.body === "string") { try { JSON.parse(cleanInit.body) } catch (e) { console.warn("Invalid JSON in request body:", e) } } const response = await fetch(url, cleanInit) const buffer = await response.arrayBuffer() const uint8Array = new Uint8Array(buffer) const array = Array.from(uint8Array) return { status: response.status, statusText: response.statusText, headers: Object.fromEntries(response.headers.entries()), data: array, ok: response.ok, type: response.type, redirected: response.redirected, url: response.url } } } export const [registerFetchProxy, getFetchProxy] = defineProxyService( "FetchProxy", () => new ProxyFetch() ) export function getProxiedFetch(): typeof fetch { const proxy = getFetchProxy() return async ( url: RequestInfo | URL, init?: RequestInit ): Promise => { const serialized = await proxy.fetch(url, init) return reconstructResponse(serialized) } }