mirror of
https://github.com/Kir-Antipov/mc-publish.git
synced 2024-11-22 08:20:58 -05:00
Made a wrapper over Mojang "API"
Well, it's not really an API, but still
This commit is contained in:
parent
8d89961eab
commit
ca25a27ca8
1 changed files with 132 additions and 0 deletions
132
src/games/minecraft/mojang-api-client.ts
Normal file
132
src/games/minecraft/mojang-api-client.ts
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
import { Fetch, createFetch, throwOnError } from "@/utils/net";
|
||||||
|
import { VersionRange, parseVersion } from "@/utils/versioning";
|
||||||
|
import { $i } from "@/utils/collections";
|
||||||
|
import { MinecraftVersion, MinecraftVersionManifest, getMinecraftVersionManifestEntries } from "./minecraft-version";
|
||||||
|
import { getMinecraftVersionRegExp, normalizeMinecraftVersion, normalizeMinecraftVersionRange } from "./minecraft-version-lookup";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default base URL for the Mojang API.
|
||||||
|
*/
|
||||||
|
export const MOJANG_API_URL = "https://piston-meta.mojang.com/mc";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes the configuration options for the Mojang API client.
|
||||||
|
*/
|
||||||
|
export interface MojangApiOptions {
|
||||||
|
/**
|
||||||
|
* The Fetch implementation used for making HTTP requests.
|
||||||
|
*/
|
||||||
|
fetch?: Fetch;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base URL for the Mojang API.
|
||||||
|
*
|
||||||
|
* Defaults to {@link MOJANG_API_URL}.
|
||||||
|
*/
|
||||||
|
baseUrl?: string | URL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A client for interacting with the Mojang API.
|
||||||
|
*/
|
||||||
|
export class MojangApiClient {
|
||||||
|
/**
|
||||||
|
* The Fetch implementation used for making HTTP requests.
|
||||||
|
*/
|
||||||
|
private readonly _fetch: Fetch;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A cached map of all available Minecraft versions.
|
||||||
|
*/
|
||||||
|
private _versions?: ReadonlyMap<string, MinecraftVersion>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A cached regular expression for matching Minecraft version strings.
|
||||||
|
*/
|
||||||
|
private _versionRegExp?: RegExp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@link MojangApiClient} instance.
|
||||||
|
*
|
||||||
|
* @param options - The configuration options for the client.
|
||||||
|
*/
|
||||||
|
constructor(options?: MojangApiOptions) {
|
||||||
|
this._fetch = createFetch({
|
||||||
|
handler: options?.fetch,
|
||||||
|
baseUrl: options?.baseUrl || options?.fetch?.["baseUrl"] || MOJANG_API_URL,
|
||||||
|
})
|
||||||
|
.use(throwOnError());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a specific Minecraft version by its ID.
|
||||||
|
*
|
||||||
|
* @param id - The ID of the Minecraft version to retrieve.
|
||||||
|
*
|
||||||
|
* @returns A promise that resolves to the Minecraft version, or `undefined` if not found.
|
||||||
|
*/
|
||||||
|
async getMinecraftVersion(id: string): Promise<MinecraftVersion | undefined> {
|
||||||
|
const versions = await this.getAllMinecraftVersions();
|
||||||
|
const version = versions.get(id);
|
||||||
|
if (version) {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
const versionRange = await this.getMinecraftVersions(id);
|
||||||
|
return versionRange[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a list of Minecraft versions that match the specified range.
|
||||||
|
*
|
||||||
|
* @param range - A version range to match.
|
||||||
|
*
|
||||||
|
* @returns A promise that resolves to an array of matching Minecraft versions.
|
||||||
|
*/
|
||||||
|
async getMinecraftVersions(range: string | Iterable<string> | VersionRange): Promise<MinecraftVersion[]> {
|
||||||
|
const versions = await this.getAllMinecraftVersions();
|
||||||
|
const regex = await this.getMinecraftVersionRegExp();
|
||||||
|
const normalizedRange = normalizeMinecraftVersionRange(range, versions, regex);
|
||||||
|
|
||||||
|
return $i(versions.values()).filter(x => normalizedRange.includes(x.version)).toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves all available Minecraft versions.
|
||||||
|
*
|
||||||
|
* @returns A promise that resolves to a map of Minecraft versions keyed by their IDs.
|
||||||
|
*/
|
||||||
|
private async getAllMinecraftVersions(): Promise<ReadonlyMap<string, MinecraftVersion>> {
|
||||||
|
if (this._versions) {
|
||||||
|
return this._versions;
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await this._fetch("/game/version_manifest_v2.json");
|
||||||
|
const manifest = await response.json<MinecraftVersionManifest>();
|
||||||
|
const manifestEntries = getMinecraftVersionManifestEntries(manifest);
|
||||||
|
|
||||||
|
const versions = manifestEntries.map((entry, i, self) => {
|
||||||
|
const normalizedVersion = normalizeMinecraftVersion(entry.id, self, i);
|
||||||
|
const version = parseVersion(normalizedVersion);
|
||||||
|
return new MinecraftVersion(entry.id, version, entry.type, entry.url, entry.releaseDate);
|
||||||
|
});
|
||||||
|
|
||||||
|
this._versions = new Map(versions.map(x => [x.id, x]));
|
||||||
|
return this._versions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a regular expression for matching Minecraft version strings.
|
||||||
|
*
|
||||||
|
* @returns A promise that resolves to a `RegExp` for matching Minecraft version strings.
|
||||||
|
*/
|
||||||
|
private async getMinecraftVersionRegExp(): Promise<RegExp> {
|
||||||
|
if (this._versionRegExp) {
|
||||||
|
return this._versionRegExp;
|
||||||
|
}
|
||||||
|
|
||||||
|
const versions = await this.getAllMinecraftVersions();
|
||||||
|
this._versionRegExp = getMinecraftVersionRegExp(versions.keys());
|
||||||
|
return this._versionRegExp;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue