gerar 0.0.2 → 0.0.3

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 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,50 @@
1
+ # Gerar
2
+
3
+ [![npm version](https://img.shields.io/npm/v/gerar.svg)](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
+ | Cartão de crédito com base na bandeira | ⏳ Pendente |
42
+ | Endereço | ⏳ Pendente |
43
+ | UUID v4 | ⏳ Pendente |
44
+ | UUID v7 | ⏳ Pendente |
45
+ | Autocomplete no Terminal | ⏳ Pendente |
46
+ | Localização de endereço norte-americano e europeu | ⏳ Pendente |
47
+
48
+ ## Licença
49
+
50
+ 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,2 @@
1
+ import { CommandStructure } from "../../shared/utils/command-structure";
2
+ export declare const cnpjCommand: CommandStructure;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cnpjCommand = void 0;
4
+ const utils_1 = require("./utils");
5
+ exports.cnpjCommand = {
6
+ name: "cnpj",
7
+ description: "Gera um CNPJ fictício válido.",
8
+ action: (options) => {
9
+ const generatedCnpjs = Array.from({ length: options.amount ?? 1 }, utils_1.generateCnpj);
10
+ generatedCnpjs.forEach((generatedCnpj, index) => {
11
+ console.log(`CNPJ ${index + 1}) Com Máscara: ${generatedCnpj.withMask} - Sem Máscara: ${generatedCnpj.withoutMask}`);
12
+ });
13
+ },
14
+ };
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/cnpj/index.ts"],"names":[],"mappings":";;;AACA,mCAAuC;AAE1B,QAAA,WAAW,GAAqB;IAC3C,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,+BAA+B;IAC5C,MAAM,EAAE,CAAC,OAA4B,EAAE,EAAE;QACvC,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,CAC/B,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,CAAC,EAAE,EAC/B,oBAAY,CACb,CAAC;QAEF,cAAc,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,KAAK,EAAE,EAAE;YAC9C,OAAO,CAAC,GAAG,CACT,QAAQ,KAAK,GAAG,CAAC,kBACf,aAAa,CAAC,QAChB,mBAAmB,aAAa,CAAC,WAAW,EAAE,CAC/C,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
@@ -0,0 +1,7 @@
1
+ type GenerateCnpjResponse = {
2
+ withMask: string;
3
+ withoutMask: string;
4
+ };
5
+ export declare const calculateCnpjDigit: (cnpj: string) => number;
6
+ export declare const generateCnpj: () => GenerateCnpjResponse;
7
+ export {};
@@ -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"}
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")
@@ -15,5 +16,10 @@ program
15
16
  .description(cpf_1.cpfCommand.description)
16
17
  .option("-a, --amount <amount>", "Quantidade a ser gerado.", (value) => Number(value))
17
18
  .action(cpf_1.cpfCommand.action);
19
+ program
20
+ .command(cnpj_1.cnpjCommand.name)
21
+ .description(cnpj_1.cnpjCommand.description)
22
+ .option("-a, --amount <amount>", "Quantidade a ser gerado.", (value) => Number(value))
23
+ .action(cnpj_1.cnpjCommand.action);
18
24
  program.parse();
19
25
  //# 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,wCAA4C;AAE5C,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,OAAO;KACJ,OAAO,CAAC,gBAAU,CAAC,IAAI,CAAC;KACxB,WAAW,CAAC,gBAAU,CAAC,WAAW,CAAC;KACnC,MAAM,CACL,uBAAuB,EACvB,0BAA0B,EAC1B,CAAC,KAAa,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CACjC;KACA,MAAM,CAAC,gBAAU,CAAC,MAAM,CAAC,CAAC;AAE7B,OAAO,CAAC,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AACA,yCAAoC;AACpC,wCAA4C;AAC5C,0CAA8C;AAE9C,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,OAAO;KACJ,OAAO,CAAC,gBAAU,CAAC,IAAI,CAAC;KACxB,WAAW,CAAC,gBAAU,CAAC,WAAW,CAAC;KACnC,MAAM,CACL,uBAAuB,EACvB,0BAA0B,EAC1B,CAAC,KAAa,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CACjC;KACA,MAAM,CAAC,gBAAU,CAAC,MAAM,CAAC,CAAC;AAE7B,OAAO;KACJ,OAAO,CAAC,kBAAW,CAAC,IAAI,CAAC;KACzB,WAAW,CAAC,kBAAW,CAAC,WAAW,CAAC;KACpC,MAAM,CACL,uBAAuB,EACvB,0BAA0B,EAC1B,CAAC,KAAa,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CACjC;KACA,MAAM,CAAC,kBAAW,CAAC,MAAM,CAAC,CAAC;AAE9B,OAAO,CAAC,KAAK,EAAE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gerar",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
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": "ISC",
18
+ "license": "MIT",
19
19
  "dependencies": {
20
20
  "commander": "^14.0.2"
21
21
  },
@@ -0,0 +1,21 @@
1
+ import { CommandStructure } from "../../shared/utils/command-structure";
2
+ import { generateCnpj } from "./utils";
3
+
4
+ export const cnpjCommand: CommandStructure = {
5
+ name: "cnpj",
6
+ description: "Gera um CNPJ fictício válido.",
7
+ action: (options: { amount?: number }) => {
8
+ const generatedCnpjs = Array.from(
9
+ { length: options.amount ?? 1 },
10
+ generateCnpj
11
+ );
12
+
13
+ generatedCnpjs.forEach((generatedCnpj, index) => {
14
+ console.log(
15
+ `CNPJ ${index + 1}) Com Máscara: ${
16
+ generatedCnpj.withMask
17
+ } - Sem Máscara: ${generatedCnpj.withoutMask}`
18
+ );
19
+ });
20
+ },
21
+ };
@@ -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,4 +1,4 @@
1
- import { describe, it, expect, expectTypeOf } from "vitest";
1
+ import { describe, it, expect } from "vitest";
2
2
  import { calculateCpfDigit, generateCpf } from "../utils";
3
3
 
4
4
  describe("calculateCpfDigit", () => {
package/src/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command } from "commander";
3
3
  import { cpfCommand } from "./commands/cpf";
4
+ import { cnpjCommand } from "./commands/cnpj";
4
5
 
5
6
  const program = new Command();
6
7
 
@@ -22,4 +23,14 @@ program
22
23
  )
23
24
  .action(cpfCommand.action);
24
25
 
26
+ program
27
+ .command(cnpjCommand.name)
28
+ .description(cnpjCommand.description)
29
+ .option(
30
+ "-a, --amount <amount>",
31
+ "Quantidade a ser gerado.",
32
+ (value: string) => Number(value)
33
+ )
34
+ .action(cnpjCommand.action);
35
+
25
36
  program.parse();