Files
image-platform/apps/cabinet/src/infra/backend-api/client.ts
S.Gromov 98295d0569 feat: добавить новый backend и cabinet
- добавлен новый Nest backend для auth, projects и project access tokens
- добавлена control-plane схема БД и миграция Drizzle
- перенесён старый backend в old-backend
- добавлен React/Vite cabinet с auth-only входом и Mantine layout
- обновлены workspace scripts и lockfile
2026-05-12 09:22:04 +03:00

78 lines
1.9 KiB
TypeScript

import { getAdminToken } from './token-storage'
import type { AdminSessionResponseDto, LoginRequestDto, LoginResponseDto } from './types/backend-api.type'
type RequestOptions = {
body?: unknown
isAuthorized?: boolean
method?: 'GET' | 'POST'
}
const API_BASE_URL = import.meta.env.VITE_BACKEND_API_BASE_URL ?? '/api'
export const backendApi = {
auth: {
login: (body: LoginRequestDto) => {
return request<LoginResponseDto>('/auth/login', { body, method: 'POST' })
},
me: () => {
return request<AdminSessionResponseDto>('/auth/me', { isAuthorized: true })
},
},
}
async function request<T>(path: string, options: RequestOptions = {}): Promise<T> {
const response = await fetch(`${API_BASE_URL}${path}`, {
body: options.body ? JSON.stringify(options.body) : undefined,
headers: buildHeaders(options),
method: options.method ?? 'GET',
})
if (!response.ok) {
throw new Error(await readErrorMessage(response))
}
return response.json() as Promise<T>
}
function buildHeaders(options: RequestOptions) {
const headers: Record<string, string> = {
Accept: 'application/json',
}
if (options.body) {
headers['Content-Type'] = 'application/json'
}
if (options.isAuthorized) {
const token = getAdminToken()
if (token) {
headers.Authorization = `Bearer ${token}`
}
}
return headers
}
async function readErrorMessage(response: Response) {
try {
const value = (await response.json()) as unknown
if (isRecord(value) && typeof value.message === 'string') {
return value.message
}
if (isRecord(value) && Array.isArray(value.message)) {
return value.message.join(', ')
}
} catch {
return `request failed with status ${response.status}`
}
return `request failed with status ${response.status}`
}
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === 'object' && value !== null && !Array.isArray(value)
}