#!/usr/bin/env node /** * 检查本地已有依赖是否可连接:PostgreSQL(DATABASE_URL)与 Redis(REDIS_URL)。 * 仓库不再启动任何数据库/缓存容器;依赖由本机 Docker 服务提供。 */ import { createConnection } from 'node:net'; import { loadEnvFile } from 'node:process'; // Node 24 支持 process.loadEnvFile;两个文件都不存在时忽略。 for (const file of ['.env.local', '.env']) { try { loadEnvFile(file); } catch { // 文件不存在时跳过。 } } const targets = [ { name: 'PostgreSQL', value: process.env.DATABASE_URL, fallbackPort: 5432 }, { name: 'Redis', value: process.env.REDIS_URL, fallbackPort: 6379 }, ]; function parseTarget({ name, value, fallbackPort }) { if (!value) { throw new Error(`${name} 未配置连接串`); } const url = new URL(value); return { name, host: url.hostname, port: Number(url.port || fallbackPort), database: url.pathname.replace(/^\//, '') || undefined, }; } function probe({ name, host, port, database }) { return new Promise((resolve, reject) => { const socket = createConnection({ host, port }); const timer = setTimeout(() => { socket.destroy(); reject(new Error(`${name} 连接超时:${host}:${port}`)); }, 3_000); socket.once('connect', () => { clearTimeout(timer); socket.end(); const suffix = database ? `/${database}` : ''; resolve(`${name} 可用:${host}:${port}${suffix}`); }); socket.once('error', (error) => { clearTimeout(timer); reject(new Error(`${name} 不可用:${host}:${port}(${error.message})`)); }); }); } try { for (const target of targets) { const info = await probe(parseTarget(target)); console.log(`✓ ${info}`); } console.log('本地依赖检查通过(PostgreSQL / Redis 使用本机已有 Docker 服务)。'); } catch (error) { console.error(`✗ ${error instanceof Error ? error.message : String(error)}`); console.error('请确认 docker-postgres-1(5432)与 docker-redis-1(6379)已启动。'); process.exit(1); }