const { execSync } = require('child_process'); const fs = require('fs'); const path = require('path'); function loadEnvFile(filePath) { if (!fs.existsSync(filePath)) return {}; return fs .readFileSync(filePath, 'utf8') .split(/\r?\n/) .reduce((acc, line) => { const trimmed = line.trim(); if (!trimmed || trimmed.startsWith('#')) return acc; const separatorIndex = trimmed.indexOf('='); if (separatorIndex === -1) return acc; const key = trimmed.slice(0, separatorIndex).trim(); const value = trimmed.slice(separatorIndex + 1).trim(); acc[key] = value; return acc; }, {}); } function getConfiguredPort() { const env = { ...loadEnvFile(path.resolve(process.cwd(), '.env.development')), ...process.env, }; return Number(env.PORT || env.BACKEND_PORT || 3001); } function getWindowsPids(port) { const output = execSync(`netstat -ano -p tcp | findstr :${port}`, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'], }); return Array.from( new Set( output .split(/\r?\n/) .filter((line) => line.includes('LISTENING')) .map((line) => line.trim().split(/\s+/).at(-1)) .filter(Boolean) .filter((pid) => pid !== String(process.pid)), ), ); } function getUnixPids(port) { const output = execSync(`lsof -ti tcp:${port} -sTCP:LISTEN`, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'], }); return Array.from( new Set( output .split(/\r?\n/) .map((pid) => pid.trim()) .filter(Boolean) .filter((pid) => pid !== String(process.pid)), ), ); } function killPid(pid) { if (process.platform === 'win32') { execSync(`taskkill /PID ${pid} /F /T`, { stdio: 'ignore' }); return; } execSync(`kill -TERM ${pid}`, { stdio: 'ignore' }); } function getWindowsWhatsappSessionPids() { const sessionPath = path.resolve(process.cwd(), 'whatsapp-session'); const escapedSessionPath = sessionPath.replace(/\\/g, '\\\\'); const command = [ 'Get-CimInstance Win32_Process', `Where-Object { $_.Name -eq 'chrome.exe' -and $_.CommandLine -like '*${escapedSessionPath}*' }`, 'Select-Object -ExpandProperty ProcessId', ].join(' | '); const output = execSync(`powershell -NoProfile -Command "${command}"`, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'], }); return Array.from( new Set( output .split(/\r?\n/) .map((pid) => pid.trim()) .filter(Boolean) .filter((pid) => pid !== String(process.pid)), ), ); } function getUnixWhatsappSessionPids() { const sessionPath = path.resolve(process.cwd(), 'whatsapp-session'); const output = execSync(`pgrep -f "${sessionPath}"`, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'], }); return Array.from( new Set( output .split(/\r?\n/) .map((pid) => pid.trim()) .filter(Boolean) .filter((pid) => pid !== String(process.pid)), ), ); } function killWhatsappSessionBrowsers() { try { const pids = process.platform === 'win32' ? getWindowsWhatsappSessionPids() : getUnixWhatsappSessionPids(); if (!pids.length) return; pids.forEach(killPid); console.log(`Sessao WhatsApp liberada. Processo(s) Chrome encerrado(s): ${pids.join(', ')}`); } catch { // Se nao houver processo usando a sessao, seguimos normalmente. } } const port = getConfiguredPort(); killWhatsappSessionBrowsers(); try { const pids = process.platform === 'win32' ? getWindowsPids(port) : getUnixPids(port); if (!pids.length) { process.exit(0); } pids.forEach(killPid); console.log(`Porta ${port} liberada. Processo(s) encerrado(s): ${pids.join(', ')}`); } catch { process.exit(0); }