fastify / light-my-request

Fake HTTP injection library
Other
357 stars 47 forks source link

Support for built-in Node.js FormData #298

Closed chrisdickinson closed 5 days ago

chrisdickinson commented 2 months ago

Prerequisites

Issue

Hi folks! Thanks for the great work on Fastify.

Piggybacking of off https://github.com/fastify/light-my-request/issues/35 – now that there's a current Node.js release (v22) that supports FormData as a builtin, could this library support it directly? The existing solution, form-data, seems to include some deprecated code and I suspect the difference between the builtin and the package-provided FormData might be hard to parse for folks new to the ecosystem.

I understand that there might be some difficulties with supporting native FormData. In particular, if I understand correctly, there's a "special relation" between RequestInit and FormData that gives the former access to the latter's headers; so in a fetch('/url', {body: formData}) there's no need to set the headers specifically. The form-data package supports accessing these headers through a .getHeaders() method, but I don't know of anything similar for builtin FormData.

I'm asking this here because of the fastify team's collective experience building the underpinnings of Node's fetch implementation in undici; if you have some pointers as to how to access the headers of builtin FormData, I'd be happy to take on this work. (Alternatively, if you say "this will be quite a yak shave", at least this issue can warn folks about the presence of yaks on the trail :smile:)

climba03003 commented 1 month ago

I don't understand what you means. Doesn't it already support FormData as body?

import { inject } from 'light-my-request'

function dispatch(request, response) {
  console.log('================== Request ==================')
  console.log(request.headers)
  console.log('================== Request ==================')
  request.pipe(response)
}

const formData = new FormData()
formData.append("hello", "world")
formData.append('blob', new Blob(['value']), '')
formData.append('blob-with-type', new Blob(['value'], { type: 'text/plain' }), '')
formData.append('blob-with-name', new Blob(['value']), 'file.txt')
formData.append('number', 1)

const response = await inject(dispatch, {
  method: "POST",
  url: "http://example.com/hello",
  payload: formData
})

console.log('================== Response ==================')
console.log(response.statusCode)
console.log(response.body)
console.log('================== Response ==================')
climba03003 commented 5 days ago

Closing as it already supported.