@semacode/cli 2.0.1 → 2.2.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 +141 -121
- package/dist/agentEntryPoints.js +499 -499
- package/dist/comandos.js +2 -0
- package/dist/doctorCommand.js +28 -0
- package/dist/execucoesExternas.js +19 -5
- package/dist/geracaoCore.js +97 -1
- package/dist/iaPrompts.d.ts +1 -1
- package/dist/iaPrompts.js +307 -307
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.part01.d.ts +1 -1
- package/dist/index.part01.js +14 -4
- package/dist/index.part02.js +21 -21
- package/dist/index.part04.js +96 -96
- package/dist/index.part06.js +1 -1
- package/dist/index.part07.js +35 -24
- package/dist/init/templates.part01.js +393 -393
- package/dist/init/templates.part02.js +189 -189
- package/dist/initTemplatesBackend.js +73 -73
- package/dist/initTemplatesBase.js +81 -81
- package/dist/initTemplatesFlutter.js +137 -137
- package/dist/initTemplatesRuntime.js +350 -350
- package/dist/initTemplatesWeb.js +309 -309
- package/dist/nativeToolchains.d.ts +15 -0
- package/dist/nativeToolchains.js +132 -0
- package/dist/pipelineConteudo/adapters.d.ts +84 -0
- package/dist/pipelineConteudo/adapters.js +449 -0
- package/dist/pipelineConteudo/canonical.d.ts +18 -0
- package/dist/pipelineConteudo/canonical.js +107 -0
- package/dist/pipelineConteudo/command.d.ts +3 -0
- package/dist/pipelineConteudo/command.js +572 -0
- package/dist/pipelineConteudo/index.d.ts +9 -0
- package/dist/pipelineConteudo/index.js +12 -0
- package/dist/pipelineConteudo/ledger.d.ts +68 -0
- package/dist/pipelineConteudo/ledger.js +732 -0
- package/dist/pipelineConteudo/planner.d.ts +12 -0
- package/dist/pipelineConteudo/planner.js +366 -0
- package/dist/pipelineConteudo/projection.d.ts +16 -0
- package/dist/pipelineConteudo/projection.js +57 -0
- package/dist/pipelineConteudo/state.d.ts +23 -0
- package/dist/pipelineConteudo/state.js +615 -0
- package/dist/pipelineConteudo/trust.d.ts +17 -0
- package/dist/pipelineConteudo/trust.js +750 -0
- package/dist/pipelineConteudo/types.d.ts +331 -0
- package/dist/pipelineConteudo/types.js +4 -0
- package/dist/projetoConfig.js +7 -1
- package/dist/projetoResolucao.js +21 -6
- package/dist/sync/index.js +35 -35
- package/docs/README.md +28 -25
- package/docs/ai-onboarding.md +62 -62
- package/docs/ai-workflow.md +1 -1
- package/docs/auth.md +26 -26
- package/docs/cli.md +79 -72
- package/docs/commands.md +1 -1
- package/docs/database.md +15 -15
- package/docs/deploy.md +41 -36
- package/docs/documentation.md +39 -39
- package/docs/env.md +16 -16
- package/docs/frontend.md +41 -41
- package/docs/getting-started.md +57 -57
- package/docs/i18n.md +15 -15
- package/docs/pipeline-conteudo.md +246 -0
- package/docs/profiles.md +45 -43
- package/docs/repositories.md +43 -43
- package/docs/rollback.md +31 -31
- package/docs/security.md +32 -32
- package/docs/support.md +8 -8
- package/docs/syntax.md +1 -1
- package/docs/testing.md +35 -28
- 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/pipeline-conteudo/README.md +44 -0
- package/exemplos/pipeline-conteudo/alvos.json +23 -0
- package/exemplos/pipeline-conteudo/definicao.json +136 -0
- 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.d.ts +3 -0
- package/node_modules/@sema/gerador-cpp/dist/index.js +859 -0
- package/node_modules/@sema/gerador-cpp/dist/index.js.map +1 -0
- package/node_modules/@sema/gerador-cpp/package.json +7 -0
- 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.d.ts +3 -0
- package/node_modules/@sema/gerador-dotnet/dist/index.js +828 -0
- package/node_modules/@sema/gerador-dotnet/dist/index.js.map +1 -0
- package/node_modules/@sema/gerador-dotnet/package.json +7 -0
- package/node_modules/@sema/gerador-html/dist/index.js +17 -17
- package/node_modules/@sema/gerador-lua/dist/index.js +53 -8
- package/node_modules/@sema/gerador-lua/dist/index.js.map +1 -1
- package/node_modules/@sema/gerador-php/dist/index.js +121 -113
- package/node_modules/@sema/gerador-php/dist/index.js.map +1 -1
- 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/padroes/dist/index.d.ts +1 -1
- package/package.json +12 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type TipoToolchainCpp = "gcc" | "clang" | "msvc" | "msvc-devcmd";
|
|
2
|
+
export interface ToolchainCpp {
|
|
3
|
+
tipo: TipoToolchainCpp;
|
|
4
|
+
comando: string;
|
|
5
|
+
rotulo: string;
|
|
6
|
+
scriptAmbiente?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ResultadoComandoNativo {
|
|
9
|
+
codigoSaida: number;
|
|
10
|
+
saidaPadrao: string;
|
|
11
|
+
saidaErro: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function resolverToolchainCpp(): ToolchainCpp | undefined;
|
|
14
|
+
export declare function compilarCpp(toolchain: ToolchainCpp, fontes: string[], diretorioIncludes: string, executavel: string, silencioso?: boolean): ResultadoComandoNativo;
|
|
15
|
+
export declare function executarBinarioNativo(executavel: string, silencioso?: boolean): ResultadoComandoNativo;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// SEMA-GOVERNED
|
|
2
|
+
// Módulo: sema.produto.geradores_nativos
|
|
3
|
+
// Contrato: contratos/sema/geradores_nativos.sema
|
|
4
|
+
// Descrição: detecta e executa toolchains C++ locais sem baixar dependências.
|
|
5
|
+
import { existsSync } from "node:fs";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import { spawnSync } from "node:child_process";
|
|
8
|
+
const TIMEOUT_DETECCAO_MS = 5_000;
|
|
9
|
+
const TIMEOUT_COMPILACAO_MS = 120_000;
|
|
10
|
+
function textoSaida(valor) {
|
|
11
|
+
return typeof valor === "string" ? valor : valor?.toString("utf8") ?? "";
|
|
12
|
+
}
|
|
13
|
+
function resultadoComando(resultado, erroPadrao) {
|
|
14
|
+
return {
|
|
15
|
+
codigoSaida: resultado.status ?? 1,
|
|
16
|
+
saidaPadrao: textoSaida(resultado.stdout),
|
|
17
|
+
saidaErro: textoSaida(resultado.stderr) || resultado.error?.message || erroPadrao,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function comandoResponde(comando, argumentos) {
|
|
21
|
+
const resultado = spawnSync(comando, argumentos, {
|
|
22
|
+
stdio: "ignore",
|
|
23
|
+
timeout: TIMEOUT_DETECCAO_MS,
|
|
24
|
+
windowsHide: true,
|
|
25
|
+
});
|
|
26
|
+
return !resultado.error && resultado.signal === null && (resultado.status ?? 1) === 0;
|
|
27
|
+
}
|
|
28
|
+
function localizarVsDevCmd() {
|
|
29
|
+
if (process.platform !== "win32") {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
const programFilesX86 = process.env["ProgramFiles(x86)"];
|
|
33
|
+
if (!programFilesX86) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
const vswhere = path.join(programFilesX86, "Microsoft Visual Studio", "Installer", "vswhere.exe");
|
|
37
|
+
if (!existsSync(vswhere)) {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
const resultado = spawnSync(vswhere, [
|
|
41
|
+
"-latest",
|
|
42
|
+
"-products",
|
|
43
|
+
"*",
|
|
44
|
+
"-requires",
|
|
45
|
+
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
|
|
46
|
+
"-property",
|
|
47
|
+
"installationPath",
|
|
48
|
+
], {
|
|
49
|
+
encoding: "utf8",
|
|
50
|
+
timeout: TIMEOUT_DETECCAO_MS,
|
|
51
|
+
windowsHide: true,
|
|
52
|
+
});
|
|
53
|
+
const instalacao = textoSaida(resultado.stdout).trim().split(/\r?\n/).at(-1);
|
|
54
|
+
if (!instalacao) {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
const script = path.join(instalacao, "Common7", "Tools", "VsDevCmd.bat");
|
|
58
|
+
return existsSync(script) ? script : undefined;
|
|
59
|
+
}
|
|
60
|
+
export function resolverToolchainCpp() {
|
|
61
|
+
const candidatos = [
|
|
62
|
+
{ comando: "c++", tipo: "gcc", rotulo: "c++" },
|
|
63
|
+
{ comando: "g++", tipo: "gcc", rotulo: "g++" },
|
|
64
|
+
{ comando: "clang++", tipo: "clang", rotulo: "clang++" },
|
|
65
|
+
];
|
|
66
|
+
for (const candidato of candidatos) {
|
|
67
|
+
if (comandoResponde(candidato.comando, ["--version"])) {
|
|
68
|
+
return candidato;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (process.platform === "win32" && comandoResponde("cl", ["/nologo", "/?"])) {
|
|
72
|
+
return { tipo: "msvc", comando: "cl", rotulo: "MSVC cl" };
|
|
73
|
+
}
|
|
74
|
+
const scriptAmbiente = localizarVsDevCmd();
|
|
75
|
+
if (scriptAmbiente) {
|
|
76
|
+
return {
|
|
77
|
+
tipo: "msvc-devcmd",
|
|
78
|
+
comando: process.env.ComSpec ?? "cmd.exe",
|
|
79
|
+
rotulo: "MSVC via VsDevCmd",
|
|
80
|
+
scriptAmbiente,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
function citarCmd(valor) {
|
|
86
|
+
return `"${valor.replace(/"/g, '""')}"`;
|
|
87
|
+
}
|
|
88
|
+
export function compilarCpp(toolchain, fontes, diretorioIncludes, executavel, silencioso = false) {
|
|
89
|
+
const cwd = path.dirname(executavel);
|
|
90
|
+
const stdio = silencioso ? "pipe" : "inherit";
|
|
91
|
+
if (toolchain.tipo === "msvc-devcmd") {
|
|
92
|
+
const comando = [
|
|
93
|
+
`call ${citarCmd(toolchain.scriptAmbiente)}`,
|
|
94
|
+
"-no_logo -arch=x64 -host_arch=x64 >nul",
|
|
95
|
+
"&& cl /nologo /std:c++20 /EHsc",
|
|
96
|
+
fontes.map(citarCmd).join(" "),
|
|
97
|
+
`/I${citarCmd(diretorioIncludes)}`,
|
|
98
|
+
`/Fe:${citarCmd(executavel)}`,
|
|
99
|
+
].join(" ");
|
|
100
|
+
const resultado = spawnSync(toolchain.comando, ["/d", "/s", "/c", comando], {
|
|
101
|
+
cwd,
|
|
102
|
+
stdio,
|
|
103
|
+
encoding: silencioso ? "utf8" : undefined,
|
|
104
|
+
timeout: TIMEOUT_COMPILACAO_MS,
|
|
105
|
+
windowsHide: true,
|
|
106
|
+
windowsVerbatimArguments: true,
|
|
107
|
+
});
|
|
108
|
+
return resultadoComando(resultado, "Falha ao executar o MSVC via VsDevCmd.");
|
|
109
|
+
}
|
|
110
|
+
const argumentos = toolchain.tipo === "msvc"
|
|
111
|
+
? ["/nologo", "/std:c++20", "/EHsc", ...fontes, `/I${diretorioIncludes}`, `/Fe:${executavel}`]
|
|
112
|
+
: ["-std=c++20", "-Wall", "-Wextra", ...fontes, `-I${diretorioIncludes}`, "-o", executavel];
|
|
113
|
+
const resultado = spawnSync(toolchain.comando, argumentos, {
|
|
114
|
+
cwd,
|
|
115
|
+
stdio,
|
|
116
|
+
encoding: silencioso ? "utf8" : undefined,
|
|
117
|
+
timeout: TIMEOUT_COMPILACAO_MS,
|
|
118
|
+
windowsHide: true,
|
|
119
|
+
});
|
|
120
|
+
return resultadoComando(resultado, `Falha ao executar ${toolchain.rotulo}.`);
|
|
121
|
+
}
|
|
122
|
+
export function executarBinarioNativo(executavel, silencioso = false) {
|
|
123
|
+
const resultado = spawnSync(executavel, [], {
|
|
124
|
+
cwd: path.dirname(executavel),
|
|
125
|
+
stdio: silencioso ? "pipe" : "inherit",
|
|
126
|
+
encoding: silencioso ? "utf8" : undefined,
|
|
127
|
+
timeout: TIMEOUT_COMPILACAO_MS,
|
|
128
|
+
windowsHide: true,
|
|
129
|
+
});
|
|
130
|
+
return resultadoComando(resultado, "Falha ao executar os testes C++ compilados.");
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=nativeToolchains.js.map
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { AdaptadorConteudo, AlvoConteudo, ArtefatoConteudo, MetadataPublicaConteudo, RestricaoDeterministicaConteudo } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Vocabulário inicial para definições usuais. O validador aceita qualquer
|
|
4
|
+
* capability opaca não vazia; esta lista não é uma whitelist.
|
|
5
|
+
*/
|
|
6
|
+
export declare const CAPABILITIES_CONTEUDO_PADRAO: readonly ["content.topic.plan", "content.research.collect", "content.master.compose", "content.target.adapt", "content.qa.deterministic", "content.qa.semantic", "content.target.deliver", "content.target.confirm"];
|
|
7
|
+
export declare const CONSTRAINTS_DETERMINISTICAS_SUPORTADAS: readonly ["artifact.bytes.min", "artifact.bytes.max", "media.duration.min", "media.duration.max", "text.length.min", "text.length.max"];
|
|
8
|
+
export interface ObservacoesDeterministicasArtefatoConteudo {
|
|
9
|
+
/** Media type observado por sniffing/verificador independente. */
|
|
10
|
+
readonly observedMediaType?: string;
|
|
11
|
+
/** Tamanho materializado do artefato, em bytes. */
|
|
12
|
+
readonly artifactBytes?: number;
|
|
13
|
+
/** Duração observada da mídia, em segundos. */
|
|
14
|
+
readonly mediaDuration?: number;
|
|
15
|
+
/** Comprimento textual observado, em pontos de código Unicode. */
|
|
16
|
+
readonly textLength?: number;
|
|
17
|
+
}
|
|
18
|
+
export interface ResultadoConstraintDeterministicaConteudo {
|
|
19
|
+
readonly constraintId: string;
|
|
20
|
+
readonly kind: string;
|
|
21
|
+
readonly observed: number | null;
|
|
22
|
+
readonly limit: number | null;
|
|
23
|
+
readonly passed: boolean;
|
|
24
|
+
readonly bloqueios: readonly string[];
|
|
25
|
+
}
|
|
26
|
+
export interface ResultadoAvaliacaoConstraintsConteudo {
|
|
27
|
+
readonly valido: boolean;
|
|
28
|
+
readonly artifactDigest: string;
|
|
29
|
+
readonly constraintsDigest: string;
|
|
30
|
+
readonly resultsDigest: string;
|
|
31
|
+
readonly resultados: readonly ResultadoConstraintDeterministicaConteudo[];
|
|
32
|
+
readonly bloqueios: readonly string[];
|
|
33
|
+
}
|
|
34
|
+
export interface ResultadoValidacaoAdaptadorConteudo {
|
|
35
|
+
readonly valido: boolean;
|
|
36
|
+
readonly bloqueios: readonly string[];
|
|
37
|
+
}
|
|
38
|
+
export interface PlanoAdaptacaoConteudo {
|
|
39
|
+
readonly targetId: string;
|
|
40
|
+
readonly adapterId: string;
|
|
41
|
+
readonly adapterVersion: string;
|
|
42
|
+
readonly accountScope: string;
|
|
43
|
+
readonly isolationKey: string;
|
|
44
|
+
readonly formatProfileId: string;
|
|
45
|
+
readonly locale: string;
|
|
46
|
+
readonly capabilities: readonly string[];
|
|
47
|
+
readonly acceptedMediaTypes: readonly string[];
|
|
48
|
+
readonly deterministicConstraints: readonly RestricaoDeterministicaConteudo[];
|
|
49
|
+
readonly requiredMetadata: readonly string[];
|
|
50
|
+
readonly optionalMetadata: readonly string[];
|
|
51
|
+
readonly confirmationPredicates: readonly string[];
|
|
52
|
+
readonly metadata: MetadataPublicaConteudo;
|
|
53
|
+
readonly masterArtifacts: readonly unknown[];
|
|
54
|
+
}
|
|
55
|
+
export interface BloqueioAlvoConteudo {
|
|
56
|
+
readonly targetId: string;
|
|
57
|
+
readonly codigo: string;
|
|
58
|
+
}
|
|
59
|
+
export interface ResultadoPlanejamentoAlvosConteudo {
|
|
60
|
+
readonly planosAdaptacao: readonly PlanoAdaptacaoConteudo[];
|
|
61
|
+
readonly bloqueiosPorAlvo: readonly BloqueioAlvoConteudo[];
|
|
62
|
+
}
|
|
63
|
+
export declare function validarReferenciaAccountScopeConteudo(valor: unknown): readonly string[];
|
|
64
|
+
/** Metadata de target e publica no plano/ledger/projecao; segredos sao sempre externos. */
|
|
65
|
+
export declare function validarMetadataPublicaConteudo(valor: unknown): readonly string[];
|
|
66
|
+
/**
|
|
67
|
+
* Escopo exato e injetivo para autorização target-bound. Alterar execução,
|
|
68
|
+
* target ou conta sempre altera o escopo.
|
|
69
|
+
*/
|
|
70
|
+
export declare function escopoAutorizacaoAlvo(runId: string, alvo: AlvoConteudo): string;
|
|
71
|
+
export declare function escopoAutorizacaoGlobal(runId: string): string;
|
|
72
|
+
/**
|
|
73
|
+
* Avalia somente medições fornecidas. Não lê arquivos, não chama ferramentas e
|
|
74
|
+
* nunca trata um kind desconhecido como aprovação implícita.
|
|
75
|
+
*/
|
|
76
|
+
export declare function avaliarConstraintsDeterministicasConteudo(artefato: ArtefatoConteudo, constraints: readonly RestricaoDeterministicaConteudo[], observacoes?: ObservacoesDeterministicasArtefatoConteudo): ResultadoAvaliacaoConstraintsConteudo;
|
|
77
|
+
/** Valida somente propriedades declarativas; nenhuma capability é executada. */
|
|
78
|
+
export declare function validarAdaptadorConteudo(adapter: AdaptadorConteudo): ResultadoValidacaoAdaptadorConteudo;
|
|
79
|
+
/**
|
|
80
|
+
* Materializa um plano isolado por targetId/accountScope. Os planos carregam
|
|
81
|
+
* instruções e referências; credenciais e chamadas de ferramenta ficam no
|
|
82
|
+
* runner externo.
|
|
83
|
+
*/
|
|
84
|
+
export declare function planejarAlvosConteudo(alvos: readonly AlvoConteudo[], adapters: readonly AdaptadorConteudo[], artefatosMestre: readonly unknown[]): ResultadoPlanejamentoAlvosConteudo;
|
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
// SEMA-GOVERNED: sema.produto.pipeline_conteudo.adaptadores
|
|
2
|
+
// Descricao: validacao e planejamento declarativo de destinos abertos do pipeline de conteudo.
|
|
3
|
+
import { digestJsonCanonico } from "./canonical.js";
|
|
4
|
+
/**
|
|
5
|
+
* Vocabulário inicial para definições usuais. O validador aceita qualquer
|
|
6
|
+
* capability opaca não vazia; esta lista não é uma whitelist.
|
|
7
|
+
*/
|
|
8
|
+
export const CAPABILITIES_CONTEUDO_PADRAO = Object.freeze([
|
|
9
|
+
"content.topic.plan",
|
|
10
|
+
"content.research.collect",
|
|
11
|
+
"content.master.compose",
|
|
12
|
+
"content.target.adapt",
|
|
13
|
+
"content.qa.deterministic",
|
|
14
|
+
"content.qa.semantic",
|
|
15
|
+
"content.target.deliver",
|
|
16
|
+
"content.target.confirm",
|
|
17
|
+
]);
|
|
18
|
+
export const CONSTRAINTS_DETERMINISTICAS_SUPORTADAS = Object.freeze([
|
|
19
|
+
"artifact.bytes.min",
|
|
20
|
+
"artifact.bytes.max",
|
|
21
|
+
"media.duration.min",
|
|
22
|
+
"media.duration.max",
|
|
23
|
+
"text.length.min",
|
|
24
|
+
"text.length.max",
|
|
25
|
+
]);
|
|
26
|
+
const VERSOES_FLUTUANTES = new Set(["*", "current", "latest", "stable"]);
|
|
27
|
+
const CONSTRAINTS_SUPORTADAS = new Set(CONSTRAINTS_DETERMINISTICAS_SUPORTADAS);
|
|
28
|
+
const DECLARACOES_NAO_CONFIAVEIS = new Set([
|
|
29
|
+
"executor_declared",
|
|
30
|
+
"executor_declaration",
|
|
31
|
+
"runner_declared",
|
|
32
|
+
"runner_declaration",
|
|
33
|
+
]);
|
|
34
|
+
const CHAVES_METADATA_SENSIVEIS = new Set([
|
|
35
|
+
"apikey", "accesstoken", "refreshtoken", "authorization", "bearer", "password", "passwd",
|
|
36
|
+
"secret", "clientsecret", "privatekey", "credential", "credentials", "apitoken",
|
|
37
|
+
"awssecretaccesskey", "sessioncookie", "sessiontoken", "authcookie", "signingkey",
|
|
38
|
+
]);
|
|
39
|
+
const PADROES_VALOR_SENSIVEL = [
|
|
40
|
+
/-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----/u,
|
|
41
|
+
/\bBearer\s+[A-Za-z0-9._~+/=-]{12,}/iu,
|
|
42
|
+
/\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/u,
|
|
43
|
+
/\b(?:github_pat_|gh[pousr]_|xox[baprs]-|sk_(?:live|test)_|sk-|AIza)[A-Za-z0-9_-]{12,}\b/u,
|
|
44
|
+
/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/u,
|
|
45
|
+
];
|
|
46
|
+
const ACCOUNT_SCOPE = /^account:[a-z0-9][a-z0-9._-]{0,63}$/u;
|
|
47
|
+
function textoOpaco(valor) {
|
|
48
|
+
return typeof valor === "string" && valor.length > 0 && valor === valor.trim() && !/[\s\u0000-\u001f\u007f]/u.test(valor);
|
|
49
|
+
}
|
|
50
|
+
function textosUnicosNaoVazios(valores) {
|
|
51
|
+
return valores.every(textoOpaco) && new Set(valores).size === valores.length;
|
|
52
|
+
}
|
|
53
|
+
function clonarJson(valor) {
|
|
54
|
+
if (Array.isArray(valor)) {
|
|
55
|
+
return valor.map((item) => clonarJson(item));
|
|
56
|
+
}
|
|
57
|
+
if (valor !== null && typeof valor === "object") {
|
|
58
|
+
return Object.fromEntries(Object.entries(valor).map(([chave, item]) => [chave, clonarJson(item)]));
|
|
59
|
+
}
|
|
60
|
+
return valor;
|
|
61
|
+
}
|
|
62
|
+
function chaveMetadataNormalizada(chave) {
|
|
63
|
+
return chave.replace(/([a-z0-9])([A-Z])/gu, "$1_$2").toLowerCase().replace(/[^a-z0-9]/gu, "");
|
|
64
|
+
}
|
|
65
|
+
function chaveMetadataSensivel(chave) {
|
|
66
|
+
const normalizada = chaveMetadataNormalizada(chave);
|
|
67
|
+
if (CHAVES_METADATA_SENSIVEIS.has(normalizada))
|
|
68
|
+
return true;
|
|
69
|
+
if (/(?:token|secret|password|passwd|credential|authorization|bearer|cookie|privatekey)/u.test(normalizada)) {
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
return /(?:api|access|aws|client|private|signing|encryption).*key/u.test(normalizada);
|
|
73
|
+
}
|
|
74
|
+
function valorPareceSegredo(valor) {
|
|
75
|
+
return PADROES_VALOR_SENSIVEL.some((padrao) => padrao.test(valor));
|
|
76
|
+
}
|
|
77
|
+
export function validarReferenciaAccountScopeConteudo(valor) {
|
|
78
|
+
if (typeof valor !== "string" || !ACCOUNT_SCOPE.test(valor))
|
|
79
|
+
return ["account_scope_referencia_invalida"];
|
|
80
|
+
if (valorPareceSegredo(valor))
|
|
81
|
+
return ["account_scope_contem_possivel_credencial"];
|
|
82
|
+
return [];
|
|
83
|
+
}
|
|
84
|
+
/** Metadata de target e publica no plano/ledger/projecao; segredos sao sempre externos. */
|
|
85
|
+
export function validarMetadataPublicaConteudo(valor) {
|
|
86
|
+
const bloqueios = [];
|
|
87
|
+
const visitar = (atual) => {
|
|
88
|
+
if (typeof atual === "string" && valorPareceSegredo(atual)) {
|
|
89
|
+
bloqueios.push("valor_sensivel_em_metadata");
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (Array.isArray(atual)) {
|
|
93
|
+
atual.forEach((item) => visitar(item));
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (atual === null || typeof atual !== "object")
|
|
97
|
+
return;
|
|
98
|
+
for (const [chave, item] of Object.entries(atual)) {
|
|
99
|
+
if (chaveMetadataSensivel(chave) || valorPareceSegredo(chave)) {
|
|
100
|
+
bloqueios.push("chave_sensivel_em_metadata");
|
|
101
|
+
}
|
|
102
|
+
visitar(item);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
visitar(valor);
|
|
106
|
+
return [...new Set(bloqueios)];
|
|
107
|
+
}
|
|
108
|
+
function chaveIsolamento(alvo) {
|
|
109
|
+
return `target:${encodeURIComponent(alvo.targetId)}:account:${encodeURIComponent(alvo.accountScope)}`;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Escopo exato e injetivo para autorização target-bound. Alterar execução,
|
|
113
|
+
* target ou conta sempre altera o escopo.
|
|
114
|
+
*/
|
|
115
|
+
export function escopoAutorizacaoAlvo(runId, alvo) {
|
|
116
|
+
if (!textoOpaco(runId) ||
|
|
117
|
+
!textoOpaco(alvo.targetId) ||
|
|
118
|
+
validarReferenciaAccountScopeConteudo(alvo.accountScope).length > 0) {
|
|
119
|
+
throw new TypeError("escopo_autorizacao_alvo_invalido");
|
|
120
|
+
}
|
|
121
|
+
return `run:${encodeURIComponent(runId)}:target:${encodeURIComponent(alvo.targetId)}:account:${encodeURIComponent(alvo.accountScope)}`;
|
|
122
|
+
}
|
|
123
|
+
export function escopoAutorizacaoGlobal(runId) {
|
|
124
|
+
if (!textoOpaco(runId))
|
|
125
|
+
throw new TypeError("escopo_autorizacao_global_invalido");
|
|
126
|
+
return `run:${encodeURIComponent(runId)}:global`;
|
|
127
|
+
}
|
|
128
|
+
function numeroFinitoNaoNegativo(valor) {
|
|
129
|
+
return typeof valor === "number" && Number.isFinite(valor) && valor >= 0;
|
|
130
|
+
}
|
|
131
|
+
function chavesLimiteConstraint(constraint) {
|
|
132
|
+
return constraint.kind.endsWith(".min")
|
|
133
|
+
? ["value", "limit", "min", "minimum"]
|
|
134
|
+
: ["value", "limit", "max", "maximum"];
|
|
135
|
+
}
|
|
136
|
+
function validarConfigConstraint(constraint) {
|
|
137
|
+
const config = constraint.config;
|
|
138
|
+
if (config === undefined
|
|
139
|
+
|| config === null
|
|
140
|
+
|| typeof config !== "object"
|
|
141
|
+
|| Array.isArray(config)
|
|
142
|
+
|| ![Object.prototype, null].includes(Object.getPrototypeOf(config))) {
|
|
143
|
+
return ["adapter_constraint_config_invalida"];
|
|
144
|
+
}
|
|
145
|
+
if (validarMetadataPublicaConteudo(config).length > 0) {
|
|
146
|
+
return ["adapter_constraint_config_sensivel"];
|
|
147
|
+
}
|
|
148
|
+
const chaves = Object.keys(config);
|
|
149
|
+
const permitidas = new Set(chavesLimiteConstraint(constraint));
|
|
150
|
+
if (chaves.length !== 1 || !permitidas.has(chaves[0])) {
|
|
151
|
+
return ["adapter_constraint_config_campos_invalidos"];
|
|
152
|
+
}
|
|
153
|
+
return numeroFinitoNaoNegativo(config[chaves[0]])
|
|
154
|
+
? []
|
|
155
|
+
: ["adapter_constraint_limite_invalido"];
|
|
156
|
+
}
|
|
157
|
+
function limiteConstraint(constraint) {
|
|
158
|
+
const config = constraint.config;
|
|
159
|
+
if (!config)
|
|
160
|
+
return undefined;
|
|
161
|
+
for (const chave of chavesLimiteConstraint(constraint)) {
|
|
162
|
+
if (numeroFinitoNaoNegativo(config[chave]))
|
|
163
|
+
return config[chave];
|
|
164
|
+
}
|
|
165
|
+
return undefined;
|
|
166
|
+
}
|
|
167
|
+
function valorEmCaminho(fonte, caminho) {
|
|
168
|
+
let atual = fonte;
|
|
169
|
+
for (const segmento of caminho) {
|
|
170
|
+
if (atual === null || typeof atual !== "object" || Array.isArray(atual))
|
|
171
|
+
return undefined;
|
|
172
|
+
atual = atual[segmento];
|
|
173
|
+
}
|
|
174
|
+
return atual;
|
|
175
|
+
}
|
|
176
|
+
function primeiraMedicaoValida(fontes, caminhos) {
|
|
177
|
+
for (const fonte of fontes) {
|
|
178
|
+
for (const caminho of caminhos) {
|
|
179
|
+
const valor = valorEmCaminho(fonte, caminho);
|
|
180
|
+
if (numeroFinitoNaoNegativo(valor))
|
|
181
|
+
return valor;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return undefined;
|
|
185
|
+
}
|
|
186
|
+
function medicaoConstraint(kind, artefato, observacoes) {
|
|
187
|
+
// Metadado do artefato e declaracao do produtor. Somente observacao
|
|
188
|
+
// independente pode satisfazer uma constraint canonica.
|
|
189
|
+
const fontes = [observacoes];
|
|
190
|
+
if (kind.startsWith("artifact.bytes.")) {
|
|
191
|
+
return primeiraMedicaoValida(fontes, [["artifactBytes"], ["artifact.bytes"], ["artifact", "bytes"], ["bytes"]]);
|
|
192
|
+
}
|
|
193
|
+
if (kind.startsWith("media.duration.")) {
|
|
194
|
+
return primeiraMedicaoValida(fontes, [["mediaDuration"], ["mediaDurationSeconds"], ["media.duration"], ["media", "duration"], ["duration"]]);
|
|
195
|
+
}
|
|
196
|
+
return primeiraMedicaoValida(fontes, [["textLength"], ["text.length"], ["text", "length"]]);
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Avalia somente medições fornecidas. Não lê arquivos, não chama ferramentas e
|
|
200
|
+
* nunca trata um kind desconhecido como aprovação implícita.
|
|
201
|
+
*/
|
|
202
|
+
export function avaliarConstraintsDeterministicasConteudo(artefato, constraints, observacoes = {}) {
|
|
203
|
+
const constraintsDigest = digestJsonCanonico(constraints);
|
|
204
|
+
const resultados = [];
|
|
205
|
+
const bloqueios = [];
|
|
206
|
+
for (const constraint of constraints) {
|
|
207
|
+
const bloqueiosConstraint = [];
|
|
208
|
+
if (!CONSTRAINTS_SUPORTADAS.has(constraint.kind)) {
|
|
209
|
+
bloqueiosConstraint.push(`constraint_kind_nao_suportado:${constraint.constraintId}:${constraint.kind}`);
|
|
210
|
+
resultados.push({
|
|
211
|
+
constraintId: constraint.constraintId,
|
|
212
|
+
kind: constraint.kind,
|
|
213
|
+
observed: null,
|
|
214
|
+
limit: null,
|
|
215
|
+
passed: false,
|
|
216
|
+
bloqueios: bloqueiosConstraint,
|
|
217
|
+
});
|
|
218
|
+
bloqueios.push(...bloqueiosConstraint);
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
const kind = constraint.kind;
|
|
222
|
+
const limit = limiteConstraint(constraint);
|
|
223
|
+
const observed = medicaoConstraint(kind, artefato, observacoes);
|
|
224
|
+
if (limit === undefined)
|
|
225
|
+
bloqueiosConstraint.push(`constraint_limite_invalido:${constraint.constraintId}`);
|
|
226
|
+
if (observed === undefined)
|
|
227
|
+
bloqueiosConstraint.push(`constraint_observacao_ausente:${constraint.constraintId}`);
|
|
228
|
+
const passed = bloqueiosConstraint.length === 0
|
|
229
|
+
&& (kind.endsWith(".min") ? observed >= limit : observed <= limit);
|
|
230
|
+
if (!passed && bloqueiosConstraint.length === 0) {
|
|
231
|
+
bloqueiosConstraint.push(`constraint_nao_satisfeita:${constraint.constraintId}`);
|
|
232
|
+
}
|
|
233
|
+
resultados.push({
|
|
234
|
+
constraintId: constraint.constraintId,
|
|
235
|
+
kind,
|
|
236
|
+
observed: observed ?? null,
|
|
237
|
+
limit: limit ?? null,
|
|
238
|
+
passed,
|
|
239
|
+
bloqueios: bloqueiosConstraint,
|
|
240
|
+
});
|
|
241
|
+
bloqueios.push(...bloqueiosConstraint);
|
|
242
|
+
}
|
|
243
|
+
const resultsDigest = digestJsonCanonico({
|
|
244
|
+
schemaVersion: "1.0",
|
|
245
|
+
artifactId: artefato.artifactId,
|
|
246
|
+
artifactDigest: artefato.digest,
|
|
247
|
+
runId: artefato.runId,
|
|
248
|
+
targetId: artefato.targetId ?? null,
|
|
249
|
+
constraintsDigest,
|
|
250
|
+
observedMediaType: observacoes.observedMediaType ?? null,
|
|
251
|
+
resultados,
|
|
252
|
+
});
|
|
253
|
+
return {
|
|
254
|
+
valido: bloqueios.length === 0 && resultados.every((resultado) => resultado.passed),
|
|
255
|
+
artifactDigest: artefato.digest,
|
|
256
|
+
constraintsDigest,
|
|
257
|
+
resultsDigest,
|
|
258
|
+
resultados,
|
|
259
|
+
bloqueios,
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
/** Valida somente propriedades declarativas; nenhuma capability é executada. */
|
|
263
|
+
export function validarAdaptadorConteudo(adapter) {
|
|
264
|
+
const bloqueios = [];
|
|
265
|
+
if (!textoOpaco(adapter.adapterId)) {
|
|
266
|
+
bloqueios.push("adapter_id_invalido");
|
|
267
|
+
}
|
|
268
|
+
if (!textoOpaco(adapter.version) || VERSOES_FLUTUANTES.has(adapter.version.toLowerCase())) {
|
|
269
|
+
bloqueios.push("adapter_version_nao_fixada");
|
|
270
|
+
}
|
|
271
|
+
if (!Array.isArray(adapter.capabilities) || adapter.capabilities.length === 0 || !textosUnicosNaoVazios(adapter.capabilities)) {
|
|
272
|
+
bloqueios.push("adapter_capabilities_invalidas");
|
|
273
|
+
}
|
|
274
|
+
if (!Array.isArray(adapter.acceptedMediaTypes)
|
|
275
|
+
|| adapter.acceptedMediaTypes.length === 0
|
|
276
|
+
|| !textosUnicosNaoVazios(adapter.acceptedMediaTypes)) {
|
|
277
|
+
bloqueios.push("adapter_media_types_invalidos");
|
|
278
|
+
}
|
|
279
|
+
if (!Array.isArray(adapter.formatProfiles) || adapter.formatProfiles.length === 0 || !textosUnicosNaoVazios(adapter.formatProfiles)) {
|
|
280
|
+
bloqueios.push("adapter_format_profiles_invalidos");
|
|
281
|
+
}
|
|
282
|
+
if (!Array.isArray(adapter.deterministicConstraints) || adapter.deterministicConstraints.length === 0) {
|
|
283
|
+
bloqueios.push("adapter_constraints_deterministicas_ausentes");
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
const ids = new Set();
|
|
287
|
+
for (const constraint of adapter.deterministicConstraints) {
|
|
288
|
+
if (!textoOpaco(constraint.constraintId) || !textoOpaco(constraint.kind)) {
|
|
289
|
+
bloqueios.push("adapter_constraint_invalida");
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
if (valorPareceSegredo(constraint.constraintId) || valorPareceSegredo(constraint.kind)) {
|
|
293
|
+
bloqueios.push("adapter_constraint_identificador_sensivel");
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
if (ids.has(constraint.constraintId)) {
|
|
297
|
+
bloqueios.push(`adapter_constraint_id_duplicado:${constraint.constraintId}`);
|
|
298
|
+
}
|
|
299
|
+
ids.add(constraint.constraintId);
|
|
300
|
+
if (!CONSTRAINTS_SUPORTADAS.has(constraint.kind)) {
|
|
301
|
+
bloqueios.push(`adapter_constraint_kind_nao_suportado:${constraint.constraintId}:${constraint.kind}`);
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
bloqueios.push(...validarConfigConstraint(constraint));
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
if (!Array.isArray(adapter.requiredMetadata) || !textosUnicosNaoVazios(adapter.requiredMetadata)) {
|
|
309
|
+
bloqueios.push("adapter_required_metadata_invalido");
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
for (const campo of adapter.requiredMetadata) {
|
|
313
|
+
if (chaveMetadataSensivel(campo) || valorPareceSegredo(campo)) {
|
|
314
|
+
bloqueios.push("adapter_required_metadata_sensivel");
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
if (!Array.isArray(adapter.optionalMetadata) || !textosUnicosNaoVazios(adapter.optionalMetadata)) {
|
|
319
|
+
bloqueios.push("adapter_optional_metadata_invalido");
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
for (const campo of adapter.optionalMetadata) {
|
|
323
|
+
if (chaveMetadataSensivel(campo) || valorPareceSegredo(campo)) {
|
|
324
|
+
bloqueios.push("adapter_optional_metadata_sensivel");
|
|
325
|
+
}
|
|
326
|
+
if (adapter.requiredMetadata.includes(campo))
|
|
327
|
+
bloqueios.push("adapter_metadata_required_optional_sobreposta");
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
if (!Array.isArray(adapter.confirmationPredicates)
|
|
331
|
+
|| adapter.confirmationPredicates.length === 0
|
|
332
|
+
|| !textosUnicosNaoVazios(adapter.confirmationPredicates)) {
|
|
333
|
+
bloqueios.push("adapter_confirmation_predicates_invalidos");
|
|
334
|
+
}
|
|
335
|
+
else if (adapter.confirmationPredicates.some((item) => DECLARACOES_NAO_CONFIAVEIS.has(item.toLowerCase()))) {
|
|
336
|
+
bloqueios.push("adapter_confirmacao_baseada_em_declaracao_do_executor");
|
|
337
|
+
}
|
|
338
|
+
return { valido: bloqueios.length === 0, bloqueios };
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Materializa um plano isolado por targetId/accountScope. Os planos carregam
|
|
342
|
+
* instruções e referências; credenciais e chamadas de ferramenta ficam no
|
|
343
|
+
* runner externo.
|
|
344
|
+
*/
|
|
345
|
+
export function planejarAlvosConteudo(alvos, adapters, artefatosMestre) {
|
|
346
|
+
const planosAdaptacao = [];
|
|
347
|
+
const bloqueiosPorAlvo = [];
|
|
348
|
+
const adicionarBloqueio = (targetId, codigo) => {
|
|
349
|
+
bloqueiosPorAlvo.push({ targetId, codigo });
|
|
350
|
+
};
|
|
351
|
+
if (alvos.length === 0) {
|
|
352
|
+
adicionarBloqueio("*", "alvos_ausentes");
|
|
353
|
+
return { planosAdaptacao, bloqueiosPorAlvo };
|
|
354
|
+
}
|
|
355
|
+
const contagemTargets = new Map();
|
|
356
|
+
for (const alvo of alvos) {
|
|
357
|
+
contagemTargets.set(alvo.targetId, (contagemTargets.get(alvo.targetId) ?? 0) + 1);
|
|
358
|
+
}
|
|
359
|
+
const adaptersPorId = new Map();
|
|
360
|
+
for (const adapter of adapters) {
|
|
361
|
+
const encontrados = adaptersPorId.get(adapter.adapterId) ?? [];
|
|
362
|
+
encontrados.push(adapter);
|
|
363
|
+
adaptersPorId.set(adapter.adapterId, encontrados);
|
|
364
|
+
}
|
|
365
|
+
for (const alvo of alvos) {
|
|
366
|
+
const targetId = textoOpaco(alvo.targetId) ? alvo.targetId : "<target-invalido>";
|
|
367
|
+
const bloqueiosAntes = bloqueiosPorAlvo.length;
|
|
368
|
+
if (!textoOpaco(alvo.targetId)) {
|
|
369
|
+
adicionarBloqueio(targetId, "target_id_invalido");
|
|
370
|
+
}
|
|
371
|
+
else if ((contagemTargets.get(alvo.targetId) ?? 0) > 1) {
|
|
372
|
+
adicionarBloqueio(targetId, "target_id_duplicado");
|
|
373
|
+
}
|
|
374
|
+
for (const bloqueio of validarReferenciaAccountScopeConteudo(alvo.accountScope)) {
|
|
375
|
+
adicionarBloqueio(targetId, bloqueio);
|
|
376
|
+
}
|
|
377
|
+
if (!textoOpaco(alvo.formatProfileId)) {
|
|
378
|
+
adicionarBloqueio(targetId, "format_profile_id_invalido");
|
|
379
|
+
}
|
|
380
|
+
if (!textoOpaco(alvo.locale)) {
|
|
381
|
+
adicionarBloqueio(targetId, "locale_invalido");
|
|
382
|
+
}
|
|
383
|
+
if (alvo.metadata === null || typeof alvo.metadata !== "object" || Array.isArray(alvo.metadata)) {
|
|
384
|
+
adicionarBloqueio(targetId, "metadata_invalido");
|
|
385
|
+
}
|
|
386
|
+
else {
|
|
387
|
+
for (const valor of Object.values(alvo.metadata)) {
|
|
388
|
+
if (valor !== null && !["string", "number", "boolean"].includes(typeof valor)) {
|
|
389
|
+
adicionarBloqueio(targetId, "metadata_valor_nao_escalar");
|
|
390
|
+
}
|
|
391
|
+
else if (typeof valor === "number" && !Number.isFinite(valor)) {
|
|
392
|
+
adicionarBloqueio(targetId, "metadata_numero_nao_finito");
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
for (const bloqueio of validarMetadataPublicaConteudo(alvo.metadata)) {
|
|
396
|
+
adicionarBloqueio(targetId, bloqueio);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
const candidatos = adaptersPorId.get(alvo.adapterId) ?? [];
|
|
400
|
+
if (candidatos.length === 0) {
|
|
401
|
+
adicionarBloqueio(targetId, "adapter_nao_encontrado");
|
|
402
|
+
}
|
|
403
|
+
else if (candidatos.length > 1) {
|
|
404
|
+
adicionarBloqueio(targetId, "adapter_id_ambiguo_na_definicao");
|
|
405
|
+
}
|
|
406
|
+
const adapter = candidatos.length === 1 ? candidatos[0] : undefined;
|
|
407
|
+
if (adapter) {
|
|
408
|
+
const resultadoAdapter = validarAdaptadorConteudo(adapter);
|
|
409
|
+
for (const bloqueio of resultadoAdapter.bloqueios) {
|
|
410
|
+
adicionarBloqueio(targetId, `adapter_invalido:${bloqueio}`);
|
|
411
|
+
}
|
|
412
|
+
if (!adapter.formatProfiles.includes(alvo.formatProfileId)) {
|
|
413
|
+
adicionarBloqueio(targetId, "format_profile_nao_declarado_no_adapter");
|
|
414
|
+
}
|
|
415
|
+
for (const campo of adapter.requiredMetadata) {
|
|
416
|
+
if (!Object.prototype.hasOwnProperty.call(alvo.metadata, campo)) {
|
|
417
|
+
adicionarBloqueio(targetId, "metadata_obrigatorio_ausente");
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
const permitidos = new Set([...adapter.requiredMetadata, ...adapter.optionalMetadata]);
|
|
421
|
+
for (const campo of Object.keys(alvo.metadata)) {
|
|
422
|
+
if (!permitidos.has(campo))
|
|
423
|
+
adicionarBloqueio(targetId, "metadata_nao_declarado_no_adapter");
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
if (bloqueiosPorAlvo.length !== bloqueiosAntes || !adapter) {
|
|
427
|
+
continue;
|
|
428
|
+
}
|
|
429
|
+
planosAdaptacao.push({
|
|
430
|
+
targetId: alvo.targetId,
|
|
431
|
+
adapterId: adapter.adapterId,
|
|
432
|
+
adapterVersion: adapter.version,
|
|
433
|
+
accountScope: alvo.accountScope,
|
|
434
|
+
isolationKey: chaveIsolamento(alvo),
|
|
435
|
+
formatProfileId: alvo.formatProfileId,
|
|
436
|
+
locale: alvo.locale,
|
|
437
|
+
capabilities: [...adapter.capabilities],
|
|
438
|
+
acceptedMediaTypes: [...adapter.acceptedMediaTypes],
|
|
439
|
+
deterministicConstraints: clonarJson(adapter.deterministicConstraints),
|
|
440
|
+
requiredMetadata: [...adapter.requiredMetadata],
|
|
441
|
+
optionalMetadata: [...adapter.optionalMetadata],
|
|
442
|
+
confirmationPredicates: [...adapter.confirmationPredicates],
|
|
443
|
+
metadata: clonarJson(alvo.metadata),
|
|
444
|
+
masterArtifacts: [...artefatosMestre],
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
return { planosAdaptacao, bloqueiosPorAlvo };
|
|
448
|
+
}
|
|
449
|
+
//# sourceMappingURL=adapters.js.map
|