Skip to content

Commit 245af22

Browse files
authored
Remove the need for CurseForge API key (#1636)
* removed the need for CF API key * Log api calls for modlist.html * remove api key from workflow too
1 parent 98ab2b9 commit 245af22

File tree

4 files changed

+38
-46
lines changed

4 files changed

+38
-46
lines changed

.github/workflows/build_pr.yml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@ on:
2525
version:
2626
required: true
2727
type: string
28-
secrets:
29-
API_TOKEN:
30-
required: true
3128

3229
jobs:
3330
pack_pr:
@@ -67,8 +64,6 @@ jobs:
6764
sed -i s/\"version\":\ \"development\"/\"version\":\ \"${{ inputs.version }}\"/ manifest.json
6865
shell: bash
6966
- name: Pack Modpack
70-
env:
71-
CFCORE_API_TOKEN: ${{ secrets.API_TOKEN }}
7267
run: |
7368
./pack-mode-switcher.sh n
7469
cd tools/build

tools/build/index.js

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@
88

99
import fs from "fs";
1010
import path, { resolve } from "path";
11-
import { env } from "process";
1211
import Juke from "juke-build";
1312
import { DownloadCF, GetModInfo } from "./lib/curseforge.js";
1413
import { CodegenAllTarget } from "./codegen/target-all.js";
14+
import { z } from "zod";
15+
import { progressNumber } from "./lib/log.js"
1516

1617
Juke.chdir("../..", import.meta.url);
1718
Juke.setup({ file: import.meta.url }).then((code) => {
@@ -113,27 +114,23 @@ export const ModeParameter = new Juke.Parameter({
113114
type: "string"
114115
})
115116

116-
// for windows users, go do -> --key=curseforgekey
117-
// not recommended, go use env vars!!
118-
export const KeyParameter = new Juke.Parameter({
119-
type: "string"
120-
})
121-
122117
export const BuildModlistTarget = new Juke.Target({
123-
parameters: [KeyParameter],
124118
inputs: ["manifest.json"],
125119
outputs: ["dist/modlist.html"],
126-
executes: async ({ get }) => {
127-
if (!env.CFCORE_API_TOKEN && !get(KeyParameter)) {
128-
Juke.logger.error("CFCORE_API_TOKEN env var is required for downloading mods.");
129-
throw new Juke.ExitCode(1);
130-
}
120+
executes: async () => {
131121
fs.mkdirSync("dist", { recursive: true })
132-
const jsonData = JSON.parse(fs.readFileSync("manifest.json", "utf-8"));
122+
const {files} = z.object({
123+
files: z.object({
124+
projectID: z.number()
125+
}).array()
126+
}).parse(
127+
JSON.parse(fs.readFileSync("manifest.json", "utf-8"))
128+
);
129+
const total = progressNumber(files.length)
133130
let html = "<ul>\n"
134-
for (const key in jsonData.files) {
135-
const file = jsonData.files[key];
136-
const modInfo = await GetModInfo(env.CFCORE_API_TOKEN ?? get(KeyParameter), file.projectID);
131+
for (const [i, {projectID}] of files.entries()) {
132+
const modInfo = await GetModInfo(projectID);
133+
Juke.logger.info(`Downloaded: (${total(i)}) Mod info "${modInfo.name}"`)
137134
html += `<li><a href=${modInfo.links.websiteUrl}>${modInfo.name} (by ${modInfo.authors[0].name})</a></li>\n`;
138135
}
139136
html += "</ul>"
@@ -144,11 +141,7 @@ export const BuildModlistTarget = new Juke.Target({
144141
export const DownloadModsTarget = new Juke.Target({
145142
inputs: ["manifest.json"],
146143
outputs: () => [], // always run, we have internal logic to check mods now
147-
executes: async ({ get }) => {
148-
if (!env.CFCORE_API_TOKEN && !get(KeyParameter)) {
149-
Juke.logger.error("CFCORE_API_TOKEN env var is required for downloading mods.");
150-
throw new Juke.ExitCode(1);
151-
}
144+
executes: async () => {
152145
const manifest = JSON.parse(fs.readFileSync("manifest.json", "utf-8"));
153146

154147
fs.mkdirSync("dist/modcache", { recursive: true })
@@ -217,7 +210,7 @@ export const DownloadModsTarget = new Juke.Target({
217210

218211
for (const modID of mIdToDownload) {
219212
const file = dataKeys[modID];
220-
const res = await DownloadCF(env.CFCORE_API_TOKEN ?? get(KeyParameter), {
213+
const res = await DownloadCF({
221214
modID,
222215
modFileID: file.fileID
223216
}, "dist/modcache/");
@@ -338,16 +331,12 @@ export const BuildAllTarget = new Juke.Target({
338331

339332
export const UploadTarget = new Juke.Target({
340333
dependsOn: [BuildAllTarget],
341-
parameters: [ModeParameter, KeyParameter],
334+
parameters: [ModeParameter],
342335
inputs: [
343336
"dist/client.zip",
344337
"dist/server.zip",
345338
],
346339
executes: async ({ get }) => {
347-
if (!env.CFCORE_API_TOKEN && !get(KeyParameter)) {
348-
Juke.logger.error("CFCORE_API_TOKEN env var is required for downloading mods.");
349-
throw new Juke.ExitCode(1);
350-
}
351340
get(ModeParameter);
352341
},
353342
})

tools/build/lib/curseforge.js

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@ import Juke from "juke-build";
22
import fs from "fs";
33
import https from "https";
44

5-
export const GetModInfo = async (key, modID) => {
6-
const modData = await fetch(`https://api.curseforge.com/v1/mods/${modID}`, {
5+
export const GetModInfo = async (modID) => {
6+
const modData = await fetch(`https://api.curse.tools/v1/cf/mods/${modID}`, {
77
redirect: "follow",
88
headers: {
9-
"X-Api-Key": key,
109
Accept: "application/json"
1110
}
1211
});
@@ -22,7 +21,7 @@ export const GetModInfo = async (key, modID) => {
2221
return (await modData.json()).data;
2322
}
2423

25-
export const DownloadCF = async (key, modInfo = {}, dest, retrycount) => {
24+
export const DownloadCF = async (modInfo = {}, dest, retrycount) => {
2625
if (retrycount === null || retrycount === undefined) {
2726
retrycount = 5;
2827
}
@@ -31,13 +30,10 @@ export const DownloadCF = async (key, modInfo = {}, dest, retrycount) => {
3130
Juke.logger.error(`Bad DownloadCF modInfo args. modID: ${modID} | modFileID: ${modFileID}`);
3231
throw new Juke.ExitCode(1);
3332
}
34-
const headers = {
35-
"X-Api-Key": key
36-
}
3733

38-
const modData = await fetch(`https://api.curseforge.com/v1/mods/${modID}/files/${modFileID}`, {
34+
const modData = await fetch(`https://api.curse.tools/v1/cf/mods/${modID}/files/${modFileID}`, {
3935
redirect: "follow",
40-
headers: {...headers, Accept: "application/json"}
36+
headers: {Accept: "application/json"}
4137
});
4238

4339
if (modData.status !== 200) {
@@ -52,7 +48,7 @@ export const DownloadCF = async (key, modInfo = {}, dest, retrycount) => {
5248
throw new Juke.ExitCode(1);
5349
}
5450
retrycount--;
55-
return await DownloadCF(key, modInfo, dest, retrycount);
51+
return await DownloadCF(modInfo, dest, retrycount);
5652
}
5753
const modDataJson = (await modData.json()).data;
5854

@@ -67,15 +63,15 @@ export const DownloadCF = async (key, modInfo = {}, dest, retrycount) => {
6763
Juke.logger.info(`Downloading: ${modDataJson.fileName}`)
6864

6965
try {
70-
await download_file(modDataJson.downloadUrl, { headers: headers }, dest);
66+
await download_file(modDataJson.downloadUrl, {}, dest);
7167
} catch {
7268
Juke.logger.warn(`Download failed ${modDataJson.fileName}`)
7369
if (retrycount <= 0) {
7470
Juke.logger.error("Exhausted retries, exiting download");
7571
throw new Juke.ExitCode(1);
7672
}
7773
retrycount--;
78-
return await DownloadCF(key, modInfo, dest, retrycount);
74+
return await DownloadCF(modInfo, dest, retrycount);
7975
}
8076

8177
if (!fs.existsSync(dest) || fs.statSync(dest).size !== modDataJson.fileLength) {
@@ -85,7 +81,7 @@ export const DownloadCF = async (key, modInfo = {}, dest, retrycount) => {
8581
throw new Juke.ExitCode(1);
8682
}
8783
retrycount--;
88-
return await DownloadCF(key, modInfo, dest, retrycount);
84+
return await DownloadCF(modInfo, dest, retrycount);
8985
}
9086
return modDataJson;
9187
};

tools/build/lib/log.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// @ts-check
2+
3+
/**
4+
* @param {number} max
5+
*/
6+
export const progressNumber = (max) => {
7+
const padLen = Math.ceil(Math.log10(max))
8+
/**
9+
* @param {number} current
10+
*/
11+
return (current) => current.toString().padStart(padLen) + "/" + max
12+
}

0 commit comments

Comments
 (0)