shelving
Version:
Toolkit for using data in JavaScript.
45 lines (44 loc) • 2.12 kB
JavaScript
import { getCurrencyStep, getCurrencySymbol, requireCurrencyCode } from "../util/currency.js";
import { formatCurrency } from "../util/format.js";
import { NULLABLE } from "./NullableSchema.js";
import { NumberSchema } from "./NumberSchema.js";
/**
* Schema representing a numeric amount in a specific currency.
*
* - The validation step is inferred from the currency's minor units.
* - The default formatter renders amounts using shelving's currency helpers.
*
* @example
* const PRICE = new CurrencyAmountSchema({ currency: "GBP", min: 0 });
* PRICE.validate("12.345"); // 12.35
* PRICE.format(12.3); // "£12.30"
*/
export class CurrencyAmountSchema extends NumberSchema {
currency;
symbol;
constructor({ currency, one = "amount", title = "Amount", symbol, step, ...options }) {
const validCurrency = requireCurrencyCode(currency, CurrencyAmountSchema);
super({
one,
title,
step: step ?? getCurrencyStep(validCurrency, CurrencyAmountSchema),
...options,
});
this.currency = validCurrency;
this.symbol = symbol ?? getCurrencySymbol(validCurrency, CurrencyAmountSchema);
}
format(value) {
const options = this.step >= 1 ? { maximumFractionDigits: 0 } : {}; // Skip showing decimal places if step is 1 or more.
return formatCurrency(value, this.currency, options, this.format);
}
}
/** Valid non-negative monetary amount in the a currency. */
export const CURRENCY_AMOUNT = (currency) => new CurrencyAmountSchema({ currency });
export const USD_AMOUNT = new CurrencyAmountSchema({ currency: "USD" });
export const GBP_AMOUNT = new CurrencyAmountSchema({ currency: "GBP" });
export const EUR_AMOUNT = new CurrencyAmountSchema({ currency: "EUR" });
/** Valid optional monetary amount in the default currency, or `null`. */
export const NULLABLE_CURRENCY_AMOUNT = (currency) => NULLABLE(CURRENCY_AMOUNT(currency));
export const NULLABLE_USD_AMOUNT = NULLABLE(USD_AMOUNT);
export const NULLABLE_GBP_AMOUNT = NULLABLE(GBP_AMOUNT);
export const NULLABLE_EUR_AMOUNT = NULLABLE(EUR_AMOUNT);