diff --git a/src/git/apiHandler.js b/src/git/apiHandler.js index e2ab8c6..0ef827a 100644 --- a/src/git/apiHandler.js +++ b/src/git/apiHandler.js @@ -135,6 +135,28 @@ async function createRepoGitHub({ if (license) { body.license_template = license; } + + const githubErrorsToText = (errors) => { + if (!Array.isArray(errors) || errors.length === 0) return ''; + return errors + .map(err => { + if (!err) return ''; + if (typeof err === 'string') return err; + const field = err.field ? `${err.field}: ` : ''; + const message = err.message || err.code || ''; + return `${field}${message}`.trim(); + }) + .filter(Boolean) + .join('; '); + }; + + const isGithubRepoAlreadyExists = (msg, errors) => { + const text = `${String(msg || '')} ${githubErrorsToText(errors)}`.toLowerCase(); + if (text.includes('already exists')) return true; + if (text.includes('already_exists')) return true; + if (text.includes('name already exists')) return true; + return false; + }; try { const response = await axiosInstance.post('https://api.github.com/user/repos', body, { @@ -151,10 +173,11 @@ async function createRepoGitHub({ throw new Error('Authentifizierung fehlgeschlagen. Bitte überprüfen Sie Ihren GitHub-Token.'); } else if (status === 422) { const msg = data?.message || 'Repository konnte nicht erstellt werden'; - if (msg.includes('name already exists')) { + const details = githubErrorsToText(data?.errors); + if (isGithubRepoAlreadyExists(msg, data?.errors)) { throw new Error(`Ein Repository mit dem Namen "${name}" existiert bereits.`); } - throw new Error(`GitHub-Fehler: ${msg}`); + throw new Error(`GitHub-Fehler: ${msg}${details ? ` (${details})` : ''}`); } else if (status === 403) { throw new Error('Zugriff verweigert. Bitte überprüfen Sie Ihre Token-Berechtigungen.'); } else { @@ -1336,6 +1359,22 @@ async function getGithubCurrentUser({ token }) { return response.data; } +async function githubRepoExists({ token, owner, repo }) { + if (!token) throw new Error('GitHub Token fehlt.'); + if (!owner || !repo) throw new Error('Owner oder Repository fehlt.'); + + try { + await axiosInstance.get(`${GITHUB_API}/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`, { + headers: githubHeaders(token), + timeout: 12000 + }); + return true; + } catch (error) { + if (error?.response?.status === 404) return false; + throw error; + } +} + async function getGithubUserHeatmap({ token, monthsBack = 20 }) { if (!token) throw new Error('GitHub Token fehlt.'); @@ -1870,6 +1909,16 @@ async function updateGithubRepoVisibility({ token, owner, repo, isPrivate }) { return response.data; } +async function updateGithubRepoDefaultBranch({ token, owner, repo, defaultBranch }) { + if (!defaultBranch) throw new Error('Default-Branch fehlt.'); + const response = await axiosInstance.patch( + `${GITHUB_API}/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`, + { default_branch: String(defaultBranch).trim() }, + { headers: githubHeaders(token), timeout: 15000 } + ); + return response.data; +} + async function updateGithubRepoTopics({ token, owner, repo, topics }) { const response = await axiosInstance.put( `${GITHUB_API}/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/topics`, @@ -1947,6 +1996,7 @@ module.exports = { // GitHub API listGithubRepos, getGithubCurrentUser, + githubRepoExists, getGithubUserHeatmap, getGithubRepoContents, getGithubFileContent, @@ -1962,6 +2012,7 @@ module.exports = { editGithubRelease, deleteGithubRelease, updateGithubRepoVisibility, + updateGithubRepoDefaultBranch, updateGithubRepoTopics, deleteGithubRepo }; \ No newline at end of file