Skip to content

Commit e06bc1e

Browse files
Update app directory with API route changes
1 parent cc2cd03 commit e06bc1e

File tree

7 files changed

+266
-330
lines changed

7 files changed

+266
-330
lines changed

app/api/github/orgs/route.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { NextResponse } from 'next/server'
2+
3+
export const dynamic = 'force-dynamic'
4+
5+
export async function GET() {
6+
try {
7+
if (!process.env.GITHUB_TOKEN) {
8+
return NextResponse.json({ error: 'GitHub token not configured' }, { status: 500 })
9+
}
10+
11+
const response = await fetch('https://api.github.com/user/orgs', {
12+
headers: {
13+
Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
14+
Accept: 'application/vnd.github.v3+json',
15+
},
16+
})
17+
18+
if (!response.ok) {
19+
throw new Error(`GitHub API error: ${response.status}`)
20+
}
21+
22+
const orgs = await response.json()
23+
24+
return NextResponse.json(
25+
orgs.map((org: any) => ({
26+
login: org.login,
27+
name: org.name || org.login,
28+
avatar_url: org.avatar_url,
29+
})),
30+
)
31+
} catch (error) {
32+
console.error('Error fetching GitHub organizations:', error)
33+
return NextResponse.json({ error: 'Failed to fetch organizations' }, { status: 500 })
34+
}
35+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { NextRequest, NextResponse } from 'next/server'
2+
3+
export const dynamic = 'force-dynamic'
4+
5+
export async function GET(
6+
request: NextRequest,
7+
{ params }: { params: { owner: string; repo: string } }
8+
) {
9+
try {
10+
if (!process.env.GITHUB_TOKEN) {
11+
return NextResponse.json({ error: 'GitHub token not configured' }, { status: 500 })
12+
}
13+
14+
const { owner, repo } = params
15+
const path = request.nextUrl.searchParams.get('path') || ''
16+
const ref = request.nextUrl.searchParams.get('ref') || 'main'
17+
18+
// Construct GitHub API URL for repository contents
19+
const apiUrl = path
20+
? `https://api.github.com/repos/${owner}/${repo}/contents/${path}?ref=${ref}`
21+
: `https://api.github.com/repos/${owner}/${repo}/contents?ref=${ref}`
22+
23+
const response = await fetch(apiUrl, {
24+
headers: {
25+
Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
26+
Accept: 'application/vnd.github.v3+json',
27+
},
28+
})
29+
30+
if (!response.ok) {
31+
if (response.status === 404) {
32+
return NextResponse.json({ error: 'File or directory not found' }, { status: 404 })
33+
}
34+
throw new Error(`GitHub API error: ${response.status}`)
35+
}
36+
37+
const data = await response.json()
38+
39+
// If it's a single file, return the file content
40+
if (data.type === 'file') {
41+
return NextResponse.json({
42+
type: 'file',
43+
name: data.name,
44+
path: data.path,
45+
size: data.size,
46+
content: {
47+
content: data.content,
48+
encoding: data.encoding
49+
},
50+
download_url: data.download_url
51+
})
52+
}
53+
54+
// If it's a directory, return the contents list
55+
if (Array.isArray(data)) {
56+
return NextResponse.json({
57+
type: 'dir',
58+
contents: data.map((item: any) => ({
59+
name: item.name,
60+
path: item.path,
61+
type: item.type,
62+
size: item.size,
63+
download_url: item.download_url
64+
}))
65+
})
66+
}
67+
68+
return NextResponse.json({ error: 'Unexpected response format' }, { status: 500 })
69+
} catch (error) {
70+
console.error('Error fetching GitHub repository content:', error)
71+
return NextResponse.json({ error: 'Failed to fetch repository content' }, { status: 500 })
72+
}
73+
}

app/api/github/repos/route.ts

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import { NextRequest, NextResponse } from 'next/server'
2+
3+
export const dynamic = 'force-dynamic'
4+
5+
export async function GET(request: NextRequest) {
6+
try {
7+
if (!process.env.GITHUB_TOKEN) {
8+
return NextResponse.json({ error: 'GitHub token not configured' }, { status: 500 })
9+
}
10+
11+
const owner = request.nextUrl.searchParams.get('owner')
12+
13+
if (!owner) {
14+
return NextResponse.json({ error: 'Owner parameter is required' }, { status: 400 })
15+
}
16+
17+
// First, get the authenticated user to check if this is their repos
18+
const userResponse = await fetch('https://api.github.com/user', {
19+
headers: {
20+
Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
21+
Accept: 'application/vnd.github.v3+json',
22+
},
23+
})
24+
25+
let isAuthenticatedUser = false
26+
if (userResponse.ok) {
27+
const user = await userResponse.json()
28+
isAuthenticatedUser = user.login === owner
29+
}
30+
31+
// Fetch all repositories by paginating through all pages
32+
const allRepos: any[] = []
33+
let page = 1
34+
const perPage = 100 // GitHub's maximum per page
35+
36+
while (true) {
37+
let apiUrl: string
38+
39+
if (isAuthenticatedUser) {
40+
// Use /user/repos for authenticated user to get private repos, but only owned repos
41+
apiUrl = `https://api.github.com/user/repos?sort=name&direction=asc&per_page=${perPage}&page=${page}&visibility=all&affiliation=owner`
42+
} else {
43+
// Check if it's an organization
44+
const orgResponse = await fetch(`https://api.github.com/orgs/${owner}`, {
45+
headers: {
46+
Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
47+
Accept: 'application/vnd.github.v3+json',
48+
},
49+
})
50+
51+
if (orgResponse.ok) {
52+
// Use /orgs/{org}/repos for organizations to get private repos
53+
apiUrl = `https://api.github.com/orgs/${owner}/repos?sort=name&direction=asc&per_page=${perPage}&page=${page}`
54+
} else {
55+
// Fallback to /users/{owner}/repos (public only)
56+
apiUrl = `https://api.github.com/users/${owner}/repos?sort=name&direction=asc&per_page=${perPage}&page=${page}`
57+
}
58+
}
59+
60+
const response = await fetch(apiUrl, {
61+
headers: {
62+
Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
63+
Accept: 'application/vnd.github.v3+json',
64+
},
65+
})
66+
67+
if (!response.ok) {
68+
throw new Error(`GitHub API error: ${response.status}`)
69+
}
70+
71+
const repos = await response.json()
72+
73+
// If we get fewer repos than the per_page limit, we've reached the end
74+
if (repos.length === 0) {
75+
break
76+
}
77+
78+
allRepos.push(...repos)
79+
80+
// If we got fewer than the max per page, we've reached the end
81+
if (repos.length < perPage) {
82+
break
83+
}
84+
85+
page++
86+
}
87+
88+
// Remove duplicates based on full_name (owner/repo)
89+
const uniqueRepos = allRepos.filter(
90+
(repo, index, self) => index === self.findIndex((r) => r.full_name === repo.full_name),
91+
)
92+
93+
// Sort alphabetically by name (GitHub API sort might not be perfect)
94+
uniqueRepos.sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase()))
95+
96+
return NextResponse.json(
97+
uniqueRepos.map((repo: any) => ({
98+
name: repo.name,
99+
full_name: repo.full_name,
100+
description: repo.description,
101+
private: repo.private,
102+
clone_url: repo.clone_url,
103+
updated_at: repo.updated_at,
104+
language: repo.language,
105+
})),
106+
)
107+
} catch (error) {
108+
console.error('Error fetching GitHub repositories:', error)
109+
return NextResponse.json({ error: 'Failed to fetch repositories' }, { status: 500 })
110+
}
111+
}

app/api/github/user/route.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { NextResponse } from 'next/server'
2+
3+
export const dynamic = 'force-dynamic'
4+
5+
export async function GET() {
6+
try {
7+
if (!process.env.GITHUB_TOKEN) {
8+
return NextResponse.json({ error: 'GitHub token not configured' }, { status: 500 })
9+
}
10+
11+
const response = await fetch('https://api.github.com/user', {
12+
headers: {
13+
Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
14+
Accept: 'application/vnd.github.v3+json',
15+
},
16+
})
17+
18+
if (!response.ok) {
19+
throw new Error(`GitHub API error: ${response.status}`)
20+
}
21+
22+
const user = await response.json()
23+
24+
return NextResponse.json({
25+
login: user.login,
26+
name: user.name,
27+
avatar_url: user.avatar_url,
28+
})
29+
} catch (error) {
30+
console.error('Error fetching GitHub user:', error)
31+
return NextResponse.json({ error: 'Failed to fetch user data' }, { status: 500 })
32+
}
33+
}

0 commit comments

Comments
 (0)