Skip to content

feat(spec): port isValidCnpj to the bridge - #581

Closed
hyanmandian wants to merge 1 commit into
claude/single-impl-multi-lang-fftjdkfrom
claude/bridge-is-valid-cnpj
Closed

hyanmandian wants to merge 1 commit into
claude/single-impl-multi-lang-fftjdkfrom
claude/bridge-is-valid-cnpj

Conversation

@hyanmandian

Copy link
Copy Markdown
Member

What does this PR do?

Stacked on #580 (the compiler). Review that one first; this PR's diff is only what isValidCnpj adds.

The first utility through the bridge, and the one that exercises what a validator needs: two compiled regular expressions, a check digit pass over both CNPJ versions, and the typeof guard that makes a number invalid in JavaScript.

The diff, in full

file what it is
source/is-valid-cnpj.ts the utility — 72 lines, one exported function
source/_internals/cnpj.ts the CNPJ rules formatCnpj will also need, written once
conformance/cases/is-valid-cnpj.ts the arguments to replay — 20 lines
conformance/cases/_cnpj-corpus.ts how the corpus is built, shared with formatCnpj

No driver, no emitter change, no compiler change. That is the point: the table's columns come from the compiled signature, the expectation comes from calling the shipped package, and the replay program for each of the eight targets is generated.

Sharing without coupling

The check digit rules go under source/_internals/. The compiler inlines them into whichever utility imports them and prunes whatever that utility cannot reach, so the emitted module carries what it uses and nothing else — no cross-module import in any of the seven targets, and nothing for a bundler to have to see through.

Parity

The corpus is every string literal in the package's own CNPJ test files, plus 120 generated CNPJs, masked variants, one-digit mutations, and the numbers a JavaScript caller can pass where a string is declared — under all three option sets. Math.random is seeded while it is built, so the table is identical on every run.

bash spec/bridge/conformance/run-all.sh:

target matched not expressible
typescript 1725 / 1725
python 1725 / 1725
ruby 1725 / 1725
go 1707 / 1707 18
rust 1707 / 1707 18
java 1707 / 1707 18
csharp 1707 / 1707 18
c abi 1707 / 1707 18

The eighteen are the numeric inputs. Go, Rust, Java and C# declare the parameter as a string, so isValidCnpj(12345678000195) is a question that cannot be asked there; the row records which targets can be handed it rather than dropping the case.

bash spec/bridge/conformance/verify-typescript.sh — the generated TypeScript dropped into src/, running the package's own suite unmodified:

Test Files  1 passed (1)
     Tests  34 passed | 3 todo (37)

Checklist

  • My commit/PR title follows Conventional Commits.
  • I added or updated tests covering this change (npm test) — not applicable: no change to src/. The generated output is checked against the package's existing suite by verify-typescript.sh, and against a recording of the shipped package by run-all.sh.
  • I updated the documentation if this adds/changes a utility — not applicable, no published utility added or changed.
  • npm run check passes locally (format, lint, types).
  • I ran npm run build:llms if I touched docs/utilities.md — not applicable, docs/ untouched.
  • This change does not introduce a breaking change.
  • This change does not add any runtime dependency.

🤖 Generated with Claude Code

https://claude.ai/code/session_01UX1gTGeMTyoXQyr1qUoQKd


Generated by Claude Code

@coderabbitai

coderabbitai Bot commented Sep 21, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 3ae85528-bce5-4f59-b15b-027212005be1

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@vercel

vercel Bot commented Sep 21, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
brazilian-utils Error Error Sep 21, 2026 4:17am UTC

@github-actions

Copy link
Copy Markdown
Contributor

Tree-shaking report

No bundle size impact. All 155 exports are the same size as on the base branch (full import 648.9 KB, gzip 166.2 KB).

All exports (155)
Export Base Head Δ gzip
GetAddressInfoByCepError 966 B 966 B 0 B 600 B
GetAddressInfoByCepNotFoundError 1.0 KB 1.0 KB 0 B 618 B
GetAddressInfoByCepServiceError 1.0 KB 1.0 KB 0 B 617 B
GetAddressInfoByCepValidationError 1.0 KB 1.0 KB 0 B 620 B
GetCepInfoByAddressError 966 B 966 B 0 B 600 B
GetCepInfoByAddressNotFoundError 1.0 KB 1.0 KB 0 B 618 B
GetCepInfoByAddressValidationError 1.0 KB 1.0 KB 0 B 620 B
addBusinessDays 6.8 KB 6.8 KB 0 B 2.8 KB
capitalize 2.5 KB 2.5 KB 0 B 1.3 KB
convertCurrencyToWords 2.8 KB 2.8 KB 0 B 1.5 KB
convertDateToWords 3.2 KB 3.2 KB 0 B 1.7 KB
convertLicensePlateToMercosul 1.3 KB 1.3 KB 0 B 807 B
convertNumberToWords 2.4 KB 2.4 KB 0 B 1.3 KB
differenceInBusinessDays 6.9 KB 6.9 KB 0 B 2.9 KB
formatBoleto 1.4 KB 1.4 KB 0 B 837 B
formatCEP 1.2 KB 1.2 KB 0 B 778 B
formatCNPJ 1.4 KB 1.4 KB 0 B 854 B
formatCPF 1.3 KB 1.3 KB 0 B 806 B
formatCaepf 1.3 KB 1.3 KB 0 B 787 B
formatCei 1.3 KB 1.3 KB 0 B 785 B
formatCep 1.2 KB 1.2 KB 0 B 778 B
formatCertidao 1.3 KB 1.3 KB 0 B 789 B
formatCnae 1.2 KB 1.2 KB 0 B 782 B
formatCnh 1.3 KB 1.3 KB 0 B 780 B
formatCno 1.3 KB 1.3 KB 0 B 786 B
formatCnpj 1.4 KB 1.4 KB 0 B 854 B
formatCns 1.3 KB 1.3 KB 0 B 780 B
formatCpf 1.3 KB 1.3 KB 0 B 806 B
formatCurrency 1.8 KB 1.8 KB 0 B 1.0 KB
formatIban 1.1 KB 1.1 KB 0 B 696 B
formatLegalNature 1.2 KB 1.2 KB 0 B 777 B
formatLicensePlate 1.2 KB 1.2 KB 0 B 738 B
formatNcm 1.2 KB 1.2 KB 0 B 780 B
formatNfeKey 1.3 KB 1.3 KB 0 B 784 B
formatPassport 1.0 KB 1.0 KB 0 B 643 B
formatPhone 2.8 KB 2.8 KB 0 B 1.5 KB
formatPis 1.3 KB 1.3 KB 0 B 781 B
formatProcessoJuridico 1.3 KB 1.3 KB 0 B 785 B
formatVoterId 1.3 KB 1.3 KB 0 B 821 B
generateBoleto 2.0 KB 2.0 KB 0 B 1.1 KB
generateCNPJ 1.6 KB 1.6 KB 0 B 965 B
generateCPF 1.4 KB 1.4 KB 0 B 878 B
generateCep 984 B 984 B 0 B 610 B
generateCnh 1.4 KB 1.4 KB 0 B 828 B
generateCnpj 1.6 KB 1.6 KB 0 B 965 B
generateCpf 1.4 KB 1.4 KB 0 B 878 B
generateLegalNature 5.9 KB 5.9 KB 0 B 2.1 KB
generateLicensePlate 1.1 KB 1.1 KB 0 B 692 B
generatePassport 1.1 KB 1.1 KB 0 B 656 B
generatePhone 1.5 KB 1.5 KB 0 B 900 B
generatePis 1.2 KB 1.2 KB 0 B 744 B
generatePixPayload 6.3 KB 6.3 KB 0 B 2.8 KB
generateProcessoJuridico 1.4 KB 1.4 KB 0 B 870 B
generateRenavam 1.2 KB 1.2 KB 0 B 760 B
generateVoterId 1.7 KB 1.7 KB 0 B 1021 B
getAddressInfoByCep 4.1 KB 4.1 KB 0 B 1.9 KB
getAreaCodeInfo 3.9 KB 3.9 KB 0 B 1.4 KB
getAreaCodesByState 1.6 KB 1.6 KB 0 B 917 B
getBankByCode 38.6 KB 38.6 KB 0 B 9.8 KB
getBankByIspb 38.6 KB 38.6 KB 0 B 9.8 KB
getBanks 38.4 KB 38.4 KB 0 B 9.6 KB
getBoletoInfo 3.1 KB 3.1 KB 0 B 1.6 KB
getCbo 119.1 KB 119.1 KB 0 B 30.7 KB
getCepInfoByAddress 2.7 KB 2.7 KB 0 B 1.4 KB
getCertidaoInfo 1.8 KB 1.8 KB 0 B 1.0 KB
getCfop 68.9 KB 68.9 KB 0 B 6.9 KB
getCities 154.3 KB 154.3 KB 0 B 49.9 KB
getCnae 93.9 KB 93.9 KB 0 B 21.2 KB
getFormatLicensePlate 1.1 KB 1.1 KB 0 B 692 B
getHolidays 6.1 KB 6.1 KB 0 B 2.6 KB
getIbanInfo 1.6 KB 1.6 KB 0 B 955 B
getLegalNature 6.3 KB 6.3 KB 0 B 2.3 KB
getLegalNatures 5.9 KB 5.9 KB 0 B 2.1 KB
getLegalNaturesByCategory 6.5 KB 6.5 KB 0 B 2.4 KB
getMunicipalities 156.4 KB 156.4 KB 0 B 50.3 KB
getMunicipality 154.9 KB 154.9 KB 0 B 50.3 KB
getMunicipalityByCode 156.5 KB 156.5 KB 0 B 50.4 KB
getNfeKeyInfo 2.7 KB 2.7 KB 0 B 1.5 KB
getPixKeyInfo 4.5 KB 4.5 KB 0 B 2.0 KB
getPixPayloadInfo 2.9 KB 2.9 KB 0 B 1.4 KB
getStateByIbgeCode 3.2 KB 3.2 KB 0 B 1.1 KB
getStateCodeByName 3.2 KB 3.2 KB 0 B 1.1 KB
getStateNameByCode 3.1 KB 3.1 KB 0 B 1.0 KB
getStates 3.0 KB 3.0 KB 0 B 1017 B
getTimezoneByState 1.6 KB 1.6 KB 0 B 809 B
isBusinessDay 6.5 KB 6.5 KB 0 B 2.7 KB
isHoliday 6.4 KB 6.4 KB 0 B 2.7 KB
isValidBankAccount 7.4 KB 7.4 KB 0 B 2.8 KB
isValidBoleto 2.4 KB 2.4 KB 0 B 1.3 KB
isValidCEP 984 B 984 B 0 B 610 B
isValidCNPJ 1.6 KB 1.6 KB 0 B 914 B
isValidCPF 1.3 KB 1.3 KB 0 B 805 B
isValidCaepf 1.5 KB 1.5 KB 0 B 913 B
isValidCbo 119.2 KB 119.2 KB 0 B 30.7 KB
isValidCei 1.5 KB 1.5 KB 0 B 899 B
isValidCep 984 B 984 B 0 B 610 B
isValidCertidao 1.6 KB 1.6 KB 0 B 938 B
isValidCfop 68.9 KB 68.9 KB 0 B 6.9 KB
isValidCnae 94.0 KB 94.0 KB 0 B 21.2 KB
isValidCnh 1.4 KB 1.4 KB 0 B 856 B
isValidCno 1.5 KB 1.5 KB 0 B 901 B
isValidCnpj 1.6 KB 1.6 KB 0 B 914 B
isValidCns 1.5 KB 1.5 KB 0 B 925 B
isValidCpf 1.3 KB 1.3 KB 0 B 805 B
isValidCreditCard 1.4 KB 1.4 KB 0 B 868 B
isValidCsosn 1.2 KB 1.2 KB 0 B 737 B
isValidCst 1.8 KB 1.8 KB 0 B 1.0 KB
isValidEmail 1.0 KB 1.0 KB 0 B 622 B
isValidIE 5.7 KB 5.7 KB 0 B 2.1 KB
isValidIban 1.3 KB 1.3 KB 0 B 836 B
isValidIe 5.7 KB 5.7 KB 0 B 2.1 KB
isValidLandlinePhone 1.5 KB 1.5 KB 0 B 933 B
isValidLegalNature 5.8 KB 5.8 KB 0 B 2.1 KB
isValidLicensePlate 1.1 KB 1.1 KB 0 B 702 B
isValidMobilePhone 1.6 KB 1.6 KB 0 B 971 B
isValidNcm 114.2 KB 114.2 KB 0 B 24.6 KB
isValidNfeKey 2.7 KB 2.7 KB 0 B 1.5 KB
isValidPIS 1.2 KB 1.2 KB 0 B 785 B
isValidPassport 1.0 KB 1.0 KB 0 B 654 B
isValidPhone 2.6 KB 2.6 KB 0 B 1.3 KB
isValidPis 1.2 KB 1.2 KB 0 B 785 B
isValidPixKey 4.6 KB 4.6 KB 0 B 2.1 KB
isValidPixPayload 2.9 KB 2.9 KB 0 B 1.5 KB
isValidProcessoJuridico 1.3 KB 1.3 KB 0 B 787 B
isValidRegistroProfissional 1.6 KB 1.6 KB 0 B 964 B
isValidRenavam 1.3 KB 1.3 KB 0 B 815 B
isValidServicePhone 1.5 KB 1.5 KB 0 B 846 B
isValidVin 1.6 KB 1.6 KB 0 B 995 B
isValidVoterId 1.6 KB 1.6 KB 0 B 900 B
parseBoleto 1020 B 1020 B 0 B 634 B
parseCaepf 1003 B 1003 B 0 B 621 B
parseCbo 1002 B 1002 B 0 B 620 B
parseCei 1003 B 1003 B 0 B 619 B
parseCep 1002 B 1002 B 0 B 620 B
parseCertidao 1003 B 1003 B 0 B 621 B
parseCfop 1002 B 1002 B 0 B 620 B
parseCnae 1002 B 1002 B 0 B 620 B
parseCnh 1003 B 1003 B 0 B 621 B
parseCno 1003 B 1003 B 0 B 619 B
parseCnpj 1.1 KB 1.1 KB 0 B 669 B
parseCns 1003 B 1003 B 0 B 621 B
parseCpf 1003 B 1003 B 0 B 621 B
parseCurrency 1.4 KB 1.4 KB 0 B 881 B
parseIban 1.0 KB 1.0 KB 0 B 638 B
parseLegalNature 1002 B 1002 B 0 B 620 B
parseLicensePlate 1.0 KB 1.0 KB 0 B 638 B
parseNcm 1002 B 1002 B 0 B 620 B
parseNfeKey 1.0 KB 1.0 KB 0 B 659 B
parsePassport 1.0 KB 1.0 KB 0 B 637 B
parsePhone 1.1 KB 1.1 KB 0 B 707 B
parsePis 1003 B 1003 B 0 B 621 B
parseProcessoJuridico 1003 B 1003 B 0 B 621 B
parseVoterId 1.0 KB 1.0 KB 0 B 650 B
removeAccents 953 B 953 B 0 B 593 B
subBusinessDays 6.9 KB 6.9 KB 0 B 2.9 KB
How this is measured

Every export is imported alone into an esbuild consumer bundle (minified, tree-shaken) built from the head and from the base of this pull request; the sizes are the resulting bundles, gzip is their gzipped size. 🔴 marks a regression: a pre-existing export that grew more than 20% and more than 256 B, or the bundle importing every pre-existing export growing more than 5%. 🟡 is growth under the threshold, 🟢 a decrease, ⚪ no change, 🆕 an export that does not exist on the base (never a regression), 🗑️ an export that was removed. An intentional increase is accepted with the tree-shaking: accepted label.

@codecov

codecov Bot commented Sep 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (4de5b16) to head (f701ac0).

Additional details and impacted files
@@                          Coverage Diff                           @@
##           claude/single-impl-multi-lang-fftjdk      #581   +/-   ##
======================================================================
  Coverage                                100.00%   100.00%           
======================================================================
  Files                                       183       183           
  Lines                                      2069      2069           
  Branches                                    612       612           
======================================================================
  Hits                                       2069      2069           
Flag Coverage Δ
node 100.00% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

The first utility through the compiler, and the one that exercises the parts a validator
needs: two compiled regular expressions, a check digit pass over both CNPJ versions, and the
`typeof` guard that makes a number invalid in JavaScript.

The CNPJ rules that `formatCnpj` will also need — the two shapes a CNPJ can be written in,
the weight vectors, the check digits — go under `source/_internals/`, written once. The
compiler inlines them into this utility and prunes the rest, so the emitted module carries
what it uses and nothing else.

The corpus is every string literal in the package's own CNPJ test files, plus generated
CNPJs, masked variants, one-digit mutations and the numbers a JavaScript caller can pass
where a string is declared, under all three option sets. The generator is seeded, so the
table is the same on every run.

    typescript  1725/1725      python  1725/1725      ruby  1725/1725
    go          1707/1707      rust    1707/1707      java  1707/1707
    csharp      1707/1707      cabi    1707/1707

The eighteen the compiled targets do not run are the numeric inputs: they declare the
parameter as a string, so `isValidCnpj(12345678000195)` is a question that cannot be asked
there. The row records that rather than dropping it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UX1gTGeMTyoXQyr1qUoQKd

Copy link
Copy Markdown
Member Author

The red Vercel status here is the same one that is red on main (69e9b1f) and on unrelated PR #576 — a failure in the Vercel project's own build, outside this repository's diff. The comment on #580 has the evidence. There is no fix to port, and I have no Vercel access to re-run the deployment.

Everything on GitHub Actions is green or still running, and this PR touches nothing under src/.


Generated by Claude Code

Copy link
Copy Markdown
Member Author

Closing this one: the stack is being collapsed into #580 at the author's request. Nothing is lost — this PR's commit (f701ac0) becomes part of #580's history, and spec/bridge/source/is-valid-cnpj.ts plus its recorded cases land there unchanged, alongside the generated output for all seven targets so the emitted code can be read in review.


Generated by Claude Code

This branch had an error being deployed

1 failed deployment
Preview f701ac06 Deployed Sep 21, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants