Files
agent-ui/server/routes/gitea.ts
josedario87 645f51a74e refactor: Modularize server into separate concerns
Split monolithic index.ts (~1400 lines) into modular structure:
- config.ts: Server configuration and constants
- db/: Database initialization, migrations, and seeds
- routes/: API handlers by domain (themes, canvas, components, etc.)
- services/: Terminal WebSocket server
- utils/: CORS helpers

Entry point now only coordinates initialization.
2026-02-13 13:01:18 -06:00

131 lines
3.6 KiB
TypeScript

import { jsonResponse, errorResponse } from '../utils/cors'
export async function handleGiteaRepo(req: Request) {
const body = await req.json()
const { giteaUrl, username, password, owner, repo } = body
if (!giteaUrl || !username || !password || !owner || !repo) {
return errorResponse('Missing required fields', 400)
}
try {
const auth = Buffer.from(`${username}:${password}`).toString('base64')
// Get repo info
const repoRes = await fetch(`${giteaUrl}/api/v1/repos/${owner}/${repo}`, {
headers: { 'Authorization': `Basic ${auth}` }
})
if (!repoRes.ok) {
if (repoRes.status === 401) {
return errorResponse('Invalid credentials', 401)
}
if (repoRes.status === 404) {
return errorResponse('Repository not found', 404)
}
throw new Error('Failed to connect to Gitea')
}
const repoData = await repoRes.json()
// Get branches
const branchesRes = await fetch(`${giteaUrl}/api/v1/repos/${owner}/${repo}/branches`, {
headers: { 'Authorization': `Basic ${auth}` }
})
let branches = ['main']
if (branchesRes.ok) {
const branchesData = await branchesRes.json()
branches = branchesData.map((b: any) => b.name)
}
return jsonResponse({
repo: {
name: repoData.name,
description: repoData.description,
default_branch: repoData.default_branch,
stars_count: repoData.stars_count,
forks_count: repoData.forks_count,
owner: { login: repoData.owner?.login || owner }
},
branches
})
} catch (e: any) {
return errorResponse(e.message, 500)
}
}
export async function handleGiteaTree(req: Request) {
const body = await req.json()
const { giteaUrl, username, password, owner, repo, branch, path } = body
try {
const auth = Buffer.from(`${username}:${password}`).toString('base64')
const apiPath = path
? `${giteaUrl}/api/v1/repos/${owner}/${repo}/contents/${path}?ref=${branch}`
: `${giteaUrl}/api/v1/repos/${owner}/${repo}/contents?ref=${branch}`
const res = await fetch(apiPath, {
headers: { 'Authorization': `Basic ${auth}` }
})
if (!res.ok) {
throw new Error('Failed to load tree')
}
const data = await res.json()
const items = Array.isArray(data) ? data : [data]
const tree = items
.map((item: any) => ({
name: item.name,
path: item.path,
type: item.type === 'dir' ? 'dir' : 'file',
children: item.type === 'dir' ? [] : undefined
}))
.sort((a: any, b: any) => {
if (a.type !== b.type) return a.type === 'dir' ? -1 : 1
return a.name.localeCompare(b.name)
})
return jsonResponse({ tree })
} catch (e: any) {
return errorResponse(e.message, 500)
}
}
export async function handleGiteaFile(req: Request) {
const body = await req.json()
const { giteaUrl, username, password, owner, repo, branch, path } = body
try {
const auth = Buffer.from(`${username}:${password}`).toString('base64')
const res = await fetch(
`${giteaUrl}/api/v1/repos/${owner}/${repo}/contents/${path}?ref=${branch}`,
{ headers: { 'Authorization': `Basic ${auth}` } }
)
if (!res.ok) {
throw new Error('Failed to load file')
}
const data = await res.json()
// Decode base64 content
let content = ''
if (data.content) {
content = Buffer.from(data.content, 'base64').toString('utf-8')
}
return jsonResponse({
content,
encoding: data.encoding,
size: data.size,
sha: data.sha
})
} catch (e: any) {
return errorResponse(e.message, 500)
}
}