Spaces:
Running
Running
File size: 3,454 Bytes
8b9f7d9 81046e2 8b9f7d9 81046e2 8b9f7d9 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
import type {
ChatMessage,
ChatResponse,
ImageResponse,
ModelsResponse,
StatsResponse,
HealthResponse,
AuthConfig,
AuthResponse,
AuthUser,
} from './types'
const BASE_URL = '/api'
// ---------------------------------------------------------------------------
// Token management
// ---------------------------------------------------------------------------
const TOKEN_KEY = 'lp_auth_token'
export function getToken(): string | null {
return localStorage.getItem(TOKEN_KEY)
}
export function setToken(token: string) {
localStorage.setItem(TOKEN_KEY, token)
}
export function clearToken() {
localStorage.removeItem(TOKEN_KEY)
}
function authHeaders(): Record<string, string> {
const token = getToken()
return token ? { Authorization: `Bearer ${token}` } : {}
}
// ---------------------------------------------------------------------------
// Generic request helper
// ---------------------------------------------------------------------------
async function request<T>(path: string, options?: RequestInit): Promise<T> {
const res = await fetch(`${BASE_URL}${path}`, {
headers: { 'Content-Type': 'application/json', ...authHeaders() },
...options,
})
if (!res.ok) {
const err = await res.json().catch(() => ({ detail: res.statusText }))
throw new Error(err.detail || `HTTP ${res.status}`)
}
return res.json()
}
// ---------------------------------------------------------------------------
// Auth
// ---------------------------------------------------------------------------
export async function getAuthConfig(): Promise<AuthConfig> {
return request('/auth/config')
}
export async function loginWithGoogle(credential: string): Promise<AuthResponse> {
return request('/auth/google', {
method: 'POST',
body: JSON.stringify({ credential }),
})
}
export async function getMe(): Promise<AuthUser> {
return request('/auth/me')
}
// ---------------------------------------------------------------------------
// Public API
// ---------------------------------------------------------------------------
export async function getHealth(): Promise<HealthResponse> {
return request('/health')
}
export async function getModels(): Promise<ModelsResponse> {
return request('/models')
}
export async function getStats(): Promise<StatsResponse> {
return request('/stats')
}
// ---------------------------------------------------------------------------
// Protected API
// ---------------------------------------------------------------------------
export async function sendChat(
message: string,
model: string,
history: ChatMessage[],
lang: string = 'hr',
): Promise<ChatResponse> {
return request('/chat', {
method: 'POST',
body: JSON.stringify({
message,
model,
lang,
history: history.map((m) => ({ role: m.role, content: m.content })),
}),
})
}
export async function analyzeImage(
imageFile: File,
question: string,
model: string,
): Promise<ImageResponse> {
const formData = new FormData()
formData.append('image', imageFile)
formData.append('question', question)
formData.append('model', model)
const res = await fetch(`${BASE_URL}/analyze-image`, {
method: 'POST',
body: formData,
headers: authHeaders(),
})
if (!res.ok) {
const err = await res.json().catch(() => ({ detail: res.statusText }))
throw new Error(err.detail || `HTTP ${res.status}`)
}
return res.json()
}
|