gerar 0.0.2 → 0.0.4
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/LICENSE +21 -0
- package/README.md +52 -0
- package/dist/commands/cnpj/index.d.ts +2 -0
- package/dist/commands/cnpj/index.js +26 -0
- package/dist/commands/cnpj/index.js.map +1 -0
- package/dist/commands/cnpj/utils.d.ts +7 -0
- package/dist/commands/cnpj/utils.js +27 -0
- package/dist/commands/cnpj/utils.js.map +1 -0
- package/dist/commands/cpf/index.d.ts +2 -2
- package/dist/commands/cpf/index.js +21 -10
- package/dist/commands/cpf/index.js.map +1 -1
- package/dist/index.js +3 -5
- package/dist/index.js.map +1 -1
- package/dist/shared/utils/command-builder.d.ts +12 -0
- package/dist/shared/utils/command-builder.js +21 -0
- package/dist/shared/utils/command-builder.js.map +1 -0
- package/dist/shared/utils/command-options.d.ts +21 -0
- package/dist/shared/utils/command-options.js +19 -0
- package/dist/shared/utils/command-options.js.map +1 -0
- package/dist/shared/utils/result-logger.d.ts +15 -0
- package/dist/shared/utils/result-logger.js +22 -0
- package/dist/shared/utils/result-logger.js.map +1 -0
- package/package.json +2 -2
- package/src/commands/cnpj/index.ts +28 -0
- package/src/commands/cnpj/tests/utils.test.ts +114 -0
- package/src/commands/cnpj/utils.ts +38 -0
- package/src/commands/cpf/index.ts +24 -17
- package/src/commands/cpf/tests/utils.test.ts +1 -1
- package/src/index.ts +4 -10
- package/src/shared/utils/command-builder.ts +40 -0
- package/src/shared/utils/command-options.ts +30 -0
- package/src/shared/utils/result-logger.ts +47 -0
- package/dist/shared/utils/command-structure.d.ts +0 -6
- package/dist/shared/utils/command-structure.js +0 -3
- package/dist/shared/utils/command-structure.js.map +0 -1
- package/src/shared/utils/command-structure.ts +0 -7
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Victor Ribeiro Boechat
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Gerar
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/gerar)
|
|
4
|
+
|
|
5
|
+
CLI brasileiro para gerar dados fictícios válidos para testes.
|
|
6
|
+
|
|
7
|
+
## Instalação
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm i -g gerar
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Exemplo de Uso
|
|
14
|
+
|
|
15
|
+
Gera um dado fictício válido, nesse caso CPF:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
gerar cpf
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Gera múltiplos dados:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
gerar cpf --amount 5
|
|
25
|
+
# ou
|
|
26
|
+
gerar cpf -a 5
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Exemplo de saída:**
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
CPF 1) Com Máscara: 123.456.789-00 - Sem Máscara: 12345678900
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Roadmap
|
|
36
|
+
|
|
37
|
+
| Funcionalidade | Status |
|
|
38
|
+
| ------------------------------------------------- | ----------- |
|
|
39
|
+
| CPF | ✅ Completo |
|
|
40
|
+
| CNPJ | ✅ Completo |
|
|
41
|
+
| Flag nos comandos para gerar com ou sem máscara | ✅ Completo |
|
|
42
|
+
| Cartão de crédito com base na bandeira | ⏳ Pendente |
|
|
43
|
+
| Endereço | ⏳ Pendente |
|
|
44
|
+
| Chassi e Placa | ⏳ Pendente |
|
|
45
|
+
| UUID v4 | ⏳ Pendente |
|
|
46
|
+
| UUID v7 | ⏳ Pendente |
|
|
47
|
+
| Autocomplete no Terminal | ⏳ Pendente |
|
|
48
|
+
| Localização de endereço norte-americano e europeu | ⏳ Pendente |
|
|
49
|
+
|
|
50
|
+
## Licença
|
|
51
|
+
|
|
52
|
+
Este projeto está licenciado sob a licença MIT. Para mais informações, consulte a [página do pacote no NPM](https://www.npmjs.com/package/gerar).
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerCnpjCommand = void 0;
|
|
4
|
+
const command_builder_1 = require("../../shared/utils/command-builder");
|
|
5
|
+
const utils_1 = require("./utils");
|
|
6
|
+
const result_logger_1 = require("../../shared/utils/result-logger");
|
|
7
|
+
const registerCnpjCommand = (program) => {
|
|
8
|
+
return (0, command_builder_1.buildCommand)(program, {
|
|
9
|
+
name: "cnpj",
|
|
10
|
+
description: "Gera um CNPJ fictício válido.",
|
|
11
|
+
action: (options) => {
|
|
12
|
+
const generatedCnpjs = Array.from({ length: options.amount ?? 1 }, utils_1.generateCnpj);
|
|
13
|
+
generatedCnpjs.forEach((generatedCnpj, index) => {
|
|
14
|
+
(0, result_logger_1.logResult)({
|
|
15
|
+
label: "CNPJ",
|
|
16
|
+
index,
|
|
17
|
+
showIndex: true,
|
|
18
|
+
result: generatedCnpj,
|
|
19
|
+
options,
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
exports.registerCnpjCommand = registerCnpjCommand;
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/cnpj/index.ts"],"names":[],"mappings":";;;AACA,wEAAkE;AAClE,mCAAuC;AAEvC,oEAA6D;AAEtD,MAAM,mBAAmB,GAAG,CAAC,OAAgB,EAAE,EAAE;IACtD,OAAO,IAAA,8BAAY,EAAC,OAAO,EAAE;QAC3B,IAAI,EAAE,MAAM;QACZ,WAAW,EAAE,+BAA+B;QAC5C,MAAM,EAAE,CAAC,OAAuB,EAAE,EAAE;YAClC,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,CAC/B,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,CAAC,EAAE,EAC/B,oBAAY,CACb,CAAC;YAEF,cAAc,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,KAAK,EAAE,EAAE;gBAC9C,IAAA,yBAAS,EAAC;oBACR,KAAK,EAAE,MAAM;oBACb,KAAK;oBACL,SAAS,EAAE,IAAI;oBACf,MAAM,EAAE,aAAa;oBACrB,OAAO;iBACR,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC;KACF,CAAC,CAAC;AACL,CAAC,CAAC;AArBW,QAAA,mBAAmB,uBAqB9B"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateCnpj = exports.calculateCnpjDigit = void 0;
|
|
4
|
+
const calculateCnpjDigit = (cnpj) => {
|
|
5
|
+
const weights = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
|
|
6
|
+
const length = cnpj.length;
|
|
7
|
+
const relevantWeights = weights.slice(weights.length - length);
|
|
8
|
+
const sum = cnpj
|
|
9
|
+
.split("")
|
|
10
|
+
.reduce((acc, num, index) => acc + Number(num) * relevantWeights[index], 0);
|
|
11
|
+
const remainder = sum % 11;
|
|
12
|
+
return remainder < 2 ? 0 : 11 - remainder;
|
|
13
|
+
};
|
|
14
|
+
exports.calculateCnpjDigit = calculateCnpjDigit;
|
|
15
|
+
const generateCnpj = () => {
|
|
16
|
+
const baseCnpj = Array.from({ length: 12 }, () => Math.floor(Math.random() * 10)).join("");
|
|
17
|
+
const firstDigit = (0, exports.calculateCnpjDigit)(baseCnpj);
|
|
18
|
+
const lastDigit = (0, exports.calculateCnpjDigit)(baseCnpj + firstDigit);
|
|
19
|
+
const fullCnpj = baseCnpj + firstDigit.toString() + lastDigit.toString();
|
|
20
|
+
return {
|
|
21
|
+
// TODO: Improve this as soon as possible.
|
|
22
|
+
withMask: `${fullCnpj.slice(0, 2)}.${fullCnpj.slice(2, 5)}.${fullCnpj.slice(5, 8)}/${fullCnpj.slice(8, 12)}-${fullCnpj.slice(12, 14)}`,
|
|
23
|
+
withoutMask: fullCnpj,
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
exports.generateCnpj = generateCnpj;
|
|
27
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/commands/cnpj/utils.ts"],"names":[],"mappings":";;;AAKO,MAAM,kBAAkB,GAAG,CAAC,IAAY,EAAU,EAAE;IACzD,MAAM,OAAO,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAC3B,MAAM,eAAe,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IAE/D,MAAM,GAAG,GAAG,IAAI;SACb,KAAK,CAAC,EAAE,CAAC;SACT,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IAE9E,MAAM,SAAS,GAAG,GAAG,GAAG,EAAE,CAAC;IAE3B,OAAO,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,SAAS,CAAC;AAC5C,CAAC,CAAC;AAZW,QAAA,kBAAkB,sBAY7B;AAEK,MAAM,YAAY,GAAG,GAAyB,EAAE;IACrD,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAC/C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAC/B,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEX,MAAM,UAAU,GAAG,IAAA,0BAAkB,EAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,SAAS,GAAG,IAAA,0BAAkB,EAAC,QAAQ,GAAG,UAAU,CAAC,CAAC;IAE5D,MAAM,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC,QAAQ,EAAE,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC;IAEzE,OAAO;QACL,0CAA0C;QAC1C,QAAQ,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,QAAQ,CAAC,KAAK,CACzE,CAAC,EACD,CAAC,CACF,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACtD,WAAW,EAAE,QAAQ;KACtB,CAAC;AACJ,CAAC,CAAC;AAlBW,QAAA,YAAY,gBAkBvB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare const
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
export declare const registerCpfCommand: (program: Command) => Command;
|
|
@@ -1,15 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.registerCpfCommand = void 0;
|
|
4
|
+
const command_builder_1 = require("../../shared/utils/command-builder");
|
|
4
5
|
const utils_1 = require("./utils");
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
const result_logger_1 = require("../../shared/utils/result-logger");
|
|
7
|
+
const registerCpfCommand = (program) => {
|
|
8
|
+
return (0, command_builder_1.buildCommand)(program, {
|
|
9
|
+
name: "cpf",
|
|
10
|
+
description: "Gera um CPF fictício válido.",
|
|
11
|
+
action: (options) => {
|
|
12
|
+
const generatedCpfs = Array.from({ length: options.amount ?? 1 }, utils_1.generateCpf);
|
|
13
|
+
generatedCpfs.forEach((generatedCpf, index) => {
|
|
14
|
+
(0, result_logger_1.logResult)({
|
|
15
|
+
label: "CPF",
|
|
16
|
+
index,
|
|
17
|
+
showIndex: true,
|
|
18
|
+
result: generatedCpf,
|
|
19
|
+
options,
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
},
|
|
23
|
+
});
|
|
14
24
|
};
|
|
25
|
+
exports.registerCpfCommand = registerCpfCommand;
|
|
15
26
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/cpf/index.ts"],"names":[],"mappings":";;;AACA,mCAAsC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/cpf/index.ts"],"names":[],"mappings":";;;AACA,wEAAkE;AAClE,mCAAsC;AAEtC,oEAA6D;AAEtD,MAAM,kBAAkB,GAAG,CAAC,OAAgB,EAAE,EAAE;IACrD,OAAO,IAAA,8BAAY,EAAC,OAAO,EAAE;QAC3B,IAAI,EAAE,KAAK;QACX,WAAW,EAAE,8BAA8B;QAC3C,MAAM,EAAE,CAAC,OAAuB,EAAE,EAAE;YAClC,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAC9B,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,CAAC,EAAE,EAC/B,mBAAW,CACZ,CAAC;YAEF,aAAa,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,KAAK,EAAE,EAAE;gBAC5C,IAAA,yBAAS,EAAC;oBACR,KAAK,EAAE,KAAK;oBACZ,KAAK;oBACL,SAAS,EAAE,IAAI;oBACf,MAAM,EAAE,YAAY;oBACpB,OAAO;iBACR,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC;KACF,CAAC,CAAC;AACL,CAAC,CAAC;AArBW,QAAA,kBAAkB,sBAqB7B"}
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
const commander_1 = require("commander");
|
|
5
5
|
const cpf_1 = require("./commands/cpf");
|
|
6
|
+
const cnpj_1 = require("./commands/cnpj");
|
|
6
7
|
const program = new commander_1.Command();
|
|
7
8
|
program
|
|
8
9
|
.name("gerar")
|
|
@@ -10,10 +11,7 @@ program
|
|
|
10
11
|
.version("0.0.1");
|
|
11
12
|
program.helpCommand("help", "Exibe informações de ajuda do CLI.");
|
|
12
13
|
// TODO: Create automatic registration for commands.
|
|
13
|
-
program
|
|
14
|
-
|
|
15
|
-
.description(cpf_1.cpfCommand.description)
|
|
16
|
-
.option("-a, --amount <amount>", "Quantidade a ser gerado.", (value) => Number(value))
|
|
17
|
-
.action(cpf_1.cpfCommand.action);
|
|
14
|
+
(0, cpf_1.registerCpfCommand)(program);
|
|
15
|
+
(0, cnpj_1.registerCnpjCommand)(program);
|
|
18
16
|
program.parse();
|
|
19
17
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AACA,yCAAoC;AACpC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AACA,yCAAoC;AACpC,wCAAoD;AACpD,0CAAsD;AAEtD,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,wDAAwD,CAAC;KACrE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,oCAAoC,CAAC,CAAC;AAElE,oDAAoD;AACpD,IAAA,wBAAkB,EAAC,OAAO,CAAC,CAAC;AAC5B,IAAA,0BAAmB,EAAC,OAAO,CAAC,CAAC;AAE7B,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { CommandBaseOptions } from "./command-options";
|
|
3
|
+
export type CommandStructure = {
|
|
4
|
+
name: string;
|
|
5
|
+
description: string;
|
|
6
|
+
action: (this: Command, ...args: any[]) => void | Promise<void>;
|
|
7
|
+
};
|
|
8
|
+
type CommandBuilderOptions = {
|
|
9
|
+
omitOptions?: CommandBaseOptions[];
|
|
10
|
+
};
|
|
11
|
+
export declare const buildCommand: (program: Command, command: CommandStructure, options?: CommandBuilderOptions) => Command;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildCommand = void 0;
|
|
4
|
+
const command_options_1 = require("./command-options");
|
|
5
|
+
const buildCommand = (program, command, options = {}) => {
|
|
6
|
+
const commandInstance = program
|
|
7
|
+
.command(command.name)
|
|
8
|
+
.description(command.description);
|
|
9
|
+
const baseOptionsKeys = Object.keys(command_options_1.commandBaseOptions).filter((option) => !options.omitOptions?.includes(option));
|
|
10
|
+
const baseOptions = baseOptionsKeys.map((option) => command_options_1.commandBaseOptions[option]);
|
|
11
|
+
baseOptions.forEach((option) => {
|
|
12
|
+
if ("validator" in option) {
|
|
13
|
+
commandInstance.option(option.flag, option.description, option.validator);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
commandInstance.option(option.flag, option.description);
|
|
17
|
+
});
|
|
18
|
+
return commandInstance.action(command.action);
|
|
19
|
+
};
|
|
20
|
+
exports.buildCommand = buildCommand;
|
|
21
|
+
//# sourceMappingURL=command-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-builder.js","sourceRoot":"","sources":["../../../src/shared/utils/command-builder.ts"],"names":[],"mappings":";;;AACA,uDAA2E;AAYpE,MAAM,YAAY,GAAG,CAC1B,OAAgB,EAChB,OAAyB,EACzB,UAAiC,EAAE,EACnC,EAAE;IACF,MAAM,eAAe,GAAG,OAAO;SAC5B,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;SACrB,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAEpC,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,oCAAkB,CAAC,CAAC,MAAM,CAC5D,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,QAAQ,CAAC,MAA4B,CAAC,CACzE,CAAC;IACF,MAAM,WAAW,GAAG,eAAe,CAAC,GAAG,CACrC,CAAC,MAAM,EAAE,EAAE,CAAC,oCAAkB,CAAC,MAA4B,CAAC,CAC7D,CAAC;IAEF,WAAW,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;QAC7B,IAAI,WAAW,IAAI,MAAM,EAAE,CAAC;YAC1B,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;YAC1E,OAAO;QACT,CAAC;QAED,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,OAAO,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AAChD,CAAC,CAAC;AA1BW,QAAA,YAAY,gBA0BvB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare const commandBaseOptions: {
|
|
2
|
+
readonly amount: {
|
|
3
|
+
readonly flag: "-a, --amount <amount>";
|
|
4
|
+
readonly description: "Quantidade a ser gerado.";
|
|
5
|
+
readonly validator: (value: string) => number;
|
|
6
|
+
};
|
|
7
|
+
readonly masked: {
|
|
8
|
+
readonly flag: "-m, --masked";
|
|
9
|
+
readonly description: "Gera o resultado com máscara.";
|
|
10
|
+
};
|
|
11
|
+
readonly unmasked: {
|
|
12
|
+
readonly flag: "-u, --unmasked";
|
|
13
|
+
readonly description: "Gera o resultado sem máscara.";
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
export type CommandBaseOptions = keyof typeof commandBaseOptions;
|
|
17
|
+
export type CommandOptions = Partial<{
|
|
18
|
+
[Option in CommandBaseOptions]: (typeof commandBaseOptions)[Option] extends {
|
|
19
|
+
validator: (value: string) => infer ValidatorReturnType;
|
|
20
|
+
} ? ValidatorReturnType : boolean;
|
|
21
|
+
}>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.commandBaseOptions = void 0;
|
|
4
|
+
exports.commandBaseOptions = {
|
|
5
|
+
amount: {
|
|
6
|
+
flag: "-a, --amount <amount>",
|
|
7
|
+
description: "Quantidade a ser gerado.",
|
|
8
|
+
validator: (value) => Number(value),
|
|
9
|
+
},
|
|
10
|
+
masked: {
|
|
11
|
+
flag: "-m, --masked",
|
|
12
|
+
description: "Gera o resultado com máscara.",
|
|
13
|
+
},
|
|
14
|
+
unmasked: {
|
|
15
|
+
flag: "-u, --unmasked",
|
|
16
|
+
description: "Gera o resultado sem máscara.",
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=command-options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-options.js","sourceRoot":"","sources":["../../../src/shared/utils/command-options.ts"],"names":[],"mappings":";;;AAMa,QAAA,kBAAkB,GAAG;IAChC,MAAM,EAAE;QACN,IAAI,EAAE,uBAAuB;QAC7B,WAAW,EAAE,0BAA0B;QACvC,SAAS,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;KAC5C;IACD,MAAM,EAAE;QACN,IAAI,EAAE,cAAc;QACpB,WAAW,EAAE,+BAA+B;KAC7C;IACD,QAAQ,EAAE;QACR,IAAI,EAAE,gBAAgB;QACtB,WAAW,EAAE,+BAA+B;KAC7C;CAC0D,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { CommandOptions } from "./command-options";
|
|
2
|
+
type ResultWithMask = {
|
|
3
|
+
withMask: string;
|
|
4
|
+
withoutMask: string;
|
|
5
|
+
};
|
|
6
|
+
type ResultWithoutMask = string;
|
|
7
|
+
type LogResultOptions = {
|
|
8
|
+
label: string;
|
|
9
|
+
index?: number;
|
|
10
|
+
showIndex?: boolean;
|
|
11
|
+
result: ResultWithMask | ResultWithoutMask;
|
|
12
|
+
options: CommandOptions;
|
|
13
|
+
};
|
|
14
|
+
export declare const logResult: ({ label, index, showIndex, result, options, }: LogResultOptions) => void;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.logResult = void 0;
|
|
4
|
+
const logResult = ({ label, index = 0, showIndex = false, result, options, }) => {
|
|
5
|
+
const indexText = showIndex ? ` ${index + 1})` : ":";
|
|
6
|
+
if (typeof result === "string") {
|
|
7
|
+
console.log(`${label}${indexText} ${result}`);
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const { masked, unmasked } = options;
|
|
11
|
+
if (unmasked) {
|
|
12
|
+
console.log(`${label}${indexText} Sem Máscara: ${result.withoutMask}`);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (masked) {
|
|
16
|
+
console.log(`${label}${indexText} Com Máscara: ${result.withMask}`);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
console.log(`${label}${indexText} Com Máscara: ${result.withMask} - Sem Máscara: ${result.withoutMask}`);
|
|
20
|
+
};
|
|
21
|
+
exports.logResult = logResult;
|
|
22
|
+
//# sourceMappingURL=result-logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result-logger.js","sourceRoot":"","sources":["../../../src/shared/utils/result-logger.ts"],"names":[],"mappings":";;;AAiBO,MAAM,SAAS,GAAG,CAAC,EACxB,KAAK,EACL,KAAK,GAAG,CAAC,EACT,SAAS,GAAG,KAAK,EACjB,MAAM,EACN,OAAO,GACU,EAAQ,EAAE;IAC3B,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IAErD,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,GAAG,SAAS,IAAI,MAAM,EAAE,CAAC,CAAC;QAC9C,OAAO;IACT,CAAC;IAED,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAErC,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,GAAG,SAAS,iBAAiB,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;QACvE,OAAO;IACT,CAAC;IAED,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,GAAG,SAAS,iBAAiB,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;QACpE,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CACT,GAAG,KAAK,GAAG,SAAS,iBAAiB,MAAM,CAAC,QAAQ,mBAAmB,MAAM,CAAC,WAAW,EAAE,CAC5F,CAAC;AACJ,CAAC,CAAC;AA7BW,QAAA,SAAS,aA6BpB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gerar",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "CLI brasileiro para gerar dados fictícios para testes.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"author": "Victor Ribeiro Boechat",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"test:watch": "vitest"
|
|
16
16
|
},
|
|
17
17
|
"keywords": [],
|
|
18
|
-
"license": "
|
|
18
|
+
"license": "MIT",
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"commander": "^14.0.2"
|
|
21
21
|
},
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { buildCommand } from "../../shared/utils/command-builder";
|
|
3
|
+
import { generateCnpj } from "./utils";
|
|
4
|
+
import { CommandOptions } from "../../shared/utils/command-options";
|
|
5
|
+
import { logResult } from "../../shared/utils/result-logger";
|
|
6
|
+
|
|
7
|
+
export const registerCnpjCommand = (program: Command) => {
|
|
8
|
+
return buildCommand(program, {
|
|
9
|
+
name: "cnpj",
|
|
10
|
+
description: "Gera um CNPJ fictício válido.",
|
|
11
|
+
action: (options: CommandOptions) => {
|
|
12
|
+
const generatedCnpjs = Array.from(
|
|
13
|
+
{ length: options.amount ?? 1 },
|
|
14
|
+
generateCnpj
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
generatedCnpjs.forEach((generatedCnpj, index) => {
|
|
18
|
+
logResult({
|
|
19
|
+
label: "CNPJ",
|
|
20
|
+
index,
|
|
21
|
+
showIndex: true,
|
|
22
|
+
result: generatedCnpj,
|
|
23
|
+
options,
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { calculateCnpjDigit, generateCnpj } from "../utils";
|
|
3
|
+
|
|
4
|
+
describe("calculateCnpjDigit", () => {
|
|
5
|
+
it("should calculate the first check digit correctly for known CNPJ", () => {
|
|
6
|
+
const firstDigit = calculateCnpjDigit("112223330001");
|
|
7
|
+
|
|
8
|
+
expect(firstDigit).toBe(8);
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it("should calculate the second check digit correctly for known CNPJ", () => {
|
|
12
|
+
const secondDigit = calculateCnpjDigit("1122233300018");
|
|
13
|
+
|
|
14
|
+
expect(secondDigit).toBe(1);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it("should return 0 when remainder is less than 2", () => {
|
|
18
|
+
const digit = calculateCnpjDigit("000000000000");
|
|
19
|
+
|
|
20
|
+
expect(digit).toBe(0);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("should return correct digit when remainder is 2 or greater", () => {
|
|
24
|
+
const digit = calculateCnpjDigit("123456780001");
|
|
25
|
+
|
|
26
|
+
expect(digit).toBeGreaterThanOrEqual(0);
|
|
27
|
+
expect(digit).toBeLessThanOrEqual(9);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("should handle 12-digit input correctly", () => {
|
|
31
|
+
const digit = calculateCnpjDigit("123456780001");
|
|
32
|
+
|
|
33
|
+
expect(digit).toBeTypeOf("number");
|
|
34
|
+
expect(digit).toBeGreaterThanOrEqual(0);
|
|
35
|
+
expect(digit).toBeLessThanOrEqual(9);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("should handle 13-digit input correctly (for second digit calculation)", () => {
|
|
39
|
+
const digit = calculateCnpjDigit("1234567800012");
|
|
40
|
+
|
|
41
|
+
expect(digit).toBeTypeOf("number");
|
|
42
|
+
expect(digit).toBeGreaterThanOrEqual(0);
|
|
43
|
+
expect(digit).toBeLessThanOrEqual(9);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
describe("generateCnpj", () => {
|
|
48
|
+
it("should generate a CNPJ with correct structure", () => {
|
|
49
|
+
const result = generateCnpj();
|
|
50
|
+
|
|
51
|
+
expect(result).toHaveProperty("withMask");
|
|
52
|
+
expect(result).toHaveProperty("withoutMask");
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("should generate CNPJ withoutMask with exactly 14 digits", () => {
|
|
56
|
+
const result = generateCnpj();
|
|
57
|
+
|
|
58
|
+
expect(result.withoutMask).toMatch(/^\d{14}$/);
|
|
59
|
+
expect(result.withoutMask.length).toBe(14);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("should generate CNPJ withMask in correct format (XX.XXX.XXX/XXXX-XX)", () => {
|
|
63
|
+
const result = generateCnpj();
|
|
64
|
+
|
|
65
|
+
expect(result.withMask).toMatch(/^\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}$/);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it("should generate valid CNPJ digits (check digits are correct)", () => {
|
|
69
|
+
const result = generateCnpj();
|
|
70
|
+
const cnpj = result.withoutMask;
|
|
71
|
+
|
|
72
|
+
const base = cnpj.slice(0, 12);
|
|
73
|
+
const firstCheckDigit = Number(cnpj[12]);
|
|
74
|
+
const secondCheckDigit = Number(cnpj[13]);
|
|
75
|
+
|
|
76
|
+
const calculatedFirstDigit = calculateCnpjDigit(base);
|
|
77
|
+
expect(firstCheckDigit).toBe(calculatedFirstDigit);
|
|
78
|
+
|
|
79
|
+
const calculatedSecondDigit = calculateCnpjDigit(base + firstCheckDigit);
|
|
80
|
+
expect(secondCheckDigit).toBe(calculatedSecondDigit);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it("should generate different CNPJs on multiple calls", () => {
|
|
84
|
+
const results = Array.from({ length: 10 }, () => generateCnpj());
|
|
85
|
+
const uniqueCnpjs = new Set(results.map((r) => r.withoutMask));
|
|
86
|
+
|
|
87
|
+
expect(uniqueCnpjs.size).toBeGreaterThan(1);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it("should generate CNPJ where withMask and withoutMask represent the same number", () => {
|
|
91
|
+
const result = generateCnpj();
|
|
92
|
+
|
|
93
|
+
const unmasked = result.withMask.replace(/[.\/-]/g, "");
|
|
94
|
+
|
|
95
|
+
expect(unmasked).toBe(result.withoutMask);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it("should generate multiple valid CNPJs", () => {
|
|
99
|
+
const results = Array.from({ length: 100 }, () => generateCnpj());
|
|
100
|
+
|
|
101
|
+
results.forEach((result) => {
|
|
102
|
+
const cnpj = result.withoutMask;
|
|
103
|
+
const base = cnpj.slice(0, 12);
|
|
104
|
+
const firstCheckDigit = Number(cnpj[12]);
|
|
105
|
+
const secondCheckDigit = Number(cnpj[13]);
|
|
106
|
+
|
|
107
|
+
const calculatedFirstDigit = calculateCnpjDigit(base);
|
|
108
|
+
const calculatedSecondDigit = calculateCnpjDigit(base + firstCheckDigit);
|
|
109
|
+
|
|
110
|
+
expect(firstCheckDigit).toBe(calculatedFirstDigit);
|
|
111
|
+
expect(secondCheckDigit).toBe(calculatedSecondDigit);
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
type GenerateCnpjResponse = {
|
|
2
|
+
withMask: string;
|
|
3
|
+
withoutMask: string;
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
export const calculateCnpjDigit = (cnpj: string): number => {
|
|
7
|
+
const weights = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
|
|
8
|
+
const length = cnpj.length;
|
|
9
|
+
const relevantWeights = weights.slice(weights.length - length);
|
|
10
|
+
|
|
11
|
+
const sum = cnpj
|
|
12
|
+
.split("")
|
|
13
|
+
.reduce((acc, num, index) => acc + Number(num) * relevantWeights[index], 0);
|
|
14
|
+
|
|
15
|
+
const remainder = sum % 11;
|
|
16
|
+
|
|
17
|
+
return remainder < 2 ? 0 : 11 - remainder;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const generateCnpj = (): GenerateCnpjResponse => {
|
|
21
|
+
const baseCnpj = Array.from({ length: 12 }, () =>
|
|
22
|
+
Math.floor(Math.random() * 10)
|
|
23
|
+
).join("");
|
|
24
|
+
|
|
25
|
+
const firstDigit = calculateCnpjDigit(baseCnpj);
|
|
26
|
+
const lastDigit = calculateCnpjDigit(baseCnpj + firstDigit);
|
|
27
|
+
|
|
28
|
+
const fullCnpj = baseCnpj + firstDigit.toString() + lastDigit.toString();
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
// TODO: Improve this as soon as possible.
|
|
32
|
+
withMask: `${fullCnpj.slice(0, 2)}.${fullCnpj.slice(2, 5)}.${fullCnpj.slice(
|
|
33
|
+
5,
|
|
34
|
+
8
|
|
35
|
+
)}/${fullCnpj.slice(8, 12)}-${fullCnpj.slice(12, 14)}`,
|
|
36
|
+
withoutMask: fullCnpj,
|
|
37
|
+
};
|
|
38
|
+
};
|
|
@@ -1,21 +1,28 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { buildCommand } from "../../shared/utils/command-builder";
|
|
2
3
|
import { generateCpf } from "./utils";
|
|
4
|
+
import { CommandOptions } from "../../shared/utils/command-options";
|
|
5
|
+
import { logResult } from "../../shared/utils/result-logger";
|
|
3
6
|
|
|
4
|
-
export const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
generatedCpfs.forEach((generatedCpf, index) => {
|
|
14
|
-
console.log(
|
|
15
|
-
`CPF ${index + 1}) Com Máscara: ${
|
|
16
|
-
generatedCpf.withMask
|
|
17
|
-
} - Sem Máscara: ${generatedCpf.withoutMask}`
|
|
7
|
+
export const registerCpfCommand = (program: Command) => {
|
|
8
|
+
return buildCommand(program, {
|
|
9
|
+
name: "cpf",
|
|
10
|
+
description: "Gera um CPF fictício válido.",
|
|
11
|
+
action: (options: CommandOptions) => {
|
|
12
|
+
const generatedCpfs = Array.from(
|
|
13
|
+
{ length: options.amount ?? 1 },
|
|
14
|
+
generateCpf
|
|
18
15
|
);
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
|
|
17
|
+
generatedCpfs.forEach((generatedCpf, index) => {
|
|
18
|
+
logResult({
|
|
19
|
+
label: "CPF",
|
|
20
|
+
index,
|
|
21
|
+
showIndex: true,
|
|
22
|
+
result: generatedCpf,
|
|
23
|
+
options,
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
},
|
|
27
|
+
});
|
|
21
28
|
};
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from "commander";
|
|
3
|
-
import {
|
|
3
|
+
import { registerCpfCommand } from "./commands/cpf";
|
|
4
|
+
import { registerCnpjCommand } from "./commands/cnpj";
|
|
4
5
|
|
|
5
6
|
const program = new Command();
|
|
6
7
|
|
|
@@ -12,14 +13,7 @@ program
|
|
|
12
13
|
program.helpCommand("help", "Exibe informações de ajuda do CLI.");
|
|
13
14
|
|
|
14
15
|
// TODO: Create automatic registration for commands.
|
|
15
|
-
program
|
|
16
|
-
|
|
17
|
-
.description(cpfCommand.description)
|
|
18
|
-
.option(
|
|
19
|
-
"-a, --amount <amount>",
|
|
20
|
-
"Quantidade a ser gerado.",
|
|
21
|
-
(value: string) => Number(value)
|
|
22
|
-
)
|
|
23
|
-
.action(cpfCommand.action);
|
|
16
|
+
registerCpfCommand(program);
|
|
17
|
+
registerCnpjCommand(program);
|
|
24
18
|
|
|
25
19
|
program.parse();
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { CommandBaseOptions, commandBaseOptions } from "./command-options";
|
|
3
|
+
|
|
4
|
+
export type CommandStructure = {
|
|
5
|
+
name: string;
|
|
6
|
+
description: string;
|
|
7
|
+
action: (this: Command, ...args: any[]) => void | Promise<void>;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
type CommandBuilderOptions = {
|
|
11
|
+
omitOptions?: CommandBaseOptions[];
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const buildCommand = (
|
|
15
|
+
program: Command,
|
|
16
|
+
command: CommandStructure,
|
|
17
|
+
options: CommandBuilderOptions = {}
|
|
18
|
+
) => {
|
|
19
|
+
const commandInstance = program
|
|
20
|
+
.command(command.name)
|
|
21
|
+
.description(command.description);
|
|
22
|
+
|
|
23
|
+
const baseOptionsKeys = Object.keys(commandBaseOptions).filter(
|
|
24
|
+
(option) => !options.omitOptions?.includes(option as CommandBaseOptions)
|
|
25
|
+
);
|
|
26
|
+
const baseOptions = baseOptionsKeys.map(
|
|
27
|
+
(option) => commandBaseOptions[option as CommandBaseOptions]
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
baseOptions.forEach((option) => {
|
|
31
|
+
if ("validator" in option) {
|
|
32
|
+
commandInstance.option(option.flag, option.description, option.validator);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
commandInstance.option(option.flag, option.description);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
return commandInstance.action(command.action);
|
|
40
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
type CommandBaseOptionsObject = {
|
|
2
|
+
flag: string;
|
|
3
|
+
description: string;
|
|
4
|
+
validator?: (value: string) => any;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export const commandBaseOptions = {
|
|
8
|
+
amount: {
|
|
9
|
+
flag: "-a, --amount <amount>",
|
|
10
|
+
description: "Quantidade a ser gerado.",
|
|
11
|
+
validator: (value: string) => Number(value),
|
|
12
|
+
},
|
|
13
|
+
masked: {
|
|
14
|
+
flag: "-m, --masked",
|
|
15
|
+
description: "Gera o resultado com máscara.",
|
|
16
|
+
},
|
|
17
|
+
unmasked: {
|
|
18
|
+
flag: "-u, --unmasked",
|
|
19
|
+
description: "Gera o resultado sem máscara.",
|
|
20
|
+
},
|
|
21
|
+
} as const satisfies Record<string, CommandBaseOptionsObject>;
|
|
22
|
+
|
|
23
|
+
export type CommandBaseOptions = keyof typeof commandBaseOptions;
|
|
24
|
+
export type CommandOptions = Partial<{
|
|
25
|
+
[Option in CommandBaseOptions]: (typeof commandBaseOptions)[Option] extends {
|
|
26
|
+
validator: (value: string) => infer ValidatorReturnType;
|
|
27
|
+
}
|
|
28
|
+
? ValidatorReturnType
|
|
29
|
+
: boolean;
|
|
30
|
+
}>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { CommandOptions } from "./command-options";
|
|
2
|
+
|
|
3
|
+
type ResultWithMask = {
|
|
4
|
+
withMask: string;
|
|
5
|
+
withoutMask: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
type ResultWithoutMask = string;
|
|
9
|
+
|
|
10
|
+
type LogResultOptions = {
|
|
11
|
+
label: string;
|
|
12
|
+
index?: number;
|
|
13
|
+
showIndex?: boolean;
|
|
14
|
+
result: ResultWithMask | ResultWithoutMask;
|
|
15
|
+
options: CommandOptions;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const logResult = ({
|
|
19
|
+
label,
|
|
20
|
+
index = 0,
|
|
21
|
+
showIndex = false,
|
|
22
|
+
result,
|
|
23
|
+
options,
|
|
24
|
+
}: LogResultOptions): void => {
|
|
25
|
+
const indexText = showIndex ? ` ${index + 1})` : ":";
|
|
26
|
+
|
|
27
|
+
if (typeof result === "string") {
|
|
28
|
+
console.log(`${label}${indexText} ${result}`);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const { masked, unmasked } = options;
|
|
33
|
+
|
|
34
|
+
if (unmasked) {
|
|
35
|
+
console.log(`${label}${indexText} Sem Máscara: ${result.withoutMask}`);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (masked) {
|
|
40
|
+
console.log(`${label}${indexText} Com Máscara: ${result.withMask}`);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
console.log(
|
|
45
|
+
`${label}${indexText} Com Máscara: ${result.withMask} - Sem Máscara: ${result.withoutMask}`
|
|
46
|
+
);
|
|
47
|
+
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"command-structure.js","sourceRoot":"","sources":["../../../src/shared/utils/command-structure.ts"],"names":[],"mappings":""}
|