porkbun: add check and register - #29
Merged
Merged
Conversation
Buying a domain was the one thing still worth opening the dashboard for.
Porkbun's API can do it now, so the CLI can too.
`register` resolves a single plan — the TLD's rules, then availability and
price — prints it, and asks before spending. The plan exists so the number in
the prompt and the number sent to the registrar are the same number by
construction, and so the availability check happens exactly once: it is rate
limited to one call per ten seconds, and re-checking to "confirm" just before
buying earns an error rather than a second answer.
Two guards against a surprise charge. `--max-price` refuses anything dearer,
because a premium name is priced in the hundreds and reads the same at a glance.
And a promotional first year is called out, since the price agreed to is then not
the price paid next year. WHOIS privacy defaults on, and a TLD that cannot do
privacy is refused rather than quietly publishing a home address.
`priceCents` is its own function because the obvious conversion is wrong:
prices are quoted as dollar strings, `/domain/create` wants integer cents that
match the quote exactly, and `parseFloat('11.08') * 100` is 1107.9999999999998
— which truncates to 1107 and buys nothing. The decimal is split as text and
never becomes a float.
`check` is the read half, so a name can be priced without going near the
purchase path.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QLFd9jDQ4D5UpHCWFJi8YM
| .trim() | ||
| .toLowerCase() | ||
| .replace(/\.$/, ''); | ||
| if (!/^[a-z0-9-]+(\.[a-z0-9-]+)+$/.test(zone)) { |
ThreatCrush Security Scan16 finding(s) HIGH/CRITICAL: 5 | MEDIUM: 2 | LOW: 9
Snippets are redacted; ThreatCrush never prints matched credential material. |
ralyodio
added a commit
that referenced
this pull request
Aug 29, 2026
The free-names branch was cut when master was 0.12.0 and bumped to 0.13.0 in its feature commit, the convention here. By the time it merged, `torrent` (#28) and porkbun's `check`/`register` (#29) had taken master to 0.14.0, and the squash replayed the older bump on top — so a release that added a command published a lower version than the one before it. 0.15.0 rather than 0.14.1: free-names is a new command, and a new command is a minor here. Worth knowing for next time: a hand-maintained version in the feature commit only works while one branch is in flight. A squash does not conflict on it when the surrounding lines still match, so nothing catches the regression at merge time — only reading the tag afterwards does. Claude-Session: https://claude.ai/code/session_01XGe9mWC6FvUjT6p1HCVjba Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Buying a domain was the one thing still worth opening the Porkbun dashboard for. Their API can do it now, so the CLI can too.
How it avoids spending money by accident
registerresolves a single plan — the TLD's rules, then availability and price — prints it, and asks. The plan exists so the number in the prompt and the number sent to the registrar are the same number by construction rather than by two lookups agreeing. It also pins the availability check to exactly one call, which matters: Porkbun rate limits it to one per ten seconds, so re-checking to "confirm" just before buying earns an error instead of a second answer.Guards on top of that:
--max-pricerefuses anything dearer. A premium name is priced in the hundreds and reads the same as a normal one at a glance..usnexus,.calegal type), is refused up front instead of after a charge.--dry-runprices it and stops.The money bug that isn't there
priceCentsis its own function with its own tests because the obvious conversion is wrong. Prices are quoted as dollar strings,/domain/createwants integer cents matching the quote exactly, andparseFloat('11.08') * 100is1107.9999999999998— truncating to1107, which buys nothing and fails as a price mismatch. The decimal is split as text and never becomes a float.Testing
--dry-runpriceddiskpush.comat $11.08/yr correctly.🤖 Generated with Claude Code
https://claude.ai/code/session_01QLFd9jDQ4D5UpHCWFJi8YM