From 111fdccfc8802c31069e070b9977519b1054b93d Mon Sep 17 00:00:00 2001 From: Anwarul Islam Date: Thu, 10 Apr 2025 13:24:26 +0600 Subject: [PATCH] feat: allow multiple params with same key to process get request queryparams (#4975) Co-authored-by: curiouscorrelation Co-authored-by: jamesgeorge007 <25279263+jamesgeorge007@users.noreply.github.com> --- .../src/helpers/functional/filter-active.ts | 15 +++++--- .../src/helpers/functional/process-request.ts | 34 ++++++++----------- .../src/helpers/kernel/rest/request.ts | 7 ++-- 3 files changed, 31 insertions(+), 25 deletions(-) diff --git a/packages/hoppscotch-common/src/helpers/functional/filter-active.ts b/packages/hoppscotch-common/src/helpers/functional/filter-active.ts index 568701bf..15f56371 100644 --- a/packages/hoppscotch-common/src/helpers/functional/filter-active.ts +++ b/packages/hoppscotch-common/src/helpers/functional/filter-active.ts @@ -3,11 +3,18 @@ import { pipe } from "fp-ts/function" import * as A from "fp-ts/Array" export const filterActiveToRecord = ( - headers: HoppRESTRequestVariables + variables: HoppRESTRequestVariables ): Record => pipe( - headers, - A.filter((header) => header.active), - A.map((header): [string, string] => [header.key, header.value]), + variables, + A.filter((variable) => variable.active), + A.map((variable): [string, string] => [variable.key, variable.value]), (entries) => Object.fromEntries(entries) ) + +export const filterActiveParams = (params: HoppRESTRequestVariables) => + pipe( + params, + A.filter((param) => param.active), + A.map((param): [string, string] => [param.key, param.value]) + ) diff --git a/packages/hoppscotch-common/src/helpers/functional/process-request.ts b/packages/hoppscotch-common/src/helpers/functional/process-request.ts index ff2eac9e..f11f15fd 100644 --- a/packages/hoppscotch-common/src/helpers/functional/process-request.ts +++ b/packages/hoppscotch-common/src/helpers/functional/process-request.ts @@ -1,13 +1,11 @@ +import type { RelayRequest } from "@hoppscotch/kernel" +import * as E from "fp-ts/Either" import { pipe } from "fp-ts/function" import * as O from "fp-ts/Option" -import * as E from "fp-ts/Either" -import * as R from "fp-ts/Record" - import { cloneDeep } from "lodash-es" -import { useSetting } from "~/composables/settings" import superjson from "superjson" -import type { RelayRequest } from "@hoppscotch/kernel" +import { useSetting } from "~/composables/settings" const isEncoded = (value: string): boolean => pipe( @@ -26,26 +24,26 @@ const encodeParam = (value: string): string => O.getOrElse(() => value) ) -const processParams = ( - params: Record -): Record => { +const processParams = (params: [string, string][]): [string, string][] => { const encodeMode = useSetting("ENCODE_MODE").value + const needsEncoding = (v: string) => /[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]+/.test(v) - return pipe( - params, - R.map((value) => + return params.map(([key, value]) => { + const isEncodingRequired = encodeMode === "enable" || (encodeMode === "auto" && needsEncoding(value)) - ? encodeParam(value) - : value - ) - ) + + const encodedKey = isEncodingRequired ? encodeParam(key) : key + const encodedValue = isEncodingRequired ? encodeParam(value) : value + + return [encodedKey, encodedValue] + }) } const updateUrl = ( url: string, - params: Record + params: [string, string][] ): E.Either => pipe( E.tryCatch( @@ -53,9 +51,7 @@ const updateUrl = ( (e) => new Error(`Invalid URL: ${e}`) ), E.map((u) => { - Object.entries(processParams(params)).forEach(([k, v]) => - u.searchParams.append(k, v) - ) + processParams(params).forEach(([k, v]) => u.searchParams.append(k, v)) return decodeURIComponent(u.toString()) }) ) diff --git a/packages/hoppscotch-common/src/helpers/kernel/rest/request.ts b/packages/hoppscotch-common/src/helpers/kernel/rest/request.ts index bba7fa8f..585b4b6e 100644 --- a/packages/hoppscotch-common/src/helpers/kernel/rest/request.ts +++ b/packages/hoppscotch-common/src/helpers/kernel/rest/request.ts @@ -8,7 +8,10 @@ import { EffectiveHoppRESTRequest } from "~/helpers/utils/EffectiveURL" import { transformAuth, transformContent } from "~/helpers/kernel/common" import { defaultAuth } from "~/helpers/kernel/common/auth" -import { filterActiveToRecord } from "~/helpers/functional/filter-active" +import { + filterActiveToRecord, + filterActiveParams, +} from "~/helpers/functional/filter-active" export const RESTRequest = { async toRequest(request: EffectiveHoppRESTRequest): Promise { @@ -24,7 +27,7 @@ export const RESTRequest = { )() const headers = filterActiveToRecord(request.effectiveFinalHeaders) - const params = filterActiveToRecord(request.effectiveFinalParams) + const params = filterActiveParams(request.effectiveFinalParams) return { id: Date.now(),