human-format
Advanced tools
Comparing version 0.11.0 to 1.0.0
330
index.js
// UMD: https://github.com/umdjs/umd/blob/master/returnExports.js | ||
(function (root, factory) { | ||
/* global define: false */ | ||
if (typeof define === 'function' && define.amd) { | ||
if (typeof define === "function" && define.amd) { | ||
// AMD. Register as an anonymous module. | ||
define([], factory) | ||
} else if (typeof exports === 'object') { | ||
define([], factory); | ||
} else if (typeof exports === "object") { | ||
// Node. Does not work with strict CommonJS, but | ||
// only CommonJS-like environments that support module.exports, | ||
// like Node. | ||
module.exports = factory() | ||
module.exports = factory(); | ||
} else { | ||
// Browser globals (root is window) | ||
root.humanFormat = factory() | ||
root.humanFormat = factory(); | ||
} | ||
}(this, function () { | ||
'use strict' | ||
})(this, function () { | ||
"use strict"; | ||
// ================================================================= | ||
function assign (dst, src) { | ||
var i, n, prop | ||
function assign(dst, src) { | ||
var i, n, prop; | ||
for (i = 1, n = arguments.length; i < n; ++i) { | ||
src = arguments[i] | ||
src = arguments[i]; | ||
if (src != null) { | ||
for (prop in src) { | ||
if (has(src, prop)) { | ||
dst[prop] = src[prop] | ||
dst[prop] = src[prop]; | ||
} | ||
@@ -33,30 +33,30 @@ } | ||
} | ||
return dst | ||
return dst; | ||
} | ||
function compareLongestFirst (a, b) { | ||
return b.length - a.length | ||
function compareLongestFirst(a, b) { | ||
return b.length - a.length; | ||
} | ||
function compareSmallestFactorFirst (a, b) { | ||
return a.factor - b.factor | ||
function compareSmallestFactorFirst(a, b) { | ||
return a.factor - b.factor; | ||
} | ||
// https://www.npmjs.org/package/escape-regexp | ||
function escapeRegexp (str) { | ||
return str.replace(/([.*+?=^!:${}()|[\]/\\])/g, '\\$1') | ||
function escapeRegexp(str) { | ||
return str.replace(/([.*+?=^!:${}()|[\]/\\])/g, "\\$1"); | ||
} | ||
function forEach (arr, iterator) { | ||
var i, n | ||
function forEach(arr, iterator) { | ||
var i, n; | ||
for (i = 0, n = arr.length; i < n; ++i) { | ||
iterator(arr[i], i) | ||
iterator(arr[i], i); | ||
} | ||
} | ||
function forOwn (obj, iterator) { | ||
var prop | ||
function forOwn(obj, iterator) { | ||
var prop; | ||
for (prop in obj) { | ||
if (has(obj, prop)) { | ||
iterator(obj[prop], prop) | ||
iterator(obj[prop], prop); | ||
} | ||
@@ -67,12 +67,12 @@ } | ||
var has = (function (hasOwnProperty) { | ||
return function has (obj, prop) { | ||
return obj != null && hasOwnProperty.call(obj, prop) | ||
} | ||
})(Object.prototype.hasOwnProperty) | ||
return function has(obj, prop) { | ||
return obj != null && hasOwnProperty.call(obj, prop); | ||
}; | ||
})(Object.prototype.hasOwnProperty); | ||
function resolve (container, entry) { | ||
while (typeof entry === 'string') { | ||
entry = container[entry] | ||
function resolve(container, entry) { | ||
while (typeof entry === "string") { | ||
entry = container[entry]; | ||
} | ||
return entry | ||
return entry; | ||
} | ||
@@ -82,95 +82,95 @@ | ||
function Scale (prefixes) { | ||
this._prefixes = prefixes | ||
function Scale(prefixes) { | ||
this._prefixes = prefixes; | ||
var escapedPrefixes = [] | ||
var list = [] | ||
var escapedPrefixes = []; | ||
var list = []; | ||
forOwn(prefixes, function (factor, prefix) { | ||
escapedPrefixes.push(escapeRegexp(prefix)) | ||
escapedPrefixes.push(escapeRegexp(prefix)); | ||
list.push({ | ||
factor: factor, | ||
prefix: prefix | ||
}) | ||
}) | ||
prefix: prefix, | ||
}); | ||
}); | ||
// Adds lower cased prefixes for case insensitive fallback. | ||
var lcPrefixes = this._lcPrefixes = {} | ||
var lcPrefixes = (this._lcPrefixes = {}); | ||
forOwn(prefixes, function (factor, prefix) { | ||
var lcPrefix = prefix.toLowerCase() | ||
var lcPrefix = prefix.toLowerCase(); | ||
if (!has(prefixes, lcPrefix)) { | ||
lcPrefixes[lcPrefix] = prefix | ||
lcPrefixes[lcPrefix] = prefix; | ||
} | ||
}) | ||
}); | ||
list.sort(compareSmallestFactorFirst) | ||
this._list = list | ||
list.sort(compareSmallestFactorFirst); | ||
this._list = list; | ||
escapedPrefixes.sort(compareLongestFirst) | ||
escapedPrefixes.sort(compareLongestFirst); | ||
this._regexp = new RegExp( | ||
'^\\s*(-)?\\s*(\\d+(?:\\.\\d+)?)\\s*(' + | ||
escapedPrefixes.join('|') + | ||
')\\s*(.*)\\s*?$', | ||
'i' | ||
) | ||
"^\\s*(-)?\\s*(\\d+(?:\\.\\d+)?)\\s*(" + | ||
escapedPrefixes.join("|") + | ||
")\\s*(.*)\\s*?$", | ||
"i" | ||
); | ||
} | ||
Scale.create = function Scale$create (prefixesList, base, initExp) { | ||
var prefixes = {} | ||
Scale.create = function Scale$create(prefixesList, base, initExp) { | ||
var prefixes = {}; | ||
if (initExp === undefined) { | ||
initExp = 0 | ||
initExp = 0; | ||
} | ||
forEach(prefixesList, function (prefix, i) { | ||
prefixes[prefix] = Math.pow(base, i + initExp) | ||
}) | ||
prefixes[prefix] = Math.pow(base, i + initExp); | ||
}); | ||
return new Scale(prefixes) | ||
} | ||
return new Scale(prefixes); | ||
}; | ||
// Binary search to find the greatest index which has a value <=. | ||
Scale.prototype.findPrefix = function Scale$findPrefix (value) { | ||
var list = this._list | ||
var low = 0 | ||
var high = list.length - 1 | ||
Scale.prototype.findPrefix = function Scale$findPrefix(value) { | ||
var list = this._list; | ||
var low = 0; | ||
var high = list.length - 1; | ||
var mid, current | ||
var mid, current; | ||
while (low !== high) { | ||
mid = (low + high + 1) >> 1 | ||
current = list[mid].factor | ||
mid = (low + high + 1) >> 1; | ||
current = list[mid].factor; | ||
if (current > value) { | ||
high = mid - 1 | ||
high = mid - 1; | ||
} else { | ||
low = mid | ||
low = mid; | ||
} | ||
} | ||
return list[low] | ||
} | ||
return list[low]; | ||
}; | ||
Scale.prototype.parse = function Scale$parse (str, strict) { | ||
var matches = str.match(this._regexp) | ||
Scale.prototype.parse = function Scale$parse(str, strict) { | ||
var matches = str.match(this._regexp); | ||
if (matches === null) { | ||
return | ||
return; | ||
} | ||
var prefix = matches[3] | ||
var factor | ||
var prefix = matches[3]; | ||
var factor; | ||
if (has(this._prefixes, prefix)) { | ||
factor = this._prefixes[prefix] | ||
factor = this._prefixes[prefix]; | ||
} else if ( | ||
!strict && | ||
(prefix = prefix.toLowerCase(), has(this._lcPrefixes, prefix)) | ||
((prefix = prefix.toLowerCase()), has(this._lcPrefixes, prefix)) | ||
) { | ||
prefix = this._lcPrefixes[prefix] | ||
factor = this._prefixes[prefix] | ||
prefix = this._lcPrefixes[prefix]; | ||
factor = this._prefixes[prefix]; | ||
} else { | ||
return | ||
return; | ||
} | ||
var value = +matches[2] | ||
var value = +matches[2]; | ||
if (matches[1] !== undefined) { | ||
value = -value | ||
value = -value; | ||
} | ||
@@ -182,5 +182,5 @@ | ||
unit: matches[4], | ||
value: value | ||
} | ||
} | ||
value: value, | ||
}; | ||
}; | ||
@@ -191,6 +191,3 @@ // ================================================================= | ||
// https://en.wikipedia.org/wiki/Binary_prefix | ||
binary: Scale.create( | ||
',Ki,Mi,Gi,Ti,Pi,Ei,Zi,Yi'.split(','), | ||
1024 | ||
), | ||
binary: Scale.create(",Ki,Mi,Gi,Ti,Pi,Ei,Zi,Yi".split(","), 1024), | ||
@@ -202,36 +199,42 @@ // https://en.wikipedia.org/wiki/Metric_prefix | ||
// the same unit to ease the comparison. | ||
SI: Scale.create( | ||
'y,z,a,f,p,n,µ,m,,k,M,G,T,P,E,Z,Y'.split(','), | ||
1000, -8 | ||
) | ||
} | ||
SI: Scale.create("y,z,a,f,p,n,µ,m,,k,M,G,T,P,E,Z,Y".split(","), 1000, -8), | ||
}; | ||
var defaults = { | ||
// Decimal digits for formatting. | ||
decimals: 2, | ||
maxDecimals: 2, | ||
// separator to use between value and units | ||
separator: ' ', | ||
separator: " ", | ||
// Unit to use for formatting. | ||
unit: '' | ||
} | ||
unit: "", | ||
}; | ||
var rawDefaults = { | ||
scale: 'SI', | ||
scale: "SI", | ||
// Strict mode prevents parsing of incorrectly cased prefixes. | ||
strict: false | ||
} | ||
strict: false, | ||
}; | ||
function humanFormat (value, opts) { | ||
opts = assign({}, defaults, opts) | ||
function humanFormat(value, opts) { | ||
opts = assign({}, defaults, opts); | ||
var info = humanFormat$raw(value, opts) | ||
value = String(info.value) | ||
var suffix = info.prefix + opts.unit | ||
return suffix === '' ? value : value + opts.separator + suffix | ||
var decimals = opts.decimals; | ||
if (decimals !== undefined) { | ||
// humanFormat$raw should not round when using decimals option | ||
delete opts.maxDecimals; | ||
} | ||
var info = humanFormat$raw(value, opts); | ||
value = | ||
decimals !== undefined | ||
? info.value.toFixed(decimals) | ||
: String(info.value); | ||
var suffix = info.prefix + opts.unit; | ||
return suffix === "" ? value : value + opts.separator + suffix; | ||
} | ||
var humanFormat$bytes$opts = { scale: 'binary', unit: 'B' } | ||
function humanFormat$bytes (value, opts) { | ||
var humanFormat$bytes$opts = { scale: "binary", unit: "B" }; | ||
function humanFormat$bytes(value, opts) { | ||
return humanFormat( | ||
@@ -242,23 +245,23 @@ value, | ||
: assign({}, humanFormat$bytes$opts, opts) | ||
) | ||
); | ||
} | ||
function humanFormat$parse (str, opts) { | ||
var info = humanFormat$parse$raw(str, opts) | ||
function humanFormat$parse(str, opts) { | ||
var info = humanFormat$parse$raw(str, opts); | ||
return info.value * info.factor | ||
return info.value * info.factor; | ||
} | ||
function humanFormat$parse$raw (str, opts) { | ||
if (typeof str !== 'string') { | ||
throw new TypeError('str must be a string') | ||
function humanFormat$parse$raw(str, opts) { | ||
if (typeof str !== "string") { | ||
throw new TypeError("str must be a string"); | ||
} | ||
// Merge default options. | ||
opts = assign({}, rawDefaults, opts) | ||
opts = assign({}, rawDefaults, opts); | ||
// Get current scale. | ||
var scale = resolve(scales, opts.scale) | ||
var scale = resolve(scales, opts.scale); | ||
if (scale === undefined) { | ||
throw new Error('missing scale') | ||
throw new Error("missing scale"); | ||
} | ||
@@ -272,11 +275,11 @@ | ||
var info = scale.parse(str, opts.strict) | ||
var info = scale.parse(str, opts.strict); | ||
if (info === undefined) { | ||
throw new Error('cannot parse str') | ||
throw new Error("cannot parse str"); | ||
} | ||
return info | ||
return info; | ||
} | ||
function humanFormat$raw (value, opts) { | ||
function humanFormat$raw(value, opts) { | ||
// Zero is a special case, it never has any prefix. | ||
@@ -286,42 +289,45 @@ if (value === 0) { | ||
value: 0, | ||
prefix: '' | ||
} | ||
prefix: "", | ||
}; | ||
} else if (value < 0) { | ||
var result = humanFormat$raw(-value, opts) | ||
result.value = -result.value | ||
return result | ||
var result = humanFormat$raw(-value, opts); | ||
result.value = -result.value; | ||
return result; | ||
} | ||
if (typeof value !== 'number' || Number.isNaN(value)) { | ||
throw new TypeError('value must be a number') | ||
if (typeof value !== "number" || Number.isNaN(value)) { | ||
throw new TypeError("value must be a number"); | ||
} | ||
// Merge default options. | ||
opts = assign({}, rawDefaults, opts) | ||
opts = assign({}, rawDefaults, opts); | ||
// Get current scale. | ||
var scale = resolve(scales, opts.scale) | ||
var scale = resolve(scales, opts.scale); | ||
if (scale === undefined) { | ||
throw new Error('missing scale') | ||
throw new Error("missing scale"); | ||
} | ||
var power | ||
var decimals = opts.decimals | ||
if (decimals !== undefined) { | ||
power = Math.pow(10, decimals) | ||
var power; | ||
var maxDecimals = opts.maxDecimals; | ||
var autoMaxDecimals = maxDecimals === "auto"; | ||
if (autoMaxDecimals) { | ||
power = 10; | ||
} else if (maxDecimals !== undefined) { | ||
power = Math.pow(10, maxDecimals); | ||
} | ||
var prefix = opts.prefix | ||
var factor | ||
var prefix = opts.prefix; | ||
var factor; | ||
if (prefix !== undefined) { | ||
if (!has(scale._prefixes, prefix)) { | ||
throw new Error('invalid prefix') | ||
throw new Error("invalid prefix"); | ||
} | ||
factor = scale._prefixes[prefix] | ||
factor = scale._prefixes[prefix]; | ||
} else { | ||
var _ref = scale.findPrefix(value) | ||
var _ref = scale.findPrefix(value); | ||
if (power !== undefined) { | ||
do { | ||
factor = _ref.factor | ||
factor = _ref.factor; | ||
@@ -331,28 +337,34 @@ // factor is usually >> power, therefore it's better to | ||
// numerical error | ||
var r = factor / power | ||
var r = factor / power; | ||
value = Math.round(value / r) * r | ||
} while ((_ref = scale.findPrefix(value)).factor !== factor) | ||
value = Math.round(value / r) * r; | ||
} while ((_ref = scale.findPrefix(value)).factor !== factor); | ||
} else { | ||
factor = _ref.factor | ||
factor = _ref.factor; | ||
} | ||
prefix = _ref.prefix | ||
prefix = _ref.prefix; | ||
} | ||
value = | ||
power === undefined | ||
? value / factor | ||
: Math.round((value * power) / factor) / power; | ||
if (autoMaxDecimals && Math.abs(value) >= 10) { | ||
value = Math.round(value); | ||
} | ||
return { | ||
prefix: prefix, | ||
value: power === undefined | ||
? value / factor | ||
: Math.round(value * power / factor) / power | ||
} | ||
value: value, | ||
}; | ||
} | ||
humanFormat.bytes = humanFormat$bytes | ||
humanFormat.parse = humanFormat$parse | ||
humanFormat$parse.raw = humanFormat$parse$raw | ||
humanFormat.raw = humanFormat$raw | ||
humanFormat.Scale = Scale | ||
humanFormat.bytes = humanFormat$bytes; | ||
humanFormat.parse = humanFormat$parse; | ||
humanFormat$parse.raw = humanFormat$parse$raw; | ||
humanFormat.raw = humanFormat$raw; | ||
humanFormat.Scale = Scale; | ||
return humanFormat | ||
})) | ||
return humanFormat; | ||
}); |
{ | ||
"name": "human-format", | ||
"version": "0.11.0", | ||
"version": "1.0.0", | ||
"license": "ISC", | ||
@@ -37,23 +37,31 @@ "description": "Converts a number to/from a human readable string: `1337` ↔ `1.34kB`", | ||
"devDependencies": { | ||
"browserify": "^16.2.3", | ||
"husky": "^3.0.7", | ||
"jest": "^24.8.0", | ||
"standard": "^14.3.1", | ||
"browserify": "^17.0.0", | ||
"eslint": "^7.32.0", | ||
"eslint-config-prettier": "^8.3.0", | ||
"eslint-config-standard": "^16.0.3", | ||
"eslint-plugin-import": "^2.25.4", | ||
"eslint-plugin-node": "^11.1.0", | ||
"eslint-plugin-promise": "^5.2.0", | ||
"husky": "^4.3.8", | ||
"lint-staged": "^12.1.5", | ||
"prettier": "^2.5.1", | ||
"tap": "^16.0.0", | ||
"uglify-js": "^3.1.8" | ||
}, | ||
"scripts": { | ||
"dev-test": "jest --watch", | ||
"dev-test": "tap --no-check-coverage --watch", | ||
"prepublishOnly": "mkdir -p dist && browserify -s humanFormat index.js | uglifyjs -c > dist/human-format.js", | ||
"pretest": "standard --fix", | ||
"test": "jest" | ||
"test": "tap --no-check-coverage" | ||
}, | ||
"jest": { | ||
"collectCoverage": true, | ||
"testEnvironment": "node" | ||
}, | ||
"husky": { | ||
"hooks": { | ||
"pre-commit": "npm run test" | ||
"pre-commit": "lint-staged && npm run test" | ||
} | ||
}, | ||
"lint-staged": { | ||
"*.js": [ | ||
"prettier --write", | ||
"eslint --ignore-pattern '!*'" | ||
] | ||
} | ||
} |
@@ -9,3 +9,2 @@ # human-format | ||
## Installation | ||
@@ -24,3 +23,3 @@ | ||
```javascript | ||
var humanFormat = require('human-format'); | ||
var humanFormat = require("human-format"); | ||
``` | ||
@@ -41,20 +40,37 @@ | ||
```javascript | ||
humanFormat(1337) | ||
humanFormat(1337); | ||
//=> '1.34 k' | ||
// The number of decimals can be changed. | ||
// The maximum number of decimals can be changed. | ||
humanFormat(1337, { | ||
decimals: 1 | ||
}) | ||
maxDecimals: 1, | ||
}); | ||
//=> '1.3 k' | ||
// maxDecimals can be set to auto, so that there is 1 decimal between -10 and 10 excluded and none out of this interval. | ||
humanFormat(1337, { | ||
maxDecimals: 'auto', | ||
}); | ||
//=> '1.3 k' | ||
humanFormat(13337, { | ||
maxDecimals: 'auto', | ||
}); | ||
//=> '13 k' | ||
// A fixed number of decimals can be set. | ||
humanFormat(1337, { | ||
decimals: 4, | ||
}); | ||
//=> '1.3370 k' | ||
// Units and scales can be specified. | ||
humanFormat(65536, { | ||
scale: 'binary', | ||
unit: 'B' | ||
}) | ||
scale: "binary", | ||
unit: "B", | ||
}); | ||
//=> 64 kiB | ||
// There is a helper for this. | ||
humanFormat.bytes(65536) | ||
humanFormat.bytes(65536); | ||
//=> 64 kiB | ||
@@ -64,4 +80,4 @@ | ||
humanFormat(1337, { | ||
separator: ' - ' | ||
}) | ||
separator: " - ", | ||
}); | ||
//=> 1.34 - k | ||
@@ -76,12 +92,12 @@ | ||
months: 2592000, | ||
}) | ||
humanFormat(26729235, { scale: timeScale }) | ||
}); | ||
humanFormat(26729235, { scale: timeScale }); | ||
//=> 10.31 months | ||
// You can force a prefix to be used. | ||
humanFormat(100, { unit: 'm', prefix: 'k' }) | ||
humanFormat(100, { unit: "m", prefix: "k" }); | ||
//=> 0.1 km | ||
// You can access the raw result. | ||
humanFormat.raw(100, { prefix: 'k' }) | ||
humanFormat.raw(100, { prefix: "k" }); | ||
//=> { | ||
@@ -96,11 +112,11 @@ // prefix: 'k', | ||
```javascript | ||
humanFormat.parse('1.34 kiB', { scale: 'binary' }) | ||
humanFormat.parse("1.34 kiB", { scale: "binary" }); | ||
//=> 1372.16 | ||
// Fallbacks when possible if the prefix is incorrectly cased. | ||
humanFormat.parse('1 g') | ||
humanFormat.parse("1 g"); | ||
// => 1000000000 | ||
// You can access the raw result. | ||
humanFormat.parse.raw('1.34 kB') | ||
humanFormat.parse.raw("1.34 kB"); | ||
//=> { | ||
@@ -116,3 +132,3 @@ // factor: 1000, | ||
Contributions are *very* welcomed, either on the documentation or on | ||
Contributions are _very_ welcomed, either on the documentation or on | ||
the code. | ||
@@ -119,0 +135,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
14385
299
0
145
12
1