100 lines
2.8 KiB
TypeScript
100 lines
2.8 KiB
TypeScript
import { NextResponse } from 'next/server';
|
|
import { getAdminAuth, getAdminDb } from '@/lib/firebase/admin';
|
|
|
|
/**
|
|
* Fetch file content from GitHub
|
|
* GET /api/github/file-content?owner=X&repo=Y&path=Z
|
|
*/
|
|
export async function GET(request: Request) {
|
|
try {
|
|
const authHeader = request.headers.get('Authorization');
|
|
if (!authHeader?.startsWith('Bearer ')) {
|
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
|
}
|
|
|
|
const idToken = authHeader.split('Bearer ')[1];
|
|
const adminAuth = getAdminAuth();
|
|
const adminDb = getAdminDb();
|
|
|
|
let userId: string;
|
|
try {
|
|
const decodedToken = await adminAuth.verifyIdToken(idToken);
|
|
userId = decodedToken.uid;
|
|
} catch (error) {
|
|
return NextResponse.json({ error: 'Invalid token' }, { status: 401 });
|
|
}
|
|
|
|
const url = new URL(request.url);
|
|
const owner = url.searchParams.get('owner');
|
|
const repo = url.searchParams.get('repo');
|
|
const path = url.searchParams.get('path');
|
|
const branch = url.searchParams.get('branch') || 'main';
|
|
|
|
if (!owner || !repo || !path) {
|
|
return NextResponse.json(
|
|
{ error: 'Missing owner, repo, or path' },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
// Get GitHub connection
|
|
const connectionDoc = await adminDb
|
|
.collection('githubConnections')
|
|
.doc(userId)
|
|
.get();
|
|
|
|
if (!connectionDoc.exists) {
|
|
return NextResponse.json(
|
|
{ error: 'GitHub not connected' },
|
|
{ status: 404 }
|
|
);
|
|
}
|
|
|
|
const connection = connectionDoc.data()!;
|
|
const accessToken = connection.accessToken; // TODO: Decrypt
|
|
|
|
// Fetch file content from GitHub API
|
|
const response = await fetch(
|
|
`https://api.github.com/repos/${owner}/${repo}/contents/${encodeURIComponent(path)}?ref=${branch}`,
|
|
{
|
|
headers: {
|
|
Authorization: `Bearer ${accessToken}`,
|
|
Accept: 'application/vnd.github.v3+json',
|
|
},
|
|
}
|
|
);
|
|
|
|
if (!response.ok) {
|
|
if (response.status === 404) {
|
|
return NextResponse.json({ error: 'File not found' }, { status: 404 });
|
|
}
|
|
const error = await response.json();
|
|
throw new Error(`GitHub API error: ${error.message || response.statusText}`);
|
|
}
|
|
|
|
const data = await response.json();
|
|
|
|
// GitHub returns base64-encoded content
|
|
const content = Buffer.from(data.content, 'base64').toString('utf-8');
|
|
|
|
return NextResponse.json({
|
|
path: data.path,
|
|
name: data.name,
|
|
size: data.size,
|
|
sha: data.sha,
|
|
content,
|
|
encoding: 'utf-8',
|
|
});
|
|
} catch (error) {
|
|
console.error('[GitHub File Content] Error:', error);
|
|
return NextResponse.json(
|
|
{
|
|
error: 'Failed to fetch file content',
|
|
details: error instanceof Error ? error.message : String(error),
|
|
},
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|
|
|