UNPKG

@makolabs/ripple

Version:

Simple Svelte 5 powered component library ✨

172 lines (171 loc) 6.91 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, fileKey) { 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; } }