shelving
Version:
Toolkit for using data in JavaScript.
47 lines (46 loc) • 1.92 kB
JavaScript
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;
}