Skip to content

Commit 71cfeff

Browse files
committed
Improve in-code documentation for utilities. Rename isFile.ts -> isFileLike.ts to match public API naming.
1 parent 1ed9fad commit 71cfeff

11 files changed

+80
-49
lines changed

lib/FormDataEncoder.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import createBoundary from "./util/createBoundary"
22
import isPlainObject from "./util/isPlainObject"
33
import normalize from "./util/normalizeValue"
4-
import isFormData from "./util/isFormData"
54
import escape from "./util/escapeName"
6-
import isFile from "./util/isFile"
75

6+
import {isFileLike} from "./util/isFileLike"
7+
import {isFormData} from "./util/isFormData"
88
import {FormDataLike} from "./FormDataLike"
99
import {FileLike} from "./FileLike"
1010

@@ -185,14 +185,14 @@ export class FormDataEncoder {
185185
header += `${this.#DASHES}${this.boundary}${this.#CRLF}`
186186
header += `Content-Disposition: form-data; name="${escape(name)}"`
187187

188-
if (isFile(value)) {
188+
if (isFileLike(value)) {
189189
header += `; filename="${escape(value.name)}"${this.#CRLF}`
190190
header += `Content-Type: ${value.type || "application/octet-stream"}`
191191
}
192192

193193
if (this.#options.enableAdditionalHeaders === true) {
194194
header += `${this.#CRLF}Content-Length: ${
195-
isFile(value) ? value.size : value.byteLength
195+
isFileLike(value) ? value.size : value.byteLength
196196
}`
197197
}
198198

@@ -206,11 +206,11 @@ export class FormDataEncoder {
206206
let length = 0
207207

208208
for (const [name, raw] of this.#form) {
209-
const value = isFile(raw) ? raw : this.#encoder.encode(normalize(raw))
209+
const value = isFileLike(raw) ? raw : this.#encoder.encode(normalize(raw))
210210

211211
length += this.#getFieldHeader(name, value).byteLength
212212

213-
length += isFile(value) ? value.size : value.byteLength
213+
length += isFileLike(value) ? value.size : value.byteLength
214214

215215
length += this.#CRLF_BYTES_LENGTH
216216
}
@@ -256,7 +256,7 @@ export class FormDataEncoder {
256256
*/
257257
* values(): Generator<Uint8Array | FileLike, void, undefined> {
258258
for (const [name, raw] of this.#form.entries()) {
259-
const value = isFile(raw) ? raw : this.#encoder.encode(normalize(raw))
259+
const value = isFileLike(raw) ? raw : this.#encoder.encode(normalize(raw))
260260

261261
yield this.#getFieldHeader(name, value)
262262

@@ -301,7 +301,7 @@ export class FormDataEncoder {
301301
*/
302302
async* encode(): AsyncGenerator<Uint8Array, void, undefined> {
303303
for (const part of this.values()) {
304-
if (isFile(part)) {
304+
if (isFileLike(part)) {
305305
yield* part.stream()
306306
} else {
307307
yield part

lib/index.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export * from "./FormDataEncoder"
2-
export * from "./FormDataLike"
3-
export * from "./FileLike"
42

5-
export {default as isFileLike} from "./util/isFile"
6-
export {default as isFormDataLike} from "./util/isFormData"
3+
// Utilities
4+
export * from "./FileLike"
5+
export * from "./FormDataLike"
6+
export * from "./util/isFileLike"
7+
export * from "./util/isFormData"

lib/util/createBoundary.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ const alphabet = "abcdefghijklmnopqrstuvwxyz0123456789"
66

77
/**
88
* Generates a boundary string for FormData encoder.
9+
*
10+
* @api private
11+
*
12+
* ```js
13+
* import createBoundary from "./util/createBoundary"
14+
*
15+
* createBoundary() // -> n2vw38xdagaq6lrv
16+
* ```
917
*/
1018
function createBoundary(): string {
1119
let size = 16

lib/util/escapeName.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
* See: https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#multipart-form-data
55
*
66
* @param name A fieldname to escape
7+
*
8+
* @api private
79
*/
810
const escapeName = (name: unknown) => String(name)
911
.replace(/\r/g, "%0D") // CR

lib/util/isFile.ts

Lines changed: 0 additions & 25 deletions
This file was deleted.

lib/util/isFile.test.ts renamed to lib/util/isFileLike.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ import {File, Blob} from "formdata-node"
44

55
import {FileLike} from "../FileLike"
66

7-
import isFile from "./isFile"
7+
import {isFileLike} from "./isFileLike"
88

99
test("Returns true for a File", t => {
1010
const file = new File(["Content"], "name.txt")
1111

12-
t.true(isFile(file))
12+
t.true(isFileLike(file))
1313
})
1414

1515
test("Returns true for a class that implements File", t => {
@@ -31,7 +31,7 @@ test("Returns true for a class that implements File", t => {
3131
}
3232
}
3333

34-
t.true(isFile(new MyFile()))
34+
t.true(isFileLike(new MyFile()))
3535
})
3636

3737
test("Returns true for a file-shaped object", t => {
@@ -53,23 +53,23 @@ test("Returns true for a file-shaped object", t => {
5353
}
5454
}
5555

56-
t.true(isFile(object))
56+
t.true(isFileLike(object))
5757
})
5858

5959
test("Returns false for null", t => {
60-
t.false(isFile(null))
60+
t.false(isFileLike(null))
6161
})
6262

6363
test("Returns false for undefined", t => {
64-
t.false(isFile(undefined))
64+
t.false(isFileLike(undefined))
6565
})
6666

6767
test("Returns false for non-File object", t => {
68-
t.false(isFile(new Map()))
68+
t.false(isFileLike(new Map()))
6969
})
7070

7171
test("Returns false for Blob", t => {
7272
const blob = new Blob(["Content"], {type: "text/plain"})
7373

74-
t.false(isFile(blob))
74+
t.false(isFileLike(blob))
7575
})

lib/util/isFileLike.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import isFunction from "./isFunction"
2+
3+
import {FileLike} from "../FileLike"
4+
5+
/**
6+
* Check if given object is `File`.
7+
*
8+
* Note that this function will return `false` for Blob, because the FormDataEncoder expects FormData to return File when a value is binary data.
9+
*
10+
* @param value an object to test
11+
*
12+
* @api public
13+
*
14+
* This function will return `true` for FileAPI compatible `File` objects:
15+
*
16+
* ```
17+
* import {isFileLike} from "form-data-encoder"
18+
*
19+
* isFileLike(new File(["Content"], "file.txt")) // -> true
20+
* ```
21+
*
22+
* However, if you pass a Node.js `Buffer` or `ReadStream`, it will return `false`:
23+
*
24+
* ```js
25+
* import {isFileLike} from "form-data-encoder"
26+
*
27+
* isFileLike(Buffer.from("Content")) // -> false
28+
* isFileLike(fs.createReadStream("path/to/a/file.txt")) // -> false
29+
* ```
30+
*/
31+
export const isFileLike = (value?: unknown): value is FileLike => Boolean(
32+
(value as FileLike)
33+
&& typeof (value as FileLike) === "object"
34+
&& isFunction((value as FileLike).constructor)
35+
&& (value as FileLike)[Symbol.toStringTag] === "File"
36+
&& isFunction((value as FileLike).stream)
37+
&& (value as FileLike).name != null
38+
&& (value as FileLike).size != null
39+
&& (value as FileLike).lastModified != null
40+
)

lib/util/isFormData.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import test from "ava"
22

33
import {FormData} from "formdata-node"
44

5-
import isFormData from "./isFormData"
5+
import {isFormData} from "./isFormData"
66

77
import {FormDataLike, FormDataEntryValue} from "../FormDataLike"
88

lib/util/isFormData.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {FormDataLike} from "../FormDataLike"
77
*
88
* @param value an object to test
99
*/
10-
const isFormData = (value?: unknown): value is FormDataLike => Boolean(
10+
export const isFormData = (value?: unknown): value is FormDataLike => Boolean(
1111
(value as FormDataLike)
1212
&& isFunction((value as FormDataLike).constructor)
1313
&& (value as FormDataLike)[Symbol.toStringTag] === "FormData"
@@ -16,5 +16,3 @@ const isFormData = (value?: unknown): value is FormDataLike => Boolean(
1616
&& isFunction((value as FormDataLike).entries)
1717
&& isFunction((value as FormDataLike)[Symbol.iterator])
1818
)
19-
20-
export default isFormData

lib/util/isFunction.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
/**
2+
* Checks if given value is a function.
3+
*
4+
* @api private
5+
*/
16
const isFunction = (value: unknown): value is Function => (
27
typeof value === "function"
38
)

0 commit comments

Comments
 (0)