@xmcl/curseforge
Version:
An implementation of curseforge (official) API in https://docs.curseforge.com/
591 lines • 14.6 kB
TypeScript
/**
* @module @xmcl/curseforge
*/
export interface ModAsset {
id: number;
modId: number;
title: string;
description: string;
thumbnailUrl: string;
url: string;
}
export declare const enum ModStatus {
New = 1,
ChangesRequired = 2,
UnderSoftReview = 3,
Approved = 4,
Rejected = 5,
ChangesMade = 6,
Inactive = 7,
Abandoned = 8,
Deleted = 9,
UnderReview = 10
}
export declare const enum FileReleaseType {
Release = 1,
Beta = 2,
Alpha = 3
}
export declare const enum FileModLoaderType {
Any = 0,
Forge = 1,
Cauldron = 2,
LiteLoader = 3,
Fabric = 4,
Quilt = 5,
NeoForge = 6
}
export interface FileIndex {
gameVersion: string;
fileId: number;
filename: string;
releaseType: FileReleaseType;
gameVersionTypeId: number | null;
modLoader: FileModLoaderType;
}
export interface Mod {
/**
* The addon id. You can use this in many functions required the `addonID`
*/
id: number;
/**
* Game id. Minecraft is 432.
*/
gameId: number;
/**
* The display name of the addon
*/
name: string;
/**
* The mod slug that would appear in the URL
*/
slug: string;
/** Relevant links for the mod such as Issue tracker and Wiki */
links: {
websiteUrl: string;
wikiUrl: string;
issuesUrl: string;
sourceUrl: string;
};
/**
* One line summery
*/
summary: string;
/**
* Current mod status
*/
status: ModStatus;
/**
* Number of downloads for the mod
*/
downloadCount: number;
/**
* Whether the mod is included in the featured mods list
*/
isFeatured: boolean;
/**
* The main category of the mod as it was chosen by the mod author
*/
primaryCategoryId: number;
/**
* List of categories that this mod is related to
*/
categories: ModCategory[];
/**
* The class id this mod belongs to
*/
classId: number | null;
/**
* The list of authors
*/
authors: Author[];
logo: ModAsset;
screenshots: ModAsset[];
/**
* The id of the main file of the mod
*/
mainFileId: number;
latestFiles: File[];
/**
* List of file related details for the latest files of the mod
*/
latestFilesIndexes: FileIndex[];
/**
* The creation date of the mod
*/
dateCreated: string;
dateModified: string;
dateReleased: string;
/**
* Is mod allowed to be distributed
*/
allowModDistribution: boolean | null;
/**
* The mod popularity rank for the game
*/
gamePopularityRank: number;
/**
* Is the mod available for search. This can be false when a mod is experimental, in a deleted state or has only alpha files
*/
isAvailable: boolean;
/**
* The default download file id
*/
defaultFileId: number;
/**
* The mod's thumbs up count
*/
thumbsUpCount: number;
}
export interface GameVersionLatestFile {
gameVersion: string;
projectFileId: number;
projectFileName: string;
fileType: number;
}
export interface CategorySection {
id: number;
gameId: number;
name: string;
packageType: number;
path: string;
initialInclusionPattern: string;
extraIncludePattern?: any;
gameCategoryId: number;
}
export declare const enum HashAlgo {
Sha1 = 1,
Md5 = 2
}
export interface FileHash {
algo: HashAlgo;
value: string;
}
export declare const enum FileStatus {
Processing = 1,
ChangesRequired = 2,
UnderReview = 3,
Approved = 4,
Rejected = 5,
MalwareDetected = 6,
Deleted = 7,
Archived = 8,
Testing = 9,
Released = 10,
ReadyForReview = 11,
Deprecated = 12,
Baking = 13,
AwaitingPublishing = 14,
FailedPublishing = 15
}
export declare const enum FileRelationType {
EmbeddedLibrary = 1,
OptionalDependency = 2,
RequiredDependency = 3,
Tool = 4,
Incompatible = 5,
Include = 6
}
export interface FileDependency {
modId: number;
relationType: FileRelationType;
}
export interface File {
/**
* The fileID
*/
id: number;
/**
* The game id related to the mod that this file belongs to
*/
gameId: number;
/**
* The projectId (addonId)
*/
modId: number;
/**
* Whether the file is available to download
*/
isAvailable: boolean;
/**
* Display name
*/
displayName: string;
/**
* File name. Might be the same with `displayName`
*/
fileName: string;
/**
* Release or type.
* - `1` is the release
* - `2` beta
* - `3` alpha
*/
releaseType: number;
fileStatus: FileStatus;
hashes: FileHash[];
fileFingerprint: number;
/**
* The date of this file uploaded
*/
fileDate: string;
/**
* # bytes of this file.
*/
fileLength: number;
/**
* Number of downloads for the mod
*/
downloadCount: number;
/**
* Url to download
*/
downloadUrl?: string;
/**
* Game version string array, like `["1.12.2"]`
*/
gameVersions: string[];
/**
* Metadata used for sorting by game versions
*/
isAlternate: boolean;
alternateFileId: number;
dependencies: FileDependency[];
/**
* What files inside?
*/
modules: Module[];
sortableGameVersions?: SortableGameVersion[];
}
export interface SortableGameVersion {
gameVersionPadded: string;
gameVersion: string;
gameVersionReleaseDate: string;
gameVersionName: string;
}
/**
* Represent a file in a `File`.
*/
export interface Module {
/**
* Actually the file name, not the folder
*/
name: string;
/**
* A number represent fingerprint
*/
fingerprint: number;
type: number;
}
/**
* The author info
*/
export interface Author {
/**
* The project id of this query
*/
projectId: number;
projectTitleId?: any;
projectTitleTitle?: any;
/**
* Display name of the author
*/
name: string;
/**
* The full url of author homepage in curseforge
*/
url: string;
/**
* The id of this author
*/
id: number;
userId: number;
twitchId: number;
}
export interface ModCategory {
/**
* The category id
*/
id: number;
gameId: number;
name: string;
slug: string;
url: string;
iconUrl: string;
dateModified: string;
/**
* A top level category for other categories
*/
isClass: boolean | null;
/**
* The class id of the category, meaning - the class of which this category is under
*/
classId: number | null;
/**
* The parent category for this category
*/
parentCategoryId: number | null;
/**
* The display index for this category
*/
displayIndex: number | null;
}
/**
* The search options of the search API.
*
* @see {@link searchMods}
*/
export interface SearchOptions {
/**
* The category section id, which is also a category id.
* You can fetch if from `getCategories`.
*
* To get available categories, you can:
*
* ```ts
* const cat = await getCategories();
* const sectionIds = cat
* .filter(c => c.gameId === 432) // 432 is minecraft game id
* .filter(c => c.rootGameCategoryId === null).map(c => c.id);
* // the sectionIds is all normal sections here
* ```
*
* @see {@link getCategories}
*/
classId?: number;
/**
* This is actually the sub category id of the `sectionId`. All the numbers for this should also be fetch by `getCategories`.
*
* To get available values, you can:
*
* ```ts
* const cat = await getCategories();
* const sectionId = 6; // the mods
* const categoryIds = cat
* .filter(c => c.gameId === 432) // 432 is minecraft game id
* .filter(c => c.rootGameCategoryId === sectionId) // only under the section id
* .map(c => c.id);
* // Use categoryIds' id to search under the corresponding section id.
* ```
*
* @see {@link getCategories}
*/
categoryId?: number;
/**
* The game id. The Minecraft is 432.
*
* @default 432
*/
gameId?: number;
/**
* The game version. For Minecraft, it should looks like 1.12.2.
*/
gameVersion?: string;
/**
* The index of the addon, NOT the page!
*
* When your page size is 25, if you want to get next page contents, you should have index = 25 to get 2nd page content.
*
* @default 0
*/
index?: number;
/**
* Filter by ModsSearchSortField enumeration
*/
sortField?: ModsSearchSortField;
/**
* 'asc' if sort is in ascending order, 'desc' if sort is in descending order
*/
sortOrder?: 'asc' | 'desc';
/**
* Filter only mods associated to a given modloader (Forge, Fabric ...). Must be coupled with gameVersion.
*/
modLoaderType?: FileModLoaderType;
modLoaderTypes?: string[];
/**
* Filter only mods that contain files tagged with versions of the given gameVersionTypeId
*/
gameVersionTypeId?: number;
/**
* Filter by slug (coupled with classId will result in a unique result).
*/
slug?: string;
/**
* The page size, or the number of the addons in a page.
*
* @default 25
*/
pageSize?: number;
/**
* The keyword of search. If this is absent, it just list out the available addons by `sectionId` and `categoryId`.
*/
searchFilter?: string;
}
export declare const enum ModsSearchSortField {
Featured = 1,
Popularity = 2,
LastUpdated = 3,
Name = 4,
Author = 5,
TotalDownloads = 6,
Category = 7,
GameVersion = 8
}
/**
* The options to query
*/
export interface QueryOption {
/**
* Additional header
*/
headers?: Record<string, any>;
/**
* override the http client
*/
client?: (url: string, options: QueryOption, body?: object, text?: boolean) => Promise<object | string>;
}
export interface GetModFilesOptions {
modId: number;
gameVersion?: string;
modLoaderType?: FileModLoaderType;
/**
* Filter only files that are tagged with versions of the given gameVersionTypeId
*/
gameVersionTypeId?: number;
index?: number;
pageSize?: number;
}
export interface Pagination {
/**
* A zero based index of the first item that is included in the response
*/
index: number;
/**
* The requested number of items to be included in the response
*/
pageSize: number;
/**
* The actual number of items that were included in the response
*/
resultCount: number;
/**
* The total number of items available by the fetch
*/
totalCount: number;
}
export interface CurseforgeClientOptions {
/**
* Extra headers
*/
headers?: Record<string, string>;
/**
* The base url, the default is `https://api.curseforge.com`
*/
baseUrl?: string;
/**
* The fetch function to use. The default is `fetch`
*/
fetch?: typeof fetch;
}
export interface FingerprintMatch {
/**
* The mod id
*/
id: number;
file: File;
latestFiles: File[];
}
export interface FingerprintsMatchesResult {
data: {
isCacheBuilt: boolean;
exactMatches: FingerprintMatch[];
exactFingerprints: number[];
partialMatches: FingerprintMatch[];
partialFingerprints: object;
unmatchedFingerprints: number[];
};
}
export interface FingerprintFuzzyMatch {
id: number;
file: File;
latestFiles: File[];
fingerprints: number[];
}
export interface FingerprintFuzzyMatchResult {
data: {
fuzzyMatches: FingerprintFuzzyMatch[];
};
}
export declare class CurseforgeApiError extends Error {
readonly url: string;
readonly status: number;
readonly body: string;
constructor(url: string, status: number, body: string);
}
/**
* Reference the https://docs.curseforge.com/#curseforge-core-api-mods
*/
export declare class CurseforgeV1Client {
private apiKey;
headers: Record<string, string>;
private fetch;
private baseUrl;
constructor(apiKey: string, options?: CurseforgeClientOptions);
/**
* @see https://docs.curseforge.com/#get-categories
*/
getCategories(signal?: AbortSignal): Promise<ModCategory[]>;
/**
* Get the mod by mod Id.
* @see https://docs.curseforge.com/#get-mod
* @param modId The id of mod
* @param options The query options
*/
getMod(modId: number, signal?: AbortSignal): Promise<Mod>;
/**
* @see https://docs.curseforge.com/#get-mod-description
*/
getModDescription(modId: number, signal?: AbortSignal): Promise<string>;
/**
* @see https://docs.curseforge.com/#get-mod-files
*/
getModFiles(options: GetModFilesOptions, signal?: AbortSignal): Promise<{
data: File[];
pagination: Pagination;
}>;
/**
* @see https://docs.curseforge.com/#curseforge-core-api-files
*/
getModFile(modId: number, fileId: number, signal?: AbortSignal): Promise<File>;
/**
* @see https://docs.curseforge.com/#get-mods
*/
getMods(modIds: number[], signal?: AbortSignal): Promise<Mod[]>;
/**
* @see https://docs.curseforge.com/#get-files
*/
getFiles(fileIds: number[], signal?: AbortSignal): Promise<File[]>;
/**
* @see https://docs.curseforge.com/#search-mods
*/
searchMods(options: SearchOptions, signal?: AbortSignal): Promise<{
data: Mod[];
pagination: Pagination;
}>;
/**
* https://docs.curseforge.com/#get-mod-file-changelog
*/
getModFileChangelog(modId: number, fileId: number, signal?: AbortSignal): Promise<string>;
getFingerprintsMatchesByGameId(gameId: number, fingerprints: number[], signal?: AbortSignal): Promise<{
isCacheBuilt: boolean;
exactMatches: FingerprintMatch[];
exactFingerprints: number[];
partialMatches: FingerprintMatch[];
partialFingerprints: object;
unmatchedFingerprints: number[];
}>;
getFingerprintsFuzzyMatchesByGameId(gameId: number, fingerprints: number[], signal?: AbortSignal): Promise<{
fuzzyMatches: FingerprintFuzzyMatch[];
}>;
}
//# sourceMappingURL=index.d.ts.map