mirror of
https://github.com/Pandipipas/scoreko-electron-dev.git
synced 2026-06-06 05:32:06 +00:00
124 lines
3.1 KiB
TypeScript
124 lines
3.1 KiB
TypeScript
export type GiteaReleaseAsset = {
|
|
name?: unknown;
|
|
browser_download_url?: unknown;
|
|
size?: unknown;
|
|
};
|
|
|
|
export type GiteaRelease = {
|
|
tag_name?: unknown;
|
|
name?: unknown;
|
|
html_url?: unknown;
|
|
assets?: unknown;
|
|
};
|
|
|
|
export type InstallerAsset = {
|
|
name: string;
|
|
downloadUrl: string;
|
|
size?: number;
|
|
};
|
|
|
|
export type ReleaseUpdate = {
|
|
version: string;
|
|
title: string;
|
|
pageUrl?: string;
|
|
installer: InstallerAsset;
|
|
};
|
|
|
|
export type UpdateFileConfig = {
|
|
enabled?: unknown;
|
|
apiUrl?: unknown;
|
|
releasePageUrl?: unknown;
|
|
assetPattern?: unknown;
|
|
};
|
|
|
|
export function isVersionNewer(candidateVersion: string, currentVersion: string): boolean {
|
|
const candidate = normalizeVersion(candidateVersion);
|
|
const current = normalizeVersion(currentVersion);
|
|
|
|
for (let index = 0; index < Math.max(candidate.length, current.length); index += 1) {
|
|
const candidatePart = candidate[index] ?? 0;
|
|
const currentPart = current[index] ?? 0;
|
|
|
|
if (candidatePart > currentPart) {
|
|
return true;
|
|
}
|
|
|
|
if (candidatePart < currentPart) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
export function getReleaseVersion(release: GiteaRelease): string | null {
|
|
const tagName = typeof release.tag_name === "string" ? release.tag_name.trim() : "";
|
|
return tagName.length > 0 ? tagName.replace(/^v/i, "") : null;
|
|
}
|
|
|
|
export function getReleaseTitle(release: GiteaRelease, version: string): string {
|
|
const releaseName = typeof release.name === "string" ? release.name.trim() : "";
|
|
return releaseName.length > 0 ? releaseName : `Scoreko ${version}`;
|
|
}
|
|
|
|
export function selectInstallerAsset(release: GiteaRelease, assetPattern: string): InstallerAsset | null {
|
|
const assets = Array.isArray(release.assets) ? release.assets : [];
|
|
const matcher = new RegExp(assetPattern, "i");
|
|
|
|
for (const asset of assets as GiteaReleaseAsset[]) {
|
|
const name = typeof asset.name === "string" ? asset.name : "";
|
|
const downloadUrl = typeof asset.browser_download_url === "string" ? asset.browser_download_url : "";
|
|
|
|
if (!name || !downloadUrl || !matcher.test(name)) {
|
|
continue;
|
|
}
|
|
|
|
return {
|
|
name,
|
|
downloadUrl,
|
|
...(typeof asset.size === "number" ? { size: asset.size } : {}),
|
|
};
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
export function buildReleaseUpdate(
|
|
release: GiteaRelease,
|
|
currentVersion: string,
|
|
assetPattern: string,
|
|
): ReleaseUpdate | null {
|
|
const version = getReleaseVersion(release);
|
|
if (!version || !isVersionNewer(version, currentVersion)) {
|
|
return null;
|
|
}
|
|
|
|
const installer = selectInstallerAsset(release, assetPattern);
|
|
if (!installer) {
|
|
return null;
|
|
}
|
|
|
|
const pageUrl = typeof release.html_url === "string" && release.html_url.length > 0 ? release.html_url : undefined;
|
|
|
|
return {
|
|
version,
|
|
title: getReleaseTitle(release, version),
|
|
pageUrl,
|
|
installer,
|
|
};
|
|
}
|
|
|
|
export function sanitizeFileName(fileName: string): string {
|
|
return fileName.replace(/[<>:"/\\|?*\x00-\x1f]/g, "_");
|
|
}
|
|
|
|
function normalizeVersion(version: string): number[] {
|
|
return version
|
|
.trim()
|
|
.replace(/^v/i, "")
|
|
.split(/[+-]/)[0]
|
|
.split(".")
|
|
.map((part) => Number.parseInt(part, 10))
|
|
.map((part) => (Number.isFinite(part) ? part : 0));
|
|
}
|