import { join } from "path"; /** * Get a fetch function * @returns A fetch function */ export function getFetch(): typeof fetch { if (typeof fetch !== "function") { return require("node-fetch"); } return fetch; } export function requestWithDefaults( baseURL: string, defaultInit?: RequestInit ): (endpoint: string, init?: RequestInit) => Promise { return async function ( endpoint: string, overrideInit?: RequestInit ): Promise { let response = await getFetch()( join(baseURL, endpoint), defaultInit ? deepMerge(defaultInit, overrideInit) : overrideInit ); if (response.ok) { return response; } throw { ...new Error("non-200 status code"), response }; }; } /** * Generate RequestInit for Hypixel authorization * @param key The API key * @returns The RequestInit */ export function authorize(key: string): RequestInit { return { headers: { "API-Key": key } }; } /** * Simple object check * @param item item to check * @returns Whether item is an object */ export function isObject(item: any): boolean { return item && typeof item === "object" && !Array.isArray(item); } /** * Deep merge two objects * @param target Target (base object) * @param sources Objects to merge into target (in order) * @returns Deep merged object */ export function deepMerge(target: T, ...sources: T[]): T { if (!sources.length) return target; const source = sources.shift(); // Two separate checks for source to make typescript chill if (isObject(target) && isObject(source) && source) { for (const key in source) { if (isObject(source[key])) { if (!target[key]) Object.assign(target, { [key]: {} }); deepMerge(target[key], source[key]); } else { Object.assign(target, { [key]: source[key] }); } } } return deepMerge(target, ...sources); }