File size: 2,896 Bytes
b1c84b5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
/**
 * PhilVerify API client β€” proxied through Vite to http://localhost:8000
 * Typed via src/types.ts which mirrors api/schemas.py
 */
import type {
  VerificationResponse,
  HistoryParams,
  HistoryResponse,
  TrendsResponse,
  HealthResponse,
  ApiError as ApiErrorType,
} from './types'
import { ApiError } from './types'

const BASE = '/api'

// ── Internal fetch helpers ─────────────────────────────────────────────────────

async function post<T>(path: string, body: unknown): Promise<T> {
  const res = await fetch(`${BASE}${path}`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  })
  if (!res.ok) {
    const err = await res.json().catch(() => ({})) as { detail?: string }
    throw new ApiError(err.detail ?? `HTTP ${res.status}`, true)
  }
  return res.json() as Promise<T>
}

async function postForm<T>(path: string, formData: FormData): Promise<T> {
  const res = await fetch(`${BASE}${path}`, { method: 'POST', body: formData })
  if (!res.ok) {
    const err = await res.json().catch(() => ({})) as { detail?: string }
    throw new ApiError(err.detail ?? `HTTP ${res.status}`, true)
  }
  return res.json() as Promise<T>
}

async function get<T>(path: string, params: Record<string, string | number | undefined> = {}): Promise<T> {
  const defined = Object.fromEntries(
    Object.entries(params).filter(([, v]) => v !== undefined),
  ) as Record<string, string>
  const qs = new URLSearchParams(defined).toString()
  const res = await fetch(`${BASE}${path}${qs ? '?' + qs : ''}`)
  if (!res.ok) throw new ApiError(`HTTP ${res.status}`)
  return res.json() as Promise<T>
}

// ── Public API surface ─────────────────────────────────────────────────────────

export const api = {
  verifyText: (text: string): Promise<VerificationResponse> =>
    post('/verify/text', { text }),

  verifyUrl: (url: string): Promise<VerificationResponse> =>
    post('/verify/url', { url }),

  verifyImage: (file: File): Promise<VerificationResponse> => {
    const f = new FormData()
    f.append('file', file)
    return postForm('/verify/image', f)
  },

  verifyVideo: (file: File): Promise<VerificationResponse> => {
    const f = new FormData()
    f.append('file', file)
    return postForm('/verify/video', f)
  },

  history: (params?: HistoryParams): Promise<HistoryResponse> =>
    get('/history', params as Record<string, string | number | undefined>),

  trends: (): Promise<TrendsResponse> =>
    get('/trends'),

  health: (): Promise<HealthResponse> =>
    get('/health'),
} as const

// Re-export error class for consumers
export { ApiError } from './types'
export type { ApiErrorType }