Spaces:
Sleeping
Sleeping
| ; | |
| const units = { | |
| b: 1, | |
| kb: 1024, | |
| mb: 1024 ** 2, | |
| gb: 1024 ** 3, | |
| tb: 1024 ** 4, | |
| pb: 1024 ** 5, | |
| }; | |
| const formatThousands = /\B(?=(\d{3})+(?!\d))/g; | |
| const trimZeros = /(?:\.0*|(\.[^0]+)0+)$/; | |
| const parsePattern = /^([-+]?\d+(?:\.\d+)?) *(kb|mb|gb|tb|pb)$/i; | |
| function bytes(value, options) { | |
| return typeof value === 'string' ? parse(value) : | |
| typeof value === 'number' ? format(value, options) : | |
| null; | |
| } | |
| function format(value, opts = {}) { | |
| if (!Number.isFinite(value)) return null; | |
| const mag = Math.abs(value); | |
| const { | |
| decimalPlaces = 2, | |
| fixedDecimals = false, | |
| thousandsSeparator = '', | |
| unitSeparator = '', | |
| unit = getAutoUnit(mag), | |
| } = opts; | |
| const lowerUnit = unit.toLowerCase(); | |
| const factor = units[lowerUnit] || 1; | |
| let result = (value / factor).toFixed(decimalPlaces); | |
| if (!fixedDecimals) result = result.replace(trimZeros, '$1'); | |
| if (thousandsSeparator) { | |
| const parts = result.split('.'); | |
| parts[0] = parts[0].replace(formatThousands, thousandsSeparator); | |
| result = parts.join('.'); | |
| } | |
| return result + unitSeparator + unit.toUpperCase(); | |
| } | |
| function parse(str) { | |
| if (typeof str === 'number') return str; | |
| if (typeof str !== 'string') return null; | |
| const match = parsePattern.exec(str.trim()); | |
| const num = match ? parseFloat(match[1]) : parseInt(str, 10); | |
| const unit = match ? match[2].toLowerCase() : 'b'; | |
| return isNaN(num) ? null : Math.floor(num * (units[unit] || 1)); | |
| } | |
| function getAutoUnit(value) { | |
| if (value >= units.pb) return 'PB'; | |
| if (value >= units.tb) return 'TB'; | |
| if (value >= units.gb) return 'GB'; | |
| if (value >= units.mb) return 'MB'; | |
| if (value >= units.kb) return 'KB'; | |
| return 'B'; | |
| } | |
| module.exports = bytes; | |
| module.exports.format = format; | |
| module.exports.parse = parse; | |