@@ -4,6 +4,7 @@ import isFormData from "./util/isFormData"
4
4
import isFile from "./util/isFile"
5
5
6
6
import { FormDataLike } from "./FormDataLike"
7
+ import { FileLike } from "./FileLike"
7
8
8
9
export class Encoder {
9
10
/**
@@ -126,8 +127,57 @@ export class Encoder {
126
127
return length + this . #footer. byteLength
127
128
}
128
129
130
+ /**
131
+ * Creates an iterator allowing to go through form-data parts (with metadata).
132
+ * This method **will not** read the files.
133
+ *
134
+ * Using this method, you can convert form-data content into Blob:
135
+ *
136
+ * @example
137
+ *
138
+ * import {Readable} from "stream"
139
+ *
140
+ * import {Encoder} from "form-data-encoder"
141
+ *
142
+ * import {FormData} from "formdata-polyfill/esm-min.js"
143
+ * import {fileFrom} from "fetch-blob/form.js"
144
+ * import {File} from "fetch-blob/file.js"
145
+ * import {Blob} from "fetch-blob"
146
+ *
147
+ * import fetch from "node-fetch"
148
+ *
149
+ * const fd = new FormData()
150
+ *
151
+ * fd.set("field", "Just a random string")
152
+ * fd.set("file", new File(["Using files is class amazing"]))
153
+ * fd.set("fileFromPath", await fileFromPath("path/to/a/file.txt"))
154
+ *
155
+ * const encoder = new Encoder(fd)
156
+ *
157
+ * const options = {
158
+ * method: "post",
159
+ * body: new Blob(encoder, {type: encoder.contentType})
160
+ * }
161
+ *
162
+ * const response = await fetch("https://httpbin.org/post", options)
163
+ *
164
+ * console.log(await response.json())
165
+ */
166
+ * values ( ) : Generator < Uint8Array | FileLike , void , undefined > {
167
+ for ( const [ name , value ] of this . #form. entries ( ) ) {
168
+ yield this . #getFieldHeader( name , value )
169
+
170
+ yield isFile ( value ) ? value : this . #encoder. encode ( String ( value ) )
171
+
172
+ yield this . #CRLF_BYTES
173
+ }
174
+
175
+ yield this . #footer
176
+ }
177
+
129
178
/**
130
179
* Creates an async iterator allowing to perform the encoding by portions.
180
+ * This method **will** also read files.
131
181
*
132
182
* @example
133
183
*
@@ -157,22 +207,26 @@ export class Encoder {
157
207
* console.log(await response.json())
158
208
*/
159
209
async * encode ( ) : AsyncGenerator < Uint8Array , void , undefined > {
160
- for ( const [ name , value ] of this . #form) {
161
- yield this . #getFieldHeader( name , value )
162
-
163
- if ( isFile ( value ) ) {
164
- yield * value . stream ( )
210
+ for ( const part of this . values ( ) ) {
211
+ if ( isFile ( part ) ) {
212
+ yield * part . stream ( )
165
213
} else {
166
- yield this . #encoder . encode ( String ( value ) )
214
+ yield part
167
215
}
168
-
169
- yield this . #CRLF_BYTES
170
216
}
217
+ }
171
218
172
- yield this . #footer
219
+ /**
220
+ * Creates an iterator allowing to read through the encoder data using for...of loops
221
+ */
222
+ [ Symbol . iterator ] ( ) : Generator < Uint8Array | FileLike , void , undefined > {
223
+ return this . values ( )
173
224
}
174
225
175
- [ Symbol . asyncIterator ] ( ) {
226
+ /**
227
+ * Creates an **async** iterator allowing to read through the encoder data using for-await...of loops
228
+ */
229
+ [ Symbol . asyncIterator ] ( ) : AsyncGenerator < Uint8Array , void , undefined > {
176
230
return this . encode ( )
177
231
}
178
232
}
0 commit comments