fix: multipart form data sorting (#2067)
* fix: multipart form data sorting place all the file types in multipart form data body in the last to avoid errors due to map key being placed after file type data * refactor: fp-ify formdata file sort implementation Co-authored-by: Liyas Thomas <liyascthomas@gmail.com> Co-authored-by: Andrew Bastin <andrewbastin.k@gmail.com>
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import { pipe } from "fp-ts/function"
|
||||
import * as A from "fp-ts/Array"
|
||||
import { combineLatest, Observable } from "rxjs"
|
||||
import { map } from "rxjs/operators"
|
||||
import {
|
||||
@@ -6,6 +8,8 @@ import {
|
||||
HoppRESTRequest,
|
||||
} from "@hoppscotch/data"
|
||||
import { parseTemplateString, parseBodyEnvVariables } from "../templating"
|
||||
import { arrayFlatMap, arraySort } from "../functional/array"
|
||||
import { toFormData } from "../functional/formData"
|
||||
import { Environment, getGlobalVariables } from "~/newstore/environments"
|
||||
|
||||
export interface EffectiveHoppRESTRequest extends HoppRESTRequest {
|
||||
@@ -59,27 +63,34 @@ function getFinalBodyFromRequest(
|
||||
}
|
||||
|
||||
if (request.body.contentType === "multipart/form-data") {
|
||||
const formData = new FormData()
|
||||
return pipe(
|
||||
request.body.body,
|
||||
A.filter((x) => x.key !== "" && x.active), // Remove empty keys
|
||||
|
||||
request.body.body
|
||||
.filter((x) => x.key !== "" && x.active) // Remove empty keys
|
||||
.map(
|
||||
(x) =>
|
||||
<FormDataKeyValue>{
|
||||
active: x.active,
|
||||
isFile: x.isFile,
|
||||
key: parseTemplateString(x.key, env.variables),
|
||||
value: x.isFile
|
||||
? x.value
|
||||
: parseTemplateString(x.value, env.variables),
|
||||
}
|
||||
)
|
||||
.forEach((entry) => {
|
||||
if (!entry.isFile) formData.append(entry.key, entry.value)
|
||||
else entry.value.forEach((blob) => formData.append(entry.key, blob))
|
||||
})
|
||||
// Sort files down
|
||||
arraySort((a, b) => {
|
||||
if (a.isFile) return 1
|
||||
if (b.isFile) return -1
|
||||
return 0
|
||||
}),
|
||||
|
||||
return formData
|
||||
// FormData allows only a single blob in an entry,
|
||||
// we split array blobs into separate entries (FormData will then join them together during exec)
|
||||
arrayFlatMap((x) =>
|
||||
x.isFile
|
||||
? x.value.map((v) => ({
|
||||
key: parseTemplateString(x.key, env.variables),
|
||||
value: v as string | Blob,
|
||||
}))
|
||||
: [
|
||||
{
|
||||
key: parseTemplateString(x.key, env.variables),
|
||||
value: parseTemplateString(x.value, env.variables),
|
||||
},
|
||||
]
|
||||
),
|
||||
toFormData
|
||||
)
|
||||
} else return parseBodyEnvVariables(request.body.body, env.variables)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user