@br-validators/cli 0.10.0-alpha.1 → 0.11.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +236 -24
  2. package/package.json +4 -2
package/dist/index.js CHANGED
@@ -6,22 +6,103 @@ import { Command } from "commander";
6
6
  // src/handlers.ts
7
7
  import { readFileSync } from "fs";
8
8
 
9
- // src/commands/cep.ts
9
+ // src/commands/brcode.ts
10
10
  import {
11
- CEP_OFFICIAL_SOURCE_URL,
12
- formatCep,
13
- stripCep,
14
- validateCep
11
+ BRCODE_OFFICIAL_SOURCE_URL,
12
+ parseBrCode,
13
+ validateBrCode
15
14
  } from "@br-validators/core";
16
15
 
17
16
  // src/constants.ts
18
- var SUPPORTED_TYPES = ["cnpj", "cpf", "cep", "placa", "pis-pasep", "pix", "boleto", "cartao", "ie"];
17
+ var SUPPORTED_TYPES = ["cnpj", "cpf", "cep", "telefone", "brcode", "placa", "pis-pasep", "pix", "boleto", "cartao", "ie"];
19
18
  var EXIT = {
20
19
  OK: 0,
21
20
  INVALID: 1,
22
21
  USAGE: 2
23
22
  };
24
23
 
24
+ // src/commands/brcode.ts
25
+ function resolveInput(value, fileContent) {
26
+ const input = value ?? fileContent?.trim();
27
+ if (!input) {
28
+ return null;
29
+ }
30
+ return input;
31
+ }
32
+ function printBrCodeResult(result, options, io = { stdout: [], stderr: [] }) {
33
+ if (options.json) {
34
+ io.stdout.push(
35
+ JSON.stringify(
36
+ result.ok ? {
37
+ ok: true,
38
+ value: result.value,
39
+ format: result.format,
40
+ merchantName: result.merchantName,
41
+ merchantCity: result.merchantCity,
42
+ ...result.amount ? { amount: result.amount } : {},
43
+ ...result.txid ? { txid: result.txid } : {},
44
+ ...result.pixKey ? { pixKey: result.pixKey, pixKeyType: result.pixKeyType } : {},
45
+ ...result.pixInitiationUrl ? { pixInitiationUrl: result.pixInitiationUrl } : {},
46
+ ...options.source ? { source: options.source } : {}
47
+ } : { ok: false, code: result.code, message: result.message },
48
+ null,
49
+ 2
50
+ )
51
+ );
52
+ return result.ok ? EXIT.OK : EXIT.INVALID;
53
+ }
54
+ if (options.quiet) {
55
+ return result.ok ? EXIT.OK : EXIT.INVALID;
56
+ }
57
+ if (result.ok) {
58
+ io.stdout.push("valid: yes");
59
+ io.stdout.push(`merchantName: ${result.merchantName}`);
60
+ io.stdout.push(`merchantCity: ${result.merchantCity}`);
61
+ if (result.amount) {
62
+ io.stdout.push(`amount: ${result.amount}`);
63
+ }
64
+ if (result.txid) {
65
+ io.stdout.push(`txid: ${result.txid}`);
66
+ }
67
+ if (result.pixKey) {
68
+ io.stdout.push(`pixKey: ${result.pixKey}`);
69
+ io.stdout.push(`pixKeyType: ${result.pixKeyType}`);
70
+ }
71
+ if (result.pixInitiationUrl) {
72
+ io.stdout.push(`pixInitiationUrl: ${result.pixInitiationUrl}`);
73
+ }
74
+ if (options.source) {
75
+ io.stdout.push(`source: ${options.source}`);
76
+ }
77
+ return EXIT.OK;
78
+ }
79
+ io.stderr.push("valid: no");
80
+ io.stderr.push(`code: ${result.code}`);
81
+ io.stderr.push(`message: ${result.message}`);
82
+ return EXIT.INVALID;
83
+ }
84
+ function runBrCodeCommand(action, input, options, io = { stdout: [], stderr: [] }) {
85
+ const source = options.source ? BRCODE_OFFICIAL_SOURCE_URL : void 0;
86
+ const result = action === "validate" ? validateBrCode(input) : parseBrCode(input);
87
+ return printBrCodeResult(result, { json: options.json, quiet: options.quiet, source }, io);
88
+ }
89
+ function runBrCode(action, value, options, io = { stdout: [], stderr: [] }) {
90
+ const input = resolveInput(value, options.file);
91
+ if (input === null) {
92
+ io.stderr.push("Missing BR Code payload. Pass an argument or use --file.");
93
+ return EXIT.USAGE;
94
+ }
95
+ return runBrCodeCommand(action, input, options, io);
96
+ }
97
+
98
+ // src/commands/cep.ts
99
+ import {
100
+ CEP_OFFICIAL_SOURCE_URL,
101
+ formatCep,
102
+ stripCep,
103
+ validateCep
104
+ } from "@br-validators/core";
105
+
25
106
  // src/output.ts
26
107
  function printValidation(result, options, io = { stdout: [], stderr: [] }) {
27
108
  if (options.json) {
@@ -81,7 +162,7 @@ function printStrip(value, options, io = { stdout: [] }) {
81
162
  }
82
163
 
83
164
  // src/commands/cep.ts
84
- function resolveInput(value, fileContent) {
165
+ function resolveInput2(value, fileContent) {
85
166
  const input = value ?? fileContent?.trim();
86
167
  if (!input) {
87
168
  return null;
@@ -105,7 +186,7 @@ function runCepCommand(action, input, options, io = { stdout: [], stderr: [] })
105
186
  }
106
187
  }
107
188
  function runCep(action, value, options, io = { stdout: [], stderr: [] }) {
108
- const input = resolveInput(value, options.file);
189
+ const input = resolveInput2(value, options.file);
109
190
  if (input === null) {
110
191
  io.stderr.push("Missing CEP value. Pass an argument or use --file.");
111
192
  return EXIT.USAGE;
@@ -113,6 +194,79 @@ function runCep(action, value, options, io = { stdout: [], stderr: [] }) {
113
194
  return runCepCommand(action, input, options, io);
114
195
  }
115
196
 
197
+ // src/commands/telefone.ts
198
+ import {
199
+ TELEFONE_OFFICIAL_SOURCE_URL,
200
+ formatTelefone,
201
+ stripTelefone,
202
+ validateTelefone
203
+ } from "@br-validators/core";
204
+ function resolveInput3(value, fileContent) {
205
+ const input = value ?? fileContent?.trim();
206
+ if (!input) {
207
+ return null;
208
+ }
209
+ return input;
210
+ }
211
+ function printTelefoneValidation(result, options, io = { stdout: [], stderr: [] }) {
212
+ if (options.json) {
213
+ io.stdout.push(
214
+ JSON.stringify(
215
+ result.ok ? {
216
+ ok: true,
217
+ value: result.value,
218
+ tipo: result.tipo,
219
+ format: result.format,
220
+ ...options.source ? { source: options.source } : {}
221
+ } : { ok: false, code: result.code, message: result.message },
222
+ null,
223
+ 2
224
+ )
225
+ );
226
+ return result.ok ? EXIT.OK : EXIT.INVALID;
227
+ }
228
+ if (options.quiet) {
229
+ return result.ok ? EXIT.OK : EXIT.INVALID;
230
+ }
231
+ if (result.ok) {
232
+ io.stdout.push(`valid: yes (${result.tipo})`);
233
+ io.stdout.push(`value: ${result.value}`);
234
+ io.stdout.push(`format: ${result.format}`);
235
+ if (options.source) {
236
+ io.stdout.push(`source: ${options.source}`);
237
+ }
238
+ return EXIT.OK;
239
+ }
240
+ io.stderr.push("valid: no");
241
+ io.stderr.push(`code: ${result.code}`);
242
+ io.stderr.push(`message: ${result.message}`);
243
+ return EXIT.INVALID;
244
+ }
245
+ function runTelefoneCommand(action, input, options, io = { stdout: [], stderr: [] }) {
246
+ const source = options.source ? TELEFONE_OFFICIAL_SOURCE_URL : void 0;
247
+ switch (action) {
248
+ case "validate":
249
+ return printTelefoneValidation(validateTelefone(input), { json: options.json, quiet: options.quiet, source }, io);
250
+ case "format":
251
+ return printFormat(formatTelefone(input), { json: options.json, quiet: options.quiet }, io);
252
+ case "strip":
253
+ return printStrip(stripTelefone(input), { json: options.json }, io);
254
+ default: {
255
+ const _exhaustive = action;
256
+ io.stderr.push(`Unknown action: ${_exhaustive}`);
257
+ return EXIT.USAGE;
258
+ }
259
+ }
260
+ }
261
+ function runTelefone(action, value, options, io = { stdout: [], stderr: [] }) {
262
+ const input = resolveInput3(value, options.file);
263
+ if (input === null) {
264
+ io.stderr.push("Missing telephone value. Pass an argument or use --file.");
265
+ return EXIT.USAGE;
266
+ }
267
+ return runTelefoneCommand(action, input, options, io);
268
+ }
269
+
116
270
  // src/commands/cnpj.ts
117
271
  import {
118
272
  CNPJ_OFFICIAL_SOURCE_URL,
@@ -120,7 +274,7 @@ import {
120
274
  stripCnpj,
121
275
  validateCnpj
122
276
  } from "@br-validators/core";
123
- function resolveInput2(value, fileContent) {
277
+ function resolveInput4(value, fileContent) {
124
278
  const input = value ?? fileContent?.trim();
125
279
  if (!input) {
126
280
  return null;
@@ -144,7 +298,7 @@ function runCnpjCommand(action, input, options, io = { stdout: [], stderr: [] })
144
298
  }
145
299
  }
146
300
  function runCnpj(action, value, options, io = { stdout: [], stderr: [] }) {
147
- const input = resolveInput2(value, options.file);
301
+ const input = resolveInput4(value, options.file);
148
302
  if (input === null) {
149
303
  io.stderr.push("Missing CNPJ value. Pass an argument or use --file.");
150
304
  return EXIT.USAGE;
@@ -159,7 +313,7 @@ import {
159
313
  stripCpf,
160
314
  validateCpf
161
315
  } from "@br-validators/core";
162
- function resolveInput3(value, fileContent) {
316
+ function resolveInput5(value, fileContent) {
163
317
  const input = value ?? fileContent?.trim();
164
318
  if (!input) {
165
319
  return null;
@@ -183,7 +337,7 @@ function runCpfCommand(action, input, options, io = { stdout: [], stderr: [] })
183
337
  }
184
338
  }
185
339
  function runCpf(action, value, options, io = { stdout: [], stderr: [] }) {
186
- const input = resolveInput3(value, options.file);
340
+ const input = resolveInput5(value, options.file);
187
341
  if (input === null) {
188
342
  io.stderr.push("Missing CPF value. Pass an argument or use --file.");
189
343
  return EXIT.USAGE;
@@ -199,7 +353,7 @@ import {
199
353
  stripPlaca,
200
354
  validatePlaca
201
355
  } from "@br-validators/core";
202
- function resolveInput4(value, fileContent) {
356
+ function resolveInput6(value, fileContent) {
203
357
  const input = value ?? fileContent?.trim();
204
358
  if (!input) {
205
359
  return null;
@@ -225,7 +379,7 @@ function runPlacaCommand(action, input, options, io = { stdout: [], stderr: [] }
225
379
  }
226
380
  }
227
381
  function runPlaca(action, value, options, io = { stdout: [], stderr: [] }) {
228
- const input = resolveInput4(value, options.file);
382
+ const input = resolveInput6(value, options.file);
229
383
  if (input === null) {
230
384
  io.stderr.push("Missing placa value. Pass an argument or use --file.");
231
385
  return EXIT.USAGE;
@@ -240,7 +394,7 @@ import {
240
394
  stripPisPasep,
241
395
  validatePisPasep
242
396
  } from "@br-validators/core";
243
- function resolveInput5(value, fileContent) {
397
+ function resolveInput7(value, fileContent) {
244
398
  const input = value ?? fileContent?.trim();
245
399
  if (!input) {
246
400
  return null;
@@ -264,7 +418,7 @@ function runPisPasepCommand(action, input, options, io = { stdout: [], stderr: [
264
418
  }
265
419
  }
266
420
  function runPisPasep(action, value, options, io = { stdout: [], stderr: [] }) {
267
- const input = resolveInput5(value, options.file);
421
+ const input = resolveInput7(value, options.file);
268
422
  if (input === null) {
269
423
  io.stderr.push("Missing PIS/PASEP value. Pass an argument or use --file.");
270
424
  return EXIT.USAGE;
@@ -279,7 +433,7 @@ import {
279
433
  formatPixKey,
280
434
  validatePixKey
281
435
  } from "@br-validators/core";
282
- function resolveInput6(value, fileContent) {
436
+ function resolveInput8(value, fileContent) {
283
437
  const input = value ?? fileContent?.trim();
284
438
  if (!input) {
285
439
  return null;
@@ -354,7 +508,7 @@ function runPixCommand(action, input, options, io = { stdout: [], stderr: [] })
354
508
  }
355
509
  }
356
510
  function runPix(action, value, options, io = { stdout: [], stderr: [] }) {
357
- const input = resolveInput6(value, options.file);
511
+ const input = resolveInput8(value, options.file);
358
512
  if (input === null) {
359
513
  io.stderr.push("Missing PIX key value. Pass an argument or use --file.");
360
514
  return EXIT.USAGE;
@@ -373,7 +527,7 @@ import {
373
527
  stripLinhaDigitavel,
374
528
  validateBoleto
375
529
  } from "@br-validators/core";
376
- function resolveInput7(value, fileContent) {
530
+ function resolveInput9(value, fileContent) {
377
531
  const input = value ?? fileContent?.trim();
378
532
  if (!input) {
379
533
  return null;
@@ -497,7 +651,7 @@ function runBoletoCommand(action, input, options, direction, io = { stdout: [],
497
651
  }
498
652
  }
499
653
  function runBoleto(action, value, options, direction, io = { stdout: [], stderr: [] }) {
500
- const input = resolveInput7(value, options.file);
654
+ const input = resolveInput9(value, options.file);
501
655
  if (input === null) {
502
656
  io.stderr.push("Missing boleto value. Pass an argument or use --file.");
503
657
  return EXIT.USAGE;
@@ -513,7 +667,7 @@ import {
513
667
  stripCartaoCredito,
514
668
  validateCartaoCredito
515
669
  } from "@br-validators/core";
516
- function resolveInput8(value, fileContent) {
670
+ function resolveInput10(value, fileContent) {
517
671
  const input = value ?? fileContent?.trim();
518
672
  if (!input) {
519
673
  return null;
@@ -589,7 +743,7 @@ function runCartaoCommand(action, input, options, io = { stdout: [], stderr: []
589
743
  }
590
744
  }
591
745
  function runCartao(action, value, options, io = { stdout: [], stderr: [] }) {
592
- const input = resolveInput8(value, options.file);
746
+ const input = resolveInput10(value, options.file);
593
747
  if (input === null) {
594
748
  io.stderr.push("Missing credit card PAN value. Pass an argument or use --file.");
595
749
  return EXIT.USAGE;
@@ -605,7 +759,7 @@ import {
605
759
  stripInscricaoEstadual,
606
760
  validateInscricaoEstadual
607
761
  } from "@br-validators/core";
608
- function resolveInput9(value, fileContent) {
762
+ function resolveInput11(value, fileContent) {
609
763
  const input = value ?? fileContent?.trim();
610
764
  if (!input) {
611
765
  return null;
@@ -686,7 +840,7 @@ function runIeCommand(action, input, options, io = { stdout: [], stderr: [] }) {
686
840
  }
687
841
  }
688
842
  function runIe(action, value, options, io = { stdout: [], stderr: [] }) {
689
- const input = resolveInput9(value, options.file);
843
+ const input = resolveInput11(value, options.file);
690
844
  if (input === null) {
691
845
  io.stderr.push("Missing IE value. Pass an argument or use --file.");
692
846
  return EXIT.USAGE;
@@ -777,6 +931,27 @@ function handleCepCli(action, value, opts, io = { stdout: [], stderr: [] }) {
777
931
  io
778
932
  );
779
933
  }
934
+ function handleTelefoneCli(action, value, opts, io = { stdout: [], stderr: [] }) {
935
+ let fileContent;
936
+ if (opts.file) {
937
+ const content = readInputFile(opts.file, io);
938
+ if (content === null) {
939
+ return EXIT.USAGE;
940
+ }
941
+ fileContent = content;
942
+ }
943
+ return runTelefone(
944
+ action,
945
+ value,
946
+ {
947
+ json: Boolean(opts.json),
948
+ quiet: Boolean(opts.quiet),
949
+ source: Boolean(opts.source),
950
+ file: fileContent
951
+ },
952
+ io
953
+ );
954
+ }
780
955
  function handlePlacaCli(action, value, opts, io = { stdout: [], stderr: [] }) {
781
956
  let fileContent;
782
957
  if (opts.file) {
@@ -906,6 +1081,27 @@ function handleCartaoCreditoCli(action, value, opts, io = { stdout: [], stderr:
906
1081
  io
907
1082
  );
908
1083
  }
1084
+ function handleBrCodeCli(action, value, opts, io = { stdout: [], stderr: [] }) {
1085
+ let fileContent;
1086
+ if (opts.file) {
1087
+ const content = readInputFile(opts.file, io);
1088
+ if (content === null) {
1089
+ return EXIT.USAGE;
1090
+ }
1091
+ fileContent = content;
1092
+ }
1093
+ return runBrCode(
1094
+ action,
1095
+ value,
1096
+ {
1097
+ json: Boolean(opts.json),
1098
+ quiet: Boolean(opts.quiet),
1099
+ source: Boolean(opts.source),
1100
+ file: fileContent
1101
+ },
1102
+ io
1103
+ );
1104
+ }
909
1105
  function handleIeCli(action, value, opts, io = { stdout: [], stderr: [] }) {
910
1106
  let fileContent;
911
1107
  if (opts.file) {
@@ -966,6 +1162,22 @@ function createProgram() {
966
1162
  writeCliIo(io);
967
1163
  });
968
1164
  }
1165
+ const telefone = program.command("telefone").description("Telefone \u2014 Brazilian fixo/celular (Anatel DDD)");
1166
+ for (const action of ["validate", "format", "strip"]) {
1167
+ 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) => {
1168
+ const io = { stdout: [], stderr: [] };
1169
+ process.exitCode = handleTelefoneCli(action, value, opts, io);
1170
+ writeCliIo(io);
1171
+ });
1172
+ }
1173
+ const brcode = program.command("brcode").description("BR Code \u2014 PIX QR payload (Bacen EMV TLV)");
1174
+ for (const action of ["parse", "validate"]) {
1175
+ brcode.command(action).description(`${action} a BR Code payload`).argument("[value]", "BR Code payload (Pix Copia e Cola)").option("--json", "JSON output").option("-q, --quiet", "Exit code only").option("--source", "Include official source URL").option("-f, --file <path>", "Read value from file").action((value, opts) => {
1176
+ const io = { stdout: [], stderr: [] };
1177
+ process.exitCode = handleBrCodeCli(action, value, opts, io);
1178
+ writeCliIo(io);
1179
+ });
1180
+ }
969
1181
  const placa = program.command("placa").description("Placa \u2014 legacy + Mercosul (CONTRAN)");
970
1182
  for (const action of ["validate", "format", "strip", "convert"]) {
971
1183
  placa.command(action).description(`${action} a license plate`).argument("[value]", "Placa 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) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@br-validators/cli",
3
- "version": "0.10.0-alpha.1",
3
+ "version": "0.11.0-alpha.0",
4
4
  "description": "Terminal CLI for Brazilian document validation — CPF, CNPJ, CEP, IE, PIX, boleto, and more",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -29,7 +29,7 @@
29
29
  },
30
30
  "dependencies": {
31
31
  "commander": "^13.1.0",
32
- "@br-validators/core": "0.10.0-alpha.0"
32
+ "@br-validators/core": "0.11.0-alpha.0"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@types/node": "^22.15.21",
@@ -44,6 +44,8 @@
44
44
  ],
45
45
  "scripts": {
46
46
  "build": "tsup",
47
+ "pretest": "pnpm run build",
48
+ "pretest:coverage": "pnpm run build",
47
49
  "pretypecheck": "pnpm --filter @br-validators/core build",
48
50
  "test": "vitest run",
49
51
  "test:coverage": "vitest run --coverage",