Skip to content

Commit

Permalink
Switch from mongoose to Typegoose (#16)
Browse files Browse the repository at this point in the history
* start migrating to typegoose

* minor fixes

* fix build
  • Loading branch information
Rdeisenroth authored Oct 23, 2023
1 parent 7cf7715 commit 291995a
Show file tree
Hide file tree
Showing 91 changed files with 1,664 additions and 2,051 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:latest AS build
FROM node:16 AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
Expand Down
5 changes: 5 additions & 0 deletions nodemon.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"execMap": {
"ts": "ts-node"
}
}
351 changes: 285 additions & 66 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"type": "commonjs",
"scripts": {
"start": "tsc --build --clean tsconfig.json; tsc --build tsconfig.json; node dist/index.js",
"nodemon": "nodemon --watch 'src/**/*.ts' src/index.ts",
"build": "tsc --build --clean tsconfig.json; tsc --build tsconfig.json",
"lint": "eslint --ext .ts src/",
"watch": "tsc -p tsconfig.json -w",
Expand All @@ -15,6 +16,7 @@
"license": "ISC",
"dependencies": {
"@discordjs/voice": "^0.16.0",
"@typegoose/typegoose": "^11.6.0",
"@types/node": "^20.8.4",
"chartjs-node-canvas": "^4.1.6",
"cheerio": "^1.0.0-rc.12",
Expand Down Expand Up @@ -48,7 +50,7 @@
"@types/glob": "^8.1.0",
"@types/jest": "^29.5.5",
"@types/mocha": "^10.0.2",
"@types/moment-duration-format": "^2.2.4",
"@types/moment-duration-format": "^2.2.5",
"@types/urban-dictionary": "^3.0.0",
"@types/yargs": "^17.0.28",
"@types/yargs-parser": "^21.0.1",
Expand All @@ -58,6 +60,7 @@
"eslint": "^8.51.0",
"jest": "^29.7.0",
"mocha": "^10.2.0",
"nodemon": "^3.0.1",
"ts-jest": "^29.1.1",
"ts-mockito": "^2.6.1",
"ts-node": "^10.9.1",
Expand Down
19 changes: 14 additions & 5 deletions src/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import glob from "glob-promise";
import { promisify } from "util";
import * as fs from "fs";
import * as utils from "./utils/utils";
import GuildSchema from "./models/guilds";
import {GuildModel} from "./models/guilds";
import parser from "yargs-parser";
import mongoose from "mongoose";
import path from "path/posix";
import { QueueSpan } from "./models/queue_span";
import { WeekTimestamp } from "./models/week_timestamp";
export class Bot extends Client {
public logger: ConsolaInstance = consola;
public commands: Collection<string, Command> = new Collection();
Expand Down Expand Up @@ -61,7 +62,12 @@ export class Bot extends Client {
*/
public async start(): Promise<void> {
this.logger.info("starting Bot...");
this.login(this.config.get("token")).catch((e) => this.logger.error(e));
try {
await this.login(this.config.get("token"));
} catch (error) {
this.logger.error("Invalid token", error);
process.exit(1);
}

// Commands
this.logger.info("Loading Commands...");
Expand Down Expand Up @@ -130,6 +136,7 @@ export class Bot extends Client {
this.logger.info("Loading Events...");
const eventFiles = fs.readdirSync(`${__dirname}/events`).filter(file => file.endsWith(".js") || file.endsWith("ts"));
await eventFiles.map(async (eventFile: string) => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const event = (await import(`${__dirname}/events/${eventFile}`)) as BotEvent<any>;
console.log(`${JSON.stringify(event.name)} (./events/${eventFile})`);
this.on(event.name, event.execute.bind(null, this));
Expand All @@ -139,7 +146,7 @@ export class Bot extends Client {
for (const g of this.guilds.cache.values()) {
console.log(new Date().toLocaleString());

const guildData = await GuildSchema.findById(g.id);
const guildData = await GuildModel.findById(g.id);
if (!guildData) {
return;
}
Expand All @@ -149,8 +156,8 @@ export class Bot extends Client {
}

if (queueData.opening_times.map(x => new QueueSpan(
new utils.general.WeekTimestamp(x.begin.weekday, x.begin.hour, x.begin.minute),
new utils.general.WeekTimestamp(x.end.weekday, x.end.hour, x.end.minute),
new WeekTimestamp(x.begin.weekday, x.begin.hour, x.begin.minute),
new WeekTimestamp(x.end.weekday, x.end.hour, x.end.minute),
x.openShift,
x.closeShift,
x.startDate,
Expand Down Expand Up @@ -187,6 +194,8 @@ export class Bot extends Client {
}, null, true, "America/Los_Angeles");
queueGuardJob.start();

this.logger.ready(`Bot ${this.user?.displayName} is Ready!`);

// public async createGuildCommand(data:any, guildId:string) {
// return await this.api.appl
// }
Expand Down
6 changes: 3 additions & 3 deletions src/commands/admin/decrypttoken.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { ApplicationCommandOptionType, Message, Role } from "discord.js";
import { Command } from "../../../typings";
import "moment-duration-format";
import UserSchema, { User } from "../../models/users";
import GuildSchema from "../../models/guilds";
import { DBRole, DBRoleDocument, InternalRoles, RoleScopes } from "../../models/bot_roles";
import {UserModel, User } from "../../models/users";
import {GuildModel} from "../../models/guilds";
import { DBRole, InternalRoles, RoleScopes } from "../../models/bot_roles";
import { Types } from "mongoose";


Expand Down
21 changes: 11 additions & 10 deletions src/commands/admin/fixverify.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Message, Role } from "discord.js";
import { Command } from "../../../typings";
import "moment-duration-format";
import UserSchema, { User } from "../../models/users";
import GuildSchema from "../../models/guilds";
import { DBRole, DBRoleDocument, InternalRoles, RoleScopes } from "../../models/bot_roles";
import {UserModel, User } from "../../models/users";
import {GuildModel} from "../../models/guilds";
import { DBRole, InternalRoles, RoleScopes } from "../../models/bot_roles";
import { Types } from "mongoose";
import { DocumentType } from "@typegoose/typegoose";



Expand All @@ -27,7 +28,7 @@ const command: Command = {
const guild = interaction.guild;
const roles = await interaction.guild.roles.fetch();
const members = await interaction.guild.members.fetch();
const dbGuild = (await GuildSchema.findOne({ _id: guild.id }))!;
const dbGuild = (await GuildModel.findOne({ _id: guild.id }))!;
const verifiedRole = interaction.guild.roles.cache.find(x => x.name.toLowerCase() === "verified");
let dbVerifyRole = dbGuild.guild_settings.roles?.find(x => x.internal_name === InternalRoles.VERIFIED);
const orgaRole = interaction.guild.roles.cache.find(x => x.name.toLowerCase() === "orga");
Expand All @@ -36,11 +37,11 @@ const command: Command = {
let dbTutorRole = dbGuild.guild_settings.roles?.find(x => x.internal_name === InternalRoles.TUTOR);

// Create the roles if they don't exist
for (const [r, dbr, irn] of ([[verifiedRole, dbVerifyRole, InternalRoles.VERIFIED], [orgaRole, dbOrgaRole, InternalRoles.SERVER_ADMIN], [tutorRole, dbTutorRole, InternalRoles.TUTOR]] as [Role, DBRoleDocument, InternalRoles][])) {
for (const [r, dbr, irn] of ([[verifiedRole, dbVerifyRole, InternalRoles.VERIFIED], [orgaRole, dbOrgaRole, InternalRoles.SERVER_ADMIN], [tutorRole, dbTutorRole, InternalRoles.TUTOR]] as [Role, DocumentType<DBRole>, InternalRoles][])) {
if (!r) continue;
if (!dbr) {
console.log(`creating role ${irn}`);
if (!dbGuild.guild_settings.roles) dbGuild.guild_settings.roles = new Types.DocumentArray<DBRoleDocument>([]);
if (!dbGuild.guild_settings.roles) dbGuild.guild_settings.roles = new Types.DocumentArray([]);
dbGuild.guild_settings.roles.push({
internal_name: irn,
role_id: r.id,
Expand All @@ -59,16 +60,16 @@ const command: Command = {
}
}

const users = await UserSchema.find({});
const users = await UserModel.find({});
let count = 0;
for (const u of users) {
console.log(`(${++count}/${users.length}) updating roles for user ${u.tu_id}`);
for (const [r, dbr, irn] of ([[verifiedRole, dbVerifyRole, InternalRoles.VERIFIED], [orgaRole, dbOrgaRole, InternalRoles.SERVER_ADMIN], [tutorRole, dbTutorRole, InternalRoles.TUTOR]] as [Role, DBRoleDocument, InternalRoles][])) {
for (const [r, dbr, irn] of ([[verifiedRole, dbVerifyRole, InternalRoles.VERIFIED], [orgaRole, dbOrgaRole, InternalRoles.SERVER_ADMIN], [tutorRole, dbTutorRole, InternalRoles.TUTOR]] as [Role, DocumentType<DBRole>, InternalRoles][])) {
if (!r || !dbr) continue;
if (members.get(u._id)?.roles.cache.has(r.id)) {
console.log(`${u.tu_id} has role ${irn}`);
if (!u.token_roles) u.token_roles = new Types.Array<Types.ObjectId>();
u.token_roles.push(dbr._id);
if (!u.token_roles) u.token_roles = new Types.Array();
u.token_roles.push(dbr);
await u.save();
}
}
Expand Down
7 changes: 1 addition & 6 deletions src/commands/admin/generatetoken.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import { ApplicationCommandOptionType, Message, Role } from "discord.js";
import { ApplicationCommandOptionType, Message } from "discord.js";
import { Command } from "../../../typings";
import "moment-duration-format";
import UserSchema, { User } from "../../models/users";
import GuildSchema from "../../models/guilds";
import { DBRole, DBRoleDocument, InternalRoles, RoleScopes } from "../../models/bot_roles";
import { Types } from "mongoose";



/**
Expand Down
16 changes: 9 additions & 7 deletions src/commands/admin/genverifyroles.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Message, Role } from "discord.js";
import { Command } from "../../../typings";
import "moment-duration-format";
import UserSchema, { User } from "../../models/users";
import GuildSchema from "../../models/guilds";
import { DBRole, DBRoleDocument, InternalRoles, RoleScopes } from "../../models/bot_roles";
import { Types } from "mongoose";
import {UserModel, User } from "../../models/users";
import {GuildModel} from "../../models/guilds";
import { DBRole, InternalRoles, RoleScopes } from "../../models/bot_roles";
import { ArraySubDocumentType, DocumentType, mongoose } from "@typegoose/typegoose";



Expand All @@ -27,7 +27,7 @@ const command: Command = {
const guild = interaction.guild;
const roles = await interaction.guild.roles.fetch();
const members = await interaction.guild.members.fetch();
const dbGuild = (await GuildSchema.findOne({ _id: guild.id }))!;
const dbGuild = (await GuildModel.findOne({ _id: guild.id }))!;
const verifiedRole = interaction.guild.roles.cache.find(x => x.name.toLowerCase() === "verified");
let dbVerifyRole = dbGuild.guild_settings.roles?.find(x => x.internal_name === InternalRoles.VERIFIED);
const orgaRole = interaction.guild.roles.cache.find(x => x.name.toLowerCase() === "orga");
Expand All @@ -36,11 +36,13 @@ const command: Command = {
let dbTutorRole = dbGuild.guild_settings.roles?.find(x => x.internal_name === InternalRoles.TUTOR);

// Create the roles if they don't exist
for (const [r, dbr, irn] of ([[verifiedRole, dbVerifyRole, InternalRoles.VERIFIED], [orgaRole, dbOrgaRole, InternalRoles.SERVER_ADMIN], [tutorRole, dbTutorRole, InternalRoles.TUTOR]] as [Role, DBRoleDocument, InternalRoles][])) {
for (const [r, dbr, irn] of ([[verifiedRole, dbVerifyRole, InternalRoles.VERIFIED], [orgaRole, dbOrgaRole, InternalRoles.SERVER_ADMIN], [tutorRole, dbTutorRole, InternalRoles.TUTOR]] as [Role, ArraySubDocumentType<DBRole>, InternalRoles][])) {
if (!r) continue;
if (!dbr) {
console.log(`creating role ${irn}`);
if (!dbGuild.guild_settings.roles) dbGuild.guild_settings.roles = new Types.DocumentArray<DBRoleDocument>([]);
if (!dbGuild.guild_settings.roles) {
dbGuild.guild_settings.roles = new mongoose.Types.DocumentArray([]);
}
dbGuild.guild_settings.roles.push({
internal_name: irn,
role_id: r.id,
Expand Down
26 changes: 14 additions & 12 deletions src/commands/admin/member/lookup-by.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { ApplicationCommandOptionType, EmbedField, Message } from "discord.js";
import moment from "moment";
import { Command } from "../../../../typings";
import GuildSchema from "../../../models/guilds";
import UserSchema, { User, UserDocument } from "../../../models/users";
import SessionSchema from "../../../models/sessions";
import QueueSchema from "../../../models/queues";
import {GuildModel} from "../../../models/guilds";
import {UserModel, User } from "../../../models/users";
import {SessionModel} from "../../../models/sessions";
import {QueueModel} from "../../../models/queues";
import { FilterQuery } from "mongoose";
import { DocumentType, mongoose } from "@typegoose/typegoose";
import { FilterOutFunctionKeys } from "@typegoose/typegoose/lib/types";

const command: Command = {
name: "lookup-by",
Expand Down Expand Up @@ -58,17 +60,17 @@ const command: Command = {
await interaction.deferReply({ ephemeral: true });
const type = interaction.options.getString("type", true);
const query = interaction.options.getString("query", true);
let userQuery: FilterQuery<UserDocument> = {};
let userData: (User & { _id: string; }) | undefined;
let userQuery: FilterQuery<DocumentType<User>> = {};
let userData: DocumentType<User> | null | undefined;
if (type === "discord-tag") {
const members = await interaction.guild?.members.fetch();
const member = members?.find(x => x.user.tag === query);
userData = {
userData = new UserModel({
_id: member?.id ?? "",
server_roles: [],
sessions: [],
token_roles: [],
};
server_roles: new mongoose.Types.Array(),
sessions: new mongoose.Types.DocumentArray([]),
token_roles: new mongoose.Types.DocumentArray([]),
} as FilterOutFunctionKeys<User>);
} else {
if (type === "tu-id") {
userQuery = { tu_id: query };
Expand All @@ -77,7 +79,7 @@ const command: Command = {
} else {
userQuery = { _id: query };
}
userData = (await UserSchema.findOne(userQuery))?.toObject<User & { _id: string }>();
userData = await UserModel.findOne(userQuery);
}
// user = await user.fetch();

Expand Down
10 changes: 5 additions & 5 deletions src/commands/admin/member/lookup.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { ApplicationCommandOptionType, EmbedData, EmbedField, Message } from "discord.js";
import moment from "moment";
import { Command } from "../../../../typings";
import GuildSchema from "../../../models/guilds";
import UserSchema from "../../../models/users";
import SessionSchema from "../../../models/sessions";
import QueueSchema from "../../../models/queues";
import {GuildModel} from "../../../models/guilds";
import {UserModel} from "../../../models/users";
import {SessionModel} from "../../../models/sessions";
import {QueueModel} from "../../../models/queues";

const command: Command = {
name: "lookup",
Expand Down Expand Up @@ -33,7 +33,7 @@ const command: Command = {
await interaction.deferReply({ ephemeral: true });
let user = interaction.options.getUser("user", true);
user = await user.fetch();
const userData = await UserSchema.findById(user.id);
const userData = await UserModel.findById(user.id);

if (!userData) {
return await client.utils.embeds.SimpleEmbed(interaction, { title: "Verification System", text: `User ${user} not found in database.`, empheral: true });
Expand Down
10 changes: 5 additions & 5 deletions src/commands/admin/member/unverify.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { ApplicationCommandOptionType, EmbedField, Message } from "discord.js";
import moment from "moment";
import { Command } from "../../../../typings";
import GuildSchema from "../../../models/guilds";
import UserSchema from "../../../models/users";
import SessionSchema from "../../../models/sessions";
import QueueSchema from "../../../models/queues";
import {GuildModel} from "../../../models/guilds";
import {UserModel} from "../../../models/users";
import {SessionModel} from "../../../models/sessions";
import {QueueModel} from "../../../models/queues";

const command: Command = {
name: "unverify",
Expand Down Expand Up @@ -40,7 +40,7 @@ const command: Command = {
let user = interaction.options.getUser("user", true);
const reason = interaction.options.getString("reason");
user = await user.fetch();
const userData = await UserSchema.findById(user.id);
const userData = await UserModel.findById(user.id);

if (!userData) {
return await client.utils.embeds.SimpleEmbed(interaction, { title: "Verification System", text: `User ${user} not found in database.`, empheral: true });
Expand Down
8 changes: 4 additions & 4 deletions src/commands/admin/queue/fixup.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { ApplicationCommandOptionType, EmbedField, Message, Role } from "discord.js";
import path from "path";
import { Command } from "../../../../typings";
import GuildSchema from "../../../models/guilds";
import UserSchema from "../../../models/users";
import {GuildModel} from "../../../models/guilds";
import {UserModel} from "../../../models/users";

const command: Command = {
name: "fixup",
Expand All @@ -26,7 +26,7 @@ const command: Command = {
}

const g = interaction.guild!;
const guildData = (await GuildSchema.findById(g.id));
const guildData = (await GuildModel.findById(g.id));
if (!guildData) {
return await client.utils.embeds.SimpleEmbed(interaction, { title: "Coaching System", text: "Guild Data Could not be found.", empheral: true });
}
Expand Down Expand Up @@ -66,7 +66,7 @@ const command: Command = {
return await client.utils.embeds.SimpleEmbed(interaction, { title: "Coaching System", text: "Active Session Role Members Could not be found.", empheral: true });
}
const user = client.utils.general.getUser(interaction);
const userEntry = await UserSchema.findOneAndUpdate({ _id: user.id }, { _id: user.id }, { new: true, upsert: true, setDefaultsOnInsert: true });
const userEntry = await UserModel.findOneAndUpdate({ _id: user.id }, { _id: user.id }, { new: true, upsert: true, setDefaultsOnInsert: true });
// Check if User has Active Sessions
const activeSessions = await userEntry.getActiveSessions();
const as_oldMemberCount = as_role_members.size;
Expand Down
6 changes: 3 additions & 3 deletions src/commands/admin/queue/info.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ApplicationCommandOptionType, Message } from "discord.js";
import { Command } from "../../../../typings";
import GuildSchema from "../../../models/guilds";
import UserSchema from "../../../models/users";
import {GuildModel} from "../../../models/guilds";
import {UserModel} from "../../../models/users";

const command: Command = {
name: "info",
Expand All @@ -28,7 +28,7 @@ const command: Command = {
}

const g = interaction.guild!;
const guildData = (await GuildSchema.findById(g.id));
const guildData = (await GuildModel.findById(g.id));
if (!guildData) {
return await client.utils.embeds.SimpleEmbed(interaction, { title: "Coaching System", text: "Guild Data Could not be found.", empheral: true });
}
Expand Down
Loading

0 comments on commit 291995a

Please sign in to comment.