2023-08-21 02:20:35 +00:00
|
|
|
import { AxiosRequestConfig } from "axios"
|
2021-07-13 05:37:29 +00:00
|
|
|
import { BehaviorSubject, Observable } from "rxjs"
|
2022-09-29 05:25:21 +00:00
|
|
|
import { cloneDeep } from "lodash-es"
|
2023-08-21 02:20:35 +00:00
|
|
|
import * as E from "fp-ts/Either"
|
2021-12-12 11:10:34 +00:00
|
|
|
import * as TE from "fp-ts/TaskEither"
|
2021-07-13 05:37:29 +00:00
|
|
|
import { HoppRESTResponse } from "./types/HoppRESTResponse"
|
|
|
|
|
import { EffectiveHoppRESTRequest } from "./utils/EffectiveURL"
|
2023-08-21 02:20:35 +00:00
|
|
|
import { getService } from "~/modules/dioc"
|
|
|
|
|
import {
|
|
|
|
|
InterceptorService,
|
|
|
|
|
NetworkResponse,
|
|
|
|
|
} from "~/services/interceptor.service"
|
2021-12-12 11:10:34 +00:00
|
|
|
|
|
|
|
|
export type NetworkStrategy = (
|
|
|
|
|
req: AxiosRequestConfig
|
|
|
|
|
) => TE.TaskEither<any, NetworkResponse>
|
|
|
|
|
|
2023-08-21 02:20:35 +00:00
|
|
|
function processResponse(
|
2021-12-12 11:10:34 +00:00
|
|
|
res: NetworkResponse,
|
|
|
|
|
req: EffectiveHoppRESTRequest,
|
|
|
|
|
backupTimeStart: number,
|
|
|
|
|
backupTimeEnd: number,
|
|
|
|
|
successState: HoppRESTResponse["type"]
|
2023-08-21 02:20:35 +00:00
|
|
|
) {
|
|
|
|
|
const contentLength = res.headers["content-length"]
|
|
|
|
|
? parseInt(res.headers["content-length"])
|
|
|
|
|
: (res.data as ArrayBuffer).byteLength
|
|
|
|
|
return <HoppRESTResponse>{
|
|
|
|
|
type: successState,
|
|
|
|
|
statusCode: res.status,
|
2023-12-04 18:01:49 +00:00
|
|
|
statusText: res.statusText,
|
2023-08-21 02:20:35 +00:00
|
|
|
body: res.data,
|
2024-06-12 08:41:43 +00:00
|
|
|
// If multi headers are present, then we can just use that, else fallback to Axios type
|
|
|
|
|
headers:
|
|
|
|
|
res.additional?.multiHeaders ??
|
|
|
|
|
Object.keys(res.headers).map((x) => ({
|
|
|
|
|
key: x,
|
|
|
|
|
value: res.headers[x],
|
|
|
|
|
})),
|
2023-08-21 02:20:35 +00:00
|
|
|
meta: {
|
|
|
|
|
responseSize: contentLength,
|
|
|
|
|
responseDuration: backupTimeEnd - backupTimeStart,
|
|
|
|
|
},
|
|
|
|
|
req,
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-07-13 05:37:29 +00:00
|
|
|
|
|
|
|
|
export function createRESTNetworkRequestStream(
|
2021-12-04 14:17:57 +00:00
|
|
|
request: EffectiveHoppRESTRequest
|
2023-08-21 02:20:35 +00:00
|
|
|
): [Observable<HoppRESTResponse>, () => void] {
|
2021-07-15 04:10:45 +00:00
|
|
|
const response = new BehaviorSubject<HoppRESTResponse>({
|
|
|
|
|
type: "loading",
|
2021-12-12 11:10:34 +00:00
|
|
|
req: request,
|
2021-07-15 04:10:45 +00:00
|
|
|
})
|
2021-07-13 05:37:29 +00:00
|
|
|
|
2023-08-21 02:20:35 +00:00
|
|
|
const req = cloneDeep(request)
|
2021-12-12 11:10:34 +00:00
|
|
|
|
2023-08-21 02:20:35 +00:00
|
|
|
const headers = req.effectiveFinalHeaders.reduce((acc, { key, value }) => {
|
|
|
|
|
return Object.assign(acc, { [key]: value })
|
|
|
|
|
}, {})
|
2021-12-12 11:10:34 +00:00
|
|
|
|
2023-08-21 02:20:35 +00:00
|
|
|
const params = new URLSearchParams()
|
|
|
|
|
for (const param of req.effectiveFinalParams) {
|
|
|
|
|
params.append(param.key, param.value)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const backupTimeStart = Date.now()
|
2021-07-15 04:10:45 +00:00
|
|
|
|
2023-08-21 02:20:35 +00:00
|
|
|
const service = getService(InterceptorService)
|
2021-07-15 04:10:45 +00:00
|
|
|
|
2023-08-21 02:20:35 +00:00
|
|
|
const res = service.runRequest({
|
|
|
|
|
method: req.method as any,
|
|
|
|
|
url: req.effectiveFinalURL.trim(),
|
|
|
|
|
headers,
|
|
|
|
|
params,
|
|
|
|
|
data: req.effectiveFinalBody,
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
res.response.then((res) => {
|
|
|
|
|
const backupTimeEnd = Date.now()
|
|
|
|
|
|
|
|
|
|
if (E.isRight(res)) {
|
|
|
|
|
const processedRes = processResponse(
|
|
|
|
|
res.right,
|
|
|
|
|
req,
|
|
|
|
|
backupTimeStart,
|
|
|
|
|
backupTimeEnd,
|
|
|
|
|
"success"
|
|
|
|
|
)
|
2021-07-15 04:10:45 +00:00
|
|
|
|
2023-08-21 02:20:35 +00:00
|
|
|
response.next(processedRes)
|
2021-12-12 11:10:34 +00:00
|
|
|
response.complete()
|
2021-07-15 04:10:45 +00:00
|
|
|
|
2023-08-21 02:20:35 +00:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
response.next({
|
|
|
|
|
type: "network_fail",
|
|
|
|
|
req,
|
|
|
|
|
error: res.left,
|
2021-07-15 04:10:45 +00:00
|
|
|
})
|
2023-08-21 02:20:35 +00:00
|
|
|
response.complete()
|
|
|
|
|
})
|
2021-07-13 05:37:29 +00:00
|
|
|
|
2023-08-21 02:20:35 +00:00
|
|
|
return [response, () => res.cancel()]
|
2021-07-13 05:37:29 +00:00
|
|
|
}
|