@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,643 @@
|
|
|
1
|
+
// SEMA-GOVERNED: sema.produto.distribuicao_global
|
|
2
|
+
// Descrição: diagnostica e sincroniza um launcher global confinado, versionado e independente de PATH.
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
import { constants } from "node:fs";
|
|
5
|
+
import { access, readdir, realpath } from "node:fs/promises";
|
|
6
|
+
import os from "node:os";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
|
+
import { FalhaDistribuicaoGlobal, caminhoContido, concluirTransacaoArquivosLauncher, diretorioExisteSeguro, escreverArquivoAtomico, falhaParaResultado, identidadeArquivoSeguro, lerArquivoSeguro, lstatOuNull, prepararTransacaoArquivosLauncher, recuperarTransacaoArquivosLauncher, removerArquivoSeguro, resolverDentroDaHome, resolverHomeReal, statDiretorioSeguro, transacaoArquivosLauncherPendente, validarArquivoRegular, validarCadeiaExistente, } from "./filesystemGlobal.js";
|
|
10
|
+
import { extrairNomeCompanionLauncherWindows, gerarArtefatosLauncherWindows, nomeAncoraLauncherWindows, nomeLauncherPowerShellWindows, nomeWrapperLauncherWindows, validarAncoraLauncherWindows, validarArtefatosLauncherWindows, validarCompanionLauncherWindows, validarReciboAncoraLauncherWindows, validarWrapperLauncherWindows, } from "./launcherWindows.js";
|
|
11
|
+
import { comLockDistribuicaoGlobal } from "./lockGlobal.js";
|
|
12
|
+
import { versaoSemanticaValida } from "./versaoSemantica.js";
|
|
13
|
+
const MARCADOR_LAUNCHER_POSIX = "SEMA-MANAGED-LAUNCHER v2";
|
|
14
|
+
const MARCADOR_RECIBO = "SEMA-LAUNCHER-RECEIPT sha256:";
|
|
15
|
+
const MARCADOR_VERSAO = "SEMA-LAUNCHER-VERSION ";
|
|
16
|
+
const LIMITE_LAUNCHER_BYTES = 64 * 1024;
|
|
17
|
+
const LIMITE_PACKAGE_JSON = 32 * 1024;
|
|
18
|
+
const PADRAO_COMPANION_WINDOWS = /^\.sema-launcher-[a-f0-9]{64}\.ps1$/u;
|
|
19
|
+
const RAIZ_PACOTE_PADRAO = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
20
|
+
function sha256(texto) {
|
|
21
|
+
return createHash("sha256").update(texto, "utf8").digest("hex");
|
|
22
|
+
}
|
|
23
|
+
function resultado(ambiente, estado, codigo, alterado = false) {
|
|
24
|
+
const reciboValido = estado === "READY" || estado === "STALE";
|
|
25
|
+
return {
|
|
26
|
+
estado,
|
|
27
|
+
alterado,
|
|
28
|
+
destino_simbolico: ambiente.destinoVirtual,
|
|
29
|
+
codigo,
|
|
30
|
+
node_absoluto: true,
|
|
31
|
+
entrypoint_absoluto: true,
|
|
32
|
+
recibo_valido: reciboValido,
|
|
33
|
+
independente_path: estado === "READY",
|
|
34
|
+
fallback_simbolico: ambiente.plataforma === "win32"
|
|
35
|
+
? "$HOME/.sema/bin/sema-managed.ps1"
|
|
36
|
+
: null,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function destinoVirtual(plataforma) {
|
|
40
|
+
return plataforma === "win32"
|
|
41
|
+
? "$HOME/.sema/bin/sema.cmd"
|
|
42
|
+
: "$HOME/.sema/bin/sema";
|
|
43
|
+
}
|
|
44
|
+
function validarCaminhoEmbutido(caminho, plataforma) {
|
|
45
|
+
const absoluto = plataforma === "win32"
|
|
46
|
+
? path.win32.isAbsolute(caminho)
|
|
47
|
+
: path.posix.isAbsolute(caminho);
|
|
48
|
+
if (!absoluto || /[\0\r\n]/u.test(caminho)) {
|
|
49
|
+
throw new FalhaDistribuicaoGlobal("BROKEN_TARGET", "AMBIENTE_INVALIDO");
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function escaparShell(caminho) {
|
|
53
|
+
return `'${caminho.replaceAll("'", `'"'"'`)}'`;
|
|
54
|
+
}
|
|
55
|
+
function gerarLauncherPosix(executavelNode, targetCli, versaoPacote) {
|
|
56
|
+
const base = [
|
|
57
|
+
"#!/bin/sh",
|
|
58
|
+
`# ${MARCADOR_LAUNCHER_POSIX}`,
|
|
59
|
+
`# ${MARCADOR_VERSAO}${versaoPacote}`,
|
|
60
|
+
`exec ${escaparShell(executavelNode)} ${escaparShell(targetCli)} "$@"`,
|
|
61
|
+
"",
|
|
62
|
+
];
|
|
63
|
+
const baseTexto = base.join("\n");
|
|
64
|
+
base.splice(3, 0, `# ${MARCADOR_RECIBO}${sha256(baseTexto)}`);
|
|
65
|
+
return base.join("\n");
|
|
66
|
+
}
|
|
67
|
+
function validarReciboPosix(conteudo) {
|
|
68
|
+
const linhas = conteudo.split("\n");
|
|
69
|
+
if (linhas.length !== 6
|
|
70
|
+
|| linhas[0] !== "#!/bin/sh"
|
|
71
|
+
|| linhas[1] !== `# ${MARCADOR_LAUNCHER_POSIX}`
|
|
72
|
+
|| linhas[5] !== "")
|
|
73
|
+
return null;
|
|
74
|
+
const versao = linhas[2]?.slice(`# ${MARCADOR_VERSAO}`.length) ?? "";
|
|
75
|
+
const recibo = linhas[3]?.match(new RegExp(`^# ${MARCADOR_RECIBO}([a-f0-9]{64})$`, "u"));
|
|
76
|
+
const token = "'(?:[^']|'\"'\"')*'";
|
|
77
|
+
const comando = linhas[4]?.match(new RegExp(`^exec (${token}) (${token}) "\\$@"$`, "u"));
|
|
78
|
+
if (!versaoSemanticaValida(versao) || !recibo || !comando)
|
|
79
|
+
return null;
|
|
80
|
+
const executavelNode = comando[1]?.slice(1, -1).replaceAll(`'"'"'`, "'") ?? "";
|
|
81
|
+
const entrypoint = comando[2]?.slice(1, -1).replaceAll(`'"'"'`, "'") ?? "";
|
|
82
|
+
if (!path.posix.isAbsolute(executavelNode) || !path.posix.isAbsolute(entrypoint))
|
|
83
|
+
return null;
|
|
84
|
+
const base = [...linhas];
|
|
85
|
+
base.splice(3, 1);
|
|
86
|
+
if (sha256(base.join("\n")) !== recibo[1])
|
|
87
|
+
return null;
|
|
88
|
+
return { versaoPacote: versao, executavelNode, entrypoint };
|
|
89
|
+
}
|
|
90
|
+
async function carregarVersaoPacote(raizPacote) {
|
|
91
|
+
const pacote = JSON.parse((await lerArquivoSeguro(path.join(raizPacote, "package.json"), LIMITE_PACKAGE_JSON, raizPacote)).toString("utf8"));
|
|
92
|
+
if (pacote.name !== "@semacode/cli" || !versaoSemanticaValida(pacote.version)) {
|
|
93
|
+
throw new FalhaDistribuicaoGlobal("BROKEN_TARGET", "PACOTE_INVALIDO");
|
|
94
|
+
}
|
|
95
|
+
return pacote.version;
|
|
96
|
+
}
|
|
97
|
+
async function resolverAmbiente(opcoes) {
|
|
98
|
+
const plataforma = opcoes.plataforma ?? process.platform;
|
|
99
|
+
const homeReal = await resolverHomeReal(opcoes.diretorioUsuario ?? os.homedir());
|
|
100
|
+
const nodeInformado = opcoes.executavelNode ?? process.execPath;
|
|
101
|
+
const raizInformada = opcoes.raizPacote ?? RAIZ_PACOTE_PADRAO;
|
|
102
|
+
if (!path.isAbsolute(nodeInformado)) {
|
|
103
|
+
throw new FalhaDistribuicaoGlobal("BROKEN_TARGET", "EXECUTAVEL_NODE_INVALIDO");
|
|
104
|
+
}
|
|
105
|
+
if (!path.isAbsolute(raizInformada)) {
|
|
106
|
+
throw new FalhaDistribuicaoGlobal("BROKEN_TARGET", "PACOTE_INVALIDO");
|
|
107
|
+
}
|
|
108
|
+
let executavelNode;
|
|
109
|
+
let raizPacote;
|
|
110
|
+
try {
|
|
111
|
+
raizPacote = await realpath(path.resolve(raizInformada));
|
|
112
|
+
await statDiretorioSeguro(raizPacote);
|
|
113
|
+
}
|
|
114
|
+
catch (erro) {
|
|
115
|
+
const falha = falhaParaResultado(erro);
|
|
116
|
+
if (falha.estado === "PERMISSION_DENIED")
|
|
117
|
+
throw falha;
|
|
118
|
+
throw new FalhaDistribuicaoGlobal("BROKEN_TARGET", "PACOTE_INVALIDO");
|
|
119
|
+
}
|
|
120
|
+
try {
|
|
121
|
+
executavelNode = await realpath(path.resolve(nodeInformado));
|
|
122
|
+
await validarArquivoRegular(executavelNode);
|
|
123
|
+
if (plataforma !== "win32")
|
|
124
|
+
await access(executavelNode, constants.X_OK);
|
|
125
|
+
}
|
|
126
|
+
catch (erro) {
|
|
127
|
+
const falha = falhaParaResultado(erro);
|
|
128
|
+
if (falha.estado === "PERMISSION_DENIED")
|
|
129
|
+
throw falha;
|
|
130
|
+
throw new FalhaDistribuicaoGlobal("BROKEN_TARGET", "EXECUTAVEL_NODE_INVALIDO");
|
|
131
|
+
}
|
|
132
|
+
const targetCli = path.resolve(raizPacote, "dist", "bin.js");
|
|
133
|
+
try {
|
|
134
|
+
if (!await diretorioExisteSeguro(path.join(raizPacote, "dist")))
|
|
135
|
+
throw new Error("dist ausente");
|
|
136
|
+
await validarArquivoRegular(targetCli, raizPacote);
|
|
137
|
+
}
|
|
138
|
+
catch (erro) {
|
|
139
|
+
const falha = falhaParaResultado(erro);
|
|
140
|
+
if (falha.estado === "PERMISSION_DENIED")
|
|
141
|
+
throw falha;
|
|
142
|
+
throw new FalhaDistribuicaoGlobal("BROKEN_TARGET", "TARGET_CLI_INVALIDO");
|
|
143
|
+
}
|
|
144
|
+
const versaoPacote = await carregarVersaoPacote(raizPacote);
|
|
145
|
+
validarCaminhoEmbutido(executavelNode, plataforma);
|
|
146
|
+
validarCaminhoEmbutido(targetCli, plataforma);
|
|
147
|
+
const nomeLauncher = plataforma === "win32" ? "sema.cmd" : "sema";
|
|
148
|
+
const destino = resolverDentroDaHome(homeReal, ".sema", "bin", nomeLauncher);
|
|
149
|
+
const destinoWrapper = plataforma === "win32"
|
|
150
|
+
? resolverDentroDaHome(homeReal, ".sema", "bin", nomeWrapperLauncherWindows())
|
|
151
|
+
: undefined;
|
|
152
|
+
const destinoPowerShell = plataforma === "win32"
|
|
153
|
+
? resolverDentroDaHome(homeReal, ".sema", "bin", nomeLauncherPowerShellWindows())
|
|
154
|
+
: undefined;
|
|
155
|
+
const destinoAnchor = plataforma === "win32"
|
|
156
|
+
? resolverDentroDaHome(homeReal, ".sema", "bin", nomeAncoraLauncherWindows())
|
|
157
|
+
: undefined;
|
|
158
|
+
const windows = plataforma === "win32"
|
|
159
|
+
? gerarArtefatosLauncherWindows(executavelNode, targetCli, versaoPacote)
|
|
160
|
+
: undefined;
|
|
161
|
+
return {
|
|
162
|
+
plataforma,
|
|
163
|
+
homeReal,
|
|
164
|
+
executavelNode,
|
|
165
|
+
raizPacote,
|
|
166
|
+
versaoPacote,
|
|
167
|
+
targetCli,
|
|
168
|
+
destino,
|
|
169
|
+
destinoPowerShell,
|
|
170
|
+
destinoWrapper,
|
|
171
|
+
destinoAnchor,
|
|
172
|
+
destinoVirtual: destinoVirtual(plataforma),
|
|
173
|
+
conteudo: windows?.launcher ?? gerarLauncherPosix(executavelNode, targetCli, versaoPacote),
|
|
174
|
+
windows,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
async function validarReciboAtual(ambiente, launcher) {
|
|
178
|
+
if (ambiente.plataforma !== "win32") {
|
|
179
|
+
const recibo = validarReciboPosix(launcher);
|
|
180
|
+
return recibo ? { recibo } : null;
|
|
181
|
+
}
|
|
182
|
+
const nomeCompanion = extrairNomeCompanionLauncherWindows(launcher);
|
|
183
|
+
if (!nomeCompanion)
|
|
184
|
+
return null;
|
|
185
|
+
const caminhoCompanion = path.join(path.dirname(ambiente.destino), nomeCompanion);
|
|
186
|
+
if (!caminhoContido(ambiente.homeReal, caminhoCompanion))
|
|
187
|
+
return null;
|
|
188
|
+
if (!await lstatOuNull(caminhoCompanion))
|
|
189
|
+
return null;
|
|
190
|
+
const identidade = await identidadeArquivoSeguro(caminhoCompanion, ambiente.homeReal);
|
|
191
|
+
const companion = await lerArquivoSeguro(caminhoCompanion, LIMITE_LAUNCHER_BYTES, ambiente.homeReal);
|
|
192
|
+
const reciboWindows = validarArtefatosLauncherWindows(launcher, companion);
|
|
193
|
+
if (!reciboWindows)
|
|
194
|
+
return null;
|
|
195
|
+
return {
|
|
196
|
+
recibo: {
|
|
197
|
+
versaoPacote: reciboWindows.versaoPacote,
|
|
198
|
+
executavelNode: reciboWindows.executavelNode,
|
|
199
|
+
entrypoint: reciboWindows.entrypoint,
|
|
200
|
+
nomeCompanion: reciboWindows.nomeCompanion,
|
|
201
|
+
},
|
|
202
|
+
companionAtual: { caminho: caminhoCompanion, identidade, conteudo: companion },
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
async function listarCompanionsGerenciadosInativos(ambiente, nomeAtivo) {
|
|
206
|
+
if (ambiente.plataforma !== "win32")
|
|
207
|
+
return [];
|
|
208
|
+
const diretorio = path.dirname(ambiente.destino);
|
|
209
|
+
let entradas;
|
|
210
|
+
try {
|
|
211
|
+
entradas = await readdir(diretorio, { withFileTypes: true });
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
return [];
|
|
215
|
+
}
|
|
216
|
+
const companions = [];
|
|
217
|
+
for (const entrada of entradas) {
|
|
218
|
+
if (entrada.name === nomeAtivo
|
|
219
|
+
|| !PADRAO_COMPANION_WINDOWS.test(entrada.name)
|
|
220
|
+
|| !entrada.isFile())
|
|
221
|
+
continue;
|
|
222
|
+
const caminho = path.join(diretorio, entrada.name);
|
|
223
|
+
try {
|
|
224
|
+
const identidade = await identidadeArquivoSeguro(caminho, ambiente.homeReal);
|
|
225
|
+
const conteudo = await lerArquivoSeguro(caminho, LIMITE_LAUNCHER_BYTES, ambiente.homeReal);
|
|
226
|
+
if (!validarCompanionLauncherWindows(conteudo, entrada.name))
|
|
227
|
+
continue;
|
|
228
|
+
companions.push({ caminho, identidade, conteudo });
|
|
229
|
+
}
|
|
230
|
+
catch {
|
|
231
|
+
// Arquivo não comprovadamente gerenciado é preservado, inclusive em erro de leitura.
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return companions;
|
|
235
|
+
}
|
|
236
|
+
async function limparCompanionsGerenciadosInativos(ambiente, nomeAtivo) {
|
|
237
|
+
let alterado = false;
|
|
238
|
+
for (const companion of await listarCompanionsGerenciadosInativos(ambiente, nomeAtivo)) {
|
|
239
|
+
try {
|
|
240
|
+
await removerArquivoSeguro(ambiente.homeReal, companion.caminho, companion.identidade);
|
|
241
|
+
alterado = true;
|
|
242
|
+
}
|
|
243
|
+
catch {
|
|
244
|
+
if (!await lstatOuNull(companion.caminho))
|
|
245
|
+
alterado = true;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return {
|
|
249
|
+
alterado,
|
|
250
|
+
pendente: (await listarCompanionsGerenciadosInativos(ambiente, nomeAtivo)).length > 0,
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
async function diagnosticarWrapperWindows(ambiente) {
|
|
254
|
+
if (ambiente.plataforma !== "win32"
|
|
255
|
+
|| !ambiente.destinoPowerShell
|
|
256
|
+
|| !ambiente.destinoWrapper
|
|
257
|
+
|| !ambiente.destinoAnchor) {
|
|
258
|
+
return { estado: "valido" };
|
|
259
|
+
}
|
|
260
|
+
let ausente = false;
|
|
261
|
+
for (const destino of [ambiente.destinoPowerShell, ambiente.destinoWrapper]) {
|
|
262
|
+
if (!await lstatOuNull(destino)) {
|
|
263
|
+
ausente = true;
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
await validarArquivoRegular(destino, ambiente.homeReal);
|
|
267
|
+
const conteudo = await lerArquivoSeguro(destino, LIMITE_LAUNCHER_BYTES, ambiente.homeReal);
|
|
268
|
+
if (!validarWrapperLauncherWindows(conteudo)) {
|
|
269
|
+
return {
|
|
270
|
+
estado: "invalido",
|
|
271
|
+
codigo: conteudo.toString("utf8").includes("SEMA-MANAGED-LAUNCHER-WRAPPER")
|
|
272
|
+
? "RECIBO_INVALIDO"
|
|
273
|
+
: "CONTEUDO_NAO_GERENCIADO",
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
if (!await lstatOuNull(ambiente.destinoAnchor)) {
|
|
278
|
+
ausente = true;
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
await validarArquivoRegular(ambiente.destinoAnchor, ambiente.homeReal);
|
|
282
|
+
const ancora = await lerArquivoSeguro(ambiente.destinoAnchor, LIMITE_LAUNCHER_BYTES, ambiente.homeReal);
|
|
283
|
+
if (!validarReciboAncoraLauncherWindows(ancora)) {
|
|
284
|
+
return {
|
|
285
|
+
estado: "invalido",
|
|
286
|
+
codigo: ancora.toString("ascii").includes("SEMA-MANAGED-LAUNCHER-ANCHOR")
|
|
287
|
+
? "RECIBO_INVALIDO"
|
|
288
|
+
: "CONTEUDO_NAO_GERENCIADO",
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return { estado: ausente ? "ausente" : "valido" };
|
|
293
|
+
}
|
|
294
|
+
async function diagnosticar(ambiente) {
|
|
295
|
+
const cadeia = await validarCadeiaExistente(ambiente.homeReal, path.dirname(ambiente.destino));
|
|
296
|
+
if (cadeia === "ausente") {
|
|
297
|
+
return { resultado: resultado(ambiente, "MISSING", "DESTINO_AUSENTE") };
|
|
298
|
+
}
|
|
299
|
+
const wrapper = await diagnosticarWrapperWindows(ambiente);
|
|
300
|
+
if (wrapper.estado === "invalido") {
|
|
301
|
+
return {
|
|
302
|
+
resultado: resultado(ambiente, "BROKEN_TARGET", wrapper.codigo ?? "RECIBO_INVALIDO"),
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
if (!await lstatOuNull(ambiente.destino)) {
|
|
306
|
+
return { resultado: resultado(ambiente, "MISSING", "DESTINO_AUSENTE") };
|
|
307
|
+
}
|
|
308
|
+
await validarArquivoRegular(ambiente.destino, ambiente.homeReal);
|
|
309
|
+
const atual = (await lerArquivoSeguro(ambiente.destino, LIMITE_LAUNCHER_BYTES, ambiente.homeReal)).toString("utf8");
|
|
310
|
+
const validado = await validarReciboAtual(ambiente, atual);
|
|
311
|
+
if (!validado) {
|
|
312
|
+
return {
|
|
313
|
+
resultado: resultado(ambiente, "BROKEN_TARGET", atual.includes("SEMA-MANAGED-LAUNCHER")
|
|
314
|
+
? "RECIBO_INVALIDO"
|
|
315
|
+
: "CONTEUDO_NAO_GERENCIADO"),
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
if (ambiente.plataforma === "win32" && wrapper.estado === "valido") {
|
|
319
|
+
if (!ambiente.destinoAnchor || !ambiente.windows || !validado.companionAtual) {
|
|
320
|
+
return { resultado: resultado(ambiente, "BROKEN_TARGET", "RECIBO_INVALIDO") };
|
|
321
|
+
}
|
|
322
|
+
const ancora = await lerArquivoSeguro(ambiente.destinoAnchor, LIMITE_LAUNCHER_BYTES, ambiente.homeReal);
|
|
323
|
+
if (!validarAncoraLauncherWindows(ancora, atual, validado.companionAtual.conteudo, validado.recibo.nomeCompanion ?? "", ambiente.windows.wrapper)) {
|
|
324
|
+
return { resultado: resultado(ambiente, "BROKEN_TARGET", "RECIBO_INVALIDO") };
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
if (ambiente.plataforma !== "win32") {
|
|
328
|
+
try {
|
|
329
|
+
await access(ambiente.destino, constants.X_OK);
|
|
330
|
+
}
|
|
331
|
+
catch {
|
|
332
|
+
return {
|
|
333
|
+
resultado: resultado(ambiente, "STALE", "PERMISSAO_EXECUCAO_INVALIDA"),
|
|
334
|
+
recibo: validado.recibo,
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
const exato = wrapper.estado === "valido"
|
|
339
|
+
&& atual === ambiente.conteudo
|
|
340
|
+
&& validado.recibo.executavelNode === ambiente.executavelNode
|
|
341
|
+
&& validado.recibo.entrypoint === ambiente.targetCli;
|
|
342
|
+
const limpezaPendente = exato && ((await listarCompanionsGerenciadosInativos(ambiente, validado.recibo.nomeCompanion)).length > 0
|
|
343
|
+
|| await transacaoArquivosLauncherPendente(ambiente.homeReal, path.dirname(ambiente.destino)));
|
|
344
|
+
return {
|
|
345
|
+
resultado: resultado(ambiente, exato ? "READY" : "STALE", exato
|
|
346
|
+
? limpezaPendente ? "LIMPEZA_PENDENTE" : "DESTINO_PRONTO"
|
|
347
|
+
: "DESTINO_DESATUALIZADO"),
|
|
348
|
+
recibo: validado.recibo,
|
|
349
|
+
companionAtual: validado.companionAtual,
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
function fallback(opcoes, erro) {
|
|
353
|
+
const falha = falhaParaResultado(erro);
|
|
354
|
+
const alterado = falha.codigo === "LOCK_PERDIDO" || falha.codigo === "ROLLBACK_FALHOU";
|
|
355
|
+
return {
|
|
356
|
+
estado: falha.estado,
|
|
357
|
+
alterado,
|
|
358
|
+
destino_simbolico: destinoVirtual(opcoes.plataforma ?? process.platform),
|
|
359
|
+
codigo: falha.codigo,
|
|
360
|
+
node_absoluto: false,
|
|
361
|
+
entrypoint_absoluto: false,
|
|
362
|
+
recibo_valido: false,
|
|
363
|
+
independente_path: false,
|
|
364
|
+
fallback_simbolico: (opcoes.plataforma ?? process.platform) === "win32"
|
|
365
|
+
? "$HOME/.sema/bin/sema-managed.ps1"
|
|
366
|
+
: null,
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
export async function statusLauncherGlobal(opcoes = {}) {
|
|
370
|
+
try {
|
|
371
|
+
return (await diagnosticar(await resolverAmbiente(opcoes))).resultado;
|
|
372
|
+
}
|
|
373
|
+
catch (erro) {
|
|
374
|
+
return fallback(opcoes, erro);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
async function garantirCompanionDesejado(ambiente) {
|
|
378
|
+
if (!ambiente.windows)
|
|
379
|
+
return { criado: false };
|
|
380
|
+
const caminho = path.join(path.dirname(ambiente.destino), ambiente.windows.nomeCompanion);
|
|
381
|
+
const existente = await lstatOuNull(caminho);
|
|
382
|
+
if (existente) {
|
|
383
|
+
const atual = await lerArquivoSeguro(caminho, LIMITE_LAUNCHER_BYTES, ambiente.homeReal);
|
|
384
|
+
if (!atual.equals(ambiente.windows.companion)) {
|
|
385
|
+
throw new FalhaDistribuicaoGlobal("BROKEN_TARGET", "CONTEUDO_NAO_GERENCIADO");
|
|
386
|
+
}
|
|
387
|
+
return { criado: false, caminho, identidade: await identidadeArquivoSeguro(caminho) };
|
|
388
|
+
}
|
|
389
|
+
await escreverArquivoAtomico(ambiente.homeReal, caminho, ambiente.windows.companion, 0o600);
|
|
390
|
+
return { criado: true, caminho, identidade: await identidadeArquivoSeguro(caminho) };
|
|
391
|
+
}
|
|
392
|
+
async function garantirWrapperDesejado(ambiente, destino) {
|
|
393
|
+
if (!ambiente.windows || !destino)
|
|
394
|
+
return { criado: false };
|
|
395
|
+
const existente = await lstatOuNull(destino);
|
|
396
|
+
if (existente) {
|
|
397
|
+
const atual = await lerArquivoSeguro(destino, LIMITE_LAUNCHER_BYTES, ambiente.homeReal);
|
|
398
|
+
if (!validarWrapperLauncherWindows(atual)) {
|
|
399
|
+
throw new FalhaDistribuicaoGlobal("BROKEN_TARGET", "CONTEUDO_NAO_GERENCIADO");
|
|
400
|
+
}
|
|
401
|
+
return {
|
|
402
|
+
criado: false,
|
|
403
|
+
caminho: destino,
|
|
404
|
+
identidade: await identidadeArquivoSeguro(destino, ambiente.homeReal),
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
await escreverArquivoAtomico(ambiente.homeReal, destino, ambiente.windows.wrapper, 0o600);
|
|
408
|
+
return {
|
|
409
|
+
criado: true,
|
|
410
|
+
caminho: destino,
|
|
411
|
+
identidade: await identidadeArquivoSeguro(destino, ambiente.homeReal),
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
async function garantirAncoraDesejada(ambiente) {
|
|
415
|
+
if (!ambiente.windows || !ambiente.destinoAnchor)
|
|
416
|
+
return { criado: false };
|
|
417
|
+
const existente = await lstatOuNull(ambiente.destinoAnchor);
|
|
418
|
+
if (existente) {
|
|
419
|
+
const atual = await lerArquivoSeguro(ambiente.destinoAnchor, LIMITE_LAUNCHER_BYTES, ambiente.homeReal);
|
|
420
|
+
if (atual.equals(ambiente.windows.anchor)) {
|
|
421
|
+
return {
|
|
422
|
+
criado: false,
|
|
423
|
+
caminho: ambiente.destinoAnchor,
|
|
424
|
+
identidade: await identidadeArquivoSeguro(ambiente.destinoAnchor, ambiente.homeReal),
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
if (!validarReciboAncoraLauncherWindows(atual)) {
|
|
428
|
+
throw new FalhaDistribuicaoGlobal("BROKEN_TARGET", "CONTEUDO_NAO_GERENCIADO");
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
await escreverArquivoAtomico(ambiente.homeReal, ambiente.destinoAnchor, ambiente.windows.anchor, 0o600);
|
|
432
|
+
return {
|
|
433
|
+
criado: !existente,
|
|
434
|
+
caminho: ambiente.destinoAnchor,
|
|
435
|
+
identidade: await identidadeArquivoSeguro(ambiente.destinoAnchor, ambiente.homeReal),
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
function artefatosDesejadosLauncher(ambiente) {
|
|
439
|
+
const artefatos = [{
|
|
440
|
+
nome: path.basename(ambiente.destino),
|
|
441
|
+
conteudoDepois: Buffer.from(ambiente.conteudo, "utf8"),
|
|
442
|
+
modo: 0o755,
|
|
443
|
+
}];
|
|
444
|
+
if (ambiente.windows) {
|
|
445
|
+
artefatos.push({ nome: ambiente.windows.nomeCompanion, conteudoDepois: ambiente.windows.companion, modo: 0o600 }, { nome: path.basename(ambiente.destinoPowerShell ?? ""), conteudoDepois: ambiente.windows.wrapper, modo: 0o600 }, { nome: path.basename(ambiente.destinoWrapper ?? ""), conteudoDepois: ambiente.windows.wrapper, modo: 0o600 }, { nome: path.basename(ambiente.destinoAnchor ?? ""), conteudoDepois: ambiente.windows.anchor, modo: 0o600 });
|
|
446
|
+
}
|
|
447
|
+
return artefatos;
|
|
448
|
+
}
|
|
449
|
+
async function sincronizarAmbiente(ambiente, preservarCompanionAnterior) {
|
|
450
|
+
let transacao;
|
|
451
|
+
try {
|
|
452
|
+
const diretorio = path.dirname(ambiente.destino);
|
|
453
|
+
const recuperacaoInicial = await recuperarTransacaoArquivosLauncher(ambiente.homeReal, diretorio);
|
|
454
|
+
const antes = await diagnosticar(ambiente);
|
|
455
|
+
if (antes.resultado.estado === "BROKEN_TARGET"
|
|
456
|
+
|| antes.resultado.estado === "PERMISSION_DENIED")
|
|
457
|
+
return antes.resultado;
|
|
458
|
+
if (antes.resultado.estado === "READY") {
|
|
459
|
+
if (preservarCompanionAnterior) {
|
|
460
|
+
return { ...antes.resultado, alterado: recuperacaoInicial.alterado };
|
|
461
|
+
}
|
|
462
|
+
const limpeza = await limparCompanionsGerenciadosInativos(ambiente, antes.recibo?.nomeCompanion);
|
|
463
|
+
const depoisLimpeza = await diagnosticar(ambiente);
|
|
464
|
+
return {
|
|
465
|
+
...depoisLimpeza.resultado,
|
|
466
|
+
alterado: limpeza.alterado || recuperacaoInicial.alterado,
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
transacao = await prepararTransacaoArquivosLauncher(ambiente.homeReal, diretorio, artefatosDesejadosLauncher(ambiente));
|
|
470
|
+
await garantirCompanionDesejado(ambiente);
|
|
471
|
+
await garantirWrapperDesejado(ambiente, ambiente.destinoPowerShell);
|
|
472
|
+
await garantirWrapperDesejado(ambiente, ambiente.destinoWrapper);
|
|
473
|
+
await garantirAncoraDesejada(ambiente);
|
|
474
|
+
await escreverArquivoAtomico(ambiente.homeReal, ambiente.destino, ambiente.conteudo, 0o755);
|
|
475
|
+
let depois = await diagnosticar(ambiente);
|
|
476
|
+
if (depois.resultado.estado !== "READY") {
|
|
477
|
+
throw new FalhaDistribuicaoGlobal("BROKEN_TARGET", depois.resultado.codigo);
|
|
478
|
+
}
|
|
479
|
+
const conclusao = await concluirTransacaoArquivosLauncher(transacao);
|
|
480
|
+
transacao = undefined;
|
|
481
|
+
if (!preservarCompanionAnterior) {
|
|
482
|
+
await limparCompanionsGerenciadosInativos(ambiente, depois.recibo?.nomeCompanion);
|
|
483
|
+
depois = await diagnosticar(ambiente);
|
|
484
|
+
}
|
|
485
|
+
const limpezaPendente = conclusao.limpezaPendente
|
|
486
|
+
|| await transacaoArquivosLauncherPendente(ambiente.homeReal, diretorio);
|
|
487
|
+
return {
|
|
488
|
+
...depois.resultado,
|
|
489
|
+
codigo: depois.resultado.estado === "READY" && limpezaPendente
|
|
490
|
+
? "LIMPEZA_PENDENTE"
|
|
491
|
+
: depois.resultado.codigo,
|
|
492
|
+
alterado: true,
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
catch (erro) {
|
|
496
|
+
if (transacao) {
|
|
497
|
+
try {
|
|
498
|
+
await recuperarTransacaoArquivosLauncher(ambiente.homeReal, path.dirname(ambiente.destino));
|
|
499
|
+
return { ...(await diagnosticar(ambiente)).resultado, alterado: false };
|
|
500
|
+
}
|
|
501
|
+
catch {
|
|
502
|
+
return resultado(ambiente, "BROKEN_TARGET", "ROLLBACK_FALHOU", true);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
const falha = falhaParaResultado(erro);
|
|
506
|
+
return resultado(ambiente, falha.estado, falha.codigo);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
async function sincronizarLauncherGlobalSemLock(opcoes = {}) {
|
|
510
|
+
try {
|
|
511
|
+
return await sincronizarAmbiente(await resolverAmbiente(opcoes), false);
|
|
512
|
+
}
|
|
513
|
+
catch (erro) {
|
|
514
|
+
return fallback(opcoes, erro);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
export async function sincronizarLauncherGlobal(opcoes = {}) {
|
|
518
|
+
try {
|
|
519
|
+
return await comLockDistribuicaoGlobal(opcoes, async ({ diretorioUsuario }) => (sincronizarLauncherGlobalSemLock({ ...opcoes, diretorioUsuario })));
|
|
520
|
+
}
|
|
521
|
+
catch (erro) {
|
|
522
|
+
return fallback(opcoes, erro);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
export async function capturarSnapshotLauncherGlobalTransacao(opcoes = {}) {
|
|
526
|
+
const ambiente = await resolverAmbiente(opcoes);
|
|
527
|
+
const diagnosticoAntes = await diagnosticar(ambiente);
|
|
528
|
+
if (diagnosticoAntes.resultado.estado === "BROKEN_TARGET"
|
|
529
|
+
|| diagnosticoAntes.resultado.estado === "PERMISSION_DENIED") {
|
|
530
|
+
throw new FalhaDistribuicaoGlobal(diagnosticoAntes.resultado.estado === "PERMISSION_DENIED"
|
|
531
|
+
? "PERMISSION_DENIED"
|
|
532
|
+
: "BROKEN_TARGET", diagnosticoAntes.resultado.codigo);
|
|
533
|
+
}
|
|
534
|
+
const launcherAntes = await lstatOuNull(ambiente.destino)
|
|
535
|
+
? await lerArquivoSeguro(ambiente.destino, LIMITE_LAUNCHER_BYTES, ambiente.homeReal)
|
|
536
|
+
: undefined;
|
|
537
|
+
const powerShellAntes = ambiente.destinoPowerShell && await lstatOuNull(ambiente.destinoPowerShell)
|
|
538
|
+
? await lerArquivoSeguro(ambiente.destinoPowerShell, LIMITE_LAUNCHER_BYTES, ambiente.homeReal)
|
|
539
|
+
: undefined;
|
|
540
|
+
const wrapperAntes = ambiente.destinoWrapper && await lstatOuNull(ambiente.destinoWrapper)
|
|
541
|
+
? await lerArquivoSeguro(ambiente.destinoWrapper, LIMITE_LAUNCHER_BYTES, ambiente.homeReal)
|
|
542
|
+
: undefined;
|
|
543
|
+
const anchorAntes = ambiente.destinoAnchor && await lstatOuNull(ambiente.destinoAnchor)
|
|
544
|
+
? await lerArquivoSeguro(ambiente.destinoAnchor, LIMITE_LAUNCHER_BYTES, ambiente.homeReal)
|
|
545
|
+
: undefined;
|
|
546
|
+
const companionDesejado = ambiente.windows
|
|
547
|
+
? path.join(path.dirname(ambiente.destino), ambiente.windows.nomeCompanion)
|
|
548
|
+
: undefined;
|
|
549
|
+
return {
|
|
550
|
+
ambiente,
|
|
551
|
+
diagnosticoAntes,
|
|
552
|
+
launcherAntes,
|
|
553
|
+
powerShellAntes,
|
|
554
|
+
wrapperAntes,
|
|
555
|
+
anchorAntes,
|
|
556
|
+
companionDesejadoExistia: companionDesejado
|
|
557
|
+
? await lstatOuNull(companionDesejado) !== null
|
|
558
|
+
: false,
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
async function sincronizarLauncherGlobalTransacionalSemLock(snapshot) {
|
|
562
|
+
return sincronizarAmbiente(snapshot.ambiente, true);
|
|
563
|
+
}
|
|
564
|
+
export async function sincronizarLauncherGlobalTransacional(snapshot) {
|
|
565
|
+
return comLockDistribuicaoGlobal({ diretorioUsuario: snapshot.ambiente.homeReal }, async () => sincronizarLauncherGlobalTransacionalSemLock(snapshot));
|
|
566
|
+
}
|
|
567
|
+
function artefatosRollbackLauncher(snapshot) {
|
|
568
|
+
const { ambiente } = snapshot;
|
|
569
|
+
const companion = ambiente.windows
|
|
570
|
+
? path.join(path.dirname(ambiente.destino), ambiente.windows.nomeCompanion)
|
|
571
|
+
: undefined;
|
|
572
|
+
return [
|
|
573
|
+
{ destino: ambiente.destino, antes: snapshot.launcherAntes, esperado: Buffer.from(ambiente.conteudo), modo: 0o755 },
|
|
574
|
+
{ destino: ambiente.destinoPowerShell, antes: snapshot.powerShellAntes, esperado: ambiente.windows?.wrapper, modo: 0o600 },
|
|
575
|
+
{ destino: ambiente.destinoWrapper, antes: snapshot.wrapperAntes, esperado: ambiente.windows?.wrapper, modo: 0o600 },
|
|
576
|
+
{ destino: ambiente.destinoAnchor, antes: snapshot.anchorAntes, esperado: ambiente.windows?.anchor, modo: 0o600 },
|
|
577
|
+
{
|
|
578
|
+
destino: companion,
|
|
579
|
+
antes: snapshot.companionDesejadoExistia ? ambiente.windows?.companion : undefined,
|
|
580
|
+
esperado: ambiente.windows?.companion,
|
|
581
|
+
modo: 0o600,
|
|
582
|
+
},
|
|
583
|
+
];
|
|
584
|
+
}
|
|
585
|
+
async function restaurarArtefatoRollback(ambiente, artefato) {
|
|
586
|
+
if (!artefato.destino || !artefato.esperado)
|
|
587
|
+
return;
|
|
588
|
+
const existe = await lstatOuNull(artefato.destino) !== null;
|
|
589
|
+
if (!existe && artefato.antes) {
|
|
590
|
+
await escreverArquivoAtomico(ambiente.homeReal, artefato.destino, artefato.antes, artefato.modo);
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
if (!existe)
|
|
594
|
+
return;
|
|
595
|
+
const atual = await lerArquivoSeguro(artefato.destino, LIMITE_LAUNCHER_BYTES, ambiente.homeReal);
|
|
596
|
+
if (artefato.antes && atual.equals(artefato.antes))
|
|
597
|
+
return;
|
|
598
|
+
if (!atual.equals(artefato.esperado)) {
|
|
599
|
+
throw new FalhaDistribuicaoGlobal("BROKEN_TARGET", "DESTINO_ALTERADO");
|
|
600
|
+
}
|
|
601
|
+
if (artefato.antes) {
|
|
602
|
+
await escreverArquivoAtomico(ambiente.homeReal, artefato.destino, artefato.antes, artefato.modo);
|
|
603
|
+
}
|
|
604
|
+
else {
|
|
605
|
+
await removerArquivoSeguro(ambiente.homeReal, artefato.destino, await identidadeArquivoSeguro(artefato.destino, ambiente.homeReal));
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
async function confirmarArtefatoRollback(ambiente, artefato) {
|
|
609
|
+
if (!artefato.destino || !artefato.esperado)
|
|
610
|
+
return;
|
|
611
|
+
const existe = await lstatOuNull(artefato.destino) !== null;
|
|
612
|
+
if (!artefato.antes) {
|
|
613
|
+
if (existe)
|
|
614
|
+
throw new FalhaDistribuicaoGlobal("BROKEN_TARGET", "ROLLBACK_FALHOU");
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
if (!existe || !(await lerArquivoSeguro(artefato.destino, LIMITE_LAUNCHER_BYTES, ambiente.homeReal)).equals(artefato.antes)) {
|
|
618
|
+
throw new FalhaDistribuicaoGlobal("BROKEN_TARGET", "ROLLBACK_FALHOU");
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
async function restaurarSnapshotLauncherGlobalTransacaoSemLock(snapshot) {
|
|
622
|
+
const artefatos = artefatosRollbackLauncher(snapshot);
|
|
623
|
+
const restauracoes = await Promise.allSettled(artefatos.map((artefato) => restaurarArtefatoRollback(snapshot.ambiente, artefato)));
|
|
624
|
+
const verificacoes = await Promise.allSettled(artefatos.map((artefato) => confirmarArtefatoRollback(snapshot.ambiente, artefato)));
|
|
625
|
+
if ([...restauracoes, ...verificacoes].some((item) => item.status === "rejected")) {
|
|
626
|
+
throw new FalhaDistribuicaoGlobal("BROKEN_TARGET", "ROLLBACK_FALHOU");
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
export async function restaurarSnapshotLauncherGlobalTransacao(snapshot) {
|
|
630
|
+
return comLockDistribuicaoGlobal({ diretorioUsuario: snapshot.ambiente.homeReal }, async () => restaurarSnapshotLauncherGlobalTransacaoSemLock(snapshot));
|
|
631
|
+
}
|
|
632
|
+
async function confirmarSnapshotLauncherGlobalTransacaoSemLock(snapshot) {
|
|
633
|
+
const atual = await diagnosticar(snapshot.ambiente);
|
|
634
|
+
if (atual.resultado.estado !== "READY")
|
|
635
|
+
return atual.resultado;
|
|
636
|
+
const limpeza = await limparCompanionsGerenciadosInativos(snapshot.ambiente, atual.recibo?.nomeCompanion);
|
|
637
|
+
const final = await diagnosticar(snapshot.ambiente);
|
|
638
|
+
return { ...final.resultado, alterado: limpeza.alterado };
|
|
639
|
+
}
|
|
640
|
+
export async function confirmarSnapshotLauncherGlobalTransacao(snapshot) {
|
|
641
|
+
return comLockDistribuicaoGlobal({ diretorioUsuario: snapshot.ambiente.homeReal }, async () => confirmarSnapshotLauncherGlobalTransacaoSemLock(snapshot));
|
|
642
|
+
}
|
|
643
|
+
//# sourceMappingURL=launcherGlobal.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface ArtefatosLauncherWindows {
|
|
2
|
+
launcher: string;
|
|
3
|
+
companion: Buffer;
|
|
4
|
+
nomeCompanion: string;
|
|
5
|
+
wrapper: Buffer;
|
|
6
|
+
anchor: Buffer;
|
|
7
|
+
}
|
|
8
|
+
export interface ReciboLauncherWindows {
|
|
9
|
+
versaoPacote: string;
|
|
10
|
+
executavelNode: string;
|
|
11
|
+
entrypoint: string;
|
|
12
|
+
nomeCompanion: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function gerarWrapperLauncherWindows(): Buffer;
|
|
15
|
+
export declare function validarWrapperLauncherWindows(conteudo: Buffer): boolean;
|
|
16
|
+
export declare function nomeWrapperLauncherWindows(): string;
|
|
17
|
+
export declare function nomeLauncherPowerShellWindows(): string;
|
|
18
|
+
export declare function nomeAncoraLauncherWindows(): string;
|
|
19
|
+
export declare function gerarArtefatosLauncherWindows(executavelNode: string, entrypoint: string, versaoPacote: string): ArtefatosLauncherWindows;
|
|
20
|
+
export declare function validarAncoraLauncherWindows(conteudo: Buffer, launcher: string, companion: Buffer, nomeCompanion: string, wrapper: Buffer): boolean;
|
|
21
|
+
export declare function validarReciboAncoraLauncherWindows(conteudo: Buffer): boolean;
|
|
22
|
+
export declare function validarCompanionLauncherWindows(conteudo: Buffer, nomeCompanion: string): {
|
|
23
|
+
versaoPacote: string;
|
|
24
|
+
executavelNode: string;
|
|
25
|
+
entrypoint: string;
|
|
26
|
+
} | null;
|
|
27
|
+
export declare function validarArtefatosLauncherWindows(launcher: string, companion: Buffer): ReciboLauncherWindows | null;
|
|
28
|
+
export declare function extrairNomeCompanionLauncherWindows(launcher: string): string | null;
|