g1t/apps/sudo/app/lib/money.ts
Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.
| Billing accounts, terms and enterprises; g1t is no longer free | 1 | /** Money is held in micros: millionths of a dollar. */ |
| 2 | export const MICROS_PER_DOLLAR = 1_000_000; | |
| 3 | ||
| 4 | const WHOLE = new Intl.NumberFormat("en-US", { style: "currency", currency: "USD", minimumFractionDigits: 2, maximumFractionDigits: 2 }); | |
| 5 | const SMALL = new Intl.NumberFormat("en-US", { style: "currency", currency: "USD", minimumFractionDigits: 2, maximumFractionDigits: 4 }); | |
| 6 | ||
| 7 | /** | |
| 8 | * Dollars, to the cent; amounts under a dollar keep up to four places, so | |
| 9 | * a run that cost a fraction of a cent does not read as nothing. | |
| 10 | */ | |
| 11 | export function usd(micros: number | null | undefined, { signed = false }: { signed?: boolean } = {}): string { | |
| 12 | if (micros == null) return "—"; | |
| 13 | const dollars = micros / MICROS_PER_DOLLAR; | |
| 14 | const text = (Math.abs(dollars) < 1 ? SMALL : WHOLE).format(Math.abs(dollars)); | |
| 15 | if (dollars < 0) return `−${text}`; | |
| 16 | return signed && dollars > 0 ? `+${text}` : text; | |
| 17 | } | |
| 18 | ||
| 19 | /** | |
| 20 | * Micros from a dollar amount as typed: `25`, `25.5`, `$1,250.00`. Null | |
| 21 | * unless it is a non-negative amount to the cent, under ten million. | |
| 22 | */ | |
| 23 | export function parseDollars(input: string): number | null { | |
| 24 | const text = input.trim().replace(/^\$/, "").replace(/,/g, ""); | |
| 25 | const match = /^(\d{1,7})(?:\.(\d{1,2}))?$/.exec(text); | |
| 26 | if (!match) return null; | |
| 27 | const cents = Number((match[2] ?? "").padEnd(2, "0")); | |
| 28 | return Number(match[1]) * MICROS_PER_DOLLAR + cents * 10_000; | |
| 29 | } | |
| 30 | ||
| 31 | /** A micros amount as dollars for a form field: `1250.5` → `"1250.50"`. */ | |
| 32 | export function dollarsField(micros: number | null | undefined): string { | |
| 33 | return micros == null ? "" : (micros / MICROS_PER_DOLLAR).toFixed(2); | |
| 34 | } |