Skip to content

Commit 40df2ed

Browse files
authored
Merge pull request #7 from Sysvale/feature/cpf-validator
Feature/cpf validator
2 parents 0517e33 + f637ac1 commit 40df2ed

7 files changed

Lines changed: 185 additions & 3 deletions

File tree

docs/utils/cpfValidator.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# CpfValidator
2+
3+
Utilitário para validar CPFs com e sem máscara.
4+
5+
## Instalação e Importação
6+
7+
```typescript
8+
import { cpfValidator } from '@sysvale/foundry';
9+
```
10+
11+
## Função
12+
13+
### `cpfValidator()`
14+
15+
Valida CPFs com e sem máscara, indicando se os mesmos são válidos.
16+
17+
#### Sintaxes
18+
19+
```typescript
20+
cpfValidator(value: string): boolean
21+
```
22+
23+
#### Parâmetros
24+
25+
**Assinatura 1:**
26+
27+
- **`value`** (`string`): CPF (com ou sem máscara) a ser validado
28+
29+
<br />
30+
31+
#### Retorno
32+
33+
`boolean` - Resultado da validação, `true` para CPF válido e `false` para inválido
34+
35+
<br />
36+
37+
#### Exemplos
38+
39+
**Usando CPF com máscara:**
40+
41+
```typescript
42+
cpfValidator('252.512.510-09'); // → true
43+
44+
cpfValidator('000.000.000-00'); // → false
45+
```
46+
47+
<br />
48+
49+
**Usando CPF sem máscara:**
50+
51+
```typescript
52+
cpfValidator('25251251009'); // → true
53+
54+
cpfValidator('00000000000'); // → false
55+
```
56+
57+
<br />
58+
59+
#### Tratamento de Erros
60+
61+
A função lança um erro quando os parâmetros obrigatórios não são fornecidos:
62+
63+
```typescript
64+
// ❌ Erro: tipagem do parâmetro é inválida
65+
cpfValidator(71234567823);
66+
// → Error: O tipo do parâmetro passado é inválido.
67+
68+
// ✅ Correto
69+
cpfValidator('71234567823'); // → false
70+
```
71+
72+
## Notas
73+
74+
- A função é **type-safe**

docs/utils/index.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,9 @@ Função para formatar listas de strings com vírgulas e conjunção "e".
1717
Função para sanitizar dados de formulário e aplicar transformações antes de enviá-los ao backend.
1818

1919
- [Documentação](./sanitizeForm.md)
20+
21+
### cpfValidator()
22+
23+
Função para validar CPFs com e sem máscara.
24+
25+
- [Documentação](./cpfValidator.md)

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@sysvale/foundry",
3-
"version": "1.5.1",
3+
"version": "1.6.0",
44
"description": "A forge for composables, helpers, and front-end utilities.",
55
"type": "module",
66
"main": "./dist/foundry.cjs.js",

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export * from './utils/pluralize';
22
export * from './utils/commaline';
33
export * from './utils/sanitizeForm';
4+
export * from './utils/cpfValidator';
45
export { maskCpf, removeCpfMask } from './formatters/cpf';
56
export { maskCns, removeCnsMask } from './formatters/cns';
67
export { maskPhone, removePhoneMask } from './formatters/phone';

src/utils/cpfValidator.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
function calcChecker1(firstNineDigits: string) {
2+
let sum = 0;
3+
4+
for (let j = 0; j < 9; ++j) {
5+
sum += Number(firstNineDigits.charAt(j)) * (10 - j);
6+
}
7+
8+
const lastSumChecker1 = sum % 11;
9+
const checker1 = lastSumChecker1 < 2 ? 0 : 11 - lastSumChecker1;
10+
11+
return checker1;
12+
}
13+
14+
function calcChecker2(cpfWithChecker1: string) {
15+
let sum = 0;
16+
17+
for (let k = 0; k < 10; ++k) {
18+
sum += Number(cpfWithChecker1.charAt(k)) * (11 - k);
19+
}
20+
const lastSumChecker2 = sum % 11;
21+
const checker2 = lastSumChecker2 < 2 ? 0 : 11 - lastSumChecker2;
22+
23+
return checker2;
24+
}
25+
26+
function cleaner(value: string) {
27+
return value.replace(/[^\d]/g, '');
28+
}
29+
30+
/**
31+
* Valida CPFs com e sem máscara.
32+
*
33+
* @param { string } value
34+
* @returns { boolean }
35+
*/
36+
export function cpfValidator(value: string): boolean {
37+
if (typeof value !== 'string') {
38+
throw new Error('O tipo do parâmetro passado é inválido.');
39+
}
40+
41+
if (!value) {
42+
return true;
43+
}
44+
45+
const cleanCPF = cleaner(value);
46+
const firstNineDigits = cleanCPF.substring(0, 9);
47+
const checker = cleanCPF.substring(9, 11);
48+
let result = false;
49+
50+
for (let i = 0; i < 10; i++) {
51+
if (firstNineDigits + checker === Array(12).join(i.toString())) {
52+
return false;
53+
}
54+
}
55+
56+
const checker1 = calcChecker1(firstNineDigits);
57+
const checker2 = calcChecker2(`${firstNineDigits}${checker1}`);
58+
59+
if (checker.toString() === checker1.toString() + checker2.toString()) {
60+
result = true;
61+
} else {
62+
result = false;
63+
}
64+
return result;
65+
}

tests/cpfValidator.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { describe, expect, test } from 'vitest';
2+
import { cpfValidator } from '../src/utils/cpfValidator';
3+
4+
describe('cpfValidator()', () => {
5+
test('retorna true quando string vazia é passada', () => {
6+
expect(cpfValidator('')).toBe(true);
7+
});
8+
9+
test('retorna false quando cpf inválido com máscara é passado', () => {
10+
expect(cpfValidator('111.111.111-11')).toBe(false);
11+
});
12+
13+
test('retorna true quando cpf válido com máscara é passado', () => {
14+
expect(cpfValidator('252.512.510-09')).toBe(true);
15+
});
16+
17+
test('retorna false quando cpf inválido sem máscara é passado', () => {
18+
expect(cpfValidator('11111111111')).toBe(false);
19+
});
20+
21+
test('retorna true quando cpf válido sem máscara é passado', () => {
22+
expect(cpfValidator('25251251009')).toBe(true);
23+
});
24+
25+
test('retorna false quando cpf possui menos que 11 dígitos', () => {
26+
expect(cpfValidator('2525125100')).toBe(false);
27+
});
28+
29+
test('retorna false quando cpf possui uma letra', () => {
30+
expect(cpfValidator('25251251a09')).toBe(false);
31+
});
32+
33+
test('lança erro quando parâmetro é do tipo number', () => {
34+
expect(() => cpfValidator(12341789324)).toThrowError();
35+
});
36+
});

0 commit comments

Comments
 (0)