Add full REST API for all deployment operations (projects, servers, docker)
Port all IPC handlers to HTTP endpoints so the UI and LLM use the same API. Adds routes/projects.js (scan, compare, init), routes/servers.js (CRUD, containers, logs), routes/docker.js (build, deploy, pull, vscode-diff). Enhanced ssh.js with full SSHService class (SFTP upload/download). Updated renderer api.js to use fetch instead of window.api IPC. Added concurrently for npm run dev (API + Vite + Electron). OpenAPI spec now covers all 24 endpoints. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,45 +1,4 @@
|
||||
const api = window.api;
|
||||
|
||||
export const serverApi = {
|
||||
getAll: () => api.getServers(),
|
||||
save: (server) => api.saveServer(server),
|
||||
delete: (id) => api.deleteServer(id),
|
||||
};
|
||||
|
||||
export const projectApi = {
|
||||
scanLocal: () => api.scanLocalProjects(),
|
||||
scanServer: (serverId) => api.scanServer(serverId),
|
||||
getRunningContainers: (serverId) => api.getRunningContainers(serverId),
|
||||
compare: (data) => api.compareProject(data),
|
||||
init: (projectPath) => api.initProject(projectPath),
|
||||
};
|
||||
|
||||
export const deployApi = {
|
||||
buildTar: (projectPath) => api.buildTar(projectPath),
|
||||
deploy: (data) => api.deployProject(data),
|
||||
};
|
||||
|
||||
export const syncApi = {
|
||||
pullFile: (data) => api.pullFile(data),
|
||||
pullFiles: (data) => api.pullFiles(data),
|
||||
};
|
||||
|
||||
export const logsApi = {
|
||||
getContainerLogs: (data) => api.getContainerLogs(data),
|
||||
};
|
||||
|
||||
export const configApi = {
|
||||
get: () => api.getConfig(),
|
||||
save: (config) => api.saveConfig(config),
|
||||
};
|
||||
|
||||
export const toolsApi = {
|
||||
openVSCodeDiff: (data) => api.openVSCodeDiff(data),
|
||||
};
|
||||
|
||||
// ─── Coolify API (HTTP fetch to Express server) ────────────────────
|
||||
|
||||
const COOLIFY_BASE = '/api/coolify';
|
||||
// ─── Shared fetch helper ────────────────────────────────────────────
|
||||
|
||||
async function fetchJson(url, options) {
|
||||
const res = await fetch(url, {
|
||||
@@ -53,6 +12,77 @@ async function fetchJson(url, options) {
|
||||
return res.json();
|
||||
}
|
||||
|
||||
// ─── Deployment Servers (CRUD + scanning) ───────────────────────────
|
||||
|
||||
export const serverApi = {
|
||||
getAll: () => fetchJson('/api/servers'),
|
||||
save: (server) => fetchJson('/api/servers', { method: 'POST', body: JSON.stringify(server) }),
|
||||
delete: (id) => fetchJson(`/api/servers/${id}`, { method: 'DELETE' }),
|
||||
scan: (serverId) => fetchJson(`/api/servers/${serverId}/scan`),
|
||||
getRunningContainers: (serverId) => fetchJson(`/api/servers/${serverId}/containers`),
|
||||
getLogs: ({ serverId, containerName, remotePath, lines }) => {
|
||||
const params = new URLSearchParams();
|
||||
if (containerName) params.set('containerName', containerName);
|
||||
if (remotePath) params.set('remotePath', remotePath);
|
||||
if (lines) params.set('lines', String(lines));
|
||||
return fetchJson(`/api/servers/${serverId}/logs?${params}`);
|
||||
},
|
||||
};
|
||||
|
||||
// ─── Projects (scan, compare, init) ────────────────────────────────
|
||||
|
||||
export const projectApi = {
|
||||
scanLocal: () => fetchJson('/api/projects'),
|
||||
scanServer: (serverId) => fetchJson(`/api/servers/${serverId}/scan`).then(r => r.deployed || []),
|
||||
getRunningContainers: (serverId) => fetchJson(`/api/servers/${serverId}/containers`).then(r => r.containers || []),
|
||||
compare: (data) => fetchJson('/api/projects/compare', { method: 'POST', body: JSON.stringify(data) }),
|
||||
init: (projectPath) => fetchJson('/api/projects/init', { method: 'POST', body: JSON.stringify({ projectPath }) }),
|
||||
};
|
||||
|
||||
// ─── Docker (build, deploy, pull) ──────────────────────────────────
|
||||
|
||||
export const deployApi = {
|
||||
buildTar: (projectPath) => fetchJson('/api/docker/build', { method: 'POST', body: JSON.stringify({ projectPath }) }),
|
||||
deploy: (data) => fetchJson('/api/docker/deploy', { method: 'POST', body: JSON.stringify(data) }),
|
||||
};
|
||||
|
||||
export const syncApi = {
|
||||
pullFile: (data) => fetchJson('/api/docker/pull', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ serverId: data.serverId, files: [{ name: data.remotePath, remotePath: data.remotePath, localPath: data.localPath, type: data.isDirectory ? 'directory' : 'file' }] }),
|
||||
}).then(r => r),
|
||||
pullFiles: (data) => fetchJson('/api/docker/pull', { method: 'POST', body: JSON.stringify(data) }),
|
||||
};
|
||||
|
||||
// ─── Config ─────────────────────────────────────────────────────────
|
||||
|
||||
export const configApi = {
|
||||
get: () => fetchJson('/api/servers').then(servers => {
|
||||
// Reconstruct config shape from servers list
|
||||
return { servers };
|
||||
}),
|
||||
save: (config) => {
|
||||
// Save each server individually
|
||||
return Promise.all((config.servers || []).map(s => serverApi.save(s)));
|
||||
},
|
||||
};
|
||||
|
||||
export const logsApi = {
|
||||
getContainerLogs: (data) => serverApi.getLogs(data),
|
||||
};
|
||||
|
||||
// ─── Coolify API (HTTP fetch to Express server) ────────────────────
|
||||
|
||||
const COOLIFY_BASE = '/api/coolify';
|
||||
|
||||
// ─── Tools (VS Code diff — opens locally, not via API) ─────────────
|
||||
|
||||
export const toolsApi = {
|
||||
openVSCodeDiff: (data) => fetchJson('/api/docker/vscode-diff', { method: 'POST', body: JSON.stringify(data) }),
|
||||
};
|
||||
|
||||
// ─── Coolify API (HTTP fetch to Express server) ────────────────────
|
||||
|
||||
export const coolifyApi = {
|
||||
listApps: () => fetchJson(`${COOLIFY_BASE}/apps`),
|
||||
findApp: (name) => fetchJson(`${COOLIFY_BASE}/apps/find/${encodeURIComponent(name)}`),
|
||||
|
||||
Reference in New Issue
Block a user