Relocate the ~6k-file docs tree from the repo root into plugins/document-navigator/docs/ so the plugin is self-contained and portable. docs/superpowers/ (specs and plans) stays at the repo root. Moved via cp+rm rather than git mv because directory rename() fails with EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the identical-content files at commit time. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
6.5 KiB
6.5 KiB
@suaveplan/money - Universal precise currency/money arithmetic using integer minor-unit (bigint) representation: immutable Money class with full arithmetic + comparison + conversion surface, locale-aware Intl-backed formatting (formatMoney, formatMoneyCompact), fair allocators preserving the input total (allocateEvenly, allocateByRatios, allocateByPercentages), aggregators (sumMoney, minMoney, maxMoney), 30 ISO 4217 fiat + 5 cryptocurrency built-ins, custom and virtual currency registration, lossless JSON round-trip, typed MoneyError hierarchy with stable MONEY.* code registry.
Universal precise currency and money arithmetic using integer minor-unit
representation. All operations use bigint so consumers never hit
floating-point rounding drift; cross-currency mistakes raise typed errors;
allocations preserve the input total to the minor unit.
Documentation tree
- allocator — The allocator module solves two related problems: splitting a
Moneyamount across N recipients (or N weights or N per…- allocator — The allocator module solves two related problems: splitting a
Moneyamount across N recipients (or N weights or N per…
- allocator — The allocator module solves two related problems: splitting a
- currencies — This module owns the currency-metadata registry that every other part of
@suaveplan/moneyconsults to compute minor-u…- currencies — This module owns the currency-metadata registry that every other part of
@suaveplan/moneyconsults to compute minor-u…
- currencies — This module owns the currency-metadata registry that every other part of
- error-codes —
@suaveplan/moneyraises only typed errors. This module owns the stableMONEY_CODESregistry (built with `defineCode…- error-codes —
@suaveplan/moneyraises only typed errors. This module owns the stableMONEY_CODESregistry (built with `defineCode…
- error-codes —
- formatter — The formatter renders
MoneyLikevalues to human-readable strings usingIntl.NumberFormat(locale)-derived separators…- formatter — The formatter renders
MoneyLikevalues to human-readable strings usingIntl.NumberFormat(locale)-derived separators…
- formatter — The formatter renders
- money —
Moneyis the cornerstone of the package: an immutable value object that stores monetary amounts asbigintminor uni…- money —
Moneyis the cornerstone of the package: an immutable value object that stores monetary amounts asbigintminor uni…
- money —
- types —
@suaveplan/moneyexposes a small, stable set of types that downstream packages (@suaveplan/currency, `@suaveplan/pa…- common —
@suaveplan/moneyexposes a small, stable set of types that downstream packages (@suaveplan/currency, `@suaveplan/pa…
- common —
Install
bun add @suaveplan/money
Quick start
import { Money, formatMoney, allocateEvenly } from "@suaveplan/money";
const price = Money.fromMajor(29.99, "USD");
const tax = price.multiply(0.08);
const total = price.add(tax);
console.log(formatMoney(total)); // "$32.39"
console.log(total.toDecimalString()); // "32.39"
// Split a $32.39 bill among 3 — no penny lost
const { shares } = allocateEvenly(total, 3);
console.log(shares.map((s) => formatMoney(s))); // ["$10.80", "$10.80", "$10.79"]
Features
- Immutable
Moneyclass with full arithmetic (add,subtract,multiply,divide,abs,negate), comparison (compareTo,equals,greaterThan, ...), and conversion (toMajor,toDecimalString,toJSON,toString). - 30 ISO 4217 fiat currencies (USD, EUR, GBP, JPY, ...) plus 5 cryptocurrencies (BTC, ETH, SOL, USDT, USDC) with accurate exponents.
- Custom and virtual currency registration via
registerCurrency(info)withvirtual/issuerIdflags for game-currency use cases. - Locale-aware formatting through
Intl.NumberFormat-derived separators;decimalSeparator/thousandsSeparatoroverrides for locked output. - Compact notation (
formatMoneyCompact) with K / M / B suffixes. - Fair allocators (
allocateEvenly,allocateByRatios,allocateByPercentages) that always preserve the input total. - Aggregators (
sumMoney,minMoney,maxMoney) with typed empty-input and cross-currency guards. - Lossless JSON round-trip via
Money.toJSON()/Money.fromJSON()(bigintencoded as decimal string). - Typed
MoneyErrorhierarchy extendingSuaveplanError<MoneyErrorCode>with stableMONEY.*code registry andcurrency/otherCurrencydiscriminants. - Subpath exports for every public module so consumers can tree-shake.
- Universal — no
node:*,bun:*, DOM, or fs imports; runs unchanged on Node ≥ 18, Bun, browsers, and Web Workers.
Modules
money/money.md—Moneyclass +applyRoundingcurrencies/currencies.md— built-in registry, lookup, custom / virtual currency registrationformatter/formatter.md—formatMoney+formatMoneyCompactallocator/allocator.md— allocators + aggregators (sumMoney,minMoney,maxMoney)error-codes/error-codes.md—MONEY_CODESregistry +MoneyErrorclasstypes/common.md— public type contracts
Subpath exports
import { Money } from "@suaveplan/money/money/money";
import { formatMoney } from "@suaveplan/money/formatter/formatter";
import { allocateEvenly } from "@suaveplan/money/allocator/allocator";
import { registerCurrency } from "@suaveplan/money/currencies/currencies";
import { MoneyError } from "@suaveplan/money/error-codes/error-codes";
import type { MoneyLike } from "@suaveplan/money/types/common";
Error handling
Every failure path raises a typed MoneyError carrying a stable
MONEY.* code. Six codes are declared: CURRENCY_MISMATCH,
UNKNOWN_CURRENCY, DIVISION_BY_ZERO, INVALID_ALLOCATION, EMPTY_INPUT,
PARSE_ERROR.
import { Money, MoneyError, MONEY_CODES } from "@suaveplan/money";
try {
Money.fromMinor(100n, "USD").add(Money.fromMinor(50n, "EUR"));
} catch (err) {
if (err instanceof MoneyError && err.code === MONEY_CODES.CURRENCY_MISMATCH) {
console.error(`mismatch: ${err.currency} vs ${err.otherCurrency}`);
}
}
License
MIT — © Suaveplan Team