HarshvardhanCn01/Voice-Assistant
0
1# FormData2 3Spec-compliant [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) implementation for Node.js4 5[](https://codecov.io/github/octet-stream/form-data?branch=master)6[](https://github.com/octet-stream/form-data/actions/workflows/ci.yml)7[](https://github.com/octet-stream/form-data/actions/workflows/eslint.yml)8 9## Highlights10 111. Spec-compliant: implements every method of the [`FormData interface`](https://developer.mozilla.org/en-US/docs/Web/API/FormData).122. Supports Blobs and Files sourced from anywhere: you can use builtin [`fileFromPath`](#filefrompathpath-filename-options---promisefile) and [`fileFromPathSync`](#filefrompathsyncpath-filename-options---file) helpers to create a File from FS, or you can implement your `BlobDataItem` object to use a different source of data.133. Supports both ESM and CJS targets. See [`ESM/CJS support`](#esmcjs-support) section for details.144. Written on TypeScript and ships with TS typings.155. Isomorphic, but only re-exports native FormData object for browsers. If you need a polyfill for browsers, use [`formdata-polyfill`](https://github.com/jimmywarting/FormData)166. It's a [`ponyfill`](https://ponyfill.com/)! Which means, no effect has been caused on `globalThis` or native `FormData` implementation.17 18## Installation19 20You can install this package with npm:21 22```23npm install formdata-node24```25 26Or yarn:27 28```29yarn add formdata-node30```31 32Or pnpm33 34```35pnpm add formdata-node36```37 38## ESM/CJS support39 40This package is targeting ESM and CJS for backwards compatibility reasons and smoothen transition period while you convert your projects to ESM only. Note that CJS support will be removed as [Node.js v12 will reach its EOL](https://github.com/nodejs/release#release-schedule). This change will be released as major version update, so you won't miss it.41 42## Usage43 441. Let's take a look at minimal example with [got](https://github.com/sindresorhus/got):45 46```js47import {FormData} from "formdata-node"48 49// I assume Got >= 12.x is used for this example50import got from "got"51 52const form = new FormData()53 54form.set("greeting", "Hello, World!")55 56const data = await got.post("https://httpbin.org/post", {body: form}).json()57 58console.log(data.form.greeting) // => Hello, World!59```60 612. If your HTTP client does not support spec-compliant FormData, you can use [`form-data-encoder`](https://github.com/octet-stream/form-data-encoder) to encode entries:62 63```js64import {Readable} from "stream"65 66import {FormDataEncoder} from "form-data-encoder"67import {FormData} from "formdata-node"68 69// Note that `node-fetch` >= 3.x have builtin support for spec-compliant FormData, sou you'll only need the `form-data-encoder` if you use `node-fetch` <= 2.x.70import fetch from "node-fetch"71 72const form = new FormData()73 74form.set("field", "Some value")75 76const encoder = new FormDataEncoder(form)77 78const options = {79 method: "post",80 headers: encoder.headers,81 body: Readable.from(encoder)82}83 84await fetch("https://httpbin.org/post", options)85```86 873. Sending files over form-data:88 89```js90import {FormData, File} from "formdata-node" // You can use `File` from fetch-blob >= 3.x91 92import fetch from "node-fetch"93 94const form = new FormData()95const file = new File(["My hovercraft is full of eels"], "file.txt")96 97form.set("file", file)98 99await fetch("https://httpbin.org/post", {method: "post", body: form})100```101 1024. Blobs as field's values allowed too:103 104```js105import {FormData, Blob} from "formdata-node" // You can use `Blob` from fetch-blob106 107const form = new FormData()108const blob = new Blob(["Some content"], {type: "text/plain"})109 110form.set("blob", blob)111 112// Will always be returned as `File`113let file = form.get("blob")114 115// The created file has "blob" as the name by default116console.log(file.name) // -> blob117 118// To change that, you need to set filename argument manually119form.set("file", blob, "some-file.txt")120 121file = form.get("file")122 123console.log(file.name) // -> some-file.txt124```125 1265. You can also append files using `fileFromPath` or `fileFromPathSync` helpers. It does the same thing as [`fetch-blob/from`](https://github.com/node-fetch/fetch-blob#blob-part-backed-up-by-filesystem), but returns a `File` instead of `Blob`:127 128```js129import {fileFromPath} from "formdata-node/file-from-path"130import {FormData} from "formdata-node"131 132import fetch from "node-fetch"133 134const form = new FormData()135 136form.set("file", await fileFromPath("/path/to/a/file"))137 138await fetch("https://httpbin.org/post", {method: "post", body: form})139```140 1416. You can still use files sourced from any stream, but unlike in v2 you'll need some extra work to achieve that:142 143```js144import {Readable} from "stream"145 146import {FormData} from "formdata-node"147 148class BlobFromStream {149 #stream150 151 constructor(stream, size) {152 this.#stream = stream153 this.size = size154 }155 156 stream() {157 return this.#stream158 }159 160 get [Symbol.toStringTag]() {161 return "Blob"162 }163}164 165const content = Buffer.from("Stream content")166 167const stream = new Readable({168 read() {169 this.push(content)170 this.push(null)171 }172})173 174const form = new FormData()175 176form.set("stream", new BlobFromStream(stream, content.length), "file.txt")177 178await fetch("https://httpbin.org/post", {method: "post", body: form})179```180 1817. Note that if you don't know the length of that stream, you'll also need to handle form-data encoding manually or use [`form-data-encoder`](https://github.com/octet-stream/form-data-encoder) package. This is necessary to control which headers will be sent with your HTTP request:182 183```js184import {Readable} from "stream"185 186import {Encoder} from "form-data-encoder"187import {FormData} from "formdata-node"188 189const form = new FormData()190 191// You can use file-shaped or blob-shaped objects as FormData value instead of creating separate class192form.set("stream", {193 type: "text/plain",194 name: "file.txt",195 [Symbol.toStringTag]: "File",196 stream() {197 return getStreamFromSomewhere()198 }199})200 201const encoder = new Encoder(form)202 203const options = {204 method: "post",205 headers: {206 "content-type": encoder.contentType207 },208 body: Readable.from(encoder)209}210 211await fetch("https://httpbin.org/post", {method: "post", body: form})212```213 214## Comparison215 216| | formdata-node | formdata-polyfill | undici FormData | form-data |217| ---------------- | ------------- | ----------------- | --------------- | -------------------- |218| .append() | ✔️ | ✔️ | ✔️ | ✔️<sup>1</sup> |219| .set() | ✔️ | ✔️ | ✔️ | ❌ |220| .get() | ✔️ | ✔️ | ✔️ | ❌ |221| .getAll() | ✔️ | ✔️ | ✔️ | ❌ |222| .forEach() | ✔️ | ✔️ | ✔️ | ❌ |223| .keys() | ✔️ | ✔️ | ✔️ | ❌ |224| .values() | ✔️ | ✔️ | ✔️ | ❌ |225| .entries() | ✔️ | ✔️ | ✔️ | ❌ |226| Symbol.iterator | ✔️ | ✔️ | ✔️ | ❌ |227| CommonJS | ✔️ | ❌ | ✔️ | ✔️ |228| ESM | ✔️ | ✔️ | ✔️<sup>2</sup> | ✔️<sup>2</sup> |229| Blob | ✔️<sup>3</sup> | ✔️<sup>4</sup> | ✔️<sup>3</sup> | ❌ |230| Browser polyfill | ❌ | ✔️ | ✔️ | ❌ |231| Builtin encoder | ❌ | ✔️ | ✔️<sup>5</sup> | ✔️ |232 233<sup>1</sup> Does not support Blob and File in entry value, but allows streams and Buffer (which is not spec-compiant, however).234 235<sup>2</sup> Can be imported in ESM, because Node.js support for CJS modules in ESM context, but it does not have ESM entry point.236 237<sup>3</sup> Have builtin implementations of Blob and/or File, allows native Blob and File as entry value.238 239<sup>4</sup> Support Blob and File via fetch-blob package, allows native Blob and File as entry value.240 241<sup>5</sup> Have `multipart/form-data` encoder as part of their `fetch` implementation.242 243✔️ - For FormData methods, indicates that the method is present and spec-compliant. For features, shows its presence.244 245❌ - Indicates that method or feature is not implemented.246 247## API248 249### `class FormData`250 251##### `constructor([entries]) -> {FormData}`252 253Creates a new FormData instance254 255 - **{array}** [entries = null] – an optional FormData initial entries.256 Each initial field should be passed as a collection of the objects257 with "name", "value" and "filename" props.258 See the [FormData#append()](#appendname-value-filename---void) for more info about the available format.259 260#### Instance methods261 262##### `set(name, value[, filename]) -> {void}`263 264Set a new value for an existing key inside **FormData**,265or add the new field if it does not already exist.266 267 - **{string}** name – The name of the field whose data is contained in `value`.268 - **{unknown}** value – The field's value. This can be [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob)269 or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File). If none of these are specified the value is converted to a string.270 - **{string}** [filename = undefined] – The filename reported to the server, when a Blob or File is passed as the second parameter. The default filename for Blob objects is "blob". The default filename for File objects is the file's filename.271 272##### `append(name, value[, filename]) -> {void}`273 274Appends a new value onto an existing key inside a FormData object,275or adds the key if it does not already exist.276 277The difference between `set()` and `append()` is that if the specified key already exists, `set()` will overwrite all existing values with the new one, whereas `append()` will append the new value onto the end of the existing set of values.278 279 - **{string}** name – The name of the field whose data is contained in `value`.280 - **{unknown}** value – The field's value. This can be [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob)281 or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File). If none of these are specified the value is converted to a string.282 - **{string}** [filename = undefined] – The filename reported to the server, when a Blob or File is passed as the second parameter. The default filename for Blob objects is "blob". The default filename for File objects is the file's filename.283 284##### `get(name) -> {FormDataValue}`285 286Returns the first value associated with a given key from within a `FormData` object.287If you expect multiple values and want all of them, use the `getAll()` method instead.288 289 - **{string}** name – A name of the value you want to retrieve.290 291##### `getAll(name) -> {Array<FormDataValue>}`292 293Returns all the values associated with a given key from within a `FormData` object.294 295 - **{string}** name – A name of the value you want to retrieve.296 297##### `has(name) -> {boolean}`298 299Returns a boolean stating whether a `FormData` object contains a certain key.300 301 - **{string}** – A string representing the name of the key you want to test for.302 303##### `delete(name) -> {void}`304 305Deletes a key and its value(s) from a `FormData` object.306 307 - **{string}** name – The name of the key you want to delete.308 309##### `forEach(callback[, thisArg]) -> {void}`310 311Executes a given **callback** for each field of the FormData instance312 313 - **{function}** callback – Function to execute for each element, taking three arguments:314 + **{FormDataValue}** value – A value(s) of the current field.315 + **{string}** name – Name of the current field.316 + **{FormData}** form – The FormData instance that **forEach** is being applied to317 - **{unknown}** [thisArg = null] – Value to use as **this** context when executing the given **callback**318 319##### `keys() -> {Generator<string>}`320 321Returns an [`iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) allowing to go through all keys contained in this `FormData` object.322Each key is a `string`.323 324##### `values() -> {Generator<FormDataValue>}`325 326Returns an [`iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) allowing to go through all values contained in this object `FormData` object.327Each value is a [`FormDataValue`](https://developer.mozilla.org/en-US/docs/Web/API/FormDataEntryValue).328 329##### `entries() -> {Generator<[string, FormDataValue]>}`330 331Returns an [`iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) allowing to go through key/value pairs contained in this `FormData` object.332The key of each pair is a string; the value is a [`FormDataValue`](https://developer.mozilla.org/en-US/docs/Web/API/FormDataEntryValue).333 334##### `[Symbol.iterator]() -> {Generator<[string, FormDataValue]>}`335 336An alias for [`FormData#entries()`](#entries---iterator)337 338### `class Blob`339 340The `Blob` object represents a blob, which is a file-like object of immutable, raw data;341they can be read as text or binary data, or converted into a ReadableStream342so its methods can be used for processing the data.343 344##### `constructor(blobParts[, options]) -> {Blob}`345 346Creates a new `Blob` instance. The `Blob` constructor accepts following arguments:347 348 - **{(ArrayBufferLike | ArrayBufferView | File | Blob | string)[]}** blobParts – An `Array` strings, or [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer), [`ArrayBufferView`](https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView), [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) objects, or a mix of any of such objects, that will be put inside the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob);349 - **{object}** [options = {}] - An options object containing optional attributes for the file. Available options are as follows;350 - **{string}** [options.type = ""] - Returns the media type ([`MIME`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types)) of the blob represented by a `Blob` object.351 352#### Instance properties353 354##### `type -> {string}`355 356Returns the [`MIME type`](https://developer.mozilla.org/en-US/docs/Glossary/MIME_type) of the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File).357 358##### `size -> {number}`359 360Returns the size of the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) in bytes.361 362#### Instance methods363 364##### `slice([start, end, contentType]) -> {Blob}`365 366Creates and returns a new [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) object which contains data from a subset of the blob on which it's called.367 368- **{number}** [start = 0] An index into the `Blob` indicating the first byte to include in the new `Blob`. If you specify a negative value, it's treated as an offset from the end of the `Blob` toward the beginning. For example, -10 would be the 10th from last byte in the `Blob`. The default value is 0. If you specify a value for start that is larger than the size of the source `Blob`, the returned `Blob` has size 0 and contains no data.369 370- **{number}** [end = `blob`.size] An index into the `Blob` indicating the first byte that will *not* be included in the new `Blob` (i.e. the byte exactly at this index is not included). If you specify a negative value, it's treated as an offset from the end of the `Blob` toward the beginning. For example, -10 would be the 10th from last byte in the `Blob`. The default value is size.371 372- **{string}** [contentType = ""] The content type to assign to the new ``Blob``; this will be the value of its type property. The default value is an empty string.373 374##### `stream() -> {ReadableStream<Uint8Array>}`375 376Returns a [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) which upon reading returns the data contained within the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob).377 378##### `arrayBuffer() -> {Promise<ArrayBuffer>}`379 380Returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves with the contents of the blob as binary data contained in an [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer).381 382##### `text() -> {Promise<string>}`383 384Returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves with a string containing the contents of the blob, interpreted as UTF-8.385 386### `class File extends Blob`387 388The `File` class provides information about files. The `File` class inherits `Blob`.389 390##### `constructor(fileBits, filename[, options]) -> {File}`391 392Creates a new `File` instance. The `File` constructor accepts following arguments:393 394 - **{(ArrayBufferLike | ArrayBufferView | File | Blob | string)[]}** fileBits – An `Array` strings, or [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer), [`ArrayBufferView`](https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView), [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) objects, or a mix of any of such objects, that will be put inside the [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File);395 - **{string}** filename – Representing the file name.396 - **{object}** [options = {}] - An options object containing optional attributes for the file. Available options are as follows;397 - **{number}** [options.lastModified = Date.now()] – provides the last modified date of the file as the number of milliseconds since the Unix epoch (January 1, 1970 at midnight). Files without a known last modified date return the current date;398 - **{string}** [options.type = ""] - Returns the media type ([`MIME`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types)) of the file represented by a `File` object.399 400### `fileFromPath(path[, filename, options]) -> {Promise<File>}`401 402Available from `formdata-node/file-from-path` subpath.403 404Creates a `File` referencing the one on a disk by given path.405 406 - **{string}** path - Path to a file407 - **{string}** [filename] - Optional name of the file. Will be passed as the second argument in `File` constructor. If not presented, the name will be taken from the file's path.408 - **{object}** [options = {}] - Additional `File` options, except for `lastModified`.409 - **{string}** [options.type = ""] - Returns the media type ([`MIME`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types)) of the file represented by a `File` object.410 411### `fileFromPathSync(path[, filename, options]) -> {File}`412 413Available from `formdata-node/file-from-path` subpath.414 415Creates a `File` referencing the one on a disk by given path. Synchronous version of the `fileFromPath`.416 - **{string}** path - Path to a file417 - **{string}** [filename] - Optional name of the file. Will be passed as the second argument in `File` constructor. If not presented, the name will be taken from the file's path.418 - **{object}** [options = {}] - Additional `File` options, except for `lastModified`.419 - **{string}** [options.type = ""] - Returns the media type ([`MIME`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types)) of the file represented by a `File` object.420 421### `isFile(value) -> {boolean}`422 423Available from `formdata-node/file-from-path` subpath.424 425Checks if given value is a File, Blob or file-look-a-like object.426 427 - **{unknown}** value - A value to test428 429### Husky installation430 431This package is using `husky` to perform git hooks on developer's machine, so your changes might be verified before you push them to `GitHub`. If you want to install these hooks, run `npm run husky` command.432 433## Related links434 435- [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) documentation on MDN436- [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) documentation on MDN437- [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) documentation on MDN438- [`FormDataValue`](https://developer.mozilla.org/en-US/docs/Web/API/FormDataEntryValue) documentation on MDN.439- [`formdata-polyfill`](https://github.com/jimmywarting/FormData) HTML5 `FormData` for Browsers & NodeJS.440- [`node-fetch`](https://github.com/node-fetch/node-fetch) a light-weight module that brings the Fetch API to Node.js441- [`fetch-blob`](https://github.com/node-fetch/fetch-blob) a Blob implementation on node.js, originally from `node-fetch`.442- [`form-data-encoder`](https://github.com/octet-stream/form-data-encoder) spec-compliant `multipart/form-data` encoder implementation.443- [`then-busboy`](https://github.com/octet-stream/then-busboy) a promise-based wrapper around Busboy. Process multipart/form-data content and returns it as a single object. Will be helpful to handle your data on the server-side applications.444- [`@octetstream/object-to-form-data`](https://github.com/octet-stream/object-to-form-data) converts JavaScript object to FormData.445 