/** * Format file size in human-readable format */ export function formatFileSize(bytes: number): string { if (bytes === 0) return '0 Bytes'; const k = 1024; const sizes = ['Bytes', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return `${Math.round(bytes / Math.pow(k, i) * 100) / 100} ${sizes[i]}`; } /** * Validate file size (max 500MB for browser processing) */ export function validateFileSize(file: File, maxSizeMB: number = 500): boolean { const maxBytes = maxSizeMB * 1024 * 1024; return file.size <= maxBytes; } /** * Get file extension from filename */ export function getFileExtension(filename: string): string { const lastDot = filename.lastIndexOf('.'); return lastDot === -1 ? '' : filename.substring(lastDot + 1).toLowerCase(); } /** * Get filename without extension */ export function getFilenameWithoutExtension(filename: string): string { const lastDot = filename.lastIndexOf('.'); return lastDot === -1 ? filename : filename.substring(0, lastDot); } /** * Generate output filename */ export function generateOutputFilename(inputFilename: string, outputExtension: string): string { const basename = getFilenameWithoutExtension(inputFilename); return `${basename}.${outputExtension}`; } /** * Download blob as file */ export function downloadBlob(blob: Blob, filename: string): void { const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); } /** * Read file as ArrayBuffer */ export async function readFileAsArrayBuffer(file: File): Promise { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => resolve(reader.result as ArrayBuffer); reader.onerror = () => reject(reader.error); reader.readAsArrayBuffer(file); }); } /** * Read file as Data URL */ export async function readFileAsDataURL(file: File): Promise { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => resolve(reader.result as string); reader.onerror = () => reject(reader.error); reader.readAsDataURL(file); }); } /** * Validate file type against allowed MIME types */ export function validateFileType(file: File, allowedTypes: string[]): boolean { return allowedTypes.some((type) => { if (type.endsWith('/*')) { const category = type.split('/')[0]; return file.type.startsWith(`${category}/`); } return file.type === type; }); } /** * Download multiple blobs as a ZIP file */ export async function downloadBlobsAsZip(files: Array<{ blob: Blob; filename: string }>, zipFilename: string): Promise { const JSZip = (await import('jszip')).default; const zip = new JSZip(); // Add all files to ZIP files.forEach(({ blob, filename }) => { zip.file(filename, blob); }); // Generate ZIP blob const zipBlob = await zip.generateAsync({ type: 'blob' }); // Download ZIP downloadBlob(zipBlob, zipFilename); }