76 lines
3.1 KiB
JavaScript
76 lines
3.1 KiB
JavaScript
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] })
|
|
},
|
|
}
|