72 lines
2.3 KiB
JavaScript
72 lines
2.3 KiB
JavaScript
import { config } from '../config.js'
|
|
|
|
/** Zeitlimit fuer jeden Gitea-API-Aufruf, in ms (ueberschreibbar via `GITEA_TIMEOUT_MS`, s. config.js). */
|
|
const GITEA_TIMEOUT_MS = config.gitea.timeoutMs
|
|
|
|
/**
|
|
* Baut die Authorization-/Content-Type-Header fuer einen Gitea-API-Aufruf.
|
|
* Wirft, wenn GITEA_API_TOKEN nicht gesetzt ist.
|
|
*/
|
|
function giteaHeaders() {
|
|
if (!config.gitea.apiToken) {
|
|
throw new Error('GITEA_API_TOKEN fehlt in .env')
|
|
}
|
|
return {
|
|
Authorization: `token ${config.gitea.apiToken}`,
|
|
'Content-Type': 'application/json',
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Ruft `${config.gitea.baseUrl}/api/v1<path>` auf und liefert die geparste JSON-Antwort
|
|
* (oder null ohne Body). Eine Nicht-2xx-Antwort wirft eine Error mit .status; ein 409
|
|
* "same name already exists" wird in die deutsche Meldung uebersetzt (Subdomain-/Repo-Name).
|
|
* Bricht nach `GITEA_TIMEOUT_MS` ab (Standard 30 s); der Abbruch wirft eine Error OHNE .status,
|
|
* damit repoMove/projectAssignment ihn wie "Gitea nicht erreichbar" einordnen.
|
|
*/
|
|
export async function giteaFetch(path, options = {}) {
|
|
let response
|
|
try {
|
|
response = await fetch(`${config.gitea.baseUrl}/api/v1${path}`, {
|
|
...options,
|
|
headers: { ...giteaHeaders(), ...options.headers },
|
|
signal: options.signal || AbortSignal.timeout(GITEA_TIMEOUT_MS),
|
|
})
|
|
} catch (err) {
|
|
if (err?.name === 'TimeoutError' || err?.name === 'AbortError') {
|
|
throw new Error(`Gitea antwortet nicht (Zeitlimit ${Math.round(GITEA_TIMEOUT_MS / 1000)} s)`)
|
|
}
|
|
throw err
|
|
}
|
|
|
|
const text = await response.text()
|
|
let data = null
|
|
if (text) {
|
|
try {
|
|
data = JSON.parse(text)
|
|
} catch {
|
|
data = { message: text }
|
|
}
|
|
}
|
|
|
|
if (!response.ok) {
|
|
let message = data?.message || `Gitea ${response.status}`
|
|
if (response.status === 409 && /same name already exists/i.test(message)) {
|
|
message = 'Ein Gitea-Repository mit diesem Namen existiert bereits. Bitte einen anderen Subdomain-/Repo-Namen w�hlen.'
|
|
}
|
|
const error = new Error(message)
|
|
error.status = response.status
|
|
throw error
|
|
}
|
|
|
|
return data
|
|
}
|
|
|
|
/**
|
|
* Zerlegt "owner/repo" in [owner, repo]. Reines String-Splitting ohne Validierung -
|
|
* fuer nicht "owner/repo"-foermige Eingaben ist das Ergebnis entsprechend kurz/lang.
|
|
*/
|
|
export function splitRepo(fullName) {
|
|
return String(fullName || '').split('/')
|
|
}
|