validador-cnpj-cpf 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +267 -0
- package/dist/cnpj-validator.d.ts +14 -0
- package/dist/cnpj-validator.js +81 -0
- package/dist/constants.d.ts +70 -0
- package/dist/constants.js +95 -0
- package/dist/cpf-validator.d.ts +14 -0
- package/dist/cpf-validator.js +90 -0
- package/dist/guards.d.ts +6 -0
- package/dist/guards.js +51 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +35 -0
- package/dist/types.d.ts +21 -0
- package/dist/types.js +8 -0
- package/dist/utils.d.ts +11 -0
- package/dist/utils.js +46 -0
- package/package.json +59 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 chrisJSeng
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
# Validador CPF/CNPJ 🇧🇷
|
|
2
|
+
|
|
3
|
+
[](https://www.typescriptlang.org/)
|
|
4
|
+
[](https://github.com/chrisJSeng/validador-cpf-cnpj)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
|
|
7
|
+
A high-performance, secure, and modular TypeScript library for validating Brazilian documents (CPF and CNPJ).
|
|
8
|
+
|
|
9
|
+
## 🚀 Features
|
|
10
|
+
|
|
11
|
+
- ✅ **TypeScript First**: Full type safety and IntelliSense support
|
|
12
|
+
- ✅ **High Performance**: Uses efficient data structures (Set, Object.freeze)
|
|
13
|
+
- ✅ **Security Focused**: Comprehensive input validation with guard rails
|
|
14
|
+
- ✅ **99%+ Test Coverage**: Thoroughly tested with Jest
|
|
15
|
+
- ✅ **SOLID Principles**: Clean, maintainable, and extensible architecture
|
|
16
|
+
- ✅ **Modern JavaScript**: ES2022 target
|
|
17
|
+
- ✅ **Zero Dependencies**: No external runtime dependencies
|
|
18
|
+
- ✅ **Modular Design**: Import only what you need
|
|
19
|
+
- ✅ **Clear Rules**: CPF is digits-only; CNPJ supports alphanumeric (`0-9`/`A-Z`)
|
|
20
|
+
|
|
21
|
+
## 📦 Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install validador-cnpj-cpf
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## 🔧 Usage
|
|
28
|
+
|
|
29
|
+
> Notes
|
|
30
|
+
>
|
|
31
|
+
> - All public APIs accept **strings only**.
|
|
32
|
+
> - CPF is **digits-only** (11 digits after cleaning/format stripping).
|
|
33
|
+
> - CNPJ supports **alphanumeric** characters (`0-9` and `A-Z`) and must match the structure `^[0-9A-Z]{12}\d{2}$` after cleaning (last two characters are numeric check digits).
|
|
34
|
+
|
|
35
|
+
### About the `{ validate: true }` flag
|
|
36
|
+
|
|
37
|
+
`formatCPF`, `maskCPF`, and `formatCNPJ` are **best-effort by default**:
|
|
38
|
+
|
|
39
|
+
- They try to clean/format what you pass in.
|
|
40
|
+
- If the cleaned value has the wrong length/shape to be formatted, they return `null`.
|
|
41
|
+
|
|
42
|
+
When you pass `{ validate: true }`, they become **strict**:
|
|
43
|
+
|
|
44
|
+
- They first run the full validator (`validateCPF`/`validateCNPJ`).
|
|
45
|
+
- If the document is invalid, they return `null`.
|
|
46
|
+
|
|
47
|
+
Use strict mode when you want to **avoid formatting/masking invalid documents** (e.g., in UI output, logs, or API responses).
|
|
48
|
+
|
|
49
|
+
### Basic CPF Validation
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import { validateCPF, formatCPF, cleanCPF, maskCPF } from 'validador-cnpj-cpf';
|
|
53
|
+
|
|
54
|
+
// Validate CPF
|
|
55
|
+
const result = validateCPF('111.444.777-35');
|
|
56
|
+
if (result.isValid) {
|
|
57
|
+
console.log('Valid CPF!');
|
|
58
|
+
} else {
|
|
59
|
+
console.log('Invalid CPF:', result.error);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Format CPF
|
|
63
|
+
const formatted = formatCPF('11144477735');
|
|
64
|
+
console.log(formatted); // "111.444.777-35"
|
|
65
|
+
|
|
66
|
+
// Format CPF only if valid
|
|
67
|
+
const formattedStrict = formatCPF('12345678901', { validate: true });
|
|
68
|
+
console.log(formattedStrict); // null
|
|
69
|
+
|
|
70
|
+
// Mask CPF (hide middle digits)
|
|
71
|
+
const masked = maskCPF('11144477735');
|
|
72
|
+
console.log(masked); // "111.***.***-35"
|
|
73
|
+
|
|
74
|
+
// Mask CPF only if valid
|
|
75
|
+
const maskedStrict = maskCPF('12345678901', { validate: true });
|
|
76
|
+
console.log(maskedStrict); // null
|
|
77
|
+
|
|
78
|
+
// Clean CPF (remove formatting)
|
|
79
|
+
const cleaned = cleanCPF('111.444.777-35');
|
|
80
|
+
console.log(cleaned); // "11144477735"
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Basic CNPJ Validation
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
import { validateCNPJ, formatCNPJ, cleanCNPJ } from 'validador-cnpj-cpf';
|
|
89
|
+
|
|
90
|
+
// Validate CNPJ
|
|
91
|
+
const result = validateCNPJ('11.222.333/0001-81');
|
|
92
|
+
if (result.isValid) {
|
|
93
|
+
console.log('Valid CNPJ!');
|
|
94
|
+
} else {
|
|
95
|
+
console.log('Invalid CNPJ:', result.error);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Format CNPJ
|
|
99
|
+
const formatted = formatCNPJ('11222333000181');
|
|
100
|
+
console.log(formatted); // "11.222.333/0001-81"
|
|
101
|
+
|
|
102
|
+
// Format CNPJ only if valid
|
|
103
|
+
const formattedStrict = formatCNPJ('11222333000182', { validate: true });
|
|
104
|
+
console.log(formattedStrict); // null
|
|
105
|
+
|
|
106
|
+
// Clean CNPJ (remove formatting)
|
|
107
|
+
const cleaned = cleanCNPJ('11.222.333/0001-81');
|
|
108
|
+
console.log(cleaned); // "11222333000181"
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Advanced Usage with Classes
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
import { CPFValidator, CNPJValidator } from 'validador-cnpj-cpf';
|
|
117
|
+
|
|
118
|
+
// Using CPF validator class
|
|
119
|
+
const cpfValidator = new CPFValidator();
|
|
120
|
+
const cpfResult = cpfValidator.validate('111.444.777-35');
|
|
121
|
+
|
|
122
|
+
// Using CNPJ validator class
|
|
123
|
+
const cnpjValidator = new CNPJValidator();
|
|
124
|
+
const cnpjResult = cnpjValidator.validate('11.222.333/0001-81');
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Custom Validation with Guards
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
import {
|
|
131
|
+
guardIsString,
|
|
132
|
+
guardNotEmpty,
|
|
133
|
+
guardValidCharacters,
|
|
134
|
+
guardLength,
|
|
135
|
+
chainGuards,
|
|
136
|
+
stripDocumentFormatting,
|
|
137
|
+
} from 'validador-cnpj-cpf';
|
|
138
|
+
|
|
139
|
+
// Create custom validation pipeline
|
|
140
|
+
const input = '12345678901';
|
|
141
|
+
const stripped = stripDocumentFormatting(input);
|
|
142
|
+
const guards = chainGuards(
|
|
143
|
+
guardIsString(input),
|
|
144
|
+
guardNotEmpty(input),
|
|
145
|
+
guardValidCharacters(stripped, /^\d+$/),
|
|
146
|
+
guardLength(stripped, 11, 'Must be 11 digits'),
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
if (!guards.isValid) {
|
|
150
|
+
console.error('Validation failed:', guards.error);
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## 🏗️ Architecture
|
|
155
|
+
|
|
156
|
+
This library follows best practices and design principles:
|
|
157
|
+
|
|
158
|
+
### SOLID Principles
|
|
159
|
+
|
|
160
|
+
- **Single Responsibility**: Each validator handles one document type
|
|
161
|
+
- **Open/Closed**: Extensible via interfaces without modifying existing code
|
|
162
|
+
- **Liskov Substitution**: Validators implement common interfaces
|
|
163
|
+
- **Interface Segregation**: Minimal, focused interfaces
|
|
164
|
+
- **Dependency Inversion**: Depends on abstractions, not concretions
|
|
165
|
+
|
|
166
|
+
### DRY, KISS, YAGNI
|
|
167
|
+
|
|
168
|
+
- **DRY (Don't Repeat Yourself)**: Shared utilities and constants
|
|
169
|
+
- **KISS (Keep It Simple, Stupid)**: Clear, straightforward implementations
|
|
170
|
+
- **YAGNI (You Aren't Gonna Need It)**: Only implements necessary features
|
|
171
|
+
|
|
172
|
+
### Performance Optimizations
|
|
173
|
+
|
|
174
|
+
- Uses `Set` for O(1) invalid pattern lookups
|
|
175
|
+
- Pre-calculates multipliers for check digit validation
|
|
176
|
+
- Uses `Object.freeze()` for immutable constants
|
|
177
|
+
- Efficient array operations with modern JavaScript
|
|
178
|
+
|
|
179
|
+
## 🛡️ Security
|
|
180
|
+
|
|
181
|
+
- Comprehensive input validation with guard rails
|
|
182
|
+
- Type-safe TypeScript implementation
|
|
183
|
+
- No eval() or unsafe operations
|
|
184
|
+
- Sanitizes all user inputs
|
|
185
|
+
- Prevents common attack vectors
|
|
186
|
+
|
|
187
|
+
## 📊 API Reference
|
|
188
|
+
|
|
189
|
+
### Validation Result
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
interface ValidationResult {
|
|
193
|
+
isValid: boolean;
|
|
194
|
+
error?: string;
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### CPF Functions
|
|
199
|
+
|
|
200
|
+
- `validateCPF(input: string): ValidationResult` - Validates a CPF
|
|
201
|
+
- `formatCPF(input: string, options?: { validate?: boolean }): string | null` - Formats a CPF (best-effort by default; strict with `{ validate: true }`)
|
|
202
|
+
- `maskCPF(input: string, options?: { validate?: boolean }): string | null` - Masks a CPF as `XXX.***.***-YY` (best-effort by default; strict with `{ validate: true }`)
|
|
203
|
+
- `cleanCPF(input: string): string` - Removes formatting from CPF
|
|
204
|
+
|
|
205
|
+
### CNPJ Functions
|
|
206
|
+
|
|
207
|
+
- `validateCNPJ(input: string): ValidationResult` - Validates a CNPJ
|
|
208
|
+
- `formatCNPJ(input: string, options?: { validate?: boolean }): string | null` - Formats a CNPJ (best-effort by default; strict with `{ validate: true }`)
|
|
209
|
+
- `cleanCNPJ(input: string): string` - Removes formatting from CNPJ
|
|
210
|
+
|
|
211
|
+
### Utils
|
|
212
|
+
|
|
213
|
+
- `stripDocumentFormatting(input: string): string` - Removes `.`, `-`, `/` and whitespace
|
|
214
|
+
|
|
215
|
+
### Classes
|
|
216
|
+
|
|
217
|
+
- `CPFValidator` - Class-based CPF validator implementing `IDocumentValidator`
|
|
218
|
+
- `CNPJValidator` - Class-based CNPJ validator implementing `IDocumentValidator`
|
|
219
|
+
|
|
220
|
+
### Guards
|
|
221
|
+
|
|
222
|
+
- `guardIsString(input: unknown): GuardResult`
|
|
223
|
+
- `guardNotEmpty(input: string): GuardResult`
|
|
224
|
+
- `guardValidCharacters(input: string, regex: RegExp): GuardResult`
|
|
225
|
+
- `guardLength(input: string, length: number, error: string): GuardResult`
|
|
226
|
+
- `chainGuards(...guards: GuardResult[]): GuardResult`
|
|
227
|
+
|
|
228
|
+
## 🧪 Testing
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
# Run tests (includes coverage)
|
|
232
|
+
npm test
|
|
233
|
+
|
|
234
|
+
# Watch mode
|
|
235
|
+
npm run test:watch
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## 🔨 Development
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
# Install dependencies
|
|
242
|
+
npm install
|
|
243
|
+
|
|
244
|
+
# Build
|
|
245
|
+
npm run build
|
|
246
|
+
|
|
247
|
+
# Lint
|
|
248
|
+
npm run lint
|
|
249
|
+
|
|
250
|
+
# Format
|
|
251
|
+
npm run format
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## 📝 License
|
|
255
|
+
|
|
256
|
+
MIT © [chrisJSeng]
|
|
257
|
+
|
|
258
|
+
## 🤝 Contributing
|
|
259
|
+
|
|
260
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
261
|
+
|
|
262
|
+
## 📚 References
|
|
263
|
+
|
|
264
|
+
- Receita Federal (gov.br) — Meu CPF: https://www.gov.br/receitafederal/pt-br/assuntos/meu-cpf
|
|
265
|
+
- gov.br — Consultar Cadastro de Pessoa Física (CPF) na Receita Federal: https://www.gov.br/pt-br/servicos/consultar-cadastro-de-pessoas-fisicas
|
|
266
|
+
- Receita Federal (gov.br) — CNPJ (Cadastro Nacional de Pessoas Jurídicas): https://www.gov.br/receitafederal/pt-br/assuntos/orientacao-tributaria/cadastros/cnpj
|
|
267
|
+
- Receita Federal — IN RFB nº 2.119/2022 (Cadastro Nacional da Pessoa Jurídica – CNPJ): https://normasinternet2.receita.fazenda.gov.br/#/consulta/externa/127567
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { FormatOptions, IDocumentValidator, ValidationResult } from './types';
|
|
2
|
+
export declare class CNPJValidator implements IDocumentValidator {
|
|
3
|
+
private readonly firstDigitMultipliers;
|
|
4
|
+
private readonly secondDigitMultipliers;
|
|
5
|
+
constructor();
|
|
6
|
+
clean(input: string): string;
|
|
7
|
+
format(input: string): string | null;
|
|
8
|
+
validate(input: string): ValidationResult;
|
|
9
|
+
private validateCleanedInput;
|
|
10
|
+
private validateCheckDigits;
|
|
11
|
+
}
|
|
12
|
+
export declare function validateCNPJ(input: string): ValidationResult;
|
|
13
|
+
export declare function formatCNPJ(input: string, options?: FormatOptions): string | null;
|
|
14
|
+
export declare function cleanCNPJ(input: string): string;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CNPJValidator = void 0;
|
|
4
|
+
exports.validateCNPJ = validateCNPJ;
|
|
5
|
+
exports.formatCNPJ = formatCNPJ;
|
|
6
|
+
exports.cleanCNPJ = cleanCNPJ;
|
|
7
|
+
const constants_1 = require("./constants");
|
|
8
|
+
const guards_1 = require("./guards");
|
|
9
|
+
const utils_1 = require("./utils");
|
|
10
|
+
class CNPJValidator {
|
|
11
|
+
firstDigitMultipliers;
|
|
12
|
+
secondDigitMultipliers;
|
|
13
|
+
constructor() {
|
|
14
|
+
this.firstDigitMultipliers = constants_1.CNPJ_FIRST_MULTIPLIERS;
|
|
15
|
+
this.secondDigitMultipliers = constants_1.CNPJ_SECOND_MULTIPLIERS;
|
|
16
|
+
}
|
|
17
|
+
clean(input) {
|
|
18
|
+
return (0, utils_1.removeNonAlphanumeric)((0, utils_1.stripDocumentFormatting)(input)).toUpperCase();
|
|
19
|
+
}
|
|
20
|
+
format(input) {
|
|
21
|
+
const cleaned = this.clean(input);
|
|
22
|
+
if (cleaned.length !== constants_1.CNPJ_LENGTH)
|
|
23
|
+
return null;
|
|
24
|
+
const part1 = cleaned.slice(0, 2);
|
|
25
|
+
const part2 = cleaned.slice(2, 5);
|
|
26
|
+
const part3 = cleaned.slice(5, 8);
|
|
27
|
+
const part4 = cleaned.slice(8, 12);
|
|
28
|
+
const part5 = cleaned.slice(12, 14);
|
|
29
|
+
return `${part1}.${part2}.${part3}/${part4}-${part5}`;
|
|
30
|
+
}
|
|
31
|
+
validate(input) {
|
|
32
|
+
const stringGuard = (0, guards_1.guardIsString)(input);
|
|
33
|
+
const notEmptyGuard = stringGuard.isValid
|
|
34
|
+
? (0, guards_1.guardNotEmpty)(stringGuard.cleanedInput)
|
|
35
|
+
: stringGuard;
|
|
36
|
+
const baseGuard = (0, guards_1.chainGuards)(stringGuard, notEmptyGuard);
|
|
37
|
+
return baseGuard.isValid
|
|
38
|
+
? this.validateCleanedInput(baseGuard.cleanedInput)
|
|
39
|
+
: (0, utils_1.invalidResult)(baseGuard.error);
|
|
40
|
+
}
|
|
41
|
+
validateCleanedInput(input) {
|
|
42
|
+
const cleaned = this.clean(input);
|
|
43
|
+
const charGuard = (0, guards_1.guardValidCharacters)(cleaned, constants_1.CNPJ_ALLOWED_CHARS_REGEX);
|
|
44
|
+
const lengthGuard = (0, guards_1.guardLength)(cleaned, constants_1.CNPJ_LENGTH, constants_1.ERROR_MESSAGES.INVALID_CNPJ_LENGTH);
|
|
45
|
+
const structureGuard = constants_1.CNPJ_ALPHANUMERIC_REGEX.test(cleaned)
|
|
46
|
+
? { isValid: true, cleanedInput: cleaned }
|
|
47
|
+
: { isValid: false, error: constants_1.ERROR_MESSAGES.INVALID_CHARACTERS };
|
|
48
|
+
const patternGuard = constants_1.CNPJ_DIGIT_REGEX.test(cleaned) && constants_1.INVALID_CNPJ_PATTERNS.has(cleaned)
|
|
49
|
+
? { isValid: false, error: constants_1.ERROR_MESSAGES.INVALID_CNPJ_PATTERN }
|
|
50
|
+
: { isValid: true, cleanedInput: cleaned };
|
|
51
|
+
const finalGuard = (0, guards_1.chainGuards)(charGuard, lengthGuard, structureGuard, patternGuard);
|
|
52
|
+
return finalGuard.isValid ? this.validateCheckDigits(cleaned) : (0, utils_1.invalidResult)(finalGuard.error);
|
|
53
|
+
}
|
|
54
|
+
validateCheckDigits(cnpj) {
|
|
55
|
+
const values = (0, utils_1.stringToBase36ValueArray)(cnpj);
|
|
56
|
+
const firstProvided = Number(cnpj[constants_1.CNPJ_FIRST_DIGIT_POSITION]);
|
|
57
|
+
const secondProvided = Number(cnpj[constants_1.CNPJ_SECOND_DIGIT_POSITION]);
|
|
58
|
+
const firstDigit = (0, utils_1.calculateCheckDigit)(values.slice(0, constants_1.CNPJ_FIRST_DIGIT_POSITION), this.firstDigitMultipliers);
|
|
59
|
+
if (firstDigit !== firstProvided)
|
|
60
|
+
return (0, utils_1.invalidResult)(constants_1.ERROR_MESSAGES.INVALID_CNPJ_DIGITS);
|
|
61
|
+
const secondDigit = (0, utils_1.calculateCheckDigit)([...values.slice(0, constants_1.CNPJ_FIRST_DIGIT_POSITION), firstDigit], this.secondDigitMultipliers);
|
|
62
|
+
if (secondDigit !== secondProvided)
|
|
63
|
+
return (0, utils_1.invalidResult)(constants_1.ERROR_MESSAGES.INVALID_CNPJ_DIGITS);
|
|
64
|
+
return (0, utils_1.validResult)();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
exports.CNPJValidator = CNPJValidator;
|
|
68
|
+
const cnpjValidatorInstance = new CNPJValidator();
|
|
69
|
+
function validateCNPJ(input) {
|
|
70
|
+
return cnpjValidatorInstance.validate(input);
|
|
71
|
+
}
|
|
72
|
+
function formatCNPJ(input, options) {
|
|
73
|
+
const shouldValidate = options?.validate === true;
|
|
74
|
+
const isInvalidWhenStrict = shouldValidate && !cnpjValidatorInstance.validate(input).isValid;
|
|
75
|
+
if (isInvalidWhenStrict)
|
|
76
|
+
return null;
|
|
77
|
+
return cnpjValidatorInstance.format(input);
|
|
78
|
+
}
|
|
79
|
+
function cleanCNPJ(input) {
|
|
80
|
+
return cnpjValidatorInstance.clean(input);
|
|
81
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
export declare const CPF_LENGTH = 11;
|
|
2
|
+
export declare const CPF_FORMATTED_LENGTH = 14;
|
|
3
|
+
export declare const CPF_FIRST_DIGIT_POSITION = 9;
|
|
4
|
+
export declare const CPF_SECOND_DIGIT_POSITION = 10;
|
|
5
|
+
export declare const CPF_FIRST_DIGIT_MULTIPLIER_START = 10;
|
|
6
|
+
export declare const CPF_SECOND_DIGIT_MULTIPLIER_START = 11;
|
|
7
|
+
export declare const CPF_FORMAT_REGEX: RegExp;
|
|
8
|
+
export declare const CPF_DIGIT_REGEX: RegExp;
|
|
9
|
+
export declare const CPF_ALLOWED_CHARS_REGEX: RegExp;
|
|
10
|
+
export declare const CPF_ALPHANUMERIC_REGEX: RegExp;
|
|
11
|
+
export declare const CPF_FIRST_MULTIPLIERS: readonly number[];
|
|
12
|
+
export declare const CPF_SECOND_MULTIPLIERS: readonly number[];
|
|
13
|
+
export declare const CNPJ_LENGTH = 14;
|
|
14
|
+
export declare const CNPJ_FORMATTED_LENGTH = 18;
|
|
15
|
+
export declare const CNPJ_FIRST_DIGIT_POSITION = 12;
|
|
16
|
+
export declare const CNPJ_SECOND_DIGIT_POSITION = 13;
|
|
17
|
+
export declare const CNPJ_FORMAT_REGEX: RegExp;
|
|
18
|
+
export declare const CNPJ_DIGIT_REGEX: RegExp;
|
|
19
|
+
export declare const CNPJ_ALLOWED_CHARS_REGEX: RegExp;
|
|
20
|
+
export declare const CNPJ_ALPHANUMERIC_REGEX: RegExp;
|
|
21
|
+
export declare const CNPJ_FIRST_MULTIPLIERS: readonly number[];
|
|
22
|
+
export declare const CNPJ_SECOND_MULTIPLIERS: readonly number[];
|
|
23
|
+
export declare const MODULO_DIVISOR = 11;
|
|
24
|
+
export declare const MIN_REMAINDER_FOR_ZERO = 2;
|
|
25
|
+
export declare const DIGIT_ZERO = 0;
|
|
26
|
+
export declare const DIGITS_ONLY_REGEX: RegExp;
|
|
27
|
+
export declare const NON_DIGIT_REGEX: RegExp;
|
|
28
|
+
export declare const DOCUMENT_FORMATTING_REGEX: RegExp;
|
|
29
|
+
export declare const NON_ALPHANUMERIC_REGEX: RegExp;
|
|
30
|
+
export declare const CPF_RULES: Readonly<{
|
|
31
|
+
LENGTH: 11;
|
|
32
|
+
FIRST_DIGIT_POSITION: 9;
|
|
33
|
+
SECOND_DIGIT_POSITION: 10;
|
|
34
|
+
FIRST_MULTIPLIERS: readonly number[];
|
|
35
|
+
SECOND_MULTIPLIERS: readonly number[];
|
|
36
|
+
ALLOWED_CHARS_REGEX: RegExp;
|
|
37
|
+
STRUCTURE_REGEX: RegExp;
|
|
38
|
+
NUMERIC_ONLY_REGEX: RegExp;
|
|
39
|
+
}>;
|
|
40
|
+
export declare const CNPJ_RULES: Readonly<{
|
|
41
|
+
LENGTH: 14;
|
|
42
|
+
FIRST_DIGIT_POSITION: 12;
|
|
43
|
+
SECOND_DIGIT_POSITION: 13;
|
|
44
|
+
FIRST_MULTIPLIERS: readonly number[];
|
|
45
|
+
SECOND_MULTIPLIERS: readonly number[];
|
|
46
|
+
ALLOWED_CHARS_REGEX: RegExp;
|
|
47
|
+
STRUCTURE_REGEX: RegExp;
|
|
48
|
+
NUMERIC_ONLY_REGEX: RegExp;
|
|
49
|
+
}>;
|
|
50
|
+
export declare const CHECK_DIGIT_RULES: Readonly<{
|
|
51
|
+
MODULO_DIVISOR: 11;
|
|
52
|
+
MIN_REMAINDER_FOR_ZERO: 2;
|
|
53
|
+
DIGIT_ZERO: 0;
|
|
54
|
+
}>;
|
|
55
|
+
export declare const INVALID_CPF_PATTERNS: Readonly<Set<string>>;
|
|
56
|
+
export declare const INVALID_CNPJ_PATTERNS: Readonly<Set<string>>;
|
|
57
|
+
export declare const ERROR_MESSAGES: Readonly<{
|
|
58
|
+
INVALID_TYPE: "Input must be a string";
|
|
59
|
+
EMPTY_INPUT: "Input cannot be empty";
|
|
60
|
+
INVALID_CPF_LENGTH: "CPF must have exactly 11 characters";
|
|
61
|
+
INVALID_CNPJ_LENGTH: "CNPJ must have exactly 14 characters";
|
|
62
|
+
INVALID_CPF_PATTERN: "CPF contains invalid pattern";
|
|
63
|
+
INVALID_CNPJ_PATTERN: "CNPJ contains invalid pattern";
|
|
64
|
+
INVALID_CPF_DIGITS: "CPF verification digits are invalid";
|
|
65
|
+
INVALID_CNPJ_DIGITS: "CNPJ verification digits are invalid";
|
|
66
|
+
INVALID_CHARACTERS: "Input contains invalid characters";
|
|
67
|
+
}>;
|
|
68
|
+
export declare const INTERNAL_MESSAGES: Readonly<{
|
|
69
|
+
CHAIN_GUARDS_REQUIRES_AT_LEAST_ONE: "chainGuards requires at least one guard";
|
|
70
|
+
}>;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.INTERNAL_MESSAGES = exports.ERROR_MESSAGES = exports.INVALID_CNPJ_PATTERNS = exports.INVALID_CPF_PATTERNS = exports.CHECK_DIGIT_RULES = exports.CNPJ_RULES = exports.CPF_RULES = exports.NON_ALPHANUMERIC_REGEX = exports.DOCUMENT_FORMATTING_REGEX = exports.NON_DIGIT_REGEX = exports.DIGITS_ONLY_REGEX = exports.DIGIT_ZERO = exports.MIN_REMAINDER_FOR_ZERO = exports.MODULO_DIVISOR = exports.CNPJ_SECOND_MULTIPLIERS = exports.CNPJ_FIRST_MULTIPLIERS = exports.CNPJ_ALPHANUMERIC_REGEX = exports.CNPJ_ALLOWED_CHARS_REGEX = exports.CNPJ_DIGIT_REGEX = exports.CNPJ_FORMAT_REGEX = exports.CNPJ_SECOND_DIGIT_POSITION = exports.CNPJ_FIRST_DIGIT_POSITION = exports.CNPJ_FORMATTED_LENGTH = exports.CNPJ_LENGTH = exports.CPF_SECOND_MULTIPLIERS = exports.CPF_FIRST_MULTIPLIERS = exports.CPF_ALPHANUMERIC_REGEX = exports.CPF_ALLOWED_CHARS_REGEX = exports.CPF_DIGIT_REGEX = exports.CPF_FORMAT_REGEX = exports.CPF_SECOND_DIGIT_MULTIPLIER_START = exports.CPF_FIRST_DIGIT_MULTIPLIER_START = exports.CPF_SECOND_DIGIT_POSITION = exports.CPF_FIRST_DIGIT_POSITION = exports.CPF_FORMATTED_LENGTH = exports.CPF_LENGTH = void 0;
|
|
4
|
+
exports.CPF_LENGTH = 11;
|
|
5
|
+
exports.CPF_FORMATTED_LENGTH = 14;
|
|
6
|
+
exports.CPF_FIRST_DIGIT_POSITION = 9;
|
|
7
|
+
exports.CPF_SECOND_DIGIT_POSITION = 10;
|
|
8
|
+
exports.CPF_FIRST_DIGIT_MULTIPLIER_START = 10;
|
|
9
|
+
exports.CPF_SECOND_DIGIT_MULTIPLIER_START = 11;
|
|
10
|
+
exports.CPF_FORMAT_REGEX = /^(\d{3})\.(\d{3})\.(\d{3})-(\d{2})$/;
|
|
11
|
+
exports.CPF_DIGIT_REGEX = /^\d+$/;
|
|
12
|
+
exports.CPF_ALLOWED_CHARS_REGEX = /^\d+$/;
|
|
13
|
+
exports.CPF_ALPHANUMERIC_REGEX = /^\d{11}$/;
|
|
14
|
+
exports.CPF_FIRST_MULTIPLIERS = Object.freeze([10, 9, 8, 7, 6, 5, 4, 3, 2]);
|
|
15
|
+
exports.CPF_SECOND_MULTIPLIERS = Object.freeze([11, 10, 9, 8, 7, 6, 5, 4, 3, 2]);
|
|
16
|
+
exports.CNPJ_LENGTH = 14;
|
|
17
|
+
exports.CNPJ_FORMATTED_LENGTH = 18;
|
|
18
|
+
exports.CNPJ_FIRST_DIGIT_POSITION = 12;
|
|
19
|
+
exports.CNPJ_SECOND_DIGIT_POSITION = 13;
|
|
20
|
+
exports.CNPJ_FORMAT_REGEX = /^(\d{2})\.(\d{3})\.(\d{3})\/(\d{4})-(\d{2})$/;
|
|
21
|
+
exports.CNPJ_DIGIT_REGEX = /^\d+$/;
|
|
22
|
+
exports.CNPJ_ALLOWED_CHARS_REGEX = /^[0-9A-Z]+$/;
|
|
23
|
+
exports.CNPJ_ALPHANUMERIC_REGEX = /^[0-9A-Z]{12}\d{2}$/;
|
|
24
|
+
exports.CNPJ_FIRST_MULTIPLIERS = Object.freeze([5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]);
|
|
25
|
+
exports.CNPJ_SECOND_MULTIPLIERS = Object.freeze([6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]);
|
|
26
|
+
exports.MODULO_DIVISOR = 11;
|
|
27
|
+
exports.MIN_REMAINDER_FOR_ZERO = 2;
|
|
28
|
+
exports.DIGIT_ZERO = 0;
|
|
29
|
+
exports.DIGITS_ONLY_REGEX = /^\d+$/;
|
|
30
|
+
exports.NON_DIGIT_REGEX = /\D/g;
|
|
31
|
+
exports.DOCUMENT_FORMATTING_REGEX = /[.\-/\s]/g;
|
|
32
|
+
exports.NON_ALPHANUMERIC_REGEX = /[^0-9A-Za-z]/g;
|
|
33
|
+
exports.CPF_RULES = Object.freeze({
|
|
34
|
+
LENGTH: exports.CPF_LENGTH,
|
|
35
|
+
FIRST_DIGIT_POSITION: exports.CPF_FIRST_DIGIT_POSITION,
|
|
36
|
+
SECOND_DIGIT_POSITION: exports.CPF_SECOND_DIGIT_POSITION,
|
|
37
|
+
FIRST_MULTIPLIERS: exports.CPF_FIRST_MULTIPLIERS,
|
|
38
|
+
SECOND_MULTIPLIERS: exports.CPF_SECOND_MULTIPLIERS,
|
|
39
|
+
ALLOWED_CHARS_REGEX: exports.CPF_ALLOWED_CHARS_REGEX,
|
|
40
|
+
STRUCTURE_REGEX: exports.CPF_ALPHANUMERIC_REGEX,
|
|
41
|
+
NUMERIC_ONLY_REGEX: exports.CPF_DIGIT_REGEX,
|
|
42
|
+
});
|
|
43
|
+
exports.CNPJ_RULES = Object.freeze({
|
|
44
|
+
LENGTH: exports.CNPJ_LENGTH,
|
|
45
|
+
FIRST_DIGIT_POSITION: exports.CNPJ_FIRST_DIGIT_POSITION,
|
|
46
|
+
SECOND_DIGIT_POSITION: exports.CNPJ_SECOND_DIGIT_POSITION,
|
|
47
|
+
FIRST_MULTIPLIERS: exports.CNPJ_FIRST_MULTIPLIERS,
|
|
48
|
+
SECOND_MULTIPLIERS: exports.CNPJ_SECOND_MULTIPLIERS,
|
|
49
|
+
ALLOWED_CHARS_REGEX: exports.CNPJ_ALLOWED_CHARS_REGEX,
|
|
50
|
+
STRUCTURE_REGEX: exports.CNPJ_ALPHANUMERIC_REGEX,
|
|
51
|
+
NUMERIC_ONLY_REGEX: exports.CNPJ_DIGIT_REGEX,
|
|
52
|
+
});
|
|
53
|
+
exports.CHECK_DIGIT_RULES = Object.freeze({
|
|
54
|
+
MODULO_DIVISOR: exports.MODULO_DIVISOR,
|
|
55
|
+
MIN_REMAINDER_FOR_ZERO: exports.MIN_REMAINDER_FOR_ZERO,
|
|
56
|
+
DIGIT_ZERO: exports.DIGIT_ZERO,
|
|
57
|
+
});
|
|
58
|
+
exports.INVALID_CPF_PATTERNS = Object.freeze(new Set([
|
|
59
|
+
'00000000000',
|
|
60
|
+
'11111111111',
|
|
61
|
+
'22222222222',
|
|
62
|
+
'33333333333',
|
|
63
|
+
'44444444444',
|
|
64
|
+
'55555555555',
|
|
65
|
+
'66666666666',
|
|
66
|
+
'77777777777',
|
|
67
|
+
'88888888888',
|
|
68
|
+
'99999999999',
|
|
69
|
+
]));
|
|
70
|
+
exports.INVALID_CNPJ_PATTERNS = Object.freeze(new Set([
|
|
71
|
+
'00000000000000',
|
|
72
|
+
'11111111111111',
|
|
73
|
+
'22222222222222',
|
|
74
|
+
'33333333333333',
|
|
75
|
+
'44444444444444',
|
|
76
|
+
'55555555555555',
|
|
77
|
+
'66666666666666',
|
|
78
|
+
'77777777777777',
|
|
79
|
+
'88888888888888',
|
|
80
|
+
'99999999999999',
|
|
81
|
+
]));
|
|
82
|
+
exports.ERROR_MESSAGES = Object.freeze({
|
|
83
|
+
INVALID_TYPE: 'Input must be a string',
|
|
84
|
+
EMPTY_INPUT: 'Input cannot be empty',
|
|
85
|
+
INVALID_CPF_LENGTH: 'CPF must have exactly 11 characters',
|
|
86
|
+
INVALID_CNPJ_LENGTH: 'CNPJ must have exactly 14 characters',
|
|
87
|
+
INVALID_CPF_PATTERN: 'CPF contains invalid pattern',
|
|
88
|
+
INVALID_CNPJ_PATTERN: 'CNPJ contains invalid pattern',
|
|
89
|
+
INVALID_CPF_DIGITS: 'CPF verification digits are invalid',
|
|
90
|
+
INVALID_CNPJ_DIGITS: 'CNPJ verification digits are invalid',
|
|
91
|
+
INVALID_CHARACTERS: 'Input contains invalid characters',
|
|
92
|
+
});
|
|
93
|
+
exports.INTERNAL_MESSAGES = Object.freeze({
|
|
94
|
+
CHAIN_GUARDS_REQUIRES_AT_LEAST_ONE: 'chainGuards requires at least one guard',
|
|
95
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { FormatOptions, IDocumentValidator, ValidationResult } from './types';
|
|
2
|
+
export declare class CPFValidator implements IDocumentValidator {
|
|
3
|
+
private readonly firstDigitMultipliers;
|
|
4
|
+
private readonly secondDigitMultipliers;
|
|
5
|
+
constructor();
|
|
6
|
+
clean(input: string): string;
|
|
7
|
+
format(input: string): string | null;
|
|
8
|
+
validate(input: string): ValidationResult;
|
|
9
|
+
private validateCheckDigits;
|
|
10
|
+
}
|
|
11
|
+
export declare function validateCPF(input: string): ValidationResult;
|
|
12
|
+
export declare function formatCPF(input: string, options?: FormatOptions): string | null;
|
|
13
|
+
export declare function cleanCPF(input: string): string;
|
|
14
|
+
export declare function maskCPF(input: string, options?: FormatOptions): string | null;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CPFValidator = void 0;
|
|
4
|
+
exports.validateCPF = validateCPF;
|
|
5
|
+
exports.formatCPF = formatCPF;
|
|
6
|
+
exports.cleanCPF = cleanCPF;
|
|
7
|
+
exports.maskCPF = maskCPF;
|
|
8
|
+
const constants_1 = require("./constants");
|
|
9
|
+
const guards_1 = require("./guards");
|
|
10
|
+
const utils_1 = require("./utils");
|
|
11
|
+
class CPFValidator {
|
|
12
|
+
firstDigitMultipliers;
|
|
13
|
+
secondDigitMultipliers;
|
|
14
|
+
constructor() {
|
|
15
|
+
this.firstDigitMultipliers = constants_1.CPF_FIRST_MULTIPLIERS;
|
|
16
|
+
this.secondDigitMultipliers = constants_1.CPF_SECOND_MULTIPLIERS;
|
|
17
|
+
}
|
|
18
|
+
clean(input) {
|
|
19
|
+
return (0, utils_1.removeNonDigits)((0, utils_1.stripDocumentFormatting)(input));
|
|
20
|
+
}
|
|
21
|
+
format(input) {
|
|
22
|
+
const cleaned = this.clean(input);
|
|
23
|
+
if (cleaned.length !== constants_1.CPF_LENGTH)
|
|
24
|
+
return null;
|
|
25
|
+
const part1 = cleaned.slice(0, 3);
|
|
26
|
+
const part2 = cleaned.slice(3, 6);
|
|
27
|
+
const part3 = cleaned.slice(6, 9);
|
|
28
|
+
const part4 = cleaned.slice(9, 11);
|
|
29
|
+
return `${part1}.${part2}.${part3}-${part4}`;
|
|
30
|
+
}
|
|
31
|
+
validate(input) {
|
|
32
|
+
const stringGuard = (0, guards_1.guardIsString)(input);
|
|
33
|
+
const notEmptyGuard = stringGuard.isValid
|
|
34
|
+
? (0, guards_1.guardNotEmpty)(stringGuard.cleanedInput)
|
|
35
|
+
: stringGuard;
|
|
36
|
+
const baseGuard = (0, guards_1.chainGuards)(stringGuard, notEmptyGuard);
|
|
37
|
+
if (!baseGuard.isValid)
|
|
38
|
+
return (0, utils_1.invalidResult)(baseGuard.error);
|
|
39
|
+
const cleaned = this.clean(baseGuard.cleanedInput);
|
|
40
|
+
const charGuard = (0, guards_1.guardValidCharacters)(cleaned, constants_1.CPF_ALLOWED_CHARS_REGEX);
|
|
41
|
+
const lengthGuard = (0, guards_1.guardLength)(cleaned, constants_1.CPF_LENGTH, constants_1.ERROR_MESSAGES.INVALID_CPF_LENGTH);
|
|
42
|
+
const structureGuard = constants_1.CPF_ALPHANUMERIC_REGEX.test(cleaned)
|
|
43
|
+
? { isValid: true, cleanedInput: cleaned }
|
|
44
|
+
: { isValid: false, error: constants_1.ERROR_MESSAGES.INVALID_CHARACTERS };
|
|
45
|
+
const patternGuard = constants_1.CPF_DIGIT_REGEX.test(cleaned) && constants_1.INVALID_CPF_PATTERNS.has(cleaned)
|
|
46
|
+
? { isValid: false, error: constants_1.ERROR_MESSAGES.INVALID_CPF_PATTERN }
|
|
47
|
+
: { isValid: true, cleanedInput: cleaned };
|
|
48
|
+
const finalGuard = (0, guards_1.chainGuards)(charGuard, lengthGuard, structureGuard, patternGuard);
|
|
49
|
+
return finalGuard.isValid ? this.validateCheckDigits(cleaned) : (0, utils_1.invalidResult)(finalGuard.error);
|
|
50
|
+
}
|
|
51
|
+
validateCheckDigits(cpf) {
|
|
52
|
+
const values = (0, utils_1.stringToDigitArray)(cpf);
|
|
53
|
+
const firstProvided = Number(cpf[constants_1.CPF_FIRST_DIGIT_POSITION]);
|
|
54
|
+
const secondProvided = Number(cpf[constants_1.CPF_SECOND_DIGIT_POSITION]);
|
|
55
|
+
const firstDigit = (0, utils_1.calculateCheckDigit)(values.slice(0, constants_1.CPF_FIRST_DIGIT_POSITION), this.firstDigitMultipliers);
|
|
56
|
+
if (firstDigit !== firstProvided)
|
|
57
|
+
return (0, utils_1.invalidResult)(constants_1.ERROR_MESSAGES.INVALID_CPF_DIGITS);
|
|
58
|
+
const secondDigit = (0, utils_1.calculateCheckDigit)([...values.slice(0, constants_1.CPF_FIRST_DIGIT_POSITION), firstDigit], this.secondDigitMultipliers);
|
|
59
|
+
if (secondDigit !== secondProvided)
|
|
60
|
+
return (0, utils_1.invalidResult)(constants_1.ERROR_MESSAGES.INVALID_CPF_DIGITS);
|
|
61
|
+
return (0, utils_1.validResult)();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.CPFValidator = CPFValidator;
|
|
65
|
+
const cpfValidatorInstance = new CPFValidator();
|
|
66
|
+
function validateCPF(input) {
|
|
67
|
+
return cpfValidatorInstance.validate(input);
|
|
68
|
+
}
|
|
69
|
+
function formatCPF(input, options) {
|
|
70
|
+
const shouldValidate = options?.validate === true;
|
|
71
|
+
const isInvalidWhenStrict = shouldValidate && !cpfValidatorInstance.validate(input).isValid;
|
|
72
|
+
if (isInvalidWhenStrict)
|
|
73
|
+
return null;
|
|
74
|
+
return cpfValidatorInstance.format(input);
|
|
75
|
+
}
|
|
76
|
+
function cleanCPF(input) {
|
|
77
|
+
return cpfValidatorInstance.clean(input);
|
|
78
|
+
}
|
|
79
|
+
function maskCPF(input, options) {
|
|
80
|
+
const shouldValidate = options?.validate === true;
|
|
81
|
+
const isInvalidWhenStrict = shouldValidate && !cpfValidatorInstance.validate(input).isValid;
|
|
82
|
+
if (isInvalidWhenStrict)
|
|
83
|
+
return null;
|
|
84
|
+
const cleaned = cpfValidatorInstance.clean(input);
|
|
85
|
+
if (cleaned.length !== constants_1.CPF_LENGTH)
|
|
86
|
+
return null;
|
|
87
|
+
const prefix = cleaned.slice(0, 3);
|
|
88
|
+
const suffix = cleaned.slice(9, 11);
|
|
89
|
+
return `${prefix}.***.***-${suffix}`;
|
|
90
|
+
}
|
package/dist/guards.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { GuardResult } from './types';
|
|
2
|
+
export declare function guardIsString(input: unknown): GuardResult;
|
|
3
|
+
export declare function guardNotEmpty(input: string): GuardResult;
|
|
4
|
+
export declare function guardValidCharacters(input: string, allowedChars: RegExp): GuardResult;
|
|
5
|
+
export declare function guardLength(input: string, expectedLength: number, errorMessage: string): GuardResult;
|
|
6
|
+
export declare function chainGuards(...guards: GuardResult[]): GuardResult;
|
package/dist/guards.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.guardIsString = guardIsString;
|
|
4
|
+
exports.guardNotEmpty = guardNotEmpty;
|
|
5
|
+
exports.guardValidCharacters = guardValidCharacters;
|
|
6
|
+
exports.guardLength = guardLength;
|
|
7
|
+
exports.chainGuards = chainGuards;
|
|
8
|
+
const constants_1 = require("./constants");
|
|
9
|
+
function guardValid(cleanedInput) {
|
|
10
|
+
return {
|
|
11
|
+
isValid: true,
|
|
12
|
+
cleanedInput,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function guardInvalid(error) {
|
|
16
|
+
return {
|
|
17
|
+
isValid: false,
|
|
18
|
+
error,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function guardIsString(input) {
|
|
22
|
+
if (typeof input !== 'string')
|
|
23
|
+
return guardInvalid(constants_1.ERROR_MESSAGES.INVALID_TYPE);
|
|
24
|
+
return guardValid(input);
|
|
25
|
+
}
|
|
26
|
+
function guardNotEmpty(input) {
|
|
27
|
+
const trimmedInput = input.trim();
|
|
28
|
+
if (trimmedInput.length === 0)
|
|
29
|
+
return guardInvalid(constants_1.ERROR_MESSAGES.EMPTY_INPUT);
|
|
30
|
+
return guardValid(trimmedInput);
|
|
31
|
+
}
|
|
32
|
+
function guardValidCharacters(input, allowedChars) {
|
|
33
|
+
if (!allowedChars.test(input))
|
|
34
|
+
return guardInvalid(constants_1.ERROR_MESSAGES.INVALID_CHARACTERS);
|
|
35
|
+
return guardValid(input);
|
|
36
|
+
}
|
|
37
|
+
function guardLength(input, expectedLength, errorMessage) {
|
|
38
|
+
if (input.length !== expectedLength)
|
|
39
|
+
return guardInvalid(errorMessage);
|
|
40
|
+
return guardValid(input);
|
|
41
|
+
}
|
|
42
|
+
function chainGuards(...guards) {
|
|
43
|
+
if (guards.length === 0)
|
|
44
|
+
throw new Error(constants_1.INTERNAL_MESSAGES.CHAIN_GUARDS_REQUIRES_AT_LEAST_ONE);
|
|
45
|
+
for (const guard of guards) {
|
|
46
|
+
if (!guard.isValid) {
|
|
47
|
+
return guard;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return guards.at(-1);
|
|
51
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { CPFValidator, validateCPF, formatCPF, cleanCPF, maskCPF } from './cpf-validator';
|
|
2
|
+
export { CNPJValidator, validateCNPJ, formatCNPJ, cleanCNPJ } from './cnpj-validator';
|
|
3
|
+
export { ValidationResult, DocumentType, IDocumentValidator } from './types';
|
|
4
|
+
export { CPF_LENGTH, CPF_FORMATTED_LENGTH, CNPJ_LENGTH, CNPJ_FORMATTED_LENGTH, CPF_ALPHANUMERIC_REGEX, ERROR_MESSAGES, CPF_RULES, CNPJ_RULES, CHECK_DIGIT_RULES, } from './constants';
|
|
5
|
+
export { guardIsString, guardNotEmpty, guardValidCharacters, guardLength, chainGuards, } from './guards';
|
|
6
|
+
export { stripDocumentFormatting, removeNonDigits, } from './utils';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.removeNonDigits = exports.stripDocumentFormatting = exports.chainGuards = exports.guardLength = exports.guardValidCharacters = exports.guardNotEmpty = exports.guardIsString = exports.CHECK_DIGIT_RULES = exports.CNPJ_RULES = exports.CPF_RULES = exports.ERROR_MESSAGES = exports.CPF_ALPHANUMERIC_REGEX = exports.CNPJ_FORMATTED_LENGTH = exports.CNPJ_LENGTH = exports.CPF_FORMATTED_LENGTH = exports.CPF_LENGTH = exports.DocumentType = exports.cleanCNPJ = exports.formatCNPJ = exports.validateCNPJ = exports.CNPJValidator = exports.maskCPF = exports.cleanCPF = exports.formatCPF = exports.validateCPF = exports.CPFValidator = void 0;
|
|
4
|
+
var cpf_validator_1 = require("./cpf-validator");
|
|
5
|
+
Object.defineProperty(exports, "CPFValidator", { enumerable: true, get: function () { return cpf_validator_1.CPFValidator; } });
|
|
6
|
+
Object.defineProperty(exports, "validateCPF", { enumerable: true, get: function () { return cpf_validator_1.validateCPF; } });
|
|
7
|
+
Object.defineProperty(exports, "formatCPF", { enumerable: true, get: function () { return cpf_validator_1.formatCPF; } });
|
|
8
|
+
Object.defineProperty(exports, "cleanCPF", { enumerable: true, get: function () { return cpf_validator_1.cleanCPF; } });
|
|
9
|
+
Object.defineProperty(exports, "maskCPF", { enumerable: true, get: function () { return cpf_validator_1.maskCPF; } });
|
|
10
|
+
var cnpj_validator_1 = require("./cnpj-validator");
|
|
11
|
+
Object.defineProperty(exports, "CNPJValidator", { enumerable: true, get: function () { return cnpj_validator_1.CNPJValidator; } });
|
|
12
|
+
Object.defineProperty(exports, "validateCNPJ", { enumerable: true, get: function () { return cnpj_validator_1.validateCNPJ; } });
|
|
13
|
+
Object.defineProperty(exports, "formatCNPJ", { enumerable: true, get: function () { return cnpj_validator_1.formatCNPJ; } });
|
|
14
|
+
Object.defineProperty(exports, "cleanCNPJ", { enumerable: true, get: function () { return cnpj_validator_1.cleanCNPJ; } });
|
|
15
|
+
var types_1 = require("./types");
|
|
16
|
+
Object.defineProperty(exports, "DocumentType", { enumerable: true, get: function () { return types_1.DocumentType; } });
|
|
17
|
+
var constants_1 = require("./constants");
|
|
18
|
+
Object.defineProperty(exports, "CPF_LENGTH", { enumerable: true, get: function () { return constants_1.CPF_LENGTH; } });
|
|
19
|
+
Object.defineProperty(exports, "CPF_FORMATTED_LENGTH", { enumerable: true, get: function () { return constants_1.CPF_FORMATTED_LENGTH; } });
|
|
20
|
+
Object.defineProperty(exports, "CNPJ_LENGTH", { enumerable: true, get: function () { return constants_1.CNPJ_LENGTH; } });
|
|
21
|
+
Object.defineProperty(exports, "CNPJ_FORMATTED_LENGTH", { enumerable: true, get: function () { return constants_1.CNPJ_FORMATTED_LENGTH; } });
|
|
22
|
+
Object.defineProperty(exports, "CPF_ALPHANUMERIC_REGEX", { enumerable: true, get: function () { return constants_1.CPF_ALPHANUMERIC_REGEX; } });
|
|
23
|
+
Object.defineProperty(exports, "ERROR_MESSAGES", { enumerable: true, get: function () { return constants_1.ERROR_MESSAGES; } });
|
|
24
|
+
Object.defineProperty(exports, "CPF_RULES", { enumerable: true, get: function () { return constants_1.CPF_RULES; } });
|
|
25
|
+
Object.defineProperty(exports, "CNPJ_RULES", { enumerable: true, get: function () { return constants_1.CNPJ_RULES; } });
|
|
26
|
+
Object.defineProperty(exports, "CHECK_DIGIT_RULES", { enumerable: true, get: function () { return constants_1.CHECK_DIGIT_RULES; } });
|
|
27
|
+
var guards_1 = require("./guards");
|
|
28
|
+
Object.defineProperty(exports, "guardIsString", { enumerable: true, get: function () { return guards_1.guardIsString; } });
|
|
29
|
+
Object.defineProperty(exports, "guardNotEmpty", { enumerable: true, get: function () { return guards_1.guardNotEmpty; } });
|
|
30
|
+
Object.defineProperty(exports, "guardValidCharacters", { enumerable: true, get: function () { return guards_1.guardValidCharacters; } });
|
|
31
|
+
Object.defineProperty(exports, "guardLength", { enumerable: true, get: function () { return guards_1.guardLength; } });
|
|
32
|
+
Object.defineProperty(exports, "chainGuards", { enumerable: true, get: function () { return guards_1.chainGuards; } });
|
|
33
|
+
var utils_1 = require("./utils");
|
|
34
|
+
Object.defineProperty(exports, "stripDocumentFormatting", { enumerable: true, get: function () { return utils_1.stripDocumentFormatting; } });
|
|
35
|
+
Object.defineProperty(exports, "removeNonDigits", { enumerable: true, get: function () { return utils_1.removeNonDigits; } });
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface ValidationResult {
|
|
2
|
+
isValid: boolean;
|
|
3
|
+
error?: string;
|
|
4
|
+
}
|
|
5
|
+
export declare enum DocumentType {
|
|
6
|
+
CPF = "CPF",
|
|
7
|
+
CNPJ = "CNPJ"
|
|
8
|
+
}
|
|
9
|
+
export interface IDocumentValidator {
|
|
10
|
+
validate(input: string): ValidationResult;
|
|
11
|
+
format(input: string): string | null;
|
|
12
|
+
clean(input: string): string;
|
|
13
|
+
}
|
|
14
|
+
export interface GuardResult {
|
|
15
|
+
isValid: boolean;
|
|
16
|
+
error?: string;
|
|
17
|
+
cleanedInput?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface FormatOptions {
|
|
20
|
+
validate?: boolean;
|
|
21
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DocumentType = void 0;
|
|
4
|
+
var DocumentType;
|
|
5
|
+
(function (DocumentType) {
|
|
6
|
+
DocumentType["CPF"] = "CPF";
|
|
7
|
+
DocumentType["CNPJ"] = "CNPJ";
|
|
8
|
+
})(DocumentType || (exports.DocumentType = DocumentType = {}));
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ValidationResult } from './types';
|
|
2
|
+
export declare function calculateCheckDigit(digits: ReadonlyArray<number>, multipliers: ReadonlyArray<number>): number;
|
|
3
|
+
export declare function stringToDigitArray(input: string): ReadonlyArray<number>;
|
|
4
|
+
export declare function removeNonDigits(input: string): string;
|
|
5
|
+
export declare function areAllDigitsSame(input: string): boolean;
|
|
6
|
+
export declare function stripDocumentFormatting(input: string): string;
|
|
7
|
+
export declare function removeNonAlphanumeric(input: string): string;
|
|
8
|
+
export declare function charToBase36Value(char: string): number;
|
|
9
|
+
export declare function stringToBase36ValueArray(input: string): ReadonlyArray<number>;
|
|
10
|
+
export declare function validResult(): ValidationResult;
|
|
11
|
+
export declare function invalidResult(error?: string): ValidationResult;
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.calculateCheckDigit = calculateCheckDigit;
|
|
4
|
+
exports.stringToDigitArray = stringToDigitArray;
|
|
5
|
+
exports.removeNonDigits = removeNonDigits;
|
|
6
|
+
exports.areAllDigitsSame = areAllDigitsSame;
|
|
7
|
+
exports.stripDocumentFormatting = stripDocumentFormatting;
|
|
8
|
+
exports.removeNonAlphanumeric = removeNonAlphanumeric;
|
|
9
|
+
exports.charToBase36Value = charToBase36Value;
|
|
10
|
+
exports.stringToBase36ValueArray = stringToBase36ValueArray;
|
|
11
|
+
exports.validResult = validResult;
|
|
12
|
+
exports.invalidResult = invalidResult;
|
|
13
|
+
const constants_1 = require("./constants");
|
|
14
|
+
function calculateCheckDigit(digits, multipliers) {
|
|
15
|
+
const sum = digits.reduce((acc, digit, index) => acc + digit * multipliers[index], constants_1.DIGIT_ZERO);
|
|
16
|
+
const remainder = sum % constants_1.MODULO_DIVISOR;
|
|
17
|
+
return remainder < constants_1.MIN_REMAINDER_FOR_ZERO ? constants_1.DIGIT_ZERO : constants_1.MODULO_DIVISOR - remainder;
|
|
18
|
+
}
|
|
19
|
+
function stringToDigitArray(input) {
|
|
20
|
+
return Array.from(input, Number);
|
|
21
|
+
}
|
|
22
|
+
function removeNonDigits(input) {
|
|
23
|
+
return input.replaceAll(constants_1.NON_DIGIT_REGEX, '');
|
|
24
|
+
}
|
|
25
|
+
function areAllDigitsSame(input) {
|
|
26
|
+
const firstChar = input[0];
|
|
27
|
+
return input.split('').every((char) => char === firstChar);
|
|
28
|
+
}
|
|
29
|
+
function stripDocumentFormatting(input) {
|
|
30
|
+
return input.replaceAll(constants_1.DOCUMENT_FORMATTING_REGEX, '');
|
|
31
|
+
}
|
|
32
|
+
function removeNonAlphanumeric(input) {
|
|
33
|
+
return input.replaceAll(constants_1.NON_ALPHANUMERIC_REGEX, '');
|
|
34
|
+
}
|
|
35
|
+
function charToBase36Value(char) {
|
|
36
|
+
return Number.parseInt(char, 36);
|
|
37
|
+
}
|
|
38
|
+
function stringToBase36ValueArray(input) {
|
|
39
|
+
return Array.from(input, (char) => charToBase36Value(char.toUpperCase()));
|
|
40
|
+
}
|
|
41
|
+
function validResult() {
|
|
42
|
+
return { isValid: true };
|
|
43
|
+
}
|
|
44
|
+
function invalidResult(error) {
|
|
45
|
+
return { isValid: false, error };
|
|
46
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "validador-cnpj-cpf",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Performant and secure Brazilian document validator (CPF/CNPJ)",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"require": "./dist/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"sideEffects": false,
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "node -e \"require('fs').rmSync('dist', { recursive: true, force: true })\" && tsc",
|
|
16
|
+
"test": "jest --coverage",
|
|
17
|
+
"test:watch": "jest --watch",
|
|
18
|
+
"lint": "eslint 'src/**/*.ts'",
|
|
19
|
+
"lint:fix": "eslint 'src/**/*.ts' --fix",
|
|
20
|
+
"format": "prettier --write 'src/**/*.ts'",
|
|
21
|
+
"prepublishOnly": "npm run build"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"cpf",
|
|
25
|
+
"cnpj",
|
|
26
|
+
"validator",
|
|
27
|
+
"brazil",
|
|
28
|
+
"document",
|
|
29
|
+
"validation",
|
|
30
|
+
"typescript"
|
|
31
|
+
],
|
|
32
|
+
"author": "Christopher Pinto - @chrisJSeng",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "git+https://github.com/chrisJSeng/validador-cpf-cnpj.git"
|
|
37
|
+
},
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/chrisJSeng/validador-cpf-cnpj/issues"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://github.com/chrisJSeng/validador-cpf-cnpj#readme",
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=18"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@types/jest": "^29.5.11",
|
|
47
|
+
"@types/node": "^20.10.6",
|
|
48
|
+
"@typescript-eslint/eslint-plugin": "^6.17.0",
|
|
49
|
+
"@typescript-eslint/parser": "^6.17.0",
|
|
50
|
+
"eslint": "^8.56.0",
|
|
51
|
+
"jest": "^29.7.0",
|
|
52
|
+
"prettier": "^3.1.1",
|
|
53
|
+
"ts-jest": "^29.1.1",
|
|
54
|
+
"typescript": "^5.3.3"
|
|
55
|
+
},
|
|
56
|
+
"files": [
|
|
57
|
+
"dist"
|
|
58
|
+
]
|
|
59
|
+
}
|