import { createInterface } from 'node:readline'; import { writeFileSync } from 'node:fs'; import { resolve } from 'node:path'; import type { Command } from 'commander'; import { DEFAULT_LOCAL_CONFIG, DEFAULT_TEAM_CONFIG, type MosaicConfig, type StorageTier, } from '@mosaic/config'; function ask(rl: ReturnType, question: string): Promise { return new Promise((res) => rl.question(question, res)); } async function runInit(opts: { tier?: string; output: string }): Promise { const outputPath = resolve(opts.output); let tier: StorageTier; if (opts.tier) { if (opts.tier !== 'local' && opts.tier !== 'team') { console.error(`Invalid tier "${opts.tier}" — expected "local" or "team"`); process.exit(1); } tier = opts.tier; } else { const rl = createInterface({ input: process.stdin, output: process.stdout }); const answer = await ask(rl, 'Select tier (local/team) [local]: '); rl.close(); const trimmed = answer.trim().toLowerCase(); tier = trimmed === 'team' ? 'team' : 'local'; } let config: MosaicConfig; if (tier === 'local') { config = DEFAULT_LOCAL_CONFIG; } else { const rl = createInterface({ input: process.stdin, output: process.stdout }); const dbUrl = await ask( rl, 'DATABASE_URL [postgresql://mosaic:mosaic@localhost:5432/mosaic]: ', ); const valkeyUrl = await ask(rl, 'VALKEY_URL [redis://localhost:6379]: '); rl.close(); config = { ...DEFAULT_TEAM_CONFIG, storage: { type: 'postgres', url: dbUrl.trim() || 'postgresql://mosaic:mosaic@localhost:5432/mosaic', }, queue: { type: 'bullmq', url: valkeyUrl.trim() || 'redis://localhost:6379', }, }; } writeFileSync(outputPath, JSON.stringify(config, null, 2) + '\n'); console.log(`\nWrote ${outputPath}`); console.log('\nNext steps:'); console.log(' 1. Review the generated config'); console.log(' 2. Run: pnpm --filter @mosaic/gateway exec tsx src/main.ts'); } export function registerGatewayCommand(program: Command): void { const gateway = program.command('gateway').description('Gateway management commands'); gateway .command('init') .description('Generate a mosaic.config.json for the gateway') .option('--tier ', 'Storage tier: local or team (skips interactive prompt)') .option('--output ', 'Output file path', './mosaic.config.json') .action(async (opts: { tier?: string; output: string }) => { await runInit(opts); }); }