/** * API service for communicating with the FastAPI backend */ const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || ""; /** * Get authorization headers with token */ function getAuthHeaders() { const token = localStorage.getItem("auth_token"); return token ? { Authorization: `Bearer ${token}` } : {}; } /** * Extract data from a document * @param {File} file - The file to extract data from * @param {string} keyFields - Optional comma-separated list of fields to extract * @returns {Promise} Extraction result with fields, confidence, etc. */ export async function extractDocument(file, keyFields = "") { const formData = new FormData(); formData.append("file", file); if (keyFields && keyFields.trim()) { formData.append("key_fields", keyFields.trim()); } const response = await fetch(`${API_BASE_URL}/api/extract`, { method: "POST", headers: getAuthHeaders(), body: formData, }); if (!response.ok) { const errorData = await response.json().catch(() => ({ error: `HTTP ${response.status}: ${response.statusText}`, })); throw new Error(errorData.error || errorData.detail || "Extraction failed"); } return await response.json(); } /** * Get extraction history * @returns {Promise} Array of extraction records */ export async function getHistory() { const response = await fetch(`${API_BASE_URL}/api/history`, { headers: getAuthHeaders(), }); if (!response.ok) { const errorData = await response.json().catch(() => ({ error: `HTTP ${response.status}: ${response.statusText}`, })); throw new Error(errorData.error || errorData.detail || "Failed to fetch history"); } return await response.json(); } /** * Get a specific extraction by ID with full fields data * @param {number} extractionId - The extraction ID * @returns {Promise} Extraction result with fields */ export async function getExtractionById(extractionId) { const response = await fetch(`${API_BASE_URL}/api/extraction/${extractionId}`, { headers: getAuthHeaders(), }); if (!response.ok) { const errorData = await response.json().catch(() => ({ error: `HTTP ${response.status}: ${response.statusText}`, })); throw new Error(errorData.error || errorData.detail || "Failed to fetch extraction"); } return await response.json(); } /** * Create a shareable link for an extraction * @param {number} extractionId - The extraction ID to share * @returns {Promise} Share link result with share_link */ export async function createShareLink(extractionId) { const response = await fetch(`${API_BASE_URL}/api/share/link`, { method: "POST", headers: { "Content-Type": "application/json", ...getAuthHeaders(), }, body: JSON.stringify({ extraction_id: extractionId, }), }); if (!response.ok) { const errorData = await response.json().catch(() => ({ error: `HTTP ${response.status}: ${response.statusText}`, })); throw new Error(errorData.error || errorData.detail || "Failed to create share link"); } return await response.json(); } /** * Share an extraction with another user(s) * @param {number} extractionId - The extraction ID to share * @param {string|string[]} recipientEmails - Recipient email address(es) - can be a single email or array of emails * @returns {Promise} Share result */ export async function shareExtraction(extractionId, recipientEmails) { // Ensure recipient_emails is always an array const emailsArray = Array.isArray(recipientEmails) ? recipientEmails : [recipientEmails]; const response = await fetch(`${API_BASE_URL}/api/share`, { method: "POST", headers: { "Content-Type": "application/json", ...getAuthHeaders(), }, body: JSON.stringify({ extraction_id: extractionId, recipient_emails: emailsArray, }), }); if (!response.ok) { const errorData = await response.json().catch(() => ({ error: `HTTP ${response.status}: ${response.statusText}`, })); throw new Error(errorData.error || errorData.detail || "Failed to share extraction"); } return await response.json(); } /** * Access a shared extraction by token * @param {string} token - Share token * @returns {Promise} Share access result with extraction_id */ export async function accessSharedExtraction(token) { const response = await fetch(`${API_BASE_URL}/api/share/${token}`, { headers: getAuthHeaders(), }); if (!response.ok) { const errorData = await response.json().catch(() => ({ error: `HTTP ${response.status}: ${response.statusText}`, })); throw new Error(errorData.error || errorData.detail || "Failed to access shared extraction"); } return await response.json(); } /** * Health check endpoint * @returns {Promise} Status object */ export async function ping() { const response = await fetch(`${API_BASE_URL}/ping`); if (!response.ok) { throw new Error("Backend is not available"); } return await response.json(); } /** * Create a new API key * @param {string} name - User-friendly name for the API key * @returns {Promise} API key creation result with api_key */ export async function createAPIKey(name) { const response = await fetch(`${API_BASE_URL}/api/auth/api-key/create`, { method: "POST", headers: { "Content-Type": "application/json", ...getAuthHeaders(), }, body: JSON.stringify({ name }), }); if (!response.ok) { const errorData = await response.json().catch(() => ({ error: `HTTP ${response.status}: ${response.statusText}`, })); throw new Error(errorData.error || errorData.detail || "Failed to create API key"); } return await response.json(); } /** * List all API keys for the current user * @returns {Promise} API keys list with api_keys array */ export async function listAPIKeys() { const response = await fetch(`${API_BASE_URL}/api/auth/api-keys`, { headers: getAuthHeaders(), }); if (!response.ok) { const errorData = await response.json().catch(() => ({ error: `HTTP ${response.status}: ${response.statusText}`, })); throw new Error(errorData.error || errorData.detail || "Failed to fetch API keys"); } return await response.json(); } /** * Delete (deactivate) an API key * @param {number} keyId - The API key ID to delete * @returns {Promise} Deletion result */ export async function deleteAPIKey(keyId) { const response = await fetch(`${API_BASE_URL}/api/auth/api-key/${keyId}`, { method: "DELETE", headers: getAuthHeaders(), }); if (!response.ok) { const errorData = await response.json().catch(() => ({ error: `HTTP ${response.status}: ${response.statusText}`, })); throw new Error(errorData.error || errorData.detail || "Failed to delete API key"); } return await response.json(); }