ModReleaser/src/services/versions.ts
2026-07-18 10:04:16 +08:00

118 lines
3.5 KiB
TypeScript
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 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 };
}