Files
cc-switch/src/main/services.ts

174 lines
4.9 KiB
TypeScript
Raw Normal View History

2025-08-04 22:16:26 +08:00
import fs from 'fs/promises'
import path from 'path'
import os from 'os'
import { Provider } from '../shared/types'
2025-08-04 22:16:26 +08:00
/**
*
*/
export function sanitizeProviderName(name: string): string {
return name.replace(/[<>:"/\\|?*]/g, '-').toLowerCase()
}
2025-08-04 22:16:26 +08:00
export function getClaudeCodeConfig() {
// Claude Code 配置文件路径
const configDir = path.join(os.homedir(), '.claude')
const configPath = path.join(configDir, 'settings.json')
2025-08-04 22:16:26 +08:00
return { path: configPath, dir: configDir }
}
/**
*
*/
export function getProviderConfigPath(providerId: string): string {
const { dir } = getClaudeCodeConfig()
return path.join(dir, `settings-${sanitizeProviderName(providerId)}.json`)
}
/**
*
*/
export async function saveProviderConfig(provider: Provider): Promise<boolean> {
try {
const { dir } = getClaudeCodeConfig()
const providerConfigPath = getProviderConfigPath(provider.id)
// 确保目录存在
await fs.mkdir(dir, { recursive: true })
// 保存配置到供应商专用文件
await fs.writeFile(
providerConfigPath,
JSON.stringify(provider.settingsConfig, null, 2),
'utf-8'
)
return true
} catch (error) {
console.error('保存供应商配置失败:', error)
return false
}
}
/**
*
*/
export async function fileExists(filePath: string): Promise<boolean> {
2025-08-04 22:16:26 +08:00
try {
await fs.access(filePath)
return true
} catch {
return false
}
}
/**
*
*/
export async function switchProvider(provider: Provider, currentProviderId?: string): Promise<boolean> {
try {
const { path: settingsPath, dir: configDir } = getClaudeCodeConfig()
const newSettingsPath = getProviderConfigPath(provider.id)
2025-08-04 22:16:26 +08:00
// 确保目录存在
await fs.mkdir(configDir, { recursive: true })
// 检查目标配置文件是否存在
if (!(await fileExists(newSettingsPath))) {
console.error(`供应商配置文件不存在: ${newSettingsPath}`)
return false
2025-08-04 22:16:26 +08:00
}
// 1. 如果当前存在settings.json先备份到当前供应商的配置文件
if (await fileExists(settingsPath)) {
if (currentProviderId) {
const currentProviderPath = getProviderConfigPath(currentProviderId)
await fs.rename(settingsPath, currentProviderPath)
} else {
// 如果没有当前供应商ID创建临时备份
const backupPath = path.join(configDir, `settings-backup-${Date.now()}.json`)
await fs.rename(settingsPath, backupPath)
console.log(`已备份当前配置到: ${backupPath}`)
}
2025-08-04 22:16:26 +08:00
}
// 2. 将目标供应商配置重命名为settings.json
await fs.rename(newSettingsPath, settingsPath)
console.log(`成功切换到供应商: ${provider.name}`)
return true
} catch (error) {
console.error('切换供应商失败:', error)
return false
}
}
/**
* settings.json
*/
export async function importCurrentConfig(name: string): Promise<{ success: boolean; provider?: Provider }> {
try {
const { path: settingsPath } = getClaudeCodeConfig()
// 检查当前配置是否存在
if (!(await fileExists(settingsPath))) {
return { success: false }
}
// 读取当前配置
const configContent = await fs.readFile(settingsPath, 'utf-8')
const settingsConfig = JSON.parse(configContent)
// 生成唯一的供应商ID
let providerId = name.toLowerCase().replace(/[^a-z0-9]/g, '-')
let counter = 1
// 检查ID是否已存在如果存在则添加数字后缀
while (await fileExists(getProviderConfigPath(providerId))) {
providerId = `${name.toLowerCase().replace(/[^a-z0-9]/g, '-')}-${counter}`
counter++
}
// 创建供应商对象
const provider: Provider = {
id: providerId,
name: name,
settingsConfig: settingsConfig,
createdAt: Date.now(),
updatedAt: Date.now()
}
// 保存为供应商配置
const success = await saveProviderConfig(provider)
if (success) {
console.log(`已导入当前配置为供应商: ${name} (${providerId})`)
return { success: true, provider }
} else {
return { success: false }
}
} catch (error: any) {
console.error('导入当前配置失败:', error)
return { success: false }
}
}
/**
*
*/
export async function deleteProviderConfig(providerId: string): Promise<boolean> {
try {
const providerConfigPath = getProviderConfigPath(providerId)
if (await fileExists(providerConfigPath)) {
await fs.unlink(providerConfigPath)
console.log(`已删除供应商配置文件: ${providerConfigPath}`)
}
2025-08-04 22:16:26 +08:00
return true
} catch (error) {
console.error('删除供应商配置失败:', error)
2025-08-04 22:16:26 +08:00
return false
}
}