2026-06-10 15:01:09 -05:00
|
|
|
import 'dotenv/config';
|
|
|
|
|
|
|
|
|
|
import { execFile } from 'node:child_process';
|
|
|
|
|
import { promisify } from 'node:util';
|
|
|
|
|
|
|
|
|
|
const execFileAsync = promisify(execFile);
|
|
|
|
|
const ports = [
|
|
|
|
|
process.env.WEB_DEV_PORT ?? '5173',
|
2026-06-25 09:46:09 -05:00
|
|
|
process.env.TOOLKIT_SOCKET_PORT ?? '5175',
|
2026-06-10 15:01:09 -05:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
async function getPortProcessIds(port) {
|
|
|
|
|
try {
|
|
|
|
|
const { stdout } = await execFileAsync('lsof', ['-ti', `tcp:${port}`]);
|
|
|
|
|
|
|
|
|
|
return stdout
|
|
|
|
|
.split('\n')
|
|
|
|
|
.map(processId => processId.trim())
|
|
|
|
|
.filter(Boolean);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
if (error != null && typeof error === 'object' && 'code' in error) {
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function killProcess(processId, port) {
|
|
|
|
|
try {
|
|
|
|
|
await execFileAsync('kill', ['-TERM', processId]);
|
|
|
|
|
console.log(`[dev:clear] stopped process ${processId} on port ${port}`);
|
|
|
|
|
} catch {
|
|
|
|
|
console.log(`[dev:clear] process ${processId} on port ${port} already stopped`);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (const port of ports) {
|
|
|
|
|
const processIds = await getPortProcessIds(port);
|
|
|
|
|
|
|
|
|
|
if (processIds.length === 0) {
|
|
|
|
|
console.log(`[dev:clear] no process listening on port ${port}`);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await Promise.all(
|
|
|
|
|
processIds.map(processId => killProcess(processId, port)),
|
|
|
|
|
);
|
|
|
|
|
}
|