@easymoney/money
Version:
Best way to do money in js
418 lines (417 loc) • 12.5 kB
JavaScript
((n, t) => {
"object" == typeof exports && "undefined" != typeof module
? t(exports, require("@easymoney/core"))
: "function" == typeof define && define.amd
? define(["exports", "@easymoney/core"], t)
: t(((n = n || self).easymoneyMoney = {}), n.easyMoneyCore);
})(this, (n, t) => {
function e(n, e = "") {
if ("" === n && "" === e) throw new TypeError("Empty number is invalid");
const a = { integerPart: r(String(n)), fractionalPart: o(String(e)) },
i = {};
return (
(i.isInteger = t.bind(u, a)),
(i.getIntegerPart = () => a.integerPart),
(i.getFractionalPart = () => a.fractionalPart),
(i.toString = t.bind(c, a)),
i
);
}
function r(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 (!j[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 o(n) {
if ("" === n) return n;
for (let t = 0; t < n.length; t++) {
const e = n[t];
if (!j[e])
throw new Error(
`Invalid fractional part ${n}. Invalid digit ${e} found`
);
}
return n;
}
function u(n) {
return "" === n.fractionalPart;
}
function a(n) {
const t = n.indexOf(".");
if (-1 === t) return e(n, "");
const r = n.substr(t + 1);
return e(n.substr(0, t), r.replace(/0+$/, ""));
}
function i(n) {
if (
"number" == typeof n &&
!isNaN(parseInt(n)) &&
isFinite(n) &&
!Number.isInteger(n)
)
return a(n.toFixed(14));
if (Number.isInteger(n)) return e(n);
if ("string" == typeof n) return a(n);
throw new TypeError("Valid numeric value expected");
}
function c(n) {
const { fractionalPart: t, integerPart: e } = n;
return "" === t ? e : `${e}.${t}`;
}
function s(n) {
return Y(n);
}
function l(n, e, r) {
R(r);
const { calculator: o } = n;
return r === t.RoundingModes.CEILING
? o.ceil(e)
: r === t.RoundingModes.FLOOR
? o.floor(e)
: o.round(e, r);
}
function d(n, money) {
const { publicInstance: t, privateInstance: e } = n,
{ calculator: r, instanceMoney: o } = e;
p(t, money);
const u = r.add(money.getAmount(), o.amount);
return Y(e.calculator)({ amount: u, currency: money.getCurrency() });
}
function m(n, money) {
const { publicInstance: t, privateInstance: e } = n,
{ calculator: r } = e;
p(t, money);
const o = r.subtract(t.getAmount(), money.getAmount());
return Y(e.calculator)({ amount: o, currency: money.getCurrency() });
}
function g(n) {
return n.instanceMoney.amount;
}
function f(n) {
return n.instanceMoney.currency;
}
function b(n, money) {
return n.getCurrency() === money.getCurrency();
}
function p(n, money) {
t.assert(b(n, money), new TypeError("Currencies must be identical"));
}
function y(n, money) {
return (
n.publicInstance.isSameCurrency(money) &&
n.privateInstance.instanceMoney.amount === money.getAmount()
);
}
function M(n, money) {
const { publicInstance: t, privateInstance: e } = n;
return (
p(t, money),
e.calculator.compare(e.instanceMoney.amount, money.getAmount())
);
}
function I(n, money) {
return n.compare(money) > 0;
}
function h(n, money) {
return n.compare(money) >= 0;
}
function N(n, money) {
return n.compare(money) < 0;
}
function E(n, money) {
return n.compare(money) <= 0;
}
function A(n, e, r = t.RoundingModes.HALF_EVEN) {
w(e), R(r);
const { publicInstance: o, privateInstance: u } = n,
{ calculator: a } = u,
i = a.multiply(o.getAmount(), e),
c = u.round(i, r);
return Y(u.calculator)({ amount: c, currency: o.getCurrency() });
}
function w(n) {
t.assert(
(n => !isNaN(parseInt(n)) && isFinite(n))(n),
new TypeError("Operand should be a numeric value.")
);
}
function R(n) {
t.assert(
[
t.RoundingModes.CEILING,
t.RoundingModes.DOWN,
t.RoundingModes.FLOOR,
t.RoundingModes.HALF_DOWN,
t.RoundingModes.HALF_EVEN,
t.RoundingModes.HALF_UP,
t.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 v(n, e, r = t.RoundingModes.HALF_EVEN) {
w(e), R(r);
const { privateInstance: o, publicInstance: u } = n,
{ round: a, calculator: c } = o,
s = i(e).toString();
if (0 === c.compare(s, "0")) throw new TypeError("Division by zero");
const l = a(c.divide(u.getAmount(), s), r);
return Y(c)({ amount: l, currency: u.getCurrency() });
}
function C(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 F(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 T(n, t) {
p(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 _(n) {
const { privateInstance: t, publicInstance: e } = n;
return Y(t.calculator)({
amount: t.calculator.absolute(e.getAmount()),
currency: e.getCurrency()
});
}
function L(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 O(n) {
const { privateInstance: t, publicInstance: e } = n,
{ calculator: r } = t;
return 0 === r.compare(e.getAmount(), "0");
}
function S(n) {
const { privateInstance: t, publicInstance: e } = n,
{ calculator: r } = t;
return r.compare(e.getAmount(), "0") > 0;
}
function P(n) {
const { privateInstance: t, publicInstance: e } = n,
{ calculator: r } = t;
return r.compare(e.getAmount(), "0") < 0;
}
function H(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 x(n) {
const t = Math.round(n);
return (n => Math.abs(n) % 1 == 0.5)(n)
? (n => n % 2 == 0)(t)
? t
: t - 1
: t;
}
function G(n) {
return -Math.sign(n) * Math.ceil(-Math.abs(n) - 0.5);
}
function D(n) {
return -Math.sign(n) * Math.floor(0.5 - Math.abs(n));
}
function U(n) {
return -Math.ceil(-n);
}
function $(n) {
return -Math.floor(-n);
}
function z(n) {
return -Math.sign(n) * Math.ceil(-Math.abs(n));
}
function V(n) {
return -Math.sign(n) * Math.floor(-Math.abs(n));
}
function W(n) {
return X(n), String(parseInt(String(n), 10));
}
function q(n) {
const e = Number(n);
t.assert(
"number" == typeof e && Number.isInteger(e),
new TypeError("The result of arithmetic operation is not an integer")
);
}
function X(n) {
t.assert(
!(n > Number.MAX_SAFE_INTEGER),
new RangeError(
"You overflowed the maximum allowed integer (Number.MAX_SAFE_INTEGER)"
)
),
t.assert(
!(n < -Number.MAX_SAFE_INTEGER),
new RangeError(
"You underflowed the minimum allowed integer (-Number.MAX_SAFE_INTEGER)"
)
);
}
const j = { 0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1, 7: 1, 8: 1, 9: 1 },
Y = n => ({ amount: e, currency: r }) => {
const money = ((n, t) => {
let e = null;
if (!Number.isInteger(Number(n))) {
let t = a(n);
if (!t.isInteger())
throw new Error("Amount must be an integer(ish) value");
e = t.getIntegerPart();
}
return { amount: e || a(String(n)).toString(), currency: t };
})(e, r),
o = { calculator: n, instanceMoney: money };
o.round = t.bind(l, o);
const u = {},
i = { privateInstance: o, publicInstance: u };
return (
(u.add = t.bind(d, i)),
(u.isSameCurrency = t.bind(b, u)),
(u.getAmount = t.bind(g, o)),
(u.getCurrency = t.bind(f, o)),
(u.equals = t.bind(y, i)),
(u.compare = t.bind(M, i)),
(u.greaterThan = t.bind(I, u)),
(u.greaterThanOrEqual = t.bind(h, u)),
(u.lessThan = t.bind(N, u)),
(u.lessThanOrEqual = t.bind(E, u)),
(u.subtract = t.bind(m, i)),
(u.multiply = t.bind(A, i)),
(u.divide = t.bind(v, i)),
(u.allocate = t.bind(C, i)),
(u.allocateTo = t.bind(F, i)),
(u.mod = t.bind(T, i)),
(u.absolute = t.bind(_, i)),
(u.negative = t.bind(L, i)),
(u.isZero = t.bind(O, i)),
(u.isPositive = t.bind(S, i)),
(u.isNegative = t.bind(P, i)),
(u.ratioOf = t.bind(H, i)),
u
);
},
Z = (n, t) => {
const e = Number(n) - Number(t);
return q(e), String(e);
},
k = (n, t) => (n < t ? -1 : n > t ? 1 : 0),
B = (n, t) => {
const e = Number(n) + Number(t);
return q(e), String(e);
},
J = (n, t) => {
const e = Number(n) * Number(t);
return X(e), i(e).toString();
},
K = n => W(Math.ceil(Number(n))),
Q = n => W(Math.floor(Number(n))),
nn = (n, t) => {
const e = Number(n) / Number(t);
return X(e), i(e).toString();
},
tn = n => {
const t = Math.abs(Number(n));
return X(t), String(t);
},
en = (n, e) =>
W(
((n, e) =>
({
[t.RoundingModes.HALF_EVEN]: x,
[t.RoundingModes.HALF_UP]: G,
[t.RoundingModes.HALF_DOWN]: D,
[t.RoundingModes.FLOOR]: U,
[t.RoundingModes.CEILING]: $,
[t.RoundingModes.DOWN]: z,
[t.RoundingModes.UP]: V
}[e](n)))(Number(n), e)
),
rn = (n, t, e) => W(Math.floor((Number(n) * Number(t)) / Number(e))),
on = (n, t) => {
const e = Number(n) % Number(t);
return X(e), String(e);
},
un = s(
(() => ({
compare: k,
add: B,
subtract: Z,
multiply: J,
divide: nn,
ceil: K,
absolute: tn,
floor: Q,
share: rn,
round: en,
mod: on
}))()
);
(n.createMoney = un),
(n.createMoneyUnit = s),
Object.defineProperty(n, "__esModule", { value: 1 });
});
//# sourceMappingURL=index.umd.js.map