export function applyNodeRuntimeDeployYamlOverlay(document: Record, overlay: Record): Record { const doc = structuredClone(document); const nodeId = requiredString(overlay.nodeId, "overlay.nodeId"); const laneId = requiredString(overlay.lane, "overlay.lane"); const nodes = record(doc.nodes); const node = record(nodes[nodeId]); nodes[nodeId] = { ...node, gitopsRoot: overlay.gitopsRoot, sourceRepo: overlay.gitUrl }; doc.nodes = nodes; const lanes = record(doc.lanes); const lane = record(lanes[laneId]); const envRecipe = record(lane.envRecipe); const downloadStack = { ...record(envRecipe.downloadStack), httpProxy: overlay.dockerProxyHttp, httpsProxy: overlay.dockerProxyHttps, noProxy: overlay.dockerNoProxyList, }; const nextLane: Record = { ...lane, node: nodeId, sourceBranch: overlay.sourceBranch, gitopsBranch: overlay.gitopsBranch, namespace: overlay.runtimeNamespace, endpoint: overlay.publicApiUrl, publicEndpoints: { frontend: overlay.publicWebUrl, api: overlay.publicApiUrl }, artifactCatalog: overlay.catalogPath, runtimePath: overlay.runtimePath, imageTagMode: "full", sourceRepo: overlay.gitUrl, observability: overlay.observability, envRecipe: { ...envRecipe, downloadStack }, }; if (overlay.externalPostgres === undefined || overlay.externalPostgres === null) delete nextLane.externalPostgres; else nextLane.externalPostgres = overlay.externalPostgres; if (overlay.runtimeStore !== undefined) nextLane.runtimeStore = overlay.runtimeStore; if (overlay.codeAgentRuntime !== undefined) nextLane.codeAgentRuntime = overlay.codeAgentRuntime; if (overlay.deployYamlGitMirror !== undefined) nextLane.gitMirror = overlay.deployYamlGitMirror; lanes[laneId] = nextLane; doc.lanes = lanes; return doc; } export function nodeRuntimeDeployYamlOverlayShellScript(): string[] { return [ "node - \"$overlay_b64\" <<'NODE_UNIDESK_DEPLOY_OVERLAY'", "const fs = require('fs');", "const YAML = require('yaml');", `const applyNodeRuntimeDeployYamlOverlay = ${applyNodeRuntimeDeployYamlOverlay.toString()};`, `const record = ${record.toString()};`, `const requiredString = ${requiredString.toString()};`, "const overlay = JSON.parse(Buffer.from(process.argv[2], 'base64').toString('utf8'));", "const path = 'deploy/deploy.yaml';", "const doc = YAML.parse(fs.readFileSync(path, 'utf8'));", "fs.writeFileSync(path, YAML.stringify(applyNodeRuntimeDeployYamlOverlay(doc, overlay)));", "NODE_UNIDESK_DEPLOY_OVERLAY", ]; } function record(value: unknown): Record { return typeof value === "object" && value !== null && !Array.isArray(value) ? value as Record : {}; } function requiredString(value: unknown, label: string): string { if (typeof value !== "string" || value.length === 0) throw new Error(`${label} must be a non-empty string`); return value; }