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 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
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.3-blue.svg)](https://www.typescriptlang.org/)
4
+ [![Coverage](https://img.shields.io/badge/coverage-99%25+-green.svg)](https://github.com/chrisJSeng/validador-cpf-cnpj)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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
+ }
@@ -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
+ }
@@ -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; } });
@@ -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 = {}));
@@ -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
+ }