-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathindex.js
60 lines (50 loc) · 1.56 KB
/
index.js
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
'use strict'
const FormData = require('form-data')
const querystring = require('fast-querystring')
const { Readable } = require('stream')
module.exports = function formMethod (json, opts) {
if (!json || typeof json !== 'object') {
throw new Error('Input must be a json object')
}
const options = Object.assign({}, { payload: 'payload', headers: 'headers', forceMultiPart: false }, opts)
const form = new FormData()
const hasFile = Object.keys(json)
.flatMap(unfold.bind(json))
.reduce((isFile, { k, v }) => {
const value = getValue(v)
const options = getOptions(v)
form.append(k, value, options)
return isFile || (value && (
(typeof value.pipe === 'function' && value.readable !== false) ||
Buffer.isBuffer(value)))
}, false)
let payload
const headers = { 'content-type': null }
if (hasFile || options.forceMultiPart) {
payload = form
Object.assign(headers, form.getHeaders())
} else {
payload = Readable.from(querystring.stringify(json))
headers['content-type'] = 'application/x-www-form-urlencoded'
}
return {
[options.payload]: payload,
[options.headers]: headers
}
}
function getValue (o) { return getField(o, 'value') || o }
function getOptions (o) { return getField(o, 'options') }
function getField (o, field) {
if (typeof o === 'object' &&
Object.hasOwnProperty.call(o, field)) {
return o[field]
}
return undefined
}
function unfold (k) {
const v = this[k]
if (Array.isArray(v)) {
return v.map(subVal => { return { k, v: subVal } })
}
return { k, v }
}