first commit
This commit is contained in:
120
docs/money/finance/money/README.md
Normal file
120
docs/money/finance/money/README.md
Normal file
@@ -0,0 +1,120 @@
|
||||
# @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.
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
## Documentation tree
|
||||
|
||||
- [allocator](./src/allocator/allocator.md) — The allocator module solves two related problems: splitting a `Money` amount across N recipients (or N weights or N per…
|
||||
- [allocator](./src/allocator/allocator.md) — The allocator module solves two related problems: splitting a `Money` amount across N recipients (or N weights or N per…
|
||||
- [currencies](./src/currencies/currencies.md) — This module owns the currency-metadata registry that every other part of `@suaveplan/money` consults to compute minor-u…
|
||||
- [currencies](./src/currencies/currencies.md) — This module owns the currency-metadata registry that every other part of `@suaveplan/money` consults to compute minor-u…
|
||||
- [error-codes](./src/error-codes/error-codes.md) — `@suaveplan/money` raises only typed errors. This module owns the stable `MONEY_CODES` registry (built with `defineCode…
|
||||
- [error-codes](./src/error-codes/error-codes.md) — `@suaveplan/money` raises only typed errors. This module owns the stable `MONEY_CODES` registry (built with `defineCode…
|
||||
- [formatter](./src/formatter/formatter.md) — The formatter renders `MoneyLike` values to human-readable strings using `Intl.NumberFormat(locale)`-derived separators…
|
||||
- [formatter](./src/formatter/formatter.md) — The formatter renders `MoneyLike` values to human-readable strings using `Intl.NumberFormat(locale)`-derived separators…
|
||||
- [money](./src/money/money.md) — `Money` is the cornerstone of the package: an immutable value object that stores monetary amounts as `bigint` minor uni…
|
||||
- [money](./src/money/money.md) — `Money` is the cornerstone of the package: an immutable value object that stores monetary amounts as `bigint` minor uni…
|
||||
- [types](./src/types/common.md) — `@suaveplan/money` exposes a small, stable set of types that downstream packages (`@suaveplan/currency`, `@suaveplan/pa…
|
||||
- [common](./src/types/common.md) — `@suaveplan/money` exposes a small, stable set of types that downstream packages (`@suaveplan/currency`, `@suaveplan/pa…
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
bun add @suaveplan/money
|
||||
```
|
||||
|
||||
## Quick start
|
||||
|
||||
```ts
|
||||
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 `Money` class** 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)`
|
||||
with `virtual` / `issuerId` flags for game-currency use cases.
|
||||
- **Locale-aware formatting** through `Intl.NumberFormat`-derived separators;
|
||||
`decimalSeparator` / `thousandsSeparator` overrides 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()`
|
||||
(`bigint` encoded as decimal string).
|
||||
- **Typed `MoneyError` hierarchy** extending `SuaveplanError<MoneyErrorCode>`
|
||||
with stable `MONEY.*` code registry and `currency` / `otherCurrency`
|
||||
discriminants.
|
||||
- **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`](./src/money/money.md) — `Money` class + `applyRounding`
|
||||
- [`currencies/currencies.md`](./src/currencies/currencies.md) — built-in
|
||||
registry, lookup, custom / virtual currency registration
|
||||
- [`formatter/formatter.md`](./src/formatter/formatter.md) — `formatMoney` +
|
||||
`formatMoneyCompact`
|
||||
- [`allocator/allocator.md`](./src/allocator/allocator.md) — allocators +
|
||||
aggregators (`sumMoney`, `minMoney`, `maxMoney`)
|
||||
- [`error-codes/error-codes.md`](./src/error-codes/error-codes.md) —
|
||||
`MONEY_CODES` registry + `MoneyError` class
|
||||
- [`types/common.md`](./src/types/common.md) — public type contracts
|
||||
|
||||
## Subpath exports
|
||||
|
||||
```ts
|
||||
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`.
|
||||
|
||||
```ts
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user