/** * Units for file sizes */ const FILE_SIZE_UNITS = ['B', 'KB', 'MB', 'GB', 'TB'] /** * Interface for file size */ export interface FileSize { value: number unit: string } /** * Base function to parse file size in bytes to value and unit * @param bytes File size in bytes * @param binary Whether to use binary (1024) or decimal (1000) units * @returns Object with numeric value and unit string */ function parseSize(bytes: number, binary: boolean = false): FileSize { // Handle invalid input if (bytes === null || bytes === undefined || isNaN(bytes) || bytes < 0) { return { value: 0, unit: 'B' } } // If the size is 0, return early if (bytes === 0) { return { value: 0, unit: 'B' } } // Otherwise, determine the appropriate unit based on the size const unit = binary ? 1024 : 1000 const unitIndex = Math.floor(Math.log(bytes) / Math.log(unit)) const unitSize = Math.pow(unit, unitIndex) const value = bytes / unitSize // Make sure we don't exceed our units array const safeUnitIndex = Math.min(unitIndex, FILE_SIZE_UNITS.length - 1) return { value: Math.round(value * 100) / 100, // Round to 2 decimal places unit: FILE_SIZE_UNITS[safeUnitIndex], } } /** * Converts a file size in bytes to a human-readable string * @param bytes File size in bytes * @param binary Whether to use binary (1024) or decimal (1000) units * @returns Formatted file size string (e.g., "1.5 MB") */ export function formatSize(bytes: number, binary: boolean = false): string { const { value, unit } = parseSize(bytes, binary) return `${value.toFixed(2)} ${unit}` } /** * Converts a file size in bytes to an object with value and unit * @param bytes File size in bytes * @param binary Whether to use binary (1024) or decimal (1000) units * @returns Object with numeric value and unit string */ export function formatSizeObject( bytes: number, binary: boolean = false, ): FileSize { return parseSize(bytes, binary) }