geekcom/validator-docs
Automatically generate documentation for Laravel validation rules. It scans your application's rules and outputs clean Markdown tables covering each rule, its parameters, and descriptions, keeping your validation docs in sync with your code via a simple Artisan command.
composer require geekcom/validator-docs
The service provider is auto-discovered (Laravel 5.5+); there is nothing to publish or configure. The package registers its checks via Validator::extend, so the rule names are usable as plain strings anywhere Laravel accepts rules:
$request->validate([
'nome' => ['required', 'string'],
'cpf' => ['required', 'cpf'],
'cnpj' => ['required', 'cnpj'],
]);
Where to look first: the rule table in the README (rule identifiers are not namespaced — no Rule:: object, no config file), then src/ if you need to know precisely what is being validated (check-digit math vs. format only) before you rely on it for anything compliance-adjacent.
First use case: a registration/profile form that takes CPF (individuals) or CNPJ (companies). Add the rule to the existing FormRequest, keep your own required/nullable rules, and you are done — the package only validates, it does not format, mask, or persist.
Keep normalization separate from validation. The rules tolerate masked input (they strip ./-// internally), so use prepareForValidation() for storage consistency rather than to make validation pass:
protected function prepareForValidation(): void
{
$this->merge([
'cnpj' => preg_replace('/\D/', '', (string) $this->cnpj),
]);
}
One field, either document type. For a generic "documento" field use cpf_cnpj instead of branching on length in a closure.
Mixed old/new CNPJ during the transition (3.12.0+). The new release adds validation for the alphanumeric CNPJ format, which coexists with the numeric-only rule. Build the rule list conditionally instead of stacking both:
$rules = ['required', 'string', 'size:14'];
// numeric-only CNPJ stays valid; new-format CNPJ carries letters in the first 12 positions
$rules[] = preg_match('/[A-Z]/i', $value) ? 'cnpj_alpha' : 'cnpj';
// or accept either, when you don't want to detect:
// ['required', 'string', 'size:14', 'cnpj', 'cnpj_alpha'] ← wrong: both must pass
Confirm the exact rule identifier for the alphanumeric variant in the README after upgrading — it follows the same Validator::extend registration as cnpj, so it is a bare string, not a namespaced class.
Wrap it for composability. The package ships strings, not Rule objects. If you need conditional/when() behaviour or reusable rule sets, wrap once:
class Cnpj implements ValidationRule
{
public function validate(string $attribute, mixed $value, Closure $fail): void
{
if (Validator::make(['v' => $value], ['v' => 'cnpj_alpha'])->fails()) {
$fail('O :attribute informado é inválido.');
}
}
}
Test with data providers, not real documents. Feed known-valid and known-invalid fixtures through Validator::make([...], [...])->passes(); this is also the fastest way to pin down which format a given rule name accepts.
Storage: keep the column at char(14) / varchar(14) and store uppercase — the alphanumeric format keeps the CNPJ at 14 characters, so no schema migration is needed for the new format itself.
numeric or digits:14. Those were fine for numeric CNPJ and will silently reject alphanumeric CNPJ. Use size:14 (plus alpha_num if you want a format guard).cpf_cnpj predates the alphanumeric format. Verify (or test) whether it accepts the new CNPJ before swapping it into an existing form; otherwise a mixed-type field will start failing for new-format companies on 3.12.0.false for empty strings, so nullable/sometimes are your responsibility — a missing nullable shows up as a confusing "invalid CNPJ" instead of "required".extend('cpf')/extend('cnpj'); last registration wins. If validation behaves unexpectedly, check composer show and the provider boot order rather than the rule itself.php artisan optimize:clear if the new rule appears unknown — a stale cached provider manifest is the usual culprit, not the package.Validator::make(['v' => $value], ['v' => 'cnpj'])->errors() in Tinker isolates the rule from your FormRequest, middleware, and prepareForValidation mutations (which run before validation and are a common source of "it works in Tinker but not in the request").12.ABC... and 12.abc... as different documents.^3.12 explicitly if you intend to accept the alphanumeric format in production, since lower versions will reject it.How can I help you explore Laravel packages today?