jcinfo-utils 1.0.53 → 1.0.55

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 (224.35)
3
+ VITE_VERSION=1.0 (327.29)
4
4
  VITE_VDATE=
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jcinfo-utils",
3
- "version": "1.0.53",
3
+ "version": "1.0.55",
4
4
  "description": "Pacote de funções utilitárias",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -0,0 +1,169 @@
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
+ // ─── helpers internos ────────────────────────────────────────────────────────
18
+
19
+ function isCaracterePermitido(c) {
20
+ c = c.toUpperCase()
21
+ return /[A-Z0-9]/.test(c) || CARACTERES_MASCARA.has(c)
22
+ }
23
+
24
+ function isAlfaNumerico(c) {
25
+ return /^[A-Z0-9]$/.test(c.toUpperCase())
26
+ }
27
+
28
+ function isDigito(c) {
29
+ return /^[0-9]$/.test(c)
30
+ }
31
+
32
+ function temCaracteresNaoPermitidos(str) {
33
+ return [...str].some((c) => !isCaracterePermitido(c))
34
+ }
35
+
36
+ function removeCaracteresMascara(str) {
37
+ return [...str].filter((c) => !CARACTERES_MASCARA.has(c)).join('')
38
+ }
39
+
40
+ function isCNPJSemDVValido(str) {
41
+ if (str.length !== TAMANHO_CNPJ_SEM_DV) return false
42
+ return [...str].every((c) => isAlfaNumerico(c))
43
+ }
44
+
45
+ function isCNPJComDVValido(str) {
46
+ if (str.length !== TAMANHO_CNPJ_COMPLETO) return false
47
+ for (let i = 0; i < TAMANHO_CNPJ_SEM_DV; i++) {
48
+ if (!isAlfaNumerico(str[i])) return false
49
+ }
50
+ for (let i = TAMANHO_CNPJ_SEM_DV; i < TAMANHO_CNPJ_COMPLETO; i++) {
51
+ if (!isDigito(str[i])) return false
52
+ }
53
+ return true
54
+ }
55
+
56
+ // ─── API pública ─────────────────────────────────────────────────────────────
57
+
58
+ const CNPJ = {
59
+ /**
60
+ * Remove os caracteres de máscara ( . / - espaço ) do CNPJ.
61
+ * @param {string} cnpj
62
+ * @returns {string}
63
+ */
64
+ removeMascara(cnpj) {
65
+ return removeCaracteresMascara(cnpj)
66
+ },
67
+
68
+ /**
69
+ * Aplica a máscara XX.XXX.XXX/XXXX-XX ao CNPJ de 14 caracteres.
70
+ * @param {string} cnpj
71
+ * @returns {string}
72
+ */
73
+ aplicarMascara(cnpj) {
74
+ const s = this.removeMascara(cnpj)
75
+ if (s.length !== TAMANHO_CNPJ_COMPLETO) {
76
+ throw new Error('CNPJ deve ter 14 caracteres para aplicar máscara')
77
+ }
78
+ return `${s.slice(0, 2)}.${s.slice(2, 5)}.${s.slice(5, 8)}/${s.slice(8, 12)}-${s.slice(12, 14)}`
79
+ },
80
+
81
+ /**
82
+ * Calcula os dois dígitos verificadores de um CNPJ base (12 caracteres).
83
+ * Lança erro se o CNPJ base for inválido.
84
+ * @param {string} cnpj CNPJ sem DV (12 chars, com ou sem máscara)
85
+ * @returns {string} String com os dois dígitos ("00"–"99")
86
+ */
87
+ calcularDV(cnpj) {
88
+ const ERROR_INVALID =
89
+ 'Não é possível calcular o DV pois o CNPJ fornecido é inválido'
90
+
91
+ if (temCaracteresNaoPermitidos(cnpj)) throw new Error(ERROR_INVALID)
92
+
93
+ const base = removeCaracteresMascara(cnpj).toUpperCase()
94
+
95
+ if (!isCNPJSemDVValido(base)) throw new Error(ERROR_INVALID)
96
+ if (base === CNPJ_ZERADO.slice(0, TAMANHO_CNPJ_SEM_DV))
97
+ throw new Error(ERROR_INVALID)
98
+
99
+ // Conversão idêntica ao Delphi: Ord(C) - Ord('0')
100
+ // Letras resultam em valores > 9 (ex.: 'A' → 17), exatamente como previsto na norma.
101
+ const valores = [...base].map((c) => c.charCodeAt(0) - '0'.charCodeAt(0))
102
+
103
+ let somaDV1 = 0
104
+ let somaDV2 = 0
105
+
106
+ for (let i = 0; i < TAMANHO_CNPJ_SEM_DV; i++) {
107
+ somaDV1 += valores[i] * PESOS_DV[i + 1]
108
+ somaDV2 += valores[i] * PESOS_DV[i]
109
+ }
110
+
111
+ const dv1 = somaDV1 % 11 < 2 ? 0 : 11 - (somaDV1 % 11)
112
+
113
+ somaDV2 += dv1 * PESOS_DV[TAMANHO_CNPJ_SEM_DV]
114
+
115
+ const dv2 = somaDV2 % 11 < 2 ? 0 : 11 - (somaDV2 % 11)
116
+
117
+ return `${dv1}${dv2}`
118
+ },
119
+
120
+ /**
121
+ * Valida um CNPJ (com ou sem máscara, numérico ou alfanumérico).
122
+ * @param {string} cnpj
123
+ * @returns {boolean}
124
+ */
125
+ isValid(cnpj) {
126
+ if (temCaracteresNaoPermitidos(cnpj)) return false
127
+
128
+ const sem = removeCaracteresMascara(cnpj).toUpperCase()
129
+
130
+ if (!isCNPJComDVValido(sem)) return false
131
+ if (sem === CNPJ_ZERADO) return false
132
+
133
+ const dvInformado = sem.slice(TAMANHO_CNPJ_SEM_DV)
134
+ const dvCalculado = this.calcularDV(sem.slice(0, TAMANHO_CNPJ_SEM_DV))
135
+
136
+ return dvInformado === dvCalculado
137
+ },
138
+
139
+ /**
140
+ * Gera um CNPJ válido aleatório.
141
+ * @param {boolean} [alfaNumerico=true] true → usa letras + dígitos; false → só dígitos
142
+ * @returns {string} 14 caracteres sem máscara
143
+ */
144
+ gerar(alfaNumerico = true) {
145
+ const chars = alfaNumerico ? CARACTERES_PERMITIDOS : '0123456789'
146
+
147
+ let base
148
+ do {
149
+ base = Array.from(
150
+ { length: TAMANHO_CNPJ_SEM_DV },
151
+ () => chars[Math.floor(Math.random() * chars.length)],
152
+ ).join('')
153
+ } while (base === CNPJ_ZERADO.slice(0, TAMANHO_CNPJ_SEM_DV))
154
+
155
+ return base + this.calcularDV(base)
156
+ },
157
+
158
+ /**
159
+ * Gera um CNPJ válido aleatório já formatado com máscara.
160
+ * @param {boolean} [alfaNumerico=true]
161
+ * @returns {string} Ex.: "AB.CDE.FGH/0001-35"
162
+ */
163
+ gerarFormatado(alfaNumerico = true) {
164
+ return this.aplicarMascara(this.gerar(alfaNumerico))
165
+ },
166
+ }
167
+
168
+ // ─── Exportação ──────────────────────────────────────────────────────────────
169
+ export default CNPJ
@@ -65,6 +65,7 @@ export function _updateDotEnv(fs, incrementBuild = false, filename = '.env') {
65
65
  const envProd = '.env'
66
66
  const envLocal = '.env.local'
67
67
  const envKey = 'VITE_VERSION'
68
+ const envKeyVDATE = 'VITE_VDATE'
68
69
 
69
70
  export function updateDotEnvKey(
70
71
  fs,
@@ -112,5 +113,5 @@ export function updateDotEnvKey(
112
113
 
113
114
  export function updateDotEnv(fs, autoInc = false, command = 'build') {
114
115
  command == 'build' && updateDotEnvKey(fs, autoInc, envKey, envProd, false)
115
- command == 'serve' && updateDotEnvKey(fs, false, envKey, envLocal, false)
116
+ command == 'serve' && updateDotEnvKey(fs, false, envKeyVDATE, envLocal, true)
116
117
  }
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,12 +119,25 @@ 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))
127
135
  console.log()
128
136
 
129
- update.updateDotEnv(fs, true, 'build')
130
- update.updateDotEnv(fs, true, 'serve')
137
+ for (let cn of cnpj) {
138
+ console.log(`Cnpj: ${cn}`, validarCNPJ(cn))
139
+ }
140
+ console.log()
141
+
142
+ //update.updateDotEnv(fs, true, 'build')
143
+ update.updateDotEnv(fs, false, 'serve')