From 5a474ba8fb4abc8907539e080f190e637eeca659 Mon Sep 17 00:00:00 2001 From: kdh8219 <65698239+kdh8219@users.noreply.github.com> Date: Wed, 26 Apr 2023 19:23:30 +0900 Subject: [PATCH] start migrationing to typescript --- .env | 1 + README.md | 11 +++ commands/add_nick_super.js | 72 --------------- main.js | 41 --------- package.json | 11 ++- src/command/commands.ts | 6 ++ .../command/commands}/add_nick.js | 0 src/command/commands/add_nick_super.ts | 89 +++++++++++++++++++ .../command/commands}/del_nick_super.js | 0 .../command/commands}/del_user_super.js | 0 {commands => src/command/commands}/dm.trash | 0 .../command/commands}/get_blacklist.js | 0 .../command/commands}/get_file.js | 0 .../command/commands}/get_file_super.js | 20 +++-- .../command/commands}/get_users.js | 0 .../command/commands}/mov_blacklist_super.js | 18 +++- {commands => src/command/commands}/ping.js | 0 {commands => src/command/commands}/search.js | 0 {commands => src/command/commands}/user.trash | 0 deploy.js => src/deploy.js | 0 src/functions.ts | 65 ++++++++++++++ src/main.ts | 54 +++++++++++ src/utils/two-way-map.ts | 47 ++++++++++ src/wrapper/firebase.ts | 19 ++++ src/wrapper/mojang-api.ts | 34 +++++++ temp/migration_database.ts | 1 + yarn.lock | 5 ++ 27 files changed, 371 insertions(+), 123 deletions(-) create mode 100644 .env create mode 100644 README.md delete mode 100755 commands/add_nick_super.js delete mode 100755 main.js create mode 100644 src/command/commands.ts rename {commands => src/command/commands}/add_nick.js (100%) create mode 100755 src/command/commands/add_nick_super.ts rename {commands => src/command/commands}/del_nick_super.js (100%) rename {commands => src/command/commands}/del_user_super.js (100%) rename {commands => src/command/commands}/dm.trash (100%) rename {commands => src/command/commands}/get_blacklist.js (100%) rename {commands => src/command/commands}/get_file.js (100%) rename {commands => src/command/commands}/get_file_super.js (69%) rename {commands => src/command/commands}/get_users.js (100%) rename {commands => src/command/commands}/mov_blacklist_super.js (72%) rename {commands => src/command/commands}/ping.js (100%) rename {commands => src/command/commands}/search.js (100%) rename {commands => src/command/commands}/user.trash (100%) rename deploy.js => src/deploy.js (100%) create mode 100644 src/functions.ts create mode 100755 src/main.ts create mode 100644 src/utils/two-way-map.ts create mode 100644 src/wrapper/firebase.ts create mode 100644 src/wrapper/mojang-api.ts create mode 100644 temp/migration_database.ts diff --git a/.env b/.env new file mode 100644 index 0000000..406d333 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +firebase_cert = '{"type":"service_account","project_id":"k2r-ec9d5","private_key_id":"3adfb8f91bb2de3c2b2814ebbd15bb7ed131d360","private_key":"btw","client_email":"firebase-adminsdk-ege3y@k2r-ec9d5.iam.gserviceaccount.com","client_id":"114795287777519067325","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_x509_cert_url":"https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-ege3y%40k2r-ec9d5.iam.gserviceaccount.com"}' \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..9966c2c --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# 2K2R namebot + +> A discord bot that manage users's minecraft accounts + +## TO-DO + +[ ] db 바꾸기(firebase/database->firebase/firestore) +[ ] typrscript 마이그레이션 완료하기 +[ ] 유져 나가면 지우는 기능 만들기 +[ ] 출력 형식 바꾸기 +[ ] 샤딩 diff --git a/commands/add_nick_super.js b/commands/add_nick_super.js deleted file mode 100755 index 6c518f0..0000000 --- a/commands/add_nick_super.js +++ /dev/null @@ -1,72 +0,0 @@ -const { SlashCommandBuilder, PermissionFlagsBits } = require("discord.js"); -const mojangAPI = new (require("mojang-api-js"))(); - -const firebase_admin = require("firebase-admin"); -const { getDatabase } = require("firebase-admin/database"); -const serviceAccount = require("../firebase/conf.json"); -if (!firebase_admin.apps.length) { - firebase_admin.initializeApp({ - credential: firebase_admin.credential.cert(serviceAccount), - databaseURL: "https://two-k-two-r-name-bot-default-rtdb.firebaseio.com", - databaseAuthVariableOverride: { - uid: process.env.FIREBASE_UID, - }, - }); -} -const firebase = getDatabase().ref("/"); - -module.exports = { - data: new SlashCommandBuilder() - .setName("add_nick_super") - .setDescription("Add your nickname on the list and share it to 2k2rs") - .addUserOption((option) => option.setName("discord").setDescription("discord account").setRequired(true)) - .addStringOption((option) => option.setName("minecraft_id").setDescription("id of the minecraft account").setRequired(true)) - .setDefaultMemberPermissions(PermissionFlagsBits.Administrator) - .setDMPermission(false), - async execute(interaction) { - await interaction.deferReply({ ephemeral: true }); - let minecraft; - try { - minecraft = await mojangAPI.nameToUuid(interaction.options.getString("minecraft_id")); - } catch (err) { - if (err.message == "204 status code") { - await interaction.editReply({ content: "`에러`: 닉네임 검색을 실패했어요(닉네임을 정확하게 입력했나요?)", ephemeral: true }); - return; - } - } - - let data = (await firebase.get()).val(); - const discord_id = interaction.options.getUser("discord").id; - - for (let discord_search_point in data["blacklist"]) { - if (data["blacklist"][discord_search_point].discord == discord_id) { - await interaction.editReply({ content: "`에러`:해당 디스코드 아이디는 블랙리스팅 되었습니다!", ephemeral: true }); - return; - } - for (let minecraft_search_point in data["blacklist"][discord_search_point].minecraft) { - if (data["blacklist"][discord_search_point].minecraft[minecraft_search_point] == minecraft["id"]) { - await interaction.editReply({ content: "`에러`:해당 마인크래프트 아이디는 블랙리스팅 되었습니다!", ephemeral: true }); - return; - } - } //신규 마크일 경우 - } //신규 디코일 경우 - - for (let discord_search_point in data["members"]) { - for (let minecraft_search_point in data["members"][discord_search_point].minecraft) { - if (data["members"][discord_search_point].minecraft[minecraft_search_point] == minecraft["id"]) { - await interaction.editReply({ content: "`에러`:해당 마인크래프트 아이디는 이미 등록되었습니다!", ephemeral: true }); - return; - } - } //신규 마크일 경우 - if (data["members"][discord_search_point].discord == discord_id) { - await interaction.editReply({ content: `${minecraft["name"]}(${minecraft["id"]})이 성공적으로 부계정으로 등록되었습니다!`, ephemeral: true }); - data["members"][discord_search_point].minecraft.push(minecraft["id"]); - await firebase.set(data); - return; - } - } //신규 디코일 경우 - await interaction.editReply({ content: `${minecraft["name"]}(${minecraft["id"]})님 2k2r에 오신것을 환영합니다!`, ephemeral: true }); - data["members"].push({ discord: discord_id, minecraft: [minecraft["id"]] }); - await firebase.set(data); - }, -}; diff --git a/main.js b/main.js deleted file mode 100755 index bbc49e6..0000000 --- a/main.js +++ /dev/null @@ -1,41 +0,0 @@ -const fs = require("node:fs"); -const path = require("node:path"); -const { Client, Collection, Events, GatewayIntentBits } = require("discord.js"); -require("dotenv").config(); - -const client = new Client({ intents: [GatewayIntentBits.Guilds] }); - -client.commands = new Collection(); -const commandsPath = path.join(__dirname, "commands"); -const commandFiles = fs.readdirSync(commandsPath).filter((file) => file.endsWith(".js")); - -for (const file of commandFiles) { - const filePath = path.join(commandsPath, file); - const command = require(filePath); - client.commands.set(command.data.name, command); -} - -client.once(Events.ClientReady, (c) => { - console.log(`Ready: discord client as ${c.user.tag}`); -}); - -client.on(Events.InteractionCreate, async (interaction) => { - if (!interaction.isChatInputCommand()) return; - - const command = client.commands.get(interaction.commandName); - - if (!command) return; - - try { - await command.execute(interaction); - } catch (error) { - console.error(error); - try { - await interaction.reply({ content: "There was an error while executing this command!", ephemeral: true }); - } catch (e) { - await interaction.editReply({ content: "There was an error while executing this command!", ephemeral: true }); - } - } -}); - -client.login(process.env.DISCORD_TOKEN); diff --git a/package.json b/package.json index 61a0be6..4033ba9 100755 --- a/package.json +++ b/package.json @@ -4,6 +4,13 @@ "dotenv": "^16.0.3", "firebase-admin": "^11.2.0", "mojang-api-js": "^1.0.1", - "nodemon": "^2.0.20" - } + "nodemon": "^2.0.20", + "typescritp": "^1.0.0" + }, + "name": "two-k-two-r-name-bot", + "version": "2.0.0", + "description": "a discord bot for 2k2r", + "main": "src/main.ts", + "author": "kdh8219 <65698239+kdh8219@users.noreply.github.com>", + "private": true } diff --git a/src/command/commands.ts b/src/command/commands.ts new file mode 100644 index 0000000..57899fe --- /dev/null +++ b/src/command/commands.ts @@ -0,0 +1,6 @@ +import { TCommand } from "../functions.js"; + +import add_nick_super from "./commands/add_nick_super.js"; + +const commands: TCommand[] = [add_nick_super]; +export default commands; diff --git a/commands/add_nick.js b/src/command/commands/add_nick.js similarity index 100% rename from commands/add_nick.js rename to src/command/commands/add_nick.js diff --git a/src/command/commands/add_nick_super.ts b/src/command/commands/add_nick_super.ts new file mode 100755 index 0000000..475d4e2 --- /dev/null +++ b/src/command/commands/add_nick_super.ts @@ -0,0 +1,89 @@ +import { + SlashCommandBuilder, + PermissionFlagsBits, + ChatInputCommandInteraction, + User, +} from "discord.js"; + +import mojangAPI from "../../wrapper/mojang-api.js"; +import firebase from "../../wrapper/firebase.js"; +import { + check_user_type_by_discord_id, + check_user_type_by_minecraft_uuid, + EUserType, + TData, +} from "../../functions.js"; + +export default { + data: new SlashCommandBuilder() + .setName("add_nick_super") + .setDescription("Add ones nickname on the list and share it to 2k2rs") + .addUserOption((option) => + option + .setName("discord") + .setDescription("discord account") + .setRequired(true) + ) + .addStringOption((option) => + option + .setName("minecraft_id") + .setDescription("id of the minecraft account") + .setRequired(true) + ) + .setDefaultMemberPermissions(PermissionFlagsBits.Administrator) + .setDMPermission(false), + async execute(interaction: ChatInputCommandInteraction) { + let data = (await firebase.get()).val() as TData; + + const discord_id = interaction.options.getUser("discord")?.id as string; + const dcusertype = check_user_type_by_discord_id(data, discord_id); + if (dcusertype == EUserType.Blacklisted) { + interaction.editReply({ + content: "`에러`: 해당 디스코드 아이디는 블랙리스트 되었습니다.", + }); + return; + } + + const mcid = interaction.options.getString("minecraft_id") as string; + let mcuuid: string; + try { + mcuuid = await mojangAPI.getUUIDFromId(mcid); + } catch { + await interaction.editReply({ + content: + "`에러`: 마인크래프트 닉네임 검색을 실패했습니다. 마인크래프트 닉네임을 정확하게 입력했나요?", + }); + return; + } + const mcusertype = check_user_type_by_minecraft_uuid(data, mcuuid); + + if (mcusertype == EUserType.Blacklisted) { + interaction.editReply({ + content: "`에러`: 해당 마인크래프트 아이디는 블랙리스트 되었습니다.", + }); + return; + } else if (mcusertype == EUserType.Member) { + interaction.editReply({ + content: "`에러`: 해당 마인크래프트 아이디는 이미 등록되었습니다.", + }); + return; + } + + if (dcusertype == EUserType.Unregistered) { + await interaction.editReply({ + content: `${mcid}(${mcuuid})님 2k2r에 오신것을 환영합니다!`, + }); + data["members"].push({ discord: discord_id, minecraft: [mcuuid] }); + } else { + for (let member of data.members) { + if (member.discord == discord_id) { + await interaction.editReply({ + content: `${mcid}(${mcuuid})이 성공적으로 부계정으로 등록되었습니다!`, + }); + member.minecraft.push(mcuuid); + } + } //신규 디코일 경우 + } + await firebase.set(data); + }, +}; diff --git a/commands/del_nick_super.js b/src/command/commands/del_nick_super.js similarity index 100% rename from commands/del_nick_super.js rename to src/command/commands/del_nick_super.js diff --git a/commands/del_user_super.js b/src/command/commands/del_user_super.js similarity index 100% rename from commands/del_user_super.js rename to src/command/commands/del_user_super.js diff --git a/commands/dm.trash b/src/command/commands/dm.trash similarity index 100% rename from commands/dm.trash rename to src/command/commands/dm.trash diff --git a/commands/get_blacklist.js b/src/command/commands/get_blacklist.js similarity index 100% rename from commands/get_blacklist.js rename to src/command/commands/get_blacklist.js diff --git a/commands/get_file.js b/src/command/commands/get_file.js similarity index 100% rename from commands/get_file.js rename to src/command/commands/get_file.js diff --git a/commands/get_file_super.js b/src/command/commands/get_file_super.js similarity index 69% rename from commands/get_file_super.js rename to src/command/commands/get_file_super.js index ffb9a27..4331575 100755 --- a/commands/get_file_super.js +++ b/src/command/commands/get_file_super.js @@ -1,8 +1,12 @@ -const { SlashCommandBuilder, AttachmentBuilder, PermissionFlagsBits } = require("discord.js"); +const { + SlashCommandBuilder, + AttachmentBuilder, + PermissionFlagsBits, +} = require("discord.js"); const firebase_admin = require("firebase-admin"); const { getDatabase } = require("firebase-admin/database"); -const serviceAccount = require("../firebase/conf.json"); +const serviceAccount = require("../../firebase/conf.json"); if (!firebase_admin.apps.length) { firebase_admin.initializeApp({ credential: firebase_admin.credential.cert(serviceAccount), @@ -15,10 +19,16 @@ if (!firebase_admin.apps.length) { const firebase = getDatabase().ref("/"); module.exports = { - data: new SlashCommandBuilder().setName("get_file_super").setDescription("get the file").setDefaultMemberPermissions(PermissionFlagsBits.Administrator).setDMPermission(false), + data: new SlashCommandBuilder() + .setName("get_file_super") + .setDescription("get the file") + .setDefaultMemberPermissions(PermissionFlagsBits.Administrator) + .setDMPermission(false), async execute(interaction) { - await interaction.deferReply({ ephemeral: true }); - await interaction.editReply("해당 커맨드에 버그가 있어서 임시로 비활성화 되었습니다...........") + await interaction.deferReply({ ephemeral: true }); + await interaction.editReply( + "해당 커맨드에 버그가 있어서 임시로 비활성화 되었습니다..........." + ); // const data = (await firebase.get()).val(); // for (let discord_search_point in data["members"]) { // if (data["members"][discord_search_point].discord == interaction.user.id) { diff --git a/commands/get_users.js b/src/command/commands/get_users.js similarity index 100% rename from commands/get_users.js rename to src/command/commands/get_users.js diff --git a/commands/mov_blacklist_super.js b/src/command/commands/mov_blacklist_super.js similarity index 72% rename from commands/mov_blacklist_super.js rename to src/command/commands/mov_blacklist_super.js index 125a15d..77852ab 100755 --- a/commands/mov_blacklist_super.js +++ b/src/command/commands/mov_blacklist_super.js @@ -18,7 +18,12 @@ module.exports = { data: new SlashCommandBuilder() .setName("mov_blacklist_super") .setDescription("add user to blacklist") - .addUserOption((option) => option.setName("discord").setDescription("discord id of blacklister").setRequired(true)) + .addUserOption((option) => + option + .setName("discord") + .setDescription("discord id of blacklister") + .setRequired(true) + ) .setDefaultMemberPermissions(PermissionFlagsBits.Administrator) .setDMPermission(false), async execute(interaction) { @@ -32,10 +37,17 @@ module.exports = { data["members"].splice(discord_search_point, 1); data["blacklist"].push(blackListing); await firebase.set(data); - await interaction.editReply({ content: "성공적으로 해당 discord id와 minecraft id를 블렉리스팅 했어요!", ephemeral: true }); + await interaction.editReply({ + content: + "성공적으로 해당 discord id와 minecraft id를 블렉리스팅 했어요!", + ephemeral: true, + }); return; } } //등록되지 않았을경우 - await interaction.editReply({ content: "`에러`:해당 discord id를 찾을 수 없었어요", ephemeral: true }); //TODO: + await interaction.editReply({ + content: "`에러`:해당 discord id를 찾을 수 없었어요", + ephemeral: true, + }); }, }; diff --git a/commands/ping.js b/src/command/commands/ping.js similarity index 100% rename from commands/ping.js rename to src/command/commands/ping.js diff --git a/commands/search.js b/src/command/commands/search.js similarity index 100% rename from commands/search.js rename to src/command/commands/search.js diff --git a/commands/user.trash b/src/command/commands/user.trash similarity index 100% rename from commands/user.trash rename to src/command/commands/user.trash diff --git a/deploy.js b/src/deploy.js similarity index 100% rename from deploy.js rename to src/deploy.js diff --git a/src/functions.ts b/src/functions.ts new file mode 100644 index 0000000..53ca914 --- /dev/null +++ b/src/functions.ts @@ -0,0 +1,65 @@ +import { SlashCommandBuilder } from "discord.js"; + +export type TCommand = { + data: SlashCommandBuilder; + execute: Function; +}; +export type TUser = { + discord: string; // id + minecraft: string[]; //uuid +}; +export type TData = { + blacklist: TUser[]; + members: TUser[]; +}; +export enum EUserType { + Unregistered, + Blacklisted, + Member, +} +export function check_user_type_by_discord_id( + data: TData, + discord_id: string +): EUserType { + for (let discord_search_point in data["blacklist"]) { + if (data.blacklist[discord_search_point].discord === discord_id) { + return EUserType.Blacklisted; + } + } + for (let discord_search_point in data["members"]) { + if (data.blacklist[discord_search_point].discord === discord_id) { + return EUserType.Member; + } + } + return EUserType.Unregistered; +} + +export function check_user_type_by_minecraft_uuid( + data: TData, + minecraft_uuid: string +): EUserType { + for (let discord_search_point in data.blacklist) { + for (let minecraft_search_point in data.blacklist[discord_search_point] + .minecraft) { + if ( + data.blacklist[discord_search_point].minecraft[ + minecraft_search_point + ] === minecraft_uuid + ) { + return EUserType.Blacklisted; + } + } + } + for (let discord_search_point in data.members) { + for (let minecraft_search_point in data.members[discord_search_point] + .minecraft) { + if ( + data.members[discord_search_point].minecraft[minecraft_search_point] === + minecraft_uuid + ) { + return EUserType.Member; + } + } + } + return EUserType.Unregistered; +} diff --git a/src/main.ts b/src/main.ts new file mode 100755 index 0000000..51dceb3 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,54 @@ +import { Client, Collection, Events, GatewayIntentBits } from "discord.js"; +import { config } from "dotenv"; +config(); + +import { TCommand } from "./functions.js"; +import commands from "./command/commands.js"; + +const client = new Client({ intents: [GatewayIntentBits.Guilds] }); + +const commandColection = getCommands(); +export let onTime: Date; + +client.once(Events.ClientReady, (c) => { + console.log(`Ready: discord client as ${c.user.tag}`); + onTime = new Date(); +}); + +client.on(Events.InteractionCreate, async (interaction) => { + if (!interaction.isChatInputCommand()) return; + + const command = commandColection.get(interaction.commandName); + if (interaction.commandName !== "ping") { + await interaction.deferReply({ ephemeral: true }); + } + + if (!command) return; + + try { + await command.execute(interaction); + } catch (error) { + console.error(error); + try { + await interaction.reply({ + content: "There was an error while executing this command!", + ephemeral: true, + }); + } catch (e) { + await interaction.editReply({ + content: "There was an error while executing this command!", + }); + console.error(e); + } + } +}); + +client.login(process.env.DISCORD_TOKEN); + +function getCommands(): Collection { + const commandColection = new Collection(); + for (const command of commands) { + commandColection.set(command.data.name, command); + } + return commandColection; +} diff --git a/src/utils/two-way-map.ts b/src/utils/two-way-map.ts new file mode 100644 index 0000000..f3640cf --- /dev/null +++ b/src/utils/two-way-map.ts @@ -0,0 +1,47 @@ +/** + * 양방향 map + * 각 인자는 유일해야 합니다 + * ex) 마인크래프트 계정의 아이디-uuid + */ +export default class TwoWayMap { + private firstMap: Map = new Map(); + private secondMap: Map = new Map(); + get_by_first(getter: T1): T2 | undefined { + return this.firstMap.get(getter); + } + get_by_second(getter: T2): T1 | undefined { + return this.secondMap.get(getter); + } + set_by_first(first: T1, second: T2) { + const secondGet = this.secondMap.get(second); + if (!secondGet) { + throw new Error("Duplicate second argument"); + } + this.firstMap.set(first, second); + this.secondMap.set(second, first); + } + set_by_second(first: T1, second: T2) { + const firstGet = this.firstMap.get(first); + if (!firstGet) { + throw new Error("Duplicate first argument"); + } + this.firstMap.set(first, second); + this.secondMap.set(second, first); + } + remove_by_first(first: T1): T2 | undefined { + const firstget = this.firstMap.get(first); + if (!firstget) return undefined; + + this.firstMap.delete(first); + this.secondMap.delete(firstget); + return firstget; + } + remove_by_second(second: T2): T1 | undefined { + const secondget = this.secondMap.get(second); + if (!secondget) return undefined; + + this.firstMap.delete(secondget); + this.secondMap.delete(second); + return secondget; + } +} diff --git a/src/wrapper/firebase.ts b/src/wrapper/firebase.ts new file mode 100644 index 0000000..1e4aeea --- /dev/null +++ b/src/wrapper/firebase.ts @@ -0,0 +1,19 @@ +import firebase_admin from "firebase-admin"; +import { getDatabase } from "firebase-admin/database"; +import { config } from "dotenv"; +config(); + +if (!firebase_admin.apps.length) { + firebase_admin.initializeApp({ + credential: firebase_admin.credential.cert( + JSON.parse(process.env["firebase_cert"] as string) + ), + databaseURL: "https://two-k-two-r-name-bot-default-rtdb.firebaseio.com", + databaseAuthVariableOverride: { + uid: process.env.FIREBASE_UID, + }, + }); +} +const firebase = getDatabase().ref("/"); + +export default firebase; diff --git a/src/wrapper/mojang-api.ts b/src/wrapper/mojang-api.ts new file mode 100644 index 0000000..605fc6e --- /dev/null +++ b/src/wrapper/mojang-api.ts @@ -0,0 +1,34 @@ +import Client from "mojang-api-js"; +import TwoWayMmap from "../utils/two-way-map.js"; + +class MojangAPI { + private mojangAPI: Client = new Client(); + private cached: TwoWayMmap = new TwoWayMmap(); // uuid, id + + async getIdFromUUID(minecraft_uuid: string): Promise { + let id = this.cached.get_by_first(minecraft_uuid); + if (id) return id; + + let mcid = await this.mojangAPI.uuidToName(minecraft_uuid); + id = mcid.id; + + if (!id) throw new Error("Failed to get minecraft id from api"); + + this.cached.set_by_first(minecraft_uuid, id); + return id; + } + async getUUIDFromId(minecraft_id): Promise { + let uuid = this.cached.get_by_second(minecraft_id); + if (uuid) return uuid; + + let mcid = await this.mojangAPI.nameToUuid(minecraft_id); + uuid = mcid.id; + if (!uuid) throw new Error("Failed to get minecraft id from api"); + + this.cached.remove_by_first(uuid); + this.cached.set_by_second(uuid, minecraft_id); + return uuid; + } +} +const mojangAPI = new MojangAPI(); +export default mojangAPI; diff --git a/temp/migration_database.ts b/temp/migration_database.ts new file mode 100644 index 0000000..254460e --- /dev/null +++ b/temp/migration_database.ts @@ -0,0 +1 @@ +// firebase/databse -> firebase/firestore diff --git a/yarn.lock b/yarn.lock index 893426d..548e98b 100755 --- a/yarn.lock +++ b/yarn.lock @@ -1680,6 +1680,11 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +typescritp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typescritp/-/typescritp-1.0.0.tgz#7923ebbd3ec74f780633c8be2e8aa1d2ecac2b8f" + integrity sha512-88hSOM0JRNE+lY8LQvwebA6WCf54+FoDUQuNCuoBvHxu+tj76LteTUymKzwuS6VVAuBLfI5xcZyv88sj4yxDaw== + uc.micro@^1.0.1, uc.micro@^1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac"