|  | 
| 1 |  | -// remove type imports from http for Deno compatibility | 
| 2 |  | -// see https://github.com/octokit/octokit.js/issues/2075#issuecomment-817361886 | 
| 3 |  | -// import type { IncomingMessage } from "node:http"; | 
| 4 |  | -// declare module "node:http" { | 
| 5 |  | -//    interface IncomingMessage { | 
| 6 |  | -//      body?: string; | 
| 7 |  | -//    } | 
| 8 |  | -// } | 
|  | 1 | +import { concatUint8Array } from "../../concat-uint8array.ts"; | 
|  | 2 | + | 
| 9 | 3 | type IncomingMessage = any; | 
| 10 | 4 | 
 | 
| 11 |  | -export function getPayload(request: IncomingMessage): Promise<string> { | 
|  | 5 | +const textDecoder = new TextDecoder("utf-8", { fatal: false }); | 
|  | 6 | +const decode = textDecoder.decode.bind(textDecoder); | 
|  | 7 | + | 
|  | 8 | +export async function getPayload(request: IncomingMessage): Promise<string> { | 
| 12 | 9 |   if ( | 
| 13 | 10 |     typeof request.body === "object" && | 
| 14 | 11 |     "rawBody" in request && | 
| 15 |  | -    request.rawBody instanceof Buffer | 
|  | 12 | +    request.rawBody instanceof Uint8Array | 
| 16 | 13 |   ) { | 
| 17 |  | -    // The body is already an Object and rawBody is a Buffer (e.g. GCF) | 
| 18 |  | -    return Promise.resolve(request.rawBody.toString("utf8")); | 
|  | 14 | +    // The body is already an Object and rawBody is a Buffer/Uint8Array (e.g. GCF) | 
|  | 15 | +    return decode(request.rawBody); | 
| 19 | 16 |   } else if (typeof request.body === "string") { | 
| 20 | 17 |     // The body is a String (e.g. Lambda) | 
| 21 |  | -    return Promise.resolve(request.body); | 
|  | 18 | +    return request.body; | 
| 22 | 19 |   } | 
| 23 | 20 | 
 | 
|  | 21 | +  // We need to load the payload from the request (normal case of Node.js server) | 
|  | 22 | +  const payload = await getPayloadFromRequestStream(request); | 
|  | 23 | +  return decode(payload); | 
|  | 24 | +} | 
|  | 25 | + | 
|  | 26 | +export function getPayloadFromRequestStream( | 
|  | 27 | +  request: IncomingMessage, | 
|  | 28 | +): Promise<Uint8Array> { | 
| 24 | 29 |   // We need to load the payload from the request (normal case of Node.js server) | 
| 25 | 30 |   return new Promise((resolve, reject) => { | 
| 26 |  | -    let data: Buffer[] = []; | 
|  | 31 | +    let data: Uint8Array[] = []; | 
| 27 | 32 | 
 | 
| 28 | 33 |     request.on("error", (error: Error) => | 
| 29 | 34 |       reject(new AggregateError([error], error.message)), | 
| 30 | 35 |     ); | 
| 31 |  | -    request.on("data", (chunk: Buffer) => data.push(chunk)); | 
| 32 |  | -    request.on("end", () => | 
| 33 |  | -      // setImmediate improves the throughput by reducing the pressure from | 
| 34 |  | -      // the event loop | 
| 35 |  | -      setImmediate( | 
| 36 |  | -        resolve, | 
| 37 |  | -        data.length === 1 | 
| 38 |  | -          ? data[0].toString("utf8") | 
| 39 |  | -          : Buffer.concat(data).toString("utf8"), | 
| 40 |  | -      ), | 
| 41 |  | -    ); | 
|  | 36 | +    request.on("data", data.push.bind(data)); | 
|  | 37 | +    request.on("end", () => { | 
|  | 38 | +      const result = concatUint8Array(data); | 
|  | 39 | +      // Switch to queue microtask when we want to support bun and deno | 
|  | 40 | +      setImmediate(resolve, result); | 
|  | 41 | +    }); | 
| 42 | 42 |   }); | 
| 43 | 43 | } | 
0 commit comments