You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
52 lines
1.6 KiB
52 lines
1.6 KiB
import { TokenStore } from "@app/state/TokenStore"; |
|
import ApiError from "@common/ApiError"; |
|
import { ErrorCode } from "@common/ErrorCode"; |
|
|
|
export { ApiError }; |
|
|
|
export default class HttpApi { |
|
baseUrl: string; |
|
|
|
tokenStore: TokenStore; |
|
|
|
private get authorizationHeader(): {} | { "Authorization": string } { |
|
if (!this.tokenStore.accessToken) { |
|
return {}; |
|
} |
|
return { Authorization: `Bearer ${this.tokenStore.accessToken.token}` }; |
|
} |
|
|
|
constructor(baseUrl: string = `${location.protocol}//${location.hostname}:${location.port}/api`) { |
|
while (baseUrl.charAt(baseUrl.length - 1) === "/") { |
|
baseUrl = baseUrl.substring(0, baseUrl.length - 1); |
|
} |
|
this.baseUrl = baseUrl; |
|
|
|
this.tokenStore = new TokenStore(this); |
|
} |
|
|
|
async makeRequest(url: string, options?: RequestInit, body?: any): Promise<any> { |
|
options = options || {}; |
|
options = { |
|
headers: { |
|
"Content-Type": "application/json", |
|
...this.authorizationHeader, |
|
...options.headers || {}, |
|
}, |
|
body: JSON.stringify(body), |
|
...options, |
|
}; |
|
const response = await fetch(this.baseUrl + url, options); |
|
let responseBody: any; |
|
try { |
|
responseBody = await response.json() || {}; |
|
} catch (e) { |
|
throw new ApiError("Invalid JSON response", ErrorCode.Internal, e); |
|
} |
|
if (!response.ok) { |
|
throw new ApiError(responseBody.message || response.statusText, responseBody.code, responseBody.data); |
|
} |
|
return responseBody; |
|
} |
|
|
|
}
|
|
|