Edge Runtime Node Utils
The @edge-runtime/node-utils package contains utilities to run web compliant code into a Node.js environment.
Installation
npm install @edge-runtime/node-utils
This package includes built-in TypeScript support.
Usage
import { once } = from 'node:events'
import { createServer } from 'node:http'
import { buildToNodeHandler } from '@edge-runtime/node-utils'
// 1. builds a transformer, using Node.js@18 globals, and a base url for URL constructor.
const transformToNode = buildToNodeHandler(global, {
defaultOrigin: 'http://example.com',
})
const server = await createServer(
// 2. takes an web compliant request handler, that uses Web globals like Request and Response,
// and turn it into a Node.js compliant request handler.
transformToNode(async (req: Request) => new Response(req.body))
)
// 3. start the node.js server
server.listen()
await once(server, 'listening')
// 4. invoke the request handler
const response = await fetch(
`http://localhost:${(server.address() as AddressInfo).port}`,
{ method: 'POST', body: 'hello world' }
)
console.log(await response.text()) // is 'hello world'
await server.close()
API
buildToNodeHandler(dependencies, options): toNodeHandler(handler: WebHandler): NodeHandler
Builds a transformer function to turn an web compliant request handler:
(req: Request) => Promise<Response> | Response | null | undefined`
into a Node.js compliant request handler (opens in a new tab):
(req: IncomingMessage, res: ServerResponse) => Promise<void> | void
Limitation: it does support the web handler second parameter, so waitUntil
is not implemented yet.
dependencies: object
List of Web globals used by the transformer function:
- Request (opens in a new tab)
- Headers (opens in a new tab)
- ReadableStream (opens in a new tab)
- Uint8Array (opens in a new tab)
- FetchEvent (opens in a new tab)
When running in Node.js 18+ (or Node.js 16 with --experimental-fetch (opens in a new tab)), you may pass the ones from global
scope.
import { buildToNodeHandler } from '@edge-runtime/node-utils'
buildToNodeHandler(globals, {
/* ... options */
})
Otherwise, you can reuse primitives from @edge-runtime/primitives
import { buildToNodeHandler } from '@edge-runtime/node-utils'
import * as primitives from '@edge-runtime/primitives'
buildToNodeHandler(primitives, {
/* ... options */
})
options: object
Options used to build the transformer function, including:
defaultOrigin: string
The incoming host
header (opens in a new tab) is used when turning the incoming request relative url into a full Request.url (opens in a new tab) string.
In case no host is provided, this default origin will be used instead.
buildToRequest(dependencies, options): toRequest(request: IncomingMessage, options: object): Request
Builds a transformer function to turn a Node.js IncomingMessage (opens in a new tab) into a Web [Request]. It needs globals Web contstructor a dependencies, as well as options to handle incoming url.
buildToFetchEvent(dependencies): toFetchEvent(request: Request): FetchEvent
Builds a transformer function to build a fetch event from a web [Request]. The returned event is linked to provided request, and has a mocked waitUntil() (opens in a new tab) method, which throws on access.
It needs globals Web constructor a dependencies.
toOutgoingHeaders(headers: Headers): OutgoingHttpHeaders
Turns Web Request.headers (opens in a new tab) into
Node.js ServerResponse
OutgoingHttpHeaders (opens in a new tab).
Includes set-cookie
special handling, splitting multiple values when relevant.
buildToHeaders(dependencies): toHeaders(nodeHeaders: IncomingHttpHeaders): Headers
Builds a transformer to turn Node.js IncomingHttpHeaders (opens in a new tab) into Web Request.headers (opens in a new tab).
toToReadable(webStream: ReadableStream, options: object): Readable
Turns Web ReadableStream (opens in a new tab) (typically, the Response.body (opens in a new tab)) into Node.js Readable (opens in a new tab) stream.
buildToReadableStream(dependencies): toReadableStream(stream: Readable): ReadableStream
Builds a transformer to turn Node.js Readable (opens in a new tab) (typically, the IncomingMessage (opens in a new tab)'s payload) into Web ReadableStream (opens in a new tab).