Gathering detailed insights and metrics for @chainsafe/form-data-encoder
Gathering detailed insights and metrics for @chainsafe/form-data-encoder
Encode FormData content into the multipart/form-data format
npm install @chainsafe/form-data-encoder
Typescript
Module System
Min. Node Version
Node Version
NPM Version
72.3
Supply Chain
98.9
Quality
75
Maintenance
100
Vulnerability
100
License
TypeScript (99.45%)
JavaScript (0.55%)
Total Downloads
3,349
Last Day
2
Last Week
18
Last Month
114
Last Year
1,242
219 Commits
1 Watching
2 Branches
27 Contributors
Minified
Minified + Gzipped
Latest Version
1.0.0
Package Id
@chainsafe/form-data-encoder@1.0.0
Unpacked Size
40.39 kB
Size
10.79 kB
File Count
29
NPM Version
8.4.1
Node Version
14.17.4
Cumulative downloads
Total Downloads
Last day
-50%
2
Compared to previous day
Last week
-5.3%
18
Compared to previous week
Last month
-37.7%
114
Compared to previous month
Last year
4.3%
1,242
Compared to previous year
22
Encode FormData
content into the multipart/form-data
format
This version of the package removes the type: "module"
declaration from the package.json, as well as updating the compilation target to ES2015
and module compilation to CommonJS
You can install this package using npm:
1npm install @chainsafe/form-data-encoder
Or yarn:
1yarn add @chainsafe/form-data-encoder
Or pnpm:
1pnpm add @chainsafe/form-data-encoder
1import { Readable } from "stream"; 2 3import { FormData, File } from "formdata-node"; 4import { FormDataEncoder } from "@chainsafe/form-data-encoder"; 5 6import fetch from "node-fetch"; 7 8const form = new FormData(); 9 10form.set("greeting", "Hello, World!"); 11form.set( 12 "file", 13 new File(["On Soviet Moon landscape see binoculars through YOU"], "file.txt") 14); 15 16const encoder = new FormDataEncoder(form); 17 18const options = { 19 method: "post", 20 21 // Set request headers provided by the Encoder. 22 // The `headers` property has `Content-Type` and `Content-Length` headers. 23 headers: encoder.headers, 24 25 // Create a Readable stream from the Encoder. 26 // You can omit usage of `Readable.from` for HTTP clients whose support async iterables in request body. 27 // The Encoder will yield FormData content portions encoded into the multipart/form-data format as node-fetch consumes the stream. 28 body: Readable.from(encoder.encode()), // or just Readable.from(encoder) 29}; 30 31const response = await fetch("https://httpbin.org/post", options); 32 33console.log(await response.json());
formdata-polyfill
:1import { Readable } from "stream"; 2 3import { FormDataEncoder } from "@chainsafe/form-data-encoder"; 4import { FormData } from "formdata-polyfill/esm-min.js"; 5import { File } from "fetch-blob"; // v3 6 7const form = new FormData(); 8 9form.set("field", "Some value"); 10form.set("file", new File(["File content goes here"], "file.txt")); 11 12const encoder = new FormDataEncoder(form); 13 14const options = { 15 method: "post", 16 headers: encoder.headers, 17 body: Readable.from(encoder), 18}; 19 20await fetch("https://httpbin.org/post", options);
Blob
, for that you can write a function like this:1import { Readable } from "stream"; 2 3import { FormDataEncoder } from "@chainsafe/form-data-encoder"; 4 5import { FormData, File, Blob, fileFromPath } from "formdata-node"; 6 7import fetch from "node-fetch"; 8 9const form = new FormData(); 10 11form.set("field", "Just a random string"); 12form.set("file", new File(["Using files is class amazing"], "file.txt")); 13form.set("fileFromPath", await fileFromPath("path/to/a/file.txt")); 14 15// Note 1: When using with native Blob or fetch-blob@2 you might also need to generate boundary string for your FormDataEncoder instance 16// because Blob will lowercase value of the `type` option and default boundary generator produces a string with both lower and upper cased alphabetical characters. Math.random() should be enough to fix this: 17// const encoder = new FormDataEncoder(form, String(Math.random())) 18const encoder = new FormDataEncoder(form); 19 20const options = { 21 method: "post", 22 23 // Note 2: To use this approach with fetch-blob@2 you probably gonna need to convert the encoder parts output to an array first: 24 // new Blob([...encoder], {type: encoder.contentType}) 25 body: new Blob(encoder, { type: encoder.contentType }), 26}; 27 28const response = await fetch("https://httpbin.org/post", options); 29 30console.log(await response.json());
1import { FormData } from "formdata-polyfill/esm-min.js"; 2import { blobFrom } from "fetch-blob/from.js"; 3import { FormDataEncoder } from "@chainsafe/form-data-encoder"; 4 5import Blob from "fetch-blob"; 6import fetch from "node-fetch"; 7 8// This approach may require much more RAM compared to the previous one, but it works too. 9async function toBlob(form) { 10 const encoder = new Encoder(form); 11 const chunks = []; 12 13 for await (const chunk of encoder) { 14 chunks.push(chunk); 15 } 16 17 return new Blob(chunks, { type: encoder.contentType }); 18} 19 20const form = new FormData(); 21 22form.set("name", "John Doe"); 23form.set("avatar", await blobFrom("path/to/an/avatar.png"), "avatar.png"); 24 25const options = { 26 method: "post", 27 body: await toBlob(form), 28}; 29 30await fetch("https://httpbin.org/post", options);
form-data-encoder
is making a Blob-ish class:1import { Readable } from "stream"; 2 3import { FormDataEncoder } from "@chainsafe/form-data-encoder"; 4import { FormData } from "formdata-polyfill/esm-min.js"; 5import { blobFrom } from "fetch-blob/from.js"; 6 7import Blob from "fetch-blob"; 8import fetch from "node-fetch"; 9 10class BlobDataItem { 11 constructor(encoder) { 12 this.#encoder = encoder; 13 this.#size = encoder.headers["Content-Length"]; 14 this.#type = encoder.headers["Content-Type"]; 15 } 16 17 get type() { 18 return this.#type; 19 } 20 21 get size() { 22 return this.#size; 23 } 24 25 stream() { 26 return Readable.from(this.#encoder); 27 } 28 29 get [Symbol.toStringTag]() { 30 return "Blob"; 31 } 32} 33 34const form = new FormData(); 35 36form.set("name", "John Doe"); 37form.set("avatar", await blobFrom("path/to/an/avatar.png"), "avatar.png"); 38 39const encoder = new FormDataEncoder(form); 40 41// Note that node-fetch@2 performs more strictness tests for Blob objects, so you may need to do extra steps before you set up request body (like, maybe you'll need to instaniate a Blob with BlobDataItem as one of its blobPart) 42const blob = new BlobDataItem(enocoder); // or new Blob([new BlobDataItem(enocoder)], {type: encoder.contentType}) 43 44const options = { 45 method: "post", 46 body: blob, 47}; 48 49await fetch("https://httpbin.org/post", options);
1// This module is only necessary when you targeting Node.js or need web streams that implement Symbol.asyncIterator 2import { ReadableStream } from "web-streams-polyfill/ponyfill/es2018"; 3 4import { FormDataEncoder } from "@chainsafe/form-data-encoder"; 5import { FormData } from "formdata-node"; 6 7import fetch from "node-fetch"; 8 9function toReadableStream(encoder) { 10 const iterator = encoder.encode(); 11 12 return new ReadableStream({ 13 async pull(controller) { 14 const { value, done } = await iterator.next(); 15 16 if (done) { 17 return controller.close(); 18 } 19 20 controller.enqueue(value); 21 }, 22 }); 23} 24 25const form = new FormData(); 26 27form.set("field", "My hovercraft is full of eels"); 28 29const encoder = new FormDataEncoder(form); 30 31const options = { 32 method: "post", 33 headers: encoder.headers, 34 body: toReadableStream(encoder), 35}; 36 37// Note that this example requires `fetch` to support Symbol.asyncIterator, which node-fetch lacks of (but will support eventually) 38await fetch("https://httpbin.org/post", options);
1import { FormDataEncoder } from "@chainsafe/form-data-encoder"; 2import { FormData } from "formdata-node"; 3 4import fetch from "node-fetch"; 5 6const form = new FormData(); 7 8form.set("field", "My hovercraft is full of eels"); 9 10const encoder = new FormDataEncoder(form); 11 12const options = { 13 method: "post", 14 headers: encoder.headers, 15 body: encoder, 16}; 17 18await fetch("https://httpbin.org/post", options);
1import { FormData } from "formdata-node"; // Or any other spec-compatible implementation 2 3import fetch from "node-fetch"; 4 5const form = new FormData(); 6 7form.set("field", "My hovercraft is full of eels"); 8 9const options = { 10 method: "post", 11 body: form, 12}; 13 14// Note that node-fetch does NOT support form-data-encoder 15await fetch("https://httpbin.org/post", options);
class FormDataEncoder
constructor(form[, boundary, options]) -> {FormDataEncoder}
Content-Length
. Please note that the web clients do not include these, so when enabled this option might cause an error if multipart/form-data
does not consider additional headers.Creates a multipart/form-data
encoder.
boundary -> {string}
Returns boundary string.
contentType -> {string}
Returns Content-Type header.
contentLength -> {string}
Return Content-Length header.
headers -> {object}
Returns headers object with Content-Type and Content-Length header.
values() -> {Generator<Uint8Array | FileLike, void, undefined>}
Creates an iterator allowing to go through form-data parts (with metadata). This method will not read the files.
encode() -> {AsyncGenerator<Uint8Array, void, undefined>}
Creates an async iterator allowing to perform the encoding by portions. This method will also read files.
[Symbol.iterator]() -> {Generator<Uint8Array | FileLike, void, undefined>}
An alias for Encoder#values()
method.
[Symbol.asyncIterator]() -> {AsyncGenerator<Uint8Array, void, undefined>}
An alias for Encoder#encode()
method.
isFile(value) -> {boolean}
Check if a value is File-ish object.
isFormData(value) -> {boolean}
Check if a value is FormData-ish object.
No vulnerabilities found.
No security vulnerabilities found.