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
158 lines (157 loc) • 4.79 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.isValidNumber = isValidNumber;
exports.splitNumber = splitNumber;
exports.roundDecimal = roundDecimal;
exports.validateDecimal = validateDecimal;
exports.normalizeDecimal = normalizeDecimal;
exports.validateCustomMappings = validateCustomMappings;
exports.getScaleValue = getScaleValue;
const scaleMappings_1 = require("../mappings/scaleMappings");
/**
* Checks if a value is a valid non-negative number, string, or bigint.
* Handles decimals, special cases, and size validation.
*/
function isValidNumber(num) {
try {
if (typeof num === 'bigint')
return num >= 0n;
if (typeof num === 'number') {
return !isNaN(num) && isFinite(num) && num >= 0;
}
const str = num.toString().trim();
if (!str)
return false;
// Special cases
if (str === 'NaN' || str === 'Infinity' || str === '-Infinity')
return false;
// Handle decimal numbers
const [intPart, decPart] = str.split('.');
if (!intPart || intPart.startsWith('-') || !/^\d+$/.test(intPart))
return false;
if (decPart !== undefined && !/^\d+$/.test(decPart))
return false;
// Validate the size
try {
BigInt(intPart);
return true;
}
catch {
return false;
}
}
catch {
return false;
}
}
/**
* Splits a number into integer and decimal parts with proper rounding.
* Handles decimals by rounding to 2 places and managing overflow.
*/
function splitNumber(num) {
if (typeof num === 'bigint')
return { integer: num };
const str = num.toString();
const [intPart, decPart] = str.split('.');
const integer = BigInt(intPart);
// If no decimal part, return only integer
if (!decPart)
return { integer };
// Pad to 3 decimal places, then take first 3 digits for precision
const decimalStr = decPart.padEnd(3, '0').slice(0, 3);
const decimalNum = Number(`0.${decimalStr}`);
// Round to 2 decimal places
const rounded = Math.round(decimalNum * 100);
// Handle edge case: if rounding up to 100, increment the integer
if (rounded === 100) {
return { integer: integer + 1n };
}
return {
integer,
decimal: rounded.toString().padStart(2, '0')
};
}
/**
* Rounds a decimal string to 2 places.
*/
function roundDecimal(decimal) {
const num = parseFloat(`0.${decimal}`);
const rounded = Math.round(num * 100);
return rounded.toString().padStart(2, '0');
}
/**
* Validates that a decimal string is within expected range.
*/
function validateDecimal(decimal) {
if (!decimal)
return true;
const num = parseInt(decimal);
return !isNaN(num) && num >= 0 && num <= 99 && /^\d{1,2}$/.test(decimal);
}
/**
* Normalizes decimal by removing zero decimals and padding.
*/
function normalizeDecimal(decimal) {
if (!decimal)
return undefined;
const num = parseInt(decimal);
if (num === 0)
return undefined;
return num.toString().padStart(2, '0');
}
/**
* Validates language mapping structure.
*/
function isValidLanguageMapping(mapping) {
if (!mapping || typeof mapping !== 'object')
return false;
return ('en' in mapping &&
'ne' in mapping &&
typeof mapping.en === 'string' &&
typeof mapping.ne === 'string');
}
/**
* Validates custom units configuration.
*/
function isValidCustomUnits(units) {
if (!units || typeof units !== 'object')
return false;
return Object.entries(units).every(([key, value]) => {
const num = Number(key);
return !isNaN(num) && num >= 0 && num <= 99 && isValidLanguageMapping(value);
});
}
/**
* Validates custom scales configuration.
*/
function isValidCustomScales(scales) {
if (!scales || typeof scales !== 'object')
return false;
const validScales = Object.values(scaleMappings_1.SCALE_VALUES).map(Number);
return Object.entries(scales).every(([key, value]) => {
const num = Number(key);
return validScales.includes(num) && isValidLanguageMapping(value);
});
}
/**
* Validates the entire custom mappings configuration.
*/
function validateCustomMappings(config) {
try {
if (config.units && !isValidCustomUnits(config.units))
return false;
if (config.scales && !isValidCustomScales(config.scales))
return false;
return true;
}
catch {
return false;
}
}
/**
* Converts a scale to its BigInt value.
*/
function getScaleValue(scale) {
const num = typeof scale === 'string' ? parseInt(scale) : scale;
return BigInt(num);
}