param( [switch]$Dev, # nodemon — авто-перезапуск при изменении кода [switch]$NoMigrate # не применять миграции на старте ) # LearnSpace — консоль-запускатор сервера. # Запуск: двойной клик по start-server.bat (или: powershell -File tools\launch-server.ps1 [-Dev] [-NoMigrate]) $ErrorActionPreference = 'Continue' try { chcp 65001 > $null } catch {} try { [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new() } catch {} $root = Split-Path -Parent $PSScriptRoot $backend = Join-Path $root 'backend' Set-Location $backend function Get-Port { try { $p = & node -e 'try{process.stdout.write(String(require("./src/config").PORT||3000))}catch(e){process.stdout.write("3000")}' 2>$null if ("$p" -match '^\d+$') { return [int]"$p" } } catch {} return 3000 } $script:Port = Get-Port function Show-Banner($status, $color) { Clear-Host $bar = ' ' + ('=' * 52) if ($Dev) { $mode = 'dev (nodemon — авто-перезапуск при правках)' } else { $mode = 'prod (node)' } Write-Host '' Write-Host $bar -ForegroundColor DarkCyan Write-Host ' LearnSpace — сервер' -ForegroundColor Cyan Write-Host $bar -ForegroundColor DarkCyan Write-Host (' URL: http://localhost:' + $script:Port) -ForegroundColor White Write-Host (' Порт: ' + $script:Port) Write-Host (' Режим: ' + $mode) Write-Host (' Папка: ' + $backend) -ForegroundColor DarkGray Write-Host (' Статус: ' + $status) -ForegroundColor $color Write-Host ' Остановить: Ctrl+C (после — меню перезапуска / выхода)' -ForegroundColor DarkGray Write-Host $bar -ForegroundColor DarkCyan Write-Host '' } function Free-Port { try { $conns = Get-NetTCPConnection -LocalPort $script:Port -State Listen -ErrorAction Stop foreach ($c in $conns) { $procId = $c.OwningProcess Write-Host (' Порт ' + $script:Port + ' занят процессом PID ' + $procId + ' — останавливаю старый экземпляр...') -ForegroundColor Yellow Stop-Process -Id $procId -Force -ErrorAction SilentlyContinue } Start-Sleep -Milliseconds 700 } catch { } # никто не слушает — ок } # ── Миграции БД (идемпотентно: применятся только новые) ── if (-not $NoMigrate) { Show-Banner 'применяю миграции базы данных...' Yellow try { & node src/db/migrations-runner.js } catch { Write-Host (' Миграции: ' + $_.Exception.Message) -ForegroundColor Red } Write-Host '' Write-Host ' Миграции готовы. Запускаю сервер...' -ForegroundColor Green Start-Sleep -Milliseconds 600 } # ── Цикл: запуск → (остановка/падение) → меню ── $running = $true while ($running) { Free-Port Show-Banner 'РАБОТАЕТ — логи ниже (Ctrl+C для остановки)' Green try { $Host.UI.RawUI.WindowTitle = "LearnSpace :$($script:Port) — running" } catch {} if ($Dev) { & npm run dev } else { & node src/server.js } $code = $LASTEXITCODE try { $Host.UI.RawUI.WindowTitle = "LearnSpace :$($script:Port) — STOPPED" } catch {} Write-Host '' Write-Host (' Сервер остановлен (код выхода ' + $code + ').') -ForegroundColor Yellow $ans = Read-Host ' [R] перезапустить / [Q] выход (Enter = перезапустить)' if ($ans -match '^[QqЙй]') { $running = $false } # Q (лат.) или Й (рус. раскладка на той же клавише) } Write-Host ' Запускатор закрыт.' -ForegroundColor Cyan