import { Validator } from "../Validator" import { Utils } from "../../../Utils" export default class CurrencyValidator extends Validator { private readonly segmenter: Intl.Segmenter private readonly symbolToCurrencyMapping: Map private readonly supportedCurrencies: Set constructor() { super("currency", "Validates monetary amounts") if (Intl.Segmenter === undefined || Utils.runningFromConsole) { // Librewolf doesn't support this return } let locale = "en-US" if (!Utils.runningFromConsole) { locale ??= navigator.language } this.segmenter = new Intl.Segmenter(locale, { granularity: "word", }) const mapping: Map = new Map() const supportedCurrencies: Set = new Set(Intl.supportedValuesOf("currency")) this.supportedCurrencies = supportedCurrencies for (const currency of supportedCurrencies) { const symbol = (0) .toLocaleString(locale, { style: "currency", currency: currency, minimumFractionDigits: 0, maximumFractionDigits: 0, }) .replace(/\d/g, "") .trim() mapping.set(symbol.toLowerCase(), currency) } this.symbolToCurrencyMapping = mapping } reformat(s: string): string { if (!this.segmenter) { return s } const parts = Array.from(this.segmenter.segment(s)) .map((i) => i.segment) .filter((part) => part.trim().length > 0) if (parts.length !== 2) { return s } const mapping = this.symbolToCurrencyMapping let currency: string = undefined let amount = undefined for (const part of parts) { const lc = part.toLowerCase() if (this.supportedCurrencies.has(part.toUpperCase())) { currency = part.toUpperCase() continue } if (mapping.has(lc)) { currency = mapping.get(lc) continue } amount = part } if (amount === undefined || currency === undefined) { return s } return amount + " " + currency } }