Files
Liam 76c6ac6acd
All checks were successful
deploy / deploy (push) Successful in 58s
cleanup, added country page and added button to go to country page on player info
2023-10-22 06:07:17 +01:00

203 lines
5.1 KiB
TypeScript

import { ScoresaberPlayer } from "@/schemas/scoresaber/player";
import { ScoresaberPlayerScore } from "@/schemas/scoresaber/playerScore";
import { FetchQueue } from "../fetchWithQueue";
import { formatString } from "../string";
// Create a fetch instance with a cache
const fetchQueue = new FetchQueue();
// Api endpoints
const API_URL = "https://proxy.fascinated.cc/https://scoresaber.com/api";
const SEARCH_PLAYER_URL =
API_URL + "/players?search={}&page=1&withMetadata=false";
const PLAYER_SCORES =
API_URL + "/player/{}/scores?limit={}&sort={}&page={}&withMetadata=true";
const GET_PLAYER_DATA_FULL = API_URL + "/player/{}/full";
const GET_PLAYERS_URL = API_URL + "/players?page={}";
const GET_PLAYERS_BY_COUNTRY_URL = API_URL + "/players?page={}&countries={}";
const SearchType = {
RECENT: "recent",
TOP: "top",
};
/**
* Search for a list of players by name
*
* @param name the name to search
* @returns a list of players
*/
export async function searchByName(
name: string,
): Promise<ScoresaberPlayer[] | undefined> {
const response = await fetchQueue.fetch(
formatString(SEARCH_PLAYER_URL, true, name),
);
const json = await response.json();
// Check if there was an error fetching the user data
if (json.errorMessage) {
return undefined;
}
return json.players as ScoresaberPlayer[];
}
/**
* Returns the player info for the provided player id
*
* @param playerId the id of the player
* @returns the player info
*/
export async function getPlayerInfo(
playerId: string,
): Promise<ScoresaberPlayer | undefined | null> {
const response = await fetchQueue.fetch(
formatString(GET_PLAYER_DATA_FULL, true, playerId),
);
const json = await response.json();
// Check if there was an error fetching the user data
if (json.errorMessage) {
return undefined;
}
return json as ScoresaberPlayer;
}
/**
* Get the players scores from the given page
*
* @param playerId the id of the player
* @param page the page to get the scores from
* @param searchType the type of search to perform
* @param limit the limit of scores to get
* @returns a list of scores
*/
export async function fetchScores(
playerId: string,
page: number = 1,
searchType: string = SearchType.RECENT,
limit: number = 100,
): Promise<
| {
scores: ScoresaberPlayerScore[];
pageInfo: {
totalScores: number;
page: number;
totalPages: number;
};
}
| undefined
> {
if (limit > 100) {
console.log(
"Scoresaber API only allows a limit of 100 scores per request, limiting to 100.",
);
limit = 100;
}
const response = await fetchQueue.fetch(
formatString(PLAYER_SCORES, true, playerId, limit, searchType, page),
);
const json = await response.json();
// Check if there was an error fetching the user data
if (json.errorMessage) {
return undefined;
}
const scores = json.playerScores as ScoresaberPlayerScore[];
const metadata = json.metadata;
return {
scores: scores,
pageInfo: {
totalScores: metadata.total,
page: metadata.page,
totalPages: Math.ceil(metadata.total / metadata.itemsPerPage),
},
};
}
/**
* Gets all of the players for the given player id
*
* @param playerId the id of the player
* @param searchType the type of search to perform
* @param callback a callback to call when a page is fetched
* @returns a list of scores
*/
export async function fetchAllScores(
playerId: string,
searchType: string,
callback?: (currentPage: number, totalPages: number) => void,
): Promise<ScoresaberPlayerScore[] | undefined> {
const scores = new Array();
let done = false,
page = 1;
do {
const response = await fetchScores(playerId, page, searchType);
if (response == undefined) {
done = true;
break;
}
const { scores: scoresFetched } = response;
if (scoresFetched.length === 0) {
done = true;
break;
}
scores.push(...scoresFetched);
if (callback) {
callback(page, response.pageInfo.totalPages);
}
page++;
} while (!done);
return scores as ScoresaberPlayerScore[];
}
/**
* Get the top players
*
* @param page the page to get the players from
* @param country the country to get the players from
* @returns a list of players
*/
export async function fetchTopPlayers(
page: number = 1,
country?: string,
): Promise<
| {
players: ScoresaberPlayer[];
pageInfo: {
totalPlayers: number;
page: number;
totalPages: number;
};
}
| undefined
> {
const url = country
? formatString(GET_PLAYERS_BY_COUNTRY_URL, true, page, country)
: formatString(GET_PLAYERS_URL, true, page);
const response = await fetchQueue.fetch(url);
const json = await response.json();
// Check if there was an error fetching the user data
if (json.errorMessage) {
return undefined;
}
const players = json.players as ScoresaberPlayer[];
const metadata = json.metadata;
return {
players: players,
pageInfo: {
totalPlayers: metadata.total,
page: metadata.page,
totalPages: Math.ceil(metadata.total / metadata.itemsPerPage),
},
};
}