// TrueDetect API client. // Single function: posts a File to /analyze, normalizes errors so the existing // toast / error states in app.jsx can display them without modification. // // API base URL precedence: // 1. window.TRUEDETECT_API (set on the page if you embed) // 2. localStorage 'truedetect.apiBase' // 3. http://localhost:8000 (default) // // API key: read from localStorage 'truedetect.apiKey'. window.TrueDetectAPI = (function(){ function getBaseUrl(){ if (window.TRUEDETECT_API) return window.TRUEDETECT_API; try { const stored = localStorage.getItem('truedetect.apiBase'); if (stored) return stored; } catch(_) {} return window.location.origin; } function getApiKey(){ try { const k = localStorage.getItem('truedetect.apiKey') || ''; // Strip non-ISO-8859-1 chars so they never land in a fetch header return k.replace(/[^\x00-\xff]/g, ''); } catch(_) { return ''; } } // Map server response to the same error shape app.jsx already handles // via the `errorState` tweak: too_large | too_short | invalid_key | server_error. function mapError(status, detail){ if (status === 401) return { kind: 'invalid_key', detail: detail || 'Invalid API key' }; if (status === 413) return { kind: 'too_large', detail: detail || 'File too large' }; if (status === 422) return { kind: 'too_short', detail: detail || 'Document too short' }; return { kind: 'server_error', detail: detail || `HTTP ${status}` }; } async function analyzeDocument(file){ const baseUrl = getBaseUrl().replace(/\/$/, ''); const apiKey = getApiKey(); const form = new FormData(); form.append('file', file, file.name); let response; try { response = await fetch(`${baseUrl}/analyze?include_pdf_report=true`, { method: 'POST', headers: apiKey ? { 'X-API-Key': apiKey } : {}, body: form, }); } catch(networkError){ throw { kind: 'server_error', detail: `Cannot reach engine at ${baseUrl}: ${networkError.message}` }; } if (!response.ok){ let detail = ''; try { const body = await response.json(); detail = body.detail || ''; } catch(_) {} throw mapError(response.status, detail); } return await response.json(); } function setApiKey(key){ try { localStorage.setItem('truedetect.apiKey', key || ''); } catch(_) {} } function setApiBase(base){ try { localStorage.setItem('truedetect.apiBase', base || ''); } catch(_) {} } return { analyzeDocument, setApiKey, setApiBase, getApiKey, getBaseUrl }; })();