UNPKG

@accounter/client

Version:
98 lines (92 loc) 2.49 kB
import { Currency } from '../gql/graphql.js'; import { formatStringifyAmount } from './index.js'; export const FIAT_CURRENCIES: Currency[] = [ Currency.Ils, Currency.Eur, Currency.Usd, Currency.Gbp, Currency.Cad, Currency.Jpy, Currency.Aud, Currency.Sek, ] as const; export type CurrencyFormatter = Pick<Intl.NumberFormat, 'format'>; export function getCurrencyFormatter( currency: Currency, options?: Omit<Intl.NumberFormatOptions, 'currency'>, ): CurrencyFormatter { // Crypto currencies (e.g. USDC, ETH, GRT) are not valid ISO 4217 codes, so // `Intl.NumberFormat` with `style: 'currency'` throws a RangeError. Fall back // to decimal formatting and prepend the currency symbol for those. if (!FIAT_CURRENCIES.includes(currency)) { const decimalFormatter = new Intl.NumberFormat('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2, ...options, style: 'decimal', }); return { format: (value: number): string => { // Place the minus sign before the symbol (e.g. `-USDC 1,234.50`) to // match the standard financial notation used for fiat currencies. const symbol = currencyCodeToSymbol(currency); const formatted = decimalFormatter.format(Math.abs(value)); return value < 0 ? `-${symbol} ${formatted}` : `${symbol} ${formatted}`; }, }; } return new Intl.NumberFormat('en-US', { style: 'currency', ...options, currency, }); } export function currencyCodeToSymbol(currency_code: Currency): string { let currencySymbol = '₪'; switch (currency_code) { case 'USD': { currencySymbol = '$'; break; } case 'EUR': { currencySymbol = '€'; break; } case 'GBP': { currencySymbol = '£'; break; } case 'CAD': { currencySymbol = 'C$'; break; } case 'JPY': { currencySymbol = '¥'; break; } case 'AUD': { currencySymbol = 'A$'; break; } case 'SEK': { currencySymbol = 'kr'; break; } case 'GRT': { currencySymbol = 'GRT'; break; } case 'USDC': { currencySymbol = 'USDC'; break; } case 'ETH': { currencySymbol = 'ETH'; break; } } return currencySymbol; } export function formatAmountWithCurrency(amount: number, currency: Currency, digits = 2): string { return `${currencyCodeToSymbol(currency)} ${formatStringifyAmount(amount, digits)}`; }