Skip to content
Code Recycle

Component · for humans & their agents

Money Shorthand Parser

not verifiedactively maintained$9 one-time

The sanitizer that turns "$25M" into 25 doesn't throw. It saves, renders $25, and looks completely normal.

by Code Recycle · New publisher

Buy for $9

Every claim on this page is refundable if it is untrue — refund policy.

Verified: 29 tests · 6/7 mutations caught

Building it yourself: ~0.8h of agent time across about 3 attempts. Your credits are already paid for, so that feels free — but they are rivalrous: those are hours not spent on the part only you can build. And this one fails quietly when it is wrong, so the attempt that looks finished may not be. $9.

☆ Save
Parses VC/finance shorthand into exact integer cents, and refuses on anything ambiguous. Separate parsers and separate units for money, percentages and multiples, so a percentage can never be assigned to a money field. Zero dependencies, pure functions.

The bug, exactly

``` String(v).replace(/[^0-9.]/g, "") → "$25M" becomes "25" → 25 ```

Twenty-five dollars, where twenty-five million belonged. **Nothing surfaced the loss.** The form saved. The toast said "Saved." The detail page rendered `$25` and looked entirely normal, because $25 is a plausible number.

A strip-non-digits sanitizer does not fail — it succeeds at the wrong thing. That is why it survives code review and ships.

The rules, each a shape that sanitizer got wrong

**Suffixes carry magnitude.** Dropping `M` is a 1,000,000× error that looks like a small number. An *unrecognised* suffix is refused rather than ignored — ignoring it is the original bug.

**Not every number is money.** `25x` is a multiple. `13%` is a percentage. Returning 25 for either is worse than returning nothing, because nothing is visible. Checked BEFORE stripping, because once the suffix is gone `25x` and `$25` are indistinguishable. Multiples and percentages get their own parsers and their own units — percentages return basis points, so one can never be assigned to a money field.

**Ambiguous input refuses.** `1.2.3` is not 1.23. A parser that guesses is a parser that silently corrupts.

**An empty string is not zero.** `""` means "not entered". Coercing it to 0 fabricates a data point: a company with no disclosed valuation becomes one valued at nothing. The result type distinguishes "left blank" from "could not read" — those need different UI, and conflating them is how bad data gets saved quietly.

**Integer minor units, exactly.** Not `Math.round(value * 100)`: 1.005 is 1.00499… in binary, so that rounds to 100 cents instead of 101 and the precision claim becomes approximately true. Decimal-to-cents shifts the point textually and is exact for anything a human can type.

Found while building it

Two real bugs in the first draft. `/[~≈about ]/` looks like it matches the word "about" — it is a **character class**, stripping `a`, `b`, `o`, `u`, `t` individually, so `"1bn"` lost its `b`. And the float rounding above.

Then a **mutation survived**, which was more useful than the ones that failed: a comment claimed the magnitude table's ordering was load-bearing. It is not — the patterns are anchored, so `mm` can never partially match `m`. The comment was wrong, the anchoring is the real protection, and there is now a test pinning it.

**29 tests passing · typecheck clean · 6/7 mutations caught, and the survivor corrected a false claim in the source.**

Delivery

Private repository invite within 24 hours. Single-product commercial license: use and modify in one shipped product; no redistribution or resale of the source.

01Capabilities

Does

  • No capabilities recorded

Doesn’t

  • No exclusions declared

02Requirements & stack

Depends on

No declared dependencies

Credentials needed

None declared

Stack

typescript

03Community

No endorsements yet

No verified confirmations yet — be the first.

Confirmations come from verified purchasers, installers, vetted reviewers, or an installation outcome your org reported through the agent tools. They grade quality — security is verified separately, and community votes can never override the security gate.

Sign in to confirm — weight comes from verified usage, not vote count.

04Trust Passport

Full passport →
/100

0/0 automated components pass. An automated score is never a security guarantee.

VersionChannelReleasedNotes
1.0.0stableAug 2, 2026First public release.