config and base request methods

This commit is contained in:
Julian Krauser 2025-01-28 15:39:30 +01:00
parent 551b6353bf
commit e9936eb35d
5 changed files with 173 additions and 0 deletions

26
src/config.ts Normal file
View file

@ -0,0 +1,26 @@
export default class Config {
private server_adress = "";
private webapi_token = "";
private access_token = "";
constructor({ serverAdress, webapiToken }: { serverAdress: string; webapiToken: string }) {
this.server_adress = serverAdress;
this.webapi_token = webapiToken;
}
public get serverAdress() {
return this.server_adress;
}
public get webapiToken() {
return this.webapi_token;
}
public get accessToken() {
return this.access_token;
}
public setAccessToken(token: string) {
this.access_token = token;
}
}

86
src/http.ts Normal file
View file

@ -0,0 +1,86 @@
import axios, { AxiosInstance } from "axios";
import { WebApiClient } from ".";
export default class http {
public http: AxiosInstance;
private host: WebApiClient;
constructor(host: WebApiClient) {
this.host = host;
this.http = axios.create({
baseURL: this.host.accessToken + "/api",
headers: {
"Cache-Control": "no-cache",
Pragma: "no-cache",
Expires: "0",
},
});
this.setRequestInterceptor();
this.setResponseInterceptor();
}
private setRequestInterceptor() {
this.http.interceptors.request.use(
(config) => {
if (config.headers && config.headers.Authorization == "") {
config.headers.Authorization = `Bearer ${this.host.accessToken}`;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
}
private setResponseInterceptor() {
this.http.interceptors.response.use(
(response) => {
return response;
},
async (error) => {
if (!error.config.url.includes("/admin")) {
return Promise.reject(error);
}
const originalRequest = error.config;
// Handle token expiration and retry the request with a refreshed token
if (error.response && error.response.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
return await this.refreshToken()
.then(() => {
return this.http(originalRequest);
})
.catch(() => {});
}
return Promise.reject(error);
}
);
}
private refreshToken(): Promise<void> {
return new Promise<void>(async (resolve, reject) => {
await this.http
.get(`/webapi/retrieve`, {
headers: {
Authorization: `Bearer ${this.host.webapiToken}`,
},
})
.then(async (response) => {
const { accessToken } = response.data;
this.host.setAccessToken(accessToken);
resolve();
})
.catch((error) => {
console.error("Error refreshing webapi token:", error);
reject("failed token retrieve");
});
});
}
}

14
src/index.ts Normal file
View file

@ -0,0 +1,14 @@
import Config from "./config";
import http from "./http";
export class WebApiClient extends Config {
private httpInstance: http;
constructor({ serverAdress, webapiToken }: { serverAdress: string; webapiToken: string }) {
super({ serverAdress, webapiToken });
this.httpInstance = new http(this);
}
get http() {
return this.httpInstance.http;
}
}

View file

@ -0,0 +1,33 @@
import { AxiosInstance, AxiosResponse } from "axios";
import {
MemberViewModel,
CreateMemberViewModel,
UpdateMemberViewModel,
} from "../../../viewmodels/admin/club/member/member.models";
import { RequestDefinition, RequestData } from "../../requeststore";
abstract class IMemberRequests {
static getAllMembers: RequestDefinition<void, void, MemberViewModel[]>;
static getMemberById: RequestDefinition<{ id: number }, void, MemberViewModel>;
static createMember: RequestDefinition<void, CreateMemberViewModel, number>;
static updateMember: RequestDefinition<{ id: number }, UpdateMemberViewModel, void>;
static deleteMember: RequestDefinition<{ id: number }, void, void>;
}
export default abstract class MemberRequests extends IMemberRequests {
static async getAllMembers(http: AxiosInstance): Promise<AxiosResponse<MemberViewModel[], any>> {
return await http.get("/admin/member");
}
static async getMemberById(http: AxiosInstance, p: RequestData<{ id: number }, void>) {
return await http.get(`/admin/member/${p.params.id}`);
}
static async createMember(http: AxiosInstance, p: RequestData<void, CreateMemberViewModel>) {
return await http.post("/admin/member", p.body);
}
static async updateMember(http: AxiosInstance, p: RequestData<{ id: number }, UpdateMemberViewModel>) {
return await http.post(`/admin/member/${p.params.id}`, p.body);
}
static async deleteMember(http: AxiosInstance, p: RequestData<{ id: number }, void>) {
return await http.post(`/admin/member/${p.params.id}`);
}
}

View file

@ -0,0 +1,14 @@
import { AxiosInstance, AxiosResponse } from "axios";
export type RequestData<PARAMS, BODY> = PARAMS extends void
? BODY extends void
? {}
: { body: BODY }
: BODY extends void
? { params: PARAMS }
: { params: PARAMS; body: BODY };
export type RequestDefinition<PARAMS = void, BODY = void, RESPONSE = void> = (
http: AxiosInstance,
params: RequestData<PARAMS, BODY>
) => Promise<AxiosResponse<RESPONSE, any>>;