@br-validators/cli 1.8.3 → 1.10.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/README.md +43 -7
- package/dist/index.js +1409 -110
- package/dist/run-captured.js +1436 -114
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
3
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
4
|
-
}) : x)(function(x) {
|
|
5
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
6
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
7
|
-
});
|
|
8
2
|
|
|
9
3
|
// src/program.ts
|
|
10
4
|
import { Command } from "commander";
|
|
11
5
|
|
|
6
|
+
// src/handlers.ts
|
|
7
|
+
import { createRequire } from "module";
|
|
8
|
+
|
|
12
9
|
// src/commands/bancos/list.ts
|
|
13
|
-
import { BANCOS_DATA_VERSION as BANCOS_DATA_VERSION2,
|
|
10
|
+
import { BANCOS_DATA_VERSION as BANCOS_DATA_VERSION2, getAllBancos } from "@br-validators/core/bancos";
|
|
14
11
|
|
|
15
12
|
// src/constants.ts
|
|
16
13
|
var SUPPORTED_TYPES = ["cnpj", "cpf", "cep", "telefone", "cnh", "renavam", "titulo-eleitor", "processo-judicial", "rg", "nfe-chave", "brcode", "placa", "pis-pasep", "pix", "boleto", "cartao", "ie"];
|
|
@@ -23,9 +20,10 @@ var EXIT = {
|
|
|
23
20
|
// src/commands/bancos/lookup.ts
|
|
24
21
|
import {
|
|
25
22
|
BANCOS_DATA_VERSION,
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
lookupBancoPorCodigo,
|
|
24
|
+
lookupBancoPorIspb
|
|
28
25
|
} from "@br-validators/core/bancos";
|
|
26
|
+
import { lookupInvalidFormat } from "@br-validators/core/lookup";
|
|
29
27
|
function normalizeBancosLookupInput(raw) {
|
|
30
28
|
const digits = raw.replace(/\D/g, "");
|
|
31
29
|
if (digits.length === 8) {
|
|
@@ -39,33 +37,36 @@ function normalizeBancosLookupInput(raw) {
|
|
|
39
37
|
function lookupBanco(raw) {
|
|
40
38
|
const normalized = normalizeBancosLookupInput(raw);
|
|
41
39
|
if (!normalized) {
|
|
42
|
-
return
|
|
40
|
+
return lookupInvalidFormat(
|
|
41
|
+
"Invalid bank code or ISPB. Use 3-digit COMPE (e.g. 001) or 8-digit ISPB."
|
|
42
|
+
);
|
|
43
43
|
}
|
|
44
|
-
return normalized.kind === "ispb" ?
|
|
44
|
+
return normalized.kind === "ispb" ? lookupBancoPorIspb(normalized.value) : lookupBancoPorCodigo(normalized.value);
|
|
45
45
|
}
|
|
46
46
|
function formatBancoHuman(banco) {
|
|
47
47
|
return `${banco.codigo} \u2014 ${banco.nome} (ISPB ${banco.ispb})`;
|
|
48
48
|
}
|
|
49
49
|
function runBancosLookupCommand(input, options, io = { stdout: [], stderr: [] }) {
|
|
50
|
-
const
|
|
51
|
-
if (!
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
50
|
+
const result = lookupBanco(input);
|
|
51
|
+
if (!result.ok) {
|
|
52
|
+
if (options.json) {
|
|
53
|
+
io.stdout.push(
|
|
54
|
+
JSON.stringify({ ok: false, code: result.code, message: result.message }, null, 2)
|
|
55
|
+
);
|
|
56
|
+
} else {
|
|
57
|
+
io.stderr.push(result.message);
|
|
58
|
+
}
|
|
59
|
+
return normalizeBancosLookupInput(input) === null ? EXIT.USAGE : EXIT.INVALID;
|
|
59
60
|
}
|
|
60
61
|
if (options.json) {
|
|
61
|
-
const payload = { ok: true, banco };
|
|
62
|
+
const payload = { ok: true, banco: result.value };
|
|
62
63
|
if (options.verbose) {
|
|
63
64
|
payload.capturadoEm = BANCOS_DATA_VERSION.capturadoEm;
|
|
64
65
|
}
|
|
65
66
|
io.stdout.push(JSON.stringify(payload, null, 2));
|
|
66
67
|
return EXIT.OK;
|
|
67
68
|
}
|
|
68
|
-
io.stdout.push(formatBancoHuman(
|
|
69
|
+
io.stdout.push(formatBancoHuman(result.value));
|
|
69
70
|
if (options.verbose) {
|
|
70
71
|
io.stdout.push(`capturadoEm: ${BANCOS_DATA_VERSION.capturadoEm}`);
|
|
71
72
|
}
|
|
@@ -81,7 +82,7 @@ function runBancosLookup(value, options, io = { stdout: [], stderr: [] }) {
|
|
|
81
82
|
|
|
82
83
|
// src/commands/bancos/list.ts
|
|
83
84
|
function sliceBancos(limit) {
|
|
84
|
-
const all =
|
|
85
|
+
const all = getAllBancos();
|
|
85
86
|
if (limit === void 0 || !Number.isFinite(limit) || limit <= 0) {
|
|
86
87
|
return all;
|
|
87
88
|
}
|
|
@@ -116,47 +117,56 @@ function runBancosList(options, io = { stdout: [], stderr: [] }) {
|
|
|
116
117
|
// src/commands/reference-lookup/registry.ts
|
|
117
118
|
import {
|
|
118
119
|
CEST_DATA_VERSION,
|
|
119
|
-
|
|
120
|
+
lookupCestPorCodigo
|
|
120
121
|
} from "@br-validators/core/cest";
|
|
121
122
|
import {
|
|
122
123
|
INCOTERMS_DATA_VERSION,
|
|
123
|
-
|
|
124
|
+
lookupIncotermPorCodigo
|
|
124
125
|
} from "@br-validators/core/incoterms";
|
|
125
126
|
import {
|
|
126
127
|
MOEDAS_DATA_VERSION,
|
|
127
|
-
|
|
128
|
+
lookupMoedaPorCodigo
|
|
128
129
|
} from "@br-validators/core/moedas";
|
|
129
130
|
import {
|
|
130
131
|
NATUREZA_JURIDICA_DATA_VERSION,
|
|
131
|
-
|
|
132
|
+
lookupNaturezaJuridicaPorCodigo
|
|
132
133
|
} from "@br-validators/core/natureza-juridica";
|
|
133
|
-
import { NBS_DATA_VERSION,
|
|
134
|
+
import { NBS_DATA_VERSION, lookupNbsPorCodigo } from "@br-validators/core/nbs";
|
|
134
135
|
import {
|
|
135
136
|
PAISES_BACEN_DATA_VERSION,
|
|
136
|
-
|
|
137
|
+
lookupPaisPorCodigoBacen
|
|
137
138
|
} from "@br-validators/core/paises-bacen";
|
|
138
139
|
import {
|
|
139
140
|
AEROPORTOS_DATA_VERSION,
|
|
140
|
-
|
|
141
|
-
|
|
141
|
+
lookupAeroportoPorIata,
|
|
142
|
+
lookupAeroportoPorIcao
|
|
142
143
|
} from "@br-validators/core/aeroportos";
|
|
143
|
-
import { PORTOS_DATA_VERSION,
|
|
144
|
+
import { PORTOS_DATA_VERSION, lookupPortoPorCodigo } from "@br-validators/core/portos";
|
|
144
145
|
import {
|
|
145
146
|
CNAES_DATA_VERSION,
|
|
146
|
-
|
|
147
|
+
lookupCnaePorCodigo
|
|
147
148
|
} from "@br-validators/core/cnaes";
|
|
148
149
|
import {
|
|
149
150
|
CFOP_DATA_VERSION,
|
|
150
|
-
|
|
151
|
+
lookupCfopPorCodigo
|
|
151
152
|
} from "@br-validators/core/cfop";
|
|
152
|
-
import {
|
|
153
|
-
|
|
153
|
+
import {
|
|
154
|
+
CSOSN_DATA_VERSION,
|
|
155
|
+
lookupCsosnPorCodigo
|
|
156
|
+
} from "@br-validators/core/csosn";
|
|
157
|
+
import { NCM_DATA_VERSION, lookupNcmPorCodigo } from "@br-validators/core/ncm";
|
|
158
|
+
import { CBO_DATA_VERSION, lookupCboPorCodigo } from "@br-validators/core/cbo";
|
|
159
|
+
import {
|
|
160
|
+
lookupInvalidFormat as lookupInvalidFormat2,
|
|
161
|
+
lookupInvalidInput
|
|
162
|
+
} from "@br-validators/core/lookup";
|
|
154
163
|
var REFERENCE_LOOKUP_COMMANDS = [
|
|
155
164
|
"natureza-juridica",
|
|
156
165
|
"nbs",
|
|
157
166
|
"cest",
|
|
158
167
|
"cnae",
|
|
159
168
|
"cfop",
|
|
169
|
+
"csosn",
|
|
160
170
|
"ncm",
|
|
161
171
|
"cbo",
|
|
162
172
|
"moedas",
|
|
@@ -165,16 +175,19 @@ var REFERENCE_LOOKUP_COMMANDS = [
|
|
|
165
175
|
"portos",
|
|
166
176
|
"aeroportos"
|
|
167
177
|
];
|
|
168
|
-
var REFERENCE_SEARCH_COMMANDS = ["cnae", "cfop", "ncm", "cbo"];
|
|
178
|
+
var REFERENCE_SEARCH_COMMANDS = ["cnae", "cfop", "csosn", "ncm", "cbo"];
|
|
169
179
|
function lookupAeroporto(input) {
|
|
170
180
|
const normalized = input.trim().toUpperCase();
|
|
181
|
+
if (normalized.length === 0) {
|
|
182
|
+
return lookupInvalidInput("Airport code is required");
|
|
183
|
+
}
|
|
171
184
|
if (/^[A-Z0-9]{3}$/.test(normalized)) {
|
|
172
|
-
return
|
|
185
|
+
return lookupAeroportoPorIata(normalized);
|
|
173
186
|
}
|
|
174
187
|
if (/^[A-Z]{4}$/.test(normalized)) {
|
|
175
|
-
return
|
|
188
|
+
return lookupAeroportoPorIcao(normalized);
|
|
176
189
|
}
|
|
177
|
-
return
|
|
190
|
+
return lookupInvalidFormat2("Airport code must be 3-character IATA or 4-character ICAO");
|
|
178
191
|
}
|
|
179
192
|
var REFERENCE_LOOKUP_MODULES = {
|
|
180
193
|
"natureza-juridica": {
|
|
@@ -182,7 +195,7 @@ var REFERENCE_LOOKUP_MODULES = {
|
|
|
182
195
|
description: "RFB legal nature codes \u2014 offline lookup",
|
|
183
196
|
resultKey: "naturezaJuridica",
|
|
184
197
|
capturadoEm: NATUREZA_JURIDICA_DATA_VERSION.capturadoEm,
|
|
185
|
-
lookup: (input) =>
|
|
198
|
+
lookup: (input) => lookupNaturezaJuridicaPorCodigo(input),
|
|
186
199
|
formatHuman: (result) => {
|
|
187
200
|
const row = result;
|
|
188
201
|
return `${row.codigo} \u2014 ${row.descricao}`;
|
|
@@ -193,7 +206,7 @@ var REFERENCE_LOOKUP_MODULES = {
|
|
|
193
206
|
description: "NFSe NBS service codes \u2014 offline lookup",
|
|
194
207
|
resultKey: "nbs",
|
|
195
208
|
capturadoEm: NBS_DATA_VERSION.capturadoEm,
|
|
196
|
-
lookup: (input) =>
|
|
209
|
+
lookup: (input) => lookupNbsPorCodigo(input),
|
|
197
210
|
formatHuman: (result) => {
|
|
198
211
|
const row = result;
|
|
199
212
|
return `${row.codigo} \u2014 ${row.descricao}`;
|
|
@@ -204,7 +217,7 @@ var REFERENCE_LOOKUP_MODULES = {
|
|
|
204
217
|
description: "CONFAZ CEST ST codes \u2014 offline lookup",
|
|
205
218
|
resultKey: "cest",
|
|
206
219
|
capturadoEm: CEST_DATA_VERSION.capturadoEm,
|
|
207
|
-
lookup: (input) =>
|
|
220
|
+
lookup: (input) => lookupCestPorCodigo(input),
|
|
208
221
|
formatHuman: (result) => {
|
|
209
222
|
const row = result;
|
|
210
223
|
return `${row.codigo} \u2014 ${row.descricao}`;
|
|
@@ -215,7 +228,7 @@ var REFERENCE_LOOKUP_MODULES = {
|
|
|
215
228
|
description: "IBGE CNAE 2.3 subclasses \u2014 offline lookup",
|
|
216
229
|
resultKey: "cnae",
|
|
217
230
|
capturadoEm: CNAES_DATA_VERSION.capturadoEm,
|
|
218
|
-
lookup: (input) =>
|
|
231
|
+
lookup: (input) => lookupCnaePorCodigo(input),
|
|
219
232
|
formatHuman: (result) => {
|
|
220
233
|
const row = result;
|
|
221
234
|
return `${row.codigo} \u2014 ${row.descricao}`;
|
|
@@ -226,7 +239,18 @@ var REFERENCE_LOOKUP_MODULES = {
|
|
|
226
239
|
description: "CONFAZ CFOP fiscal operations \u2014 offline lookup",
|
|
227
240
|
resultKey: "cfop",
|
|
228
241
|
capturadoEm: CFOP_DATA_VERSION.capturadoEm,
|
|
229
|
-
lookup: (input) =>
|
|
242
|
+
lookup: (input) => lookupCfopPorCodigo(input),
|
|
243
|
+
formatHuman: (result) => {
|
|
244
|
+
const row = result;
|
|
245
|
+
return `${row.codigo} \u2014 ${row.descricao}`;
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
csosn: {
|
|
249
|
+
command: "csosn",
|
|
250
|
+
description: "CONFAZ CSOSN Simples Nacional \u2014 offline lookup",
|
|
251
|
+
resultKey: "csosn",
|
|
252
|
+
capturadoEm: CSOSN_DATA_VERSION.capturadoEm,
|
|
253
|
+
lookup: (input) => lookupCsosnPorCodigo(input),
|
|
230
254
|
formatHuman: (result) => {
|
|
231
255
|
const row = result;
|
|
232
256
|
return `${row.codigo} \u2014 ${row.descricao}`;
|
|
@@ -237,7 +261,7 @@ var REFERENCE_LOOKUP_MODULES = {
|
|
|
237
261
|
description: "Siscomex NCM Mercosur codes \u2014 offline lookup",
|
|
238
262
|
resultKey: "ncm",
|
|
239
263
|
capturadoEm: NCM_DATA_VERSION.capturadoEm,
|
|
240
|
-
lookup: (input) =>
|
|
264
|
+
lookup: (input) => lookupNcmPorCodigo(input),
|
|
241
265
|
formatHuman: (result) => {
|
|
242
266
|
const row = result;
|
|
243
267
|
return `${row.codigo} \u2014 ${row.descricao}`;
|
|
@@ -248,7 +272,7 @@ var REFERENCE_LOOKUP_MODULES = {
|
|
|
248
272
|
description: "MTE CBO 2002 occupations \u2014 offline lookup",
|
|
249
273
|
resultKey: "cbo",
|
|
250
274
|
capturadoEm: CBO_DATA_VERSION.capturadoEm,
|
|
251
|
-
lookup: (input) =>
|
|
275
|
+
lookup: (input) => lookupCboPorCodigo(input),
|
|
252
276
|
formatHuman: (result) => {
|
|
253
277
|
const row = result;
|
|
254
278
|
return `${row.codigo} \u2014 ${row.descricao}`;
|
|
@@ -259,7 +283,7 @@ var REFERENCE_LOOKUP_MODULES = {
|
|
|
259
283
|
description: "ISO 4217 + Bacen PTAX currencies \u2014 offline lookup",
|
|
260
284
|
resultKey: "moeda",
|
|
261
285
|
capturadoEm: MOEDAS_DATA_VERSION.capturadoEm,
|
|
262
|
-
lookup: (input) =>
|
|
286
|
+
lookup: (input) => lookupMoedaPorCodigo(input),
|
|
263
287
|
formatHuman: (result) => {
|
|
264
288
|
const row = result;
|
|
265
289
|
const symbol = row.simbolo ?? "\u2014";
|
|
@@ -271,7 +295,7 @@ var REFERENCE_LOOKUP_MODULES = {
|
|
|
271
295
|
description: "NF-e Bacen country codes \u2014 offline lookup",
|
|
272
296
|
resultKey: "pais",
|
|
273
297
|
capturadoEm: PAISES_BACEN_DATA_VERSION.capturadoEm,
|
|
274
|
-
lookup: (input) =>
|
|
298
|
+
lookup: (input) => lookupPaisPorCodigoBacen(input),
|
|
275
299
|
formatHuman: (result) => {
|
|
276
300
|
const row = result;
|
|
277
301
|
return `${row.codigo} \u2014 ${row.nome}`;
|
|
@@ -282,7 +306,7 @@ var REFERENCE_LOOKUP_MODULES = {
|
|
|
282
306
|
description: "ICC Incoterms 2020 \u2014 offline lookup",
|
|
283
307
|
resultKey: "incoterm",
|
|
284
308
|
capturadoEm: INCOTERMS_DATA_VERSION.capturadoEm,
|
|
285
|
-
lookup: (input) =>
|
|
309
|
+
lookup: (input) => lookupIncotermPorCodigo(input),
|
|
286
310
|
formatHuman: (result) => {
|
|
287
311
|
const row = result;
|
|
288
312
|
return `${row.codigo} \u2014 ${row.nome} (${row.edicao})`;
|
|
@@ -293,7 +317,7 @@ var REFERENCE_LOOKUP_MODULES = {
|
|
|
293
317
|
description: "ANTAQ port installations \u2014 offline lookup",
|
|
294
318
|
resultKey: "porto",
|
|
295
319
|
capturadoEm: PORTOS_DATA_VERSION.capturadoEm,
|
|
296
|
-
lookup: (input) =>
|
|
320
|
+
lookup: (input) => lookupPortoPorCodigo(input),
|
|
297
321
|
formatHuman: (result) => {
|
|
298
322
|
const row = result;
|
|
299
323
|
return `${row.codigo} \u2014 ${row.nome} (${row.uf})`;
|
|
@@ -320,6 +344,15 @@ function isReferenceSearchCommand(value) {
|
|
|
320
344
|
}
|
|
321
345
|
|
|
322
346
|
// src/commands/reference-lookup/lookup.ts
|
|
347
|
+
function emitLookupFailure(result, options, io) {
|
|
348
|
+
if (options.json) {
|
|
349
|
+
io.stdout.push(
|
|
350
|
+
JSON.stringify({ ok: false, code: result.code, message: result.message }, null, 2)
|
|
351
|
+
);
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
io.stderr.push(result.message);
|
|
355
|
+
}
|
|
323
356
|
function runReferenceLookupCommand(command, input, options, io = { stdout: [], stderr: [] }) {
|
|
324
357
|
const module = REFERENCE_LOOKUP_MODULES[command];
|
|
325
358
|
const trimmed = input.trim();
|
|
@@ -328,20 +361,20 @@ function runReferenceLookupCommand(command, input, options, io = { stdout: [], s
|
|
|
328
361
|
return EXIT.USAGE;
|
|
329
362
|
}
|
|
330
363
|
const result = module.lookup(trimmed);
|
|
331
|
-
if (!result) {
|
|
332
|
-
|
|
364
|
+
if (!result.ok) {
|
|
365
|
+
emitLookupFailure(result, options, io);
|
|
333
366
|
return EXIT.INVALID;
|
|
334
367
|
}
|
|
335
368
|
if (options.json) {
|
|
336
369
|
const payload = {
|
|
337
370
|
ok: true,
|
|
338
|
-
[module.resultKey]: result,
|
|
371
|
+
[module.resultKey]: result.value,
|
|
339
372
|
...options.verbose ? { capturadoEm: module.capturadoEm } : {}
|
|
340
373
|
};
|
|
341
374
|
io.stdout.push(JSON.stringify(payload, null, 2));
|
|
342
375
|
return EXIT.OK;
|
|
343
376
|
}
|
|
344
|
-
io.stdout.push(module.formatHuman(result));
|
|
377
|
+
io.stdout.push(module.formatHuman(result.value));
|
|
345
378
|
if (options.verbose) {
|
|
346
379
|
io.stdout.push(`capturadoEm: ${module.capturadoEm}`);
|
|
347
380
|
}
|
|
@@ -363,6 +396,7 @@ function runReferenceLookup(command, value, options, io = { stdout: [], stderr:
|
|
|
363
396
|
import { searchCbo } from "@br-validators/core/cbo";
|
|
364
397
|
import { searchCnaes } from "@br-validators/core/cnaes";
|
|
365
398
|
import { searchCfop } from "@br-validators/core/cfop";
|
|
399
|
+
import { searchCsosn } from "@br-validators/core/csosn";
|
|
366
400
|
import { searchNcm } from "@br-validators/core/ncm";
|
|
367
401
|
function runSearch(command, query, limit) {
|
|
368
402
|
switch (command) {
|
|
@@ -370,6 +404,8 @@ function runSearch(command, query, limit) {
|
|
|
370
404
|
return searchCnaes(query, { limit });
|
|
371
405
|
case "cfop":
|
|
372
406
|
return searchCfop(query, { limit });
|
|
407
|
+
case "csosn":
|
|
408
|
+
return searchCsosn(query, { limit });
|
|
373
409
|
case "ncm":
|
|
374
410
|
return searchNcm(query, { limit });
|
|
375
411
|
case "cbo":
|
|
@@ -425,11 +461,242 @@ function runReferenceSearch(command, query, options, io = { stdout: [], stderr:
|
|
|
425
461
|
return runReferenceSearchCommand(command, query.trim(), options, io);
|
|
426
462
|
}
|
|
427
463
|
|
|
464
|
+
// src/commands/reference-lookup/validate.ts
|
|
465
|
+
import { validateCfop } from "@br-validators/core/cfop";
|
|
466
|
+
import { validateCsosn } from "@br-validators/core/csosn";
|
|
467
|
+
import { validateNcm } from "@br-validators/core/ncm";
|
|
468
|
+
var REFERENCE_VALIDATE_COMMANDS = ["ncm", "cfop", "csosn"];
|
|
469
|
+
var VALIDATORS = {
|
|
470
|
+
ncm: validateNcm,
|
|
471
|
+
cfop: validateCfop,
|
|
472
|
+
csosn: validateCsosn
|
|
473
|
+
};
|
|
474
|
+
var CAPTURED_AT = {
|
|
475
|
+
ncm: "ncm",
|
|
476
|
+
cfop: "cfop",
|
|
477
|
+
csosn: "csosn"
|
|
478
|
+
};
|
|
479
|
+
function emitFailure(result, options, io) {
|
|
480
|
+
if (options.json) {
|
|
481
|
+
io.stdout.push(JSON.stringify({ ok: false, code: result.code, message: result.message }, null, 2));
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
io.stderr.push(result.message);
|
|
485
|
+
}
|
|
486
|
+
function isReferenceValidateCommand(command) {
|
|
487
|
+
return REFERENCE_VALIDATE_COMMANDS.includes(command);
|
|
488
|
+
}
|
|
489
|
+
function runReferenceValidateCommand(command, input, options, io = { stdout: [], stderr: [] }) {
|
|
490
|
+
const trimmed = input.trim();
|
|
491
|
+
if (trimmed.length === 0) {
|
|
492
|
+
io.stderr.push(`Missing code. Pass a value to validate for ${command}.`);
|
|
493
|
+
return EXIT.USAGE;
|
|
494
|
+
}
|
|
495
|
+
const result = VALIDATORS[command](trimmed);
|
|
496
|
+
if (!result.ok) {
|
|
497
|
+
emitFailure(result, options, io);
|
|
498
|
+
return EXIT.INVALID;
|
|
499
|
+
}
|
|
500
|
+
if (options.json) {
|
|
501
|
+
const payload = {
|
|
502
|
+
ok: true,
|
|
503
|
+
value: result.value,
|
|
504
|
+
description: result.description,
|
|
505
|
+
...result.format !== void 0 ? { format: result.format } : {},
|
|
506
|
+
...options.verbose ? { module: CAPTURED_AT[command] } : {}
|
|
507
|
+
};
|
|
508
|
+
io.stdout.push(JSON.stringify(payload, null, 2));
|
|
509
|
+
return EXIT.OK;
|
|
510
|
+
}
|
|
511
|
+
const lines = [`${result.value} \u2014 ${result.description}`];
|
|
512
|
+
if (result.format !== void 0) {
|
|
513
|
+
lines.push(`format: ${result.format}`);
|
|
514
|
+
}
|
|
515
|
+
io.stdout.push(lines.join("\n"));
|
|
516
|
+
return EXIT.OK;
|
|
517
|
+
}
|
|
518
|
+
function runReferenceValidate(command, value, options, io = { stdout: [], stderr: [] }) {
|
|
519
|
+
if (!isReferenceValidateCommand(command)) {
|
|
520
|
+
io.stderr.push(`Unknown reference validate command: ${command}`);
|
|
521
|
+
return EXIT.USAGE;
|
|
522
|
+
}
|
|
523
|
+
if (!value?.trim()) {
|
|
524
|
+
io.stderr.push(`Missing code. Usage: br-validators ${command} validate <codigo>`);
|
|
525
|
+
return EXIT.USAGE;
|
|
526
|
+
}
|
|
527
|
+
return runReferenceValidateCommand(command, value.trim(), options, io);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
// src/commands/cst/index.ts
|
|
531
|
+
import {
|
|
532
|
+
CST_DATA_VERSION,
|
|
533
|
+
lookupCstCofinsPorCodigo,
|
|
534
|
+
lookupCstIcmsPorCodigo,
|
|
535
|
+
lookupCstIpiPorCodigo,
|
|
536
|
+
lookupCstPisPorCodigo,
|
|
537
|
+
searchCstCofins,
|
|
538
|
+
searchCstIcms,
|
|
539
|
+
searchCstIpi,
|
|
540
|
+
searchCstPis,
|
|
541
|
+
validateCst
|
|
542
|
+
} from "@br-validators/core/cst";
|
|
543
|
+
var CST_TAXES = ["icms", "ipi", "pis", "cofins"];
|
|
544
|
+
function parseCstTax(raw) {
|
|
545
|
+
if (raw === void 0) {
|
|
546
|
+
return null;
|
|
547
|
+
}
|
|
548
|
+
const normalized = raw.trim().toLowerCase();
|
|
549
|
+
if (CST_TAXES.includes(normalized)) {
|
|
550
|
+
return normalized;
|
|
551
|
+
}
|
|
552
|
+
return null;
|
|
553
|
+
}
|
|
554
|
+
function lookupByTax(tax, codigo) {
|
|
555
|
+
switch (tax) {
|
|
556
|
+
case "icms":
|
|
557
|
+
return lookupCstIcmsPorCodigo(codigo);
|
|
558
|
+
case "ipi":
|
|
559
|
+
return lookupCstIpiPorCodigo(codigo);
|
|
560
|
+
case "pis":
|
|
561
|
+
return lookupCstPisPorCodigo(codigo);
|
|
562
|
+
case "cofins":
|
|
563
|
+
return lookupCstCofinsPorCodigo(codigo);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
function searchByTax(tax, query, limit) {
|
|
567
|
+
const options = limit !== void 0 ? { limit } : void 0;
|
|
568
|
+
switch (tax) {
|
|
569
|
+
case "icms":
|
|
570
|
+
return searchCstIcms(query, options);
|
|
571
|
+
case "ipi":
|
|
572
|
+
return searchCstIpi(query, options);
|
|
573
|
+
case "pis":
|
|
574
|
+
return searchCstPis(query, options);
|
|
575
|
+
case "cofins":
|
|
576
|
+
return searchCstCofins(query, options);
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
function emitLookupFailure2(result, options, io) {
|
|
580
|
+
if (options.json) {
|
|
581
|
+
io.stdout.push(JSON.stringify({ ok: false, code: result.code, message: result.message }, null, 2));
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
584
|
+
io.stderr.push(result.message);
|
|
585
|
+
}
|
|
586
|
+
function emitValidateFailure(result, options, io) {
|
|
587
|
+
if (options.json) {
|
|
588
|
+
io.stdout.push(JSON.stringify({ ok: false, code: result.code, message: result.message }, null, 2));
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
io.stderr.push(result.message);
|
|
592
|
+
}
|
|
593
|
+
function runCstLookup(codigo, options, io = { stdout: [], stderr: [] }) {
|
|
594
|
+
const tax = parseCstTax(options.tax);
|
|
595
|
+
if (tax === null) {
|
|
596
|
+
io.stderr.push("Missing or invalid --tax. Expected: icms | ipi | pis | cofins");
|
|
597
|
+
return EXIT.USAGE;
|
|
598
|
+
}
|
|
599
|
+
const trimmed = codigo?.trim() ?? "";
|
|
600
|
+
if (trimmed.length === 0) {
|
|
601
|
+
io.stderr.push("Missing code. Usage: br-validators cst lookup <codigo> --tax icms");
|
|
602
|
+
return EXIT.USAGE;
|
|
603
|
+
}
|
|
604
|
+
const result = lookupByTax(tax, trimmed);
|
|
605
|
+
if (!result.ok) {
|
|
606
|
+
emitLookupFailure2(result, options, io);
|
|
607
|
+
return EXIT.INVALID;
|
|
608
|
+
}
|
|
609
|
+
if (options.json) {
|
|
610
|
+
io.stdout.push(
|
|
611
|
+
JSON.stringify(
|
|
612
|
+
{
|
|
613
|
+
ok: true,
|
|
614
|
+
cst: result.value,
|
|
615
|
+
tax,
|
|
616
|
+
...options.verbose ? { capturadoEm: CST_DATA_VERSION.capturadoEm } : {}
|
|
617
|
+
},
|
|
618
|
+
null,
|
|
619
|
+
2
|
|
620
|
+
)
|
|
621
|
+
);
|
|
622
|
+
return EXIT.OK;
|
|
623
|
+
}
|
|
624
|
+
io.stdout.push(`${result.value.codigo} \u2014 ${result.value.descricao}`);
|
|
625
|
+
if (options.verbose) {
|
|
626
|
+
io.stdout.push(`tax: ${tax}`);
|
|
627
|
+
io.stdout.push(`capturadoEm: ${CST_DATA_VERSION.capturadoEm}`);
|
|
628
|
+
}
|
|
629
|
+
return EXIT.OK;
|
|
630
|
+
}
|
|
631
|
+
function runCstSearch(query, options, io = { stdout: [], stderr: [] }) {
|
|
632
|
+
const tax = parseCstTax(options.tax);
|
|
633
|
+
if (tax === null) {
|
|
634
|
+
io.stderr.push("Missing or invalid --tax. Expected: icms | ipi | pis | cofins");
|
|
635
|
+
return EXIT.USAGE;
|
|
636
|
+
}
|
|
637
|
+
const trimmed = query?.trim() ?? "";
|
|
638
|
+
if (trimmed.length === 0) {
|
|
639
|
+
io.stderr.push("Missing query. Usage: br-validators cst search <query> --tax icms");
|
|
640
|
+
return EXIT.USAGE;
|
|
641
|
+
}
|
|
642
|
+
const rows = searchByTax(tax, trimmed, options.limit);
|
|
643
|
+
if (options.json) {
|
|
644
|
+
io.stdout.push(JSON.stringify({ ok: true, tax, results: rows }, null, 2));
|
|
645
|
+
return EXIT.OK;
|
|
646
|
+
}
|
|
647
|
+
if (rows.length === 0) {
|
|
648
|
+
io.stdout.push("No matches.");
|
|
649
|
+
return EXIT.OK;
|
|
650
|
+
}
|
|
651
|
+
for (const row of rows) {
|
|
652
|
+
io.stdout.push(`${row.codigo} \u2014 ${row.descricao}`);
|
|
653
|
+
}
|
|
654
|
+
return EXIT.OK;
|
|
655
|
+
}
|
|
656
|
+
function runCstValidate(codigo, options, io = { stdout: [], stderr: [] }) {
|
|
657
|
+
const tax = parseCstTax(options.tax);
|
|
658
|
+
if (tax === null) {
|
|
659
|
+
io.stderr.push("Missing or invalid --tax. Expected: icms | ipi | pis | cofins");
|
|
660
|
+
return EXIT.USAGE;
|
|
661
|
+
}
|
|
662
|
+
const trimmed = codigo?.trim() ?? "";
|
|
663
|
+
if (trimmed.length === 0) {
|
|
664
|
+
io.stderr.push("Missing code. Usage: br-validators cst validate <codigo> --tax icms");
|
|
665
|
+
return EXIT.USAGE;
|
|
666
|
+
}
|
|
667
|
+
const result = validateCst(trimmed, { tax });
|
|
668
|
+
if (!result.ok) {
|
|
669
|
+
emitValidateFailure(result, options, io);
|
|
670
|
+
return EXIT.INVALID;
|
|
671
|
+
}
|
|
672
|
+
if (options.json) {
|
|
673
|
+
io.stdout.push(
|
|
674
|
+
JSON.stringify(
|
|
675
|
+
{
|
|
676
|
+
ok: true,
|
|
677
|
+
tax,
|
|
678
|
+
value: result.value,
|
|
679
|
+
description: result.description
|
|
680
|
+
},
|
|
681
|
+
null,
|
|
682
|
+
2
|
|
683
|
+
)
|
|
684
|
+
);
|
|
685
|
+
return EXIT.OK;
|
|
686
|
+
}
|
|
687
|
+
io.stdout.push(`${result.value} \u2014 ${result.description}`);
|
|
688
|
+
if (options.verbose) {
|
|
689
|
+
io.stdout.push(`tax: ${tax}`);
|
|
690
|
+
}
|
|
691
|
+
return EXIT.OK;
|
|
692
|
+
}
|
|
693
|
+
|
|
428
694
|
// src/commands/ibge/lookup.ts
|
|
429
695
|
import {
|
|
430
|
-
|
|
696
|
+
lookupMunicipioPorCodigo,
|
|
431
697
|
IBGE_DATA_VERSION
|
|
432
698
|
} from "@br-validators/core/ibge";
|
|
699
|
+
import { lookupInvalidFormat as lookupInvalidFormat3 } from "@br-validators/core/lookup";
|
|
433
700
|
function normalizeIbgeMunicipioCode(raw) {
|
|
434
701
|
const digits = raw.replace(/\D/g, "");
|
|
435
702
|
if (digits.length !== 7) {
|
|
@@ -437,24 +704,35 @@ function normalizeIbgeMunicipioCode(raw) {
|
|
|
437
704
|
}
|
|
438
705
|
return Number(digits);
|
|
439
706
|
}
|
|
707
|
+
function lookupMunicipio(raw) {
|
|
708
|
+
const codigo = normalizeIbgeMunicipioCode(raw);
|
|
709
|
+
if (codigo === null) {
|
|
710
|
+
return lookupInvalidFormat3("Invalid IBGE municipality code. Use 7 digits (e.g. 3550308).");
|
|
711
|
+
}
|
|
712
|
+
return lookupMunicipioPorCodigo(codigo);
|
|
713
|
+
}
|
|
440
714
|
function formatMunicipioHuman(municipio) {
|
|
441
715
|
return `${municipio.codigo} \u2014 ${municipio.nome} (${municipio.uf})`;
|
|
442
716
|
}
|
|
443
|
-
function
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
717
|
+
function emitLookupFailure3(result, options, io) {
|
|
718
|
+
if (options.json) {
|
|
719
|
+
io.stdout.push(
|
|
720
|
+
JSON.stringify({ ok: false, code: result.code, message: result.message }, null, 2)
|
|
721
|
+
);
|
|
722
|
+
return result.code === "INVALID_FORMAT" ? EXIT.USAGE : EXIT.INVALID;
|
|
448
723
|
}
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
724
|
+
io.stderr.push(result.message);
|
|
725
|
+
return result.code === "INVALID_FORMAT" ? EXIT.USAGE : EXIT.INVALID;
|
|
726
|
+
}
|
|
727
|
+
function runIbgeLookupCommand(input, options, io = { stdout: [], stderr: [] }) {
|
|
728
|
+
const result = lookupMunicipio(input);
|
|
729
|
+
if (!result.ok) {
|
|
730
|
+
return emitLookupFailure3(result, options, io);
|
|
453
731
|
}
|
|
454
732
|
if (options.json) {
|
|
455
733
|
const payload = {
|
|
456
734
|
ok: true,
|
|
457
|
-
municipio
|
|
735
|
+
municipio: result.value
|
|
458
736
|
};
|
|
459
737
|
if (options.verbose) {
|
|
460
738
|
payload.capturadoEm = IBGE_DATA_VERSION.capturadoEm;
|
|
@@ -462,7 +740,7 @@ function runIbgeLookupCommand(input, options, io = { stdout: [], stderr: [] }) {
|
|
|
462
740
|
io.stdout.push(JSON.stringify(payload, null, 2));
|
|
463
741
|
return EXIT.OK;
|
|
464
742
|
}
|
|
465
|
-
io.stdout.push(formatMunicipioHuman(
|
|
743
|
+
io.stdout.push(formatMunicipioHuman(result.value));
|
|
466
744
|
if (options.verbose) {
|
|
467
745
|
io.stdout.push(`capturadoEm: ${IBGE_DATA_VERSION.capturadoEm}`);
|
|
468
746
|
}
|
|
@@ -478,8 +756,8 @@ function runIbgeLookup(value, options, io = { stdout: [], stderr: [] }) {
|
|
|
478
756
|
|
|
479
757
|
// src/commands/ibge/list.ts
|
|
480
758
|
import {
|
|
481
|
-
|
|
482
|
-
|
|
759
|
+
getAllEstados,
|
|
760
|
+
getAllMunicipios,
|
|
483
761
|
IBGE_DATA_VERSION as IBGE_DATA_VERSION2
|
|
484
762
|
} from "@br-validators/core/ibge";
|
|
485
763
|
function sliceRows(rows, limit) {
|
|
@@ -492,7 +770,7 @@ function formatEstadoHuman(estado) {
|
|
|
492
770
|
return `${estado.codigo} \u2014 ${estado.sigla} \u2014 ${estado.nome}`;
|
|
493
771
|
}
|
|
494
772
|
function runIbgeListEstadosCommand(options, io = { stdout: [], stderr: [] }) {
|
|
495
|
-
const estados = sliceRows(
|
|
773
|
+
const estados = sliceRows(getAllEstados(), options.limit);
|
|
496
774
|
if (options.json) {
|
|
497
775
|
const payload = {
|
|
498
776
|
ok: true,
|
|
@@ -515,7 +793,7 @@ function runIbgeListEstadosCommand(options, io = { stdout: [], stderr: [] }) {
|
|
|
515
793
|
}
|
|
516
794
|
function runIbgeListMunicipiosCommand(options, io = { stdout: [], stderr: [] }) {
|
|
517
795
|
const uf = options.uf?.trim().toUpperCase();
|
|
518
|
-
const municipios = sliceRows(
|
|
796
|
+
const municipios = sliceRows(getAllMunicipios(uf ? { uf } : void 0), options.limit);
|
|
519
797
|
if (options.json) {
|
|
520
798
|
const payload = {
|
|
521
799
|
ok: true,
|
|
@@ -547,7 +825,7 @@ function runIbgeList(target, options, io = { stdout: [], stderr: [] }) {
|
|
|
547
825
|
// src/commands/feriados/list.ts
|
|
548
826
|
import {
|
|
549
827
|
FERIADOS_DATA_VERSION,
|
|
550
|
-
|
|
828
|
+
getAllFeriados
|
|
551
829
|
} from "@br-validators/core/feriados";
|
|
552
830
|
function resolveYear(year) {
|
|
553
831
|
if (year !== void 0 && Number.isInteger(year) && year >= 1900 && year <= 2100) {
|
|
@@ -560,7 +838,7 @@ function formatFeriadoHuman(feriado) {
|
|
|
560
838
|
}
|
|
561
839
|
function runFeriadosListCommand(options, io = { stdout: [], stderr: [] }) {
|
|
562
840
|
const year = resolveYear(options.year);
|
|
563
|
-
const feriados =
|
|
841
|
+
const feriados = getAllFeriados(year);
|
|
564
842
|
if (options.json) {
|
|
565
843
|
const payload = {
|
|
566
844
|
ok: true,
|
|
@@ -586,13 +864,193 @@ function runFeriadosList(options, io = { stdout: [], stderr: [] }) {
|
|
|
586
864
|
return runFeriadosListCommand(options, io);
|
|
587
865
|
}
|
|
588
866
|
|
|
867
|
+
// src/commands/inss/index.ts
|
|
868
|
+
import {
|
|
869
|
+
calcularInssMensal,
|
|
870
|
+
getInssTabelaContribuicao,
|
|
871
|
+
INSS_DATA_VERSION,
|
|
872
|
+
INSS_DEFAULT_ANO
|
|
873
|
+
} from "@br-validators/core/inss";
|
|
874
|
+
function resolveAno(ano) {
|
|
875
|
+
if (ano !== void 0 && Number.isInteger(ano) && ano >= 1900 && ano <= 2100) {
|
|
876
|
+
return ano;
|
|
877
|
+
}
|
|
878
|
+
return INSS_DEFAULT_ANO;
|
|
879
|
+
}
|
|
880
|
+
function formatInssFaixaHuman(faixa) {
|
|
881
|
+
const aliquotaPct = `${String(faixa.aliquota * 100).replace(".", ",")}%`;
|
|
882
|
+
return `Faixa ${String(faixa.faixa)} \u2014 ${faixa.descricao} \u2014 ${aliquotaPct}`;
|
|
883
|
+
}
|
|
884
|
+
function runInssTabelaCommand(options, io = { stdout: [], stderr: [] }) {
|
|
885
|
+
const ano = resolveAno(options.ano);
|
|
886
|
+
const tabela = getInssTabelaContribuicao(ano);
|
|
887
|
+
if (tabela === void 0) {
|
|
888
|
+
io.stderr.push(`INSS contribution table not found for year ${String(ano)}`);
|
|
889
|
+
return EXIT.INVALID;
|
|
890
|
+
}
|
|
891
|
+
if (options.json) {
|
|
892
|
+
const payload = {
|
|
893
|
+
ok: true,
|
|
894
|
+
ano,
|
|
895
|
+
teto: tabela.teto,
|
|
896
|
+
faixas: tabela.faixas
|
|
897
|
+
};
|
|
898
|
+
if (options.verbose) {
|
|
899
|
+
payload.capturadoEm = INSS_DATA_VERSION.capturadoEm;
|
|
900
|
+
}
|
|
901
|
+
io.stdout.push(JSON.stringify(payload, null, 2));
|
|
902
|
+
return EXIT.OK;
|
|
903
|
+
}
|
|
904
|
+
io.stdout.push(`Teto: R$ ${tabela.teto.toFixed(2)}`);
|
|
905
|
+
for (const faixa of tabela.faixas) {
|
|
906
|
+
io.stdout.push(formatInssFaixaHuman(faixa));
|
|
907
|
+
}
|
|
908
|
+
if (options.verbose) {
|
|
909
|
+
io.stdout.push(`capturadoEm: ${INSS_DATA_VERSION.capturadoEm}`);
|
|
910
|
+
}
|
|
911
|
+
return EXIT.OK;
|
|
912
|
+
}
|
|
913
|
+
function runInssCalcCommand(salarioRaw, options, io = { stdout: [], stderr: [] }) {
|
|
914
|
+
const trimmed = salarioRaw.trim().replace(",", ".");
|
|
915
|
+
const salarioContribuicao = Number(trimmed);
|
|
916
|
+
if (!Number.isFinite(salarioContribuicao)) {
|
|
917
|
+
io.stderr.push("Invalid sal\xE1rio de contribui\xE7\xE3o. Pass a numeric value (e.g. 3000).");
|
|
918
|
+
return EXIT.USAGE;
|
|
919
|
+
}
|
|
920
|
+
const ano = resolveAno(options.ano);
|
|
921
|
+
const result = calcularInssMensal(salarioContribuicao, ano);
|
|
922
|
+
if (result === void 0) {
|
|
923
|
+
if (getInssTabelaContribuicao(ano) === void 0) {
|
|
924
|
+
io.stderr.push(`INSS contribution table not found for year ${String(ano)}`);
|
|
925
|
+
return EXIT.INVALID;
|
|
926
|
+
}
|
|
927
|
+
io.stderr.push("Sal\xE1rio de contribui\xE7\xE3o must be a non-negative number");
|
|
928
|
+
return EXIT.INVALID;
|
|
929
|
+
}
|
|
930
|
+
if (options.json) {
|
|
931
|
+
const payload = {
|
|
932
|
+
ok: true,
|
|
933
|
+
...result,
|
|
934
|
+
...options.verbose ? { capturadoEm: INSS_DATA_VERSION.capturadoEm } : {}
|
|
935
|
+
};
|
|
936
|
+
io.stdout.push(JSON.stringify(payload, null, 2));
|
|
937
|
+
return EXIT.OK;
|
|
938
|
+
}
|
|
939
|
+
io.stdout.push(
|
|
940
|
+
`INSS ${String(result.ano)} \u2014 sal\xE1rio R$ ${result.salarioContribuicao.toFixed(2)} \u2014 faixa ${String(result.faixa)} \u2014 contribui\xE7\xE3o R$ ${result.contribuicao.toFixed(2)}`
|
|
941
|
+
);
|
|
942
|
+
if (options.verbose) {
|
|
943
|
+
io.stdout.push(`capturadoEm: ${INSS_DATA_VERSION.capturadoEm}`);
|
|
944
|
+
}
|
|
945
|
+
return EXIT.OK;
|
|
946
|
+
}
|
|
947
|
+
function runInssTabela(options, io = { stdout: [], stderr: [] }) {
|
|
948
|
+
return runInssTabelaCommand(options, io);
|
|
949
|
+
}
|
|
950
|
+
function runInssCalc(salario, options, io = { stdout: [], stderr: [] }) {
|
|
951
|
+
if (!salario?.trim()) {
|
|
952
|
+
io.stderr.push("Missing sal\xE1rio de contribui\xE7\xE3o. Usage: br-validators inss calc <salario>");
|
|
953
|
+
return EXIT.USAGE;
|
|
954
|
+
}
|
|
955
|
+
return runInssCalcCommand(salario.trim(), options, io);
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
// src/commands/irpf/index.ts
|
|
959
|
+
import {
|
|
960
|
+
calcularIrpfMensal,
|
|
961
|
+
getIrpfTabelaProgressiva,
|
|
962
|
+
IRPF_DATA_VERSION,
|
|
963
|
+
IRPF_DEFAULT_ANO
|
|
964
|
+
} from "@br-validators/core/irpf";
|
|
965
|
+
function resolveAno2(ano) {
|
|
966
|
+
if (ano !== void 0 && Number.isInteger(ano) && ano >= 1900 && ano <= 2100) {
|
|
967
|
+
return ano;
|
|
968
|
+
}
|
|
969
|
+
return IRPF_DEFAULT_ANO;
|
|
970
|
+
}
|
|
971
|
+
function formatIrpfFaixaHuman(faixa) {
|
|
972
|
+
const aliquotaPct = `${String(faixa.aliquota * 100).replace(".", ",")}%`;
|
|
973
|
+
return `Faixa ${String(faixa.faixa)} \u2014 ${faixa.descricao} \u2014 ${aliquotaPct} \u2014 deduzir R$ ${faixa.parcelaDeduzir.toFixed(2)}`;
|
|
974
|
+
}
|
|
975
|
+
function runIrpfTabelaCommand(options, io = { stdout: [], stderr: [] }) {
|
|
976
|
+
const ano = resolveAno2(options.ano);
|
|
977
|
+
const faixas = getIrpfTabelaProgressiva(ano);
|
|
978
|
+
if (faixas === void 0) {
|
|
979
|
+
io.stderr.push(`IRPF progressive table not found for year ${String(ano)}`);
|
|
980
|
+
return EXIT.INVALID;
|
|
981
|
+
}
|
|
982
|
+
if (options.json) {
|
|
983
|
+
const payload = {
|
|
984
|
+
ok: true,
|
|
985
|
+
ano,
|
|
986
|
+
faixas
|
|
987
|
+
};
|
|
988
|
+
if (options.verbose) {
|
|
989
|
+
payload.capturadoEm = IRPF_DATA_VERSION.capturadoEm;
|
|
990
|
+
}
|
|
991
|
+
io.stdout.push(JSON.stringify(payload, null, 2));
|
|
992
|
+
return EXIT.OK;
|
|
993
|
+
}
|
|
994
|
+
for (const faixa of faixas) {
|
|
995
|
+
io.stdout.push(formatIrpfFaixaHuman(faixa));
|
|
996
|
+
}
|
|
997
|
+
if (options.verbose) {
|
|
998
|
+
io.stdout.push(`capturadoEm: ${IRPF_DATA_VERSION.capturadoEm}`);
|
|
999
|
+
}
|
|
1000
|
+
return EXIT.OK;
|
|
1001
|
+
}
|
|
1002
|
+
function runIrpfCalcCommand(baseRaw, options, io = { stdout: [], stderr: [] }) {
|
|
1003
|
+
const trimmed = baseRaw.trim().replace(",", ".");
|
|
1004
|
+
const baseCalculo = Number(trimmed);
|
|
1005
|
+
if (!Number.isFinite(baseCalculo)) {
|
|
1006
|
+
io.stderr.push("Invalid base de c\xE1lculo. Pass a numeric value (e.g. 3000).");
|
|
1007
|
+
return EXIT.USAGE;
|
|
1008
|
+
}
|
|
1009
|
+
const ano = resolveAno2(options.ano);
|
|
1010
|
+
const result = calcularIrpfMensal(baseCalculo, ano);
|
|
1011
|
+
if (result === void 0) {
|
|
1012
|
+
if (getIrpfTabelaProgressiva(ano) === void 0) {
|
|
1013
|
+
io.stderr.push(`IRPF progressive table not found for year ${String(ano)}`);
|
|
1014
|
+
return EXIT.INVALID;
|
|
1015
|
+
}
|
|
1016
|
+
io.stderr.push("Base de c\xE1lculo must be a non-negative number");
|
|
1017
|
+
return EXIT.INVALID;
|
|
1018
|
+
}
|
|
1019
|
+
if (options.json) {
|
|
1020
|
+
const payload = {
|
|
1021
|
+
ok: true,
|
|
1022
|
+
...result,
|
|
1023
|
+
...options.verbose ? { capturadoEm: IRPF_DATA_VERSION.capturadoEm } : {}
|
|
1024
|
+
};
|
|
1025
|
+
io.stdout.push(JSON.stringify(payload, null, 2));
|
|
1026
|
+
return EXIT.OK;
|
|
1027
|
+
}
|
|
1028
|
+
io.stdout.push(
|
|
1029
|
+
`IRPF ${String(result.ano)} \u2014 base R$ ${result.baseCalculo.toFixed(2)} \u2014 faixa ${String(result.faixa)} \u2014 imposto R$ ${result.imposto.toFixed(2)}`
|
|
1030
|
+
);
|
|
1031
|
+
if (options.verbose) {
|
|
1032
|
+
io.stdout.push(`capturadoEm: ${IRPF_DATA_VERSION.capturadoEm}`);
|
|
1033
|
+
}
|
|
1034
|
+
return EXIT.OK;
|
|
1035
|
+
}
|
|
1036
|
+
function runIrpfTabela(options, io = { stdout: [], stderr: [] }) {
|
|
1037
|
+
return runIrpfTabelaCommand(options, io);
|
|
1038
|
+
}
|
|
1039
|
+
function runIrpfCalc(base, options, io = { stdout: [], stderr: [] }) {
|
|
1040
|
+
if (!base?.trim()) {
|
|
1041
|
+
io.stderr.push("Missing base de c\xE1lculo. Usage: br-validators irpf calc <base>");
|
|
1042
|
+
return EXIT.USAGE;
|
|
1043
|
+
}
|
|
1044
|
+
return runIrpfCalcCommand(base.trim(), options, io);
|
|
1045
|
+
}
|
|
1046
|
+
|
|
589
1047
|
// src/commands/tse-municipios/lookup.ts
|
|
590
1048
|
import {
|
|
591
1049
|
getCodigosTsePorMunicipio,
|
|
592
1050
|
getMunicipioIbgePorCodigoTse,
|
|
593
1051
|
TSE_MUNICIPIOS_DATA_VERSION
|
|
594
1052
|
} from "@br-validators/core/tse-municipios";
|
|
595
|
-
import { getMunicipioPorCodigo
|
|
1053
|
+
import { getMunicipioPorCodigo } from "@br-validators/core/ibge";
|
|
596
1054
|
function normalizeTseInput(raw) {
|
|
597
1055
|
const digits = raw.replace(/\D/g, "");
|
|
598
1056
|
if (digits.length === 5) {
|
|
@@ -623,11 +1081,11 @@ function lookupTseMunicipio(raw) {
|
|
|
623
1081
|
}
|
|
624
1082
|
function formatTseLookupHuman(result) {
|
|
625
1083
|
if (result.kind === "tse-to-ibge") {
|
|
626
|
-
const municipio2 =
|
|
1084
|
+
const municipio2 = getMunicipioPorCodigo(result.ibgeCodigo);
|
|
627
1085
|
const name2 = municipio2 ? `${municipio2.nome} (${municipio2.uf})` : String(result.ibgeCodigo);
|
|
628
1086
|
return `TSE ${result.codigoTse} \u2192 IBGE ${result.ibgeCodigo} \u2014 ${name2}`;
|
|
629
1087
|
}
|
|
630
|
-
const municipio =
|
|
1088
|
+
const municipio = getMunicipioPorCodigo(result.ibgeCodigo);
|
|
631
1089
|
const name = municipio ? `${municipio.nome} (${municipio.uf})` : String(result.ibgeCodigo);
|
|
632
1090
|
return `IBGE ${result.ibgeCodigo} \u2014 ${name} \u2192 TSE ${result.codigosTse.join(", ")}`;
|
|
633
1091
|
}
|
|
@@ -771,6 +1229,339 @@ function runDddLookup(value, options, io = { stdout: [], stderr: [] }) {
|
|
|
771
1229
|
return runDddLookupCommand(value.trim(), options, io);
|
|
772
1230
|
}
|
|
773
1231
|
|
|
1232
|
+
// src/commands/nfe-cuf/lookup.ts
|
|
1233
|
+
import {
|
|
1234
|
+
lookupCufPorCodigo,
|
|
1235
|
+
NFE_CUF_DATA_VERSION
|
|
1236
|
+
} from "@br-validators/core/nfe-cuf";
|
|
1237
|
+
function formatNfeCufHuman(row) {
|
|
1238
|
+
return `cUF ${row.codigo} \u2014 ${row.uf} \u2014 ${row.nome} (IBGE UF ${row.codigoIbge})`;
|
|
1239
|
+
}
|
|
1240
|
+
function runNfeCufLookupCommand(input, options, io = { stdout: [], stderr: [] }) {
|
|
1241
|
+
const trimmed = input.trim();
|
|
1242
|
+
if (trimmed.length === 0) {
|
|
1243
|
+
io.stderr.push("Invalid cUF code. Use 2 digits (e.g. 35).");
|
|
1244
|
+
return EXIT.USAGE;
|
|
1245
|
+
}
|
|
1246
|
+
const result = lookupCufPorCodigo(trimmed);
|
|
1247
|
+
if (!result.ok) {
|
|
1248
|
+
if (options.json) {
|
|
1249
|
+
io.stdout.push(JSON.stringify({ ok: false, code: result.code, message: result.message }, null, 2));
|
|
1250
|
+
return EXIT.INVALID;
|
|
1251
|
+
}
|
|
1252
|
+
io.stderr.push(result.message);
|
|
1253
|
+
return EXIT.INVALID;
|
|
1254
|
+
}
|
|
1255
|
+
if (options.json) {
|
|
1256
|
+
const payload = {
|
|
1257
|
+
ok: true,
|
|
1258
|
+
cuf: result.value
|
|
1259
|
+
};
|
|
1260
|
+
if (options.verbose) {
|
|
1261
|
+
payload.capturadoEm = NFE_CUF_DATA_VERSION.capturadoEm;
|
|
1262
|
+
}
|
|
1263
|
+
io.stdout.push(JSON.stringify(payload, null, 2));
|
|
1264
|
+
return EXIT.OK;
|
|
1265
|
+
}
|
|
1266
|
+
io.stdout.push(formatNfeCufHuman(result.value));
|
|
1267
|
+
if (options.verbose) {
|
|
1268
|
+
io.stdout.push(`capturadoEm: ${NFE_CUF_DATA_VERSION.capturadoEm}`);
|
|
1269
|
+
}
|
|
1270
|
+
return EXIT.OK;
|
|
1271
|
+
}
|
|
1272
|
+
function runNfeCufLookup(value, options, io = { stdout: [], stderr: [] }) {
|
|
1273
|
+
if (!value?.trim()) {
|
|
1274
|
+
io.stderr.push("Missing cUF code. Usage: br-validators nfe-cuf lookup <code>");
|
|
1275
|
+
return EXIT.USAGE;
|
|
1276
|
+
}
|
|
1277
|
+
return runNfeCufLookupCommand(value.trim(), options, io);
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
// src/commands/selic/index.ts
|
|
1281
|
+
import {
|
|
1282
|
+
getSelicMeta,
|
|
1283
|
+
getSelicMetaPorData,
|
|
1284
|
+
SELIC_DATA_VERSION
|
|
1285
|
+
} from "@br-validators/core/selic";
|
|
1286
|
+
function formatSelicMetaHuman(meta) {
|
|
1287
|
+
return `SELIC meta ${meta.dataReferencia} \u2014 ${String(meta.valor)}% a.a.`;
|
|
1288
|
+
}
|
|
1289
|
+
function runSelicCommand(options, io = { stdout: [], stderr: [] }) {
|
|
1290
|
+
const meta = options.date === void 0 || options.date.trim().length === 0 ? getSelicMeta() : getSelicMetaPorData(options.date.trim());
|
|
1291
|
+
if (meta === void 0) {
|
|
1292
|
+
io.stderr.push(
|
|
1293
|
+
options.date ? `SELIC meta not found for date ${options.date}` : "SELIC meta series is empty"
|
|
1294
|
+
);
|
|
1295
|
+
return EXIT.INVALID;
|
|
1296
|
+
}
|
|
1297
|
+
if (options.json) {
|
|
1298
|
+
const payload = {
|
|
1299
|
+
ok: true,
|
|
1300
|
+
meta
|
|
1301
|
+
};
|
|
1302
|
+
if (options.verbose) {
|
|
1303
|
+
payload.capturadoEm = SELIC_DATA_VERSION.capturadoEm;
|
|
1304
|
+
}
|
|
1305
|
+
io.stdout.push(JSON.stringify(payload, null, 2));
|
|
1306
|
+
return EXIT.OK;
|
|
1307
|
+
}
|
|
1308
|
+
io.stdout.push(formatSelicMetaHuman(meta));
|
|
1309
|
+
if (options.verbose) {
|
|
1310
|
+
io.stdout.push(`dataReferencia: ${meta.dataReferencia}`);
|
|
1311
|
+
io.stdout.push(`isStale: ${String(meta.isStale)}`);
|
|
1312
|
+
if (meta.warning !== void 0) {
|
|
1313
|
+
io.stdout.push(`warning: ${meta.warning}`);
|
|
1314
|
+
}
|
|
1315
|
+
io.stdout.push(`capturadoEm: ${SELIC_DATA_VERSION.capturadoEm}`);
|
|
1316
|
+
}
|
|
1317
|
+
return EXIT.OK;
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1320
|
+
// src/commands/iss-municipal/index.ts
|
|
1321
|
+
import {
|
|
1322
|
+
getIssMunicipalPorUf,
|
|
1323
|
+
getIssMunicipalPorUfMunicipio,
|
|
1324
|
+
ISS_MUNICIPAL_DATA_VERSION,
|
|
1325
|
+
ISS_MUNICIPAL_ESTIMATION_WARNING,
|
|
1326
|
+
lookupIssMunicipalPorIbge,
|
|
1327
|
+
searchIssMunicipal
|
|
1328
|
+
} from "@br-validators/core/iss-municipal";
|
|
1329
|
+
function sliceRows2(rows, limit) {
|
|
1330
|
+
if (limit === void 0 || !Number.isFinite(limit) || limit <= 0) {
|
|
1331
|
+
return rows;
|
|
1332
|
+
}
|
|
1333
|
+
return rows.slice(0, limit);
|
|
1334
|
+
}
|
|
1335
|
+
function formatIssMunicipalHuman(row) {
|
|
1336
|
+
return `${row.nome}/${row.uf} \u2014 ISS ${String(row.aliquotaMin)}%\u2013${String(row.aliquotaMax)}%`;
|
|
1337
|
+
}
|
|
1338
|
+
function emitDisclaimer(options, io) {
|
|
1339
|
+
if (options.json) {
|
|
1340
|
+
return;
|
|
1341
|
+
}
|
|
1342
|
+
io.stderr.push(ISS_MUNICIPAL_ESTIMATION_WARNING);
|
|
1343
|
+
}
|
|
1344
|
+
function runIssMunicipalLookup(codigo, options, io = { stdout: [], stderr: [] }) {
|
|
1345
|
+
const trimmed = codigo?.trim() ?? "";
|
|
1346
|
+
if (trimmed.length === 0) {
|
|
1347
|
+
io.stderr.push("Missing IBGE code. Usage: br-validators iss-municipal lookup <codigoIbge>");
|
|
1348
|
+
return EXIT.USAGE;
|
|
1349
|
+
}
|
|
1350
|
+
const result = lookupIssMunicipalPorIbge(trimmed);
|
|
1351
|
+
if (result === void 0) {
|
|
1352
|
+
io.stderr.push(`ISS municipal row not found for IBGE code ${trimmed}`);
|
|
1353
|
+
return EXIT.INVALID;
|
|
1354
|
+
}
|
|
1355
|
+
emitDisclaimer(options, io);
|
|
1356
|
+
if (options.json) {
|
|
1357
|
+
const payload = {
|
|
1358
|
+
ok: true,
|
|
1359
|
+
iss: result
|
|
1360
|
+
};
|
|
1361
|
+
if (options.verbose) {
|
|
1362
|
+
payload.capturadoEm = ISS_MUNICIPAL_DATA_VERSION.capturadoEm;
|
|
1363
|
+
}
|
|
1364
|
+
io.stdout.push(JSON.stringify(payload, null, 2));
|
|
1365
|
+
return EXIT.OK;
|
|
1366
|
+
}
|
|
1367
|
+
io.stdout.push(formatIssMunicipalHuman(result));
|
|
1368
|
+
io.stdout.push(`fonte: ${result.fonte}`);
|
|
1369
|
+
io.stdout.push(`warning: ${result.warning}`);
|
|
1370
|
+
if (options.verbose) {
|
|
1371
|
+
io.stdout.push(`leiUrl: ${result.leiUrl}`);
|
|
1372
|
+
io.stdout.push(`estimativa: ${String(result.estimativa)}`);
|
|
1373
|
+
io.stdout.push(`capturadoEm: ${ISS_MUNICIPAL_DATA_VERSION.capturadoEm}`);
|
|
1374
|
+
}
|
|
1375
|
+
return EXIT.OK;
|
|
1376
|
+
}
|
|
1377
|
+
function runIssMunicipalList(options, io = { stdout: [], stderr: [] }) {
|
|
1378
|
+
const uf = options.uf?.trim() ?? "";
|
|
1379
|
+
if (uf.length === 0) {
|
|
1380
|
+
io.stderr.push("Missing UF. Usage: br-validators iss-municipal list --uf <UF>");
|
|
1381
|
+
return EXIT.USAGE;
|
|
1382
|
+
}
|
|
1383
|
+
const rows = sliceRows2(getIssMunicipalPorUf(uf), options.limit);
|
|
1384
|
+
emitDisclaimer(options, io);
|
|
1385
|
+
if (options.json) {
|
|
1386
|
+
const payload = {
|
|
1387
|
+
ok: true,
|
|
1388
|
+
uf: uf.toUpperCase(),
|
|
1389
|
+
total: rows.length,
|
|
1390
|
+
results: rows
|
|
1391
|
+
};
|
|
1392
|
+
if (options.verbose) {
|
|
1393
|
+
payload.capturadoEm = ISS_MUNICIPAL_DATA_VERSION.capturadoEm;
|
|
1394
|
+
}
|
|
1395
|
+
io.stdout.push(JSON.stringify(payload, null, 2));
|
|
1396
|
+
return EXIT.OK;
|
|
1397
|
+
}
|
|
1398
|
+
if (rows.length === 0) {
|
|
1399
|
+
io.stdout.push(`No ISS municipal rows embedded for UF ${uf.toUpperCase()}.`);
|
|
1400
|
+
return EXIT.OK;
|
|
1401
|
+
}
|
|
1402
|
+
for (const row of rows) {
|
|
1403
|
+
io.stdout.push(formatIssMunicipalHuman(row));
|
|
1404
|
+
}
|
|
1405
|
+
if (options.verbose) {
|
|
1406
|
+
io.stdout.push(`capturadoEm: ${ISS_MUNICIPAL_DATA_VERSION.capturadoEm}`);
|
|
1407
|
+
}
|
|
1408
|
+
return EXIT.OK;
|
|
1409
|
+
}
|
|
1410
|
+
function runIssMunicipalSearch(query, options, io = { stdout: [], stderr: [] }) {
|
|
1411
|
+
const trimmed = query?.trim() ?? "";
|
|
1412
|
+
if (trimmed.length === 0) {
|
|
1413
|
+
io.stderr.push("Missing query. Usage: br-validators iss-municipal search <query>");
|
|
1414
|
+
return EXIT.USAGE;
|
|
1415
|
+
}
|
|
1416
|
+
const rows = searchIssMunicipal(trimmed, {
|
|
1417
|
+
limit: options.limit,
|
|
1418
|
+
...options.uf !== void 0 && options.uf.trim().length > 0 ? { uf: options.uf } : {}
|
|
1419
|
+
});
|
|
1420
|
+
emitDisclaimer(options, io);
|
|
1421
|
+
if (options.json) {
|
|
1422
|
+
io.stdout.push(JSON.stringify({ ok: true, results: rows }, null, 2));
|
|
1423
|
+
return EXIT.OK;
|
|
1424
|
+
}
|
|
1425
|
+
if (rows.length === 0) {
|
|
1426
|
+
io.stdout.push("No ISS municipal rows matched.");
|
|
1427
|
+
return EXIT.OK;
|
|
1428
|
+
}
|
|
1429
|
+
for (const row of rows) {
|
|
1430
|
+
io.stdout.push(formatIssMunicipalHuman(row));
|
|
1431
|
+
}
|
|
1432
|
+
return EXIT.OK;
|
|
1433
|
+
}
|
|
1434
|
+
function runIssMunicipalResolve(uf, nome, options, io = { stdout: [], stderr: [] }) {
|
|
1435
|
+
const normalizedUf = uf?.trim() ?? "";
|
|
1436
|
+
const normalizedNome = nome?.trim() ?? "";
|
|
1437
|
+
if (normalizedUf.length === 0 || normalizedNome.length === 0) {
|
|
1438
|
+
io.stderr.push("Missing UF or municipality name. Usage: br-validators iss-municipal resolve <uf> <nome>");
|
|
1439
|
+
return EXIT.USAGE;
|
|
1440
|
+
}
|
|
1441
|
+
const result = getIssMunicipalPorUfMunicipio(normalizedUf, normalizedNome);
|
|
1442
|
+
if (result === void 0) {
|
|
1443
|
+
io.stderr.push(`ISS municipal row not found for ${normalizedNome}/${normalizedUf}`);
|
|
1444
|
+
return EXIT.INVALID;
|
|
1445
|
+
}
|
|
1446
|
+
return runIssMunicipalLookup(String(result.codigoIbge), options, io);
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
// src/commands/ptax/lookup.ts
|
|
1450
|
+
import {
|
|
1451
|
+
getPtaxCotacao,
|
|
1452
|
+
PTAX_DATA_VERSION
|
|
1453
|
+
} from "@br-validators/core/ptax";
|
|
1454
|
+
function formatPtaxCotacaoHuman(cotacao) {
|
|
1455
|
+
return `${cotacao.moeda} Fechamento PTAX \u2014 compra ${String(cotacao.cotacaoCompra)} / venda ${String(cotacao.cotacaoVenda)} (${cotacao.dataReferencia})`;
|
|
1456
|
+
}
|
|
1457
|
+
function runPtaxLookupCommand(moeda, data, options, io = { stdout: [], stderr: [] }) {
|
|
1458
|
+
const trimmedMoeda = moeda.trim();
|
|
1459
|
+
if (trimmedMoeda.length === 0) {
|
|
1460
|
+
io.stderr.push("Missing currency code. Pass a 3-letter ISO code (e.g. USD).");
|
|
1461
|
+
return EXIT.USAGE;
|
|
1462
|
+
}
|
|
1463
|
+
const cotacao = data === void 0 || data.trim().length === 0 ? getPtaxCotacao(trimmedMoeda) : getPtaxCotacao(trimmedMoeda, data.trim());
|
|
1464
|
+
if (cotacao === void 0) {
|
|
1465
|
+
io.stderr.push(`PTAX quote not found: ${trimmedMoeda}${data ? ` ${data}` : ""}`);
|
|
1466
|
+
return EXIT.INVALID;
|
|
1467
|
+
}
|
|
1468
|
+
if (options.json) {
|
|
1469
|
+
const payload = {
|
|
1470
|
+
ok: true,
|
|
1471
|
+
cotacao
|
|
1472
|
+
};
|
|
1473
|
+
if (options.verbose) {
|
|
1474
|
+
payload.capturadoEm = PTAX_DATA_VERSION.capturadoEm;
|
|
1475
|
+
}
|
|
1476
|
+
io.stdout.push(JSON.stringify(payload, null, 2));
|
|
1477
|
+
return EXIT.OK;
|
|
1478
|
+
}
|
|
1479
|
+
io.stdout.push(formatPtaxCotacaoHuman(cotacao));
|
|
1480
|
+
if (options.verbose) {
|
|
1481
|
+
io.stdout.push(`dataReferencia: ${cotacao.dataReferencia}`);
|
|
1482
|
+
io.stdout.push(`isStale: ${String(cotacao.isStale)}`);
|
|
1483
|
+
if (cotacao.warning !== void 0) {
|
|
1484
|
+
io.stdout.push(`warning: ${cotacao.warning}`);
|
|
1485
|
+
}
|
|
1486
|
+
io.stdout.push(`capturadoEm: ${PTAX_DATA_VERSION.capturadoEm}`);
|
|
1487
|
+
}
|
|
1488
|
+
return EXIT.OK;
|
|
1489
|
+
}
|
|
1490
|
+
function runPtaxLookup(moeda, data, options, io = { stdout: [], stderr: [] }) {
|
|
1491
|
+
if (!moeda?.trim()) {
|
|
1492
|
+
io.stderr.push("Missing currency code. Usage: ptax lookup <moeda> [data]");
|
|
1493
|
+
return EXIT.USAGE;
|
|
1494
|
+
}
|
|
1495
|
+
return runPtaxLookupCommand(moeda.trim(), data?.trim(), options, io);
|
|
1496
|
+
}
|
|
1497
|
+
|
|
1498
|
+
// src/commands/ptax/historico.ts
|
|
1499
|
+
import {
|
|
1500
|
+
getPtaxHistorico,
|
|
1501
|
+
PTAX_DATA_VERSION as PTAX_DATA_VERSION2
|
|
1502
|
+
} from "@br-validators/core/ptax";
|
|
1503
|
+
function formatPtaxHistoricoHuman(results) {
|
|
1504
|
+
return results.map(
|
|
1505
|
+
(cotacao) => `${cotacao.dataReferencia} \u2014 compra ${String(cotacao.cotacaoCompra)} / venda ${String(cotacao.cotacaoVenda)}`
|
|
1506
|
+
);
|
|
1507
|
+
}
|
|
1508
|
+
function runPtaxHistoricoCommand(moeda, desde, ate, options, io = { stdout: [], stderr: [] }) {
|
|
1509
|
+
const trimmedMoeda = moeda.trim();
|
|
1510
|
+
const trimmedDesde = desde.trim();
|
|
1511
|
+
const trimmedAte = ate.trim();
|
|
1512
|
+
if (trimmedMoeda.length === 0) {
|
|
1513
|
+
io.stderr.push("Missing currency code. Pass a 3-letter ISO code (e.g. USD).");
|
|
1514
|
+
return EXIT.USAGE;
|
|
1515
|
+
}
|
|
1516
|
+
if (trimmedDesde.length === 0 || trimmedAte.length === 0) {
|
|
1517
|
+
io.stderr.push("Missing date range. Pass desde and ate as YYYY-MM-DD.");
|
|
1518
|
+
return EXIT.USAGE;
|
|
1519
|
+
}
|
|
1520
|
+
const results = getPtaxHistorico(trimmedMoeda, { desde: trimmedDesde, ate: trimmedAte });
|
|
1521
|
+
if (results.length === 0) {
|
|
1522
|
+
io.stderr.push(
|
|
1523
|
+
`No PTAX quotes in embed for ${trimmedMoeda} between ${trimmedDesde} and ${trimmedAte}`
|
|
1524
|
+
);
|
|
1525
|
+
return EXIT.INVALID;
|
|
1526
|
+
}
|
|
1527
|
+
if (options.json) {
|
|
1528
|
+
const payload = {
|
|
1529
|
+
ok: true,
|
|
1530
|
+
moeda: trimmedMoeda.toUpperCase(),
|
|
1531
|
+
desde: trimmedDesde,
|
|
1532
|
+
ate: trimmedAte,
|
|
1533
|
+
total: results.length,
|
|
1534
|
+
cotacoes: results
|
|
1535
|
+
};
|
|
1536
|
+
if (options.verbose) {
|
|
1537
|
+
payload.capturadoEm = PTAX_DATA_VERSION2.capturadoEm;
|
|
1538
|
+
payload.janelaDiasUteis = PTAX_DATA_VERSION2.janelaDiasUteis;
|
|
1539
|
+
}
|
|
1540
|
+
io.stdout.push(JSON.stringify(payload, null, 2));
|
|
1541
|
+
return EXIT.OK;
|
|
1542
|
+
}
|
|
1543
|
+
io.stdout.push(`${trimmedMoeda.toUpperCase()} PTAX historico (${String(results.length)} rows)`);
|
|
1544
|
+
for (const line of formatPtaxHistoricoHuman(results)) {
|
|
1545
|
+
io.stdout.push(line);
|
|
1546
|
+
}
|
|
1547
|
+
if (options.verbose) {
|
|
1548
|
+
io.stdout.push(`capturadoEm: ${PTAX_DATA_VERSION2.capturadoEm}`);
|
|
1549
|
+
io.stdout.push(`janelaDiasUteis: ${String(PTAX_DATA_VERSION2.janelaDiasUteis)}`);
|
|
1550
|
+
}
|
|
1551
|
+
return EXIT.OK;
|
|
1552
|
+
}
|
|
1553
|
+
function runPtaxHistorico(moeda, desde, ate, options, io = { stdout: [], stderr: [] }) {
|
|
1554
|
+
if (!moeda?.trim()) {
|
|
1555
|
+
io.stderr.push("Missing currency code. Usage: ptax historico <moeda> <desde> <ate>");
|
|
1556
|
+
return EXIT.USAGE;
|
|
1557
|
+
}
|
|
1558
|
+
if (!desde?.trim() || !ate?.trim()) {
|
|
1559
|
+
io.stderr.push("Missing date range. Usage: ptax historico <moeda> <desde> <ate>");
|
|
1560
|
+
return EXIT.USAGE;
|
|
1561
|
+
}
|
|
1562
|
+
return runPtaxHistoricoCommand(moeda.trim(), desde.trim(), ate.trim(), options, io);
|
|
1563
|
+
}
|
|
1564
|
+
|
|
774
1565
|
// src/commands/brcode.ts
|
|
775
1566
|
import {
|
|
776
1567
|
BRCODE_OFFICIAL_SOURCE_URL,
|
|
@@ -2225,9 +3016,99 @@ function runDetect(value, options, io = { stdout: [], stderr: [] }) {
|
|
|
2225
3016
|
return printDetect(result, options, io);
|
|
2226
3017
|
}
|
|
2227
3018
|
|
|
2228
|
-
// src/commands/sanitize.ts
|
|
2229
|
-
import { sanitize } from "@br-validators/core";
|
|
2230
|
-
var SANITIZABLE_TYPES = [
|
|
3019
|
+
// src/commands/sanitize.ts
|
|
3020
|
+
import { sanitize } from "@br-validators/core";
|
|
3021
|
+
var SANITIZABLE_TYPES = [
|
|
3022
|
+
"cpf",
|
|
3023
|
+
"cnpj",
|
|
3024
|
+
"cep",
|
|
3025
|
+
"placa",
|
|
3026
|
+
"pis-pasep",
|
|
3027
|
+
"telefone",
|
|
3028
|
+
"cnh",
|
|
3029
|
+
"renavam",
|
|
3030
|
+
"titulo-eleitor",
|
|
3031
|
+
"nfe-chave",
|
|
3032
|
+
"boleto",
|
|
3033
|
+
"cartao-credito",
|
|
3034
|
+
"ean",
|
|
3035
|
+
"inscricao-estadual",
|
|
3036
|
+
"inscricao-estadual-produtor-rural",
|
|
3037
|
+
"pix"
|
|
3038
|
+
];
|
|
3039
|
+
function isSanitizableType(type) {
|
|
3040
|
+
return SANITIZABLE_TYPES.includes(type);
|
|
3041
|
+
}
|
|
3042
|
+
function resolveInput21(value, fileContent) {
|
|
3043
|
+
const input = value ?? fileContent?.trim();
|
|
3044
|
+
if (!input) {
|
|
3045
|
+
return null;
|
|
3046
|
+
}
|
|
3047
|
+
return input;
|
|
3048
|
+
}
|
|
3049
|
+
function printSanitize(result, options, io = { stdout: [], stderr: [] }) {
|
|
3050
|
+
if (options.json) {
|
|
3051
|
+
io.stdout.push(JSON.stringify(result, null, 2));
|
|
3052
|
+
return result.ok ? EXIT.OK : EXIT.INVALID;
|
|
3053
|
+
}
|
|
3054
|
+
if (options.quiet) {
|
|
3055
|
+
return result.ok ? EXIT.OK : EXIT.INVALID;
|
|
3056
|
+
}
|
|
3057
|
+
if (result.ok) {
|
|
3058
|
+
io.stdout.push("valid: yes");
|
|
3059
|
+
io.stdout.push(`value: ${result.value}`);
|
|
3060
|
+
io.stdout.push(`fixes: ${result.fixes.join(", ")}`);
|
|
3061
|
+
return EXIT.OK;
|
|
3062
|
+
}
|
|
3063
|
+
io.stderr.push("valid: no");
|
|
3064
|
+
io.stderr.push(`code: ${result.code}`);
|
|
3065
|
+
io.stderr.push(`message: ${result.message}`);
|
|
3066
|
+
return EXIT.INVALID;
|
|
3067
|
+
}
|
|
3068
|
+
function runSanitize(type, value, options, io = { stdout: [], stderr: [] }) {
|
|
3069
|
+
if (!isSanitizableType(type)) {
|
|
3070
|
+
io.stderr.push(`Unsupported sanitize type: ${type}`);
|
|
3071
|
+
return EXIT.USAGE;
|
|
3072
|
+
}
|
|
3073
|
+
const input = resolveInput21(value, options.file);
|
|
3074
|
+
if (input === null) {
|
|
3075
|
+
io.stderr.push("Missing value. Pass an argument or use --file.");
|
|
3076
|
+
return EXIT.USAGE;
|
|
3077
|
+
}
|
|
3078
|
+
const uf = options.uf?.toUpperCase();
|
|
3079
|
+
const result = sanitize(input, type, uf ? { uf } : {});
|
|
3080
|
+
return printSanitize(result, options, io);
|
|
3081
|
+
}
|
|
3082
|
+
|
|
3083
|
+
// src/commands/mask.ts
|
|
3084
|
+
import { isMaskableDocumentType, maskRuntime } from "@br-validators/core";
|
|
3085
|
+
function resolveInput22(value, fileContent) {
|
|
3086
|
+
const input = value ?? fileContent?.trim();
|
|
3087
|
+
if (!input) {
|
|
3088
|
+
return null;
|
|
3089
|
+
}
|
|
3090
|
+
return input;
|
|
3091
|
+
}
|
|
3092
|
+
function runMask(type, value, options, io = { stdout: [], stderr: [] }) {
|
|
3093
|
+
if (!isMaskableDocumentType(type)) {
|
|
3094
|
+
io.stderr.push(`Unsupported mask type: ${type}`);
|
|
3095
|
+
return EXIT.USAGE;
|
|
3096
|
+
}
|
|
3097
|
+
const input = resolveInput22(value, options.file);
|
|
3098
|
+
if (input === null) {
|
|
3099
|
+
io.stderr.push("Missing value. Pass an argument or use --file.");
|
|
3100
|
+
return EXIT.USAGE;
|
|
3101
|
+
}
|
|
3102
|
+
const uf = options.uf?.toUpperCase();
|
|
3103
|
+
const result = maskRuntime(type, input, uf ? { uf } : {});
|
|
3104
|
+
return printFormat(result, options, io);
|
|
3105
|
+
}
|
|
3106
|
+
|
|
3107
|
+
// src/commands/compare.ts
|
|
3108
|
+
import { compareRuntime } from "@br-validators/core";
|
|
3109
|
+
|
|
3110
|
+
// src/commands/platform-document-types.ts
|
|
3111
|
+
var PLATFORM_DOCUMENT_TYPES = [
|
|
2231
3112
|
"cpf",
|
|
2232
3113
|
"cnpj",
|
|
2233
3114
|
"cep",
|
|
@@ -2237,55 +3118,162 @@ var SANITIZABLE_TYPES = [
|
|
|
2237
3118
|
"cnh",
|
|
2238
3119
|
"renavam",
|
|
2239
3120
|
"titulo-eleitor",
|
|
3121
|
+
"processo-judicial",
|
|
3122
|
+
"rg",
|
|
2240
3123
|
"nfe-chave",
|
|
2241
3124
|
"boleto",
|
|
2242
3125
|
"cartao-credito",
|
|
2243
3126
|
"ean",
|
|
2244
3127
|
"inscricao-estadual",
|
|
2245
|
-
"inscricao-estadual-produtor-rural"
|
|
3128
|
+
"inscricao-estadual-produtor-rural",
|
|
3129
|
+
"pix",
|
|
3130
|
+
"brcode"
|
|
2246
3131
|
];
|
|
2247
|
-
function
|
|
2248
|
-
return
|
|
3132
|
+
function isPlatformDocumentType(type) {
|
|
3133
|
+
return PLATFORM_DOCUMENT_TYPES.includes(type);
|
|
2249
3134
|
}
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
3135
|
+
|
|
3136
|
+
// src/commands/compare.ts
|
|
3137
|
+
function printCompare(result, options, io = { stdout: [], stderr: [] }) {
|
|
3138
|
+
if (options.json) {
|
|
3139
|
+
io.stdout.push(JSON.stringify(result, null, 2));
|
|
3140
|
+
if ("code" in result) {
|
|
3141
|
+
return EXIT.USAGE;
|
|
3142
|
+
}
|
|
3143
|
+
return result.equal ? EXIT.OK : EXIT.INVALID;
|
|
2254
3144
|
}
|
|
2255
|
-
|
|
3145
|
+
if (options.quiet) {
|
|
3146
|
+
if ("code" in result) {
|
|
3147
|
+
return EXIT.USAGE;
|
|
3148
|
+
}
|
|
3149
|
+
return result.equal ? EXIT.OK : EXIT.INVALID;
|
|
3150
|
+
}
|
|
3151
|
+
if ("code" in result) {
|
|
3152
|
+
io.stderr.push(`code: ${result.code}`);
|
|
3153
|
+
io.stderr.push(`message: ${result.message}`);
|
|
3154
|
+
return EXIT.USAGE;
|
|
3155
|
+
}
|
|
3156
|
+
io.stdout.push(`equal: ${result.equal ? "yes" : "no"}`);
|
|
3157
|
+
return result.equal ? EXIT.OK : EXIT.INVALID;
|
|
2256
3158
|
}
|
|
2257
|
-
function
|
|
3159
|
+
function runCompare(type, valueA, valueB, options, io = { stdout: [], stderr: [] }) {
|
|
3160
|
+
if (!isPlatformDocumentType(type)) {
|
|
3161
|
+
io.stderr.push(`Unsupported compare type: ${type}`);
|
|
3162
|
+
return EXIT.USAGE;
|
|
3163
|
+
}
|
|
3164
|
+
if (!valueA || !valueB) {
|
|
3165
|
+
io.stderr.push("Missing values. Usage: compare <type> <valueA> <valueB>");
|
|
3166
|
+
return EXIT.USAGE;
|
|
3167
|
+
}
|
|
3168
|
+
const uf = options.uf?.toUpperCase();
|
|
3169
|
+
const platformOptions = uf ? { uf } : {};
|
|
3170
|
+
const result = compareRuntime(valueA, valueB, type, platformOptions);
|
|
3171
|
+
return printCompare(result, options, io);
|
|
3172
|
+
}
|
|
3173
|
+
|
|
3174
|
+
// src/commands/batch.ts
|
|
3175
|
+
import { batch, parseBatchCsv } from "@br-validators/core";
|
|
3176
|
+
function parseBatchLines(raw) {
|
|
3177
|
+
return raw.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0);
|
|
3178
|
+
}
|
|
3179
|
+
function resolveBatchInputs(options) {
|
|
3180
|
+
if (options.lines === void 0) {
|
|
3181
|
+
return { ok: false, reason: "missing_input" };
|
|
3182
|
+
}
|
|
3183
|
+
let parsed;
|
|
3184
|
+
if (options.col !== void 0) {
|
|
3185
|
+
const csv = parseBatchCsv(options.lines, {
|
|
3186
|
+
col: options.col,
|
|
3187
|
+
delimiter: options.delimiter,
|
|
3188
|
+
skipHeader: options.skipHeader
|
|
3189
|
+
});
|
|
3190
|
+
if (!csv.ok) {
|
|
3191
|
+
return { ok: false, reason: "parse_error", message: csv.message };
|
|
3192
|
+
}
|
|
3193
|
+
parsed = csv.values;
|
|
3194
|
+
} else {
|
|
3195
|
+
parsed = parseBatchLines(options.lines);
|
|
3196
|
+
}
|
|
3197
|
+
if (parsed.length === 0) {
|
|
3198
|
+
return { ok: false, reason: "empty" };
|
|
3199
|
+
}
|
|
3200
|
+
if (options.limit !== void 0 && options.limit > 0) {
|
|
3201
|
+
return { ok: true, values: parsed.slice(0, options.limit) };
|
|
3202
|
+
}
|
|
3203
|
+
return { ok: true, values: parsed };
|
|
3204
|
+
}
|
|
3205
|
+
function printBatch(result, options, io = { stdout: [], stderr: [] }) {
|
|
2258
3206
|
if (options.json) {
|
|
2259
3207
|
io.stdout.push(JSON.stringify(result, null, 2));
|
|
2260
|
-
return result.
|
|
3208
|
+
return result.summary.invalid === 0 ? EXIT.OK : EXIT.INVALID;
|
|
2261
3209
|
}
|
|
2262
3210
|
if (options.quiet) {
|
|
2263
|
-
return result.
|
|
3211
|
+
return result.summary.invalid === 0 ? EXIT.OK : EXIT.INVALID;
|
|
2264
3212
|
}
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
3213
|
+
io.stdout.push(`total: ${String(result.summary.total)}`);
|
|
3214
|
+
io.stdout.push(`valid: ${String(result.summary.valid)}`);
|
|
3215
|
+
io.stdout.push(`invalid: ${String(result.summary.invalid)}`);
|
|
3216
|
+
for (const entry of result.valid) {
|
|
3217
|
+
io.stdout.push(`ok[${String(entry.index)}]: ${entry.value}`);
|
|
2270
3218
|
}
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
return EXIT.INVALID;
|
|
3219
|
+
for (const entry of result.invalid) {
|
|
3220
|
+
io.stderr.push(`fail[${String(entry.index)}]: ${entry.code} \u2014 ${entry.message}`);
|
|
3221
|
+
}
|
|
3222
|
+
return result.summary.invalid === 0 ? EXIT.OK : EXIT.INVALID;
|
|
2275
3223
|
}
|
|
2276
|
-
function
|
|
2277
|
-
if (!
|
|
2278
|
-
io.stderr.push(`Unsupported
|
|
3224
|
+
function runBatch(type, options, io = { stdout: [], stderr: [] }) {
|
|
3225
|
+
if (!isPlatformDocumentType(type)) {
|
|
3226
|
+
io.stderr.push(`Unsupported batch type: ${type}`);
|
|
2279
3227
|
return EXIT.USAGE;
|
|
2280
3228
|
}
|
|
2281
|
-
const
|
|
2282
|
-
if (
|
|
2283
|
-
|
|
3229
|
+
const resolved = resolveBatchInputs(options);
|
|
3230
|
+
if (!resolved.ok) {
|
|
3231
|
+
if (resolved.reason === "missing_input") {
|
|
3232
|
+
io.stderr.push("Missing input. Pass --file <path> or pipe one value per line on stdin.");
|
|
3233
|
+
} else if (resolved.reason === "empty") {
|
|
3234
|
+
io.stderr.push("No values to validate.");
|
|
3235
|
+
} else {
|
|
3236
|
+
io.stderr.push(resolved.message);
|
|
3237
|
+
}
|
|
2284
3238
|
return EXIT.USAGE;
|
|
2285
3239
|
}
|
|
2286
3240
|
const uf = options.uf?.toUpperCase();
|
|
2287
|
-
const
|
|
2288
|
-
|
|
3241
|
+
const platformOptions = uf ? { uf } : {};
|
|
3242
|
+
const result = batch(resolved.values, type, platformOptions);
|
|
3243
|
+
return printBatch(result, options, io);
|
|
3244
|
+
}
|
|
3245
|
+
|
|
3246
|
+
// src/commands/diff.ts
|
|
3247
|
+
import { diff } from "@br-validators/core";
|
|
3248
|
+
function printDiff(result, options, io = { stdout: [], stderr: [] }) {
|
|
3249
|
+
if (options.json) {
|
|
3250
|
+
io.stdout.push(JSON.stringify(result, null, 2));
|
|
3251
|
+
return result.changed ? EXIT.INVALID : EXIT.OK;
|
|
3252
|
+
}
|
|
3253
|
+
if (options.quiet) {
|
|
3254
|
+
return result.changed ? EXIT.INVALID : EXIT.OK;
|
|
3255
|
+
}
|
|
3256
|
+
io.stdout.push(`changed: ${result.changed ? "yes" : "no"}`);
|
|
3257
|
+
for (const field of result.fields) {
|
|
3258
|
+
io.stdout.push(`field: ${field.field}`);
|
|
3259
|
+
io.stdout.push(` a: ${field.a}`);
|
|
3260
|
+
io.stdout.push(` b: ${field.b}`);
|
|
3261
|
+
}
|
|
3262
|
+
return result.changed ? EXIT.INVALID : EXIT.OK;
|
|
3263
|
+
}
|
|
3264
|
+
function runDiff(type, valueA, valueB, options, io = { stdout: [], stderr: [] }) {
|
|
3265
|
+
if (!isPlatformDocumentType(type)) {
|
|
3266
|
+
io.stderr.push(`Unsupported diff type: ${type}`);
|
|
3267
|
+
return EXIT.USAGE;
|
|
3268
|
+
}
|
|
3269
|
+
if (!valueA || !valueB) {
|
|
3270
|
+
io.stderr.push("Missing values. Usage: diff <type> <valueA> <valueB>");
|
|
3271
|
+
return EXIT.USAGE;
|
|
3272
|
+
}
|
|
3273
|
+
const uf = options.uf?.toUpperCase();
|
|
3274
|
+
const platformOptions = uf ? { uf } : {};
|
|
3275
|
+
const result = diff(valueA, valueB, type, platformOptions);
|
|
3276
|
+
return printDiff(result, options, io);
|
|
2289
3277
|
}
|
|
2290
3278
|
|
|
2291
3279
|
// src/commands/generate.ts
|
|
@@ -2317,6 +3305,9 @@ function buildGenerateOptions(options) {
|
|
|
2317
3305
|
if (options.masked) {
|
|
2318
3306
|
core.masked = true;
|
|
2319
3307
|
}
|
|
3308
|
+
if (options.stripped) {
|
|
3309
|
+
core.stripped = true;
|
|
3310
|
+
}
|
|
2320
3311
|
if (options.seed !== void 0) {
|
|
2321
3312
|
core.seed = options.seed;
|
|
2322
3313
|
}
|
|
@@ -2360,10 +3351,14 @@ function listSupportedTypes(io = { stdout: [] }) {
|
|
|
2360
3351
|
}
|
|
2361
3352
|
|
|
2362
3353
|
// src/handlers.ts
|
|
3354
|
+
var nodeRequire = createRequire(import.meta.url);
|
|
3355
|
+
function readNodeFileSync(path, encoding) {
|
|
3356
|
+
const fs = nodeRequire("node:fs");
|
|
3357
|
+
return fs.readFileSync(path, encoding);
|
|
3358
|
+
}
|
|
2363
3359
|
function readInputFile(path, io) {
|
|
2364
3360
|
try {
|
|
2365
|
-
|
|
2366
|
-
return fsModule.readFileSync(path, "utf8");
|
|
3361
|
+
return readNodeFileSync(path, "utf8");
|
|
2367
3362
|
} catch {
|
|
2368
3363
|
io.stderr.push(`Cannot read file: ${path}`);
|
|
2369
3364
|
return null;
|
|
@@ -2840,6 +3835,93 @@ function handleSanitizeCli(type, value, opts, io = { stdout: [], stderr: [] }) {
|
|
|
2840
3835
|
io
|
|
2841
3836
|
);
|
|
2842
3837
|
}
|
|
3838
|
+
function handleMaskCli(type, value, opts, io = { stdout: [], stderr: [] }) {
|
|
3839
|
+
let fileContent;
|
|
3840
|
+
if (opts.file) {
|
|
3841
|
+
const content = readInputFile(opts.file, io);
|
|
3842
|
+
if (content === null) {
|
|
3843
|
+
return EXIT.USAGE;
|
|
3844
|
+
}
|
|
3845
|
+
fileContent = content;
|
|
3846
|
+
}
|
|
3847
|
+
return runMask(
|
|
3848
|
+
type,
|
|
3849
|
+
value,
|
|
3850
|
+
{
|
|
3851
|
+
json: Boolean(opts.json),
|
|
3852
|
+
quiet: Boolean(opts.quiet),
|
|
3853
|
+
uf: opts.uf,
|
|
3854
|
+
file: fileContent
|
|
3855
|
+
},
|
|
3856
|
+
io
|
|
3857
|
+
);
|
|
3858
|
+
}
|
|
3859
|
+
function readStdinSync(io) {
|
|
3860
|
+
try {
|
|
3861
|
+
if (process.stdin.isTTY) {
|
|
3862
|
+
return null;
|
|
3863
|
+
}
|
|
3864
|
+
return readNodeFileSync(0, "utf8");
|
|
3865
|
+
} catch {
|
|
3866
|
+
io.stderr.push("Cannot read stdin.");
|
|
3867
|
+
return null;
|
|
3868
|
+
}
|
|
3869
|
+
}
|
|
3870
|
+
function handleCompareCli(type, valueA, valueB, opts, io = { stdout: [], stderr: [] }) {
|
|
3871
|
+
return runCompare(
|
|
3872
|
+
type,
|
|
3873
|
+
valueA,
|
|
3874
|
+
valueB,
|
|
3875
|
+
{
|
|
3876
|
+
json: Boolean(opts.json),
|
|
3877
|
+
quiet: Boolean(opts.quiet),
|
|
3878
|
+
uf: opts.uf
|
|
3879
|
+
},
|
|
3880
|
+
io
|
|
3881
|
+
);
|
|
3882
|
+
}
|
|
3883
|
+
function handleDiffCli(type, valueA, valueB, opts, io = { stdout: [], stderr: [] }) {
|
|
3884
|
+
return runDiff(
|
|
3885
|
+
type,
|
|
3886
|
+
valueA,
|
|
3887
|
+
valueB,
|
|
3888
|
+
{
|
|
3889
|
+
json: Boolean(opts.json),
|
|
3890
|
+
quiet: Boolean(opts.quiet),
|
|
3891
|
+
uf: opts.uf
|
|
3892
|
+
},
|
|
3893
|
+
io
|
|
3894
|
+
);
|
|
3895
|
+
}
|
|
3896
|
+
function handleBatchCli(type, opts, io = { stdout: [], stderr: [] }) {
|
|
3897
|
+
let lines;
|
|
3898
|
+
if (opts.file) {
|
|
3899
|
+
const content = readInputFile(opts.file, io);
|
|
3900
|
+
if (content === null) {
|
|
3901
|
+
return EXIT.USAGE;
|
|
3902
|
+
}
|
|
3903
|
+
lines = content;
|
|
3904
|
+
} else {
|
|
3905
|
+
const stdin = readStdinSync(io);
|
|
3906
|
+
if (stdin !== null) {
|
|
3907
|
+
lines = stdin;
|
|
3908
|
+
}
|
|
3909
|
+
}
|
|
3910
|
+
return runBatch(
|
|
3911
|
+
type,
|
|
3912
|
+
{
|
|
3913
|
+
json: Boolean(opts.json),
|
|
3914
|
+
quiet: Boolean(opts.quiet),
|
|
3915
|
+
uf: opts.uf,
|
|
3916
|
+
lines,
|
|
3917
|
+
limit: opts.limit,
|
|
3918
|
+
col: opts.col,
|
|
3919
|
+
delimiter: opts.delimiter,
|
|
3920
|
+
skipHeader: opts.skipHeader
|
|
3921
|
+
},
|
|
3922
|
+
io
|
|
3923
|
+
);
|
|
3924
|
+
}
|
|
2843
3925
|
function handleGenerateCli(type, opts, io = { stdout: [], stderr: [] }) {
|
|
2844
3926
|
return runGenerate(
|
|
2845
3927
|
type,
|
|
@@ -2847,6 +3929,7 @@ function handleGenerateCli(type, opts, io = { stdout: [], stderr: [] }) {
|
|
|
2847
3929
|
json: Boolean(opts.json),
|
|
2848
3930
|
quiet: Boolean(opts.quiet),
|
|
2849
3931
|
masked: Boolean(opts.masked),
|
|
3932
|
+
stripped: Boolean(opts.stripped),
|
|
2850
3933
|
format: opts.format,
|
|
2851
3934
|
seed: opts.seed,
|
|
2852
3935
|
uf: opts.uf,
|
|
@@ -2898,6 +3981,39 @@ function handleReferenceSearchCli(command, query, opts, io = { stdout: [], stder
|
|
|
2898
3981
|
io
|
|
2899
3982
|
);
|
|
2900
3983
|
}
|
|
3984
|
+
function handleReferenceValidateCli(command, value, opts, io = { stdout: [], stderr: [] }) {
|
|
3985
|
+
return runReferenceValidate(
|
|
3986
|
+
command,
|
|
3987
|
+
value,
|
|
3988
|
+
{
|
|
3989
|
+
json: Boolean(opts.json),
|
|
3990
|
+
verbose: Boolean(opts.verbose)
|
|
3991
|
+
},
|
|
3992
|
+
io
|
|
3993
|
+
);
|
|
3994
|
+
}
|
|
3995
|
+
function handleCstLookupCli(value, opts, io = { stdout: [], stderr: [] }) {
|
|
3996
|
+
return runCstLookup(value, {
|
|
3997
|
+
json: Boolean(opts.json),
|
|
3998
|
+
verbose: Boolean(opts.verbose),
|
|
3999
|
+
tax: opts.tax
|
|
4000
|
+
}, io);
|
|
4001
|
+
}
|
|
4002
|
+
function handleCstSearchCli(query, opts, io = { stdout: [], stderr: [] }) {
|
|
4003
|
+
return runCstSearch(query, {
|
|
4004
|
+
json: Boolean(opts.json),
|
|
4005
|
+
verbose: Boolean(opts.verbose),
|
|
4006
|
+
tax: opts.tax,
|
|
4007
|
+
limit: opts.limit
|
|
4008
|
+
}, io);
|
|
4009
|
+
}
|
|
4010
|
+
function handleCstValidateCli(value, opts, io = { stdout: [], stderr: [] }) {
|
|
4011
|
+
return runCstValidate(value, {
|
|
4012
|
+
json: Boolean(opts.json),
|
|
4013
|
+
verbose: Boolean(opts.verbose),
|
|
4014
|
+
tax: opts.tax
|
|
4015
|
+
}, io);
|
|
4016
|
+
}
|
|
2901
4017
|
function handleIbgeLookupCli(value, opts, io = { stdout: [], stderr: [] }) {
|
|
2902
4018
|
return runIbgeLookup(value, { json: Boolean(opts.json), verbose: Boolean(opts.verbose) }, io);
|
|
2903
4019
|
}
|
|
@@ -2916,6 +4032,34 @@ function handleFeriadosListCli(opts, io = { stdout: [], stderr: [] }) {
|
|
|
2916
4032
|
year: opts.year
|
|
2917
4033
|
}, io);
|
|
2918
4034
|
}
|
|
4035
|
+
function handleInssTabelaCli(opts, io = { stdout: [], stderr: [] }) {
|
|
4036
|
+
return runInssTabela({
|
|
4037
|
+
json: Boolean(opts.json),
|
|
4038
|
+
verbose: Boolean(opts.verbose),
|
|
4039
|
+
ano: opts.year
|
|
4040
|
+
}, io);
|
|
4041
|
+
}
|
|
4042
|
+
function handleInssCalcCli(value, opts, io = { stdout: [], stderr: [] }) {
|
|
4043
|
+
return runInssCalc(value, {
|
|
4044
|
+
json: Boolean(opts.json),
|
|
4045
|
+
verbose: Boolean(opts.verbose),
|
|
4046
|
+
ano: opts.year
|
|
4047
|
+
}, io);
|
|
4048
|
+
}
|
|
4049
|
+
function handleIrpfTabelaCli(opts, io = { stdout: [], stderr: [] }) {
|
|
4050
|
+
return runIrpfTabela({
|
|
4051
|
+
json: Boolean(opts.json),
|
|
4052
|
+
verbose: Boolean(opts.verbose),
|
|
4053
|
+
ano: opts.year
|
|
4054
|
+
}, io);
|
|
4055
|
+
}
|
|
4056
|
+
function handleIrpfCalcCli(value, opts, io = { stdout: [], stderr: [] }) {
|
|
4057
|
+
return runIrpfCalc(value, {
|
|
4058
|
+
json: Boolean(opts.json),
|
|
4059
|
+
verbose: Boolean(opts.verbose),
|
|
4060
|
+
ano: opts.year
|
|
4061
|
+
}, io);
|
|
4062
|
+
}
|
|
2919
4063
|
function handleTseMunicipiosLookupCli(value, opts, io = { stdout: [], stderr: [] }) {
|
|
2920
4064
|
return runTseMunicipiosLookup(value, { json: Boolean(opts.json), verbose: Boolean(opts.verbose) }, io);
|
|
2921
4065
|
}
|
|
@@ -2925,6 +4069,50 @@ function handleCepFaixaCli(value, opts, io = { stdout: [], stderr: [] }) {
|
|
|
2925
4069
|
function handleDddLookupCli(value, opts, io = { stdout: [], stderr: [] }) {
|
|
2926
4070
|
return runDddLookup(value, { json: Boolean(opts.json), verbose: Boolean(opts.verbose) }, io);
|
|
2927
4071
|
}
|
|
4072
|
+
function handleNfeCufLookupCli(value, opts, io = { stdout: [], stderr: [] }) {
|
|
4073
|
+
return runNfeCufLookup(value, { json: Boolean(opts.json), verbose: Boolean(opts.verbose) }, io);
|
|
4074
|
+
}
|
|
4075
|
+
function handleSelicCli(opts, io = { stdout: [], stderr: [] }) {
|
|
4076
|
+
return runSelicCommand({
|
|
4077
|
+
json: Boolean(opts.json),
|
|
4078
|
+
verbose: Boolean(opts.verbose),
|
|
4079
|
+
date: opts.date
|
|
4080
|
+
}, io);
|
|
4081
|
+
}
|
|
4082
|
+
function handleIssMunicipalListCli(opts, io = { stdout: [], stderr: [] }) {
|
|
4083
|
+
return runIssMunicipalList({
|
|
4084
|
+
json: Boolean(opts.json),
|
|
4085
|
+
verbose: Boolean(opts.verbose),
|
|
4086
|
+
uf: opts.uf,
|
|
4087
|
+
limit: opts.limit
|
|
4088
|
+
}, io);
|
|
4089
|
+
}
|
|
4090
|
+
function handleIssMunicipalLookupCli(codigo, opts, io = { stdout: [], stderr: [] }) {
|
|
4091
|
+
return runIssMunicipalLookup(codigo, { json: Boolean(opts.json), verbose: Boolean(opts.verbose) }, io);
|
|
4092
|
+
}
|
|
4093
|
+
function handleIssMunicipalSearchCli(query, opts, io = { stdout: [], stderr: [] }) {
|
|
4094
|
+
return runIssMunicipalSearch(query, {
|
|
4095
|
+
json: Boolean(opts.json),
|
|
4096
|
+
verbose: Boolean(opts.verbose),
|
|
4097
|
+
limit: opts.limit,
|
|
4098
|
+
uf: opts.uf
|
|
4099
|
+
}, io);
|
|
4100
|
+
}
|
|
4101
|
+
function handleIssMunicipalResolveCli(uf, nome, opts, io = { stdout: [], stderr: [] }) {
|
|
4102
|
+
return runIssMunicipalResolve(uf, nome, { json: Boolean(opts.json), verbose: Boolean(opts.verbose) }, io);
|
|
4103
|
+
}
|
|
4104
|
+
function handlePtaxLookupCli(moeda, data, opts, io = { stdout: [], stderr: [] }) {
|
|
4105
|
+
return runPtaxLookup(moeda, data, { json: Boolean(opts.json), verbose: Boolean(opts.verbose) }, io);
|
|
4106
|
+
}
|
|
4107
|
+
function handlePtaxHistoricoCli(moeda, desde, ate, opts, io = { stdout: [], stderr: [] }) {
|
|
4108
|
+
return runPtaxHistorico(
|
|
4109
|
+
moeda,
|
|
4110
|
+
desde,
|
|
4111
|
+
ate,
|
|
4112
|
+
{ json: Boolean(opts.json), verbose: Boolean(opts.verbose) },
|
|
4113
|
+
io
|
|
4114
|
+
);
|
|
4115
|
+
}
|
|
2928
4116
|
function writeCliIo(io) {
|
|
2929
4117
|
for (const line of io.stdout) console.log(line);
|
|
2930
4118
|
for (const line of io.stderr) console.error(line);
|
|
@@ -2940,6 +4128,13 @@ function registerReferenceLookupCommands(program) {
|
|
|
2940
4128
|
process.exitCode = handleReferenceLookupCli(command, codigo, opts, io);
|
|
2941
4129
|
writeCliIo(io);
|
|
2942
4130
|
});
|
|
4131
|
+
if (REFERENCE_VALIDATE_COMMANDS.includes(command)) {
|
|
4132
|
+
root.command("validate").description(`Validate ${command} format and embedded table`).argument("<codigo>", "Code to validate").option("--json", "JSON output").option("--verbose", "Include module metadata").action((codigo, opts) => {
|
|
4133
|
+
const io = { stdout: [], stderr: [] };
|
|
4134
|
+
process.exitCode = handleReferenceValidateCli(command, codigo, opts, io);
|
|
4135
|
+
writeCliIo(io);
|
|
4136
|
+
});
|
|
4137
|
+
}
|
|
2943
4138
|
if (REFERENCE_SEARCH_COMMANDS.includes(command)) {
|
|
2944
4139
|
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) => {
|
|
2945
4140
|
const io = { stdout: [], stderr: [] };
|
|
@@ -3194,6 +4389,28 @@ function createProgram() {
|
|
|
3194
4389
|
process.exitCode = handleFeriadosListCli(opts, io);
|
|
3195
4390
|
writeCliIo(io);
|
|
3196
4391
|
});
|
|
4392
|
+
const inss = program.command("inss").description("INSS employee contribution progressive table \u2014 offline");
|
|
4393
|
+
inss.command("tabela").description("Show embedded progressive contribution brackets").option("--ano <yyyy>", "Compet\xEAncia year", (v) => Number(v)).option("--json", "JSON output").option("--verbose", "Include dataset capture date").action((opts) => {
|
|
4394
|
+
const io = { stdout: [], stderr: [] };
|
|
4395
|
+
process.exitCode = handleInssTabelaCli({ ...opts, year: opts.ano ?? opts.year }, io);
|
|
4396
|
+
writeCliIo(io);
|
|
4397
|
+
});
|
|
4398
|
+
inss.command("calc").description("Estimate monthly INSS contribution from salary").argument("<salario>", "Monthly contribution salary (BRL)").option("--ano <yyyy>", "Compet\xEAncia year", (v) => Number(v)).option("--json", "JSON output").option("--verbose", "Include dataset capture date").action((salario, opts) => {
|
|
4399
|
+
const io = { stdout: [], stderr: [] };
|
|
4400
|
+
process.exitCode = handleInssCalcCli(salario, { ...opts, year: opts.ano ?? opts.year }, io);
|
|
4401
|
+
writeCliIo(io);
|
|
4402
|
+
});
|
|
4403
|
+
const irpf = program.command("irpf").description("RFB IRPF progressive monthly table \u2014 offline");
|
|
4404
|
+
irpf.command("tabela").description("Show embedded monthly progressive brackets").option("--ano <yyyy>", "Tax year", (v) => Number(v)).option("--json", "JSON output").option("--verbose", "Include dataset capture date").action((opts) => {
|
|
4405
|
+
const io = { stdout: [], stderr: [] };
|
|
4406
|
+
process.exitCode = handleIrpfTabelaCli({ ...opts, year: opts.ano ?? opts.year }, io);
|
|
4407
|
+
writeCliIo(io);
|
|
4408
|
+
});
|
|
4409
|
+
irpf.command("calc").description("Estimate monthly IRPF from taxable base").argument("<base>", "Monthly taxable base (BRL)").option("--ano <yyyy>", "Tax year", (v) => Number(v)).option("--json", "JSON output").option("--verbose", "Include dataset capture date").action((base, opts) => {
|
|
4410
|
+
const io = { stdout: [], stderr: [] };
|
|
4411
|
+
process.exitCode = handleIrpfCalcCli(base, { ...opts, year: opts.ano ?? opts.year }, io);
|
|
4412
|
+
writeCliIo(io);
|
|
4413
|
+
});
|
|
3197
4414
|
const tseMunicipios = program.command("tse-municipios").description("TSE \u2194 IBGE municipality cross-walk \u2014 offline lookup");
|
|
3198
4415
|
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) => {
|
|
3199
4416
|
const io = { stdout: [], stderr: [] };
|
|
@@ -3206,6 +4423,68 @@ function createProgram() {
|
|
|
3206
4423
|
process.exitCode = handleDddLookupCli(code, opts, io);
|
|
3207
4424
|
writeCliIo(io);
|
|
3208
4425
|
});
|
|
4426
|
+
const nfeCuf = program.command("nfe-cuf").description("NF-e cUF \u2014 SEFAZ federative unit codes (offline)");
|
|
4427
|
+
nfeCuf.command("lookup").description("Resolve NF-e cUF code to UF sigla and IBGE cross-ref").argument("<code>", "2-digit cUF code (e.g. 35 for SP)").option("--json", "JSON output").option("--verbose", "Include dataset capture date").action((code, opts) => {
|
|
4428
|
+
const io = { stdout: [], stderr: [] };
|
|
4429
|
+
process.exitCode = handleNfeCufLookupCli(code, opts, io);
|
|
4430
|
+
writeCliIo(io);
|
|
4431
|
+
});
|
|
4432
|
+
const selic = program.command("selic").description("Bacen SELIC meta (SGS 432) \u2014 offline embedded series");
|
|
4433
|
+
selic.description("Resolve Copom SELIC meta rate (optional historical date)").option("--date <yyyy-mm-dd>", "Observation date (ISO or MM-DD-YYYY)").option("--json", "JSON output").option("--verbose", "Include dataReferencia, staleness, and dataset capture date").action((opts) => {
|
|
4434
|
+
const io = { stdout: [], stderr: [] };
|
|
4435
|
+
process.exitCode = handleSelicCli(opts, io);
|
|
4436
|
+
writeCliIo(io);
|
|
4437
|
+
});
|
|
4438
|
+
const issMunicipal = program.command("iss-municipal").description("Municipal ISS al\xEDquotas \u2014 partial embed (estimation only, not NFSe)");
|
|
4439
|
+
issMunicipal.command("list").description("List embedded municipalities for a UF").requiredOption("--uf <uf>", "UF sigla (2 letters)").option("--json", "JSON output").option("--verbose", "Include dataset capture date in JSON responses").option("--limit <n>", "Maximum rows", (value) => Number(value)).action((opts) => {
|
|
4440
|
+
const io = { stdout: [], stderr: [] };
|
|
4441
|
+
process.exitCode = handleIssMunicipalListCli(opts, io);
|
|
4442
|
+
writeCliIo(io);
|
|
4443
|
+
});
|
|
4444
|
+
issMunicipal.command("lookup").description("Resolve ISS band by IBGE municipality code").argument("<codigoIbge>", "IBGE municipality code (7 digits)").option("--json", "JSON output").option("--verbose", "Include leiUrl, estimativa flag, and dataset capture date").action((codigoIbge, opts) => {
|
|
4445
|
+
const io = { stdout: [], stderr: [] };
|
|
4446
|
+
process.exitCode = handleIssMunicipalLookupCli(codigoIbge, opts, io);
|
|
4447
|
+
writeCliIo(io);
|
|
4448
|
+
});
|
|
4449
|
+
issMunicipal.command("resolve").description("Resolve ISS band by UF and municipality name").argument("<uf>", "UF sigla (2 letters)").argument("<nome>", "Municipality name").option("--json", "JSON output").option("--verbose", "Include leiUrl, estimativa flag, and dataset capture date").action((uf, nome, opts) => {
|
|
4450
|
+
const io = { stdout: [], stderr: [] };
|
|
4451
|
+
process.exitCode = handleIssMunicipalResolveCli(uf, nome, opts, io);
|
|
4452
|
+
writeCliIo(io);
|
|
4453
|
+
});
|
|
4454
|
+
issMunicipal.command("search").description("Search embedded municipalities by name, UF, or IBGE code fragment").argument("<query>", "Search query").option("--uf <uf>", "Scope search to a UF").option("--json", "JSON output").option("--verbose", "Include dataset capture date in JSON responses").option("--limit <n>", "Maximum rows", (value) => Number(value)).action((query, opts) => {
|
|
4455
|
+
const io = { stdout: [], stderr: [] };
|
|
4456
|
+
process.exitCode = handleIssMunicipalSearchCli(query, opts, io);
|
|
4457
|
+
writeCliIo(io);
|
|
4458
|
+
});
|
|
4459
|
+
const ptax = program.command("ptax").description("Bacen PTAX Fechamento \u2014 offline embedded rates");
|
|
4460
|
+
ptax.command("lookup").description("Resolve Fechamento PTAX for currency (optional ISO or Bacen date)").argument("<moeda>", "ISO 4217 currency code (e.g. USD)").argument("[data]", "Quote date \u2014 YYYY-MM-DD or MM-DD-YYYY").option("--json", "JSON output").option("--verbose", "Include dataReferencia, staleness, and dataset capture date").action((moeda, data, opts) => {
|
|
4461
|
+
const io = { stdout: [], stderr: [] };
|
|
4462
|
+
process.exitCode = handlePtaxLookupCli(moeda, data, opts, io);
|
|
4463
|
+
writeCliIo(io);
|
|
4464
|
+
});
|
|
4465
|
+
ptax.command("historico").description("List embedded Fechamento PTAX rows for a currency and date range").argument("<moeda>", "ISO 4217 currency code (e.g. USD)").argument("<desde>", "Range start \u2014 YYYY-MM-DD or MM-DD-YYYY").argument("<ate>", "Range end \u2014 YYYY-MM-DD or MM-DD-YYYY").option("--json", "JSON output").option("--verbose", "Include capturadoEm and janelaDiasUteis in JSON responses").action(
|
|
4466
|
+
(moeda, desde, ate, opts) => {
|
|
4467
|
+
const io = { stdout: [], stderr: [] };
|
|
4468
|
+
process.exitCode = handlePtaxHistoricoCli(moeda, desde, ate, opts, io);
|
|
4469
|
+
writeCliIo(io);
|
|
4470
|
+
}
|
|
4471
|
+
);
|
|
4472
|
+
const cst = program.command("cst").description("RFB SPED CST \u2014 offline ICMS, IPI, PIS, COFINS tables");
|
|
4473
|
+
cst.command("lookup").description("Resolve CST by code and tax").argument("<codigo>", "CST code").requiredOption("--tax <tax>", "Tax table: icms | ipi | pis | cofins").option("--json", "JSON output").option("--verbose", "Include dataset capture date").action((codigo, opts) => {
|
|
4474
|
+
const io = { stdout: [], stderr: [] };
|
|
4475
|
+
process.exitCode = handleCstLookupCli(codigo, opts, io);
|
|
4476
|
+
writeCliIo(io);
|
|
4477
|
+
});
|
|
4478
|
+
cst.command("search").description("Search CST descriptions by tax").argument("<query>", "Search query").requiredOption("--tax <tax>", "Tax table: icms | ipi | pis | cofins").option("--json", "JSON output").option("--limit <n>", "Maximum rows", (v) => Number(v)).action((query, opts) => {
|
|
4479
|
+
const io = { stdout: [], stderr: [] };
|
|
4480
|
+
process.exitCode = handleCstSearchCli(query, opts, io);
|
|
4481
|
+
writeCliIo(io);
|
|
4482
|
+
});
|
|
4483
|
+
cst.command("validate").description("Validate CST format and embedded table").argument("<codigo>", "CST code").requiredOption("--tax <tax>", "Tax table: icms | ipi | pis | cofins").option("--json", "JSON output").option("--verbose", "Include tax metadata").action((codigo, opts) => {
|
|
4484
|
+
const io = { stdout: [], stderr: [] };
|
|
4485
|
+
process.exitCode = handleCstValidateCli(codigo, opts, io);
|
|
4486
|
+
writeCliIo(io);
|
|
4487
|
+
});
|
|
3209
4488
|
registerReferenceLookupCommands(program);
|
|
3210
4489
|
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) => {
|
|
3211
4490
|
const io = { stdout: [], stderr: [] };
|
|
@@ -3217,11 +4496,31 @@ function createProgram() {
|
|
|
3217
4496
|
process.exitCode = handleSanitizeCli(type, value, opts, io);
|
|
3218
4497
|
writeCliIo(io);
|
|
3219
4498
|
});
|
|
3220
|
-
program.command("
|
|
4499
|
+
program.command("mask <type> [value]").description("Apply unified display mask (validate first)").option("--uf <uf>", "State code (required for inscricao-estadual and rg)").option("--json", "JSON output").option("-q, --quiet", "Exit code only").option("-f, --file <path>", "Read value from file").action((type, value, opts) => {
|
|
4500
|
+
const io = { stdout: [], stderr: [] };
|
|
4501
|
+
process.exitCode = handleMaskCli(type, value, opts, io);
|
|
4502
|
+
writeCliIo(io);
|
|
4503
|
+
});
|
|
4504
|
+
program.command("generate <type>").description("Generate synthetic valid test document").option("--json", "JSON output").option("-q, --quiet", "Exit code only").option("--masked", "Return masked/formatted output").option("--stripped", "Return canonical stripped digits (default; explicit flag)").option("--format <format>", "Format variant (numeric, alphanumeric, legacy, mercosul, celular, fixo)").option("--seed <number>", "Deterministic PRNG seed", (v) => Number(v)).option("--uf <uf>", "State code (required for inscricao-estadual and titulo-eleitor)").option("--brand <brand>", "Card brand (visa, mastercard, amex, elo, hipercard)").action((type, opts) => {
|
|
3221
4505
|
const io = { stdout: [], stderr: [] };
|
|
3222
4506
|
process.exitCode = handleGenerateCli(type, opts, io);
|
|
3223
4507
|
writeCliIo(io);
|
|
3224
4508
|
});
|
|
4509
|
+
program.command("compare <type> <valueA> [valueB...]").description("Compare two values for normalized equality").option("--uf <uf>", "State code (required for inscricao-estadual, rg, titulo-eleitor)").option("--json", "JSON output").option("-q, --quiet", "Exit code only").action((type, valueA, valueB, opts) => {
|
|
4510
|
+
const io = { stdout: [], stderr: [] };
|
|
4511
|
+
process.exitCode = handleCompareCli(type, valueA, valueB.join(" ") || void 0, opts, io);
|
|
4512
|
+
writeCliIo(io);
|
|
4513
|
+
});
|
|
4514
|
+
program.command("batch <type>").description("Bulk validate values from stdin or --file").option("--uf <uf>", "State code (required for inscricao-estadual, rg, titulo-eleitor)").option("--json", "JSON output").option("-q, --quiet", "Exit code only").option("-f, --file <path>", "Read values from file (one per line, or CSV with --col)").option("--col <name>", "CSV column name or zero-based index (requires --file)").option("--delimiter <char>", "CSV delimiter (default: comma)").option("--skip-header", "Treat first CSV row as header (default: true)", true).option("--no-skip-header", "Parse CSV without header row").option("--limit <n>", "Max number of values to process", (v) => Number(v)).action((type, opts) => {
|
|
4515
|
+
const io = { stdout: [], stderr: [] };
|
|
4516
|
+
process.exitCode = handleBatchCli(type, opts, io);
|
|
4517
|
+
writeCliIo(io);
|
|
4518
|
+
});
|
|
4519
|
+
program.command("diff <type> <valueA> [valueB...]").description("Field-level structural diff between two values").option("--uf <uf>", "State code (required for inscricao-estadual, rg, titulo-eleitor)").option("--json", "JSON output").option("-q, --quiet", "Exit code only").action((type, valueA, valueB, opts) => {
|
|
4520
|
+
const io = { stdout: [], stderr: [] };
|
|
4521
|
+
process.exitCode = handleDiffCli(type, valueA, valueB.join(" ") || void 0, opts, io);
|
|
4522
|
+
writeCliIo(io);
|
|
4523
|
+
});
|
|
3225
4524
|
return program;
|
|
3226
4525
|
}
|
|
3227
4526
|
function run(argv) {
|