fix: reject fractional amounts for currencies with no minor unit, and unbreak the docs generator - #430
Merged
Merged
Conversation
…rencies with no minor unit Five currencies have no everyday minor unit, and all five mishandled a fractional amount. Reproduced on 5.1.2: ko-KR toCurrency(0.99) -> '영원' (zero won) vi-VN toCurrency(0.99) -> 'không đồng' (zero dong) fa-IR toCurrency(0.99) -> 'صفر ریال' (zero rial) id-ID toCurrency(0.99) -> 'nol rupiah' (zero rupiah) ja-JP toCurrency(0.99) -> '九十九銭' (99 sen) The first four destructured only `dollars` from parseCurrencyValue and never read `cents`, so the fractional part was silently discarded — the caller gets a well-formed string naming an amount that isn't the one they passed. ja-JP did read it, and spelled 銭 (sen), a unit demonetised in 1953. Both are "well-formed but wrong", the exact bug class this project's contract system exists to catch, and neither is detectable by fuzzing for malformed output. All five now throw RangeError — loud beats silent, the same philosophy checkMax already applies to its own precondition. Removes ja-JP's fixture cases that asserted the old fictitious-sen output. No API surface changes: these forms take no options today and still don't.
…piler API typescript@7.0.2 removed the classic ts.createProgram/getTypeChecker API that buildOptionsIndex() relied on to read JSDoc option types, so `npm run docs:languages` fails outright on main: TypeError: Cannot read properties of undefined (reading 'ES2022') Rewrite it against typescript/unstable/sync (the tsgo-backed replacement) and typescript/unstable/ast, reusing the project's existing src/tsconfig.json so compiler options can't drift from what CI's checkJs already enforces. The regenerated LANGUAGES.md differs only in union member ordering — tsgo returns union constituents sorted rather than in declaration order, so `'masculine' | 'feminine'` now renders as `'feminine' | 'masculine'`. Left as the new API reports it rather than re-sorted here, so the generator stays a faithful view of the checker.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Extracted from #428 so they can land on their own.
8 files, +139/−131.
1. Fractional amounts for zero-subunit currencies
Five currencies have no everyday minor unit, and all five mishandled a fractional amount. Reproduced on
5.1.2:ko-KRtoCurrency(0.99)영원vi-VNtoCurrency(0.99)không đồngfa-IRtoCurrency(0.99)صفر ریالid-IDtoCurrency(0.99)nol rupiahja-JPtoCurrency(0.99)九十九銭The first four destructure only
dollarsfromparseCurrencyValueand never readcents, so the fractional part is silently discarded — the caller gets a well-formed string naming an amount that isn't the one they passed.ja-JPdoes read it, and spells 銭 (sen), a unit demonetised in 1953.Both are "well-formed but wrong" — the bug class the contract system exists to catch, and undetectable by fuzzing for malformed output. All five now throw
RangeError. Loud beats silent, same ascheckMax.Breaking for anyone relying on the old behaviour, but the old behaviour was data loss.
No API surface change: these forms take no options today and still don't.
ja-JP's fixture cases asserting the fictitious-sen output are removed.2.
npm run docs:languagesis broken on maintypescript@7.0.2removed the classicts.createProgram/getTypeCheckerAPI thatbuildOptionsIndex()used:Rewritten against
typescript/unstable/sync(the tsgo-backed replacement) andtypescript/unstable/ast, reusing the existingsrc/tsconfig.jsonso compiler options can't drift from what CI'scheckJsenforces.The regenerated
LANGUAGES.mddiffers only in union member ordering — tsgo returns constituents sorted rather than in declaration order, so'masculine' | 'feminine'renders as'feminine' | 'masculine'. Left as the new API reports it rather than re-sorted, so the generator stays a faithful view of the checker.Verification
npm test— 453 tests passnpm run lint— cleannpm run docs:languages— runs again, output committedBoth commits are already in #428; that branch will rebase onto this and drop them.