From 7322e3894f42acca9b6eef97b957e97401749853 Mon Sep 17 00:00:00 2001 From: feugy Date: Fri, 25 Nov 2022 11:15:36 +0100 Subject: [PATCH] refactor(utils): extract enrichFromResponse() in a file --- packages/utils/src/edge-to-node/handler.ts | 44 +++------------------ packages/utils/src/edge-to-node/headers.ts | 4 +- packages/utils/src/edge-to-node/index.ts | 1 + packages/utils/src/edge-to-node/response.ts | 40 +++++++++++++++++++ packages/utils/src/types.ts | 1 + 5 files changed, 49 insertions(+), 41 deletions(-) create mode 100644 packages/utils/src/edge-to-node/response.ts diff --git a/packages/utils/src/edge-to-node/handler.ts b/packages/utils/src/edge-to-node/handler.ts index 7f86edeb3..0500cced4 100644 --- a/packages/utils/src/edge-to-node/handler.ts +++ b/packages/utils/src/edge-to-node/handler.ts @@ -1,52 +1,18 @@ -import type { IncomingMessage, ServerResponse } from 'http' +import type { IncomingMessage, ServerResponse } from 'node:http' import type { WebHandler, NodeHandler } from '../types' -import { transformToOugoingHeaders } from './headers' -import { transformToReadable } from './stream' +import { enrichFromResponse } from './response' export function transformToNode(webHandler: WebHandler): NodeHandler { return (request: IncomingMessage, response: ServerResponse) => { // TODO map incoming message // @ts-ignore TODO map IncompingMessage into Request const maybePromise = webHandler(request) - const mapResponse = buildResponseMapper(response) if (maybePromise instanceof Promise) { - maybePromise.then(mapResponse) - } else { - mapResponse(maybePromise) - } - } -} - -function buildResponseMapper(serverResponse: ServerResponse) { - return function (webResponse: Response | null | undefined) { - if (!webResponse) { - serverResponse.end() - return - } - for (const [name, value] of Object.entries( - transformToOugoingHeaders( - // @ts-ignore getAll() may not be defined on headers object - webResponse.headers, - serverResponse.getHeaders() + maybePromise.then((webResponse) => + enrichFromResponse(response, webResponse) ) - )) { - serverResponse.setHeader(name, value) - } - - serverResponse.statusCode = webResponse.status - serverResponse.statusMessage = webResponse.statusText - // TODO trailers? https://nodejs.org/api/http.html#responseaddtrailersheaders https://developer.mozilla.org/en-US/docs/Web/API/Response - if (!webResponse.body) { - serverResponse.end() - return - } - if ('getReader' in webResponse.body) { - transformToReadable(webResponse.body).pipe(serverResponse) - } else if ('pipe' in webResponse.body) { - // @ts-ignore TODO @shniz how could the web response body have a pipe operator? - webResponse.body.pipe(serverResponse) } else { - serverResponse.end(webResponse.body) + enrichFromResponse(response, maybePromise) } } } diff --git a/packages/utils/src/edge-to-node/headers.ts b/packages/utils/src/edge-to-node/headers.ts index dfd927e83..744b7c12e 100644 --- a/packages/utils/src/edge-to-node/headers.ts +++ b/packages/utils/src/edge-to-node/headers.ts @@ -1,9 +1,9 @@ import type { Headers } from '@edge-runtime/primitives' -import type { OutgoingHttpHeader } from 'node:http' +import type { OutgoingHttpHeaders } from 'node:http' export function transformToOugoingHeaders( headers: Headers, - existingHeaders: Record = {} + existingHeaders: OutgoingHttpHeaders = {} ) { for (const name of 'raw' in headers ? // @ts-ignore TODO @schniz where does raw come from? diff --git a/packages/utils/src/edge-to-node/index.ts b/packages/utils/src/edge-to-node/index.ts index 206e3c59f..155841678 100644 --- a/packages/utils/src/edge-to-node/index.ts +++ b/packages/utils/src/edge-to-node/index.ts @@ -1,3 +1,4 @@ export * from './handler' export * from './headers' +export * from './response' export * from './stream' diff --git a/packages/utils/src/edge-to-node/response.ts b/packages/utils/src/edge-to-node/response.ts new file mode 100644 index 000000000..d51983051 --- /dev/null +++ b/packages/utils/src/edge-to-node/response.ts @@ -0,0 +1,40 @@ +import { Response } from '@edge-runtime/primitives' +import { ServerResponse } from 'node:http' +import { transformToOugoingHeaders } from './headers' +import { transformToReadable } from './stream' + +export function enrichFromResponse( + serverResponse: ServerResponse, + webResponse: Response | null | undefined +) { + if (!webResponse) { + serverResponse.end() + return + } + for (const [name, value] of Object.entries( + transformToOugoingHeaders( + // @ts-ignore getAll() may not be defined on headers object + webResponse.headers, + serverResponse.getHeaders() + ) + )) { + if (value !== undefined) { + serverResponse.setHeader(name, value) + } + } + + serverResponse.statusCode = webResponse.status + serverResponse.statusMessage = webResponse.statusText + if (!webResponse.body) { + serverResponse.end() + return + } + if ('getReader' in webResponse.body) { + transformToReadable(webResponse.body).pipe(serverResponse) + } else if ('pipe' in webResponse.body) { + // @ts-ignore TODO @shniz how could the web response body have a pipe operator? + webResponse.body.pipe(serverResponse) + } else { + serverResponse.end(webResponse.body) + } +} diff --git a/packages/utils/src/types.ts b/packages/utils/src/types.ts index 1a014faee..32409cc0c 100644 --- a/packages/utils/src/types.ts +++ b/packages/utils/src/types.ts @@ -1,4 +1,5 @@ import type { IncomingMessage, ServerResponse } from 'http' +import type { Request, Response } from '@edge-runtime/primitives' export type NodeHandler = (req: IncomingMessage, res: ServerResponse) => void export type WebHandler = (