feat: adiciona máscaras de input e suporte a CNPJ alfanumérico#33
Merged
Conversation
Centralizes mask functions previously scattered across 34 MFEs. Adds support for the alphanumeric CNPJ format (RFB NT 49/2024) in formatCnpj, normalizeCpfOrCnpj, and isCnpj. - New module src/masks/ exposing: maskValue, maskInput, maskCpf, maskCpfOrCnpj, maskComplete, setupMultipleMask, maskHintBankAccount - isCnpj is now a wrapper over cpf-cnpj-validator@2.1.0 with uppercase normalization (handles both numeric and alphanumeric CNPJ) - formatCnpj and normalizeCpfOrCnpj preserve A-Z characters - Strip regexes centralized in src/masks/strip.ts - vanilla-masker added as runtime dependency Refs #32 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
actions/cache@v2 was deprecated and started auto-failing builds. cpf-cnpj-validator@2.1.0 (added in this branch) requires Node >=18, breaking the linter job that pinned Node 16. - ci.yaml: Node 14 → 20, checkout/setup-node v2 → v4, removed legacy actions/cache step (setup-node v4 handles caching when a lockfile exists; this repo gitignores yarn.lock so omitted) - linter.yaml: Node 16 → 20, checkout v3 → v4, setup-node v2 → v4, reviewdog/action-eslint v1.16.1 → v1.33.0 - cd.yml: same bumps applied preventatively (would break on master after this branch merges) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The Intl.DateTimeFormat output for pt-BR with dateStyle: full and timeStyle: long started including the "às" connector word in newer ICU versions (Node >= 18). The CI bump from Node 14 to Node 20 in this branch surfaced the divergence. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
acassiovilasboas
previously approved these changes
May 7, 2026
danimuller20
previously approved these changes
May 7, 2026
Contributor
danimuller20
left a comment
There was a problem hiding this comment.
Eu não sei se foi feito, mas seria interessante atualizar a base de conhecimento
…appears The previous logic only switched from CPF mask to CNPJ mask when the stripped input crossed 11 characters. Since the CPF pattern uses the digit-only `9` placeholder from vanilla-masker, letters typed before that threshold were silently dropped — making it impossible to enter an alphanumeric CNPJ progressively (e.g. `12A`, `12AB`, ...). Detect any A-Z early and route to MASKS.CNPJ (`SS.SSS.SSS/SSSS-99`) immediately, while keeping the length-based branch for purely numeric input so retrocompatibility with CPF/CNPJ numérico is preserved. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
c82d24d
danimuller20
approved these changes
May 8, 2026
This was referenced May 12, 2026
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.
Tipo de mudança
featureContexto
Atualmente 34 MFEs do ecossistema mantêm cópias quase idênticas de
src/utils/masks.ts/masks.jsbaseadas emvanilla-masker, gerando manutenção pulverizada. Além disso, a Receita Federal está adotando o CNPJ alfanumérico (Nota Técnica RFB NT 49/2024) — letras A-Z nas 12 primeiras posições + 2 dígitos verificadores numéricos —, e as funções atuais deformatCnpj,normalizeCpfOrCnpjeisCnpjnoblu-utilsusamreplace(/\D/g, '')/regex puramente numérica, destruindo silenciosamente as letras.Esta PR é a Fase 1 descrita no PRD: centralizar todas as máscaras de input no
@useblu/utils(já re-exportado pelomfe-corecomocore/blu-utilsvia Module Federation) e atualizar as funções existentes para suportarem o novo formato. A Fase 2 (migração dos 34 MFEs para consumiremcore/blu-utilsem vez dos arquivos locais) ficará para depois.Solução
Novo módulo
src/masks/Reúne em um lugar único:
maskValue,maskInput,maskCpf,maskCpfOrCnpj,maskComplete,setupMultipleMask,maskHintBankAccount.vanilla-masker(adicionado comodependency) — placeholders9(dígito),S(alfanumérico),A(letra). CNPJ usa patternSS.SSS.SSS/SSSS-99(12 alfa + 2 dígito).isCnpj.tsvirou wrapper sobrecpf-cnpj-validator@2.1.0(cnpj.isValid(value.toUpperCase())), que já implementa o algoritmo de DV alfanumérico oficial e mantém blacklist de CNPJs inválidos. A blacklist e overifierDigitlocais foram removidos (a lib cuida)..toUpperCase()no ponto de entrada via helperstripAlphanumeric(regex/[^A-Za-z0-9]/g+ uppercase). Helpers de strip centralizados emsrc/masks/strip.tspara evitar duplicação de regex em 6+ arquivos.API pública enxuta
Após análise de uso real nos MFEs, não foram expostos:
masks(constante),cnpjMask,cpfMask,bankAccountMasks,maskBankAccount. A constante interna foi renomeadamasks→MASKScom chaves UPPERCASE para deixar claro que é detalhe de implementação.Retrocompatibilidade
formatCnpj,normalizeCpfOrCnpjeisCnpjmantêm a mesma assinatura. CNPJ numérico continua funcionando exatamente como antes (cobertura via testes de regressão).strictdeisCnpjperde efeito prático (acpf-cnpj-validatoraceita ambos os formatos). Marcado como@deprecatedno JSDoc.Principais mudanças
src/masks/com 9 arquivos (types.ts,masks.ts,strip.ts,maskValue.ts,maskInput.ts,maskCpf.ts,maskCpfOrCnpj.ts,maskComplete.ts,setupMultipleMask.ts,maskHintBankAccount.ts,vanilla-masker.d.ts)src/formatters/formatCnpj.tsreescrito para usarstripAlphanumeric+VMasker.toPattern(stripped, MASKS.CNPJ)src/normalizers/normalizeCpfOrCnpj.tsatualizado para CNPJ alfanumérico (>11 chars limpos)src/validations/isCnpj.tsvirou wrapper de 4 linhas sobrecpf-cnpj-validatorsrc/index.tsadiciona bloco// maskscom 7 funções e 3 types públicospackage.json:vanilla-masker@^1.2.0ecpf-cnpj-validator@2.1.0emdependencies;jest-environment-jsdom@29emdevDependencies(necessário para testes domaskInput)tests/masks/+tests/formatCnpj.spec.ts;tests/isCnpj.spec.tsetests/normalizeCpfOrCnpj.spec.tsestendidos com casos de CNPJ alfanuméricoImpacto
@useblu/utils. Nenhum MFE é afetado nesta entrega — a migração paracore/blu-utilsé Fase 2.Cenários de teste
maskValue('11222333000181', 'cnpj')→'11.222.333/0001-81'(numérico — retrocompat)maskValue('12ABC34501DE35', 'cnpj')→'12.ABC.345/01DE-35'(alfanumérico)maskValue('12abc34501de35', 'cnpj')→'12.ABC.345/01DE-35'(minúsculo normaliza)maskCpfOrCnpj('93231097037')→'932.310.970-37'(CPF, ≤11 chars)maskCpfOrCnpj('12ABC34501DE35')→'12.ABC.345/01DE-35'(CNPJ alfa, >11 chars)maskInput(input, 'cpf')aplica máscara em tempo real ao digitar e pode ser desfeito via teardownsetupMultipleMask(input)transiciona de CPF → CNPJ ao digitar o 12º caractereisCnpj(cnpj.generate())→true(CNPJ alfa válido gerado pela própria lib)isCnpj('12ABC34501DE99')→false(DV alfa errado)isCnpj('00000000000000')→false(blacklist numérica preservada via lib)formatCnpj('11222333000181')→'11.222.333/0001-81'(regressão numérica)formatCnpj('12abc34501de35')→'12.ABC.345/01DE-35'(alfa + uppercase)maskComplete('12.ABC.345/01DE-35', 'cnpj')→truemaskHintBankAccount('1')→'00000000-0'(BB)Validações automáticas:
yarn build,yarn lint,yarn test --testPathPattern=\"masks|formatCnpj|isCnpj|normalizeCpfOrCnpj\"(10 suítes, 63 testes verdes localmente).Breaking changes
Nenhum em assinaturas públicas. Mudanças de comportamento documentar no CHANGELOG da
1.3.0:formatCnpjagora preserva letras A-Z e normaliza para uppercase. MFEs que assumiam retorno numérico devem ser auditados na Fase 2.isCnpj(value, strict)ignorastrict(soft deprecation). A libcpf-cnpj-validatoraceita ambos os formatos por padrão.verifierDigitantes exportado como named export emsrc/validations/isCnpj.tsfoi removido (decisão registrada no spec).Dependências entre PRs
Pagnet/mfe-corebumpando@useblu/utilspara1.3.0é hand-off para a squad Core (T9 do plano de execução do spec).Rollback
npm deprecate @useblu/utils@1.3.0+ revert do bump nomfe-corequando aplicado. Como nenhum MFE consome a nova API ainda, o impacto de rollback é zero no curto prazo.Links