UNPKG

qgenutils

Version:

A security-first Node.js utility library providing authentication, HTTP operations, URL processing, validation, datetime formatting, and template rendering. Designed as a lightweight alternative to heavy npm packages with comprehensive error handling and

93 lines (80 loc) 3.18 kB
/** * Format File Size in Human-Readable Units * * RATIONALE: File sizes in bytes are difficult for users to interpret. * Converting to appropriate units (B, KB, MB, GB) with proper decimal precision * makes file size information accessible and meaningful for users. * * IMPLEMENTATION STRATEGY: * - Use standard 1024-byte conversion factors for binary file sizes * - Select appropriate unit based on magnitude to avoid tiny decimals or huge numbers * - Round to 1 decimal place for readability while maintaining reasonable precision * - Handle edge cases like zero, negative, and non-numeric inputs gracefully * - Return formatted string with unit suffix for immediate display use * * UNIT SELECTION LOGIC: * - Bytes (B): Less than 1 KB, displayed as whole numbers * - Kilobytes (KB): 1 KB to 999.9 KB * - Megabytes (MB): 1 MB to 999.9 MB * - Gigabytes (GB): 1 GB and above * * PRECISION HANDLING: * - Bytes shown as integers (no decimals needed) * - KB, MB, GB shown with 1 decimal place for useful precision * - Rounds rather than truncates for more accurate representation * * ERROR HANDLING: * - Invalid inputs return "0 B" to provide safe fallback * - Negative values return "0 B" (file sizes can't be negative) * - Non-numeric inputs are handled gracefully without throwing * * @param {number} bytes - File size in bytes to format * @returns {string} Formatted file size with appropriate unit (e.g., "1.5 MB", "230 B") * @throws Never throws - returns "0 B" for any invalid input */ const { qerrors } = require('qerrors'); const logger = require('../../logger'); function formatFileSize(bytes) { logger.debug(`formatFileSize formatting file size`, { bytes }); try { // Handle invalid inputs gracefully if (typeof bytes !== `number` || isNaN(bytes) || bytes < 0) { logger.warn(`formatFileSize received invalid bytes value`, { bytes }); return `0 B`; } // Handle zero bytes if (bytes === 0) { logger.debug(`formatFileSize: zero bytes`); return `0 B`; } // Define conversion thresholds using binary (1024) factors const kilobyte = 1024; const megabyte = kilobyte * 1024; const gigabyte = megabyte * 1024; let result; if (bytes >= gigabyte) { // Format as gigabytes with 1 decimal place const gb = bytes / gigabyte; result = `${gb.toFixed(1)} GB`; } else if (bytes >= megabyte) { // Format as megabytes with 1 decimal place const mb = bytes / megabyte; result = `${mb.toFixed(1)} MB`; } else if (bytes >= kilobyte) { // Format as kilobytes with 1 decimal place const kb = bytes / kilobyte; result = `${kb.toFixed(1)} KB`; } else { // Format as bytes (whole numbers only) result = `${bytes} B`; } logger.debug(`formatFileSize formatted successfully`, { input: bytes, output: result }); return result; } catch (error) { qerrors(error, `formatFileSize`, { bytes }); logger.error(`formatFileSize failed with error`, { error: error.message, bytes }); // Return safe fallback value return `0 B`; } } module.exports = formatFileSize;