UNPKG

@makolabs/ripple

Version:

Simple Svelte 5 powered component library ✨

172 lines (171 loc) 6.85 kB
/** * Base storage adapter with common functionality */ export class BaseAdapter { // Common implementation of import and getImportStatus async import(file, options) { try { const endpoint = `/api/${this.getApiPath()}/import`; const response = await fetch(endpoint, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ key: file.key, fileId: file.id, // For Google Drive contentType: options.contentType, fileFormat: options.fileFormat, reference: options.reference || file.name, insurer: options.contentType === 'insurer_statement' ? options.insurer : null }) }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error || 'Failed to import file'); } const result = await response.json(); return { success: true, message: `File ${file.name} imported successfully`, fileId: result.fileId || result.importResponse?.uuid, status: 'pending', progress: 10 }; } catch (err) { console.error(`Error importing ${this.getName()} file:`, err); return { success: false, message: `Failed to import file from ${this.getName()}`, error: err instanceof Error ? err.message : 'Unknown error' }; } } async getImportStatus(importId) { try { const response = await fetch(`/api/v1/uploads/${importId}`); if (!response.ok) { if (response.status === 404) { throw new Error(`404: File ${importId} not found on server`); } throw new Error(`Failed to get file status: ${response.status} ${response.statusText}`); } const fileData = await response.json(); return { fileId: importId, status: fileData.processing_status, progress: this.calculateProgress(fileData.processing_status, fileData.processed_rows, fileData.total_rows), processedRows: fileData.processed_rows, totalRows: fileData.total_rows, detailedStatus: this.getDetailedStatus(fileData.processing_status), error: fileData.error_details?.message, created_at: fileData.created_at }; } catch (err) { console.error('Error polling file status:', err); throw err; } } // Common implementation of batch import async batchImport(files, options) { // Process files sequentially const individualResults = []; for (const file of files) { try { const result = await this.import(file, options); individualResults.push(result); } catch (err) { individualResults.push({ success: false, message: `Failed to import ${file.name}`, error: err instanceof Error ? err.message : 'Unknown error', fileId: file.id }); } } // Count successes and failures const succeeded = individualResults.filter((r) => r.success).length; const failed = individualResults.length - succeeded; // Return batch import result return { success: failed === 0, // Overall success if all files succeeded message: `Imported ${succeeded} of ${individualResults.length} files`, summary: { total: individualResults.length, succeeded, failed }, results: individualResults.map((r) => ({ key: r.fileId || '', success: r.success, fileId: r.fileId, error: r.error })) }; } // Set a flag to reopen the browser after authentication setReopenFlag() { // Default implementation does nothing // Subclasses should override this method to implement storage-specific reopening flags } // Check if the browser should be reopened shouldReopenBrowser() { // Default implementation returns false // Subclasses should override this method to check their specific reopening flags return false; } // Clear the browser reopening flag clearReopenFlag() { // Default implementation does nothing // Subclasses should override this method to clear their specific reopening flags } // Helper method to get detailed status getDetailedStatus(status) { const statusMap = { pending: 'Waiting to start', pending_import: 'Preparing import', initializing: 'Initializing import', pending_file_retrieval: 'Retrieving file', retrieving_file: 'Downloading file', file_retrieved: 'File downloaded', loading_file_contents_to_db: 'Loading data', file_contents_loaded: 'Data loaded', ready_to_process: 'Ready for processing', validating_source_file_rows: 'Validating file', converting_to_business_objects: 'Converting data', processing: 'Processing data', completed: 'Import completed', failed: 'Import failed', partially_processed: 'Partially processed' }; return statusMap[status] || status; } // Helper method to calculate progress calculateProgress(status, processedRows, totalRows) { // If we have row counts, use them for more accurate progress if (processedRows !== undefined && totalRows && totalRows > 0) { return Math.min(95, Math.round((processedRows / totalRows) * 100)); } // Otherwise, use status-based progress estimates const progressMap = { pending: 5, pending_import: 10, initializing: 15, pending_file_retrieval: 20, retrieving_file: 30, file_retrieved: 40, loading_file_contents_to_db: 50, file_contents_loaded: 60, ready_to_process: 70, validating_source_file_rows: 80, converting_to_business_objects: 90, completed: 100, failed: 0, partially_processed: 95 }; return progressMap[status] || 50; } }