Files
DeskClaw/electron/api/routes/settings.ts
2026-03-21 17:09:08 +08:00

113 lines
3.8 KiB
TypeScript

import type { IncomingMessage, ServerResponse } from 'http';
import { applyProxySettings } from '../../main/proxy';
import { syncLaunchAtStartupSettingFromStore } from '../../main/launch-at-startup';
import { syncProxyConfigToOpenClaw } from '../../utils/openclaw-proxy';
import { getAllSettings, getSetting, resetSettings, setSetting, type AppSettings } from '../../utils/store';
import type { HostApiContext } from '../context';
import { parseJsonBody, sendJson } from '../route-utils';
async function handleProxySettingsChange(ctx: HostApiContext): Promise<void> {
const settings = await getAllSettings();
await syncProxyConfigToOpenClaw(settings, { preserveExistingWhenDisabled: false });
await applyProxySettings(settings);
if (ctx.gatewayManager.getStatus().state === 'running') {
await ctx.gatewayManager.restart();
}
}
function patchTouchesProxy(patch: Partial<AppSettings>): boolean {
return Object.keys(patch).some((key) => (
key === 'proxyEnabled' ||
key === 'proxyServer' ||
key === 'proxyHttpServer' ||
key === 'proxyHttpsServer' ||
key === 'proxyAllServer' ||
key === 'proxyBypassRules'
));
}
function patchTouchesLaunchAtStartup(patch: Partial<AppSettings>): boolean {
return Object.prototype.hasOwnProperty.call(patch, 'launchAtStartup');
}
export async function handleSettingsRoutes(
req: IncomingMessage,
res: ServerResponse,
url: URL,
ctx: HostApiContext,
): Promise<boolean> {
if (url.pathname === '/api/settings' && req.method === 'GET') {
sendJson(res, 200, await getAllSettings());
return true;
}
if (url.pathname === '/api/settings' && req.method === 'PUT') {
try {
const patch = await parseJsonBody<Partial<AppSettings>>(req);
const entries = Object.entries(patch) as Array<[keyof AppSettings, AppSettings[keyof AppSettings]]>;
for (const [key, value] of entries) {
await setSetting(key, value);
}
if (patchTouchesProxy(patch)) {
await handleProxySettingsChange(ctx);
}
if (patchTouchesLaunchAtStartup(patch)) {
await syncLaunchAtStartupSettingFromStore();
}
sendJson(res, 200, { success: true });
} catch (error) {
sendJson(res, 500, { success: false, error: String(error) });
}
return true;
}
if (url.pathname.startsWith('/api/settings/') && req.method === 'GET') {
const key = url.pathname.slice('/api/settings/'.length) as keyof AppSettings;
try {
sendJson(res, 200, { value: await getSetting(key) });
} catch (error) {
sendJson(res, 404, { success: false, error: String(error) });
}
return true;
}
if (url.pathname.startsWith('/api/settings/') && req.method === 'PUT') {
const key = url.pathname.slice('/api/settings/'.length) as keyof AppSettings;
try {
const body = await parseJsonBody<{ value: AppSettings[keyof AppSettings] }>(req);
await setSetting(key, body.value);
if (
key === 'proxyEnabled' ||
key === 'proxyServer' ||
key === 'proxyHttpServer' ||
key === 'proxyHttpsServer' ||
key === 'proxyAllServer' ||
key === 'proxyBypassRules'
) {
await handleProxySettingsChange(ctx);
}
if (key === 'launchAtStartup') {
await syncLaunchAtStartupSettingFromStore();
}
sendJson(res, 200, { success: true });
} catch (error) {
sendJson(res, 500, { success: false, error: String(error) });
}
return true;
}
if (url.pathname === '/api/settings/reset' && req.method === 'POST') {
try {
await resetSettings();
await handleProxySettingsChange(ctx);
await syncLaunchAtStartupSettingFromStore();
sendJson(res, 200, { success: true, settings: await getAllSettings() });
} catch (error) {
sendJson(res, 500, { success: false, error: String(error) });
}
return true;
}
return false;
}