form-data-encoder
Advanced tools
Comparing version 0.2.0 to 0.3.0
@@ -5,3 +5,3 @@ import { FormDataLike } from "./FormDataLike"; | ||
/** | ||
* Returns a boundary string | ||
* Returns boundary string | ||
*/ | ||
@@ -14,5 +14,12 @@ readonly boundary: string; | ||
/** | ||
* Returns headers object with Content-Type and Content-Length header | ||
*/ | ||
readonly headers: { | ||
"Content-Type": string; | ||
"Content-Length": number; | ||
}; | ||
/** | ||
* Creates a multipart/form-data encoder. | ||
* | ||
* @param form - A FormData object to encode. This object must be a spec-compatible FormData implementation. | ||
* @param form - FormData object to encode. This object must be a spec-compatible FormData implementation. | ||
* @param boundary - An optional boundary string that will be used by the encoder. If there's no boundary string is present, Encoder will generate it automatically. | ||
@@ -32,9 +39,2 @@ * | ||
constructor(form: FormDataLike, boundary?: string); | ||
/** | ||
* Returns headers for multipart/form-data | ||
*/ | ||
get headers(): { | ||
"Content-Type": string; | ||
"Content-Length": number; | ||
}; | ||
private _getFieldHeader; | ||
@@ -41,0 +41,0 @@ /** |
@@ -33,3 +33,3 @@ "use strict"; | ||
* | ||
* @param form - A FormData object to encode. This object must be a spec-compatible FormData implementation. | ||
* @param form - FormData object to encode. This object must be a spec-compatible FormData implementation. | ||
* @param boundary - An optional boundary string that will be used by the encoder. If there's no boundary string is present, Encoder will generate it automatically. | ||
@@ -67,11 +67,6 @@ * | ||
__classPrivateFieldSet(this, _footer, new TextEncoder().encode(`${DASHES}${this.boundary}${DASHES}${CRLF.repeat(2)}`)); | ||
} | ||
/** | ||
* Returns headers for multipart/form-data | ||
*/ | ||
get headers() { | ||
return { | ||
this.headers = Object.freeze({ | ||
"Content-Type": this.contentType, | ||
"Content-Length": this.getContentLength(), | ||
}; | ||
"Content-Length": this.getContentLength() | ||
}); | ||
} | ||
@@ -78,0 +73,0 @@ _getFieldHeader(name, value) { |
@@ -27,3 +27,3 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) { | ||
* | ||
* @param form - A FormData object to encode. This object must be a spec-compatible FormData implementation. | ||
* @param form - FormData object to encode. This object must be a spec-compatible FormData implementation. | ||
* @param boundary - An optional boundary string that will be used by the encoder. If there's no boundary string is present, Encoder will generate it automatically. | ||
@@ -61,11 +61,6 @@ * | ||
__classPrivateFieldSet(this, _footer, new TextEncoder().encode(`${DASHES}${this.boundary}${DASHES}${CRLF.repeat(2)}`)); | ||
} | ||
/** | ||
* Returns headers for multipart/form-data | ||
*/ | ||
get headers() { | ||
return { | ||
this.headers = Object.freeze({ | ||
"Content-Type": this.contentType, | ||
"Content-Length": this.getContentLength(), | ||
}; | ||
"Content-Length": this.getContentLength() | ||
}); | ||
} | ||
@@ -72,0 +67,0 @@ _getFieldHeader(name, value) { |
{ | ||
"name": "form-data-encoder", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"description": "Encode FormData content into the multipart/form-data format", | ||
@@ -5,0 +5,0 @@ "repository": "octet-stream/form-data-encoder", |
146
readme.md
@@ -31,3 +31,3 @@ # form-data-encoder | ||
// Set request headers provided the Encoder. | ||
// Set request headers provided by the Encoder. | ||
// The `headers` property has `Content-Type` and `Content-Length` headers. | ||
@@ -71,2 +71,122 @@ headers: encoder.headers, | ||
3. Because the Encoder is async iterable, you can use it with different targets. Let's say you want to put FormData content into `Blob`, for that you can write a function like this: | ||
```js | ||
import {randomBytes} from "crypto" | ||
import {FormData} from "formdata-polyfill/esm-min.js" | ||
import {blobFrom} from "fetch-blob/from.js" | ||
import {Encoder} from "form-data-encoder" | ||
import {Blob} from "fetch-blob" // For this example I will use v3 of this package | ||
import fetch from "node-fetch" | ||
async function toBlob(form) { | ||
// Note that Blob will lowercase the boundary string before assign it to Blob#type property. So you may need to bring your own boundary string, which must contain only lowercase alphabetic characters. | ||
const boundary = randomBytes(16).toString("hex") | ||
const encoder = new Encoder(form, boundary) | ||
const chunks = [] | ||
for await (const chunk of encoder) { | ||
chunks.push(chunk) | ||
} | ||
return new Blob(chunks, {type: encoder.contentType}) | ||
} | ||
const fd = new FormData() | ||
fd.set("name", "John Doe") | ||
fd.set("avatar", await blobFrom("path/to/an/avatar.png"). "avatar.jpg") | ||
const options = { | ||
method: "post", | ||
body: await toBlob(fd) | ||
} | ||
await fetch("https://httpbin.org/post", options) | ||
``` | ||
4. In this example we will pull FormData content into the ReadableStream: | ||
```js | ||
// This module is only necessary when you targeting Node.js or need web streams that implement Symbol.asyncIterator | ||
import {ReadableStream} from "web-streams-api/ponyfill/es2018" | ||
import {Encoder} from "form-data-encoder" | ||
import {FormData} from "formdata-node" | ||
import fetch from "node-fetch" | ||
const toReadableStream = iterator => new ReadableStream({ | ||
async pull(controller) { | ||
const {value, done} = await iterator.next() | ||
if (done) { | ||
return controller.close() | ||
} | ||
controller.enqueue(value) | ||
} | ||
}) | ||
const fd = new FormData() | ||
fd.set("field", "My hovercraft is full of eels") | ||
const encoder = new Encoder(fd) | ||
const options = { | ||
method: "post", | ||
headers: encoder.headers, | ||
body: toReadableStream(encoder.encode()) | ||
} | ||
// Note that this example requires `fetch` to support Symbol.asyncIterator, which node-fetch lacks of (but will support eventually) | ||
await fetch("https://httpbin.org/post", options) | ||
``` | ||
5. Speaking of async iterables - if HTTP client supports them, you can use encoder like this: | ||
```js | ||
import {Encoder} from "form-data-encoder" | ||
import {FormData} from "formdata-node" | ||
import fetch from "node-fetch" | ||
const fd = new FormData() | ||
fd.set("field", "My hovercraft is full of eels") | ||
const encoder = new Encoder(fd) | ||
const options = { | ||
method: "post", | ||
headers: encoder.headers, | ||
body: encoder | ||
} | ||
await fetch("https://httpbin.org/post", options) | ||
``` | ||
6. ...And for those client whose supporting form-data-encoder out of the box, the usage will be much, much more simpler: | ||
```js | ||
import {FormData} from "formdata-node" // Or any other spec-compatible implementation | ||
import fetch from "node-fetch" | ||
const fd = new FormData() | ||
fd.set("field", "My hovercraft is full of eels") | ||
const options = { | ||
method: "post", | ||
body: fd | ||
} | ||
// Note that node-fetch does NOT support form-data-encoder | ||
await fetch("https://httpbin.org/post", options) | ||
``` | ||
# Installation | ||
@@ -96,5 +216,5 @@ | ||
#### `constructor(form[, boundary]) -> {Encoder}` | ||
##### `constructor(form[, boundary]) -> {Encoder}` | ||
- **{FormDataLike}** form - A FormData object to encode. This object must be a spec-compatible FormData implementation. | ||
- **{FormDataLike}** form - FormData object to encode. This object must be a spec-compatible FormData implementation. | ||
- **{string}** boundary - An optional boundary string that will be used by the encoder. If there's no boundary string is present, Encoder will generate it automatically. | ||
@@ -104,8 +224,24 @@ | ||
#### `encode() -> {AsyncGenerator<Uint8Array, void, undefined>}` | ||
#### Instance properties | ||
##### `boundary -> {string}` | ||
Returns boundary string | ||
##### `contentType -> {string}` | ||
Returns Content-Type header for multipart/form-data | ||
##### `headers -> {object}` | ||
Returns headers object with Content-Type and Content-Length header | ||
#### Instance methods | ||
##### `encode() -> {AsyncGenerator<Uint8Array, void, undefined>}` | ||
Creates an async iterator allowing to perform the encoding by portions. | ||
#### `[Symbol.asyncIterator]() -> {AsyncGenerator<Uint8Array, void, undefined>}` | ||
##### `[Symbol.asyncIterator]() -> {AsyncGenerator<Uint8Array, void, undefined>}` | ||
An alias for `Encoder#encode()` method. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
29629
244
559