#!/usr/bin/env node // Boots postgres + redis, waits for healthy, then runs drizzle push and exits. // Used by `pnpm dev` before turbo takes over. import { spawnSync, spawn } from 'node:child_process'; import fs from 'node:fs'; import path from 'node:path'; // Load .env at repo root so children inherit it. const envPath = path.resolve(process.cwd(), '.env'); if (fs.existsSync(envPath)) { for (const line of fs.readFileSync(envPath, 'utf8').split(/\r?\n/)) { const m = line.match(/^\s*([A-Z][A-Z0-9_]*)\s*=\s*(.*)\s*$/); if (!m) continue; let value = m[2]; if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) { value = value.slice(1, -1); } if (!(m[1] in process.env)) process.env[m[1]] = value; } console.log('[bootstrap] loaded .env'); } else { console.warn('[bootstrap] no .env at repo root — copy .env.example to .env'); } function run(cmd, args, opts = {}) { return spawnSync(cmd, args, { stdio: 'inherit', shell: process.platform === 'win32', ...opts }); } console.log('[bootstrap] starting docker compose services...'); const up = run('docker', ['compose', 'up', '-d', '--wait', 'postgres', 'redis']); if (up.status !== 0) { console.error('[bootstrap] docker compose failed. Is Docker Desktop running?'); process.exit(up.status ?? 1); } console.log('[bootstrap] pushing schema via drizzle-kit...'); const push = run('pnpm', ['--filter', '@bmm/db', 'exec', 'drizzle-kit', 'push', '--force']); if (push.status !== 0) { console.warn('[bootstrap] drizzle-kit push --force failed; falling back to interactive push'); const push2 = run('pnpm', ['--filter', '@bmm/db', 'exec', 'drizzle-kit', 'push']); if (push2.status !== 0) { console.error('[bootstrap] schema push failed.'); process.exit(push2.status ?? 1); } } console.log('[bootstrap] done. starting turbo dev...'); const turbo = spawn('pnpm', ['turbo', 'run', 'dev', '--parallel'], { stdio: 'inherit', shell: process.platform === 'win32', }); turbo.on('exit', (code) => process.exit(code ?? 0)); process.on('SIGINT', () => turbo.kill('SIGINT')); process.on('SIGTERM', () => turbo.kill('SIGTERM'));