From d22bae2c603f0401eb94e2e34b5bf9fbfc52edb9 Mon Sep 17 00:00:00 2001 From: Jason Casareno Date: Fri, 29 Jul 2022 16:06:20 -0700 Subject: [PATCH 1/6] Fixing final endpoint url (WIP) --- packages/hoppscotch-app/components/smart/EnvInput.vue | 5 ++++- packages/hoppscotch-app/helpers/RequestRunner.ts | 1 + packages/hoppscotch-app/helpers/utils/EffectiveURL.ts | 10 +++++++++- packages/hoppscotch-data/src/environment.ts | 6 ++++++ 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/packages/hoppscotch-app/components/smart/EnvInput.vue b/packages/hoppscotch-app/components/smart/EnvInput.vue index 3fd0d251f..8d8dcb31b 100644 --- a/packages/hoppscotch-app/components/smart/EnvInput.vue +++ b/packages/hoppscotch-app/components/smart/EnvInput.vue @@ -41,6 +41,7 @@ import { HoppReactiveEnvPlugin } from "~/helpers/editor/extensions/HoppEnvironme import { useReadonlyStream } from "~/helpers/utils/composables" import { AggregateEnvironment, aggregateEnvs$ } from "~/newstore/environments" import { HoppReactiveVarPlugin } from "~/helpers/editor/extensions/HoppVariable" +import { restVars$ } from "~/newstore/RESTSession" const props = withDefaults( defineProps<{ @@ -114,6 +115,8 @@ const aggregateEnvs = useReadonlyStream(aggregateEnvs$, []) as Ref< AggregateEnvironment[] > +const aggregateVars = useReadonlyStream(restVars$, []) as Ref + const envVars = computed(() => props.envs ? props.envs.map((x) => ({ @@ -130,7 +133,7 @@ const varVars = computed(() => key: x.key, value: x.value, })) - : ([{ key: "size", value: "500" }] as HoppRESTVar[]) + : aggregateVars.value ) const envTooltipPlugin = new HoppReactiveEnvPlugin(envVars, view) diff --git a/packages/hoppscotch-app/helpers/RequestRunner.ts b/packages/hoppscotch-app/helpers/RequestRunner.ts index a6e38ce81..9d8722424 100644 --- a/packages/hoppscotch-app/helpers/RequestRunner.ts +++ b/packages/hoppscotch-app/helpers/RequestRunner.ts @@ -77,6 +77,7 @@ export const runRESTRequest$ = (): TaskEither< name: "Env", variables: combineEnvVariables(envs), }) + console.log("effectiveRequest", effectiveRequest) const stream = createRESTNetworkRequestStream(effectiveRequest) diff --git a/packages/hoppscotch-app/helpers/utils/EffectiveURL.ts b/packages/hoppscotch-app/helpers/utils/EffectiveURL.ts index fae74280e..fbdad1a6b 100644 --- a/packages/hoppscotch-app/helpers/utils/EffectiveURL.ts +++ b/packages/hoppscotch-app/helpers/utils/EffectiveURL.ts @@ -29,6 +29,7 @@ export interface EffectiveHoppRESTRequest extends HoppRESTRequest { effectiveFinalHeaders: { key: string; value: string }[] effectiveFinalParams: { key: string; value: string }[] effectiveFinalBody: FormData | string | null + effectiveFinalVars: { key: string; value: string }[] } /** @@ -299,14 +300,21 @@ export function getEffectiveRESTRequest( })) ) + const effectiveFinalVars = request.vars + const effectiveFinalBody = getFinalBodyFromRequest(request, envVariables) return { ...request, - effectiveFinalURL: parseTemplateString(request.endpoint, envVariables), + effectiveFinalURL: parseTemplateString( + request.endpoint, + envVariables, + request.vars + ), effectiveFinalHeaders, effectiveFinalParams, effectiveFinalBody, + effectiveFinalVars, } } diff --git a/packages/hoppscotch-data/src/environment.ts b/packages/hoppscotch-data/src/environment.ts index 415977344..6fad88619 100644 --- a/packages/hoppscotch-data/src/environment.ts +++ b/packages/hoppscotch-data/src/environment.ts @@ -9,7 +9,13 @@ export type Environment = { }[] } +export type Variables = { + key: string + value: string +}[] + const REGEX_ENV_VAR = /<<([^>]*)>>/g // "<>" +const REGEX_PATH_VAR = /{{([^>]*)}}/g // "{{myVariable}}" /** * How much times can we expand environment variables From 1e8805ab4f136a7660877d9483811e3cdf2949c9 Mon Sep 17 00:00:00 2001 From: Jason Casareno Date: Fri, 29 Jul 2022 18:03:37 -0700 Subject: [PATCH 2/6] Debugging effective final url (WIP) --- .../helpers/utils/EffectiveURL.ts | 3 +- packages/hoppscotch-data/src/pathVariables.ts | 75 +++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 packages/hoppscotch-data/src/pathVariables.ts diff --git a/packages/hoppscotch-app/helpers/utils/EffectiveURL.ts b/packages/hoppscotch-app/helpers/utils/EffectiveURL.ts index fbdad1a6b..e8e8e08ff 100644 --- a/packages/hoppscotch-app/helpers/utils/EffectiveURL.ts +++ b/packages/hoppscotch-app/helpers/utils/EffectiveURL.ts @@ -14,6 +14,7 @@ import { HoppRESTHeader, HoppRESTParam, } from "@hoppscotch/data" +import { parseTemplateStringV } from "@hoppscotch/data/src/pathVariables" import { arrayFlatMap, arraySort } from "../functional/array" import { toFormData } from "../functional/formData" import { tupleToRecord } from "../functional/record" @@ -306,7 +307,7 @@ export function getEffectiveRESTRequest( return { ...request, - effectiveFinalURL: parseTemplateString( + effectiveFinalURL: parseTemplateStringV( request.endpoint, envVariables, request.vars diff --git a/packages/hoppscotch-data/src/pathVariables.ts b/packages/hoppscotch-data/src/pathVariables.ts new file mode 100644 index 000000000..20ad20f5b --- /dev/null +++ b/packages/hoppscotch-data/src/pathVariables.ts @@ -0,0 +1,75 @@ +import { pipe } from "fp-ts/function" +import * as E from "fp-ts/Either" +import {parseTemplateStringE} from "./environment"; + +export type Environment = { + name: string + variables: { + key: string + value: string + }[] +} + +export type Variables = { + key: string + value: string +}[] + +const REGEX_ENV_VAR = /<<([^>]*)>>/g // "<>" +const REGEX_PATH_VAR = /{{([^>]*)}}/g // "{{myVariable}}" + +/** + * How much times can we expand environment variables + */ +const ENV_MAX_EXPAND_LIMIT = 10 + +/** + * Error state when there is a suspected loop while + * recursively expanding variables + */ +const ENV_EXPAND_LOOP = "ENV_EXPAND_LOOP" as const + +export function parseTemplateStringEV( + str: string, + variables: Environment["variables"], + pathVariables: Variables +) { + if (!variables || !str || !pathVariables) { + return E.right(str) + } + + let result = str + let depth = 0 + + while (result.match(REGEX_ENV_VAR) != null && depth <= ENV_MAX_EXPAND_LIMIT) { + result = decodeURI(encodeURI(result)).replace( + REGEX_ENV_VAR, + (_, p1) => variables.find((x) => x.key === p1)?.value || "" + ) + depth++ + } + + while (result.match(REGEX_PATH_VAR) != null && depth <= ENV_MAX_EXPAND_LIMIT) { + result = decodeURI(encodeURI(result)).replace( + REGEX_PATH_VAR, + (_, p1) => pathVariables.find((x) => x.key === p1)?.value || "" + ) + } + + return depth > ENV_MAX_EXPAND_LIMIT + ? E.left(ENV_EXPAND_LOOP) + : E.right(result) +} + +/** + * @deprecated Use `parseTemplateStringEV` instead + */ +export const parseTemplateStringV = ( + str: string, + variables: Environment["variables"], + pathVariables: Variables +) => + pipe( + parseTemplateStringEV(str, variables, pathVariables), + E.getOrElse(() => str) + ) From 42144b724bd0c3a1c5ceaa6909356ecfadeaaf42 Mon Sep 17 00:00:00 2001 From: Jason Casareno Date: Mon, 1 Aug 2022 11:44:24 -0700 Subject: [PATCH 3/6] Modified regex expression to pit path variables match cases --- packages/hoppscotch-data/src/pathVariables.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/hoppscotch-data/src/pathVariables.ts b/packages/hoppscotch-data/src/pathVariables.ts index 20ad20f5b..de747573a 100644 --- a/packages/hoppscotch-data/src/pathVariables.ts +++ b/packages/hoppscotch-data/src/pathVariables.ts @@ -16,7 +16,7 @@ export type Variables = { }[] const REGEX_ENV_VAR = /<<([^>]*)>>/g // "<>" -const REGEX_PATH_VAR = /{{([^>]*)}}/g // "{{myVariable}}" +const REGEX_PATH_VAR = /{{([^}]*)}}/g // "{{myVariable}}" /** * How much times can we expand environment variables From 5538b9a5b9118f6695d7badb8197e77daf962f33 Mon Sep 17 00:00:00 2001 From: Jason Casareno Date: Mon, 1 Aug 2022 12:08:19 -0700 Subject: [PATCH 4/6] Bug fix, removed console.logs --- packages/hoppscotch-app/components/http/Request.vue | 3 ++- packages/hoppscotch-app/helpers/RequestRunner.ts | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/hoppscotch-app/components/http/Request.vue b/packages/hoppscotch-app/components/http/Request.vue index d2d1b1385..f9600f608 100644 --- a/packages/hoppscotch-app/components/http/Request.vue +++ b/packages/hoppscotch-app/components/http/Request.vue @@ -348,7 +348,8 @@ const newSendRequest = async () => { const ensureMethodInEndpoint = () => { if ( !/^http[s]?:\/\//.test(newEndpoint.value) && - !newEndpoint.value.startsWith("<<") + !newEndpoint.value.startsWith("<<") && + !newEndpoint.value.startsWith("{{") ) { const domain = newEndpoint.value.split(/[/:#?]+/)[0] if (domain === "localhost" || /([0-9]+\.)*[0-9]/.test(domain)) { diff --git a/packages/hoppscotch-app/helpers/RequestRunner.ts b/packages/hoppscotch-app/helpers/RequestRunner.ts index 9d8722424..a6e38ce81 100644 --- a/packages/hoppscotch-app/helpers/RequestRunner.ts +++ b/packages/hoppscotch-app/helpers/RequestRunner.ts @@ -77,7 +77,6 @@ export const runRESTRequest$ = (): TaskEither< name: "Env", variables: combineEnvVariables(envs), }) - console.log("effectiveRequest", effectiveRequest) const stream = createRESTNetworkRequestStream(effectiveRequest) From 7bf66d8339295f7d60d7330ca9bb2dcff205eab9 Mon Sep 17 00:00:00 2001 From: Jason Casareno Date: Mon, 1 Aug 2022 13:07:27 -0700 Subject: [PATCH 5/6] Renamed file and refactored, added new TODO --- packages/hoppscotch-app/helpers/utils/EffectiveURL.ts | 2 +- .../src/{pathVariables.ts => variables.ts} | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) rename packages/hoppscotch-data/src/{pathVariables.ts => variables.ts} (85%) diff --git a/packages/hoppscotch-app/helpers/utils/EffectiveURL.ts b/packages/hoppscotch-app/helpers/utils/EffectiveURL.ts index e8e8e08ff..32f10aa56 100644 --- a/packages/hoppscotch-app/helpers/utils/EffectiveURL.ts +++ b/packages/hoppscotch-app/helpers/utils/EffectiveURL.ts @@ -14,7 +14,7 @@ import { HoppRESTHeader, HoppRESTParam, } from "@hoppscotch/data" -import { parseTemplateStringV } from "@hoppscotch/data/src/pathVariables" +import { parseTemplateStringV } from "@hoppscotch/data/src/variables" import { arrayFlatMap, arraySort } from "../functional/array" import { toFormData } from "../functional/formData" import { tupleToRecord } from "../functional/record" diff --git a/packages/hoppscotch-data/src/pathVariables.ts b/packages/hoppscotch-data/src/variables.ts similarity index 85% rename from packages/hoppscotch-data/src/pathVariables.ts rename to packages/hoppscotch-data/src/variables.ts index de747573a..110064706 100644 --- a/packages/hoppscotch-data/src/pathVariables.ts +++ b/packages/hoppscotch-data/src/variables.ts @@ -16,7 +16,7 @@ export type Variables = { }[] const REGEX_ENV_VAR = /<<([^>]*)>>/g // "<>" -const REGEX_PATH_VAR = /{{([^}]*)}}/g // "{{myVariable}}" +const REGEX_MY_VAR = /{{([^}]*)}}/g // "{{myVariable}}" /** * How much times can we expand environment variables @@ -49,9 +49,12 @@ export function parseTemplateStringEV( depth++ } - while (result.match(REGEX_PATH_VAR) != null && depth <= ENV_MAX_EXPAND_LIMIT) { + /** + * TODO: Create an error state when there is a suspected loop while recursively expanding these variables + */ + while (result.match(REGEX_MY_VAR) != null && depth <= ENV_MAX_EXPAND_LIMIT) { result = decodeURI(encodeURI(result)).replace( - REGEX_PATH_VAR, + REGEX_MY_VAR, (_, p1) => pathVariables.find((x) => x.key === p1)?.value || "" ) } From f515ac4f522cb4d6e32cb29e8cec9eb57267914f Mon Sep 17 00:00:00 2001 From: Jason Casareno Date: Mon, 1 Aug 2022 13:15:01 -0700 Subject: [PATCH 6/6] Renaming variables and parameters --- .../components/http/Variables.vue | 18 +++++++++--------- packages/hoppscotch-data/src/variables.ts | 10 +++++----- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/hoppscotch-app/components/http/Variables.vue b/packages/hoppscotch-app/components/http/Variables.vue index 0590a6a47..25fcb08da 100644 --- a/packages/hoppscotch-app/components/http/Variables.vue +++ b/packages/hoppscotch-app/components/http/Variables.vue @@ -3,7 +3,7 @@
- +
pathVariables.find((x) => x.key === p1)?.value || "" + (_, p1) => myVariables.find((x) => x.key === p1)?.value || "" ) } @@ -70,9 +70,9 @@ export function parseTemplateStringEV( export const parseTemplateStringV = ( str: string, variables: Environment["variables"], - pathVariables: Variables + myVariables: Variables ) => pipe( - parseTemplateStringEV(str, variables, pathVariables), + parseTemplateStringEV(str, variables, myVariables), E.getOrElse(() => str) )