Repository navigation
Expand file tree
/
Copy pathapi.js
More file actions
148 lines (118 loc) · 4.51 KB
/
Copy pathapi.js
File metadata and controls
148 lines (118 loc) · 4.51 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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/* ================================================
GitHub Developer Explorer – api.js
API Layer: All GitHub REST API calls live here.
Uses fetch() + async/await + try/catch/finally
================================================ */
// Base URL for the GitHub REST API
const BASE_URL = "https://api.github.com";
/* ------------------------------------------------
Build request headers.
If a token is provided in config.js, attach it
so the rate limit rises from 60 → 5,000 / hour.
------------------------------------------------ */
const getHeaders = () => {
const headers = {
"Accept": "application/vnd.github+json"
};
// Only add the Authorization header if a token is set
if (typeof CONFIG !== "undefined" && CONFIG.GITHUB_TOKEN) {
headers["Authorization"] = `Bearer ${CONFIG.GITHUB_TOKEN}`;
}
return headers;
};
/* ================================================
1. fetchProfile(username)
Fetches a GitHub user's public profile data.
Returns the raw API response object on success.
Throws an Error with a user-friendly message
on failure (404, 403, network error, etc.).
================================================ */
const fetchProfile = async (username) => {
const response = await fetch(`${BASE_URL}/users/${username}`, {
headers: getHeaders()
});
// GitHub returns 404 when the username does not exist
if (response.status === 404) {
throw new Error(`User "${username}" not found. Please check the username and try again.`);
}
// 403 usually means the API rate limit has been exceeded
if (response.status === 403) {
throw new Error("GitHub API rate limit exceeded. Please wait a moment and try again.");
}
// Catch any other non-OK status codes
if (!response.ok) {
throw new Error(`Failed to fetch profile. (HTTP ${response.status})`);
}
const data = await response.json();
return data;
};
/* ================================================
2. fetchRepositories(username)
Fetches up to 100 public repositories for a
given GitHub user, sorted by last updated.
Returns an array of raw repo objects on success.
Throws an Error on failure.
================================================ */
const fetchRepositories = async (username) => {
// per_page=100 gives us the maximum repos in one request
const response = await fetch(
`${BASE_URL}/users/${username}/repos?per_page=100&sort=updated`,
{ headers: getHeaders() }
);
if (response.status === 404) {
throw new Error(`Repositories for "${username}" could not be found.`);
}
if (response.status === 403) {
throw new Error("GitHub API rate limit exceeded. Please wait a moment and try again.");
}
if (!response.ok) {
throw new Error(`Failed to fetch repositories. (HTTP ${response.status})`);
}
const data = await response.json();
return data;
};
/* ================================================
3. fetchRateLimit()
Fetches the current GitHub API rate limit info.
Returns an object with:
{
limit : number – max requests allowed
used : number – requests used so far
remaining : number – requests left
resetTime : string – human-readable reset time
}
Does NOT throw on failure – returns a fallback
object so the UI is never broken by rate-limit
lookup errors.
================================================ */
const fetchRateLimit = async () => {
try {
const response = await fetch(`${BASE_URL}/rate_limit`, {
headers: getHeaders()
});
if (!response.ok) {
throw new Error("Could not retrieve rate limit data.");
}
const data = await response.json();
// Destructure the core rate-limit info from the response
const { limit, used, remaining, reset } = data.rate;
// Convert the Unix timestamp to a readable local time string
const resetDate = new Date(reset * 1000);
const resetTime = resetDate.toLocaleTimeString();
return { limit, used, remaining, resetTime };
} catch (error) {
// Return a safe fallback so the rest of the app keeps working
return {
limit: "N/A",
used: "N/A",
remaining: "N/A",
resetTime: "N/A"
};
}
};
/* ================================================
EXPORTS (browser-safe, no module bundler needed)
================================================ */
window.fetchProfile = fetchProfile;
window.fetchRepositories = fetchRepositories;
window.fetchRateLimit = fetchRateLimit;