@xmcl/curseforge
Version:
An implementation of curseforge (official) API in https://docs.curseforge.com/
388 lines (386 loc) • 14.7 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// index.ts
var curseforge_exports = {};
__export(curseforge_exports, {
CurseforgeApiError: () => CurseforgeApiError,
CurseforgeV1Client: () => CurseforgeV1Client,
FileModLoaderType: () => FileModLoaderType,
FileRelationType: () => FileRelationType,
FileReleaseType: () => FileReleaseType,
FileStatus: () => FileStatus,
HashAlgo: () => HashAlgo,
ModStatus: () => ModStatus,
ModsSearchSortField: () => ModsSearchSortField
});
module.exports = __toCommonJS(curseforge_exports);
var ModStatus = /* @__PURE__ */ ((ModStatus2) => {
ModStatus2[ModStatus2["New"] = 1] = "New";
ModStatus2[ModStatus2["ChangesRequired"] = 2] = "ChangesRequired";
ModStatus2[ModStatus2["UnderSoftReview"] = 3] = "UnderSoftReview";
ModStatus2[ModStatus2["Approved"] = 4] = "Approved";
ModStatus2[ModStatus2["Rejected"] = 5] = "Rejected";
ModStatus2[ModStatus2["ChangesMade"] = 6] = "ChangesMade";
ModStatus2[ModStatus2["Inactive"] = 7] = "Inactive";
ModStatus2[ModStatus2["Abandoned"] = 8] = "Abandoned";
ModStatus2[ModStatus2["Deleted"] = 9] = "Deleted";
ModStatus2[ModStatus2["UnderReview"] = 10] = "UnderReview";
return ModStatus2;
})(ModStatus || {});
var FileReleaseType = /* @__PURE__ */ ((FileReleaseType2) => {
FileReleaseType2[FileReleaseType2["Release"] = 1] = "Release";
FileReleaseType2[FileReleaseType2["Beta"] = 2] = "Beta";
FileReleaseType2[FileReleaseType2["Alpha"] = 3] = "Alpha";
return FileReleaseType2;
})(FileReleaseType || {});
var FileModLoaderType = /* @__PURE__ */ ((FileModLoaderType2) => {
FileModLoaderType2[FileModLoaderType2["Any"] = 0] = "Any";
FileModLoaderType2[FileModLoaderType2["Forge"] = 1] = "Forge";
FileModLoaderType2[FileModLoaderType2["Cauldron"] = 2] = "Cauldron";
FileModLoaderType2[FileModLoaderType2["LiteLoader"] = 3] = "LiteLoader";
FileModLoaderType2[FileModLoaderType2["Fabric"] = 4] = "Fabric";
FileModLoaderType2[FileModLoaderType2["Quilt"] = 5] = "Quilt";
FileModLoaderType2[FileModLoaderType2["NeoForge"] = 6] = "NeoForge";
return FileModLoaderType2;
})(FileModLoaderType || {});
var HashAlgo = /* @__PURE__ */ ((HashAlgo2) => {
HashAlgo2[HashAlgo2["Sha1"] = 1] = "Sha1";
HashAlgo2[HashAlgo2["Md5"] = 2] = "Md5";
return HashAlgo2;
})(HashAlgo || {});
var FileStatus = /* @__PURE__ */ ((FileStatus2) => {
FileStatus2[FileStatus2["Processing"] = 1] = "Processing";
FileStatus2[FileStatus2["ChangesRequired"] = 2] = "ChangesRequired";
FileStatus2[FileStatus2["UnderReview"] = 3] = "UnderReview";
FileStatus2[FileStatus2["Approved"] = 4] = "Approved";
FileStatus2[FileStatus2["Rejected"] = 5] = "Rejected";
FileStatus2[FileStatus2["MalwareDetected"] = 6] = "MalwareDetected";
FileStatus2[FileStatus2["Deleted"] = 7] = "Deleted";
FileStatus2[FileStatus2["Archived"] = 8] = "Archived";
FileStatus2[FileStatus2["Testing"] = 9] = "Testing";
FileStatus2[FileStatus2["Released"] = 10] = "Released";
FileStatus2[FileStatus2["ReadyForReview"] = 11] = "ReadyForReview";
FileStatus2[FileStatus2["Deprecated"] = 12] = "Deprecated";
FileStatus2[FileStatus2["Baking"] = 13] = "Baking";
FileStatus2[FileStatus2["AwaitingPublishing"] = 14] = "AwaitingPublishing";
FileStatus2[FileStatus2["FailedPublishing"] = 15] = "FailedPublishing";
return FileStatus2;
})(FileStatus || {});
var FileRelationType = /* @__PURE__ */ ((FileRelationType2) => {
FileRelationType2[FileRelationType2["EmbeddedLibrary"] = 1] = "EmbeddedLibrary";
FileRelationType2[FileRelationType2["OptionalDependency"] = 2] = "OptionalDependency";
FileRelationType2[FileRelationType2["RequiredDependency"] = 3] = "RequiredDependency";
FileRelationType2[FileRelationType2["Tool"] = 4] = "Tool";
FileRelationType2[FileRelationType2["Incompatible"] = 5] = "Incompatible";
FileRelationType2[FileRelationType2["Include"] = 6] = "Include";
return FileRelationType2;
})(FileRelationType || {});
var ModsSearchSortField = /* @__PURE__ */ ((ModsSearchSortField2) => {
ModsSearchSortField2[ModsSearchSortField2["Featured"] = 1] = "Featured";
ModsSearchSortField2[ModsSearchSortField2["Popularity"] = 2] = "Popularity";
ModsSearchSortField2[ModsSearchSortField2["LastUpdated"] = 3] = "LastUpdated";
ModsSearchSortField2[ModsSearchSortField2["Name"] = 4] = "Name";
ModsSearchSortField2[ModsSearchSortField2["Author"] = 5] = "Author";
ModsSearchSortField2[ModsSearchSortField2["TotalDownloads"] = 6] = "TotalDownloads";
ModsSearchSortField2[ModsSearchSortField2["Category"] = 7] = "Category";
ModsSearchSortField2[ModsSearchSortField2["GameVersion"] = 8] = "GameVersion";
return ModsSearchSortField2;
})(ModsSearchSortField || {});
var CurseforgeApiError = class extends Error {
constructor(url, status, body) {
super(`Fail to fetch curseforge api ${url}. Status=${status}. ${body}`);
this.url = url;
this.status = status;
this.body = body;
this.name = "CurseforgeApiError";
}
};
var CurseforgeV1Client = class {
constructor(apiKey, options) {
this.apiKey = apiKey;
this.headers = {
"x-api-key": this.apiKey,
...options == null ? void 0 : options.headers
};
this.baseUrl = (options == null ? void 0 : options.baseUrl) || "https://api.curseforge.com";
this.fetch = (options == null ? void 0 : options.fetch) || ((...args) => fetch(...args));
}
headers;
fetch;
baseUrl;
/**
* @see https://docs.curseforge.com/#get-categories
*/
async getCategories(signal) {
const url = new URL(this.baseUrl + "/v1/categories");
url.searchParams.append("gameId", "432");
const response = await this.fetch(url, {
headers: {
...this.headers,
accept: "application/json"
},
signal
});
if (response.status !== 200) {
throw new CurseforgeApiError(url.toString(), response.status, await response.text());
}
const categories = await response.json();
return categories.data;
}
/**
* Get the mod by mod Id.
* @see https://docs.curseforge.com/#get-mod
* @param modId The id of mod
* @param options The query options
*/
async getMod(modId, signal) {
const url = new URL(this.baseUrl + `/v1/mods/${modId}`);
const response = await this.fetch(url, {
headers: {
accept: "application/json",
...this.headers
},
signal
});
if (response.status !== 200) {
throw new CurseforgeApiError(url.toString(), response.status, await response.text());
}
const result = await response.json();
return result.data;
}
/**
* @see https://docs.curseforge.com/#get-mod-description
*/
async getModDescription(modId, signal) {
const url = new URL(this.baseUrl + `/v1/mods/${modId}/description`);
const response = await this.fetch(url, {
headers: {
...this.headers,
accept: "application/json"
},
signal
});
if (response.status !== 200) {
throw new CurseforgeApiError(url.toString(), response.status, await response.text());
}
const result = await response.json();
return result.data;
}
/**
* @see https://docs.curseforge.com/#get-mod-files
*/
async getModFiles(options, signal) {
var _a, _b, _c, _d;
const url = new URL(this.baseUrl + `/v1/mods/${options.modId}/files`);
url.searchParams.append("gameVersion", options.gameVersion ?? "");
if (options.modLoaderType !== void 0) {
url.searchParams.append("modLoaderType", ((_a = options.modLoaderType) == null ? void 0 : _a.toString()) ?? "");
}
url.searchParams.append("gameVersionTypeId", ((_b = options.gameVersionTypeId) == null ? void 0 : _b.toString()) ?? "");
url.searchParams.append("index", ((_c = options.index) == null ? void 0 : _c.toString()) ?? "");
url.searchParams.append("pageSize", ((_d = options.pageSize) == null ? void 0 : _d.toString()) ?? "");
const response = await this.fetch(url, {
headers: {
...this.headers,
accept: "application/json"
},
signal
});
if (response.status !== 200) {
throw new CurseforgeApiError(url.toString(), response.status, await response.text());
}
const result = await response.json();
return result;
}
/**
* @see https://docs.curseforge.com/#curseforge-core-api-files
*/
async getModFile(modId, fileId, signal) {
const url = new URL(this.baseUrl + `/v1/mods/${modId}/files/${fileId}`);
const response = await this.fetch(url, {
headers: {
...this.headers,
accept: "application/json"
},
signal
});
if (response.status !== 200) {
throw new CurseforgeApiError(url.toString(), response.status, await response.text());
}
const result = await response.json();
return result.data;
}
/**
* @see https://docs.curseforge.com/#get-mods
*/
async getMods(modIds, signal) {
const url = new URL(this.baseUrl + "/v1/mods");
const response = await this.fetch(url, {
method: "POST",
body: JSON.stringify({ modIds }),
headers: {
...this.headers,
"content-type": "application/json",
accept: "application/json"
},
signal
});
if (response.status !== 200) {
throw new CurseforgeApiError(url.toString(), response.status, await response.text());
}
const result = await response.json();
return result.data;
}
/**
* @see https://docs.curseforge.com/#get-files
*/
async getFiles(fileIds, signal) {
const url = new URL(this.baseUrl + "/v1/mods/files");
const response = await this.fetch(url, {
method: "POST",
body: JSON.stringify({ fileIds }),
headers: {
...this.headers,
"content-type": "application/json",
accept: "application/json"
},
signal
});
if (response.status !== 200) {
throw new CurseforgeApiError(url.toString(), response.status, await response.text());
}
const result = await response.json();
return result.data;
}
/**
* @see https://docs.curseforge.com/#search-mods
*/
async searchMods(options, signal) {
var _a, _b, _c;
const url = new URL(this.baseUrl + "/v1/mods/search");
url.searchParams.append("gameId", "432");
if (options.classId) {
url.searchParams.append("classId", options.classId.toString());
}
if (options.categoryId) {
url.searchParams.append("categoryId", options.categoryId.toString());
}
if (options.gameVersion) {
url.searchParams.append("gameVersion", options.gameVersion);
}
if (options.searchFilter) {
url.searchParams.append("searchFilter", options.searchFilter);
}
url.searchParams.append("sortField", ((_a = options.sortField) == null ? void 0 : _a.toString()) ?? 2 /* Popularity */.toString());
url.searchParams.append("sortOrder", options.sortOrder ?? "desc");
if (options.modLoaderType) {
url.searchParams.append("modLoaderType", options.modLoaderType.toString());
}
if (options.modLoaderTypes) {
url.searchParams.append("modLoaderTypes", "[" + options.modLoaderTypes.join(",") + "]");
}
if (options.gameVersionTypeId) {
url.searchParams.append("gameVersionTypeId", options.gameVersionTypeId.toString());
}
url.searchParams.append("index", ((_b = options.index) == null ? void 0 : _b.toString()) ?? "0");
url.searchParams.append("pageSize", ((_c = options.pageSize) == null ? void 0 : _c.toString()) ?? "25");
if (options.slug) {
url.searchParams.append("slug", options.slug);
}
const response = await this.fetch(url, {
headers: {
...this.headers,
accept: "application/json"
},
signal
});
if (response.status !== 200) {
throw new CurseforgeApiError(url.toString(), response.status, await response.text());
}
const result = await response.json();
return result;
}
/**
* https://docs.curseforge.com/#get-mod-file-changelog
*/
async getModFileChangelog(modId, fileId, signal) {
const url = new URL(this.baseUrl + `/v1/mods/${modId}/files/${fileId}/changelog`);
const response = await this.fetch(url, {
headers: {
...this.headers,
accept: "application/json"
},
signal
});
if (response.status !== 200) {
throw new CurseforgeApiError(url.toString(), response.status, await response.text());
}
const result = await response.json();
return result.data;
}
async getFingerprintsMatchesByGameId(gameId, fingerprints, signal) {
const url = new URL(this.baseUrl + `/v1/fingerprints/${gameId}`);
const response = await this.fetch(url, {
method: "POST",
body: JSON.stringify({ fingerprints }),
headers: {
...this.headers,
"content-type": "application/json",
accept: "application/json"
},
signal
});
if (response.status !== 200) {
throw new CurseforgeApiError(url.toString(), response.status, await response.text());
}
const result = await response.json();
return result.data;
}
async getFingerprintsFuzzyMatchesByGameId(gameId, fingerprints, signal) {
const url = new URL(this.baseUrl + `/v1/fingerprints/fuzzy/${gameId}`);
const response = await this.fetch(url, {
method: "POST",
body: JSON.stringify({ fingerprints }),
headers: {
...this.headers,
"content-type": "application/json",
accept: "application/json"
},
signal
});
if (response.status !== 200) {
throw new CurseforgeApiError(url.toString(), response.status, await response.text());
}
const result = await response.json();
return result.data;
}
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
CurseforgeApiError,
CurseforgeV1Client,
FileModLoaderType,
FileRelationType,
FileReleaseType,
FileStatus,
HashAlgo,
ModStatus,
ModsSearchSortField
});
//# sourceMappingURL=index.js.map