Extensão do validart com validadores brasileiros
e locale pt-BR.
Validadores implementados como patterns dos pontos de extensão do core — mesma
API que qualquer outro país. Traz também um VLocale pt-BR completo (cobre todas
as mensagens do core + as deste pacote) e métodos de atalho para reduzir o verbosismo
em código BR-only.
- Instalação
- Uso básico
- Validadores
- Duas formas equivalentes
ModoValidacao- Locale pt-BR
- Extensibilidade
- Exemplo completo
- Licença
dart pub add validart validart_brOu no pubspec.yaml:
dependencies:
validart: ^2.1.0
validart_br: ^1.1.0import 'package:validart/validart.dart';
import 'package:validart_br/validart_br.dart';// Aplica as traduções pt-BR do core + validart_br
V.setLocale(VLocaleBr.ptBr);
final schema = V.string().trim().cpf();
schema.validate('123.456.789-09'); // true
schema.validate('111.111.111-11'); // false
schema.errors('000.000.000-00')?.first.message; // 'CPF inválido'
// parse — lança ao falhar
schema.parse('123.456.789-09'); // '123.456.789-09'
// safeParse — nunca lança
final result = schema.safeParse('000.000.000-00');
if (result case VFailure(:final errors)) {
print(errors.first.message); // 'CPF inválido'
}| Método | Descrição |
|---|---|
cpf({modo, mensagem}) |
CPF (11 dígitos). modo controla se aceita máscara. |
cnpj({modo, alfanumerico, mensagem}) |
CNPJ. Default aceita o novo formato alfanumérico da Receita. |
cep({modo, mensagem}) |
CEP (8 dígitos). |
pis({modo, mensagem}) |
PIS/PASEP/NIS (11 dígitos). |
tituloEleitor({mensagem}) |
Título de eleitor (12 dígitos, UF 01–28). |
cnh({mensagem}) |
CNH (11 dígitos). |
renavam({mensagem}) |
Renavam (11 dígitos). |
telefone({…}) |
Telefone BR com flags de ddd, pais, apenasCelular e modo. |
placa({modo, mensagem}) |
Placa — formato antigo (AAA-9999) ou Mercosul (AAA9A99). |
chavePix({tipos, mensagem}) |
Identificador PIX — chaves do DICT e/ou BR Code. tipos restringe os tipos aceitos. |
uf({mensagem}) |
UF brasileira (sigla de 2 letras em caixa alta, dentre as 27 unidades federativas). |
codigoBanco({mensagem}) |
Código de banco brasileiro (COMPE — 3 dígitos da tabela do Bacen). |
ddd({mensagem}) |
DDD brasileiro (2 dígitos da lista oficial Anatel). |
boleto({formato, mensagem}) |
Boleto — bancário ou arrecadação, linha digitável (47/48) ou código de barras (44). |
V.string().cpf().validate('123.456.789-09'); // true
V.string().cpf().validate('11111111111'); // false (repetido)
V.string().cpf(modo: ModoValidacao.semMascara)
.validate('12345678909'); // trueA partir de julho/2026 a Receita Federal emite CNPJs alfanuméricos: os
12 primeiros caracteres podem ser [0-9A-Z] e os 2 últimos (DVs)
continuam numéricos. validart_br aceita esse formato por padrão e
continua validando os CNPJs puramente numéricos existentes — dígitos são
subconjunto do alfanumérico.
V.string().cnpj().validate('12.345.678/0001-95'); // true (numérico)
V.string().cnpj().validate('12.ABC.345/01DE-35'); // true (alfanumérico)
V.string().cnpj(alfanumerico: false)
.validate('12.ABC.345/01DE-35'); // false — só dígitosLetras devem vir em caixa alta. Se o input pode vir com minúsculas,
encadeie .toUpperCase() antes (mesma regra para plate()):
V.string().toUpperCase().cnpj();
V.string().toUpperCase().placa();V.string().cep().validate('01001-000'); // true
V.string().cep().validate('01001000'); // true
V.string().cep().validate('0100100'); // falseV.string().pis().validate('120.54789.01-3'); // true
V.string().pis().validate('12054789013'); // trueV.string().tituloEleitor().validate('876543210329'); // true
V.string().tituloEleitor().validate('123456780099'); // false (UF 00)V.string().cnh().validate('12345678900'); // true
V.string().cnh().validate('00000000000'); // falseV.string().renavam().validate('12345678900'); // trueAceita celular (9 dígitos iniciando com 9) e fixo (8 dígitos), com ou
sem DDD e DDI. Use os parâmetros para restringir a forma.
V.string().telefone().validate('(11) 98765-4321'); // true
V.string().telefone().validate('11987654321'); // true
V.string().telefone().validate('+55 11 98765-4321'); // true
V.string().telefone(
pais: FormatoPais.obrigatorio, // exige +55
ddd: FormatoDdd.obrigatorio, // exige DDD
apenasCelular: true, // só celular
modo: ModoValidacao.comMascara, // exige separadores
).validate('+55 (11) 98765-4321'); // trueAceita formato antigo (AAA-9999 / AAA9999) e Mercosul (AAA9A99).
Letras devem estar em caixa alta — encadeie .toUpperCase() quando o
input pode vir minúsculo.
V.string().placa().validate('ABC-1234'); // true (antiga)
V.string().placa().validate('ABC1D23'); // true (Mercosul)
V.string().toUpperCase().placa().validate('abc-1234'); // truechavePix() aceita por padrão as cinco chaves do DICT:
- CPF (11 dígitos, sem máscara)
- CNPJ (14 dígitos, só numérico, sem máscara)
- Telefone em E.164 com
+55e celular (+55DDDNNNNNNNNN) - UUID v4 (chave aleatória)
Cada formato é checado no modo estrito exigido pelo PIX.
V.string().chavePix().validate('12345678909'); // true (CPF)
V.string().chavePix().validate('user@example.com'); // true (e-mail)
V.string().chavePix().validate('+5511987654321'); // true (telefone)
V.string().chavePix().validate('123e4567-e89b-12d3-a456-426614174000'); // true (UUID)Restrinja os tipos aceitos com tipos:
V.string().chavePix(tipos: const [TipoChavePix.email, TipoChavePix.telefone]);
// rejeita CPF, CNPJ e UUIDInclua TipoChavePix.brCode para também aceitar o BR Code — payload
EMVCo do QR Code PIX ("copia e cola"). A validação segue o padrão de
mercado (estrito): estrutura TLV, CRC16-CCITT-FALSE batendo e campos
obrigatórios do Bacen (moeda 986, país BR, GUID br.gov.bcb.pix).
// Aceita os 5 tipos de chave + BR Code:
V.string().chavePix(tipos: TipoChavePix.values);
// Só BR Code:
V.string().chavePix(tipos: const [TipoChavePix.brCode]);Aceita apenas as 27 siglas oficiais em caixa alta (AC, AL, …,
TO). Encadeie .toUpperCase() para aceitar input em minúsculas.
V.string().uf().validate('SP'); // true
V.string().uf().validate('XY'); // false
V.string().toUpperCase().uf().validate('rj'); // trueAceita os 3 dígitos da tabela COMPE do Banco Central (497 instituições
ativas hoje). Não aceita formato com DV ('001-9'); extraia os 3
primeiros se vier no formato com check digit.
V.string().codigoBanco().validate('001'); // true (Banco do Brasil)
V.string().codigoBanco().validate('033'); // true (Santander)
V.string().codigoBanco().validate('260'); // true (Nubank)
V.string().codigoBanco().validate('999'); // false2 dígitos da lista oficial da Anatel (67 códigos). Para validar o
telefone completo (DDD + número), use telefone() que já cobre o DDD
internamente.
V.string().ddd().validate('11'); // true (São Paulo)
V.string().ddd().validate('21'); // true (Rio de Janeiro)
V.string().ddd().validate('20'); // false (não atribuído)Aceita boleto bancário (cobrança) ou de arrecadação (concessionárias e
tributos), em qualquer das quatro formas — linha digitável (47/48
dígitos) ou código de barras (44). Caracteres não numéricos são
descartados antes da validação, então máscaras (., , -) são
toleradas.
V.string().boleto().validate(
'23793381286000782713695000063305975520000370000',
); // true (linha digitável bancária)
V.string().boleto().validate(
'836200000005667800481000180975657313001589636081',
); // true (linha digitável arrecadação mod-10)
V.string().boleto().validate(
'23793.38128 60007.827136 95000.063305 9 75520000370000',
); // true (com máscara)
// Restrinja a um formato específico:
V.string().boleto(formato: FormatoBoleto.bancario);
V.string().boleto(formato: FormatoBoleto.arrecadacao);DVs verificados: mod-10 nos campos 1, 2 e 3 da linha digitável
bancária + mod-11 do DV geral; nos boletos de arrecadação, mod-10 ou
mod-11 conforme o terceiro dígito do código de barras (6/7 →
mod-10, 8/9 → mod-11).
Cada validador BR tem duas formas de uso, ambas sempre equivalentes:
| Atalho | Forma explícita via pattern do core |
|---|---|
V.string().cpf() |
V.string().taxId(patterns: [const CpfPattern()]) |
V.string().cnpj() |
V.string().taxId(patterns: [const CnpjPattern()]) |
V.string().pis() |
V.string().taxId(patterns: [const PisPattern()]) |
V.string().tituloEleitor() |
V.string().taxId(patterns: [const TituloEleitorPattern()]) |
V.string().cnh() |
V.string().taxId(patterns: [const CnhPattern()]) |
V.string().renavam() |
V.string().taxId(patterns: [const RenavamPattern()]) |
V.string().cep() |
V.string().postalCode(patterns: [const CepPattern()]) |
V.string().placa() |
V.string().licensePlate(patterns: [const PlacaPattern()]) |
V.string().telefone() |
V.string().phone(patterns: [const TelefonePattern()]) |
V.string().uf() |
V.string().add(const UfValidator()) |
V.string().codigoBanco() |
V.string().add(const CodigoBancoValidator()) |
V.string().ddd() |
V.string().add(const DddValidator()) |
V.string().boleto() |
V.string().add(const BoletoValidator()) |
Use os atalhos em código BR-only (mais legível). Use os patterns explícitos quando precisar compor múltiplos países na mesma validação:
V.string().taxId(patterns: [const CpfPattern(), const UsSsnPattern()]);
// aceita CPF brasileiro OU Social Security Number americanoValidadores com máscara aceitam ModoValidacao para controlar a forma:
V.string().cpf(modo: ModoValidacao.qualquer); // default: com ou sem máscara
V.string().cpf(modo: ModoValidacao.comMascara); // só com máscara
V.string().cpf(modo: ModoValidacao.semMascara); // só dígitosAplica-se a cpf, cnpj, cep, pis, placa e telefone.
Equivalente em pt-BR do ValidationMode do core — os atalhos fazem
o depara internamente. Quem usa a forma explícita
(V.string().taxId(patterns: [const CpfPattern(mode: ValidationMode.formatted)]))
continua usando ValidationMode direto.
VLocaleBr.ptBr traduz todas as mensagens do core do validart mais
os códigos específicos do validart_br:
V.setLocale(VLocaleBr.ptBr);
V.string().email().errors('x')?.first.message;
// 'E-mail inválido'
V.string().cpf().errors('000.000.000-00')?.first.message;
// 'CPF inválido'
V.string().min(3).errors('a')?.first.message;
// 'Deve ter no mínimo 3 caracteres'Duas formas de aplicar:
// 1. Pronto para uso (core + BR):
V.setLocale(VLocaleBr.ptBr);
// 2. Override pontual:
V.setLocale(VLocaleBr.ptBrWith({
VCode.required: 'Obrigatório',
VStringCode.taxId: '{name} fora do padrão',
}));Se precisar de acesso aos mapas brutos (ex.: compor com mensagens de
outro pacote), use VLocaleBr.coreMessages, VLocaleBr.brMessages e
VLocaleBr.messages (união das duas).
Override global (via locale) afeta todos os validadores que emitem o código:
V.setLocale(VLocaleBr.ptBrWith({
VStringCode.taxId: '{name} fora do padrão', // CPF/CNPJ/PIS/CNH/…
}));Override por chamada (via parâmetro message) sobrescreve só aquela
instância — útil quando o gênero gramatical da mensagem importa:
V.string().cnh(mensagem: 'CNH inválida'); // força feminino só aqui
V.string().placa(mensagem: 'Placa não reconhecida');Os patterns plugáveis do core usam códigos genéricos com interpolação
de {name}:
| Código do core | Template pt-BR | Exemplos renderizados |
|---|---|---|
VStringCode.taxId |
{name} inválido |
"CPF inválido", "CNPJ inválido", "CNH inválido" |
VStringCode.postalCode |
{name} inválido |
"CEP inválido" |
VStringCode.licensePlate |
{name} inválida |
"Placa inválida" |
VStringCode.phone |
Telefone inválido (sem interpolação) |
"Telefone inválido" |
O {name} vem da propriedade name de cada pattern — CpfPattern
declara 'CPF', CnpjPattern declara 'CNPJ', e assim por diante.
Códigos específicos do validart_br:
| Constante | Código | Mensagem pt-BR |
|---|---|---|
VStringCodeBr.chavePixInvalida |
chave_pix_invalida |
Chave PIX inválida |
VStringCodeBr.ufInvalida |
uf_invalida |
UF inválida |
VStringCodeBr.codigoBancoInvalido |
codigo_banco_invalido |
Código de banco inválido |
VStringCodeBr.dddInvalido |
ddd_invalido |
DDD inválido |
VStringCodeBr.boletoInvalido |
boleto_invalido |
Boleto inválido |
Este pacote é construído inteiramente sobre os pontos de extensão públicos do core. Cada validador BR é uma classe que estende um abstract do validart:
| Pattern BR | Abstract do core |
|---|---|
CpfPattern |
TaxIdPattern |
CnpjPattern |
TaxIdPattern |
PisPattern |
TaxIdPattern |
TituloEleitorPattern |
TaxIdPattern |
CnhPattern |
TaxIdPattern |
RenavamPattern |
TaxIdPattern |
CepPattern |
PostalCodePattern |
PlacaPattern |
LicensePlatePattern |
TelefonePattern |
PhonePattern |
Validadores standalone (não estendem nenhum abstract do core):
| Validator | Por quê standalone |
|---|---|
ChavePixValidator |
União heterogênea (CPF/CNPJ/e-mail/telefone/UUID/BR Code). |
UfValidator |
Lookup contra lista finita (27 UFs); não é tax-id/CEP/placa. |
CodigoBancoValidator |
Lookup contra lista oficial (COMPE). |
DddValidator |
Lookup contra lista Anatel; não cabe em PhonePattern (parcial). |
BoletoValidator |
Agrega múltiplos checksums (mod-10/mod-11) sobre 2 layouts. |
Se precisar de um validador que não está aqui, escreva um pattern próprio — mesma API que os patterns deste pacote:
class MeuDocumentoPattern extends TaxIdPattern {
const MeuDocumentoPattern();
@override
String get name => 'Meu Documento';
@override
bool matches(String value) {
// sua regra de validação aqui
return value.length == 10;
}
}
V.string().taxId(patterns: [const MeuDocumentoPattern()]);
// Mensagem com VLocaleBr.ptBr: "Meu Documento inválido"Se quiser combinar vários países/documentos na mesma validação, passe
todos em patterns::
V.string().taxId(patterns: [
const CpfPattern(),
const CnpjPattern(),
const MeuDocumentoPattern(),
]);Veja example/example.dart. Para rodar:
dart run example/example.dartVeja LICENSE para detalhes.