You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
encodeFormBody can handle Blob and File values in json mode, but there's no ergonomic way for a caller to submit raw binary data (e.g. a Buffer) with a specific MIME type and filename. Without this, submitting files/binaries requires the caller to manually construct a Blob before passing it in.
Proposed Solution
Add a createBlob(data, type, filename) helper that returns a wrapped class instance (BlobEntry). encodeFormBody recognises BlobEntry values in json mode and converts them to a typed, named Blob before appending to the FormData.
Usage:
import { createBlob, encodeFormBody } from '@openfn/language-common/util';
const form = encodeFormBody({
name: 'upload',
file: createBlob(buffer, 'image/jpeg', 'photo.jpg'),
});
Implementation
Add unexported BlobEntry class to packages/common/src/util/http.js
Just thinking aloud, but would it also make sense - or maybe more sense? - to:
a) expose a createFormData() function, to get raw undici FormData object
b) expose a simple createBlob() function, to get a raw nodejs blob
This would allow users to have full control of building their own formdata object in a more normal sort of way. It would also mean the common request helper could just accept a FormData instance without needing a content type (we might need to detect it and set the headers, not sure)
Both issues could be worked around by exposing undici Form and native Blob in the runtime. Not that happy about exposing library code though - should really just be node globals in the runtime.
Had a sync with Joe,
We agreed on the approach for handling FormData for adaptors that need to work with files or binary data:
FormData Implementation: We will expose undici FormData global at the job level within common. This allows job code to create a new FormData() object and attach forms and blobs directly, specifically for use cases that involve files or binary data. If an adaptor needs to pass the FormData object, its exports must be updated.
I think we should be making standard classes like FormData and probably Blob available, so that users used to them are able to do standard Javascript manipulation of these structures.
We might also want to keep a common util for toFormData(), so long as its an easier API to use than the standard browser ones.
Where I get stuck is: FormData needs to be a global, and shoud probably use Unidici's FormData implementation to be consistent and compatible with undici. So how do we hoist it to global? Using undici's install within common might do it
Activity
josephjclark commentedon Mar 30, 2026
Just thinking aloud, but would it also make sense - or maybe more sense? - to:
a) expose a
createFormData()function, to get raw undici FormData objectb) expose a simple
createBlob()function, to get a raw nodejs blobThis would allow users to have full control of building their own formdata object in a more normal sort of way. It would also mean the common request helper could just accept a FormData instance without needing a content type (we might need to detect it and set the headers, not sure)
Both issues could be worked around by exposing undici Form and native Blob in the runtime. Not that happy about exposing library code though - should really just be node globals in the runtime.
josephjclark commentedon Mar 30, 2026
I suppose
commoncould export a FormData global, available to all job code. That would be fine.mtuchi commentedon Apr 1, 2026
Had a sync with Joe,
We agreed on the approach for handling
FormDatafor adaptors that need to work with files or binary data:FormDataImplementation: We will expose undiciFormDataglobal at the job level withincommon. This allows job code to create anew FormData()object and attach forms and blobs directly, specifically for use cases that involve files or binary data. If an adaptor needs to pass theFormDataobject, its exports must be updated.mtuchi commentedon Jul 6, 2026
@josephjclark i think it should be
createFormData()orutil.formData(formObj). I think exporting undiciFormDatais confusing.I think something like this
Internally the function uses
FormData, andFilefrom undici, what do you think?mtuchi commentedon Jul 7, 2026
Will wait for @josephjclark input here, We want to export undici FormData globally but it's notvery easy, Joe will suggest a way forward
josephjclark commentedon Jul 7, 2026
Thank you Mtuchi
I think we should be making standard classes like FormData and probably Blob available, so that users used to them are able to do standard Javascript manipulation of these structures.
We might also want to keep a common util for
toFormData(), so long as its an easier API to use than the standard browser ones.Where I get stuck is: FormData needs to be a global, and shoud probably use Unidici's FormData implementation to be consistent and compatible with undici. So how do we hoist it to global? Using undici's
installwithin common might do itmtuchi commentedon Aug 25, 2026
There is on going discussion on slack for adding native support for node api like
FormData,node:crypto.Here is the ticket from kit OpenFn/kit#1503