150 assignable roles should be its own table to prevent limitations on length (#158)

* Add entity

* Update role config command to use new entity

* Update role command to use new entity

* Remove legacy code from config command
This commit is contained in:
Vylpes 2022-05-14 14:59:32 +01:00 committed by GitHub
parent 6522bee37b
commit 514be692fd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 126 additions and 37 deletions

View file

@ -5,7 +5,6 @@ bot.prefix: The bot prefix for the server (Default: "v!")
commands.disabled: Disabled commands, separated by commas (Default: "") 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.moderator: The moderator role name (Default: "Moderator")
role.administrator: The administrator role name (Default: "Administrator") role.administrator: The administrator role name (Default: "Administrator")
role.muted: The muted role name (Default: "Muted") role.muted: The muted role name (Default: "Muted")

View file

@ -7,7 +7,9 @@
"scripts": { "scripts": {
"build": "tsc", "build": "tsc",
"start": "node ./dist/vylbot", "start": "node ./dist/vylbot",
"test": "jest" "test": "jest",
"db:up": "typeorm migration:run",
"db:down": "typeorm migration:revert"
}, },
"repository": { "repository": {
"type": "git", "type": "git",

View file

@ -6,6 +6,9 @@ import { ICommandContext } from "../contracts/ICommandContext";
import ICommandReturnContext from "../contracts/ICommandReturnContext"; import ICommandReturnContext from "../contracts/ICommandReturnContext";
import SettingsHelper from "../helpers/SettingsHelper"; import SettingsHelper from "../helpers/SettingsHelper";
import { readFileSync } from "fs"; import { readFileSync } from "fs";
import { default as eRole } from "../entity/Role";
import Server from "../entity/Server";
export default class Role extends Command { export default class Role extends Command {
constructor() { constructor() {
super(); super();
@ -30,27 +33,34 @@ export default class Role extends Command {
// ======= // =======
private async UseDefault(context: ICommandContext) { 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) { if (context.args.length == 0) {
await this.SendRolesList(context, rolesArray, context.message.guild!.id); await this.SendRolesList(context, context.message.guild!.id);
} else { } else {
await this.ToggleRole(context, rolesArray); await this.ToggleRole(context);
} }
} }
public async SendRolesList(context: ICommandContext, roles: String[], serverId: string): Promise<ICommandReturnContext> { public async GetRolesList(context: ICommandContext): Promise<string[]> {
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<ICommandReturnContext> {
const roles = await this.GetRolesList(context);
const botPrefix = await SettingsHelper.GetServerPrefix(serverId); const botPrefix = await SettingsHelper.GetServerPrefix(serverId);
const description = `Do ${botPrefix}role <role> to get the role!\n${roles.join('\n')}`; const description = roles.length == 0 ? "*no roles*" : `Do ${botPrefix}role <role> to get the role!\n\n${roles.join('\n')}`;
const embed = new PublicEmbed(context, "Roles", description); const embed = new PublicEmbed(context, "Roles", description);
embed.SendToCurrentChannel(); embed.SendToCurrentChannel();
@ -61,7 +71,8 @@ export default class Role extends Command {
}; };
} }
public async ToggleRole(context: ICommandContext, roles: String[]): Promise<ICommandReturnContext> { public async ToggleRole(context: ICommandContext): Promise<ICommandReturnContext> {
const roles = await this.GetRolesList(context);
const requestedRole = context.args.join(" "); const requestedRole = context.args.join(" ");
if (!roles.includes(requestedRole)) { if (!roles.includes(requestedRole)) {
@ -165,15 +176,32 @@ export default class Role extends Command {
return; return;
} }
let setting = await SettingsHelper.GetSetting("role.assignable", context.message.guild!.id) || ""; const existingRole = await eRole.FetchOneByRoleId(role.id);
const settingArray = setting.split(","); if (existingRole) {
const errorEmbed = new ErrorEmbed(context, "This role has already been setup");
errorEmbed.SendToCurrentChannel();
settingArray.push(role.name); return;
}
setting = settingArray.join(","); const server = await Server.FetchOneById(Server, context.message.guild!.id, [
"Roles",
]);
await SettingsHelper.SetSetting("role.assignable", context.message.guild!.id, setting); 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);
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`); const embed = new PublicEmbed(context, "", `Added \`${role.name}\` as a new assignable role`);
embed.SendToCurrentChannel(); embed.SendToCurrentChannel();
@ -187,21 +215,16 @@ export default class Role extends Command {
return; return;
} }
let setting = await SettingsHelper.GetSetting("role.assignable", context.message.guild!.id); const existingRole = await eRole.FetchOneByRoleId(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); await eRole.Remove(eRole, existingRole);
if (index == -1) return;
settingArray.splice(index, 1);
setting = settingArray.join(",");
await SettingsHelper.SetSetting("role.assignable", context.message.guild!.id, setting);
const embed = new PublicEmbed(context, "", `Removed \`${role.name}\` from the list of assignable roles`); const embed = new PublicEmbed(context, "", `Removed \`${role.name}\` from the list of assignable roles`);
embed.SendToCurrentChannel(); embed.SendToCurrentChannel();

44
src/entity/Role.ts Normal file
View file

@ -0,0 +1,44 @@
import { Column, Entity, EntityTarget, getConnection, 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;
public static async FetchOneByRoleId(roleId: string, relations?: string[]): Promise<Role | undefined> {
const connection = getConnection();
const repository = connection.getRepository(Role);
const single = await repository.findOne({ RoleId: roleId}, { relations: relations || [] });
return single;
}
public static async FetchAllByServerId(serverId: string): Promise<Role[]> {
const connection = getConnection();
const repository = connection.getRepository(Server);
const all = await repository.findOne(serverId, { relations: [
"Roles",
]});
if (!all) {
return [];
}
return all.Roles;
}
}

View file

@ -1,5 +1,6 @@
import { Column, Entity, getConnection, OneToMany } from "typeorm"; import { Entity, OneToMany } from "typeorm";
import BaseEntity from "../contracts/BaseEntity"; import BaseEntity from "../contracts/BaseEntity";
import Role from "./Role";
import Setting from "./Setting"; import Setting from "./Setting";
@Entity() @Entity()
@ -13,7 +14,14 @@ export default class Server extends BaseEntity {
@OneToMany(() => Setting, x => x.Server) @OneToMany(() => Setting, x => x.Server)
Settings: Setting[]; Settings: Setting[];
@OneToMany(() => Role, x => x.Server)
Roles: Role[];
public AddSettingToServer(setting: Setting) { public AddSettingToServer(setting: Setting) {
this.Settings.push(setting); this.Settings.push(setting);
} }
public AddRoleToServer(role: Role) {
this.Roles.push(role);
}
} }

View file

@ -0,0 +1,13 @@
import { MigrationInterface, QueryRunner } from "typeorm"
export class migration1652375907691 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
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<void> {
queryRunner.query(`DROP TABLE role`);
}
}