@br-validators/cli 1.8.3 → 1.9.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 +13 -6
- package/dist/index.js +1192 -78
- package/dist/run-captured.js +1259 -119
- 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,41 +117,45 @@ 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 { NCM_DATA_VERSION,
|
|
153
|
-
import { CBO_DATA_VERSION,
|
|
153
|
+
import { NCM_DATA_VERSION, lookupNcmPorCodigo } from "@br-validators/core/ncm";
|
|
154
|
+
import { CBO_DATA_VERSION, lookupCboPorCodigo } from "@br-validators/core/cbo";
|
|
155
|
+
import {
|
|
156
|
+
lookupInvalidFormat as lookupInvalidFormat2,
|
|
157
|
+
lookupInvalidInput
|
|
158
|
+
} from "@br-validators/core/lookup";
|
|
154
159
|
var REFERENCE_LOOKUP_COMMANDS = [
|
|
155
160
|
"natureza-juridica",
|
|
156
161
|
"nbs",
|
|
@@ -168,13 +173,16 @@ var REFERENCE_LOOKUP_COMMANDS = [
|
|
|
168
173
|
var REFERENCE_SEARCH_COMMANDS = ["cnae", "cfop", "ncm", "cbo"];
|
|
169
174
|
function lookupAeroporto(input) {
|
|
170
175
|
const normalized = input.trim().toUpperCase();
|
|
176
|
+
if (normalized.length === 0) {
|
|
177
|
+
return lookupInvalidInput("Airport code is required");
|
|
178
|
+
}
|
|
171
179
|
if (/^[A-Z0-9]{3}$/.test(normalized)) {
|
|
172
|
-
return
|
|
180
|
+
return lookupAeroportoPorIata(normalized);
|
|
173
181
|
}
|
|
174
182
|
if (/^[A-Z]{4}$/.test(normalized)) {
|
|
175
|
-
return
|
|
183
|
+
return lookupAeroportoPorIcao(normalized);
|
|
176
184
|
}
|
|
177
|
-
return
|
|
185
|
+
return lookupInvalidFormat2("Airport code must be 3-character IATA or 4-character ICAO");
|
|
178
186
|
}
|
|
179
187
|
var REFERENCE_LOOKUP_MODULES = {
|
|
180
188
|
"natureza-juridica": {
|
|
@@ -182,7 +190,7 @@ var REFERENCE_LOOKUP_MODULES = {
|
|
|
182
190
|
description: "RFB legal nature codes \u2014 offline lookup",
|
|
183
191
|
resultKey: "naturezaJuridica",
|
|
184
192
|
capturadoEm: NATUREZA_JURIDICA_DATA_VERSION.capturadoEm,
|
|
185
|
-
lookup: (input) =>
|
|
193
|
+
lookup: (input) => lookupNaturezaJuridicaPorCodigo(input),
|
|
186
194
|
formatHuman: (result) => {
|
|
187
195
|
const row = result;
|
|
188
196
|
return `${row.codigo} \u2014 ${row.descricao}`;
|
|
@@ -193,7 +201,7 @@ var REFERENCE_LOOKUP_MODULES = {
|
|
|
193
201
|
description: "NFSe NBS service codes \u2014 offline lookup",
|
|
194
202
|
resultKey: "nbs",
|
|
195
203
|
capturadoEm: NBS_DATA_VERSION.capturadoEm,
|
|
196
|
-
lookup: (input) =>
|
|
204
|
+
lookup: (input) => lookupNbsPorCodigo(input),
|
|
197
205
|
formatHuman: (result) => {
|
|
198
206
|
const row = result;
|
|
199
207
|
return `${row.codigo} \u2014 ${row.descricao}`;
|
|
@@ -204,7 +212,7 @@ var REFERENCE_LOOKUP_MODULES = {
|
|
|
204
212
|
description: "CONFAZ CEST ST codes \u2014 offline lookup",
|
|
205
213
|
resultKey: "cest",
|
|
206
214
|
capturadoEm: CEST_DATA_VERSION.capturadoEm,
|
|
207
|
-
lookup: (input) =>
|
|
215
|
+
lookup: (input) => lookupCestPorCodigo(input),
|
|
208
216
|
formatHuman: (result) => {
|
|
209
217
|
const row = result;
|
|
210
218
|
return `${row.codigo} \u2014 ${row.descricao}`;
|
|
@@ -215,7 +223,7 @@ var REFERENCE_LOOKUP_MODULES = {
|
|
|
215
223
|
description: "IBGE CNAE 2.3 subclasses \u2014 offline lookup",
|
|
216
224
|
resultKey: "cnae",
|
|
217
225
|
capturadoEm: CNAES_DATA_VERSION.capturadoEm,
|
|
218
|
-
lookup: (input) =>
|
|
226
|
+
lookup: (input) => lookupCnaePorCodigo(input),
|
|
219
227
|
formatHuman: (result) => {
|
|
220
228
|
const row = result;
|
|
221
229
|
return `${row.codigo} \u2014 ${row.descricao}`;
|
|
@@ -226,7 +234,7 @@ var REFERENCE_LOOKUP_MODULES = {
|
|
|
226
234
|
description: "CONFAZ CFOP fiscal operations \u2014 offline lookup",
|
|
227
235
|
resultKey: "cfop",
|
|
228
236
|
capturadoEm: CFOP_DATA_VERSION.capturadoEm,
|
|
229
|
-
lookup: (input) =>
|
|
237
|
+
lookup: (input) => lookupCfopPorCodigo(input),
|
|
230
238
|
formatHuman: (result) => {
|
|
231
239
|
const row = result;
|
|
232
240
|
return `${row.codigo} \u2014 ${row.descricao}`;
|
|
@@ -237,7 +245,7 @@ var REFERENCE_LOOKUP_MODULES = {
|
|
|
237
245
|
description: "Siscomex NCM Mercosur codes \u2014 offline lookup",
|
|
238
246
|
resultKey: "ncm",
|
|
239
247
|
capturadoEm: NCM_DATA_VERSION.capturadoEm,
|
|
240
|
-
lookup: (input) =>
|
|
248
|
+
lookup: (input) => lookupNcmPorCodigo(input),
|
|
241
249
|
formatHuman: (result) => {
|
|
242
250
|
const row = result;
|
|
243
251
|
return `${row.codigo} \u2014 ${row.descricao}`;
|
|
@@ -248,7 +256,7 @@ var REFERENCE_LOOKUP_MODULES = {
|
|
|
248
256
|
description: "MTE CBO 2002 occupations \u2014 offline lookup",
|
|
249
257
|
resultKey: "cbo",
|
|
250
258
|
capturadoEm: CBO_DATA_VERSION.capturadoEm,
|
|
251
|
-
lookup: (input) =>
|
|
259
|
+
lookup: (input) => lookupCboPorCodigo(input),
|
|
252
260
|
formatHuman: (result) => {
|
|
253
261
|
const row = result;
|
|
254
262
|
return `${row.codigo} \u2014 ${row.descricao}`;
|
|
@@ -259,7 +267,7 @@ var REFERENCE_LOOKUP_MODULES = {
|
|
|
259
267
|
description: "ISO 4217 + Bacen PTAX currencies \u2014 offline lookup",
|
|
260
268
|
resultKey: "moeda",
|
|
261
269
|
capturadoEm: MOEDAS_DATA_VERSION.capturadoEm,
|
|
262
|
-
lookup: (input) =>
|
|
270
|
+
lookup: (input) => lookupMoedaPorCodigo(input),
|
|
263
271
|
formatHuman: (result) => {
|
|
264
272
|
const row = result;
|
|
265
273
|
const symbol = row.simbolo ?? "\u2014";
|
|
@@ -271,7 +279,7 @@ var REFERENCE_LOOKUP_MODULES = {
|
|
|
271
279
|
description: "NF-e Bacen country codes \u2014 offline lookup",
|
|
272
280
|
resultKey: "pais",
|
|
273
281
|
capturadoEm: PAISES_BACEN_DATA_VERSION.capturadoEm,
|
|
274
|
-
lookup: (input) =>
|
|
282
|
+
lookup: (input) => lookupPaisPorCodigoBacen(input),
|
|
275
283
|
formatHuman: (result) => {
|
|
276
284
|
const row = result;
|
|
277
285
|
return `${row.codigo} \u2014 ${row.nome}`;
|
|
@@ -282,7 +290,7 @@ var REFERENCE_LOOKUP_MODULES = {
|
|
|
282
290
|
description: "ICC Incoterms 2020 \u2014 offline lookup",
|
|
283
291
|
resultKey: "incoterm",
|
|
284
292
|
capturadoEm: INCOTERMS_DATA_VERSION.capturadoEm,
|
|
285
|
-
lookup: (input) =>
|
|
293
|
+
lookup: (input) => lookupIncotermPorCodigo(input),
|
|
286
294
|
formatHuman: (result) => {
|
|
287
295
|
const row = result;
|
|
288
296
|
return `${row.codigo} \u2014 ${row.nome} (${row.edicao})`;
|
|
@@ -293,7 +301,7 @@ var REFERENCE_LOOKUP_MODULES = {
|
|
|
293
301
|
description: "ANTAQ port installations \u2014 offline lookup",
|
|
294
302
|
resultKey: "porto",
|
|
295
303
|
capturadoEm: PORTOS_DATA_VERSION.capturadoEm,
|
|
296
|
-
lookup: (input) =>
|
|
304
|
+
lookup: (input) => lookupPortoPorCodigo(input),
|
|
297
305
|
formatHuman: (result) => {
|
|
298
306
|
const row = result;
|
|
299
307
|
return `${row.codigo} \u2014 ${row.nome} (${row.uf})`;
|
|
@@ -320,6 +328,15 @@ function isReferenceSearchCommand(value) {
|
|
|
320
328
|
}
|
|
321
329
|
|
|
322
330
|
// src/commands/reference-lookup/lookup.ts
|
|
331
|
+
function emitLookupFailure(result, options, io) {
|
|
332
|
+
if (options.json) {
|
|
333
|
+
io.stdout.push(
|
|
334
|
+
JSON.stringify({ ok: false, code: result.code, message: result.message }, null, 2)
|
|
335
|
+
);
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
io.stderr.push(result.message);
|
|
339
|
+
}
|
|
323
340
|
function runReferenceLookupCommand(command, input, options, io = { stdout: [], stderr: [] }) {
|
|
324
341
|
const module = REFERENCE_LOOKUP_MODULES[command];
|
|
325
342
|
const trimmed = input.trim();
|
|
@@ -328,20 +345,20 @@ function runReferenceLookupCommand(command, input, options, io = { stdout: [], s
|
|
|
328
345
|
return EXIT.USAGE;
|
|
329
346
|
}
|
|
330
347
|
const result = module.lookup(trimmed);
|
|
331
|
-
if (!result) {
|
|
332
|
-
|
|
348
|
+
if (!result.ok) {
|
|
349
|
+
emitLookupFailure(result, options, io);
|
|
333
350
|
return EXIT.INVALID;
|
|
334
351
|
}
|
|
335
352
|
if (options.json) {
|
|
336
353
|
const payload = {
|
|
337
354
|
ok: true,
|
|
338
|
-
[module.resultKey]: result,
|
|
355
|
+
[module.resultKey]: result.value,
|
|
339
356
|
...options.verbose ? { capturadoEm: module.capturadoEm } : {}
|
|
340
357
|
};
|
|
341
358
|
io.stdout.push(JSON.stringify(payload, null, 2));
|
|
342
359
|
return EXIT.OK;
|
|
343
360
|
}
|
|
344
|
-
io.stdout.push(module.formatHuman(result));
|
|
361
|
+
io.stdout.push(module.formatHuman(result.value));
|
|
345
362
|
if (options.verbose) {
|
|
346
363
|
io.stdout.push(`capturadoEm: ${module.capturadoEm}`);
|
|
347
364
|
}
|
|
@@ -425,11 +442,239 @@ function runReferenceSearch(command, query, options, io = { stdout: [], stderr:
|
|
|
425
442
|
return runReferenceSearchCommand(command, query.trim(), options, io);
|
|
426
443
|
}
|
|
427
444
|
|
|
445
|
+
// src/commands/reference-lookup/validate.ts
|
|
446
|
+
import { validateCfop } from "@br-validators/core/cfop";
|
|
447
|
+
import { validateNcm } from "@br-validators/core/ncm";
|
|
448
|
+
var REFERENCE_VALIDATE_COMMANDS = ["ncm", "cfop"];
|
|
449
|
+
var VALIDATORS = {
|
|
450
|
+
ncm: validateNcm,
|
|
451
|
+
cfop: validateCfop
|
|
452
|
+
};
|
|
453
|
+
var CAPTURED_AT = {
|
|
454
|
+
ncm: "ncm",
|
|
455
|
+
cfop: "cfop"
|
|
456
|
+
};
|
|
457
|
+
function emitFailure(result, options, io) {
|
|
458
|
+
if (options.json) {
|
|
459
|
+
io.stdout.push(JSON.stringify({ ok: false, code: result.code, message: result.message }, null, 2));
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
io.stderr.push(result.message);
|
|
463
|
+
}
|
|
464
|
+
function isReferenceValidateCommand(command) {
|
|
465
|
+
return REFERENCE_VALIDATE_COMMANDS.includes(command);
|
|
466
|
+
}
|
|
467
|
+
function runReferenceValidateCommand(command, input, options, io = { stdout: [], stderr: [] }) {
|
|
468
|
+
const trimmed = input.trim();
|
|
469
|
+
if (trimmed.length === 0) {
|
|
470
|
+
io.stderr.push(`Missing code. Pass a value to validate for ${command}.`);
|
|
471
|
+
return EXIT.USAGE;
|
|
472
|
+
}
|
|
473
|
+
const result = VALIDATORS[command](trimmed);
|
|
474
|
+
if (!result.ok) {
|
|
475
|
+
emitFailure(result, options, io);
|
|
476
|
+
return EXIT.INVALID;
|
|
477
|
+
}
|
|
478
|
+
if (options.json) {
|
|
479
|
+
const payload = {
|
|
480
|
+
ok: true,
|
|
481
|
+
value: result.value,
|
|
482
|
+
description: result.description,
|
|
483
|
+
...result.format !== void 0 ? { format: result.format } : {},
|
|
484
|
+
...options.verbose ? { module: CAPTURED_AT[command] } : {}
|
|
485
|
+
};
|
|
486
|
+
io.stdout.push(JSON.stringify(payload, null, 2));
|
|
487
|
+
return EXIT.OK;
|
|
488
|
+
}
|
|
489
|
+
const lines = [`${result.value} \u2014 ${result.description}`];
|
|
490
|
+
if (result.format !== void 0) {
|
|
491
|
+
lines.push(`format: ${result.format}`);
|
|
492
|
+
}
|
|
493
|
+
io.stdout.push(lines.join("\n"));
|
|
494
|
+
return EXIT.OK;
|
|
495
|
+
}
|
|
496
|
+
function runReferenceValidate(command, value, options, io = { stdout: [], stderr: [] }) {
|
|
497
|
+
if (!isReferenceValidateCommand(command)) {
|
|
498
|
+
io.stderr.push(`Unknown reference validate command: ${command}`);
|
|
499
|
+
return EXIT.USAGE;
|
|
500
|
+
}
|
|
501
|
+
if (!value?.trim()) {
|
|
502
|
+
io.stderr.push(`Missing code. Usage: br-validators ${command} validate <codigo>`);
|
|
503
|
+
return EXIT.USAGE;
|
|
504
|
+
}
|
|
505
|
+
return runReferenceValidateCommand(command, value.trim(), options, io);
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
// src/commands/cst/index.ts
|
|
509
|
+
import {
|
|
510
|
+
CST_DATA_VERSION,
|
|
511
|
+
lookupCstCofinsPorCodigo,
|
|
512
|
+
lookupCstIcmsPorCodigo,
|
|
513
|
+
lookupCstIpiPorCodigo,
|
|
514
|
+
lookupCstPisPorCodigo,
|
|
515
|
+
searchCstCofins,
|
|
516
|
+
searchCstIcms,
|
|
517
|
+
searchCstIpi,
|
|
518
|
+
searchCstPis,
|
|
519
|
+
validateCst
|
|
520
|
+
} from "@br-validators/core/cst";
|
|
521
|
+
var CST_TAXES = ["icms", "ipi", "pis", "cofins"];
|
|
522
|
+
function parseCstTax(raw) {
|
|
523
|
+
if (raw === void 0) {
|
|
524
|
+
return null;
|
|
525
|
+
}
|
|
526
|
+
const normalized = raw.trim().toLowerCase();
|
|
527
|
+
if (CST_TAXES.includes(normalized)) {
|
|
528
|
+
return normalized;
|
|
529
|
+
}
|
|
530
|
+
return null;
|
|
531
|
+
}
|
|
532
|
+
function lookupByTax(tax, codigo) {
|
|
533
|
+
switch (tax) {
|
|
534
|
+
case "icms":
|
|
535
|
+
return lookupCstIcmsPorCodigo(codigo);
|
|
536
|
+
case "ipi":
|
|
537
|
+
return lookupCstIpiPorCodigo(codigo);
|
|
538
|
+
case "pis":
|
|
539
|
+
return lookupCstPisPorCodigo(codigo);
|
|
540
|
+
case "cofins":
|
|
541
|
+
return lookupCstCofinsPorCodigo(codigo);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
function searchByTax(tax, query, limit) {
|
|
545
|
+
const options = limit !== void 0 ? { limit } : void 0;
|
|
546
|
+
switch (tax) {
|
|
547
|
+
case "icms":
|
|
548
|
+
return searchCstIcms(query, options);
|
|
549
|
+
case "ipi":
|
|
550
|
+
return searchCstIpi(query, options);
|
|
551
|
+
case "pis":
|
|
552
|
+
return searchCstPis(query, options);
|
|
553
|
+
case "cofins":
|
|
554
|
+
return searchCstCofins(query, options);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
function emitLookupFailure2(result, options, io) {
|
|
558
|
+
if (options.json) {
|
|
559
|
+
io.stdout.push(JSON.stringify({ ok: false, code: result.code, message: result.message }, null, 2));
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
io.stderr.push(result.message);
|
|
563
|
+
}
|
|
564
|
+
function emitValidateFailure(result, options, io) {
|
|
565
|
+
if (options.json) {
|
|
566
|
+
io.stdout.push(JSON.stringify({ ok: false, code: result.code, message: result.message }, null, 2));
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
io.stderr.push(result.message);
|
|
570
|
+
}
|
|
571
|
+
function runCstLookup(codigo, options, io = { stdout: [], stderr: [] }) {
|
|
572
|
+
const tax = parseCstTax(options.tax);
|
|
573
|
+
if (tax === null) {
|
|
574
|
+
io.stderr.push("Missing or invalid --tax. Expected: icms | ipi | pis | cofins");
|
|
575
|
+
return EXIT.USAGE;
|
|
576
|
+
}
|
|
577
|
+
const trimmed = codigo?.trim() ?? "";
|
|
578
|
+
if (trimmed.length === 0) {
|
|
579
|
+
io.stderr.push("Missing code. Usage: br-validators cst lookup <codigo> --tax icms");
|
|
580
|
+
return EXIT.USAGE;
|
|
581
|
+
}
|
|
582
|
+
const result = lookupByTax(tax, trimmed);
|
|
583
|
+
if (!result.ok) {
|
|
584
|
+
emitLookupFailure2(result, options, io);
|
|
585
|
+
return EXIT.INVALID;
|
|
586
|
+
}
|
|
587
|
+
if (options.json) {
|
|
588
|
+
io.stdout.push(
|
|
589
|
+
JSON.stringify(
|
|
590
|
+
{
|
|
591
|
+
ok: true,
|
|
592
|
+
cst: result.value,
|
|
593
|
+
tax,
|
|
594
|
+
...options.verbose ? { capturadoEm: CST_DATA_VERSION.capturadoEm } : {}
|
|
595
|
+
},
|
|
596
|
+
null,
|
|
597
|
+
2
|
|
598
|
+
)
|
|
599
|
+
);
|
|
600
|
+
return EXIT.OK;
|
|
601
|
+
}
|
|
602
|
+
io.stdout.push(`${result.value.codigo} \u2014 ${result.value.descricao}`);
|
|
603
|
+
if (options.verbose) {
|
|
604
|
+
io.stdout.push(`tax: ${tax}`);
|
|
605
|
+
io.stdout.push(`capturadoEm: ${CST_DATA_VERSION.capturadoEm}`);
|
|
606
|
+
}
|
|
607
|
+
return EXIT.OK;
|
|
608
|
+
}
|
|
609
|
+
function runCstSearch(query, options, io = { stdout: [], stderr: [] }) {
|
|
610
|
+
const tax = parseCstTax(options.tax);
|
|
611
|
+
if (tax === null) {
|
|
612
|
+
io.stderr.push("Missing or invalid --tax. Expected: icms | ipi | pis | cofins");
|
|
613
|
+
return EXIT.USAGE;
|
|
614
|
+
}
|
|
615
|
+
const trimmed = query?.trim() ?? "";
|
|
616
|
+
if (trimmed.length === 0) {
|
|
617
|
+
io.stderr.push("Missing query. Usage: br-validators cst search <query> --tax icms");
|
|
618
|
+
return EXIT.USAGE;
|
|
619
|
+
}
|
|
620
|
+
const rows = searchByTax(tax, trimmed, options.limit);
|
|
621
|
+
if (options.json) {
|
|
622
|
+
io.stdout.push(JSON.stringify({ ok: true, tax, results: rows }, null, 2));
|
|
623
|
+
return EXIT.OK;
|
|
624
|
+
}
|
|
625
|
+
if (rows.length === 0) {
|
|
626
|
+
io.stdout.push("No matches.");
|
|
627
|
+
return EXIT.OK;
|
|
628
|
+
}
|
|
629
|
+
for (const row of rows) {
|
|
630
|
+
io.stdout.push(`${row.codigo} \u2014 ${row.descricao}`);
|
|
631
|
+
}
|
|
632
|
+
return EXIT.OK;
|
|
633
|
+
}
|
|
634
|
+
function runCstValidate(codigo, options, io = { stdout: [], stderr: [] }) {
|
|
635
|
+
const tax = parseCstTax(options.tax);
|
|
636
|
+
if (tax === null) {
|
|
637
|
+
io.stderr.push("Missing or invalid --tax. Expected: icms | ipi | pis | cofins");
|
|
638
|
+
return EXIT.USAGE;
|
|
639
|
+
}
|
|
640
|
+
const trimmed = codigo?.trim() ?? "";
|
|
641
|
+
if (trimmed.length === 0) {
|
|
642
|
+
io.stderr.push("Missing code. Usage: br-validators cst validate <codigo> --tax icms");
|
|
643
|
+
return EXIT.USAGE;
|
|
644
|
+
}
|
|
645
|
+
const result = validateCst(trimmed, { tax });
|
|
646
|
+
if (!result.ok) {
|
|
647
|
+
emitValidateFailure(result, options, io);
|
|
648
|
+
return EXIT.INVALID;
|
|
649
|
+
}
|
|
650
|
+
if (options.json) {
|
|
651
|
+
io.stdout.push(
|
|
652
|
+
JSON.stringify(
|
|
653
|
+
{
|
|
654
|
+
ok: true,
|
|
655
|
+
tax,
|
|
656
|
+
value: result.value,
|
|
657
|
+
description: result.description
|
|
658
|
+
},
|
|
659
|
+
null,
|
|
660
|
+
2
|
|
661
|
+
)
|
|
662
|
+
);
|
|
663
|
+
return EXIT.OK;
|
|
664
|
+
}
|
|
665
|
+
io.stdout.push(`${result.value} \u2014 ${result.description}`);
|
|
666
|
+
if (options.verbose) {
|
|
667
|
+
io.stdout.push(`tax: ${tax}`);
|
|
668
|
+
}
|
|
669
|
+
return EXIT.OK;
|
|
670
|
+
}
|
|
671
|
+
|
|
428
672
|
// src/commands/ibge/lookup.ts
|
|
429
673
|
import {
|
|
430
|
-
|
|
674
|
+
lookupMunicipioPorCodigo,
|
|
431
675
|
IBGE_DATA_VERSION
|
|
432
676
|
} from "@br-validators/core/ibge";
|
|
677
|
+
import { lookupInvalidFormat as lookupInvalidFormat3 } from "@br-validators/core/lookup";
|
|
433
678
|
function normalizeIbgeMunicipioCode(raw) {
|
|
434
679
|
const digits = raw.replace(/\D/g, "");
|
|
435
680
|
if (digits.length !== 7) {
|
|
@@ -437,24 +682,35 @@ function normalizeIbgeMunicipioCode(raw) {
|
|
|
437
682
|
}
|
|
438
683
|
return Number(digits);
|
|
439
684
|
}
|
|
685
|
+
function lookupMunicipio(raw) {
|
|
686
|
+
const codigo = normalizeIbgeMunicipioCode(raw);
|
|
687
|
+
if (codigo === null) {
|
|
688
|
+
return lookupInvalidFormat3("Invalid IBGE municipality code. Use 7 digits (e.g. 3550308).");
|
|
689
|
+
}
|
|
690
|
+
return lookupMunicipioPorCodigo(codigo);
|
|
691
|
+
}
|
|
440
692
|
function formatMunicipioHuman(municipio) {
|
|
441
693
|
return `${municipio.codigo} \u2014 ${municipio.nome} (${municipio.uf})`;
|
|
442
694
|
}
|
|
443
|
-
function
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
695
|
+
function emitLookupFailure3(result, options, io) {
|
|
696
|
+
if (options.json) {
|
|
697
|
+
io.stdout.push(
|
|
698
|
+
JSON.stringify({ ok: false, code: result.code, message: result.message }, null, 2)
|
|
699
|
+
);
|
|
700
|
+
return result.code === "INVALID_FORMAT" ? EXIT.USAGE : EXIT.INVALID;
|
|
448
701
|
}
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
702
|
+
io.stderr.push(result.message);
|
|
703
|
+
return result.code === "INVALID_FORMAT" ? EXIT.USAGE : EXIT.INVALID;
|
|
704
|
+
}
|
|
705
|
+
function runIbgeLookupCommand(input, options, io = { stdout: [], stderr: [] }) {
|
|
706
|
+
const result = lookupMunicipio(input);
|
|
707
|
+
if (!result.ok) {
|
|
708
|
+
return emitLookupFailure3(result, options, io);
|
|
453
709
|
}
|
|
454
710
|
if (options.json) {
|
|
455
711
|
const payload = {
|
|
456
712
|
ok: true,
|
|
457
|
-
municipio
|
|
713
|
+
municipio: result.value
|
|
458
714
|
};
|
|
459
715
|
if (options.verbose) {
|
|
460
716
|
payload.capturadoEm = IBGE_DATA_VERSION.capturadoEm;
|
|
@@ -462,7 +718,7 @@ function runIbgeLookupCommand(input, options, io = { stdout: [], stderr: [] }) {
|
|
|
462
718
|
io.stdout.push(JSON.stringify(payload, null, 2));
|
|
463
719
|
return EXIT.OK;
|
|
464
720
|
}
|
|
465
|
-
io.stdout.push(formatMunicipioHuman(
|
|
721
|
+
io.stdout.push(formatMunicipioHuman(result.value));
|
|
466
722
|
if (options.verbose) {
|
|
467
723
|
io.stdout.push(`capturadoEm: ${IBGE_DATA_VERSION.capturadoEm}`);
|
|
468
724
|
}
|
|
@@ -478,8 +734,8 @@ function runIbgeLookup(value, options, io = { stdout: [], stderr: [] }) {
|
|
|
478
734
|
|
|
479
735
|
// src/commands/ibge/list.ts
|
|
480
736
|
import {
|
|
481
|
-
|
|
482
|
-
|
|
737
|
+
getAllEstados,
|
|
738
|
+
getAllMunicipios,
|
|
483
739
|
IBGE_DATA_VERSION as IBGE_DATA_VERSION2
|
|
484
740
|
} from "@br-validators/core/ibge";
|
|
485
741
|
function sliceRows(rows, limit) {
|
|
@@ -492,7 +748,7 @@ function formatEstadoHuman(estado) {
|
|
|
492
748
|
return `${estado.codigo} \u2014 ${estado.sigla} \u2014 ${estado.nome}`;
|
|
493
749
|
}
|
|
494
750
|
function runIbgeListEstadosCommand(options, io = { stdout: [], stderr: [] }) {
|
|
495
|
-
const estados = sliceRows(
|
|
751
|
+
const estados = sliceRows(getAllEstados(), options.limit);
|
|
496
752
|
if (options.json) {
|
|
497
753
|
const payload = {
|
|
498
754
|
ok: true,
|
|
@@ -515,7 +771,7 @@ function runIbgeListEstadosCommand(options, io = { stdout: [], stderr: [] }) {
|
|
|
515
771
|
}
|
|
516
772
|
function runIbgeListMunicipiosCommand(options, io = { stdout: [], stderr: [] }) {
|
|
517
773
|
const uf = options.uf?.trim().toUpperCase();
|
|
518
|
-
const municipios = sliceRows(
|
|
774
|
+
const municipios = sliceRows(getAllMunicipios(uf ? { uf } : void 0), options.limit);
|
|
519
775
|
if (options.json) {
|
|
520
776
|
const payload = {
|
|
521
777
|
ok: true,
|
|
@@ -547,7 +803,7 @@ function runIbgeList(target, options, io = { stdout: [], stderr: [] }) {
|
|
|
547
803
|
// src/commands/feriados/list.ts
|
|
548
804
|
import {
|
|
549
805
|
FERIADOS_DATA_VERSION,
|
|
550
|
-
|
|
806
|
+
getAllFeriados
|
|
551
807
|
} from "@br-validators/core/feriados";
|
|
552
808
|
function resolveYear(year) {
|
|
553
809
|
if (year !== void 0 && Number.isInteger(year) && year >= 1900 && year <= 2100) {
|
|
@@ -560,7 +816,7 @@ function formatFeriadoHuman(feriado) {
|
|
|
560
816
|
}
|
|
561
817
|
function runFeriadosListCommand(options, io = { stdout: [], stderr: [] }) {
|
|
562
818
|
const year = resolveYear(options.year);
|
|
563
|
-
const feriados =
|
|
819
|
+
const feriados = getAllFeriados(year);
|
|
564
820
|
if (options.json) {
|
|
565
821
|
const payload = {
|
|
566
822
|
ok: true,
|
|
@@ -586,13 +842,193 @@ function runFeriadosList(options, io = { stdout: [], stderr: [] }) {
|
|
|
586
842
|
return runFeriadosListCommand(options, io);
|
|
587
843
|
}
|
|
588
844
|
|
|
845
|
+
// src/commands/inss/index.ts
|
|
846
|
+
import {
|
|
847
|
+
calcularInssMensal,
|
|
848
|
+
getInssTabelaContribuicao,
|
|
849
|
+
INSS_DATA_VERSION,
|
|
850
|
+
INSS_DEFAULT_ANO
|
|
851
|
+
} from "@br-validators/core/inss";
|
|
852
|
+
function resolveAno(ano) {
|
|
853
|
+
if (ano !== void 0 && Number.isInteger(ano) && ano >= 1900 && ano <= 2100) {
|
|
854
|
+
return ano;
|
|
855
|
+
}
|
|
856
|
+
return INSS_DEFAULT_ANO;
|
|
857
|
+
}
|
|
858
|
+
function formatInssFaixaHuman(faixa) {
|
|
859
|
+
const aliquotaPct = `${String(faixa.aliquota * 100).replace(".", ",")}%`;
|
|
860
|
+
return `Faixa ${String(faixa.faixa)} \u2014 ${faixa.descricao} \u2014 ${aliquotaPct}`;
|
|
861
|
+
}
|
|
862
|
+
function runInssTabelaCommand(options, io = { stdout: [], stderr: [] }) {
|
|
863
|
+
const ano = resolveAno(options.ano);
|
|
864
|
+
const tabela = getInssTabelaContribuicao(ano);
|
|
865
|
+
if (tabela === void 0) {
|
|
866
|
+
io.stderr.push(`INSS contribution table not found for year ${String(ano)}`);
|
|
867
|
+
return EXIT.INVALID;
|
|
868
|
+
}
|
|
869
|
+
if (options.json) {
|
|
870
|
+
const payload = {
|
|
871
|
+
ok: true,
|
|
872
|
+
ano,
|
|
873
|
+
teto: tabela.teto,
|
|
874
|
+
faixas: tabela.faixas
|
|
875
|
+
};
|
|
876
|
+
if (options.verbose) {
|
|
877
|
+
payload.capturadoEm = INSS_DATA_VERSION.capturadoEm;
|
|
878
|
+
}
|
|
879
|
+
io.stdout.push(JSON.stringify(payload, null, 2));
|
|
880
|
+
return EXIT.OK;
|
|
881
|
+
}
|
|
882
|
+
io.stdout.push(`Teto: R$ ${tabela.teto.toFixed(2)}`);
|
|
883
|
+
for (const faixa of tabela.faixas) {
|
|
884
|
+
io.stdout.push(formatInssFaixaHuman(faixa));
|
|
885
|
+
}
|
|
886
|
+
if (options.verbose) {
|
|
887
|
+
io.stdout.push(`capturadoEm: ${INSS_DATA_VERSION.capturadoEm}`);
|
|
888
|
+
}
|
|
889
|
+
return EXIT.OK;
|
|
890
|
+
}
|
|
891
|
+
function runInssCalcCommand(salarioRaw, options, io = { stdout: [], stderr: [] }) {
|
|
892
|
+
const trimmed = salarioRaw.trim().replace(",", ".");
|
|
893
|
+
const salarioContribuicao = Number(trimmed);
|
|
894
|
+
if (!Number.isFinite(salarioContribuicao)) {
|
|
895
|
+
io.stderr.push("Invalid sal\xE1rio de contribui\xE7\xE3o. Pass a numeric value (e.g. 3000).");
|
|
896
|
+
return EXIT.USAGE;
|
|
897
|
+
}
|
|
898
|
+
const ano = resolveAno(options.ano);
|
|
899
|
+
const result = calcularInssMensal(salarioContribuicao, ano);
|
|
900
|
+
if (result === void 0) {
|
|
901
|
+
if (getInssTabelaContribuicao(ano) === void 0) {
|
|
902
|
+
io.stderr.push(`INSS contribution table not found for year ${String(ano)}`);
|
|
903
|
+
return EXIT.INVALID;
|
|
904
|
+
}
|
|
905
|
+
io.stderr.push("Sal\xE1rio de contribui\xE7\xE3o must be a non-negative number");
|
|
906
|
+
return EXIT.INVALID;
|
|
907
|
+
}
|
|
908
|
+
if (options.json) {
|
|
909
|
+
const payload = {
|
|
910
|
+
ok: true,
|
|
911
|
+
...result,
|
|
912
|
+
...options.verbose ? { capturadoEm: INSS_DATA_VERSION.capturadoEm } : {}
|
|
913
|
+
};
|
|
914
|
+
io.stdout.push(JSON.stringify(payload, null, 2));
|
|
915
|
+
return EXIT.OK;
|
|
916
|
+
}
|
|
917
|
+
io.stdout.push(
|
|
918
|
+
`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)}`
|
|
919
|
+
);
|
|
920
|
+
if (options.verbose) {
|
|
921
|
+
io.stdout.push(`capturadoEm: ${INSS_DATA_VERSION.capturadoEm}`);
|
|
922
|
+
}
|
|
923
|
+
return EXIT.OK;
|
|
924
|
+
}
|
|
925
|
+
function runInssTabela(options, io = { stdout: [], stderr: [] }) {
|
|
926
|
+
return runInssTabelaCommand(options, io);
|
|
927
|
+
}
|
|
928
|
+
function runInssCalc(salario, options, io = { stdout: [], stderr: [] }) {
|
|
929
|
+
if (!salario?.trim()) {
|
|
930
|
+
io.stderr.push("Missing sal\xE1rio de contribui\xE7\xE3o. Usage: br-validators inss calc <salario>");
|
|
931
|
+
return EXIT.USAGE;
|
|
932
|
+
}
|
|
933
|
+
return runInssCalcCommand(salario.trim(), options, io);
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
// src/commands/irpf/index.ts
|
|
937
|
+
import {
|
|
938
|
+
calcularIrpfMensal,
|
|
939
|
+
getIrpfTabelaProgressiva,
|
|
940
|
+
IRPF_DATA_VERSION,
|
|
941
|
+
IRPF_DEFAULT_ANO
|
|
942
|
+
} from "@br-validators/core/irpf";
|
|
943
|
+
function resolveAno2(ano) {
|
|
944
|
+
if (ano !== void 0 && Number.isInteger(ano) && ano >= 1900 && ano <= 2100) {
|
|
945
|
+
return ano;
|
|
946
|
+
}
|
|
947
|
+
return IRPF_DEFAULT_ANO;
|
|
948
|
+
}
|
|
949
|
+
function formatIrpfFaixaHuman(faixa) {
|
|
950
|
+
const aliquotaPct = `${String(faixa.aliquota * 100).replace(".", ",")}%`;
|
|
951
|
+
return `Faixa ${String(faixa.faixa)} \u2014 ${faixa.descricao} \u2014 ${aliquotaPct} \u2014 deduzir R$ ${faixa.parcelaDeduzir.toFixed(2)}`;
|
|
952
|
+
}
|
|
953
|
+
function runIrpfTabelaCommand(options, io = { stdout: [], stderr: [] }) {
|
|
954
|
+
const ano = resolveAno2(options.ano);
|
|
955
|
+
const faixas = getIrpfTabelaProgressiva(ano);
|
|
956
|
+
if (faixas === void 0) {
|
|
957
|
+
io.stderr.push(`IRPF progressive table not found for year ${String(ano)}`);
|
|
958
|
+
return EXIT.INVALID;
|
|
959
|
+
}
|
|
960
|
+
if (options.json) {
|
|
961
|
+
const payload = {
|
|
962
|
+
ok: true,
|
|
963
|
+
ano,
|
|
964
|
+
faixas
|
|
965
|
+
};
|
|
966
|
+
if (options.verbose) {
|
|
967
|
+
payload.capturadoEm = IRPF_DATA_VERSION.capturadoEm;
|
|
968
|
+
}
|
|
969
|
+
io.stdout.push(JSON.stringify(payload, null, 2));
|
|
970
|
+
return EXIT.OK;
|
|
971
|
+
}
|
|
972
|
+
for (const faixa of faixas) {
|
|
973
|
+
io.stdout.push(formatIrpfFaixaHuman(faixa));
|
|
974
|
+
}
|
|
975
|
+
if (options.verbose) {
|
|
976
|
+
io.stdout.push(`capturadoEm: ${IRPF_DATA_VERSION.capturadoEm}`);
|
|
977
|
+
}
|
|
978
|
+
return EXIT.OK;
|
|
979
|
+
}
|
|
980
|
+
function runIrpfCalcCommand(baseRaw, options, io = { stdout: [], stderr: [] }) {
|
|
981
|
+
const trimmed = baseRaw.trim().replace(",", ".");
|
|
982
|
+
const baseCalculo = Number(trimmed);
|
|
983
|
+
if (!Number.isFinite(baseCalculo)) {
|
|
984
|
+
io.stderr.push("Invalid base de c\xE1lculo. Pass a numeric value (e.g. 3000).");
|
|
985
|
+
return EXIT.USAGE;
|
|
986
|
+
}
|
|
987
|
+
const ano = resolveAno2(options.ano);
|
|
988
|
+
const result = calcularIrpfMensal(baseCalculo, ano);
|
|
989
|
+
if (result === void 0) {
|
|
990
|
+
if (getIrpfTabelaProgressiva(ano) === void 0) {
|
|
991
|
+
io.stderr.push(`IRPF progressive table not found for year ${String(ano)}`);
|
|
992
|
+
return EXIT.INVALID;
|
|
993
|
+
}
|
|
994
|
+
io.stderr.push("Base de c\xE1lculo must be a non-negative number");
|
|
995
|
+
return EXIT.INVALID;
|
|
996
|
+
}
|
|
997
|
+
if (options.json) {
|
|
998
|
+
const payload = {
|
|
999
|
+
ok: true,
|
|
1000
|
+
...result,
|
|
1001
|
+
...options.verbose ? { capturadoEm: IRPF_DATA_VERSION.capturadoEm } : {}
|
|
1002
|
+
};
|
|
1003
|
+
io.stdout.push(JSON.stringify(payload, null, 2));
|
|
1004
|
+
return EXIT.OK;
|
|
1005
|
+
}
|
|
1006
|
+
io.stdout.push(
|
|
1007
|
+
`IRPF ${String(result.ano)} \u2014 base R$ ${result.baseCalculo.toFixed(2)} \u2014 faixa ${String(result.faixa)} \u2014 imposto R$ ${result.imposto.toFixed(2)}`
|
|
1008
|
+
);
|
|
1009
|
+
if (options.verbose) {
|
|
1010
|
+
io.stdout.push(`capturadoEm: ${IRPF_DATA_VERSION.capturadoEm}`);
|
|
1011
|
+
}
|
|
1012
|
+
return EXIT.OK;
|
|
1013
|
+
}
|
|
1014
|
+
function runIrpfTabela(options, io = { stdout: [], stderr: [] }) {
|
|
1015
|
+
return runIrpfTabelaCommand(options, io);
|
|
1016
|
+
}
|
|
1017
|
+
function runIrpfCalc(base, options, io = { stdout: [], stderr: [] }) {
|
|
1018
|
+
if (!base?.trim()) {
|
|
1019
|
+
io.stderr.push("Missing base de c\xE1lculo. Usage: br-validators irpf calc <base>");
|
|
1020
|
+
return EXIT.USAGE;
|
|
1021
|
+
}
|
|
1022
|
+
return runIrpfCalcCommand(base.trim(), options, io);
|
|
1023
|
+
}
|
|
1024
|
+
|
|
589
1025
|
// src/commands/tse-municipios/lookup.ts
|
|
590
1026
|
import {
|
|
591
1027
|
getCodigosTsePorMunicipio,
|
|
592
1028
|
getMunicipioIbgePorCodigoTse,
|
|
593
1029
|
TSE_MUNICIPIOS_DATA_VERSION
|
|
594
1030
|
} from "@br-validators/core/tse-municipios";
|
|
595
|
-
import { getMunicipioPorCodigo
|
|
1031
|
+
import { getMunicipioPorCodigo } from "@br-validators/core/ibge";
|
|
596
1032
|
function normalizeTseInput(raw) {
|
|
597
1033
|
const digits = raw.replace(/\D/g, "");
|
|
598
1034
|
if (digits.length === 5) {
|
|
@@ -623,11 +1059,11 @@ function lookupTseMunicipio(raw) {
|
|
|
623
1059
|
}
|
|
624
1060
|
function formatTseLookupHuman(result) {
|
|
625
1061
|
if (result.kind === "tse-to-ibge") {
|
|
626
|
-
const municipio2 =
|
|
1062
|
+
const municipio2 = getMunicipioPorCodigo(result.ibgeCodigo);
|
|
627
1063
|
const name2 = municipio2 ? `${municipio2.nome} (${municipio2.uf})` : String(result.ibgeCodigo);
|
|
628
1064
|
return `TSE ${result.codigoTse} \u2192 IBGE ${result.ibgeCodigo} \u2014 ${name2}`;
|
|
629
1065
|
}
|
|
630
|
-
const municipio =
|
|
1066
|
+
const municipio = getMunicipioPorCodigo(result.ibgeCodigo);
|
|
631
1067
|
const name = municipio ? `${municipio.nome} (${municipio.uf})` : String(result.ibgeCodigo);
|
|
632
1068
|
return `IBGE ${result.ibgeCodigo} \u2014 ${name} \u2192 TSE ${result.codigosTse.join(", ")}`;
|
|
633
1069
|
}
|
|
@@ -771,6 +1207,228 @@ function runDddLookup(value, options, io = { stdout: [], stderr: [] }) {
|
|
|
771
1207
|
return runDddLookupCommand(value.trim(), options, io);
|
|
772
1208
|
}
|
|
773
1209
|
|
|
1210
|
+
// src/commands/nfe-cuf/lookup.ts
|
|
1211
|
+
import {
|
|
1212
|
+
lookupCufPorCodigo,
|
|
1213
|
+
NFE_CUF_DATA_VERSION
|
|
1214
|
+
} from "@br-validators/core/nfe-cuf";
|
|
1215
|
+
function formatNfeCufHuman(row) {
|
|
1216
|
+
return `cUF ${row.codigo} \u2014 ${row.uf} \u2014 ${row.nome} (IBGE UF ${row.codigoIbge})`;
|
|
1217
|
+
}
|
|
1218
|
+
function runNfeCufLookupCommand(input, options, io = { stdout: [], stderr: [] }) {
|
|
1219
|
+
const trimmed = input.trim();
|
|
1220
|
+
if (trimmed.length === 0) {
|
|
1221
|
+
io.stderr.push("Invalid cUF code. Use 2 digits (e.g. 35).");
|
|
1222
|
+
return EXIT.USAGE;
|
|
1223
|
+
}
|
|
1224
|
+
const result = lookupCufPorCodigo(trimmed);
|
|
1225
|
+
if (!result.ok) {
|
|
1226
|
+
if (options.json) {
|
|
1227
|
+
io.stdout.push(JSON.stringify({ ok: false, code: result.code, message: result.message }, null, 2));
|
|
1228
|
+
return EXIT.INVALID;
|
|
1229
|
+
}
|
|
1230
|
+
io.stderr.push(result.message);
|
|
1231
|
+
return EXIT.INVALID;
|
|
1232
|
+
}
|
|
1233
|
+
if (options.json) {
|
|
1234
|
+
const payload = {
|
|
1235
|
+
ok: true,
|
|
1236
|
+
cuf: result.value
|
|
1237
|
+
};
|
|
1238
|
+
if (options.verbose) {
|
|
1239
|
+
payload.capturadoEm = NFE_CUF_DATA_VERSION.capturadoEm;
|
|
1240
|
+
}
|
|
1241
|
+
io.stdout.push(JSON.stringify(payload, null, 2));
|
|
1242
|
+
return EXIT.OK;
|
|
1243
|
+
}
|
|
1244
|
+
io.stdout.push(formatNfeCufHuman(result.value));
|
|
1245
|
+
if (options.verbose) {
|
|
1246
|
+
io.stdout.push(`capturadoEm: ${NFE_CUF_DATA_VERSION.capturadoEm}`);
|
|
1247
|
+
}
|
|
1248
|
+
return EXIT.OK;
|
|
1249
|
+
}
|
|
1250
|
+
function runNfeCufLookup(value, options, io = { stdout: [], stderr: [] }) {
|
|
1251
|
+
if (!value?.trim()) {
|
|
1252
|
+
io.stderr.push("Missing cUF code. Usage: br-validators nfe-cuf lookup <code>");
|
|
1253
|
+
return EXIT.USAGE;
|
|
1254
|
+
}
|
|
1255
|
+
return runNfeCufLookupCommand(value.trim(), options, io);
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
// src/commands/selic/index.ts
|
|
1259
|
+
import {
|
|
1260
|
+
getSelicMeta,
|
|
1261
|
+
getSelicMetaPorData,
|
|
1262
|
+
SELIC_DATA_VERSION
|
|
1263
|
+
} from "@br-validators/core/selic";
|
|
1264
|
+
function formatSelicMetaHuman(meta) {
|
|
1265
|
+
return `SELIC meta ${meta.dataReferencia} \u2014 ${String(meta.valor)}% a.a.`;
|
|
1266
|
+
}
|
|
1267
|
+
function runSelicCommand(options, io = { stdout: [], stderr: [] }) {
|
|
1268
|
+
const meta = options.date === void 0 || options.date.trim().length === 0 ? getSelicMeta() : getSelicMetaPorData(options.date.trim());
|
|
1269
|
+
if (meta === void 0) {
|
|
1270
|
+
io.stderr.push(
|
|
1271
|
+
options.date ? `SELIC meta not found for date ${options.date}` : "SELIC meta series is empty"
|
|
1272
|
+
);
|
|
1273
|
+
return EXIT.INVALID;
|
|
1274
|
+
}
|
|
1275
|
+
if (options.json) {
|
|
1276
|
+
const payload = {
|
|
1277
|
+
ok: true,
|
|
1278
|
+
meta
|
|
1279
|
+
};
|
|
1280
|
+
if (options.verbose) {
|
|
1281
|
+
payload.capturadoEm = SELIC_DATA_VERSION.capturadoEm;
|
|
1282
|
+
}
|
|
1283
|
+
io.stdout.push(JSON.stringify(payload, null, 2));
|
|
1284
|
+
return EXIT.OK;
|
|
1285
|
+
}
|
|
1286
|
+
io.stdout.push(formatSelicMetaHuman(meta));
|
|
1287
|
+
if (options.verbose) {
|
|
1288
|
+
io.stdout.push(`dataReferencia: ${meta.dataReferencia}`);
|
|
1289
|
+
io.stdout.push(`isStale: ${String(meta.isStale)}`);
|
|
1290
|
+
if (meta.warning !== void 0) {
|
|
1291
|
+
io.stdout.push(`warning: ${meta.warning}`);
|
|
1292
|
+
}
|
|
1293
|
+
io.stdout.push(`capturadoEm: ${SELIC_DATA_VERSION.capturadoEm}`);
|
|
1294
|
+
}
|
|
1295
|
+
return EXIT.OK;
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
// src/commands/iss-municipal/index.ts
|
|
1299
|
+
import {
|
|
1300
|
+
getIssMunicipalPorIbge,
|
|
1301
|
+
getIssMunicipalPorUfMunicipio,
|
|
1302
|
+
ISS_MUNICIPAL_DATA_VERSION,
|
|
1303
|
+
ISS_MUNICIPAL_ESTIMATION_WARNING,
|
|
1304
|
+
searchIssMunicipal
|
|
1305
|
+
} from "@br-validators/core/iss-municipal";
|
|
1306
|
+
function formatIssMunicipalHuman(row) {
|
|
1307
|
+
return `${row.nome}/${row.uf} \u2014 ISS ${String(row.aliquotaMin)}%\u2013${String(row.aliquotaMax)}%`;
|
|
1308
|
+
}
|
|
1309
|
+
function emitDisclaimer(options, io) {
|
|
1310
|
+
if (options.json) {
|
|
1311
|
+
return;
|
|
1312
|
+
}
|
|
1313
|
+
io.stderr.push(ISS_MUNICIPAL_ESTIMATION_WARNING);
|
|
1314
|
+
}
|
|
1315
|
+
function runIssMunicipalLookup(codigo, options, io = { stdout: [], stderr: [] }) {
|
|
1316
|
+
const trimmed = codigo?.trim() ?? "";
|
|
1317
|
+
if (trimmed.length === 0) {
|
|
1318
|
+
io.stderr.push("Missing IBGE code. Usage: br-validators iss-municipal lookup <codigoIbge>");
|
|
1319
|
+
return EXIT.USAGE;
|
|
1320
|
+
}
|
|
1321
|
+
const result = getIssMunicipalPorIbge(trimmed);
|
|
1322
|
+
if (result === void 0) {
|
|
1323
|
+
io.stderr.push(`ISS municipal row not found for IBGE code ${trimmed}`);
|
|
1324
|
+
return EXIT.INVALID;
|
|
1325
|
+
}
|
|
1326
|
+
emitDisclaimer(options, io);
|
|
1327
|
+
if (options.json) {
|
|
1328
|
+
const payload = {
|
|
1329
|
+
ok: true,
|
|
1330
|
+
iss: result
|
|
1331
|
+
};
|
|
1332
|
+
if (options.verbose) {
|
|
1333
|
+
payload.capturadoEm = ISS_MUNICIPAL_DATA_VERSION.capturadoEm;
|
|
1334
|
+
}
|
|
1335
|
+
io.stdout.push(JSON.stringify(payload, null, 2));
|
|
1336
|
+
return EXIT.OK;
|
|
1337
|
+
}
|
|
1338
|
+
io.stdout.push(formatIssMunicipalHuman(result));
|
|
1339
|
+
io.stdout.push(`warning: ${result.warning}`);
|
|
1340
|
+
if (options.verbose) {
|
|
1341
|
+
io.stdout.push(`leiUrl: ${result.leiUrl}`);
|
|
1342
|
+
io.stdout.push(`estimativa: ${String(result.estimativa)}`);
|
|
1343
|
+
io.stdout.push(`capturadoEm: ${ISS_MUNICIPAL_DATA_VERSION.capturadoEm}`);
|
|
1344
|
+
}
|
|
1345
|
+
return EXIT.OK;
|
|
1346
|
+
}
|
|
1347
|
+
function runIssMunicipalSearch(query, options, io = { stdout: [], stderr: [] }) {
|
|
1348
|
+
const trimmed = query?.trim() ?? "";
|
|
1349
|
+
if (trimmed.length === 0) {
|
|
1350
|
+
io.stderr.push("Missing query. Usage: br-validators iss-municipal search <query>");
|
|
1351
|
+
return EXIT.USAGE;
|
|
1352
|
+
}
|
|
1353
|
+
const rows = searchIssMunicipal(trimmed, { limit: options.limit });
|
|
1354
|
+
emitDisclaimer(options, io);
|
|
1355
|
+
if (options.json) {
|
|
1356
|
+
io.stdout.push(JSON.stringify({ ok: true, results: rows }, null, 2));
|
|
1357
|
+
return EXIT.OK;
|
|
1358
|
+
}
|
|
1359
|
+
if (rows.length === 0) {
|
|
1360
|
+
io.stdout.push("No ISS municipal rows matched.");
|
|
1361
|
+
return EXIT.OK;
|
|
1362
|
+
}
|
|
1363
|
+
for (const row of rows) {
|
|
1364
|
+
io.stdout.push(formatIssMunicipalHuman(row));
|
|
1365
|
+
}
|
|
1366
|
+
return EXIT.OK;
|
|
1367
|
+
}
|
|
1368
|
+
function runIssMunicipalResolve(uf, nome, options, io = { stdout: [], stderr: [] }) {
|
|
1369
|
+
const normalizedUf = uf?.trim() ?? "";
|
|
1370
|
+
const normalizedNome = nome?.trim() ?? "";
|
|
1371
|
+
if (normalizedUf.length === 0 || normalizedNome.length === 0) {
|
|
1372
|
+
io.stderr.push("Missing UF or municipality name. Usage: br-validators iss-municipal resolve <uf> <nome>");
|
|
1373
|
+
return EXIT.USAGE;
|
|
1374
|
+
}
|
|
1375
|
+
const result = getIssMunicipalPorUfMunicipio(normalizedUf, normalizedNome);
|
|
1376
|
+
if (result === void 0) {
|
|
1377
|
+
io.stderr.push(`ISS municipal row not found for ${normalizedNome}/${normalizedUf}`);
|
|
1378
|
+
return EXIT.INVALID;
|
|
1379
|
+
}
|
|
1380
|
+
return runIssMunicipalLookup(String(result.codigoIbge), options, io);
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
// src/commands/ptax/lookup.ts
|
|
1384
|
+
import {
|
|
1385
|
+
getPtaxCotacao,
|
|
1386
|
+
PTAX_DATA_VERSION
|
|
1387
|
+
} from "@br-validators/core/ptax";
|
|
1388
|
+
function formatPtaxCotacaoHuman(cotacao) {
|
|
1389
|
+
return `${cotacao.moeda} Fechamento PTAX \u2014 compra ${String(cotacao.cotacaoCompra)} / venda ${String(cotacao.cotacaoVenda)} (${cotacao.dataReferencia})`;
|
|
1390
|
+
}
|
|
1391
|
+
function runPtaxLookupCommand(moeda, data, options, io = { stdout: [], stderr: [] }) {
|
|
1392
|
+
const trimmedMoeda = moeda.trim();
|
|
1393
|
+
if (trimmedMoeda.length === 0) {
|
|
1394
|
+
io.stderr.push("Missing currency code. Pass a 3-letter ISO code (e.g. USD).");
|
|
1395
|
+
return EXIT.USAGE;
|
|
1396
|
+
}
|
|
1397
|
+
const cotacao = data === void 0 || data.trim().length === 0 ? getPtaxCotacao(trimmedMoeda) : getPtaxCotacao(trimmedMoeda, data.trim());
|
|
1398
|
+
if (cotacao === void 0) {
|
|
1399
|
+
io.stderr.push(`PTAX quote not found: ${trimmedMoeda}${data ? ` ${data}` : ""}`);
|
|
1400
|
+
return EXIT.INVALID;
|
|
1401
|
+
}
|
|
1402
|
+
if (options.json) {
|
|
1403
|
+
const payload = {
|
|
1404
|
+
ok: true,
|
|
1405
|
+
cotacao
|
|
1406
|
+
};
|
|
1407
|
+
if (options.verbose) {
|
|
1408
|
+
payload.capturadoEm = PTAX_DATA_VERSION.capturadoEm;
|
|
1409
|
+
}
|
|
1410
|
+
io.stdout.push(JSON.stringify(payload, null, 2));
|
|
1411
|
+
return EXIT.OK;
|
|
1412
|
+
}
|
|
1413
|
+
io.stdout.push(formatPtaxCotacaoHuman(cotacao));
|
|
1414
|
+
if (options.verbose) {
|
|
1415
|
+
io.stdout.push(`dataReferencia: ${cotacao.dataReferencia}`);
|
|
1416
|
+
io.stdout.push(`isStale: ${String(cotacao.isStale)}`);
|
|
1417
|
+
if (cotacao.warning !== void 0) {
|
|
1418
|
+
io.stdout.push(`warning: ${cotacao.warning}`);
|
|
1419
|
+
}
|
|
1420
|
+
io.stdout.push(`capturadoEm: ${PTAX_DATA_VERSION.capturadoEm}`);
|
|
1421
|
+
}
|
|
1422
|
+
return EXIT.OK;
|
|
1423
|
+
}
|
|
1424
|
+
function runPtaxLookup(moeda, data, options, io = { stdout: [], stderr: [] }) {
|
|
1425
|
+
if (!moeda?.trim()) {
|
|
1426
|
+
io.stderr.push("Missing currency code. Usage: ptax lookup <moeda> [data]");
|
|
1427
|
+
return EXIT.USAGE;
|
|
1428
|
+
}
|
|
1429
|
+
return runPtaxLookupCommand(moeda.trim(), data?.trim(), options, io);
|
|
1430
|
+
}
|
|
1431
|
+
|
|
774
1432
|
// src/commands/brcode.ts
|
|
775
1433
|
import {
|
|
776
1434
|
BRCODE_OFFICIAL_SOURCE_URL,
|
|
@@ -2288,6 +2946,184 @@ function runSanitize(type, value, options, io = { stdout: [], stderr: [] }) {
|
|
|
2288
2946
|
return printSanitize(result, options, io);
|
|
2289
2947
|
}
|
|
2290
2948
|
|
|
2949
|
+
// src/commands/mask.ts
|
|
2950
|
+
import { isMaskableDocumentType, maskRuntime } from "@br-validators/core";
|
|
2951
|
+
function resolveInput22(value, fileContent) {
|
|
2952
|
+
const input = value ?? fileContent?.trim();
|
|
2953
|
+
if (!input) {
|
|
2954
|
+
return null;
|
|
2955
|
+
}
|
|
2956
|
+
return input;
|
|
2957
|
+
}
|
|
2958
|
+
function runMask(type, value, options, io = { stdout: [], stderr: [] }) {
|
|
2959
|
+
if (!isMaskableDocumentType(type)) {
|
|
2960
|
+
io.stderr.push(`Unsupported mask type: ${type}`);
|
|
2961
|
+
return EXIT.USAGE;
|
|
2962
|
+
}
|
|
2963
|
+
const input = resolveInput22(value, options.file);
|
|
2964
|
+
if (input === null) {
|
|
2965
|
+
io.stderr.push("Missing value. Pass an argument or use --file.");
|
|
2966
|
+
return EXIT.USAGE;
|
|
2967
|
+
}
|
|
2968
|
+
const uf = options.uf?.toUpperCase();
|
|
2969
|
+
const result = maskRuntime(type, input, uf ? { uf } : {});
|
|
2970
|
+
return printFormat(result, options, io);
|
|
2971
|
+
}
|
|
2972
|
+
|
|
2973
|
+
// src/commands/compare.ts
|
|
2974
|
+
import { compareRuntime } from "@br-validators/core";
|
|
2975
|
+
|
|
2976
|
+
// src/commands/platform-document-types.ts
|
|
2977
|
+
var PLATFORM_DOCUMENT_TYPES = [
|
|
2978
|
+
"cpf",
|
|
2979
|
+
"cnpj",
|
|
2980
|
+
"cep",
|
|
2981
|
+
"placa",
|
|
2982
|
+
"pis-pasep",
|
|
2983
|
+
"telefone",
|
|
2984
|
+
"cnh",
|
|
2985
|
+
"renavam",
|
|
2986
|
+
"titulo-eleitor",
|
|
2987
|
+
"processo-judicial",
|
|
2988
|
+
"rg",
|
|
2989
|
+
"nfe-chave",
|
|
2990
|
+
"boleto",
|
|
2991
|
+
"cartao-credito",
|
|
2992
|
+
"ean",
|
|
2993
|
+
"inscricao-estadual",
|
|
2994
|
+
"inscricao-estadual-produtor-rural",
|
|
2995
|
+
"pix",
|
|
2996
|
+
"brcode"
|
|
2997
|
+
];
|
|
2998
|
+
function isPlatformDocumentType(type) {
|
|
2999
|
+
return PLATFORM_DOCUMENT_TYPES.includes(type);
|
|
3000
|
+
}
|
|
3001
|
+
|
|
3002
|
+
// src/commands/compare.ts
|
|
3003
|
+
function printCompare(result, options, io = { stdout: [], stderr: [] }) {
|
|
3004
|
+
if (options.json) {
|
|
3005
|
+
io.stdout.push(JSON.stringify(result, null, 2));
|
|
3006
|
+
if ("code" in result) {
|
|
3007
|
+
return EXIT.USAGE;
|
|
3008
|
+
}
|
|
3009
|
+
return result.equal ? EXIT.OK : EXIT.INVALID;
|
|
3010
|
+
}
|
|
3011
|
+
if (options.quiet) {
|
|
3012
|
+
if ("code" in result) {
|
|
3013
|
+
return EXIT.USAGE;
|
|
3014
|
+
}
|
|
3015
|
+
return result.equal ? EXIT.OK : EXIT.INVALID;
|
|
3016
|
+
}
|
|
3017
|
+
if ("code" in result) {
|
|
3018
|
+
io.stderr.push(`code: ${result.code}`);
|
|
3019
|
+
io.stderr.push(`message: ${result.message}`);
|
|
3020
|
+
return EXIT.USAGE;
|
|
3021
|
+
}
|
|
3022
|
+
io.stdout.push(`equal: ${result.equal ? "yes" : "no"}`);
|
|
3023
|
+
return result.equal ? EXIT.OK : EXIT.INVALID;
|
|
3024
|
+
}
|
|
3025
|
+
function runCompare(type, valueA, valueB, options, io = { stdout: [], stderr: [] }) {
|
|
3026
|
+
if (!isPlatformDocumentType(type)) {
|
|
3027
|
+
io.stderr.push(`Unsupported compare type: ${type}`);
|
|
3028
|
+
return EXIT.USAGE;
|
|
3029
|
+
}
|
|
3030
|
+
if (!valueA || !valueB) {
|
|
3031
|
+
io.stderr.push("Missing values. Usage: compare <type> <valueA> <valueB>");
|
|
3032
|
+
return EXIT.USAGE;
|
|
3033
|
+
}
|
|
3034
|
+
const uf = options.uf?.toUpperCase();
|
|
3035
|
+
const platformOptions = uf ? { uf } : {};
|
|
3036
|
+
const result = compareRuntime(valueA, valueB, type, platformOptions);
|
|
3037
|
+
return printCompare(result, options, io);
|
|
3038
|
+
}
|
|
3039
|
+
|
|
3040
|
+
// src/commands/batch.ts
|
|
3041
|
+
import { batch } from "@br-validators/core";
|
|
3042
|
+
function parseBatchLines(raw) {
|
|
3043
|
+
return raw.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0);
|
|
3044
|
+
}
|
|
3045
|
+
function resolveBatchInputs(options) {
|
|
3046
|
+
if (options.lines === void 0) {
|
|
3047
|
+
return null;
|
|
3048
|
+
}
|
|
3049
|
+
const parsed = parseBatchLines(options.lines);
|
|
3050
|
+
if (options.limit !== void 0 && options.limit > 0) {
|
|
3051
|
+
return parsed.slice(0, options.limit);
|
|
3052
|
+
}
|
|
3053
|
+
return parsed;
|
|
3054
|
+
}
|
|
3055
|
+
function printBatch(result, options, io = { stdout: [], stderr: [] }) {
|
|
3056
|
+
if (options.json) {
|
|
3057
|
+
io.stdout.push(JSON.stringify(result, null, 2));
|
|
3058
|
+
return result.summary.invalid === 0 ? EXIT.OK : EXIT.INVALID;
|
|
3059
|
+
}
|
|
3060
|
+
if (options.quiet) {
|
|
3061
|
+
return result.summary.invalid === 0 ? EXIT.OK : EXIT.INVALID;
|
|
3062
|
+
}
|
|
3063
|
+
io.stdout.push(`total: ${String(result.summary.total)}`);
|
|
3064
|
+
io.stdout.push(`valid: ${String(result.summary.valid)}`);
|
|
3065
|
+
io.stdout.push(`invalid: ${String(result.summary.invalid)}`);
|
|
3066
|
+
for (const entry of result.valid) {
|
|
3067
|
+
io.stdout.push(`ok[${String(entry.index)}]: ${entry.value}`);
|
|
3068
|
+
}
|
|
3069
|
+
for (const entry of result.invalid) {
|
|
3070
|
+
io.stderr.push(`fail[${String(entry.index)}]: ${entry.code} \u2014 ${entry.message}`);
|
|
3071
|
+
}
|
|
3072
|
+
return result.summary.invalid === 0 ? EXIT.OK : EXIT.INVALID;
|
|
3073
|
+
}
|
|
3074
|
+
function runBatch(type, options, io = { stdout: [], stderr: [] }) {
|
|
3075
|
+
if (!isPlatformDocumentType(type)) {
|
|
3076
|
+
io.stderr.push(`Unsupported batch type: ${type}`);
|
|
3077
|
+
return EXIT.USAGE;
|
|
3078
|
+
}
|
|
3079
|
+
const inputs = resolveBatchInputs(options);
|
|
3080
|
+
if (inputs === null) {
|
|
3081
|
+
io.stderr.push("Missing input. Pass --file <path> or pipe one value per line on stdin.");
|
|
3082
|
+
return EXIT.USAGE;
|
|
3083
|
+
}
|
|
3084
|
+
if (inputs.length === 0) {
|
|
3085
|
+
io.stderr.push("No values to validate.");
|
|
3086
|
+
return EXIT.USAGE;
|
|
3087
|
+
}
|
|
3088
|
+
const uf = options.uf?.toUpperCase();
|
|
3089
|
+
const platformOptions = uf ? { uf } : {};
|
|
3090
|
+
const result = batch(inputs, type, platformOptions);
|
|
3091
|
+
return printBatch(result, options, io);
|
|
3092
|
+
}
|
|
3093
|
+
|
|
3094
|
+
// src/commands/diff.ts
|
|
3095
|
+
import { diff } from "@br-validators/core";
|
|
3096
|
+
function printDiff(result, options, io = { stdout: [], stderr: [] }) {
|
|
3097
|
+
if (options.json) {
|
|
3098
|
+
io.stdout.push(JSON.stringify(result, null, 2));
|
|
3099
|
+
return result.changed ? EXIT.INVALID : EXIT.OK;
|
|
3100
|
+
}
|
|
3101
|
+
if (options.quiet) {
|
|
3102
|
+
return result.changed ? EXIT.INVALID : EXIT.OK;
|
|
3103
|
+
}
|
|
3104
|
+
io.stdout.push(`changed: ${result.changed ? "yes" : "no"}`);
|
|
3105
|
+
for (const field of result.fields) {
|
|
3106
|
+
io.stdout.push(`field: ${field.field}`);
|
|
3107
|
+
io.stdout.push(` a: ${field.a}`);
|
|
3108
|
+
io.stdout.push(` b: ${field.b}`);
|
|
3109
|
+
}
|
|
3110
|
+
return result.changed ? EXIT.INVALID : EXIT.OK;
|
|
3111
|
+
}
|
|
3112
|
+
function runDiff(type, valueA, valueB, options, io = { stdout: [], stderr: [] }) {
|
|
3113
|
+
if (!isPlatformDocumentType(type)) {
|
|
3114
|
+
io.stderr.push(`Unsupported diff type: ${type}`);
|
|
3115
|
+
return EXIT.USAGE;
|
|
3116
|
+
}
|
|
3117
|
+
if (!valueA || !valueB) {
|
|
3118
|
+
io.stderr.push("Missing values. Usage: diff <type> <valueA> <valueB>");
|
|
3119
|
+
return EXIT.USAGE;
|
|
3120
|
+
}
|
|
3121
|
+
const uf = options.uf?.toUpperCase();
|
|
3122
|
+
const platformOptions = uf ? { uf } : {};
|
|
3123
|
+
const result = diff(valueA, valueB, type, platformOptions);
|
|
3124
|
+
return printDiff(result, options, io);
|
|
3125
|
+
}
|
|
3126
|
+
|
|
2291
3127
|
// src/commands/generate.ts
|
|
2292
3128
|
import { generate, isGeneratableCardBrand } from "@br-validators/core";
|
|
2293
3129
|
var GENERATABLE_TYPES = [
|
|
@@ -2317,6 +3153,9 @@ function buildGenerateOptions(options) {
|
|
|
2317
3153
|
if (options.masked) {
|
|
2318
3154
|
core.masked = true;
|
|
2319
3155
|
}
|
|
3156
|
+
if (options.stripped) {
|
|
3157
|
+
core.stripped = true;
|
|
3158
|
+
}
|
|
2320
3159
|
if (options.seed !== void 0) {
|
|
2321
3160
|
core.seed = options.seed;
|
|
2322
3161
|
}
|
|
@@ -2360,10 +3199,14 @@ function listSupportedTypes(io = { stdout: [] }) {
|
|
|
2360
3199
|
}
|
|
2361
3200
|
|
|
2362
3201
|
// src/handlers.ts
|
|
3202
|
+
var nodeRequire = createRequire(import.meta.url);
|
|
3203
|
+
function readNodeFileSync(path, encoding) {
|
|
3204
|
+
const fs = nodeRequire("node:fs");
|
|
3205
|
+
return fs.readFileSync(path, encoding);
|
|
3206
|
+
}
|
|
2363
3207
|
function readInputFile(path, io) {
|
|
2364
3208
|
try {
|
|
2365
|
-
|
|
2366
|
-
return fsModule.readFileSync(path, "utf8");
|
|
3209
|
+
return readNodeFileSync(path, "utf8");
|
|
2367
3210
|
} catch {
|
|
2368
3211
|
io.stderr.push(`Cannot read file: ${path}`);
|
|
2369
3212
|
return null;
|
|
@@ -2840,6 +3683,90 @@ function handleSanitizeCli(type, value, opts, io = { stdout: [], stderr: [] }) {
|
|
|
2840
3683
|
io
|
|
2841
3684
|
);
|
|
2842
3685
|
}
|
|
3686
|
+
function handleMaskCli(type, value, opts, io = { stdout: [], stderr: [] }) {
|
|
3687
|
+
let fileContent;
|
|
3688
|
+
if (opts.file) {
|
|
3689
|
+
const content = readInputFile(opts.file, io);
|
|
3690
|
+
if (content === null) {
|
|
3691
|
+
return EXIT.USAGE;
|
|
3692
|
+
}
|
|
3693
|
+
fileContent = content;
|
|
3694
|
+
}
|
|
3695
|
+
return runMask(
|
|
3696
|
+
type,
|
|
3697
|
+
value,
|
|
3698
|
+
{
|
|
3699
|
+
json: Boolean(opts.json),
|
|
3700
|
+
quiet: Boolean(opts.quiet),
|
|
3701
|
+
uf: opts.uf,
|
|
3702
|
+
file: fileContent
|
|
3703
|
+
},
|
|
3704
|
+
io
|
|
3705
|
+
);
|
|
3706
|
+
}
|
|
3707
|
+
function readStdinSync(io) {
|
|
3708
|
+
try {
|
|
3709
|
+
if (process.stdin.isTTY) {
|
|
3710
|
+
return null;
|
|
3711
|
+
}
|
|
3712
|
+
return readNodeFileSync(0, "utf8");
|
|
3713
|
+
} catch {
|
|
3714
|
+
io.stderr.push("Cannot read stdin.");
|
|
3715
|
+
return null;
|
|
3716
|
+
}
|
|
3717
|
+
}
|
|
3718
|
+
function handleCompareCli(type, valueA, valueB, opts, io = { stdout: [], stderr: [] }) {
|
|
3719
|
+
return runCompare(
|
|
3720
|
+
type,
|
|
3721
|
+
valueA,
|
|
3722
|
+
valueB,
|
|
3723
|
+
{
|
|
3724
|
+
json: Boolean(opts.json),
|
|
3725
|
+
quiet: Boolean(opts.quiet),
|
|
3726
|
+
uf: opts.uf
|
|
3727
|
+
},
|
|
3728
|
+
io
|
|
3729
|
+
);
|
|
3730
|
+
}
|
|
3731
|
+
function handleDiffCli(type, valueA, valueB, opts, io = { stdout: [], stderr: [] }) {
|
|
3732
|
+
return runDiff(
|
|
3733
|
+
type,
|
|
3734
|
+
valueA,
|
|
3735
|
+
valueB,
|
|
3736
|
+
{
|
|
3737
|
+
json: Boolean(opts.json),
|
|
3738
|
+
quiet: Boolean(opts.quiet),
|
|
3739
|
+
uf: opts.uf
|
|
3740
|
+
},
|
|
3741
|
+
io
|
|
3742
|
+
);
|
|
3743
|
+
}
|
|
3744
|
+
function handleBatchCli(type, opts, io = { stdout: [], stderr: [] }) {
|
|
3745
|
+
let lines;
|
|
3746
|
+
if (opts.file) {
|
|
3747
|
+
const content = readInputFile(opts.file, io);
|
|
3748
|
+
if (content === null) {
|
|
3749
|
+
return EXIT.USAGE;
|
|
3750
|
+
}
|
|
3751
|
+
lines = content;
|
|
3752
|
+
} else {
|
|
3753
|
+
const stdin = readStdinSync(io);
|
|
3754
|
+
if (stdin !== null) {
|
|
3755
|
+
lines = stdin;
|
|
3756
|
+
}
|
|
3757
|
+
}
|
|
3758
|
+
return runBatch(
|
|
3759
|
+
type,
|
|
3760
|
+
{
|
|
3761
|
+
json: Boolean(opts.json),
|
|
3762
|
+
quiet: Boolean(opts.quiet),
|
|
3763
|
+
uf: opts.uf,
|
|
3764
|
+
lines,
|
|
3765
|
+
limit: opts.limit
|
|
3766
|
+
},
|
|
3767
|
+
io
|
|
3768
|
+
);
|
|
3769
|
+
}
|
|
2843
3770
|
function handleGenerateCli(type, opts, io = { stdout: [], stderr: [] }) {
|
|
2844
3771
|
return runGenerate(
|
|
2845
3772
|
type,
|
|
@@ -2847,6 +3774,7 @@ function handleGenerateCli(type, opts, io = { stdout: [], stderr: [] }) {
|
|
|
2847
3774
|
json: Boolean(opts.json),
|
|
2848
3775
|
quiet: Boolean(opts.quiet),
|
|
2849
3776
|
masked: Boolean(opts.masked),
|
|
3777
|
+
stripped: Boolean(opts.stripped),
|
|
2850
3778
|
format: opts.format,
|
|
2851
3779
|
seed: opts.seed,
|
|
2852
3780
|
uf: opts.uf,
|
|
@@ -2898,6 +3826,39 @@ function handleReferenceSearchCli(command, query, opts, io = { stdout: [], stder
|
|
|
2898
3826
|
io
|
|
2899
3827
|
);
|
|
2900
3828
|
}
|
|
3829
|
+
function handleReferenceValidateCli(command, value, opts, io = { stdout: [], stderr: [] }) {
|
|
3830
|
+
return runReferenceValidate(
|
|
3831
|
+
command,
|
|
3832
|
+
value,
|
|
3833
|
+
{
|
|
3834
|
+
json: Boolean(opts.json),
|
|
3835
|
+
verbose: Boolean(opts.verbose)
|
|
3836
|
+
},
|
|
3837
|
+
io
|
|
3838
|
+
);
|
|
3839
|
+
}
|
|
3840
|
+
function handleCstLookupCli(value, opts, io = { stdout: [], stderr: [] }) {
|
|
3841
|
+
return runCstLookup(value, {
|
|
3842
|
+
json: Boolean(opts.json),
|
|
3843
|
+
verbose: Boolean(opts.verbose),
|
|
3844
|
+
tax: opts.tax
|
|
3845
|
+
}, io);
|
|
3846
|
+
}
|
|
3847
|
+
function handleCstSearchCli(query, opts, io = { stdout: [], stderr: [] }) {
|
|
3848
|
+
return runCstSearch(query, {
|
|
3849
|
+
json: Boolean(opts.json),
|
|
3850
|
+
verbose: Boolean(opts.verbose),
|
|
3851
|
+
tax: opts.tax,
|
|
3852
|
+
limit: opts.limit
|
|
3853
|
+
}, io);
|
|
3854
|
+
}
|
|
3855
|
+
function handleCstValidateCli(value, opts, io = { stdout: [], stderr: [] }) {
|
|
3856
|
+
return runCstValidate(value, {
|
|
3857
|
+
json: Boolean(opts.json),
|
|
3858
|
+
verbose: Boolean(opts.verbose),
|
|
3859
|
+
tax: opts.tax
|
|
3860
|
+
}, io);
|
|
3861
|
+
}
|
|
2901
3862
|
function handleIbgeLookupCli(value, opts, io = { stdout: [], stderr: [] }) {
|
|
2902
3863
|
return runIbgeLookup(value, { json: Boolean(opts.json), verbose: Boolean(opts.verbose) }, io);
|
|
2903
3864
|
}
|
|
@@ -2916,6 +3877,34 @@ function handleFeriadosListCli(opts, io = { stdout: [], stderr: [] }) {
|
|
|
2916
3877
|
year: opts.year
|
|
2917
3878
|
}, io);
|
|
2918
3879
|
}
|
|
3880
|
+
function handleInssTabelaCli(opts, io = { stdout: [], stderr: [] }) {
|
|
3881
|
+
return runInssTabela({
|
|
3882
|
+
json: Boolean(opts.json),
|
|
3883
|
+
verbose: Boolean(opts.verbose),
|
|
3884
|
+
ano: opts.year
|
|
3885
|
+
}, io);
|
|
3886
|
+
}
|
|
3887
|
+
function handleInssCalcCli(value, opts, io = { stdout: [], stderr: [] }) {
|
|
3888
|
+
return runInssCalc(value, {
|
|
3889
|
+
json: Boolean(opts.json),
|
|
3890
|
+
verbose: Boolean(opts.verbose),
|
|
3891
|
+
ano: opts.year
|
|
3892
|
+
}, io);
|
|
3893
|
+
}
|
|
3894
|
+
function handleIrpfTabelaCli(opts, io = { stdout: [], stderr: [] }) {
|
|
3895
|
+
return runIrpfTabela({
|
|
3896
|
+
json: Boolean(opts.json),
|
|
3897
|
+
verbose: Boolean(opts.verbose),
|
|
3898
|
+
ano: opts.year
|
|
3899
|
+
}, io);
|
|
3900
|
+
}
|
|
3901
|
+
function handleIrpfCalcCli(value, opts, io = { stdout: [], stderr: [] }) {
|
|
3902
|
+
return runIrpfCalc(value, {
|
|
3903
|
+
json: Boolean(opts.json),
|
|
3904
|
+
verbose: Boolean(opts.verbose),
|
|
3905
|
+
ano: opts.year
|
|
3906
|
+
}, io);
|
|
3907
|
+
}
|
|
2919
3908
|
function handleTseMunicipiosLookupCli(value, opts, io = { stdout: [], stderr: [] }) {
|
|
2920
3909
|
return runTseMunicipiosLookup(value, { json: Boolean(opts.json), verbose: Boolean(opts.verbose) }, io);
|
|
2921
3910
|
}
|
|
@@ -2925,6 +3914,32 @@ function handleCepFaixaCli(value, opts, io = { stdout: [], stderr: [] }) {
|
|
|
2925
3914
|
function handleDddLookupCli(value, opts, io = { stdout: [], stderr: [] }) {
|
|
2926
3915
|
return runDddLookup(value, { json: Boolean(opts.json), verbose: Boolean(opts.verbose) }, io);
|
|
2927
3916
|
}
|
|
3917
|
+
function handleNfeCufLookupCli(value, opts, io = { stdout: [], stderr: [] }) {
|
|
3918
|
+
return runNfeCufLookup(value, { json: Boolean(opts.json), verbose: Boolean(opts.verbose) }, io);
|
|
3919
|
+
}
|
|
3920
|
+
function handleSelicCli(opts, io = { stdout: [], stderr: [] }) {
|
|
3921
|
+
return runSelicCommand({
|
|
3922
|
+
json: Boolean(opts.json),
|
|
3923
|
+
verbose: Boolean(opts.verbose),
|
|
3924
|
+
date: opts.date
|
|
3925
|
+
}, io);
|
|
3926
|
+
}
|
|
3927
|
+
function handleIssMunicipalLookupCli(codigo, opts, io = { stdout: [], stderr: [] }) {
|
|
3928
|
+
return runIssMunicipalLookup(codigo, { json: Boolean(opts.json), verbose: Boolean(opts.verbose) }, io);
|
|
3929
|
+
}
|
|
3930
|
+
function handleIssMunicipalSearchCli(query, opts, io = { stdout: [], stderr: [] }) {
|
|
3931
|
+
return runIssMunicipalSearch(query, {
|
|
3932
|
+
json: Boolean(opts.json),
|
|
3933
|
+
verbose: Boolean(opts.verbose),
|
|
3934
|
+
limit: opts.limit
|
|
3935
|
+
}, io);
|
|
3936
|
+
}
|
|
3937
|
+
function handleIssMunicipalResolveCli(uf, nome, opts, io = { stdout: [], stderr: [] }) {
|
|
3938
|
+
return runIssMunicipalResolve(uf, nome, { json: Boolean(opts.json), verbose: Boolean(opts.verbose) }, io);
|
|
3939
|
+
}
|
|
3940
|
+
function handlePtaxLookupCli(moeda, data, opts, io = { stdout: [], stderr: [] }) {
|
|
3941
|
+
return runPtaxLookup(moeda, data, { json: Boolean(opts.json), verbose: Boolean(opts.verbose) }, io);
|
|
3942
|
+
}
|
|
2928
3943
|
function writeCliIo(io) {
|
|
2929
3944
|
for (const line of io.stdout) console.log(line);
|
|
2930
3945
|
for (const line of io.stderr) console.error(line);
|
|
@@ -2940,6 +3955,13 @@ function registerReferenceLookupCommands(program) {
|
|
|
2940
3955
|
process.exitCode = handleReferenceLookupCli(command, codigo, opts, io);
|
|
2941
3956
|
writeCliIo(io);
|
|
2942
3957
|
});
|
|
3958
|
+
if (REFERENCE_VALIDATE_COMMANDS.includes(command)) {
|
|
3959
|
+
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) => {
|
|
3960
|
+
const io = { stdout: [], stderr: [] };
|
|
3961
|
+
process.exitCode = handleReferenceValidateCli(command, codigo, opts, io);
|
|
3962
|
+
writeCliIo(io);
|
|
3963
|
+
});
|
|
3964
|
+
}
|
|
2943
3965
|
if (REFERENCE_SEARCH_COMMANDS.includes(command)) {
|
|
2944
3966
|
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
3967
|
const io = { stdout: [], stderr: [] };
|
|
@@ -3194,6 +4216,28 @@ function createProgram() {
|
|
|
3194
4216
|
process.exitCode = handleFeriadosListCli(opts, io);
|
|
3195
4217
|
writeCliIo(io);
|
|
3196
4218
|
});
|
|
4219
|
+
const inss = program.command("inss").description("INSS employee contribution progressive table \u2014 offline");
|
|
4220
|
+
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) => {
|
|
4221
|
+
const io = { stdout: [], stderr: [] };
|
|
4222
|
+
process.exitCode = handleInssTabelaCli({ ...opts, year: opts.ano ?? opts.year }, io);
|
|
4223
|
+
writeCliIo(io);
|
|
4224
|
+
});
|
|
4225
|
+
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) => {
|
|
4226
|
+
const io = { stdout: [], stderr: [] };
|
|
4227
|
+
process.exitCode = handleInssCalcCli(salario, { ...opts, year: opts.ano ?? opts.year }, io);
|
|
4228
|
+
writeCliIo(io);
|
|
4229
|
+
});
|
|
4230
|
+
const irpf = program.command("irpf").description("RFB IRPF progressive monthly table \u2014 offline");
|
|
4231
|
+
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) => {
|
|
4232
|
+
const io = { stdout: [], stderr: [] };
|
|
4233
|
+
process.exitCode = handleIrpfTabelaCli({ ...opts, year: opts.ano ?? opts.year }, io);
|
|
4234
|
+
writeCliIo(io);
|
|
4235
|
+
});
|
|
4236
|
+
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) => {
|
|
4237
|
+
const io = { stdout: [], stderr: [] };
|
|
4238
|
+
process.exitCode = handleIrpfCalcCli(base, { ...opts, year: opts.ano ?? opts.year }, io);
|
|
4239
|
+
writeCliIo(io);
|
|
4240
|
+
});
|
|
3197
4241
|
const tseMunicipios = program.command("tse-municipios").description("TSE \u2194 IBGE municipality cross-walk \u2014 offline lookup");
|
|
3198
4242
|
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
4243
|
const io = { stdout: [], stderr: [] };
|
|
@@ -3206,6 +4250,56 @@ function createProgram() {
|
|
|
3206
4250
|
process.exitCode = handleDddLookupCli(code, opts, io);
|
|
3207
4251
|
writeCliIo(io);
|
|
3208
4252
|
});
|
|
4253
|
+
const nfeCuf = program.command("nfe-cuf").description("NF-e cUF \u2014 SEFAZ federative unit codes (offline)");
|
|
4254
|
+
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) => {
|
|
4255
|
+
const io = { stdout: [], stderr: [] };
|
|
4256
|
+
process.exitCode = handleNfeCufLookupCli(code, opts, io);
|
|
4257
|
+
writeCliIo(io);
|
|
4258
|
+
});
|
|
4259
|
+
const selic = program.command("selic").description("Bacen SELIC meta (SGS 432) \u2014 offline embedded series");
|
|
4260
|
+
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) => {
|
|
4261
|
+
const io = { stdout: [], stderr: [] };
|
|
4262
|
+
process.exitCode = handleSelicCli(opts, io);
|
|
4263
|
+
writeCliIo(io);
|
|
4264
|
+
});
|
|
4265
|
+
const issMunicipal = program.command("iss-municipal").description("Municipal ISS al\xEDquotas \u2014 partial embed (estimation only, not NFSe)");
|
|
4266
|
+
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) => {
|
|
4267
|
+
const io = { stdout: [], stderr: [] };
|
|
4268
|
+
process.exitCode = handleIssMunicipalLookupCli(codigoIbge, opts, io);
|
|
4269
|
+
writeCliIo(io);
|
|
4270
|
+
});
|
|
4271
|
+
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) => {
|
|
4272
|
+
const io = { stdout: [], stderr: [] };
|
|
4273
|
+
process.exitCode = handleIssMunicipalResolveCli(uf, nome, opts, io);
|
|
4274
|
+
writeCliIo(io);
|
|
4275
|
+
});
|
|
4276
|
+
issMunicipal.command("search").description("Search embedded municipalities by name, UF, or IBGE code fragment").argument("<query>", "Search query").option("--json", "JSON output").option("--verbose", "Include dataset capture date in JSON responses").option("--limit <n>", "Maximum rows", (value) => Number(value)).action((query, opts) => {
|
|
4277
|
+
const io = { stdout: [], stderr: [] };
|
|
4278
|
+
process.exitCode = handleIssMunicipalSearchCli(query, opts, io);
|
|
4279
|
+
writeCliIo(io);
|
|
4280
|
+
});
|
|
4281
|
+
const ptax = program.command("ptax").description("Bacen PTAX Fechamento \u2014 offline embedded rates");
|
|
4282
|
+
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) => {
|
|
4283
|
+
const io = { stdout: [], stderr: [] };
|
|
4284
|
+
process.exitCode = handlePtaxLookupCli(moeda, data, opts, io);
|
|
4285
|
+
writeCliIo(io);
|
|
4286
|
+
});
|
|
4287
|
+
const cst = program.command("cst").description("RFB SPED CST \u2014 offline ICMS, IPI, PIS, COFINS tables");
|
|
4288
|
+
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) => {
|
|
4289
|
+
const io = { stdout: [], stderr: [] };
|
|
4290
|
+
process.exitCode = handleCstLookupCli(codigo, opts, io);
|
|
4291
|
+
writeCliIo(io);
|
|
4292
|
+
});
|
|
4293
|
+
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) => {
|
|
4294
|
+
const io = { stdout: [], stderr: [] };
|
|
4295
|
+
process.exitCode = handleCstSearchCli(query, opts, io);
|
|
4296
|
+
writeCliIo(io);
|
|
4297
|
+
});
|
|
4298
|
+
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) => {
|
|
4299
|
+
const io = { stdout: [], stderr: [] };
|
|
4300
|
+
process.exitCode = handleCstValidateCli(codigo, opts, io);
|
|
4301
|
+
writeCliIo(io);
|
|
4302
|
+
});
|
|
3209
4303
|
registerReferenceLookupCommands(program);
|
|
3210
4304
|
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
4305
|
const io = { stdout: [], stderr: [] };
|
|
@@ -3217,11 +4311,31 @@ function createProgram() {
|
|
|
3217
4311
|
process.exitCode = handleSanitizeCli(type, value, opts, io);
|
|
3218
4312
|
writeCliIo(io);
|
|
3219
4313
|
});
|
|
3220
|
-
program.command("
|
|
4314
|
+
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) => {
|
|
4315
|
+
const io = { stdout: [], stderr: [] };
|
|
4316
|
+
process.exitCode = handleMaskCli(type, value, opts, io);
|
|
4317
|
+
writeCliIo(io);
|
|
4318
|
+
});
|
|
4319
|
+
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
4320
|
const io = { stdout: [], stderr: [] };
|
|
3222
4321
|
process.exitCode = handleGenerateCli(type, opts, io);
|
|
3223
4322
|
writeCliIo(io);
|
|
3224
4323
|
});
|
|
4324
|
+
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) => {
|
|
4325
|
+
const io = { stdout: [], stderr: [] };
|
|
4326
|
+
process.exitCode = handleCompareCli(type, valueA, valueB.join(" ") || void 0, opts, io);
|
|
4327
|
+
writeCliIo(io);
|
|
4328
|
+
});
|
|
4329
|
+
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)").option("--limit <n>", "Max number of values to process", (v) => Number(v)).action((type, opts) => {
|
|
4330
|
+
const io = { stdout: [], stderr: [] };
|
|
4331
|
+
process.exitCode = handleBatchCli(type, opts, io);
|
|
4332
|
+
writeCliIo(io);
|
|
4333
|
+
});
|
|
4334
|
+
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) => {
|
|
4335
|
+
const io = { stdout: [], stderr: [] };
|
|
4336
|
+
process.exitCode = handleDiffCli(type, valueA, valueB.join(" ") || void 0, opts, io);
|
|
4337
|
+
writeCliIo(io);
|
|
4338
|
+
});
|
|
3225
4339
|
return program;
|
|
3226
4340
|
}
|
|
3227
4341
|
function run(argv) {
|