Skip to content

Commit

Permalink
refactor(utils): extract enrichFromResponse() in a file
Browse files Browse the repository at this point in the history
  • Loading branch information
feugy committed Nov 25, 2022
1 parent b2fe9d0 commit 7322e38
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 41 deletions.
44 changes: 5 additions & 39 deletions packages/utils/src/edge-to-node/handler.ts
Original file line number Diff line number Diff line change
@@ -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)
}
}
}
4 changes: 2 additions & 2 deletions packages/utils/src/edge-to-node/headers.ts
Original file line number Diff line number Diff line change
@@ -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<string, OutgoingHttpHeader> = {}
existingHeaders: OutgoingHttpHeaders = {}
) {
for (const name of 'raw' in headers
? // @ts-ignore TODO @schniz where does raw come from?
Expand Down
1 change: 1 addition & 0 deletions packages/utils/src/edge-to-node/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './handler'
export * from './headers'
export * from './response'
export * from './stream'
40 changes: 40 additions & 0 deletions packages/utils/src/edge-to-node/response.ts
Original file line number Diff line number Diff line change
@@ -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)
}
}
1 change: 1 addition & 0 deletions packages/utils/src/types.ts
Original file line number Diff line number Diff line change
@@ -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 = (
Expand Down

0 comments on commit 7322e38

Please sign in to comment.