UNPKG

@accounter/scraper-app

Version:
148 lines (123 loc) 4.96 kB
import type { BankAccount, Settings } from '../../server/vault.js'; import type { RunRecord } from '../../shared/types.js'; export class ApiError extends Error { constructor( public readonly status: number, message: string, ) { super(message); this.name = 'ApiError'; } } async function apiFetch<T>(url: string, init?: RequestInit): Promise<T> { const res = await fetch(url, init); if (!res.ok) { const body = (await res.json().catch(() => ({}))) as { error?: string }; throw new ApiError(res.status, body.error ?? `HTTP ${res.status}`); } return res.json() as Promise<T>; } export function vaultStatus(): Promise<{ locked: boolean; hasFile: boolean }> { return apiFetch('/api/vault/status'); } export function vaultUnlock(password: string): Promise<{ ok: boolean }> { return apiFetch('/api/vault/unlock', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ password }), }); } export function vaultCreate( password: string, serverUrl: string, apiKey: string, ): Promise<{ ok: boolean }> { return apiFetch('/api/vault/create', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ password, serverUrl, apiKey }), }); } // ── Sources ─────────────────────────────────────────────────────────────────── export function getSources<T>(): Promise<T[]> { return apiFetch('/api/vault/sources'); } export function createSource<T>(data: unknown): Promise<T[]> { return apiFetch('/api/vault/sources', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data), }); } export function updateSource<T>(id: string, data: unknown): Promise<T[]> { return apiFetch(`/api/vault/sources/${id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data), }); } export function deleteSource<T>(id: string): Promise<T[]> { return apiFetch(`/api/vault/sources/${id}`, { method: 'DELETE' }); } export function loadSettings(): Promise<Settings> { return apiFetch('/api/vault/settings'); } export function saveSettings(patch: Partial<Settings>): Promise<Settings> { return apiFetch('/api/vault/settings', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(patch), }); } export function fetchAccounts(): Promise<BankAccount[]> { return apiFetch('/api/vault/accounts'); } export function updateStatus(id: string, status: 'accepted' | 'ignored'): Promise<BankAccount[]> { return apiFetch(`/api/vault/accounts/${id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ status }), }); } export function deleteAccount(id: string): Promise<BankAccount[]> { return apiFetch(`/api/vault/accounts/${id}`, { method: 'DELETE' }); } // ── Vault path ──────────────────────────────────────────────────────────────── export function getVaultPath(): Promise<{ path: string }> { return apiFetch('/api/vault/path'); } export function getEnvVaultPath(): Promise<{ path: string }> { return apiFetch('/api/vault/env-path'); } export function vaultUpload(file: File, force = false): Promise<{ ok: boolean }> { const url = force ? '/api/vault/upload?force=true' : '/api/vault/upload'; return apiFetch(url, { method: 'POST', headers: { 'Content-Type': 'application/octet-stream' }, body: file, }); } export async function vaultDownload(suggestedName = '.vault'): Promise<void> { const res = await fetch('/api/vault/download'); if (!res.ok) { const body = (await res.json().catch(() => ({}))) as { error?: string }; throw new ApiError(res.status, body.error ?? `HTTP ${res.status}`); } const blob = await res.blob(); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = suggestedName; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); } // ── Connection test ─────────────────────────────────────────────────────────── export function testConnection(): Promise<{ ok: boolean; latencyMs?: number; error?: string }> { return apiFetch('/api/vault/test-connection'); } // ── History ─────────────────────────────────────────────────────────────────── export function getHistory(): Promise<RunRecord[]> { return apiFetch('/api/history'); }