UNPKG

digit-to-words-nepali

Version:

A comprehensive TypeScript library for converting numbers to words in English and Nepali languages. Supports numbers up to 10^39 (Adanta Singhar), currency formatting, decimal handling with individual digit pronunciation, and BigInt. Zero dependencies, fu

161 lines (160 loc) 6.43 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.digitToEnglishWords = exports.EnglishConverter = void 0; const baseConverter_1 = require("./baseConverter"); const validationUtils_1 = require("../utils/validationUtils"); const scaleMappings_1 = require("../mappings/scaleMappings"); const numberMappings_1 = require("../mappings/numberMappings"); const cacheUtils_1 = require("../utils/cacheUtils"); const converterFactory_1 = require("../utils/converterFactory"); /** * EnglishConverter * Converts numbers to English words with support for currency, decimals, and custom mappings. * Optimized for readability, maintainability, and performance. */ class EnglishConverter extends baseConverter_1.BaseConverter { constructor() { super(); this.wordCache = (0, numberMappings_1.createNumberWordMap)(); this.scales = scaleMappings_1.englishScaleMappings; } /** * Convert decimal digits individually to English words. * @param decimal - The decimal string (e.g., "33") * @param config - Conversion configuration * @returns Array of individual digit words */ convertDecimalDigitsIndividually(decimal, config) { const digits = decimal.split(''); const words = []; for (const digit of digits) { const digitNum = parseInt(digit); words.push(this.getWordMapping(digitNum, 'en')); } return words; } /** * Convert a number to English words. * @param num - The number to convert * @param config - Conversion configuration (all fields required) */ convert(num, config) { this.setCustomMappings(config); // Validate input if (!(0, validationUtils_1.isValidNumber)(num)) { throw new Error('Input must contain only valid digits'); } // Use cache if no custom mappings const hasCustomMappings = Object.keys(config.units).length > 0 || Object.keys(config.scales).length > 0; if (!hasCustomMappings) { const cacheKey = { value: num.toString(), lang: config.lang, isCurrency: config.isCurrency, includeDecimal: config.includeDecimal, individualDecimalDigits: config.individualDecimalDigits, currency: config.currency, decimalSuffix: config.decimalSuffix, currencyDecimalSuffix: config.currencyDecimalSuffix }; const cachedResult = cacheUtils_1.conversionCache.get(cacheKey); if (cachedResult) return cachedResult; } // Split number into integer and decimal parts const { integer, decimal } = (0, validationUtils_1.splitNumber)(num); const words = []; // Integer part conversion if (integer === 0n) { words.push(this.getWordMapping(0, 'en')); } else { this.processLargeNumber(integer, words, config); } // Decimal part conversion if (config.includeDecimal && decimal) { words.push(config.isCurrency ? config.currencyDecimalSuffix : config.decimalSuffix); const decimalNum = parseInt(decimal); if (decimalNum === 0) { words.push(this.getWordMapping(0, 'en')); } else { // Use individual digits for non-currency or when explicitly configured if (config.individualDecimalDigits) { const individualDigits = this.convertDecimalDigitsIndividually(decimal, config); words.push(...individualDigits); } else { words.push(this.getWordMapping(decimalNum, 'en')); } } } // Add currency prefix if needed if (config.isCurrency) { words.unshift(config.currency); } const result = { words, meta: { originalNumber: num.toString(), language: 'en', isCurrency: config.isCurrency } }; // Store in cache if no custom mappings if (!hasCustomMappings) { const cacheKey = { value: num.toString(), lang: config.lang, isCurrency: config.isCurrency, includeDecimal: config.includeDecimal, individualDecimalDigits: config.individualDecimalDigits, currency: config.currency, decimalSuffix: config.decimalSuffix, currencyDecimalSuffix: config.currencyDecimalSuffix }; cacheUtils_1.conversionCache.set(cacheKey, result); } return result; } processNumber(num, words, config) { for (const scale of this.scales) { if (num >= scale.value) { const quotient = num / scale.value; num = num % scale.value; if (quotient > 0n) { this.processNumber(quotient, words, config); words.push(this.getScaleName(scale.value, 'en')); } } } if (num > 0n && num <= 99n) { words.push(this.getWordMapping(Number(num), 'en')); } } } exports.EnglishConverter = EnglishConverter; const digitToEnglishWords = (num, config = {}) => { // Use the singleton pattern via factory const converter = converterFactory_1.ConverterFactory.getInstance('EnglishConverter', () => new EnglishConverter()); // Default English language settings const defaultConfig = { lang: 'en', isCurrency: false, includeDecimal: true, individualDecimalDigits: true, // Default to individual digits currency: 'Dollars', decimalSuffix: 'point', currencyDecimalSuffix: 'cents', units: {}, scales: {}, ...config }; // Override individualDecimalDigits based on currency setting if not explicitly set if (config.individualDecimalDigits === undefined) { defaultConfig.individualDecimalDigits = !defaultConfig.isCurrency; } const result = converter.convert(num, defaultConfig); return result.words.filter((word) => word !== '').join(' ').trim(); }; exports.digitToEnglishWords = digitToEnglishWords;