* Proxy a request to the cloud API.
( req: IncomingMessage, res: ServerResponse, pathname: string )
| 231 | * Proxy a request to the cloud API. |
| 232 | */ |
| 233 | async function proxyToCloud( |
| 234 | req: IncomingMessage, |
| 235 | res: ServerResponse, |
| 236 | pathname: string |
| 237 | ): Promise<void> { |
| 238 | const method = req.method || "GET"; |
| 239 | const cloudUrl = `${CLOUD_API_URL}${pathname}`; |
| 240 | |
| 241 | const headers: Record<string, string> = { |
| 242 | "x-api-key": cloudApiKey!, |
| 243 | }; |
| 244 | |
| 245 | // Forward content-type for requests with body |
| 246 | if (req.headers["content-type"]) { |
| 247 | headers["Content-Type"] = req.headers["content-type"]; |
| 248 | } |
| 249 | |
| 250 | let body: string | undefined; |
| 251 | if (method !== "GET" && method !== "HEAD") { |
| 252 | body = await new Promise<string>((resolve, reject) => { |
| 253 | let data = ""; |
| 254 | req.on("data", (chunk) => (data += chunk)); |
| 255 | req.on("end", () => resolve(data)); |
| 256 | req.on("error", reject); |
| 257 | }); |
| 258 | } |
| 259 | |
| 260 | try { |
| 261 | const cloudRes = await fetch(cloudUrl, { |
| 262 | method, |
| 263 | headers, |
| 264 | body, |
| 265 | }); |
| 266 | |
| 267 | // Handle SSE responses |
| 268 | if (cloudRes.headers.get("content-type")?.includes("text/event-stream")) { |
| 269 | res.writeHead(cloudRes.status, { |
| 270 | "Content-Type": "text/event-stream", |
| 271 | "Cache-Control": "no-cache", |
| 272 | Connection: "keep-alive", |
| 273 | "Access-Control-Allow-Origin": "*", |
| 274 | }); |
| 275 | |
| 276 | const reader = cloudRes.body?.getReader(); |
| 277 | if (reader) { |
| 278 | const pump = async () => { |
| 279 | while (true) { |
| 280 | const { done, value } = await reader.read(); |
| 281 | if (done) break; |
| 282 | res.write(value); |
| 283 | } |
| 284 | res.end(); |
| 285 | }; |
| 286 | pump().catch(() => res.end()); |
| 287 | |
| 288 | req.on("close", () => { |
| 289 | reader.cancel(); |
| 290 | }); |
no test coverage detected
searching dependent graphs…