import type { Server } from "node:http"; import type { AddressInfo } from "node:net"; // WHATWG Fetch blocks a fixed list of ports. Node's HTTP adapter uses fetch, // so e2e mock servers must avoid ephemeral assignments like :6000. const FETCH_BLOCKED_PORTS = new Set([ 1, 7, 9, 11, 13, 15, 17, 19, 20, 21, 22, 23, 25, 37, 42, 43, 53, 69, 77, 79, 87, 95, 101, 102, 103, 104, 109, 110, 111, 113, 115, 117, 119, 123, 135, 137, 139, 143, 161, 179, 389, 427, 465, 512, 513, 514, 515, 526, 530, 531, 532, 540, 548, 554, 556, 563, 587, 601, 636, 989, 990, 993, 995, 1719, 1720, 1723, 2049, 3659, 4045, 4190, 5060, 5061, 6000, 6566, 6665, 6666, 6667, 6668, 6669, 6697, 10080, ]); export async function listenOnFetchAllowedPort(server: Server): Promise { for (let attempt = 0; attempt < 20; attempt += 1) { await new Promise((resolve, reject) => { const onError = (error: Error) => { server.off("error", onError); reject(error); }; server.once("error", onError); server.listen(0, "127.0.0.1", () => { server.off("error", onError); resolve(); }); }); const address = server.address() as AddressInfo | null; const port = address?.port; if (port && !FETCH_BLOCKED_PORTS.has(port)) return port; await new Promise((resolve, reject) => { server.close((error) => error ? reject(error) : resolve()); }); } throw new Error("Unable to allocate a Fetch-allowed local test server port"); }