@br-validators/cli 1.3.0 → 1.6.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.
package/dist/index.js CHANGED
@@ -9,22 +9,774 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
9
9
  // src/program.ts
10
10
  import { Command } from "commander";
11
11
 
12
- // src/commands/brcode.ts
13
- import {
14
- BRCODE_OFFICIAL_SOURCE_URL,
15
- parseBrCode,
16
- validateBrCode
17
- } from "@br-validators/core";
12
+ // src/commands/bancos/list.ts
13
+ import { BANCOS_DATA_VERSION as BANCOS_DATA_VERSION2, getBancos } from "@br-validators/core/bancos";
18
14
 
19
15
  // src/constants.ts
20
- var SUPPORTED_TYPES = ["cnpj", "cpf", "cep", "telefone", "cnh", "renavam", "titulo-eleitor", "nfe-chave", "brcode", "placa", "pis-pasep", "pix", "boleto", "cartao", "ie"];
16
+ var SUPPORTED_TYPES = ["cnpj", "cpf", "cep", "telefone", "cnh", "renavam", "titulo-eleitor", "processo-judicial", "rg", "nfe-chave", "brcode", "placa", "pis-pasep", "pix", "boleto", "cartao", "ie"];
21
17
  var EXIT = {
22
18
  OK: 0,
23
19
  INVALID: 1,
24
20
  USAGE: 2
25
21
  };
26
22
 
23
+ // src/commands/bancos/lookup.ts
24
+ import {
25
+ BANCOS_DATA_VERSION,
26
+ getBancoPorCodigo,
27
+ getBancoPorIspb
28
+ } from "@br-validators/core/bancos";
29
+ function normalizeBancosLookupInput(raw) {
30
+ const digits = raw.replace(/\D/g, "");
31
+ if (digits.length === 8) {
32
+ return { kind: "ispb", value: digits.padStart(8, "0") };
33
+ }
34
+ if (digits.length >= 1 && digits.length <= 3) {
35
+ return { kind: "codigo", value: digits.padStart(3, "0").slice(-3) };
36
+ }
37
+ return null;
38
+ }
39
+ function lookupBanco(raw) {
40
+ const normalized = normalizeBancosLookupInput(raw);
41
+ if (!normalized) {
42
+ return void 0;
43
+ }
44
+ return normalized.kind === "ispb" ? getBancoPorIspb(normalized.value) : getBancoPorCodigo(normalized.value);
45
+ }
46
+ function formatBancoHuman(banco) {
47
+ return `${banco.codigo} \u2014 ${banco.nome} (ISPB ${banco.ispb})`;
48
+ }
49
+ function runBancosLookupCommand(input, options, io = { stdout: [], stderr: [] }) {
50
+ const normalized = normalizeBancosLookupInput(input);
51
+ if (!normalized) {
52
+ io.stderr.push("Invalid bank code or ISPB. Use 3-digit COMPE (e.g. 001) or 8-digit ISPB.");
53
+ return EXIT.USAGE;
54
+ }
55
+ const banco = lookupBanco(input);
56
+ if (!banco) {
57
+ io.stderr.push(`Bank not found: ${input}`);
58
+ return EXIT.INVALID;
59
+ }
60
+ if (options.json) {
61
+ const payload = { ok: true, banco };
62
+ if (options.verbose) {
63
+ payload.capturadoEm = BANCOS_DATA_VERSION.capturadoEm;
64
+ }
65
+ io.stdout.push(JSON.stringify(payload, null, 2));
66
+ return EXIT.OK;
67
+ }
68
+ io.stdout.push(formatBancoHuman(banco));
69
+ if (options.verbose) {
70
+ io.stdout.push(`capturadoEm: ${BANCOS_DATA_VERSION.capturadoEm}`);
71
+ }
72
+ return EXIT.OK;
73
+ }
74
+ function runBancosLookup(value, options, io = { stdout: [], stderr: [] }) {
75
+ if (!value?.trim()) {
76
+ io.stderr.push("Missing bank code or ISPB. Pass COMPE (001) or ISPB (8 digits).");
77
+ return EXIT.USAGE;
78
+ }
79
+ return runBancosLookupCommand(value.trim(), options, io);
80
+ }
81
+
82
+ // src/commands/bancos/list.ts
83
+ function sliceBancos(limit) {
84
+ const all = getBancos();
85
+ if (limit === void 0 || !Number.isFinite(limit) || limit <= 0) {
86
+ return all;
87
+ }
88
+ return all.slice(0, limit);
89
+ }
90
+ function runBancosListCommand(options, io = { stdout: [], stderr: [] }) {
91
+ const bancos = sliceBancos(options.limit);
92
+ if (options.json) {
93
+ const payload = {
94
+ ok: true,
95
+ total: bancos.length,
96
+ bancos
97
+ };
98
+ if (options.verbose) {
99
+ payload.capturadoEm = BANCOS_DATA_VERSION2.capturadoEm;
100
+ }
101
+ io.stdout.push(JSON.stringify(payload, null, 2));
102
+ return EXIT.OK;
103
+ }
104
+ for (const banco of bancos) {
105
+ io.stdout.push(formatBancoHuman(banco));
106
+ }
107
+ if (options.verbose) {
108
+ io.stdout.push(`capturadoEm: ${BANCOS_DATA_VERSION2.capturadoEm}`);
109
+ }
110
+ return EXIT.OK;
111
+ }
112
+ function runBancosList(options, io = { stdout: [], stderr: [] }) {
113
+ return runBancosListCommand(options, io);
114
+ }
115
+
116
+ // src/commands/reference-lookup/registry.ts
117
+ import {
118
+ CEST_DATA_VERSION,
119
+ getCestPorCodigo
120
+ } from "@br-validators/core/cest";
121
+ import {
122
+ INCOTERMS_DATA_VERSION,
123
+ getIncotermPorCodigo
124
+ } from "@br-validators/core/incoterms";
125
+ import {
126
+ MOEDAS_DATA_VERSION,
127
+ getMoedaPorCodigo
128
+ } from "@br-validators/core/moedas";
129
+ import {
130
+ NATUREZA_JURIDICA_DATA_VERSION,
131
+ getNaturezaJuridicaPorCodigo
132
+ } from "@br-validators/core/natureza-juridica";
133
+ import { NBS_DATA_VERSION, getNbsPorCodigo } from "@br-validators/core/nbs";
134
+ import {
135
+ PAISES_BACEN_DATA_VERSION,
136
+ getPaisPorCodigoBacen
137
+ } from "@br-validators/core/paises-bacen";
138
+ import {
139
+ AEROPORTOS_DATA_VERSION,
140
+ getAeroportoPorIata,
141
+ getAeroportoPorIcao
142
+ } from "@br-validators/core/aeroportos";
143
+ import { PORTOS_DATA_VERSION, getPortoPorCodigo } from "@br-validators/core/portos";
144
+ import {
145
+ CNAES_DATA_VERSION,
146
+ getCnaePorCodigo
147
+ } from "@br-validators/core/cnaes";
148
+ import {
149
+ CFOP_DATA_VERSION,
150
+ getCfopPorCodigo
151
+ } from "@br-validators/core/cfop";
152
+ import { NCM_DATA_VERSION, getNcmPorCodigo } from "@br-validators/core/ncm";
153
+ import { CBO_DATA_VERSION, getCboPorCodigo } from "@br-validators/core/cbo";
154
+ var REFERENCE_LOOKUP_COMMANDS = [
155
+ "natureza-juridica",
156
+ "nbs",
157
+ "cest",
158
+ "cnae",
159
+ "cfop",
160
+ "ncm",
161
+ "cbo",
162
+ "moedas",
163
+ "paises-bacen",
164
+ "incoterms",
165
+ "portos",
166
+ "aeroportos"
167
+ ];
168
+ var REFERENCE_SEARCH_COMMANDS = ["cnae", "cfop", "ncm", "cbo"];
169
+ function lookupAeroporto(input) {
170
+ const normalized = input.trim().toUpperCase();
171
+ if (/^[A-Z0-9]{3}$/.test(normalized)) {
172
+ return getAeroportoPorIata(normalized);
173
+ }
174
+ if (/^[A-Z]{4}$/.test(normalized)) {
175
+ return getAeroportoPorIcao(normalized);
176
+ }
177
+ return void 0;
178
+ }
179
+ var REFERENCE_LOOKUP_MODULES = {
180
+ "natureza-juridica": {
181
+ command: "natureza-juridica",
182
+ description: "RFB legal nature codes \u2014 offline lookup",
183
+ resultKey: "naturezaJuridica",
184
+ capturadoEm: NATUREZA_JURIDICA_DATA_VERSION.capturadoEm,
185
+ lookup: (input) => getNaturezaJuridicaPorCodigo(input),
186
+ formatHuman: (result) => {
187
+ const row = result;
188
+ return `${row.codigo} \u2014 ${row.descricao}`;
189
+ }
190
+ },
191
+ nbs: {
192
+ command: "nbs",
193
+ description: "NFSe NBS service codes \u2014 offline lookup",
194
+ resultKey: "nbs",
195
+ capturadoEm: NBS_DATA_VERSION.capturadoEm,
196
+ lookup: (input) => getNbsPorCodigo(input),
197
+ formatHuman: (result) => {
198
+ const row = result;
199
+ return `${row.codigo} \u2014 ${row.descricao}`;
200
+ }
201
+ },
202
+ cest: {
203
+ command: "cest",
204
+ description: "CONFAZ CEST ST codes \u2014 offline lookup",
205
+ resultKey: "cest",
206
+ capturadoEm: CEST_DATA_VERSION.capturadoEm,
207
+ lookup: (input) => getCestPorCodigo(input),
208
+ formatHuman: (result) => {
209
+ const row = result;
210
+ return `${row.codigo} \u2014 ${row.descricao}`;
211
+ }
212
+ },
213
+ cnae: {
214
+ command: "cnae",
215
+ description: "IBGE CNAE 2.3 subclasses \u2014 offline lookup",
216
+ resultKey: "cnae",
217
+ capturadoEm: CNAES_DATA_VERSION.capturadoEm,
218
+ lookup: (input) => getCnaePorCodigo(input),
219
+ formatHuman: (result) => {
220
+ const row = result;
221
+ return `${row.codigo} \u2014 ${row.descricao}`;
222
+ }
223
+ },
224
+ cfop: {
225
+ command: "cfop",
226
+ description: "CONFAZ CFOP fiscal operations \u2014 offline lookup",
227
+ resultKey: "cfop",
228
+ capturadoEm: CFOP_DATA_VERSION.capturadoEm,
229
+ lookup: (input) => getCfopPorCodigo(input),
230
+ formatHuman: (result) => {
231
+ const row = result;
232
+ return `${row.codigo} \u2014 ${row.descricao}`;
233
+ }
234
+ },
235
+ ncm: {
236
+ command: "ncm",
237
+ description: "Siscomex NCM Mercosur codes \u2014 offline lookup",
238
+ resultKey: "ncm",
239
+ capturadoEm: NCM_DATA_VERSION.capturadoEm,
240
+ lookup: (input) => getNcmPorCodigo(input),
241
+ formatHuman: (result) => {
242
+ const row = result;
243
+ return `${row.codigo} \u2014 ${row.descricao}`;
244
+ }
245
+ },
246
+ cbo: {
247
+ command: "cbo",
248
+ description: "MTE CBO 2002 occupations \u2014 offline lookup",
249
+ resultKey: "cbo",
250
+ capturadoEm: CBO_DATA_VERSION.capturadoEm,
251
+ lookup: (input) => getCboPorCodigo(input),
252
+ formatHuman: (result) => {
253
+ const row = result;
254
+ return `${row.codigo} \u2014 ${row.descricao}`;
255
+ }
256
+ },
257
+ moedas: {
258
+ command: "moedas",
259
+ description: "ISO 4217 + Bacen PTAX currencies \u2014 offline lookup",
260
+ resultKey: "moeda",
261
+ capturadoEm: MOEDAS_DATA_VERSION.capturadoEm,
262
+ lookup: (input) => getMoedaPorCodigo(input),
263
+ formatHuman: (result) => {
264
+ const row = result;
265
+ const symbol = row.simbolo ?? "\u2014";
266
+ return `${row.codigo} \u2014 ${row.nome} (${symbol})`;
267
+ }
268
+ },
269
+ "paises-bacen": {
270
+ command: "paises-bacen",
271
+ description: "NF-e Bacen country codes \u2014 offline lookup",
272
+ resultKey: "pais",
273
+ capturadoEm: PAISES_BACEN_DATA_VERSION.capturadoEm,
274
+ lookup: (input) => getPaisPorCodigoBacen(input),
275
+ formatHuman: (result) => {
276
+ const row = result;
277
+ return `${row.codigo} \u2014 ${row.nome}`;
278
+ }
279
+ },
280
+ incoterms: {
281
+ command: "incoterms",
282
+ description: "ICC Incoterms 2020 \u2014 offline lookup",
283
+ resultKey: "incoterm",
284
+ capturadoEm: INCOTERMS_DATA_VERSION.capturadoEm,
285
+ lookup: (input) => getIncotermPorCodigo(input),
286
+ formatHuman: (result) => {
287
+ const row = result;
288
+ return `${row.codigo} \u2014 ${row.nome} (${row.edicao})`;
289
+ }
290
+ },
291
+ portos: {
292
+ command: "portos",
293
+ description: "ANTAQ port installations \u2014 offline lookup",
294
+ resultKey: "porto",
295
+ capturadoEm: PORTOS_DATA_VERSION.capturadoEm,
296
+ lookup: (input) => getPortoPorCodigo(input),
297
+ formatHuman: (result) => {
298
+ const row = result;
299
+ return `${row.codigo} \u2014 ${row.nome} (${row.uf})`;
300
+ }
301
+ },
302
+ aeroportos: {
303
+ command: "aeroportos",
304
+ description: "ANAC public aerodromos \u2014 offline lookup by IATA or ICAO",
305
+ resultKey: "aeroporto",
306
+ capturadoEm: AEROPORTOS_DATA_VERSION.capturadoEm,
307
+ lookup: lookupAeroporto,
308
+ formatHuman: (result) => {
309
+ const row = result;
310
+ const iata = row.iata ?? "\u2014";
311
+ return `${iata}/${row.icao} \u2014 ${row.nome} (${row.uf})`;
312
+ }
313
+ }
314
+ };
315
+ function isReferenceLookupCommand(value) {
316
+ return REFERENCE_LOOKUP_COMMANDS.includes(value);
317
+ }
318
+ function isReferenceSearchCommand(value) {
319
+ return REFERENCE_SEARCH_COMMANDS.includes(value);
320
+ }
321
+
322
+ // src/commands/reference-lookup/lookup.ts
323
+ function runReferenceLookupCommand(command, input, options, io = { stdout: [], stderr: [] }) {
324
+ const module = REFERENCE_LOOKUP_MODULES[command];
325
+ const trimmed = input.trim();
326
+ if (trimmed.length === 0) {
327
+ io.stderr.push(`Missing code. Pass a lookup value for ${command}.`);
328
+ return EXIT.USAGE;
329
+ }
330
+ const result = module.lookup(trimmed);
331
+ if (!result) {
332
+ io.stderr.push(`Not found: ${trimmed}`);
333
+ return EXIT.INVALID;
334
+ }
335
+ if (options.json) {
336
+ const payload = {
337
+ ok: true,
338
+ [module.resultKey]: result,
339
+ ...options.verbose ? { capturadoEm: module.capturadoEm } : {}
340
+ };
341
+ io.stdout.push(JSON.stringify(payload, null, 2));
342
+ return EXIT.OK;
343
+ }
344
+ io.stdout.push(module.formatHuman(result));
345
+ if (options.verbose) {
346
+ io.stdout.push(`capturadoEm: ${module.capturadoEm}`);
347
+ }
348
+ return EXIT.OK;
349
+ }
350
+ function runReferenceLookup(command, value, options, io = { stdout: [], stderr: [] }) {
351
+ if (!isReferenceLookupCommand(command)) {
352
+ io.stderr.push(`Unknown reference lookup command: ${command}`);
353
+ return EXIT.USAGE;
354
+ }
355
+ if (!value?.trim()) {
356
+ io.stderr.push(`Missing code. Usage: br-validators ${command} lookup <codigo>`);
357
+ return EXIT.USAGE;
358
+ }
359
+ return runReferenceLookupCommand(command, value.trim(), options, io);
360
+ }
361
+
362
+ // src/commands/reference-lookup/search.ts
363
+ import { searchCbo } from "@br-validators/core/cbo";
364
+ import { searchCnaes } from "@br-validators/core/cnaes";
365
+ import { searchCfop } from "@br-validators/core/cfop";
366
+ import { searchNcm } from "@br-validators/core/ncm";
367
+ function runSearch(command, query, limit) {
368
+ switch (command) {
369
+ case "cnae":
370
+ return searchCnaes(query, { limit });
371
+ case "cfop":
372
+ return searchCfop(query, { limit });
373
+ case "ncm":
374
+ return searchNcm(query, { limit });
375
+ case "cbo":
376
+ return searchCbo(query, { limit });
377
+ }
378
+ }
379
+ function formatSearchHuman(command, results) {
380
+ const module = REFERENCE_LOOKUP_MODULES[command];
381
+ return results.map((row) => module.formatHuman(row));
382
+ }
383
+ function runReferenceSearchCommand(command, query, options, io = { stdout: [], stderr: [] }) {
384
+ const trimmed = query.trim();
385
+ if (trimmed.length === 0) {
386
+ io.stderr.push(`Missing search query. Pass a description fragment for ${command}.`);
387
+ return EXIT.USAGE;
388
+ }
389
+ const limit = options.limit !== void 0 && options.limit > 0 ? options.limit : 10;
390
+ const results = runSearch(command, trimmed, limit);
391
+ const module = REFERENCE_LOOKUP_MODULES[command];
392
+ const resultKey = `${module.resultKey}s`;
393
+ if (options.json) {
394
+ const payload = {
395
+ ok: true,
396
+ query: trimmed,
397
+ total: results.length,
398
+ [resultKey]: results,
399
+ ...options.verbose ? { capturadoEm: module.capturadoEm } : {}
400
+ };
401
+ io.stdout.push(JSON.stringify(payload, null, 2));
402
+ return EXIT.OK;
403
+ }
404
+ if (results.length === 0) {
405
+ io.stderr.push(`No matches for: ${trimmed}`);
406
+ return EXIT.INVALID;
407
+ }
408
+ for (const line of formatSearchHuman(command, results)) {
409
+ io.stdout.push(line);
410
+ }
411
+ if (options.verbose) {
412
+ io.stdout.push(`capturadoEm: ${module.capturadoEm}`);
413
+ }
414
+ return EXIT.OK;
415
+ }
416
+ function runReferenceSearch(command, query, options, io = { stdout: [], stderr: [] }) {
417
+ if (!isReferenceSearchCommand(command)) {
418
+ io.stderr.push(`Unknown reference search command: ${command}`);
419
+ return EXIT.USAGE;
420
+ }
421
+ if (!query?.trim()) {
422
+ io.stderr.push(`Missing query. Usage: br-validators ${command} search <query>`);
423
+ return EXIT.USAGE;
424
+ }
425
+ return runReferenceSearchCommand(command, query.trim(), options, io);
426
+ }
427
+
428
+ // src/commands/ibge/lookup.ts
429
+ import {
430
+ getMunicipioPorCodigo,
431
+ IBGE_DATA_VERSION
432
+ } from "@br-validators/core/ibge";
433
+ function normalizeIbgeMunicipioCode(raw) {
434
+ const digits = raw.replace(/\D/g, "");
435
+ if (digits.length !== 7) {
436
+ return null;
437
+ }
438
+ return Number(digits);
439
+ }
440
+ function formatMunicipioHuman(municipio) {
441
+ return `${municipio.codigo} \u2014 ${municipio.nome} (${municipio.uf})`;
442
+ }
443
+ function runIbgeLookupCommand(input, options, io = { stdout: [], stderr: [] }) {
444
+ const codigo = normalizeIbgeMunicipioCode(input);
445
+ if (codigo === null) {
446
+ io.stderr.push("Invalid IBGE municipality code. Use 7 digits (e.g. 3550308).");
447
+ return EXIT.USAGE;
448
+ }
449
+ const municipio = getMunicipioPorCodigo(codigo);
450
+ if (!municipio) {
451
+ io.stderr.push(`Municipality not found: ${input}`);
452
+ return EXIT.INVALID;
453
+ }
454
+ if (options.json) {
455
+ const payload = {
456
+ ok: true,
457
+ municipio
458
+ };
459
+ if (options.verbose) {
460
+ payload.capturadoEm = IBGE_DATA_VERSION.capturadoEm;
461
+ }
462
+ io.stdout.push(JSON.stringify(payload, null, 2));
463
+ return EXIT.OK;
464
+ }
465
+ io.stdout.push(formatMunicipioHuman(municipio));
466
+ if (options.verbose) {
467
+ io.stdout.push(`capturadoEm: ${IBGE_DATA_VERSION.capturadoEm}`);
468
+ }
469
+ return EXIT.OK;
470
+ }
471
+ function runIbgeLookup(value, options, io = { stdout: [], stderr: [] }) {
472
+ if (!value?.trim()) {
473
+ io.stderr.push("Missing IBGE municipality code. Pass a 7-digit code.");
474
+ return EXIT.USAGE;
475
+ }
476
+ return runIbgeLookupCommand(value.trim(), options, io);
477
+ }
478
+
479
+ // src/commands/ibge/list.ts
480
+ import {
481
+ getEstados,
482
+ getMunicipios,
483
+ IBGE_DATA_VERSION as IBGE_DATA_VERSION2
484
+ } from "@br-validators/core/ibge";
485
+ function sliceRows(rows, limit) {
486
+ if (limit === void 0 || !Number.isFinite(limit) || limit <= 0) {
487
+ return rows;
488
+ }
489
+ return rows.slice(0, limit);
490
+ }
491
+ function formatEstadoHuman(estado) {
492
+ return `${estado.codigo} \u2014 ${estado.sigla} \u2014 ${estado.nome}`;
493
+ }
494
+ function runIbgeListEstadosCommand(options, io = { stdout: [], stderr: [] }) {
495
+ const estados = sliceRows(getEstados(), options.limit);
496
+ if (options.json) {
497
+ const payload = {
498
+ ok: true,
499
+ total: estados.length,
500
+ estados
501
+ };
502
+ if (options.verbose) {
503
+ payload.capturadoEm = IBGE_DATA_VERSION2.capturadoEm;
504
+ }
505
+ io.stdout.push(JSON.stringify(payload, null, 2));
506
+ return EXIT.OK;
507
+ }
508
+ for (const estado of estados) {
509
+ io.stdout.push(formatEstadoHuman(estado));
510
+ }
511
+ if (options.verbose) {
512
+ io.stdout.push(`capturadoEm: ${IBGE_DATA_VERSION2.capturadoEm}`);
513
+ }
514
+ return EXIT.OK;
515
+ }
516
+ function runIbgeListMunicipiosCommand(options, io = { stdout: [], stderr: [] }) {
517
+ const uf = options.uf?.trim().toUpperCase();
518
+ const municipios = sliceRows(getMunicipios(uf ? { uf } : void 0), options.limit);
519
+ if (options.json) {
520
+ const payload = {
521
+ ok: true,
522
+ total: municipios.length,
523
+ municipios,
524
+ ...uf ? { uf } : {}
525
+ };
526
+ if (options.verbose) {
527
+ payload.capturadoEm = IBGE_DATA_VERSION2.capturadoEm;
528
+ }
529
+ io.stdout.push(JSON.stringify(payload, null, 2));
530
+ return EXIT.OK;
531
+ }
532
+ for (const municipio of municipios) {
533
+ io.stdout.push(formatMunicipioHuman(municipio));
534
+ }
535
+ if (options.verbose) {
536
+ io.stdout.push(`capturadoEm: ${IBGE_DATA_VERSION2.capturadoEm}`);
537
+ }
538
+ return EXIT.OK;
539
+ }
540
+ function runIbgeList(target, options, io = { stdout: [], stderr: [] }) {
541
+ if (target === "estados") {
542
+ return runIbgeListEstadosCommand(options, io);
543
+ }
544
+ return runIbgeListMunicipiosCommand(options, io);
545
+ }
546
+
547
+ // src/commands/feriados/list.ts
548
+ import {
549
+ FERIADOS_DATA_VERSION,
550
+ getFeriadosNacionais
551
+ } from "@br-validators/core/feriados";
552
+ function resolveYear(year) {
553
+ if (year !== void 0 && Number.isInteger(year) && year >= 1900 && year <= 2100) {
554
+ return year;
555
+ }
556
+ return (/* @__PURE__ */ new Date()).getUTCFullYear();
557
+ }
558
+ function formatFeriadoHuman(feriado) {
559
+ return `${feriado.data} \u2014 ${feriado.nome} (${feriado.tipo})`;
560
+ }
561
+ function runFeriadosListCommand(options, io = { stdout: [], stderr: [] }) {
562
+ const year = resolveYear(options.year);
563
+ const feriados = getFeriadosNacionais(year);
564
+ if (options.json) {
565
+ const payload = {
566
+ ok: true,
567
+ year,
568
+ total: feriados.length,
569
+ feriados
570
+ };
571
+ if (options.verbose) {
572
+ payload.capturadoEm = FERIADOS_DATA_VERSION.capturadoEm;
573
+ }
574
+ io.stdout.push(JSON.stringify(payload, null, 2));
575
+ return EXIT.OK;
576
+ }
577
+ for (const feriado of feriados) {
578
+ io.stdout.push(formatFeriadoHuman(feriado));
579
+ }
580
+ if (options.verbose) {
581
+ io.stdout.push(`capturadoEm: ${FERIADOS_DATA_VERSION.capturadoEm}`);
582
+ }
583
+ return EXIT.OK;
584
+ }
585
+ function runFeriadosList(options, io = { stdout: [], stderr: [] }) {
586
+ return runFeriadosListCommand(options, io);
587
+ }
588
+
589
+ // src/commands/tse-municipios/lookup.ts
590
+ import {
591
+ getCodigosTsePorMunicipio,
592
+ getMunicipioIbgePorCodigoTse,
593
+ TSE_MUNICIPIOS_DATA_VERSION
594
+ } from "@br-validators/core/tse-municipios";
595
+ import { getMunicipioPorCodigo as getMunicipioPorCodigo2 } from "@br-validators/core/ibge";
596
+ function normalizeTseInput(raw) {
597
+ const digits = raw.replace(/\D/g, "");
598
+ if (digits.length === 5) {
599
+ return { kind: "tse", value: digits.padStart(5, "0") };
600
+ }
601
+ if (digits.length === 7) {
602
+ return { kind: "ibge", value: Number(digits) };
603
+ }
604
+ return null;
605
+ }
606
+ function lookupTseMunicipio(raw) {
607
+ const normalized = normalizeTseInput(raw);
608
+ if (!normalized) {
609
+ return void 0;
610
+ }
611
+ if (normalized.kind === "tse") {
612
+ const ibgeCodigo = getMunicipioIbgePorCodigoTse(normalized.value);
613
+ if (ibgeCodigo === void 0) {
614
+ return void 0;
615
+ }
616
+ return { kind: "tse-to-ibge", codigoTse: normalized.value, ibgeCodigo };
617
+ }
618
+ const codigosTse = getCodigosTsePorMunicipio(normalized.value);
619
+ if (codigosTse.length === 0) {
620
+ return void 0;
621
+ }
622
+ return { kind: "ibge-to-tse", ibgeCodigo: normalized.value, codigosTse };
623
+ }
624
+ function formatTseLookupHuman(result) {
625
+ if (result.kind === "tse-to-ibge") {
626
+ const municipio2 = getMunicipioPorCodigo2(result.ibgeCodigo);
627
+ const name2 = municipio2 ? `${municipio2.nome} (${municipio2.uf})` : String(result.ibgeCodigo);
628
+ return `TSE ${result.codigoTse} \u2192 IBGE ${result.ibgeCodigo} \u2014 ${name2}`;
629
+ }
630
+ const municipio = getMunicipioPorCodigo2(result.ibgeCodigo);
631
+ const name = municipio ? `${municipio.nome} (${municipio.uf})` : String(result.ibgeCodigo);
632
+ return `IBGE ${result.ibgeCodigo} \u2014 ${name} \u2192 TSE ${result.codigosTse.join(", ")}`;
633
+ }
634
+ function runTseMunicipiosLookupCommand(input, options, io = { stdout: [], stderr: [] }) {
635
+ const normalized = normalizeTseInput(input);
636
+ if (!normalized) {
637
+ io.stderr.push("Invalid code. Use 5-digit TSE or 7-digit IBGE municipality code.");
638
+ return EXIT.USAGE;
639
+ }
640
+ const result = lookupTseMunicipio(input);
641
+ if (!result) {
642
+ io.stderr.push(`Mapping not found: ${input}`);
643
+ return EXIT.INVALID;
644
+ }
645
+ if (options.json) {
646
+ const payload = {
647
+ ok: true,
648
+ mapping: result
649
+ };
650
+ if (options.verbose) {
651
+ payload.capturadoEm = TSE_MUNICIPIOS_DATA_VERSION.capturadoEm;
652
+ }
653
+ io.stdout.push(JSON.stringify(payload, null, 2));
654
+ return EXIT.OK;
655
+ }
656
+ io.stdout.push(formatTseLookupHuman(result));
657
+ if (options.verbose) {
658
+ io.stdout.push(`capturadoEm: ${TSE_MUNICIPIOS_DATA_VERSION.capturadoEm}`);
659
+ }
660
+ return EXIT.OK;
661
+ }
662
+ function runTseMunicipiosLookup(value, options, io = { stdout: [], stderr: [] }) {
663
+ if (!value?.trim()) {
664
+ io.stderr.push("Missing code. Pass a 5-digit TSE or 7-digit IBGE municipality code.");
665
+ return EXIT.USAGE;
666
+ }
667
+ return runTseMunicipiosLookupCommand(value.trim(), options, io);
668
+ }
669
+
670
+ // src/commands/cep/faixa.ts
671
+ import {
672
+ CEP_FAIXA_DATA_VERSION,
673
+ getCepFaixaInfo
674
+ } from "@br-validators/core/cep";
675
+ function normalizePrefix(raw) {
676
+ const digits = raw.replace(/\D/g, "");
677
+ if (digits.length < 5) {
678
+ return null;
679
+ }
680
+ return digits.slice(0, 5);
681
+ }
682
+ function formatCepFaixaHuman(faixa) {
683
+ return `${faixa.prefixo} \u2014 ${faixa.cidade} (${faixa.uf}) \xB7 IBGE ${faixa.codigoIbge}`;
684
+ }
685
+ function runCepFaixaCommand(input, options, io = { stdout: [], stderr: [] }) {
686
+ const prefix = normalizePrefix(input);
687
+ if (prefix === null) {
688
+ io.stderr.push("Invalid CEP prefix. Use at least 5 digits (e.g. 01310).");
689
+ return EXIT.USAGE;
690
+ }
691
+ const faixa = getCepFaixaInfo(prefix);
692
+ if (!faixa) {
693
+ io.stderr.push(`CEP prefix not found: ${input}`);
694
+ return EXIT.INVALID;
695
+ }
696
+ if (options.json) {
697
+ const payload = {
698
+ ok: true,
699
+ faixa
700
+ };
701
+ if (options.verbose) {
702
+ payload.capturadoEm = CEP_FAIXA_DATA_VERSION.capturadoEm;
703
+ }
704
+ io.stdout.push(JSON.stringify(payload, null, 2));
705
+ return EXIT.OK;
706
+ }
707
+ io.stdout.push(formatCepFaixaHuman(faixa));
708
+ if (options.verbose) {
709
+ io.stdout.push(`capturadoEm: ${CEP_FAIXA_DATA_VERSION.capturadoEm}`);
710
+ }
711
+ return EXIT.OK;
712
+ }
713
+ function runCepFaixa(value, options, io = { stdout: [], stderr: [] }) {
714
+ if (!value?.trim()) {
715
+ io.stderr.push("Missing CEP prefix. Pass at least 5 digits.");
716
+ return EXIT.USAGE;
717
+ }
718
+ return runCepFaixaCommand(value.trim(), options, io);
719
+ }
720
+
721
+ // src/commands/ddd/lookup.ts
722
+ import {
723
+ getDddInfo,
724
+ TELEFONE_DDD_DATA_VERSION
725
+ } from "@br-validators/core/telefone";
726
+ function normalizeDdd(raw) {
727
+ const digits = raw.replace(/\D/g, "");
728
+ if (digits.length === 0) {
729
+ return null;
730
+ }
731
+ return digits.padStart(2, "0").slice(-2);
732
+ }
733
+ function formatDddHuman(info) {
734
+ const municipios = info.municipios.slice(0, 3).join(", ");
735
+ const suffix = info.municipios.length > 3 ? "\u2026" : "";
736
+ return `DDD ${info.ddd} \u2014 ${info.uf} / ${info.regiao} \u2014 ${municipios}${suffix}`;
737
+ }
738
+ function runDddLookupCommand(input, options, io = { stdout: [], stderr: [] }) {
739
+ const ddd = normalizeDdd(input);
740
+ if (ddd === null) {
741
+ io.stderr.push("Invalid DDD. Use 2 digits (e.g. 11).");
742
+ return EXIT.USAGE;
743
+ }
744
+ const info = getDddInfo(ddd);
745
+ if (!info) {
746
+ io.stderr.push(`DDD not found: ${input}`);
747
+ return EXIT.INVALID;
748
+ }
749
+ if (options.json) {
750
+ const payload = {
751
+ ok: true,
752
+ ddd: info
753
+ };
754
+ if (options.verbose) {
755
+ payload.capturadoEm = TELEFONE_DDD_DATA_VERSION.capturadoEm;
756
+ }
757
+ io.stdout.push(JSON.stringify(payload, null, 2));
758
+ return EXIT.OK;
759
+ }
760
+ io.stdout.push(formatDddHuman(info));
761
+ if (options.verbose) {
762
+ io.stdout.push(`capturadoEm: ${TELEFONE_DDD_DATA_VERSION.capturadoEm}`);
763
+ }
764
+ return EXIT.OK;
765
+ }
766
+ function runDddLookup(value, options, io = { stdout: [], stderr: [] }) {
767
+ if (!value?.trim()) {
768
+ io.stderr.push("Missing DDD code. Pass 2 digits (e.g. 11).");
769
+ return EXIT.USAGE;
770
+ }
771
+ return runDddLookupCommand(value.trim(), options, io);
772
+ }
773
+
27
774
  // src/commands/brcode.ts
775
+ import {
776
+ BRCODE_OFFICIAL_SOURCE_URL,
777
+ parseBrCode,
778
+ validateBrCode
779
+ } from "@br-validators/core";
28
780
  function resolveInput(value, fileContent) {
29
781
  const input = value ?? fileContent?.trim();
30
782
  if (!input) {
@@ -179,6 +931,45 @@ function printNfeChaveValidation(result, options, io = { stdout: [], stderr: []
179
931
  io.stderr.push(`message: ${result.message}`);
180
932
  return EXIT.INVALID;
181
933
  }
934
+ function printProcessoJudicialValidation(result, options, io = { stdout: [], stderr: [] }) {
935
+ if (options.json) {
936
+ io.stdout.push(
937
+ JSON.stringify(
938
+ result.ok ? {
939
+ ok: true,
940
+ value: result.value,
941
+ format: result.format,
942
+ segments: result.segments,
943
+ ...options.source ? { source: options.source } : {}
944
+ } : { ok: false, code: result.code, message: result.message },
945
+ null,
946
+ 2
947
+ )
948
+ );
949
+ return result.ok ? EXIT.OK : EXIT.INVALID;
950
+ }
951
+ if (options.quiet) {
952
+ return result.ok ? EXIT.OK : EXIT.INVALID;
953
+ }
954
+ if (result.ok) {
955
+ io.stdout.push(`valid: yes (${result.format})`);
956
+ io.stdout.push(`value: ${result.value}`);
957
+ io.stdout.push(`sequencial: ${result.segments.sequencial}`);
958
+ io.stdout.push(`checkDigits: ${result.segments.checkDigits}`);
959
+ io.stdout.push(`ano: ${result.segments.ano}`);
960
+ io.stdout.push(`segmentoJustica: ${result.segments.segmentoJustica}`);
961
+ io.stdout.push(`tribunal: ${result.segments.tribunal}`);
962
+ io.stdout.push(`origem: ${result.segments.origem}`);
963
+ if (options.source) {
964
+ io.stdout.push(`source: ${options.source}`);
965
+ }
966
+ return EXIT.OK;
967
+ }
968
+ io.stderr.push("valid: no");
969
+ io.stderr.push(`code: ${result.code}`);
970
+ io.stderr.push(`message: ${result.message}`);
971
+ return EXIT.INVALID;
972
+ }
182
973
  function printFormat(result, options, io = { stdout: [], stderr: [] }) {
183
974
  if (options.json) {
184
975
  io.stdout.push(JSON.stringify(result, null, 2));
@@ -204,23 +995,176 @@ function printStrip(value, options, io = { stdout: [] }) {
204
995
  return EXIT.OK;
205
996
  }
206
997
 
207
- // src/commands/cep.ts
208
- function resolveInput2(value, fileContent) {
998
+ // src/commands/cep.ts
999
+ function resolveInput2(value, fileContent) {
1000
+ const input = value ?? fileContent?.trim();
1001
+ if (!input) {
1002
+ return null;
1003
+ }
1004
+ return input;
1005
+ }
1006
+ function runCepCommand(action, input, options, io = { stdout: [], stderr: [] }) {
1007
+ const source = options.source ? CEP_OFFICIAL_SOURCE_URL : void 0;
1008
+ switch (action) {
1009
+ case "validate":
1010
+ return printValidation(validateCep(input), { json: options.json, quiet: options.quiet, source }, io);
1011
+ case "format":
1012
+ return printFormat(formatCep(input), { json: options.json, quiet: options.quiet }, io);
1013
+ case "strip":
1014
+ return printStrip(stripCep(input), { json: options.json }, io);
1015
+ default: {
1016
+ const _exhaustive = action;
1017
+ io.stderr.push(`Unknown action: ${_exhaustive}`);
1018
+ return EXIT.USAGE;
1019
+ }
1020
+ }
1021
+ }
1022
+ function runCep(action, value, options, io = { stdout: [], stderr: [] }) {
1023
+ const input = resolveInput2(value, options.file);
1024
+ if (input === null) {
1025
+ io.stderr.push("Missing CEP value. Pass an argument or use --file.");
1026
+ return EXIT.USAGE;
1027
+ }
1028
+ return runCepCommand(action, input, options, io);
1029
+ }
1030
+
1031
+ // src/commands/telefone.ts
1032
+ import {
1033
+ TELEFONE_OFFICIAL_SOURCE_URL,
1034
+ formatTelefone,
1035
+ stripTelefone,
1036
+ validateTelefone
1037
+ } from "@br-validators/core";
1038
+ function resolveInput3(value, fileContent) {
1039
+ const input = value ?? fileContent?.trim();
1040
+ if (!input) {
1041
+ return null;
1042
+ }
1043
+ return input;
1044
+ }
1045
+ function printTelefoneValidation(result, options, io = { stdout: [], stderr: [] }) {
1046
+ if (options.json) {
1047
+ io.stdout.push(
1048
+ JSON.stringify(
1049
+ result.ok ? {
1050
+ ok: true,
1051
+ value: result.value,
1052
+ tipo: result.tipo,
1053
+ format: result.format,
1054
+ ...options.source ? { source: options.source } : {}
1055
+ } : { ok: false, code: result.code, message: result.message },
1056
+ null,
1057
+ 2
1058
+ )
1059
+ );
1060
+ return result.ok ? EXIT.OK : EXIT.INVALID;
1061
+ }
1062
+ if (options.quiet) {
1063
+ return result.ok ? EXIT.OK : EXIT.INVALID;
1064
+ }
1065
+ if (result.ok) {
1066
+ io.stdout.push(`valid: yes (${result.tipo})`);
1067
+ io.stdout.push(`value: ${result.value}`);
1068
+ io.stdout.push(`format: ${result.format}`);
1069
+ if (options.source) {
1070
+ io.stdout.push(`source: ${options.source}`);
1071
+ }
1072
+ return EXIT.OK;
1073
+ }
1074
+ io.stderr.push("valid: no");
1075
+ io.stderr.push(`code: ${result.code}`);
1076
+ io.stderr.push(`message: ${result.message}`);
1077
+ return EXIT.INVALID;
1078
+ }
1079
+ function runTelefoneCommand(action, input, options, io = { stdout: [], stderr: [] }) {
1080
+ const source = options.source ? TELEFONE_OFFICIAL_SOURCE_URL : void 0;
1081
+ switch (action) {
1082
+ case "validate":
1083
+ return printTelefoneValidation(validateTelefone(input), { json: options.json, quiet: options.quiet, source }, io);
1084
+ case "format":
1085
+ return printFormat(formatTelefone(input), { json: options.json, quiet: options.quiet }, io);
1086
+ case "strip":
1087
+ return printStrip(stripTelefone(input), { json: options.json }, io);
1088
+ default: {
1089
+ const _exhaustive = action;
1090
+ io.stderr.push(`Unknown action: ${_exhaustive}`);
1091
+ return EXIT.USAGE;
1092
+ }
1093
+ }
1094
+ }
1095
+ function runTelefone(action, value, options, io = { stdout: [], stderr: [] }) {
1096
+ const input = resolveInput3(value, options.file);
1097
+ if (input === null) {
1098
+ io.stderr.push("Missing telephone value. Pass an argument or use --file.");
1099
+ return EXIT.USAGE;
1100
+ }
1101
+ return runTelefoneCommand(action, input, options, io);
1102
+ }
1103
+
1104
+ // src/commands/cnh.ts
1105
+ import {
1106
+ CNH_OFFICIAL_SOURCE_URL,
1107
+ formatCnh,
1108
+ stripCnh,
1109
+ validateCnh
1110
+ } from "@br-validators/core";
1111
+ function resolveInput4(value, fileContent) {
1112
+ const input = value ?? fileContent?.trim();
1113
+ if (!input) {
1114
+ return null;
1115
+ }
1116
+ return input;
1117
+ }
1118
+ function runCnhCommand(action, input, options, io = { stdout: [], stderr: [] }) {
1119
+ const source = options.source ? CNH_OFFICIAL_SOURCE_URL : void 0;
1120
+ switch (action) {
1121
+ case "validate":
1122
+ return printValidation(validateCnh(input), { json: options.json, quiet: options.quiet, source }, io);
1123
+ case "format":
1124
+ return printFormat(formatCnh(input), { json: options.json, quiet: options.quiet }, io);
1125
+ case "strip":
1126
+ return printStrip(stripCnh(input), { json: options.json }, io);
1127
+ default: {
1128
+ const _exhaustive = action;
1129
+ io.stderr.push(`Unknown action: ${_exhaustive}`);
1130
+ return EXIT.USAGE;
1131
+ }
1132
+ }
1133
+ }
1134
+ function runCnh(action, value, options, io = { stdout: [], stderr: [] }) {
1135
+ const input = resolveInput4(value, options.file);
1136
+ if (input === null) {
1137
+ io.stderr.push("Missing CNH value. Pass an argument or use --file.");
1138
+ return EXIT.USAGE;
1139
+ }
1140
+ return runCnhCommand(action, input, options, io);
1141
+ }
1142
+
1143
+ // src/commands/processo-judicial.ts
1144
+ import {
1145
+ PROCESSO_JUDICIAL_OFFICIAL_SOURCE_URL,
1146
+ formatProcessoJudicial,
1147
+ stripProcessoJudicial,
1148
+ validateProcessoJudicial
1149
+ } from "@br-validators/core/processo-judicial";
1150
+ function resolveInput5(value, fileContent) {
209
1151
  const input = value ?? fileContent?.trim();
210
1152
  if (!input) {
211
1153
  return null;
212
1154
  }
213
1155
  return input;
214
1156
  }
215
- function runCepCommand(action, input, options, io = { stdout: [], stderr: [] }) {
216
- const source = options.source ? CEP_OFFICIAL_SOURCE_URL : void 0;
1157
+ function runProcessoJudicialCommand(action, input, options, io = { stdout: [], stderr: [] }) {
1158
+ const source = options.source ? PROCESSO_JUDICIAL_OFFICIAL_SOURCE_URL : void 0;
217
1159
  switch (action) {
218
1160
  case "validate":
219
- return printValidation(validateCep(input), { json: options.json, quiet: options.quiet, source }, io);
1161
+ return printValidation(validateProcessoJudicial(input), { json: options.json, quiet: options.quiet, source }, io);
1162
+ case "parse":
1163
+ return printProcessoJudicialValidation(validateProcessoJudicial(input), { json: options.json, quiet: options.quiet, source }, io);
220
1164
  case "format":
221
- return printFormat(formatCep(input), { json: options.json, quiet: options.quiet }, io);
1165
+ return printFormat(formatProcessoJudicial(input), { json: options.json, quiet: options.quiet }, io);
222
1166
  case "strip":
223
- return printStrip(stripCep(input), { json: options.json }, io);
1167
+ return printStrip(stripProcessoJudicial(input), { json: options.json }, io);
224
1168
  default: {
225
1169
  const _exhaustive = action;
226
1170
  io.stderr.push(`Unknown action: ${_exhaustive}`);
@@ -228,40 +1172,57 @@ function runCepCommand(action, input, options, io = { stdout: [], stderr: [] })
228
1172
  }
229
1173
  }
230
1174
  }
231
- function runCep(action, value, options, io = { stdout: [], stderr: [] }) {
232
- const input = resolveInput2(value, options.file);
1175
+ function runProcessoJudicial(action, value, options, io = { stdout: [], stderr: [] }) {
1176
+ const input = resolveInput5(value, options.file);
233
1177
  if (input === null) {
234
- io.stderr.push("Missing CEP value. Pass an argument or use --file.");
1178
+ io.stderr.push("Missing processo judicial value. Pass an argument or use --file.");
235
1179
  return EXIT.USAGE;
236
1180
  }
237
- return runCepCommand(action, input, options, io);
1181
+ return runProcessoJudicialCommand(action, input, options, io);
238
1182
  }
239
1183
 
240
- // src/commands/telefone.ts
1184
+ // src/commands/rg.ts
241
1185
  import {
242
- TELEFONE_OFFICIAL_SOURCE_URL,
243
- formatTelefone,
244
- stripTelefone,
245
- validateTelefone
246
- } from "@br-validators/core";
247
- function resolveInput3(value, fileContent) {
1186
+ RG_SUPPORTED_UFS,
1187
+ formatRg,
1188
+ getRgOfficialSourceUrl,
1189
+ stripRg,
1190
+ validateRg
1191
+ } from "@br-validators/core/rg";
1192
+ function resolveInput6(value, fileContent) {
248
1193
  const input = value ?? fileContent?.trim();
249
1194
  if (!input) {
250
1195
  return null;
251
1196
  }
252
1197
  return input;
253
1198
  }
254
- function printTelefoneValidation(result, options, io = { stdout: [], stderr: [] }) {
1199
+ function resolveRgUf(uf) {
1200
+ if (uf === void 0) {
1201
+ return null;
1202
+ }
1203
+ const normalized = uf.toUpperCase();
1204
+ if (RG_SUPPORTED_UFS.includes(normalized)) {
1205
+ return normalized;
1206
+ }
1207
+ return null;
1208
+ }
1209
+ function printRgValidation(result, options, io = { stdout: [], stderr: [] }) {
255
1210
  if (options.json) {
256
1211
  io.stdout.push(
257
1212
  JSON.stringify(
258
1213
  result.ok ? {
259
1214
  ok: true,
260
1215
  value: result.value,
261
- tipo: result.tipo,
1216
+ uf: result.uf,
262
1217
  format: result.format,
1218
+ checkDigitValidated: result.checkDigitValidated,
263
1219
  ...options.source ? { source: options.source } : {}
264
- } : { ok: false, code: result.code, message: result.message },
1220
+ } : {
1221
+ ok: false,
1222
+ code: result.code,
1223
+ message: result.message,
1224
+ ...result.uf ? { uf: result.uf } : {}
1225
+ },
265
1226
  null,
266
1227
  2
267
1228
  )
@@ -272,7 +1233,8 @@ function printTelefoneValidation(result, options, io = { stdout: [], stderr: []
272
1233
  return result.ok ? EXIT.OK : EXIT.INVALID;
273
1234
  }
274
1235
  if (result.ok) {
275
- io.stdout.push(`valid: yes (${result.tipo})`);
1236
+ io.stdout.push(`valid: yes (${result.uf})`);
1237
+ io.stdout.push(`checkDigitValidated: ${result.checkDigitValidated ? "yes" : "no"}`);
276
1238
  io.stdout.push(`value: ${result.value}`);
277
1239
  io.stdout.push(`format: ${result.format}`);
278
1240
  if (options.source) {
@@ -283,56 +1245,25 @@ function printTelefoneValidation(result, options, io = { stdout: [], stderr: []
283
1245
  io.stderr.push("valid: no");
284
1246
  io.stderr.push(`code: ${result.code}`);
285
1247
  io.stderr.push(`message: ${result.message}`);
286
- return EXIT.INVALID;
287
- }
288
- function runTelefoneCommand(action, input, options, io = { stdout: [], stderr: [] }) {
289
- const source = options.source ? TELEFONE_OFFICIAL_SOURCE_URL : void 0;
290
- switch (action) {
291
- case "validate":
292
- return printTelefoneValidation(validateTelefone(input), { json: options.json, quiet: options.quiet, source }, io);
293
- case "format":
294
- return printFormat(formatTelefone(input), { json: options.json, quiet: options.quiet }, io);
295
- case "strip":
296
- return printStrip(stripTelefone(input), { json: options.json }, io);
297
- default: {
298
- const _exhaustive = action;
299
- io.stderr.push(`Unknown action: ${_exhaustive}`);
300
- return EXIT.USAGE;
301
- }
1248
+ if (result.uf) {
1249
+ io.stderr.push(`uf: ${result.uf}`);
302
1250
  }
1251
+ return EXIT.INVALID;
303
1252
  }
304
- function runTelefone(action, value, options, io = { stdout: [], stderr: [] }) {
305
- const input = resolveInput3(value, options.file);
306
- if (input === null) {
307
- io.stderr.push("Missing telephone value. Pass an argument or use --file.");
1253
+ function runRgCommand(action, input, options, io = { stdout: [], stderr: [] }) {
1254
+ const uf = resolveRgUf(options.uf);
1255
+ if (!uf) {
1256
+ io.stderr.push(`Missing or invalid --uf. Use one of: ${RG_SUPPORTED_UFS.join(", ")}.`);
308
1257
  return EXIT.USAGE;
309
1258
  }
310
- return runTelefoneCommand(action, input, options, io);
311
- }
312
-
313
- // src/commands/cnh.ts
314
- import {
315
- CNH_OFFICIAL_SOURCE_URL,
316
- formatCnh,
317
- stripCnh,
318
- validateCnh
319
- } from "@br-validators/core";
320
- function resolveInput4(value, fileContent) {
321
- const input = value ?? fileContent?.trim();
322
- if (!input) {
323
- return null;
324
- }
325
- return input;
326
- }
327
- function runCnhCommand(action, input, options, io = { stdout: [], stderr: [] }) {
328
- const source = options.source ? CNH_OFFICIAL_SOURCE_URL : void 0;
1259
+ const source = options.source ? getRgOfficialSourceUrl(uf) : void 0;
329
1260
  switch (action) {
330
1261
  case "validate":
331
- return printValidation(validateCnh(input), { json: options.json, quiet: options.quiet, source }, io);
1262
+ return printRgValidation(validateRg(input, { uf }), { json: options.json, quiet: options.quiet, source }, io);
332
1263
  case "format":
333
- return printFormat(formatCnh(input), { json: options.json, quiet: options.quiet }, io);
1264
+ return printFormat(formatRg(input, { uf }), { json: options.json, quiet: options.quiet }, io);
334
1265
  case "strip":
335
- return printStrip(stripCnh(input), { json: options.json }, io);
1266
+ return printStrip(stripRg(input, { uf }), { json: options.json }, io);
336
1267
  default: {
337
1268
  const _exhaustive = action;
338
1269
  io.stderr.push(`Unknown action: ${_exhaustive}`);
@@ -340,13 +1271,13 @@ function runCnhCommand(action, input, options, io = { stdout: [], stderr: [] })
340
1271
  }
341
1272
  }
342
1273
  }
343
- function runCnh(action, value, options, io = { stdout: [], stderr: [] }) {
344
- const input = resolveInput4(value, options.file);
1274
+ function runRg(action, value, options, io = { stdout: [], stderr: [] }) {
1275
+ const input = resolveInput6(value, options.file);
345
1276
  if (input === null) {
346
- io.stderr.push("Missing CNH value. Pass an argument or use --file.");
1277
+ io.stderr.push("Missing RG value. Pass an argument or use --file.");
347
1278
  return EXIT.USAGE;
348
1279
  }
349
- return runCnhCommand(action, input, options, io);
1280
+ return runRgCommand(action, input, options, io);
350
1281
  }
351
1282
 
352
1283
  // src/commands/renavam.ts
@@ -356,7 +1287,7 @@ import {
356
1287
  stripRenavam,
357
1288
  validateRenavam
358
1289
  } from "@br-validators/core";
359
- function resolveInput5(value, fileContent) {
1290
+ function resolveInput7(value, fileContent) {
360
1291
  const input = value ?? fileContent?.trim();
361
1292
  if (!input) {
362
1293
  return null;
@@ -380,7 +1311,7 @@ function runRenavamCommand(action, input, options, io = { stdout: [], stderr: []
380
1311
  }
381
1312
  }
382
1313
  function runRenavam(action, value, options, io = { stdout: [], stderr: [] }) {
383
- const input = resolveInput5(value, options.file);
1314
+ const input = resolveInput7(value, options.file);
384
1315
  if (input === null) {
385
1316
  io.stderr.push("Missing RENAVAM value. Pass an argument or use --file.");
386
1317
  return EXIT.USAGE;
@@ -395,7 +1326,7 @@ import {
395
1326
  stripTituloEleitor,
396
1327
  validateTituloEleitor
397
1328
  } from "@br-validators/core";
398
- function resolveInput6(value, fileContent) {
1329
+ function resolveInput8(value, fileContent) {
399
1330
  const input = value ?? fileContent?.trim();
400
1331
  if (!input) {
401
1332
  return null;
@@ -419,7 +1350,7 @@ function runTituloEleitorCommand(action, input, options, io = { stdout: [], stde
419
1350
  }
420
1351
  }
421
1352
  function runTituloEleitor(action, value, options, io = { stdout: [], stderr: [] }) {
422
- const input = resolveInput6(value, options.file);
1353
+ const input = resolveInput8(value, options.file);
423
1354
  if (input === null) {
424
1355
  io.stderr.push("Missing T\xEDtulo de Eleitor value. Pass an argument or use --file.");
425
1356
  return EXIT.USAGE;
@@ -435,7 +1366,7 @@ import {
435
1366
  stripNfeChave,
436
1367
  validateNfeChave
437
1368
  } from "@br-validators/core";
438
- function resolveInput7(value, fileContent) {
1369
+ function resolveInput9(value, fileContent) {
439
1370
  const input = value ?? fileContent?.trim();
440
1371
  if (!input) {
441
1372
  return null;
@@ -461,7 +1392,7 @@ function runNfeChaveCommand(action, input, options, io = { stdout: [], stderr: [
461
1392
  }
462
1393
  }
463
1394
  function runNfeChave(action, value, options, io = { stdout: [], stderr: [] }) {
464
- const input = resolveInput7(value, options.file);
1395
+ const input = resolveInput9(value, options.file);
465
1396
  if (input === null) {
466
1397
  io.stderr.push("Missing NF-e chave de acesso value. Pass an argument or use --file.");
467
1398
  return EXIT.USAGE;
@@ -476,7 +1407,7 @@ import {
476
1407
  stripCnpj,
477
1408
  validateCnpj
478
1409
  } from "@br-validators/core";
479
- function resolveInput8(value, fileContent) {
1410
+ function resolveInput10(value, fileContent) {
480
1411
  const input = value ?? fileContent?.trim();
481
1412
  if (!input) {
482
1413
  return null;
@@ -500,7 +1431,7 @@ function runCnpjCommand(action, input, options, io = { stdout: [], stderr: [] })
500
1431
  }
501
1432
  }
502
1433
  function runCnpj(action, value, options, io = { stdout: [], stderr: [] }) {
503
- const input = resolveInput8(value, options.file);
1434
+ const input = resolveInput10(value, options.file);
504
1435
  if (input === null) {
505
1436
  io.stderr.push("Missing CNPJ value. Pass an argument or use --file.");
506
1437
  return EXIT.USAGE;
@@ -515,7 +1446,7 @@ import {
515
1446
  stripCpf,
516
1447
  validateCpf
517
1448
  } from "@br-validators/core";
518
- function resolveInput9(value, fileContent) {
1449
+ function resolveInput11(value, fileContent) {
519
1450
  const input = value ?? fileContent?.trim();
520
1451
  if (!input) {
521
1452
  return null;
@@ -539,7 +1470,7 @@ function runCpfCommand(action, input, options, io = { stdout: [], stderr: [] })
539
1470
  }
540
1471
  }
541
1472
  function runCpf(action, value, options, io = { stdout: [], stderr: [] }) {
542
- const input = resolveInput9(value, options.file);
1473
+ const input = resolveInput11(value, options.file);
543
1474
  if (input === null) {
544
1475
  io.stderr.push("Missing CPF value. Pass an argument or use --file.");
545
1476
  return EXIT.USAGE;
@@ -555,7 +1486,7 @@ import {
555
1486
  stripPlaca,
556
1487
  validatePlaca
557
1488
  } from "@br-validators/core";
558
- function resolveInput10(value, fileContent) {
1489
+ function resolveInput12(value, fileContent) {
559
1490
  const input = value ?? fileContent?.trim();
560
1491
  if (!input) {
561
1492
  return null;
@@ -581,7 +1512,7 @@ function runPlacaCommand(action, input, options, io = { stdout: [], stderr: [] }
581
1512
  }
582
1513
  }
583
1514
  function runPlaca(action, value, options, io = { stdout: [], stderr: [] }) {
584
- const input = resolveInput10(value, options.file);
1515
+ const input = resolveInput12(value, options.file);
585
1516
  if (input === null) {
586
1517
  io.stderr.push("Missing placa value. Pass an argument or use --file.");
587
1518
  return EXIT.USAGE;
@@ -596,7 +1527,7 @@ import {
596
1527
  stripPisPasep,
597
1528
  validatePisPasep
598
1529
  } from "@br-validators/core";
599
- function resolveInput11(value, fileContent) {
1530
+ function resolveInput13(value, fileContent) {
600
1531
  const input = value ?? fileContent?.trim();
601
1532
  if (!input) {
602
1533
  return null;
@@ -620,7 +1551,7 @@ function runPisPasepCommand(action, input, options, io = { stdout: [], stderr: [
620
1551
  }
621
1552
  }
622
1553
  function runPisPasep(action, value, options, io = { stdout: [], stderr: [] }) {
623
- const input = resolveInput11(value, options.file);
1554
+ const input = resolveInput13(value, options.file);
624
1555
  if (input === null) {
625
1556
  io.stderr.push("Missing PIS/PASEP value. Pass an argument or use --file.");
626
1557
  return EXIT.USAGE;
@@ -635,7 +1566,7 @@ import {
635
1566
  formatPixKey,
636
1567
  validatePixKey
637
1568
  } from "@br-validators/core";
638
- function resolveInput12(value, fileContent) {
1569
+ function resolveInput14(value, fileContent) {
639
1570
  const input = value ?? fileContent?.trim();
640
1571
  if (!input) {
641
1572
  return null;
@@ -710,7 +1641,7 @@ function runPixCommand(action, input, options, io = { stdout: [], stderr: [] })
710
1641
  }
711
1642
  }
712
1643
  function runPix(action, value, options, io = { stdout: [], stderr: [] }) {
713
- const input = resolveInput12(value, options.file);
1644
+ const input = resolveInput14(value, options.file);
714
1645
  if (input === null) {
715
1646
  io.stderr.push("Missing PIX key value. Pass an argument or use --file.");
716
1647
  return EXIT.USAGE;
@@ -729,7 +1660,7 @@ import {
729
1660
  stripLinhaDigitavel,
730
1661
  validateBoleto
731
1662
  } from "@br-validators/core";
732
- function resolveInput13(value, fileContent) {
1663
+ function resolveInput15(value, fileContent) {
733
1664
  const input = value ?? fileContent?.trim();
734
1665
  if (!input) {
735
1666
  return null;
@@ -864,7 +1795,7 @@ function runBoletoCommand(action, input, options, direction, io = { stdout: [],
864
1795
  }
865
1796
  }
866
1797
  function runBoleto(action, value, options, direction, io = { stdout: [], stderr: [] }) {
867
- const input = resolveInput13(value, options.file);
1798
+ const input = resolveInput15(value, options.file);
868
1799
  if (input === null) {
869
1800
  io.stderr.push("Missing boleto value. Pass an argument or use --file.");
870
1801
  return EXIT.USAGE;
@@ -880,7 +1811,7 @@ import {
880
1811
  stripCartaoCredito,
881
1812
  validateCartaoCredito
882
1813
  } from "@br-validators/core";
883
- function resolveInput14(value, fileContent) {
1814
+ function resolveInput16(value, fileContent) {
884
1815
  const input = value ?? fileContent?.trim();
885
1816
  if (!input) {
886
1817
  return null;
@@ -956,7 +1887,7 @@ function runCartaoCommand(action, input, options, io = { stdout: [], stderr: []
956
1887
  }
957
1888
  }
958
1889
  function runCartao(action, value, options, io = { stdout: [], stderr: [] }) {
959
- const input = resolveInput14(value, options.file);
1890
+ const input = resolveInput16(value, options.file);
960
1891
  if (input === null) {
961
1892
  io.stderr.push("Missing credit card PAN value. Pass an argument or use --file.");
962
1893
  return EXIT.USAGE;
@@ -977,7 +1908,7 @@ import {
977
1908
  validateIeProdutorRural,
978
1909
  validateInscricaoEstadual
979
1910
  } from "@br-validators/core";
980
- function resolveInput15(value, fileContent) {
1911
+ function resolveInput17(value, fileContent) {
981
1912
  const input = value ?? fileContent?.trim();
982
1913
  if (!input) {
983
1914
  return null;
@@ -1074,7 +2005,7 @@ function runIeCommand(action, input, options, io = { stdout: [], stderr: [] }) {
1074
2005
  }
1075
2006
  }
1076
2007
  function runIe(action, value, options, io = { stdout: [], stderr: [] }) {
1077
- const input = resolveInput15(value, options.file);
2008
+ const input = resolveInput17(value, options.file);
1078
2009
  if (input === null) {
1079
2010
  io.stderr.push("Missing IE value. Pass an argument or use --file.");
1080
2011
  return EXIT.USAGE;
@@ -1084,7 +2015,7 @@ function runIe(action, value, options, io = { stdout: [], stderr: [] }) {
1084
2015
 
1085
2016
  // src/commands/detect.ts
1086
2017
  import { detect } from "@br-validators/core";
1087
- function resolveInput16(value, fileContent) {
2018
+ function resolveInput18(value, fileContent) {
1088
2019
  const input = value ?? fileContent?.trim();
1089
2020
  if (!input) {
1090
2021
  return null;
@@ -1118,7 +2049,7 @@ function printDetect(result, options, io = { stdout: [], stderr: [] }) {
1118
2049
  return EXIT.INVALID;
1119
2050
  }
1120
2051
  function runDetect(value, options, io = { stdout: [], stderr: [] }) {
1121
- const input = resolveInput16(value, options.file);
2052
+ const input = resolveInput18(value, options.file);
1122
2053
  if (input === null) {
1123
2054
  io.stderr.push("Missing value. Pass an argument or use --file.");
1124
2055
  return EXIT.USAGE;
@@ -1149,7 +2080,7 @@ var SANITIZABLE_TYPES = [
1149
2080
  function isSanitizableType(type) {
1150
2081
  return SANITIZABLE_TYPES.includes(type);
1151
2082
  }
1152
- function resolveInput17(value, fileContent) {
2083
+ function resolveInput19(value, fileContent) {
1153
2084
  const input = value ?? fileContent?.trim();
1154
2085
  if (!input) {
1155
2086
  return null;
@@ -1180,7 +2111,7 @@ function runSanitize(type, value, options, io = { stdout: [], stderr: [] }) {
1180
2111
  io.stderr.push(`Unsupported sanitize type: ${type}`);
1181
2112
  return EXIT.USAGE;
1182
2113
  }
1183
- const input = resolveInput17(value, options.file);
2114
+ const input = resolveInput19(value, options.file);
1184
2115
  if (input === null) {
1185
2116
  io.stderr.push("Missing value. Pass an argument or use --file.");
1186
2117
  return EXIT.USAGE;
@@ -1550,6 +2481,27 @@ function handleTituloEleitorCli(action, value, opts, io = { stdout: [], stderr:
1550
2481
  io
1551
2482
  );
1552
2483
  }
2484
+ function handleProcessoJudicialCli(action, value, opts, io = { stdout: [], stderr: [] }) {
2485
+ let fileContent;
2486
+ if (opts.file) {
2487
+ const content = readInputFile(opts.file, io);
2488
+ if (content === null) {
2489
+ return EXIT.USAGE;
2490
+ }
2491
+ fileContent = content;
2492
+ }
2493
+ return runProcessoJudicial(
2494
+ action,
2495
+ value,
2496
+ {
2497
+ json: Boolean(opts.json),
2498
+ quiet: Boolean(opts.quiet),
2499
+ source: Boolean(opts.source),
2500
+ file: fileContent
2501
+ },
2502
+ io
2503
+ );
2504
+ }
1553
2505
  function handleNfeChaveCli(action, value, opts, io = { stdout: [], stderr: [] }) {
1554
2506
  let fileContent;
1555
2507
  if (opts.file) {
@@ -1614,6 +2566,28 @@ function handleIeCli(action, value, opts, io = { stdout: [], stderr: [] }) {
1614
2566
  io
1615
2567
  );
1616
2568
  }
2569
+ function handleRgCli(action, value, opts, io = { stdout: [], stderr: [] }) {
2570
+ let fileContent;
2571
+ if (opts.file) {
2572
+ const content = readInputFile(opts.file, io);
2573
+ if (content === null) {
2574
+ return EXIT.USAGE;
2575
+ }
2576
+ fileContent = content;
2577
+ }
2578
+ return runRg(
2579
+ action,
2580
+ value,
2581
+ {
2582
+ json: Boolean(opts.json),
2583
+ quiet: Boolean(opts.quiet),
2584
+ source: Boolean(opts.source),
2585
+ uf: opts.uf,
2586
+ file: fileContent
2587
+ },
2588
+ io
2589
+ );
2590
+ }
1617
2591
  function handleDetectCli(value, opts, io = { stdout: [], stderr: [] }) {
1618
2592
  let fileContent;
1619
2593
  if (opts.file) {
@@ -1670,11 +2644,101 @@ function handleGenerateCli(type, opts, io = { stdout: [], stderr: [] }) {
1670
2644
  io
1671
2645
  );
1672
2646
  }
2647
+ function handleBancosLookupCli(value, opts, io = { stdout: [], stderr: [] }) {
2648
+ return runBancosLookup(
2649
+ value,
2650
+ {
2651
+ json: Boolean(opts.json),
2652
+ verbose: Boolean(opts.verbose)
2653
+ },
2654
+ io
2655
+ );
2656
+ }
2657
+ function handleBancosListCli(opts, io = { stdout: [], stderr: [] }) {
2658
+ return runBancosList(
2659
+ {
2660
+ json: Boolean(opts.json),
2661
+ verbose: Boolean(opts.verbose),
2662
+ limit: opts.limit
2663
+ },
2664
+ io
2665
+ );
2666
+ }
2667
+ function handleReferenceLookupCli(command, value, opts, io = { stdout: [], stderr: [] }) {
2668
+ return runReferenceLookup(
2669
+ command,
2670
+ value,
2671
+ {
2672
+ json: Boolean(opts.json),
2673
+ verbose: Boolean(opts.verbose)
2674
+ },
2675
+ io
2676
+ );
2677
+ }
2678
+ function handleReferenceSearchCli(command, query, opts, io = { stdout: [], stderr: [] }) {
2679
+ return runReferenceSearch(
2680
+ command,
2681
+ query,
2682
+ {
2683
+ json: Boolean(opts.json),
2684
+ verbose: Boolean(opts.verbose),
2685
+ limit: opts.limit
2686
+ },
2687
+ io
2688
+ );
2689
+ }
2690
+ function handleIbgeLookupCli(value, opts, io = { stdout: [], stderr: [] }) {
2691
+ return runIbgeLookup(value, { json: Boolean(opts.json), verbose: Boolean(opts.verbose) }, io);
2692
+ }
2693
+ function handleIbgeListCli(target, opts, io = { stdout: [], stderr: [] }) {
2694
+ return runIbgeList(target, {
2695
+ json: Boolean(opts.json),
2696
+ verbose: Boolean(opts.verbose),
2697
+ uf: opts.uf,
2698
+ limit: opts.limit
2699
+ }, io);
2700
+ }
2701
+ function handleFeriadosListCli(opts, io = { stdout: [], stderr: [] }) {
2702
+ return runFeriadosList({
2703
+ json: Boolean(opts.json),
2704
+ verbose: Boolean(opts.verbose),
2705
+ year: opts.year
2706
+ }, io);
2707
+ }
2708
+ function handleTseMunicipiosLookupCli(value, opts, io = { stdout: [], stderr: [] }) {
2709
+ return runTseMunicipiosLookup(value, { json: Boolean(opts.json), verbose: Boolean(opts.verbose) }, io);
2710
+ }
2711
+ function handleCepFaixaCli(value, opts, io = { stdout: [], stderr: [] }) {
2712
+ return runCepFaixa(value, { json: Boolean(opts.json), verbose: Boolean(opts.verbose) }, io);
2713
+ }
2714
+ function handleDddLookupCli(value, opts, io = { stdout: [], stderr: [] }) {
2715
+ return runDddLookup(value, { json: Boolean(opts.json), verbose: Boolean(opts.verbose) }, io);
2716
+ }
1673
2717
  function writeCliIo(io) {
1674
2718
  for (const line of io.stdout) console.log(line);
1675
2719
  for (const line of io.stderr) console.error(line);
1676
2720
  }
1677
2721
 
2722
+ // src/commands/reference-lookup/register-program.ts
2723
+ function registerReferenceLookupCommands(program) {
2724
+ for (const command of REFERENCE_LOOKUP_COMMANDS) {
2725
+ const module = REFERENCE_LOOKUP_MODULES[command];
2726
+ const root = program.command(command).description(module.description);
2727
+ root.command("lookup").description(`Resolve ${command} by official code`).argument("<codigo>", "Lookup code").option("--json", "JSON output").option("--verbose", "Include dataset capture date").action((codigo, opts) => {
2728
+ const io = { stdout: [], stderr: [] };
2729
+ process.exitCode = handleReferenceLookupCli(command, codigo, opts, io);
2730
+ writeCliIo(io);
2731
+ });
2732
+ if (REFERENCE_SEARCH_COMMANDS.includes(command)) {
2733
+ root.command("search").description(`Search ${command} by description fragment`).argument("<query>", "Search query").option("--json", "JSON output").option("--verbose", "Include dataset capture date").option("--limit <n>", "Maximum rows", (v) => Number(v)).action((query, opts) => {
2734
+ const io = { stdout: [], stderr: [] };
2735
+ process.exitCode = handleReferenceSearchCli(command, query, opts, io);
2736
+ writeCliIo(io);
2737
+ });
2738
+ }
2739
+ }
2740
+ }
2741
+
1678
2742
  // src/program.ts
1679
2743
  function createProgram() {
1680
2744
  const program = new Command();
@@ -1708,6 +2772,11 @@ function createProgram() {
1708
2772
  writeCliIo(io);
1709
2773
  });
1710
2774
  }
2775
+ cep.command("faixa").description("Resolve CEP prefix to municipality (IBGE CNEFE)").argument("<prefixo>", "CEP prefix (5+ digits)").option("--json", "JSON output").option("--verbose", "Include dataset capture date").action((prefixo, opts) => {
2776
+ const io = { stdout: [], stderr: [] };
2777
+ process.exitCode = handleCepFaixaCli(prefixo, opts, io);
2778
+ writeCliIo(io);
2779
+ });
1711
2780
  const telefone = program.command("telefone").description("Telefone \u2014 Brazilian fixo/celular (Anatel DDD)");
1712
2781
  for (const action of ["validate", "format", "strip"]) {
1713
2782
  telefone.command(action).description(`${action} a Brazilian telephone number`).argument("[value]", "Telephone value (raw or masked)").option("--json", "JSON output").option("-q, --quiet", "Exit code only").option("--source", "Include official source URL (validate only)").option("-f, --file <path>", "Read value from file").action((value, opts) => {
@@ -1740,6 +2809,14 @@ function createProgram() {
1740
2809
  writeCliIo(io);
1741
2810
  });
1742
2811
  }
2812
+ const processoJudicial = program.command("processo-judicial").description("Processo judicial CNJ \u2014 n\xFAmero \xFAnico NNNNNNN-DD.AAAA.J.TR.OOOO (Resolu\xE7\xE3o 65/2008)");
2813
+ for (const action of ["validate", "parse", "format", "strip"]) {
2814
+ processoJudicial.command(action).description(`${action} a processo judicial CNJ`).argument("[value]", "CNJ process number (masked or 20 digits)").option("--json", "JSON output").option("-q, --quiet", "Exit code only").option("--source", "Include official source URL (validate/parse only)").option("-f, --file <path>", "Read value from file").action((value, opts) => {
2815
+ const io = { stdout: [], stderr: [] };
2816
+ process.exitCode = handleProcessoJudicialCli(action, value, opts, io);
2817
+ writeCliIo(io);
2818
+ });
2819
+ }
1743
2820
  const nfeChave = program.command("nfe-chave").description("NF-e / NFC-e chave de acesso \u2014 44 digits (SEFAZ MOC \xA72.2.6)");
1744
2821
  for (const action of ["validate", "parse", "format", "strip"]) {
1745
2822
  nfeChave.command(action).description(`${action} an NF-e chave de acesso`).argument("[value]", "Chave de acesso (44 digits, spaces allowed)").option("--json", "JSON output").option("-q, --quiet", "Exit code only").option("--source", "Include official source URL (validate/parse only)").option("-f, --file <path>", "Read value from file").action((value, opts) => {
@@ -1843,6 +2920,61 @@ function createProgram() {
1843
2920
  writeCliIo(io);
1844
2921
  });
1845
2922
  }
2923
+ const rg = program.command("rg").description("RG (Registro Geral) \u2014 per-UF validation (phase 1: SP, RJ, MG, PR, RS, SC)");
2924
+ for (const action of ["validate", "format", "strip"]) {
2925
+ rg.command(action).description(`${action} an RG`).argument("[value]", "RG value (raw or masked)").requiredOption("--uf <uf>", "State code (SP, RJ, MG, PR, RS, SC)").option("--json", "JSON output").option("-q, --quiet", "Exit code only").option("--source", "Include official source URL (validate only)").option("-f, --file <path>", "Read value from file").action((value, opts) => {
2926
+ const io = { stdout: [], stderr: [] };
2927
+ process.exitCode = handleRgCli(action, value, opts, io);
2928
+ writeCliIo(io);
2929
+ });
2930
+ }
2931
+ const bancos = program.command("bancos").description("Bacen STR participants \u2014 offline lookup");
2932
+ bancos.command("lookup").description("Resolve bank by COMPE (3 digits) or ISPB (8 digits)").argument("<codigoOuIspb>", "COMPE or ISPB").option("--json", "JSON output").option("--verbose", "Include dataset capture date (BANCOS_DATA_VERSION)").action((codigoOuIspb, opts) => {
2933
+ const io = { stdout: [], stderr: [] };
2934
+ process.exitCode = handleBancosLookupCli(codigoOuIspb, opts, io);
2935
+ writeCliIo(io);
2936
+ });
2937
+ bancos.command("list").description("List STR participants (optional --limit)").option("--json", "JSON output").option("--verbose", "Include dataset capture date (BANCOS_DATA_VERSION)").option("--limit <n>", "Maximum rows to print", (v) => Number(v)).action((opts) => {
2938
+ const io = { stdout: [], stderr: [] };
2939
+ process.exitCode = handleBancosListCli(opts, io);
2940
+ writeCliIo(io);
2941
+ });
2942
+ const ibge = program.command("ibge").description("IBGE states and municipalities \u2014 offline lookup");
2943
+ ibge.command("lookup").description("Resolve municipality by 7-digit IBGE code").argument("<codigo>", "IBGE municipality code").option("--json", "JSON output").option("--verbose", "Include dataset capture date").action((codigo, opts) => {
2944
+ const io = { stdout: [], stderr: [] };
2945
+ process.exitCode = handleIbgeLookupCli(codigo, opts, io);
2946
+ writeCliIo(io);
2947
+ });
2948
+ ibge.command("list").description("List estados or municipios").argument("<target>", "estados | municipios").option("--json", "JSON output").option("--verbose", "Include dataset capture date").option("--uf <uf>", "Filter municipalities by UF").option("--limit <n>", "Maximum rows", (v) => Number(v)).action((target, opts) => {
2949
+ const io = { stdout: [], stderr: [] };
2950
+ if (target !== "estados" && target !== "municipios") {
2951
+ io.stderr.push("Expected target: estados | municipios");
2952
+ process.exitCode = 2;
2953
+ writeCliIo(io);
2954
+ return;
2955
+ }
2956
+ process.exitCode = handleIbgeListCli(target, opts, io);
2957
+ writeCliIo(io);
2958
+ });
2959
+ const feriados = program.command("feriados").description("Brazilian national holidays \u2014 offline calendar");
2960
+ feriados.command("list").description("List national holidays for a year").option("--year <yyyy>", "Calendar year", (v) => Number(v)).option("--json", "JSON output").option("--verbose", "Include dataset capture date").action((opts) => {
2961
+ const io = { stdout: [], stderr: [] };
2962
+ process.exitCode = handleFeriadosListCli(opts, io);
2963
+ writeCliIo(io);
2964
+ });
2965
+ const tseMunicipios = program.command("tse-municipios").description("TSE \u2194 IBGE municipality cross-walk \u2014 offline lookup");
2966
+ tseMunicipios.command("lookup").description("Resolve TSE (5 digits) or IBGE (7 digits) municipality code").argument("<codigo>", "TSE or IBGE code").option("--json", "JSON output").option("--verbose", "Include dataset capture date").action((codigo, opts) => {
2967
+ const io = { stdout: [], stderr: [] };
2968
+ process.exitCode = handleTseMunicipiosLookupCli(codigo, opts, io);
2969
+ writeCliIo(io);
2970
+ });
2971
+ const ddd = program.command("ddd").description("Anatel DDD geographic lookup \u2014 offline");
2972
+ ddd.command("lookup").description("Resolve DDD to UF, region, and municipalities").argument("<code>", "2-digit DDD").option("--json", "JSON output").option("--verbose", "Include dataset capture date").action((code, opts) => {
2973
+ const io = { stdout: [], stderr: [] };
2974
+ process.exitCode = handleDddLookupCli(code, opts, io);
2975
+ writeCliIo(io);
2976
+ });
2977
+ registerReferenceLookupCommands(program);
1846
2978
  program.command("detect").description("Detect document type from raw input").argument("[value]", "Raw value to classify").option("--uf <uf>", "State code for Inscri\xE7\xE3o Estadual detection").option("--json", "JSON output").option("-q, --quiet", "Exit code only").option("-f, --file <path>", "Read value from file").action((value, opts) => {
1847
2979
  const io = { stdout: [], stderr: [] };
1848
2980
  process.exitCode = handleDetectCli(value, opts, io);