@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,516 @@
|
|
|
1
|
+
// SEMA-GOVERNED: sema.produto.governanca_ia.drift, sema.produto.governanca_ia.drift.cache.store
|
|
2
|
+
// Descrição: cataloga somente o plano físico do drift e compartilha uma leitura estável por arquivo.
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
import { lstat, open, readdir, realpath } from "node:fs/promises";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
const CONCORRENCIA_PADRAO = 8;
|
|
7
|
+
const CONCORRENCIA_MAXIMA = 64;
|
|
8
|
+
function emitirEvento(observador, evento) {
|
|
9
|
+
try {
|
|
10
|
+
observador?.(evento);
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
// Observabilidade nunca altera o resultado funcional do drift.
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function normalizarConcorrencia(valor) {
|
|
17
|
+
if (!Number.isFinite(valor)) {
|
|
18
|
+
return CONCORRENCIA_PADRAO;
|
|
19
|
+
}
|
|
20
|
+
return Math.max(1, Math.min(CONCORRENCIA_MAXIMA, Math.trunc(valor)));
|
|
21
|
+
}
|
|
22
|
+
function normalizarExtensao(extensao) {
|
|
23
|
+
const limpa = extensao.trim().toLowerCase();
|
|
24
|
+
if (!limpa) {
|
|
25
|
+
return limpa;
|
|
26
|
+
}
|
|
27
|
+
return limpa.startsWith(".") ? limpa : `.${limpa}`;
|
|
28
|
+
}
|
|
29
|
+
function ehFiltroCatalogoDrift(valor) {
|
|
30
|
+
return !Array.isArray(valor);
|
|
31
|
+
}
|
|
32
|
+
function chaveCaminho(caminho) {
|
|
33
|
+
const normalizado = path.normalize(path.resolve(caminho));
|
|
34
|
+
return process.platform === "win32" ? normalizado.toLowerCase() : normalizado;
|
|
35
|
+
}
|
|
36
|
+
function caminhoEstaDentro(raiz, alvo) {
|
|
37
|
+
const relativo = path.relative(path.resolve(raiz), path.resolve(alvo));
|
|
38
|
+
return relativo === "" || (relativo !== ".."
|
|
39
|
+
&& !relativo.startsWith(`..${path.sep}`)
|
|
40
|
+
&& !path.isAbsolute(relativo));
|
|
41
|
+
}
|
|
42
|
+
function erroEhAusencia(erro) {
|
|
43
|
+
return ["ENOENT", "ENOTDIR"].includes(erro.code ?? "");
|
|
44
|
+
}
|
|
45
|
+
function assinaturaDiretorio(info) {
|
|
46
|
+
return {
|
|
47
|
+
mtimeNs: info.mtimeNs,
|
|
48
|
+
ctimeNs: info.ctimeNs,
|
|
49
|
+
dev: info.dev,
|
|
50
|
+
ino: info.ino,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function assinaturasDiretorioIguais(a, b) {
|
|
54
|
+
return a.mtimeNs === b.mtimeNs
|
|
55
|
+
&& a.ctimeNs === b.ctimeNs
|
|
56
|
+
&& a.dev === b.dev
|
|
57
|
+
&& a.ino === b.ino;
|
|
58
|
+
}
|
|
59
|
+
function identidadeArquivoEstavel(a, b) {
|
|
60
|
+
return a.isFile()
|
|
61
|
+
&& b.isFile()
|
|
62
|
+
&& !a.isSymbolicLink()
|
|
63
|
+
&& !b.isSymbolicLink()
|
|
64
|
+
&& a.nlink === 1n
|
|
65
|
+
&& b.nlink === 1n
|
|
66
|
+
&& a.dev === b.dev
|
|
67
|
+
&& a.ino === b.ino
|
|
68
|
+
&& a.size === b.size
|
|
69
|
+
&& a.mtimeNs === b.mtimeNs
|
|
70
|
+
&& a.ctimeNs === b.ctimeNs;
|
|
71
|
+
}
|
|
72
|
+
function criarIdentidadeArquivoCatalogado(caminhoReal, informacao) {
|
|
73
|
+
return {
|
|
74
|
+
caminhoReal: path.resolve(caminhoReal),
|
|
75
|
+
dev: informacao.dev,
|
|
76
|
+
ino: informacao.ino,
|
|
77
|
+
nlink: informacao.nlink,
|
|
78
|
+
size: informacao.size,
|
|
79
|
+
mtimeNs: informacao.mtimeNs,
|
|
80
|
+
ctimeNs: informacao.ctimeNs,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function identidadeCatalogadaCorresponde(identidade, caminhoReal, informacao) {
|
|
84
|
+
return chaveCaminho(identidade.caminhoReal) === chaveCaminho(caminhoReal)
|
|
85
|
+
&& informacao.isFile()
|
|
86
|
+
&& !informacao.isSymbolicLink()
|
|
87
|
+
&& identidade.nlink === 1n
|
|
88
|
+
&& informacao.nlink === 1n
|
|
89
|
+
&& identidade.dev === informacao.dev
|
|
90
|
+
&& identidade.ino === informacao.ino
|
|
91
|
+
&& identidade.size === informacao.size
|
|
92
|
+
&& identidade.mtimeNs === informacao.mtimeNs
|
|
93
|
+
&& identidade.ctimeNs === informacao.ctimeNs;
|
|
94
|
+
}
|
|
95
|
+
function chavesFisicasArquivo(identidade) {
|
|
96
|
+
const chaves = [`real:${chaveCaminho(identidade.caminhoReal)}`];
|
|
97
|
+
if (identidade.dev !== 0n || identidade.ino !== 0n) {
|
|
98
|
+
chaves.push(`id:${identidade.dev.toString()}:${identidade.ino.toString()}`);
|
|
99
|
+
}
|
|
100
|
+
return chaves;
|
|
101
|
+
}
|
|
102
|
+
function mesmoObjetoFisico(a, b) {
|
|
103
|
+
const possuiIdentidadeInode = (a.dev !== 0n || a.ino !== 0n) && (b.dev !== 0n || b.ino !== 0n);
|
|
104
|
+
return possuiIdentidadeInode
|
|
105
|
+
? a.dev === b.dev && a.ino === b.ino
|
|
106
|
+
: chaveCaminho(a.caminhoReal) === chaveCaminho(b.caminhoReal);
|
|
107
|
+
}
|
|
108
|
+
async function mapearComLimite(itens, limite, executar) {
|
|
109
|
+
if (itens.length === 0) {
|
|
110
|
+
return [];
|
|
111
|
+
}
|
|
112
|
+
const resultados = new Array(itens.length);
|
|
113
|
+
let proximoIndice = 0;
|
|
114
|
+
const trabalhador = async () => {
|
|
115
|
+
for (;;) {
|
|
116
|
+
const indice = proximoIndice;
|
|
117
|
+
proximoIndice += 1;
|
|
118
|
+
if (indice >= itens.length) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
resultados[indice] = await executar(itens[indice]);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
await Promise.all(Array.from({ length: Math.min(limite, itens.length) }, () => trabalhador()));
|
|
125
|
+
return resultados;
|
|
126
|
+
}
|
|
127
|
+
class CatalogoDriftImplementacao {
|
|
128
|
+
baseDiretorio;
|
|
129
|
+
raizes;
|
|
130
|
+
registros = new Map();
|
|
131
|
+
registrosFisicos = new Map();
|
|
132
|
+
conteudos = new Map();
|
|
133
|
+
extensoesPermitidas;
|
|
134
|
+
concorrencia;
|
|
135
|
+
observador;
|
|
136
|
+
baseDiretorioReal;
|
|
137
|
+
contadores = {
|
|
138
|
+
diretoriosVisitados: 0,
|
|
139
|
+
arquivosCatalogados: 0,
|
|
140
|
+
leiturasConteudo: 0,
|
|
141
|
+
bytesLidos: 0,
|
|
142
|
+
acertosMemoriaConteudo: 0,
|
|
143
|
+
origem: "plano_explicito",
|
|
144
|
+
};
|
|
145
|
+
constructor(opcoes) {
|
|
146
|
+
this.baseDiretorio = path.resolve(opcoes.baseDiretorio ?? process.cwd());
|
|
147
|
+
this.baseDiretorioReal = realpath(this.baseDiretorio);
|
|
148
|
+
this.raizes = [...new Map((opcoes.raizes ?? [])
|
|
149
|
+
.map((raiz) => path.resolve(this.baseDiretorio, raiz))
|
|
150
|
+
.filter((raiz) => caminhoEstaDentro(this.baseDiretorio, raiz))
|
|
151
|
+
.map((raiz) => [chaveCaminho(raiz), raiz])).values()].sort((a, b) => a.localeCompare(b, "pt-BR"));
|
|
152
|
+
const extensoes = opcoes.extensoes
|
|
153
|
+
?.map(normalizarExtensao)
|
|
154
|
+
.filter(Boolean);
|
|
155
|
+
this.extensoesPermitidas = extensoes?.length
|
|
156
|
+
? new Set(extensoes)
|
|
157
|
+
: undefined;
|
|
158
|
+
this.concorrencia = normalizarConcorrencia(opcoes.concorrencia);
|
|
159
|
+
this.observador = opcoes.observador;
|
|
160
|
+
}
|
|
161
|
+
async construir(arquivosExplicitos, diretoriosIgnorados) {
|
|
162
|
+
await this.baseDiretorioReal;
|
|
163
|
+
if (this.raizes.length > 0) {
|
|
164
|
+
this.contadores.origem = "caminhada";
|
|
165
|
+
await this.caminharRaizes(diretoriosIgnorados);
|
|
166
|
+
}
|
|
167
|
+
await this.incluir(arquivosExplicitos);
|
|
168
|
+
}
|
|
169
|
+
async incluir(arquivosExplicitos) {
|
|
170
|
+
const explicitos = [...new Map(arquivosExplicitos
|
|
171
|
+
.map((arquivo) => path.resolve(this.baseDiretorio, arquivo))
|
|
172
|
+
.map((arquivo) => [chaveCaminho(arquivo), arquivo])).values()].sort((a, b) => a.localeCompare(b, "pt-BR"));
|
|
173
|
+
const sondagens = await mapearComLimite(explicitos, this.concorrencia, async (arquivo) => this.sondarArquivoSeguro(arquivo));
|
|
174
|
+
for (const sondagem of sondagens
|
|
175
|
+
.filter((item) => Boolean(item))
|
|
176
|
+
.sort((a, b) => a.caminho.localeCompare(b.caminho, "pt-BR"))) {
|
|
177
|
+
this.adicionarArquivo(sondagem, true);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
listar(extensoesOuFiltro = [], raizes) {
|
|
181
|
+
if (ehFiltroCatalogoDrift(extensoesOuFiltro)) {
|
|
182
|
+
return this.listarEntradas(extensoesOuFiltro).map((arquivo) => arquivo.caminho);
|
|
183
|
+
}
|
|
184
|
+
const extensoes = extensoesOuFiltro.length ? extensoesOuFiltro : undefined;
|
|
185
|
+
if (!raizes?.length) {
|
|
186
|
+
return this.listarEntradas({ extensoes }).map((arquivo) => arquivo.caminho);
|
|
187
|
+
}
|
|
188
|
+
const raizesAbsolutas = raizes.map((raiz) => path.resolve(this.baseDiretorio, raiz));
|
|
189
|
+
return [...new Map(raizesAbsolutas.flatMap((raiz) => this.listarEntradas({ extensoes, raiz }).map((arquivo) => [chaveCaminho(arquivo.caminho), arquivo.caminho]))).values()].sort((a, b) => a.localeCompare(b, "pt-BR"));
|
|
190
|
+
}
|
|
191
|
+
listarEntradas(filtro = {}) {
|
|
192
|
+
const extensoes = filtro.extensoes
|
|
193
|
+
? new Set(filtro.extensoes.map(normalizarExtensao).filter(Boolean))
|
|
194
|
+
: undefined;
|
|
195
|
+
const raiz = filtro.raiz
|
|
196
|
+
? path.resolve(this.baseDiretorio, filtro.raiz)
|
|
197
|
+
: undefined;
|
|
198
|
+
return [...new Set(this.registros.values())]
|
|
199
|
+
.filter((registro) => !extensoes || extensoes.has(registro.extensao))
|
|
200
|
+
.filter((registro) => !raiz || [...registro.aliases].some((alias) => caminhoEstaDentro(raiz, alias)))
|
|
201
|
+
.map((registro) => ({
|
|
202
|
+
caminho: registro.caminho,
|
|
203
|
+
extensao: registro.extensao,
|
|
204
|
+
explicito: registro.explicito,
|
|
205
|
+
raizes: [...registro.raizes].sort((a, b) => a.localeCompare(b, "pt-BR")),
|
|
206
|
+
}))
|
|
207
|
+
.sort((a, b) => a.caminho.localeCompare(b.caminho, "pt-BR"));
|
|
208
|
+
}
|
|
209
|
+
listarPorExtensoes(extensoes, raiz) {
|
|
210
|
+
return raiz ? this.listar(extensoes, [raiz]) : this.listar(extensoes);
|
|
211
|
+
}
|
|
212
|
+
listarPorRaiz(raiz, extensoes) {
|
|
213
|
+
return this.listar(extensoes, [raiz]);
|
|
214
|
+
}
|
|
215
|
+
arquivosCatalogados() {
|
|
216
|
+
return this.listar();
|
|
217
|
+
}
|
|
218
|
+
contem(caminho) {
|
|
219
|
+
return this.registros.has(chaveCaminho(path.resolve(this.baseDiretorio, caminho)));
|
|
220
|
+
}
|
|
221
|
+
ler(caminho) {
|
|
222
|
+
const absoluto = path.resolve(this.baseDiretorio, caminho);
|
|
223
|
+
const chave = chaveCaminho(absoluto);
|
|
224
|
+
const registro = this.registros.get(chave);
|
|
225
|
+
if (!registro) {
|
|
226
|
+
const descricao = caminhoEstaDentro(this.baseDiretorio, absoluto)
|
|
227
|
+
? absoluto
|
|
228
|
+
: `[fora_do_workspace]/${path.basename(absoluto)}`;
|
|
229
|
+
return Promise.reject(new Error(`Arquivo fora do plano explicito do drift: ${descricao}`));
|
|
230
|
+
}
|
|
231
|
+
const existente = this.conteudos.get(registro);
|
|
232
|
+
if (existente) {
|
|
233
|
+
this.contadores.acertosMemoriaConteudo += 1;
|
|
234
|
+
return existente;
|
|
235
|
+
}
|
|
236
|
+
const leitura = this.lerFisicamente(registro);
|
|
237
|
+
this.conteudos.set(registro, leitura);
|
|
238
|
+
void leitura.catch(() => {
|
|
239
|
+
if (this.conteudos.get(registro) === leitura) {
|
|
240
|
+
this.conteudos.delete(registro);
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
return leitura;
|
|
244
|
+
}
|
|
245
|
+
async lerTexto(caminho) {
|
|
246
|
+
return (await this.ler(caminho)).texto;
|
|
247
|
+
}
|
|
248
|
+
async digest(caminho) {
|
|
249
|
+
return (await this.ler(caminho)).digest;
|
|
250
|
+
}
|
|
251
|
+
emitir(tipo, arquivo) {
|
|
252
|
+
emitirEvento(this.observador, {
|
|
253
|
+
tipo,
|
|
254
|
+
caminho: arquivo ? path.resolve(this.baseDiretorio, arquivo) : undefined,
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
metricas() {
|
|
258
|
+
return { ...this.contadores };
|
|
259
|
+
}
|
|
260
|
+
async caminharRaizes(diretoriosIgnorados) {
|
|
261
|
+
let nivel = [...this.raizes];
|
|
262
|
+
const visitados = new Set();
|
|
263
|
+
while (nivel.length > 0) {
|
|
264
|
+
const nivelUnico = [...new Map(nivel.map((diretorio) => [chaveCaminho(diretorio), diretorio])).values()]
|
|
265
|
+
.filter((diretorio) => {
|
|
266
|
+
const chave = chaveCaminho(diretorio);
|
|
267
|
+
if (visitados.has(chave)) {
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
270
|
+
visitados.add(chave);
|
|
271
|
+
return true;
|
|
272
|
+
})
|
|
273
|
+
.sort((a, b) => a.localeCompare(b, "pt-BR"));
|
|
274
|
+
const proximos = await mapearComLimite(nivelUnico, this.concorrencia, async (diretorio) => this.visitarDiretorio(diretorio, diretoriosIgnorados));
|
|
275
|
+
nivel = proximos.flat();
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
async visitarDiretorio(diretorio, diretoriosIgnorados) {
|
|
279
|
+
if (!await this.caminhoPermaneceNoWorkspace(diretorio)) {
|
|
280
|
+
return [];
|
|
281
|
+
}
|
|
282
|
+
let informacao;
|
|
283
|
+
try {
|
|
284
|
+
informacao = await lstat(diretorio, { bigint: true });
|
|
285
|
+
}
|
|
286
|
+
catch (erro) {
|
|
287
|
+
if (erroEhAusencia(erro)) {
|
|
288
|
+
return [];
|
|
289
|
+
}
|
|
290
|
+
throw erro;
|
|
291
|
+
}
|
|
292
|
+
if (informacao.isSymbolicLink()) {
|
|
293
|
+
return [];
|
|
294
|
+
}
|
|
295
|
+
if (informacao.isFile()) {
|
|
296
|
+
const sondagem = await this.sondarArquivoSeguro(diretorio);
|
|
297
|
+
if (sondagem) {
|
|
298
|
+
this.adicionarArquivo(sondagem, false);
|
|
299
|
+
}
|
|
300
|
+
return [];
|
|
301
|
+
}
|
|
302
|
+
if (!informacao.isDirectory()) {
|
|
303
|
+
return [];
|
|
304
|
+
}
|
|
305
|
+
const entradas = await readdir(diretorio, { withFileTypes: true });
|
|
306
|
+
const informacaoDepois = await lstat(diretorio, { bigint: true });
|
|
307
|
+
if (!informacaoDepois.isDirectory()
|
|
308
|
+
|| informacaoDepois.isSymbolicLink()
|
|
309
|
+
|| !assinaturasDiretorioIguais(assinaturaDiretorio(informacao), assinaturaDiretorio(informacaoDepois))) {
|
|
310
|
+
throw new Error(`catalogo_diretorio_instavel:${diretorio}`);
|
|
311
|
+
}
|
|
312
|
+
this.contadores.diretoriosVisitados += 1;
|
|
313
|
+
emitirEvento(this.observador, {
|
|
314
|
+
tipo: "catalog.visit",
|
|
315
|
+
caminho: diretorio,
|
|
316
|
+
categoria: "diretorio",
|
|
317
|
+
});
|
|
318
|
+
const proximos = [];
|
|
319
|
+
const arquivos = [];
|
|
320
|
+
for (const entrada of entradas.sort((a, b) => a.name.localeCompare(b.name, "pt-BR"))) {
|
|
321
|
+
if (entrada.isSymbolicLink()) {
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
const caminhoAtual = path.join(diretorio, entrada.name);
|
|
325
|
+
if (entrada.isDirectory()) {
|
|
326
|
+
if (!diretoriosIgnorados.has(entrada.name.toLowerCase())) {
|
|
327
|
+
proximos.push(caminhoAtual);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
else if (entrada.isFile()) {
|
|
331
|
+
arquivos.push(caminhoAtual);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
const sondagens = await mapearComLimite(arquivos, this.concorrencia, async (arquivo) => this.sondarArquivoSeguro(arquivo));
|
|
335
|
+
for (const sondagem of sondagens
|
|
336
|
+
.filter((item) => Boolean(item))
|
|
337
|
+
.sort((a, b) => a.caminho.localeCompare(b.caminho, "pt-BR"))) {
|
|
338
|
+
this.adicionarArquivo(sondagem, false);
|
|
339
|
+
}
|
|
340
|
+
return proximos;
|
|
341
|
+
}
|
|
342
|
+
adicionarArquivo(sondagem, explicito) {
|
|
343
|
+
const absoluto = path.resolve(sondagem.caminho);
|
|
344
|
+
const extensao = path.extname(absoluto).toLowerCase();
|
|
345
|
+
if (!explicito && this.extensoesPermitidas && !this.extensoesPermitidas.has(extensao)) {
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
const chave = chaveCaminho(absoluto);
|
|
349
|
+
const chavesFisicas = chavesFisicasArquivo(sondagem.identidade);
|
|
350
|
+
const existentePorCaminho = this.registros.get(chave);
|
|
351
|
+
if (existentePorCaminho && !mesmoObjetoFisico(existentePorCaminho.identidade, sondagem.identidade)) {
|
|
352
|
+
throw new Error(`Arquivo catalogado mudou de identidade fisica: ${absoluto}`);
|
|
353
|
+
}
|
|
354
|
+
const existente = existentePorCaminho
|
|
355
|
+
?? chavesFisicas.map((chaveFisica) => this.registrosFisicos.get(chaveFisica)).find(Boolean);
|
|
356
|
+
const raizes = this.raizes.filter((raiz) => caminhoEstaDentro(raiz, absoluto));
|
|
357
|
+
if (existente) {
|
|
358
|
+
existente.explicito = existente.explicito || explicito;
|
|
359
|
+
existente.aliases.add(absoluto);
|
|
360
|
+
this.registros.set(chave, existente);
|
|
361
|
+
for (const raiz of raizes) {
|
|
362
|
+
existente.raizes.add(raiz);
|
|
363
|
+
}
|
|
364
|
+
for (const chaveFisica of chavesFisicas) {
|
|
365
|
+
this.registrosFisicos.set(chaveFisica, existente);
|
|
366
|
+
}
|
|
367
|
+
if (absoluto.localeCompare(existente.caminho, "pt-BR") < 0) {
|
|
368
|
+
existente.caminho = absoluto;
|
|
369
|
+
existente.extensao = extensao;
|
|
370
|
+
existente.identidade = sondagem.identidade;
|
|
371
|
+
}
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
const registro = {
|
|
375
|
+
caminho: absoluto,
|
|
376
|
+
extensao,
|
|
377
|
+
explicito,
|
|
378
|
+
raizes: new Set(raizes),
|
|
379
|
+
aliases: new Set([absoluto]),
|
|
380
|
+
identidade: sondagem.identidade,
|
|
381
|
+
};
|
|
382
|
+
this.registros.set(chave, registro);
|
|
383
|
+
for (const chaveFisica of chavesFisicas) {
|
|
384
|
+
this.registrosFisicos.set(chaveFisica, registro);
|
|
385
|
+
}
|
|
386
|
+
this.contadores.arquivosCatalogados += 1;
|
|
387
|
+
emitirEvento(this.observador, {
|
|
388
|
+
tipo: "catalog.visit",
|
|
389
|
+
caminho: absoluto,
|
|
390
|
+
categoria: "arquivo",
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
async sondarArquivoSeguro(caminho) {
|
|
394
|
+
const absoluto = path.resolve(caminho);
|
|
395
|
+
if (!caminhoEstaDentro(this.baseDiretorio, absoluto)) {
|
|
396
|
+
return undefined;
|
|
397
|
+
}
|
|
398
|
+
try {
|
|
399
|
+
const informacaoAntes = await lstat(absoluto, { bigint: true });
|
|
400
|
+
if (!informacaoAntes.isFile() || informacaoAntes.isSymbolicLink() || informacaoAntes.nlink !== 1n) {
|
|
401
|
+
return undefined;
|
|
402
|
+
}
|
|
403
|
+
const [baseReal, caminhoReal] = await Promise.all([
|
|
404
|
+
this.baseDiretorioReal,
|
|
405
|
+
realpath(absoluto),
|
|
406
|
+
]);
|
|
407
|
+
const informacaoDepois = await lstat(absoluto, { bigint: true });
|
|
408
|
+
if (!caminhoEstaDentro(baseReal, caminhoReal)
|
|
409
|
+
|| !identidadeArquivoEstavel(informacaoAntes, informacaoDepois)) {
|
|
410
|
+
return undefined;
|
|
411
|
+
}
|
|
412
|
+
return {
|
|
413
|
+
caminho: absoluto,
|
|
414
|
+
identidade: criarIdentidadeArquivoCatalogado(caminhoReal, informacaoDepois),
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
catch (erro) {
|
|
418
|
+
if (erroEhAusencia(erro)) {
|
|
419
|
+
return undefined;
|
|
420
|
+
}
|
|
421
|
+
throw erro;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
async lerFisicamente(registro) {
|
|
425
|
+
const caminho = registro.caminho;
|
|
426
|
+
const informacaoAntes = await lstat(caminho, { bigint: true });
|
|
427
|
+
const [baseReal, caminhoRealAntes] = await Promise.all([
|
|
428
|
+
this.baseDiretorioReal,
|
|
429
|
+
realpath(caminho),
|
|
430
|
+
]);
|
|
431
|
+
if (!caminhoEstaDentro(baseReal, caminhoRealAntes)
|
|
432
|
+
|| !identidadeCatalogadaCorresponde(registro.identidade, caminhoRealAntes, informacaoAntes)) {
|
|
433
|
+
throw new Error(`Arquivo catalogado mudou entre catalogacao e primeira leitura: ${caminho}`);
|
|
434
|
+
}
|
|
435
|
+
const handle = await open(caminho, "r");
|
|
436
|
+
let bytes;
|
|
437
|
+
try {
|
|
438
|
+
const informacaoHandleAntes = await handle.stat({ bigint: true });
|
|
439
|
+
emitirEvento(this.observador, {
|
|
440
|
+
tipo: "content.open",
|
|
441
|
+
caminho,
|
|
442
|
+
categoria: "arquivo",
|
|
443
|
+
});
|
|
444
|
+
const [informacaoCaminhoAberto, caminhoRealAberto] = await Promise.all([
|
|
445
|
+
lstat(caminho, { bigint: true }),
|
|
446
|
+
realpath(caminho),
|
|
447
|
+
]);
|
|
448
|
+
if (!caminhoEstaDentro(baseReal, caminhoRealAberto)
|
|
449
|
+
|| !identidadeCatalogadaCorresponde(registro.identidade, caminhoRealAberto, informacaoCaminhoAberto)
|
|
450
|
+
|| !identidadeArquivoEstavel(informacaoAntes, informacaoHandleAntes)
|
|
451
|
+
|| !identidadeArquivoEstavel(informacaoHandleAntes, informacaoCaminhoAberto)) {
|
|
452
|
+
throw new Error(`Arquivo catalogado mudou durante abertura segura: ${caminho}`);
|
|
453
|
+
}
|
|
454
|
+
bytes = await handle.readFile();
|
|
455
|
+
const [informacaoHandleDepois, informacaoCaminhoDepois, caminhoRealDepois] = await Promise.all([
|
|
456
|
+
handle.stat({ bigint: true }),
|
|
457
|
+
lstat(caminho, { bigint: true }),
|
|
458
|
+
realpath(caminho),
|
|
459
|
+
]);
|
|
460
|
+
if (!caminhoEstaDentro(baseReal, caminhoRealDepois)
|
|
461
|
+
|| !identidadeCatalogadaCorresponde(registro.identidade, caminhoRealDepois, informacaoCaminhoDepois)
|
|
462
|
+
|| !identidadeArquivoEstavel(informacaoHandleAntes, informacaoHandleDepois)
|
|
463
|
+
|| !identidadeArquivoEstavel(informacaoHandleDepois, informacaoCaminhoDepois)) {
|
|
464
|
+
throw new Error(`Arquivo catalogado mudou durante leitura segura: ${caminho}`);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
finally {
|
|
468
|
+
await handle.close().catch(() => undefined);
|
|
469
|
+
}
|
|
470
|
+
const digest = `sha256:${createHash("sha256").update(bytes).digest("hex")}`;
|
|
471
|
+
this.contadores.leiturasConteudo += 1;
|
|
472
|
+
this.contadores.bytesLidos += bytes.byteLength;
|
|
473
|
+
emitirEvento(this.observador, {
|
|
474
|
+
tipo: "content.read",
|
|
475
|
+
caminho,
|
|
476
|
+
categoria: "arquivo",
|
|
477
|
+
bytes: bytes.byteLength,
|
|
478
|
+
digest,
|
|
479
|
+
});
|
|
480
|
+
return {
|
|
481
|
+
caminho,
|
|
482
|
+
bytes,
|
|
483
|
+
texto: bytes.toString("utf8"),
|
|
484
|
+
digest,
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
async caminhoPermaneceNoWorkspace(caminho) {
|
|
488
|
+
const absoluto = path.resolve(caminho);
|
|
489
|
+
if (!caminhoEstaDentro(this.baseDiretorio, absoluto)) {
|
|
490
|
+
return false;
|
|
491
|
+
}
|
|
492
|
+
try {
|
|
493
|
+
const [baseReal, caminhoReal] = await Promise.all([
|
|
494
|
+
this.baseDiretorioReal,
|
|
495
|
+
realpath(absoluto),
|
|
496
|
+
]);
|
|
497
|
+
return caminhoEstaDentro(baseReal, caminhoReal);
|
|
498
|
+
}
|
|
499
|
+
catch (erro) {
|
|
500
|
+
if (erroEhAusencia(erro)) {
|
|
501
|
+
return false;
|
|
502
|
+
}
|
|
503
|
+
throw erro;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
export async function criarCatalogoDrift(opcoes) {
|
|
508
|
+
const ignoradosOrigem = opcoes.diretoriosIgnorados ?? [];
|
|
509
|
+
const ignorados = new Set([...ignoradosOrigem]
|
|
510
|
+
.map((diretorio) => diretorio.trim().toLowerCase())
|
|
511
|
+
.filter(Boolean));
|
|
512
|
+
const catalogo = new CatalogoDriftImplementacao(opcoes);
|
|
513
|
+
await catalogo.construir(opcoes.arquivos ?? [], ignorados);
|
|
514
|
+
return catalogo;
|
|
515
|
+
}
|
|
516
|
+
//# sourceMappingURL=driftCatalogo.js.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ContextoProjetoCarregado } from "./projeto.js";
|
|
2
|
+
import type { ConfiguracaoEscopoDriftAplicada, EscopoDriftReal } from "./drift.part01.js";
|
|
3
|
+
import type { CatalogoDrift } from "./driftCatalogo.js";
|
|
4
|
+
export { extrairReferenciasLocaisDrift } from "./driftEscopoReferencias.js";
|
|
5
|
+
export type EstrategiaEscopoDrift = "arquivos_vinculados" | "projeto";
|
|
6
|
+
export type CoberturaEscopoDrift = "completa" | "parcial";
|
|
7
|
+
export interface PlanoEscopoDrift {
|
|
8
|
+
escopo: EscopoDriftReal;
|
|
9
|
+
estrategia: EstrategiaEscopoDrift;
|
|
10
|
+
arquivos: string[];
|
|
11
|
+
arquivosDeclarados: string[];
|
|
12
|
+
arquivosInferidos: string[];
|
|
13
|
+
arquivosAusentes: string[];
|
|
14
|
+
diretorios: string[];
|
|
15
|
+
modulos: string[];
|
|
16
|
+
cobertura: CoberturaEscopoDrift;
|
|
17
|
+
bloqueios: string[];
|
|
18
|
+
dependencias: Record<string, string[]>;
|
|
19
|
+
}
|
|
20
|
+
export declare function planejarEscopoDrift(contexto: ContextoProjetoCarregado, configuracao: ConfiguracaoEscopoDriftAplicada): Promise<PlanoEscopoDrift>;
|
|
21
|
+
export declare function expandirDependenciasPlanoDrift(contexto: ContextoProjetoCarregado, plano: PlanoEscopoDrift, catalogo: CatalogoDrift): Promise<PlanoEscopoDrift>;
|