@semacode/cli 2.3.0 → 3.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/LICENSE +39 -39
- package/README.md +112 -41
- package/dist/agentContextPack.js +14 -10
- package/dist/agentEntryPoints.d.ts +5 -0
- package/dist/agentEntryPoints.js +102 -91
- package/dist/angular-consumer-standalone.d.ts +3 -1
- package/dist/angular-consumer-standalone.js +12 -8
- package/dist/bin.d.ts +6 -0
- package/dist/bin.js +130 -0
- package/dist/cliArgs.js +4 -4
- package/dist/cliControlError.d.ts +12 -0
- package/dist/cliControlError.js +47 -0
- package/dist/cliGrammar.d.ts +11 -0
- package/dist/cliGrammar.js +551 -0
- package/dist/cliHelp.d.ts +13 -0
- package/dist/cliHelp.js +19 -0
- package/dist/cliHelpTexto.d.ts +3 -0
- package/dist/cliHelpTexto.js +168 -0
- package/dist/cliRuntime.d.ts +2 -0
- package/dist/cliRuntime.js +31 -0
- package/dist/comandos.js +9 -22
- package/dist/contexto.js +5 -5
- package/dist/dev/index.d.ts +1 -0
- package/dist/dev/index.js +51 -9
- package/dist/discovery/catalog.js +3 -3
- package/dist/distribuicao/filesystemGlobal.d.ts +63 -0
- package/dist/distribuicao/filesystemGlobal.js +701 -0
- package/dist/distribuicao/index.d.ts +7 -0
- package/dist/distribuicao/index.js +227 -0
- package/dist/distribuicao/launcherGlobal.d.ts +53 -0
- package/dist/distribuicao/launcherGlobal.js +643 -0
- package/dist/distribuicao/launcherWindows.d.ts +28 -0
- package/dist/distribuicao/launcherWindows.js +326 -0
- package/dist/distribuicao/lockContextGlobal.d.ts +10 -0
- package/dist/distribuicao/lockContextGlobal.js +17 -0
- package/dist/distribuicao/lockGlobal.d.ts +6 -0
- package/dist/distribuicao/lockGlobal.js +520 -0
- package/dist/distribuicao/skillGlobal.d.ts +48 -0
- package/dist/distribuicao/skillGlobal.js +652 -0
- package/dist/distribuicao/skillIntentPolicy.d.ts +21 -0
- package/dist/distribuicao/skillIntentPolicy.js +115 -0
- package/dist/distribuicao/tipos.d.ts +50 -0
- package/dist/distribuicao/tipos.js +10 -0
- package/dist/distribuicao/versaoSemantica.d.ts +3 -0
- package/dist/distribuicao/versaoSemantica.js +62 -0
- package/dist/drift.part01.d.ts +34 -2
- package/dist/drift.part01.js +3 -0
- package/dist/drift.part04.d.ts +12 -2
- package/dist/drift.part04.js +89 -15
- package/dist/drift.part05.d.ts +2 -1
- package/dist/drift.part05.js +9 -6
- package/dist/drift.part06.d.ts +2 -1
- package/dist/drift.part06.js +115 -24
- package/dist/drift.part07.d.ts +11 -10
- package/dist/drift.part07.js +261 -255
- package/dist/drift.part08.d.ts +2 -1
- package/dist/drift.part08.js +35 -25
- package/dist/drift.part11.js +279 -32
- package/dist/drift.part12.d.ts +1 -1
- package/dist/drift.part12.js +196 -11
- package/dist/drift.part13.d.ts +18 -2
- package/dist/drift.part13.js +654 -76
- package/dist/drift.part14.js +21 -7
- package/dist/driftCacheCas.d.ts +43 -0
- package/dist/driftCacheCas.js +351 -0
- package/dist/driftCacheFilesystem.d.ts +64 -0
- package/dist/driftCacheFilesystem.js +313 -0
- package/dist/driftCacheModes.d.ts +38 -0
- package/dist/driftCacheModes.js +147 -0
- package/dist/driftCacheStore.d.ts +80 -0
- package/dist/driftCacheStore.js +603 -0
- package/dist/driftCatalogo.d.ts +65 -0
- package/dist/driftCatalogo.js +516 -0
- package/dist/driftEscopo.d.ts +21 -0
- package/dist/driftEscopo.js +647 -0
- package/dist/driftEscopoReferencias.d.ts +8 -0
- package/dist/driftEscopoReferencias.js +612 -0
- package/dist/driftOrcamento.d.ts +6 -0
- package/dist/driftOrcamento.js +20 -3
- package/dist/geracaoCore.js +4 -6
- package/dist/iaPrompts.d.ts +3 -3
- package/dist/iaPrompts.js +13 -14
- package/dist/index.d.ts +4 -1
- package/dist/index.js +6 -25
- package/dist/index.part01.d.ts +21 -14
- package/dist/index.part01.js +20 -165
- package/dist/index.part02.js +57 -43
- package/dist/index.part03.d.ts +23 -1
- package/dist/index.part03.js +83 -8
- package/dist/index.part04.d.ts +10 -2
- package/dist/index.part04.js +48 -14
- package/dist/index.part05.d.ts +1 -1
- package/dist/index.part05.js +109 -30
- package/dist/index.part06.js +34 -16
- package/dist/index.part07.js +31 -27
- package/dist/index.part08.d.ts +1 -1
- package/dist/index.part08.js +23 -28
- package/dist/init/templates.part01.js +393 -393
- package/dist/init/templates.part02.js +189 -189
- package/dist/initCommand.js +5 -1
- package/dist/initTemplatesBackend.js +73 -73
- package/dist/initTemplatesBase.js +7 -5
- package/dist/initTemplatesFlutter.js +137 -137
- package/dist/initTemplatesRuntime.js +350 -350
- package/dist/initTemplatesWeb.js +309 -309
- package/dist/pipelineConteudo/command.d.ts +1 -0
- package/dist/pipelineConteudo/command.js +4 -32
- package/dist/pipelineConteudo/help.d.ts +2 -0
- package/dist/pipelineConteudo/help.js +33 -0
- package/dist/profileAuthorCommand.js +3 -7
- package/dist/profileCommand.js +3 -7
- package/dist/projeto.d.ts +1 -1
- package/dist/projetoCarregar.d.ts +2 -2
- package/dist/projetoCarregar.js +69 -28
- package/dist/projetoCatalogo.d.ts +8 -0
- package/dist/projetoCatalogo.js +164 -0
- package/dist/projetoOrigens.d.ts +2 -0
- package/dist/projetoOrigens.js +65 -9
- package/dist/projetoTipos.d.ts +15 -5
- package/dist/resultadoCli.d.ts +20 -0
- package/dist/resultadoCli.js +57 -0
- package/dist/saidaCli.d.ts +35 -0
- package/dist/saidaCli.js +118 -0
- package/dist/sistemasInterativos/acceptanceEvidence.d.ts +22 -0
- package/dist/sistemasInterativos/acceptanceEvidence.js +345 -0
- package/dist/sistemasInterativos/engineObservation.d.ts +12 -0
- package/dist/sistemasInterativos/engineObservation.js +438 -0
- package/dist/sistemasInterativos/jobOrchestration.d.ts +2 -0
- package/dist/sistemasInterativos/jobOrchestration.js +204 -0
- package/dist/sistemasInterativos/operationPrimitives.d.ts +21 -0
- package/dist/sistemasInterativos/operationPrimitives.js +194 -0
- package/dist/sistemasInterativos/operations.d.ts +4 -39
- package/dist/sistemasInterativos/operations.js +5 -1164
- package/dist/skillCommand.d.ts +5 -0
- package/dist/skillCommand.js +88 -0
- package/dist/sync/index.js +35 -35
- package/docs/README.md +11 -7
- package/docs/ai-integration.md +18 -11
- package/docs/ai-onboarding.md +81 -62
- package/docs/ai-workflow.md +10 -4
- package/docs/auth.md +26 -26
- package/docs/cli.md +197 -79
- package/docs/commands.md +30 -6
- package/docs/database.md +15 -15
- package/docs/deploy.md +54 -41
- package/docs/documentation.md +11 -10
- package/docs/drift-cache.md +108 -0
- package/docs/env.md +16 -16
- package/docs/frontend.md +41 -41
- package/docs/getting-started.md +82 -57
- package/docs/i18n.md +15 -15
- package/docs/repositories.md +60 -43
- package/docs/rollback.md +38 -31
- package/docs/security.md +54 -32
- package/docs/sistemas-interativos.md +27 -27
- package/docs/support.md +8 -8
- package/docs/testing.md +123 -17
- package/docs/vocabulary.md +29 -29
- package/exemplos/agendamento.sema +1 -1
- package/exemplos/assinatura.sema +1 -1
- package/exemplos/auditoria.sema +1 -1
- package/exemplos/autenticacao.sema +1 -1
- package/exemplos/author_obra_comum.sema +1 -1
- package/exemplos/author_tema_sensivel.sema +1 -1
- package/exemplos/automacao.sema +1 -1
- package/exemplos/cadastro_usuario.sema +1 -1
- package/exemplos/calculadora.sema +1 -1
- package/exemplos/crud_simples.sema +1 -1
- package/exemplos/estoque.sema +1 -1
- package/exemplos/exportacao.sema +1 -1
- package/exemplos/fila.sema +1 -1
- package/exemplos/integracao_externa.sema +1 -1
- package/exemplos/multi_tenant.sema +1 -1
- package/exemplos/notificacao.sema +1 -1
- package/exemplos/operacao_estrategia.sema +132 -132
- package/exemplos/operacao_estrategia_discovery.sema +220 -220
- package/exemplos/operacao_estrategia_fluxo.sema +114 -114
- package/exemplos/operacao_estrategia_gates.sema +106 -106
- package/exemplos/operacao_estrategia_quarentena.sema +133 -133
- package/exemplos/operacao_estrategia_rollout.sema +124 -124
- package/exemplos/pagamento.sema +1 -1
- package/exemplos/pagamento_dominio.sema +1 -1
- package/exemplos/pedido.sema +1 -1
- package/exemplos/permissao.sema +1 -1
- package/exemplos/persistencia_vendor_first.sema +1 -1
- package/exemplos/profile_conversas.sema +165 -165
- package/exemplos/profile_game.sema +1 -1
- package/exemplos/profile_legal.sema +1 -1
- package/exemplos/profile_ops.sema +1 -1
- package/exemplos/profile_research.sema +1 -1
- package/exemplos/profile_software.sema +1 -1
- package/exemplos/profile_workflow_n8n.sema +1 -1
- package/exemplos/relatorio.sema +1 -1
- package/exemplos/replica_analitica_erp.sema +1 -1
- package/exemplos/testes_embutidos.sema +1 -1
- package/exemplos/tratamento_erro.sema +1 -1
- package/exemplos/upload_arquivo.sema +1 -1
- package/exemplos/webhook.sema +1 -1
- package/node_modules/@sema/gerador-cpp/dist/index.js +176 -176
- package/node_modules/@sema/gerador-css/dist/index.part01.js +10 -10
- package/node_modules/@sema/gerador-css/dist/index.part02.js +460 -460
- package/node_modules/@sema/gerador-dotnet/dist/index.js +169 -169
- package/node_modules/@sema/gerador-html/dist/index.js +17 -17
- package/node_modules/@sema/gerador-python/dist/index.part02.js +3 -3
- package/node_modules/@sema/gerador-typescript/dist/index.part02.js +11 -11
- package/node_modules/@sema/nucleo/dist/diagnosticos/melhorador.js +42 -42
- package/node_modules/@sema/nucleo/dist/semantico/analisador.d.ts +1 -0
- package/node_modules/@sema/nucleo/dist/semantico/analisador.js +1 -0
- package/package.json +7 -2
- package/scripts/postinstall.mjs +148 -0
- package/skills/sema/SKILL.md +199 -0
- package/skills/sema/agents/openai.yaml +4 -0
- package/node_modules/@sema/gerador-cpp/dist/index.js.map +0 -1
- package/node_modules/@sema/gerador-css/dist/index.js.map +0 -1
- package/node_modules/@sema/gerador-css/dist/index.part01.js.map +0 -1
- package/node_modules/@sema/gerador-css/dist/index.part02.js.map +0 -1
- package/node_modules/@sema/gerador-dart/dist/index.js.map +0 -1
- package/node_modules/@sema/gerador-dotnet/dist/index.js.map +0 -1
- package/node_modules/@sema/gerador-html/dist/index.js.map +0 -1
- package/node_modules/@sema/gerador-javascript/dist/index.js.map +0 -1
- package/node_modules/@sema/gerador-lua/dist/index.js.map +0 -1
- package/node_modules/@sema/gerador-php/dist/index.js.map +0 -1
- package/node_modules/@sema/gerador-python/dist/index.js.map +0 -1
- package/node_modules/@sema/gerador-python/dist/index.part01.js.map +0 -1
- package/node_modules/@sema/gerador-python/dist/index.part02.js.map +0 -1
- package/node_modules/@sema/gerador-typescript/dist/index.js.map +0 -1
- package/node_modules/@sema/gerador-typescript/dist/index.part01.js.map +0 -1
- package/node_modules/@sema/gerador-typescript/dist/index.part02.js.map +0 -1
- package/node_modules/@sema/gerador-typescript/dist/index.part03.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/ast/tipos.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/diagnosticos/index.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/diagnosticos/melhorador.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/diagnosticos/snippets.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/formatador/index.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/formatador/index.part01.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/formatador/index.part02.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/index.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/ir/conversor.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/ir/conversor.part01.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/ir/conversor.part02.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/ir/conversor.part03.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/ir/modelos.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/lexer/lexer.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/lexer/tokens.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/parser/parser.declaracoes.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/parser/parser.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/parser/parser.modulo.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/parser/parser.part01.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/parser/parser.part02.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/parser/parser.part03.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/persistencia/contratos.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/semantico/analisador.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/semantico/analisador.part01.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/semantico/analisador.part02.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/semantico/analisador.part03.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/semantico/analisador.part04.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/semantico/analisador.part05.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/semantico/analisador.part06.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/semantico/analisador.part07.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/semantico/analisador.part08.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/semantico/estruturas.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/semantico/estruturas.part01.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/semantico/estruturas.part02.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/semantico/orcamentoSemantico.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/semantico/seguranca.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/util/arquivos.js.map +0 -1
- package/node_modules/@sema/padroes/dist/index.js.map +0 -1
|
@@ -0,0 +1,647 @@
|
|
|
1
|
+
// SEMA-GOVERNED: sema.produto.governanca_ia.drift
|
|
2
|
+
// Descricao: planeja o conjunto fisico minimo que pode ser indexado antes de qualquer caminhada de drift.
|
|
3
|
+
import { lstat, realpath } from "node:fs/promises";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { filtrarCaminhosEscopoReal, resolverDiretoriosCodigoEscopoReal, } from "./drift.part02.js";
|
|
6
|
+
import { candidatosReferenciaLocalDrift, extrairReferenciasLocaisDrift, raizesCodigoLogicasDrift, } from "./driftEscopoReferencias.js";
|
|
7
|
+
export { extrairReferenciasLocaisDrift } from "./driftEscopoReferencias.js";
|
|
8
|
+
const CONCORRENCIA_SONDAGENS_DRIFT = 16;
|
|
9
|
+
const CONCORRENCIA_MAPEAMENTO_DEPENDENCIAS_DRIFT = 8;
|
|
10
|
+
const EXTENSAO_POR_ORIGEM = {
|
|
11
|
+
ts: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"],
|
|
12
|
+
js: [".js", ".jsx", ".mjs", ".cjs", ".ts", ".tsx"],
|
|
13
|
+
py: [".py"],
|
|
14
|
+
dart: [".dart"],
|
|
15
|
+
lua: [".lua"],
|
|
16
|
+
cs: [".cs"],
|
|
17
|
+
java: [".java"],
|
|
18
|
+
go: [".go"],
|
|
19
|
+
rust: [".rs"],
|
|
20
|
+
cpp: [".cpp", ".cc", ".cxx", ".hpp", ".h"],
|
|
21
|
+
php: [".php"],
|
|
22
|
+
};
|
|
23
|
+
const EXTENSOES_CODIGO_PLANEJADO = new Set([
|
|
24
|
+
...Object.values(EXTENSAO_POR_ORIGEM).flat(),
|
|
25
|
+
".sql", ".psql", ".ddl", ".prisma",
|
|
26
|
+
]);
|
|
27
|
+
function chaveCaminho(caminho) {
|
|
28
|
+
const absoluto = path.normalize(path.resolve(caminho));
|
|
29
|
+
return process.platform === "win32" ? absoluto.toLowerCase() : absoluto;
|
|
30
|
+
}
|
|
31
|
+
function caminhoEstaDentro(raiz, alvo) {
|
|
32
|
+
const relativo = path.relative(path.resolve(raiz), path.resolve(alvo));
|
|
33
|
+
return relativo === "" || (relativo !== ".."
|
|
34
|
+
&& !relativo.startsWith(`..${path.sep}`)
|
|
35
|
+
&& !path.isAbsolute(relativo));
|
|
36
|
+
}
|
|
37
|
+
function identidadesArquivoIguais(a, b) {
|
|
38
|
+
return a.isFile()
|
|
39
|
+
&& b.isFile()
|
|
40
|
+
&& !a.isSymbolicLink()
|
|
41
|
+
&& !b.isSymbolicLink()
|
|
42
|
+
&& a.dev === b.dev
|
|
43
|
+
&& a.ino === b.ino
|
|
44
|
+
&& a.size === b.size
|
|
45
|
+
&& a.mtimeNs === b.mtimeNs
|
|
46
|
+
&& a.ctimeNs === b.ctimeNs;
|
|
47
|
+
}
|
|
48
|
+
async function mapearComLimite(itens, limite, executar) {
|
|
49
|
+
if (itens.length === 0) {
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
const resultados = new Array(itens.length);
|
|
53
|
+
let proximoIndice = 0;
|
|
54
|
+
const trabalhador = async () => {
|
|
55
|
+
for (;;) {
|
|
56
|
+
const indice = proximoIndice;
|
|
57
|
+
proximoIndice += 1;
|
|
58
|
+
if (indice >= itens.length) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
resultados[indice] = await executar(itens[indice]);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
await Promise.all(Array.from({ length: Math.min(Math.max(1, limite), itens.length) }, () => trabalhador()));
|
|
65
|
+
return resultados;
|
|
66
|
+
}
|
|
67
|
+
async function arquivoRegularContido(caminho, raizReal) {
|
|
68
|
+
try {
|
|
69
|
+
const informacaoAntes = await lstat(caminho, { bigint: true });
|
|
70
|
+
if (!informacaoAntes.isFile() || informacaoAntes.isSymbolicLink()) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
const caminhoReal = await realpath(caminho);
|
|
74
|
+
const informacaoDepois = await lstat(caminho, { bigint: true });
|
|
75
|
+
return caminhoEstaDentro(raizReal, caminhoReal)
|
|
76
|
+
&& identidadesArquivoIguais(informacaoAntes, informacaoDepois);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
async function sondarArquivosRegularesContidos(caminhos, raizReal) {
|
|
83
|
+
const unicos = [...new Map(caminhos.map((caminho) => [chaveCaminho(caminho), caminho])).entries()];
|
|
84
|
+
const resultados = await mapearComLimite(unicos, CONCORRENCIA_SONDAGENS_DRIFT, async ([chave, caminho]) => [chave, await arquivoRegularContido(caminho, raizReal)]);
|
|
85
|
+
return new Map(resultados);
|
|
86
|
+
}
|
|
87
|
+
function vinculosModulo(ir) {
|
|
88
|
+
return [
|
|
89
|
+
...ir.vinculos,
|
|
90
|
+
...ir.tasks.flatMap((task) => task.vinculos),
|
|
91
|
+
...ir.flows.flatMap((flow) => flow.vinculos),
|
|
92
|
+
...ir.routes.flatMap((route) => route.vinculos),
|
|
93
|
+
...ir.superficies.flatMap((superficie) => superficie.vinculos),
|
|
94
|
+
];
|
|
95
|
+
}
|
|
96
|
+
function implementacoesModulo(ir) {
|
|
97
|
+
return [
|
|
98
|
+
...ir.tasks.flatMap((task) => task.implementacoesExternas),
|
|
99
|
+
...ir.superficies.flatMap((superficie) => superficie.implementacoesExternas),
|
|
100
|
+
];
|
|
101
|
+
}
|
|
102
|
+
function moduloExigeAncoraCodigo(ir) {
|
|
103
|
+
return ir.tasks.length > 0
|
|
104
|
+
|| ir.routes.length > 0
|
|
105
|
+
|| ir.superficies.length > 0
|
|
106
|
+
|| implementacoesModulo(ir).length > 0
|
|
107
|
+
|| vinculosModulo(ir).some((vinculo) => Boolean(vinculo.arquivo || vinculo.tipo === "arquivo"));
|
|
108
|
+
}
|
|
109
|
+
function resolverArquivoWorkspace(baseProjeto, valor) {
|
|
110
|
+
const absoluto = path.isAbsolute(valor)
|
|
111
|
+
? path.resolve(valor)
|
|
112
|
+
: path.resolve(baseProjeto, valor);
|
|
113
|
+
return caminhoEstaDentro(baseProjeto, absoluto) ? absoluto : undefined;
|
|
114
|
+
}
|
|
115
|
+
function descreverArquivoForaWorkspace(valor) {
|
|
116
|
+
const nome = path.basename(path.normalize(valor)) || "alvo";
|
|
117
|
+
return `[fora_do_workspace]/${nome}`;
|
|
118
|
+
}
|
|
119
|
+
function variantesSegmentoDiretorio(segmento) {
|
|
120
|
+
const camel = segmento.replace(/_([a-z0-9])/gi, (_ocorrencia, caractere) => caractere.toUpperCase());
|
|
121
|
+
return [...new Set([
|
|
122
|
+
segmento,
|
|
123
|
+
segmento.includes("_") ? segmento.replace(/_/g, "-") : undefined,
|
|
124
|
+
segmento.includes("_") && camel !== segmento ? camel : undefined,
|
|
125
|
+
/(?:^|_)id$/i.test(segmento) ? `[${segmento}]` : undefined,
|
|
126
|
+
/(?:^|_)id$/i.test(segmento) && camel !== segmento ? `[${camel}]` : undefined,
|
|
127
|
+
].filter((item) => Boolean(item)))];
|
|
128
|
+
}
|
|
129
|
+
function adicionarCandidatoPreservandoForma(candidatos, baseProjeto, caminho) {
|
|
130
|
+
const absoluto = path.resolve(caminho);
|
|
131
|
+
if (!caminhoEstaDentro(baseProjeto, absoluto)) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const chave = chaveCaminho(absoluto);
|
|
135
|
+
if (!candidatos.has(chave)) {
|
|
136
|
+
candidatos.set(chave, absoluto);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function variantesNomeArquivo(segmento) {
|
|
140
|
+
const pascal = segmento
|
|
141
|
+
.split(/[_-]+/)
|
|
142
|
+
.filter(Boolean)
|
|
143
|
+
.map((parte) => `${parte[0]?.toUpperCase() ?? ""}${parte.slice(1)}`)
|
|
144
|
+
.join("");
|
|
145
|
+
return [...new Set([
|
|
146
|
+
segmento,
|
|
147
|
+
segmento.includes("_") ? segmento.replace(/_/g, "-") : undefined,
|
|
148
|
+
segmento.includes("_") ? segmento.replace(/_/g, ".") : undefined,
|
|
149
|
+
pascal && pascal !== segmento ? pascal : undefined,
|
|
150
|
+
].filter((item) => Boolean(item)))];
|
|
151
|
+
}
|
|
152
|
+
function resolverDiretoriosCodigoPlanejados(contexto, irs, configuracao) {
|
|
153
|
+
const raizesModulo = irs.flatMap((ir) => {
|
|
154
|
+
const primeiroSegmento = ir.nome.split(".").map((item) => item.trim()).find(Boolean);
|
|
155
|
+
return primeiroSegmento
|
|
156
|
+
? variantesNomeArquivo(primeiroSegmento).map((segmento) => path.resolve(contexto.baseProjeto, segmento))
|
|
157
|
+
: [];
|
|
158
|
+
});
|
|
159
|
+
const candidatos = [...resolverDiretoriosCodigoEscopoReal(contexto, configuracao), ...raizesModulo];
|
|
160
|
+
return [...new Map(filtrarCaminhosEscopoReal(candidatos, contexto, configuracao)
|
|
161
|
+
.map((diretorio) => [chaveCaminho(diretorio), diretorio])).values()];
|
|
162
|
+
}
|
|
163
|
+
function variantesCaminhoSegmentos(segmentos) {
|
|
164
|
+
let variantes = [[]];
|
|
165
|
+
for (const segmento of segmentos) {
|
|
166
|
+
const opcoes = variantesSegmentoDiretorio(segmento);
|
|
167
|
+
variantes = variantes.flatMap((prefixo) => opcoes.map((opcao) => [...prefixo, opcao]));
|
|
168
|
+
}
|
|
169
|
+
return variantes.slice(0, 16);
|
|
170
|
+
}
|
|
171
|
+
function candidatosArquivoImpl(contexto, impl, diretoriosCodigo = contexto.diretoriosCodigo) {
|
|
172
|
+
const grupos = [];
|
|
173
|
+
if (impl.origemArquivo) {
|
|
174
|
+
const declarado = resolverArquivoWorkspace(contexto.baseProjeto, impl.origemArquivo);
|
|
175
|
+
if (declarado) {
|
|
176
|
+
grupos.push([declarado]);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
const partes = impl.caminho.split(".").map((parte) => parte.trim()).filter(Boolean);
|
|
180
|
+
if (partes.length < 2) {
|
|
181
|
+
return grupos;
|
|
182
|
+
}
|
|
183
|
+
const bases = [...new Map([contexto.baseProjeto, ...diretoriosCodigo]
|
|
184
|
+
.map((base) => [chaveCaminho(base), base])).values()];
|
|
185
|
+
const extensoes = EXTENSAO_POR_ORIGEM[impl.origem] ?? [];
|
|
186
|
+
for (const removerCauda of [1, 2]) {
|
|
187
|
+
const candidatos = new Map();
|
|
188
|
+
const adicionar = (caminho) => {
|
|
189
|
+
adicionarCandidatoPreservandoForma(candidatos, contexto.baseProjeto, caminho);
|
|
190
|
+
};
|
|
191
|
+
const segmentosOriginais = partes.slice(0, Math.max(1, partes.length - removerCauda));
|
|
192
|
+
for (const base of bases) {
|
|
193
|
+
const nomeBase = path.basename(base).toLowerCase();
|
|
194
|
+
const segmentos = segmentosOriginais[0]?.toLowerCase() === nomeBase
|
|
195
|
+
? segmentosOriginais.slice(1)
|
|
196
|
+
: segmentosOriginais;
|
|
197
|
+
if (segmentos.length === 0) {
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
for (const diretorios of variantesCaminhoSegmentos(segmentos.slice(0, -1))) {
|
|
201
|
+
for (const nomeArquivo of variantesNomeArquivo(segmentos.at(-1))) {
|
|
202
|
+
for (const extensao of extensoes) {
|
|
203
|
+
adicionar(path.join(base, ...diretorios, `${nomeArquivo}${extensao}`));
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
for (const caminhoDiretorio of variantesCaminhoSegmentos(segmentos)) {
|
|
208
|
+
for (const extensao of extensoes) {
|
|
209
|
+
adicionar(path.join(base, ...caminhoDiretorio, `index${extensao}`));
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
if (candidatos.size > 0) {
|
|
214
|
+
grupos.push([...candidatos.values()]);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return grupos;
|
|
218
|
+
}
|
|
219
|
+
function candidatosConsumerDeterministicos(contexto, irs, termosEscopo, diretoriosCodigo) {
|
|
220
|
+
const segmentos = new Set();
|
|
221
|
+
for (const termo of termosEscopo) {
|
|
222
|
+
segmentos.add(termo);
|
|
223
|
+
segmentos.add(termo.replace(/_/g, "-"));
|
|
224
|
+
}
|
|
225
|
+
for (const ir of irs) {
|
|
226
|
+
for (const rota of ir.routes) {
|
|
227
|
+
for (const segmento of (rota.caminho ?? "").split("/").filter((item) => item && !item.startsWith(":"))) {
|
|
228
|
+
segmentos.add(segmento);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
const candidatos = new Map();
|
|
233
|
+
const extensoes = [".ts", ".tsx", ".js", ".jsx"];
|
|
234
|
+
for (const raiz of diretoriosCodigo) {
|
|
235
|
+
for (const segmento of segmentos) {
|
|
236
|
+
for (const extensao of extensoes) {
|
|
237
|
+
for (const relativo of [
|
|
238
|
+
["src", "app", segmento, `page${extensao}`],
|
|
239
|
+
["app", segmento, `page${extensao}`],
|
|
240
|
+
["src", "pages", `${segmento}${extensao}`],
|
|
241
|
+
["pages", `${segmento}${extensao}`],
|
|
242
|
+
]) {
|
|
243
|
+
adicionarCandidatoPreservandoForma(candidatos, contexto.baseProjeto, path.resolve(raiz, ...relativo));
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return [...candidatos.values()];
|
|
249
|
+
}
|
|
250
|
+
function candidatosRotasDeterministicos(contexto, irs, diretoriosCodigo) {
|
|
251
|
+
const candidatos = new Map();
|
|
252
|
+
const extensoes = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".py"];
|
|
253
|
+
const segmentos = new Set();
|
|
254
|
+
for (const ir of irs) {
|
|
255
|
+
for (const rota of ir.routes) {
|
|
256
|
+
for (const segmento of (rota.caminho ?? "").split("/").filter((item) => item && !item.startsWith(":") && !item.startsWith("{"))) {
|
|
257
|
+
segmentos.add(segmento);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
for (const raiz of diretoriosCodigo) {
|
|
262
|
+
for (const segmento of segmentos) {
|
|
263
|
+
const nomes = variantesNomeArquivo(segmento);
|
|
264
|
+
for (const nome of nomes) {
|
|
265
|
+
for (const extensao of extensoes) {
|
|
266
|
+
for (const relativo of [
|
|
267
|
+
[segmento, `${nome}.controller${extensao}`],
|
|
268
|
+
[`${nome}.controller${extensao}`],
|
|
269
|
+
["controllers", `${nome}.controller${extensao}`],
|
|
270
|
+
["routes", `${nome}${extensao}`],
|
|
271
|
+
]) {
|
|
272
|
+
adicionarCandidatoPreservandoForma(candidatos, contexto.baseProjeto, path.resolve(raiz, ...relativo));
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return [...candidatos.values()];
|
|
279
|
+
}
|
|
280
|
+
function candidatosConvencionaisEscopo(contexto, irs, diretoriosCodigo) {
|
|
281
|
+
const candidatos = new Map();
|
|
282
|
+
const adicionar = (caminho) => {
|
|
283
|
+
adicionarCandidatoPreservandoForma(candidatos, contexto.baseProjeto, caminho);
|
|
284
|
+
};
|
|
285
|
+
const origens = new Set(irs.flatMap((ir) => implementacoesModulo(ir).map((impl) => impl.origem)));
|
|
286
|
+
const possuiRotas = irs.some((ir) => ir.routes.length > 0);
|
|
287
|
+
const possuiPersistencia = irs.some((ir) => ir.databases.length > 0
|
|
288
|
+
|| ir.tasks.some((task) => task.effects.some((efeito) => /\b(?:db|database|persist|storage)\b/i.test(efeito))));
|
|
289
|
+
const bases = diretoriosCodigo;
|
|
290
|
+
if (possuiRotas && origens.has("rust")) {
|
|
291
|
+
for (const base of bases) {
|
|
292
|
+
adicionar(path.join(base, "main.rs"));
|
|
293
|
+
adicionar(path.join(base, "src", "main.rs"));
|
|
294
|
+
adicionar(path.join(base, "lib.rs"));
|
|
295
|
+
adicionar(path.join(base, "src", "lib.rs"));
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if (possuiPersistencia) {
|
|
299
|
+
for (const base of bases) {
|
|
300
|
+
adicionar(path.join(base, "schema.sql"));
|
|
301
|
+
adicionar(path.join(base, "schema.prisma"));
|
|
302
|
+
adicionar(path.join(base, "db", "schema.sql"));
|
|
303
|
+
adicionar(path.join(base, "prisma", "schema.prisma"));
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return [...candidatos.values()];
|
|
307
|
+
}
|
|
308
|
+
function escolherDiretoriosLogicos(contexto, arquivos, diretoriosCodigo = contexto.diretoriosCodigo) {
|
|
309
|
+
const candidatos = [...new Map(diretoriosCodigo
|
|
310
|
+
.map((diretorio) => path.resolve(diretorio))
|
|
311
|
+
.map((diretorio) => [chaveCaminho(diretorio), diretorio])).values()]
|
|
312
|
+
.sort((a, b) => b.length - a.length || a.localeCompare(b, "pt-BR"));
|
|
313
|
+
const escolhidos = new Map();
|
|
314
|
+
for (const arquivo of arquivos) {
|
|
315
|
+
if (!EXTENSOES_CODIGO_PLANEJADO.has(path.extname(arquivo).toLowerCase())) {
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
const raiz = candidatos.find((diretorio) => caminhoEstaDentro(diretorio, arquivo));
|
|
319
|
+
const raizEfetiva = raiz ?? path.dirname(arquivo);
|
|
320
|
+
escolhidos.set(chaveCaminho(raizEfetiva), raizEfetiva);
|
|
321
|
+
}
|
|
322
|
+
return [...escolhidos.values()].sort((a, b) => a.localeCompare(b, "pt-BR"));
|
|
323
|
+
}
|
|
324
|
+
export async function planejarEscopoDrift(contexto, configuracao) {
|
|
325
|
+
if (configuracao.escopo === "projeto") {
|
|
326
|
+
const diretorios = resolverDiretoriosCodigoEscopoReal(contexto, configuracao);
|
|
327
|
+
return {
|
|
328
|
+
escopo: configuracao.escopo,
|
|
329
|
+
estrategia: "projeto",
|
|
330
|
+
arquivos: [],
|
|
331
|
+
arquivosDeclarados: [],
|
|
332
|
+
arquivosInferidos: [],
|
|
333
|
+
arquivosAusentes: [],
|
|
334
|
+
diretorios,
|
|
335
|
+
modulos: contexto.modulosSelecionados
|
|
336
|
+
.map((modulo) => modulo.resultado.ir?.nome)
|
|
337
|
+
.filter((nome) => Boolean(nome)),
|
|
338
|
+
cobertura: "completa",
|
|
339
|
+
bloqueios: [],
|
|
340
|
+
dependencias: {},
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
const modulosFonte = configuracao.escopo === "arquivo"
|
|
344
|
+
? contexto.modulosSelecionados
|
|
345
|
+
: contexto.modulosCarregados;
|
|
346
|
+
const irs = modulosFonte
|
|
347
|
+
.map((modulo) => modulo.resultado.ir)
|
|
348
|
+
.filter((ir) => Boolean(ir));
|
|
349
|
+
const declarados = new Map();
|
|
350
|
+
const ausentes = new Map();
|
|
351
|
+
const inferidos = new Map();
|
|
352
|
+
const bloqueiosPlano = new Set();
|
|
353
|
+
const raizReal = await realpath(contexto.baseProjeto);
|
|
354
|
+
const diretoriosCodigoPermitidos = resolverDiretoriosCodigoPlanejados(contexto, irs, configuracao);
|
|
355
|
+
const vinculosPlanejados = irs.flatMap((ir) => vinculosModulo(ir))
|
|
356
|
+
.map((vinculo) => vinculo.arquivo ?? (vinculo.tipo === "arquivo" ? vinculo.valor : undefined))
|
|
357
|
+
.filter((valor) => Boolean(valor))
|
|
358
|
+
.map((valor) => ({
|
|
359
|
+
valor,
|
|
360
|
+
absoluto: resolverArquivoWorkspace(contexto.baseProjeto, valor),
|
|
361
|
+
}));
|
|
362
|
+
const implementacoesPlanejadas = irs
|
|
363
|
+
.flatMap((ir) => implementacoesModulo(ir))
|
|
364
|
+
.map((impl) => candidatosArquivoImpl(contexto, impl, diretoriosCodigoPermitidos));
|
|
365
|
+
const resultadoSondagens = await sondarArquivosRegularesContidos([
|
|
366
|
+
...vinculosPlanejados.flatMap((vinculo) => vinculo.absoluto ? [vinculo.absoluto] : []),
|
|
367
|
+
...implementacoesPlanejadas.flat(2),
|
|
368
|
+
], raizReal);
|
|
369
|
+
const arquivoExiste = (arquivo) => resultadoSondagens.get(chaveCaminho(arquivo)) === true;
|
|
370
|
+
for (const vinculo of vinculosPlanejados) {
|
|
371
|
+
if (!vinculo.absoluto) {
|
|
372
|
+
const descricaoSegura = descreverArquivoForaWorkspace(vinculo.valor);
|
|
373
|
+
ausentes.set(`fora:${descricaoSegura}`, descricaoSegura);
|
|
374
|
+
continue;
|
|
375
|
+
}
|
|
376
|
+
if (arquivoExiste(vinculo.absoluto)) {
|
|
377
|
+
declarados.set(chaveCaminho(vinculo.absoluto), vinculo.absoluto);
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
ausentes.set(chaveCaminho(vinculo.absoluto), vinculo.absoluto);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
const raizesDeclaradasCodigo = escolherDiretoriosLogicos(contexto, [...declarados.values()]);
|
|
384
|
+
for (const gruposCandidatos of implementacoesPlanejadas) {
|
|
385
|
+
const grupoResolvido = gruposCandidatos.find((grupo) => grupo.some(arquivoExiste));
|
|
386
|
+
let encontrados = grupoResolvido?.filter(arquivoExiste) ?? [];
|
|
387
|
+
const encontradosDeclarados = encontrados.filter((candidato) => declarados.has(chaveCaminho(candidato)));
|
|
388
|
+
if (encontradosDeclarados.length > 0) {
|
|
389
|
+
encontrados = encontradosDeclarados;
|
|
390
|
+
}
|
|
391
|
+
else if (raizesDeclaradasCodigo.length > 0) {
|
|
392
|
+
const proximosDeDeclarados = encontrados.filter((candidato) => raizesDeclaradasCodigo.some((raiz) => caminhoEstaDentro(raiz, candidato)));
|
|
393
|
+
if (proximosDeDeclarados.length > 0) {
|
|
394
|
+
encontrados = proximosDeDeclarados;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
if (encontrados.length > 1) {
|
|
398
|
+
bloqueiosPlano.add("escopo_estreito_ambiguo");
|
|
399
|
+
continue;
|
|
400
|
+
}
|
|
401
|
+
for (const candidato of encontrados) {
|
|
402
|
+
const chave = chaveCaminho(candidato);
|
|
403
|
+
if (!declarados.has(chave) && !inferidos.has(chave)) {
|
|
404
|
+
inferidos.set(chave, candidato);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
const primeiroCandidato = gruposCandidatos[0]?.[0];
|
|
408
|
+
if (encontrados.length === 0 && primeiroCandidato) {
|
|
409
|
+
ausentes.set(chaveCaminho(primeiroCandidato), primeiroCandidato);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
const raizesAncoradas = escolherDiretoriosLogicos(contexto, [...declarados.values(), ...inferidos.values()]);
|
|
413
|
+
if (raizesAncoradas.length > 0) {
|
|
414
|
+
const candidatosDeterministicos = [
|
|
415
|
+
...candidatosConsumerDeterministicos(contexto, irs, configuracao.termosEscopo, raizesAncoradas),
|
|
416
|
+
...candidatosRotasDeterministicos(contexto, irs, raizesAncoradas),
|
|
417
|
+
...candidatosConvencionaisEscopo(contexto, irs, raizesAncoradas),
|
|
418
|
+
];
|
|
419
|
+
const sondagensDeterministicas = await sondarArquivosRegularesContidos(candidatosDeterministicos, raizReal);
|
|
420
|
+
for (const candidato of candidatosDeterministicos) {
|
|
421
|
+
if (sondagensDeterministicas.get(chaveCaminho(candidato)) !== true) {
|
|
422
|
+
continue;
|
|
423
|
+
}
|
|
424
|
+
const chave = chaveCaminho(candidato);
|
|
425
|
+
if (!declarados.has(chave) && !inferidos.has(chave)) {
|
|
426
|
+
inferidos.set(chave, candidato);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
const arquivosMesclados = new Map(declarados);
|
|
431
|
+
for (const [chave, arquivo] of inferidos) {
|
|
432
|
+
if (!arquivosMesclados.has(chave)) {
|
|
433
|
+
arquivosMesclados.set(chave, arquivo);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
const arquivos = [...arquivosMesclados.values()].sort((a, b) => a.localeCompare(b, "pt-BR"));
|
|
437
|
+
const arquivosAusentes = [...ausentes.values()].sort((a, b) => a.localeCompare(b, "pt-BR"));
|
|
438
|
+
const exigeAncoraCodigo = irs.some(moduloExigeAncoraCodigo);
|
|
439
|
+
if (arquivos.length === 0
|
|
440
|
+
&& exigeAncoraCodigo
|
|
441
|
+
&& !bloqueiosPlano.has("escopo_estreito_ambiguo")) {
|
|
442
|
+
bloqueiosPlano.add("escopo_estreito_sem_vinculos");
|
|
443
|
+
}
|
|
444
|
+
const bloqueios = [...bloqueiosPlano].sort((a, b) => a.localeCompare(b, "pt-BR"));
|
|
445
|
+
return {
|
|
446
|
+
escopo: configuracao.escopo,
|
|
447
|
+
estrategia: "arquivos_vinculados",
|
|
448
|
+
arquivos,
|
|
449
|
+
arquivosDeclarados: [...declarados.values()].sort((a, b) => a.localeCompare(b, "pt-BR")),
|
|
450
|
+
arquivosInferidos: [...inferidos.values()].sort((a, b) => a.localeCompare(b, "pt-BR")),
|
|
451
|
+
arquivosAusentes,
|
|
452
|
+
diretorios: escolherDiretoriosLogicos(contexto, arquivos),
|
|
453
|
+
modulos: irs.map((ir) => ir.nome),
|
|
454
|
+
cobertura: arquivosAusentes.length === 0 && bloqueios.length === 0 ? "completa" : "parcial",
|
|
455
|
+
bloqueios,
|
|
456
|
+
dependencias: {},
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
async function construirConfinamentoDependencias(contexto) {
|
|
460
|
+
const raizWorkspaceReal = await realpath(contexto.baseProjeto);
|
|
461
|
+
const logicas = raizesCodigoLogicasDrift(contexto);
|
|
462
|
+
const reaisPossiveis = await mapearComLimite(logicas, CONCORRENCIA_SONDAGENS_DRIFT, async (raiz) => {
|
|
463
|
+
try {
|
|
464
|
+
const raizReal = await realpath(raiz);
|
|
465
|
+
return caminhoEstaDentro(raizWorkspaceReal, raizReal) ? raizReal : undefined;
|
|
466
|
+
}
|
|
467
|
+
catch {
|
|
468
|
+
return undefined;
|
|
469
|
+
}
|
|
470
|
+
});
|
|
471
|
+
const raizesCodigoReais = [...new Map(reaisPossiveis
|
|
472
|
+
.filter((raiz) => Boolean(raiz))
|
|
473
|
+
.map((raiz) => [chaveCaminho(raiz), raiz])).values()];
|
|
474
|
+
return {
|
|
475
|
+
raizWorkspaceReal,
|
|
476
|
+
raizesCodigoLogicas: logicas,
|
|
477
|
+
raizesCodigoReais,
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
async function arquivoRegularConfinadoDependencias(caminho, confinamento) {
|
|
481
|
+
const absoluto = path.resolve(caminho);
|
|
482
|
+
if (!confinamento.raizesCodigoLogicas.some((raiz) => caminhoEstaDentro(raiz, absoluto))) {
|
|
483
|
+
return false;
|
|
484
|
+
}
|
|
485
|
+
try {
|
|
486
|
+
const informacaoAntes = await lstat(absoluto, { bigint: true });
|
|
487
|
+
if (!informacaoAntes.isFile() || informacaoAntes.isSymbolicLink()) {
|
|
488
|
+
return false;
|
|
489
|
+
}
|
|
490
|
+
const caminhoReal = await realpath(absoluto);
|
|
491
|
+
const informacaoDepois = await lstat(absoluto, { bigint: true });
|
|
492
|
+
return caminhoEstaDentro(confinamento.raizWorkspaceReal, caminhoReal)
|
|
493
|
+
&& confinamento.raizesCodigoReais.some((raiz) => caminhoEstaDentro(raiz, caminhoReal))
|
|
494
|
+
&& identidadesArquivoIguais(informacaoAntes, informacaoDepois);
|
|
495
|
+
}
|
|
496
|
+
catch {
|
|
497
|
+
return false;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
function candidatoAusenteSeguro(contexto, candidatos, referencia) {
|
|
501
|
+
const seguro = candidatos.find((candidato) => caminhoEstaDentro(contexto.baseProjeto, candidato));
|
|
502
|
+
return seguro ?? referencia;
|
|
503
|
+
}
|
|
504
|
+
function referenciaPythonEhLocalObrigatoria(referencia) {
|
|
505
|
+
return referencia.startsWith("python:.");
|
|
506
|
+
}
|
|
507
|
+
async function resolverReferenciasLocais(contexto, arquivoOrigem, referencias, confinamento) {
|
|
508
|
+
const resultados = await mapearComLimite(referencias, CONCORRENCIA_SONDAGENS_DRIFT, async (referencia) => {
|
|
509
|
+
const candidatos = candidatosReferenciaLocalDrift(contexto, arquivoOrigem, referencia);
|
|
510
|
+
for (const candidato of candidatos) {
|
|
511
|
+
if (await arquivoRegularConfinadoDependencias(candidato, confinamento)) {
|
|
512
|
+
return { referencia, resolvida: candidato };
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
const ehPython = referencia.startsWith("python:");
|
|
516
|
+
return {
|
|
517
|
+
referencia,
|
|
518
|
+
ausente: !ehPython || referenciaPythonEhLocalObrigatoria(referencia)
|
|
519
|
+
? candidatoAusenteSeguro(contexto, candidatos, referencia)
|
|
520
|
+
: undefined,
|
|
521
|
+
};
|
|
522
|
+
});
|
|
523
|
+
const modulosPythonResolvidos = resultados
|
|
524
|
+
.filter((item) => item.resolvida && item.referencia.startsWith("python:"))
|
|
525
|
+
.map((item) => item.referencia.slice("python:".length));
|
|
526
|
+
const dependenciasPythonMarcadas = resultados.map((item) => {
|
|
527
|
+
if (item.resolvida || !item.referencia.startsWith("python:")) {
|
|
528
|
+
return item;
|
|
529
|
+
}
|
|
530
|
+
const modulo = item.referencia.slice("python:".length);
|
|
531
|
+
const prefixoLocalResolvido = modulosPythonResolvidos.some((prefixo) => prefixo !== modulo && modulo.startsWith(`${prefixo}.`));
|
|
532
|
+
if (!referenciaPythonEhLocalObrigatoria(item.referencia) && !prefixoLocalResolvido) {
|
|
533
|
+
return item;
|
|
534
|
+
}
|
|
535
|
+
const candidatos = candidatosReferenciaLocalDrift(contexto, arquivoOrigem, item.referencia);
|
|
536
|
+
return {
|
|
537
|
+
referencia: item.referencia,
|
|
538
|
+
ausente: candidatoAusenteSeguro(contexto, candidatos, item.referencia),
|
|
539
|
+
};
|
|
540
|
+
});
|
|
541
|
+
const modulosPythonAusentes = dependenciasPythonMarcadas
|
|
542
|
+
.filter((item) => item.ausente && item.referencia.startsWith("python:"))
|
|
543
|
+
.map((item) => item.referencia.slice("python:".length));
|
|
544
|
+
return dependenciasPythonMarcadas.map((item) => {
|
|
545
|
+
if (!item.ausente || !item.referencia.startsWith("python:")) {
|
|
546
|
+
return item;
|
|
547
|
+
}
|
|
548
|
+
const modulo = item.referencia.slice("python:".length);
|
|
549
|
+
const possuiPaiAusente = modulosPythonAusentes.some((prefixo) => prefixo !== modulo && modulo.startsWith(`${prefixo}.`));
|
|
550
|
+
return possuiPaiAusente ? { referencia: item.referencia } : item;
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
export async function expandirDependenciasPlanoDrift(contexto, plano, catalogo) {
|
|
554
|
+
if (plano.estrategia !== "arquivos_vinculados" || plano.arquivos.length === 0) {
|
|
555
|
+
return plano;
|
|
556
|
+
}
|
|
557
|
+
const arquivos = new Map(plano.arquivos.map((arquivo) => [chaveCaminho(arquivo), arquivo]));
|
|
558
|
+
const inferidos = new Map(plano.arquivosInferidos.map((arquivo) => [chaveCaminho(arquivo), arquivo]));
|
|
559
|
+
const ausentes = new Map(plano.arquivosAusentes.map((arquivo) => [chaveCaminho(arquivo), arquivo]));
|
|
560
|
+
const visitados = new Set();
|
|
561
|
+
const fila = [...plano.arquivos];
|
|
562
|
+
const confinamento = await construirConfinamentoDependencias(contexto);
|
|
563
|
+
const dependencias = new Map(Object.entries(plano.dependencias).map(([arquivo, itens]) => [arquivo, new Set(itens)]));
|
|
564
|
+
while (fila.length > 0) {
|
|
565
|
+
const lote = fila.splice(0).filter((arquivo) => {
|
|
566
|
+
const chave = chaveCaminho(arquivo);
|
|
567
|
+
if (visitados.has(chave)) {
|
|
568
|
+
return false;
|
|
569
|
+
}
|
|
570
|
+
visitados.add(chave);
|
|
571
|
+
return true;
|
|
572
|
+
});
|
|
573
|
+
const resultadosLote = await mapearComLimite(lote, CONCORRENCIA_MAPEAMENTO_DEPENDENCIAS_DRIFT, async (arquivo) => {
|
|
574
|
+
try {
|
|
575
|
+
const referencias = extrairReferenciasLocaisDrift(await catalogo.lerTexto(arquivo), { contexto, arquivoOrigem: arquivo });
|
|
576
|
+
return {
|
|
577
|
+
arquivo,
|
|
578
|
+
referencias: await resolverReferenciasLocais(contexto, arquivo, referencias, confinamento),
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
catch {
|
|
582
|
+
return {
|
|
583
|
+
arquivo,
|
|
584
|
+
referencias: [],
|
|
585
|
+
leituraFalhou: true,
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
});
|
|
589
|
+
const candidatosParaIncluir = new Map();
|
|
590
|
+
for (const resultado of resultadosLote) {
|
|
591
|
+
if (resultado.leituraFalhou) {
|
|
592
|
+
ausentes.set(chaveCaminho(resultado.arquivo), resultado.arquivo);
|
|
593
|
+
}
|
|
594
|
+
for (const referencia of resultado.referencias) {
|
|
595
|
+
if (referencia.ausente) {
|
|
596
|
+
ausentes.set(chaveCaminho(referencia.ausente), referencia.ausente);
|
|
597
|
+
}
|
|
598
|
+
if (referencia.resolvida && !catalogo.contem(referencia.resolvida)) {
|
|
599
|
+
candidatosParaIncluir.set(chaveCaminho(referencia.resolvida), referencia.resolvida);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
await catalogo.incluir([...candidatosParaIncluir.values()]);
|
|
604
|
+
const novos = new Map();
|
|
605
|
+
for (const resultado of resultadosLote) {
|
|
606
|
+
const lista = dependencias.get(resultado.arquivo) ?? new Set();
|
|
607
|
+
for (const referencia of resultado.referencias) {
|
|
608
|
+
if (!referencia.resolvida) {
|
|
609
|
+
continue;
|
|
610
|
+
}
|
|
611
|
+
if (!catalogo.contem(referencia.resolvida)) {
|
|
612
|
+
ausentes.set(chaveCaminho(referencia.resolvida), referencia.resolvida);
|
|
613
|
+
continue;
|
|
614
|
+
}
|
|
615
|
+
lista.add(referencia.resolvida);
|
|
616
|
+
const chave = chaveCaminho(referencia.resolvida);
|
|
617
|
+
if (!arquivos.has(chave)) {
|
|
618
|
+
novos.set(chave, referencia.resolvida);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
if (lista.size > 0) {
|
|
622
|
+
dependencias.set(resultado.arquivo, lista);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
const novosOrdenados = [...novos.values()].sort((a, b) => a.localeCompare(b, "pt-BR"));
|
|
626
|
+
for (const candidato of novosOrdenados) {
|
|
627
|
+
const chave = chaveCaminho(candidato);
|
|
628
|
+
arquivos.set(chave, candidato);
|
|
629
|
+
inferidos.set(chave, candidato);
|
|
630
|
+
fila.push(candidato);
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
const arquivosExpandidos = [...arquivos.values()].sort((a, b) => a.localeCompare(b, "pt-BR"));
|
|
634
|
+
const arquivosAusentes = [...ausentes.values()].sort((a, b) => a.localeCompare(b, "pt-BR"));
|
|
635
|
+
return {
|
|
636
|
+
...plano,
|
|
637
|
+
arquivos: arquivosExpandidos,
|
|
638
|
+
arquivosInferidos: [...inferidos.values()].sort((a, b) => a.localeCompare(b, "pt-BR")),
|
|
639
|
+
arquivosAusentes,
|
|
640
|
+
diretorios: escolherDiretoriosLogicos(contexto, arquivosExpandidos),
|
|
641
|
+
cobertura: arquivosAusentes.length === 0 && plano.bloqueios.length === 0 ? "completa" : "parcial",
|
|
642
|
+
dependencias: Object.fromEntries([...dependencias.entries()]
|
|
643
|
+
.sort(([a], [b]) => a.localeCompare(b, "pt-BR"))
|
|
644
|
+
.map(([arquivo, itens]) => [arquivo, [...itens].sort((a, b) => a.localeCompare(b, "pt-BR"))])),
|
|
645
|
+
};
|
|
646
|
+
}
|
|
647
|
+
//# sourceMappingURL=driftEscopo.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ContextoProjetoCarregado } from "./projeto.js";
|
|
2
|
+
export interface OpcoesExtracaoReferenciasDrift {
|
|
3
|
+
contexto?: ContextoProjetoCarregado;
|
|
4
|
+
arquivoOrigem?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function extrairReferenciasLocaisDrift(codigo: string, opcoes?: OpcoesExtracaoReferenciasDrift): string[];
|
|
7
|
+
export declare function raizesCodigoLogicasDrift(contexto: ContextoProjetoCarregado): string[];
|
|
8
|
+
export declare function candidatosReferenciaLocalDrift(contexto: ContextoProjetoCarregado, arquivoOrigem: string, referencia: string): string[];
|