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