Files
claude-relay-service/scripts/setup.js
2025-07-14 18:14:13 +08:00

107 lines
3.7 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
const bcrypt = require('bcryptjs');
const chalk = require('chalk');
const ora = require('ora');
const config = require('../config/config');
async function setup() {
console.log(chalk.blue.bold('\n🚀 Claude Relay Service 初始化设置\n'));
const spinner = ora('正在进行初始化设置...').start();
try {
// 1. 创建必要目录
const directories = [
'logs',
'data',
'temp'
];
directories.forEach(dir => {
const dirPath = path.join(__dirname, '..', dir);
if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath, { recursive: true });
}
});
// 2. 生成环境配置文件
if (!fs.existsSync(path.join(__dirname, '..', '.env'))) {
const envTemplate = fs.readFileSync(path.join(__dirname, '..', '.env.example'), 'utf8');
// 生成随机密钥
const jwtSecret = crypto.randomBytes(64).toString('hex');
const encryptionKey = crypto.randomBytes(32).toString('hex');
const envContent = envTemplate
.replace('your-jwt-secret-here', jwtSecret)
.replace('your-encryption-key-here', encryptionKey);
fs.writeFileSync(path.join(__dirname, '..', '.env'), envContent);
}
// 3. 生成随机管理员凭据
const adminUsername = `cr_admin_${crypto.randomBytes(4).toString('hex')}`;
const adminPassword = crypto.randomBytes(16).toString('base64').replace(/[^a-zA-Z0-9]/g, '').substring(0, 16);
// 4. 创建初始化完成标记文件
const initData = {
initializedAt: new Date().toISOString(),
adminUsername,
adminPassword,
version: '1.0.0'
};
fs.writeFileSync(
path.join(__dirname, '..', 'data', 'init.json'),
JSON.stringify(initData, null, 2)
);
spinner.succeed('初始化设置完成');
console.log(chalk.green('\n✅ 设置完成!\n'));
console.log(chalk.yellow('📋 重要信息:\n'));
console.log(` 管理员用户名: ${chalk.cyan(adminUsername)}`);
console.log(` 管理员密码: ${chalk.cyan(adminPassword)}`);
console.log(chalk.red('\n⚠ 请立即保存这些凭据!首次登录后建议修改密码。\n'));
console.log(chalk.blue('🚀 启动服务:\n'));
console.log(' npm start - 启动生产服务');
console.log(' npm run dev - 启动开发服务');
console.log(' npm run cli admin - 管理员CLI工具\n');
console.log(chalk.blue('🌐 访问地址:\n'));
console.log(` Web管理界面: http://localhost:${config.server.port}/web`);
console.log(` API端点: http://localhost:${config.server.port}/api/v1/messages`);
console.log(` 健康检查: http://localhost:${config.server.port}/health\n`);
} catch (error) {
spinner.fail('初始化设置失败');
console.error(chalk.red('❌ 错误:'), error.message);
process.exit(1);
}
}
// 检查是否已初始化
function checkInitialized() {
const initFile = path.join(__dirname, '..', 'data', 'init.json');
if (fs.existsSync(initFile)) {
const initData = JSON.parse(fs.readFileSync(initFile, 'utf8'));
console.log(chalk.yellow('⚠️ 服务已经初始化过了!'));
console.log(` 初始化时间: ${new Date(initData.initializedAt).toLocaleString()}`);
console.log(` 管理员用户名: ${initData.adminUsername}`);
console.log('\n如需重新初始化请删除 data/init.json 文件。');
return true;
}
return false;
}
if (require.main === module) {
if (!checkInitialized()) {
setup();
}
}
module.exports = { setup, checkInitialized };