UNPKG

3.71 kBJavaScriptView Raw
1const b = /^(b|B)$/,
2 symbol = {
3 iec: {
4 bits: ["b", "Kib", "Mib", "Gib", "Tib", "Pib", "Eib", "Zib", "Yib"],
5 bytes: ["B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"]
6 },
7 jedec: {
8 bits: ["b", "Kb", "Mb", "Gb", "Tb", "Pb", "Eb", "Zb", "Yb"],
9 bytes: ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]
10 }
11 },
12 fullform = {
13 iec: ["", "kibi", "mebi", "gibi", "tebi", "pebi", "exbi", "zebi", "yobi"],
14 jedec: ["", "kilo", "mega", "giga", "tera", "peta", "exa", "zetta", "yotta"]
15 };
16
17function filesize (arg, descriptor = {}) {
18 if (isNaN(arg)) {
19 throw new TypeError("Invalid number");
20 }
21
22 let result = [],
23 val = 0,
24 bits = descriptor.bits === true,
25 unix = descriptor.unix === true,
26 base = descriptor.base || 2,
27 round = descriptor.round !== void 0 ? descriptor.round : unix ? 1 : 2,
28 locale = descriptor.locale !== void 0 ? descriptor.locale : "",
29 localeOptions = descriptor.localeOptions || {},
30 separator = descriptor.separator !== void 0 ? descriptor.separator : "",
31 spacer = descriptor.spacer !== void 0 ? descriptor.spacer : unix ? "" : " ",
32 symbols = descriptor.symbols || {},
33 standard = base === 2 ? descriptor.standard || "jedec" : "jedec",
34 output = descriptor.output || "string",
35 full = descriptor.fullform === true,
36 fullforms = descriptor.fullforms instanceof Array ? descriptor.fullforms : [],
37 e = descriptor.exponent !== void 0 ? descriptor.exponent : -1,
38 num = Number(arg),
39 neg = num < 0,
40 ceil = base > 2 ? 1000 : 1024;
41
42 // Flipping a negative number to determine the size
43 if (neg) {
44 num = -num;
45 }
46
47 // Determining the exponent
48 if (e === -1 || isNaN(e)) {
49 e = Math.floor(Math.log(num) / Math.log(ceil));
50
51 if (e < 0) {
52 e = 0;
53 }
54 }
55
56 // Exceeding supported length, time to reduce & multiply
57 if (e > 8) {
58 e = 8;
59 }
60
61 if (output === "exponent") {
62 return e;
63 }
64
65 // Zero is now a special case because bytes divide by 1
66 if (num === 0) {
67 result[0] = 0;
68 result[1] = unix ? "" : symbol[standard][bits ? "bits" : "bytes"][e];
69 } else {
70 val = num / (base === 2 ? Math.pow(2, e * 10) : Math.pow(1000, e));
71
72 if (bits) {
73 val = val * 8;
74
75 if (val >= ceil && e < 8) {
76 val = val / ceil;
77 e++;
78 }
79 }
80
81 result[0] = Number(val.toFixed(e > 0 ? round : 0));
82
83 if (result[0] === ceil && e < 8 && descriptor.exponent === void 0) {
84 result[0] = 1;
85 e++;
86 }
87
88 result[1] = base === 10 && e === 1 ? bits ? "kb" : "kB" : symbol[standard][bits ? "bits" : "bytes"][e];
89
90 if (unix) {
91 result[1] = standard === "jedec" ? result[1].charAt(0) : e > 0 ? result[1].replace(/B$/, "") : result[1];
92
93 if (b.test(result[1])) {
94 result[0] = Math.floor(result[0]);
95 result[1] = "";
96 }
97 }
98 }
99
100 // Decorating a 'diff'
101 if (neg) {
102 result[0] = -result[0];
103 }
104
105 // Applying custom symbol
106 result[1] = symbols[result[1]] || result[1];
107
108 if (locale === true) {
109 result[0] = result[0].toLocaleString();
110 } else if (locale.length > 0) {
111 result[0] = result[0].toLocaleString(locale, localeOptions);
112 } else if (separator.length > 0) {
113 result[0] = result[0].toString().replace(".", separator);
114 }
115
116 // Returning Array, Object, or String (default)
117 if (output === "array") {
118 return result;
119 }
120
121 if (full) {
122 result[1] = fullforms[e] ? fullforms[e] : fullform[standard][e] + (bits ? "bit" : "byte") + (result[0] === 1 ? "" : "s");
123 }
124
125 if (output === "object") {
126 return {value: result[0], symbol: result[1]};
127 }
128
129 return result.join(spacer);
130}
131
132// Partial application for functional programming
133filesize.partial = opt => arg => filesize(arg, opt);
134
135export default filesize;