Files
PaperClipAI/ui/src/api/projects.ts
T
2026-08-01 22:54:01 +00:00

79 lines
3.7 KiB
TypeScript

import type {
Project,
ProjectAccessMember,
ProjectWorkspace,
WorkspaceOperation,
WorkspaceRuntimeControlTarget,
} from "@paperclipai/shared";
import { api } from "./client";
import { sanitizeWorkspaceRuntimeControlTarget } from "./workspace-runtime-control";
function withCompanyScope(path: string, companyId?: string) {
if (!companyId) return path;
const separator = path.includes("?") ? "&" : "?";
return `${path}${separator}companyId=${encodeURIComponent(companyId)}`;
}
function projectPath(id: string, companyId?: string, suffix = "") {
return withCompanyScope(`/projects/${encodeURIComponent(id)}${suffix}`, companyId);
}
export const projectsApi = {
list: (companyId: string, opts: { includeArchived?: boolean } = {}) => {
const params = new URLSearchParams();
if (opts.includeArchived) params.set("includeArchived", "true");
const query = params.toString();
return api.get<Project[]>("/companies/" + encodeURIComponent(companyId) + "/projects" + (query ? "?" + query : ""));
},
get: (id: string, companyId?: string) => api.get<Project>(projectPath(id, companyId)),
create: (companyId: string, data: Record<string, unknown>) =>
api.post<Project>(`/companies/${companyId}/projects`, data),
update: (id: string, data: Record<string, unknown>, companyId?: string) =>
api.patch<Project>(projectPath(id, companyId), data),
listAccessMembers: (id: string, companyId?: string) =>
api.get<ProjectAccessMember[]>(projectPath(id, companyId, "/access-members")),
addAccessMember: (
id: string,
data: { subjectType: "user" | "agent"; subjectId: string },
companyId?: string,
) => api.post<ProjectAccessMember>(projectPath(id, companyId, "/access-members"), data),
removeAccessMember: (id: string, memberId: string, companyId?: string) =>
api.delete<ProjectAccessMember>(
projectPath(id, companyId, `/access-members/${encodeURIComponent(memberId)}`),
),
listWorkspaces: (projectId: string, companyId?: string) =>
api.get<ProjectWorkspace[]>(projectPath(projectId, companyId, "/workspaces")),
createWorkspace: (projectId: string, data: Record<string, unknown>, companyId?: string) =>
api.post<ProjectWorkspace>(projectPath(projectId, companyId, "/workspaces"), data),
updateWorkspace: (projectId: string, workspaceId: string, data: Record<string, unknown>, companyId?: string) =>
api.patch<ProjectWorkspace>(
projectPath(projectId, companyId, `/workspaces/${encodeURIComponent(workspaceId)}`),
data,
),
controlWorkspaceRuntimeServices: (
projectId: string,
workspaceId: string,
action: "start" | "stop" | "restart",
companyId?: string,
target: WorkspaceRuntimeControlTarget = {},
) =>
api.post<{ workspace: ProjectWorkspace; operation: WorkspaceOperation }>(
projectPath(projectId, companyId, `/workspaces/${encodeURIComponent(workspaceId)}/runtime-services/${action}`),
sanitizeWorkspaceRuntimeControlTarget(target),
),
controlWorkspaceCommands: (
projectId: string,
workspaceId: string,
action: "start" | "stop" | "restart" | "run",
companyId?: string,
target: WorkspaceRuntimeControlTarget = {},
) =>
api.post<{ workspace: ProjectWorkspace; operation: WorkspaceOperation }>(
projectPath(projectId, companyId, `/workspaces/${encodeURIComponent(workspaceId)}/runtime-commands/${action}`),
sanitizeWorkspaceRuntimeControlTarget(target),
),
removeWorkspace: (projectId: string, workspaceId: string, companyId?: string) =>
api.delete<ProjectWorkspace>(projectPath(projectId, companyId, `/workspaces/${encodeURIComponent(workspaceId)}`)),
remove: (id: string, companyId?: string) => api.delete<Project>(projectPath(id, companyId)),
};