diff --git a/src/lib/curseforge/client.ts b/src/lib/curseforge/client.ts index 24f55b0..fa8737e 100644 --- a/src/lib/curseforge/client.ts +++ b/src/lib/curseforge/client.ts @@ -2,20 +2,27 @@ import { readErrorBody, summarizeFormData } from "../utils/fetch"; /** CurseForge API 客户端,封装两套 API 的鉴权与 User-Agent。 */ export class CurseForgeClient { - /** GET /v1/mods/{modId}/files 等只读接口 */ + /** V1 API (api.curseforge.com):GET /v1/mods/{modId}/files 等只读接口 */ private apiBase = "https://api.curseforge.com"; - /** 上传 / 更新文件、Game Version Types / Versions 等接口 */ + /** Legacy API (minecraft.curseforge.com):上传 / 更新文件、Game Version Types / Versions 等接口 */ private uploadBase = "https://minecraft.curseforge.com"; - private token: string; + /** 新 API (api.curseforge.com) 的 token */ + private apiToken: string; + + /** 旧 API (minecraft.curseforge.com) 的 token */ + private legacyToken: string; + private userAgent: string; constructor( - token: string, + apiToken: string, + legacyToken: string, userAgent?: string, ) { - this.token = token; + this.apiToken = apiToken; + this.legacyToken = legacyToken; this.userAgent = userAgent ?? "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"; @@ -23,13 +30,13 @@ export class CurseForgeClient { /** V1 API 请求头(x-api-key)。 */ private apiHeaders(): Record { - return { "x-api-key": this.token }; + return { "x-api-key": this.apiToken }; } - /** Upload API 请求头(X-Api-Token + browser User-Agent)。 */ + /** Legacy API 请求头(X-Api-Token + browser User-Agent)。 */ private uploadHeaders(): Record { return { - "X-Api-Token": this.token, + "X-Api-Token": this.legacyToken, "User-Agent": this.userAgent, }; } diff --git a/src/lib/curseforge/game.test.ts b/src/lib/curseforge/game.test.ts index 83002de..1a8f714 100644 --- a/src/lib/curseforge/game.test.ts +++ b/src/lib/curseforge/game.test.ts @@ -3,7 +3,7 @@ import { CurseForgeClient } from "./client"; import { getVersionTypes, getGameVersions, getMinecraftVersions } from "./game"; import secrets from "../../../secrets.json"; -const client = new CurseForgeClient(secrets.curseforge); +const client = new CurseForgeClient(secrets.curseforge, secrets.curseforge_legacy); describe("getVersionTypes", () => { test("GET /api/game/version-types", async () => { diff --git a/src/services/clients.ts b/src/services/clients.ts index 384e6e2..839636d 100644 --- a/src/services/clients.ts +++ b/src/services/clients.ts @@ -33,4 +33,7 @@ export const modrinthClient = new ModrinthClient( "ModReleaser (local)", ); -export const curseforgeClient = new CurseForgeClient(secrets.curseforge); +export const curseforgeClient = new CurseForgeClient( + secrets.curseforge, + secrets.curseforge_legacy, +); diff --git a/src/types/config.ts b/src/types/config.ts index 45277aa..3a6ecd3 100644 --- a/src/types/config.ts +++ b/src/types/config.ts @@ -73,8 +73,10 @@ export type Config = z.infer; // region Secrets — secrets.json 结构 export const SecretsSchema = z.object({ - /** CurseForge API Token */ + /** CurseForge 新 API (api.curseforge.com) Token */ curseforge: z.string().min(1), + /** CurseForge 旧 API (minecraft.curseforge.com) Token */ + curseforge_legacy: z.string().min(1), /** Modrinth Personal Access Token */ modrinth: z.string().min(1), });