edge-runtime icon indicating copy to clipboard operation
edge-runtime copied to clipboard

`@edge-runtime/node-utils` can't start example server from docs using `primitives` (node v18.18.2) Headers2 is not a constructor

Open seveibar opened this issue 2 years ago • 1 comments

node v18.18.2 operating system: arch linux

Bug Report

The following code from the docs example fails:

import { once } from "node:events"
import { createServer } from "node:http"
import { buildToNodeHandler } from "@edge-runtime/node-utils"
import * as primitives from "@edge-runtime/primitives"

// 1. builds a transformer, using Node.js@18 globals, and a base url for URL constructor.
const transformToNode = buildToNodeHandler(primitives, {
  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) => 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().port}`, {
  method: "POST",
  body: "hello world",
})

console.log(await response.text()) // is 'hello world'
await server.close()

-> % node test.js
.../node_modules/@edge-runtime/node-utils/dist/index.js:1008
    const headers = new Headers2();
                    ^

TypeError: Headers2 is not a constructor
    at toHeaders (/.../node_modules/@edge-runtime/node-utils/dist/index.js:1008:21)
    at toRequest (/.../node_modules/@edge-runtime/node-utils/dist/index.js:1057:18)
    at Server.<anonymous> (/.../node_modules/@edge-runtime/node-utils/dist/index.js:1151:23)
    at Server.emit (node:events:517:28)
    at parserOnIncoming (node:_http_server:1107:12)
    at HTTPParser.parserOnHeadersComplete (node:_http_common:119:17)

Expected behavior/code

The server should print "hello world"

I also tried this with global instead of primitives but got a different error. I think the primitives case is easier to debug so I've kept this issue using primitives

seveibar avatar Nov 25 '23 20:11 seveibar

I was able to get this working with the following workaround:

import primitives from "@edge-runtime/primitives"

const dependencies = {
  ...primitives,
  Uint8Array,
}

// 1. builds a transformer, using Node.js@18 globals, and a base url for URL constructor.
const transformToNode = buildToNodeHandler(dependencies, {
  defaultOrigin: "http://example.com",
})

Perhaps Uint8Array should be included as part of primitives?

The docs also seem out of date since they suggest using globals to pass to buildToNodeHandler, however this does not seem to include FetchEvent...

mxsdev avatar Jan 15 '24 23:01 mxsdev