90 lines
3.2 KiB
JavaScript
90 lines
3.2 KiB
JavaScript
// src/github.js
|
|
|
|
/**
|
|
* Generic wrapper for calling the GitHub API.
|
|
*/
|
|
export async function callGitHubApi(env, path, method = 'GET', body = null) {
|
|
const GITHUB_TOKEN = env.GITHUB_TOKEN;
|
|
const GITHUB_REPO_OWNER = env.GITHUB_REPO_OWNER;
|
|
const GITHUB_REPO_NAME = env.GITHUB_REPO_NAME;
|
|
|
|
if (!GITHUB_TOKEN || !GITHUB_REPO_OWNER || !GITHUB_REPO_NAME) {
|
|
console.error("GitHub environment variables (GITHUB_TOKEN, GITHUB_REPO_OWNER, GITHUB_REPO_NAME) are not configured.");
|
|
throw new Error("GitHub API configuration is missing in environment variables.");
|
|
}
|
|
|
|
const url = `https://api.github.com/repos/${GITHUB_REPO_OWNER}/${GITHUB_REPO_NAME}${path}`;
|
|
const headers = {
|
|
'Authorization': `Bearer ${GITHUB_TOKEN}`,
|
|
'Accept': 'application/vnd.github.v3+json',
|
|
'User-Agent': 'Cloudflare-Worker-ContentBot/1.0'
|
|
};
|
|
|
|
if (method !== 'GET' && method !== 'DELETE' && body) {
|
|
headers['Content-Type'] = 'application/json';
|
|
}
|
|
|
|
const response = await fetch(url, {
|
|
method: method,
|
|
headers: headers,
|
|
body: body ? JSON.stringify(body) : null
|
|
});
|
|
|
|
if (!response.ok) {
|
|
const errorText = await response.text();
|
|
let errorJsonMessage = errorText;
|
|
try {
|
|
const errorJson = JSON.parse(errorText);
|
|
if (errorJson && errorJson.message) {
|
|
errorJsonMessage = errorJson.message;
|
|
if (errorJson.errors) {
|
|
errorJsonMessage += ` Details: ${JSON.stringify(errorJson.errors)}`;
|
|
}
|
|
}
|
|
} catch (e) { /* Ignore */ }
|
|
console.error(`GitHub API Error: ${response.status} ${response.statusText} for ${method} ${url}. Message: ${errorJsonMessage}`);
|
|
throw new Error(`GitHub API request to ${path} failed: ${response.status} - ${errorJsonMessage}`);
|
|
}
|
|
|
|
if (response.status === 204 || response.headers.get("content-length") === "0") {
|
|
return null;
|
|
}
|
|
return response.json();
|
|
}
|
|
|
|
/**
|
|
* Gets the SHA of a file from GitHub.
|
|
*/
|
|
export async function getGitHubFileSha(env, filePath) {
|
|
const GITHUB_BRANCH = env.GITHUB_BRANCH || 'main';
|
|
try {
|
|
const data = await callGitHubApi(env, `/contents/${filePath}?ref=${GITHUB_BRANCH}`);
|
|
return data && data.sha ? data.sha : null;
|
|
} catch (error) {
|
|
if (error.message.includes("404") || error.message.toLowerCase().includes("not found")) {
|
|
console.log(`File not found on GitHub: ${filePath} (branch: ${GITHUB_BRANCH})`);
|
|
return null;
|
|
}
|
|
console.error(`Error getting SHA for ${filePath}:`, error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Creates a new file or updates an existing one on GitHub.
|
|
*/
|
|
export async function createOrUpdateGitHubFile(env, filePath, content, commitMessage, existingSha = null) {
|
|
const GITHUB_BRANCH = env.GITHUB_BRANCH || 'main';
|
|
const base64Content = btoa(String.fromCharCode(...new TextEncoder().encode(content)));
|
|
|
|
const payload = {
|
|
message: commitMessage,
|
|
content: base64Content,
|
|
branch: GITHUB_BRANCH
|
|
};
|
|
|
|
if (existingSha) {
|
|
payload.sha = existingSha;
|
|
}
|
|
return callGitHubApi(env, `/contents/${filePath}`, 'PUT', payload);
|
|
} |