From a3486193c8ae8e39908b135127133ac617270729 Mon Sep 17 00:00:00 2001 From: Rodry <38259440+ImRodry@users.noreply.github.com> Date: Sun, 6 Feb 2022 13:07:50 +0000 Subject: [PATCH] refactor: switch to undici undici's fetch is coming to node in v18: https://github.com/nodejs/node/pull/41749 Not putting this in production because undici is using many experimental node features for now Ref: https://github.com/Hypixel-Translators/hypixel-translators-bot/commit/6ce33eb8cf35d1362029d81fd1ad9a9f3eb7ad8f --- .github/workflows/lintCompile.yml | 2 +- package.json | 4 ++-- src/commands/Admin/eval.ts | 2 +- src/commands/Utility/hypixelstats.ts | 19 ++++++++------- src/commands/Utility/hypixelverify.ts | 11 ++++----- src/commands/Utility/languagestats.ts | 2 +- src/commands/Utility/minecraft.ts | 14 ++++++------ src/lib/util.ts | 33 +++++++++++++++++---------- yarn.lock | 20 ++++++++-------- 9 files changed, 56 insertions(+), 51 deletions(-) diff --git a/.github/workflows/lintCompile.yml b/.github/workflows/lintCompile.yml index d98ebdcd8d0..f7851f25fd2 100644 --- a/.github/workflows/lintCompile.yml +++ b/.github/workflows/lintCompile.yml @@ -15,7 +15,7 @@ jobs: - name: Use Node.js 16 uses: actions/setup-node@v2 with: - node-version: 16 + node-version: 18 cache: "yarn" - name: Install dependencies and compile run: yarn diff --git a/package.json b/package.json index 8ed4cfe6fc3..dcf7ac5fb0e 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,6 @@ "dependencies": { "@crowdin/crowdin-api-client": "^1.17.0", "@messageformat/core": "^3.0.1", - "axios": "^0.26.1", "canvas": "2.9.0", "discord.js": "14.0.0-dev.1650413390-585169f", "language-flag-colors": "^2.0.4", @@ -27,10 +26,11 @@ "node-cron": "^3.0.0", "puppeteer": "^13.6.0", "typescript": "^4.6.3", + "undici": "^4.13.0", "uuid": "^8.3.2" }, "engines": { - "node": "16.x" + "node": "18.x" }, "devDependencies": { "@types/node": "^16.11.27", diff --git a/src/commands/Admin/eval.ts b/src/commands/Admin/eval.ts index 33cf58c4f16..f62a1c56e8d 100644 --- a/src/commands/Admin/eval.ts +++ b/src/commands/Admin/eval.ts @@ -1,7 +1,7 @@ /* eslint-disable import/order */ /* eslint-disable @typescript-eslint/no-unused-vars */ const fs = require("node:fs"), - axios = require("axios"), + { fetch } = require("undici"), flagColors = require("language-flag-colors"), { colors, listeningStatuses, watchingStatuses, playingStatuses, ids } = require("../../config.json"), { crowdin } = require("../../index"), diff --git a/src/commands/Utility/hypixelstats.ts b/src/commands/Utility/hypixelstats.ts index ab905faec82..1037628eed6 100644 --- a/src/commands/Utility/hypixelstats.ts +++ b/src/commands/Utility/hypixelstats.ts @@ -1,10 +1,10 @@ -import axios from "axios" import { type GuildMember, type Message, EmbedBuilder, SelectMenuBuilder, ComponentType, ApplicationCommandOptionType, Colors } from "discord.js" +import { fetch } from "undici" import { ids } from "../../config.json" import { client } from "../../index" import { db, type DbUser } from "../../lib/dbclient" -import { fetchSettings, generateTip, getMCProfile, getUUID, gql, type GraphQLQuery, transformDiscordLocale, updateRoles } from "../../lib/util" +import { postSettings, generateTip, getMCProfile, getUUID, gql, type GraphQLQuery, transformDiscordLocale, updateRoles } from "../../lib/util" import type { Command, GetStringFunction } from "../../lib/imports" @@ -48,19 +48,18 @@ const command: Command = { if (!uuid) throw "falseUser" // Make a request to the slothpixel api (hypixel api but we dont need an api key) - const graphqlQuery = await axios - .get("https://api.slothpixel.me/api/graphql", { - ...fetchSettings, - data: { query: query, variables: { uuid }, operationName: "HypixelStats" }, - }) - .then(res => res.data) + const graphqlQuery = (await fetch("https://api.slothpixel.me/api/graphql", { + ...postSettings, + body: JSON.stringify({ query: query, variables: { uuid }, operationName: "HypixelStats" }), + }) + .then(res => res.json()) .catch(e => { - if (e.code === "ECONNABORTED") { + if (e.code === "ECONNRESET") { // This means the request timed out console.error("Slothpixel is down, sending error.") throw "apiError" } else throw e - }), + })) as GraphQLQuery, playerJson = graphqlQuery.data.players.player, guildJson = graphqlQuery.data.guild diff --git a/src/commands/Utility/hypixelverify.ts b/src/commands/Utility/hypixelverify.ts index dafe428539b..63cb9bf624a 100644 --- a/src/commands/Utility/hypixelverify.ts +++ b/src/commands/Utility/hypixelverify.ts @@ -1,5 +1,5 @@ -import axios from "axios" import { ApplicationCommandOptionType, EmbedBuilder } from "discord.js" +import { fetch } from "undici" import { colors, ids } from "../../config.json" import { db, type DbUser } from "../../lib/dbclient" @@ -36,16 +36,15 @@ const command: Command = { if (!uuid) throw "noUser" // Make a response to the slothpixel api (hypixel api but we dont need an api key) - const json = await axios - .get(`https://api.slothpixel.me/api/players/${uuid}`, fetchSettings) - .then(res => res.data) + const json = (await fetch(`https://api.slothpixel.me/api/players/${uuid}`, fetchSettings) + .then(res => res.json()) .catch(e => { - if (e.code === "ECONNABORTED") { + if (e.code === "ECONNRESET") { // This means the request timed out console.error("slothpixel is down, sending error.") throw "apiError" } else throw e - }) + })) as GraphQLQuery["data"]["players"]["player"] & { error?: string } // Handle errors if (json.error === "Player does not exist" || json.error === "Invalid username or UUID!") throw "falseUser" diff --git a/src/commands/Utility/languagestats.ts b/src/commands/Utility/languagestats.ts index f04cfb6a436..5881979d2c7 100644 --- a/src/commands/Utility/languagestats.ts +++ b/src/commands/Utility/languagestats.ts @@ -41,7 +41,7 @@ const command: Command = { .getProjectProgress(ids.projects.hypixel) .then(res => res.data.find(language => language.data.languageId === lang.id)?.data ?? null) .catch(e => { - if (e.code === "ECONNABORTED") { + if (e.code === "ECONNRESET") { // This means the request timed out console.error("Crowdin API is down, sending error.") throw "apiError" diff --git a/src/commands/Utility/minecraft.ts b/src/commands/Utility/minecraft.ts index 0d4c3b1117d..0f12e28c8e0 100644 --- a/src/commands/Utility/minecraft.ts +++ b/src/commands/Utility/minecraft.ts @@ -1,5 +1,5 @@ -import axios from "axios" import { ComponentType, GuildMember, Message, ApplicationCommandOptionType, EmbedBuilder } from "discord.js" +import { fetch } from "undici" import { colors, ids } from "../../config.json" import { client } from "../../index" @@ -174,17 +174,17 @@ const command: Command = { export default command async function getPlayer(uuid: string) { - const json = await axios - .get(`https://sessionserver.mojang.com/session/minecraft/profile/${uuid}`, fetchSettings) - .then(res => res.data) + const json = (await fetch(`https://sessionserver.mojang.com/session/minecraft/profile/${uuid}`, fetchSettings).then(res => + res.json(), + )) as UserProfile & { error?: string } if (json.error) throw "falseUUID" return json } async function getNameHistory(uuid: string) { - const json = await axios - .get(`https://api.mojang.com/user/profiles/${uuid}/names`, fetchSettings) - .then(res => res.data || null) + const json = (await fetch(`https://api.mojang.com/user/profiles/${uuid}/names`, fetchSettings) + .then(res => res.json()) + .catch(() => null)) as NameHistory[] | MCAPIError if (!json || "error" in json) throw "falseUUID" return json.reverse() } diff --git a/src/lib/util.ts b/src/lib/util.ts index c26cf54144d..bcae519606a 100644 --- a/src/lib/util.ts +++ b/src/lib/util.ts @@ -3,7 +3,6 @@ import { readdirSync } from "node:fs" import process from "node:process" import { setInterval } from "node:timers" -import axios from "axios" import { type ChatInputCommandInteraction, type GuildMember, @@ -21,6 +20,7 @@ import { LocaleString, } from "discord.js" import puppeteer from "puppeteer" +import { fetch, RequestInit } from "undici" import { v4 } from "uuid" import { db } from "./dbclient" @@ -33,7 +33,12 @@ import type { ResponseObject, TranslationStatusModel } from "@crowdin/crowdin-ap // #region Variables -export const fetchSettings = { headers: { "User-Agent": "Hypixel Translators Bot" }, timeout: 30_000 } +export const fetchSettings: RequestInit = { headers: { "User-Agent": "Hypixel Translators Bot" } } + +export const postSettings: RequestInit = { + headers: { "Content-Type": "application/json", ...fetchSettings.headers }, + method: "POST", +} // Browser-related variables, not exported let browser: puppeteer.Browser | null = null, @@ -303,17 +308,15 @@ export async function getInviteLink() { return `https://discord.gg/${inviteCode}` } -export async function getMCProfile(uuid: string) { - return await axios - .get(`https://sessionserver.mojang.com/session/minecraft/profile/${uuid}`, fetchSettings) - .then(json => json.data) +export function getMCProfile(uuid: string) { + return fetch(`https://sessionserver.mojang.com/session/minecraft/profile/${uuid}`, fetchSettings) + .then(res => res.json() as Promise) .catch(() => null) } -export async function getUUID(username: string): Promise { - return await axios - .get(`https://api.mojang.com/users/profiles/minecraft/${username}`, fetchSettings) - .then(data => data.data.id ?? null) +export function getUUID(username: string) { + return fetch(`https://api.mojang.com/users/profiles/minecraft/${username}`, fetchSettings) + .then(async res => ((await res.json()) as UUIDResponse).id ?? null) .catch(() => null) } @@ -342,13 +345,14 @@ export function parseToNumberString(num: number, getString: GetStringFunction): return format(num) } -export async function restart(interaction?: ChatInputCommandInteraction) { - await axios.delete("https://api.heroku.com/apps/hypixel-translators/dynos", { +export function restart(interaction?: ChatInputCommandInteraction) { + return fetch("https://api.heroku.com/apps/hypixel-translators/dynos", { headers: { "User-Agent": `${interaction?.user.tag ?? client.user.tag}`, Authorization: `Bearer ${process.env.HEROKU_API}`, Accept: "application/vnd.heroku+json; version=3", }, + method: "DELETE", }) } @@ -620,4 +624,9 @@ export interface Stats { errorMessage?: string } +interface UUIDResponse { + name: string + id: string +} + // #endregion diff --git a/yarn.lock b/yarn.lock index 37c5e1c0162..4ee9c9af207 100644 --- a/yarn.lock +++ b/yarn.lock @@ -406,13 +406,6 @@ axios@0.21.3: dependencies: follow-redirects "^1.14.0" -axios@^0.26.1: - version "0.26.1" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.26.1.tgz#1ede41c51fcf51bbbd6fd43669caaa4f0495aaa9" - integrity sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA== - dependencies: - follow-redirects "^1.14.8" - balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" @@ -1010,10 +1003,10 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== -follow-redirects@^1.14.0, follow-redirects@^1.14.8: - version "1.14.9" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7" - integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w== +follow-redirects@^1.14.0: + version "1.14.7" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.7.tgz#2004c02eb9436eee9a21446a6477debf17e81685" + integrity sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ== form-data@^3.0.0: version "3.0.1" @@ -2155,6 +2148,11 @@ unbzip2-stream@1.4.3: buffer "^5.2.1" through "^2.3.8" +undici@^4.13.0: + version "4.13.0" + resolved "https://registry.yarnpkg.com/undici/-/undici-4.13.0.tgz#7d10fe150c3241a6b3b0eba80eff59c9fb40f359" + integrity sha512-8lk8S/f2V0VUNGf2scU2b+KI2JSzEQLdCyRNRF3XmHu+5jectlSDaPSBCXAHFaUlt1rzngzOBVDgJS9/Gue/KA== + undici@^4.16.0: version "4.16.0" resolved "https://registry.yarnpkg.com/undici/-/undici-4.16.0.tgz#469bb87b3b918818d3d7843d91a1d08da357d5ff"