From a44c6424e3f9113b7f10972e054daaaffbae870e Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Thu, 12 May 2022 18:28:47 +0100 Subject: [PATCH 1/4] Add entity --- package.json | 4 +++- src/entity/Role.ts | 18 ++++++++++++++++++ src/entity/Server.ts | 10 +++++++++- src/migration/1652375907691-CreateRole.ts | 13 +++++++++++++ 4 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 src/entity/Role.ts create mode 100644 src/migration/1652375907691-CreateRole.ts diff --git a/package.json b/package.json index ce8b454..e4416f2 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,9 @@ "scripts": { "build": "tsc", "start": "node ./dist/vylbot", - "test": "jest" + "test": "jest", + "db:up": "typeorm migration:run", + "db:down": "typeorm migration:revert" }, "repository": { "type": "git", diff --git a/src/entity/Role.ts b/src/entity/Role.ts new file mode 100644 index 0000000..05babcb --- /dev/null +++ b/src/entity/Role.ts @@ -0,0 +1,18 @@ +import { Column, Entity, ManyToOne } from "typeorm"; +import BaseEntity from "../contracts/BaseEntity" +import Server from "./Server"; + +@Entity() +export default class Role extends BaseEntity { + constructor(roleId: string) { + super(); + + this.RoleId = roleId; + } + + @Column() + RoleId: string; + + @ManyToOne(() => Server, x => x.Roles) + Server: Server; +} \ No newline at end of file diff --git a/src/entity/Server.ts b/src/entity/Server.ts index 180aef0..f669e58 100644 --- a/src/entity/Server.ts +++ b/src/entity/Server.ts @@ -1,5 +1,6 @@ -import { Column, Entity, getConnection, OneToMany } from "typeorm"; +import { Entity, OneToMany } from "typeorm"; import BaseEntity from "../contracts/BaseEntity"; +import Role from "./Role"; import Setting from "./Setting"; @Entity() @@ -13,7 +14,14 @@ export default class Server extends BaseEntity { @OneToMany(() => Setting, x => x.Server) Settings: Setting[]; + @OneToMany(() => Role, x => x.Server) + Roles: Role[]; + public AddSettingToServer(setting: Setting) { this.Settings.push(setting); } + + public AddRoleToServer(role: Role) { + this.Roles.push(role); + } } \ No newline at end of file diff --git a/src/migration/1652375907691-CreateRole.ts b/src/migration/1652375907691-CreateRole.ts new file mode 100644 index 0000000..255ed0f --- /dev/null +++ b/src/migration/1652375907691-CreateRole.ts @@ -0,0 +1,13 @@ +import { MigrationInterface, QueryRunner } from "typeorm" + +export class migration1652375907691 implements MigrationInterface { + + public async up(queryRunner: QueryRunner): Promise { + queryRunner.query(`CREATE TABLE role (Id varchar(255), WhenCreated datetime, WhenUpdated datetime, RoleId varchar(255), serverId varchar(255), PRIMARY KEY (Id), FOREIGN KEY (serverId) REFERENCES server(Id))`); + } + + public async down(queryRunner: QueryRunner): Promise { + queryRunner.query(`DROP TABLE role`); + } + +} -- 2.43.4 From a40af24b18af9e454e39a1123a78795f8089e5d0 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Fri, 13 May 2022 17:33:50 +0100 Subject: [PATCH 2/4] Update role config command to use new entity --- src/commands/role.ts | 46 +++++++++++++++++++++++++++----------------- src/entity/Role.ts | 18 ++++++++++++++++- 2 files changed, 45 insertions(+), 19 deletions(-) diff --git a/src/commands/role.ts b/src/commands/role.ts index 9a0af00..3112730 100644 --- a/src/commands/role.ts +++ b/src/commands/role.ts @@ -6,6 +6,9 @@ import { ICommandContext } from "../contracts/ICommandContext"; import ICommandReturnContext from "../contracts/ICommandReturnContext"; import SettingsHelper from "../helpers/SettingsHelper"; import { readFileSync } from "fs"; +import { default as eRole } from "../entity/Role"; +import Server from "../entity/Server"; + export default class Role extends Command { constructor() { super(); @@ -164,16 +167,28 @@ export default class Role extends Command { this.SendConfigHelp(context); return; } - - let setting = await SettingsHelper.GetSetting("role.assignable", context.message.guild!.id) || ""; - const settingArray = setting.split(","); + const existingRole = await eRole.FetchOneByServerId(context.message.guild!.id, role.id); - settingArray.push(role.name); + if (existingRole) { + const errorEmbed = new ErrorEmbed(context, "This role has already been setup"); + errorEmbed.SendToCurrentChannel(); - setting = settingArray.join(","); + return; + } - await SettingsHelper.SetSetting("role.assignable", context.message.guild!.id, setting); + const server = await Server.FetchOneById(Server, context.message.guild!.id, [ + "Roles", + ]); + + if (!server) return; + + const roleSetting = new eRole(role.id); + + await roleSetting.Save(eRole, roleSetting); + + server.AddRoleToServer(roleSetting); + await server.Save(Server, server); const embed = new PublicEmbed(context, "", `Added \`${role.name}\` as a new assignable role`); embed.SendToCurrentChannel(); @@ -187,21 +202,16 @@ export default class Role extends Command { return; } - let setting = await SettingsHelper.GetSetting("role.assignable", context.message.guild!.id); + const existingRole = await eRole.FetchOneByServerId(context.message.guild!.id, role.id); - if (!setting) return; + if (!existingRole) { + const errorEmbed = new ErrorEmbed(context, "Unable to find this role"); + errorEmbed.SendToCurrentChannel(); - const settingArray = setting.split(","); + return; + } - const index = settingArray.findIndex(x => x == role.name); - - if (index == -1) return; - - settingArray.splice(index, 1); - - setting = settingArray.join(","); - - await SettingsHelper.SetSetting("role.assignable", context.message.guild!.id, setting); + await eRole.Remove(eRole, existingRole); const embed = new PublicEmbed(context, "", `Removed \`${role.name}\` from the list of assignable roles`); embed.SendToCurrentChannel(); diff --git a/src/entity/Role.ts b/src/entity/Role.ts index 05babcb..5770ab1 100644 --- a/src/entity/Role.ts +++ b/src/entity/Role.ts @@ -1,4 +1,4 @@ -import { Column, Entity, ManyToOne } from "typeorm"; +import { Column, Entity, EntityTarget, getConnection, ManyToOne } from "typeorm"; import BaseEntity from "../contracts/BaseEntity" import Server from "./Server"; @@ -15,4 +15,20 @@ export default class Role extends BaseEntity { @ManyToOne(() => Server, x => x.Roles) Server: Server; + + public static async FetchOneByServerId(serverId: string, roleId: string): Promise { + const connection = getConnection(); + + const repository = connection.getRepository(Server); + + const single = await repository.findOne(serverId, { relations: [ + "Roles", + ]}); + + if (!single) return undefined; + + const search = single.Roles.find(x => x.Id == roleId); + + return search; + } } \ No newline at end of file -- 2.43.4 From 28976060653a28b4fbe54a2568beb2c18ae9e3d9 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Fri, 13 May 2022 17:55:10 +0100 Subject: [PATCH 3/4] Update role command to use new entity --- src/commands/role.ts | 51 +++++++++++++++++++++++++++----------------- src/entity/Role.ts | 22 +++++++++++++------ 2 files changed, 48 insertions(+), 25 deletions(-) diff --git a/src/commands/role.ts b/src/commands/role.ts index 3112730..9dbda89 100644 --- a/src/commands/role.ts +++ b/src/commands/role.ts @@ -33,27 +33,34 @@ export default class Role extends Command { // ======= private async UseDefault(context: ICommandContext) { - const roles = await SettingsHelper.GetSetting("role.assignable", context.message.guild!.id); - - if (!roles) { - const errorEmbed = new ErrorEmbed(context, "Unable to find any assignable roles"); - errorEmbed.SendToCurrentChannel(); - - return; - } - - const rolesArray = roles.split(","); - if (context.args.length == 0) { - await this.SendRolesList(context, rolesArray, context.message.guild!.id); + await this.SendRolesList(context, context.message.guild!.id); } else { - await this.ToggleRole(context, rolesArray); + await this.ToggleRole(context); } } - public async SendRolesList(context: ICommandContext, roles: String[], serverId: string): Promise { + public async GetRolesList(context: ICommandContext): Promise { + const rolesArray = await eRole.FetchAllByServerId(context.message.guild!.id); + + const stringArray: string[] = []; + + for (let i = 0; i < rolesArray.length; i++) { + const serverRole = context.message.guild!.roles.cache.find(x => x.id == rolesArray[i].RoleId); + + if (serverRole) { + stringArray.push(serverRole.name); + } + } + + return stringArray; + } + + public async SendRolesList(context: ICommandContext, serverId: string): Promise { + const roles = await this.GetRolesList(context); + const botPrefix = await SettingsHelper.GetServerPrefix(serverId); - const description = `Do ${botPrefix}role to get the role!\n${roles.join('\n')}`; + const description = roles.length == 0 ? "*no roles*" : `Do ${botPrefix}role to get the role!\n\n${roles.join('\n')}`; const embed = new PublicEmbed(context, "Roles", description); embed.SendToCurrentChannel(); @@ -64,7 +71,8 @@ export default class Role extends Command { }; } - public async ToggleRole(context: ICommandContext, roles: String[]): Promise { + public async ToggleRole(context: ICommandContext): Promise { + const roles = await this.GetRolesList(context); const requestedRole = context.args.join(" "); if (!roles.includes(requestedRole)) { @@ -168,7 +176,7 @@ export default class Role extends Command { return; } - const existingRole = await eRole.FetchOneByServerId(context.message.guild!.id, role.id); + const existingRole = await eRole.FetchOneByRoleId(role.id); if (existingRole) { const errorEmbed = new ErrorEmbed(context, "This role has already been setup"); @@ -181,7 +189,12 @@ export default class Role extends Command { "Roles", ]); - if (!server) return; + if (!server) { + const errorEmbed = new ErrorEmbed(context, "Server not setup, please request the server owner runs the setup command."); + errorEmbed.SendToCurrentChannel(); + + return; + } const roleSetting = new eRole(role.id); @@ -202,7 +215,7 @@ export default class Role extends Command { return; } - const existingRole = await eRole.FetchOneByServerId(context.message.guild!.id, role.id); + const existingRole = await eRole.FetchOneByRoleId(role.id); if (!existingRole) { const errorEmbed = new ErrorEmbed(context, "Unable to find this role"); diff --git a/src/entity/Role.ts b/src/entity/Role.ts index 5770ab1..5b534ad 100644 --- a/src/entity/Role.ts +++ b/src/entity/Role.ts @@ -15,20 +15,30 @@ export default class Role extends BaseEntity { @ManyToOne(() => Server, x => x.Roles) Server: Server; + + public static async FetchOneByRoleId(roleId: string, relations?: string[]): Promise { + const connection = getConnection(); - public static async FetchOneByServerId(serverId: string, roleId: string): Promise { + const repository = connection.getRepository(Role); + + const single = await repository.findOne({ RoleId: roleId}, { relations: relations || [] }); + + return single; + } + + public static async FetchAllByServerId(serverId: string): Promise { const connection = getConnection(); const repository = connection.getRepository(Server); - const single = await repository.findOne(serverId, { relations: [ + const all = await repository.findOne(serverId, { relations: [ "Roles", ]}); - if (!single) return undefined; + if (!all) { + return []; + } - const search = single.Roles.find(x => x.Id == roleId); - - return search; + return all.Roles; } } \ No newline at end of file -- 2.43.4 From 6e56f03c51cf1c73635776fff10c9660dafe1fca Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Fri, 13 May 2022 17:56:15 +0100 Subject: [PATCH 4/4] Remove legacy code from config command --- data/usage/config.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/data/usage/config.txt b/data/usage/config.txt index ffbcf1b..f284c78 100644 --- a/data/usage/config.txt +++ b/data/usage/config.txt @@ -5,7 +5,6 @@ bot.prefix: The bot prefix for the server (Default: "v!") commands.disabled: Disabled commands, separated by commas (Default: "") -role.assignable: List of roles assignable to user, separated by commas (Default: "") role.moderator: The moderator role name (Default: "Moderator") role.administrator: The administrator role name (Default: "Administrator") role.muted: The muted role name (Default: "Muted") -- 2.43.4