import { HttpError } from 'ra-core' async function request(path = '', options) { const response = await fetch(`/api${path}`, options) if (!response.ok) { const body = await response.json().catch(() => ({})) throw new HttpError(body.error || `请求失败 (${response.status})`, response.status, body) } return response.status === 204 ? null : response.json() } const jsonOptions = (method, data) => ({ method, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data), }) const unsupported = (resource, operation) => Promise.reject(new Error(`${resource} 不支持 ${operation}`)) const resourcePaths = { browsers: '/browsers', 'browser-images': '/browser-images', gateways: '/gateways', accounts: '/phase-a/accounts', 'network-exits': '/network-exits', } export const dataProvider = { async getList(resource) { const path = resourcePaths[resource] if (!path) return unsupported(resource, 'getList') const records = await request(path) return { data: records.map(record => ({ ...record, id: record.id ?? record.alias ?? record.version ?? record.name })), total: records.length } }, async create(resource, { data }) { const path = resourcePaths[resource] if (!path) return unsupported(resource, 'create') const created = await request(path, jsonOptions('POST', data)) return { data: { ...data, ...created, id: created?.alias ?? created?.version ?? created?.name ?? data.alias } } }, async update(resource, { id, data }) { const path = resourcePaths[resource] if (!path || resource === 'browsers') return unsupported(resource, 'update') // browser-images 的 PUT 不接受 version 字段(路径已携带),透传其余字段。 const { version: _ignored, ...rest } = data ?? {} await request(`${path}/${encodeURIComponent(id)}`, jsonOptions('PUT', rest)) return { data: { ...rest, id } } }, async delete(resource, { id }) { const path = resourcePaths[resource] if (!path) return unsupported(resource, 'delete') await request(`${path}/${encodeURIComponent(id)}`, { method: 'DELETE' }) return { data: { id } } }, getOne: resource => unsupported(resource, 'getOne'), getMany: resource => unsupported(resource, 'getMany'), getManyReference: resource => unsupported(resource, 'getManyReference'), updateMany: resource => unsupported(resource, 'updateMany'), deleteMany: resource => unsupported(resource, 'deleteMany'), // 环境的领域动作保持显式动词,不伪装成 CRUD update。 async browserAction(alias, action, data) { if (action === 'upgrade') { await request(`/browsers/${encodeURIComponent(alias)}/upgrade`, jsonOptions('POST', data)) return } const paths = { start: [`/browsers/${encodeURIComponent(alias)}/start`, 'POST'], stop: [`/browsers/${encodeURIComponent(alias)}/stop`, 'POST'], recycle: [`/browsers/${encodeURIComponent(alias)}`, 'DELETE'], } const target = paths[action] if (!target) throw new Error(`未知运行环境操作: ${action}`) await request(target[0], { method: target[1] }) }, }