mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-23 00:53:33 +00:00
refactor: standardize code formatting and linting configuration
- Replace .eslintrc.js with .eslintrc.cjs for better ES module compatibility - Add .prettierrc configuration for consistent code formatting - Update package.json with new lint and format scripts - Add nodemon.json for development hot reloading configuration - Standardize code formatting across all JavaScript and Vue files - Update web admin SPA with improved linting rules and formatting - Add prettier configuration to web admin SPA 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -2,58 +2,58 @@
|
||||
|
||||
/**
|
||||
* 数据迁移脚本:为现有 API Key 设置默认有效期
|
||||
*
|
||||
*
|
||||
* 使用方法:
|
||||
* node scripts/migrate-apikey-expiry.js [--days=30] [--dry-run]
|
||||
*
|
||||
*
|
||||
* 参数:
|
||||
* --days: 设置默认有效期天数(默认30天)
|
||||
* --dry-run: 仅模拟运行,不实际修改数据
|
||||
*/
|
||||
|
||||
const redis = require('../src/models/redis');
|
||||
const logger = require('../src/utils/logger');
|
||||
const readline = require('readline');
|
||||
const redis = require('../src/models/redis')
|
||||
const logger = require('../src/utils/logger')
|
||||
const readline = require('readline')
|
||||
|
||||
// 解析命令行参数
|
||||
const args = process.argv.slice(2);
|
||||
const params = {};
|
||||
args.forEach(arg => {
|
||||
const [key, value] = arg.split('=');
|
||||
params[key.replace('--', '')] = value || true;
|
||||
});
|
||||
const args = process.argv.slice(2)
|
||||
const params = {}
|
||||
args.forEach((arg) => {
|
||||
const [key, value] = arg.split('=')
|
||||
params[key.replace('--', '')] = value || true
|
||||
})
|
||||
|
||||
const DEFAULT_DAYS = params.days ? parseInt(params.days) : 30;
|
||||
const DRY_RUN = params['dry-run'] === true;
|
||||
const DEFAULT_DAYS = params.days ? parseInt(params.days) : 30
|
||||
const DRY_RUN = params['dry-run'] === true
|
||||
|
||||
// 创建 readline 接口用于用户确认
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout
|
||||
});
|
||||
})
|
||||
|
||||
async function askConfirmation(question) {
|
||||
return new Promise((resolve) => {
|
||||
rl.question(question + ' (yes/no): ', (answer) => {
|
||||
resolve(answer.toLowerCase() === 'yes' || answer.toLowerCase() === 'y');
|
||||
});
|
||||
});
|
||||
rl.question(`${question} (yes/no): `, (answer) => {
|
||||
resolve(answer.toLowerCase() === 'yes' || answer.toLowerCase() === 'y')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
async function migrateApiKeys() {
|
||||
try {
|
||||
logger.info('🔄 Starting API Key expiry migration...');
|
||||
logger.info(`📅 Default expiry period: ${DEFAULT_DAYS} days`);
|
||||
logger.info(`🔍 Mode: ${DRY_RUN ? 'DRY RUN (no changes will be made)' : 'LIVE RUN'}`);
|
||||
|
||||
logger.info('🔄 Starting API Key expiry migration...')
|
||||
logger.info(`📅 Default expiry period: ${DEFAULT_DAYS} days`)
|
||||
logger.info(`🔍 Mode: ${DRY_RUN ? 'DRY RUN (no changes will be made)' : 'LIVE RUN'}`)
|
||||
|
||||
// 连接 Redis
|
||||
await redis.connect();
|
||||
logger.success('✅ Connected to Redis');
|
||||
|
||||
await redis.connect()
|
||||
logger.success('✅ Connected to Redis')
|
||||
|
||||
// 获取所有 API Keys
|
||||
const apiKeys = await redis.getAllApiKeys();
|
||||
logger.info(`📊 Found ${apiKeys.length} API Keys in total`);
|
||||
|
||||
const apiKeys = await redis.getAllApiKeys()
|
||||
logger.info(`📊 Found ${apiKeys.length} API Keys in total`)
|
||||
|
||||
// 统计信息
|
||||
const stats = {
|
||||
total: apiKeys.length,
|
||||
@@ -61,98 +61,99 @@ async function migrateApiKeys() {
|
||||
alreadyHasExpiry: 0,
|
||||
migrated: 0,
|
||||
errors: 0
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// 需要迁移的 Keys
|
||||
const keysToMigrate = [];
|
||||
|
||||
const keysToMigrate = []
|
||||
|
||||
// 分析每个 API Key
|
||||
for (const key of apiKeys) {
|
||||
if (!key.expiresAt || key.expiresAt === 'null' || key.expiresAt === '') {
|
||||
keysToMigrate.push(key);
|
||||
stats.needsMigration++;
|
||||
logger.info(`📌 API Key "${key.name}" (${key.id}) needs migration`);
|
||||
keysToMigrate.push(key)
|
||||
stats.needsMigration++
|
||||
logger.info(`📌 API Key "${key.name}" (${key.id}) needs migration`)
|
||||
} else {
|
||||
stats.alreadyHasExpiry++;
|
||||
const expiryDate = new Date(key.expiresAt);
|
||||
logger.info(`✓ API Key "${key.name}" (${key.id}) already has expiry: ${expiryDate.toLocaleString()}`);
|
||||
stats.alreadyHasExpiry++
|
||||
const expiryDate = new Date(key.expiresAt)
|
||||
logger.info(
|
||||
`✓ API Key "${key.name}" (${key.id}) already has expiry: ${expiryDate.toLocaleString()}`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (keysToMigrate.length === 0) {
|
||||
logger.success('✨ No API Keys need migration!');
|
||||
return;
|
||||
logger.success('✨ No API Keys need migration!')
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 显示迁移摘要
|
||||
console.log('\n' + '='.repeat(60));
|
||||
console.log('📋 Migration Summary:');
|
||||
console.log('='.repeat(60));
|
||||
console.log(`Total API Keys: ${stats.total}`);
|
||||
console.log(`Already have expiry: ${stats.alreadyHasExpiry}`);
|
||||
console.log(`Need migration: ${stats.needsMigration}`);
|
||||
console.log(`Default expiry: ${DEFAULT_DAYS} days from now`);
|
||||
console.log('='.repeat(60) + '\n');
|
||||
|
||||
console.log(`\n${'='.repeat(60)}`)
|
||||
console.log('📋 Migration Summary:')
|
||||
console.log('='.repeat(60))
|
||||
console.log(`Total API Keys: ${stats.total}`)
|
||||
console.log(`Already have expiry: ${stats.alreadyHasExpiry}`)
|
||||
console.log(`Need migration: ${stats.needsMigration}`)
|
||||
console.log(`Default expiry: ${DEFAULT_DAYS} days from now`)
|
||||
console.log(`${'='.repeat(60)}\n`)
|
||||
|
||||
// 如果不是 dry run,请求确认
|
||||
if (!DRY_RUN) {
|
||||
const confirmed = await askConfirmation(
|
||||
`⚠️ This will set expiry dates for ${keysToMigrate.length} API Keys. Continue?`
|
||||
);
|
||||
|
||||
)
|
||||
|
||||
if (!confirmed) {
|
||||
logger.warn('❌ Migration cancelled by user');
|
||||
return;
|
||||
logger.warn('❌ Migration cancelled by user')
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 计算新的过期时间
|
||||
const newExpiryDate = new Date();
|
||||
newExpiryDate.setDate(newExpiryDate.getDate() + DEFAULT_DAYS);
|
||||
const newExpiryISO = newExpiryDate.toISOString();
|
||||
|
||||
logger.info(`\n🚀 Starting migration... New expiry date: ${newExpiryDate.toLocaleString()}`);
|
||||
|
||||
const newExpiryDate = new Date()
|
||||
newExpiryDate.setDate(newExpiryDate.getDate() + DEFAULT_DAYS)
|
||||
const newExpiryISO = newExpiryDate.toISOString()
|
||||
|
||||
logger.info(`\n🚀 Starting migration... New expiry date: ${newExpiryDate.toLocaleString()}`)
|
||||
|
||||
// 执行迁移
|
||||
for (const key of keysToMigrate) {
|
||||
try {
|
||||
if (!DRY_RUN) {
|
||||
// 直接更新 Redis 中的数据
|
||||
// 使用 hset 更新单个字段
|
||||
await redis.client.hset(`apikey:${key.id}`, 'expiresAt', newExpiryISO);
|
||||
logger.success(`✅ Migrated: "${key.name}" (${key.id})`);
|
||||
await redis.client.hset(`apikey:${key.id}`, 'expiresAt', newExpiryISO)
|
||||
logger.success(`✅ Migrated: "${key.name}" (${key.id})`)
|
||||
} else {
|
||||
logger.info(`[DRY RUN] Would migrate: "${key.name}" (${key.id})`);
|
||||
logger.info(`[DRY RUN] Would migrate: "${key.name}" (${key.id})`)
|
||||
}
|
||||
stats.migrated++;
|
||||
stats.migrated++
|
||||
} catch (error) {
|
||||
logger.error(`❌ Error migrating "${key.name}" (${key.id}):`, error.message);
|
||||
stats.errors++;
|
||||
logger.error(`❌ Error migrating "${key.name}" (${key.id}):`, error.message)
|
||||
stats.errors++
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 显示最终结果
|
||||
console.log('\n' + '='.repeat(60));
|
||||
console.log('✅ Migration Complete!');
|
||||
console.log('='.repeat(60));
|
||||
console.log(`Successfully migrated: ${stats.migrated}`);
|
||||
console.log(`Errors: ${stats.errors}`);
|
||||
console.log(`New expiry date: ${newExpiryDate.toLocaleString()}`);
|
||||
console.log('='.repeat(60) + '\n');
|
||||
|
||||
console.log(`\n${'='.repeat(60)}`)
|
||||
console.log('✅ Migration Complete!')
|
||||
console.log('='.repeat(60))
|
||||
console.log(`Successfully migrated: ${stats.migrated}`)
|
||||
console.log(`Errors: ${stats.errors}`)
|
||||
console.log(`New expiry date: ${newExpiryDate.toLocaleString()}`)
|
||||
console.log(`${'='.repeat(60)}\n`)
|
||||
|
||||
if (DRY_RUN) {
|
||||
logger.warn('⚠️ This was a DRY RUN. No actual changes were made.');
|
||||
logger.info('💡 Run without --dry-run flag to apply changes.');
|
||||
logger.warn('⚠️ This was a DRY RUN. No actual changes were made.')
|
||||
logger.info('💡 Run without --dry-run flag to apply changes.')
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
logger.error('💥 Migration failed:', error);
|
||||
process.exit(1);
|
||||
logger.error('💥 Migration failed:', error)
|
||||
process.exit(1)
|
||||
} finally {
|
||||
// 清理
|
||||
rl.close();
|
||||
await redis.disconnect();
|
||||
logger.info('👋 Disconnected from Redis');
|
||||
rl.close()
|
||||
await redis.disconnect()
|
||||
logger.info('👋 Disconnected from Redis')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,12 +181,12 @@ Examples:
|
||||
|
||||
# Test run without making changes
|
||||
node scripts/migrate-apikey-expiry.js --dry-run
|
||||
`);
|
||||
process.exit(0);
|
||||
`)
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
// 运行迁移
|
||||
migrateApiKeys().catch(error => {
|
||||
logger.error('💥 Unexpected error:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
migrateApiKeys().catch((error) => {
|
||||
logger.error('💥 Unexpected error:', error)
|
||||
process.exit(1)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user