diff --git a/packages/hoppscotch-common/package.json b/packages/hoppscotch-common/package.json index 0152e9b1..50709480 100644 --- a/packages/hoppscotch-common/package.json +++ b/packages/hoppscotch-common/package.json @@ -21,7 +21,7 @@ "do-lintfix": "pnpm run lintfix" }, "dependencies": { - "@apidevtools/swagger-parser": "10.1.0", + "@apidevtools/swagger-parser": "10.1.1", "@codemirror/autocomplete": "6.18.1", "@codemirror/commands": "6.7.0", "@codemirror/lang-javascript": "6.2.2", diff --git a/packages/hoppscotch-common/src/components/importExport/ImportExportSteps/UrlImport.vue b/packages/hoppscotch-common/src/components/importExport/ImportExportSteps/UrlImport.vue index d675397f..e91211de 100644 --- a/packages/hoppscotch-common/src/components/importExport/ImportExportSteps/UrlImport.vue +++ b/packages/hoppscotch-common/src/components/importExport/ImportExportSteps/UrlImport.vue @@ -45,7 +45,11 @@ import { computed, ref, watch } from "vue" import { useI18n } from "@composables/i18n" import { useToast } from "~/composables/toast" -import axios, { AxiosResponse } from "axios" +import { InterceptorService } from "~/services/interceptor.service" +import { useService } from "dioc/vue" +import * as E from "fp-ts/Either" + +const interceptorService = useService(InterceptorService) const t = useI18n() @@ -54,7 +58,7 @@ const toast = useToast() const props = withDefaults( defineProps<{ caption: string - fetchLogic?: (url: string) => Promise> + fetchLogic?: (url: string) => Promise> loading?: boolean description?: string }>(), @@ -79,7 +83,8 @@ const disableImportCTA = computed(() => !hasURL.value || props.loading) const urlFetchLogic = props.fetchLogic ?? async function (url: string) { - const res = await axios.get(url, { + const res = await interceptorService.runRequest({ + url: url, transitional: { forcedJSONParsing: false, silentJSONParsing: false, @@ -87,23 +92,38 @@ const urlFetchLogic = }, }) - return res + const response = await res.response + + if (E.isLeft(response)) { + return E.left("REQUEST_FAILED") + } + + // convert ArrayBuffer to string + if (!(response.right.data instanceof ArrayBuffer)) { + return E.left("REQUEST_FAILED") + } + + try { + return E.right( + InterceptorService.convertArrayBufferToString(response.right.data) + ) + } catch (e) { + return E.left("REQUEST_FAILED") + } } async function fetchUrlData() { isFetchingUrl.value = true + const res = await urlFetchLogic(inputChooseGistToImportFrom.value) - try { - const res = await urlFetchLogic(inputChooseGistToImportFrom.value) - - if (res.status === 200) { - emit("importFromURL", res.data) - } - } catch (e) { + if (E.isLeft(res)) { toast.error(t("import.failed")) - console.log(e) - } finally { isFetchingUrl.value = false + return } + + emit("importFromURL", res.right) + + isFetchingUrl.value = false } diff --git a/packages/hoppscotch-common/src/helpers/import-export/import/import-sources/GistSource.ts b/packages/hoppscotch-common/src/helpers/import-export/import/import-sources/GistSource.ts index 7e3b5e73..b7486783 100644 --- a/packages/hoppscotch-common/src/helpers/import-export/import/import-sources/GistSource.ts +++ b/packages/hoppscotch-common/src/helpers/import-export/import/import-sources/GistSource.ts @@ -1,4 +1,3 @@ -import axios from "axios" import UrlImport from "~/components/importExport/ImportExportSteps/UrlImport.vue" import { defineStep } from "~/composables/step-components" @@ -7,6 +6,10 @@ import { z } from "zod" import { v4 as uuidv4 } from "uuid" import { Ref } from "vue" +import { getService } from "~/modules/dioc" +import { InterceptorService } from "~/services/interceptor.service" + +const interceptorService = getService(InterceptorService) export function GistSource(metadata: { caption: string @@ -44,9 +47,32 @@ export function GistSource(metadata: { })) } -const fetchGistFromUrl = (url: string) => - axios.get(`https://api.github.com/gists/${url.split("/").pop()}`, { +const fetchGistFromUrl = async (url: string) => { + const res = await interceptorService.runRequest({ + url: `https://api.github.com/gists/${url.split("/").pop()}`, headers: { Accept: "application/vnd.github.v3+json", }, }) + + const response = await res.response + + if (E.isLeft(response)) { + return E.left("REQUEST_FAILED") + } + + // convert ArrayBuffer to string + if (!(response.right.data instanceof ArrayBuffer)) { + return E.left("REQUEST_FAILED") + } + + try { + return E.right( + JSON.parse( + InterceptorService.convertArrayBufferToString(response.right.data) + ) + ) + } catch (e) { + return E.left("REQUEST_FAILED") + } +} diff --git a/packages/hoppscotch-common/src/helpers/import-export/import/openapi.ts b/packages/hoppscotch-common/src/helpers/import-export/import/openapi.ts index c2db7c2b..dddf4876 100644 --- a/packages/hoppscotch-common/src/helpers/import-export/import/openapi.ts +++ b/packages/hoppscotch-common/src/helpers/import-export/import/openapi.ts @@ -179,12 +179,25 @@ const parseOpenAPIV3Responses = ( }, ] + let stringifiedBody = "" + + // I think it'll be better to just drop the response body with circular refs + // because it's not possible to stringify them, using stringify from a library like flatted, will change the structure, + // and it converts the object into an array format, which can only be parsed back by the parse method from the same library + // also we're displaying it as a string, so doesnt make much sense + try { + stringifiedBody = JSON.stringify(body ?? "") + // the parsing will fail for a circular response schema + } catch (e) { + // eat five star, do nothing + } + res[name] = { name, status, code, headers, - body: JSON.stringify(body ?? ""), + body: stringifiedBody, originalRequest, } } diff --git a/packages/hoppscotch-common/src/services/interceptor.service.ts b/packages/hoppscotch-common/src/services/interceptor.service.ts index 629240f6..92ee2505 100644 --- a/packages/hoppscotch-common/src/services/interceptor.service.ts +++ b/packages/hoppscotch-common/src/services/interceptor.service.ts @@ -258,4 +258,8 @@ export class InterceptorService extends Service { return interceptor.runRequest(req) } + + public static convertArrayBufferToString(data: ArrayBuffer): string { + return new TextDecoder().decode(data).replace(/\0+$/, "") + } }