diff options
author | IRONM00N <64110067+IRONM00N@users.noreply.github.com> | 2021-07-23 22:02:44 -0400 |
---|---|---|
committer | IRONM00N <64110067+IRONM00N@users.noreply.github.com> | 2021-07-23 22:02:44 -0400 |
commit | b015bec7f66526ec5e959ae99865845f4db4b181 (patch) | |
tree | 67538c9549b7e0f7cd6a97e9c82db8d8462a19c7 | |
parent | 5c242f597595b8db71875d92c0afe0a5947442a6 (diff) | |
download | tanzanite-b015bec7f66526ec5e959ae99865845f4db4b181.tar.gz tanzanite-b015bec7f66526ec5e959ae99865845f4db4b181.tar.bz2 tanzanite-b015bec7f66526ec5e959ae99865845f4db4b181.zip |
feat: some shit
- fix breaking changes
- refactored active punishments into one table
- made listeners args have stricter types
35 files changed, 334 insertions, 548 deletions
diff --git a/.yarn/sdks/typescript/package.json b/.yarn/sdks/typescript/package.json index fbe0980..27270c7 100644 --- a/.yarn/sdks/typescript/package.json +++ b/.yarn/sdks/typescript/package.json @@ -1,6 +1,6 @@ { "name": "typescript", - "version": "0.0.0-sdk", + "version": "4.2.4-pnpify", "main": "./lib/typescript.js", "type": "commonjs" } diff --git a/package.json b/package.json index 716d351..364b9a2 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "chalk": "^4.1.1", "common-tags": "^1.8.0", "discord-akairo": "NotEnoughUpdates/discord-akairo", - "discord-api-types": "0.19.0-next.f393ba520d7d6d2aacaca7b3ca5d355fab614f6e", + "discord-api-types": "0.19.0", "discord.js": "NotEnoughUpdates/discord.js", "discord.js-minesweeper": "^1.0.6", "fuse.js": "^6.4.6", diff --git a/src/commands/dev/eval.ts b/src/commands/dev/eval.ts index 0de0aa1..f8ba7e1 100644 --- a/src/commands/dev/eval.ts +++ b/src/commands/dev/eval.ts @@ -181,7 +181,7 @@ export default class EvalCommand extends BushCommand { members = message.guild?.members, roles = message.guild?.roles, client = this.client, - { Ban, Global, Guild, Level, ModLog, StickyRole } = await import('@lib'), + { ActivePunishment, Global, Guild, Level, ModLog, StickyRole } = await import('@lib'), { ButtonInteraction, Collector, diff --git a/src/commands/dev/servers.ts b/src/commands/dev/servers.ts index 08f74e8..3986451 100644 --- a/src/commands/dev/servers.ts +++ b/src/commands/dev/servers.ts @@ -4,7 +4,7 @@ import { BushCommand, BushMessage, BushSlashMessage } from '../../lib'; export default class ServersCommand extends BushCommand { public constructor() { super('servers', { - aliases: ['servers'], + aliases: ['servers', 'guilds'], category: 'dev', description: { content: 'Displays all the severs the bot is in', @@ -37,7 +37,7 @@ export default class ServersCommand extends BushCommand { `**ID:** ${g.id}\n**Owner:** ${owner ? owner : g.ownerId}\n**Members:** ${g.memberCount.toLocaleString()}`, false ) - .setTitle('Server List') + .setTitle(`Server List [${this.client.guilds.cache.size}]`) .setColor(this.client.util.colors.default); }); embeds.push(embed); diff --git a/src/commands/moderation/removeReactionEmoji.ts b/src/commands/moderation/removeReactionEmoji.ts index 3d274e1..b0079c6 100644 --- a/src/commands/moderation/removeReactionEmoji.ts +++ b/src/commands/moderation/removeReactionEmoji.ts @@ -13,7 +13,7 @@ export default class RemoveReactionEmojiCommand extends BushCommand { examples: ['removereactionemoji 791413052347252786 <:omegaclown:782630946435366942>'] }, clientPermissions: ['MANAGE_MESSAGES', 'SEND_MESSAGES', 'EMBED_LINKS'], - userPermissions: ['MANAGE_MESSAGES', 'MANAGE_EMOJIS'], // Can't undo the removal of 1000s of reactions + userPermissions: ['MANAGE_MESSAGES', 'MANAGE_EMOJIS_AND_STICKERS'], // Can't undo the removal of 1000s of reactions args: [ { id: 'messageToRemoveFrom', diff --git a/src/lib/extensions/discord-akairo/BushClient.ts b/src/lib/extensions/discord-akairo/BushClient.ts index 66204ac..8eec3ce 100644 --- a/src/lib/extensions/discord-akairo/BushClient.ts +++ b/src/lib/extensions/discord-akairo/BushClient.ts @@ -18,13 +18,11 @@ import { Sequelize } from 'sequelize'; import { contentWithDurationTypeCaster } from '../../../arguments/contentWithDuration'; import { durationTypeCaster } from '../../../arguments/duration'; import { UpdateCacheTask } from '../../../tasks/updateCache'; -import { Ban } from '../../models/Ban'; +import { ActivePunishment } from '../../models/ActivePunishment'; import { Global } from '../../models/Global'; import { Guild as GuildModel } from '../../models/Guild'; import { Level } from '../../models/Level'; import { ModLog } from '../../models/ModLog'; -import { Mute } from '../../models/Mute'; -import { PunishmentRole } from '../../models/PunishmentRole'; import { StickyRole } from '../../models/StickyRole'; import { AllowedMentions } from '../../utils/AllowedMentions'; import { BushCache } from '../../utils/BushCache'; @@ -107,39 +105,23 @@ export class BushClient extends AkairoClient { public constants = BushConstants; public cache = BushCache; public constructor(config: Config) { - super( - { - ownerID: config.owners, - intents: Object.values(Intents.FLAGS).reduce((acc, p) => acc | p, 0), - presence: { - activities: [ - { - name: 'Beep Boop', - type: 'WATCHING' - } - ], - status: 'online' - } + super({ + ownerID: config.owners, + intents: Object.values(Intents.FLAGS).reduce((acc, p) => acc | p, 0), + presence: { + activities: [ + { + name: 'Beep Boop', + type: 'WATCHING' + } + ], + status: 'online' }, - { - allowedMentions: AllowedMentions.users(), // No everyone or role mentions by default - intents: Object.values(Intents.FLAGS).reduce((acc, p) => acc | p, 0), - presence: { - activities: [ - { - name: 'Beep Boop', - type: 'WATCHING' - } - ], - status: 'online' - } - } - ); + http: { api: 'https://canary.discord.com/api' }, + allowedMentions: AllowedMentions.users() // No everyone or role mentions by default + }); - // Set token this.token = config.token; - - // Set config this.config = config; // Create listener handler @@ -170,7 +152,7 @@ export class BushClient extends AkairoClient { allowMention: true, handleEdits: true, commandUtil: true, - commandUtilLifetime: 300_000, + commandUtilLifetime: 300_000, // 5 minutes argumentDefaults: { prompt: { start: 'Placeholder argument prompt. If you see this please tell my developers.', @@ -259,11 +241,9 @@ export class BushClient extends AkairoClient { Global.initModel(this.db); GuildModel.initModel(this.db, this); ModLog.initModel(this.db); - Ban.initModel(this.db); - Mute.initModel(this.db); + ActivePunishment.initModel(this.db); Level.initModel(this.db); StickyRole.initModel(this.db); - PunishmentRole.initModel(this.db); await this.db.sync({ alter: true }); // Sync all tables to fix everything if updated await this.console.success('Startup', `Successfully connected to <<database>>.`, false); } catch (e) { @@ -277,7 +257,7 @@ export class BushClient extends AkairoClient { /** Starts the bot */ public async start(): Promise<void> { - global.client = this; + global.client = this; // makes the client a global object try { await this._init(); diff --git a/src/lib/extensions/discord-akairo/BushClientUtil.ts b/src/lib/extensions/discord-akairo/BushClientUtil.ts index 0e3a904..306e049 100644 --- a/src/lib/extensions/discord-akairo/BushClientUtil.ts +++ b/src/lib/extensions/discord-akairo/BushClientUtil.ts @@ -2,7 +2,6 @@ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { - Ban, BushCache, BushClient, BushConstants, @@ -14,9 +13,7 @@ import { Global, Guild, ModLog, - ModLogType, - Mute, - PunishmentRole + ModLogType } from '@lib'; import { exec } from 'child_process'; import { ClientUtil } from 'discord-akairo'; @@ -43,8 +40,8 @@ import { } from 'discord.js'; import got from 'got'; import humanizeDuration from 'humanize-duration'; -import { Op } from 'sequelize'; import { promisify } from 'util'; +import { ActivePunishment, ActivePunishmentType } from '../../models/ActivePunishment'; import { BushNewsChannel } from '../discord.js/BushNewsChannel'; import { BushTextChannel } from '../discord.js/BushTextChannel'; import { BushUserResolvable } from './BushClient'; @@ -96,12 +93,6 @@ interface bushColors { orange: '#E86100'; } -interface punishmentModels { - mute: Mute; - ban: Ban; - role: PunishmentRole; -} - interface MojangProfile { username: string; uuid: string; @@ -664,22 +655,21 @@ export class BushClientUtil extends ClientUtil { } public async createPunishmentEntry(options: { - type: 'mute' | 'ban' | 'role'; + type: 'mute' | 'ban' | 'role' | 'block'; user: BushGuildMemberResolvable; duration: number; guild: BushGuildResolvable; modlog: string; - role?: Snowflake; - }): Promise<Mute | Ban | PunishmentRole> { - const dbModel = this.findPunishmentModel(options.type); + extraInfo?: Snowflake; + }): Promise<ActivePunishment> { const expires = options.duration ? new Date(new Date().getTime() + options.duration) : null; const user = this.client.users.resolveId(options.user); const guild = this.client.guilds.resolveId(options.guild); + const type = this.findTypeEnum(options.type); - const entry = - options.type === 'role' - ? (dbModel as typeof PunishmentRole).build({ user, guild, expires, modlog: options.modlog, role: options.role }) - : dbModel.build({ user, guild, expires, modlog: options.modlog }); + const entry = options.extraInfo + ? ActivePunishment.build({ user, type, guild, expires, modlog: options.modlog, extraInfo: options.extraInfo }) + : ActivePunishment.build({ user, type, guild, expires, modlog: options.modlog }); return await entry.save().catch((e) => { this.client.console.error('createPunishmentEntry', e?.stack || e); return null; @@ -687,28 +677,23 @@ export class BushClientUtil extends ClientUtil { } public async removePunishmentEntry(options: { - type: 'mute' | 'ban' | 'role'; + type: 'mute' | 'ban' | 'role' | 'block'; user: BushGuildMemberResolvable; guild: BushGuildResolvable; }): Promise<boolean> { - const dbModel = this.findPunishmentModel(options.type); const user = this.client.users.resolveId(options.user); const guild = this.client.guilds.resolveId(options.guild); + const type = this.findTypeEnum(options.type); let success = true; - const entries = await dbModel - .findAll({ - // finding all cases of a certain type incase there were duplicates or something - where: { - user, - guild - } - }) - .catch((e) => { - this.client.console.error('removePunishmentEntry', e?.stack || e); - success = false; - }); + const entries = await ActivePunishment.findAll({ + // finding all cases of a certain type incase there were duplicates or something + where: { user, guild, type } + }).catch((e) => { + this.client.console.error('removePunishmentEntry', e?.stack || e); + success = false; + }); if (entries) { entries.forEach(async (entry) => { await entry.destroy().catch((e) => { @@ -720,33 +705,14 @@ export class BushClientUtil extends ClientUtil { return success; } - public async findExpiredEntries<K extends keyof punishmentModels>(type: K): Promise<punishmentModels[K][]> { - const dbModel = this.findPunishmentModel(type); - //@ts-ignore: stfu idc - return await dbModel.findAll({ - where: { - [Op.and]: [ - { - expires: { - [Op.lt]: new Date() // Find all rows with an expiry date before now - } - } - ] - } - }); - } - - private findPunishmentModel<K extends keyof punishmentModels>(type: K): typeof Mute | typeof Ban | typeof PunishmentRole { - switch (type) { - case 'mute': - return Mute; - case 'ban': - return Ban; - case 'role': - return PunishmentRole; - default: - throw 'choose a valid punishment entry type'; - } + private findTypeEnum(type: 'mute' | 'ban' | 'role' | 'block') { + const typeMap = { + ['mute']: ActivePunishmentType.MUTE, + ['ban']: ActivePunishmentType.BAN, + ['role']: ActivePunishmentType.ROLE, + ['block']: ActivePunishmentType.BLOCK + }; + return typeMap[type]; } public humanizeDuration(duration: number): string { @@ -782,5 +748,7 @@ export class BushClientUtil extends ClientUtil { return arrByte[1] + ', ' + arrByte[2] + ', ' + arrByte[3]; } + /* eslint-disable @typescript-eslint/no-unused-vars */ public async lockdownChannel(options: { channel: BushTextChannel | BushNewsChannel; moderator: BushUserResolvable }) {} + /* eslint-enable @typescript-eslint/no-unused-vars */ } diff --git a/src/lib/extensions/discord-akairo/BushCommandHandler.ts b/src/lib/extensions/discord-akairo/BushCommandHandler.ts index 09baf2e..dacd17f 100644 --- a/src/lib/extensions/discord-akairo/BushCommandHandler.ts +++ b/src/lib/extensions/discord-akairo/BushCommandHandler.ts @@ -1,15 +1,26 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { Category, CommandHandler, CommandHandlerOptions } from 'discord-akairo'; -import { Collection } from 'discord.js'; +import { Category, CommandHandler, CommandHandlerEvents, CommandHandlerOptions } from 'discord-akairo'; +import { Collection, PermissionString } from 'discord.js'; import { BushConstants } from '../../utils/BushConstants'; import { BushMessage } from '../discord.js/BushMessage'; import { BushClient } from './BushClient'; import { BushCommand } from './BushCommand'; +import { BushSlashMessage } from './BushSlashMessage'; export type BushCommandHandlerOptions = CommandHandlerOptions; -const CommandHandlerEvents = BushConstants.CommandHandlerEvents; -const BlockedReasons = BushConstants.BlockedReasons; +const commandHandlerEvents = BushConstants.CommandHandlerEvents; +const blockedReasons = BushConstants.BlockedReasons; + +export interface BushCommandHandlerEvents extends CommandHandlerEvents { + commandBlocked: [message: BushMessage, command: BushCommand, reason: string]; + + missingPermissions: [message: BushMessage, command: BushCommand, type: 'client' | 'user', missing: Array<PermissionString>]; + + slashBlocked: [message: BushSlashMessage, command: BushCommand, reason: string]; + + slashMissingPermissions: [message: BushSlashMessage, command: BushCommand, type: 'client' | 'user', missing: Array<PermissionString>]; +} export class BushCommandHandler extends CommandHandler { public declare client: BushClient; @@ -24,10 +35,10 @@ export class BushCommandHandler extends CommandHandler { const isOwner = this.client.isOwner(message.author); if (!isOwner) { this.emit( - slash ? CommandHandlerEvents.SLASH_BLOCKED : CommandHandlerEvents.COMMAND_BLOCKED, + slash ? commandHandlerEvents.SLASH_BLOCKED : commandHandlerEvents.COMMAND_BLOCKED, message, command, - BlockedReasons.OWNER + blockedReasons.OWNER ); return true; } @@ -37,10 +48,10 @@ export class BushCommandHandler extends CommandHandler { const isSuperUser = this.client.isSuperUser(message.author); if (!isSuperUser) { this.emit( - slash ? CommandHandlerEvents.SLASH_BLOCKED : CommandHandlerEvents.COMMAND_BLOCKED, + slash ? commandHandlerEvents.SLASH_BLOCKED : commandHandlerEvents.COMMAND_BLOCKED, message, command, - BlockedReasons.OWNER + blockedReasons.OWNER ); return true; } @@ -48,32 +59,32 @@ export class BushCommandHandler extends CommandHandler { if (command.channel === 'guild' && !message.guild) { this.emit( - slash ? CommandHandlerEvents.SLASH_BLOCKED : CommandHandlerEvents.COMMAND_BLOCKED, + slash ? commandHandlerEvents.SLASH_BLOCKED : commandHandlerEvents.COMMAND_BLOCKED, message, command, - BlockedReasons.GUILD + blockedReasons.GUILD ); return true; } if (command.channel === 'dm' && message.guild) { this.emit( - slash ? CommandHandlerEvents.SLASH_BLOCKED : CommandHandlerEvents.COMMAND_BLOCKED, + slash ? commandHandlerEvents.SLASH_BLOCKED : commandHandlerEvents.COMMAND_BLOCKED, message, command, - BlockedReasons.DM + blockedReasons.DM ); return true; } if (command.restrictedChannels?.length && message.channel) { if (!command.restrictedChannels.includes(message.channel.id)) { - this.emit(CommandHandlerEvents.COMMAND_BLOCKED, message, command, BlockedReasons.RESTRICTED_CHANNEL); + this.emit(commandHandlerEvents.COMMAND_BLOCKED, message, command, blockedReasons.RESTRICTED_CHANNEL); return true; } } if (command.restrictedGuilds?.length && message.guild) { if (!command.restrictedGuilds.includes(message.guild.id)) { - this.emit(CommandHandlerEvents.COMMAND_BLOCKED, message, command, BlockedReasons.RESTRICTED_GUILD); + this.emit(commandHandlerEvents.COMMAND_BLOCKED, message, command, blockedReasons.RESTRICTED_GUILD); return true; } } @@ -82,7 +93,7 @@ export class BushCommandHandler extends CommandHandler { } const reason = this.inhibitorHandler ? await this.inhibitorHandler.test('post', message, command) : null; if (reason != null) { - this.emit(CommandHandlerEvents.COMMAND_BLOCKED, message, command, reason); + this.emit(commandHandlerEvents.COMMAND_BLOCKED, message, command, reason); return true; } return !!this.runCooldowns(message, command); diff --git a/src/lib/extensions/discord-akairo/BushListener.ts b/src/lib/extensions/discord-akairo/BushListener.ts index e555e89..2583e85 100644 --- a/src/lib/extensions/discord-akairo/BushListener.ts +++ b/src/lib/extensions/discord-akairo/BushListener.ts @@ -1,6 +1,9 @@ import { Listener } from 'discord-akairo'; +import EventEmitter from 'events'; import { BushClient } from './BushClient'; - export class BushListener extends Listener { public declare client: BushClient; + public constructor(id: string, options?:{emitter: string|EventEmitter, event: string, type?: 'on'|'once', category?: string}){ + super(id, options) + } } diff --git a/src/lib/extensions/discord.js/BushButtonInteraction.ts b/src/lib/extensions/discord.js/BushButtonInteraction.ts index 3a54f61..846786c 100644 --- a/src/lib/extensions/discord.js/BushButtonInteraction.ts +++ b/src/lib/extensions/discord.js/BushButtonInteraction.ts @@ -1,4 +1,4 @@ -import { APIInteractionGuildMember } from 'discord-api-types/v8'; +import { APIInteractionGuildMember } from 'discord-api-types/v9'; import { ButtonInteraction, PartialDMChannel } from 'discord.js'; import { BushClient } from '../discord-akairo/BushClient'; import { BushDMChannel } from './BushDMChannel'; diff --git a/src/lib/extensions/discord.js/BushCommandInteraction.ts b/src/lib/extensions/discord.js/BushCommandInteraction.ts index 84c0707..e4fdb53 100644 --- a/src/lib/extensions/discord.js/BushCommandInteraction.ts +++ b/src/lib/extensions/discord.js/BushCommandInteraction.ts @@ -1,4 +1,4 @@ -import { APIInteractionGuildMember } from 'discord-api-types/v8'; +import { APIInteractionGuildMember } from 'discord-api-types/v9'; import { ApplicationCommand, CommandInteraction, diff --git a/src/lib/extensions/discord.js/BushGuildMember.ts b/src/lib/extensions/discord.js/BushGuildMember.ts index 40e4a3a..50875cc 100644 --- a/src/lib/extensions/discord.js/BushGuildMember.ts +++ b/src/lib/extensions/discord.js/BushGuildMember.ts @@ -137,7 +137,7 @@ export class BushGuildMember extends GuildMember { guild: this.guild, duration: options.duration, modlog: modlog.id, - role: options.role.id + extraInfo: options.role.id }) .catch(() => null); if (!punishmentEntrySuccess) return 'error creating role entry'; diff --git a/src/lib/extensions/discord.js/BushSelectMenuInteraction.ts b/src/lib/extensions/discord.js/BushSelectMenuInteraction.ts index 1dd1638..18db8ef 100644 --- a/src/lib/extensions/discord.js/BushSelectMenuInteraction.ts +++ b/src/lib/extensions/discord.js/BushSelectMenuInteraction.ts @@ -1,4 +1,4 @@ -import { APIInteractionGuildMember } from 'discord-api-types/v8'; +import { APIInteractionGuildMember } from 'discord-api-types/v9'; import { PartialDMChannel, SelectMenuInteraction } from 'discord.js'; import { BushClient } from '../discord-akairo/BushClient'; import { BushDMChannel } from './BushDMChannel'; diff --git a/src/lib/index.ts b/src/lib/index.ts index 1059e2b..73cee56 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -46,14 +46,12 @@ export * from './extensions/discord.js/BushThreadMemberManager'; export * from './extensions/discord.js/BushUser'; export * from './extensions/discord.js/BushVoiceChannel'; export * from './extensions/discord.js/BushVoiceState'; -export * from './models/Ban'; +export * from './models/ActivePunishment'; export * from './models/BaseModel'; export * from './models/Global'; export * from './models/Guild'; export * from './models/Level'; export * from './models/ModLog'; -export * from './models/Mute'; -export * from './models/PunishmentRole'; export * from './models/StickyRole'; export * from './utils/AllowedMentions'; export * from './utils/BushCache'; diff --git a/src/lib/models/PunishmentRole.ts b/src/lib/models/ActivePunishment.ts index 0b54f31..9fcafbe 100644 --- a/src/lib/models/PunishmentRole.ts +++ b/src/lib/models/ActivePunishment.ts @@ -3,54 +3,67 @@ import { DataTypes, Sequelize } from 'sequelize'; import { v4 as uuidv4 } from 'uuid'; import { BaseModel } from './BaseModel'; -export interface PunishmentRoleModel { +export enum ActivePunishmentType { + BAN = 'BAN', + MUTE = 'MUTE', + ROLE = 'ROLE', + BLOCK = 'BLOCK' +} + +export interface ActivePunishmentModel { id: string; + type: ActivePunishmentType; user: Snowflake; - role: Snowflake; guild: Snowflake; + extraInfo: Snowflake; expires: Date; modlog: string; } -export interface PunishmentRoleModelCreationAttributes { +export interface ActivePunishmentModelCreationAttributes { id?: string; + type: ActivePunishmentType; user: Snowflake; - role?: Snowflake; guild: Snowflake; + extraInfo?: Snowflake; expires?: Date; modlog: string; } -export class PunishmentRole - extends BaseModel<PunishmentRoleModel, PunishmentRoleModelCreationAttributes> - implements PunishmentRoleModel +export class ActivePunishment + extends BaseModel<ActivePunishmentModel, ActivePunishmentModelCreationAttributes> + implements ActivePunishmentModel { /** - * The ID of this punishment role (no real use just for a primary key) + * The ID of this punishment (no real use just for a primary key) */ id: string; /** - * The user who received a role + * The type of punishment. */ - user: Snowflake; + type: ActivePunishmentType; /** - * The role added to the user. + * The user who is punished. */ - role: Snowflake; + user: Snowflake; /** - * The guild they received a role in + * The guild they are punished in. */ guild: Snowflake; /** - * The date at which this role expires and should be removed (optional) + * Additional info about the punishment if applicable. The channel id for channel blocks and role for punishment roles. + */ + extraInfo: Snowflake; + /** + * The date when this punishment expires (optional). */ expires: Date | null; /** - * The ref to the modlog entry + * The reference to the modlog entry. */ modlog: string; static initModel(sequelize: Sequelize): void { - PunishmentRole.init( + ActivePunishment.init( { id: { type: DataTypes.STRING, @@ -58,11 +71,11 @@ export class PunishmentRole allowNull: false, defaultValue: uuidv4 }, - user: { + type: { type: DataTypes.STRING, allowNull: false }, - role: { + user: { type: DataTypes.STRING, allowNull: false }, @@ -74,6 +87,10 @@ export class PunishmentRole key: 'id' } }, + extraInfo: { + type: DataTypes.DATE, + allowNull: true + }, expires: { type: DataTypes.DATE, allowNull: true diff --git a/src/lib/models/Ban.ts b/src/lib/models/Ban.ts deleted file mode 100644 index 1bdda6f..0000000 --- a/src/lib/models/Ban.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { Snowflake } from 'discord.js'; -import { DataTypes, Sequelize } from 'sequelize'; -import { v4 as uuidv4 } from 'uuid'; -import { BaseModel } from './BaseModel'; - -export interface BanModel { - id: string; - user: Snowflake; - guild: Snowflake; - expires: Date; - modlog: string; -} -export interface BanModelCreationAttributes { - id?: string; - user: Snowflake; - guild: Snowflake; - expires?: Date; - modlog: string; -} - -export class Ban extends BaseModel<BanModel, BanModelCreationAttributes> implements BanModel { - /** - * The ID of this ban (no real use just for a primary key) - */ - id: string; - /** - * The user who is banned - */ - user: Snowflake; - /** - * The guild they are banned from - */ - guild: Snowflake; - /** - * The date at which this ban expires and should be unbanned (optional) - */ - expires: Date | null; - /** - * The ref to the modlog entry - */ - modlog: string; - - static initModel(sequelize: Sequelize): void { - Ban.init( - { - id: { - type: DataTypes.STRING, - primaryKey: true, - allowNull: false, - defaultValue: uuidv4 - }, - user: { - type: DataTypes.STRING, - allowNull: false - }, - guild: { - type: DataTypes.STRING, - allowNull: false, - references: { - model: 'Guilds', - key: 'id' - } - }, - expires: { - type: DataTypes.DATE, - allowNull: true - }, - modlog: { - type: DataTypes.STRING, - allowNull: false, - references: { - model: 'ModLogs', - key: 'id' - } - } - }, - { sequelize: sequelize } - ); - } -} diff --git a/src/lib/models/ModLog.ts b/src/lib/models/ModLog.ts index 40dc86d..3375751 100644 --- a/src/lib/models/ModLog.ts +++ b/src/lib/models/ModLog.ts @@ -14,7 +14,10 @@ export enum ModLogType { WARN = 'WARN', PERM_PUNISHMENT_ROLE = 'PERM_PUNISHMENT_ROLE', TEMP_PUNISHMENT_ROLE = 'TEMP_PUNISHMENT_ROLE', - REMOVE_PUNISHMENT_ROLE = 'REMOVE_PUNISHMENT_ROLE' + REMOVE_PUNISHMENT_ROLE = 'REMOVE_PUNISHMENT_ROLE', + PERM_CHANNEL_BLOCK = 'PERM_CHANNEL_BLOCK', + TEMP_CHANNEL_BLOCK = 'TEMP_CHANNEL_BLOCK', + CHANNEL_UNBLOCK = 'CHANNEL_UNBLOCK' } export interface ModLogModel { diff --git a/src/lib/models/Mute.ts b/src/lib/models/Mute.ts deleted file mode 100644 index 4208d02..0000000 --- a/src/lib/models/Mute.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { Snowflake } from 'discord.js'; -import { DataTypes, Sequelize } from 'sequelize'; -import { v4 as uuidv4 } from 'uuid'; -import { BaseModel } from './BaseModel'; - -export interface MuteModel { - id: string; - user: Snowflake; - guild: Snowflake; - expires: Date; - modlog: string; -} -export interface MuteModelCreationAttributes { - id?: string; - user: Snowflake; - guild: Snowflake; - expires?: Date; - modlog: string; -} - -export class Mute extends BaseModel<MuteModel, MuteModelCreationAttributes> implements MuteModel { - /** - * The ID of this mute (no real use just for a primary key) - */ - id: string; - /** - * The user who is muted - */ - user: Snowflake; - /** - * The guild they are muted in - */ - guild: Snowflake; - /** - * The date at which this Mute expires and should be unmuted (optional) - */ - expires: Date | null; - /** - * The ref to the modlog entry - */ - modlog: string; - - static initModel(sequelize: Sequelize): void { - Mute.init( - { - id: { - type: DataTypes.STRING, - primaryKey: true, - allowNull: false, - defaultValue: uuidv4 - }, - user: { - type: DataTypes.STRING, - allowNull: false - }, - guild: { - type: DataTypes.STRING, - allowNull: false, - references: { - model: 'Guilds', - key: 'id' - } - }, - expires: { - type: DataTypes.DATE, - allowNull: true - }, - modlog: { - type: DataTypes.STRING, - allowNull: false, - references: { - model: 'ModLogs', - key: 'id' - } - } - }, - { sequelize: sequelize } - ); - } -} diff --git a/src/listeners/client/interactionCreate.ts b/src/listeners/client/interactionCreate.ts index 1183004..0e77fea 100644 --- a/src/listeners/client/interactionCreate.ts +++ b/src/listeners/client/interactionCreate.ts @@ -1,5 +1,5 @@ import { BushListener } from '@lib'; -import { ButtonInteraction, CommandInteraction, Interaction, SelectMenuInteraction } from 'discord.js'; +import { ClientEvents } from 'discord.js'; export default class InteractionCreateListener extends BushListener { public constructor() { @@ -10,7 +10,7 @@ export default class InteractionCreateListener extends BushListener { }); } - async exec(interaction: Interaction | CommandInteraction | ButtonInteraction | SelectMenuInteraction): Promise<unknown> { + async exec([interaction]: ClientEvents['interactionCreate']): Promise<unknown> { if (!interaction) return; if (interaction.isCommand()) { this.client.console.info( diff --git a/src/listeners/commands/commandBlocked.ts b/src/listeners/commands/commandBlocked.ts index 24d46af..c02f21c 100644 --- a/src/listeners/commands/commandBlocked.ts +++ b/src/listeners/commands/commandBlocked.ts @@ -1,4 +1,4 @@ -import { BushCommand, BushListener, BushMessage } from '@lib'; +import { BushCommandHandlerEvents, BushListener } from '@lib'; export default class CommandBlockedListener extends BushListener { public constructor() { @@ -8,7 +8,7 @@ export default class CommandBlockedListener extends BushListener { }); } - public async exec(message: BushMessage, command: BushCommand, reason: string): Promise<unknown> { + public async exec([message, command, reason]: BushCommandHandlerEvents['commandBlocked']): Promise<unknown> { this.client.console.info( 'CommandBlocked', `<<${message.author.tag}>> tried to run <<${message.util.parsed.command}>> but was blocked because <<${reason}>>.`, diff --git a/src/listeners/commands/commandError.ts b/src/listeners/commands/commandError.ts index 696b59b..1aaefad 100644 --- a/src/listeners/commands/commandError.ts +++ b/src/listeners/commands/commandError.ts @@ -1,6 +1,5 @@ -import { BushListener, BushMessage } from '@lib'; +import { BushCommandHandlerEvents, BushListener } from '@lib'; import { stripIndents } from 'common-tags'; -import { Command } from 'discord-akairo'; import { MessageEmbed } from 'discord.js'; export default class CommandErrorListener extends BushListener { @@ -11,7 +10,7 @@ export default class CommandErrorListener extends BushListener { }); } - public async exec(error: Error, message: BushMessage, command: Command | null | undefined): Promise<void> { + public async exec([error, message, command]: BushCommandHandlerEvents['error']): Promise<void> { const errorNo = Math.floor(Math.random() * 6969696969) + 69; // hehe funny number const errorEmbed: MessageEmbed = new MessageEmbed() .setTitle(`Error # \`${errorNo}\`: An error occurred`) diff --git a/src/listeners/commands/commandMissingPermissions.ts b/src/listeners/commands/commandMissingPermissions.ts index f3d2218..765bc72 100644 --- a/src/listeners/commands/commandMissingPermissions.ts +++ b/src/listeners/commands/commandMissingPermissions.ts @@ -1,5 +1,4 @@ -import { BushCommand, BushListener, BushMessage } from '@lib'; -import { PermissionString } from 'discord.js'; +import { BushCommandHandlerEvents, BushListener } from '@lib'; export default class CommandMissingPermissionsListener extends BushListener { public constructor() { @@ -10,12 +9,7 @@ export default class CommandMissingPermissionsListener extends BushListener { }); } - public async exec( - message: BushMessage, - command: BushCommand | null | undefined, - type: 'client' | 'user', - missing: Array<PermissionString> - ): Promise<void> { + public async exec([message, command, type, missing]: BushCommandHandlerEvents['missingPermissions']): Promise<void> { const niceMissing = []; missing.forEach((missing) => { if (this.client.consts.mappings.permissions[missing]) { diff --git a/src/listeners/commands/commandStarted.ts b/src/listeners/commands/commandStarted.ts index 24bb041..dcc1d83 100644 --- a/src/listeners/commands/commandStarted.ts +++ b/src/listeners/commands/commandStarted.ts @@ -1,20 +1,20 @@ -import { BushCommand, BushListener } from '@lib'; -import { Message } from 'discord.js'; +import { BushCommandHandlerEvents, BushListener } from '@lib'; export default class CommandStartedListener extends BushListener { public constructor() { super('commandStarted', { emitter: 'commandHandler', - event: 'commandStarted' + event: 'commandStarted', + category: 'commands' }); } - exec(message: Message, command: BushCommand): void { + exec([message, command]: BushCommandHandlerEvents['commandStarted']): void { this.client.logger.info( 'Command', `The <<${command.id}>> command was used by <<${message.author.tag}>> in ${ message.channel.type === 'DM' ? `their <<DMs>>` : `<<#${message.channel.name}>> in <<${message.guild?.name}>>` }.`, - true //// I don't want to spam the log channel when people use commands + true ); } } diff --git a/src/listeners/commands/slashBlocked.ts b/src/listeners/commands/slashBlocked.ts index 2443efb..ecbe863 100644 --- a/src/listeners/commands/slashBlocked.ts +++ b/src/listeners/commands/slashBlocked.ts @@ -1,14 +1,15 @@ -import { BushCommand, BushListener, BushSlashMessage } from '@lib'; +import { BushCommandHandlerEvents, BushListener } from '@lib'; export default class SlashBlockedListener extends BushListener { public constructor() { super('slashBlocked', { emitter: 'commandHandler', - event: 'slashBlocked' + event: 'slashBlocked', + category: 'commands' }); } - public async exec(message: BushSlashMessage, command: BushCommand, reason: string): Promise<unknown> { + public async exec([message, command, reason]: BushCommandHandlerEvents['slashBlocked']): Promise<unknown> { this.client.console.info( 'SlashBlocked', `<<${message.author.tag}>> tried to run <<${message.util.parsed.command}>> but was blocked because <<${reason}>>.`, diff --git a/src/listeners/commands/slashCommandError.ts b/src/listeners/commands/slashCommandError.ts index 8abe788..4eaf293 100644 --- a/src/listeners/commands/slashCommandError.ts +++ b/src/listeners/commands/slashCommandError.ts @@ -1,4 +1,4 @@ -import { BushCommand, BushListener, BushSlashMessage } from '@lib'; +import { BushCommandHandlerEvents, BushListener } from '@lib'; import { stripIndents } from 'common-tags'; import { GuildChannel, MessageEmbed } from 'discord.js'; @@ -6,10 +6,11 @@ export default class SlashCommandErrorListener extends BushListener { public constructor() { super('slashError', { emitter: 'commandHandler', - event: 'slashError' + event: 'slashError', + category: 'commands' }); } - async exec(error: Error, message: BushSlashMessage, command: BushCommand): Promise<void> { + async exec([error, message, command]: BushCommandHandlerEvents['slashError']): Promise<void> { const errorNo = Math.floor(Math.random() * 6969696969) + 69; // hehe funny number const errorEmbed: MessageEmbed = new MessageEmbed() .setTitle(`Slash Error # \`${errorNo}\`: An error occurred`) diff --git a/src/listeners/commands/slashMissingPermissions.ts b/src/listeners/commands/slashMissingPermissions.ts index a410bef..45966bb 100644 --- a/src/listeners/commands/slashMissingPermissions.ts +++ b/src/listeners/commands/slashMissingPermissions.ts @@ -1,22 +1,15 @@ -import { BushListener } from '@lib'; -import { Command } from 'discord-akairo'; -import { CommandInteraction } from 'discord.js'; +import { BushCommandHandlerEvents, BushListener } from '@lib'; export default class SlashMissingPermissionsListener extends BushListener { public constructor() { super('slashMissingPermissions', { emitter: 'commandHandler', event: 'slashMissingPermissions', - category: 'slashCommands' + category: 'commands' }); } - public async exec( - interaction: CommandInteraction, - command: Command, - type: 'user' | 'client', - missing?: string[] - ): Promise<void> { + public async exec([message, command, type, missing]: BushCommandHandlerEvents['slashMissingPermissions']): Promise<void> { const niceMissing = []; missing.forEach((missing) => { if (this.client.consts.mappings.permissions[missing]) { @@ -30,24 +23,22 @@ export default class SlashMissingPermissionsListener extends BushListener { const consoleFormat = this.client.util.oxford(this.client.util.surroundArray(niceMissing, '<<', '>>'), 'and', ''); this.client.console.info( 'CommandMissingPermissions', - `<<${interaction.user.tag}>> tried to run <<${ + `<<${message.author.tag}>> tried to run <<${ command?.id }>> but could not because <<${type}>> is missing the ${consoleFormat} permissions${missing.length ? 's' : ''}.`, true ); if (type == 'client') { - await this.client.util - .slashRespond( - interaction, + await message.util + .reply( `${this.client.util.emojis.error} I am missing the ${discordFormat} permission${ missing.length ? 's' : '' } required for the \`${command?.id}\` command.` ) .catch(() => {}); } else if (type == 'user') { - await this.client.util - .slashRespond( - interaction, + await message.util + .reply( `${this.client.util.emojis.error} You are missing the ${discordFormat} permission${ missing.length ? 's' : '' } required for the \`${command?.id}\` command.` diff --git a/src/listeners/commands/slashStarted.ts b/src/listeners/commands/slashStarted.ts index a0201c5..6ff3c6e 100644 --- a/src/listeners/commands/slashStarted.ts +++ b/src/listeners/commands/slashStarted.ts @@ -1,19 +1,20 @@ -import { BushCommand, BushListener, BushSlashMessage } from '@lib'; +import { BushCommandHandlerEvents, BushListener } from '@lib'; export default class SlashStartedListener extends BushListener { public constructor() { super('slashStarted', { emitter: 'commandHandler', - event: 'slashStarted' + event: 'slashStarted', + category: 'commands' }); } - exec(message: BushSlashMessage, command: BushCommand): void { - this.client.logger.info( + async exec([message, command]: BushCommandHandlerEvents['slashStarted']): Promise<unknown> { + return await this.client.logger.info( 'SlashCommand', `The <<${command.id}>> command was used by <<${message.author.tag}>> in ${ message.channel.type === 'DM' ? `their <<DMs>>` : `<<#${message.channel.name}>> in <<${message.guild?.name}>>` }.`, - true //// I don't want to spam the log channel when people use commands + true ); } } diff --git a/src/listeners/guild/syncUnban.ts b/src/listeners/guild/syncUnban.ts index aa148f9..c9ba0cb 100644 --- a/src/listeners/guild/syncUnban.ts +++ b/src/listeners/guild/syncUnban.ts @@ -1,5 +1,5 @@ -import { Ban, BushListener } from '@lib'; -import { Guild, User } from 'discord.js'; +import { ActivePunishment, ActivePunishmentType, BushListener } from '@lib'; +import { ClientEvents } from 'discord.js'; export default class SyncUnbanListener extends BushListener { public constructor() { @@ -9,11 +9,12 @@ export default class SyncUnbanListener extends BushListener { }); } - public async exec(guild: Guild, user: User): Promise<void> { - const bans = await Ban.findAll({ + public async exec([ban]: ClientEvents['guildBanRemove']): Promise<void> { + const bans = await ActivePunishment.findAll({ where: { - user: user.id, - guild: guild.id + user: ban.user, + guild: ban.guild, + type: ActivePunishmentType.BAN } }); for (const dbBan of bans) { diff --git a/src/listeners/message/level.ts b/src/listeners/message/level.ts index 1f57930..b06fdd2 100644 --- a/src/listeners/message/level.ts +++ b/src/listeners/message/level.ts @@ -1,5 +1,5 @@ import { BushListener, Level } from '@lib'; -import { Message } from 'discord.js'; +import { Message, MessageType } from 'discord.js'; export default class LevelListener extends BushListener { private levelCooldowns: Set<string> = new Set(); @@ -17,7 +17,8 @@ export default class LevelListener extends BushListener { if (message.util?.parsed?.command) return; if (this.levelCooldowns.has(`${message.guild.id}-${message.author.id}`)) return; if (this.blacklistedChannels.includes(message.channel.id)) return; - if (!['DEFAULT', 'REPLY'].includes(message.type)) return; //checks for join messages, slash commands, booster messages etc + const allowedMessageTypes: MessageType[] = ['DEFAULT', 'REPLY']; // this is so ts will yell at me when discord.js makes some unnecessary breaking change + if (!allowedMessageTypes.includes(message.type)) return; //checks for join messages, slash commands, booster messages etc const [user] = await Level.findOrBuild({ where: { user: message.author.id, diff --git a/src/listeners/other/consoleListener.ts b/src/listeners/other/consoleListener.ts index ef1efd5..90f9871 100644 --- a/src/listeners/other/consoleListener.ts +++ b/src/listeners/other/consoleListener.ts @@ -1,6 +1,8 @@ /* eslint-disable @typescript-eslint/no-var-requires */ /* eslint-disable @typescript-eslint/no-unused-vars */ import { BushListener } from '@lib'; +import { exec } from 'child_process'; +import { promisify } from 'util'; export default class ConsoleListener extends BushListener { public constructor() { @@ -12,10 +14,12 @@ export default class ConsoleListener extends BushListener { public async exec(line: string): Promise<void> { if (line.startsWith('eval ') || line.startsWith('ev ')) { - const bot = this.client, + const + sh = promisify(exec), + bot = this.client, config = this.client.config, client = this.client, - { Ban, Global, Guild, Level, ModLog, StickyRole } = await import('@lib'), + { ActivePunishment, Global, Guild, Level, ModLog, StickyRole } = await import('@lib'), { ButtonInteraction, Collector, @@ -26,12 +30,14 @@ export default class ConsoleListener extends BushListener { MessageAttachment, MessageButton, MessageCollector, - MessageComponentInteractionCollector, + InteractionCollector, MessageEmbed, MessageSelectMenu, ReactionCollector, - Util - } = require('discord.js'); + Util, + Collection + } = await import('discord.js'), + { Canvas } = await import('node-canvas'); try { const input = line.replace('eval ', '').replace('ev ', ''); let output = eval(input); diff --git a/src/tasks/removeExpiredPunishements.ts b/src/tasks/removeExpiredPunishements.ts new file mode 100644 index 0000000..d0220ba --- /dev/null +++ b/src/tasks/removeExpiredPunishements.ts @@ -0,0 +1,74 @@ +import { BushGuild, BushGuildMember, BushTask } from '@lib'; +import { Op } from 'sequelize'; +import { ActivePunishment, ActivePunishmentType } from '../lib/models/ActivePunishment'; + +export default class RemoveExpiredPunishmentsTask extends BushTask { + public constructor() { + super('removeExpiredPunishments', { + delay: 15_000, // 15 seconds + runOnStart: true + }); + } + async exec(): Promise<void> { + const expiredEntries = await ActivePunishment.findAll({ + where: { + [Op.and]: [ + { + expires: { + [Op.lt]: new Date() // Find all rows with an expiry date before now + } + } + ] + } + }); + + this.client.logger.verbose( + `removeExpiredPunishments`, + `Queried punishments, found <<${expiredEntries.length}>> expired punishments.` + ); + + for (const entry of expiredEntries) { + const guild = this.client.guilds.cache.get(entry.guild) as BushGuild; + const member = guild.members.cache.get(entry.user) as BushGuildMember; + + if (!guild) { + await entry.destroy(); + continue; + } + + switch (entry.type) { + case ActivePunishmentType.BAN: { + const result = await guild.unban({ user: entry.user, reason: 'Punishment expired.' }); + if (['success', 'user not banned'].includes(result)) await entry.destroy(); + else throw result; + this.client.logger.verbose(`removeExpiredPunishments`, `Unbanned ${entry.user}.`); + break; + } + case ActivePunishmentType.BLOCK: { + //todo + break; + } + case ActivePunishmentType.MUTE: { + const result = await member.unmute({ reason: 'Punishment expired.' }); + if (['success', 'failed to dm'].includes(result)) await entry.destroy(); + else throw result; + this.client.logger.verbose(`removeExpiredPunishments`, `Unmuted ${entry.user}.`); + break; + } + case ActivePunishmentType.ROLE: { + const role = guild?.roles?.cache?.get(entry.extraInfo); + const result = await member.removeRole({ + reason: 'Punishment expired.', + role: role, + addToModlog: true + }); + + if (['success', 'failed to dm'].includes(result)) await entry.destroy(); + else throw result; + this.client.logger.verbose(`removeExpiredPunishments`, `Removed a punishment role from ${entry.user}.`); + break; + } + } + } + } +} diff --git a/src/tasks/removePunishmentRole.ts b/src/tasks/removePunishmentRole.ts deleted file mode 100644 index 9830338..0000000 --- a/src/tasks/removePunishmentRole.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { BushGuildMember, BushTask } from '@lib'; - -export default class RemovePunishmentRole extends BushTask { - public constructor() { - super('removePunishmentRole', { - delay: 30_000, // 1/2 min - runOnStart: true - }); - } - async exec(): Promise<void> { - const expiredEntries = await this.client.util.findExpiredEntries('role'); - this.client.logger.verbose( - `RemovePunishmentRoleTask`, - `Queried punishment roles, found <<${expiredEntries.length}>> expired punishment roles.` - ); - - for (const entry of expiredEntries) { - const guild = this.client.guilds.cache.get(entry.guild); - const role = guild?.roles?.cache?.get(entry.role); - if (!guild || !role) { - await entry.destroy(); - continue; - } - - const member = guild.members.cache.get(entry.user) as BushGuildMember; - const result = await member.removeRole({ - reason: 'Punishment expired.', - role: role, - addToModlog: true - }); - if (['success', 'failed to dm'].includes(result)) await entry.destroy(); - else throw result; - - this.client.logger.verbose(`RemovePunishmentRoleTask`, `Removed a punishment role from ${entry.user}.`); - } - } -} diff --git a/src/tasks/unban.ts b/src/tasks/unban.ts deleted file mode 100644 index 136e6c2..0000000 --- a/src/tasks/unban.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { BushGuild, BushTask } from '@lib'; - -export default class UnbanTask extends BushTask { - public constructor() { - super('unban', { - delay: 30_000, // 1/2 min - runOnStart: true - }); - } - async exec(): Promise<void> { - const rows = await this.client.util.findExpiredEntries('mute'); - this.client.logger.verbose(`UnbanTask`, `Queried bans, found <<${rows.length}>> expired bans.`); - - for (const row of rows) { - const guild = this.client.guilds.cache.get(row.guild) as BushGuild; - if (!guild) { - await row.destroy(); - continue; - } - - const result = await guild.unban({ user: row.user, reason: 'Punishment expired.' }); - if (['success', 'user not banned'].includes(result)) await row.destroy(); - else throw result; - this.client.logger.verbose(`UnbanTask`, `Unbanned ${row.user}`); - } - } -} diff --git a/src/tasks/unmute.ts b/src/tasks/unmute.ts deleted file mode 100644 index c61c6e9..0000000 --- a/src/tasks/unmute.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { BushGuildMember, BushTask, Mute } from '@lib'; -import { Op } from 'sequelize'; - -export default class UnmuteTask extends BushTask { - public constructor() { - super('unmute', { - delay: 30_000, // 1/2 min - runOnStart: true - }); - } - async exec(): Promise<void> { - const rows = await Mute.findAll({ - where: { - [Op.and]: [ - { - expires: { - [Op.lt]: new Date() // Find all rows with an expiry date before now - } - } - ] - } - }); - this.client.logger.verbose(`UnmuteTask`, `Queried mutes, found <<${rows.length}>> expired mutes.`); - for (const row of rows) { - const guild = this.client.guilds.cache.get(row.guild); - if (!guild) { - await row.destroy(); - continue; - } - - const member = guild.members.cache.get(row.user) as BushGuildMember; - const result = await member.unmute({ reason: 'Punishment expired.' }); - if (['success', 'failed to dm'].includes(result)) await row.destroy(); - else throw result; - - this.client.logger.verbose(`UnmuteTask`, `Unmuted ${row.user}`); - } - } -} @@ -14,10 +14,10 @@ __metadata: languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/helper-validator-identifier@npm:7.14.5" - checksum: 6366bceab4498785defc083a1bd96344f788d90a1aa7a6f18d6813c1d3d134640bfc05690453c0b79bbfc820472cf5b29110dfddaca1f8e2763dfe1bd5df0b88 +"@babel/helper-validator-identifier@npm:^7.14.5, @babel/helper-validator-identifier@npm:^7.14.8": + version: 7.14.8 + resolution: "@babel/helper-validator-identifier@npm:7.14.8" + checksum: f21ad9a9f0a66a02e0e5f62d505cbeb9e01a7ac5bd34be0af9f916f0b6d8d40718efaf51b656b41759e3454703090b4d386105f1f97f6598ee5a3f8eb98adc6a languageName: node linkType: hard @@ -33,21 +33,21 @@ __metadata: linkType: hard "@babel/parser@npm:^7.0.0": - version: 7.14.7 - resolution: "@babel/parser@npm:7.14.7" + version: 7.14.8 + resolution: "@babel/parser@npm:7.14.8" bin: parser: ./bin/babel-parser.js - checksum: 0d7acc8cf9c19ccd0e80ab0608953f32f4375f3867c080211270e7bb4bb94c551fd1fc3f49b3cc92a4eec356cf507801f5c93c4c72996968bdc4c28815fe0550 + checksum: 9e532b2bbe690fff8cdaf8c25cfecb684ebe9e9d50d30cd775852dd711649ddb964368b26fda55786404fadf500f944043fb0f731b765104ad857d677dd29ce5 languageName: node linkType: hard "@babel/types@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/types@npm:7.14.5" + version: 7.14.8 + resolution: "@babel/types@npm:7.14.8" dependencies: - "@babel/helper-validator-identifier": ^7.14.5 + "@babel/helper-validator-identifier": ^7.14.8 to-fast-properties: ^2.0.0 - checksum: 7c1ab6e8bdf438d44236034cab10f7d0f1971179bc405dca26733a9b89dd87dd692dc49a238a7495075bc41a9a17fb6f08b4d1da45ea6ddcce1e5c8593574aea + checksum: d4ebd2e0e52f05cbcb3ded434d9fb49db73c239d98c4f7bd27beaf32fcd7c81aa30618237e87d53505d5e65fd20d688cb4237b6fa927a04831129a6044f2e4b5 languageName: node linkType: hard @@ -319,19 +319,19 @@ __metadata: linkType: hard "@types/node-fetch@npm:^2": - version: 2.5.11 - resolution: "@types/node-fetch@npm:2.5.11" + version: 2.5.12 + resolution: "@types/node-fetch@npm:2.5.12" dependencies: "@types/node": "*" form-data: ^3.0.0 - checksum: a52ee9a205ce3130404a1c8eb0a163aa013fb94c5c93150735dda55bd4d21a556713834b11f6f031721ad7c82d9d7f77d45436010cefc11e851f518dfeeaca3e + checksum: ad63c85ba6a9477b8e057ec8682257738130d98e8ece4e31141789bd99df9d9147985cc8bc0cb5c8983ed5aa6bb95d46df23d1e055f4ad5cf8b82fc69cf626c7 languageName: node linkType: hard "@types/node@npm:*": - version: 16.3.3 - resolution: "@types/node@npm:16.3.3" - checksum: fa885b835e57a4a2fd15571e5cbfe361d4ac48278196416aa2690ebdfb118a116249dd81475078c61fbf2d95920324f8f3a66ae7f19fac424ae74ab87a41c1e4 + version: 16.4.1 + resolution: "@types/node@npm:16.4.1" + checksum: 6cff78c802a1efecc900506a468a9bdaa321c7132a05e87552ab710f3d3a5cd230308317634f94b8db4833c66c72a765b28670d5ccf8c7c5a7363fcce32d1b1e languageName: node linkType: hard @@ -390,20 +390,20 @@ __metadata: linkType: hard "@types/ws@npm:^7.4.4, @types/ws@npm:^7.4.5": - version: 7.4.6 - resolution: "@types/ws@npm:7.4.6" + version: 7.4.7 + resolution: "@types/ws@npm:7.4.7" dependencies: "@types/node": "*" - checksum: 500c2f7edcb5bbcb34ecf535c6163aad6c901a04d806089931125eecd630e9f30e41a167a4b9929aaaae9658d4fc4146f3a29762857f0d18a4038b6641ec36f8 + checksum: b4c9b8ad209620c9b21e78314ce4ff07515c0cadab9af101c1651e7bfb992d7fd933bd8b9c99d110738fd6db523ed15f82f29f50b45510288da72e964dedb1a3 languageName: node linkType: hard "@typescript-eslint/eslint-plugin@npm:^4.14.1": - version: 4.28.3 - resolution: "@typescript-eslint/eslint-plugin@npm:4.28.3" + version: 4.28.4 + resolution: "@typescript-eslint/eslint-plugin@npm:4.28.4" dependencies: - "@typescript-eslint/experimental-utils": 4.28.3 - "@typescript-eslint/scope-manager": 4.28.3 + "@typescript-eslint/experimental-utils": 4.28.4 + "@typescript-eslint/scope-manager": 4.28.4 debug: ^4.3.1 functional-red-black-tree: ^1.0.1 regexpp: ^3.1.0 @@ -415,66 +415,66 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 2ac7113dbb0916ee911c3cee552b31b82c3c286ce4be1d2b5b8fbbe64eb05eb8c5187a64aba2fc5d46f2bc2d391887b33e00edbb65f2f25f41342efa346776ef + checksum: 8de0301888e7308bca45c1cbfb28693b365780e85e0d7810ec9f004fc3f81b90871d2a55ad71d5865a93ce5d382e13ca9bbdc43d4234e0e409ef65f1348fe864 languageName: node linkType: hard -"@typescript-eslint/experimental-utils@npm:4.28.3": - version: 4.28.3 - resolution: "@typescript-eslint/experimental-utils@npm:4.28.3" +"@typescript-eslint/experimental-utils@npm:4.28.4": + version: 4.28.4 + resolution: "@typescript-eslint/experimental-utils@npm:4.28.4" dependencies: "@types/json-schema": ^7.0.7 - "@typescript-eslint/scope-manager": 4.28.3 - "@typescript-eslint/types": 4.28.3 - "@typescript-eslint/typescript-estree": 4.28.3 + "@typescript-eslint/scope-manager": 4.28.4 + "@typescript-eslint/types": 4.28.4 + "@typescript-eslint/typescript-estree": 4.28.4 eslint-scope: ^5.1.1 eslint-utils: ^3.0.0 peerDependencies: eslint: "*" - checksum: 09b1b196318acbf6efbb9ea93fc73b18a77c1fc04efb24bc77d941666b5a0c48828f2d788079bdfd340828045d15054a4c95fba5367e7c8b1fe53de53736a1db + checksum: 71eb19a55efb32b28f2cf130c6a9689ac9df18d41ac0eb0351f1bd47c2ef39e8acbc20d743830ecd2f60d2b18f38a45a588f1b6e292cacf5e55b5f57c2043583 languageName: node linkType: hard "@typescript-eslint/parser@npm:^4.14.1": - version: 4.28.3 - resolution: "@typescript-eslint/parser@npm:4.28.3" + version: 4.28.4 + resolution: "@typescript-eslint/parser@npm:4.28.4" dependencies: - "@typescript-eslint/scope-manager": 4.28.3 - "@typescript-eslint/types": 4.28.3 - "@typescript-eslint/typescript-estree": 4.28.3 + "@typescript-eslint/scope-manager": 4.28.4 + "@typescript-eslint/types": 4.28.4 + "@typescript-eslint/typescript-estree": 4.28.4 debug: ^4.3.1 peerDependencies: eslint: ^5.0.0 || ^6.0.0 || ^7.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 3a5d64237e7085235f3b27eece73105bd5a7b51f17c868c086a6062bd8ab6901c908270d41c055f44d9f440c6a1bb3203429693a07436905cc60d3a03cd361e9 + checksum: 838c4fed7ad14652edd02a3649a4da2c2a0f8c3e7496657f573791114c9e0aa0278163350b349e722b2d414080c108d18e9c6571c110b229bb17ff089c8ebda3 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:4.28.3": - version: 4.28.3 - resolution: "@typescript-eslint/scope-manager@npm:4.28.3" +"@typescript-eslint/scope-manager@npm:4.28.4": + version: 4.28.4 + resolution: "@typescript-eslint/scope-manager@npm:4.28.4" dependencies: - "@typescript-eslint/types": 4.28.3 - "@typescript-eslint/visitor-keys": 4.28.3 - checksum: 9ffb955581311ef46d7aebf23ac544c96164bac00f7657f963680ba7b239b1c021733318ea22ca2965ff9b8f2798dff8ae5d7add0dae4207d3dad86d5e4f0f1f + "@typescript-eslint/types": 4.28.4 + "@typescript-eslint/visitor-keys": 4.28.4 + checksum: 75ff460989d334dcef513b8ea06d8c9039731092f65790abee90f4251d1f145f9496894d5fe076b1f26612a1dce29acbddfdb73472d49fa8a0dd63451a8eb2b5 languageName: node linkType: hard -"@typescript-eslint/types@npm:4.28.3": - version: 4.28.3 - resolution: "@typescript-eslint/types@npm:4.28.3" - checksum: 15f052f92ee429056e7bdd4b0ff3750d72a6ab6c202a46f394dcd7490da7f670d7b516fc5febc96332cced39fdf3fd20c4893ee58fb93ce9b58e2f1e1766d7bb +"@typescript-eslint/types@npm:4.28.4": + version: 4.28.4 + resolution: "@typescript-eslint/types@npm:4.28.4" + checksum: be565692cc42ce387fe8a1cc9ad44edaa8dea45728a33f3ad8cc8ee664bbd3ef220d529fdc7a2165b60cd1eb5280b767fbb7f351e56f2c0b90c99d2ccf24ad06 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:4.28.3, @typescript-eslint/typescript-estree@npm:^4.8.2": - version: 4.28.3 - resolution: "@typescript-eslint/typescript-estree@npm:4.28.3" +"@typescript-eslint/typescript-estree@npm:4.28.4, @typescript-eslint/typescript-estree@npm:^4.8.2": + version: 4.28.4 + resolution: "@typescript-eslint/typescript-estree@npm:4.28.4" dependencies: - "@typescript-eslint/types": 4.28.3 - "@typescript-eslint/visitor-keys": 4.28.3 + "@typescript-eslint/types": 4.28.4 + "@typescript-eslint/visitor-keys": 4.28.4 debug: ^4.3.1 globby: ^11.0.3 is-glob: ^4.0.1 @@ -483,17 +483,17 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 674cdd5e3c24306f906d6479ede454d5f5a2100e22cd5aa08f9bc27953cdb4930384ad3b4434937e31e8e92e6b3cc867f8d56c3b65e2254f7042662deafef583 + checksum: 526f41028d63ddb506586abe6ca5ffd6cee54b2773fc70e803d61988682f4528228bef8a6773ea5219e7412887e4c74732736620a4e904e51239b7acab4441b9 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:4.28.3": - version: 4.28.3 - resolution: "@typescript-eslint/visitor-keys@npm:4.28.3" +"@typescript-eslint/visitor-keys@npm:4.28.4": + version: 4.28.4 + resolution: "@typescript-eslint/visitor-keys@npm:4.28.4" dependencies: - "@typescript-eslint/types": 4.28.3 + "@typescript-eslint/types": 4.28.4 eslint-visitor-keys: ^2.0.0 - checksum: b570740ae16901df85febde13b5e34b95dfa13fc51b035875bc087fef356f2db1284ff045812ace06b0e8f821171a7ddaf7606cee672d35df486989e79a0c7df + checksum: d0b359dc0aaf0f6c3396bf7bee31f9ec7a6d90b7f69890478a002af6eb9ab4a7be466b4ddb050af87ce5f1d01384ce41fd976d472cbe587787b2ee21d977e8f6 languageName: node linkType: hard @@ -804,7 +804,7 @@ __metadata: chalk: ^4.1.1 common-tags: ^1.8.0 discord-akairo: NotEnoughUpdates/discord-akairo - discord-api-types: 0.19.0-next.f393ba520d7d6d2aacaca7b3ca5d355fab614f6e + discord-api-types: 0.19.0 discord.js: NotEnoughUpdates/discord.js discord.js-minesweeper: ^1.0.6 esbuild: ^0.12.11 @@ -1328,15 +1328,15 @@ __metadata: discord-akairo@NotEnoughUpdates/discord-akairo: version: 8.2.2 - resolution: "discord-akairo@https://github.com/NotEnoughUpdates/discord-akairo.git#commit=7164ae3af00266b0ac357e3e65ef5d4101308c40" - checksum: 63a85f0de4d018b83ecd537b42dadafdc471d90c67559281ea8e202527f4b11eef6a1b88cb43b229e883f9ed52041994df7a5653077ba8e3dae6bf8fea1c9c75 + resolution: "discord-akairo@https://github.com/NotEnoughUpdates/discord-akairo.git#commit=f31c8e8b27e1ca8c918cf10e720d36ba31fdd7dc" + checksum: 193b6ca28637f542a1ee10090e3b54a83c36fdd188f746eb86881dee94b8b5d85c74a544c6febba274e49898f504ea84e224fa82ac41e60b06a98c8744c1258e languageName: node linkType: hard -"discord-api-types@npm:0.19.0-next.f393ba520d7d6d2aacaca7b3ca5d355fab614f6e, discord-api-types@npm:^0.19.0-next.f393ba520d7d6d2aacaca7b3ca5d355fab614f6e": - version: 0.19.0-next.f393ba520d7d6d2aacaca7b3ca5d355fab614f6e - resolution: "discord-api-types@npm:0.19.0-next.f393ba520d7d6d2aacaca7b3ca5d355fab614f6e" - checksum: 0b3f2cad00edd005bf6542bb6ce712777b09e917f955f8d4f69a292ed5da2f60721e709cc11ab226879658e839056e1aff16d724b3b1c6689217eb34c2b4d3f5 +"discord-api-types@npm:0.19.0, discord-api-types@npm:^0.19.0": + version: 0.19.0 + resolution: "discord-api-types@npm:0.19.0" + checksum: 83d9363772a0ac0fcfa9df61da1c510c5427c2d82cc4b1c2e0a8ab50c31b2ae297a416cd1559b21b039dcc8065e5dca962dbac12522ee5e3447e9f4ebcb8a846 languageName: node linkType: hard @@ -1356,7 +1356,7 @@ discord-akairo@NotEnoughUpdates/discord-akairo: discord.js@NotEnoughUpdates/discord.js: version: 13.0.0-dev - resolution: "discord.js@https://github.com/NotEnoughUpdates/discord.js.git#commit=8551402ddbac89a53133385f953c595e8be16d98" + resolution: "discord.js@https://github.com/NotEnoughUpdates/discord.js.git#commit=d0edf2a15b62e3b739d3f0ee8fc4ffd9c569fce5" dependencies: "@discordjs/builders": ^0.2.0 "@discordjs/collection": ^0.1.6 @@ -1364,10 +1364,10 @@ discord.js@NotEnoughUpdates/discord.js: "@sapphire/async-queue": ^1.1.4 "@types/ws": ^7.4.5 abort-controller: ^3.0.0 - discord-api-types: ^0.19.0-next.f393ba520d7d6d2aacaca7b3ca5d355fab614f6e + discord-api-types: ^0.19.0 node-fetch: ^2.6.1 ws: ^7.5.1 - checksum: f5a41b02faa95d7d5efafd734c8af9b063badcce257fe87c3399fcafab083026ba2334793d46d01553670cd57081a4650c68a6c05a417bf2640591b05c54f82c + checksum: 44a2c3f49b0a553af63b80dad1b6c5df2ae5f289dd61b980a1a342d446727d07f0703750e92d932d04430f74ed281a5d7d11dd0b2499045e15aa9b65ef7c6294 languageName: node linkType: hard @@ -3104,13 +3104,13 @@ discord.js@NotEnoughUpdates/discord.js: linkType: hard "postcss@npm:^8.1.7, postcss@npm:^8.2.13": - version: 8.3.5 - resolution: "postcss@npm:8.3.5" + version: 8.3.6 + resolution: "postcss@npm:8.3.6" dependencies: colorette: ^1.2.2 nanoid: ^3.1.23 source-map-js: ^0.6.2 - checksum: c73fc4825ed27396d453a942628cd8e34dd43c11b724f43f65f376d3900037736013b6446f1d9947ce5a847837cf96649e9a3f200ca2bd94a884e91e56ee1ceb + checksum: ff55b91bea21f42c2a94d77fd05c3f66dd15889c68506cf1dbb9cdee8c3b9e9d0e219bcbc6e61a107bd63e3cac0670176486e2a5794c106a4e1b9babceb79317 languageName: node linkType: hard @@ -3383,9 +3383,9 @@ discord.js@NotEnoughUpdates/discord.js: linkType: hard "resolve-alpn@npm:^1.0.0": - version: 1.1.2 - resolution: "resolve-alpn@npm:1.1.2" - checksum: 99ffb597caf1cbe811a6cab283a9a0cd74198e4439c8c91f444d426a81b880e29829c7293b349f3647fd82b226a63424bc492d59ef7d8070a180e2c13f402721 + version: 1.2.0 + resolution: "resolve-alpn@npm:1.2.0" + checksum: a38b5bf2084d384586fe15b31735396cff4640cbe137c87ffd1dcc94dcdc0c743e6875ec4baa7a9eed460355a46e3f9ebafa4cdbb8122264ed5f4e3260f69d0c languageName: node linkType: hard @@ -3889,8 +3889,8 @@ resolve@^1.19.0: linkType: hard "tar@npm:^6.0.2, tar@npm:^6.1.0": - version: 6.1.0 - resolution: "tar@npm:6.1.0" + version: 6.1.1 + resolution: "tar@npm:6.1.1" dependencies: chownr: ^2.0.0 fs-minipass: ^2.0.0 @@ -3898,7 +3898,7 @@ resolve@^1.19.0: minizlib: ^2.1.1 mkdirp: ^1.0.3 yallist: ^4.0.0 - checksum: 0638a405b625263e0c47e97f0ea5e871b1a549da4593e31bf1792bcc83d97c28065ed172669f186744526637ea627a424d519ddd99f3fd52b17ac75f58f43519 + checksum: ffd7d67d5bfa6f8ef0024c0c7c6da575f2257988f022e61299372db1d50b78868cfaf04d13abe41f480d593ace5628b44d2998ac7b0bda883d1385b578877514 languageName: node linkType: hard |