diff --git a/components/realtime/Log.vue b/components/realtime/Log.vue
index a09fdf7ca..ef1bf74d0 100644
--- a/components/realtime/Log.vue
+++ b/components/realtime/Log.vue
@@ -17,14 +17,13 @@
{{ title }}
-
+
{{ entry.ts }}{{ getSourcePrefix(entry.source)
- }}{{ entry.payload }}{{ entry.ts }}{{ source(entry.source) }}{{ entry.payload }}
{{ $t("response.waiting_for_connection") }}
@@ -32,27 +31,14 @@
-
diff --git a/components/realtime/Mqtt.vue b/components/realtime/Mqtt.vue
index 9f1bb3b7b..5cc5f0b7f 100644
--- a/components/realtime/Mqtt.vue
+++ b/components/realtime/Mqtt.vue
@@ -145,7 +145,7 @@ import { defineComponent } from "@nuxtjs/composition-api"
import { Splitpanes, Pane } from "splitpanes"
import "splitpanes/dist/splitpanes.css"
import Paho from "paho-mqtt"
-import debounce from "~/helpers/utils/debounce"
+import debounce from "lodash/debounce"
import { logHoppRequestRunToAnalytics } from "~/helpers/fb/analytics"
import { useSetting } from "~/newstore/settings"
import useWindowSize from "~/helpers/utils/useWindowSize"
diff --git a/components/realtime/Socketio.vue b/components/realtime/Socketio.vue
index e9e461aee..7d933e3bf 100644
--- a/components/realtime/Socketio.vue
+++ b/components/realtime/Socketio.vue
@@ -165,7 +165,7 @@ import { Splitpanes, Pane } from "splitpanes"
import "splitpanes/dist/splitpanes.css"
import { io as Client } from "socket.io-client"
import wildcard from "socketio-wildcard"
-import debounce from "~/helpers/utils/debounce"
+import debounce from "lodash/debounce"
import { logHoppRequestRunToAnalytics } from "~/helpers/fb/analytics"
import { useSetting } from "~/newstore/settings"
import useWindowSize from "~/helpers/utils/useWindowSize"
diff --git a/components/realtime/Sse.vue b/components/realtime/Sse.vue
index 3d230dc38..ca78d4b1a 100644
--- a/components/realtime/Sse.vue
+++ b/components/realtime/Sse.vue
@@ -89,8 +89,8 @@
import { defineComponent } from "@nuxtjs/composition-api"
import { Splitpanes, Pane } from "splitpanes"
import "splitpanes/dist/splitpanes.css"
+import debounce from "lodash/debounce"
import { logHoppRequestRunToAnalytics } from "~/helpers/fb/analytics"
-import debounce from "~/helpers/utils/debounce"
export default defineComponent({
components: { Splitpanes, Pane },
diff --git a/components/realtime/Websocket.vue b/components/realtime/Websocket.vue
index 75220c973..2bacf97e5 100644
--- a/components/realtime/Websocket.vue
+++ b/components/realtime/Websocket.vue
@@ -205,8 +205,8 @@
import { defineComponent } from "@nuxtjs/composition-api"
import { Splitpanes, Pane } from "splitpanes"
import "splitpanes/dist/splitpanes.css"
+import debounce from "lodash/debounce"
import { logHoppRequestRunToAnalytics } from "~/helpers/fb/analytics"
-import debounce from "~/helpers/utils/debounce"
import useWindowSize from "~/helpers/utils/useWindowSize"
import { useSetting } from "~/newstore/settings"
diff --git a/helpers/lenses/htmlLens.js b/helpers/lenses/htmlLens.ts
similarity index 62%
rename from helpers/lenses/htmlLens.js
rename to helpers/lenses/htmlLens.ts
index 7a18570eb..8c4f9da65 100644
--- a/helpers/lenses/htmlLens.js
+++ b/helpers/lenses/htmlLens.ts
@@ -1,10 +1,12 @@
-const htmlLens = {
+import { Lens } from "./lenses"
+
+const htmlLens: Lens = {
lensName: "response.html",
isSupportedContentType: (contentType) =>
/\btext\/html|application\/xhtml\+xml\b/i.test(contentType),
renderer: "htmlres",
rendererImport: () =>
- import("~/components/lenses/renderers/HTMLLensRenderer"),
+ import("~/components/lenses/renderers/HTMLLensRenderer.vue"),
}
export default htmlLens
diff --git a/helpers/lenses/imageLens.js b/helpers/lenses/imageLens.ts
similarity index 67%
rename from helpers/lenses/imageLens.js
rename to helpers/lenses/imageLens.ts
index 2c49b38df..d08d204ad 100644
--- a/helpers/lenses/imageLens.js
+++ b/helpers/lenses/imageLens.ts
@@ -1,4 +1,6 @@
-const imageLens = {
+import { Lens } from "./lenses"
+
+const imageLens: Lens = {
lensName: "response.image",
isSupportedContentType: (contentType) =>
/\bimage\/(?:gif|jpeg|png|bmp|svg\+xml|x-icon|vnd\.microsoft\.icon)\b/i.test(
@@ -6,7 +8,7 @@ const imageLens = {
),
renderer: "imageres",
rendererImport: () =>
- import("~/components/lenses/renderers/ImageLensRenderer"),
+ import("~/components/lenses/renderers/ImageLensRenderer.vue"),
}
export default imageLens
diff --git a/helpers/lenses/jsonLens.js b/helpers/lenses/jsonLens.ts
similarity index 62%
rename from helpers/lenses/jsonLens.js
rename to helpers/lenses/jsonLens.ts
index 1d9135a24..28ad97348 100644
--- a/helpers/lenses/jsonLens.js
+++ b/helpers/lenses/jsonLens.ts
@@ -1,11 +1,12 @@
import { isJSONContentType } from "../utils/contenttypes"
+import { Lens } from "./lenses"
-const jsonLens = {
+const jsonLens: Lens = {
lensName: "response.json",
isSupportedContentType: isJSONContentType,
renderer: "json",
rendererImport: () =>
- import("~/components/lenses/renderers/JSONLensRenderer"),
+ import("~/components/lenses/renderers/JSONLensRenderer.vue"),
}
export default jsonLens
diff --git a/helpers/lenses/lenses.js b/helpers/lenses/lenses.js
deleted file mode 100644
index 674797fce..000000000
--- a/helpers/lenses/lenses.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import jsonLens from "./jsonLens"
-import rawLens from "./rawLens"
-import imageLens from "./imageLens"
-import htmlLens from "./htmlLens"
-import xmlLens from "./xmlLens"
-
-export const lenses = [jsonLens, imageLens, htmlLens, xmlLens, rawLens]
-
-export function getSuitableLenses(response) {
- const contentType = response.headers.find((h) => h.key === "content-type")
-
- if (!contentType) return [rawLens]
-
- const result = []
- for (const lens of lenses) {
- if (lens.isSupportedContentType(contentType.value)) result.push(lens)
- }
-
- return result
-}
-
-export function getLensRenderers() {
- const response = {}
- for (const lens of lenses) {
- response[lens.renderer] = lens.rendererImport
- }
- return response
-}
diff --git a/helpers/lenses/lenses.ts b/helpers/lenses/lenses.ts
new file mode 100644
index 000000000..a6fe10728
--- /dev/null
+++ b/helpers/lenses/lenses.ts
@@ -0,0 +1,42 @@
+import { HoppRESTResponse } from "../types/HoppRESTResponse"
+import jsonLens from "./jsonLens"
+import rawLens from "./rawLens"
+import imageLens from "./imageLens"
+import htmlLens from "./htmlLens"
+import xmlLens from "./xmlLens"
+
+export type Lens = {
+ lensName: string
+ isSupportedContentType: (contentType: string) => boolean
+ renderer: string
+ rendererImport: () => Promise
+}
+
+export const lenses: Lens[] = [jsonLens, imageLens, htmlLens, xmlLens, rawLens]
+
+export function getSuitableLenses(response: HoppRESTResponse): Lens[] {
+ // return empty array if response is loading or error
+ if (response.type === "loading" || response.type === "network_fail") return []
+
+ const contentType = response.headers.find((h) => h.key === "content-type")
+
+ if (!contentType) return [rawLens]
+
+ const result = []
+ for (const lens of lenses) {
+ if (lens.isSupportedContentType(contentType.value)) result.push(lens)
+ }
+ return result
+}
+
+type LensRenderers = {
+ [key: string]: Lens["rendererImport"]
+}
+
+export function getLensRenderers(): LensRenderers {
+ const response: LensRenderers = {}
+ for (const lens of lenses) {
+ response[lens.renderer] = lens.rendererImport
+ }
+ return response
+}
diff --git a/helpers/lenses/rawLens.js b/helpers/lenses/rawLens.js
deleted file mode 100644
index f8a18e193..000000000
--- a/helpers/lenses/rawLens.js
+++ /dev/null
@@ -1,8 +0,0 @@
-const rawLens = {
- lensName: "response.raw",
- isSupportedContentType: () => true,
- renderer: "raw",
- rendererImport: () => import("~/components/lenses/renderers/RawLensRenderer"),
-}
-
-export default rawLens
diff --git a/helpers/lenses/rawLens.ts b/helpers/lenses/rawLens.ts
new file mode 100644
index 000000000..ec3a7c64f
--- /dev/null
+++ b/helpers/lenses/rawLens.ts
@@ -0,0 +1,11 @@
+import { Lens } from "./lenses"
+
+const rawLens: Lens = {
+ lensName: "response.raw",
+ isSupportedContentType: () => true,
+ renderer: "raw",
+ rendererImport: () =>
+ import("~/components/lenses/renderers/RawLensRenderer.vue"),
+}
+
+export default rawLens
diff --git a/helpers/lenses/xmlLens.js b/helpers/lenses/xmlLens.ts
similarity index 50%
rename from helpers/lenses/xmlLens.js
rename to helpers/lenses/xmlLens.ts
index d393be5f2..2f126bbb7 100644
--- a/helpers/lenses/xmlLens.js
+++ b/helpers/lenses/xmlLens.ts
@@ -1,8 +1,11 @@
-const xmlLens = {
+import { Lens } from "./lenses"
+
+const xmlLens: Lens = {
lensName: "response.xml",
isSupportedContentType: (contentType) => /\bxml\b/i.test(contentType),
renderer: "xmlres",
- rendererImport: () => import("~/components/lenses/renderers/XMLLensRenderer"),
+ rendererImport: () =>
+ import("~/components/lenses/renderers/XMLLensRenderer.vue"),
}
export default xmlLens
diff --git a/helpers/utils/StreamUtils.ts b/helpers/utils/StreamUtils.ts
index fad17f58e..342e9b4b3 100644
--- a/helpers/utils/StreamUtils.ts
+++ b/helpers/utils/StreamUtils.ts
@@ -8,9 +8,9 @@ import { map } from "rxjs/operators"
*
* @returns The constructed object observable
*/
-export function constructFromStreams(
- streamObj: { [key in keyof T]: Observable }
-): Observable {
+export function constructFromStreams(streamObj: {
+ [key in keyof T]: Observable
+}): Observable {
return combineLatest(Object.values>(streamObj)).pipe(
map((streams) => {
const keys = Object.keys(streamObj) as (keyof T)[]
diff --git a/helpers/utils/__tests__/debounce.spec.js b/helpers/utils/__tests__/debounce.spec.js
deleted file mode 100644
index 198c103d9..000000000
--- a/helpers/utils/__tests__/debounce.spec.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import debounce from "../debounce"
-
-describe("debounce", () => {
- test("doesn't call function right after calling", () => {
- const fn = jest.fn()
-
- const debFunc = debounce(fn, 100)
- debFunc()
-
- expect(fn).not.toHaveBeenCalled()
- })
-
- test("calls the function after the given timeout", () => {
- const fn = jest.fn()
-
- jest.useFakeTimers()
-
- const debFunc = debounce(fn, 100)
- debFunc()
-
- jest.runAllTimers()
-
- expect(fn).toHaveBeenCalled()
- // expect(setTimeout).toHaveBeenCalledWith(expect.any(Function), 100)
- })
-
- test("calls the function only one time within the timeframe", () => {
- const fn = jest.fn()
-
- const debFunc = debounce(fn, 1000)
-
- for (let i = 0; i < 100; i++) debFunc()
-
- jest.runAllTimers()
-
- expect(fn).toHaveBeenCalledTimes(1)
- })
-})
diff --git a/helpers/utils/__tests__/uri.spec.js b/helpers/utils/__tests__/uri.spec.js
deleted file mode 100644
index 1b1dcf5a0..000000000
--- a/helpers/utils/__tests__/uri.spec.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import { parseUrlAndPath } from "../uri"
-
-describe("parseUrlAndPath", () => {
- test("has url and path fields", () => {
- const result = parseUrlAndPath("https://hoppscotch.io/")
-
- expect(result).toHaveProperty("url")
- expect(result).toHaveProperty("path")
- })
-
- test("parses out URL correctly", () => {
- const result = parseUrlAndPath("https://hoppscotch.io/test/page")
-
- expect(result.url).toBe("https://hoppscotch.io")
- })
- test("parses out Path correctly", () => {
- const result = parseUrlAndPath("https://hoppscotch.io/test/page")
-
- expect(result.path).toBe("/test/page")
- })
-})
diff --git a/helpers/utils/b64.js b/helpers/utils/b64.ts
similarity index 91%
rename from helpers/utils/b64.js
rename to helpers/utils/b64.ts
index 942b003c4..3b364c0e9 100644
--- a/helpers/utils/b64.js
+++ b/helpers/utils/b64.ts
@@ -1,4 +1,4 @@
-export const decodeB64StringToArrayBuffer = (input) => {
+export function decodeB64StringToArrayBuffer(input: string): ArrayBuffer {
const bytes = Math.floor((input.length / 4) * 3)
const ab = new ArrayBuffer(bytes)
const uarray = new Uint8Array(ab)
diff --git a/helpers/utils/debounce.js b/helpers/utils/debounce.js
deleted file mode 100644
index 0db17993b..000000000
--- a/helpers/utils/debounce.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// Debounce is a higher order function which makes its enclosed function be executed
-// only if the function wasn't called again till 'delay' time has passed, this helps reduce impact of heavy working
-// functions which might be called frequently
-// NOTE : Don't use lambda functions as this doesn't get bound properly in them, use the 'function (args) {}' format
-const debounce = (func, delay) => {
- let inDebounce
- return function () {
- const context = this
- const args = arguments
- clearTimeout(inDebounce)
- inDebounce = setTimeout(() => func.apply(context, args), delay)
- }
-}
-
-export default debounce
diff --git a/helpers/utils/string.js b/helpers/utils/string.js
deleted file mode 100644
index 6967e1c35..000000000
--- a/helpers/utils/string.js
+++ /dev/null
@@ -1,12 +0,0 @@
-export function getSourcePrefix(source) {
- const sourceEmojis = {
- // Source used for info messages.
- info: "\tℹ️ [INFO]:\t",
- // Source used for client to server messages.
- client: "\t⬅️ [SENT]:\t",
- // Source used for server to client messages.
- server: "\t➡️ [RECEIVED]:\t",
- }
- if (Object.keys(sourceEmojis).includes(source)) return sourceEmojis[source]
- return ""
-}
diff --git a/helpers/utils/string.ts b/helpers/utils/string.ts
new file mode 100644
index 000000000..f23107591
--- /dev/null
+++ b/helpers/utils/string.ts
@@ -0,0 +1,12 @@
+const sourceEmojis = {
+ // Source used for info messages.
+ info: "\tℹ️ [INFO]:\t",
+ // Source used for client to server messages.
+ client: "\t⬅️ [SENT]:\t",
+ // Source used for server to client messages.
+ server: "\t➡️ [RECEIVED]:\t",
+}
+
+export function getSourcePrefix(source: keyof typeof sourceEmojis) {
+ return sourceEmojis[source]
+}
diff --git a/helpers/utils/uri.js b/helpers/utils/uri.js
deleted file mode 100644
index 69b57ee04..000000000
--- a/helpers/utils/uri.js
+++ /dev/null
@@ -1,15 +0,0 @@
-export function parseUrlAndPath(value) {
- const result = {}
- try {
- const url = new URL(value)
- result.url = url.origin
- result.path = url.pathname
- } catch (e) {
- const uriRegex = value.match(
- /^((http[s]?:\/\/)?(<<[^/]+>>)?[^/]*|)(\/?.*)$/
- )
- result.url = uriRegex[1]
- result.path = uriRegex[4]
- }
- return result
-}