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