1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
import axios, { Axios, AxiosError, AxiosResponse } from "axios";
import { BehaviorSubject, Observable } from "rxjs";
import { identity } from "lodash";
export { axios };
export const apiBaseUrl = "/api";
export class HttpNetworkError extends Error {
constructor(public innerError?: AxiosError) {
super();
}
}
export class HttpForbiddenError extends Error {
constructor(
public type: "unauthorized" | "forbidden",
public innerError?: AxiosError
) {
super();
}
}
export class HttpNotFoundError extends Error {
constructor(public innerError?: AxiosError) {
super();
}
}
function convertNetworkError(error: AxiosError): never {
if (error.isAxiosError && error.response == null) {
throw new HttpNetworkError(error);
} else {
throw error;
}
}
function convertForbiddenError(error: AxiosError): never {
const statusCode = error.response?.status;
if (statusCode === 401 || statusCode === 403) {
throw new HttpForbiddenError(
statusCode === 401 ? "unauthorized" : "forbidden",
error
);
} else {
throw error;
}
}
function convertNotFoundError(error: AxiosError): never {
const statusCode = error.response?.status;
if (statusCode === 404) {
throw new HttpNotFoundError(error);
} else {
throw error;
}
}
export function configureAxios(axios: Axios): void {
axios.interceptors.response.use(identity, convertNetworkError);
axios.interceptors.response.use(identity, convertForbiddenError);
axios.interceptors.response.use(identity, convertNotFoundError);
}
configureAxios(axios);
const tokenSubject = new BehaviorSubject<string | null>(null);
export function getHttpToken(): string | null {
return tokenSubject.value;
}
export function setHttpToken(token: string | null): void {
tokenSubject.next(token);
if (token == null) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
delete axios.defaults.headers.common["Authorization"];
} else {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
axios.defaults.headers.common["Authorization"] = `Bearer ${token}`;
}
}
export const token$: Observable<string | null> = tokenSubject.asObservable();
export class NotModified {}
export interface BlobWithEtag {
data: Blob;
etag: string;
}
export function extractResponseData<T>(res: AxiosResponse<T>): T {
return res.data;
}
export function convertToNotModified(error: AxiosError): NotModified {
const statusCode = error.response?.status;
if (statusCode == 304) {
return new NotModified();
} else {
throw error;
}
}
export function convertToBlobWithEtag(res: AxiosResponse<Blob>): BlobWithEtag {
return {
data: res.data,
etag: (res.headers as Record<"etag", string>)["etag"],
};
}
export function extractEtag(res: AxiosResponse): string {
return (res.headers as Record<"etag", string>)["etag"];
}
export interface Page<T> {
pageNumber: number;
pageSize: number;
totalPageCount: number;
totalCount: number;
items: T[];
}
|