import { API_BASE_URL } from '@/config/api'; import type { SaveListItem, SaveDetailResponse, CreateSaveFromUrlRequest, UpdateSaveRequest, SaveResponse, User } from '@shared-types'; // Получить токен из сессии Better Auth async function getAuthToken(): Promise { // Better Auth хранит токен в cookies, но для React Native нужно использовать другой подход // Временно возвращаем null, токен будет передаваться через headers в Better Auth клиенте return null; } async function apiRequest( endpoint: string, options: RequestInit = {} ): Promise { const token = await getAuthToken(); const headers: Record = { 'Content-Type': 'application/json', ...(options.headers as Record || {}), }; 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 { return apiRequest('/saves/my'); }, // Получить сейв по ID async getSaveById(id: number, shareToken?: string): Promise { const url = shareToken ? `/saves/${id}?share=${shareToken}` : `/saves/${id}`; return apiRequest(url); }, // Создать сейв из URL async createFromUrl(data: CreateSaveFromUrlRequest): Promise { return apiRequest('/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 { 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 = {}; 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 { return apiRequest(`/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 { return apiRequest(`/saves/u/${slug}`); }, }; // API для работы с пользователями export const usersApi = { // Получить пользователя по имени async getUserByName(name: string): Promise { return apiRequest(`/users/by-name?name=${encodeURIComponent(name)}`); }, // Получить пользователя по ID async getUserById(id: string): Promise { return apiRequest(`/users/${id}`); }, };