p
File size: 1,811 Bytes
035e5df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
'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;