number-string
Version:
Functions to format number to string
202 lines (201 loc) • 7.08 kB
JavaScript
;
exports.__esModule = true;
exports.toClosest = exports.toMoney = exports.toClean = exports.toNumber = exports.toNumberString = void 0;
/**
* Escape special RegExp characters in string
*/
function regexpEscape(s) {
return s.replace(/[-[\]/{}()*+?.\\^$]/g, "\\$&");
}
/**
* Convert value to number string
*/
function toNumberString(value, _a) {
var _b = _a === void 0 ? {} : _a, _c = _b.decimalMark, decimalMark = _c === void 0 ? "." : _c;
if (typeof value === "number") {
return value.toString();
}
if (typeof value !== "string") {
return "NaN";
}
var regexpDecimalMark = regexpEscape(decimalMark);
var n = value.trim();
var negative = n.match(/^\(.*\)$|^-/); //negative if matches '(...)' or '-...'
var getNumberRegexp = new RegExp("[^\\d" + regexpDecimalMark + "]|" + regexpDecimalMark + "(?=.*" + regexpDecimalMark + ")|^\\D*" + regexpDecimalMark + "\\D*$", "g");
n = n.replace(getNumberRegexp, "").replace(decimalMark, "."); //remove all except digits and last dot
if (n === "") {
n = "NaN";
}
else if (negative) {
n = "-" + n;
}
return n;
}
exports.toNumberString = toNumberString;
/**
* Convert value to number
*/
function toNumber(value, _a) {
var _b = _a === void 0 ? {} : _a, _c = _b.decimalMark, decimalMark = _c === void 0 ? "." : _c;
var s = toNumberString(value, { decimalMark: decimalMark });
if (s === "NaN") {
return NaN;
}
return Number(s);
}
exports.toNumber = toNumber;
/**
* Like `toFixed` but removes trailing zeros
*/
function toClean(value, _a) {
var _b = _a === void 0 ? {} : _a, _c = _b.decimalMark, decimalMark = _c === void 0 ? "." : _c, _d = _b.thousandSeperator, thousandSeperator = _d === void 0 ? null : _d, _e = _b.thousandSeparator, thousandSeparator = _e === void 0 ? "," : _e, _f = _b.maxPrecision, maxPrecision = _f === void 0 ? 100 : _f, _g = _b.minPrecision, minPrecision = _g === void 0 ? 0 : _g;
if (thousandSeperator) {
thousandSeparator = thousandSeperator;
console.error("`thousandSeperator` is deprecated use `thousandSeparator` instead.");
}
value = toNumberString(value);
if (value === "NaN") {
return "NaN";
}
if (maxPrecision < 0) {
throw new Error("maxPrecision must be >= 0");
}
if (minPrecision < 0) {
throw new Error("minPrecision must be >= 0");
}
if (maxPrecision > 100) {
throw new Error("maxPrecision must be <= 100");
}
if (minPrecision > 100) {
throw new Error("minPrecision must be <= 100");
}
if (minPrecision > maxPrecision) {
throw new Error("minPrecision must be <= maxPrecision");
}
var s = value;
// limit to maxPrecision
var dotIndex = s.lastIndexOf(".");
if (dotIndex > -1) {
var integer = (dotIndex === 0 ? "0" : s.slice(0, dotIndex));
var fraction = s.slice(dotIndex + 1, dotIndex + 1 + maxPrecision);
var remainder = s.slice(dotIndex + 1 + maxPrecision);
if (remainder.length > 0 && +remainder[0] > 4) {
// round up
var i = (BigInt(integer + fraction) + BigInt(1)).toString(10);
integer = i.slice(0, i.length - fraction.length);
fraction = i.slice(i.length - fraction.length);
}
s = integer + decimalMark + fraction;
}
else {
s += decimalMark;
}
// remove trailing 0s
var rmLen = 0;
for (var i = s.length - 1; i >= 0; i--) {
if (s[i] !== "0") {
break;
}
rmLen++;
}
s = s.slice(0, s.length - rmLen);
// limit to minPrecision
if (minPrecision > 0) {
var numZeros = void 0;
if (dotIndex > -1) {
numZeros = minPrecision - (s.length - dotIndex - 1);
}
else {
numZeros = minPrecision;
}
for (var i = 0; i < numZeros; i++) {
s += "0";
}
}
var regexpDecimalMark = regexpEscape(decimalMark);
var thousandSeparatorRegexp = new RegExp("\\d(?=(\\d{3})+" + regexpDecimalMark + ")", "g");
var trimRegexp = new RegExp(regexpDecimalMark + "$");
s = s.replace(thousandSeparatorRegexp, "$&" + thousandSeparator).replace(trimRegexp, "");
return s;
}
exports.toClean = toClean;
/**
* Convert string or number to currency string
* modified from http://stackoverflow.com/a/149099/806777\
*/
function toMoney(value, _a) {
var _b = _a === void 0 ? {} : _a, _c = _b.decimalMark, decimalMark = _c === void 0 ? "." : _c, _d = _b.thousandSeperator, thousandSeperator = _d === void 0 ? null : _d, _e = _b.thousandSeparator, thousandSeparator = _e === void 0 ? "," : _e, _f = _b.maxPrecision, maxPrecision = _f === void 0 ? 2 : _f, _g = _b.minPrecision, minPrecision = _g === void 0 ? 2 : _g, _h = _b.symbol, symbol = _h === void 0 ? "$" : _h, _j = _b.symbolBehind, symbolBehind = _j === void 0 ? false : _j, _k = _b.useParens, useParens = _k === void 0 ? true : _k;
if (thousandSeperator) {
thousandSeparator = thousandSeperator;
console.error("`thousandSeperator` is deprecated use `thousandSeparator` instead.");
}
var n = (typeof value === "number"
? value
: toNumber(value, {
decimalMark: decimalMark
}));
var s = toNumberString(value, {
decimalMark: decimalMark
});
if (isNaN(n)) {
return "NaN";
}
if (n === Infinity) {
return "Infinity";
}
if (n === -Infinity) {
return (useParens ? "(Infinity)" : "-Infinity");
}
if (maxPrecision < 2 && typeof arguments[1].minPrecision === "undefined") {
minPrecision = maxPrecision;
}
if (minPrecision > 2 && typeof arguments[1].maxPrecision === "undefined") {
maxPrecision = minPrecision;
}
var negative = n < 0;
s = toClean(negative ? s.slice(1) : s, {
decimalMark: decimalMark,
thousandSeparator: thousandSeparator,
maxPrecision: maxPrecision,
minPrecision: minPrecision
});
s = (symbolBehind ? s + " " + symbol : symbol + s);
if (negative) {
s = (useParens ? "(" + s + ")" : "-" + s);
}
return s;
}
exports.toMoney = toMoney;
/**
* Round number to closest multiple of number
*/
function toClosest(value, roundTo) {
if (roundTo === void 0) { roundTo = 1; }
if (typeof value !== "number") {
value = toNumber(value);
}
if (isNaN(value)) {
return NaN;
}
if (value === Infinity || value === -Infinity) {
return value;
}
if (typeof roundTo !== "number") {
roundTo = toNumber(roundTo);
}
if (isNaN(roundTo)) {
throw Error("roundTo must be a number");
}
if (roundTo === Infinity || roundTo === -Infinity) {
return roundTo;
}
var n = Math.round(value / roundTo) * roundTo;
var maxPrecision = 0;
while (!Number.isInteger(roundTo)) {
roundTo *= 10;
maxPrecision++;
}
n = +n.toFixed(maxPrecision);
return n;
}
exports.toClosest = toClosest;