UNPKG

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