import { apiRequest } from '../../lib/api'; import { filterAppsByCurrentAdmin } from '../../lib/admin-app-permissions'; import type { AppRelease, AppWithComponents, BuildJob, ComponentType, DeploymentJob, GiteaRepo, RuntimeControlJob, SourceComponent } from '../../types/application'; import type { ApiAppComponent } from '../../types/runtime'; export type GiteaCommit = { sha: string; commit?: { message?: string; author?: { name?: string; date?: string; }; committer?: { name?: string; date?: string; }; }; author?: { login?: string; username?: string; full_name?: string; name?: string; } | null; committer?: { login?: string; username?: string; full_name?: string; name?: string; } | null; created?: string; }; export function listApps() { return apiRequest('/apps').then(filterAppsByCurrentAdmin); } export function createApp(input: { key: string; name: string; description?: string; namespace?: string; status?: string; }) { return apiRequest<{ app: AppWithComponents }>('/apps', { method: 'POST', body: JSON.stringify(input) }); } export function createComponent( appId: string, input: { name: string; type: ComponentType; imageSource?: string; externalImage?: string; workloadType?: string; replicas?: number; serviceType?: string; storageEnabled?: boolean; storageSize?: string; storageMountPath?: string; storageRetain?: boolean; repository?: string; branch?: string; buildTarget?: string; port?: number; targetPort?: number; ports?: Array<{ name?: string; port?: number; targetPort?: number; nodePort?: number; protocol?: string }>; } ) { return apiRequest<{ component: ApiAppComponent }>(`/apps/${appId}/components`, { method: 'POST', body: JSON.stringify(input) }); } export function listSources() { return apiRequest('/apps/sources'); } export function linkComponentSource( componentId: string, input: { repository: string; branch?: string; buildTarget?: string } ) { return apiRequest<{ component: SourceComponent }>(`/apps/components/${componentId}/source`, { method: 'PATCH', body: JSON.stringify(input) }); } export function listGiteaRepos(owner = 'platform', limit = 50) { return apiRequest<{ owner: string | null; repos: GiteaRepo[] }>( `/gitea/repos?owner=${encodeURIComponent(owner)}&limit=${limit}` ).then((result) => result.repos); } export function createGiteaOrgRepo( org: string, input: { name: string; description?: string; private?: boolean; autoInit?: boolean; createDevelopBranch?: boolean; createReleaseBranch?: boolean; } ) { return apiRequest<{ repo: GiteaRepo; branches: unknown }>(`/gitea/orgs/${encodeURIComponent(org)}/repos`, { method: 'POST', body: JSON.stringify(input) }).then((result) => result.repo); } export function listGiteaCommitsPage( owner: string, repo: string, branch = 'develop', options?: { page?: number; limit?: number; since?: string } ) { const params = new URLSearchParams({ sha: branch, page: String(options?.page ?? 1), limit: String(options?.limit ?? 5) }); if (options?.since) params.set('since', options.since); return apiRequest<{ commits: GiteaCommit[]; total: number | null; page: number; limit: number }>( `/gitea/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/commits?${params.toString()}` ); } export function getGiteaCommitDiff(owner: string, repo: string, sha: string) { return apiRequest<{ diff: string }>( `/gitea/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/commits/${encodeURIComponent(sha)}/diff` ).then((result) => result.diff); } export function listBuildJobs(appKey?: string) { const query = appKey ? `?appKey=${encodeURIComponent(appKey)}` : ''; return apiRequest(`/apps/builds${query}`); } export function listBuildJobsPage(options: { appKey?: string; page: number; limit: number; since?: string; status?: string; hideReleaseCandidates?: boolean }) { const params = new URLSearchParams({ page: String(options.page), limit: String(options.limit) }); if (options.appKey) params.set('appKey', options.appKey); if (options.since) params.set('since', options.since); if (options.status) params.set('status', options.status); if (options.hideReleaseCandidates) params.set('hideReleaseCandidates', 'true'); return apiRequest<{ jobs: BuildJob[]; total: number; page: number; limit: number }>(`/apps/builds?${params.toString()}`); } export function createBuildJob(input: { componentId: string; branch?: string; commitSha?: string }) { return apiRequest<{ buildJob: BuildJob }>('/apps/builds', { method: 'POST', body: JSON.stringify(input) }); } export function cancelBuildJob(buildJobId: string) { return apiRequest<{ buildJob: BuildJob }>(`/apps/builds/${buildJobId}/cancel`, { method: 'PATCH' }); } export function deleteBuildJob(buildJobId: string) { return apiRequest<{ deleted: boolean }>(`/apps/builds/${buildJobId}`, { method: 'DELETE' }); } export function hideReleaseCandidate(buildJobId: string) { return apiRequest<{ buildJob: BuildJob }>(`/apps/builds/${buildJobId}/hide-release-candidate`, { method: 'PATCH' }); } export function listReleases(appKey?: string) { const query = appKey ? `?appKey=${encodeURIComponent(appKey)}` : ''; return apiRequest(`/apps/releases${query}`); } export function listReleasesPage(options: { appKey?: string; page: number; limit: number; since?: string }) { const params = new URLSearchParams({ page: String(options.page), limit: String(options.limit) }); if (options.appKey) params.set('appKey', options.appKey); if (options.since) params.set('since', options.since); return apiRequest<{ releases: AppRelease[]; total: number; page: number; limit: number; usedBuildIds?: string[]; usedValues?: string[] }>(`/apps/releases?${params.toString()}`); } export function createRelease(input: { appId: string; version: string; branch?: string; buildJobIds: string[] }) { return apiRequest<{ release: AppRelease }>('/apps/releases', { method: 'POST', body: JSON.stringify(input) }); } export function deleteRelease(releaseId: string) { return apiRequest<{ deleted: boolean }>(`/apps/releases/${releaseId}`, { method: 'DELETE' }); } export function listDeployments(appKey?: string) { const query = appKey ? `?appKey=${encodeURIComponent(appKey)}` : ''; return apiRequest(`/apps/deployments${query}`); } export function listDeploymentsPage(options: { appKey?: string; page: number; limit: number; since?: string }) { const params = new URLSearchParams({ page: String(options.page), limit: String(options.limit) }); if (options.appKey) params.set('appKey', options.appKey); if (options.since) params.set('since', options.since); return apiRequest<{ deployments: DeploymentJob[]; total: number; page: number; limit: number; deployedReleaseIds?: string[] }>(`/apps/deployments?${params.toString()}`); } export function createDeployment(input: { releaseId: string; environment: string; namespace: string; updateLauncherAppVersion?: boolean }) { return apiRequest<{ deploymentJob: DeploymentJob }>('/apps/deployments', { method: 'POST', body: JSON.stringify(input) }); } export function listMigrations() { return apiRequest('/apps/migrations'); } export function listMigrationsPage(options: { appId?: string; page: number; limit: number; since?: string }) { const params = new URLSearchParams({ page: String(options.page), limit: String(options.limit) }); if (options.appId) params.set('appId', options.appId); if (options.since) params.set('since', options.since); return apiRequest<{ jobs: RuntimeControlJob[]; total: number; page: number; limit: number }>(`/apps/migrations?${params.toString()}`); } export function createMigration(input: { releaseId: string; migrationComponentId: string; imageComponentName: string; namespace: string; command: string; envSecretName: string; }) { return apiRequest<{ migrationJob: RuntimeControlJob }>('/apps/migrations', { method: 'POST', body: JSON.stringify(input) }); }