@easymoney/money
Version:
Best way to do money in js
391 lines (390 loc) • 11.3 kB
JavaScript
function n(n, o = "") {
if ("" === n && "" === o) throw new TypeError("Empty number is invalid");
const u = { integerPart: t(String(n)), fractionalPart: e(String(o)) },
i = {};
return (
(i.isInteger = q.bind(r, u)),
(i.getIntegerPart = () => u.integerPart),
(i.getFractionalPart = () => u.fractionalPart),
(i.toString = q.bind(a, u)),
i
);
}
function t(n) {
if ("" === n || "0" === n) return "0";
if ("-" === n) return "-0";
let t = 0,
e = 0;
for (let r = 0; r < n.length; r++) {
const o = n[r];
if (!X[o] && (0 !== r || ("-" !== o && "+" !== o)))
throw new Error(`Invalid integer part ${n}. Invalid digit ${o} found`);
if ((0 === r && "+" === o && (e = 1), 0 == t && "0" === o))
throw new Error("Leading zeros are not allowed");
t = 1;
}
return e ? n.substr(1) : n;
}
function e(n) {
if ("" === n) return n;
for (let t = 0; t < n.length; t++) {
const e = n[t];
if (!X[e])
throw new Error(`Invalid fractional part ${n}. Invalid digit ${e} found`);
}
return n;
}
function r(n) {
return "" === n.fractionalPart;
}
function o(t) {
const e = t.indexOf(".");
if (-1 === e) return n(t, "");
const r = t.substr(e + 1);
return n(t.substr(0, e), r.replace(/0+$/, ""));
}
function u(t) {
if (
"number" == typeof t &&
!isNaN(parseInt(t)) &&
isFinite(t) &&
!Number.isInteger(t)
)
return o(t.toFixed(14));
if (Number.isInteger(t)) return n(t);
if ("string" == typeof t) return o(t);
throw new TypeError("Valid numeric value expected");
}
function a(n) {
const { fractionalPart: t, integerPart: e } = n;
return "" === t ? e : `${e}.${t}`;
}
function i(n) {
return Y(n);
}
function c(n, t, e) {
A(e);
const { calculator: r } = n;
return e === q.RoundingModes.CEILING
? r.ceil(t)
: e === q.RoundingModes.FLOOR
? r.floor(t)
: r.round(t, e);
}
function s(n, money) {
const { publicInstance: t, privateInstance: e } = n,
{ calculator: r, instanceMoney: o } = e;
b(t, money);
const u = r.add(money.getAmount(), o.amount);
return Y(e.calculator)({ amount: u, currency: money.getCurrency() });
}
function l(n, money) {
const { publicInstance: t, privateInstance: e } = n,
{ calculator: r } = e;
b(t, money);
const o = r.subtract(t.getAmount(), money.getAmount());
return Y(e.calculator)({ amount: o, currency: money.getCurrency() });
}
function d(n) {
return n.instanceMoney.amount;
}
function g(n) {
return n.instanceMoney.currency;
}
function m(n, money) {
return n.getCurrency() === money.getCurrency();
}
function b(n, money) {
q.assert(m(n, money), new TypeError("Currencies must be identical"));
}
function f(n, money) {
return (
n.publicInstance.isSameCurrency(money) &&
n.privateInstance.instanceMoney.amount === money.getAmount()
);
}
function p(n, money) {
const { publicInstance: t, privateInstance: e } = n;
return (
b(t, money), e.calculator.compare(e.instanceMoney.amount, money.getAmount())
);
}
function y(n, money) {
return n.compare(money) > 0;
}
function I(n, money) {
return n.compare(money) >= 0;
}
function M(n, money) {
return n.compare(money) < 0;
}
function h(n, money) {
return n.compare(money) <= 0;
}
function N(n, t, e = q.RoundingModes.HALF_EVEN) {
E(t), A(e);
const { publicInstance: r, privateInstance: o } = n,
{ calculator: u } = o,
a = u.multiply(r.getAmount(), t),
i = o.round(a, e);
return Y(o.calculator)({ amount: i, currency: r.getCurrency() });
}
function E(n) {
var t;
q.assert(
((t = n), !isNaN(parseInt(t)) && isFinite(t)),
new TypeError("Operand should be a numeric value.")
);
}
function A(n) {
q.assert(
[
q.RoundingModes.CEILING,
q.RoundingModes.DOWN,
q.RoundingModes.FLOOR,
q.RoundingModes.HALF_DOWN,
q.RoundingModes.HALF_EVEN,
q.RoundingModes.HALF_UP,
q.RoundingModes.UP
].includes(n),
new TypeError(
"rounding mode should be one of RoundingModes.CEILING RoundingModes.DOWN RoundingModes.FLOOR RoundingModes.HALF_DOWN RoundingModes.HALF_EVEN RoundingModes.HALF_UP RoundingModes.UP"
)
);
}
function w(n, t, e = q.RoundingModes.HALF_EVEN) {
E(t), A(e);
const { privateInstance: r, publicInstance: o } = n,
{ round: a, calculator: i } = r,
c = u(t).toString();
if (0 === i.compare(c, "0")) throw new TypeError("Division by zero");
const s = a(i.divide(o.getAmount(), c), e);
return Y(i)({ amount: s, currency: o.getCurrency() });
}
function v(n, t) {
if (0 === t.length)
throw new TypeError(
"Cannot allocate to none, ratios cannot be an empty array"
);
const { privateInstance: e, publicInstance: r } = n,
{ calculator: o } = e;
let u = r.getAmount();
const a = [],
i = t.reduce((n, t) => n + t, 0);
if (i <= 0)
throw new TypeError(
"Cannot allocate to none, sum of ratios must be greater than zero"
);
for (let n = 0; n < t.length; n++) {
const e = t[n];
if (e < 0)
throw new TypeError(
"Cannot allocate to none, ratio must be zero or positive"
);
const c = o.share(r.getAmount(), e, i);
(a[n] = c), (u = o.subtract(u, c));
}
if (0 === o.compare(u, "0"))
return a.map(n => Y(o)({ amount: n, currency: r.getCurrency() }));
const c = t.map(n => {
const t = (n / i) * Number(r.getAmount());
return t - Math.floor(t);
});
for (; o.compare(u, "0") > 0; ) {
let n;
if (0 !== c.length) {
let t = [];
c.forEach((n, e) => {
n === Math.max(...c) && t.push(e);
}),
(n = t[0]);
} else n = 0;
(a[n] = o.add(a[n], "1")), (u = o.subtract(u, "1")), (c[n] = 0);
}
return a.map(n => Y(o)({ amount: n, currency: r.getCurrency() }));
}
function R(n, t) {
if (!Number.isInteger(t))
throw new TypeError("Number of targets must be an integer");
if (t <= 0)
throw new TypeError(
"Cannot allocate to none, target must be greater than zero"
);
return n.publicInstance.allocate(Array(t).fill(1));
}
function C(n, t) {
b(n.publicInstance, t);
const { publicInstance: e, privateInstance: r } = n,
{ calculator: o } = r,
u = o.mod(e.getAmount(), t.getAmount());
return Y(r.calculator)({ amount: u, currency: e.getCurrency() });
}
function F(n) {
const { privateInstance: t, publicInstance: e } = n;
return Y(t.calculator)({
amount: t.calculator.absolute(e.getAmount()),
currency: e.getCurrency()
});
}
function T(n) {
const { privateInstance: t, publicInstance: e } = n,
{ calculator: r } = t,
o = r.subtract("0", e.getAmount());
return Y(r)({ amount: o, currency: e.getCurrency() });
}
function _(n) {
const { privateInstance: t, publicInstance: e } = n,
{ calculator: r } = t;
return 0 === r.compare(e.getAmount(), "0");
}
function L(n) {
const { privateInstance: t, publicInstance: e } = n,
{ calculator: r } = t;
return r.compare(e.getAmount(), "0") > 0;
}
function O(n) {
const { privateInstance: t, publicInstance: e } = n,
{ calculator: r } = t;
return r.compare(e.getAmount(), "0") < 0;
}
function S(n, money) {
if (money.isZero()) throw new TypeError("Cannot calculate a ratio of zero");
const { privateInstance: t, publicInstance: e } = n,
{ calculator: r } = t;
return r.divide(e.getAmount(), money.getAmount());
}
function P(n) {
const t = Math.round(n);
return (n => Math.abs(n) % 1 == 0.5)(n) ? (t % 2 == 0 ? t : t - 1) : t;
}
function H(n) {
return -Math.sign(n) * Math.ceil(-Math.abs(n) - 0.5);
}
function x(n) {
return -Math.sign(n) * Math.floor(0.5 - Math.abs(n));
}
function G(n) {
return -Math.ceil(-n);
}
function D(n) {
return -Math.floor(-n);
}
function U(n) {
return -Math.sign(n) * Math.ceil(-Math.abs(n));
}
function $(n) {
return -Math.sign(n) * Math.floor(-Math.abs(n));
}
function z(n) {
return W(n), String(parseInt(String(n), 10));
}
function V(n) {
const t = Number(n);
q.assert(
"number" == typeof t && Number.isInteger(t),
new TypeError("The result of arithmetic operation is not an integer")
);
}
function W(n) {
q.assert(
!(n > Number.MAX_SAFE_INTEGER),
new RangeError(
"You overflowed the maximum allowed integer (Number.MAX_SAFE_INTEGER)"
)
),
q.assert(
!(n < -Number.MAX_SAFE_INTEGER),
new RangeError(
"You underflowed the minimum allowed integer (-Number.MAX_SAFE_INTEGER)"
)
);
}
Object.defineProperty(exports, "__esModule", { value: 1 });
var q = require("@easymoney/core");
const X = { 0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1, 7: 1, 8: 1, 9: 1 },
Y = n => ({ amount: t, currency: e }) => {
const money = ((n, t) => {
let e = null;
if (!Number.isInteger(Number(n))) {
let t = o(n);
if (!t.isInteger())
throw new Error("Amount must be an integer(ish) value");
e = t.getIntegerPart();
}
return { amount: e || o(String(n)).toString(), currency: t };
})(t, e),
r = { calculator: n, instanceMoney: money };
r.round = q.bind(c, r);
const u = {},
a = { privateInstance: r, publicInstance: u };
return (
(u.add = q.bind(s, a)),
(u.isSameCurrency = q.bind(m, u)),
(u.getAmount = q.bind(d, r)),
(u.getCurrency = q.bind(g, r)),
(u.equals = q.bind(f, a)),
(u.compare = q.bind(p, a)),
(u.greaterThan = q.bind(y, u)),
(u.greaterThanOrEqual = q.bind(I, u)),
(u.lessThan = q.bind(M, u)),
(u.lessThanOrEqual = q.bind(h, u)),
(u.subtract = q.bind(l, a)),
(u.multiply = q.bind(N, a)),
(u.divide = q.bind(w, a)),
(u.allocate = q.bind(v, a)),
(u.allocateTo = q.bind(R, a)),
(u.mod = q.bind(C, a)),
(u.absolute = q.bind(F, a)),
(u.negative = q.bind(T, a)),
(u.isZero = q.bind(_, a)),
(u.isPositive = q.bind(L, a)),
(u.isNegative = q.bind(O, a)),
(u.ratioOf = q.bind(S, a)),
u
);
},
Z = i({
compare: (n, t) => (n < t ? -1 : n > t ? 1 : 0),
add: (n, t) => {
const e = Number(n) + Number(t);
return V(e), String(e);
},
subtract: (n, t) => {
const e = Number(n) - Number(t);
return V(e), String(e);
},
multiply: (n, t) => {
const e = Number(n) * Number(t);
return W(e), u(e).toString();
},
divide: (n, t) => {
const e = Number(n) / Number(t);
return W(e), u(e).toString();
},
ceil: n => z(Math.ceil(Number(n))),
absolute: n => {
const t = Math.abs(Number(n));
return W(t), String(t);
},
floor: n => z(Math.floor(Number(n))),
share: (n, t, e) => z(Math.floor((Number(n) * Number(t)) / Number(e))),
round: (n, t) =>
z(
((n, t) =>
({
[q.RoundingModes.HALF_EVEN]: P,
[q.RoundingModes.HALF_UP]: H,
[q.RoundingModes.HALF_DOWN]: x,
[q.RoundingModes.FLOOR]: G,
[q.RoundingModes.CEILING]: D,
[q.RoundingModes.DOWN]: U,
[q.RoundingModes.UP]: $
}[t](n)))(Number(n), t)
),
mod: (n, t) => {
const e = Number(n) % Number(t);
return W(e), String(e);
}
});
(exports.createMoney = Z), (exports.createMoneyUnit = i);
//# sourceMappingURL=index.cjs.js.map