-
-
Notifications
You must be signed in to change notification settings - Fork 36
/
Copy pathfetch-projects.ts
113 lines (97 loc) · 3.04 KB
/
fetch-projects.ts
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
112
113
import { siteConfig } from '@/src/configs/config';
const GITHUB_USERNAME = siteConfig.social.github;
const GITHUB_TOKEN = process.env.GITHUB_TOKEN;
if (!GITHUB_TOKEN) {
throw new Error('GitHub token is not defined in .env.local');
}
// In-memory cache to store repository data
let cache: {
data: any;
timestamp: number;
} = { data: null, timestamp: 0 };
// Cache expiration time (in milliseconds)
const CACHE_EXPIRATION = 10 * 60 * 1000; // 10 minutes
export default async function handler(
req: { query: { search?: string } },
res: {
status: (arg0: number) => {
(): any;
new (): any;
json: (arg0: any) => void;
};
}
) {
const { search } = req.query;
try {
// Check if cached data is still valid
const now = Date.now();
if (cache.data && now - cache.timestamp < CACHE_EXPIRATION) {
console.log('Serving data from cache');
return sendFilteredProjects(cache.data, search, res);
}
// Fetch data from GitHub API
const response = await fetch(
`https://api.github.com/users/${GITHUB_USERNAME}/repos?sort=updated&per_page=100`,
{
headers: {
Authorization: `token ${GITHUB_TOKEN}`
}
}
);
if (!response.ok) {
throw new Error('Failed to fetch repositories');
}
const data = await response.json();
// Fetch topics for each repository
const projectsWithTopics = await Promise.all(
data.map(async (repo: any) => {
const topicsResponse = await fetch(
`https://api.github.com/repos/${GITHUB_USERNAME}/${repo.name}/topics`,
{
headers: {
Authorization: `token ${GITHUB_TOKEN}`,
Accept: 'application/vnd.github.v3+json'
}
}
);
const topicsData = await topicsResponse.json();
const topics = topicsData.names || [];
return {
id: repo.id.toString(),
title: repo.name,
des: repo.description || 'No description provided.',
category: repo.language ? repo.language.toLowerCase() : 'unknown',
repo: repo.html_url,
link: repo.homepage || repo.html_url,
topics
};
})
);
// Cache the fetched data
cache = {
data: projectsWithTopics,
timestamp: Date.now()
};
sendFilteredProjects(projectsWithTopics, search, res);
} catch (error) {
console.error('Error fetching GitHub repositories:', error);
res.status(500).json({ message: 'Error fetching repositories' });
}
}
function sendFilteredProjects(
projects: any[],
search: string | undefined,
res: any
) {
const filteredProjects = search
? projects.filter(
(project: { category: string; title: string; topics: string[] }) =>
project.category.toLowerCase().includes(search.toLowerCase()) ||
project.title.toLowerCase().includes(search.toLowerCase()) ||
project.topics.some((topic) =>
topic.toLowerCase().includes(search.toLowerCase())
)
)
: projects;
res.status(200).json(filteredProjects);
}