fix: improve VS Code config sync reliability and TOML parsing
- Support both single and double quotes in TOML base_url parsing - Fix regex capture group index for consistent parsing - Improve "applied" status detection by comparing normalized URLs - Add validation to prevent empty base_url writes for non-official providers - Enhance error handling with user-friendly notifications
This commit is contained in:
@@ -3,7 +3,7 @@ import { Provider } from "../types";
|
|||||||
import { Play, Edit3, Trash2, CheckCircle2, Users } from "lucide-react";
|
import { Play, Edit3, Trash2, CheckCircle2, Users } from "lucide-react";
|
||||||
import { buttonStyles, cardStyles, badgeStyles, cn } from "../lib/styles";
|
import { buttonStyles, cardStyles, badgeStyles, cn } from "../lib/styles";
|
||||||
import { AppType } from "../lib/tauri-api";
|
import { AppType } from "../lib/tauri-api";
|
||||||
import { applyProviderToVSCode, detectApplied } from "../utils/vscodeSettings";
|
import { applyProviderToVSCode, detectApplied, normalizeBaseUrl } from "../utils/vscodeSettings";
|
||||||
// 不再在列表中显示分类徽章,避免造成困惑
|
// 不再在列表中显示分类徽章,避免造成困惑
|
||||||
|
|
||||||
interface ProviderListProps {
|
interface ProviderListProps {
|
||||||
@@ -35,8 +35,9 @@ const ProviderList: React.FC<ProviderListProps> = ({
|
|||||||
}
|
}
|
||||||
// Codex: 从 TOML 配置中解析 base_url
|
// Codex: 从 TOML 配置中解析 base_url
|
||||||
if (typeof cfg?.config === "string" && cfg.config.includes("base_url")) {
|
if (typeof cfg?.config === "string" && cfg.config.includes("base_url")) {
|
||||||
const match = cfg.config.match(/base_url\s*=\s*"([^"]+)"/);
|
// 支持单/双引号
|
||||||
if (match && match[1]) return match[1];
|
const match = cfg.config.match(/base_url\s*=\s*(['"])([^'\"]+)\1/);
|
||||||
|
if (match && match[2]) return match[2];
|
||||||
}
|
}
|
||||||
return "未配置官网地址";
|
return "未配置官网地址";
|
||||||
} catch {
|
} catch {
|
||||||
@@ -58,8 +59,9 @@ const ProviderList: React.FC<ProviderListProps> = ({
|
|||||||
const cfg = provider.settingsConfig;
|
const cfg = provider.settingsConfig;
|
||||||
const text = typeof cfg?.config === "string" ? cfg.config : "";
|
const text = typeof cfg?.config === "string" ? cfg.config : "";
|
||||||
if (!text) return undefined;
|
if (!text) return undefined;
|
||||||
const m = text.match(/base_url\s*=\s*"([^"]+)"/);
|
// 支持单/双引号
|
||||||
return m && m[1] ? m[1] : undefined;
|
const m = text.match(/base_url\s*=\s*(['"])([^'\"]+)\1/);
|
||||||
|
return m && m[2] ? m[2] : undefined;
|
||||||
} catch {
|
} catch {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
@@ -83,15 +85,22 @@ const ProviderList: React.FC<ProviderListProps> = ({
|
|||||||
try {
|
try {
|
||||||
const content = await window.api.readVSCodeSettings();
|
const content = await window.api.readVSCodeSettings();
|
||||||
const detected = detectApplied(content);
|
const detected = detectApplied(content);
|
||||||
// 认为“已应用”的条件:存在任意一个我们管理的键
|
// 认为“已应用”的条件(非官方供应商):VS Code 中的 apiBase 与当前供应商的 base_url 完全一致
|
||||||
const applied = detected.hasApiBase || detected.hasPreferredAuthMethod;
|
const current = providers[currentProviderId];
|
||||||
|
let applied = false;
|
||||||
|
if (current && current.category !== "official") {
|
||||||
|
const base = getCodexBaseUrl(current);
|
||||||
|
if (detected.apiBase && base) {
|
||||||
|
applied = normalizeBaseUrl(detected.apiBase) === normalizeBaseUrl(base);
|
||||||
|
}
|
||||||
|
}
|
||||||
setVscodeAppliedFor(applied ? currentProviderId : null);
|
setVscodeAppliedFor(applied ? currentProviderId : null);
|
||||||
} catch {
|
} catch {
|
||||||
setVscodeAppliedFor(null);
|
setVscodeAppliedFor(null);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
check();
|
check();
|
||||||
}, [appType, currentProviderId]);
|
}, [appType, currentProviderId, providers]);
|
||||||
|
|
||||||
const handleApplyToVSCode = async (provider: Provider) => {
|
const handleApplyToVSCode = async (provider: Provider) => {
|
||||||
try {
|
try {
|
||||||
@@ -104,6 +113,15 @@ const ProviderList: React.FC<ProviderListProps> = ({
|
|||||||
const raw = await window.api.readVSCodeSettings();
|
const raw = await window.api.readVSCodeSettings();
|
||||||
|
|
||||||
const isOfficial = provider.category === "official";
|
const isOfficial = provider.category === "official";
|
||||||
|
// 非官方且缺少 base_url 时直接报错并返回,避免“空写入”假成功
|
||||||
|
if (!isOfficial) {
|
||||||
|
const parsed = getCodexBaseUrl(provider);
|
||||||
|
if (!parsed) {
|
||||||
|
onNotify?.("当前配置缺少 base_url,无法写入 VS Code", "error", 4000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const baseUrl = isOfficial ? undefined : getCodexBaseUrl(provider);
|
const baseUrl = isOfficial ? undefined : getCodexBaseUrl(provider);
|
||||||
const next = applyProviderToVSCode(raw, { baseUrl, isOfficial });
|
const next = applyProviderToVSCode(raw, { baseUrl, isOfficial });
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user