@br-validators/core 0.10.0-alpha.0 → 0.12.0-alpha.0

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.
Files changed (177) hide show
  1. package/README.md +6 -3
  2. package/dist/boleto.d.ts +2 -2
  3. package/dist/boleto.js +3 -2
  4. package/dist/brcode.d.ts +79 -0
  5. package/dist/brcode.js +13 -0
  6. package/dist/brcode.js.map +1 -0
  7. package/dist/cartao-credito.d.ts +2 -2
  8. package/dist/cartao-credito.js +4 -2
  9. package/dist/cep.d.ts +2 -2
  10. package/dist/cep.js +6 -3
  11. package/dist/chunk-2CNYSY3Z.js +3 -0
  12. package/dist/chunk-2CNYSY3Z.js.map +1 -0
  13. package/dist/{chunk-RMKTJQBB.js → chunk-2JJS46FM.js} +5 -23
  14. package/dist/chunk-2JJS46FM.js.map +1 -0
  15. package/dist/{chunk-Z4F75QEC.js → chunk-3QP6R46N.js} +119 -496
  16. package/dist/chunk-3QP6R46N.js.map +1 -0
  17. package/dist/chunk-4SNBZFS5.js +8 -0
  18. package/dist/chunk-4SNBZFS5.js.map +1 -0
  19. package/dist/{chunk-AKJHIJ5E.js → chunk-4W4OKLSZ.js} +4 -25
  20. package/dist/chunk-4W4OKLSZ.js.map +1 -0
  21. package/dist/chunk-4Y2FBO57.js +26 -0
  22. package/dist/chunk-4Y2FBO57.js.map +1 -0
  23. package/dist/chunk-5UL3M7IU.js +192 -0
  24. package/dist/chunk-5UL3M7IU.js.map +1 -0
  25. package/dist/chunk-6QJFMOIX.js +22 -0
  26. package/dist/chunk-6QJFMOIX.js.map +1 -0
  27. package/dist/chunk-7ZL7PZII.js +187 -0
  28. package/dist/chunk-7ZL7PZII.js.map +1 -0
  29. package/dist/chunk-BFZPCEYB.js +14 -0
  30. package/dist/chunk-BFZPCEYB.js.map +1 -0
  31. package/dist/chunk-CDGRHI7W.js +22 -0
  32. package/dist/chunk-CDGRHI7W.js.map +1 -0
  33. package/dist/chunk-CQPM43VV.js +3 -0
  34. package/dist/chunk-CQPM43VV.js.map +1 -0
  35. package/dist/chunk-D36RM7OD.js +207 -0
  36. package/dist/chunk-D36RM7OD.js.map +1 -0
  37. package/dist/{chunk-54DTXC6V.js → chunk-EPKHEW5V.js} +4 -13
  38. package/dist/chunk-EPKHEW5V.js.map +1 -0
  39. package/dist/{chunk-PBNVKDCF.js → chunk-F6PTZY4O.js} +5 -14
  40. package/dist/chunk-F6PTZY4O.js.map +1 -0
  41. package/dist/chunk-FXLVNCG3.js +26 -0
  42. package/dist/chunk-FXLVNCG3.js.map +1 -0
  43. package/dist/chunk-G24G7WR5.js +3 -0
  44. package/dist/chunk-G24G7WR5.js.map +1 -0
  45. package/dist/chunk-G2Y63PIF.js +24 -0
  46. package/dist/chunk-G2Y63PIF.js.map +1 -0
  47. package/dist/chunk-G32U6YQ5.js +14 -0
  48. package/dist/chunk-G32U6YQ5.js.map +1 -0
  49. package/dist/chunk-GRDUTHNX.js +28 -0
  50. package/dist/chunk-GRDUTHNX.js.map +1 -0
  51. package/dist/chunk-GVK6IMBF.js +3 -0
  52. package/dist/chunk-GVK6IMBF.js.map +1 -0
  53. package/dist/chunk-IQGRFAQV.js +23 -0
  54. package/dist/chunk-IQGRFAQV.js.map +1 -0
  55. package/dist/chunk-JQABTHUJ.js +3 -0
  56. package/dist/chunk-JQABTHUJ.js.map +1 -0
  57. package/dist/{chunk-OWJ5HN4T.js → chunk-KH7DWOUA.js} +5 -23
  58. package/dist/chunk-KH7DWOUA.js.map +1 -0
  59. package/dist/chunk-KQDLIGSG.js +14 -0
  60. package/dist/chunk-KQDLIGSG.js.map +1 -0
  61. package/dist/chunk-LF2B4VPE.js +3 -0
  62. package/dist/chunk-LF2B4VPE.js.map +1 -0
  63. package/dist/chunk-LGD2JJBZ.js +288 -0
  64. package/dist/chunk-LGD2JJBZ.js.map +1 -0
  65. package/dist/{chunk-7FOWIH6F.js → chunk-LYBFUKHR.js} +4 -3
  66. package/dist/chunk-LYBFUKHR.js.map +1 -0
  67. package/dist/chunk-MFNJTAUS.js +3 -0
  68. package/dist/chunk-MFNJTAUS.js.map +1 -0
  69. package/dist/{chunk-SE33CFGM.js → chunk-MK7OJUF5.js} +8 -29
  70. package/dist/chunk-MK7OJUF5.js.map +1 -0
  71. package/dist/chunk-MLPXW7N2.js +226 -0
  72. package/dist/chunk-MLPXW7N2.js.map +1 -0
  73. package/dist/chunk-MSLJF2FM.js +56 -0
  74. package/dist/chunk-MSLJF2FM.js.map +1 -0
  75. package/dist/{chunk-RZ2JG5PP.js → chunk-NHLLC6WH.js} +4 -3
  76. package/dist/chunk-NHLLC6WH.js.map +1 -0
  77. package/dist/chunk-OCYXNLHO.js +307 -0
  78. package/dist/chunk-OCYXNLHO.js.map +1 -0
  79. package/dist/{chunk-B2TDI3YS.js → chunk-OTZHMJYE.js} +3 -3
  80. package/dist/{chunk-B2TDI3YS.js.map → chunk-OTZHMJYE.js.map} +1 -1
  81. package/dist/chunk-P55H5YRX.js +3 -0
  82. package/dist/chunk-P55H5YRX.js.map +1 -0
  83. package/dist/chunk-PB4RIS6G.js +27 -0
  84. package/dist/chunk-PB4RIS6G.js.map +1 -0
  85. package/dist/chunk-QGMVUIDD.js +3 -0
  86. package/dist/chunk-QGMVUIDD.js.map +1 -0
  87. package/dist/chunk-RYGAK7PB.js +3 -0
  88. package/dist/chunk-RYGAK7PB.js.map +1 -0
  89. package/dist/chunk-US4OLTJ2.js +104 -0
  90. package/dist/chunk-US4OLTJ2.js.map +1 -0
  91. package/dist/chunk-WCQUQ2WX.js +241 -0
  92. package/dist/chunk-WCQUQ2WX.js.map +1 -0
  93. package/dist/chunk-WLE2ENQA.js +86 -0
  94. package/dist/chunk-WLE2ENQA.js.map +1 -0
  95. package/dist/{chunk-YY4M2YS6.js → chunk-WPL47PWJ.js} +5 -14
  96. package/dist/chunk-WPL47PWJ.js.map +1 -0
  97. package/dist/chunk-XKY2CV3G.js +14 -0
  98. package/dist/chunk-XKY2CV3G.js.map +1 -0
  99. package/dist/chunk-XUO7FV6Z.js +14 -0
  100. package/dist/chunk-XUO7FV6Z.js.map +1 -0
  101. package/dist/chunk-Y2KUN2D3.js +3 -0
  102. package/dist/chunk-Y2KUN2D3.js.map +1 -0
  103. package/dist/chunk-Y6IW2LMW.js +460 -0
  104. package/dist/chunk-Y6IW2LMW.js.map +1 -0
  105. package/dist/chunk-YGA5W54J.js +3 -0
  106. package/dist/chunk-YGA5W54J.js.map +1 -0
  107. package/dist/{chunk-M66MGLHE.js → chunk-YXELVV37.js} +5 -14
  108. package/dist/chunk-YXELVV37.js.map +1 -0
  109. package/dist/chunk-YYHS5WQN.js +28 -0
  110. package/dist/chunk-YYHS5WQN.js.map +1 -0
  111. package/dist/chunk-ZAUZRIOU.js +23 -0
  112. package/dist/chunk-ZAUZRIOU.js.map +1 -0
  113. package/dist/chunk-ZH4RJNG7.js +3 -0
  114. package/dist/chunk-ZH4RJNG7.js.map +1 -0
  115. package/dist/cnh.d.ts +39 -0
  116. package/dist/cnh.js +11 -0
  117. package/dist/cnh.js.map +1 -0
  118. package/dist/cnpj.d.ts +2 -2
  119. package/dist/cnpj.js +6 -4
  120. package/dist/cpf.d.ts +2 -2
  121. package/dist/cpf.js +6 -4
  122. package/dist/detect.d.ts +23 -0
  123. package/dist/detect.js +26 -0
  124. package/dist/detect.js.map +1 -0
  125. package/dist/generate.d.ts +10 -0
  126. package/dist/generate.js +29 -0
  127. package/dist/generate.js.map +1 -0
  128. package/dist/index-CZLo9YOT.d.ts +21 -0
  129. package/dist/index.d.ts +14 -4
  130. package/dist/index.js +60 -22
  131. package/dist/index.js.map +1 -1
  132. package/dist/inscricao-estadual-produtor-rural-CfWUaggb.d.ts +46 -0
  133. package/dist/inscricao-estadual-produtor-rural.d.ts +2 -0
  134. package/dist/inscricao-estadual-produtor-rural.js +7 -0
  135. package/dist/inscricao-estadual-produtor-rural.js.map +1 -0
  136. package/dist/inscricao-estadual.d.ts +4 -21
  137. package/dist/inscricao-estadual.js +5 -2
  138. package/dist/nfe-chave.d.ts +71 -0
  139. package/dist/nfe-chave.js +6 -0
  140. package/dist/nfe-chave.js.map +1 -0
  141. package/dist/pis-pasep.d.ts +2 -2
  142. package/dist/pis-pasep.js +5 -3
  143. package/dist/{pix-DP6jnwpN.d.ts → pix-ddldLlb7.d.ts} +1 -1
  144. package/dist/pix.d.ts +2 -2
  145. package/dist/pix.js +8 -5
  146. package/dist/placa.d.ts +2 -2
  147. package/dist/placa.js +6 -3
  148. package/dist/renavam.d.ts +37 -0
  149. package/dist/renavam.js +11 -0
  150. package/dist/renavam.js.map +1 -0
  151. package/dist/sanitize.d.ts +9 -0
  152. package/dist/sanitize.js +24 -0
  153. package/dist/sanitize.js.map +1 -0
  154. package/dist/telefone.d.ts +29 -0
  155. package/dist/telefone.js +6 -0
  156. package/dist/telefone.js.map +1 -0
  157. package/dist/titulo-eleitor.d.ts +56 -0
  158. package/dist/titulo-eleitor.js +10 -0
  159. package/dist/titulo-eleitor.js.map +1 -0
  160. package/dist/validation-result-BhQE-1_O.d.ts +196 -0
  161. package/package.json +46 -5
  162. package/dist/chunk-54DTXC6V.js.map +0 -1
  163. package/dist/chunk-7FOWIH6F.js.map +0 -1
  164. package/dist/chunk-AKJHIJ5E.js.map +0 -1
  165. package/dist/chunk-DKRM66US.js +0 -35
  166. package/dist/chunk-DKRM66US.js.map +0 -1
  167. package/dist/chunk-M66MGLHE.js.map +0 -1
  168. package/dist/chunk-OWJ5HN4T.js.map +0 -1
  169. package/dist/chunk-PBNVKDCF.js.map +0 -1
  170. package/dist/chunk-RMKTJQBB.js.map +0 -1
  171. package/dist/chunk-RZ2JG5PP.js.map +0 -1
  172. package/dist/chunk-SE33CFGM.js.map +0 -1
  173. package/dist/chunk-W6UXVWSR.js +0 -13
  174. package/dist/chunk-W6UXVWSR.js.map +0 -1
  175. package/dist/chunk-YY4M2YS6.js.map +0 -1
  176. package/dist/chunk-Z4F75QEC.js.map +0 -1
  177. package/dist/validation-result-BK4qJuei.d.ts +0 -101
@@ -0,0 +1,307 @@
1
+ import { validateTituloEleitor } from './chunk-MLPXW7N2.js';
2
+ import { validateTelefone } from './chunk-5UL3M7IU.js';
3
+ import { validateInscricaoEstadual } from './chunk-3QP6R46N.js';
4
+ import { isSpRuralIeInput, validateIeProdutorRural } from './chunk-Y6IW2LMW.js';
5
+ import { validateNfeChave, NFE_CHAVE_LENGTH } from './chunk-D36RM7OD.js';
6
+ import { validatePisPasep } from './chunk-KH7DWOUA.js';
7
+ import { validatePlaca, PLACA_LENGTH } from './chunk-WPL47PWJ.js';
8
+ import { validateBoleto, detectBoletoInputKind } from './chunk-4W4OKLSZ.js';
9
+ import { validateBrCode } from './chunk-WCQUQ2WX.js';
10
+ import { validatePixKey } from './chunk-MK7OJUF5.js';
11
+ import { validateCartaoCredito, CARTAO_PAN_MIN_LENGTH, CARTAO_PAN_MAX_LENGTH } from './chunk-EPKHEW5V.js';
12
+ import { validateCep } from './chunk-2JJS46FM.js';
13
+ import { validateCnh } from './chunk-US4OLTJ2.js';
14
+ import { validateCnpj, CNPJ_LENGTH } from './chunk-YXELVV37.js';
15
+ import { validateCpf } from './chunk-F6PTZY4O.js';
16
+
17
+ // src/detect/helpers.ts
18
+ function stripDigits(input) {
19
+ return input.replace(/\D/g, "");
20
+ }
21
+ function stripAlnumUpper(input) {
22
+ return input.replace(/[^A-Za-z0-9]/g, "").toUpperCase();
23
+ }
24
+ function hasLetters(input) {
25
+ return /[A-Za-z]/.test(input);
26
+ }
27
+ function looksLikeBrCode(input) {
28
+ const trimmed = input.trim();
29
+ return trimmed.startsWith("00020") && trimmed.length > 20;
30
+ }
31
+ function looksLikeBoleto(input) {
32
+ const kind = detectBoletoInputKind(input);
33
+ return kind === "linha-digitavel" || kind === "codigo-barras";
34
+ }
35
+ function isBoletoArrecadacao(input) {
36
+ return detectBoletoInputKind(input) === "arrecadacao";
37
+ }
38
+ function looksLikeNfeChave(input) {
39
+ const digits = stripDigits(input);
40
+ return digits.length === NFE_CHAVE_LENGTH && /^\d+$/.test(digits);
41
+ }
42
+ function looksLikeCnpjNumeric(input) {
43
+ const digits = stripDigits(input);
44
+ return digits.length === CNPJ_LENGTH && /^\d+$/.test(digits);
45
+ }
46
+ function looksLikeCnpjAlphanumeric(input) {
47
+ const stripped = stripAlnumUpper(input);
48
+ return stripped.length === CNPJ_LENGTH && hasLetters(input);
49
+ }
50
+ function looksLikeElevenDigits(input) {
51
+ const digits = stripDigits(input);
52
+ return digits.length === 11 && /^\d+$/.test(digits);
53
+ }
54
+ function looksLikeTituloEleitor(input) {
55
+ const digits = stripDigits(input);
56
+ return digits.length === 12 && /^\d+$/.test(digits);
57
+ }
58
+ function looksLikeCep(input) {
59
+ const digits = stripDigits(input);
60
+ return digits.length === 8 && /^\d+$/.test(digits);
61
+ }
62
+ function looksLikePlaca(input) {
63
+ const stripped = stripAlnumUpper(input);
64
+ return stripped.length === PLACA_LENGTH && /^[A-Z0-9]+$/.test(stripped);
65
+ }
66
+ function looksLikeCartao(input) {
67
+ const withoutMask = input.replace(/[\s-]/g, "");
68
+ if (/[^0-9]/.test(withoutMask)) {
69
+ return false;
70
+ }
71
+ const digits = stripDigits(input);
72
+ return digits.length >= CARTAO_PAN_MIN_LENGTH && digits.length <= CARTAO_PAN_MAX_LENGTH;
73
+ }
74
+ function looksLikeIe(input, uf) {
75
+ if (!uf) {
76
+ return false;
77
+ }
78
+ if (uf === "SP" && isSpRuralIeInput(input)) {
79
+ return true;
80
+ }
81
+ const digits = stripDigits(input);
82
+ return digits.length >= 8 && digits.length <= 14;
83
+ }
84
+ function looksLikePix(input) {
85
+ const trimmed = input.trim();
86
+ if (trimmed.includes("@")) {
87
+ return true;
88
+ }
89
+ if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(trimmed)) {
90
+ return true;
91
+ }
92
+ if (/^\+?\d/.test(trimmed)) {
93
+ const digits = stripDigits(trimmed);
94
+ return digits.length === 11 || digits.length === 14;
95
+ }
96
+ return false;
97
+ }
98
+ function looksLikeTelefone(input) {
99
+ const digits = stripDigits(input);
100
+ return digits.length >= 10 && digits.length <= 13;
101
+ }
102
+
103
+ // src/detect/index.ts
104
+ function success(type, value, format, meta) {
105
+ return { type, ok: true, value, ...format ? { format } : {}, ...meta ? { meta } : {} };
106
+ }
107
+ function tryValidators(attempts) {
108
+ for (const attempt of attempts) {
109
+ const result = attempt();
110
+ if (result) {
111
+ return result;
112
+ }
113
+ }
114
+ return null;
115
+ }
116
+ var CANDIDATES = [
117
+ {
118
+ canTry: (raw) => looksLikeBoleto(raw) && !isBoletoArrecadacao(raw),
119
+ detect: (raw) => {
120
+ const result = validateBoleto(raw);
121
+ if (!result.ok) {
122
+ return null;
123
+ }
124
+ return success("boleto", result.value, result.format, {
125
+ inputKind: result.inputKind,
126
+ situacao: result.situacao
127
+ });
128
+ }
129
+ },
130
+ {
131
+ canTry: (raw) => looksLikeNfeChave(raw),
132
+ detect: (raw) => {
133
+ const result = validateNfeChave(raw);
134
+ if (!result.ok) {
135
+ return null;
136
+ }
137
+ return success("nfe-chave", result.value, result.format, {
138
+ parsed: result.parsed,
139
+ uf: result.uf
140
+ });
141
+ }
142
+ },
143
+ {
144
+ canTry: (raw) => looksLikeBrCode(raw),
145
+ detect: (raw) => {
146
+ const result = validateBrCode(raw);
147
+ if (!result.ok) {
148
+ return null;
149
+ }
150
+ return success("brcode", result.value, result.format, {
151
+ merchantName: result.merchantName,
152
+ merchantCity: result.merchantCity,
153
+ pixKey: result.pixKey,
154
+ pixKeyType: result.pixKeyType
155
+ });
156
+ }
157
+ },
158
+ {
159
+ canTry: (raw) => looksLikeCnpjAlphanumeric(raw),
160
+ detect: (raw) => {
161
+ const result = validateCnpj(raw);
162
+ if (!result.ok) {
163
+ return null;
164
+ }
165
+ return success("cnpj", result.value, result.format);
166
+ }
167
+ },
168
+ {
169
+ canTry: (raw) => looksLikeCnpjNumeric(raw),
170
+ detect: (raw) => {
171
+ const result = validateCnpj(raw);
172
+ if (!result.ok) {
173
+ return null;
174
+ }
175
+ return success("cnpj", result.value, result.format);
176
+ }
177
+ },
178
+ {
179
+ canTry: (raw) => looksLikeElevenDigits(raw),
180
+ detect: (raw) => tryValidators([
181
+ () => {
182
+ const result = validateCpf(raw);
183
+ return result.ok ? success("cpf", result.value, result.format) : null;
184
+ },
185
+ () => {
186
+ const result = validateCnh(raw);
187
+ return result.ok ? success("cnh", result.value, result.format) : null;
188
+ },
189
+ () => {
190
+ const result = validatePisPasep(raw);
191
+ return result.ok ? success("pis-pasep", result.value, result.format) : null;
192
+ }
193
+ ])
194
+ },
195
+ {
196
+ canTry: (raw) => looksLikeTituloEleitor(raw),
197
+ detect: (raw) => {
198
+ const result = validateTituloEleitor(raw);
199
+ if (!result.ok) {
200
+ return null;
201
+ }
202
+ return success("titulo-eleitor", result.value, result.format, {
203
+ ufCode: result.ufCode,
204
+ ...result.uf ? { uf: result.uf } : {},
205
+ ...result.exterior ? { exterior: result.exterior } : {}
206
+ });
207
+ }
208
+ },
209
+ {
210
+ canTry: (raw) => looksLikeCep(raw),
211
+ detect: (raw) => {
212
+ const result = validateCep(raw);
213
+ if (!result.ok) {
214
+ return null;
215
+ }
216
+ return success("cep", result.value, result.format);
217
+ }
218
+ },
219
+ {
220
+ canTry: (raw) => looksLikePlaca(raw),
221
+ detect: (raw) => {
222
+ const result = validatePlaca(raw);
223
+ if (!result.ok) {
224
+ return null;
225
+ }
226
+ return success("placa", result.value, result.format);
227
+ }
228
+ },
229
+ {
230
+ canTry: (raw) => looksLikePix(raw),
231
+ detect: (raw) => {
232
+ const result = validatePixKey(raw);
233
+ if (!result.ok) {
234
+ return null;
235
+ }
236
+ return success("pix", result.value, result.format, { keyType: result.keyType });
237
+ }
238
+ },
239
+ {
240
+ canTry: (raw) => looksLikeTelefone(raw),
241
+ detect: (raw) => {
242
+ const result = validateTelefone(raw);
243
+ if (!result.ok) {
244
+ return null;
245
+ }
246
+ return success("telefone", result.value, result.format, { tipo: result.tipo });
247
+ }
248
+ },
249
+ {
250
+ canTry: (raw) => looksLikeCartao(raw),
251
+ detect: (raw) => {
252
+ const result = validateCartaoCredito(raw);
253
+ if (!result.ok) {
254
+ return null;
255
+ }
256
+ return success("cartao-credito", result.value, result.format, { brand: result.brand });
257
+ }
258
+ },
259
+ {
260
+ canTry: (raw, options) => looksLikeIe(raw, options.uf),
261
+ detect: (raw, options) => {
262
+ const uf = options.uf;
263
+ if (uf === "SP" && isSpRuralIeInput(raw)) {
264
+ const result2 = validateIeProdutorRural(uf, raw);
265
+ if (!result2.ok) {
266
+ return null;
267
+ }
268
+ return success("inscricao-estadual-produtor-rural", result2.value, result2.format, { uf: result2.uf });
269
+ }
270
+ const result = validateInscricaoEstadual(raw, { uf });
271
+ if (!result.ok) {
272
+ return null;
273
+ }
274
+ return success("inscricao-estadual", result.value, result.format, { uf: result.uf });
275
+ }
276
+ }
277
+ ];
278
+ function detect(raw, options = {}) {
279
+ const trimmed = raw.trim();
280
+ if (trimmed.length === 0) {
281
+ return {
282
+ type: "unknown",
283
+ ok: false,
284
+ code: "EMPTY_INPUT",
285
+ message: "Input is empty"
286
+ };
287
+ }
288
+ for (const candidate of CANDIDATES) {
289
+ if (!candidate.canTry(trimmed, options)) {
290
+ continue;
291
+ }
292
+ const result = candidate.detect(trimmed, options);
293
+ if (result?.ok) {
294
+ return result;
295
+ }
296
+ }
297
+ return {
298
+ type: "unknown",
299
+ ok: false,
300
+ code: "UNSUPPORTED_FORMAT",
301
+ message: options.uf ? "No supported document type matched the input" : "No supported document type matched the input; provide options.uf for Inscri\xE7\xE3o Estadual detection"
302
+ };
303
+ }
304
+
305
+ export { detect };
306
+ //# sourceMappingURL=chunk-OCYXNLHO.js.map
307
+ //# sourceMappingURL=chunk-OCYXNLHO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/detect/helpers.ts","../src/detect/index.ts"],"names":["result"],"mappings":"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","file":"chunk-OCYXNLHO.js","sourcesContent":["import { BOLETO_CODIGO_BARRAS_LENGTH, BOLETO_LINHA_LENGTH } from '../core/boleto/constants.js';\nimport { CARTAO_PAN_MAX_LENGTH, CARTAO_PAN_MIN_LENGTH } from '../core/cartao-credito/constants.js';\nimport { CNPJ_LENGTH } from '../core/cnpj/constants.js';\nimport { NFE_CHAVE_LENGTH } from '../core/nfe-chave/constants.js';\nimport { PLACA_LENGTH } from '../core/placa/constants.js';\nimport { detectBoletoInputKind } from '../core/boleto/detect.js';\nimport { isSpRuralIeInput } from '../core/inscricao-estadual/sp-rural.js';\n\nexport function stripDigits(input: string): string {\n return input.replace(/\\D/g, '');\n}\n\nexport function stripAlnumUpper(input: string): string {\n return input.replace(/[^A-Za-z0-9]/g, '').toUpperCase();\n}\n\nexport function hasLetters(input: string): boolean {\n return /[A-Za-z]/.test(input);\n}\n\nexport function looksLikeBrCode(input: string): boolean {\n const trimmed = input.trim();\n return trimmed.startsWith('00020') && trimmed.length > 20;\n}\n\nexport function looksLikeBoleto(input: string): boolean {\n const kind = detectBoletoInputKind(input);\n return kind === 'linha-digitavel' || kind === 'codigo-barras';\n}\n\nexport function isBoletoArrecadacao(input: string): boolean {\n return detectBoletoInputKind(input) === 'arrecadacao';\n}\n\nexport function looksLikeNfeChave(input: string): boolean {\n const digits = stripDigits(input);\n return digits.length === NFE_CHAVE_LENGTH && /^\\d+$/.test(digits);\n}\n\nexport function looksLikeCnpjNumeric(input: string): boolean {\n const digits = stripDigits(input);\n return digits.length === CNPJ_LENGTH && /^\\d+$/.test(digits);\n}\n\nexport function looksLikeCnpjAlphanumeric(input: string): boolean {\n const stripped = stripAlnumUpper(input);\n return stripped.length === CNPJ_LENGTH && hasLetters(input);\n}\n\nexport function looksLikeElevenDigits(input: string): boolean {\n const digits = stripDigits(input);\n return digits.length === 11 && /^\\d+$/.test(digits);\n}\n\nexport function looksLikeTituloEleitor(input: string): boolean {\n const digits = stripDigits(input);\n return digits.length === 12 && /^\\d+$/.test(digits);\n}\n\nexport function looksLikeCep(input: string): boolean {\n const digits = stripDigits(input);\n return digits.length === 8 && /^\\d+$/.test(digits);\n}\n\nexport function looksLikePlaca(input: string): boolean {\n const stripped = stripAlnumUpper(input);\n return stripped.length === PLACA_LENGTH && /^[A-Z0-9]+$/.test(stripped);\n}\n\nexport function looksLikeCartao(input: string): boolean {\n const withoutMask = input.replace(/[\\s-]/g, '');\n if (/[^0-9]/.test(withoutMask)) {\n return false;\n }\n const digits = stripDigits(input);\n return digits.length >= CARTAO_PAN_MIN_LENGTH && digits.length <= CARTAO_PAN_MAX_LENGTH;\n}\n\nexport function looksLikeIe(input: string, uf?: string): boolean {\n if (!uf) {\n return false;\n }\n if (uf === 'SP' && isSpRuralIeInput(input)) {\n return true;\n }\n const digits = stripDigits(input);\n return digits.length >= 8 && digits.length <= 14;\n}\n\nexport function looksLikePix(input: string): boolean {\n const trimmed = input.trim();\n if (trimmed.includes('@')) {\n return true;\n }\n if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(trimmed)) {\n return true;\n }\n if (/^\\+?\\d/.test(trimmed)) {\n const digits = stripDigits(trimmed);\n return digits.length === 11 || digits.length === 14;\n }\n return false;\n}\n\nexport function looksLikeTelefone(input: string): boolean {\n const digits = stripDigits(input);\n return digits.length >= 10 && digits.length <= 13;\n}\n\nexport {\n BOLETO_CODIGO_BARRAS_LENGTH,\n BOLETO_LINHA_LENGTH,\n};\n","/**\n * Unified document type detection — delegates to existing validators (BR-DETECT-001).\n * @see docs/VALIDATION-RULES.md\n */\nimport { validateBoleto } from '../core/boleto/index.js';\nimport { validateBrCode } from '../core/brcode/index.js';\nimport { validateCartaoCredito } from '../core/cartao-credito/index.js';\nimport { validateCep } from '../core/cep/index.js';\nimport { validateCnh } from '../core/cnh/index.js';\nimport { validateCnpj } from '../core/cnpj/index.js';\nimport { validateCpf } from '../core/cpf/index.js';\nimport { validateInscricaoEstadual } from '../core/inscricao-estadual/index.js';\nimport { validateIeProdutorRural } from '../core/inscricao-estadual/validate-produtor-rural.js';\nimport { isSpRuralIeInput } from '../core/inscricao-estadual/sp-rural.js';\nimport { validateNfeChave } from '../core/nfe-chave/index.js';\nimport { validatePisPasep } from '../core/pis-pasep/index.js';\nimport { validatePlaca } from '../core/placa/index.js';\nimport { validatePixKey } from '../core/pix/index.js';\nimport { validateTelefone } from '../core/telefone/index.js';\nimport { validateTituloEleitor } from '../core/titulo-eleitor/index.js';\nimport {\n isBoletoArrecadacao,\n looksLikeBoleto,\n looksLikeBrCode,\n looksLikeCartao,\n looksLikeCep,\n looksLikeCnpjAlphanumeric,\n looksLikeCnpjNumeric,\n looksLikeElevenDigits,\n looksLikeIe,\n looksLikeNfeChave,\n looksLikePix,\n looksLikePlaca,\n looksLikeTelefone,\n looksLikeTituloEleitor,\n} from './helpers.js';\nimport type { DocumentFormat, UfCode, ValidationErrorCode } from '../types/validation-result.js';\n\nexport type DetectableDocumentType =\n | 'cpf'\n | 'cnpj'\n | 'cep'\n | 'placa'\n | 'pis-pasep'\n | 'pix'\n | 'telefone'\n | 'boleto'\n | 'cartao-credito'\n | 'cnh'\n | 'renavam'\n | 'nfe-chave'\n | 'titulo-eleitor'\n | 'inscricao-estadual'\n | 'inscricao-estadual-produtor-rural'\n | 'brcode'\n | 'unknown';\n\nexport type DetectOptions = {\n uf?: UfCode;\n};\n\nexport type DetectSuccess = {\n type: DetectableDocumentType;\n ok: true;\n value: string;\n format?: DocumentFormat;\n meta?: Record<string, unknown>;\n};\n\nexport type DetectFailure = {\n type: DetectableDocumentType;\n ok: false;\n code: ValidationErrorCode;\n message: string;\n};\n\nexport type DetectResult = DetectSuccess | DetectFailure;\n\ntype Candidate = {\n canTry: (raw: string, options: DetectOptions) => boolean;\n detect: (raw: string, options: DetectOptions) => DetectResult | null;\n};\n\n/** @internal Test hook for success result branches. */\nexport function buildDetectSuccess(\n type: DetectableDocumentType,\n value: string,\n format?: DocumentFormat,\n meta?: Record<string, unknown>,\n): DetectResult {\n return success(type, value, format, meta);\n}\n\nfunction success(\n type: DetectableDocumentType,\n value: string,\n format?: DocumentFormat,\n meta?: Record<string, unknown>,\n): DetectResult {\n return { type, ok: true, value, ...(format ? { format } : {}), ...(meta ? { meta } : {}) };\n}\n\nfunction tryValidators(attempts: Array<() => DetectResult | null>): DetectResult | null {\n for (const attempt of attempts) {\n const result = attempt();\n if (result) {\n return result;\n }\n }\n return null;\n}\n\nconst CANDIDATES: Candidate[] = [\n {\n canTry: (raw) => looksLikeBoleto(raw) && !isBoletoArrecadacao(raw),\n detect: (raw) => {\n const result = validateBoleto(raw);\n if (!result.ok) {\n return null;\n }\n return success('boleto', result.value, result.format, {\n inputKind: result.inputKind,\n situacao: result.situacao,\n });\n },\n },\n {\n canTry: (raw) => looksLikeNfeChave(raw),\n detect: (raw) => {\n const result = validateNfeChave(raw);\n if (!result.ok) {\n return null;\n }\n return success('nfe-chave', result.value, result.format, {\n parsed: result.parsed,\n uf: result.uf,\n });\n },\n },\n {\n canTry: (raw) => looksLikeBrCode(raw),\n detect: (raw) => {\n const result = validateBrCode(raw);\n if (!result.ok) {\n return null;\n }\n return success('brcode', result.value, result.format, {\n merchantName: result.merchantName,\n merchantCity: result.merchantCity,\n pixKey: result.pixKey,\n pixKeyType: result.pixKeyType,\n });\n },\n },\n {\n canTry: (raw) => looksLikeCnpjAlphanumeric(raw),\n detect: (raw) => {\n const result = validateCnpj(raw);\n if (!result.ok) {\n return null;\n }\n return success('cnpj', result.value, result.format);\n },\n },\n {\n canTry: (raw) => looksLikeCnpjNumeric(raw),\n detect: (raw) => {\n const result = validateCnpj(raw);\n if (!result.ok) {\n return null;\n }\n return success('cnpj', result.value, result.format);\n },\n },\n {\n canTry: (raw) => looksLikeElevenDigits(raw),\n detect: (raw) =>\n tryValidators([\n () => {\n const result = validateCpf(raw);\n return result.ok ? success('cpf', result.value, result.format) : null;\n },\n () => {\n const result = validateCnh(raw);\n return result.ok ? success('cnh', result.value, result.format) : null;\n },\n () => {\n const result = validatePisPasep(raw);\n return result.ok ? success('pis-pasep', result.value, result.format) : null;\n },\n ]),\n },\n {\n canTry: (raw) => looksLikeTituloEleitor(raw),\n detect: (raw) => {\n const result = validateTituloEleitor(raw);\n if (!result.ok) {\n return null;\n }\n return success('titulo-eleitor', result.value, result.format, {\n ufCode: result.ufCode,\n ...(result.uf ? { uf: result.uf } : {}),\n ...(result.exterior ? { exterior: result.exterior } : {}),\n });\n },\n },\n {\n canTry: (raw) => looksLikeCep(raw),\n detect: (raw) => {\n const result = validateCep(raw);\n if (!result.ok) {\n return null;\n }\n return success('cep', result.value, result.format);\n },\n },\n {\n canTry: (raw) => looksLikePlaca(raw),\n detect: (raw) => {\n const result = validatePlaca(raw);\n if (!result.ok) {\n return null;\n }\n return success('placa', result.value, result.format);\n },\n },\n {\n canTry: (raw) => looksLikePix(raw),\n detect: (raw) => {\n const result = validatePixKey(raw);\n if (!result.ok) {\n return null;\n }\n return success('pix', result.value, result.format, { keyType: result.keyType });\n },\n },\n {\n canTry: (raw) => looksLikeTelefone(raw),\n detect: (raw) => {\n const result = validateTelefone(raw);\n if (!result.ok) {\n return null;\n }\n return success('telefone', result.value, result.format, { tipo: result.tipo });\n },\n },\n {\n canTry: (raw) => looksLikeCartao(raw),\n detect: (raw) => {\n const result = validateCartaoCredito(raw);\n if (!result.ok) {\n return null;\n }\n return success('cartao-credito', result.value, result.format, { brand: result.brand });\n },\n },\n {\n canTry: (raw, options) => looksLikeIe(raw, options.uf),\n detect: (raw, options) => {\n const uf = options.uf as UfCode;\n if (uf === 'SP' && isSpRuralIeInput(raw)) {\n const result = validateIeProdutorRural(uf, raw);\n if (!result.ok) {\n return null;\n }\n return success('inscricao-estadual-produtor-rural', result.value, result.format, { uf: result.uf });\n }\n const result = validateInscricaoEstadual(raw, { uf });\n if (!result.ok) {\n return null;\n }\n return success('inscricao-estadual', result.value, result.format, { uf: result.uf });\n },\n },\n];\n\nexport function detect(raw: string, options: DetectOptions = {}): DetectResult {\n const trimmed = raw.trim();\n if (trimmed.length === 0) {\n return {\n type: 'unknown',\n ok: false,\n code: 'EMPTY_INPUT',\n message: 'Input is empty',\n };\n }\n\n for (const candidate of CANDIDATES) {\n if (!candidate.canTry(trimmed, options)) {\n continue;\n }\n const result = candidate.detect(trimmed, options);\n if (result?.ok) {\n return result;\n }\n }\n\n return {\n type: 'unknown',\n ok: false,\n code: 'UNSUPPORTED_FORMAT',\n message: options.uf\n ? 'No supported document type matched the input'\n : 'No supported document type matched the input; provide options.uf for Inscrição Estadual detection',\n };\n}\n"]}
@@ -18,6 +18,6 @@ function computeCheckDigit(chars, weights, valueFn) {
18
18
  return modulo11CheckDigit(weightedSum(values, weights));
19
19
  }
20
20
 
21
- export { computeCheckDigit };
22
- //# sourceMappingURL=chunk-B2TDI3YS.js.map
23
- //# sourceMappingURL=chunk-B2TDI3YS.js.map
21
+ export { computeCheckDigit, weightedSum };
22
+ //# sourceMappingURL=chunk-OTZHMJYE.js.map
23
+ //# sourceMappingURL=chunk-OTZHMJYE.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/cnpj/modulo11.ts"],"names":[],"mappings":";AAIO,SAAS,mBAAmB,GAAA,EAAqB;AACtD,EAAA,MAAM,YAAY,GAAA,GAAM,EAAA;AACxB,EAAA,OAAO,SAAA,GAAY,CAAA,GAAI,CAAA,GAAI,EAAA,GAAK,SAAA;AAClC;AAEO,SAAS,WAAA,CAAY,QAAkB,OAAA,EAAoC;AAChF,EAAA,IAAI,GAAA,GAAM,CAAA;AACV,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,OAAA,CAAQ,QAAQ,CAAA,EAAA,EAAK;AACvC,IAAA,GAAA,IAAO,MAAA,CAAO,CAAC,CAAA,GAAI,OAAA,CAAQ,CAAC,CAAA;AAAA,EAC9B;AACA,EAAA,OAAO,GAAA;AACT;AAEO,SAAS,iBAAA,CAAkB,KAAA,EAAe,OAAA,EAA4B,OAAA,EAAwC;AACnH,EAAA,MAAM,SAAmB,EAAC;AAC1B,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,IAAA,MAAA,CAAO,KAAK,OAAA,CAAQ,KAAA,CAAM,MAAA,CAAO,CAAC,CAAC,CAAC,CAAA;AAAA,EACtC;AACA,EAAA,OAAO,kBAAA,CAAmB,WAAA,CAAY,MAAA,EAAQ,OAAO,CAAC,CAAA;AACxD","file":"chunk-B2TDI3YS.js","sourcesContent":["/**\n * Modulo 11 check digit — RFB Q14 remainder rule.\n * @see https://www.gov.br/receitafederal/pt-br/centrais-de-conteudo/publicacoes/perguntas-e-respostas/cnpj/cnpj-alfanumerico.pdf\n */\nexport function modulo11CheckDigit(sum: number): number {\n const remainder = sum % 11;\n return remainder < 2 ? 0 : 11 - remainder;\n}\n\nexport function weightedSum(values: number[], weights: readonly number[]): number {\n let sum = 0;\n for (let i = 0; i < weights.length; i++) {\n sum += values[i] * weights[i];\n }\n return sum;\n}\n\nexport function computeCheckDigit(chars: string, weights: readonly number[], valueFn: (c: string) => number): number {\n const values: number[] = [];\n for (let i = 0; i < chars.length; i++) {\n values.push(valueFn(chars.charAt(i)));\n }\n return modulo11CheckDigit(weightedSum(values, weights));\n}\n"]}
1
+ {"version":3,"sources":["../src/core/cnpj/modulo11.ts"],"names":[],"mappings":";AAIO,SAAS,mBAAmB,GAAA,EAAqB;AACtD,EAAA,MAAM,YAAY,GAAA,GAAM,EAAA;AACxB,EAAA,OAAO,SAAA,GAAY,CAAA,GAAI,CAAA,GAAI,EAAA,GAAK,SAAA;AAClC;AAEO,SAAS,WAAA,CAAY,QAAkB,OAAA,EAAoC;AAChF,EAAA,IAAI,GAAA,GAAM,CAAA;AACV,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,OAAA,CAAQ,QAAQ,CAAA,EAAA,EAAK;AACvC,IAAA,GAAA,IAAO,MAAA,CAAO,CAAC,CAAA,GAAI,OAAA,CAAQ,CAAC,CAAA;AAAA,EAC9B;AACA,EAAA,OAAO,GAAA;AACT;AAEO,SAAS,iBAAA,CAAkB,KAAA,EAAe,OAAA,EAA4B,OAAA,EAAwC;AACnH,EAAA,MAAM,SAAmB,EAAC;AAC1B,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,IAAA,MAAA,CAAO,KAAK,OAAA,CAAQ,KAAA,CAAM,MAAA,CAAO,CAAC,CAAC,CAAC,CAAA;AAAA,EACtC;AACA,EAAA,OAAO,kBAAA,CAAmB,WAAA,CAAY,MAAA,EAAQ,OAAO,CAAC,CAAA;AACxD","file":"chunk-OTZHMJYE.js","sourcesContent":["/**\n * Modulo 11 check digit — RFB Q14 remainder rule.\n * @see https://www.gov.br/receitafederal/pt-br/centrais-de-conteudo/publicacoes/perguntas-e-respostas/cnpj/cnpj-alfanumerico.pdf\n */\nexport function modulo11CheckDigit(sum: number): number {\n const remainder = sum % 11;\n return remainder < 2 ? 0 : 11 - remainder;\n}\n\nexport function weightedSum(values: number[], weights: readonly number[]): number {\n let sum = 0;\n for (let i = 0; i < weights.length; i++) {\n sum += values[i] * weights[i];\n }\n return sum;\n}\n\nexport function computeCheckDigit(chars: string, weights: readonly number[], valueFn: (c: string) => number): number {\n const values: number[] = [];\n for (let i = 0; i < chars.length; i++) {\n values.push(valueFn(chars.charAt(i)));\n }\n return modulo11CheckDigit(weightedSum(values, weights));\n}\n"]}
@@ -0,0 +1,3 @@
1
+
2
+ //# sourceMappingURL=chunk-P55H5YRX.js.map
3
+ //# sourceMappingURL=chunk-P55H5YRX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-P55H5YRX.js"}
@@ -0,0 +1,27 @@
1
+ import { validateTituloEleitor, TITULO_ELEITOR_NUMERIC_PATTERN_12, TITULO_ELEITOR_NUMERIC_PATTERN_13, TITULO_ELEITOR_LENGTH, TITULO_ELEITOR_LENGTH_EXTENDED } from './chunk-MLPXW7N2.js';
2
+
3
+ // src/core/titulo-eleitor/mask.ts
4
+ function applyTituloEleitorMask(canonical) {
5
+ if (TITULO_ELEITOR_NUMERIC_PATTERN_12.test(canonical)) {
6
+ return `${canonical.slice(0, 4)} ${canonical.slice(4, 8)} ${canonical.slice(8)}`;
7
+ }
8
+ if (TITULO_ELEITOR_NUMERIC_PATTERN_13.test(canonical)) {
9
+ return `${canonical.slice(0, 5)} ${canonical.slice(5, 9)} ${canonical.slice(9)}`;
10
+ }
11
+ throw new Error(
12
+ `T\xEDtulo de Eleitor must have exactly ${TITULO_ELEITOR_LENGTH} or ${TITULO_ELEITOR_LENGTH_EXTENDED} digits to format`
13
+ );
14
+ }
15
+
16
+ // src/format/titulo-eleitor.ts
17
+ function formatTituloEleitor(input) {
18
+ const result = validateTituloEleitor(input);
19
+ if (!result.ok) {
20
+ return { ok: false, code: result.code, message: result.message };
21
+ }
22
+ return { ok: true, formatted: applyTituloEleitorMask(result.value) };
23
+ }
24
+
25
+ export { formatTituloEleitor };
26
+ //# sourceMappingURL=chunk-PB4RIS6G.js.map
27
+ //# sourceMappingURL=chunk-PB4RIS6G.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/titulo-eleitor/mask.ts","../src/format/titulo-eleitor.ts"],"names":[],"mappings":";;;AAWO,SAAS,uBAAuB,SAAA,EAA2B;AAChE,EAAA,IAAI,iCAAA,CAAkC,IAAA,CAAK,SAAS,CAAA,EAAG;AACrD,IAAA,OAAO,GAAG,SAAA,CAAU,KAAA,CAAM,CAAA,EAAG,CAAC,CAAC,CAAA,CAAA,EAAI,SAAA,CAAU,KAAA,CAAM,CAAA,EAAG,CAAC,CAAC,CAAA,CAAA,EAAI,SAAA,CAAU,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AAAA,EAChF;AACA,EAAA,IAAI,iCAAA,CAAkC,IAAA,CAAK,SAAS,CAAA,EAAG;AACrD,IAAA,OAAO,GAAG,SAAA,CAAU,KAAA,CAAM,CAAA,EAAG,CAAC,CAAC,CAAA,CAAA,EAAI,SAAA,CAAU,KAAA,CAAM,CAAA,EAAG,CAAC,CAAC,CAAA,CAAA,EAAI,SAAA,CAAU,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AAAA,EAChF;AACA,EAAA,MAAM,IAAI,KAAA;AAAA,IACR,CAAA,uCAAA,EAAuC,qBAAqB,CAAA,IAAA,EAAO,8BAA8B,CAAA,iBAAA;AAAA,GACnG;AACF;;;ACjBO,SAAS,oBAAoB,KAAA,EAA6B;AAC/D,EAAA,MAAM,MAAA,GAAS,sBAAsB,KAAK,CAAA;AAC1C,EAAA,IAAI,CAAC,OAAO,EAAA,EAAI;AACd,IAAA,OAAO,EAAE,IAAI,KAAA,EAAO,IAAA,EAAM,OAAO,IAAA,EAAM,OAAA,EAAS,OAAO,OAAA,EAAQ;AAAA,EACjE;AACA,EAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,WAAW,sBAAA,CAAuB,MAAA,CAAO,KAAK,CAAA,EAAE;AACrE","file":"chunk-PB4RIS6G.js","sourcesContent":["import {\n TITULO_ELEITOR_LENGTH,\n TITULO_ELEITOR_LENGTH_EXTENDED,\n TITULO_ELEITOR_NUMERIC_PATTERN_12,\n TITULO_ELEITOR_NUMERIC_PATTERN_13,\n} from './constants.js';\n\n/**\n * Display mask — `XXXX XXXX XXXX` (BR-TITULO-005).\n * @see https://pt.wikipedia.org/wiki/T%C3%ADtulo_eleitoral#C%C3%A1lculo_do_d%C3%ADgito_verificador\n */\nexport function applyTituloEleitorMask(canonical: string): string {\n if (TITULO_ELEITOR_NUMERIC_PATTERN_12.test(canonical)) {\n return `${canonical.slice(0, 4)} ${canonical.slice(4, 8)} ${canonical.slice(8)}`;\n }\n if (TITULO_ELEITOR_NUMERIC_PATTERN_13.test(canonical)) {\n return `${canonical.slice(0, 5)} ${canonical.slice(5, 9)} ${canonical.slice(9)}`;\n }\n throw new Error(\n `Título de Eleitor must have exactly ${TITULO_ELEITOR_LENGTH} or ${TITULO_ELEITOR_LENGTH_EXTENDED} digits to format`,\n );\n}\n","import { applyTituloEleitorMask } from '../core/titulo-eleitor/mask.js';\nimport { validateTituloEleitor } from '../core/titulo-eleitor/index.js';\nimport type { FormatResult } from '../types/validation-result.js';\n\nexport function formatTituloEleitor(input: string): FormatResult {\n const result = validateTituloEleitor(input);\n if (!result.ok) {\n return { ok: false, code: result.code, message: result.message };\n }\n return { ok: true, formatted: applyTituloEleitorMask(result.value) };\n}\n"]}
@@ -0,0 +1,3 @@
1
+
2
+ //# sourceMappingURL=chunk-QGMVUIDD.js.map
3
+ //# sourceMappingURL=chunk-QGMVUIDD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-QGMVUIDD.js"}
@@ -0,0 +1,3 @@
1
+
2
+ //# sourceMappingURL=chunk-RYGAK7PB.js.map
3
+ //# sourceMappingURL=chunk-RYGAK7PB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-RYGAK7PB.js"}
@@ -0,0 +1,104 @@
1
+ import { stripCnh } from './chunk-YYHS5WQN.js';
2
+ import { weightedSum } from './chunk-OTZHMJYE.js';
3
+ import { brandCnh } from './chunk-MSLJF2FM.js';
4
+
5
+ // src/core/cnh/constants.ts
6
+ var CNH_DV1_WEIGHTS = [9, 8, 7, 6, 5, 4, 3, 2, 1];
7
+ var CNH_DV2_WEIGHTS = [1, 2, 3, 4, 5, 6, 7, 8, 9];
8
+ var CNH_LENGTH = 11;
9
+ var CNH_BASE_LENGTH = 9;
10
+ var CNH_NUMERIC_PATTERN = /^\d{11}$/;
11
+ var CNH_GOLDEN_PRIMARY = "62472927637";
12
+ var CNH_GOLDEN_SECONDARY = "69044271146";
13
+ var CNH_GOLDEN_DISCOUNT_CASE = "00000001801";
14
+ var CNH_GOLDEN_PRIMARY_DECORATED_INPUT = "624.729.276-37";
15
+ var CNH_OFFICIAL_SOURCE_URL = "https://www.gov.br/transportes/pt-br/assuntos/transito/conteudo-contran/resolucoes/resolucao5112014.pdf";
16
+ var CNH_SENATRAN_VALIDAR_URL = "https://www.gov.br/pt-br/servicos/validar-cnh";
17
+
18
+ // src/core/cnh/check-digits.ts
19
+ function digitValues(chars) {
20
+ const values = [];
21
+ for (let i = 0; i < chars.length; i++) {
22
+ values.push(Number(chars.charAt(i)));
23
+ }
24
+ return values;
25
+ }
26
+ function computeCnhFirstCheckDigit(base) {
27
+ const remainder = weightedSum(digitValues(base), CNH_DV1_WEIGHTS) % 11;
28
+ if (remainder >= 10) {
29
+ return { dv: 0, discount: 2 };
30
+ }
31
+ return { dv: remainder, discount: 0 };
32
+ }
33
+ function computeCnhSecondCheckDigit(base, discount) {
34
+ let dv = weightedSum(digitValues(base), CNH_DV2_WEIGHTS) % 11;
35
+ if (discount === 2) {
36
+ if (dv - 2 < 0) {
37
+ dv += 9;
38
+ } else {
39
+ dv -= 2;
40
+ }
41
+ }
42
+ if (dv > 9) {
43
+ dv = 0;
44
+ }
45
+ return dv;
46
+ }
47
+ function computeCnhCheckDigits(base) {
48
+ const { dv: dv1, discount } = computeCnhFirstCheckDigit(base);
49
+ const dv2 = computeCnhSecondCheckDigit(base, discount);
50
+ return `${String(dv1)}${String(dv2)}`;
51
+ }
52
+
53
+ // src/core/cnh/index.ts
54
+ function failure(code, message) {
55
+ return { ok: false, code, message };
56
+ }
57
+ function hasRepeatedDigits(value) {
58
+ const first = value[0];
59
+ for (let i = 1; i < value.length; i++) {
60
+ if (value[i] !== first) {
61
+ return false;
62
+ }
63
+ }
64
+ return true;
65
+ }
66
+ function isValidCnhChecksum(stripped) {
67
+ const base = stripped.slice(0, CNH_BASE_LENGTH);
68
+ const expected = computeCnhCheckDigits(base);
69
+ return stripped.slice(CNH_BASE_LENGTH) === expected;
70
+ }
71
+ function validateStructure(input, stripped) {
72
+ if (stripped.length === 0) {
73
+ return failure("EMPTY_INPUT", "CNH input is empty");
74
+ }
75
+ const withoutMask = input.replace(/[.\s-]/g, "");
76
+ if (/[^0-9]/.test(withoutMask)) {
77
+ return failure("INVALID_CHARACTER", "CNH contains invalid characters");
78
+ }
79
+ if (stripped.length !== CNH_LENGTH) {
80
+ return failure("INVALID_LENGTH", `CNH must have ${CNH_LENGTH} digits after normalization`);
81
+ }
82
+ if (hasRepeatedDigits(stripped)) {
83
+ return failure("KNOWN_INVALID_PATTERN", "CNH with all identical digits is invalid");
84
+ }
85
+ return null;
86
+ }
87
+ function isValidCnh(input) {
88
+ return validateCnh(input).ok;
89
+ }
90
+ function validateCnh(input) {
91
+ const stripped = stripCnh(input);
92
+ const structural = validateStructure(input, stripped);
93
+ if (structural) {
94
+ return structural;
95
+ }
96
+ if (isValidCnhChecksum(stripped)) {
97
+ return { ok: true, value: brandCnh(stripped), format: "numeric" };
98
+ }
99
+ return failure("INVALID_CHECK_DIGIT", "CNH check digits are invalid");
100
+ }
101
+
102
+ export { CNH_BASE_LENGTH, CNH_DV1_WEIGHTS, CNH_DV2_WEIGHTS, CNH_GOLDEN_DISCOUNT_CASE, CNH_GOLDEN_PRIMARY, CNH_GOLDEN_PRIMARY_DECORATED_INPUT, CNH_GOLDEN_SECONDARY, CNH_LENGTH, CNH_NUMERIC_PATTERN, CNH_OFFICIAL_SOURCE_URL, CNH_SENATRAN_VALIDAR_URL, computeCnhCheckDigits, isValidCnh, validateCnh };
103
+ //# sourceMappingURL=chunk-US4OLTJ2.js.map
104
+ //# sourceMappingURL=chunk-US4OLTJ2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/cnh/constants.ts","../src/core/cnh/check-digits.ts","../src/core/cnh/index.ts"],"names":[],"mappings":"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","file":"chunk-US4OLTJ2.js","sourcesContent":["/**\n * CNH constants — Registro Nacional modulo 11 (CONTRAN / SENATRAN).\n * @see https://www.gov.br/transportes/pt-br/assuntos/transito/conteudo-contran/resolucoes/resolucao5112014.pdf\n * @see https://www.gov.br/transportes/pt-br/assuntos/transito/conteudo-contran/resolucoes/Resolucao8862021.pdf\n * @see https://www.gov.br/pt-br/servicos/validar-cnh\n * @see https://siga0984.wordpress.com/2019/05/01/algoritmos-validacao-de-cnh/ — algorithm cross-check (AdvPL)\n * @see https://www.geravalida.com.br/validador-cnh — implementation cross-check\n * @see https://geradorbr.com/validador-de-cnh/ — implementation cross-check\n */\nexport const CNH_DV1_WEIGHTS = [9, 8, 7, 6, 5, 4, 3, 2, 1] as const;\nexport const CNH_DV2_WEIGHTS = [1, 2, 3, 4, 5, 6, 7, 8, 9] as const;\nexport const CNH_LENGTH = 11;\nexport const CNH_BASE_LENGTH = 9;\nexport const CNH_NUMERIC_PATTERN = /^\\d{11}$/;\n\n/** Golden primary — DV walkthrough: base `624729276` → DV `37`. */\nexport const CNH_GOLDEN_PRIMARY = '62472927637';\nexport const CNH_GOLDEN_SECONDARY = '69044271146';\nexport const CNH_GOLDEN_DISCOUNT_CASE = '00000001801';\n\n/** Non-official CPF-style decoration — accepted on input via strip, never emitted by format. */\nexport const CNH_GOLDEN_PRIMARY_DECORATED_INPUT = '624.729.276-37';\n\nexport const CNH_OFFICIAL_SOURCE_URL =\n 'https://www.gov.br/transportes/pt-br/assuntos/transito/conteudo-contran/resolucoes/resolucao5112014.pdf';\n\n/** SENATRAN online validation — requires plain 11-digit registration number. */\nexport const CNH_SENATRAN_VALIDAR_URL = 'https://www.gov.br/pt-br/servicos/validar-cnh';\n","/**\n * CNH check digits — modulo 11 with inter-DV discount (desconto).\n * DV1 and DV2 weighted sums are computed in parallel on the same 9 base digits.\n * @see https://www.gov.br/transportes/pt-br/assuntos/transito/conteudo-contran/resolucoes/resolucao5112014.pdf\n * @see https://siga0984.wordpress.com/2019/05/01/algoritmos-validacao-de-cnh/ — algorithm cross-check (AdvPL)\n */\nimport { weightedSum } from '../cnpj/modulo11.js';\nimport { CNH_DV1_WEIGHTS, CNH_DV2_WEIGHTS } from './constants.js';\n\nfunction digitValues(chars: string): number[] {\n const values: number[] = [];\n for (let i = 0; i < chars.length; i++) {\n values.push(Number(chars.charAt(i)));\n }\n return values;\n}\n\nexport function computeCnhFirstCheckDigit(base: string): { dv: number; discount: number } {\n const remainder = weightedSum(digitValues(base), CNH_DV1_WEIGHTS) % 11;\n if (remainder >= 10) {\n return { dv: 0, discount: 2 };\n }\n return { dv: remainder, discount: 0 };\n}\n\nexport function computeCnhSecondCheckDigit(base: string, discount: number): number {\n let dv = weightedSum(digitValues(base), CNH_DV2_WEIGHTS) % 11;\n if (discount === 2) {\n if (dv - 2 < 0) {\n dv += 9;\n } else {\n dv -= 2;\n }\n }\n if (dv > 9) {\n dv = 0;\n }\n return dv;\n}\n\nexport function computeCnhCheckDigits(base: string): string {\n const { dv: dv1, discount } = computeCnhFirstCheckDigit(base);\n const dv2 = computeCnhSecondCheckDigit(base, discount);\n return `${String(dv1)}${String(dv2)}`;\n}\n","/**\n * CNH validation — Registro Nacional modulo 11 with inter-DV discount.\n * @see https://www.gov.br/transportes/pt-br/assuntos/transito/conteudo-contran/resolucoes/resolucao5112014.pdf\n * @see https://www.gov.br/infraestrutura/pt-br/assuntos/transito/senatran\n */\nimport { stripCnh } from '../../strip/index.js';\nimport type { Cnh, ValidationResult } from '../../types/validation-result.js';\nimport { brandCnh } from '../../types/validation-result.js';\nimport { computeCnhCheckDigits } from './check-digits.js';\nimport { CNH_BASE_LENGTH, CNH_LENGTH } from './constants.js';\n\nexport {\n CNH_BASE_LENGTH,\n CNH_DV1_WEIGHTS,\n CNH_DV2_WEIGHTS,\n CNH_GOLDEN_DISCOUNT_CASE,\n CNH_GOLDEN_PRIMARY,\n CNH_GOLDEN_PRIMARY_DECORATED_INPUT,\n CNH_GOLDEN_SECONDARY,\n CNH_LENGTH,\n CNH_NUMERIC_PATTERN,\n CNH_OFFICIAL_SOURCE_URL,\n CNH_SENATRAN_VALIDAR_URL,\n} from './constants.js';\n\ntype FailedResult = Extract<ValidationResult, { ok: false }>;\n\nfunction failure(code: FailedResult['code'], message: string): FailedResult {\n return { ok: false, code, message };\n}\n\nfunction hasRepeatedDigits(value: string): boolean {\n const first = value[0];\n for (let i = 1; i < value.length; i++) {\n if (value[i] !== first) {\n return false;\n }\n }\n return true;\n}\n\nfunction isValidCnhChecksum(stripped: string): boolean {\n const base = stripped.slice(0, CNH_BASE_LENGTH);\n const expected = computeCnhCheckDigits(base);\n return stripped.slice(CNH_BASE_LENGTH) === expected;\n}\n\nfunction validateStructure(input: string, stripped: string): FailedResult | null {\n if (stripped.length === 0) {\n return failure('EMPTY_INPUT', 'CNH input is empty');\n }\n\n const withoutMask = input.replace(/[.\\s-]/g, '');\n if (/[^0-9]/.test(withoutMask)) {\n return failure('INVALID_CHARACTER', 'CNH contains invalid characters');\n }\n\n if (stripped.length !== CNH_LENGTH) {\n return failure('INVALID_LENGTH', `CNH must have ${CNH_LENGTH} digits after normalization`);\n }\n\n if (hasRepeatedDigits(stripped)) {\n return failure('KNOWN_INVALID_PATTERN', 'CNH with all identical digits is invalid');\n }\n\n return null;\n}\n\nexport function isValidCnh(input: string): boolean {\n return validateCnh(input).ok;\n}\n\nexport function validateCnh(input: string): ValidationResult<Cnh> {\n const stripped = stripCnh(input);\n const structural = validateStructure(input, stripped);\n if (structural) {\n return structural;\n }\n\n if (isValidCnhChecksum(stripped)) {\n return { ok: true, value: brandCnh(stripped), format: 'numeric' };\n }\n\n return failure('INVALID_CHECK_DIGIT', 'CNH check digits are invalid');\n}\n"]}