Express API server on :3100 exposing all Coolify operations: - CRUD for apps, env vars, servers - Full upsert pipeline (create/update + env + route + deploy) - Drift detection, Traefik route management via SSH - Scalar API docs at /reference, OpenAPI 3.1 spec UI: New Coolify page with app cards, deploy/delete actions, env var expansion. Sidebar nav + React Query hooks + fetch client. Both UI and LLM/CLI use the same HTTP endpoints. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
29 lines
883 B
JavaScript
29 lines
883 B
JavaScript
/**
|
|
* Authenticated fetch wrapper for the Coolify API.
|
|
* Ported from gitea.repo.management/electron/main.cjs:166-183
|
|
*/
|
|
export async function coolifyFetch(config, apiPath, options = {}) {
|
|
const base = (config.coolify?.apiUrl || '').replace(/\/$/, '');
|
|
const token = config.coolify?.apiToken || '';
|
|
const url = `${base}/api/v1${apiPath}`;
|
|
|
|
const headers = {
|
|
'Authorization': `Bearer ${token}`,
|
|
'Content-Type': 'application/json',
|
|
...(options.headers || {})
|
|
};
|
|
|
|
const res = await fetch(url, { ...options, headers });
|
|
|
|
if (!res.ok) {
|
|
const text = await res.text();
|
|
const err = new Error(`Coolify ${options.method || 'GET'} ${apiPath} failed: ${res.status} ${text}`);
|
|
err.status = res.status;
|
|
throw err;
|
|
}
|
|
|
|
const ct = res.headers.get('content-type') || '';
|
|
if (ct.includes('application/json')) return res.json();
|
|
return res.text();
|
|
}
|