async function request(url, options = {}) { const response = await fetch(url, { ...options, headers: { 'content-type': 'application/json', ...(options.headers || {}), }, }); const data = await response.json().catch(() => ({})); if (!response.ok || data?.success === false) { const error = new Error(data?.error || `Запрос ${url} завершился ошибкой ${response.status}`); error.status = response.status; throw error; } return data; } export const api = { state: () => request('/api/state'), subscription: { validate: (url, signal) => request('/api/subscription/validate', { method: 'POST', body: JSON.stringify({ url }), signal, }), fetch: (url) => request('/api/subscription/fetch', { method: 'POST', body: JSON.stringify({ url }), }), refresh: () => request('/api/subscription/refresh', { method: 'POST' }), forget: () => request('/api/subscription', { method: 'DELETE' }), }, apply: (selectedTag) => request('/api/apply', { method: 'POST', body: JSON.stringify({ selectedTag }), }), gatewayAuto: { setEnabled: (enabled) => request('/api/gateway-auto', { method: 'POST', body: JSON.stringify({ enabled }), }), }, singbox: { stop: () => request('/api/singbox/stop', { method: 'POST' }), restart: () => request('/api/singbox/restart', { method: 'POST' }), }, servers: { pingAll: () => request('/api/servers/ping-all', { method: 'POST' }), }, };