import { formatAmount, formatNumber } from '@transferwise/formatting'; import { DEFAULT_LOCALE } from '../common/locale'; export { formatAmount, formatNumber }; // TODO: do not duplicate this between formatting and components const currencyDecimals: Record = { BIF: 0, BYR: 0, CLP: 0, DJF: 0, GNF: 0, JPY: 0, KMF: 0, KRW: 0, MGA: 0, PYG: 0, RWF: 0, VND: 0, VUV: 0, XAF: 0, XOF: 0, XPF: 0, // technically HUF does have decimals, but due to the exchange rate banks // do not accept decimal amounts HUF: 0, BHD: 3, JOD: 3, KWD: 3, OMR: 3, TND: 3, }; const DEFAULT_CURRENCY_DECIMALS = 2; function isNumberLocaleSupported() { const number = 1234; const numberString = number.toLocaleString && number.toLocaleString(DEFAULT_LOCALE); return numberString === '1,234'; } function getValidLocale(locale: string) { try { const noUnderscoreLocale = locale.replace(/_/, '-'); Intl.NumberFormat(noUnderscoreLocale); return noUnderscoreLocale; } catch { return DEFAULT_LOCALE; } } export function getCurrencyDecimals(currency: string) { const upperCaseCurrency = currency.toUpperCase(); return currencyDecimals[upperCaseCurrency] ?? DEFAULT_CURRENCY_DECIMALS; } function getDecimalSeparator(locale: string) { return isNumberLocaleSupported() ? (1.1).toLocaleString(locale)[1] : '.'; } export function parseAmount( number: string, currency: string, locale = DEFAULT_LOCALE, decimals?: number, ) { const validLocale = getValidLocale(locale); const currencyDefault = getCurrencyDecimals(currency); const precision = currencyDefault === 0 ? 0 : (decimals ?? currencyDefault); const groupSeparator = isNumberLocaleSupported() ? (10000).toLocaleString(validLocale)[2] : ','; const decimalSeparator = getDecimalSeparator(validLocale); const numberWithStandardDecimalSeparator = (number || '') .replace(new RegExp(`\\${groupSeparator}`, 'g'), '') .replace(new RegExp(`\\${decimalSeparator}`, 'g'), '.') .replace(/[^0-9.]/g, ''); const parsedAmount = Number.parseFloat( Number.parseFloat(numberWithStandardDecimalSeparator).toFixed(precision), ); return Math.abs(parsedAmount); }