@semacode/cli 0.8.8 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -3
- package/dist/drift.d.ts +30 -1
- package/dist/drift.js +373 -17
- package/dist/drift.js.map +1 -1
- package/dist/index.js +828 -53
- package/dist/index.js.map +1 -1
- package/docs/AGENT_STARTER.md +10 -4
- package/docs/como-ensinar-a-sema-para-ia.md +17 -11
- package/docs/fluxo-pratico-ia-sema.md +42 -38
- package/docs/instalacao-e-primeiro-uso.md +189 -0
- package/docs/integracao-com-ia.md +228 -0
- package/docs/pagamento-ponta-a-ponta.md +155 -0
- package/docs/prompt-base-ia-sema.md +10 -3
- package/docs/sintaxe.md +267 -0
- package/exemplos/automacao.sema +107 -0
- package/exemplos/cadastro_usuario.sema +54 -0
- package/exemplos/calculadora.sema +78 -0
- package/exemplos/crud_simples.sema +89 -0
- package/exemplos/operacao_estrategia.sema +402 -0
- package/exemplos/pagamento.sema +222 -0
- package/exemplos/pagamento_dominio.sema +35 -0
- package/exemplos/testes_embutidos.sema +45 -0
- package/exemplos/tratamento_erro.sema +157 -0
- package/node_modules/@sema/gerador-dart/package.json +1 -1
- package/node_modules/@sema/gerador-python/package.json +1 -1
- package/node_modules/@sema/gerador-typescript/package.json +1 -1
- package/node_modules/@sema/nucleo/dist/ast/tipos.d.ts +14 -1
- package/node_modules/@sema/nucleo/dist/formatador/index.js +131 -22
- package/node_modules/@sema/nucleo/dist/formatador/index.js.map +1 -1
- package/node_modules/@sema/nucleo/dist/ir/conversor.js +546 -102
- package/node_modules/@sema/nucleo/dist/ir/conversor.js.map +1 -1
- package/node_modules/@sema/nucleo/dist/ir/modelos.d.ts +83 -5
- package/node_modules/@sema/nucleo/dist/lexer/lexer.js +1 -1
- package/node_modules/@sema/nucleo/dist/lexer/lexer.js.map +1 -1
- package/node_modules/@sema/nucleo/dist/lexer/tokens.js +10 -0
- package/node_modules/@sema/nucleo/dist/lexer/tokens.js.map +1 -1
- package/node_modules/@sema/nucleo/dist/parser/parser.js +230 -19
- package/node_modules/@sema/nucleo/dist/parser/parser.js.map +1 -1
- package/node_modules/@sema/nucleo/dist/semantico/analisador.d.ts +6 -1
- package/node_modules/@sema/nucleo/dist/semantico/analisador.js +269 -10
- package/node_modules/@sema/nucleo/dist/semantico/analisador.js.map +1 -1
- package/node_modules/@sema/nucleo/package.json +1 -1
- package/node_modules/@sema/padroes/package.json +1 -1
- package/package.json +7 -6
|
@@ -1,13 +1,131 @@
|
|
|
1
1
|
import { parsearEfeitoSemantico, parsearEtapaFlow, parsearExpressaoSemantica, parsearTransicaoEstado } from "../semantico/estruturas.js";
|
|
2
|
+
const TIPOS_PRIMITIVOS = new Set([
|
|
3
|
+
"Texto",
|
|
4
|
+
"Numero",
|
|
5
|
+
"Inteiro",
|
|
6
|
+
"Decimal",
|
|
7
|
+
"Booleano",
|
|
8
|
+
"Data",
|
|
9
|
+
"DataHora",
|
|
10
|
+
"Id",
|
|
11
|
+
"Email",
|
|
12
|
+
"Url",
|
|
13
|
+
"Json",
|
|
14
|
+
"Vazio",
|
|
15
|
+
]);
|
|
16
|
+
function encontrarSubBloco(bloco, palavraChave) {
|
|
17
|
+
return bloco.blocos.find((subbloco) => subbloco.tipo === "bloco_generico" && subbloco.palavraChave === palavraChave);
|
|
18
|
+
}
|
|
19
|
+
function localizarCampo(bloco, ...nomes) {
|
|
20
|
+
return bloco?.campos.find((campo) => nomes.includes(campo.nome));
|
|
21
|
+
}
|
|
22
|
+
function valorCampoCompleto(campo) {
|
|
23
|
+
if (!campo) {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
return [campo.valor, ...campo.modificadores].join(" ").trim() || undefined;
|
|
27
|
+
}
|
|
28
|
+
function normalizarTipoDeclarado(tipo) {
|
|
29
|
+
return tipo
|
|
30
|
+
.replace(/\s*([<>\[\](),|?])\s*/g, "$1")
|
|
31
|
+
.replace(/\s+/g, "")
|
|
32
|
+
.trim();
|
|
33
|
+
}
|
|
34
|
+
function dividirNoNivelRaiz(texto, separador) {
|
|
35
|
+
const partes = [];
|
|
36
|
+
let profundidadeAngular = 0;
|
|
37
|
+
let profundidadeColchete = 0;
|
|
38
|
+
let inicio = 0;
|
|
39
|
+
for (let indice = 0; indice < texto.length; indice += 1) {
|
|
40
|
+
const caractere = texto[indice];
|
|
41
|
+
if (caractere === "<") {
|
|
42
|
+
profundidadeAngular += 1;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (caractere === ">") {
|
|
46
|
+
profundidadeAngular = Math.max(0, profundidadeAngular - 1);
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (caractere === "[") {
|
|
50
|
+
profundidadeColchete += 1;
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (caractere === "]") {
|
|
54
|
+
profundidadeColchete = Math.max(0, profundidadeColchete - 1);
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (profundidadeAngular === 0 && profundidadeColchete === 0 && texto.startsWith(separador, indice)) {
|
|
58
|
+
partes.push(texto.slice(inicio, indice));
|
|
59
|
+
inicio = indice + separador.length;
|
|
60
|
+
indice += separador.length - 1;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
partes.push(texto.slice(inicio));
|
|
64
|
+
return partes.map((parte) => parte.trim()).filter(Boolean);
|
|
65
|
+
}
|
|
66
|
+
function analisarCampoTipo(tipo, modificadores) {
|
|
67
|
+
const tipoOriginal = normalizarTipoDeclarado(tipo);
|
|
68
|
+
const modificadoresNormalizados = modificadores.map((item) => item.trim()).filter(Boolean);
|
|
69
|
+
const refinamentos = modificadoresNormalizados.filter((item) => !["required", "optional", "opcional"].includes(item));
|
|
70
|
+
const opcionalPorModificador = modificadoresNormalizados.includes("optional") || modificadoresNormalizados.includes("opcional");
|
|
71
|
+
let tipoBase = tipoOriginal;
|
|
72
|
+
let cardinalidade = "unitario";
|
|
73
|
+
let tiposAlternativos = [];
|
|
74
|
+
let tipoItem;
|
|
75
|
+
let chaveMapa;
|
|
76
|
+
let valorMapa;
|
|
77
|
+
let opcional = opcionalPorModificador;
|
|
78
|
+
if (tipoBase.endsWith("?")) {
|
|
79
|
+
opcional = true;
|
|
80
|
+
tipoBase = tipoBase.slice(0, -1);
|
|
81
|
+
}
|
|
82
|
+
if (/^Opcional<.+>$/.test(tipoBase)) {
|
|
83
|
+
opcional = true;
|
|
84
|
+
tipoBase = tipoBase.slice("Opcional<".length, -1);
|
|
85
|
+
}
|
|
86
|
+
const uniao = dividirNoNivelRaiz(tipoBase, "|");
|
|
87
|
+
if (uniao.length > 1) {
|
|
88
|
+
cardinalidade = "uniao";
|
|
89
|
+
tiposAlternativos = uniao.map(normalizarTipoDeclarado);
|
|
90
|
+
tipoBase = tiposAlternativos[0] ?? tipoBase;
|
|
91
|
+
}
|
|
92
|
+
else if (/^Lista<.+>$/.test(tipoBase)) {
|
|
93
|
+
cardinalidade = "lista";
|
|
94
|
+
tipoItem = tipoBase.slice("Lista<".length, -1).trim();
|
|
95
|
+
tipoBase = tipoItem;
|
|
96
|
+
}
|
|
97
|
+
else if (/^Mapa<.+>$/.test(tipoBase)) {
|
|
98
|
+
cardinalidade = "mapa";
|
|
99
|
+
const partesMapa = dividirNoNivelRaiz(tipoBase.slice("Mapa<".length, -1), ",");
|
|
100
|
+
chaveMapa = partesMapa[0];
|
|
101
|
+
valorMapa = partesMapa[1];
|
|
102
|
+
tipoBase = valorMapa ?? tipoBase;
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
tipo: tipoOriginal,
|
|
106
|
+
modificadores: modificadoresNormalizados,
|
|
107
|
+
tipoOriginal,
|
|
108
|
+
tipoBase,
|
|
109
|
+
cardinalidade,
|
|
110
|
+
opcional,
|
|
111
|
+
tiposAlternativos,
|
|
112
|
+
tipoItem,
|
|
113
|
+
chaveMapa,
|
|
114
|
+
valorMapa,
|
|
115
|
+
refinamentos,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
function converterCampo(campo) {
|
|
119
|
+
return {
|
|
120
|
+
nome: campo.nome,
|
|
121
|
+
...analisarCampoTipo(campo.valor, campo.modificadores),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
2
124
|
function converterCampos(bloco) {
|
|
3
125
|
if (!bloco) {
|
|
4
126
|
return [];
|
|
5
127
|
}
|
|
6
|
-
return bloco.campos.map(
|
|
7
|
-
nome: campo.nome,
|
|
8
|
-
tipo: campo.valor,
|
|
9
|
-
modificadores: campo.modificadores,
|
|
10
|
-
}));
|
|
128
|
+
return bloco.campos.map(converterCampo);
|
|
11
129
|
}
|
|
12
130
|
function converterBloco(bloco) {
|
|
13
131
|
return {
|
|
@@ -30,29 +148,276 @@ function converterCaso(caso) {
|
|
|
30
148
|
error: caso.error ? converterBloco(caso.error) : undefined,
|
|
31
149
|
};
|
|
32
150
|
}
|
|
33
|
-
function
|
|
34
|
-
|
|
151
|
+
function converterImplementacoes(bloco) {
|
|
152
|
+
const implementacoes = [];
|
|
153
|
+
for (const campo of bloco?.campos ?? []) {
|
|
154
|
+
const origem = campo.nome.toLowerCase();
|
|
155
|
+
if (origem === "ts" || origem === "typescript") {
|
|
156
|
+
implementacoes.push({ origem: "ts", caminho: campo.valor, resolucaoImpl: campo.valor, statusImpl: "nao_verificado" });
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
if (origem === "py" || origem === "python") {
|
|
160
|
+
implementacoes.push({ origem: "py", caminho: campo.valor, resolucaoImpl: campo.valor, statusImpl: "nao_verificado" });
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
if (origem === "dart") {
|
|
164
|
+
implementacoes.push({ origem: "dart", caminho: campo.valor, resolucaoImpl: campo.valor, statusImpl: "nao_verificado" });
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
if (origem === "cs" || origem === "csharp" || origem === "dotnet") {
|
|
168
|
+
implementacoes.push({ origem: "cs", caminho: campo.valor, resolucaoImpl: campo.valor, statusImpl: "nao_verificado" });
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
if (origem === "java") {
|
|
172
|
+
implementacoes.push({ origem: "java", caminho: campo.valor, resolucaoImpl: campo.valor, statusImpl: "nao_verificado" });
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
if (origem === "go" || origem === "golang") {
|
|
176
|
+
implementacoes.push({ origem: "go", caminho: campo.valor, resolucaoImpl: campo.valor, statusImpl: "nao_verificado" });
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
if (origem === "rust" || origem === "rs") {
|
|
180
|
+
implementacoes.push({ origem: "rust", caminho: campo.valor, resolucaoImpl: campo.valor, statusImpl: "nao_verificado" });
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
if (origem === "cpp" || origem === "cxx" || origem === "cc" || origem === "c++") {
|
|
184
|
+
implementacoes.push({ origem: "cpp", caminho: campo.valor, resolucaoImpl: campo.valor, statusImpl: "nao_verificado" });
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return implementacoes;
|
|
35
188
|
}
|
|
36
|
-
function
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
189
|
+
function converterVinculos(bloco) {
|
|
190
|
+
if (!bloco) {
|
|
191
|
+
return [];
|
|
192
|
+
}
|
|
193
|
+
const campos = bloco.campos.map((campo) => {
|
|
194
|
+
const valor = valorCampoCompleto(campo) ?? "";
|
|
195
|
+
return {
|
|
196
|
+
tipo: campo.nome,
|
|
197
|
+
valor,
|
|
198
|
+
arquivo: campo.nome === "arquivo" ? valor : undefined,
|
|
199
|
+
simbolo: campo.nome === "simbolo" ? valor : undefined,
|
|
200
|
+
recurso: ["recurso", "tabela", "fila", "cache", "storage"].includes(campo.nome) ? valor : undefined,
|
|
201
|
+
superficie: ["superficie", "rota", "worker", "cron", "webhook", "evento", "policy", "fila", "cache", "storage"].includes(campo.nome) ? valor : undefined,
|
|
202
|
+
statusResolucao: "nao_verificado",
|
|
203
|
+
};
|
|
204
|
+
});
|
|
205
|
+
const linhas = bloco.linhas.map((linha) => {
|
|
206
|
+
const [tipo, ...resto] = linha.conteudo.split(/\s+/);
|
|
207
|
+
const valor = resto.join(" ").trim();
|
|
208
|
+
return {
|
|
209
|
+
tipo: tipo ?? "desconhecido",
|
|
210
|
+
valor,
|
|
211
|
+
statusResolucao: "nao_verificado",
|
|
212
|
+
};
|
|
213
|
+
}).filter((item) => item.valor);
|
|
214
|
+
const subblocos = bloco.blocos
|
|
215
|
+
.filter((item) => item.tipo === "bloco_generico")
|
|
216
|
+
.map((item) => ({
|
|
217
|
+
tipo: item.palavraChave === "desconhecido" ? (item.nome ?? "desconhecido") : item.palavraChave,
|
|
218
|
+
valor: item.nome ?? item.palavraChave,
|
|
219
|
+
arquivo: valorCampoCompleto(localizarCampo(item, "arquivo")),
|
|
220
|
+
simbolo: valorCampoCompleto(localizarCampo(item, "simbolo")),
|
|
221
|
+
recurso: valorCampoCompleto(localizarCampo(item, "recurso", "tabela", "fila", "cache", "storage")),
|
|
222
|
+
superficie: valorCampoCompleto(localizarCampo(item, "superficie", "rota", "worker", "cron", "webhook", "evento")),
|
|
223
|
+
statusResolucao: "nao_verificado",
|
|
41
224
|
}));
|
|
225
|
+
return [...campos, ...linhas, ...subblocos];
|
|
42
226
|
}
|
|
43
|
-
function
|
|
44
|
-
|
|
45
|
-
|
|
227
|
+
function converterExecucao(bloco) {
|
|
228
|
+
const idempotencia = valorCampoCompleto(localizarCampo(bloco, "idempotencia"));
|
|
229
|
+
const criticidadeOperacional = valorCampoCompleto(localizarCampo(bloco, "criticidade_operacional"));
|
|
230
|
+
return {
|
|
231
|
+
idempotencia: idempotencia === "verdadeiro" || idempotencia === "true",
|
|
232
|
+
timeout: valorCampoCompleto(localizarCampo(bloco, "timeout")) ?? "padrao",
|
|
233
|
+
retry: valorCampoCompleto(localizarCampo(bloco, "retry")) ?? "nenhum",
|
|
234
|
+
compensacao: valorCampoCompleto(localizarCampo(bloco, "compensacao")) ?? "nenhuma",
|
|
235
|
+
criticidadeOperacional: (criticidadeOperacional === "baixa"
|
|
236
|
+
|| criticidadeOperacional === "alta"
|
|
237
|
+
|| criticidadeOperacional === "critica") ? criticidadeOperacional : "media",
|
|
238
|
+
explicita: Boolean(bloco),
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
function converterErrosTask(bloco, fallback) {
|
|
242
|
+
const erros = new Map();
|
|
243
|
+
for (const campo of bloco?.campos ?? []) {
|
|
244
|
+
erros.set(campo.nome, {
|
|
245
|
+
codigo: campo.nome,
|
|
246
|
+
mensagem: valorCampoCompleto(campo) ?? "",
|
|
247
|
+
});
|
|
46
248
|
}
|
|
47
|
-
|
|
48
|
-
.
|
|
49
|
-
|
|
50
|
-
|
|
249
|
+
for (const subbloco of bloco?.blocos ?? []) {
|
|
250
|
+
if (subbloco.tipo !== "bloco_generico") {
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
const codigo = subbloco.nome ?? subbloco.palavraChave;
|
|
254
|
+
if (!codigo || codigo === "desconhecido") {
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
erros.set(codigo, {
|
|
258
|
+
codigo,
|
|
259
|
+
mensagem: valorCampoCompleto(localizarCampo(subbloco, "mensagem")) ?? `Erro estruturado "${codigo}".`,
|
|
260
|
+
categoria: valorCampoCompleto(localizarCampo(subbloco, "categoria")),
|
|
261
|
+
recuperabilidade: valorCampoCompleto(localizarCampo(subbloco, "recuperabilidade")),
|
|
262
|
+
acaoChamador: valorCampoCompleto(localizarCampo(subbloco, "acao_chamador")),
|
|
263
|
+
impactaEstado: valorCampoCompleto(localizarCampo(subbloco, "impacta_estado")) === "verdadeiro",
|
|
264
|
+
requerCompensacao: valorCampoCompleto(localizarCampo(subbloco, "requer_compensacao")) === "verdadeiro",
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
for (const erro of fallback ?? []) {
|
|
268
|
+
if (!erros.has(erro.codigo)) {
|
|
269
|
+
erros.set(erro.codigo, {
|
|
270
|
+
codigo: erro.codigo,
|
|
271
|
+
mensagem: erro.mensagem,
|
|
272
|
+
categoria: erro.categoria,
|
|
273
|
+
recuperabilidade: erro.recuperabilidade,
|
|
274
|
+
acaoChamador: erro.acaoChamador,
|
|
275
|
+
impactaEstado: erro.impactaEstado,
|
|
276
|
+
requerCompensacao: erro.requerCompensacao,
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return [...erros.values()];
|
|
281
|
+
}
|
|
282
|
+
function extrairPerfil(bloco, padrao = "interno") {
|
|
283
|
+
const perfil = valorCampoCompleto(localizarCampo(bloco, "perfil", "compatibilidade"))?.toLowerCase();
|
|
284
|
+
if (perfil === "publico"
|
|
285
|
+
|| perfil === "interno"
|
|
286
|
+
|| perfil === "experimental"
|
|
287
|
+
|| perfil === "legado"
|
|
288
|
+
|| perfil === "deprecado") {
|
|
289
|
+
return perfil;
|
|
290
|
+
}
|
|
291
|
+
return padrao;
|
|
292
|
+
}
|
|
293
|
+
function tipoNaoPrimitivo(campo) {
|
|
294
|
+
if (!TIPOS_PRIMITIVOS.has(campo.tipoBase)) {
|
|
295
|
+
return campo.tipoBase;
|
|
296
|
+
}
|
|
297
|
+
if (campo.tipoItem && !TIPOS_PRIMITIVOS.has(campo.tipoItem)) {
|
|
298
|
+
return campo.tipoItem;
|
|
299
|
+
}
|
|
300
|
+
if (campo.valorMapa && !TIPOS_PRIMITIVOS.has(campo.valorMapa)) {
|
|
301
|
+
return campo.valorMapa;
|
|
302
|
+
}
|
|
303
|
+
return undefined;
|
|
304
|
+
}
|
|
305
|
+
function deduplicarTexto(valores) {
|
|
306
|
+
return [...new Set(valores.filter(Boolean))].sort((a, b) => a.localeCompare(b, "pt-BR"));
|
|
307
|
+
}
|
|
308
|
+
function resumirAgente(params) {
|
|
309
|
+
const entidadesAfetadas = deduplicarTexto([
|
|
310
|
+
...(params.input ?? []).map(tipoNaoPrimitivo).filter((item) => Boolean(item)),
|
|
311
|
+
...(params.output ?? []).map(tipoNaoPrimitivo).filter((item) => Boolean(item)),
|
|
312
|
+
...(params.efeitos ?? []).map((efeito) => efeito.alvo),
|
|
313
|
+
]);
|
|
314
|
+
const mutacoesPrevistas = deduplicarTexto((params.efeitos ?? []).map((efeito) => `${efeito.categoria}:${efeito.alvo}`));
|
|
315
|
+
const riscos = new Set();
|
|
316
|
+
if ((params.efeitos ?? []).some((efeito) => efeito.categoria === "persistencia")) {
|
|
317
|
+
riscos.add("altera_persistencia");
|
|
318
|
+
}
|
|
319
|
+
if ((params.efeitos ?? []).some((efeito) => efeito.criticidade === "alta" || efeito.criticidade === "critica")) {
|
|
320
|
+
riscos.add("efeito_critico");
|
|
321
|
+
}
|
|
322
|
+
if (params.execucao?.criticidadeOperacional === "alta" || params.execucao?.criticidadeOperacional === "critica") {
|
|
323
|
+
riscos.add("execucao_critica");
|
|
324
|
+
}
|
|
325
|
+
if ((params.vinculos ?? []).length === 0) {
|
|
326
|
+
riscos.add("vinculo_fraco");
|
|
327
|
+
}
|
|
328
|
+
const checks = new Set();
|
|
329
|
+
checks.add("rodar sema validar --json");
|
|
330
|
+
if ((params.output ?? []).length > 0) {
|
|
331
|
+
checks.add("verificar guarantees");
|
|
332
|
+
}
|
|
333
|
+
if ((params.vinculos ?? []).length > 0) {
|
|
334
|
+
checks.add("rodar sema drift --json");
|
|
335
|
+
}
|
|
336
|
+
if (params.superficiePublica) {
|
|
337
|
+
checks.add("validar superficie publica impactada");
|
|
338
|
+
}
|
|
339
|
+
return {
|
|
340
|
+
riscos: [...riscos],
|
|
341
|
+
checks: [...checks],
|
|
342
|
+
entidadesAfetadas,
|
|
343
|
+
superficiesPublicas: params.superficiePublica ? [params.superficiePublica] : [],
|
|
344
|
+
mutacoesPrevistas,
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
function recomporCaminho(campo) {
|
|
348
|
+
const valor = valorCampoCompleto(campo);
|
|
349
|
+
return valor?.replace(/\s*\/\s*/g, "/").trim();
|
|
51
350
|
}
|
|
52
351
|
function ehUseInterop(use) {
|
|
53
352
|
return use.origem !== "sema";
|
|
54
353
|
}
|
|
354
|
+
function converterErroPublico(erro, origemTask) {
|
|
355
|
+
return {
|
|
356
|
+
nome: erro.codigo,
|
|
357
|
+
codigo: erro.codigo,
|
|
358
|
+
mensagem: erro.mensagem,
|
|
359
|
+
categoria: erro.categoria,
|
|
360
|
+
recuperabilidade: erro.recuperabilidade,
|
|
361
|
+
acaoChamador: erro.acaoChamador,
|
|
362
|
+
impactaEstado: erro.impactaEstado,
|
|
363
|
+
requerCompensacao: erro.requerCompensacao,
|
|
364
|
+
origemTask,
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
function calcularConfiancaPublica(route) {
|
|
368
|
+
if (route.task && route.vinculos.length > 0) {
|
|
369
|
+
return "alta";
|
|
370
|
+
}
|
|
371
|
+
if (route.task || route.vinculos.length > 0) {
|
|
372
|
+
return "media";
|
|
373
|
+
}
|
|
374
|
+
return "baixa";
|
|
375
|
+
}
|
|
376
|
+
function calcularRiscoPublico(route) {
|
|
377
|
+
if (route.efeitosPublicos.some((efeito) => efeito.categoria === "persistencia" || efeito.criticidade === "critica")) {
|
|
378
|
+
return "alto";
|
|
379
|
+
}
|
|
380
|
+
if (route.efeitosPublicos.length > 0 || route.errosPublicos.length > 0) {
|
|
381
|
+
return "medio";
|
|
382
|
+
}
|
|
383
|
+
return "baixo";
|
|
384
|
+
}
|
|
385
|
+
function converterSuperficie(tipo, superficie) {
|
|
386
|
+
const input = converterCampos(encontrarSubBloco(superficie, "input"));
|
|
387
|
+
const output = converterCampos(encontrarSubBloco(superficie, "output"));
|
|
388
|
+
const effects = (encontrarSubBloco(superficie, "effects")?.linhas ?? [])
|
|
389
|
+
.map((linha) => parsearEfeitoSemantico(linha.conteudo))
|
|
390
|
+
.filter((linha) => Boolean(linha));
|
|
391
|
+
const vinculos = converterVinculos(encontrarSubBloco(superficie, "vinculos"));
|
|
392
|
+
const execucao = converterExecucao(encontrarSubBloco(superficie, "execucao"));
|
|
393
|
+
const task = valorCampoCompleto(localizarCampo(superficie, "task", "tarefa"));
|
|
394
|
+
const perfilCompatibilidade = extrairPerfil(superficie, tipo === "webhook" ? "publico" : "interno");
|
|
395
|
+
const resumoAgente = resumirAgente({
|
|
396
|
+
input,
|
|
397
|
+
output,
|
|
398
|
+
efeitos: effects,
|
|
399
|
+
vinculos,
|
|
400
|
+
execucao,
|
|
401
|
+
superficiePublica: perfilCompatibilidade === "publico" ? `${tipo}:${superficie.nome ?? tipo}` : undefined,
|
|
402
|
+
});
|
|
403
|
+
return {
|
|
404
|
+
tipo,
|
|
405
|
+
nome: superficie.nome ?? tipo,
|
|
406
|
+
campos: converterCampos(superficie),
|
|
407
|
+
linhas: superficie.linhas.map((linha) => linha.conteudo),
|
|
408
|
+
task: task || undefined,
|
|
409
|
+
input,
|
|
410
|
+
output,
|
|
411
|
+
effects,
|
|
412
|
+
implementacoesExternas: converterImplementacoes(encontrarSubBloco(superficie, "impl")),
|
|
413
|
+
vinculos,
|
|
414
|
+
execucao,
|
|
415
|
+
perfilCompatibilidade,
|
|
416
|
+
resumoAgente,
|
|
417
|
+
};
|
|
418
|
+
}
|
|
55
419
|
export function converterParaIr(modulo, diagnosticos, contexto) {
|
|
420
|
+
const perfilModulo = extrairPerfil(modulo.vinculos, modulo.routes.length > 0 || modulo.webhooks.length > 0 ? "publico" : "interno");
|
|
56
421
|
const types = modulo.types.map((type) => ({
|
|
57
422
|
nome: type.nome,
|
|
58
423
|
definicao: converterBloco(encontrarSubBloco(type.corpo, "fields") ?? type.corpo),
|
|
@@ -67,85 +432,88 @@ export function converterParaIr(modulo, diagnosticos, contexto) {
|
|
|
67
432
|
.map((linha) => parsearExpressaoSemantica(linha.conteudo))
|
|
68
433
|
.filter((linha) => Boolean(linha)),
|
|
69
434
|
}));
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
input
|
|
73
|
-
output
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
if (origem === "go" || origem === "golang") {
|
|
97
|
-
return { origem: "go", caminho: campo.valor, resolucaoImpl: campo.valor, statusImpl: "nao_verificado" };
|
|
98
|
-
}
|
|
99
|
-
if (origem === "rust" || origem === "rs") {
|
|
100
|
-
return { origem: "rust", caminho: campo.valor, resolucaoImpl: campo.valor, statusImpl: "nao_verificado" };
|
|
101
|
-
}
|
|
102
|
-
if (origem === "cpp" || origem === "cxx" || origem === "cc" || origem === "c++") {
|
|
103
|
-
return { origem: "cpp", caminho: campo.valor, resolucaoImpl: campo.valor, statusImpl: "nao_verificado" };
|
|
104
|
-
}
|
|
105
|
-
return undefined;
|
|
106
|
-
})
|
|
107
|
-
.filter((item) => Boolean(item)),
|
|
108
|
-
guarantees: task.guarantees?.linhas.map((linha) => linha.conteudo) ?? [],
|
|
109
|
-
garantiasEstruturadas: (task.guarantees?.linhas ?? []).map((linha) => parsearExpressaoSemantica(linha.conteudo)).filter((linha) => Boolean(linha)),
|
|
110
|
-
errors: Object.fromEntries((task.error?.campos ?? []).map((campo) => [campo.nome, [campo.valor, ...campo.modificadores].join(" ").trim()])),
|
|
111
|
-
stateContract: task.state ? {
|
|
112
|
-
nomeEstado: task.state.nome ?? task.state.campos.find((campo) => campo.nome === "state" || campo.nome === "estado")?.valor,
|
|
113
|
-
campos: converterCampos(task.state),
|
|
114
|
-
linhas: task.state.linhas.map((linha) => linha.conteudo),
|
|
115
|
-
transicoes: (encontrarSubBloco(task.state, "transitions")?.linhas ?? task.state.linhas)
|
|
116
|
-
.map((linha) => parsearTransicaoEstado(linha.conteudo))
|
|
435
|
+
const tarefasSemanticas = contexto?.tarefasDetalhadas ?? new Map();
|
|
436
|
+
const tasks = modulo.tasks.map((task) => {
|
|
437
|
+
const input = converterCampos(task.input);
|
|
438
|
+
const output = converterCampos(task.output);
|
|
439
|
+
const effects = (task.effects?.linhas ?? [])
|
|
440
|
+
.map((linha) => parsearEfeitoSemantico(linha.conteudo))
|
|
441
|
+
.filter((linha) => Boolean(linha));
|
|
442
|
+
const vinculos = converterVinculos(task.vinculos);
|
|
443
|
+
const execucao = converterExecucao(task.execucao);
|
|
444
|
+
const errosDetalhados = converterErrosTask(task.error, tarefasSemanticas.get(task.nome)?.errors);
|
|
445
|
+
const perfilCompatibilidade = extrairPerfil(task.corpo, "interno");
|
|
446
|
+
const resumoAgente = resumirAgente({
|
|
447
|
+
input,
|
|
448
|
+
output,
|
|
449
|
+
efeitos: effects,
|
|
450
|
+
vinculos,
|
|
451
|
+
execucao,
|
|
452
|
+
});
|
|
453
|
+
return {
|
|
454
|
+
nome: task.nome,
|
|
455
|
+
input,
|
|
456
|
+
output,
|
|
457
|
+
rules: task.rules?.linhas.map((linha) => linha.conteudo) ?? [],
|
|
458
|
+
regrasEstruturadas: (task.rules?.linhas ?? [])
|
|
459
|
+
.map((linha) => parsearExpressaoSemantica(linha.conteudo))
|
|
117
460
|
.filter((linha) => Boolean(linha)),
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
461
|
+
effects: task.effects?.linhas.map((linha) => linha.conteudo) ?? [],
|
|
462
|
+
efeitosEstruturados: effects,
|
|
463
|
+
implementacoesExternas: converterImplementacoes(task.impl),
|
|
464
|
+
vinculos,
|
|
465
|
+
execucao,
|
|
466
|
+
guarantees: task.guarantees?.linhas.map((linha) => linha.conteudo) ?? [],
|
|
467
|
+
garantiasEstruturadas: (task.guarantees?.linhas ?? [])
|
|
468
|
+
.map((linha) => parsearExpressaoSemantica(linha.conteudo))
|
|
469
|
+
.filter((linha) => Boolean(linha)),
|
|
470
|
+
errors: Object.fromEntries(errosDetalhados.map((erro) => [erro.codigo, erro.mensagem])),
|
|
471
|
+
errosDetalhados,
|
|
472
|
+
perfilCompatibilidade,
|
|
473
|
+
stateContract: task.state ? {
|
|
474
|
+
nomeEstado: task.state.nome ?? task.state.campos.find((campo) => campo.nome === "state" || campo.nome === "estado")?.valor,
|
|
475
|
+
campos: converterCampos(task.state),
|
|
476
|
+
linhas: task.state.linhas.map((linha) => linha.conteudo),
|
|
477
|
+
transicoes: (encontrarSubBloco(task.state, "transitions")?.linhas ?? task.state.linhas)
|
|
478
|
+
.map((linha) => parsearTransicaoEstado(linha.conteudo))
|
|
479
|
+
.filter((linha) => Boolean(linha)),
|
|
480
|
+
} : undefined,
|
|
481
|
+
resumoAgente,
|
|
482
|
+
tests: (task.tests?.blocos.filter((bloco) => bloco.tipo === "caso_teste") ?? []).map(converterCaso),
|
|
483
|
+
};
|
|
484
|
+
});
|
|
121
485
|
const tarefasPorNome = new Map(tasks.map((task) => [task.nome, task]));
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
campos: flow.corpo.campos.map((campo) => ({
|
|
126
|
-
nome: campo.nome,
|
|
127
|
-
tipo: campo.valor,
|
|
128
|
-
modificadores: campo.modificadores,
|
|
129
|
-
})),
|
|
130
|
-
linhas: flow.corpo.linhas.map((linha) => linha.conteudo),
|
|
131
|
-
tasksReferenciadas: flow.corpo.campos
|
|
132
|
-
.filter((campo) => campo.nome === "task" || campo.nome === "tarefa")
|
|
133
|
-
.map((campo) => campo.valor),
|
|
134
|
-
etapasEstruturadas: flow.corpo.linhas
|
|
135
|
-
.map((linha) => parsearEtapaFlow(linha.conteudo))
|
|
136
|
-
.filter((linha) => Boolean(linha)),
|
|
137
|
-
effects: (encontrarSubBloco(flow.corpo, "effects")?.linhas ?? []).map((linha) => linha.conteudo),
|
|
138
|
-
efeitosEstruturados: (encontrarSubBloco(flow.corpo, "effects")?.linhas ?? [])
|
|
486
|
+
const flows = modulo.flows.map((flow) => {
|
|
487
|
+
const campos = converterCampos(flow.corpo);
|
|
488
|
+
const effects = (encontrarSubBloco(flow.corpo, "effects")?.linhas ?? [])
|
|
139
489
|
.map((linha) => parsearEfeitoSemantico(linha.conteudo))
|
|
140
|
-
.filter((linha) => Boolean(linha))
|
|
141
|
-
|
|
490
|
+
.filter((linha) => Boolean(linha));
|
|
491
|
+
const vinculos = converterVinculos(flow.vinculos);
|
|
492
|
+
const perfilCompatibilidade = extrairPerfil(flow.corpo, "interno");
|
|
493
|
+
return {
|
|
494
|
+
nome: flow.nome,
|
|
495
|
+
campos,
|
|
496
|
+
linhas: flow.corpo.linhas.map((linha) => linha.conteudo),
|
|
497
|
+
tasksReferenciadas: flow.corpo.campos
|
|
498
|
+
.filter((campo) => campo.nome === "task" || campo.nome === "tarefa")
|
|
499
|
+
.map((campo) => campo.valor),
|
|
500
|
+
etapasEstruturadas: flow.corpo.linhas
|
|
501
|
+
.map((linha) => parsearEtapaFlow(linha.conteudo))
|
|
502
|
+
.filter((linha) => Boolean(linha)),
|
|
503
|
+
effects: (encontrarSubBloco(flow.corpo, "effects")?.linhas ?? []).map((linha) => linha.conteudo),
|
|
504
|
+
efeitosEstruturados: effects,
|
|
505
|
+
vinculos,
|
|
506
|
+
perfilCompatibilidade,
|
|
507
|
+
resumoAgente: resumirAgente({
|
|
508
|
+
input: campos,
|
|
509
|
+
efeitos: effects,
|
|
510
|
+
vinculos,
|
|
511
|
+
}),
|
|
512
|
+
};
|
|
513
|
+
});
|
|
142
514
|
const routes = modulo.routes.map((route) => ({
|
|
143
515
|
nome: route.nome,
|
|
144
|
-
campos: route.corpo
|
|
145
|
-
nome: campo.nome,
|
|
146
|
-
tipo: campo.valor,
|
|
147
|
-
modificadores: campo.modificadores,
|
|
148
|
-
})),
|
|
516
|
+
campos: converterCampos(route.corpo),
|
|
149
517
|
linhas: route.corpo.linhas.map((linha) => linha.conteudo),
|
|
150
518
|
metodo: route.corpo.campos.find((campo) => campo.nome === "metodo")?.valor,
|
|
151
519
|
caminho: recomporCaminho(route.corpo.campos.find((campo) => campo.nome === "caminho")),
|
|
@@ -154,7 +522,16 @@ export function converterParaIr(modulo, diagnosticos, contexto) {
|
|
|
154
522
|
outputPublico: [],
|
|
155
523
|
errosPublicos: [],
|
|
156
524
|
efeitosPublicos: [],
|
|
525
|
+
vinculos: converterVinculos(route.vinculos),
|
|
526
|
+
perfilCompatibilidade: extrairPerfil(route.corpo, "publico"),
|
|
157
527
|
garantiasPublicasMinimas: [],
|
|
528
|
+
resumoAgente: {
|
|
529
|
+
riscos: [],
|
|
530
|
+
checks: [],
|
|
531
|
+
entidadesAfetadas: [],
|
|
532
|
+
superficiesPublicas: [],
|
|
533
|
+
mutacoesPrevistas: [],
|
|
534
|
+
},
|
|
158
535
|
publico: {
|
|
159
536
|
metodo: undefined,
|
|
160
537
|
caminho: undefined,
|
|
@@ -171,32 +548,57 @@ export function converterParaIr(modulo, diagnosticos, contexto) {
|
|
|
171
548
|
const tarefaSemantica = route.task ? tarefasSemanticas.get(route.task) : undefined;
|
|
172
549
|
const inputPublicoDeclarado = converterCampos(encontrarSubBloco(routeAst.corpo, "input"));
|
|
173
550
|
const outputPublicoDeclarado = converterCampos(encontrarSubBloco(routeAst.corpo, "output"));
|
|
174
|
-
const
|
|
551
|
+
const errosDeclarados = converterErrosTask(encontrarSubBloco(routeAst.corpo, "error"), tarefaSemantica?.errors);
|
|
175
552
|
const efeitosPublicosDeclarados = (encontrarSubBloco(routeAst.corpo, "effects")?.linhas ?? [])
|
|
176
553
|
.map((linha) => parsearEfeitoSemantico(linha.conteudo))
|
|
177
554
|
.filter((linha) => Boolean(linha));
|
|
178
555
|
const inputPublicoResolvido = inputPublicoDeclarado.length > 0
|
|
179
556
|
? inputPublicoDeclarado
|
|
180
|
-
: (tarefaAssociada?.input ?? tarefaSemantica?.input
|
|
557
|
+
: (tarefaAssociada?.input ?? tarefaSemantica?.input?.map((campo) => ({
|
|
558
|
+
nome: campo.nome,
|
|
559
|
+
tipo: campo.tipo,
|
|
560
|
+
modificadores: campo.modificadores,
|
|
561
|
+
tipoOriginal: campo.tipo,
|
|
562
|
+
tipoBase: campo.tipo,
|
|
563
|
+
cardinalidade: "unitario",
|
|
564
|
+
opcional: false,
|
|
565
|
+
tiposAlternativos: [],
|
|
566
|
+
refinamentos: [],
|
|
567
|
+
})) ?? []);
|
|
181
568
|
const outputPublicoResolvido = outputPublicoDeclarado.length > 0
|
|
182
569
|
? outputPublicoDeclarado
|
|
183
|
-
: (tarefaAssociada?.output ?? tarefaSemantica?.output
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
:
|
|
570
|
+
: (tarefaAssociada?.output ?? tarefaSemantica?.output?.map((campo) => ({
|
|
571
|
+
nome: campo.nome,
|
|
572
|
+
tipo: campo.tipo,
|
|
573
|
+
modificadores: campo.modificadores,
|
|
574
|
+
tipoOriginal: campo.tipo,
|
|
575
|
+
tipoBase: campo.tipo,
|
|
576
|
+
cardinalidade: "unitario",
|
|
577
|
+
opcional: false,
|
|
578
|
+
tiposAlternativos: [],
|
|
579
|
+
refinamentos: [],
|
|
580
|
+
})) ?? []);
|
|
581
|
+
const errosPublicosResolvidos = errosDeclarados.length > 0
|
|
582
|
+
? errosDeclarados.map((erro) => converterErroPublico(erro, route.task))
|
|
583
|
+
: (tarefaAssociada?.errosDetalhados ?? (tarefaSemantica?.errors ?? []).map((erro) => ({ codigo: erro.codigo, mensagem: erro.mensagem }))).map((erro) => converterErroPublico(erro, route.task));
|
|
189
584
|
const garantiasPublicasMinimas = (tarefaAssociada?.guarantees ?? tarefaSemantica?.guarantees ?? []).filter((garantia) => {
|
|
190
585
|
const referencia = garantia.trim().split(/\s+/)[0] ?? "";
|
|
191
586
|
return outputPublicoResolvido.some((campo) => campo.nome === referencia || garantia.includes(`${campo.nome}.`));
|
|
192
587
|
});
|
|
193
|
-
|
|
588
|
+
const routeResolvida = {
|
|
194
589
|
...route,
|
|
195
590
|
inputPublico: inputPublicoResolvido,
|
|
196
591
|
outputPublico: outputPublicoResolvido,
|
|
197
592
|
errosPublicos: errosPublicosResolvidos,
|
|
198
593
|
efeitosPublicos: efeitosPublicosDeclarados,
|
|
199
594
|
garantiasPublicasMinimas,
|
|
595
|
+
resumoAgente: resumirAgente({
|
|
596
|
+
input: inputPublicoResolvido,
|
|
597
|
+
output: outputPublicoResolvido,
|
|
598
|
+
efeitos: efeitosPublicosDeclarados,
|
|
599
|
+
vinculos: route.vinculos,
|
|
600
|
+
superficiePublica: `${route.metodo ?? "?"} ${route.caminho ?? "?"}`,
|
|
601
|
+
}),
|
|
200
602
|
publico: {
|
|
201
603
|
metodo: route.metodo,
|
|
202
604
|
caminho: route.caminho,
|
|
@@ -206,10 +608,25 @@ export function converterParaIr(modulo, diagnosticos, contexto) {
|
|
|
206
608
|
errors: errosPublicosResolvidos,
|
|
207
609
|
effects: efeitosPublicosDeclarados,
|
|
208
610
|
garantiasMinimas: garantiasPublicasMinimas,
|
|
611
|
+
confiancaContrato: "media",
|
|
612
|
+
riscoRegressao: "medio",
|
|
209
613
|
divergenciasPublicas: [],
|
|
210
614
|
},
|
|
211
615
|
};
|
|
616
|
+
routeResolvida.publico.confiancaContrato = calcularConfiancaPublica(routeResolvida);
|
|
617
|
+
routeResolvida.publico.riscoRegressao = calcularRiscoPublico(routeResolvida);
|
|
618
|
+
return routeResolvida;
|
|
212
619
|
});
|
|
620
|
+
const superficies = [
|
|
621
|
+
...modulo.workers.map((item) => converterSuperficie("worker", item)),
|
|
622
|
+
...modulo.eventos.map((item) => converterSuperficie("evento", item)),
|
|
623
|
+
...modulo.filas.map((item) => converterSuperficie("fila", item)),
|
|
624
|
+
...modulo.crons.map((item) => converterSuperficie("cron", item)),
|
|
625
|
+
...modulo.webhooks.map((item) => converterSuperficie("webhook", item)),
|
|
626
|
+
...modulo.caches.map((item) => converterSuperficie("cache", item)),
|
|
627
|
+
...modulo.storages.map((item) => converterSuperficie("storage", item)),
|
|
628
|
+
...modulo.policies.map((item) => converterSuperficie("policy", item)),
|
|
629
|
+
];
|
|
213
630
|
const states = modulo.states.map((state) => ({
|
|
214
631
|
nome: state.nome,
|
|
215
632
|
campos: converterCampos(encontrarSubBloco(state.corpo, "fields") ?? state.corpo),
|
|
@@ -221,6 +638,21 @@ export function converterParaIr(modulo, diagnosticos, contexto) {
|
|
|
221
638
|
.map((linha) => parsearTransicaoEstado(linha.conteudo))
|
|
222
639
|
.filter((linha) => Boolean(linha)),
|
|
223
640
|
}));
|
|
641
|
+
const resumoAgenteModulo = resumirAgente({
|
|
642
|
+
input: [],
|
|
643
|
+
output: [],
|
|
644
|
+
efeitos: [
|
|
645
|
+
...tasks.flatMap((task) => task.efeitosEstruturados),
|
|
646
|
+
...routes.flatMap((route) => route.efeitosPublicos),
|
|
647
|
+
...superficies.flatMap((superficie) => superficie.effects),
|
|
648
|
+
],
|
|
649
|
+
vinculos: [
|
|
650
|
+
...converterVinculos(modulo.vinculos),
|
|
651
|
+
...tasks.flatMap((task) => task.vinculos),
|
|
652
|
+
...routes.flatMap((route) => route.vinculos),
|
|
653
|
+
...superficies.flatMap((superficie) => superficie.vinculos),
|
|
654
|
+
],
|
|
655
|
+
});
|
|
224
656
|
return {
|
|
225
657
|
nome: modulo.nome,
|
|
226
658
|
uses: contexto?.modulosImportados.length
|
|
@@ -234,13 +666,25 @@ export function converterParaIr(modulo, diagnosticos, contexto) {
|
|
|
234
666
|
interoperabilidades: contexto?.interoperabilidades.map((interop) => ({ ...interop })) ?? modulo.uses
|
|
235
667
|
.filter(ehUseInterop)
|
|
236
668
|
.map((use) => ({ origem: use.origem, caminho: use.caminho })),
|
|
669
|
+
vinculos: converterVinculos(modulo.vinculos),
|
|
670
|
+
perfilCompatibilidade: perfilModulo,
|
|
237
671
|
types,
|
|
238
672
|
entities,
|
|
239
673
|
enums: modulo.enums.map((enumeracao) => ({ nome: enumeracao.nome, valores: enumeracao.valores })),
|
|
240
674
|
tasks,
|
|
241
675
|
flows,
|
|
242
676
|
routes,
|
|
677
|
+
superficies,
|
|
243
678
|
states,
|
|
679
|
+
resumoAgente: {
|
|
680
|
+
...resumoAgenteModulo,
|
|
681
|
+
superficiesPublicas: deduplicarTexto([
|
|
682
|
+
...routes.map((route) => `${route.metodo ?? "?"} ${route.caminho ?? route.nome}`),
|
|
683
|
+
...superficies
|
|
684
|
+
.filter((superficie) => superficie.perfilCompatibilidade === "publico")
|
|
685
|
+
.map((superficie) => `${superficie.tipo}:${superficie.nome}`),
|
|
686
|
+
]),
|
|
687
|
+
},
|
|
244
688
|
diagnosticos,
|
|
245
689
|
};
|
|
246
690
|
}
|