Merge branch 'hoppscotch:main' into codeday/main

This commit is contained in:
Jason Jock Nava Casareno
2022-08-22 12:54:54 -07:00
committed by GitHub
2 changed files with 75 additions and 20 deletions

View File

@@ -1,3 +1,11 @@
/**
* Converts an array of key-value tuples (for e.g ["key", "value"]), into a record.
* (for eg. output -> { "key": "value" })
* NOTE: This function will discard duplicate key occurances and only keep the last occurance. If you do not want that behaviour,
* use `tupleWithSamesKeysToRecord`.
* @param tuples Array of tuples ([key, value])
* @returns A record with value corresponding to the last occurance of that key
*/
export const tupleToRecord = <
KeyType extends string | number | symbol,
ValueType
@@ -5,5 +13,32 @@ export const tupleToRecord = <
tuples: [KeyType, ValueType][]
): Record<KeyType, ValueType> =>
tuples.length > 0
? (Object.assign as any)(...tuples.map(([key, val]) => ({ [key]: val })))
? (Object.assign as any)(...tuples.map(([key, val]) => ({ [key]: val }))) // This is technically valid, but we have no way of telling TypeScript it is valid. Hence the assertion
: {}
/**
* Converts an array of key-value tuples (for e.g ["key", "value"]), into a record.
* (for eg. output -> { "key": ["value"] })
* NOTE: If you do not want the array as values (because of duplicate keys) and want to instead get the last occurance, use `tupleToRecord`
* @param tuples Array of tuples ([key, value])
* @returns A Record with values being arrays corresponding to each key occurance
*/
export const tupleWithSameKeysToRecord = <
KeyType extends string | number | symbol,
ValueType
>(
tuples: [KeyType, ValueType][]
): Record<KeyType, ValueType[]> => {
// By the end of the function we do ensure this typing, this can't be infered now though, hence the assertion
const out = {} as Record<KeyType, ValueType[]>
for (const [key, value] of tuples) {
if (!out[key]) {
out[key] = [value]
} else {
out[key].push(value)
}
}
return out
}

View File

@@ -1,6 +1,10 @@
import * as A from "fp-ts/Array"
import * as E from "fp-ts/Either"
import * as O from "fp-ts/Option"
import * as RA from "fp-ts/ReadonlyArray"
import * as S from "fp-ts/string"
import qs from "qs"
import { pipe } from "fp-ts/function"
import { flow, pipe } from "fp-ts/function"
import { combineLatest, Observable } from "rxjs"
import { map } from "rxjs/operators"
import {
@@ -9,14 +13,15 @@ import {
HoppRESTRequest,
parseTemplateString,
parseBodyEnvVariables,
parseRawKeyValueEntries,
Environment,
HoppRESTHeader,
HoppRESTParam,
parseRawKeyValueEntriesE,
parseTemplateStringE,
} from "@hoppscotch/data"
import { arrayFlatMap, arraySort } from "../functional/array"
import { toFormData } from "../functional/formData"
import { tupleToRecord } from "../functional/record"
import { tupleWithSameKeysToRecord } from "../functional/record"
import { getGlobalVariables } from "~/newstore/environments"
export interface EffectiveHoppRESTRequest extends HoppRESTRequest {
@@ -211,25 +216,40 @@ function getFinalBodyFromRequest(
}
if (request.body.contentType === "application/x-www-form-urlencoded") {
return pipe(
const parsedBodyRecord = pipe(
request.body.body,
parseRawKeyValueEntries,
parseRawKeyValueEntriesE,
E.map(
flow(
RA.toArray,
/**
* Filtering out empty keys and non-active pairs.
*/
A.filter(({ active, key }) => active && !S.isEmpty(key)),
// Filter out active
A.filter((x) => x.active),
// Convert to tuple
A.map(
({ key, value }) =>
[
parseTemplateString(key, envVariables),
parseTemplateString(value, envVariables),
] as [string, string]
),
// Tuple to Record object
tupleToRecord,
// Stringify
qs.stringify
/**
* Mapping each key-value to template-string-parser with either on array,
* which will be resolved in further steps.
*/
A.map(({ key, value }) => [
parseTemplateStringE(key, envVariables),
parseTemplateStringE(value, envVariables),
]),
/**
* Filtering and mapping only right-eithers for each key-value as [string, string].
*/
A.filterMap(([key, value]) =>
E.isRight(key) && E.isRight(value)
? O.some([key.right, value.right] as [string, string])
: O.none
),
tupleWithSameKeysToRecord,
(obj) => qs.stringify(obj, { indices: false })
)
)
)
return E.isRight(parsedBodyRecord) ? parsedBodyRecord.right : null
}
if (request.body.contentType === "multipart/form-data") {