Archived
1
0
This repository has been archived on 2025-11-29. You can view files and clone it, but cannot push or open issues or pull requests.
Files
app/apps/frontend/lib/api.ts

163 lines
5.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { API_BASE_URL } from '@/config/api';
import type {
SaveListItem,
SaveDetailResponse,
CreateSaveFromUrlRequest,
UpdateSaveRequest,
SaveResponse,
User
} from '@shared-types';
// Получить токен из сессии Better Auth
async function getAuthToken(): Promise<string | null> {
// Better Auth хранит токен в cookies, но для React Native нужно использовать другой подход
// Временно возвращаем null, токен будет передаваться через headers в Better Auth клиенте
return null;
}
async function apiRequest<T>(
endpoint: string,
options: RequestInit = {}
): Promise<T> {
const token = await getAuthToken();
const headers: Record<string, string> = {
'Content-Type': 'application/json',
...(options.headers as Record<string, string> || {}),
};
if (token) {
headers['Authorization'] = `Bearer ${token}`;
}
const response = await fetch(`${API_BASE_URL}${endpoint}`, {
...options,
headers,
credentials: 'include', // Для cookies Better Auth
});
if (!response.ok) {
const error = await response.json().catch(() => ({ error: 'Unknown error' }));
throw new Error(error.error || `HTTP error! status: ${response.status}`);
}
return response.json();
}
// API для работы с сейвами
export const savesApi = {
// Получить все сейвы текущего пользователя
async getMySaves(): Promise<SaveListItem[]> {
return apiRequest<SaveListItem[]>('/saves/my');
},
// Получить сейв по ID
async getSaveById(id: number, shareToken?: string): Promise<SaveDetailResponse> {
const url = shareToken
? `/saves/${id}?share=${shareToken}`
: `/saves/${id}`;
return apiRequest<SaveDetailResponse>(url);
},
// Создать сейв из URL
async createFromUrl(data: CreateSaveFromUrlRequest): Promise<SaveResponse> {
return apiRequest<SaveResponse>('/saves/external', {
method: 'POST',
body: JSON.stringify(data),
});
},
// Загрузить файл
async uploadFile(
file: File | { uri: string; type: string; name: string },
metadata?: {
name?: string;
description?: string;
tags?: string[];
visibility?: 'public' | 'link';
}
): Promise<SaveResponse> {
const formData = new FormData();
// Для React Native используем другой формат
if ('uri' in file) {
// React Native
formData.append('file', {
uri: file.uri,
type: file.type,
name: file.name,
} as any);
} else {
// Web
formData.append('file', file);
}
if (metadata?.name) formData.append('name', metadata.name);
if (metadata?.description) formData.append('description', metadata.description);
if (metadata?.tags) {
metadata.tags.forEach(tag => formData.append('tags[]', tag));
}
if (metadata?.visibility) formData.append('visibility', metadata.visibility);
const token = await getAuthToken();
const headers: Record<string, string> = {};
if (token) {
headers['Authorization'] = `Bearer ${token}`;
}
// Не устанавливаем Content-Type для FormData - браузер/платформа сделает это автоматически
const response = await fetch(`${API_BASE_URL}/saves/upload`, {
method: 'POST',
headers,
body: formData,
credentials: 'include',
});
if (!response.ok) {
const error = await response.json().catch(() => ({ error: 'Unknown error' }));
throw new Error(error.error || `HTTP error! status: ${response.status}`);
}
return response.json();
},
// Обновить сейв
async updateSave(id: number, data: UpdateSaveRequest): Promise<SaveDetailResponse> {
return apiRequest<SaveDetailResponse>(`/saves/${id}`, {
method: 'PATCH',
body: JSON.stringify(data),
});
},
// Удалить сейв
async deleteSave(id: number): Promise<{ success: boolean; message: string }> {
return apiRequest<{ success: boolean; message: string }>(`/saves/${id}`, {
method: 'DELETE',
});
},
// Получить URL для скачивания
getDownloadUrl(id: number, shareToken?: string): string {
const baseUrl = `${API_BASE_URL}/saves/${id}/download`;
return shareToken ? `${baseUrl}?share=${shareToken}` : baseUrl;
},
// Получить публичные сейвы пользователя по slug (userId)
async getPublicSavesByUser(slug: string): Promise<SaveListItem[]> {
return apiRequest<SaveListItem[]>(`/saves/u/${slug}`);
},
};
// API для работы с пользователями
export const usersApi = {
// Получить пользователя по имени
async getUserByName(name: string): Promise<User> {
return apiRequest<User>(`/users/by-name?name=${encodeURIComponent(name)}`);
},
// Получить пользователя по ID
async getUserById(id: string): Promise<User> {
return apiRequest<User>(`/users/${id}`);
},
};