UNPKG

@mesh-tech/mesh-cli

Version:

CLI for Mesh platform development utilities

63 lines (62 loc) 2.46 kB
import * as fs from 'fs'; import * as net from 'net'; import * as path from 'path'; export const ENV_FILE_MODE = 0o600; const ENV_KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/; export function quoteShellValue(value) { return `'${value.replace(/'/g, "'\\''")}'`; } export function renderEnvFile(env) { const lines = [ '# Auto-generated by mesh dev — do not edit.', '# Sourced by service launch/restart commands; this file IS the', "# session's env contract for the service (restart fidelity).", ]; for (const [key, value] of Object.entries(env)) { if (!ENV_KEY_RE.test(key)) { throw new Error(`Invalid env var name for env file: ${JSON.stringify(key)}`); } lines.push(`export ${key}=${quoteShellValue(value)}`); } return lines.join('\n') + '\n'; } export function envFileName(serviceName) { return `${serviceName.replace(/[^A-Za-z0-9._-]/g, '-')}.env.sh`; } export function writeEnvFile(filePath, env) { fs.mkdirSync(path.dirname(filePath), { recursive: true }); fs.writeFileSync(filePath, renderEnvFile(env), { mode: ENV_FILE_MODE }); fs.chmodSync(filePath, ENV_FILE_MODE); } export function buildLaunchCommand(envFilePath, dir, command, logShipper) { const base = `cd ${quoteShellValue(dir)} && source ${quoteShellValue(envFilePath)} && `; if (!logShipper) return `${base}${command}`; return `${base}{ ${command}; } 2>&1 | NODE_OPTIONS= node ${quoteShellValue(logShipper)}`; } export async function waitForPort(host, port, timeoutMs, intervalMs = 500) { const deadline = Date.now() + timeoutMs; for (;;) { const remaining = deadline - Date.now(); const attemptTimeout = Math.max(250, Math.min(1000, remaining)); if (await tryConnect(host, port, attemptTimeout)) return true; if (Date.now() + intervalMs >= deadline) return false; await new Promise((resolve) => setTimeout(resolve, intervalMs)); } } function tryConnect(host, port, timeoutMs) { return new Promise((resolve) => { const socket = net.connect({ host, port }); const done = (ok) => { socket.removeAllListeners(); socket.destroy(); resolve(ok); }; socket.setTimeout(timeoutMs); socket.once('connect', () => done(true)); socket.once('timeout', () => done(false)); socket.once('error', () => done(false)); }); }