mirror of
https://github.com/Kir-Antipov/mc-publish.git
synced 2024-11-21 16:00:59 -05:00
Made utils for interacting with the CurseForge API
This commit is contained in:
parent
e38f6957c3
commit
27004e5242
3 changed files with 126 additions and 0 deletions
21
package-lock.json
generated
21
package-lock.json
generated
|
@ -2778,6 +2778,22 @@
|
|||
"mime-types": "^2.1.12"
|
||||
}
|
||||
},
|
||||
"formdata-node": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.2.2.tgz",
|
||||
"integrity": "sha512-rDQeb6tk/Noep0MXvKhctr5x3gSpeJ+e5gYLFGM4jAt0MilYQLDR1jq61u60Piig3/EtxB/xBZ8WLTmunE5BoA==",
|
||||
"requires": {
|
||||
"node-domexception": "1.0.0",
|
||||
"web-streams-polyfill": "4.0.0-beta.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"web-streams-polyfill": {
|
||||
"version": "4.0.0-beta.1",
|
||||
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.1.tgz",
|
||||
"integrity": "sha512-3ux37gEX670UUphBF9AMCq8XM6iQ8Ac6A+DSRRjDoRBm1ufCkaCDdNVbaqq60PsEkdNlLKrGtv/YBP4EJXqNtQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
|
@ -3923,6 +3939,11 @@
|
|||
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
|
||||
"dev": true
|
||||
},
|
||||
"node-domexception": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
|
||||
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.0.0.tgz",
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
"dependencies": {
|
||||
"@actions/core": "^1.5.0",
|
||||
"fast-glob": "^3.2.7",
|
||||
"formdata-node": "^4.2.2",
|
||||
"node-fetch": "^3.0.0"
|
||||
}
|
||||
}
|
||||
|
|
104
src/utils/curseforge-utils.ts
Normal file
104
src/utils/curseforge-utils.ts
Normal file
|
@ -0,0 +1,104 @@
|
|||
import fetch from "node-fetch";
|
||||
import { FormData } from "formdata-node";
|
||||
import { fileFromPath } from "formdata-node/file-from-path";
|
||||
import { File } from "../utils/file-utils";
|
||||
import { findVersionByName } from "./minecraft-utils";
|
||||
|
||||
const baseUrl = "https://minecraft.curseforge.com/api";
|
||||
|
||||
interface CurseForgeVersion {
|
||||
id: number;
|
||||
gameVersionTypeID: number;
|
||||
name: string;
|
||||
slug: string;
|
||||
}
|
||||
|
||||
interface CurseForgeVersions {
|
||||
gameVersions: CurseForgeVersion[];
|
||||
loaders: CurseForgeVersion[];
|
||||
java: CurseForgeVersion[];
|
||||
}
|
||||
|
||||
|
||||
let cachedCurseForgeVersions: CurseForgeVersions = null;
|
||||
async function getCurseForgeVersions(token: string): Promise<CurseForgeVersions> {
|
||||
if (!cachedCurseForgeVersions) {
|
||||
cachedCurseForgeVersions = await loadCurseForgeVersions(token);
|
||||
}
|
||||
return cachedCurseForgeVersions;
|
||||
}
|
||||
|
||||
async function loadCurseForgeVersions(token: string): Promise<CurseForgeVersions> {
|
||||
const versionTypes = <{ id: number, slug: string }[]>await (await fetch(`${baseUrl}/game/version-types?token=${token}`)).json();
|
||||
const javaVersionTypes = versionTypes.filter(x => x.slug.startsWith("java")).map(x => x.id);
|
||||
const minecraftVersionTypes = versionTypes.filter(x => x.slug.startsWith("minecraft")).map(x => x.id);
|
||||
const loaderVersionTypes = versionTypes.filter(x => x.slug.startsWith("modloader")).map(x => x.id);
|
||||
|
||||
const versions = <CurseForgeVersion[]>await (await fetch(`${baseUrl}/game/versions?token=${token}`)).json();
|
||||
return versions.reduce((container, version) => {
|
||||
if (javaVersionTypes.includes(version.gameVersionTypeID)) {
|
||||
container.java.push(version);
|
||||
} else if (minecraftVersionTypes.includes(version.gameVersionTypeID)) {
|
||||
container.gameVersions.push(version);
|
||||
} else if (loaderVersionTypes.includes(version.gameVersionTypeID)) {
|
||||
container.loaders.push(version);
|
||||
}
|
||||
return container;
|
||||
}, { gameVersions: new Array<CurseForgeVersion>(), loaders: new Array<CurseForgeVersion>(), java: new Array<CurseForgeVersion>() });
|
||||
}
|
||||
|
||||
export async function unifyGameVersion(gameVersion: string): Promise<string> {
|
||||
gameVersion = gameVersion.trim();
|
||||
const minecraftVersion = await findVersionByName(gameVersion);
|
||||
if (minecraftVersion) {
|
||||
return `${minecraftVersion.name}${(minecraftVersion.isSnapshot ? "-Snapshot" : "")}`;
|
||||
}
|
||||
return gameVersion.replace(/([^\w]|_)+/g, ".").replace(/[.-][a-zA-Z]\w+$/, "-Snapshot");
|
||||
}
|
||||
|
||||
export function unifyJava(java: string): string {
|
||||
java = java.trim();
|
||||
const match = java.match(/(?:\d+\D)?(\d+)$/);
|
||||
if (match && match.length === 2) {
|
||||
return `Java ${match[1]}`;
|
||||
}
|
||||
return java;
|
||||
}
|
||||
|
||||
async function addVersionIntersectionToSet(curseForgeVersions: CurseForgeVersion[], versions: string[], unify: (v: string) => string | Promise<string>, comparer: (cfv: CurseForgeVersion, v: string) => boolean, intersection: Set<number> ) {
|
||||
for (const version of versions) {
|
||||
const unifiedVersion = await unify(version);
|
||||
const curseForgeVersion = curseForgeVersions.find(x => comparer(x, unifiedVersion));
|
||||
if (curseForgeVersion) {
|
||||
intersection.add(curseForgeVersion.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function convertToCurseForgeVersions(gameVersions: string[], loaders: string[], java: string[], token: string): Promise<number[]> {
|
||||
const versions = new Set<number>();
|
||||
const curseForgeVersions = await getCurseForgeVersions(token);
|
||||
|
||||
await addVersionIntersectionToSet(curseForgeVersions.gameVersions, gameVersions, unifyGameVersion, (cfv, v) => cfv.name === v, versions);
|
||||
await addVersionIntersectionToSet(curseForgeVersions.loaders, loaders, x => x.trim().toLowerCase(), (cfv, v) => cfv.slug === v, versions);
|
||||
await addVersionIntersectionToSet(curseForgeVersions.java, java, unifyJava, (cfv, v) => cfv.name === v, versions);
|
||||
|
||||
return [...versions];
|
||||
}
|
||||
|
||||
export async function uploadFile(id: string, data: Record<string, any>, file: File, token: string): Promise<number> {
|
||||
const form = new FormData();
|
||||
form.append("file", await fileFromPath(file.path), file.name);
|
||||
form.append("metadata", JSON.stringify(data));
|
||||
|
||||
const response = await fetch(`${baseUrl}/projects/${id}/upload-file?token=${token}`, {
|
||||
method: "POST",
|
||||
body: <any>form
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to upload file: ${response.status} (${response.statusText})`)
|
||||
}
|
||||
|
||||
return (<{ id: number }>await response.json()).id;
|
||||
}
|
Loading…
Reference in a new issue