Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions docs/utils/cpfValidator.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# CpfValidator

Utilitário para validar CPFs com e sem máscara.

## Instalação e Importação

```typescript
import { cpfValidator } from '@sysvale/foundry';
```

## Função

### `cpfValidator()`

Valida CPFs com e sem máscara, indicando se os mesmos são válidos.

#### Sintaxes

```typescript
cpfValidator(value: string): boolean
```

#### Parâmetros

**Assinatura 1:**

- **`value`** (`string`): CPF (com ou sem máscara) a ser validado

<br />

#### Retorno

`boolean` - Resultado da validação, `true` para CPF válido e `false` para inválido

<br />

#### Exemplos

**Usando CPF com máscara:**

```typescript
cpfValidator('252.512.510-09'); // → true

cpfValidator('000.000.000-00'); // → false
```

<br />

**Usando CPF sem máscara:**

```typescript
cpfValidator('25251251009'); // → true

cpfValidator('00000000000'); // → false
```

<br />

#### Tratamento de Erros

A função lança um erro quando os parâmetros obrigatórios não são fornecidos:

```typescript
// ❌ Erro: tipagem do parâmetro é inválida
cpfValidator(71234567823);
// → Error: O tipo do parâmetro passado é inválido.

// ✅ Correto
cpfValidator('71234567823'); // → false
```

## Notas

- A função é **type-safe**
6 changes: 6 additions & 0 deletions docs/utils/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,9 @@ Função para formatar listas de strings com vírgulas e conjunção "e".
Função para sanitizar dados de formulário e aplicar transformações antes de enviá-los ao backend.

- [Documentação](./sanitizeForm.md)

### cpfValidator()

Função para validar CPFs com e sem máscara.

- [Documentação](./cpfValidator.md)
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@sysvale/foundry",
"version": "1.5.1",
"version": "1.6.0",
"description": "A forge for composables, helpers, and front-end utilities.",
"type": "module",
"main": "./dist/foundry.cjs.js",
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export * from './utils/pluralize';
export * from './utils/commaline';
export * from './utils/sanitizeForm';
export * from './utils/cpfValidator';
export { maskCpf, removeCpfMask } from './formatters/cpf';
export { maskCns, removeCnsMask } from './formatters/cns';
export { maskPhone, removePhoneMask } from './formatters/phone';
Expand Down
65 changes: 65 additions & 0 deletions src/utils/cpfValidator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
function calcChecker1(firstNineDigits: string) {
let sum = 0;

for (let j = 0; j < 9; ++j) {
sum += Number(firstNineDigits.charAt(j)) * (10 - j);
}

const lastSumChecker1 = sum % 11;
const checker1 = lastSumChecker1 < 2 ? 0 : 11 - lastSumChecker1;

return checker1;
}

function calcChecker2(cpfWithChecker1: string) {
let sum = 0;

for (let k = 0; k < 10; ++k) {
sum += Number(cpfWithChecker1.charAt(k)) * (11 - k);
}
const lastSumChecker2 = sum % 11;
const checker2 = lastSumChecker2 < 2 ? 0 : 11 - lastSumChecker2;

return checker2;
}

function cleaner(value: string) {
return value.replace(/[^\d]/g, '');
}

/**
* Valida CPFs com e sem máscara.
*
* @param { string } value
* @returns { boolean }
*/
export function cpfValidator(value: string): boolean {
if (typeof value !== 'string') {
throw new Error('O tipo do parâmetro passado é inválido.');
}

if (!value) {
return true;
}

const cleanCPF = cleaner(value);
const firstNineDigits = cleanCPF.substring(0, 9);
const checker = cleanCPF.substring(9, 11);
let result = false;

for (let i = 0; i < 10; i++) {
if (firstNineDigits + checker === Array(12).join(i.toString())) {
return false;
}
}

const checker1 = calcChecker1(firstNineDigits);
const checker2 = calcChecker2(`${firstNineDigits}${checker1}`);

if (checker.toString() === checker1.toString() + checker2.toString()) {
result = true;
} else {
result = false;
}
return result;
}
36 changes: 36 additions & 0 deletions tests/cpfValidator.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { describe, expect, test } from 'vitest';
import { cpfValidator } from '../src/utils/cpfValidator';

describe('cpfValidator()', () => {
test('retorna true quando string vazia é passada', () => {
expect(cpfValidator('')).toBe(true);
});

test('retorna false quando cpf inválido com máscara é passado', () => {
expect(cpfValidator('111.111.111-11')).toBe(false);
});

test('retorna true quando cpf válido com máscara é passado', () => {
expect(cpfValidator('252.512.510-09')).toBe(true);
});

test('retorna false quando cpf inválido sem máscara é passado', () => {
expect(cpfValidator('11111111111')).toBe(false);
});

test('retorna true quando cpf válido sem máscara é passado', () => {
expect(cpfValidator('25251251009')).toBe(true);
});

test('retorna false quando cpf possui menos que 11 dígitos', () => {
expect(cpfValidator('2525125100')).toBe(false);
});

test('retorna false quando cpf possui uma letra', () => {
expect(cpfValidator('25251251a09')).toBe(false);
});

test('lança erro quando parâmetro é do tipo number', () => {
expect(() => cpfValidator(12341789324)).toThrowError();
});
});