UNPKG

monzolib

Version:

Fully Featured JS/Node Monzo Library

173 lines (172 loc) 4.72 kB
"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;