mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-06-16 13:34:04 +08:00
chore: remove dead code from providerConfigUtils and config API
- Remove unused functions: updateCommonConfigSnippet, replaceCommonConfigSnippet, replaceGeminiCommonConfigSnippet, updateTomlCommonConfigSnippet, replaceTomlCommonConfigSnippet and their internal helpers (~600 lines) - Remove deprecated getClaudeCommonConfigSnippet and setClaudeCommonConfigSnippet - Remove unused imports (deepClone, deepMerge)
This commit is contained in:
@@ -66,27 +66,6 @@ const pendingSyncParams: Record<
|
||||
|
||||
const SYNC_DEBOUNCE_MS = 500;
|
||||
|
||||
/**
|
||||
* 获取 Claude 通用配置片段(已废弃,使用 getCommonConfigSnippet)
|
||||
* @returns 通用配置片段(JSON 字符串),如果不存在则返回 null
|
||||
* @deprecated 使用 getCommonConfigSnippet('claude') 替代
|
||||
*/
|
||||
export async function getClaudeCommonConfigSnippet(): Promise<string | null> {
|
||||
return invoke<string | null>("get_claude_common_config_snippet");
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 Claude 通用配置片段(已废弃,使用 setCommonConfigSnippet)
|
||||
* @param snippet - 通用配置片段(JSON 字符串)
|
||||
* @throws 如果 JSON 格式无效
|
||||
* @deprecated 使用 setCommonConfigSnippet('claude', snippet) 替代
|
||||
*/
|
||||
export async function setClaudeCommonConfigSnippet(
|
||||
snippet: string,
|
||||
): Promise<void> {
|
||||
return invoke("set_claude_common_config_snippet", { snippet });
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取通用配置片段(统一接口)
|
||||
* @param appType - 应用类型(claude/codex/gemini)
|
||||
@@ -453,7 +432,6 @@ function getSettingsConfigString(
|
||||
|
||||
case "gemini":
|
||||
// Gemini: settingsConfig 是包含 env 字段的 JSON 对象
|
||||
// replaceGeminiCommonConfigSnippet 期望接收完整的 settingsConfig JSON
|
||||
return typeof config === "string" ? config : JSON.stringify(config);
|
||||
|
||||
default:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import type { TemplateValueConfig } from "../config/claudeProviderPresets";
|
||||
import { normalizeQuotes } from "@/utils/textNormalization";
|
||||
import { isPlainObject, deepClone, deepMerge } from "@/utils/configMerge";
|
||||
import { isPlainObject } from "@/utils/configMerge";
|
||||
|
||||
// Gemini 通用配置禁止的键(共享常量,供 hook 和同步逻辑复用)
|
||||
export const GEMINI_COMMON_ENV_FORBIDDEN_KEYS = [
|
||||
@@ -12,26 +12,6 @@ export const GEMINI_COMMON_ENV_FORBIDDEN_KEYS = [
|
||||
export type GeminiForbiddenEnvKey =
|
||||
(typeof GEMINI_COMMON_ENV_FORBIDDEN_KEYS)[number];
|
||||
|
||||
const deepRemove = (
|
||||
target: Record<string, any>,
|
||||
source: Record<string, any>,
|
||||
) => {
|
||||
Object.entries(source).forEach(([key, value]) => {
|
||||
if (!(key in target)) return;
|
||||
|
||||
if (isPlainObject(value) && isPlainObject(target[key])) {
|
||||
// 只移除完全匹配的嵌套属性
|
||||
deepRemove(target[key], value);
|
||||
if (Object.keys(target[key]).length === 0) {
|
||||
delete target[key];
|
||||
}
|
||||
} else if (isSubset(target[key], value)) {
|
||||
// 只有当值完全匹配时才删除
|
||||
delete target[key];
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const isSubset = (target: any, source: any): boolean => {
|
||||
if (isPlainObject(source)) {
|
||||
if (!isPlainObject(target)) return false;
|
||||
@@ -48,11 +28,6 @@ const isSubset = (target: any, source: any): boolean => {
|
||||
return target === source;
|
||||
};
|
||||
|
||||
export interface UpdateCommonConfigResult {
|
||||
updatedConfig: string;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
// 验证JSON配置格式
|
||||
export const validateJsonConfig = (
|
||||
value: string,
|
||||
@@ -72,53 +47,6 @@ export const validateJsonConfig = (
|
||||
}
|
||||
};
|
||||
|
||||
// 将通用配置片段写入/移除 settingsConfig
|
||||
export const updateCommonConfigSnippet = (
|
||||
jsonString: string,
|
||||
snippetString: string,
|
||||
enabled: boolean,
|
||||
): UpdateCommonConfigResult => {
|
||||
let config: Record<string, any>;
|
||||
try {
|
||||
config = jsonString ? JSON.parse(jsonString) : {};
|
||||
} catch (err) {
|
||||
return {
|
||||
updatedConfig: jsonString,
|
||||
error: "配置 JSON 解析失败,无法写入通用配置",
|
||||
};
|
||||
}
|
||||
|
||||
if (!snippetString.trim()) {
|
||||
return {
|
||||
updatedConfig: JSON.stringify(config, null, 2),
|
||||
};
|
||||
}
|
||||
|
||||
// 使用统一的验证函数
|
||||
const snippetError = validateJsonConfig(snippetString, "通用配置片段");
|
||||
if (snippetError) {
|
||||
return {
|
||||
updatedConfig: JSON.stringify(config, null, 2),
|
||||
error: snippetError,
|
||||
};
|
||||
}
|
||||
|
||||
const snippet = JSON.parse(snippetString) as Record<string, any>;
|
||||
|
||||
if (enabled) {
|
||||
const merged = deepMerge(deepClone(config), snippet);
|
||||
return {
|
||||
updatedConfig: JSON.stringify(merged, null, 2),
|
||||
};
|
||||
}
|
||||
|
||||
const cloned = deepClone(config);
|
||||
deepRemove(cloned, snippet);
|
||||
return {
|
||||
updatedConfig: JSON.stringify(cloned, null, 2),
|
||||
};
|
||||
};
|
||||
|
||||
// 检查当前配置是否已包含通用配置片段
|
||||
export const hasCommonConfigSnippet = (
|
||||
jsonString: string,
|
||||
@@ -180,122 +108,6 @@ export const hasGeminiCommonConfigSnippet = (
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 替换通用配置片段(用于同步更新)
|
||||
* 先移除旧的通用配置,再添加新的通用配置
|
||||
*/
|
||||
export const replaceCommonConfigSnippet = (
|
||||
jsonString: string,
|
||||
oldSnippet: string,
|
||||
newSnippet: string,
|
||||
): UpdateCommonConfigResult => {
|
||||
// 先移除旧的通用配置
|
||||
const removeResult = updateCommonConfigSnippet(jsonString, oldSnippet, false);
|
||||
if (removeResult.error) {
|
||||
return removeResult;
|
||||
}
|
||||
|
||||
// 再添加新的通用配置
|
||||
return updateCommonConfigSnippet(
|
||||
removeResult.updatedConfig,
|
||||
newSnippet,
|
||||
true,
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 替换 Gemini 通用配置片段(用于同步更新)
|
||||
* Gemini 的通用配置是 JSON 格式的 env 对象
|
||||
*/
|
||||
export const replaceGeminiCommonConfigSnippet = (
|
||||
jsonString: string,
|
||||
oldSnippet: string,
|
||||
newSnippet: string,
|
||||
): UpdateCommonConfigResult => {
|
||||
try {
|
||||
const config = jsonString ? JSON.parse(jsonString) : {};
|
||||
|
||||
// 校验 config 是对象类型
|
||||
if (!isPlainObject(config)) {
|
||||
return {
|
||||
updatedConfig: jsonString,
|
||||
error: "CONFIG_NOT_OBJECT",
|
||||
};
|
||||
}
|
||||
|
||||
const env = config.env ?? {};
|
||||
|
||||
// 校验 env 是对象类型
|
||||
if (!isPlainObject(env)) {
|
||||
return {
|
||||
updatedConfig: jsonString,
|
||||
error: "ENV_NOT_OBJECT",
|
||||
};
|
||||
}
|
||||
|
||||
// 解析旧的通用配置
|
||||
let oldEnv: Record<string, string> = {};
|
||||
if (oldSnippet.trim()) {
|
||||
try {
|
||||
const parsed = JSON.parse(oldSnippet);
|
||||
if (isPlainObject(parsed)) {
|
||||
oldEnv = parsed as Record<string, string>;
|
||||
}
|
||||
} catch {
|
||||
// ignore parse error
|
||||
}
|
||||
}
|
||||
|
||||
// 解析新的通用配置
|
||||
let newEnv: Record<string, string> = {};
|
||||
if (newSnippet.trim()) {
|
||||
try {
|
||||
const parsed = JSON.parse(newSnippet);
|
||||
if (isPlainObject(parsed)) {
|
||||
// 过滤掉禁止的键
|
||||
for (const [key, value] of Object.entries(parsed)) {
|
||||
if (
|
||||
typeof value === "string" &&
|
||||
!GEMINI_COMMON_ENV_FORBIDDEN_KEYS.includes(
|
||||
key as GeminiForbiddenEnvKey,
|
||||
)
|
||||
) {
|
||||
newEnv[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
return {
|
||||
updatedConfig: jsonString,
|
||||
error: "COMMON_CONFIG_JSON_INVALID",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// 移除旧的通用配置键值对
|
||||
const updatedEnv = { ...env };
|
||||
for (const [key, value] of Object.entries(oldEnv)) {
|
||||
if (updatedEnv[key] === value) {
|
||||
delete updatedEnv[key];
|
||||
}
|
||||
}
|
||||
|
||||
// 添加新的通用配置键值对
|
||||
for (const [key, value] of Object.entries(newEnv)) {
|
||||
updatedEnv[key] = value;
|
||||
}
|
||||
|
||||
return {
|
||||
updatedConfig: JSON.stringify({ ...config, env: updatedEnv }, null, 2),
|
||||
};
|
||||
} catch (err) {
|
||||
return {
|
||||
updatedConfig: jsonString,
|
||||
error: "CONFIG_JSON_PARSE_FAILED",
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// 读取配置中的 API Key(支持 Claude, Codex, Gemini)
|
||||
export const getApiKeyFromConfig = (
|
||||
jsonString: string,
|
||||
@@ -460,389 +272,6 @@ export const setApiKeyInConfig = (
|
||||
}
|
||||
};
|
||||
|
||||
// ========== TOML Config Utilities ==========
|
||||
|
||||
export interface UpdateTomlCommonConfigResult {
|
||||
updatedConfig: string;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
const TOML_COMMON_CONFIG_START = "# cc-switch:common-config:start";
|
||||
const TOML_COMMON_CONFIG_END = "# cc-switch:common-config:end";
|
||||
|
||||
/**
|
||||
* 移除旧版标记块(兼容性清理)
|
||||
* 仅用于清理历史遗留的标记,新版本不再写入标记
|
||||
*/
|
||||
const stripTomlCommonConfigBlock = (tomlString: string): string => {
|
||||
const startIndex = tomlString.indexOf(TOML_COMMON_CONFIG_START);
|
||||
const endIndex = tomlString.indexOf(TOML_COMMON_CONFIG_END);
|
||||
if (startIndex === -1 || endIndex === -1 || endIndex < startIndex) {
|
||||
return tomlString;
|
||||
}
|
||||
const before = tomlString.slice(0, startIndex);
|
||||
const after = tomlString.slice(endIndex + TOML_COMMON_CONFIG_END.length);
|
||||
return `${before}${after}`;
|
||||
};
|
||||
|
||||
/**
|
||||
* 解析 TOML 文本为段落结构
|
||||
* 返回 { topLevel: string[], sections: Map<string, string[]> }
|
||||
* - topLevel: 顶级键值对行(在任何 [section] 之前)
|
||||
* - sections: 每个 [section] 及其内容行
|
||||
*/
|
||||
interface TomlParsedStructure {
|
||||
topLevel: string[];
|
||||
sections: Map<string, string[]>;
|
||||
sectionOrder: string[];
|
||||
}
|
||||
|
||||
function parseTomlStructure(tomlText: string): TomlParsedStructure {
|
||||
const lines = tomlText.split("\n");
|
||||
const topLevel: string[] = [];
|
||||
const sections = new Map<string, string[]>();
|
||||
const sectionOrder: string[] = [];
|
||||
|
||||
let currentSection: string | null = null;
|
||||
|
||||
for (const line of lines) {
|
||||
const trimmed = line.trim();
|
||||
|
||||
// 检查是否是 section 头(如 [mcp_servers.mcpServers])
|
||||
const sectionMatch = trimmed.match(/^\[([^\]]+)\]$/);
|
||||
if (sectionMatch) {
|
||||
currentSection = sectionMatch[1];
|
||||
if (!sections.has(currentSection)) {
|
||||
sections.set(currentSection, []);
|
||||
sectionOrder.push(currentSection);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (currentSection === null) {
|
||||
// 顶级内容
|
||||
topLevel.push(line);
|
||||
} else {
|
||||
// section 内容
|
||||
const sectionLines = sections.get(currentSection)!;
|
||||
sectionLines.push(line);
|
||||
}
|
||||
}
|
||||
|
||||
return { topLevel, sections, sectionOrder };
|
||||
}
|
||||
|
||||
/**
|
||||
* 从顶级行中提取键名
|
||||
*/
|
||||
function extractKeyFromLine(line: string): string | null {
|
||||
const trimmed = line.trim();
|
||||
// 跳过空行和注释
|
||||
if (!trimmed || trimmed.startsWith("#")) {
|
||||
return null;
|
||||
}
|
||||
// 匹配 key = value 格式
|
||||
const match = trimmed.match(/^([a-zA-Z_][a-zA-Z0-9_]*)\s*=/);
|
||||
return match ? match[1] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 智能合并 TOML 配置
|
||||
* - 顶级键值对:snippet 中的键会覆盖或添加到 base 的顶级区域
|
||||
* - sections:同名 section 会合并内容,不同 section 会追加
|
||||
*/
|
||||
function mergeTomlConfigs(baseText: string, snippetText: string): string {
|
||||
const base = parseTomlStructure(baseText);
|
||||
const snippet = parseTomlStructure(snippetText);
|
||||
|
||||
// 1. 合并顶级键值对
|
||||
// 提取 snippet 中的顶级键
|
||||
const snippetTopLevelKeys = new Set<string>();
|
||||
for (const line of snippet.topLevel) {
|
||||
const key = extractKeyFromLine(line);
|
||||
if (key) {
|
||||
snippetTopLevelKeys.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
// 过滤 base 中被 snippet 覆盖的键
|
||||
const filteredBaseTopLevel = base.topLevel.filter((line) => {
|
||||
const key = extractKeyFromLine(line);
|
||||
return key === null || !snippetTopLevelKeys.has(key);
|
||||
});
|
||||
|
||||
// 合并顶级内容:base 的非覆盖行 + snippet 的顶级行
|
||||
const mergedTopLevel = [...filteredBaseTopLevel];
|
||||
// 添加 snippet 的顶级行(跳过空行,除非是有意义的)
|
||||
for (const line of snippet.topLevel) {
|
||||
const trimmed = line.trim();
|
||||
if (trimmed) {
|
||||
mergedTopLevel.push(line);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 合并 sections
|
||||
const mergedSections = new Map<string, string[]>();
|
||||
const mergedSectionOrder: string[] = [];
|
||||
|
||||
// 先添加 base 的 sections
|
||||
for (const sectionName of base.sectionOrder) {
|
||||
mergedSections.set(sectionName, [...base.sections.get(sectionName)!]);
|
||||
mergedSectionOrder.push(sectionName);
|
||||
}
|
||||
|
||||
// 合并 snippet 的 sections
|
||||
for (const sectionName of snippet.sectionOrder) {
|
||||
const snippetLines = snippet.sections.get(sectionName)!;
|
||||
|
||||
if (mergedSections.has(sectionName)) {
|
||||
// 同名 section:合并内容
|
||||
const existingLines = mergedSections.get(sectionName)!;
|
||||
|
||||
// 提取 snippet section 中的键
|
||||
const snippetSectionKeys = new Set<string>();
|
||||
for (const line of snippetLines) {
|
||||
const key = extractKeyFromLine(line);
|
||||
if (key) {
|
||||
snippetSectionKeys.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
// 过滤 existing 中被覆盖的键
|
||||
const filteredExisting = existingLines.filter((line) => {
|
||||
const key = extractKeyFromLine(line);
|
||||
return key === null || !snippetSectionKeys.has(key);
|
||||
});
|
||||
|
||||
// 合并:existing 的非覆盖行 + snippet 的行
|
||||
const merged = [...filteredExisting];
|
||||
for (const line of snippetLines) {
|
||||
const trimmed = line.trim();
|
||||
if (trimmed) {
|
||||
merged.push(line);
|
||||
}
|
||||
}
|
||||
mergedSections.set(sectionName, merged);
|
||||
} else {
|
||||
// 新 section:直接添加
|
||||
mergedSections.set(sectionName, [...snippetLines]);
|
||||
mergedSectionOrder.push(sectionName);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 重建 TOML 文本
|
||||
const resultLines: string[] = [];
|
||||
|
||||
// 添加顶级内容(清理多余空行)
|
||||
let lastWasEmpty = true;
|
||||
for (const line of mergedTopLevel) {
|
||||
const isEmpty = !line.trim();
|
||||
if (isEmpty && lastWasEmpty) {
|
||||
continue; // 跳过连续空行
|
||||
}
|
||||
resultLines.push(line);
|
||||
lastWasEmpty = isEmpty;
|
||||
}
|
||||
|
||||
// 添加 sections
|
||||
for (const sectionName of mergedSectionOrder) {
|
||||
const sectionLines = mergedSections.get(sectionName)!;
|
||||
|
||||
// 确保 section 前有空行分隔
|
||||
if (resultLines.length > 0 && resultLines[resultLines.length - 1].trim()) {
|
||||
resultLines.push("");
|
||||
}
|
||||
|
||||
// 添加 section 头
|
||||
resultLines.push(`[${sectionName}]`);
|
||||
|
||||
// 添加 section 内容(清理多余空行)
|
||||
lastWasEmpty = false;
|
||||
for (const line of sectionLines) {
|
||||
const isEmpty = !line.trim();
|
||||
if (isEmpty && lastWasEmpty) {
|
||||
continue;
|
||||
}
|
||||
resultLines.push(line);
|
||||
lastWasEmpty = isEmpty;
|
||||
}
|
||||
}
|
||||
|
||||
// 清理末尾空行,确保以单个换行结尾
|
||||
while (
|
||||
resultLines.length > 0 &&
|
||||
!resultLines[resultLines.length - 1].trim()
|
||||
) {
|
||||
resultLines.pop();
|
||||
}
|
||||
|
||||
return resultLines.join("\n") + "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 TOML 配置中移除指定的片段内容
|
||||
* - 移除 snippet 中定义的顶级键
|
||||
* - 移除 snippet 中定义的 section 内的键(如果 section 变空则移除整个 section)
|
||||
*/
|
||||
function removeTomlSnippet(baseText: string, snippetText: string): string {
|
||||
const base = parseTomlStructure(baseText);
|
||||
const snippet = parseTomlStructure(snippetText);
|
||||
|
||||
// 1. 从顶级移除 snippet 的键
|
||||
const snippetTopLevelKeys = new Set<string>();
|
||||
for (const line of snippet.topLevel) {
|
||||
const key = extractKeyFromLine(line);
|
||||
if (key) {
|
||||
snippetTopLevelKeys.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
const filteredTopLevel = base.topLevel.filter((line) => {
|
||||
const key = extractKeyFromLine(line);
|
||||
return key === null || !snippetTopLevelKeys.has(key);
|
||||
});
|
||||
|
||||
// 2. 从 sections 移除 snippet 的键
|
||||
const filteredSections = new Map<string, string[]>();
|
||||
const filteredSectionOrder: string[] = [];
|
||||
|
||||
for (const sectionName of base.sectionOrder) {
|
||||
const baseLines = base.sections.get(sectionName)!;
|
||||
|
||||
// 检查 snippet 是否有这个 section
|
||||
if (snippet.sections.has(sectionName)) {
|
||||
const snippetLines = snippet.sections.get(sectionName)!;
|
||||
|
||||
// 提取 snippet section 中的键
|
||||
const snippetSectionKeys = new Set<string>();
|
||||
for (const line of snippetLines) {
|
||||
const key = extractKeyFromLine(line);
|
||||
if (key) {
|
||||
snippetSectionKeys.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
// 过滤掉 snippet 中的键
|
||||
const filtered = baseLines.filter((line) => {
|
||||
const key = extractKeyFromLine(line);
|
||||
return key === null || !snippetSectionKeys.has(key);
|
||||
});
|
||||
|
||||
// 检查过滤后是否还有实质内容
|
||||
const hasContent = filtered.some((line) => {
|
||||
const trimmed = line.trim();
|
||||
return trimmed && !trimmed.startsWith("#");
|
||||
});
|
||||
|
||||
if (hasContent) {
|
||||
filteredSections.set(sectionName, filtered);
|
||||
filteredSectionOrder.push(sectionName);
|
||||
}
|
||||
// 如果没有实质内容,整个 section 被移除
|
||||
} else {
|
||||
// snippet 中没有这个 section,保留
|
||||
filteredSections.set(sectionName, baseLines);
|
||||
filteredSectionOrder.push(sectionName);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 重建 TOML 文本
|
||||
const resultLines: string[] = [];
|
||||
|
||||
// 添加顶级内容
|
||||
let lastWasEmpty = true;
|
||||
for (const line of filteredTopLevel) {
|
||||
const isEmpty = !line.trim();
|
||||
if (isEmpty && lastWasEmpty) {
|
||||
continue;
|
||||
}
|
||||
resultLines.push(line);
|
||||
lastWasEmpty = isEmpty;
|
||||
}
|
||||
|
||||
// 添加 sections
|
||||
for (const sectionName of filteredSectionOrder) {
|
||||
const sectionLines = filteredSections.get(sectionName)!;
|
||||
|
||||
if (resultLines.length > 0 && resultLines[resultLines.length - 1].trim()) {
|
||||
resultLines.push("");
|
||||
}
|
||||
|
||||
resultLines.push(`[${sectionName}]`);
|
||||
|
||||
lastWasEmpty = false;
|
||||
for (const line of sectionLines) {
|
||||
const isEmpty = !line.trim();
|
||||
if (isEmpty && lastWasEmpty) {
|
||||
continue;
|
||||
}
|
||||
resultLines.push(line);
|
||||
lastWasEmpty = isEmpty;
|
||||
}
|
||||
}
|
||||
|
||||
while (
|
||||
resultLines.length > 0 &&
|
||||
!resultLines[resultLines.length - 1].trim()
|
||||
) {
|
||||
resultLines.pop();
|
||||
}
|
||||
|
||||
return resultLines.length > 0 ? resultLines.join("\n") + "\n" : "";
|
||||
}
|
||||
|
||||
// 将通用配置片段写入/移除 TOML 配置
|
||||
// 使用智能合并,避免重复定义 section
|
||||
export const updateTomlCommonConfigSnippet = (
|
||||
tomlString: string,
|
||||
snippetString: string,
|
||||
enabled: boolean,
|
||||
): UpdateTomlCommonConfigResult => {
|
||||
if (enabled) {
|
||||
if (!snippetString.trim()) {
|
||||
return {
|
||||
updatedConfig: tomlString,
|
||||
};
|
||||
}
|
||||
|
||||
// 先清理旧版标记块(兼容性)
|
||||
let baseConfig = stripTomlCommonConfigBlock(tomlString);
|
||||
baseConfig = baseConfig.replace(/\n{3,}/g, "\n\n").trim();
|
||||
if (baseConfig) {
|
||||
baseConfig += "\n";
|
||||
}
|
||||
|
||||
// 使用智能合并
|
||||
const merged = mergeTomlConfigs(baseConfig, snippetString);
|
||||
|
||||
return {
|
||||
updatedConfig: merged,
|
||||
};
|
||||
} else {
|
||||
// 移除通用配置
|
||||
// 先清理旧版标记块(兼容性)
|
||||
const strippedConfig = stripTomlCommonConfigBlock(tomlString);
|
||||
if (strippedConfig !== tomlString) {
|
||||
const cleaned = strippedConfig.replace(/\n{3,}/g, "\n\n").trim();
|
||||
return {
|
||||
updatedConfig: cleaned ? cleaned + "\n" : "",
|
||||
};
|
||||
}
|
||||
|
||||
// 使用智能移除
|
||||
if (snippetString.trim()) {
|
||||
const removed = removeTomlSnippet(tomlString, snippetString);
|
||||
return {
|
||||
updatedConfig: removed,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
updatedConfig: tomlString,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// 检查 TOML 配置是否已包含通用配置片段
|
||||
export const hasTomlCommonConfigSnippet = (
|
||||
tomlString: string,
|
||||
@@ -859,32 +288,6 @@ export const hasTomlCommonConfigSnippet = (
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 替换 TOML 通用配置片段(用于同步更新)
|
||||
* 先移除旧的通用配置,再添加新的通用配置
|
||||
*/
|
||||
export const replaceTomlCommonConfigSnippet = (
|
||||
tomlString: string,
|
||||
oldSnippet: string,
|
||||
newSnippet: string,
|
||||
): UpdateTomlCommonConfigResult => {
|
||||
// 先清理旧版标记块(兼容性)
|
||||
let configWithoutOld = stripTomlCommonConfigBlock(tomlString);
|
||||
|
||||
// 通过内容匹配移除旧片段
|
||||
if (oldSnippet.trim() && configWithoutOld.includes(oldSnippet.trim())) {
|
||||
configWithoutOld = configWithoutOld.replace(oldSnippet.trim(), "");
|
||||
// 清理多余的空行
|
||||
configWithoutOld = configWithoutOld.replace(/\n{3,}/g, "\n\n").trim();
|
||||
if (configWithoutOld) {
|
||||
configWithoutOld += "\n";
|
||||
}
|
||||
}
|
||||
|
||||
// 添加新的通用配置
|
||||
return updateTomlCommonConfigSnippet(configWithoutOld, newSnippet, true);
|
||||
};
|
||||
|
||||
// ========== Codex base_url utils ==========
|
||||
|
||||
// 从 Codex 的 TOML 配置文本中提取 base_url(支持单/双引号)
|
||||
|
||||
Reference in New Issue
Block a user