@useinvio/nfse-sdk 3.0.0 → 3.2.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/CHANGELOG.md +176 -0
- package/README.en.md +146 -0
- package/README.md +77 -518
- package/dist/agent.d.ts +131 -0
- package/dist/agent.js +551 -0
- package/dist/agent.js.map +1 -0
- package/dist/certificate.d.ts +96 -0
- package/dist/certificate.js +218 -0
- package/dist/certificate.js.map +1 -0
- package/dist/certificateValidation.d.ts +11 -6
- package/dist/certificateValidation.js +23 -12
- package/dist/certificateValidation.js.map +1 -1
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +520 -0
- package/dist/cli.js.map +1 -0
- package/dist/cliBin.d.ts +2 -0
- package/dist/cliBin.js +6 -0
- package/dist/cliBin.js.map +1 -0
- package/dist/cliExample.d.ts +6 -0
- package/dist/cliExample.js +29 -0
- package/dist/cliExample.js.map +1 -0
- package/dist/client.d.ts +51 -4
- package/dist/client.js +41 -10
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +3 -0
- package/dist/config.js +8 -0
- package/dist/config.js.map +1 -1
- package/dist/consultas.d.ts +34 -0
- package/dist/consultas.js +61 -0
- package/dist/consultas.js.map +1 -0
- package/dist/dpsJson.js +1 -41
- package/dist/dpsJson.js.map +1 -1
- package/dist/dpsJsonSchema.d.ts +17 -0
- package/dist/dpsJsonSchema.js +184 -0
- package/dist/dpsJsonSchema.js.map +1 -0
- package/dist/emissaoNota.d.ts +11 -6
- package/dist/emissaoNota.js +10 -6
- package/dist/emissaoNota.js.map +1 -1
- package/dist/eventoJson.d.ts +76 -0
- package/dist/eventoJson.js +128 -0
- package/dist/eventoJson.js.map +1 -0
- package/dist/eventosNfse.d.ts +38 -0
- package/dist/eventosNfse.js +73 -0
- package/dist/eventosNfse.js.map +1 -0
- package/dist/fiscalDomains.d.ts +22 -0
- package/dist/fiscalDomains.js +99 -0
- package/dist/fiscalDomains.js.map +1 -0
- package/dist/fiscalValidation.js +21 -53
- package/dist/fiscalValidation.js.map +1 -1
- package/dist/gzipB64.d.ts +5 -0
- package/dist/gzipB64.js +12 -0
- package/dist/gzipB64.js.map +1 -1
- package/dist/index.d.ts +22 -7
- package/dist/index.js +11 -4
- package/dist/index.js.map +1 -1
- package/dist/jsonSchemaCheck.d.ts +12 -0
- package/dist/jsonSchemaCheck.js +70 -0
- package/dist/jsonSchemaCheck.js.map +1 -0
- package/dist/loadPfx.d.ts +2 -0
- package/dist/loadPfx.js +2 -1
- package/dist/loadPfx.js.map +1 -1
- package/dist/mcpCli.d.ts +2 -0
- package/dist/mcpCli.js +7 -0
- package/dist/mcpCli.js.map +1 -0
- package/dist/mcpServer.d.ts +49 -0
- package/dist/mcpServer.js +159 -0
- package/dist/mcpServer.js.map +1 -0
- package/dist/nfseXml.d.ts +48 -0
- package/dist/nfseXml.js +86 -0
- package/dist/nfseXml.js.map +1 -0
- package/dist/rejeicoes.d.ts +50 -0
- package/dist/rejeicoes.js +62 -0
- package/dist/rejeicoes.js.map +1 -0
- package/dist/rejeicoesCatalog.d.ts +10 -0
- package/dist/rejeicoesCatalog.js +4449 -0
- package/dist/rejeicoesCatalog.js.map +1 -0
- package/dist/sefinClient.d.ts +107 -7
- package/dist/sefinClient.js +232 -22
- package/dist/sefinClient.js.map +1 -1
- package/dist/signXml.d.ts +3 -3
- package/dist/signXml.js +17 -7
- package/dist/signXml.js.map +1 -1
- package/dist/testing.d.ts +80 -0
- package/dist/testing.js +285 -0
- package/dist/testing.js.map +1 -0
- package/dist/xmlBuild.d.ts +11 -0
- package/dist/xmlBuild.js +44 -0
- package/dist/xmlBuild.js.map +1 -0
- package/dist/xmlInspection.d.ts +1 -1
- package/dist/xmlInspection.js +10 -9
- package/dist/xmlInspection.js.map +1 -1
- package/dist/xsdValidation.d.ts +24 -5
- package/dist/xsdValidation.js +97 -67
- package/dist/xsdValidation.js.map +1 -1
- package/docs/README.md +47 -0
- package/docs/REGRAS_NEGOCIO_EMISSAO.md +8 -8
- package/docs/conceitos/como-funciona.md +87 -0
- package/docs/guias/adn.md +51 -0
- package/docs/guias/agentes-ia.md +111 -0
- package/docs/guias/cancelar.md +70 -0
- package/docs/guias/certificado.md +88 -0
- package/docs/guias/cli.md +68 -0
- package/docs/guias/consultar.md +54 -0
- package/docs/guias/emitir.md +172 -0
- package/docs/guias/recuperar-emissao.md +33 -0
- package/docs/guias/rejeicoes.md +70 -0
- package/docs/guias/testes.md +79 -0
- package/docs/guias/timeouts.md +33 -0
- package/docs/referencia/ambientes.md +35 -0
- package/docs/referencia/api.md +137 -0
- package/docs/referencia/erros.md +55 -0
- package/docs/tutoriais/primeira-nfse.md +130 -0
- package/examples/README.md +3 -1
- package/examples/cancel-nfse.ts +29 -0
- package/examples/client-resource.ts +3 -5
- package/examples/emit-homologation.ts +3 -4
- package/examples/handle-errors.ts +3 -3
- package/examples/recover-emission.ts +29 -0
- package/llms.txt +97 -82
- package/package.json +31 -6
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model Context Protocol server for the NFS-e Nacional, over stdio.
|
|
3
|
+
*
|
|
4
|
+
* A tools-only MCP server needs nothing beyond JSON-RPC 2.0 over newline-delimited
|
|
5
|
+
* stdin/stdout, so this module has no dependencies besides the SDK itself.
|
|
6
|
+
* Run it with `npx -y @useinvio/nfse-mcp` (or `npx -y -p @useinvio/nfse-sdk nfse-mcp`).
|
|
7
|
+
*
|
|
8
|
+
* Configuration comes from the host environment, never from the model:
|
|
9
|
+
* NFSE_CERT_PATH / NFSE_CERT_BASE64 + NFSE_CERT_PASSWORD / NFSE_CERT_PASSWORD_FILE
|
|
10
|
+
* NFSE_AMBIENTE=restrita|producao (default: restrita)
|
|
11
|
+
* NFSE_MCP_ALLOW_WRITE=1 (enables prepare/confirm emission and cancellation)
|
|
12
|
+
* NFSE_MCP_MOCK=1 (in-process mock SEFIN and a test certificate; no real calls)
|
|
13
|
+
*/
|
|
14
|
+
import { createInterface } from 'node:readline';
|
|
15
|
+
import { createNfseAgentToolkit } from './agent.js';
|
|
16
|
+
import { NfseCertificate } from './certificate.js';
|
|
17
|
+
export const NFSE_MCP_ENV = {
|
|
18
|
+
ambiente: 'NFSE_AMBIENTE',
|
|
19
|
+
allowWrite: 'NFSE_MCP_ALLOW_WRITE',
|
|
20
|
+
mock: 'NFSE_MCP_MOCK',
|
|
21
|
+
};
|
|
22
|
+
const SUPPORTED_PROTOCOL_VERSIONS = ['2025-11-25', '2025-06-18', '2025-03-26', '2024-11-05'];
|
|
23
|
+
const SERVER_INFO = { name: 'nfse-nacional', title: 'NFS-e Nacional (SEFIN)', version: '0.1.0' };
|
|
24
|
+
const INSTRUCTIONS = [
|
|
25
|
+
'Ferramentas para a NFS-e Nacional (SEFIN). O ambiente e o certificado sao definidos pelo host.',
|
|
26
|
+
'Antes de emitir, use validate_dps ate valid=true. Nao invente codigos fiscais (cTribNac, regime, tributacao): pergunte ao usuario.',
|
|
27
|
+
'Emissao e cancelamento tem duas etapas: prepare_* devolve um resumo; mostre-o e so chame confirm_* apos aprovacao explicita do usuario.',
|
|
28
|
+
'Depois de uma rejeicao, use explain_rejection com os codigos para explicar a regra oficial ao usuario.',
|
|
29
|
+
'Depois de timeout na emissao, nunca prepare uma nova DPS: repita confirm_nfse_emission ou use recover_nfse_by_dps.',
|
|
30
|
+
].join('\n');
|
|
31
|
+
function toolDescriptor(tool, protocolVersion) {
|
|
32
|
+
const modern = protocolVersion >= '2025-06-18';
|
|
33
|
+
return {
|
|
34
|
+
name: tool.name,
|
|
35
|
+
...(modern ? { title: tool.title } : {}),
|
|
36
|
+
description: tool.description,
|
|
37
|
+
inputSchema: tool.inputSchema,
|
|
38
|
+
...(modern ? { outputSchema: tool.outputSchema } : {}),
|
|
39
|
+
annotations: { title: tool.title, ...tool.annotations },
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Transport-independent MCP server. `handle` takes one parsed JSON-RPC message
|
|
44
|
+
* and returns the response, or `undefined` for notifications.
|
|
45
|
+
*/
|
|
46
|
+
export function createNfseMcpServer(options = {}) {
|
|
47
|
+
const { tools } = createNfseAgentToolkit({ allowWrite: options.allowWrite });
|
|
48
|
+
const context = { pfx: options.certificate, ambiente: options.ambiente ?? 'restrita' };
|
|
49
|
+
let protocolVersion = SUPPORTED_PROTOCOL_VERSIONS[0];
|
|
50
|
+
async function callTool(params) {
|
|
51
|
+
const tool = tools.find((t) => t.name === params?.name);
|
|
52
|
+
if (!tool) {
|
|
53
|
+
return { content: [{ type: 'text', text: `Ferramenta desconhecida: ${String(params?.name)}` }], isError: true };
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
const output = await tool.run(params?.arguments ?? {}, context);
|
|
57
|
+
const failed = output?.ok === false;
|
|
58
|
+
return {
|
|
59
|
+
content: [{ type: 'text', text: JSON.stringify(output, null, 2) }],
|
|
60
|
+
...(protocolVersion >= '2025-06-18' ? { structuredContent: output } : {}),
|
|
61
|
+
...(failed ? { isError: true } : {}),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
options.log?.(`tool ${tool.name} failed: ${error instanceof Error ? error.stack ?? error.message : String(error)}`);
|
|
66
|
+
return {
|
|
67
|
+
content: [{ type: 'text', text: `Falha de infraestrutura em ${tool.name}: ${error instanceof Error ? error.message : String(error)}` }],
|
|
68
|
+
isError: true,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async function handle(message) {
|
|
73
|
+
const isRequest = message.id !== undefined && message.id !== null;
|
|
74
|
+
const reply = (result) => ({ jsonrpc: '2.0', id: message.id ?? null, result });
|
|
75
|
+
const fail = (code, text) => ({ jsonrpc: '2.0', id: message.id ?? null, error: { code, message: text } });
|
|
76
|
+
switch (message.method) {
|
|
77
|
+
case 'initialize': {
|
|
78
|
+
const requested = String(message.params?.protocolVersion ?? '');
|
|
79
|
+
protocolVersion = SUPPORTED_PROTOCOL_VERSIONS.includes(requested) ? requested : SUPPORTED_PROTOCOL_VERSIONS[0];
|
|
80
|
+
return reply({
|
|
81
|
+
protocolVersion,
|
|
82
|
+
capabilities: { tools: { listChanged: false } },
|
|
83
|
+
serverInfo: SERVER_INFO,
|
|
84
|
+
instructions: INSTRUCTIONS,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
case 'ping':
|
|
88
|
+
return reply({});
|
|
89
|
+
case 'tools/list':
|
|
90
|
+
return reply({ tools: tools.map((tool) => toolDescriptor(tool, protocolVersion)) });
|
|
91
|
+
case 'tools/call':
|
|
92
|
+
return reply(await callTool(message.params));
|
|
93
|
+
default:
|
|
94
|
+
if (!isRequest)
|
|
95
|
+
return undefined; // notifications/initialized, notifications/cancelled, ...
|
|
96
|
+
return fail(-32601, `Method not found: ${message.method}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return { handle, tools, context };
|
|
100
|
+
}
|
|
101
|
+
function truthy(value) {
|
|
102
|
+
return ['1', 'true', 'yes', 'on'].includes(String(value ?? '').trim().toLowerCase());
|
|
103
|
+
}
|
|
104
|
+
/** Reads server options from environment variables; see the module comment. */
|
|
105
|
+
export async function nfseMcpOptionsFromEnv(env = process.env) {
|
|
106
|
+
const mock = truthy(env[NFSE_MCP_ENV.mock]);
|
|
107
|
+
const ambiente = (env[NFSE_MCP_ENV.ambiente] ?? 'restrita').trim().toLowerCase();
|
|
108
|
+
if (ambiente !== 'restrita' && ambiente !== 'producao') {
|
|
109
|
+
throw new Error(`${NFSE_MCP_ENV.ambiente} deve ser "restrita" ou "producao" (recebido "${ambiente}").`);
|
|
110
|
+
}
|
|
111
|
+
if (mock && ambiente === 'producao')
|
|
112
|
+
throw new Error(`${NFSE_MCP_ENV.mock}=1 nao pode ser usado com ${NFSE_MCP_ENV.ambiente}=producao.`);
|
|
113
|
+
const hasCertificate = Boolean(env.NFSE_CERT_PATH || env.NFSE_CERT_BASE64);
|
|
114
|
+
let certificate = hasCertificate ? NfseCertificate.fromEnv(env) : undefined;
|
|
115
|
+
if (mock) {
|
|
116
|
+
const { createTestCertificate, installMockSefin } = await import('./testing.js');
|
|
117
|
+
installMockSefin();
|
|
118
|
+
certificate ??= createTestCertificate().certificate;
|
|
119
|
+
}
|
|
120
|
+
return { certificate, ambiente, allowWrite: truthy(env[NFSE_MCP_ENV.allowWrite]), mock };
|
|
121
|
+
}
|
|
122
|
+
/** Runs the server on stdin/stdout until stdin closes. Logs go to stderr only. */
|
|
123
|
+
export async function runNfseMcpStdio(options) {
|
|
124
|
+
const log = (message) => process.stderr.write(`[nfse-mcp] ${message}\n`);
|
|
125
|
+
const resolved = options ?? await nfseMcpOptionsFromEnv();
|
|
126
|
+
const server = createNfseMcpServer({ ...resolved, log });
|
|
127
|
+
const certificate = resolved.certificate instanceof NfseCertificate ? resolved.certificate : undefined;
|
|
128
|
+
log(`ambiente=${resolved.ambiente ?? 'restrita'} escrita=${resolved.allowWrite ? 'habilitada' : 'desabilitada'} `
|
|
129
|
+
+ `certificado=${certificate ? `${certificate.cnpj ?? certificate.cpf ?? 'sem documento'} (vence ${certificate.notAfter.toISOString().slice(0, 10)})` : resolved.certificate ? 'legado' : 'ausente'}`
|
|
130
|
+
+ `${resolved.mock ? ' mock=SEFIN simulada' : ''}`);
|
|
131
|
+
const write = (response) => process.stdout.write(`${JSON.stringify(response)}\n`);
|
|
132
|
+
const lines = createInterface({ input: process.stdin, crlfDelay: Infinity });
|
|
133
|
+
const inflight = new Set();
|
|
134
|
+
for await (const line of lines) {
|
|
135
|
+
if (!line.trim())
|
|
136
|
+
continue;
|
|
137
|
+
let message;
|
|
138
|
+
try {
|
|
139
|
+
message = JSON.parse(line);
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
write({ jsonrpc: '2.0', id: null, error: { code: -32700, message: 'Parse error' } });
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
for (const item of Array.isArray(message) ? message : [message]) {
|
|
146
|
+
if (!item || typeof item.method !== 'string')
|
|
147
|
+
continue; // responses from the client are not expected
|
|
148
|
+
const task = server.handle(item).then((response) => { if (response)
|
|
149
|
+
write(response); }, (error) => {
|
|
150
|
+
log(`request failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
151
|
+
if (item.id !== undefined && item.id !== null)
|
|
152
|
+
write({ jsonrpc: '2.0', id: item.id, error: { code: -32603, message: 'Internal error' } });
|
|
153
|
+
}).finally(() => inflight.delete(task));
|
|
154
|
+
inflight.add(task);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
await Promise.all(inflight);
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=mcpServer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcpServer.js","sourceRoot":"","sources":["../mcpServer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Ambiente } from './config.js';
|
|
2
|
+
export interface NfsePessoaResumo {
|
|
3
|
+
CNPJ?: string;
|
|
4
|
+
CPF?: string;
|
|
5
|
+
NIF?: string;
|
|
6
|
+
IM?: string;
|
|
7
|
+
xNome?: string;
|
|
8
|
+
}
|
|
9
|
+
/** Typed view of the authorized NFS-e fields most integrations need. Values are kept as XML strings. */
|
|
10
|
+
export interface NfseResumo {
|
|
11
|
+
chaveAcesso: string;
|
|
12
|
+
/** Numero da NFS-e. */
|
|
13
|
+
nNFSe: string;
|
|
14
|
+
/** Numero do documento fiscal no ADN. */
|
|
15
|
+
nDFSe: string;
|
|
16
|
+
/** Situacao (TStat), ex.: "100" = NFS-e gerada. */
|
|
17
|
+
cStat: string;
|
|
18
|
+
/** Data/hora de processamento (UTC). */
|
|
19
|
+
dhProc: string;
|
|
20
|
+
ambiente: Ambiente;
|
|
21
|
+
xLocEmi: string;
|
|
22
|
+
xLocPrestacao: string;
|
|
23
|
+
cLocIncid?: string;
|
|
24
|
+
xLocIncid?: string;
|
|
25
|
+
xTribNac: string;
|
|
26
|
+
emitente: NfsePessoaResumo;
|
|
27
|
+
tomador?: NfsePessoaResumo;
|
|
28
|
+
dps: {
|
|
29
|
+
id: string;
|
|
30
|
+
serie: string;
|
|
31
|
+
nDPS: string;
|
|
32
|
+
dhEmi: string;
|
|
33
|
+
dCompet: string;
|
|
34
|
+
};
|
|
35
|
+
valores: {
|
|
36
|
+
vServ?: string;
|
|
37
|
+
vBC?: string;
|
|
38
|
+
pAliqAplic?: string;
|
|
39
|
+
vISSQN?: string;
|
|
40
|
+
vTotalRet?: string;
|
|
41
|
+
vLiq: string;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Reads an authorized NFS-e XML (layout v1.01) into a typed summary.
|
|
46
|
+
* The XML is parsed without DTDs, external entities or network access.
|
|
47
|
+
*/
|
|
48
|
+
export declare function lerNfse(nfseXml: string): NfseResumo;
|
package/dist/nfseXml.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { directChildren, parseNfseXml } from './xmlInspection.js';
|
|
2
|
+
function child(element, ...path) {
|
|
3
|
+
let current = element;
|
|
4
|
+
for (const name of path) {
|
|
5
|
+
if (!current)
|
|
6
|
+
return undefined;
|
|
7
|
+
current = directChildren(current, name)[0];
|
|
8
|
+
}
|
|
9
|
+
return current;
|
|
10
|
+
}
|
|
11
|
+
function text(element, ...path) {
|
|
12
|
+
const value = child(element, ...path)?.textContent ?? undefined;
|
|
13
|
+
return value === '' ? undefined : value;
|
|
14
|
+
}
|
|
15
|
+
function required(element, ...path) {
|
|
16
|
+
const value = text(element, ...path);
|
|
17
|
+
if (value === undefined)
|
|
18
|
+
throw new Error(`XML da NFS-e sem o campo obrigatorio ${path.join('/')}.`);
|
|
19
|
+
return value;
|
|
20
|
+
}
|
|
21
|
+
function pessoa(element) {
|
|
22
|
+
if (!element)
|
|
23
|
+
return undefined;
|
|
24
|
+
const result = {};
|
|
25
|
+
for (const field of ['CNPJ', 'CPF', 'NIF', 'IM', 'xNome']) {
|
|
26
|
+
const value = text(element, field);
|
|
27
|
+
if (value !== undefined)
|
|
28
|
+
result[field] = value;
|
|
29
|
+
}
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Reads an authorized NFS-e XML (layout v1.01) into a typed summary.
|
|
34
|
+
* The XML is parsed without DTDs, external entities or network access.
|
|
35
|
+
*/
|
|
36
|
+
export function lerNfse(nfseXml) {
|
|
37
|
+
const root = parseNfseXml(nfseXml, 'NFSe');
|
|
38
|
+
const inf = child(root, 'infNFSe');
|
|
39
|
+
const id = inf?.getAttribute('Id') ?? '';
|
|
40
|
+
if (!/^NFS\d{50}$/.test(id))
|
|
41
|
+
throw new Error('XML da NFS-e sem Id valido em <infNFSe>.');
|
|
42
|
+
const infDps = child(inf, 'DPS', 'infDPS');
|
|
43
|
+
const tpAmb = required(infDps, 'tpAmb');
|
|
44
|
+
const resumo = {
|
|
45
|
+
chaveAcesso: id.slice(3),
|
|
46
|
+
nNFSe: required(inf, 'nNFSe'),
|
|
47
|
+
nDFSe: required(inf, 'nDFSe'),
|
|
48
|
+
cStat: required(inf, 'cStat'),
|
|
49
|
+
dhProc: required(inf, 'dhProc'),
|
|
50
|
+
ambiente: tpAmb === '1' ? 'producao' : 'restrita',
|
|
51
|
+
xLocEmi: required(inf, 'xLocEmi'),
|
|
52
|
+
xLocPrestacao: required(inf, 'xLocPrestacao'),
|
|
53
|
+
xTribNac: required(inf, 'xTribNac'),
|
|
54
|
+
emitente: pessoa(child(inf, 'emit')),
|
|
55
|
+
dps: {
|
|
56
|
+
id: infDps?.getAttribute('Id') ?? '',
|
|
57
|
+
serie: required(infDps, 'serie'),
|
|
58
|
+
nDPS: required(infDps, 'nDPS'),
|
|
59
|
+
dhEmi: required(infDps, 'dhEmi'),
|
|
60
|
+
dCompet: required(infDps, 'dCompet'),
|
|
61
|
+
},
|
|
62
|
+
valores: {
|
|
63
|
+
vServ: text(infDps, 'valores', 'vServPrest', 'vServ'),
|
|
64
|
+
vBC: text(inf, 'valores', 'vBC'),
|
|
65
|
+
pAliqAplic: text(inf, 'valores', 'pAliqAplic'),
|
|
66
|
+
vISSQN: text(inf, 'valores', 'vISSQN'),
|
|
67
|
+
vTotalRet: text(inf, 'valores', 'vTotalRet'),
|
|
68
|
+
vLiq: required(inf, 'valores', 'vLiq'),
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
const cLocIncid = text(inf, 'cLocIncid');
|
|
72
|
+
const xLocIncid = text(inf, 'xLocIncid');
|
|
73
|
+
const tomador = pessoa(child(infDps, 'toma'));
|
|
74
|
+
if (cLocIncid)
|
|
75
|
+
resumo.cLocIncid = cLocIncid;
|
|
76
|
+
if (xLocIncid)
|
|
77
|
+
resumo.xLocIncid = xLocIncid;
|
|
78
|
+
if (tomador)
|
|
79
|
+
resumo.tomador = tomador;
|
|
80
|
+
for (const key of Object.keys(resumo.valores)) {
|
|
81
|
+
if (resumo.valores[key] === undefined)
|
|
82
|
+
delete resumo.valores[key];
|
|
83
|
+
}
|
|
84
|
+
return resumo;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=nfseXml.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nfseXml.js","sourceRoot":"","sources":["../nfseXml.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { SefinErro } from './sefinClient.js';
|
|
2
|
+
export { REJEICOES_FONTES } from './rejeicoesCatalog.js';
|
|
3
|
+
/** One business rule from the official SEFIN/ADN annexes. Text is kept verbatim. */
|
|
4
|
+
export interface RejeicaoOficial {
|
|
5
|
+
/** Error code, e.g. "E0014". */
|
|
6
|
+
codigo: string;
|
|
7
|
+
/** Official error message returned by SEFIN. */
|
|
8
|
+
mensagem: string;
|
|
9
|
+
/** Business rule that triggers the rejection. */
|
|
10
|
+
regra: string;
|
|
11
|
+
/** XML path of the field the rule checks, when the annex names one. */
|
|
12
|
+
campo?: string;
|
|
13
|
+
/** 1 = layout consistency, 2 = national rules, 3 = municipal rules. */
|
|
14
|
+
nivel?: number;
|
|
15
|
+
/** Index into {@link REJEICOES_FONTES}. */
|
|
16
|
+
fonte: number;
|
|
17
|
+
/** Annex sheet the rule comes from. */
|
|
18
|
+
planilha: string;
|
|
19
|
+
}
|
|
20
|
+
export interface ExplicacaoRejeicao {
|
|
21
|
+
codigo: string;
|
|
22
|
+
/** False when the code is not in the bundled catalog (e.g. a newer rule or an SDK-side code). */
|
|
23
|
+
conhecida: boolean;
|
|
24
|
+
/** What SEFIN said, when explaining a received error. */
|
|
25
|
+
descricaoRecebida?: string;
|
|
26
|
+
complemento?: string;
|
|
27
|
+
mensagemOficial?: string;
|
|
28
|
+
regra?: string;
|
|
29
|
+
campo?: string;
|
|
30
|
+
nivel?: number;
|
|
31
|
+
/** Where to look: official annex and, when known, the SDK documentation. */
|
|
32
|
+
fonte?: {
|
|
33
|
+
documento: string;
|
|
34
|
+
url: string;
|
|
35
|
+
};
|
|
36
|
+
/** Short, code-independent hint about what usually fixes this class of rule. */
|
|
37
|
+
dica?: string;
|
|
38
|
+
}
|
|
39
|
+
/** Looks up an official rule by code ("E0014", "e0014" or "0014"). */
|
|
40
|
+
export declare function buscarRejeicao(codigo: string): RejeicaoOficial | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Explains a SEFIN error code or a received `SefinErro` with the official
|
|
43
|
+
* message, rule and field from the published annexes. Never invents a cause:
|
|
44
|
+
* unknown codes come back with `conhecida: false`.
|
|
45
|
+
*/
|
|
46
|
+
export declare function explicarRejeicao(erro: string | SefinErro): ExplicacaoRejeicao;
|
|
47
|
+
/** Explains every error of a rejection (`EmitirNotaError.erros`, `RegistrarEventoError.erros`). */
|
|
48
|
+
export declare function explicarErros(erros: readonly SefinErro[]): ExplicacaoRejeicao[];
|
|
49
|
+
/** All bundled official rules, sorted by code. */
|
|
50
|
+
export declare function listarRejeicoes(): readonly RejeicaoOficial[];
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { REJEICOES_FONTES, REJEICOES_OFICIAIS } from './rejeicoesCatalog.js';
|
|
2
|
+
export { REJEICOES_FONTES } from './rejeicoesCatalog.js';
|
|
3
|
+
const BY_CODE = new Map(REJEICOES_OFICIAIS.map((entry) => [entry.codigo, entry]));
|
|
4
|
+
const NIVEL_DICA = {
|
|
5
|
+
1: 'Regra de leiaute: corrija o formato ou a consistência do campo indicado na DPS ou no evento.',
|
|
6
|
+
2: 'Regra nacional: confira o dado com o cadastro e a situação do contribuinte no Sistema Nacional NFS-e.',
|
|
7
|
+
3: 'Regra municipal: confira os parâmetros do município (convênio, alíquota, regimes) com consultarConvenio/consultarAliquota.',
|
|
8
|
+
};
|
|
9
|
+
const SDK_CODES = {
|
|
10
|
+
INVALID_AUTHORIZATION_RESPONSE: 'A SEFIN respondeu 2xx sem XML autorizado válido. O resultado é incerto: use recuperarNfsePorDps antes de reenviar.',
|
|
11
|
+
INVALID_QUERY_RESPONSE: 'A consulta respondeu sem o XML esperado. Tente novamente; se persistir, registre o corpo da resposta.',
|
|
12
|
+
DESCONHECIDO: 'A SEFIN respondeu sem um código de erro reconhecível. Veja o corpo bruto da resposta.',
|
|
13
|
+
};
|
|
14
|
+
function normalizeCode(codigo) {
|
|
15
|
+
const trimmed = codigo.trim().toUpperCase();
|
|
16
|
+
return /^\d{4}$/.test(trimmed) ? `E${trimmed}` : trimmed;
|
|
17
|
+
}
|
|
18
|
+
/** Looks up an official rule by code ("E0014", "e0014" or "0014"). */
|
|
19
|
+
export function buscarRejeicao(codigo) {
|
|
20
|
+
return BY_CODE.get(normalizeCode(codigo));
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Explains a SEFIN error code or a received `SefinErro` with the official
|
|
24
|
+
* message, rule and field from the published annexes. Never invents a cause:
|
|
25
|
+
* unknown codes come back with `conhecida: false`.
|
|
26
|
+
*/
|
|
27
|
+
export function explicarRejeicao(erro) {
|
|
28
|
+
const received = typeof erro === 'string' ? undefined : erro;
|
|
29
|
+
const codigo = normalizeCode(typeof erro === 'string' ? erro : erro.Codigo);
|
|
30
|
+
const entry = BY_CODE.get(codigo);
|
|
31
|
+
const result = { codigo, conhecida: Boolean(entry) };
|
|
32
|
+
if (received?.Descricao)
|
|
33
|
+
result.descricaoRecebida = received.Descricao;
|
|
34
|
+
if (received?.Complemento)
|
|
35
|
+
result.complemento = received.Complemento;
|
|
36
|
+
if (entry) {
|
|
37
|
+
result.mensagemOficial = entry.mensagem;
|
|
38
|
+
if (entry.regra)
|
|
39
|
+
result.regra = entry.regra;
|
|
40
|
+
if (entry.campo)
|
|
41
|
+
result.campo = entry.campo;
|
|
42
|
+
if (entry.nivel)
|
|
43
|
+
result.nivel = entry.nivel;
|
|
44
|
+
result.fonte = { ...REJEICOES_FONTES[entry.fonte] };
|
|
45
|
+
const dica = entry.nivel ? NIVEL_DICA[entry.nivel] : undefined;
|
|
46
|
+
if (dica)
|
|
47
|
+
result.dica = dica;
|
|
48
|
+
}
|
|
49
|
+
else if (SDK_CODES[codigo]) {
|
|
50
|
+
result.dica = SDK_CODES[codigo];
|
|
51
|
+
}
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
/** Explains every error of a rejection (`EmitirNotaError.erros`, `RegistrarEventoError.erros`). */
|
|
55
|
+
export function explicarErros(erros) {
|
|
56
|
+
return erros.map((erro) => explicarRejeicao(erro));
|
|
57
|
+
}
|
|
58
|
+
/** All bundled official rules, sorted by code. */
|
|
59
|
+
export function listarRejeicoes() {
|
|
60
|
+
return REJEICOES_OFICIAIS;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=rejeicoes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rejeicoes.js","sourceRoot":"","sources":["../rejeicoes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { RejeicaoOficial } from './rejeicoes.js';
|
|
2
|
+
/** Official spreadsheets this catalog was generated from (gov.br/nfse, documentacao atual). */
|
|
3
|
+
export declare const REJEICOES_FONTES: readonly [{
|
|
4
|
+
readonly documento: "Anexo I - Leiaute e Regras de Negocio DPS/NFS-e v1.01 (09/02/2026)";
|
|
5
|
+
readonly url: "https://www.gov.br/nfse/pt-br/biblioteca/documentacao-tecnica/documentacao-atual/anexo_i-sefin_adn-dps_nfse-snnfse-v1-01-20260209.xlsx";
|
|
6
|
+
}, {
|
|
7
|
+
readonly documento: "Anexo II - Leiaute e Regras de Negocio de Eventos v1.01 (22/01/2026)";
|
|
8
|
+
readonly url: "https://www.gov.br/nfse/pt-br/biblioteca/documentacao-tecnica/documentacao-atual/anexo_ii-sefin_adn-pedregevt_evt-snnfse-v1-01-20260122.xlsx";
|
|
9
|
+
}];
|
|
10
|
+
export declare const REJEICOES_OFICIAIS: readonly RejeicaoOficial[];
|