@semacode/cli 1.5.4 → 1.5.6
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 +3 -1
- package/dist/angular-consumer-standalone.d.ts +6 -0
- package/dist/angular-consumer-standalone.js +264 -0
- package/dist/angular-consumer-standalone.js.map +1 -0
- package/dist/drift.d.ts +10 -1
- package/dist/drift.js +147 -21
- package/dist/drift.js.map +1 -1
- package/dist/importador.js +9 -1
- package/dist/importador.js.map +1 -1
- package/dist/index.js +22 -4
- package/dist/index.js.map +1 -1
- package/docs/cli.md +1 -1
- package/docs/persistencia-vendor-first.md +1 -1
- package/docs/sintaxe.md +2 -0
- package/node_modules/@sema/gerador-css/package.json +1 -1
- package/node_modules/@sema/gerador-dart/package.json +1 -1
- package/node_modules/@sema/gerador-html/package.json +1 -1
- package/node_modules/@sema/gerador-javascript/package.json +1 -1
- package/node_modules/@sema/gerador-lua/package.json +1 -1
- package/node_modules/@sema/gerador-python/dist/index.js +157 -23
- package/node_modules/@sema/gerador-python/dist/index.js.map +1 -1
- package/node_modules/@sema/gerador-python/package.json +1 -1
- package/node_modules/@sema/gerador-typescript/dist/index.js +172 -22
- package/node_modules/@sema/gerador-typescript/dist/index.js.map +1 -1
- package/node_modules/@sema/gerador-typescript/package.json +1 -1
- package/node_modules/@sema/nucleo/package.json +1 -1
- package/node_modules/@sema/padroes/package.json +1 -1
- package/package.json +10 -10
package/dist/drift.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readdir, readFile } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import ts from "typescript";
|
|
4
|
+
import { coletarSuperficiesAngularStandaloneConsumer } from "./angular-consumer-standalone.js";
|
|
4
5
|
import { extrairSimbolosCpp } from "./cpp-symbols.js";
|
|
5
6
|
import { extrairRotasDotnet, extrairSimbolosDotnet } from "./dotnet-http.js";
|
|
6
7
|
import { extrairRotasGo, extrairSimbolosGo } from "./go-http.js";
|
|
@@ -677,6 +678,8 @@ function extrairRecursosArquivoLocal(arquivo, codigo) {
|
|
|
677
678
|
const contextoArquivoLocal = /\b(?:json|jsonl|ndjson)\b/i.test(codigo)
|
|
678
679
|
|| /\b(?:read_text|write_text|readFile(?:Sync)?|writeFile(?:Sync)?|open)\b/i.test(codigo)
|
|
679
680
|
|| /\.(?:json|jsonl|ndjson|db|sqlite|sqlite3)\b/i.test(codigo)
|
|
681
|
+
|| /@capacitor\/preferences|Preferences\.(?:get|set|remove)\s*\(/i.test(codigo)
|
|
682
|
+
|| /\b(?:localStorage|sessionStorage)\.(?:getItem|setItem|removeItem)\s*\(/i.test(codigo)
|
|
680
683
|
|| /(?:repository|repositories|repositorio|repo|store|storage|persist|cache)/i.test(normalizarFragmentoArquivo(arquivo));
|
|
681
684
|
if (!contextoArquivoLocal) {
|
|
682
685
|
return [];
|
|
@@ -693,6 +696,12 @@ function extrairRecursosArquivoLocal(arquivo, codigo) {
|
|
|
693
696
|
if (nomeStore && /(?:repository|repositories|repositorio|repo|store|storage|persist|cache)/i.test(nomeArquivo)) {
|
|
694
697
|
registrarRecursoDrift(recursos, "arquivo", "arquivo_local", nomeStore, arquivo);
|
|
695
698
|
}
|
|
699
|
+
for (const match of codigo.matchAll(/Preferences\.(?:get|set|remove)\s*\(\s*\{[\s\S]{0,160}?key\s*:\s*["'`]([^"'`]+)["'`]/gi)) {
|
|
700
|
+
registrarRecursoDrift(recursos, "arquivo", "arquivo_local", match[1], arquivo);
|
|
701
|
+
}
|
|
702
|
+
for (const match of codigo.matchAll(/\b(?:localStorage|sessionStorage)\.(?:getItem|setItem|removeItem)\s*\(\s*["'`]([^"'`]+)["'`]/gi)) {
|
|
703
|
+
registrarRecursoDrift(recursos, "arquivo", "arquivo_local", match[1], arquivo);
|
|
704
|
+
}
|
|
696
705
|
return [...recursos.values()];
|
|
697
706
|
}
|
|
698
707
|
function extrairRecursosPersistenciaCodigoVivo(arquivo, codigo) {
|
|
@@ -1445,7 +1454,10 @@ function inferirConsumerFrameworkPrincipal(fontesLegado, consumerSurfaces, consu
|
|
|
1445
1454
|
|| /(?:^|\/)(?:src\/)?(?:app\/)?(?:router|routes)\.(?:ts|tsx|js|jsx)$/i.test(arquivo))) {
|
|
1446
1455
|
return "react-vite-consumer";
|
|
1447
1456
|
}
|
|
1448
|
-
if (arquivos.some((arquivo) => /(?:^|\/)(?:src\/)?app
|
|
1457
|
+
if (arquivos.some((arquivo) => /(?:^|\/)(?:src\/)?app\.component\.(?:ts|js)$/i.test(arquivo)
|
|
1458
|
+
|| /(?:^|\/)(?:src\/)?app\/.+\.component\.(?:ts|js)$/i.test(arquivo)
|
|
1459
|
+
|| /(?:^|\/)(?:src\/)?components\/.+\.component\.(?:ts|js)$/i.test(arquivo)
|
|
1460
|
+
|| arquivoEhRotasAngularConsumer(arquivo))) {
|
|
1449
1461
|
return "angular-consumer";
|
|
1450
1462
|
}
|
|
1451
1463
|
if (arquivos.some((arquivo) => /(?:^|\/)(?:lib\/)?(?:screens|pages)\/.+\.dart$/i.test(arquivo)
|
|
@@ -1501,6 +1513,7 @@ async function indexarTypeScript(diretorios) {
|
|
|
1501
1513
|
.filter((arquivo) => arquivoEhRotasAngularConsumerRaiz(path.relative(diretorio, arquivo)))
|
|
1502
1514
|
.map((arquivo) => path.resolve(arquivo)));
|
|
1503
1515
|
const usarApenasRotasAngularRaiz = arquivosRotasAngularRaiz.size > 0;
|
|
1516
|
+
let encontrouSuperficieAngularPorRotas = false;
|
|
1504
1517
|
for (const arquivo of arquivos) {
|
|
1505
1518
|
const codigo = await readFile(arquivo, "utf8");
|
|
1506
1519
|
const scriptKind = arquivo.endsWith(".tsx") ? ts.ScriptKind.TSX : ts.ScriptKind.TS;
|
|
@@ -1578,6 +1591,7 @@ async function indexarTypeScript(diretorios) {
|
|
|
1578
1591
|
}
|
|
1579
1592
|
}
|
|
1580
1593
|
if (arquivoEhRotasAngularConsumer(relacao) && (!usarApenasRotasAngularRaiz || arquivosRotasAngularRaiz.has(path.resolve(arquivo)))) {
|
|
1594
|
+
encontrouSuperficieAngularPorRotas = true;
|
|
1581
1595
|
for (const rotaAngular of await extrairRotasAngularConsumer(diretorio, relacao)) {
|
|
1582
1596
|
const arquivoRotasAngular = path.join(diretorio, rotaAngular.arquivoRotas);
|
|
1583
1597
|
consumerSurfaces.set(`${rotaAngular.rota}:${arquivoRotasAngular}:routes`, {
|
|
@@ -1673,6 +1687,23 @@ async function indexarTypeScript(diretorios) {
|
|
|
1673
1687
|
}
|
|
1674
1688
|
}
|
|
1675
1689
|
}
|
|
1690
|
+
if (!encontrouSuperficieAngularPorRotas) {
|
|
1691
|
+
for (const superficie of await coletarSuperficiesAngularStandaloneConsumer(diretorio, arquivos)) {
|
|
1692
|
+
const arquivoSuperficie = path.join(diretorio, superficie.arquivo);
|
|
1693
|
+
consumerSurfaces.set(`${superficie.rota}:${arquivoSuperficie}:${superficie.tipoArquivo}`, {
|
|
1694
|
+
rota: superficie.rota,
|
|
1695
|
+
arquivo: arquivoSuperficie,
|
|
1696
|
+
tipoArquivo: superficie.tipoArquivo,
|
|
1697
|
+
});
|
|
1698
|
+
rotas.push({
|
|
1699
|
+
origem: "angular-consumer",
|
|
1700
|
+
metodo: "VIEW",
|
|
1701
|
+
caminho: superficie.rota,
|
|
1702
|
+
arquivo: arquivoSuperficie,
|
|
1703
|
+
simbolo: superficie.tipoArquivo,
|
|
1704
|
+
});
|
|
1705
|
+
}
|
|
1706
|
+
}
|
|
1676
1707
|
}
|
|
1677
1708
|
return {
|
|
1678
1709
|
simbolos: [...simbolos.values()],
|
|
@@ -2190,12 +2221,18 @@ function extrairCamposArquivoLocalDetalhados(arquivo, codigo) {
|
|
|
2190
2221
|
registrarCampo(recurso.nome, bloco[1] ?? "");
|
|
2191
2222
|
}
|
|
2192
2223
|
}
|
|
2224
|
+
for (const match of codigo.matchAll(/Preferences\.(?:get|set|remove)\s*\(\s*\{[\s\S]{0,160}?key\s*:\s*["'`]([^"'`]+)["'`]/gi)) {
|
|
2225
|
+
registrarColunaPersistenciaDrift(colunas, "arquivo", match[1], match[1], arquivo);
|
|
2226
|
+
}
|
|
2227
|
+
for (const match of codigo.matchAll(/\b(?:localStorage|sessionStorage)\.(?:getItem|setItem|removeItem)\s*\(\s*["'`]([^"'`]+)["'`]/gi)) {
|
|
2228
|
+
registrarColunaPersistenciaDrift(colunas, "arquivo", match[1], match[1], arquivo);
|
|
2229
|
+
}
|
|
2193
2230
|
return [...colunas.values()];
|
|
2194
2231
|
}
|
|
2195
2232
|
function registrarRepositoriosPorRecursos(repositorios, arquivo, codigo, recursos) {
|
|
2196
2233
|
const contextoRepositorio = /(?:repository|repositories|repositorio|repositorios|repo|dao|store|queries|persistence|persistencia)/i.test(arquivo)
|
|
2197
2234
|
|| /\b(?:Repository|Repositories|Dao|Store)\b/.test(codigo);
|
|
2198
|
-
const contextoAcesso = /\b(?:select|insert|update|delete|aggregate|findOne|findMany|findUnique|findFirst|prisma\.|db\.collection|createClient|hset|hget|xadd|xread|json\.(?:load|loads|dump|dumps)|JSON\.(?:parse|stringify)|read_text|write_text|readFile(?:Sync)?|writeFile(?:Sync)?|open)\b/i.test(codigo)
|
|
2235
|
+
const contextoAcesso = /\b(?:select|insert|update|delete|aggregate|findOne|findMany|findUnique|findFirst|prisma\.|db\.collection|createClient|hset|hget|xadd|xread|json\.(?:load|loads|dump|dumps)|JSON\.(?:parse|stringify)|read_text|write_text|readFile(?:Sync)?|writeFile(?:Sync)?|open|Preferences\.(?:get|set|remove)|localStorage\.(?:getItem|setItem|removeItem)|sessionStorage\.(?:getItem|setItem|removeItem))\b/i.test(codigo)
|
|
2199
2236
|
|| /\.(?:json|jsonl|ndjson|db|sqlite|sqlite3)\b/i.test(codigo);
|
|
2200
2237
|
if (!contextoRepositorio && !contextoAcesso) {
|
|
2201
2238
|
return;
|
|
@@ -2255,7 +2292,7 @@ function arquivoCombinaDeclaradoDrift(arquivoReal, arquivoDeclarado) {
|
|
|
2255
2292
|
const declarado = normalizarArquivoDeclaradoDrift(arquivoDeclarado);
|
|
2256
2293
|
return real === declarado || real.endsWith(declarado) || declarado.endsWith(real);
|
|
2257
2294
|
}
|
|
2258
|
-
function coletarArquivosPreferidosPersistenciaTask(task) {
|
|
2295
|
+
function coletarArquivosPreferidosPersistenciaTask(task, mapaImpl) {
|
|
2259
2296
|
const arquivos = new Set();
|
|
2260
2297
|
for (const vinculo of task.vinculos) {
|
|
2261
2298
|
if (vinculo.arquivo) {
|
|
@@ -2265,17 +2302,45 @@ function coletarArquivosPreferidosPersistenciaTask(task) {
|
|
|
2265
2302
|
arquivos.add(vinculo.valor);
|
|
2266
2303
|
}
|
|
2267
2304
|
}
|
|
2305
|
+
if (mapaImpl) {
|
|
2306
|
+
for (const impl of task.implementacoesExternas) {
|
|
2307
|
+
const resolvido = mapaImpl.get(impl.caminho);
|
|
2308
|
+
if (resolvido?.arquivo) {
|
|
2309
|
+
arquivos.add(resolvido.arquivo);
|
|
2310
|
+
}
|
|
2311
|
+
}
|
|
2312
|
+
}
|
|
2268
2313
|
return arquivos;
|
|
2269
2314
|
}
|
|
2270
|
-
function resolverPersistenciaLocalPorTask(mapaRecursos, task, ir, esperado) {
|
|
2315
|
+
function resolverPersistenciaLocalPorTask(mapaRecursos, task, ir, esperado, mapaImpl) {
|
|
2271
2316
|
const todosRecursos = deduplicarRecursosResolvidos([...mapaRecursos.values()].flat());
|
|
2272
|
-
const arquivosPreferidos = [...coletarArquivosPreferidosPersistenciaTask(task)];
|
|
2317
|
+
const arquivosPreferidos = [...coletarArquivosPreferidosPersistenciaTask(task, mapaImpl)];
|
|
2273
2318
|
const candidatosPorArquivo = arquivosPreferidos.length > 0
|
|
2274
2319
|
? todosRecursos.filter((recurso) => recurso.origem === "arquivo"
|
|
2275
2320
|
&& arquivosPreferidos.some((arquivo) => arquivoCombinaDeclaradoDrift(recurso.arquivo, arquivo)))
|
|
2276
2321
|
: [];
|
|
2322
|
+
const variantesAlvo = new Set(variantesNomeRecursoDrift(esperado.alvo));
|
|
2323
|
+
const normalizarBusca = (valor) => valor.toLowerCase().replace(/[^a-z0-9]+/g, "_");
|
|
2324
|
+
const pontuarCandidato = (recurso) => {
|
|
2325
|
+
let score = 0;
|
|
2326
|
+
if (recursoResolvidoCombinaEsperado(recurso, esperado)) {
|
|
2327
|
+
score += 4;
|
|
2328
|
+
}
|
|
2329
|
+
if (variantesNomeRecursoDrift(recurso.nome).some((variacao) => variantesAlvo.has(variacao))) {
|
|
2330
|
+
score += 2;
|
|
2331
|
+
}
|
|
2332
|
+
const nomeNormalizado = normalizarBusca(recurso.nome);
|
|
2333
|
+
const alvoNormalizado = normalizarBusca(esperado.alvo);
|
|
2334
|
+
if (nomeNormalizado.includes(alvoNormalizado) || alvoNormalizado.includes(nomeNormalizado)) {
|
|
2335
|
+
score += 1;
|
|
2336
|
+
}
|
|
2337
|
+
return score;
|
|
2338
|
+
};
|
|
2339
|
+
const ordenarCandidatos = (candidatos) => [...candidatos].sort((a, b) => pontuarCandidato(b) - pontuarCandidato(a)
|
|
2340
|
+
|| a.nome.localeCompare(b.nome, "pt-BR")
|
|
2341
|
+
|| a.arquivo.localeCompare(b.arquivo, "pt-BR"));
|
|
2277
2342
|
if (candidatosPorArquivo.length > 0) {
|
|
2278
|
-
return candidatosPorArquivo;
|
|
2343
|
+
return ordenarCandidatos(candidatosPorArquivo);
|
|
2279
2344
|
}
|
|
2280
2345
|
const termos = new Set([
|
|
2281
2346
|
...quebrarTermosEscopo(ir.nome),
|
|
@@ -2285,8 +2350,8 @@ function resolverPersistenciaLocalPorTask(mapaRecursos, task, ir, esperado) {
|
|
|
2285
2350
|
if (termos.size === 0) {
|
|
2286
2351
|
return [];
|
|
2287
2352
|
}
|
|
2288
|
-
return todosRecursos.filter((recurso) => recurso.origem === "arquivo"
|
|
2289
|
-
&& [...termos].some((termo) => variantesNomeRecursoDrift(recurso.nome).some((variacao) => variacao.includes(termo))));
|
|
2353
|
+
return ordenarCandidatos(todosRecursos.filter((recurso) => recurso.origem === "arquivo"
|
|
2354
|
+
&& [...termos].some((termo) => variantesNomeRecursoDrift(recurso.nome).some((variacao) => variacao.includes(termo)))));
|
|
2290
2355
|
}
|
|
2291
2356
|
function detalhePersistenciaCombinaOrigem(origemDetalhe, recursoReal) {
|
|
2292
2357
|
if (!recursoReal) {
|
|
@@ -2334,7 +2399,7 @@ function localizarCompatibilidadePersistencia(bancos, esperado, recursoReal) {
|
|
|
2334
2399
|
tipo: recursoReal?.tipo ?? esperado.tiposAceitos[0] ?? "query",
|
|
2335
2400
|
};
|
|
2336
2401
|
}
|
|
2337
|
-
export async function analisarPersistenciaReal(contexto, mapaRecursos, detalhesPersistencia, opcoes) {
|
|
2402
|
+
export async function analisarPersistenciaReal(contexto, mapaRecursos, detalhesPersistencia, opcoes, mapaImpl) {
|
|
2338
2403
|
const opcoesResolvidas = resolverOpcoesDrift(opcoes);
|
|
2339
2404
|
const diretoriosCodigoAtivos = resolverDiretoriosCodigoEscopoReal(contexto, opcoesResolvidas);
|
|
2340
2405
|
const mapa = mapaRecursos ?? construirMapaRecursos((await indexarPersistenciaDeclarativa(diretoriosCodigoAtivos)).recursos);
|
|
@@ -2346,12 +2411,12 @@ export async function analisarPersistenciaReal(contexto, mapaRecursos, detalhesP
|
|
|
2346
2411
|
continue;
|
|
2347
2412
|
}
|
|
2348
2413
|
for (const task of ir.tasks) {
|
|
2349
|
-
for (const esperado of extrairRecursosEsperados(task, ir)) {
|
|
2414
|
+
for (const esperado of extrairRecursosEsperados(task, ir, mapa, mapaImpl)) {
|
|
2350
2415
|
const correspondencias = esperado.nomes.flatMap((nome) => variantesNomeRecursoDrift(nome).flatMap((variante) => (mapa.get(variante) ?? []).filter((recurso) => recursoResolvidoCombinaEsperado(recurso, esperado))));
|
|
2351
2416
|
let recursosReais = deduplicarRecursosResolvidos(correspondencias);
|
|
2352
|
-
const arquivosPreferidos = [...coletarArquivosPreferidosPersistenciaTask(task)];
|
|
2417
|
+
const arquivosPreferidos = [...coletarArquivosPreferidosPersistenciaTask(task, mapaImpl)];
|
|
2353
2418
|
if (recursosReais.length === 0) {
|
|
2354
|
-
recursosReais = resolverPersistenciaLocalPorTask(mapa, task, ir, esperado);
|
|
2419
|
+
recursosReais = resolverPersistenciaLocalPorTask(mapa, task, ir, esperado, mapaImpl);
|
|
2355
2420
|
}
|
|
2356
2421
|
const compatibilidade = localizarCompatibilidadePersistencia(ir.databases, esperado, recursosReais[0]);
|
|
2357
2422
|
let colunas = [...new Set(detalhes.colunas
|
|
@@ -2624,11 +2689,25 @@ function recursoPersistenciaCombinaAlvo(recurso, alvo) {
|
|
|
2624
2689
|
}
|
|
2625
2690
|
return nomesRecursoPersistencia(recurso).some((nome) => variantesNomeRecursoDrift(nome).some((variacao) => alvoVariantes.has(variacao)));
|
|
2626
2691
|
}
|
|
2627
|
-
function taskSugerePersistenciaSemBanco(task) {
|
|
2628
|
-
|
|
2629
|
-
|
|
2692
|
+
function taskSugerePersistenciaSemBanco(task, mapaRecursos, mapaImpl) {
|
|
2693
|
+
if (task.vinculos.some((vinculo) => /(?:repository|repositories|repositorio|repo|store|storage|persist|cache)/i.test(`${vinculo.valor} ${vinculo.arquivo ?? ""} ${vinculo.simbolo ?? ""}`))) {
|
|
2694
|
+
return true;
|
|
2695
|
+
}
|
|
2696
|
+
if (task.implementacoesExternas.some((impl) => /(?:repository|repositories|repositorio|repo|store|storage|persist|cache)/i.test(impl.caminho))) {
|
|
2697
|
+
return true;
|
|
2698
|
+
}
|
|
2699
|
+
if (!mapaRecursos || !mapaImpl) {
|
|
2700
|
+
return false;
|
|
2701
|
+
}
|
|
2702
|
+
const arquivosPreferidos = [...coletarArquivosPreferidosPersistenciaTask(task, mapaImpl)];
|
|
2703
|
+
if (arquivosPreferidos.length === 0) {
|
|
2704
|
+
return false;
|
|
2705
|
+
}
|
|
2706
|
+
const recursos = deduplicarRecursosResolvidos([...mapaRecursos.values()].flat());
|
|
2707
|
+
return recursos.some((recurso) => recurso.origem === "arquivo"
|
|
2708
|
+
&& arquivosPreferidos.some((arquivo) => arquivoCombinaDeclaradoDrift(recurso.arquivo, arquivo)));
|
|
2630
2709
|
}
|
|
2631
|
-
function extrairRecursosEsperados(task, ir) {
|
|
2710
|
+
function extrairRecursosEsperados(task, ir, mapaRecursos, mapaImpl) {
|
|
2632
2711
|
const esperados = new Map();
|
|
2633
2712
|
const registrar = (esperado) => {
|
|
2634
2713
|
const chave = `${esperado.origem ?? "qualquer"}:${esperado.tiposAceitos.join(",")}:${esperado.nomes.join("|")}:${esperado.alvo}`;
|
|
@@ -2652,9 +2731,9 @@ function extrairRecursosEsperados(task, ir) {
|
|
|
2652
2731
|
return [...esperados.values()];
|
|
2653
2732
|
}
|
|
2654
2733
|
if (ir.databases.length === 0) {
|
|
2655
|
-
const sugerePersistenciaLocal = taskSugerePersistenciaSemBanco(task);
|
|
2734
|
+
const sugerePersistenciaLocal = taskSugerePersistenciaSemBanco(task, mapaRecursos, mapaImpl);
|
|
2656
2735
|
for (const efeito of efeitosPersistencia) {
|
|
2657
|
-
if (
|
|
2736
|
+
if (!sugerePersistenciaLocal) {
|
|
2658
2737
|
continue;
|
|
2659
2738
|
}
|
|
2660
2739
|
if ([...esperados.values()].some((item) => item.alvo === efeito.alvo)) {
|
|
@@ -2819,12 +2898,24 @@ export async function analisarDriftLegado(contexto, opcoes) {
|
|
|
2819
2898
|
const taskPorChave = new Map();
|
|
2820
2899
|
const guardrailsPorTask = new Map();
|
|
2821
2900
|
const resumoVinculosPorTask = new Map();
|
|
2901
|
+
const arquivosAncoraHerdadosPorTask = new Map();
|
|
2822
2902
|
for (const item of contexto.modulosSelecionados) {
|
|
2823
2903
|
const ir = item.resultado.ir;
|
|
2824
2904
|
if (!ir) {
|
|
2825
2905
|
continue;
|
|
2826
2906
|
}
|
|
2827
2907
|
const superficiesPorChave = new Map(ir.superficies.map((superficie) => [`${superficie.tipo}:${superficie.nome}`, superficie]));
|
|
2908
|
+
const routesPorNome = new Map(ir.routes.map((route) => [route.nome, route]));
|
|
2909
|
+
const flowsPorNome = new Map(ir.flows.map((flow) => [flow.nome, flow]));
|
|
2910
|
+
const registrarArquivoAncoraHerdado = (taskNome, arquivo) => {
|
|
2911
|
+
if (!arquivo) {
|
|
2912
|
+
return;
|
|
2913
|
+
}
|
|
2914
|
+
const chaveTask = `${ir.nome}:${taskNome}`;
|
|
2915
|
+
const arquivos = arquivosAncoraHerdadosPorTask.get(chaveTask) ?? new Set();
|
|
2916
|
+
arquivos.add(arquivo);
|
|
2917
|
+
arquivosAncoraHerdadosPorTask.set(chaveTask, arquivos);
|
|
2918
|
+
};
|
|
2828
2919
|
for (const task of ir.tasks) {
|
|
2829
2920
|
guardrailsPorTask.set(`${ir.nome}:${task.nome}`, {
|
|
2830
2921
|
publica: false,
|
|
@@ -2950,16 +3041,18 @@ export async function analisarDriftLegado(contexto, opcoes) {
|
|
|
2950
3041
|
confiancaVinculo: "baixa",
|
|
2951
3042
|
riscoOperacional: "baixo",
|
|
2952
3043
|
lacunas: [],
|
|
3044
|
+
ancoragemVinculo: "ausente",
|
|
2953
3045
|
arquivosReferenciados: [...arquivosReferenciados].sort((a, b) => a.localeCompare(b, "pt-BR")),
|
|
3046
|
+
arquivosAncoraHerdados: [],
|
|
2954
3047
|
arquivosProvaveisEditar: [],
|
|
2955
3048
|
simbolosReferenciados: [...simbolosReferenciados].sort((a, b) => a.localeCompare(b, "pt-BR")),
|
|
2956
3049
|
candidatosImpl: ordenarCandidatos([...candidatosTask.values()]).slice(0, 5),
|
|
2957
3050
|
checksSugeridos: [],
|
|
2958
3051
|
});
|
|
2959
|
-
for (const recursoEsperado of extrairRecursosEsperados(task, ir)) {
|
|
3052
|
+
for (const recursoEsperado of extrairRecursosEsperados(task, ir, mapaRecursos, mapaImpl)) {
|
|
2960
3053
|
let resolvido = resolverRecursoEsperado(mapaRecursos, recursoEsperado, arquivosReferenciados);
|
|
2961
3054
|
if (!resolvido) {
|
|
2962
|
-
resolvido = resolverPersistenciaLocalPorTask(mapaRecursos, task, ir, recursoEsperado)[0];
|
|
3055
|
+
resolvido = resolverPersistenciaLocalPorTask(mapaRecursos, task, ir, recursoEsperado, mapaImpl)[0];
|
|
2963
3056
|
}
|
|
2964
3057
|
const registro = {
|
|
2965
3058
|
modulo: ir.nome,
|
|
@@ -3155,6 +3248,29 @@ export async function analisarDriftLegado(contexto, opcoes) {
|
|
|
3155
3248
|
}
|
|
3156
3249
|
else {
|
|
3157
3250
|
vinculosValidos.push(registro);
|
|
3251
|
+
if (itemVinculo.donoTipo === "modulo") {
|
|
3252
|
+
for (const task of ir.tasks) {
|
|
3253
|
+
registrarArquivoAncoraHerdado(task.nome, registro.arquivo);
|
|
3254
|
+
}
|
|
3255
|
+
}
|
|
3256
|
+
else if (itemVinculo.donoTipo === "flow") {
|
|
3257
|
+
const flow = flowsPorNome.get(itemVinculo.dono);
|
|
3258
|
+
for (const taskNome of flow?.tasksReferenciadas ?? []) {
|
|
3259
|
+
registrarArquivoAncoraHerdado(taskNome, registro.arquivo);
|
|
3260
|
+
}
|
|
3261
|
+
}
|
|
3262
|
+
else if (itemVinculo.donoTipo === "route") {
|
|
3263
|
+
const route = routesPorNome.get(itemVinculo.dono);
|
|
3264
|
+
if (route?.task) {
|
|
3265
|
+
registrarArquivoAncoraHerdado(route.task, registro.arquivo);
|
|
3266
|
+
}
|
|
3267
|
+
}
|
|
3268
|
+
else if (itemVinculo.donoTipo === "superficie") {
|
|
3269
|
+
const superficie = superficiesPorChave.get(itemVinculo.dono);
|
|
3270
|
+
if (superficie?.task) {
|
|
3271
|
+
registrarArquivoAncoraHerdado(superficie.task, registro.arquivo);
|
|
3272
|
+
}
|
|
3273
|
+
}
|
|
3158
3274
|
}
|
|
3159
3275
|
if (itemVinculo.donoTipo === "task") {
|
|
3160
3276
|
const chaveTask = `${ir.nome}:${itemVinculo.dono}`;
|
|
@@ -3197,6 +3313,9 @@ export async function analisarDriftLegado(contexto, opcoes) {
|
|
|
3197
3313
|
quebrados: 0,
|
|
3198
3314
|
arquivos: new Set(),
|
|
3199
3315
|
};
|
|
3316
|
+
const arquivosAncoraHerdados = [...(arquivosAncoraHerdadosPorTask.get(chaveTask) ?? new Set())]
|
|
3317
|
+
.filter((arquivo) => !resumoVinculos.arquivos.has(arquivo))
|
|
3318
|
+
.sort((a, b) => a.localeCompare(b, "pt-BR"));
|
|
3200
3319
|
if (!task) {
|
|
3201
3320
|
continue;
|
|
3202
3321
|
}
|
|
@@ -3204,8 +3323,15 @@ export async function analisarDriftLegado(contexto, opcoes) {
|
|
|
3204
3323
|
resumo.riscoOperacional = calcularRiscoOperacional(task);
|
|
3205
3324
|
resumo.lacunas = resumirLacunasTask(task, resumo.semImplementacao, resumo.implsQuebrados, resumoVinculos.quebrados, guardrails);
|
|
3206
3325
|
resumo.scoreSemantico = calcularScoreTask(task, resumo.implsValidos, resumo.implsQuebrados, resumoVinculos.validos, resumoVinculos.quebrados, resumo.semImplementacao);
|
|
3326
|
+
resumo.ancoragemVinculo = task.vinculos.length > 0
|
|
3327
|
+
? "propria"
|
|
3328
|
+
: arquivosAncoraHerdados.length > 0
|
|
3329
|
+
? "herdada_modulo"
|
|
3330
|
+
: "ausente";
|
|
3331
|
+
resumo.arquivosAncoraHerdados = arquivosAncoraHerdados;
|
|
3207
3332
|
resumo.arquivosProvaveisEditar = [...new Set([
|
|
3208
3333
|
...resumo.arquivosReferenciados,
|
|
3334
|
+
...arquivosAncoraHerdados,
|
|
3209
3335
|
...resumo.candidatosImpl.map((candidato) => candidato.arquivo),
|
|
3210
3336
|
...resumoVinculos.arquivos,
|
|
3211
3337
|
])].sort((a, b) => a.localeCompare(b, "pt-BR"));
|
|
@@ -3312,7 +3438,7 @@ export async function analisarDriftLegado(contexto, opcoes) {
|
|
|
3312
3438
|
const appRoutes = [...new Set(consumerSurfaces.map((surface) => surface.rota))]
|
|
3313
3439
|
.sort((a, b) => a.localeCompare(b, "pt-BR"));
|
|
3314
3440
|
const consumerFramework = inferirConsumerFrameworkPrincipal(contexto.fontesLegado, consumerSurfaces, consumerBridges);
|
|
3315
|
-
const persistenciaReal = await analisarPersistenciaReal(contexto, mapaRecursos, detalhesPersistencia, opcoesResolvidas);
|
|
3441
|
+
const persistenciaReal = await analisarPersistenciaReal(contexto, mapaRecursos, detalhesPersistencia, opcoesResolvidas, mapaImpl);
|
|
3316
3442
|
for (const item of persistenciaReal) {
|
|
3317
3443
|
if (item.status === "divergente") {
|
|
3318
3444
|
diagnosticos.push({
|