@br-validators/cli 1.5.0 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -13,7 +13,7 @@ import { Command } from "commander";
13
13
  import { BANCOS_DATA_VERSION as BANCOS_DATA_VERSION2, getBancos } from "@br-validators/core/bancos";
14
14
 
15
15
  // src/constants.ts
16
- 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"];
17
17
  var EXIT = {
18
18
  OK: 0,
19
19
  INVALID: 1,
@@ -141,16 +141,31 @@ import {
141
141
  getAeroportoPorIcao
142
142
  } from "@br-validators/core/aeroportos";
143
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";
144
154
  var REFERENCE_LOOKUP_COMMANDS = [
145
155
  "natureza-juridica",
146
156
  "nbs",
147
157
  "cest",
158
+ "cnae",
159
+ "cfop",
160
+ "ncm",
161
+ "cbo",
148
162
  "moedas",
149
163
  "paises-bacen",
150
164
  "incoterms",
151
165
  "portos",
152
166
  "aeroportos"
153
167
  ];
168
+ var REFERENCE_SEARCH_COMMANDS = ["cnae", "cfop", "ncm", "cbo"];
154
169
  function lookupAeroporto(input) {
155
170
  const normalized = input.trim().toUpperCase();
156
171
  if (/^[A-Z0-9]{3}$/.test(normalized)) {
@@ -195,6 +210,50 @@ var REFERENCE_LOOKUP_MODULES = {
195
210
  return `${row.codigo} \u2014 ${row.descricao}`;
196
211
  }
197
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
+ },
198
257
  moedas: {
199
258
  command: "moedas",
200
259
  description: "ISO 4217 + Bacen PTAX currencies \u2014 offline lookup",
@@ -256,6 +315,9 @@ var REFERENCE_LOOKUP_MODULES = {
256
315
  function isReferenceLookupCommand(value) {
257
316
  return REFERENCE_LOOKUP_COMMANDS.includes(value);
258
317
  }
318
+ function isReferenceSearchCommand(value) {
319
+ return REFERENCE_SEARCH_COMMANDS.includes(value);
320
+ }
259
321
 
260
322
  // src/commands/reference-lookup/lookup.ts
261
323
  function runReferenceLookupCommand(command, input, options, io = { stdout: [], stderr: [] }) {
@@ -297,6 +359,418 @@ function runReferenceLookup(command, value, options, io = { stdout: [], stderr:
297
359
  return runReferenceLookupCommand(command, value.trim(), options, io);
298
360
  }
299
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
+
300
774
  // src/commands/brcode.ts
301
775
  import {
302
776
  BRCODE_OFFICIAL_SOURCE_URL,
@@ -457,6 +931,45 @@ function printNfeChaveValidation(result, options, io = { stdout: [], stderr: []
457
931
  io.stderr.push(`message: ${result.message}`);
458
932
  return EXIT.INVALID;
459
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
+ }
460
973
  function printFormat(result, options, io = { stdout: [], stderr: [] }) {
461
974
  if (options.json) {
462
975
  io.stdout.push(JSON.stringify(result, null, 2));
@@ -627,6 +1140,146 @@ function runCnh(action, value, options, io = { stdout: [], stderr: [] }) {
627
1140
  return runCnhCommand(action, input, options, io);
628
1141
  }
629
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) {
1151
+ const input = value ?? fileContent?.trim();
1152
+ if (!input) {
1153
+ return null;
1154
+ }
1155
+ return input;
1156
+ }
1157
+ function runProcessoJudicialCommand(action, input, options, io = { stdout: [], stderr: [] }) {
1158
+ const source = options.source ? PROCESSO_JUDICIAL_OFFICIAL_SOURCE_URL : void 0;
1159
+ switch (action) {
1160
+ case "validate":
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);
1164
+ case "format":
1165
+ return printFormat(formatProcessoJudicial(input), { json: options.json, quiet: options.quiet }, io);
1166
+ case "strip":
1167
+ return printStrip(stripProcessoJudicial(input), { json: options.json }, io);
1168
+ default: {
1169
+ const _exhaustive = action;
1170
+ io.stderr.push(`Unknown action: ${_exhaustive}`);
1171
+ return EXIT.USAGE;
1172
+ }
1173
+ }
1174
+ }
1175
+ function runProcessoJudicial(action, value, options, io = { stdout: [], stderr: [] }) {
1176
+ const input = resolveInput5(value, options.file);
1177
+ if (input === null) {
1178
+ io.stderr.push("Missing processo judicial value. Pass an argument or use --file.");
1179
+ return EXIT.USAGE;
1180
+ }
1181
+ return runProcessoJudicialCommand(action, input, options, io);
1182
+ }
1183
+
1184
+ // src/commands/rg.ts
1185
+ import {
1186
+ RG_SUPPORTED_UFS,
1187
+ formatRg,
1188
+ getRgOfficialSourceUrl,
1189
+ stripRg,
1190
+ validateRg
1191
+ } from "@br-validators/core/rg";
1192
+ function resolveInput6(value, fileContent) {
1193
+ const input = value ?? fileContent?.trim();
1194
+ if (!input) {
1195
+ return null;
1196
+ }
1197
+ return input;
1198
+ }
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: [] }) {
1210
+ if (options.json) {
1211
+ io.stdout.push(
1212
+ JSON.stringify(
1213
+ result.ok ? {
1214
+ ok: true,
1215
+ value: result.value,
1216
+ uf: result.uf,
1217
+ format: result.format,
1218
+ checkDigitValidated: result.checkDigitValidated,
1219
+ ...options.source ? { source: options.source } : {}
1220
+ } : {
1221
+ ok: false,
1222
+ code: result.code,
1223
+ message: result.message,
1224
+ ...result.uf ? { uf: result.uf } : {}
1225
+ },
1226
+ null,
1227
+ 2
1228
+ )
1229
+ );
1230
+ return result.ok ? EXIT.OK : EXIT.INVALID;
1231
+ }
1232
+ if (options.quiet) {
1233
+ return result.ok ? EXIT.OK : EXIT.INVALID;
1234
+ }
1235
+ if (result.ok) {
1236
+ io.stdout.push(`valid: yes (${result.uf})`);
1237
+ io.stdout.push(`checkDigitValidated: ${result.checkDigitValidated ? "yes" : "no"}`);
1238
+ io.stdout.push(`value: ${result.value}`);
1239
+ io.stdout.push(`format: ${result.format}`);
1240
+ if (options.source) {
1241
+ io.stdout.push(`source: ${options.source}`);
1242
+ }
1243
+ return EXIT.OK;
1244
+ }
1245
+ io.stderr.push("valid: no");
1246
+ io.stderr.push(`code: ${result.code}`);
1247
+ io.stderr.push(`message: ${result.message}`);
1248
+ if (result.uf) {
1249
+ io.stderr.push(`uf: ${result.uf}`);
1250
+ }
1251
+ return EXIT.INVALID;
1252
+ }
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(", ")}.`);
1257
+ return EXIT.USAGE;
1258
+ }
1259
+ const source = options.source ? getRgOfficialSourceUrl(uf) : void 0;
1260
+ switch (action) {
1261
+ case "validate":
1262
+ return printRgValidation(validateRg(input, { uf }), { json: options.json, quiet: options.quiet, source }, io);
1263
+ case "format":
1264
+ return printFormat(formatRg(input, { uf }), { json: options.json, quiet: options.quiet }, io);
1265
+ case "strip":
1266
+ return printStrip(stripRg(input, { uf }), { json: options.json }, io);
1267
+ default: {
1268
+ const _exhaustive = action;
1269
+ io.stderr.push(`Unknown action: ${_exhaustive}`);
1270
+ return EXIT.USAGE;
1271
+ }
1272
+ }
1273
+ }
1274
+ function runRg(action, value, options, io = { stdout: [], stderr: [] }) {
1275
+ const input = resolveInput6(value, options.file);
1276
+ if (input === null) {
1277
+ io.stderr.push("Missing RG value. Pass an argument or use --file.");
1278
+ return EXIT.USAGE;
1279
+ }
1280
+ return runRgCommand(action, input, options, io);
1281
+ }
1282
+
630
1283
  // src/commands/renavam.ts
631
1284
  import {
632
1285
  RENAVAM_OFFICIAL_SOURCE_URL,
@@ -634,7 +1287,7 @@ import {
634
1287
  stripRenavam,
635
1288
  validateRenavam
636
1289
  } from "@br-validators/core";
637
- function resolveInput5(value, fileContent) {
1290
+ function resolveInput7(value, fileContent) {
638
1291
  const input = value ?? fileContent?.trim();
639
1292
  if (!input) {
640
1293
  return null;
@@ -658,7 +1311,7 @@ function runRenavamCommand(action, input, options, io = { stdout: [], stderr: []
658
1311
  }
659
1312
  }
660
1313
  function runRenavam(action, value, options, io = { stdout: [], stderr: [] }) {
661
- const input = resolveInput5(value, options.file);
1314
+ const input = resolveInput7(value, options.file);
662
1315
  if (input === null) {
663
1316
  io.stderr.push("Missing RENAVAM value. Pass an argument or use --file.");
664
1317
  return EXIT.USAGE;
@@ -673,7 +1326,7 @@ import {
673
1326
  stripTituloEleitor,
674
1327
  validateTituloEleitor
675
1328
  } from "@br-validators/core";
676
- function resolveInput6(value, fileContent) {
1329
+ function resolveInput8(value, fileContent) {
677
1330
  const input = value ?? fileContent?.trim();
678
1331
  if (!input) {
679
1332
  return null;
@@ -697,7 +1350,7 @@ function runTituloEleitorCommand(action, input, options, io = { stdout: [], stde
697
1350
  }
698
1351
  }
699
1352
  function runTituloEleitor(action, value, options, io = { stdout: [], stderr: [] }) {
700
- const input = resolveInput6(value, options.file);
1353
+ const input = resolveInput8(value, options.file);
701
1354
  if (input === null) {
702
1355
  io.stderr.push("Missing T\xEDtulo de Eleitor value. Pass an argument or use --file.");
703
1356
  return EXIT.USAGE;
@@ -713,7 +1366,7 @@ import {
713
1366
  stripNfeChave,
714
1367
  validateNfeChave
715
1368
  } from "@br-validators/core";
716
- function resolveInput7(value, fileContent) {
1369
+ function resolveInput9(value, fileContent) {
717
1370
  const input = value ?? fileContent?.trim();
718
1371
  if (!input) {
719
1372
  return null;
@@ -739,7 +1392,7 @@ function runNfeChaveCommand(action, input, options, io = { stdout: [], stderr: [
739
1392
  }
740
1393
  }
741
1394
  function runNfeChave(action, value, options, io = { stdout: [], stderr: [] }) {
742
- const input = resolveInput7(value, options.file);
1395
+ const input = resolveInput9(value, options.file);
743
1396
  if (input === null) {
744
1397
  io.stderr.push("Missing NF-e chave de acesso value. Pass an argument or use --file.");
745
1398
  return EXIT.USAGE;
@@ -754,7 +1407,7 @@ import {
754
1407
  stripCnpj,
755
1408
  validateCnpj
756
1409
  } from "@br-validators/core";
757
- function resolveInput8(value, fileContent) {
1410
+ function resolveInput10(value, fileContent) {
758
1411
  const input = value ?? fileContent?.trim();
759
1412
  if (!input) {
760
1413
  return null;
@@ -778,7 +1431,7 @@ function runCnpjCommand(action, input, options, io = { stdout: [], stderr: [] })
778
1431
  }
779
1432
  }
780
1433
  function runCnpj(action, value, options, io = { stdout: [], stderr: [] }) {
781
- const input = resolveInput8(value, options.file);
1434
+ const input = resolveInput10(value, options.file);
782
1435
  if (input === null) {
783
1436
  io.stderr.push("Missing CNPJ value. Pass an argument or use --file.");
784
1437
  return EXIT.USAGE;
@@ -793,7 +1446,7 @@ import {
793
1446
  stripCpf,
794
1447
  validateCpf
795
1448
  } from "@br-validators/core";
796
- function resolveInput9(value, fileContent) {
1449
+ function resolveInput11(value, fileContent) {
797
1450
  const input = value ?? fileContent?.trim();
798
1451
  if (!input) {
799
1452
  return null;
@@ -817,7 +1470,7 @@ function runCpfCommand(action, input, options, io = { stdout: [], stderr: [] })
817
1470
  }
818
1471
  }
819
1472
  function runCpf(action, value, options, io = { stdout: [], stderr: [] }) {
820
- const input = resolveInput9(value, options.file);
1473
+ const input = resolveInput11(value, options.file);
821
1474
  if (input === null) {
822
1475
  io.stderr.push("Missing CPF value. Pass an argument or use --file.");
823
1476
  return EXIT.USAGE;
@@ -833,7 +1486,7 @@ import {
833
1486
  stripPlaca,
834
1487
  validatePlaca
835
1488
  } from "@br-validators/core";
836
- function resolveInput10(value, fileContent) {
1489
+ function resolveInput12(value, fileContent) {
837
1490
  const input = value ?? fileContent?.trim();
838
1491
  if (!input) {
839
1492
  return null;
@@ -859,7 +1512,7 @@ function runPlacaCommand(action, input, options, io = { stdout: [], stderr: [] }
859
1512
  }
860
1513
  }
861
1514
  function runPlaca(action, value, options, io = { stdout: [], stderr: [] }) {
862
- const input = resolveInput10(value, options.file);
1515
+ const input = resolveInput12(value, options.file);
863
1516
  if (input === null) {
864
1517
  io.stderr.push("Missing placa value. Pass an argument or use --file.");
865
1518
  return EXIT.USAGE;
@@ -874,7 +1527,7 @@ import {
874
1527
  stripPisPasep,
875
1528
  validatePisPasep
876
1529
  } from "@br-validators/core";
877
- function resolveInput11(value, fileContent) {
1530
+ function resolveInput13(value, fileContent) {
878
1531
  const input = value ?? fileContent?.trim();
879
1532
  if (!input) {
880
1533
  return null;
@@ -898,7 +1551,7 @@ function runPisPasepCommand(action, input, options, io = { stdout: [], stderr: [
898
1551
  }
899
1552
  }
900
1553
  function runPisPasep(action, value, options, io = { stdout: [], stderr: [] }) {
901
- const input = resolveInput11(value, options.file);
1554
+ const input = resolveInput13(value, options.file);
902
1555
  if (input === null) {
903
1556
  io.stderr.push("Missing PIS/PASEP value. Pass an argument or use --file.");
904
1557
  return EXIT.USAGE;
@@ -913,7 +1566,7 @@ import {
913
1566
  formatPixKey,
914
1567
  validatePixKey
915
1568
  } from "@br-validators/core";
916
- function resolveInput12(value, fileContent) {
1569
+ function resolveInput14(value, fileContent) {
917
1570
  const input = value ?? fileContent?.trim();
918
1571
  if (!input) {
919
1572
  return null;
@@ -988,7 +1641,7 @@ function runPixCommand(action, input, options, io = { stdout: [], stderr: [] })
988
1641
  }
989
1642
  }
990
1643
  function runPix(action, value, options, io = { stdout: [], stderr: [] }) {
991
- const input = resolveInput12(value, options.file);
1644
+ const input = resolveInput14(value, options.file);
992
1645
  if (input === null) {
993
1646
  io.stderr.push("Missing PIX key value. Pass an argument or use --file.");
994
1647
  return EXIT.USAGE;
@@ -1007,7 +1660,7 @@ import {
1007
1660
  stripLinhaDigitavel,
1008
1661
  validateBoleto
1009
1662
  } from "@br-validators/core";
1010
- function resolveInput13(value, fileContent) {
1663
+ function resolveInput15(value, fileContent) {
1011
1664
  const input = value ?? fileContent?.trim();
1012
1665
  if (!input) {
1013
1666
  return null;
@@ -1142,7 +1795,7 @@ function runBoletoCommand(action, input, options, direction, io = { stdout: [],
1142
1795
  }
1143
1796
  }
1144
1797
  function runBoleto(action, value, options, direction, io = { stdout: [], stderr: [] }) {
1145
- const input = resolveInput13(value, options.file);
1798
+ const input = resolveInput15(value, options.file);
1146
1799
  if (input === null) {
1147
1800
  io.stderr.push("Missing boleto value. Pass an argument or use --file.");
1148
1801
  return EXIT.USAGE;
@@ -1158,7 +1811,7 @@ import {
1158
1811
  stripCartaoCredito,
1159
1812
  validateCartaoCredito
1160
1813
  } from "@br-validators/core";
1161
- function resolveInput14(value, fileContent) {
1814
+ function resolveInput16(value, fileContent) {
1162
1815
  const input = value ?? fileContent?.trim();
1163
1816
  if (!input) {
1164
1817
  return null;
@@ -1234,7 +1887,7 @@ function runCartaoCommand(action, input, options, io = { stdout: [], stderr: []
1234
1887
  }
1235
1888
  }
1236
1889
  function runCartao(action, value, options, io = { stdout: [], stderr: [] }) {
1237
- const input = resolveInput14(value, options.file);
1890
+ const input = resolveInput16(value, options.file);
1238
1891
  if (input === null) {
1239
1892
  io.stderr.push("Missing credit card PAN value. Pass an argument or use --file.");
1240
1893
  return EXIT.USAGE;
@@ -1255,7 +1908,7 @@ import {
1255
1908
  validateIeProdutorRural,
1256
1909
  validateInscricaoEstadual
1257
1910
  } from "@br-validators/core";
1258
- function resolveInput15(value, fileContent) {
1911
+ function resolveInput17(value, fileContent) {
1259
1912
  const input = value ?? fileContent?.trim();
1260
1913
  if (!input) {
1261
1914
  return null;
@@ -1352,7 +2005,7 @@ function runIeCommand(action, input, options, io = { stdout: [], stderr: [] }) {
1352
2005
  }
1353
2006
  }
1354
2007
  function runIe(action, value, options, io = { stdout: [], stderr: [] }) {
1355
- const input = resolveInput15(value, options.file);
2008
+ const input = resolveInput17(value, options.file);
1356
2009
  if (input === null) {
1357
2010
  io.stderr.push("Missing IE value. Pass an argument or use --file.");
1358
2011
  return EXIT.USAGE;
@@ -1362,7 +2015,7 @@ function runIe(action, value, options, io = { stdout: [], stderr: [] }) {
1362
2015
 
1363
2016
  // src/commands/detect.ts
1364
2017
  import { detect } from "@br-validators/core";
1365
- function resolveInput16(value, fileContent) {
2018
+ function resolveInput18(value, fileContent) {
1366
2019
  const input = value ?? fileContent?.trim();
1367
2020
  if (!input) {
1368
2021
  return null;
@@ -1396,7 +2049,7 @@ function printDetect(result, options, io = { stdout: [], stderr: [] }) {
1396
2049
  return EXIT.INVALID;
1397
2050
  }
1398
2051
  function runDetect(value, options, io = { stdout: [], stderr: [] }) {
1399
- const input = resolveInput16(value, options.file);
2052
+ const input = resolveInput18(value, options.file);
1400
2053
  if (input === null) {
1401
2054
  io.stderr.push("Missing value. Pass an argument or use --file.");
1402
2055
  return EXIT.USAGE;
@@ -1427,7 +2080,7 @@ var SANITIZABLE_TYPES = [
1427
2080
  function isSanitizableType(type) {
1428
2081
  return SANITIZABLE_TYPES.includes(type);
1429
2082
  }
1430
- function resolveInput17(value, fileContent) {
2083
+ function resolveInput19(value, fileContent) {
1431
2084
  const input = value ?? fileContent?.trim();
1432
2085
  if (!input) {
1433
2086
  return null;
@@ -1458,7 +2111,7 @@ function runSanitize(type, value, options, io = { stdout: [], stderr: [] }) {
1458
2111
  io.stderr.push(`Unsupported sanitize type: ${type}`);
1459
2112
  return EXIT.USAGE;
1460
2113
  }
1461
- const input = resolveInput17(value, options.file);
2114
+ const input = resolveInput19(value, options.file);
1462
2115
  if (input === null) {
1463
2116
  io.stderr.push("Missing value. Pass an argument or use --file.");
1464
2117
  return EXIT.USAGE;
@@ -1828,6 +2481,27 @@ function handleTituloEleitorCli(action, value, opts, io = { stdout: [], stderr:
1828
2481
  io
1829
2482
  );
1830
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
+ }
1831
2505
  function handleNfeChaveCli(action, value, opts, io = { stdout: [], stderr: [] }) {
1832
2506
  let fileContent;
1833
2507
  if (opts.file) {
@@ -1892,6 +2566,28 @@ function handleIeCli(action, value, opts, io = { stdout: [], stderr: [] }) {
1892
2566
  io
1893
2567
  );
1894
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
+ }
1895
2591
  function handleDetectCli(value, opts, io = { stdout: [], stderr: [] }) {
1896
2592
  let fileContent;
1897
2593
  if (opts.file) {
@@ -1979,6 +2675,45 @@ function handleReferenceLookupCli(command, value, opts, io = { stdout: [], stder
1979
2675
  io
1980
2676
  );
1981
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
+ }
1982
2717
  function writeCliIo(io) {
1983
2718
  for (const line of io.stdout) console.log(line);
1984
2719
  for (const line of io.stderr) console.error(line);
@@ -1994,6 +2729,13 @@ function registerReferenceLookupCommands(program) {
1994
2729
  process.exitCode = handleReferenceLookupCli(command, codigo, opts, io);
1995
2730
  writeCliIo(io);
1996
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
+ }
1997
2739
  }
1998
2740
  }
1999
2741
 
@@ -2030,6 +2772,11 @@ function createProgram() {
2030
2772
  writeCliIo(io);
2031
2773
  });
2032
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
+ });
2033
2780
  const telefone = program.command("telefone").description("Telefone \u2014 Brazilian fixo/celular (Anatel DDD)");
2034
2781
  for (const action of ["validate", "format", "strip"]) {
2035
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) => {
@@ -2062,6 +2809,14 @@ function createProgram() {
2062
2809
  writeCliIo(io);
2063
2810
  });
2064
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
+ }
2065
2820
  const nfeChave = program.command("nfe-chave").description("NF-e / NFC-e chave de acesso \u2014 44 digits (SEFAZ MOC \xA72.2.6)");
2066
2821
  for (const action of ["validate", "parse", "format", "strip"]) {
2067
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) => {
@@ -2165,6 +2920,14 @@ function createProgram() {
2165
2920
  writeCliIo(io);
2166
2921
  });
2167
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
+ }
2168
2931
  const bancos = program.command("bancos").description("Bacen STR participants \u2014 offline lookup");
2169
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) => {
2170
2933
  const io = { stdout: [], stderr: [] };
@@ -2176,6 +2939,41 @@ function createProgram() {
2176
2939
  process.exitCode = handleBancosListCli(opts, io);
2177
2940
  writeCliIo(io);
2178
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
+ });
2179
2977
  registerReferenceLookupCommands(program);
2180
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) => {
2181
2979
  const io = { stdout: [], stderr: [] };