@easymoney/money
Version:
Best way to do money in js
108 lines • 3.28 kB
JavaScript
import { bind } from "@easymoney/core";
const numbers = {
"0": 1,
"1": 1,
"2": 1,
"3": 1,
"4": 1,
"5": 1,
"6": 1,
"7": 1,
"8": 1,
"9": 1
};
export function createNumber(integerPart, fractionalPart = "") {
if ("" === integerPart && "" === fractionalPart) {
throw new TypeError("Empty number is invalid");
}
const innerInstance = {
integerPart: parseIntegerPart(String(integerPart)),
fractionalPart: parseFractionalPart(String(fractionalPart))
};
const instance = {};
instance.isInteger = bind(isInt, innerInstance);
instance.getIntegerPart = () => innerInstance.integerPart;
instance.getFractionalPart = () => innerInstance.fractionalPart;
instance.toString = bind(toString, innerInstance);
return instance;
}
function parseIntegerPart(number) {
if ("" === number || "0" === number) {
return "0";
}
if ("-" === number) {
return "-0";
}
let nonZero = false;
let withPlus = false;
for (let position = 0; position < number.length; position++) {
const digit = number[position];
if (!numbers[digit] &&
!(0 === position && ("-" === digit || "+" === digit))) {
throw new Error(`Invalid integer part ${number}. Invalid digit ${digit} found`);
}
if (0 === position && digit === "+") {
withPlus = true;
}
if (false === nonZero && digit === "0") {
throw new Error("Leading zeros are not allowed");
}
nonZero = true;
}
if (withPlus) {
return number.substr(1);
}
return number;
}
function parseFractionalPart(number) {
if ("" === number) {
return number;
}
for (let position = 0; position < number.length; position++) {
const digit = number[position];
if (!numbers[digit]) {
throw new Error(`Invalid fractional part ${number}. Invalid digit ${digit} found`);
}
}
return number;
}
function isInt(innerInstance) {
return innerInstance.fractionalPart === "";
}
export function fromString(number) {
const decimalSeparatorPosition = number.indexOf(".");
if (decimalSeparatorPosition === -1) {
return createNumber(number, "");
}
const subString = number.substr(decimalSeparatorPosition + 1);
return createNumber(number.substr(0, decimalSeparatorPosition), subString.replace(/0+$/, ""));
}
export function fromNumber(number) {
if (typeof number === "number" &&
!isNaN(parseInt(number)) &&
isFinite(number) &&
!Number.isInteger(number)) {
return fromString(number.toFixed(14));
}
if (Number.isInteger(number)) {
return createNumber(number);
}
if (typeof number === "string") {
return fromString(number);
}
throw new TypeError("Valid numeric value expected");
}
function toString(innerInstance) {
const { fractionalPart, integerPart } = innerInstance;
if (fractionalPart === "") {
return integerPart;
}
return `${integerPart}.${fractionalPart}`;
}
export function isEven(value) {
return value % 2 === 0;
}
export function isHalf(number) {
return Math.abs(number) % 1 === 0.5;
}
//# sourceMappingURL=number.js.map