jcinfo-utils 1.0.54 → 1.0.56

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/.env CHANGED
@@ -1,4 +1,4 @@
1
1
  # apenas para testar a função updateDotEnv() & updateDotEnvKey()
2
2
  # REACT_APP_VERSION=1.0 (1116.1)
3
- VITE_VERSION=1.0 (115.8)
3
+ VITE_VERSION=1.0 (404.3)
4
4
  VITE_VDATE=
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jcinfo-utils",
3
- "version": "1.0.54",
3
+ "version": "1.0.56",
4
4
  "description": "Pacote de funções utilitárias",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -0,0 +1,184 @@
1
+ 'use strict'
2
+
3
+ /**
4
+ * CNPJ — validação, cálculo de DV, geração e máscara.
5
+ * Suporta o novo formato alfanumérico (Receita Federal 2026).
6
+ *
7
+ * Equivalente JS da classe Delphi TCNPJ.
8
+ */
9
+
10
+ const PESOS_DV = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
11
+ const TAMANHO_CNPJ_SEM_DV = 12
12
+ const TAMANHO_CNPJ_COMPLETO = 14
13
+ const CNPJ_ZERADO = '00000000000000'
14
+ const CARACTERES_PERMITIDOS = 'ABCDEGHJKLMNPRSTUVWXYZ0123456789'
15
+ const CARACTERES_MASCARA = new Set(['.', '/', ' ', '-'])
16
+
17
+ // Regex derivado de CARACTERES_PERMITIDOS
18
+ const REGEX_CARACTERE_PERMITIDO = /^[ABCDEGHJKLMNPRSTUVWXYZ0-9]$/
19
+
20
+ // ─── helpers internos ────────────────────────────────────────────────────────
21
+
22
+ function isCaracterePermitido(c) {
23
+ c = c.toUpperCase()
24
+ return /[A-Z0-9]/.test(c) || CARACTERES_MASCARA.has(c)
25
+ }
26
+
27
+ function isAlfaNumerico(c) {
28
+ return /^[A-Z0-9]$/.test(c.toUpperCase())
29
+ }
30
+
31
+ function isDigito(c) {
32
+ return /^[0-9]$/.test(c)
33
+ }
34
+
35
+ function isCNPJSemDVValido(str) {
36
+ return /^[A-Z0-9]{12}$/.test(str)
37
+ }
38
+
39
+ function removeCaracteresMascara(str) {
40
+ return str.replace(/[./ -]/g, '')
41
+ }
42
+
43
+ function temCaracteresNaoPermitidos(str) {
44
+ return /[^ABCDEGHJKLMNPRSTUVWXYZ0-9]/.test(str)
45
+ }
46
+
47
+ // function isCNPJSemDVValido(str) {
48
+ // if (str.length !== TAMANHO_CNPJ_SEM_DV) return false
49
+ // return [...str].every((c) => isAlfaNumerico(c))
50
+ // }
51
+
52
+ // function removeCaracteresMascara(str) {
53
+ // return [...str].filter((c) => !CARACTERES_MASCARA.has(c)).join('')
54
+ // }
55
+
56
+ // function temCaracteresNaoPermitidos(str) {
57
+ // return [...str].some((c) => !isCaracterePermitido(c))
58
+ // }
59
+
60
+ function isCNPJComDVValido(str) {
61
+ if (str.length !== TAMANHO_CNPJ_COMPLETO) return false
62
+ for (let i = 0; i < TAMANHO_CNPJ_SEM_DV; i++) {
63
+ if (!isAlfaNumerico(str[i])) return false
64
+ }
65
+ for (let i = TAMANHO_CNPJ_SEM_DV; i < TAMANHO_CNPJ_COMPLETO; i++) {
66
+ if (!isDigito(str[i])) return false
67
+ }
68
+ return true
69
+ }
70
+
71
+ // ─── API pública ─────────────────────────────────────────────────────────────
72
+
73
+ const CNPJ = {
74
+ /**
75
+ * Remove os caracteres de máscara ( . / - espaço ) do CNPJ.
76
+ * @param {string} cnpj
77
+ * @returns {string}
78
+ */
79
+ removeMascara(cnpj) {
80
+ return removeCaracteresMascara(cnpj)
81
+ },
82
+
83
+ /**
84
+ * Aplica a máscara XX.XXX.XXX/XXXX-XX ao CNPJ de 14 caracteres.
85
+ * @param {string} cnpj
86
+ * @returns {string}
87
+ */
88
+ aplicarMascara(cnpj) {
89
+ const s = this.removeMascara(cnpj)
90
+ if (s.length !== TAMANHO_CNPJ_COMPLETO) {
91
+ throw new Error('CNPJ deve ter 14 caracteres para aplicar máscara')
92
+ }
93
+ return `${s.slice(0, 2)}.${s.slice(2, 5)}.${s.slice(5, 8)}/${s.slice(8, 12)}-${s.slice(12, 14)}`
94
+ },
95
+
96
+ /**
97
+ * Calcula os dois dígitos verificadores de um CNPJ base (12 caracteres).
98
+ * Lança erro se o CNPJ base for inválido.
99
+ * @param {string} cnpj CNPJ sem DV (12 chars, com ou sem máscara)
100
+ * @returns {string} String com os dois dígitos ("00"–"99")
101
+ */
102
+ calcularDV(cnpj) {
103
+ const ERROR_INVALID =
104
+ 'Não é possível calcular o DV pois o CNPJ fornecido é inválido'
105
+
106
+ if (temCaracteresNaoPermitidos(cnpj)) throw new Error(ERROR_INVALID)
107
+
108
+ const base = removeCaracteresMascara(cnpj).toUpperCase()
109
+
110
+ if (!isCNPJSemDVValido(base)) throw new Error(ERROR_INVALID)
111
+ if (base === CNPJ_ZERADO.slice(0, TAMANHO_CNPJ_SEM_DV))
112
+ throw new Error(ERROR_INVALID)
113
+
114
+ // Conversão idêntica ao Delphi: Ord(C) - Ord('0')
115
+ // Letras resultam em valores > 9 (ex.: 'A' → 17), exatamente como previsto na norma.
116
+ const valores = [...base].map((c) => c.charCodeAt(0) - '0'.charCodeAt(0))
117
+
118
+ let somaDV1 = 0
119
+ let somaDV2 = 0
120
+
121
+ for (let i = 0; i < TAMANHO_CNPJ_SEM_DV; i++) {
122
+ somaDV1 += valores[i] * PESOS_DV[i + 1]
123
+ somaDV2 += valores[i] * PESOS_DV[i]
124
+ }
125
+
126
+ const dv1 = somaDV1 % 11 < 2 ? 0 : 11 - (somaDV1 % 11)
127
+
128
+ somaDV2 += dv1 * PESOS_DV[TAMANHO_CNPJ_SEM_DV]
129
+
130
+ const dv2 = somaDV2 % 11 < 2 ? 0 : 11 - (somaDV2 % 11)
131
+
132
+ return `${dv1}${dv2}`
133
+ },
134
+
135
+ /**
136
+ * Valida um CNPJ (com ou sem máscara, numérico ou alfanumérico).
137
+ * @param {string} cnpj
138
+ * @returns {boolean}
139
+ */
140
+ isValid(cnpj) {
141
+ if (temCaracteresNaoPermitidos(cnpj)) return false
142
+
143
+ const sem = removeCaracteresMascara(cnpj).toUpperCase()
144
+
145
+ if (!isCNPJComDVValido(sem)) return false
146
+ if (sem === CNPJ_ZERADO) return false
147
+
148
+ const dvInformado = sem.slice(TAMANHO_CNPJ_SEM_DV)
149
+ const dvCalculado = this.calcularDV(sem.slice(0, TAMANHO_CNPJ_SEM_DV))
150
+
151
+ return dvInformado === dvCalculado
152
+ },
153
+
154
+ /**
155
+ * Gera um CNPJ válido aleatório.
156
+ * @param {boolean} [alfaNumerico=true] true → usa letras + dígitos; false → só dígitos
157
+ * @returns {string} 14 caracteres sem máscara
158
+ */
159
+ gerar(alfaNumerico = true) {
160
+ const chars = alfaNumerico ? CARACTERES_PERMITIDOS : '0123456789'
161
+
162
+ let base
163
+ do {
164
+ base = Array.from(
165
+ { length: TAMANHO_CNPJ_SEM_DV },
166
+ () => chars[Math.floor(Math.random() * chars.length)],
167
+ ).join('')
168
+ } while (base === CNPJ_ZERADO.slice(0, TAMANHO_CNPJ_SEM_DV))
169
+
170
+ return base + this.calcularDV(base)
171
+ },
172
+
173
+ /**
174
+ * Gera um CNPJ válido aleatório já formatado com máscara.
175
+ * @param {boolean} [alfaNumerico=true]
176
+ * @returns {string} Ex.: "AB.CDE.FGH/0001-35"
177
+ */
178
+ gerarFormatado(alfaNumerico = true) {
179
+ return this.aplicarMascara(this.gerar(alfaNumerico))
180
+ },
181
+ }
182
+
183
+ // ─── Exportação ──────────────────────────────────────────────────────────────
184
+ export default CNPJ
package/src/validator.js CHANGED
@@ -1,40 +1,54 @@
1
+ import CNPJ from './cnpj-validate.js'
2
+
1
3
  /**
2
4
  * Função para validar CNPJ
3
5
  * @param {string} aValue Número do CNPJ com ou sem máscara
4
6
  * @returns {boolean}
5
7
  */
6
- export function validarCNPJ(aValue) {
7
- let acumulador = 0
8
- let contador = 5
9
- let finalChar = 12
10
- let strDigito = ''
11
- // Função para remover caracteres não numéricos
12
- function soNumeros(value) {
13
- return value.replace(/\D/g, '')
14
- }
15
- aValue = soNumeros(aValue)
16
- if (aValue === '') {
17
- return false
8
+ export function validarCNPJ(value) {
9
+ value = CNPJ.removeMascara(value)
10
+ if (!value || value.trim() === '' || value.trim() === '00000000000000') {
11
+ return true
18
12
  }
19
- if (aValue.length !== 14) {
13
+ try {
14
+ return CNPJ.isValid(value)
15
+ } catch {
20
16
  return false
21
17
  }
22
- for (let i = 0; i < 2; i++) {
23
- for (let j = 0; j < finalChar; j++) {
24
- acumulador += parseInt(aValue[j]) * contador
25
- contador = contador === 2 ? 9 : contador - 1
26
- }
27
-
28
- let digito = Math.abs(11 - (acumulador % 11))
29
- digito = digito > 9 ? 0 : digito
30
- strDigito += digito.toString()
31
- acumulador = 0
32
- contador = 6
33
- finalChar = 13
34
- }
35
- return aValue.substring(12, 14) === strDigito
36
18
  }
37
19
 
20
+ // export function validarCNPJ(aValue) {
21
+ // let acumulador = 0
22
+ // let contador = 5
23
+ // let finalChar = 12
24
+ // let strDigito = ''
25
+ // // Função para remover caracteres não numéricos
26
+ // function soNumeros(value) {
27
+ // return value.replace(/\D/g, '')
28
+ // }
29
+ // aValue = soNumeros(aValue)
30
+ // if (aValue === '') {
31
+ // return false
32
+ // }
33
+ // if (aValue.length !== 14) {
34
+ // return false
35
+ // }
36
+ // for (let i = 0; i < 2; i++) {
37
+ // for (let j = 0; j < finalChar; j++) {
38
+ // acumulador += parseInt(aValue[j]) * contador
39
+ // contador = contador === 2 ? 9 : contador - 1
40
+ // }
41
+
42
+ // let digito = Math.abs(11 - (acumulador % 11))
43
+ // digito = digito > 9 ? 0 : digito
44
+ // strDigito += digito.toString()
45
+ // acumulador = 0
46
+ // contador = 6
47
+ // finalChar = 13
48
+ // }
49
+ // return aValue.substring(12, 14) === strDigito
50
+ // }
51
+
38
52
  /**
39
53
  * Função para validar CPF
40
54
  * @param {string} aValue Número de CPF a validar com ou sem máscara
package/test/testar.js CHANGED
@@ -119,11 +119,24 @@ import { validarCNPJ, validarCPF } from '../src/validator.js'
119
119
  console.groupEnd()
120
120
  }
121
121
 
122
- const cpf = '068.816.807-83',
123
- cnpj = '05.438.177/0001-98'
122
+ const cpf = '068.816.807-83'
123
+ const cnpj = [
124
+ '05.438.177/0001-98',
125
+ 'LE.BAP.J51/3305-54',
126
+ 'LE.BAP.J51/NN8D-54',
127
+ '1C.YWT.X7Y/M7P7-38',
128
+ '',
129
+ '00.000.000/0000-00',
130
+ ' . . / - ',
131
+ '05.438.177/0001-98',
132
+ ]
124
133
 
125
134
  console.log(`Cpf : ${cpf}`, validarCPF(cpf))
126
- console.log(`Cnpj: ${cnpj}`, validarCNPJ(cnpj))
135
+ console.log()
136
+
137
+ for (let cn of cnpj) {
138
+ console.log(`Cnpj: ${cn}`, validarCNPJ(cn))
139
+ }
127
140
  console.log()
128
141
 
129
142
  //update.updateDotEnv(fs, true, 'build')