-
-
Notifications
You must be signed in to change notification settings - Fork 98
/
formData.ts
100 lines (95 loc) · 2.78 KB
/
formData.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import type { Wretch, Config, WretchAddon } from "../types.js"
function convertFormData(
formObject: object,
recursive: string[] | boolean = false,
config: Config,
formData = config.polyfill("FormData", true, true),
ancestors = [],
) {
Object.entries(formObject).forEach(([key, value]) => {
let formKey = ancestors.reduce((acc, ancestor) => (
acc ? `${acc}[${ancestor}]` : ancestor
), null)
formKey = formKey ? `${formKey}[${key}]` : key
if (value instanceof Array) {
for (const item of value)
formData.append(formKey, item)
} else if (
recursive &&
typeof value === "object" &&
(
!(recursive instanceof Array) ||
!recursive.includes(key)
)
) {
if (value !== null) {
convertFormData(value, recursive, config, formData, [...ancestors, key])
}
} else {
formData.append(formKey, value)
}
})
return formData
}
export interface FormDataAddon {
/**
* Converts the javascript object to a FormData and sets the request body.
*
* ```js
* const form = {
* hello: "world",
* duck: "Muscovy",
* };
*
* wretch("...").addons(FormDataAddon).formData(form).post();
* ```
*
* The `recursive` argument when set to `true` will enable recursion through all
* nested objects and produce `object[key]` keys. It can be set to an array of
* string to exclude specific keys.
*
* > Warning: Be careful to exclude `Blob` instances in the Browser, and
* > `ReadableStream` and `Buffer` instances when using the node.js compatible
* > `form-data` package.
*
* ```js
* const form = {
* duck: "Muscovy",
* duckProperties: {
* beak: {
* color: "yellow",
* },
* legs: 2,
* },
* ignored: {
* key: 0,
* },
* };
*
* // Will append the following keys to the FormData payload:
* // "duck", "duckProperties[beak][color]", "duckProperties[legs]"
* wretch("...").addons(FormDataAddon).formData(form, ["ignored"]).post();
* ```
*
* @param formObject - An object which will be converted to a FormData
* @param recursive - If `true`, will recurse through all nested objects. Can be set as an array of string to exclude specific keys.
*/
formData<T extends FormDataAddon, C, R>(this: T & Wretch<T, C, R>, formObject: object, recursive?: string[] | boolean): this
}
/**
* Adds the ability to convert a an object to a FormData and use it as a request body.
*
* ```js
* import FormDataAddon from "wretch/addons/formData"
*
* wretch().addon(FormDataAddon)
* ```
*/
const formData: WretchAddon<FormDataAddon> = {
wretch: {
formData(formObject, recursive = false) {
return this.body(convertFormData(formObject, recursive, this._config))
}
}
}
export default formData