dualisia-cli 0.1.0 → 0.1.2
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 +136 -74
- package/bin/dualisia.mjs +163 -155
- package/package.json +46 -37
package/README.md
CHANGED
|
@@ -1,74 +1,136 @@
|
|
|
1
|
-
# dualisia-cli
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
#
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
1
|
+
# dualisia-cli
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/dualisia-cli)
|
|
4
|
+
[](https://github.com/munhoz-iago/dualisia-cli/actions/workflows/ci.yml)
|
|
5
|
+
[](./LICENSE)
|
|
6
|
+
|
|
7
|
+
CLI oficial do [Dualisia](https://dualisia.com.br): apura **CBS** e **IBS** a
|
|
8
|
+
partir de XMLs de NF-e e consulta os dados do escritório pela API REST.
|
|
9
|
+
|
|
10
|
+
Entre 2026 e 2033 a Reforma Tributária brasileira roda em transição: o regime
|
|
11
|
+
atual continua gerando a obrigação enquanto os tributos novos (CBS e IBS,
|
|
12
|
+
LC 214/2025) precisam ser apurados em paralelo. Este CLI põe essa apuração no
|
|
13
|
+
terminal — para conferir uma nota, encadear num script ou deixar um agente
|
|
14
|
+
chamar sem escrever integração.
|
|
15
|
+
|
|
16
|
+
## Instalação
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install -g dualisia-cli
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Ou sem instalar nada:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npx dualisia-cli --help
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Requer Node.js 20 ou superior.
|
|
29
|
+
|
|
30
|
+
## Uso
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Apura CBS e IBS de uma nota — público, sem chave
|
|
34
|
+
dualisia apurar nota.xml --ano 2027
|
|
35
|
+
|
|
36
|
+
# Projeta a carga ano a ano da transição
|
|
37
|
+
dualisia simular nota.xml --anos 2026,2029,2033
|
|
38
|
+
|
|
39
|
+
# Dados do escritório — exige API key
|
|
40
|
+
export DUALISIA_API_KEY=dlai_live_xxx
|
|
41
|
+
dualisia clientes --limit 10
|
|
42
|
+
dualisia documentos --from 2026-01-01 --to 2026-12-31
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Saída de `apurar`:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
Nota 35260612345678000190550010000001231234567890
|
|
49
|
+
Emitente Empresa Teste Ltda (SP)
|
|
50
|
+
Valor total R$ 2.000,00
|
|
51
|
+
Itens 2
|
|
52
|
+
|
|
53
|
+
Ano de referência 2027 · modo projecao
|
|
54
|
+
Regime atual R$ 545,00 (27.25%)
|
|
55
|
+
Regime novo R$ 176,00 (8.8%)
|
|
56
|
+
|
|
57
|
+
Atenção: este ano usa alíquotas ESTIMADAS — dependem de Resolução do Senado
|
|
58
|
+
ainda não publicada.
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`--json` devolve a resposta bruta da API, para encadear com `jq`:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
dualisia apurar nota.xml --ano 2027 --json | jq '.resultado.regimeNovo'
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Comandos
|
|
68
|
+
|
|
69
|
+
| Comando | O que faz | Autenticação |
|
|
70
|
+
| --- | --- | --- |
|
|
71
|
+
| `apurar <arquivo.xml>` | Apura CBS e IBS de uma NF-e (modelo 55 ou 65). | pública |
|
|
72
|
+
| `simular <arquivo.xml>` | Projeta a carga ano a ano, 2026-2033. | pública |
|
|
73
|
+
| `clientes` | Lista os clientes PJ do escritório. | API key |
|
|
74
|
+
| `documentos` | Lista as NF-e já processadas. | API key |
|
|
75
|
+
|
|
76
|
+
A chave é gerada pelo owner do escritório no painel do Dualisia, em
|
|
77
|
+
Configurações → API keys.
|
|
78
|
+
|
|
79
|
+
## Variáveis de ambiente
|
|
80
|
+
|
|
81
|
+
| Variável | Para que serve |
|
|
82
|
+
| --- | --- |
|
|
83
|
+
| `DUALISIA_API_KEY` | API key da organização (`dlai_live_...`). Equivale a `--api-key`. |
|
|
84
|
+
| `DUALISIA_BASE_URL` | Origem da API. Padrão: `https://dualisia.com.br`. Equivale a `--base-url`. |
|
|
85
|
+
|
|
86
|
+
## Códigos de saída
|
|
87
|
+
|
|
88
|
+
| Código | Significado |
|
|
89
|
+
| --- | --- |
|
|
90
|
+
| `0` | Sucesso. |
|
|
91
|
+
| `1` | Erro de uso ou erro 4xx da API. |
|
|
92
|
+
| `2` | Erro 5xx da API. |
|
|
93
|
+
|
|
94
|
+
Erros da API chegam em JSON estruturado, com um campo `code` estável para
|
|
95
|
+
ramificar e um `hint` dizendo o que corrigir. O CLI imprime os dois.
|
|
96
|
+
|
|
97
|
+
## O que este CLI não é
|
|
98
|
+
|
|
99
|
+
O cálculo acontece no servidor: este pacote é um cliente da API do Dualisia,
|
|
100
|
+
não um motor fiscal offline. Ele **não** transmite obrigação acessória à Receita
|
|
101
|
+
ou à SEFAZ, não baixa XML da SEFAZ e não emite parecer fiscal.
|
|
102
|
+
|
|
103
|
+
As alíquotas de 2026 a 2028 são as publicadas na LC 214/2025. De 2029 em diante
|
|
104
|
+
dependem de Resolução do Senado ainda não publicada, e por isso são tratadas
|
|
105
|
+
como estimativas — a saída sempre diz quando é o caso.
|
|
106
|
+
|
|
107
|
+
## Desenvolvimento
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
git clone https://github.com/munhoz-iago/dualisia-cli.git
|
|
111
|
+
cd dualisia-cli
|
|
112
|
+
npm install
|
|
113
|
+
npm test
|
|
114
|
+
node ./bin/dualisia.mjs --help
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Não há etapa de build: os arquivos são publicados como estão.
|
|
118
|
+
|
|
119
|
+
### Publicação
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
npm version patch
|
|
123
|
+
npm publish --otp=123456
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
O npm exige segundo fator para publicar. O `.npmrc` do repositório fixa o
|
|
127
|
+
registry em HTTPS, para não depender da configuração da máquina.
|
|
128
|
+
|
|
129
|
+
## Documentação da API
|
|
130
|
+
|
|
131
|
+
- Portal do desenvolvedor: <https://dualisia.com.br/developers>
|
|
132
|
+
- Especificação OpenAPI 3.1: <https://dualisia.com.br/openapi.json>
|
|
133
|
+
|
|
134
|
+
## Licença
|
|
135
|
+
|
|
136
|
+
MIT — ver [LICENSE](./LICENSE).
|
package/bin/dualisia.mjs
CHANGED
|
@@ -1,155 +1,163 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Binário do CLI. Só faz I/O: lê argv e variáveis de ambiente, chama o núcleo
|
|
4
|
-
* em `src/index.mjs`, escreve em stdout/stderr e define o código de saída.
|
|
5
|
-
*
|
|
6
|
-
* Toda a lógica testável vive no núcleo — este arquivo não tem regra de
|
|
7
|
-
* negócio de propósito.
|
|
8
|
-
*/
|
|
9
|
-
import { readFile } from "node:fs/promises";
|
|
10
|
-
import { basename } from "node:path";
|
|
11
|
-
import { createRequire } from "node:module";
|
|
12
|
-
|
|
13
|
-
import {
|
|
14
|
-
CliError,
|
|
15
|
-
COMMANDS,
|
|
16
|
-
USAGE,
|
|
17
|
-
apurar,
|
|
18
|
-
formatApuracao,
|
|
19
|
-
formatLista,
|
|
20
|
-
listarClientes,
|
|
21
|
-
listarDocumentos,
|
|
22
|
-
parseArgs,
|
|
23
|
-
simular,
|
|
24
|
-
} from "../src/index.mjs";
|
|
25
|
-
|
|
26
|
-
const require = createRequire(import.meta.url);
|
|
27
|
-
const { version } = require("../package.json");
|
|
28
|
-
|
|
29
|
-
function fail(message, hint) {
|
|
30
|
-
process.stderr.write(`erro: ${message}\n`);
|
|
31
|
-
if (hint) process.stderr.write(`${hint}\n`);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async function readXml(path) {
|
|
35
|
-
if (!path) {
|
|
36
|
-
throw new CliError("Informe o caminho do arquivo XML.", {
|
|
37
|
-
hint: "Exemplo: dualisia apurar nota.xml",
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
try {
|
|
41
|
-
const buffer = await readFile(path);
|
|
42
|
-
return { file: new Blob([buffer]), filename: basename(path) };
|
|
43
|
-
} catch {
|
|
44
|
-
throw new CliError(`Não foi possível ler o arquivo: ${path}`, {
|
|
45
|
-
hint: "Confira o caminho e a permissão de leitura.",
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
async function main(argv) {
|
|
51
|
-
const { command, positionals, flags } = parseArgs(argv);
|
|
52
|
-
|
|
53
|
-
if (flags.version) {
|
|
54
|
-
process.stdout.write(`${version}\n`);
|
|
55
|
-
return 0;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
`
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Binário do CLI. Só faz I/O: lê argv e variáveis de ambiente, chama o núcleo
|
|
4
|
+
* em `src/index.mjs`, escreve em stdout/stderr e define o código de saída.
|
|
5
|
+
*
|
|
6
|
+
* Toda a lógica testável vive no núcleo — este arquivo não tem regra de
|
|
7
|
+
* negócio de propósito.
|
|
8
|
+
*/
|
|
9
|
+
import { readFile } from "node:fs/promises";
|
|
10
|
+
import { basename } from "node:path";
|
|
11
|
+
import { createRequire } from "node:module";
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
CliError,
|
|
15
|
+
COMMANDS,
|
|
16
|
+
USAGE,
|
|
17
|
+
apurar,
|
|
18
|
+
formatApuracao,
|
|
19
|
+
formatLista,
|
|
20
|
+
listarClientes,
|
|
21
|
+
listarDocumentos,
|
|
22
|
+
parseArgs,
|
|
23
|
+
simular,
|
|
24
|
+
} from "../src/index.mjs";
|
|
25
|
+
|
|
26
|
+
const require = createRequire(import.meta.url);
|
|
27
|
+
const { version } = require("../package.json");
|
|
28
|
+
|
|
29
|
+
function fail(message, hint) {
|
|
30
|
+
process.stderr.write(`erro: ${message}\n`);
|
|
31
|
+
if (hint) process.stderr.write(`${hint}\n`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function readXml(path) {
|
|
35
|
+
if (!path) {
|
|
36
|
+
throw new CliError("Informe o caminho do arquivo XML.", {
|
|
37
|
+
hint: "Exemplo: dualisia apurar nota.xml",
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
const buffer = await readFile(path);
|
|
42
|
+
return { file: new Blob([buffer]), filename: basename(path) };
|
|
43
|
+
} catch {
|
|
44
|
+
throw new CliError(`Não foi possível ler o arquivo: ${path}`, {
|
|
45
|
+
hint: "Confira o caminho e a permissão de leitura.",
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async function main(argv) {
|
|
51
|
+
const { command, positionals, flags } = parseArgs(argv);
|
|
52
|
+
|
|
53
|
+
if (flags.version) {
|
|
54
|
+
process.stdout.write(`${version}\n`);
|
|
55
|
+
return 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Ajuda pedida explicitamente é sucesso: vai pro stdout e sai 0, senão
|
|
59
|
+
// `dualisia --help && algo` quebra e o texto polui um pipe de dados.
|
|
60
|
+
if (flags.help) {
|
|
61
|
+
process.stdout.write(USAGE);
|
|
62
|
+
return 0;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Invocação sem comando é erro de uso: o texto vai pro stderr e o código é 1.
|
|
66
|
+
if (!command) {
|
|
67
|
+
process.stderr.write(USAGE);
|
|
68
|
+
return 1;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const spec = COMMANDS[command];
|
|
72
|
+
if (!spec) {
|
|
73
|
+
fail(
|
|
74
|
+
`Comando desconhecido: ${command}`,
|
|
75
|
+
"Rode `dualisia --help` para ver os comandos disponíveis.",
|
|
76
|
+
);
|
|
77
|
+
return 1;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const apiKey = flags["api-key"] ?? process.env.DUALISIA_API_KEY ?? null;
|
|
81
|
+
if (spec.needsKey && !apiKey) {
|
|
82
|
+
fail(
|
|
83
|
+
`O comando \`${command}\` exige uma API key.`,
|
|
84
|
+
"Defina DUALISIA_API_KEY ou passe --api-key. Gere a chave em /dashboard/settings/api-keys.",
|
|
85
|
+
);
|
|
86
|
+
return 1;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const baseUrl = flags["base-url"] ?? process.env.DUALISIA_BASE_URL;
|
|
90
|
+
const raw = flags.json === true;
|
|
91
|
+
|
|
92
|
+
let payload;
|
|
93
|
+
|
|
94
|
+
switch (command) {
|
|
95
|
+
case "apurar": {
|
|
96
|
+
const { file, filename } = await readXml(positionals[0]);
|
|
97
|
+
payload = await apurar({ baseUrl, file, filename, ano: flags.ano });
|
|
98
|
+
process.stdout.write(
|
|
99
|
+
(raw ? JSON.stringify(payload, null, 2) : formatApuracao(payload)) + "\n",
|
|
100
|
+
);
|
|
101
|
+
return 0;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
case "simular": {
|
|
105
|
+
const { file, filename } = await readXml(positionals[0]);
|
|
106
|
+
payload = await simular({ baseUrl, file, filename, anos: flags.anos });
|
|
107
|
+
process.stdout.write(JSON.stringify(payload, null, 2) + "\n");
|
|
108
|
+
return 0;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
case "clientes": {
|
|
112
|
+
payload = await listarClientes({
|
|
113
|
+
baseUrl,
|
|
114
|
+
apiKey,
|
|
115
|
+
limit: flags.limit,
|
|
116
|
+
offset: flags.offset,
|
|
117
|
+
});
|
|
118
|
+
process.stdout.write(
|
|
119
|
+
(raw
|
|
120
|
+
? JSON.stringify(payload, null, 2)
|
|
121
|
+
: formatLista(payload, ["cnpj", "razao_social", "uf"])) + "\n",
|
|
122
|
+
);
|
|
123
|
+
return 0;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
case "documentos": {
|
|
127
|
+
payload = await listarDocumentos({
|
|
128
|
+
baseUrl,
|
|
129
|
+
apiKey,
|
|
130
|
+
clientId: flags["client-id"],
|
|
131
|
+
from: flags.from,
|
|
132
|
+
to: flags.to,
|
|
133
|
+
limit: flags.limit,
|
|
134
|
+
offset: flags.offset,
|
|
135
|
+
});
|
|
136
|
+
process.stdout.write(
|
|
137
|
+
(raw
|
|
138
|
+
? JSON.stringify(payload, null, 2)
|
|
139
|
+
: formatLista(payload, [
|
|
140
|
+
"chave_acesso",
|
|
141
|
+
"data_emissao",
|
|
142
|
+
"valor_total",
|
|
143
|
+
])) + "\n",
|
|
144
|
+
);
|
|
145
|
+
return 0;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
default:
|
|
149
|
+
return 1;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
try {
|
|
154
|
+
process.exitCode = await main(process.argv.slice(2));
|
|
155
|
+
} catch (error) {
|
|
156
|
+
if (error instanceof CliError) {
|
|
157
|
+
fail(error.message, error.hint);
|
|
158
|
+
process.exitCode = error.exitCode;
|
|
159
|
+
} else {
|
|
160
|
+
fail(error?.message ?? String(error));
|
|
161
|
+
process.exitCode = 1;
|
|
162
|
+
}
|
|
163
|
+
}
|
package/package.json
CHANGED
|
@@ -1,37 +1,46 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "dualisia-cli",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "CLI oficial do Dualisia: apura CBS e IBS de XMLs de NF-e e consulta os dados do escritório pela API REST.",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"cbs",
|
|
7
|
-
"ibs",
|
|
8
|
-
"reforma-tributaria",
|
|
9
|
-
"nfe",
|
|
10
|
-
"fiscal",
|
|
11
|
-
"brasil",
|
|
12
|
-
"dualisia"
|
|
13
|
-
],
|
|
14
|
-
"homepage": "https://dualisia.com.br/developers",
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"src/index.mjs"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
"
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "dualisia-cli",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "CLI oficial do Dualisia: apura CBS e IBS de XMLs de NF-e e consulta os dados do escritório pela API REST.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"cbs",
|
|
7
|
+
"ibs",
|
|
8
|
+
"reforma-tributaria",
|
|
9
|
+
"nfe",
|
|
10
|
+
"fiscal",
|
|
11
|
+
"brasil",
|
|
12
|
+
"dualisia"
|
|
13
|
+
],
|
|
14
|
+
"homepage": "https://dualisia.com.br/developers",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/munhoz-iago/dualisia-cli.git"
|
|
18
|
+
},
|
|
19
|
+
"bugs": "https://github.com/munhoz-iago/dualisia-cli/issues",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"author": "Dualisia Tecnologia",
|
|
22
|
+
"type": "module",
|
|
23
|
+
"bin": {
|
|
24
|
+
"dualisia": "bin/dualisia.mjs"
|
|
25
|
+
},
|
|
26
|
+
"exports": {
|
|
27
|
+
".": "./src/index.mjs"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"bin",
|
|
31
|
+
"src/index.mjs",
|
|
32
|
+
"README.md",
|
|
33
|
+
"LICENSE"
|
|
34
|
+
],
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=20"
|
|
37
|
+
},
|
|
38
|
+
"scripts": {
|
|
39
|
+
"test": "vitest run",
|
|
40
|
+
"test:watch": "vitest",
|
|
41
|
+
"smoke": "node ./bin/dualisia.mjs --help"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"vitest": "^4.1.5"
|
|
45
|
+
}
|
|
46
|
+
}
|