Files

65 lines
2.3 KiB
TypeScript

const BASE_URL = import.meta.env.VITE_API_URL ?? '';
export type ServiceStatus = 'running' | 'stopped' | 'unhealthy' | 'unknown';
export interface InfraService {
name: string;
container: string;
status: ServiceStatus;
ports: string[];
uptime?: string;
}
export interface InfraStatusResponse {
services: InfraService[];
checkedAt: string;
}
export async function getInfraStatus(): Promise<InfraStatusResponse> {
const res = await fetch(`${BASE_URL}/api/infra/status`);
if (!res.ok) throw new Error('Failed to fetch infra status');
return res.json();
}
export async function infraServiceAction(
service: string,
action: 'start' | 'stop' | 'restart'
): Promise<void> {
const res = await fetch(`${BASE_URL}/api/infra/${service}/${action}`, { method: 'POST' });
if (!res.ok) throw new Error(`Failed to ${action} ${service}`);
}
export function streamComposeUp(onLine: (line: string) => void, onDone: () => void): EventSource {
const src = new EventSource(`${BASE_URL}/api/infra/compose/up/stream`);
src.onmessage = (e) => onLine(e.data);
src.onerror = () => { onDone(); src.close(); };
return src;
}
/** Force-recreates all containers and removes orphans — fixes name-conflict errors. */
export function streamComposeForceUp(onLine: (line: string) => void, onDone: () => void): EventSource {
const src = new EventSource(`${BASE_URL}/api/infra/compose/up-force/stream`);
src.onmessage = (e) => onLine(e.data);
src.onerror = () => { onDone(); src.close(); };
return src;
}
/**
* Nuke & Recreate — force-removes every known platform container by name first
* (kills orphans that --remove-orphans won't touch), then runs compose up fresh.
* Use this when Force Recreate still fails with "container name already in use".
*/
export function streamComposeNuke(onLine: (line: string) => void, onDone: () => void): EventSource {
const src = new EventSource(`${BASE_URL}/api/infra/compose/nuke/stream`);
src.onmessage = (e) => onLine(e.data);
src.onerror = () => { onDone(); src.close(); };
return src;
}
export function streamComposeDown(onLine: (line: string) => void, onDone: () => void): EventSource {
const src = new EventSource(`${BASE_URL}/api/infra/compose/down/stream`);
src.onmessage = (e) => onLine(e.data);
src.onerror = () => { onDone(); src.close(); };
return src;
}