monzolib
Version:
Fully Featured JS/Node Monzo Library
173 lines (172 loc) • 4.72 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const irregularExponents = {
BIF: 0,
CLP: 0,
CVE: 0,
DJF: 0,
GNF: 0,
ISK: 0,
JPY: 0,
KMF: 0,
KRW: 0,
PYG: 0,
RWF: 0,
UGX: 0,
UYI: 0,
VND: 0,
VUV: 0,
XAF: 0,
XOF: 0,
XPF: 0,
MGA: 1,
MRU: 1,
BHD: 3,
IQD: 3,
JOD: 3,
KWD: 3,
LYD: 3,
OMR: 3,
TND: 3,
CLF: 4,
};
class Amount {
constructor({ domestic, local }) {
if (!domestic)
throw new TypeError('provide an amount');
if (!('amount' in domestic) || typeof domestic.amount !== 'number') {
throw new TypeError('provide a valid value');
}
if (!('currency' in domestic) || typeof domestic.currency !== 'string') {
throw new TypeError('provide a valid currency');
}
if (local && (!('amount' in local) || typeof local.amount !== 'number')) {
throw new TypeError('provide a valid value');
}
if (local &&
(!('currency' in local) || typeof local.currency !== 'string')) {
throw new TypeError('provide a valid currency');
}
this.domestic = domestic;
this.local = local;
const language = (typeof navigator !== 'undefined' &&
navigator &&
(navigator.language || navigator.browserLanguage)) ||
'en-GB';
this.formatter = Intl.NumberFormat(language, {
style: 'currency',
currency: this.domestic.currency,
minimumFractionDigits: this.exponent,
});
}
get currency() {
return this.domestic.currency;
}
get foreign() {
return !!this.local;
}
get exchanged() {
if (this.local)
return new Amount({ domestic: this.local });
else
return;
}
get negative() {
return this.domestic.amount <= 0;
}
get positive() {
return !this.negative;
}
get sign() {
return this.negative ? '-' : '+';
}
get amount() {
return Math.abs(this.domestic.amount) / this.scale;
}
get exponent() {
return irregularExponents.hasOwnProperty(this.domestic.currency)
? irregularExponents[this.domestic.currency]
: 2;
}
get scale() {
return 10 ** this.exponent;
}
get raw() {
return this.domestic.amount;
}
formatParts({ showCurrency = true, signMode = 'always', } = {}) {
const parts = this.formatter.formatToParts(this.amount);
if (this.positive) {
parts.unshift({
type: 'plusSign',
value: '+',
});
}
else {
parts.unshift({
type: 'minusSign',
value: '−',
});
}
const strfpart = {
currency: () => {
return showCurrency;
},
minusSign: () => {
return signMode === 'always' || signMode === 'onlyNegative';
},
plusSign: () => {
return signMode === 'always' || signMode === 'onlyPositive';
},
};
return parts.filter(({ type, value }) => {
if (strfpart.hasOwnProperty(type)) {
return strfpart[type]({ type, value });
}
else {
return true;
}
});
}
format(formatOpts) {
return this.formatParts(formatOpts).reduce((str, part) => str + part.value, '');
}
html(formatOpts) {
const str = this.formatParts(formatOpts)
.map(({ type, value }) => `<span class="amount__${type}">${value}</span>`)
.reduce((str, part) => str + part);
const el = document.createElement('span');
el.classList.add('amount');
el.dataset.positive = this.positive ? 'positive' : 'negative';
el.dataset.currency = this.currency;
el.innerHTML = str;
return el.outerHTML;
}
get json() {
return {
domestic: this.domestic,
local: this.local,
};
}
get stringify() {
return JSON.stringify(this.json);
}
add(amount) {
if (this.currency !== amount.currency) {
throw new Error('amounts cannot be added');
}
return new Amount({
domestic: {
amount: this.raw + amount.raw,
currency: this.currency,
},
});
}
toString() {
return this.format();
}
valueOf() {
return this.domestic.amount;
}
}
exports.Amount = Amount;