astro_advokat/scripts/dev.js

175 lines
No EOL
4.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bun
import { $ } from "bun";
import { spawn } from "child_process";
import path from "path";
import { promisify } from "util";
import net from "net";
import chalk from "chalk";
const sleep = promisify(setTimeout);
async function isPortInUse(port) {
return new Promise((resolve) => {
const server = net.createServer();
server.once("error", () => resolve(true));
server.once("listening", () => {
server.close();
resolve(false);
});
server.listen(port);
});
}
async function killProcess(pid, force = true) {
try {
if (process.platform === "win32") {
await $`taskkill /PID ${pid} ${force ? "/F" : ""}`.quiet();
} else {
process.kill(pid, force ? "SIGKILL" : "SIGTERM");
}
} catch (e) {
}
}
async function killPort(port) {
try {
if (process.platform === "win32") {
const { stdout } = await $`netstat -ano | findstr :${port}`.quiet().nothrow();
const lines = stdout.toString().trim().split("\n");
const pids = new Set();
for (const line of lines) {
const parts = line.trim().split(/\s+/);
if (parts.length >= 5) {
const pid = parts[4];
if (pid && !isNaN(parseInt(pid))) {
pids.add(parseInt(pid));
}
}
}
for (const pid of pids) {
await killProcess(pid);
console.log(chalk.yellow(` 🔪 Убит процесс ${pid} на порту ${port}`));
}
} else {
await $`lsof -ti:${port} | xargs kill -9`.quiet().nothrow();
}
} catch (e) {
}
}
async function cleanupPorts() {
console.log(chalk.cyan("🔍 Проверка портов..."));
const ports = [1025, 1080, 4321, 8090];
for (const port of ports) {
if (await isPortInUse(port)) {
console.log(chalk.yellow(` ⚠️ Порт ${port} занят, освобождаем...`));
await killPort(port);
await sleep(500);
}
}
}
let maildev, backend, frontend;
async function cleanup() {
console.log(chalk.red("\n🛑 Остановка серверов..."));
const kills = [];
if (maildev && !maildev.killed) {
maildev.kill("SIGKILL");
kills.push(new Promise(r => maildev.once("exit", r)));
}
if (backend && !backend.killed) {
backend.kill("SIGKILL");
kills.push(new Promise(r => backend.once("exit", r)));
}
if (frontend && !frontend.killed) {
frontend.kill("SIGKILL");
kills.push(new Promise(r => frontend.once("exit", r)));
}
await Promise.race([
Promise.all(kills),
sleep(3000)
]);
process.exit(0);
}
async function main() {
await cleanupPorts();
console.log(chalk.green.bold("🚀 Запуск серверов astro-advokat...\n"));
maildev = spawn("maildev", ["--web", "1080", "--smtp", "1025"], {
stdio: "inherit",
shell: true,
windowsHide: true,
detached: false
});
backend = spawn("pocketbase.exe", ["serve"], {
cwd: path.join(process.cwd(), "backend"),
stdio: "inherit",
shell: true,
windowsHide: true,
detached: false,
env: {
...process.env,
PB_SMTP_HOST: "localhost",
PB_SMTP_PORT: "1025",
PB_SMTP_FROM: "noreply@advokat-surgut.ru"
}
});
frontend = spawn("bun", ["dev"], {
cwd: "frontend",
stdio: "inherit",
shell: true,
windowsHide: true,
detached: false
});
process.on("SIGINT", cleanup);
process.on("SIGTERM", cleanup);
process.on("SIGBREAK", cleanup);
if (process.platform === "win32") {
const readline = await import("readline");
readline.createInterface({
input: process.stdin,
output: process.stdout
}).on("SIGINT", cleanup);
}
maildev.on("exit", (code) => {
console.log(chalk.gray(`\n📧 Maildev остановлен с кодом ${code}`));
if (code !== 0 && code !== null) cleanup();
});
backend.on("exit", (code) => {
console.log(chalk.gray(`\n💾 Backend остановлен с кодом ${code}`));
if (code !== 0 && code !== null) cleanup();
});
frontend.on("exit", (code) => {
console.log(chalk.gray(`\n🌐 Frontend остановлен с кодом ${code}`));
cleanup();
});
console.log(chalk.green("✅ Серверы запущены:\n"));
console.log(chalk.blue(" 📧 Maildev (SMTP): ") + chalk.underline("http://localhost:1080"));
console.log(chalk.blue(" 💾 Backend (PocketBase): ") + chalk.underline("http://localhost:8090"));
console.log(chalk.blue(" 🌐 Frontend (Astro): ") + chalk.underline("http://localhost:4321") + "\n");
console.log(chalk.gray("Нажмите Ctrl+C для остановки\n"));
}
main().catch(err => {
console.error(chalk.red("❌ Ошибка:"), err);
process.exit(1);
});