p / lib /bytes.js
jijahaulia1x2's picture
Upload 8 files
035e5df verified
'use strict';
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;