Package Exports
- monie-utils
- monie-utils/dist/index.js
- monie-utils/dist/index.mjs
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (monie-utils) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
๐ฐ Monie Utils
A comprehensive TypeScript library for money-related utilities including currency formatting, conversion, validation, and financial calculations.
โจ Features
- ๐ฏ Type-safe - Built with TypeScript for excellent developer experience
- ๐ International - Support for multiple currencies and locales
- ๐ฑ Currency operations - Formatting, conversion, and validation
- ๐งฎ Financial calculations - Interest, loans, investments, and more
- ๐ Business utilities - Payment processing, subscriptions, analytics
- ๐ Lightweight - Tree-shakeable with zero dependencies
- โ Well-tested - Comprehensive test coverage
- ๐ Well-documented - Extensive documentation and examples
๐ Installation
npm install monie-utilsyarn add monie-utilspnpm add monie-utils๐ Quick Start
import {
isValidAmount,
isValidCurrency,
} from 'monie-utils';
// Validate amounts
console.log(isValidAmount(100.50)); // true
console.log(isValidAmount(NaN)); // false
// Validate currencies
console.log(isValidCurrency('USD')); // true
console.log(isValidCurrency('BTC')); // true
console.log(isValidCurrency('INVALID')); // false
๐ API Reference
Currency Formatting
formatCurrency(amount: number, currency: string, options?: FormatCurrencyOptions): FormattedCurrency
Formats a currency amount with locale-specific formatting.
formatCurrency(1234.56, 'USD')
// Returns: { formatted: '$1,234.56', amount: 1234.56, currency: 'USD', locale: 'en-US', isCompact: false }
formatCurrency(1234.56, 'EUR', { locale: 'de-DE', showCode: true })
// Returns: { formatted: '1.234,56 EUR', amount: 1234.56, currency: 'EUR', locale: 'de-DE', isCompact: false }formatMoney(amount: number, currency: string, locale?: string): string
Simple string formatting for currency amounts.
formatMoney(1234.56, 'USD')
// Returns: '$1,234.56'
formatMoney(1234.56, 'EUR', 'de-DE')
// Returns: '1.234,56 โฌ'formatCents(cents: number, currency: string, options?: FormatCurrencyOptions): FormattedCurrency
Formats amounts from smallest currency unit (cents/satoshis).
formatCents(12345, 'USD')
// Returns: { formatted: '$123.45', amount: 123.45, currency: 'USD', locale: 'en-US', isCompact: false }
formatCents(10000000, 'BTC')
// Returns: { formatted: 'โฟ0.10000000', amount: 0.1, currency: 'BTC', locale: 'en-US', isCompact: false }formatCompactCurrency(amount: number, currency: string, options?: FormatCurrencyOptions): FormattedCurrency
Formats large amounts in compact notation (1M, 1B, etc.).
formatCompactCurrency(1500000, 'USD')
// Returns: { formatted: '$1.5M', amount: 1500000, currency: 'USD', locale: 'en-US', isCompact: true }
formatCompactCurrency(2500000000, 'USD')
// Returns: { formatted: '$2.5B', amount: 2500000000, currency: 'USD', locale: 'en-US', isCompact: true }Percentage Formatting
formatPercentage(decimal: number, options?: PercentageOptions): string
Formats decimal values as percentages.
formatPercentage(0.1525)
// Returns: '15.25%'
formatPercentage(0.1525, { precision: 1, locale: 'de-DE' })
// Returns: '15,3 %'Localization
formatCurrencyByLocale(amount: number, currency: string, locale: string): string
Formats currency with specific locale rules.
formatCurrencyByLocale(1234.56, 'USD', 'en-US')
// Returns: '$1,234.56'
formatCurrencyByLocale(1234.56, 'EUR', 'de-DE')
// Returns: '1.234,56 โฌ'getLocaleCurrencyInfo(locale: string): LocaleCurrencyInfo
Gets currency information for a locale.
getLocaleCurrencyInfo('en-US')
// Returns: { currency: 'USD', symbol: '$', name: 'US Dollar' }
getLocaleCurrencyInfo('de-DE')
// Returns: { currency: 'EUR', symbol: 'โฌ', name: 'Euro' }formatWithGrouping(amount: number, locale?: string): string
Adds thousand separators based on locale.
formatWithGrouping(1234567.89)
// Returns: '1,234,567.89'
formatWithGrouping(1234567.89, 'de-DE')
// Returns: '1.234.567,89'formatDecimalPlaces(amount: number, decimalPlaces: number): string
Formats number with specific decimal places.
formatDecimalPlaces(123.456789, 2)
// Returns: '123.46'
formatDecimalPlaces(123.1, 4)
// Returns: '123.1000'Validation and Parsing
isValidAmount(amount: unknown): amount is number
Checks if a value is a valid money amount.
isValidAmount(100.50)
// Returns: true
isValidAmount(NaN)
// Returns: falseisValidCurrency(currencyCode): currencyCode is string
Validates currency codes against ISO 4217 and cryptocurrencies.
isValidCurrency('USD')
// Returns: true
isValidCurrency('BTC')
// Returns: true
isValidCurrency('INVALID')
// Returns: falseisPositiveAmount(amount: number): boolean
Checks if an amount is positive.
isPositiveAmount(100)
// Returns: true
isPositiveAmount(-50)
// Returns: falseisWithinRange(amount: number, min: number, max: number): boolean
Checks if an amount is within a specified range.
isWithinRange(50, 10, 100)
// Returns: true
isWithinRange(150, 10, 100)
// Returns: falseparseAmount(amountString: string): ParsedAmount
Parses string to number amount.
parseAmount('123.45')
// Returns: { amount: 123.45, isValid: true }
parseAmount('invalid')
// Returns: { amount: 0, isValid: false }parseCurrencyString(currencyString: string): ParsedCurrency
Extracts amount and currency from formatted string.
parseCurrencyString('$123.45')
// Returns: { amount: 123.45, currency: 'USD', isValid: true }
parseCurrencyString('โฌ1.234,56')
// Returns: { amount: 1234.56, currency: 'EUR', isValid: true }normalizeAmount(amount: number, decimalPlaces?: number): number
Normalizes amount to standard format.
normalizeAmount(123.456789)
// Returns: 123.46
normalizeAmount(123.456789, 4)
// Returns: 123.4568parseFormattedCurrency(formattedString: string, locale?: string): ParsedCurrency
Parses formatted currency string with locale awareness.
parseFormattedCurrency('$1,234.56', 'en-US')
// Returns: { amount: 1234.56, currency: 'USD', isValid: true }
parseFormattedCurrency('1.234,56 โฌ', 'de-DE')
// Returns: { amount: 1234.56, currency: 'EUR', isValid: true }Currency Conversion
convertCurrency(amount: number, fromCurrency: string, toCurrency: string, rate?: number): ConversionResult
Converts between currencies with exchange rates.
convertCurrency(100, 'USD', 'EUR', 0.85)
// Returns: { amount: 85, fromCurrency: 'USD', toCurrency: 'EUR', rate: 0.85 }
convertCurrency(100, 'USD', 'USD')
// Returns: { amount: 100, fromCurrency: 'USD', toCurrency: 'USD', rate: 1 }convertWithFee(amount: number, rate: number, feePercentage: number): ConversionWithFee
Converts currency with transaction fee.
convertWithFee(100, 0.85, 2.5)
// Returns: { convertedAmount: 85, fee: 2.125, totalCost: 87.125, effectiveRate: 0.8713 }bulkConvert(amounts: number[], fromCurrency: string, toCurrency: string, rate: number): BulkConversionResult
Converts multiple amounts at once.
bulkConvert([100, 200, 300], 'USD', 'EUR', 0.85)
// Returns: { convertedAmounts: [85, 170, 255], totalOriginal: 600, totalConverted: 510, rate: 0.85 }Arithmetic Operations
roundMoney(amount: number, precision?: number): number
Rounds money to specified precision.
roundMoney(123.456)
// Returns: 123.46
roundMoney(123.456, 1)
// Returns: 123.5addMoney(amount1: number, amount2: number, currency?: string): number
Adds two money amounts.
addMoney(100.25, 50.75)
// Returns: 151
addMoney(100.25, 50.75, 'USD')
// Returns: 151subtractMoney(amount1: number, amount2: number, currency?: string): number
Subtracts money amounts.
subtractMoney(100.75, 25.25)
// Returns: 75.5
subtractMoney(100.75, 25.25, 'USD')
// Returns: 75.5multiplyMoney(amount: number, multiplier: number): number
Multiplies money by a number.
multiplyMoney(50.25, 3)
// Returns: 150.75
multiplyMoney(100, 1.5)
// Returns: 150divideMoney(amount: number, divisor: number): number
Divides money by a number.
divideMoney(150, 3)
// Returns: 50
divideMoney(100, 4)
// Returns: 25calculateTip(amount: number, percentage: number): number
Calculates tip amount.
calculateTip(100, 15)
// Returns: 15
calculateTip(85.50, 20)
// Returns: 17.1calculateTax(amount: number, taxRate: number): number
Calculates tax amount.
calculateTax(100, 8.5)
// Returns: 8.5
calculateTax(250, 10)
// Returns: 25calculateDiscount(amount: number, discountRate: number): number
Calculates discount amount.
calculateDiscount(100, 10)
// Returns: 10
calculateDiscount(250, 15)
// Returns: 37.5calculateSimpleInterest(principal: number, rate: number, time: number): number
Calculates simple interest.
calculateSimpleInterest(1000, 5, 2)
// Returns: 100
calculateSimpleInterest(5000, 3.5, 1.5)
// Returns: 262.5calculateCompoundInterest(principal: number, rate: number, time: number, frequency?: number): CompoundInterestResult
Calculates compound interest.
calculateCompoundInterest(1000, 5, 2)
// Returns: { finalAmount: 1102.5, interestEarned: 102.5, effectiveRate: 5.125 }
calculateCompoundInterest(1000, 5, 2, 12)
// Returns: { finalAmount: 1104.89, interestEarned: 104.89, effectiveRate: 5.244 }splitAmount(totalAmount: number, numberOfParts: number): number[]
Splits amount into equal parts.
splitAmount(100, 3)
// Returns: [33.33, 33.33, 33.34]
splitAmount(150, 4)
// Returns: [37.5, 37.5, 37.5, 37.5]distributeProportionally(totalAmount: number, ratios: number[]): number[]
Distributes amount by ratios.
distributeProportionally(100, [1, 2, 3])
// Returns: [16.67, 33.33, 50]
distributeProportionally(500, [40, 30, 30])
// Returns: [200, 150, 150]calculatePercentageOfTotal(amount: number, total: number): number
Calculates percentage share.
calculatePercentageOfTotal(25, 100)
// Returns: 25
calculatePercentageOfTotal(150, 500)
// Returns: 30Loan and Credit Utilities
calculateMonthlyPayment(principal: number, rate: number, termMonths: number): number
Calculates monthly loan payment.
calculateMonthlyPayment(200000, 4.5, 360)
// Returns: 1013.37
calculateMonthlyPayment(50000, 6, 60)
// Returns: 966.64calculateLoanBalance(principal: number, rate: number, termMonths: number, paymentsMade: number): number
Calculates remaining loan balance.
calculateLoanBalance(200000, 4.5, 360, 12)
// Returns: 197834.23
calculateLoanBalance(50000, 6, 60, 24)
// Returns: 28844.35calculateTotalInterest(principal: number, rate: number, termMonths: number): number
Calculates total interest over loan term.
calculateTotalInterest(200000, 4.5, 360)
// Returns: 164813.42
calculateTotalInterest(50000, 6, 60)
// Returns: 7998.12generateAmortizationSchedule(principal: number, rate: number, termMonths: number): AmortizationEntry[]
Generates complete amortization schedule.
generateAmortizationSchedule(100000, 5, 12)
// Returns: [
// { month: 1, payment: 8560.75, principal: 8144.08, interest: 416.67, balance: 91855.92 },
// { month: 2, payment: 8560.75, principal: 8178.02, interest: 382.73, balance: 83677.90 },
// ...
// ]calculateCreditUtilization(usedCredit: number, totalCredit: number): number
Calculates credit utilization ratio.
calculateCreditUtilization(2500, 10000)
// Returns: 25
calculateCreditUtilization(1200, 5000)
// Returns: 24calculateMinimumPayment(balance: number, rate: number, minimumRate: number): number
Calculates minimum credit payment.
calculateMinimumPayment(5000, 18, 2)
// Returns: 100
calculateMinimumPayment(2500, 24, 3)
// Returns: 75calculatePayoffTime(balance: number, payment: number, rate: number): PayoffResult
Calculates time to pay off debt.
calculatePayoffTime(5000, 200, 18)
// Returns: { months: 30, totalInterest: 983.45, totalPaid: 5983.45 }
calculatePayoffTime(10000, 300, 24)
// Returns: { months: 43, totalInterest: 2804.32, totalPaid: 12804.32 }Investment and Returns
calculateROI(initialInvestment: number, finalValue: number): number
Calculates return on investment.
calculateROI(10000, 12000)
// Returns: 20
calculateROI(5000, 4500)
// Returns: -10calculateAnnualizedReturn(initialValue: number, finalValue: number, years: number): number
Calculates annualized return.
calculateAnnualizedReturn(10000, 15000, 3)
// Returns: 14.47
calculateAnnualizedReturn(5000, 7500, 2)
// Returns: 22.47calculateDividendYield(dividendPerShare: number, pricePerShare: number): number
Calculates dividend yield.
calculateDividendYield(2.50, 50)
// Returns: 5
calculateDividendYield(1.25, 75)
// Returns: 1.67calculateFutureValue(presentValue: number, rate: number, periods: number): number
Calculates future value.
calculateFutureValue(10000, 7, 10)
// Returns: 19671.51
calculateFutureValue(5000, 5, 20)
// Returns: 13266.49Subscription and Recurring Payments
calculateSubscriptionValue(monthlyAmount: number, months: number): number
Calculates total subscription cost.
calculateSubscriptionValue(29.99, 12)
// Returns: 359.88
calculateSubscriptionValue(99, 6)
// Returns: 594compareSubscriptionPlans(plans: SubscriptionPlan[]): PlanComparison[]
Compares subscription plans.
compareSubscriptionPlans([
{ name: 'Basic', monthlyPrice: 10, features: [] },
{ name: 'Pro', monthlyPrice: 25, features: [] }
])
// Returns: [
// { plan: 'Basic', monthlyPrice: 10, annualPrice: 120, savings: 0 },
// { plan: 'Pro', monthlyPrice: 25, annualPrice: 300, savings: 0 }
// ]calculateProrationAmount(amount: number, daysUsed: number, totalDays: number): number
Calculates prorated amount.
calculateProrationAmount(100, 15, 30)
// Returns: 50
calculateProrationAmount(299, 10, 31)
// Returns: 96.45calculateUpgradeCredit(oldPlan: SubscriptionPlan, newPlan: SubscriptionPlan, daysRemaining: number): UpgradeCredit
Calculates upgrade credit.
calculateUpgradeCredit(
{ name: 'Basic', monthlyPrice: 10 },
{ name: 'Pro', monthlyPrice: 25 },
15
)
// Returns: { credit: 5, additionalCost: 12.5, totalCost: 7.5 }calculateAnnualEquivalent(amount: number, frequency: 'monthly' | 'weekly' | 'quarterly'): number
Converts to annual amount.
calculateAnnualEquivalent(100, 'monthly')
// Returns: 1200
calculateAnnualEquivalent(25, 'weekly')
// Returns: 1300calculateNextPaymentDate(startDate: Date, frequency: 'monthly' | 'weekly' | 'quarterly'): Date
Calculates next payment date.
calculateNextPaymentDate(new Date('2024-01-15'), 'monthly')
// Returns: Date object for 2024-02-15
calculateNextPaymentDate(new Date('2024-01-15'), 'weekly')
// Returns: Date object for 2024-01-22calculateTotalRecurringCost(amount: number, frequency: 'monthly' | 'weekly' | 'quarterly', duration: number): number
Calculates total recurring cost.
calculateTotalRecurringCost(50, 'monthly', 12)
// Returns: 600
calculateTotalRecurringCost(25, 'weekly', 52)
// Returns: 1300Utility Functions
roundToNearestCent(amount: number): number
Rounds to nearest cent.
roundToNearestCent(123.456)
// Returns: 123.46
roundToNearestCent(99.994)
// Returns: 99.99roundToBankersRounding(amount: number, decimalPlaces?: number): number
Applies banker's rounding (round half to even).
roundToBankersRounding(2.125, 2)
// Returns: 2.12
roundToBankersRounding(2.135, 2)
// Returns: 2.14truncateToDecimalPlaces(amount: number, places: number): number
Truncates without rounding.
truncateToDecimalPlaces(123.789, 2)
// Returns: 123.78
truncateToDecimalPlaces(99.999, 1)
// Returns: 99.9ceilToNearestCent(amount: number): number
Ceils to nearest cent.
ceilToNearestCent(123.451)
// Returns: 123.46
ceilToNearestCent(99.001)
// Returns: 99.01formatThousands(number: number, options?: ThousandsOptions): string
Adds thousand separators.
formatThousands(1234567.89)
// Returns: '1,234,567.89'
formatThousands(1234567.89, { thousandsSeparator: '.', decimalSeparator: ',' })
// Returns: '1.234.567,89'formatToHundreds(amount: number, options?: ThousandsOptions): string
Formats cents to dollars with separators.
formatToHundreds(123456)
// Returns: '1,234.56'
formatToHundreds(987654, { thousandsSeparator: ' ', decimalSeparator: ',' })
// Returns: '9 876,54'removeFormattingFromNumber(formattedString: string): string
Removes formatting characters.
removeFormattingFromNumber('$1,234.56')
// Returns: '1234.56'
removeFormattingFromNumber('โฌ 1.234,56')
// Returns: '1234.56'convertToWords(amount: number, options?: { currency?: string }): NumberToWordsResult
Converts number to words.
convertToWords(123.45)
// Returns: { words: 'one hundred twenty-three and forty-five cents' }
convertToWords(1500, { currency: 'USD' })
// Returns: { words: 'one thousand five hundred dollars', currency: 'USD' }formatAccountNumber(accountNumber: string, options?: AccountNumberOptions): FormattedAccountResult
Formats account numbers with masking.
formatAccountNumber('1234567890')
// Returns: { formatted: '******7890', masked: true, groupSize: 4 }
formatAccountNumber('1234567890', { maskCharacter: 'X', showLast: 6 })
// Returns: { formatted: 'XXXX567890', masked: true, groupSize: 4 }๐งช Development
Prerequisites
- Node.js 18+
- npm, yarn, or pnpm
Setup
# Clone the repository
git clone https://github.com/spiderocious/monie-utils.git
cd monie-utils
# Install dependencies
npm install
# Run tests
npm test
# Run tests in watch mode
npm run test:watch
# Build the library
npm run build
# Lint and format
npm run lint
npm run formatScripts
npm run dev- Start development server with Vitenpm run build- Build the library with tsupnpm test- Run tests with Jestnpm run test:watch- Run tests in watch modenpm run test:coverage- Run tests with coverage reportnpm run lint- Lint code with ESLintnpm run lint:fix- Fix linting issuesnpm run format- Format code with Prettiernpm run type-check- Run TypeScript type checking
๐ Acknowledgments
- Inspired by financial libraries from Stripe, PayStack, Monnify, and other payment processors
- Built with modern TypeScript and development tools
- Thanks to all contributors and the open-source community
Made with โค๏ธ by Oluwaferanmi (https://github.com/spiderocious)