3da7ea6408
- Remove clone_mode/branch/new_branch from createInstance API helper - Remove clone mode UI and branch fields from CreateSessionForm Remaining: wire workspace_id in form/tool-starter, remove session-card badge, tests
218 lines
5.3 KiB
TypeScript
218 lines
5.3 KiB
TypeScript
import { AxiosError } from "axios";
|
|
import { apiClient } from "./client";
|
|
|
|
export interface ToolInstance {
|
|
id: string;
|
|
name: string;
|
|
display_name: string;
|
|
tool_type_id: string;
|
|
tool_type_name: string;
|
|
tool_type_interfaces: string[];
|
|
status: string;
|
|
url: string | null;
|
|
port: number | null;
|
|
selected_config_profile_id: string | null;
|
|
ssh_key_ids: string[];
|
|
created_at: string;
|
|
}
|
|
|
|
export interface Session {
|
|
id: string;
|
|
display_name: string;
|
|
tool_type_name: string;
|
|
tool_icon: string;
|
|
tool_type_interfaces: string[];
|
|
repository_name: string;
|
|
repository_id: string;
|
|
project_name: string;
|
|
project_id: string;
|
|
workspace_name?: string | null;
|
|
status: string;
|
|
url: string | null;
|
|
container_status?: string;
|
|
probe_status?: string;
|
|
created_at?: string;
|
|
}
|
|
|
|
export async function listInstances(
|
|
projectId: string,
|
|
repoId: string,
|
|
): Promise<ToolInstance[]> {
|
|
const response = await apiClient.get(
|
|
`/projects/${projectId}/repositories/${repoId}/instances`,
|
|
);
|
|
return response.data.instances;
|
|
}
|
|
|
|
export async function createInstance(
|
|
projectId: string,
|
|
repoId: string,
|
|
toolTypeId: string,
|
|
displayName?: string,
|
|
workspaceId?: string,
|
|
configProfileId?: string,
|
|
sshKeyIds?: string[],
|
|
): Promise<ToolInstance> {
|
|
const response = await apiClient.post(
|
|
`/projects/${projectId}/repositories/${repoId}/instances`,
|
|
{
|
|
tool_type_id: toolTypeId,
|
|
display_name: displayName,
|
|
workspace_id: workspaceId || undefined,
|
|
config_profile_id: configProfileId,
|
|
ssh_key_ids: sshKeyIds || [],
|
|
},
|
|
);
|
|
return response.data;
|
|
}
|
|
|
|
export async function startInstance(
|
|
projectId: string,
|
|
repoId: string,
|
|
instanceId: string,
|
|
configProfileId?: string,
|
|
sshKeyIds?: string[],
|
|
retries = 2,
|
|
): Promise<{ status: string; url?: string }> {
|
|
try {
|
|
const response = await apiClient.post(
|
|
`/projects/${projectId}/repositories/${repoId}/instances/${instanceId}/start`,
|
|
{ config_profile_id: configProfileId, ssh_key_ids: sshKeyIds || [] },
|
|
);
|
|
return response.data;
|
|
} catch (error) {
|
|
// Retry on network errors (e.g. Docker creating network interfaces)
|
|
const axiosError = error as AxiosError;
|
|
if (retries > 0 && !axiosError.response) {
|
|
await new Promise((r) => setTimeout(r, 1500));
|
|
return startInstance(
|
|
projectId,
|
|
repoId,
|
|
instanceId,
|
|
configProfileId,
|
|
sshKeyIds,
|
|
retries - 1,
|
|
);
|
|
}
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
export async function stopInstance(
|
|
projectId: string,
|
|
repoId: string,
|
|
instanceId: string,
|
|
): Promise<{ status: string }> {
|
|
const response = await apiClient.post(
|
|
`/projects/${projectId}/repositories/${repoId}/instances/${instanceId}/stop`,
|
|
);
|
|
return response.data;
|
|
}
|
|
|
|
export async function restartInstance(
|
|
projectId: string,
|
|
repoId: string,
|
|
instanceId: string,
|
|
configProfileId?: string,
|
|
sshKeyIds?: string[],
|
|
retries = 2,
|
|
): Promise<{ status: string; url?: string }> {
|
|
try {
|
|
const response = await apiClient.post(
|
|
`/projects/${projectId}/repositories/${repoId}/instances/${instanceId}/restart`,
|
|
{ config_profile_id: configProfileId, ssh_key_ids: sshKeyIds || [] },
|
|
);
|
|
return response.data;
|
|
} catch (error) {
|
|
// Retry on network errors (e.g. Docker creating network interfaces)
|
|
const axiosError = error as AxiosError;
|
|
if (retries > 0 && !axiosError.response) {
|
|
await new Promise((r) => setTimeout(r, 1500));
|
|
return restartInstance(
|
|
projectId,
|
|
repoId,
|
|
instanceId,
|
|
configProfileId,
|
|
sshKeyIds,
|
|
retries - 1,
|
|
);
|
|
}
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
export async function deleteInstance(
|
|
projectId: string,
|
|
repoId: string,
|
|
instanceId: string,
|
|
force?: boolean,
|
|
): Promise<void> {
|
|
await apiClient.delete(
|
|
`/projects/${projectId}/repositories/${repoId}/instances/${instanceId}`,
|
|
{ params: { force } },
|
|
);
|
|
}
|
|
|
|
export async function getInstance(
|
|
projectId: string,
|
|
repoId: string,
|
|
instanceId: string,
|
|
): Promise<ToolInstance> {
|
|
const response = await apiClient.get(
|
|
`/projects/${projectId}/repositories/${repoId}/instances/${instanceId}`,
|
|
);
|
|
return response.data;
|
|
}
|
|
|
|
export async function getUserSessions(): Promise<Session[]> {
|
|
const response = await apiClient.get("/users/me/sessions");
|
|
return response.data.sessions;
|
|
}
|
|
|
|
export interface InstanceHealth {
|
|
healthy: boolean;
|
|
container_status: string;
|
|
container_health: string | null;
|
|
container_exit_code: number | null;
|
|
tunnel_status: string;
|
|
tunnel_status_code: number | null;
|
|
probe_status: string;
|
|
last_probe_output: string | null;
|
|
error: string | null;
|
|
}
|
|
|
|
export async function checkInstanceHealth(
|
|
projectId: string,
|
|
repoId: string,
|
|
instanceId: string,
|
|
): Promise<InstanceHealth> {
|
|
const response = await apiClient.get(
|
|
`/projects/${projectId}/repositories/${repoId}/instances/${instanceId}/health`,
|
|
);
|
|
return response.data;
|
|
}
|
|
|
|
export async function renameInstance(
|
|
projectId: string,
|
|
repoId: string,
|
|
instanceId: string,
|
|
displayName: string,
|
|
): Promise<{ id: string; name: string; display_name: string }> {
|
|
const response = await apiClient.patch(
|
|
`/projects/${projectId}/repositories/${repoId}/instances/${instanceId}`,
|
|
{ display_name: displayName },
|
|
);
|
|
return response.data;
|
|
}
|
|
|
|
export async function recreateInstanceTunnel(
|
|
projectId: string,
|
|
repoId: string,
|
|
instanceId: string,
|
|
): Promise<{ status: string; url?: string }> {
|
|
const response = await apiClient.post(
|
|
`/projects/${projectId}/repositories/${repoId}/instances/${instanceId}/recreate-tunnel`,
|
|
);
|
|
return response.data;
|
|
}
|