1/** 2 * excel-safe-helpers.js 3 * Funciones helper para acceso seguro a propiedades .length y otras operaciones 4 */ 5 6class ExcelSafeHelpers { 7 8 /** 9 * Obtiene la longitud de un objeto de forma segura 10 * @param {*} obj - El objeto del cual obtener la longitud 11 * @param {number} defaultValue - Valor por defecto si no se puede obtener la longitud 12 * @returns {number} La longitud o el valor por defecto 13 */ 14 static safeGetLength(obj, defaultValue = 0) { 15 if (!obj) return defaultValue; 16 if (Array.isArray(obj)) return obj.length; 17 if (typeof obj === 'object') return Object.keys(obj).length; 18 if (typeof obj === 'string') return obj.length; 19 return defaultValue; 20 } 21 22 /** 23 * Verifica de forma segura si un array tiene elementos 24 * @param {*} arr - El array a verificar 25 * @returns {boolean} true si el array existe y tiene elementos 26 */ 27 static hasElements(arr) { 28 return Array.isArray(arr) && arr.length > 0; 29 } 30 31 /** 32 * Obtiene un elemento de un array de forma segura 33 * @param {*} arr - El array del cual obtener el elemento 34 * @param {number} index - Ãndice del elemento 35 * @param {*} defaultValue - Valor por defecto si no se puede obtener el elemento 36 * @returns {*} El elemento o el valor por defecto 37 */ 38 static safeGetArrayElement(arr, index, defaultValue = null) { 39 if (!Array.isArray(arr)) return defaultValue; 40 if (index < 0 || index >= arr.length) return defaultValue; 41 return arr[index] ?? defaultValue; 42 } 43 44 /** 45 * Obtiene una propiedad de un objeto de forma segura 46 * @param {*} obj - El objeto del cual obtener la propiedad 47 * @param {string} prop - Nombre de la propiedad 48 * @param {*} defaultValue - Valor por defecto si no se puede obtener la propiedad 49 * @returns {*} El valor de la propiedad o el valor por defecto 50 */ 51 static safeGetProperty(obj, prop, defaultValue = null) { 52 if (!obj || typeof obj !== 'object') return defaultValue; 53 return obj[prop] ?? defaultValue; 54 } 55 56 /** 57 * Itera de forma segura sobre un array 58 * @param {*} arr - El array a iterar 59 * @param {Function} callback - Función a ejecutar por cada elemento 60 */ 61 static safeForEach(arr, callback) { 62 if (!Array.isArray(arr)) { 63 console.warn('safeForEach: arr no es un array válido'); 64 return; 65 } 66 67 for (let i = 0; i < arr.length; i++) { 68 try { 69 callback(arr[i], i, arr); 70 } catch (error) { 71 console.error(`Error en safeForEach Ãndice ${i}:`, error); 72 } 73 } 74 } 75 76 /** 77 * Mapea de forma segura un array 78 * @param {*} arr - El array a mapear 79 * @param {Function} callback - Función de transformación 80 * @param {*} defaultValue - Valor por defecto si arr no es válido 81 * @returns {Array} Array mapeado o valor por defecto 82 */ 83 static safeMap(arr, callback, defaultValue = []) { 84 if (!Array.isArray(arr)) { 85 console.warn('safeMap: arr no es un array válido'); 86 return defaultValue; 87 } 88 89 const result = []; 90 for (let i = 0; i < arr.length; i++) { 91 try { 92 result.push(callback(arr[i], i, arr)); 93 } catch (error) { 94 console.error(`Error en safeMap Ãndice ${i}:`, error); 95 } 96 } 97 return result; 98 } 99 100 /** 101 * Filtra de forma segura un array 102 * @param {*} arr - El array a filtrar 103 * @param {Function} callback - Función de filtrado 104 * @param {*} defaultValue - Valor por defecto si arr no es válido 105 * @returns {Array} Array filtrado o valor por defecto 106 */ 107 static safeFilter(arr, callback, defaultValue = []) { 108 if (!Array.isArray(arr)) { 109 console.warn('safeFilter: arr no es un array válido'); 110 return defaultValue; 111 } 112 113 const result = []; 114 for (let i = 0; i < arr.length; i++) { 115 try { 116 if (callback(arr[i], i, arr)) { 117 result.push(arr[i]); 118 } 119 } catch (error) { 120 console.error(`Error en safeFilter Ãndice ${i}:`, error); 121 } 122 } 123 return result; 124 } 125 126 /** 127 * Valida que un workbook de XLSX sea válido 128 * @param {*} workbook - El workbook a validar 129 * @returns {Object} Objeto con resultado de validación 130 */ 131 static validateWorkbook(workbook) { 132 const result = { 133 valid: false, 134 error: null, 135 sheetNames: [], 136 hasSheets: false 137 }; 138 139 if (!workbook) { 140 result.error = 'Workbook es null o undefined'; 141 return result; 142 } 143 144 if (!workbook.SheetNames) { 145 result.error = 'Workbook.SheetNames es null o undefined'; 146 return result; 147 } 148 149 if (!Array.isArray(workbook.SheetNames)) { 150 result.error = 'Workbook.SheetNames no es un array'; 151 return result; 152 } 153 154 if (workbook.SheetNames.length === 0) { 155 result.error = 'Workbook.SheetNames está vacÃo'; 156 return result; 157 } 158 159 result.valid = true; 160 result.sheetNames = workbook.SheetNames; 161 result.hasSheets = true; 162 163 return result; 164 } 165 166 /** 167 * Obtiene una hoja del workbook de forma segura 168 * @param {*} workbook - El workbook 169 * @param {string|number} sheetIdentifier - Nombre o Ãndice de la hoja 170 * @returns {Object} Objeto con resultado 171 */ 172 static safeGetWorksheet(workbook, sheetIdentifier = 0) { 173 const result = { 174 valid: false, 175 error: null, 176 worksheet: null, 177 sheetName: null 178 }; 179 180 const validation = this.validateWorkbook(workbook); 181 if (!validation.valid) { 182 result.error = validation.error; 183 return result; 184 } 185 186 let sheetName; 187 if (typeof sheetIdentifier === 'number') { 188 if (sheetIdentifier < 0 || sheetIdentifier >= workbook.SheetNames.length) { 189 result.error = `Ãndice de hoja ${sheetIdentifier} fuera de rango (0-${workbook.SheetNames.length - 1})`; 190 return result; 191 } 192 sheetName = workbook.SheetNames[sheetIdentifier]; 193 } else { 194 sheetName = sheetIdentifier; 195 } 196 197 const worksheet = workbook.Sheets?.[sheetName]; 198 if (!worksheet) { 199 result.error = `La hoja "${sheetName}" no existe en el workbook`; 200 return result; 201 } 202 203 result.valid = true; 204 result.worksheet = worksheet; 205 result.sheetName = sheetName; 206 207 return result; 208 } 209 210 /** 211 * Valida que jsonData de XLSX sea válido 212 * @param {*} jsonData - Los datos en formato JSON 213 * @returns {Object} Objeto con resultado de validación 214 */ 215 static validateJsonData(jsonData) { 216 const result = { 217 valid: false, 218 error: null, 219 rowCount: 0, 220 isEmpty: true, 221 isArray: false 222 }; 223 224 if (!jsonData) { 225 result.error = 'jsonData es null o undefined'; 226 return result; 227 } 228 229 if (!Array.isArray(jsonData)) { 230 result.error = 'jsonData no es un array'; 231 return result; 232 } 233 234 result.isArray = true; 235 result.rowCount = jsonData.length; 236 result.isEmpty = jsonData.length === 0; 237 result.valid = true; 238 239 return result; 240 } 241 242 /** 243 * Activa o desactiva el modo debug 244 * @param {boolean} enabled - true para activar, false para desactivar 245 */ 246 static setDebugMode(enabled) { 247 window.EXCEL_DEBUG_MODE = enabled; 248 console.log(`[ExcelSafeHelpers] Modo debug ${enabled ? 'ACTIVADO' : 'DESACTIVADO'}`); 249 } 250 251 /** 252 * Log de debug condicional 253 * @param {string} message - Mensaje a imprimir 254 * @param {*} data - Datos adicionales 255 */ 256 static debugLog(message, data = null) { 257 if (window.EXCEL_DEBUG_MODE) { 258 console.log(`%c[EXCEL-DEBUG] ${message}`, 'color: #9C27B0; font-weight: bold;', data || ''); 259 } 260 } 261 262 /** 263 * Crea un wrapper seguro para procesamiento de Excel 264 * @param {Function} fn - Función a ejecutar 265 * @param {string} fnName - Nombre de la función (para debugging) 266 * @returns {Function} Función envuelta con manejo de errores 267 */ 268 static safeExcelOperation(fn, fnName = 'operación') { 269 return function(...args) {
270 try { 271 ExcelSafeHelpers.debugLog(`Iniciando ${fnName}`, { args }); 272 const result = fn.apply(this, args); 273 ExcelSafeHelpers.debugLog(`${fnName} completado`, { result }); 274 return result; 275 } catch (error) { 276 console.error(`â Error en ${fnName}:`, error); 277 console.error('Stack:', error.stack); 278 throw error; 279 } 280 }; 281 } 282} 283 284// ===== EXPORTAR ===== 285if (typeof window !== 'undefined') { 286 window.ExcelSafeHelpers = ExcelSafeHelpers; 287 // Desactivar debug por defecto 288 window.EXCEL_DEBUG_MODE = false; 289} 290 291console.log('[ExcelSafeHelpers] Módulo cargado');
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.