UNPKG

shelving

Version:

Toolkit for using data in JavaScript.

47 lines (46 loc) 1.92 kB
import { RequiredError } from "../error/RequiredError.js"; /** Array of all supported currency codes in this runtime. */ export const CURRENCY_CODES = Intl.supportedValuesOf("currency"); /** * Require that a value is a valid ISO 4217 currency code, and return it as a `Currency` type. */ export function getCurrencyCode(value) { const currency = value.toUpperCase().trim(); return CURRENCY_CODES.includes(currency) ? currency : undefined; } /** * Require that a value is a valid ISO 4217 currency code, and return it as a `Currency` type. */ export function requireCurrencyCode(value, caller = requireCurrencyCode) { const currency = getCurrencyCode(value); if (!currency) throw new RequiredError("Unknown currency code", { received: value, caller }); return currency; } function _formatter(currency, caller) { return new Intl.NumberFormat(undefined, { style: "currency", currency: requireCurrencyCode(currency, caller), currencyDisplay: "narrowSymbol", }); } const _isCurrencyNumberPart = ({ type }) => type === "currency"; /** * Get the display symbol used for a currency. * * @throws {RequiredError} If the currency code is malformed or unsupported. * * @example getCurrencySymbol("GBP"); // "£" */ export function getCurrencySymbol(currency, caller = getCurrencySymbol) { return _formatter(currency, caller).formatToParts(0).find(_isCurrencyNumberPart)?.value; } /** * Get the "step" value for a currency, i.e. the smallest fractional unit that is used for that currency. * - E.g. `0.01` for USD, `0.001` for some cryptocurrencies, and `1` for JPY. * @throws {RequiredError} If the currency code is malformed or unsupported. */ export function getCurrencyStep(currency, caller = getCurrencyStep) { const { minimumFractionDigits = 0 } = _formatter(currency, caller).resolvedOptions(); return 1 / 10 ** minimumFractionDigits; }