fix: curl array support within multipart/form-data (#3838) (#5999)

ft: utils.createObjWithHashedKeys
ft: curlify.extractKey
test: curlify with array representation
This commit is contained in:
Tim Lai
2020-05-13 16:59:37 -07:00
committed by GitHub
parent ce45c37020
commit 96c7b4cbf5
3 changed files with 92 additions and 10 deletions

View File

@@ -67,17 +67,64 @@ export function arrayify (thing) {
return normalizeArray(thing)
}
export function fromJSOrdered (js) {
if(isImmutable(js))
export function fromJSOrdered(js) {
if (isImmutable(js)) {
return js // Can't do much here
if (js instanceof win.File)
}
if (js instanceof win.File) {
return js
}
if (!isObject(js)) {
return js
}
if (Array.isArray(js)) {
return Im.Seq(js).map(fromJSOrdered).toList()
}
if (js.entries) {
// handle multipart/form-data
const objWithHashedKeys = createObjWithHashedKeys(js)
return Im.OrderedMap(objWithHashedKeys).map(fromJSOrdered)
}
return Im.OrderedMap(js).map(fromJSOrdered)
}
return !isObject(js) ? js :
Array.isArray(js) ?
Im.Seq(js).map(fromJSOrdered).toList() :
Im.OrderedMap(js).map(fromJSOrdered)
/**
* Convert a FormData object into plain object
* Append a hashIdx and counter to the key name, if multiple exists
* if single, key name = <original>
* if multiple, key name = <original><hashIdx><count>
* @param {FormData} fdObj - a FormData object
* @return {Object} - a plain object
*/
export function createObjWithHashedKeys (fdObj) {
if (!fdObj.entries) {
return fdObj // not a FormData object with iterable
}
const newObj = {}
const hashIdx = "_**[]" // our internal identifier
const trackKeys = {}
for (let pair of fdObj.entries()) {
if (!newObj[pair[0]] && !(trackKeys[pair[0]] && trackKeys[pair[0]].containsMultiple)) {
newObj[pair[0]] = pair[1] // first key name: no hash required
} else {
if (!trackKeys[pair[0]]) {
// initiate tracking key for multiple
trackKeys[pair[0]] = {
containsMultiple: true,
length: 1
}
// "reassign" first pair to matching hashed format for multiple
let hashedKeyFirst = `${pair[0]}${hashIdx}${trackKeys[pair[0]].length}`
newObj[hashedKeyFirst] = newObj[pair[0]]
// remove non-hashed key of multiple
delete newObj[pair[0]] // first
}
trackKeys[pair[0]].length += 1
let hashedKeyCurrent = `${pair[0]}${hashIdx}${trackKeys[pair[0]].length}`
newObj[hashedKeyCurrent] = pair[1]
}
}
return newObj
}
export function bindToState(obj, state) {