import {spawn} from 'node:child_process'; import {existsSync, readFileSync} from 'node:fs'; import {resolve} from 'node:path'; const repoRoot = process.cwd(); function loadEnvFile(path, target) { if (!existsSync(path)) { return; } const rawText = readFileSync(path, 'utf8'); for (const rawLine of rawText.split(/\r?\n/u)) { const line = rawLine.trim(); if (!line || line.startsWith('#')) { continue; } const match = line.match(/^([A-Za-z_][A-Za-z0-9_]*)=(.*)$/u); if (!match) { continue; } const [, key, rawValue] = match; if (target[key] !== undefined) { continue; } target[key] = rawValue.replace(/^['"]|['"]$/gu, ''); } } const mergedEnv = {...process.env}; loadEnvFile(resolve(repoRoot, '.env'), mergedEnv); loadEnvFile(resolve(repoRoot, '.env.local'), mergedEnv); mergedEnv.GENARRATIVE_API_HOST = mergedEnv.GENARRATIVE_API_HOST || '127.0.0.1'; mergedEnv.GENARRATIVE_API_PORT = mergedEnv.GENARRATIVE_API_PORT || '3100'; mergedEnv.GENARRATIVE_SPACETIME_SERVER_URL = mergedEnv.GENARRATIVE_SPACETIME_MAINCLOUD_SERVER_URL || mergedEnv.GENARRATIVE_SPACETIME_SERVER_URL || 'https://maincloud.spacetimedb.com'; mergedEnv.GENARRATIVE_SPACETIME_DATABASE = mergedEnv.GENARRATIVE_SPACETIME_MAINCLOUD_DATABASE || mergedEnv.GENARRATIVE_SPACETIME_DATABASE || ''; mergedEnv.GENARRATIVE_SPACETIME_TOKEN = mergedEnv.GENARRATIVE_SPACETIME_MAINCLOUD_TOKEN || mergedEnv.GENARRATIVE_SPACETIME_TOKEN || ''; if (!mergedEnv.GENARRATIVE_SPACETIME_DATABASE) { console.error( '[api-server:maincloud] 缺少 GENARRATIVE_SPACETIME_MAINCLOUD_DATABASE 或 GENARRATIVE_SPACETIME_DATABASE。', ); process.exit(1); } console.log( `[api-server:maincloud] SpacetimeDB ${mergedEnv.GENARRATIVE_SPACETIME_DATABASE} @ ${mergedEnv.GENARRATIVE_SPACETIME_SERVER_URL}`, ); const child = spawn( 'cargo', ['run', '-p', 'api-server', '--manifest-path', 'server-rs/Cargo.toml'], { cwd: repoRoot, env: mergedEnv, stdio: 'inherit', shell: process.platform === 'win32', }, ); child.on('error', (error) => { console.error(`[api-server:maincloud] 启动 cargo 失败: ${error.message}`); process.exit(1); }); child.on('exit', (code, signal) => { if (signal) { console.error(`[api-server:maincloud] api-server 被信号终止: ${signal}`); process.exit(1); } process.exit(code ?? 0); });