/** * money-value.ts, the codec for config keys that hold an amount of money. * * ── What a money setting is now ─────────────────────────────────────────── * * An amount setting holds the number the owner would say out loud. They write * `100` and the file reads `100`. They write `19.99` and the file reads `19.99`. * There is no second representation to keep straight, no suffix on the key * telling them which one they are in, and nothing here rewrites what they * typed into a "canonical" form, a whole number stays whole, and a decimal * keeps exactly the decimal they entered. * * These keys used to be named for, and stored in, the currency's smallest * division, so `100` in the file meant one dollar and buying something for a * hundred dollars meant typing `10000`. Every entry point was one absent zero * away from a hundredfold error in a spending limit, in the direction that * spends more. The name is gone, the smallest-division storage is gone, and the * migration in ./migrations.ts carries existing values across. * * ── What this module is responsible for ─────────────────────────────────── * * Reading what a person typed and either producing the number they meant or * refusing with an example. It is deliberately currency-NEUTRAL: it knows * nothing about dollars, does not consult `payments.currency`, and never names * a unit in an error. Whatever `payments.currency` is set to, an amount is an * amount of it. * * Exact arithmetic on these amounts is the payments layer's job (it multiplies * up to whole units of the currency's smallest division and does integer math * from there). That is an implementation detail of the arithmetic and never * reaches a message, a key name, or a settings screen. */ /** * The largest amount any of these settings accepts. * * A ceiling on the ceiling: it is what stops a slipped keystroke turning a * budget into a number that could buy a car, while sitting far above any * amount a real limit would name. */ export declare const MAX_MONEY_AMOUNT = 1000000; /** The hint the config schema attaches to every amount setting. */ export declare const MONEY_VALIDATION_HINT = "a plain number like 100 or 19.99, no greater than 1000000"; export type MoneyParseResult = { readonly ok: true; readonly value: number; } | { readonly ok: false; readonly reason: string; }; /** True when `value` is a number an amount setting may hold. */ export declare function isValidMoneyAmount(value: unknown): value is number; /** * Read an amount as a person may have written it. * * Accepts a number (`100`, `19.99`) or the text of one, with a leading currency * symbol and thousands grouping tolerated and removed (`$100`, `1,250.50`). * Refuses anything else, text that is not a number, more decimal places than * an amount can carry, a negative, or a figure past {@link MAX_MONEY_AMOUNT}, * and the refusal names an example rather than a units rule. * * The returned number is the one that was typed. Nothing is rounded, padded, or * re-formatted on the way through. */ export declare function parseMoneyAmount(raw: unknown): MoneyParseResult; /** * Coerce a value on its way into an amount setting, or throw the refusal text. * * Used by the config set path so `$100`, `100` and `19.99` all reach the same * stored number, and anything that is not a number is refused before it can be * written. */ export declare function coerceMoneyAmount(key: string, raw: unknown): number; /** * `unit` + `validate` + `validationHint` for an amount setting in the config * schema. * * The `unit: 'money'` mark is the part consumers key off. Anything that needs * to know "is this key an amount of money" asks the schema for that mark, not * the shape of the key's name, which is how the previous naming scheme reached * into every surface that touched one of these keys. */ export declare function moneyAmount(): { unit: 'money'; validate: (value: unknown) => boolean; validationHint: string; }; //# sourceMappingURL=money-value.d.ts.map