()
| 132 | } |
| 133 | |
| 134 | function createWebTransport(): ApiTransport { |
| 135 | const noop = () => () => {} |
| 136 | |
| 137 | async function fetchJson<T>(url: string, options?: RequestInit): Promise<T> { |
| 138 | const resp = await fetchWithAuth(url, options) |
| 139 | if (!resp.ok) { |
| 140 | const body = await resp.json().catch(() => ({})) |
| 141 | throw new Error((body as any)?.error || `HTTP ${resp.status}`) |
| 142 | } |
| 143 | return resp.json() |
| 144 | } |
| 145 | |
| 146 | return { |
| 147 | getConfig: () => fetchJson('/_web/automation/config'), |
| 148 | |
| 149 | getStatus: async () => ({ |
| 150 | running: true, |
| 151 | port: null, |
| 152 | startedAt: null, |
| 153 | error: null, |
| 154 | }), |
| 155 | |
| 156 | setEnabled: async () => ({ |
| 157 | running: true, |
| 158 | port: null, |
| 159 | startedAt: null, |
| 160 | error: null, |
| 161 | }), |
| 162 | |
| 163 | setPort: async () => ({ |
| 164 | running: true, |
| 165 | port: null, |
| 166 | startedAt: null, |
| 167 | error: null, |
| 168 | }), |
| 169 | |
| 170 | regenerateToken: async () => fetchJson('/_web/automation/config'), |
| 171 | |
| 172 | onStartupError: noop, |
| 173 | |
| 174 | getDataSources: () => fetchJson('/_web/automation/data-sources'), |
| 175 | |
| 176 | addDataSource: (partial) => |
| 177 | fetchJson('/_web/automation/data-sources', { |
| 178 | method: 'POST', |
| 179 | headers: { 'Content-Type': 'application/json' }, |
| 180 | body: JSON.stringify(partial), |
| 181 | }), |
| 182 | |
| 183 | updateDataSource: (id, updates) => |
| 184 | fetchJson(`/_web/automation/data-sources/${id}`, { |
| 185 | method: 'PATCH', |
| 186 | headers: { 'Content-Type': 'application/json' }, |
| 187 | body: JSON.stringify(updates), |
| 188 | }), |
| 189 | |
| 190 | deleteDataSource: async (id) => { |
| 191 | const result = await fetchJson<{ success: boolean }>(`/_web/automation/data-sources/${id}`, { |
no test coverage detected