Files
Fractured/tools/fractured-launcher-electron/lib/gitea-release.js
T
Docker Build 6c4d7244c3 fix(launcher): add missing gitea-release and patch-manifest to repo
These modules were required by main.js / auto-update.js / github.js but never
committed, so packaged builds lacked them and crashed at startup.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-10 19:08:55 -05:00

101 lines
3.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use strict';
const { downloadBodyToFile } = require('./http-download');
function giteaApiBase(cfg) {
const base = String(cfg.gitea.base_url || '').trim().replace(/\/+$/, '');
return `${base}/api/v1`;
}
function giteaToken(cfg) {
const name = cfg.gitea && cfg.gitea.token_env;
if (name && process.env[name]) return String(process.env[name]).trim();
return String(process.env.GITEA_TOKEN || '').trim();
}
function giteaHeaders(token, json = false) {
const h = { 'User-Agent': 'Fractured-Launcher-Electron' };
if (json) h.Accept = 'application/json';
if (token) h.Authorization = `token ${token}`;
return h;
}
function useGiteaReleases(cfg) {
const g = cfg.gitea;
if (!g) return false;
return !!(String(g.base_url || '').trim() && String(g.owner || '').trim() && String(g.repo || '').trim());
}
async function downloadGiteaReleaseAsset(cfg, assetName, destPath) {
const api = giteaApiBase(cfg);
const { owner, repo } = cfg.gitea;
const tag = (cfg.gitea.release_tag || 'latest').trim() || 'latest';
const token = giteaToken(cfg);
let listUrl;
if (tag.toLowerCase() === 'latest') {
listUrl = `${api}/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/releases/latest`;
} else {
listUrl = `${api}/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/releases/tags/${encodeURIComponent(tag)}`;
}
const res = await fetch(listUrl, { headers: giteaHeaders(token, true) });
const text = await res.text();
if (!res.ok) {
let hint = '';
if (res.status === 404) hint = ' (wrong tag / no release / check base_url owner repo)';
if (res.status === 401 || res.status === 403) hint = ' (set GITEA_TOKEN or gitea.token_env)';
throw new Error(`Gitea release ${res.status}${hint}: ${text.slice(0, 600)}`);
}
const rel = JSON.parse(text);
const list = rel.attachments || rel.assets || [];
let downloadUrl = '';
for (const a of list) {
if (a.name !== assetName) continue;
downloadUrl = a.browser_download_url || a.download_url || '';
break;
}
if (!downloadUrl) {
const names = list.map((x) => x.name).filter(Boolean);
throw new Error(`Gitea release asset "${assetName}" not found; attachments: ${names.join(', ') || '(none)'}`);
}
const h = { Accept: 'application/octet-stream' };
if (token) h.Authorization = `token ${token}`;
const dl = await fetch(downloadUrl, { headers: h, redirect: 'follow' });
await downloadBodyToFile(dl, destPath);
}
/**
* Base URL for electron-updater generic provider (expects latest.yml under this path).
* Matches Giteas pattern: …/owner/repo/releases/download/{tag}/latest.yml
*/
async function getGiteaUpdaterFeedBase(cfg) {
if (!useGiteaReleases(cfg)) return null;
const api = giteaApiBase(cfg);
const { owner, repo } = cfg.gitea;
const tag = (cfg.gitea.release_tag || 'latest').trim() || 'latest';
const token = giteaToken(cfg);
let listUrl;
if (tag.toLowerCase() === 'latest') {
listUrl = `${api}/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/releases/latest`;
} else {
listUrl = `${api}/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/releases/tags/${encodeURIComponent(tag)}`;
}
const res = await fetch(listUrl, { headers: giteaHeaders(token, true) });
if (!res.ok) return null;
const rel = await res.json();
const tagName = rel.tag_name;
if (!tagName || typeof tagName !== 'string') return null;
const root = String(cfg.gitea.base_url || '').trim().replace(/\/+$/, '');
const url = `${root}/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/releases/download/${encodeURIComponent(tagName)}/`;
return { url, token };
}
module.exports = {
downloadGiteaReleaseAsset,
giteaToken,
useGiteaReleases,
getGiteaUpdaterFeedBase,
};