Skip to content

Commit eb4edfe

Browse files
committed
feat: 添加文档历史 API 路由,调用 GitHub commits 接口返回最近 5 次更新
1 parent 356cecc commit eb4edfe

1 file changed

Lines changed: 107 additions & 0 deletions

File tree

app/api/docs/history/route.ts

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import { NextRequest, NextResponse } from "next/server";
2+
3+
// 响应缓存 1 小时,GitHub API 每小时限额 5000 次
4+
export const revalidate = 3600;
5+
6+
interface GitHubCommit {
7+
sha: string;
8+
commit: {
9+
author: {
10+
name: string;
11+
date: string;
12+
};
13+
message: string;
14+
};
15+
author: {
16+
login: string;
17+
avatar_url: string;
18+
} | null;
19+
html_url: string;
20+
}
21+
22+
export interface HistoryItem {
23+
sha: string;
24+
authorName: string;
25+
authorLogin: string;
26+
avatarUrl: string;
27+
date: string;
28+
message: string;
29+
htmlUrl: string;
30+
}
31+
32+
export async function GET(req: NextRequest) {
33+
const { searchParams } = new URL(req.url);
34+
const path = searchParams.get("path");
35+
36+
if (!path) {
37+
return NextResponse.json(
38+
{ success: false, error: "缺少 path 参数" },
39+
{ status: 400 },
40+
);
41+
}
42+
43+
const token = process.env.GITHUB_TOKEN;
44+
if (!token) {
45+
return NextResponse.json(
46+
{ success: false, error: "服务端未配置 GITHUB_TOKEN" },
47+
{ status: 500 },
48+
);
49+
}
50+
51+
const apiUrl = `https://api.github.com/repos/InvolutionHell/involutionhell/commits?path=${encodeURIComponent(path)}&per_page=5`;
52+
53+
let res: Response;
54+
try {
55+
res = await fetch(apiUrl, {
56+
headers: {
57+
Authorization: `Bearer ${token}`,
58+
Accept: "application/vnd.github+json",
59+
"X-GitHub-Api-Version": "2022-11-28",
60+
},
61+
// Next.js fetch 缓存,与 revalidate 配合
62+
next: { revalidate: 3600 },
63+
});
64+
} catch {
65+
return NextResponse.json(
66+
{ success: false, error: "无法连接 GitHub API" },
67+
{ status: 502 },
68+
);
69+
}
70+
71+
if (res.status === 403) {
72+
return NextResponse.json(
73+
{ success: false, error: "GitHub API 限流,请稍后重试" },
74+
{ status: 429 },
75+
);
76+
}
77+
78+
if (!res.ok) {
79+
return NextResponse.json(
80+
{ success: false, error: `GitHub API 返回 ${res.status}` },
81+
{ status: 502 },
82+
);
83+
}
84+
85+
const commits: GitHubCommit[] = await res.json();
86+
87+
const data: HistoryItem[] = commits.map((c) => ({
88+
sha: c.sha,
89+
authorName: c.commit.author.name,
90+
authorLogin: c.author?.login ?? c.commit.author.name,
91+
avatarUrl:
92+
c.author?.avatar_url ?? `https://github.com/${c.commit.author.name}.png`,
93+
date: c.commit.author.date,
94+
// 只取 commit message 第一行
95+
message: c.commit.message.split("\n")[0],
96+
htmlUrl: c.html_url,
97+
}));
98+
99+
return NextResponse.json(
100+
{ success: true, data },
101+
{
102+
headers: {
103+
"Cache-Control": "public, s-maxage=3600, stale-while-revalidate=86400",
104+
},
105+
},
106+
);
107+
}

0 commit comments

Comments
 (0)