v0.1 - макет интерфейса, аутентификация через логин, аккаунт админа, создание партии в 2 этапа, базовые настройки профиля и группы, переключение между группами, статистика
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
import createClient from "openapi-fetch";
|
||||
import type { paths } from "./schema";
|
||||
|
||||
function readCookie(name: string): string | null {
|
||||
const m = document.cookie.match(new RegExp("(?:^|; )" + name + "=([^;]*)"));
|
||||
return m ? decodeURIComponent(m[1]) : null;
|
||||
}
|
||||
|
||||
// Пути в схеме уже содержат /api; baseUrl — origin (пусто в dev/prod).
|
||||
export const api = createClient<paths>({
|
||||
baseUrl: import.meta.env.VITE_API_BASE_URL || "",
|
||||
credentials: "include",
|
||||
});
|
||||
|
||||
// CSRF double-submit: дублируем cookie csrf_token в заголовок на всех запросах.
|
||||
api.use({
|
||||
onRequest({ request }) {
|
||||
const csrf = readCookie("csrf_token");
|
||||
if (csrf) request.headers.set("X-CSRF-Token", csrf);
|
||||
return request;
|
||||
},
|
||||
});
|
||||
|
||||
export class ApiError extends Error {
|
||||
code: string;
|
||||
status: number;
|
||||
details?: unknown;
|
||||
constructor(message: string, code: string, status: number, details?: unknown) {
|
||||
super(message);
|
||||
this.code = code;
|
||||
this.status = status;
|
||||
this.details = details;
|
||||
}
|
||||
}
|
||||
|
||||
interface FetchResult<T> {
|
||||
data?: T;
|
||||
error?: unknown;
|
||||
response: Response;
|
||||
}
|
||||
|
||||
/** Разворачивает ответ openapi-fetch: возвращает данные или бросает ApiError. */
|
||||
export function unwrap<T>(res: FetchResult<T>): T {
|
||||
if (res.error || !res.response.ok) {
|
||||
const env = (res.error as { error?: { code?: string; message?: string; details?: unknown } })
|
||||
?.error;
|
||||
throw new ApiError(
|
||||
env?.message || "Ошибка запроса",
|
||||
env?.code || "ERROR",
|
||||
res.response.status,
|
||||
env?.details,
|
||||
);
|
||||
}
|
||||
return res.data as T;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
export const qk = {
|
||||
me: ["me"] as const,
|
||||
adminMe: ["adminMe"] as const,
|
||||
home: ["home"] as const,
|
||||
leaderboard: ["leaderboard"] as const,
|
||||
expansions: ["expansions"] as const,
|
||||
factions: ["factions"] as const,
|
||||
myStats: ["myStats"] as const,
|
||||
groups: ["groups"] as const,
|
||||
group: (id: number) => ["group", id] as const,
|
||||
groupFactions: (id: number) => ["group", id, "factions"] as const,
|
||||
groupMembers: (id: number) => ["group", id, "members"] as const,
|
||||
groupMatches: (id: number) => ["group", id, "matches"] as const,
|
||||
groupStats: (id: number) => ["group", id, "stats"] as const,
|
||||
match: (id: number) => ["match", id] as const,
|
||||
authConfig: ["authConfig"] as const,
|
||||
devUsers: ["devUsers"] as const,
|
||||
adminUsers: ["adminUsers"] as const,
|
||||
adminGroups: ["adminGroups"] as const,
|
||||
adminMatches: ["adminMatches"] as const,
|
||||
adminLogs: ["adminLogs"] as const,
|
||||
};
|
||||
Vendored
+2842
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user