UNPKG

earthmc

Version:

An unofficial EarthMC library providing handy methods and extensive info.

87 lines (71 loc) 3.01 kB
import endpoints from '../endpoints.json' import { request, type Dispatcher } from "undici" import type { AnyMap, RequestBodyV3 } from "../types/index.js" export type EndpointVersion = 'v3' export type ReqOptions = { dispatcher?: Dispatcher } & Omit<Dispatcher.RequestOptions, 'origin' | 'path' | 'method'> & Partial<Pick<Dispatcher.RequestOptions, 'method'>> /** * @internal * Gets the appropriate endpoint from the given keys. */ export const getEndpointUrl = (dataType: keyof typeof endpoints, map: string) => { //@ts-ignore return (endpoints[dataType][map.toLowerCase()]) as string } /** * @internal * Used internally to send a **GET** request to the specified URL * and retrieve the response as a **JSON** object. * * @param url - The full URL to send the request to. * @param retries - The amount of retries to attempt before erroring. Default is 3. */ export const asJSON = async (url: string, options: ReqOptions = null, retries = 3) => { const res = await request(url, options) .then(res => res.body?.json()) .catch(async err => await retry(err, url, retries)) return res ?? await retry(null, url, retries) } const retry = (val: any, url: string, amt: number): any => amt === 1 ? val : asJSON(url, null, amt - 1) let archiveTs = 0 export const useArchive = (ts: number) => archiveTs = ts export const getArchive = async (url: string, unixTs = Date.now()) => { const formattedTs = new Date(unixTs * 1000) .toISOString() .replace(/[^0-9]/g, '') .slice(0, -3) return await asJSON(`https://web.archive.org/web/${formattedTs}id_/${decodeURIComponent(url)}`) } export const configData = async <T>(mapName: AnyMap): Promise<T> => asJSON(getEndpointUrl("config", mapName)) export const playerData = async <T>(mapName: AnyMap): Promise<T> => { const url = mapName.toLowerCase() == 'aurora' ? getEndpointUrl('squaremap', 'players') : getEndpointUrl("players", mapName) return asJSON(url) } export const mapData = async <T>(mapName: AnyMap): Promise<T> => { const url = mapName.toLowerCase() == 'aurora' ? getEndpointUrl('squaremap', 'map') : getEndpointUrl("map", mapName) return !archiveTs ? asJSON(url) : getArchive(url, archiveTs) } /** * Gets info from a given Official API endpoint.\ * If `endpoint` is an empty string or not provided, it will get the base `v3/aurora` endpoint. * @param endpoint The endpoint not including the domain, e.g: "/nations" */ export const oapiDataV3 = async <TQuery>( endpoint?: string, body?: RequestBodyV3<TQuery> ) => { // make sure null/undefined is string if (!endpoint) endpoint = '' const url = getEndpointUrl("towny", "v3/aurora") if (!body) return asJSON(`${url}${endpoint}`) return asJSON(`${url}${endpoint}`, { method: "POST", body: JSON.stringify(body) }) }