114 lines
3.4 KiB
TypeScript
114 lines
3.4 KiB
TypeScript
import { auth } from '@/lib/auth'
|
|
|
|
export async function getFileContent(path: string) {
|
|
const owner = process.env.GITHUB_OWNER!
|
|
const repo = process.env.GITHUB_REPO!
|
|
const branch = process.env.GITHUB_BRANCH || 'main'
|
|
|
|
try {
|
|
const session = await auth()
|
|
const token = session?.user?.accessToken
|
|
|
|
const apiUrl = `https://api.github.com/repos/${owner}/${repo}/contents/${path}?ref=${branch}`
|
|
const response = await fetch(apiUrl, {
|
|
headers: {
|
|
Accept: 'application/vnd.github.v3.raw',
|
|
Authorization: token ? `token ${token}` : '',
|
|
'User-Agent': 'NavSphere',
|
|
},
|
|
})
|
|
|
|
if (response.status === 404) {
|
|
console.log(`File not found: ${path}, returning default data`)
|
|
if (path.includes('navigation.json')) {
|
|
return { navigationItems: [] }
|
|
}
|
|
return {}
|
|
}
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`GitHub API error: ${response.statusText}`)
|
|
}
|
|
|
|
const data = await response.json()
|
|
return data
|
|
} catch (error) {
|
|
console.error('Error fetching file:', error)
|
|
if (path.includes('navigation.json')) {
|
|
return { navigationItems: [] }
|
|
}
|
|
return {}
|
|
}
|
|
}
|
|
|
|
export async function commitFile(
|
|
path: string,
|
|
content: string,
|
|
message: string,
|
|
token: string,
|
|
retryCount = 3
|
|
) {
|
|
const owner = process.env.GITHUB_OWNER!
|
|
const repo = process.env.GITHUB_REPO!
|
|
const branch = process.env.GITHUB_BRANCH || 'main'
|
|
|
|
const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms))
|
|
|
|
for (let attempt = 1; attempt <= retryCount; attempt++) {
|
|
try {
|
|
// 1. 获取当前文件信息(如果存在)
|
|
const currentFileUrl = `https://api.github.com/repos/${owner}/${repo}/contents/${path}?ref=${branch}`
|
|
const currentFileResponse = await fetch(currentFileUrl, {
|
|
headers: {
|
|
Authorization: `token ${token}`,
|
|
Accept: 'application/vnd.github.v3+json',
|
|
'User-Agent': 'NavSphere',
|
|
},
|
|
cache: 'no-store', // 禁用缓存,确保获取最新的文件信息
|
|
})
|
|
|
|
let sha = undefined
|
|
if (currentFileResponse.ok) {
|
|
const currentFile = await currentFileResponse.json()
|
|
sha = currentFile.sha
|
|
}
|
|
|
|
// 2. 创建或更新文件
|
|
const updateUrl = `https://api.github.com/repos/${owner}/${repo}/contents/${path}`
|
|
const response = await fetch(updateUrl, {
|
|
method: 'PUT',
|
|
headers: {
|
|
Authorization: `token ${token}`,
|
|
Accept: 'application/vnd.github.v3+json',
|
|
'Content-Type': 'application/json',
|
|
'User-Agent': 'NavSphere',
|
|
},
|
|
body: JSON.stringify({
|
|
message,
|
|
content: Buffer.from(content).toString('base64'),
|
|
sha,
|
|
branch,
|
|
}),
|
|
})
|
|
|
|
if (!response.ok) {
|
|
const error = await response.json()
|
|
if (attempt < retryCount && error.message?.includes('sha')) {
|
|
console.log(`Attempt ${attempt} failed, retrying after delay...`)
|
|
await delay(1000 * attempt) // 指数退避
|
|
continue
|
|
}
|
|
throw new Error(`Failed to commit file: ${error.message}`)
|
|
}
|
|
|
|
return await response.json()
|
|
} catch (error) {
|
|
if (attempt === retryCount) {
|
|
console.error('Error in commitFile:', error)
|
|
throw error
|
|
}
|
|
console.log(`Attempt ${attempt} failed, retrying...`)
|
|
await delay(1000 * attempt)
|
|
}
|
|
}
|
|
}
|