MCPcopy
hub / github.com/rejetto/hfs / apiCall

Function apiCall

shared/api.ts:41–84  ·  view source on GitHub ↗
(cmd: string, params?: Dict, options: ApiCallOptions={})

Source from the content-addressed store, hash-verified

39type ApiData<FT> = Jsonify<FT extends (...args: any[]) => infer R ? SanitizeReturn<R> : SanitizeReturn<FT>>
40type SanitizeReturn<R> = Exclude<Awaited<R>, BackendApiError | Readable | AsyncGenerator<any>>
41export function apiCall<FT=any>(cmd: string, params?: Dict, options: ApiCallOptions={}) {
42 _.defaults(options, defaultApiCallOptions)
43 const stop = options.modal?.(cmd, params)
44 const controller = window.AbortController ? new AbortController() : undefined
45 let aborted = ''
46 const ms = 1000 * (timeoutByApi[cmd] ?? options.timeout ?? 10)
47 const timeout = ms && setTimeout(() => {
48 controller?.abort(aborted = 'timeout')
49 console.debug('API TIMEOUT', cmd, params??'')
50 }, ms)
51 const asRest = options.restUri
52 const started = new Date
53 // rebuilding the whole url makes it resistant to url-with-credentials
54 return Object.assign(fetch(`${location.origin}${asRest || (getPrefixUrl() + API_URL + cmd)}`, {
55 method: asRest ? cmd : (options.method || 'POST'),
56 headers: { 'content-type': 'application/json', 'x-hfs-anti-csrf': '1' },
57 signal: controller?.signal,
58 body: params && JSON.stringify(params),
59 }).then(async res => {
60 stop?.()
61 let body: any = await res.text()
62 let data: ApiData<FT>
63 try { data = options.skipParse ? body : JSON.parse(body) }
64 catch { data = body }
65 if (!options?.skipLog)
66 console.debug(res.ok ? 'API' : 'API FAILED', cmd, params??'', '>>', data, { started: formatTime(started), duration: (Date.now() - +started) })
67 await options.onResponse?.(res, data)
68 if (!res.ok)
69 throw new ApiError(res.status, data === body ? body : `Failed API ${cmd}: ${res.statusText}`, data)
70 return data
71 }, err => {
72 stop?.()
73 if (err?.message?.includes('fetch')) {
74 console.error(err.message)
75 throw Error("Server unreachable")
76 }
77 throw aborted || err
78 }).finally(() => clearTimeout(timeout)), {
79 abort() {
80 controller?.abort(aborted='cancel')
81 },
82 aborted: () => controller?.signal.aborted
83 })
84}
85
86export class ApiError extends Error {
87 constructor(readonly code:number, message: string, data?: any) {

Callers 15

loginFunction · 0.90
logoutFunction · 0.90
useFetchListFunction · 0.90
moveFilesFunction · 0.90
createFolderFunction · 0.90
customRestCallFunction · 0.90
deleteFilesFunction · 0.90
renameFunction · 0.90
editCommentFunction · 0.90
refreshSessionFunction · 0.90
apiNewPasswordFunction · 0.90
ContentFunction · 0.90

Calls 5

setTimeoutFunction · 0.85
getPrefixUrlFunction · 0.85
errorMethod · 0.80
stopFunction · 0.70
formatTimeFunction · 0.50

Tested by

no test coverage detected