29 lines
1.8 KiB
JavaScript
29 lines
1.8 KiB
JavaScript
export function normalizeTargetUrl(raw) {
|
|
const url = new URL(raw)
|
|
if (!['http:', 'https:'].includes(url.protocol)) throw new Error('target URL must use http or https')
|
|
url.hash = ''; url.search = ''
|
|
return url.toString().replace(/\/$/, '')
|
|
}
|
|
|
|
export function createApiClient({ fetchImpl = globalThis.fetch } = {}) {
|
|
const request = async (url, options) => {
|
|
const response = await fetchImpl(url, options)
|
|
const data = await response.json().catch(() => ({}))
|
|
if (!response.ok) throw new Error(data.error || `HTTP ${response.status}`)
|
|
return data
|
|
}
|
|
return {
|
|
request,
|
|
config: () => request('/api/config'),
|
|
catalog: () => request('/api/catalog'),
|
|
status: () => request('/api/status'),
|
|
proxy: (id, endpoint, options) => fetchImpl(`/api/proxy/${encodeURIComponent(id)}${endpoint}`, options),
|
|
prepareConfirmation: payload => request('/api/proxy-confirmations/prepare', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(payload) }),
|
|
createInstance: payload => request('/api/instances', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(payload) }),
|
|
updateInstance: (id, payload) => request(`/api/instances/${encodeURIComponent(id)}`, { method: 'PUT', headers: { 'content-type': 'application/json' }, body: JSON.stringify(payload) }),
|
|
deleteInstance: id => request(`/api/instances/${encodeURIComponent(id)}`, { method: 'DELETE' }),
|
|
login: (id, password) => request(`/api/instances/${encodeURIComponent(id)}/login`, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(password === undefined ? {} : { password }) }),
|
|
logout: id => request(`/api/instances/${encodeURIComponent(id)}/logout`, { method: 'POST' }),
|
|
}
|
|
}
|