import { loadContext } from './config/headplane' export class HeadscaleError extends Error { status: number constructor(message: string, status: number) { super(message) this.name = 'HeadscaleError' this.status = status } } export class FatalError extends Error { constructor() { super('The Headscale server is not accessible or the supplied API key is invalid') this.name = 'FatalError' } } export async function pull(url: string, key: string) { const context = await loadContext() const prefix = context.headscaleUrl const response = await fetch(`${prefix}/api/${url}`, { headers: { Authorization: `Bearer ${key}`, }, }) if (!response.ok) { throw new HeadscaleError(await response.text(), response.status) } return (response.json() as Promise) } export async function post(url: string, key: string, body?: unknown) { const context = await loadContext() const prefix = context.headscaleUrl const response = await fetch(`${prefix}/api/${url}`, { method: 'POST', body: body ? JSON.stringify(body) : undefined, headers: { Authorization: `Bearer ${key}`, }, }) if (!response.ok) { throw new HeadscaleError(await response.text(), response.status) } return (response.json() as Promise) } export async function put(url: string, key: string, body?: unknown) { const context = await loadContext() const prefix = context.headscaleUrl const response = await fetch(`${prefix}/api/${url}`, { method: 'PUT', body: body ? JSON.stringify(body) : undefined, headers: { Authorization: `Bearer ${key}`, }, }) if (!response.ok) { throw new HeadscaleError(await response.text(), response.status) } return (response.json() as Promise) } export async function del(url: string, key: string) { const context = await loadContext() const prefix = context.headscaleUrl const response = await fetch(`${prefix}/api/${url}`, { method: 'DELETE', headers: { Authorization: `Bearer ${key}`, }, }) if (!response.ok) { throw new HeadscaleError(await response.text(), response.status) } return (response.json() as Promise) }