ModReleaser/src/services/versions.ts

118 lines
3.5 KiB
TypeScript
Raw Normal View History

"use server";
import type { Config, Version, CurseForgeFile } from "@/types";
import { modrinthClient, curseforgeClient } from "./clients";
import { listVersions } from "@/lib/modrinth";
import { getFiles } from "@/lib/curseforge";
import { Template } from "@/lib/utils/template";
/**
* Modrinth changelog
*/
export async function fetchModrinthVersions(
config: Config,
): Promise<Version[]> {
return listVersions(modrinthClient, config.modrinth.project_id, {
include_changelog: false,
});
}
/**
* CurseForge
*/
export async function fetchCurseForgeVersions(
config: Config,
): Promise<CurseForgeFile[]> {
const pageSize = 50;
let index = 0;
const allFiles: CurseForgeFile[] = [];
while (true) {
const response = await getFiles(curseforgeClient, {
modId: config.curseforge.project_id,
index,
pageSize,
});
allFiles.push(...response.data);
if (allFiles.length >= response.pagination.totalCount) {
break;
}
index += pageSize;
}
return allFiles;
}
/** 单个 MC 版本的比较结果 */
export interface VersionMatch {
exists: boolean;
existingVersion?: Version;
}
/** 单个 MC 版本的文件比较结果 */
export interface FileMatch {
exists: boolean;
existingFile?: CurseForgeFile;
}
/** 版本确认的完整比较结果 */
export interface VersionComparison {
modrinth: Record<string, VersionMatch>;
curseforge: Record<string, FileMatch>;
/** Modrinth 全量已有版本(含未匹配项),用于第一页展示 */
modrinthVersions: Version[];
/** CurseForge 全量已有文件(含未匹配项),用于第一页展示 */
curseforgeFiles: CurseForgeFile[];
}
/**
*
*
* @param config
* @param version "1.0.0"
* @param mc_versions MC
* @returns MC +
*/
export async function compareVersions(
config: Config,
version: string,
mc_versions: string[],
): Promise<VersionComparison> {
// 并行获取两个平台的已有版本
const [modrinthVersions, curseforgeFiles] = await Promise.all([
fetchModrinthVersions(config),
fetchCurseForgeVersions(config),
]);
// ── Modrinth按 version 模板生成 version_number 后匹配 ──
const modrinth: Record<string, VersionMatch> = {};
const modrinthTmpl = new Template(config.modrinth.version);
for (const mc_version of mc_versions) {
const generatedVersion = modrinthTmpl.format({ version, mc_version });
const existing = modrinthVersions.find(
(v) => v.version_number === generatedVersion,
);
modrinth[mc_version] = existing
? { exists: true, existingVersion: existing }
: { exists: false };
}
// ── CurseForge按 filename_format 模板生成文件名后匹配 ──
const curseforge: Record<string, FileMatch> = {};
const curseforgeTmpl = new Template(config.filename_format);
for (const mc_version of mc_versions) {
const generatedFilename = curseforgeTmpl.format({ version, mc_version });
const existing = curseforgeFiles.find(
(f) => f.fileName === generatedFilename,
);
curseforge[mc_version] = existing
? { exists: true, existingFile: existing }
: { exists: false };
}
return { modrinth, curseforge, modrinthVersions, curseforgeFiles };
}