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 { const response = new BehaviorSubject({ 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 }