hoppscotch/packages/hoppscotch-app/helpers/network.ts
2021-09-10 00:28:28 +05:30

142 lines
3.7 KiB
TypeScript

import { AxiosRequestConfig } from "axios"
import { BehaviorSubject, Observable } from "rxjs"
import AxiosStrategy, {
cancelRunningAxiosRequest,
} from "./strategies/AxiosStrategy"
import ExtensionStrategy, {
cancelRunningExtensionRequest,
hasExtensionInstalled,
} from "./strategies/ExtensionStrategy"
import { HoppRESTResponse } from "./types/HoppRESTResponse"
import { EffectiveHoppRESTRequest } from "./utils/EffectiveURL"
import { settingsStore } from "~/newstore/settings"
export const cancelRunningRequest = () => {
if (isExtensionsAllowed() && hasExtensionInstalled()) {
cancelRunningExtensionRequest()
} else {
cancelRunningAxiosRequest()
}
}
const isExtensionsAllowed = () => settingsStore.value.EXTENSIONS_ENABLED
const runAppropriateStrategy = (req: AxiosRequestConfig) => {
if (isExtensionsAllowed() && hasExtensionInstalled()) {
return ExtensionStrategy(req)
}
return AxiosStrategy(req)
}
/**
* Returns an identifier for how a request will be ran
* if the system is asked to fire a request
*
* @returns {"normal" | "extension" | "proxy"}
*/
export function getCurrentStrategyID() {
if (isExtensionsAllowed() && hasExtensionInstalled()) {
return "extension"
} else if (settingsStore.value.PROXY_ENABLED) {
return "proxy"
} else {
return "normal"
}
}
export const sendNetworkRequest = (req: any) =>
runAppropriateStrategy(req).finally(() => window.$nuxt.$loading.finish())
export function createRESTNetworkRequestStream(
req: EffectiveHoppRESTRequest
): Observable<HoppRESTResponse> {
const response = new BehaviorSubject<HoppRESTResponse>({
type: "loading",
req,
})
const headers = req.effectiveFinalHeaders.reduce((acc, { key, value }) => {
return Object.assign(acc, { [key]: value })
}, {})
const params = req.effectiveFinalParams.reduce((acc, { key, value }) => {
return Object.assign(acc, { [key]: value })
}, {})
const timeStart = Date.now()
runAppropriateStrategy({
method: req.method as any,
url: req.effectiveFinalURL,
headers,
params,
data: req.effectiveFinalBody,
})
.then((res: any) => {
const timeEnd = Date.now()
const contentLength = res.headers["content-length"]
? parseInt(res.headers["content-length"])
: (res.data as ArrayBuffer).byteLength
const resObj: HoppRESTResponse = {
type: "success",
statusCode: res.status,
body: res.data,
headers: Object.keys(res.headers).map((x) => ({
key: x,
value: res.headers[x],
})),
meta: {
responseSize: contentLength,
responseDuration: timeEnd - timeStart,
},
req,
}
response.next(resObj)
response.complete()
})
.catch((e) => {
if (e.response) {
const timeEnd = Date.now()
const contentLength = e.response.headers["content-length"]
? parseInt(e.response.headers["content-length"])
: (e.response.data as ArrayBuffer).byteLength
const resObj: HoppRESTResponse = {
type: "fail",
body: e.response.data,
headers: Object.keys(e.response.headers).map((x) => ({
key: x,
value: e.response.headers[x],
})),
meta: {
responseDuration: timeEnd - timeStart,
responseSize: contentLength,
},
req,
statusCode: e.response.status,
}
response.next(resObj)
response.complete()
} else {
const resObj: HoppRESTResponse = {
type: "network_fail",
error: e,
req,
}
response.next(resObj)
response.complete()
}
})
return response
}