epicleaderboard-ts
Version:
Universal TypeScript SDK for EpicLeaderboard - Works in Node.js and browsers
243 lines • 9.38 kB
JavaScript
/**
* EpicLeaderboard TypeScript SDK
* Universal leaderboard solution for games
* Works in both Node.js and browser environments
*/
const SERVER_URL = "https://epicleaderboard.com";
// Enums
export var Timeframe;
(function (Timeframe) {
Timeframe[Timeframe["AllTime"] = 0] = "AllTime";
Timeframe[Timeframe["Year"] = 1] = "Year";
Timeframe[Timeframe["Month"] = 2] = "Month";
Timeframe[Timeframe["Week"] = 3] = "Week";
Timeframe[Timeframe["Day"] = 4] = "Day";
})(Timeframe || (Timeframe = {}));
// Add timeframe update bitflag enum
export var TimeframeUpdateResult;
(function (TimeframeUpdateResult) {
TimeframeUpdateResult[TimeframeUpdateResult["None"] = 0] = "None";
TimeframeUpdateResult[TimeframeUpdateResult["AllTime"] = 1] = "AllTime";
TimeframeUpdateResult[TimeframeUpdateResult["Year"] = 2] = "Year";
TimeframeUpdateResult[TimeframeUpdateResult["Month"] = 4] = "Month";
TimeframeUpdateResult[TimeframeUpdateResult["Week"] = 8] = "Week";
TimeframeUpdateResult[TimeframeUpdateResult["Day"] = 16] = "Day"; // 16
})(TimeframeUpdateResult || (TimeframeUpdateResult = {}));
export var IsUsernameAvailableResponse;
(function (IsUsernameAvailableResponse) {
IsUsernameAvailableResponse[IsUsernameAvailableResponse["Available"] = 0] = "Available";
IsUsernameAvailableResponse[IsUsernameAvailableResponse["Invalid"] = 1] = "Invalid";
IsUsernameAvailableResponse[IsUsernameAvailableResponse["Profanity"] = 2] = "Profanity";
IsUsernameAvailableResponse[IsUsernameAvailableResponse["Taken"] = 3] = "Taken";
})(IsUsernameAvailableResponse || (IsUsernameAvailableResponse = {}));
// Utility functions
export class EpicLeaderboardUtils {
/**
* Constructs URL parameters from a key-value map
*/
static constructParamsURL(params) {
if (Object.keys(params).length === 0) {
return "";
}
const encodedParams = Object.entries(params)
.map(([key, value]) => {
const encodedKey = encodeURIComponent(key);
const encodedValue = encodeURIComponent(value);
return `${encodedKey}=${encodedValue}`;
})
.join("&");
return encodedParams;
}
/**
* Serializes a metadata map to JSON string
*/
static serializeMap(metadata) {
return JSON.stringify(metadata);
}
/**
* Deserializes a JSON string to a metadata map
*/
static deserializeMap(json) {
try {
const parsed = JSON.parse(json);
if (typeof parsed === "object" && parsed !== null) {
return parsed;
}
return {};
}
catch {
return {};
}
}
}
// Custom error class for EpicLeaderboard errors
export class EpicLeaderboardError extends Error {
constructor(message, statusCode) {
super(message);
this.statusCode = statusCode;
this.name = "EpicLeaderboardError";
}
}
// Main EpicLeaderboard class
export class EpicLeaderboard {
constructor(baseURL = SERVER_URL) {
this.baseURL = baseURL;
}
/**
* Gets leaderboard entries
*/
async getLeaderboardEntries(game, leaderboard, username, timeframe = Timeframe.AllTime, aroundPlayer = true, local = false) {
const queryParams = {
gameID: game.gameID,
primaryID: leaderboard.primaryID,
secondaryID: leaderboard.secondaryID,
username: username,
timeframe: timeframe.toString(),
around: aroundPlayer ? "1" : "0",
local: local ? "1" : "0",
};
const url = `${this.baseURL}/api/getScores?${EpicLeaderboardUtils.constructParamsURL(queryParams)}`;
try {
const response = await this.makeRequest(url, {
method: "GET",
headers: {
"User-Agent": "X-EpicLeaderboard TS",
"Content-Type": "application/x-www-form-urlencoded",
"Accept": "application/json",
},
});
if (!response.ok) {
throw new EpicLeaderboardError(`Failed to get leaderboard entries: ${response.status}`, response.status);
}
const data = await response.json();
// Parse the response
const result = {
entries: [],
playerEntry: null,
};
// parse scores
if (data.scores && Array.isArray(data.scores)) {
for (const entry of data.scores) {
result.entries.push({
rank: parseInt(entry.rank) || 0,
username: entry.username || "",
score: entry.score || "",
country: entry.country || "",
meta: EpicLeaderboardUtils.deserializeMap(entry.meta) || {},
});
}
}
if (data.playerscore) {
result.playerEntry = {
rank: parseInt(data.playerscore.rank) || 0,
username: data.playerscore.username || "",
score: data.playerscore.score || "",
country: data.playerscore.country || "",
meta: EpicLeaderboardUtils.deserializeMap(data.playerscore.meta) || {},
};
}
return result;
}
catch (error) {
if (error instanceof EpicLeaderboardError) {
throw error;
}
throw new EpicLeaderboardError(`Failed to get leaderboard entries: ${error}`);
}
}
/**
* Submits a leaderboard entry with metadata
*/
async submitLeaderboardEntry(game, leaderboard, username, score, metadata = {}) {
const metaJson = EpicLeaderboardUtils.serializeMap(metadata);
const params = {
gameID: game.gameID,
gameKey: game.gameKey,
primaryID: leaderboard.primaryID,
secondaryID: leaderboard.secondaryID,
username: username,
score: score.toString(),
meta: metaJson,
};
const content = EpicLeaderboardUtils.constructParamsURL(params);
const url = `${this.baseURL}/api/submitScore`;
try {
const response = await this.makeRequest(url, {
method: "POST",
headers: {
"User-Agent": "X-EpicLeaderboard TS",
"Content-Type": "application/x-www-form-urlencoded",
"Accept": "application/json",
},
body: content,
});
if (!response.ok) {
throw new EpicLeaderboardError(`Failed to submit leaderboard entry: ${response.status}`, response.status);
}
const data = await response.json();
return data;
}
catch (error) {
if (error instanceof EpicLeaderboardError) {
throw error;
}
throw new EpicLeaderboardError(`Failed to submit leaderboard entry: ${error}`);
}
}
/**
* Checks if a username is available
*/
async isUsernameAvailable(game, username) {
const queryParams = {
gameID: game.gameID,
username: username,
};
const url = `${this.baseURL}/api/isUsernameAvailable_v2?${EpicLeaderboardUtils.constructParamsURL(queryParams)}`;
try {
const response = await this.makeRequest(url, {
method: "GET",
headers: {
"User-Agent": "X-EpicLeaderboard TS",
"Content-Type": "application/x-www-form-urlencoded",
"Accept": "application/json",
},
});
if (!response.ok) {
throw new EpicLeaderboardError(`Failed to check username availability: ${response.status}`, response.status);
}
const data = await response.text();
// Convert string response to enum
switch (data) {
case "0":
return IsUsernameAvailableResponse.Available;
case "2":
return IsUsernameAvailableResponse.Profanity;
case "3":
return IsUsernameAvailableResponse.Taken;
default:
return IsUsernameAvailableResponse.Invalid;
}
}
catch (error) {
if (error instanceof EpicLeaderboardError) {
throw error;
}
throw new EpicLeaderboardError(`Failed to check username availability: ${error}`);
}
}
/**
* Makes HTTP requests using fetch API (available in both Node.js 18+ and browsers)
*/
async makeRequest(url, options) {
// Check if fetch is available
if (typeof fetch === "undefined") {
throw new EpicLeaderboardError("Fetch API not available. Please use Node.js 18+ or polyfill fetch for older versions.");
}
return fetch(url, options);
}
}
// Default export for convenience
export default EpicLeaderboard;
// Create a default instance
export const epicleaderboard = new EpicLeaderboard();
//# sourceMappingURL=index.js.map