This commit is contained in:
Christian Fehmer 2024-06-01 03:12:24 +02:00
parent 4d6a7ad2d8
commit 37832b26c1
No known key found for this signature in database
GPG key ID: FE53784A69964062
6 changed files with 69 additions and 130 deletions

View file

@ -116,7 +116,7 @@ export const configUpdate = rateLimit({
export const configGet = rateLimit({
windowMs: ONE_HOUR_MS,
max: 1 * REQUEST_MULTIPLIER,
max: 120 * REQUEST_MULTIPLIER,
keyGenerator: getKeyWithUid,
handler: customHandler,
});

View file

@ -0,0 +1,60 @@
import { AppRouter, initClient, type ApiFetcherArgs } from "@ts-rest/core";
import { Axios, AxiosError, AxiosResponse, Method, isAxiosError } from "axios";
import { getIdToken } from "firebase/auth";
import { envConfig } from "../../constants/env-config";
import { getAuthenticatedUser, isAuthenticated } from "../../firebase";
function buildApi(axios: Axios): (args: ApiFetcherArgs) => Promise<{
status: number;
body: unknown;
headers: Headers;
}> {
//@ts-expect-error trust me bro
return async (args: ApiFetcherArgs) => {
const token = isAuthenticated()
? await getIdToken(getAuthenticatedUser())
: "";
try {
const result = await axios.request({
method: args.method as Method,
url: args.path,
headers: {
...args.headers,
Authorization: `Bearer ${token}`,
"X-Client-Version": envConfig.clientVersion,
},
data: args.body,
});
return {
status: result.status,
body: result.data,
headers: result.headers,
};
} catch (e: Error | AxiosError | unknown) {
if (isAxiosError(e)) {
const error = e as AxiosError;
const response = error.response as AxiosResponse;
return {
status: response.status,
body: response.data,
headers: response.headers,
};
}
throw e;
}
};
}
/* eslint-disable @typescript-eslint/explicit-function-return-type */
export function buildClient<T extends AppRouter>(
contract: T,
axios: Axios,
baseUrl: string
) {
return initClient(contract, {
baseUrl: baseUrl,
jsonQuery: true,
api: buildApi(axios),
});
}
/* eslint-enable @typescript-eslint/explicit-function-return-type */

View file

@ -1,60 +0,0 @@
import { initClient } from "@ts-rest/core";
import {
GetConfig,
configContract,
} from "./../../../../../shared/contract/config.contract";
import { getAuthenticatedUser, isAuthenticated } from "../../firebase";
import { getIdToken } from "firebase/auth";
import { Axios, AxiosError, AxiosResponse, Method, isAxiosError } from "axios";
export default class Users {
private client;
constructor(baseUrl: string, axios: Axios) {
this.client = initClient(configContract, {
baseUrl,
jsonQuery: true,
//TODO extract
api: async ({ path, method, headers, body }) => {
const token = isAuthenticated()
? await getIdToken(getAuthenticatedUser())
: "";
try {
const result = await axios.request({
method: method as Method,
url: path,
headers: {
...headers,
Authorization: `Bearer ${token}`,
},
data: body,
});
return {
status: result.status,
body: result.data,
headers: result.headers,
};
} catch (e: Error | AxiosError | unknown) {
if (isAxiosError(e)) {
const error = e as AxiosError;
const response = error.response as AxiosResponse;
return {
status: response.status,
body: response.data,
headers: response.headers,
};
}
throw e;
}
},
});
}
async get(): Promise<GetConfig> {
return (await this.client.get()).body;
}
getClient() {
return this.client;
}
}

View file

@ -1,15 +1,13 @@
import ApeKeys from "./ape-keys";
import Configs from "./configs";
import Configuration from "./configuration";
import Leaderboards from "./leaderboards";
import Presets from "./presets";
import Psas from "./psas";
import Public from "./public";
import Quotes from "./quotes";
import Results from "./results";
import Users from "./users";
import ApeKeys from "./ape-keys";
import Public from "./public";
import Configuration from "./configuration";
import UsersV2 from "./usersV2";
import ConfigsV2 from "./configsV2";
export default {
Configs,
@ -22,6 +20,4 @@ export default {
Users,
ApeKeys,
Configuration,
UsersV2,
ConfigsV2,
};

View file

@ -1,60 +0,0 @@
import { initClient } from "@ts-rest/core";
import {
GetUserType,
userContract,
} from "./../../../../../shared/contract/user.contract";
import { getAuthenticatedUser, isAuthenticated } from "../../firebase";
import { getIdToken } from "firebase/auth";
import { Axios, AxiosError, AxiosResponse, Method, isAxiosError } from "axios";
export default class Users {
private client;
constructor(baseUrl: string, axios: Axios) {
this.client = initClient(userContract, {
baseUrl,
jsonQuery: true,
//TODO extract
api: async ({ path, method, headers, body }) => {
const token = isAuthenticated()
? await getIdToken(getAuthenticatedUser())
: "";
try {
const result = await axios.request({
method: method as Method,
url: path,
headers: {
...headers,
Authorization: `Bearer ${token}`,
},
data: body,
});
return {
status: result.status,
body: result.data,
headers: result.headers,
};
} catch (e: Error | AxiosError | unknown) {
if (isAxiosError(e)) {
const error = e as AxiosError;
const response = error.response as AxiosResponse;
return {
status: response.status,
body: response.data,
headers: response.headers,
};
}
throw e;
}
},
});
}
async getData(): Promise<GetUserType> {
return (await this.client.get()).body;
}
getClient() {
return this.client;
}
}

View file

@ -2,6 +2,9 @@ import endpoints from "./endpoints";
import { buildHttpClient } from "./adapters/axios-adapter";
import { envConfig } from "../constants/env-config";
import axios from "axios";
import { buildClient } from "./endpoints/ApeClient";
import { configContract } from "./../../../../shared/contract/config.contract";
import { userContract } from "./../../../../shared/contract/user.contract";
const API_PATH = "";
const BASE_URL = envConfig.backendUrl;
@ -25,8 +28,8 @@ const Ape = {
publicStats: new endpoints.Public(httpClient),
apeKeys: new endpoints.ApeKeys(httpClient),
configuration: new endpoints.Configuration(httpClient),
usersV2: new endpoints.UsersV2(BASE_URL, axiosClient).getClient(),
configsV2: new endpoints.ConfigsV2(BASE_URL, axiosClient).getClient(),
usersV2: buildClient(userContract, axios, BASE_URL),
configsV2: buildClient(configContract, axios, BASE_URL),
};
export default Ape;