aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--package.json10
-rw-r--r--src/commands/moderation/ban.ts13
-rw-r--r--src/commands/moderation/block.ts15
-rw-r--r--src/commands/moderation/evidence.ts4
-rw-r--r--src/commands/moderation/hideCase.ts4
-rw-r--r--src/commands/moderation/kick.ts22
-rw-r--r--src/commands/moderation/mute.ts19
-rw-r--r--src/commands/moderation/role.ts30
-rw-r--r--src/commands/moderation/timeout.ts22
-rw-r--r--src/commands/moderation/unban.ts23
-rw-r--r--src/commands/moderation/unblock.ts15
-rw-r--r--src/commands/moderation/unmute.ts19
-rw-r--r--src/commands/moderation/untimeout.ts19
-rw-r--r--src/commands/moderation/warn.ts8
-rw-r--r--src/lib/common/util/Moderation.ts62
-rw-r--r--src/lib/extensions/discord-akairo/BushClientUtil.ts4
-rw-r--r--src/lib/extensions/discord.js/BushButtonInteraction.ts2
-rw-r--r--src/lib/extensions/discord.js/BushClientEvents.d.ts2
-rw-r--r--src/lib/extensions/discord.js/BushCommandInteraction.ts2
-rw-r--r--src/lib/extensions/discord.js/BushGuild.ts149
-rw-r--r--src/lib/extensions/discord.js/BushGuildMember.ts379
-rw-r--r--src/lib/extensions/discord.js/BushSelectMenuInteraction.ts2
-rw-r--r--yarn.lock186
23 files changed, 625 insertions, 386 deletions
diff --git a/package.json b/package.json
index 0bc6679..18a87e9 100644
--- a/package.json
+++ b/package.json
@@ -78,7 +78,7 @@
"prettier": "^2.5.1",
"pretty-bytes": "^5.6.0",
"rimraf": "^3.0.2",
- "sequelize": "^6.12.4",
+ "sequelize": "^6.12.5",
"source-map-support": "^0.5.21",
"tinycolor2": "^1.4.2",
"tslib": "^2.3.1",
@@ -89,7 +89,7 @@
"@types/eslint": "^8",
"@types/express": "^4.17.13",
"@types/lodash": "^4.14.178",
- "@types/node": "^17.0.5",
+ "@types/node": "^17.0.8",
"@types/node-os-utils": "^1.2.0",
"@types/numeral": "^2.0.2",
"@types/pg": "^8",
@@ -98,10 +98,10 @@
"@types/source-map-support": "^0",
"@types/tinycolor2": "^1.4.3",
"@types/validator": "^13.7.1",
- "@typescript-eslint/eslint-plugin": "^5.8.1",
- "@typescript-eslint/parser": "^5.8.1",
+ "@typescript-eslint/eslint-plugin": "^5.9.0",
+ "@typescript-eslint/parser": "^5.9.0",
"discord-api-types": "0.26.0",
- "eslint": "^8.5.0",
+ "eslint": "^8.6.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-deprecation": "^1.3.2"
},
diff --git a/src/commands/moderation/ban.ts b/src/commands/moderation/ban.ts
index f21ccdc..7f0b91f 100644
--- a/src/commands/moderation/ban.ts
+++ b/src/commands/moderation/ban.ts
@@ -1,5 +1,6 @@
import {
AllowedMentions,
+ banResponse,
BushCommand,
Moderation,
type ArgType,
@@ -126,17 +127,17 @@ export default class BanCommand extends BushCommand {
const responseMessage = (): string => {
const victim = util.format.input(user.tag);
switch (responseCode) {
- case 'missing permissions':
+ case banResponse.MISSING_PERMISSIONS:
return `${util.emojis.error} Could not ban ${victim} because I am missing the **Ban Members** permission.`;
- case 'error banning':
+ case banResponse.ACTION_ERROR:
return `${util.emojis.error} An error occurred while trying to ban ${victim}.`;
- case 'error creating ban entry':
+ case banResponse.PUNISHMENT_ENTRY_ADD_ERROR:
return `${util.emojis.error} While banning ${victim}, there was an error creating a ban entry, please report this to my developers.`;
- case 'error creating modlog entry':
+ case banResponse.MODLOG_ERROR:
return `${util.emojis.error} While banning ${victim}, there was an error creating a modlog entry, please report this to my developers.`;
- case 'failed to dm':
+ case banResponse.DM_ERROR:
return `${util.emojis.warn} Banned ${victim} however I could not send them a dm.`;
- case 'success':
+ case banResponse.SUCCESS:
return `${util.emojis.success} Successfully banned ${victim}.`;
}
};
diff --git a/src/commands/moderation/block.ts b/src/commands/moderation/block.ts
index d53ffd5..57f909a 100644
--- a/src/commands/moderation/block.ts
+++ b/src/commands/moderation/block.ts
@@ -1,5 +1,6 @@
import {
AllowedMentions,
+ blockResponse,
BushCommand,
BushTextChannel,
BushThreadChannel,
@@ -105,19 +106,19 @@ export default class BlockCommand extends BushCommand {
const responseMessage = (): string => {
const victim = util.format.input(member.user.tag);
switch (responseCode) {
- case 'missing permissions':
+ case blockResponse.MISSING_PERMISSIONS:
return `${util.emojis.error} Could not block ${victim} because I am missing the **Manage Channel** permission.`;
- case 'invalid channel':
+ case blockResponse.INVALID_CHANNEL:
return `${util.emojis.error} Could not block ${victim}, you can only block users in text or thread channels.`;
- case 'error blocking':
+ case blockResponse.ACTION_ERROR:
return `${util.emojis.error} An unknown error occurred while trying to block ${victim}.`;
- case 'error creating modlog entry':
+ case blockResponse.MODLOG_ERROR:
return `${util.emojis.error} There was an error creating a modlog entry, please report this to my developers.`;
- case 'error creating block entry':
+ case blockResponse.PUNISHMENT_ENTRY_ADD_ERROR:
return `${util.emojis.error} There was an error creating a punishment entry, please report this to my developers.`;
- case 'failed to dm':
+ case blockResponse.DM_ERROR:
return `${util.emojis.warn} Blocked ${victim} however I could not send them a dm.`;
- case 'success':
+ case blockResponse.SUCCESS:
return `${util.emojis.success} Successfully blocked ${victim}.`;
}
};
diff --git a/src/commands/moderation/evidence.ts b/src/commands/moderation/evidence.ts
index 714a2e5..cff63ed 100644
--- a/src/commands/moderation/evidence.ts
+++ b/src/commands/moderation/evidence.ts
@@ -7,8 +7,8 @@ export default class EvidenceCommand extends BushCommand {
aliases: ['evidence'],
category: 'moderation',
description: 'Add evidence to a modlog case.',
- usage: ['evidence <case_id> <evidence>'],
- examples: ['evidence 9210b1ea-91f5-4ea2-801b-02b394469c77 was spamming in #general'],
+ usage: ['evidence <caseId> <evidence>'],
+ examples: ['evidence IgQvFpzgIKJ77mZ62TEuG was spamming in #general'],
args: [
{
id: 'case_id',
diff --git a/src/commands/moderation/hideCase.ts b/src/commands/moderation/hideCase.ts
index 04160fd..e12d8c8 100644
--- a/src/commands/moderation/hideCase.ts
+++ b/src/commands/moderation/hideCase.ts
@@ -6,8 +6,8 @@ export default class HideCaseCommand extends BushCommand {
aliases: ['hide-case', 'hide_case', 'show-case', 'show_case', 'cover-up-mod-abuse', 'cover_up_mod_abuse'],
category: 'moderation',
description: 'Hide a particular modlog case from the modlog command unless the `--hidden` flag is specified',
- usage: ['hide-case <case_id>'],
- examples: ['hide-case 9210b1ea-91f5-4ea2-801b-02b394469c77'],
+ usage: ['hide-case <caseId>'],
+ examples: ['hide-case Xurm---HdRyHlrKLsOcIO'],
args: [
{
id: 'case_id',
diff --git a/src/commands/moderation/kick.ts b/src/commands/moderation/kick.ts
index 6d96ae9..af486ac 100644
--- a/src/commands/moderation/kick.ts
+++ b/src/commands/moderation/kick.ts
@@ -1,4 +1,12 @@
-import { AllowedMentions, BushCommand, Moderation, type ArgType, type BushMessage, type BushSlashMessage } from '#lib';
+import {
+ AllowedMentions,
+ BushCommand,
+ kickResponse,
+ Moderation,
+ type ArgType,
+ type BushMessage,
+ type BushSlashMessage
+} from '#lib';
export default class KickCommand extends BushCommand {
public constructor() {
@@ -68,15 +76,15 @@ export default class KickCommand extends BushCommand {
const responseMessage = (): string => {
const victim = util.format.input(member.user.tag);
switch (responseCode) {
- case 'missing permissions':
- return `${util.emojis.error} Could not kick ${victim} because I am missing the \`Kick Members\` permission.`;
- case 'error kicking':
+ case kickResponse.MISSING_PERMISSIONS:
+ return `${util.emojis.error} Could not kick ${victim} because I am missing the **Kick Members** permission.`;
+ case kickResponse.ACTION_ERROR:
return `${util.emojis.error} An error occurred while trying to kick ${victim}.`;
- case 'error creating modlog entry':
+ case kickResponse.MODLOG_ERROR:
return `${util.emojis.error} While muting ${victim}, there was an error creating a modlog entry, please report this to my developers.`;
- case 'failed to dm':
+ case kickResponse.DM_ERROR:
return `${util.emojis.warn} Kicked ${victim} however I could not send them a dm.`;
- case 'success':
+ case kickResponse.SUCCESS:
return `${util.emojis.success} Successfully kicked ${victim}.`;
}
};
diff --git a/src/commands/moderation/mute.ts b/src/commands/moderation/mute.ts
index e731e30..40e13e7 100644
--- a/src/commands/moderation/mute.ts
+++ b/src/commands/moderation/mute.ts
@@ -2,6 +2,7 @@ import {
AllowedMentions,
BushCommand,
Moderation,
+ muteResponse,
type ArgType,
type BushMessage,
type BushSlashMessage,
@@ -99,23 +100,23 @@ export default class MuteCommand extends BushCommand {
const prefix = util.prefix(message);
const victim = util.format.input(member.user.tag);
switch (responseCode) {
- case 'missing permissions':
+ case muteResponse.MISSING_PERMISSIONS:
return `${util.emojis.error} Could not mute ${victim} because I am missing the **Manage Roles** permission.`;
- case 'no mute role':
+ case muteResponse.NO_MUTE_ROLE:
return `${util.emojis.error} Could not mute ${victim}, you must set a mute role with \`${prefix}config muteRole\`.`;
- case 'invalid mute role':
+ case muteResponse.MUTE_ROLE_INVALID:
return `${util.emojis.error} Could not mute ${victim} because the current mute role no longer exists. Please set a new mute role with \`${prefix}config muteRole\`.`;
- case 'mute role not manageable':
+ case muteResponse.MUTE_ROLE_NOT_MANAGEABLE:
return `${util.emojis.error} Could not mute ${victim} because I cannot assign the current mute role, either change the role's position or set a new mute role with \`${prefix}config muteRole\`.`;
- case 'error giving mute role':
+ case muteResponse.ACTION_ERROR:
return `${util.emojis.error} Could not mute ${victim}, there was an error assigning them the mute role.`;
- case 'error creating modlog entry':
+ case muteResponse.MODLOG_ERROR:
return `${util.emojis.error} There was an error creating a modlog entry, please report this to my developers.`;
- case 'error creating mute entry':
+ case muteResponse.PUNISHMENT_ENTRY_ADD_ERROR:
return `${util.emojis.error} There was an error creating a punishment entry, please report this to my developers.`;
- case 'failed to dm':
+ case muteResponse.DM_ERROR:
return `${util.emojis.warn} Muted ${victim} however I could not send them a dm.`;
- case 'success':
+ case muteResponse.SUCCESS:
return `${util.emojis.success} Successfully muted ${victim}.`;
}
};
diff --git a/src/commands/moderation/role.ts b/src/commands/moderation/role.ts
index 6cb8d2f..f0d0448 100644
--- a/src/commands/moderation/role.ts
+++ b/src/commands/moderation/role.ts
@@ -1,4 +1,13 @@
-import { AllowedMentions, BushCommand, type ArgType, type BushMessage, type BushSlashMessage, type OptionalArgType } from '#lib';
+import {
+ addRoleResponse,
+ AllowedMentions,
+ BushCommand,
+ removeRoleResponse,
+ type ArgType,
+ type BushMessage,
+ type BushSlashMessage,
+ type OptionalArgType
+} from '#lib';
import { type ArgumentOptions, type Flag } from 'discord-akairo';
import { type Snowflake } from 'discord.js';
@@ -170,25 +179,26 @@ export default class RoleCommand extends BushCommand {
const responseMessage = (): string => {
const victim = util.format.input(args.member.user.tag);
switch (responseCode) {
- case 'user hierarchy':
+ case addRoleResponse.MISSING_PERMISSIONS:
+ return `${util.emojis.error} I don't have the **Manage Roles** permission.`;
+ case addRoleResponse.USER_HIERARCHY:
return `${util.emojis.error} <@&${args.role.id}> is higher or equal to your highest role.`;
- case 'role managed':
+ case addRoleResponse.ROLE_MANAGED:
return `${util.emojis.error} <@&${args.role.id}> is managed by an integration and cannot be managed.`;
- case 'client hierarchy':
+ case addRoleResponse.CLIENT_HIERARCHY:
return `${util.emojis.error} <@&${args.role.id}> is higher or equal to my highest role.`;
- case 'error creating modlog entry':
+ case addRoleResponse.MODLOG_ERROR:
return `${util.emojis.error} There was an error creating a modlog entry, please report this to my developers.`;
- case 'error creating role entry':
- case 'error removing role entry':
+ case addRoleResponse.PUNISHMENT_ENTRY_ADD_ERROR:
+ case removeRoleResponse.PUNISHMENT_ENTRY_REMOVE_ERROR:
return `${util.emojis.error} There was an error ${
args.action === 'add' ? 'creating' : 'removing'
} a punishment entry, please report this to my developers.`;
- case 'error adding role':
- case 'error removing role':
+ case addRoleResponse.ACTION_ERROR:
return `${util.emojis.error} An error occurred while trying to ${args.action} <@&${args.role.id}> ${
args.action === 'add' ? 'to' : 'from'
} ${victim}.`;
- case 'success':
+ case addRoleResponse.SUCCESS:
return `${util.emojis.success} Successfully ${args.action === 'add' ? 'added' : 'removed'} <@&${args.role.id}> ${
args.action === 'add' ? 'to' : 'from'
} ${victim}${args.duration ? ` for ${util.humanizeDuration(args.duration)}` : ''}.`;
diff --git a/src/commands/moderation/timeout.ts b/src/commands/moderation/timeout.ts
index 3968bde..ec79271 100644
--- a/src/commands/moderation/timeout.ts
+++ b/src/commands/moderation/timeout.ts
@@ -1,4 +1,12 @@
-import { AllowedMentions, BushCommand, Moderation, type ArgType, type BushMessage, type BushSlashMessage } from '#lib';
+import {
+ AllowedMentions,
+ BushCommand,
+ Moderation,
+ timeoutResponse,
+ type ArgType,
+ type BushMessage,
+ type BushSlashMessage
+} from '#lib';
import assert from 'assert';
export default class TimeoutCommand extends BushCommand {
@@ -81,17 +89,17 @@ export default class TimeoutCommand extends BushCommand {
const responseMessage = (): string => {
const victim = util.format.input(member.user.tag);
switch (responseCode) {
- case 'missing permissions':
+ case timeoutResponse.MISSING_PERMISSIONS:
return `${util.emojis.error} Could not timeout ${victim} because I am missing the **Timeout Members** permission.`;
- case 'duration too long':
+ case timeoutResponse.INVALID_DURATION:
return `${util.emojis.error} The duration you specified is too long, the longest you can timeout someone for is 28 days.`;
- case 'error timing out':
+ case timeoutResponse.ACTION_ERROR:
return `${util.emojis.error} An unknown error occurred while trying to timeout ${victim}.`;
- case 'error creating modlog entry':
+ case timeoutResponse.MODLOG_ERROR:
return `${util.emojis.error} There was an error creating a modlog entry, please report this to my developers.`;
- case 'failed to dm':
+ case timeoutResponse.DM_ERROR:
return `${util.emojis.warn} Timed out ${victim} however I could not send them a dm.`;
- case 'success':
+ case timeoutResponse.SUCCESS:
return `${util.emojis.success} Successfully timed out ${victim}.`;
}
};
diff --git a/src/commands/moderation/unban.ts b/src/commands/moderation/unban.ts
index bbce4e0..c939792 100644
--- a/src/commands/moderation/unban.ts
+++ b/src/commands/moderation/unban.ts
@@ -1,4 +1,12 @@
-import { AllowedMentions, BushCommand, type ArgType, type BushMessage, type BushSlashMessage, type OptionalArgType } from '#lib';
+import {
+ AllowedMentions,
+ BushCommand,
+ unbanResponse,
+ type ArgType,
+ type BushMessage,
+ type BushSlashMessage,
+ type OptionalArgType
+} from '#lib';
export default class UnbanCommand extends BushCommand {
public constructor() {
@@ -47,17 +55,18 @@ export default class UnbanCommand extends BushCommand {
const responseMessage = (): string => {
const victim = util.format.input(user.tag);
switch (responseCode) {
- case 'missing permissions':
+ case unbanResponse.MISSING_PERMISSIONS:
return `${util.emojis.error} Could not unban ${victim} because I am missing the **Ban Members** permission.`;
- case 'error unbanning':
+ case unbanResponse.ACTION_ERROR:
return `${util.emojis.error} An error occurred while trying to unban ${victim}.`;
- case 'error removing ban entry':
+ case unbanResponse.PUNISHMENT_ENTRY_REMOVE_ERROR:
return `${util.emojis.error} While unbanning ${victim}, there was an error removing their ban entry, please report this to my developers.`;
- case 'error creating modlog entry':
+ case unbanResponse.MODLOG_ERROR:
return `${util.emojis.error} While unbanning ${victim}, there was an error creating a modlog entry, please report this to my developers.`;
- case 'user not banned':
+ case unbanResponse.NOT_BANNED:
return `${util.emojis.warn} ${victim} is not banned but I tried to unban them anyways.`;
- case 'success':
+ case unbanResponse.DM_ERROR:
+ case unbanResponse.SUCCESS:
return `${util.emojis.success} Successfully unbanned ${victim}.`;
}
};
diff --git a/src/commands/moderation/unblock.ts b/src/commands/moderation/unblock.ts
index 4cc8b49..454de8b 100644
--- a/src/commands/moderation/unblock.ts
+++ b/src/commands/moderation/unblock.ts
@@ -4,6 +4,7 @@ import {
BushTextChannel,
BushThreadChannel,
Moderation,
+ unblockResponse,
type ArgType,
type BushMessage,
type BushSlashMessage,
@@ -87,19 +88,19 @@ export default class UnblockCommand extends BushCommand {
const responseMessage = (): string => {
const victim = util.format.input(member.user.tag);
switch (responseCode) {
- case 'missing permissions':
+ case unblockResponse.MISSING_PERMISSIONS:
return `${util.emojis.error} Could not unblock ${victim} because I am missing the **Manage Channel** permission.`;
- case 'invalid channel':
+ case unblockResponse.INVALID_CHANNEL:
return `${util.emojis.error} Could not unblock ${victim}, you can only unblock users in text or thread channels.`;
- case 'error unblocking':
+ case unblockResponse.ACTION_ERROR:
return `${util.emojis.error} An unknown error occurred while trying to unblock ${victim}.`;
- case 'error creating modlog entry':
+ case unblockResponse.MODLOG_ERROR:
return `${util.emojis.error} There was an error creating a modlog entry, please report this to my developers.`;
- case 'error removing block entry':
+ case unblockResponse.PUNISHMENT_ENTRY_REMOVE_ERROR:
return `${util.emojis.error} There was an error creating a punishment entry, please report this to my developers.`;
- case 'failed to dm':
+ case unblockResponse.DM_ERROR:
return `${util.emojis.warn} Unblocked ${victim} however I could not send them a dm.`;
- case 'success':
+ case unblockResponse.SUCCESS:
return `${util.emojis.success} Successfully unblocked ${victim}.`;
}
};
diff --git a/src/commands/moderation/unmute.ts b/src/commands/moderation/unmute.ts
index 631f213..3bd399f 100644
--- a/src/commands/moderation/unmute.ts
+++ b/src/commands/moderation/unmute.ts
@@ -2,6 +2,7 @@ import {
AllowedMentions,
BushCommand,
Moderation,
+ unmuteResponse,
type ArgType,
type BushGuildMember,
type BushMessage,
@@ -79,23 +80,23 @@ export default class UnmuteCommand extends BushCommand {
const prefix = util.prefix(message);
const victim = util.format.input(member.user.tag);
switch (responseCode) {
- case 'missing permissions':
+ case unmuteResponse.MISSING_PERMISSIONS:
return `${error} Could not unmute ${victim} because I am missing the **Manage Roles** permission.`;
- case 'no mute role':
+ case unmuteResponse.NO_MUTE_ROLE:
return `${error} Could not unmute ${victim}, you must set a mute role with \`${prefix}config muteRole\`.`;
- case 'invalid mute role':
+ case unmuteResponse.MUTE_ROLE_INVALID:
return `${error} Could not unmute ${victim} because the current mute role no longer exists. Please set a new mute role with \`${prefix}config muteRole\`.`;
- case 'mute role not manageable':
+ case unmuteResponse.MUTE_ROLE_NOT_MANAGEABLE:
return `${error} Could not unmute ${victim} because I cannot assign the current mute role, either change the role's position or set a new mute role with \`${prefix}config muteRole\`.`;
- case 'error removing mute role':
+ case unmuteResponse.ACTION_ERROR:
return `${error} Could not unmute ${victim}, there was an error removing their mute role.`;
- case 'error creating modlog entry':
+ case unmuteResponse.MODLOG_ERROR:
return `${error} While muting ${victim}, there was an error creating a modlog entry, please report this to my developers.`;
- case 'error removing mute entry':
+ case unmuteResponse.PUNISHMENT_ENTRY_REMOVE_ERROR:
return `${error} While muting ${victim}, there was an error removing their mute entry, please report this to my developers.`;
- case 'failed to dm':
+ case unmuteResponse.DM_ERROR:
return `${util.emojis.warn} unmuted ${victim} however I could not send them a dm.`;
- case 'success':
+ case unmuteResponse.SUCCESS:
return `${util.emojis.success} Successfully unmuted ${victim}.`;
}
};
diff --git a/src/commands/moderation/untimeout.ts b/src/commands/moderation/untimeout.ts
index b5ea5be..c5518b4 100644
--- a/src/commands/moderation/untimeout.ts
+++ b/src/commands/moderation/untimeout.ts
@@ -2,6 +2,7 @@ import {
AllowedMentions,
BushCommand,
Moderation,
+ removeTimeoutResponse,
type ArgType,
type BushMessage,
type BushSlashMessage,
@@ -81,18 +82,16 @@ export default class UntimeoutCommand extends BushCommand {
const responseMessage = (): string => {
const victim = util.format.input(member.user.tag);
switch (responseCode) {
- case 'missing permissions':
- return `${util.emojis.error} Could not timeout ${victim} because I am missing the **Timeout Members** permission.`;
- case 'duration too long':
- return `${util.emojis.error} The duration you specified is too long, the longest you can timeout someone for is 28 days.`;
- case 'error removing timeout':
+ case removeTimeoutResponse.MISSING_PERMISSIONS:
+ return `${util.emojis.error} Could not untimeout ${victim} because I am missing the **Timeout Members** permission.`;
+ case removeTimeoutResponse.ACTION_ERROR:
return `${util.emojis.error} An unknown error occurred while trying to timeout ${victim}.`;
- case 'error creating modlog entry':
+ case removeTimeoutResponse.MODLOG_ERROR:
return `${util.emojis.error} There was an error creating a modlog entry, please report this to my developers.`;
- case 'failed to dm':
- return `${util.emojis.warn} Timed out ${victim} however I could not send them a dm.`;
- case 'success':
- return `${util.emojis.success} Successfully timed out ${victim}.`;
+ case removeTimeoutResponse.DM_ERROR:
+ return `${util.emojis.warn} Removed ${victim}'s timeout however I could not send them a dm.`;
+ case removeTimeoutResponse.SUCCESS:
+ return `${util.emojis.success} Successfully removed ${victim}'s timeout.`;
}
};
return await message.util.reply({ content: responseMessage(), allowedMentions: AllowedMentions.none() });
diff --git a/src/commands/moderation/warn.ts b/src/commands/moderation/warn.ts
index 05b1e36..aebf300 100644
--- a/src/commands/moderation/warn.ts
+++ b/src/commands/moderation/warn.ts
@@ -2,6 +2,7 @@ import {
AllowedMentions,
BushCommand,
Moderation,
+ warnResponse,
type ArgType,
type BushGuildMember,
type BushMessage,
@@ -75,13 +76,14 @@ export default class WarnCommand extends BushCommand {
const responseMessage = (): string => {
const victim = util.format.input(member.user.tag);
switch (response) {
- case 'error creating modlog entry':
+ case warnResponse.MODLOG_ERROR:
return `${util.emojis.error} While warning ${victim}, there was an error creating a modlog entry, please report this to my developers.`;
- case 'failed to dm':
+ case warnResponse.ACTION_ERROR:
+ case warnResponse.DM_ERROR:
return `${util.emojis.warn} ${victim} has been warned for the ${util.ordinal(
caseNum ?? 0
)} time, however I could not send them a dm.`;
- case 'success':
+ case warnResponse.SUCCESS:
return `${util.emojis.success} Successfully warned ${victim} for the ${util.ordinal(caseNum ?? 0)} time.`;
}
};
diff --git a/src/lib/common/util/Moderation.ts b/src/lib/common/util/Moderation.ts
index a09930b..9757f25 100644
--- a/src/lib/common/util/Moderation.ts
+++ b/src/lib/common/util/Moderation.ts
@@ -3,12 +3,14 @@ import {
ActivePunishmentType,
Guild,
ModLog,
+ type BushGuild,
type BushGuildMember,
type BushGuildMemberResolvable,
type BushGuildResolvable,
+ type BushUserResolvable,
type ModLogType
} from '#lib';
-import { type Snowflake } from 'discord.js';
+import { MessageEmbed, type Snowflake } from 'discord.js';
/**
* A utility class with moderation-related methods.
@@ -197,6 +199,28 @@ export class Moderation {
};
return typeMap[type];
}
+
+ public static async punishDM(options: PunishDMOptions): Promise<boolean> {
+ const ending = await options.guild.getSetting('punishmentEnding');
+ const dmEmbed =
+ ending && ending.length && options.sendFooter
+ ? new MessageEmbed().setDescription(ending).setColor(util.colors.newBlurple)
+ : undefined;
+
+ const dmSuccess = await client.users
+ .send(options.user, {
+ content: `You have been ${options.punishment} in **${options.guild.name}** ${
+ options.duration !== null && options.duration !== undefined
+ ? options.duration
+ ? `for ${util.humanizeDuration(options.duration)} `
+ : 'permanently '
+ : ''
+ }for **${options.reason?.trim() ? options.reason?.trim() : 'No reason provided'}**.`,
+ embeds: dmEmbed ? [dmEmbed] : undefined
+ })
+ .catch(() => false);
+ return !!dmSuccess;
+ }
}
/**
@@ -303,3 +327,39 @@ export interface RemovePunishmentEntryOptions {
*/
extraInfo?: Snowflake;
}
+
+/**
+ * Options for sending a user a punishment dm.
+ */
+export interface PunishDMOptions {
+ /**
+ * The guild that the punishment is taking place in.
+ */
+ guild: BushGuild;
+
+ /**
+ * The user that is being punished.
+ */
+ user: BushUserResolvable;
+
+ /**
+ * The punishment that the user has received.
+ */
+ punishment: string;
+
+ /**
+ * The reason the user's punishment.
+ */
+ reason?: string;
+
+ /**
+ * The duration of the punishment.
+ */
+ duration?: number;
+
+ /**
+ * Whether or not to send the guild's punishment footer with the dm.
+ * @default true
+ */
+ sendFooter: boolean;
+}
diff --git a/src/lib/extensions/discord-akairo/BushClientUtil.ts b/src/lib/extensions/discord-akairo/BushClientUtil.ts
index 47a3717..d7416bb 100644
--- a/src/lib/extensions/discord-akairo/BushClientUtil.ts
+++ b/src/lib/extensions/discord-akairo/BushClientUtil.ts
@@ -2,7 +2,6 @@ import {
Arg,
BushConstants,
Global,
- GlobalCache,
type BushClient,
type BushInspectOptions,
type BushMessage,
@@ -11,14 +10,15 @@ import {
type BushSlashSendMessageType,
type BushUser,
type CodeBlockLang,
+ type GlobalCache,
type Pronoun,
type PronounCode
} from '#lib';
+import type { APIMessage } from '@discordjs/builders/node_modules/discord-api-types';
import { humanizeDuration } from '@notenoughupdates/humanize-duration';
import { exec } from 'child_process';
import deepLock from 'deep-lock';
import { ClientUtil, Util as AkairoUtil } from 'discord-akairo';
-import { APIMessage } from 'discord-api-types';
import {
Constants as DiscordConstants,
GuildMember,
diff --git a/src/lib/extensions/discord.js/BushButtonInteraction.ts b/src/lib/extensions/discord.js/BushButtonInteraction.ts
index 2bc1c25..191ad5c 100644
--- a/src/lib/extensions/discord.js/BushButtonInteraction.ts
+++ b/src/lib/extensions/discord.js/BushButtonInteraction.ts
@@ -1,5 +1,5 @@
import type { BushClient, BushGuild, BushGuildMember, BushGuildTextBasedChannel, BushTextBasedChannel, BushUser } from '#lib';
-import type { APIInteractionGuildMember } from 'discord-api-types/v9';
+import type { APIInteractionGuildMember } from '@discordjs/builders/node_modules/discord-api-types/payloads/v9/_interactions/base';
import { ButtonInteraction, type CacheType, type CacheTypeReducer } from 'discord.js';
import type { RawMessageButtonInteractionData } from 'discord.js/typings/rawDataTypes';
diff --git a/src/lib/extensions/discord.js/BushClientEvents.d.ts b/src/lib/extensions/discord.js/BushClientEvents.d.ts
index 16eccd4..b5ad749 100644
--- a/src/lib/extensions/discord.js/BushClientEvents.d.ts
+++ b/src/lib/extensions/discord.js/BushClientEvents.d.ts
@@ -173,7 +173,7 @@ export interface BushClientEvents extends AkairoClientEvents {
evidence?: string
];
bushBlock: [
- victim: BushGuildMember | BushUser,
+ victim: BushGuildMember,
moderator: BushUser,
guild: BushGuild,
reason: string | undefined,
diff --git a/src/lib/extensions/discord.js/BushCommandInteraction.ts b/src/lib/extensions/discord.js/BushCommandInteraction.ts
index 5f32829..f4be5ed 100644
--- a/src/lib/extensions/discord.js/BushCommandInteraction.ts
+++ b/src/lib/extensions/discord.js/BushCommandInteraction.ts
@@ -10,7 +10,7 @@ import type {
BushTextBasedChannel,
BushUser
} from '#lib';
-import type { APIInteractionGuildMember } from 'discord-api-types/v9';
+import type { APIInteractionGuildMember } from '@discordjs/builders/node_modules/discord-api-types';
import { CommandInteraction, type CacheType, type CacheTypeReducer, type Invite, type Snowflake } from 'discord.js';
import type { RawCommandInteractionData } from 'discord.js/typings/rawDataTypes';
diff --git a/src/lib/extensions/discord.js/BushGuild.ts b/src/lib/extensions/discord.js/BushGuild.ts
index ea8b67e..0011ce6 100644
--- a/src/lib/extensions/discord.js/BushGuild.ts
+++ b/src/lib/extensions/discord.js/BushGuild.ts
@@ -1,26 +1,23 @@
-import type {
- BushClient,
- BushGuildMember,
- BushGuildMemberManager,
- BushGuildMemberResolvable,
- BushNewsChannel,
- BushTextChannel,
- BushThreadChannel,
- BushUser,
- BushUserResolvable,
- GuildFeatures,
- GuildLogType,
- GuildModel
-} from '#lib';
import {
- Collection,
- Guild,
- GuildChannelManager,
- Snowflake,
- type MessageOptions,
- type MessagePayload,
- type UserResolvable
-} from 'discord.js';
+ banResponse,
+ dmResponse,
+ permissionsResponse,
+ punishmentEntryRemove,
+ type BanResponse,
+ type BushClient,
+ type BushGuildMember,
+ type BushGuildMemberManager,
+ type BushGuildMemberResolvable,
+ type BushNewsChannel,
+ type BushTextChannel,
+ type BushThreadChannel,
+ type BushUser,
+ type BushUserResolvable,
+ type GuildFeatures,
+ type GuildLogType,
+ type GuildModel
+} from '#lib';
+import { Collection, Guild, Snowflake, type GuildChannelManager, type MessageOptions, type MessagePayload } from 'discord.js';
import type { RawGuildData } from 'discord.js/typings/rawDataTypes';
import _ from 'lodash';
import { Moderation } from '../../common/util/Moderation.js';
@@ -157,16 +154,25 @@ export class BushGuild extends Guild {
* @param options Options for banning the user.
* @returns A string status message of the ban.
*/
- public async bushBan(options: GuildBushBanOptions): Promise<GuildBanResponse> {
+ public async bushBan(options: GuildBushBanOptions): Promise<BanResponse> {
// checks
- if (!this.me!.permissions.has('BAN_MEMBERS')) return 'missing permissions';
+ if (!this.me!.permissions.has('BAN_MEMBERS')) return banResponse.MISSING_PERMISSIONS;
let caseID: string | undefined = undefined;
+ let dmSuccessEvent: boolean | undefined = undefined;
const user = (await util.resolveNonCachedUser(options.user))!;
- const moderator = (await util.resolveNonCachedUser(options.moderator!)) ?? client.user!;
+ const moderator = client.users.resolve(options.moderator ?? client.user!)!;
const ret = await (async () => {
- await this.members.cache.get(user.id)?.bushPunishDM('banned', options.reason, options.duration ?? 0);
+ // dm user
+ dmSuccessEvent = await Moderation.punishDM({
+ guild: this,
+ user: user,
+ punishment: 'banned',
+ duration: options.duration ?? 0,
+ reason: options.reason ?? undefined,
+ sendFooter: true
+ });
// ban
const banSuccess = await this.bans
@@ -175,7 +181,7 @@ export class BushGuild extends Guild {
days: options.deleteDays
})
.catch(() => false);
- if (!banSuccess) return 'error banning';
+ if (!banSuccess) return banResponse.ACTION_ERROR;
// add modlog entry
const { log: modlog } = await Moderation.createModLogEntry({
@@ -187,7 +193,7 @@ export class BushGuild extends Guild {
guild: this,
evidence: options.evidence
});
- if (!modlog) return 'error creating modlog entry';
+ if (!modlog) return banResponse.MODLOG_ERROR;
caseID = modlog.id;
// add punishment entry so they can be unbanned later
@@ -198,13 +204,24 @@ export class BushGuild extends Guild {
duration: options.duration,
modlog: modlog.id
});
- if (!punishmentEntrySuccess) return 'error creating ban entry';
+ if (!punishmentEntrySuccess) return banResponse.PUNISHMENT_ENTRY_ADD_ERROR;
- return 'success';
+ if (!dmSuccessEvent) return banResponse.DM_ERROR;
+ return banResponse.SUCCESS;
})();
- if (!['error banning', 'error creating modlog entry', 'error creating ban entry'].includes(ret))
- client.emit('bushBan', user, moderator, this, options.reason ?? undefined, caseID!, options.duration ?? 0);
+ if (!([banResponse.ACTION_ERROR, banResponse.MODLOG_ERROR, banResponse.PUNISHMENT_ENTRY_ADD_ERROR] as const).includes(ret))
+ client.emit(
+ 'bushBan',
+ user,
+ moderator,
+ this,
+ options.reason ?? undefined,
+ caseID!,
+ options.duration ?? 0,
+ dmSuccessEvent,
+ options.evidence
+ );
return ret;
}
@@ -213,11 +230,14 @@ export class BushGuild extends Guild {
* @param options Options for unbanning the user.
* @returns A status message of the unban.
*/
- public async bushUnban(options: GuildBushUnbanOptions): Promise<GuildUnbanResponse> {
+ public async bushUnban(options: GuildBushUnbanOptions): Promise<UnbanResponse> {
+ // checks
+ if (!this.me!.permissions.has('BAN_MEMBERS')) return unbanResponse.MISSING_PERMISSIONS;
+
let caseID: string | undefined = undefined;
let dmSuccessEvent: boolean | undefined = undefined;
const user = (await util.resolveNonCachedUser(options.user))!;
- const moderator = (await util.resolveNonCachedUser(options.moderator ?? this.me))!;
+ const moderator = client.users.resolve(options.moderator ?? client.user!)!;
const ret = await (async () => {
const bans = await this.bans.fetch();
@@ -234,8 +254,8 @@ export class BushGuild extends Guild {
} else return false;
});
- if (notBanned) return 'user not banned';
- if (!unbanSuccess) return 'error unbanning';
+ if (notBanned) return unbanResponse.NOT_BANNED;
+ if (!unbanSuccess) return unbanResponse.ACTION_ERROR;
// add modlog entry
const { log: modlog } = await Moderation.createModLogEntry({
@@ -243,9 +263,10 @@ export class BushGuild extends Guild {
user: user.id,
moderator: moderator.id,
reason: options.reason,
- guild: this
+ guild: this,
+ evidence: options.evidence
});
- if (!modlog) return 'error creating modlog entry';
+ if (!modlog) return unbanResponse.MODLOG_ERROR;
caseID = modlog.id;
// remove punishment entry
@@ -254,23 +275,26 @@ export class BushGuild extends Guild {
user: user.id,
guild: this
});
- if (!removePunishmentEntrySuccess) return 'error removing ban entry';
+ if (!removePunishmentEntrySuccess) return unbanResponse.PUNISHMENT_ENTRY_REMOVE_ERROR;
- const userObject = client.users.cache.get(user.id);
-
- const dmSuccess = await userObject
- ?.send(
- `You have been unbanned from **${util.discord.escapeMarkdown(this.toString())}** for **${
- options.reason ?? 'No reason provided'
- }**.`
- )
- .catch(() => false);
- dmSuccessEvent = !!dmSuccess;
+ // dm user
+ dmSuccessEvent = await Moderation.punishDM({
+ guild: this,
+ user: user,
+ punishment: 'unbanned',
+ reason: options.reason ?? undefined,
+ sendFooter: false
+ });
- return 'success';
+ if (!dmSuccessEvent) return unbanResponse.DM_ERROR;
+ return unbanResponse.SUCCESS;
})();
- if (!['error unbanning', 'error creating modlog entry', 'error removing ban entry'].includes(ret))
- client.emit('bushUnban', user, moderator, this, options.reason ?? undefined, caseID!, dmSuccessEvent!);
+ if (
+ !([unbanResponse.ACTION_ERROR, unbanResponse.MODLOG_ERROR, unbanResponse.PUNISHMENT_ENTRY_REMOVE_ERROR] as const).includes(
+ ret
+ )
+ )
+ client.emit('bushUnban', user, moderator, this, options.reason ?? undefined, caseID!, dmSuccessEvent!, options.evidence);
return ret;
}
@@ -367,6 +391,11 @@ export interface GuildBushUnbanOptions {
* The moderator who unbanned the user
*/
moderator?: BushUserResolvable;
+
+ /**
+ * The evidence for the unban
+ */
+ evidence?: string;
}
/**
@@ -376,7 +405,7 @@ export interface GuildBushBanOptions {
/**
* The user to ban
*/
- user: BushUserResolvable | UserResolvable;
+ user: BushUserResolvable;
/**
* The reason to ban the user
@@ -404,17 +433,19 @@ export interface GuildBushBanOptions {
evidence?: string;
}
-export type GuildPunishmentResponse = 'success' | 'missing permissions' | 'error creating modlog entry';
+type ValueOf<T> = T[keyof T];
-/**
- * Response returned when banning a user
- */
-export type GuildBanResponse = GuildPunishmentResponse | 'error banning' | 'error creating ban entry';
+export const unbanResponse = Object.freeze({
+ ...dmResponse,
+ ...permissionsResponse,
+ ...punishmentEntryRemove,
+ NOT_BANNED: 'user not banned'
+} as const);
/**
* Response returned when unbanning a user
*/
-export type GuildUnbanResponse = GuildPunishmentResponse | 'user not banned' | 'error unbanning' | 'error removing ban entry';
+export type UnbanResponse = ValueOf<typeof unbanResponse>;
/**
* Options for locking down channel(s)
diff --git a/src/lib/extensions/discord.js/BushGuildMember.ts b/src/lib/extensions/discord.js/BushGuildMember.ts
index e7df926..8ff1943 100644
--- a/src/lib/extensions/discord.js/BushGuildMember.ts
+++ b/src/lib/extensions/discord.js/BushGuildMember.ts
@@ -11,7 +11,7 @@ import {
type BushThreadChannelResolvable,
type BushUser
} from '#lib';
-import { GuildMember, MessageEmbed, type Partialize, type Role } from 'discord.js';
+import { GuildMember, type Partialize, type Role } from 'discord.js';
import type { RawGuildMemberData } from 'discord.js/typings/rawDataTypes';
/* eslint-enable @typescript-eslint/no-unused-vars */
@@ -30,25 +30,13 @@ export class BushGuildMember extends GuildMember {
/**
* Send a punishment dm to the user.
* @param punishment The punishment that the user has received.
- * @param reason The reason the user to be punished.
+ * @param reason The reason for the user's punishment.
* @param duration The duration of the punishment.
* @param sendFooter Whether or not to send the guild's punishment footer with the dm.
* @returns Whether or not the dm was sent successfully.
*/
public async bushPunishDM(punishment: string, reason?: string | null, duration?: number, sendFooter = true): Promise<boolean> {
- const ending = await this.guild.getSetting('punishmentEnding');
- const dmEmbed =
- ending && ending.length && sendFooter
- ? new MessageEmbed().setDescription(ending).setColor(util.colors.newBlurple)
- : undefined;
- const dmSuccess = await this.send({
- content: `You have been ${punishment} in **${this.guild.name}** ${
- duration !== null && duration !== undefined ? (duration ? `for ${util.humanizeDuration(duration)} ` : 'permanently ') : ''
- // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
- }for **${reason?.trim() || 'No reason provided'}**.`,
- embeds: dmEmbed ? [dmEmbed] : undefined
- }).catch(() => false);
- return !!dmSuccess;
+ return Moderation.punishDM({ guild: this.guild, user: this, punishment, reason: reason ?? undefined, duration, sendFooter });
}
/**
@@ -76,16 +64,16 @@ export class BushGuildMember extends GuildMember {
true
);
caseID = result.log?.id;
- if (!result || !result.log) return { result: 'error creating modlog entry', caseNum: null };
+ if (!result || !result.log) return { result: warnResponse.MODLOG_ERROR, caseNum: null };
// dm user
const dmSuccess = await this.bushPunishDM('warned', options.reason);
dmSuccessEvent = dmSuccess;
- if (!dmSuccess) return { result: 'failed to dm', caseNum: result.caseNum };
+ if (!dmSuccess) return { result: warnResponse.DM_ERROR, caseNum: result.caseNum };
- return { result: 'success', caseNum: result.caseNum };
+ return { result: warnResponse.SUCCESS, caseNum: result.caseNum };
})();
- if (!(['error creating modlog entry'] as const).includes(ret.result))
+ if (!([warnResponse.MODLOG_ERROR] as const).includes(ret.result))
client.emit('bushWarn', this, moderator, this.guild, options.reason ?? undefined, caseID!, dmSuccessEvent!);
return ret;
}
@@ -97,6 +85,8 @@ export class BushGuildMember extends GuildMember {
* @emits {@link BushClientEvents.bushPunishRole}
*/
public async bushAddRole(options: AddRoleOptions): Promise<AddRoleResponse> {
+ // checks
+ if (!this.guild.me!.permissions.has('MANAGE_ROLES')) return addRoleResponse.MISSING_PERMISSIONS;
const ifShouldAddRole = this.#checkIfShouldAddRole(options.role, options.moderator);
if (ifShouldAddRole !== true) return ifShouldAddRole;
@@ -115,7 +105,7 @@ export class BushGuildMember extends GuildMember {
evidence: options.evidence
});
- if (!modlog) return 'error creating modlog entry';
+ if (!modlog) return addRoleResponse.MODLOG_ERROR;
caseID = modlog.id;
if (options.addToModlog || options.duration) {
@@ -127,17 +117,19 @@ export class BushGuildMember extends GuildMember {
duration: options.duration,
extraInfo: options.role.id
});
- if (!punishmentEntrySuccess) return 'error creating role entry';
+ if (!punishmentEntrySuccess) return addRoleResponse.PUNISHMENT_ENTRY_ADD_ERROR;
}
}
const removeRoleSuccess = await this.roles.add(options.role, `${moderator.tag}`);
- if (!removeRoleSuccess) return 'error adding role';
+ if (!removeRoleSuccess) return addRoleResponse.ACTION_ERROR;
- return 'success';
+ return addRoleResponse.SUCCESS;
})();
if (
- !(['error adding role', 'error creating modlog entry', 'error creating role entry'] as const).includes(ret) &&
+ !(
+ [addRoleResponse.ACTION_ERROR, addRoleResponse.MODLOG_ERROR, addRoleResponse.PUNISHMENT_ENTRY_ADD_ERROR] as const
+ ).includes(ret) &&
options.addToModlog
)
client.emit(
@@ -161,6 +153,8 @@ export class BushGuildMember extends GuildMember {
* @emits {@link BushClientEvents.bushPunishRoleRemove}
*/
public async bushRemoveRole(options: RemoveRoleOptions): Promise<RemoveRoleResponse> {
+ // checks
+ if (!this.guild.me!.permissions.has('MANAGE_ROLES')) return removeRoleResponse.MISSING_PERMISSIONS;
const ifShouldAddRole = this.#checkIfShouldAddRole(options.role, options.moderator);
if (ifShouldAddRole !== true) return ifShouldAddRole;
@@ -178,7 +172,7 @@ export class BushGuildMember extends GuildMember {
evidence: options.evidence
});
- if (!modlog) return 'error creating modlog entry';
+ if (!modlog) return removeRoleResponse.MODLOG_ERROR;
caseID = modlog.id;
const punishmentEntrySuccess = await Moderation.removePunishmentEntry({
@@ -188,17 +182,23 @@ export class BushGuildMember extends GuildMember {
extraInfo: options.role.id
});
- if (!punishmentEntrySuccess) return 'error removing role entry';
+ if (!punishmentEntrySuccess) return removeRoleResponse.PUNISHMENT_ENTRY_REMOVE_ERROR;
}
const removeRoleSuccess = await this.roles.remove(options.role, `${moderator.tag}`);
- if (!removeRoleSuccess) return 'error removing role';
+ if (!removeRoleSuccess) return removeRoleResponse.ACTION_ERROR;
- return 'success';
+ return removeRoleResponse.SUCCESS;
})();
if (
- !(['error removing role', 'error creating modlog entry', 'error removing role entry'] as const).includes(ret) &&
+ !(
+ [
+ removeRoleResponse.ACTION_ERROR,
+ removeRoleResponse.MODLOG_ERROR,
+ removeRoleResponse.PUNISHMENT_ENTRY_REMOVE_ERROR
+ ] as const
+ ).includes(ret) &&
options.addToModlog
)
client.emit(
@@ -225,12 +225,11 @@ export class BushGuildMember extends GuildMember {
moderator?: BushGuildMember
): true | 'user hierarchy' | 'role managed' | 'client hierarchy' {
if (moderator && moderator.roles.highest.position <= role.position && this.guild.ownerId !== this.user.id) {
- client.console.debug(`${this.roles.highest.position} <= ${role.position}`);
- return 'user hierarchy';
+ return shouldAddRoleResponse.USER_HIERARCHY;
} else if (role.managed) {
- return 'role managed';
+ return shouldAddRoleResponse.ROLE_MANAGED;
} else if (this.guild.me!.roles.highest.position <= role.position) {
- return 'client hierarchy';
+ return shouldAddRoleResponse.CLIENT_HIERARCHY;
}
return true;
}
@@ -243,12 +242,13 @@ export class BushGuildMember extends GuildMember {
*/
public async bushMute(options: BushTimedPunishmentOptions): Promise<MuteResponse> {
// checks
- if (!this.guild.me!.permissions.has('MANAGE_ROLES')) return 'missing permissions';
+ if (!this.guild.me!.permissions.has('MANAGE_ROLES')) return muteResponse.MISSING_PERMISSIONS;
const muteRoleID = await this.guild.getSetting('muteRole');
- if (!muteRoleID) return 'no mute role';
+ if (!muteRoleID) return muteResponse.NO_MUTE_ROLE;
const muteRole = this.guild.roles.cache.get(muteRoleID);
- if (!muteRole) return 'invalid mute role';
- if (muteRole.position >= this.guild.me!.roles.highest.position || muteRole.managed) return 'mute role not manageable';
+ if (!muteRole) return muteResponse.MUTE_ROLE_INVALID;
+ if (muteRole.position >= this.guild.me!.roles.highest.position || muteRole.managed)
+ return muteResponse.MUTE_ROLE_NOT_MANAGEABLE;
let caseID: string | undefined = undefined;
let dmSuccessEvent: boolean | undefined = undefined;
@@ -263,7 +263,7 @@ export class BushGuildMember extends GuildMember {
client.console.debug(e);
return false;
});
- if (!muteSuccess) return 'error giving mute role';
+ if (!muteSuccess) return muteResponse.ACTION_ERROR;
// add modlog entry
const { log: modlog } = await Moderation.createModLogEntry({
@@ -276,7 +276,7 @@ export class BushGuildMember extends GuildMember {
evidence: options.evidence
});
- if (!modlog) return 'error creating modlog entry';
+ if (!modlog) return muteResponse.MODLOG_ERROR;
caseID = modlog.id;
// add punishment entry so they can be unmuted later
@@ -288,18 +288,18 @@ export class BushGuildMember extends GuildMember {
modlog: modlog.id
});
- if (!punishmentEntrySuccess) return 'error creating mute entry';
+ if (!punishmentEntrySuccess) return muteResponse.PUNISHMENT_ENTRY_ADD_ERROR;
// dm user
const dmSuccess = await this.bushPunishDM('muted', options.reason, options.duration ?? 0);
dmSuccessEvent = dmSuccess;
- if (!dmSuccess) return 'failed to dm';
+ if (!dmSuccess) return muteResponse.DM_ERROR;
- return 'success';
+ return muteResponse.SUCCESS;
})();
- if (!(['error giving mute role', 'error creating modlog entry', 'error creating mute entry'] as const).includes(ret))
+ if (!([muteResponse.ACTION_ERROR, muteResponse.MODLOG_ERROR, muteResponse.PUNISHMENT_ENTRY_ADD_ERROR] as const).includes(ret))
client.emit(
'bushMute',
this,
@@ -322,12 +322,13 @@ export class BushGuildMember extends GuildMember {
*/
public async bushUnmute(options: BushPunishmentOptions): Promise<UnmuteResponse> {
// checks
- if (!this.guild.me!.permissions.has('MANAGE_ROLES')) return 'missing permissions';
+ if (!this.guild.me!.permissions.has('MANAGE_ROLES')) return unmuteResponse.MISSING_PERMISSIONS;
const muteRoleID = await this.guild.getSetting('muteRole');
- if (!muteRoleID) return 'no mute role';
+ if (!muteRoleID) return unmuteResponse.NO_MUTE_ROLE;
const muteRole = this.guild.roles.cache.get(muteRoleID);
- if (!muteRole) return 'invalid mute role';
- if (muteRole.position >= this.guild.me!.roles.highest.position || muteRole.managed) return 'mute role not manageable';
+ if (!muteRole) return unmuteResponse.MUTE_ROLE_INVALID;
+ if (muteRole.position >= this.guild.me!.roles.highest.position || muteRole.managed)
+ return unmuteResponse.MUTE_ROLE_NOT_MANAGEABLE;
let caseID: string | undefined = undefined;
let dmSuccessEvent: boolean | undefined = undefined;
@@ -341,7 +342,7 @@ export class BushGuildMember extends GuildMember {
await client.console.warn('muteRoleAddError', e?.stack || e);
return false;
});
- if (!muteSuccess) return 'error removing mute role';
+ if (!muteSuccess) return unmuteResponse.ACTION_ERROR;
// add modlog entry
const { log: modlog } = await Moderation.createModLogEntry({
@@ -353,7 +354,7 @@ export class BushGuildMember extends GuildMember {
evidence: options.evidence
});
- if (!modlog) return 'error creating modlog entry';
+ if (!modlog) return unmuteResponse.MODLOG_ERROR;
caseID = modlog.id;
// remove mute entry
@@ -363,18 +364,22 @@ export class BushGuildMember extends GuildMember {
guild: this.guild
});
- if (!removePunishmentEntrySuccess) return 'error removing mute entry';
+ if (!removePunishmentEntrySuccess) return unmuteResponse.PUNISHMENT_ENTRY_REMOVE_ERROR;
// dm user
const dmSuccess = await this.bushPunishDM('unmuted', options.reason, undefined, false);
dmSuccessEvent = dmSuccess;
- if (!dmSuccess) return 'failed to dm';
+ if (!dmSuccess) return unmuteResponse.DM_ERROR;
- return 'success';
+ return unmuteResponse.SUCCESS;
})();
- if (!(['error removing mute role', 'error creating modlog entry', 'error removing mute entry'] as const).includes(ret))
+ if (
+ !(
+ [unmuteResponse.ACTION_ERROR, unmuteResponse.MODLOG_ERROR, unmuteResponse.PUNISHMENT_ENTRY_REMOVE_ERROR] as const
+ ).includes(ret)
+ )
client.emit(
'bushUnmute',
this,
@@ -396,7 +401,7 @@ export class BushGuildMember extends GuildMember {
*/
public async bushKick(options: BushPunishmentOptions): Promise<KickResponse> {
// checks
- if (!this.guild.me?.permissions.has('KICK_MEMBERS') || !this.kickable) return 'missing permissions';
+ if (!this.guild.me?.permissions.has('KICK_MEMBERS') || !this.kickable) return kickResponse.MISSING_PERMISSIONS;
let caseID: string | undefined = undefined;
let dmSuccessEvent: boolean | undefined = undefined;
@@ -408,7 +413,7 @@ export class BushGuildMember extends GuildMember {
// kick
const kickSuccess = await this.kick(`${moderator?.tag} | ${options.reason ?? 'No reason provided.'}`).catch(() => false);
- if (!kickSuccess) return 'error kicking';
+ if (!kickSuccess) return kickResponse.ACTION_ERROR;
// add modlog entry
const { log: modlog } = await Moderation.createModLogEntry({
@@ -419,12 +424,12 @@ export class BushGuildMember extends GuildMember {
guild: this.guild,
evidence: options.evidence
});
- if (!modlog) return 'error creating modlog entry';
+ if (!modlog) return kickResponse.MODLOG_ERROR;
caseID = modlog.id;
- if (!dmSuccess) return 'failed to dm';
- return 'success';
+ if (!dmSuccess) return kickResponse.DM_ERROR;
+ return kickResponse.SUCCESS;
})();
- if (!(['error kicking', 'error creating modlog entry'] as const).includes(ret))
+ if (!([kickResponse.ACTION_ERROR, kickResponse.MODLOG_ERROR] as const).includes(ret))
client.emit(
'bushKick',
this,
@@ -446,11 +451,18 @@ export class BushGuildMember extends GuildMember {
*/
public async bushBan(options: BushBanOptions): Promise<BanResponse> {
// checks
- if (!this.guild.me!.permissions.has('BAN_MEMBERS') || !this.bannable) return 'missing permissions';
+ if (!this.guild.me!.permissions.has('BAN_MEMBERS') || !this.bannable) return banResponse.MISSING_PERMISSIONS;
let caseID: string | undefined = undefined;
let dmSuccessEvent: boolean | undefined = undefined;
const moderator = (await util.resolveNonCachedUser(options.moderator ?? this.guild.me))!;
+
+ // ignore result, they should still be banned even if their mute cannot be removed
+ await this.bushUnmute({
+ reason: 'User is about to be banned, a mute is no longer necessary.',
+ moderator: this.guild.me!
+ });
+
const ret = await (async () => {
// dm user
const dmSuccess = await this.bushPunishDM('banned', options.reason, options.duration ?? 0);
@@ -461,7 +473,7 @@ export class BushGuildMember extends GuildMember {
reason: `${moderator.tag} | ${options.reason ?? 'No reason provided.'}`,
days: options.deleteDays
}).catch(() => false);
- if (!banSuccess) return 'error banning';
+ if (!banSuccess) return banResponse.ACTION_ERROR;
// add modlog entry
const { log: modlog } = await Moderation.createModLogEntry({
@@ -473,7 +485,7 @@ export class BushGuildMember extends GuildMember {
guild: this.guild,
evidence: options.evidence
});
- if (!modlog) return 'error creating modlog entry';
+ if (!modlog) return banResponse.MODLOG_ERROR;
caseID = modlog.id;
// add punishment entry so they can be unbanned later
@@ -484,12 +496,12 @@ export class BushGuildMember extends GuildMember {
duration: options.duration,
modlog: modlog.id
});
- if (!punishmentEntrySuccess) return 'error creating ban entry';
+ if (!punishmentEntrySuccess) return banResponse.PUNISHMENT_ENTRY_ADD_ERROR;
- if (!dmSuccess) return 'failed to dm';
- return 'success';
+ if (!dmSuccess) return banResponse.DM_ERROR;
+ return banResponse.SUCCESS;
})();
- if (!(['error banning', 'error creating modlog entry', 'error creating ban entry'] as const).includes(ret))
+ if (!([banResponse.ACTION_ERROR, banResponse.MODLOG_ERROR, banResponse.PUNISHMENT_ENTRY_ADD_ERROR] as const).includes(ret))
client.emit(
'bushBan',
this,
@@ -510,11 +522,11 @@ export class BushGuildMember extends GuildMember {
*/
public async bushBlock(options: BlockOptions): Promise<BlockResponse> {
const _channel = this.guild.channels.resolve(options.channel);
- if (!_channel || (!_channel.isText() && !_channel.isThread())) return 'invalid channel';
+ if (!_channel || (!_channel.isText() && !_channel.isThread())) return blockResponse.INVALID_CHANNEL;
const channel = _channel as BushGuildTextBasedChannel;
// checks
- if (!channel.permissionsFor(this.guild.me!)!.has('MANAGE_CHANNELS')) return 'missing permissions';
+ if (!channel.permissionsFor(this.guild.me!)!.has('MANAGE_CHANNELS')) return blockResponse.MISSING_PERMISSIONS;
let caseID: string | undefined = undefined;
let dmSuccessEvent: boolean | undefined = undefined;
@@ -527,7 +539,7 @@ export class BushGuildMember extends GuildMember {
const blockSuccess = await channelToUse.permissionOverwrites
.edit(this, perm, { reason: `[Block] ${moderator.tag} | ${options.reason ?? 'No reason provided.'}` })
.catch(() => false);
- if (!blockSuccess) return 'error blocking';
+ if (!blockSuccess) return blockResponse.ACTION_ERROR;
// add modlog entry
const { log: modlog } = await Moderation.createModLogEntry({
@@ -538,7 +550,7 @@ export class BushGuildMember extends GuildMember {
guild: this.guild,
evidence: options.evidence
});
- if (!modlog) return 'error creating modlog entry';
+ if (!modlog) return blockResponse.MODLOG_ERROR;
caseID = modlog.id;
// add punishment entry so they can be unblocked later
@@ -550,7 +562,7 @@ export class BushGuildMember extends GuildMember {
modlog: modlog.id,
extraInfo: channel.id
});
- if (!punishmentEntrySuccess) return 'error creating block entry';
+ if (!punishmentEntrySuccess) return blockResponse.PUNISHMENT_ENTRY_ADD_ERROR;
// dm user
const dmSuccess = await this.send({
@@ -560,17 +572,18 @@ export class BushGuildMember extends GuildMember {
? `for ${util.humanizeDuration(options.duration)} `
: 'permanently '
: ''
- // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
- }for **${options.reason?.trim() || 'No reason provided'}**.`
+ }for **${options.reason?.trim() ? options.reason?.trim() : 'No reason provided'}**.`
}).catch(() => false);
dmSuccessEvent = !!dmSuccess;
- if (!dmSuccess) return 'failed to dm';
+ if (!dmSuccess) return blockResponse.DM_ERROR;
- return 'success';
+ return blockResponse.SUCCESS;
})();
- if (!(['error creating modlog entry', 'error creating block entry', 'error blocking'] as const).includes(ret))
+ if (
+ !([blockResponse.ACTION_ERROR, blockResponse.MODLOG_ERROR, blockResponse.PUNISHMENT_ENTRY_ADD_ERROR] as const).includes(ret)
+ )
client.emit(
'bushBlock',
this,
@@ -592,11 +605,11 @@ export class BushGuildMember extends GuildMember {
*/
public async bushUnblock(options: UnblockOptions): Promise<UnblockResponse> {
const _channel = this.guild.channels.resolve(options.channel);
- if (!_channel || (!_channel.isText() && !_channel.isThread())) return 'invalid channel';
+ if (!_channel || (!_channel.isText() && !_channel.isThread())) return unblockResponse.INVALID_CHANNEL;
const channel = _channel as BushGuildTextBasedChannel;
// checks
- if (!channel.permissionsFor(this.guild.me!)!.has('MANAGE_CHANNELS')) return 'missing permissions';
+ if (!channel.permissionsFor(this.guild.me!)!.has('MANAGE_CHANNELS')) return unblockResponse.MISSING_PERMISSIONS;
let caseID: string | undefined = undefined;
let dmSuccessEvent: boolean | undefined = undefined;
@@ -609,7 +622,7 @@ export class BushGuildMember extends GuildMember {
const blockSuccess = await channelToUse.permissionOverwrites
.edit(this, perm, { reason: `[Unblock] ${moderator.tag} | ${options.reason ?? 'No reason provided.'}` })
.catch(() => false);
- if (!blockSuccess) return 'error unblocking';
+ if (!blockSuccess) return unblockResponse.ACTION_ERROR;
// add modlog entry
const { log: modlog } = await Moderation.createModLogEntry({
@@ -620,7 +633,7 @@ export class BushGuildMember extends GuildMember {
guild: this.guild,
evidence: options.evidence
});
- if (!modlog) return 'error creating modlog entry';
+ if (!modlog) return unblockResponse.MODLOG_ERROR;
caseID = modlog.id;
// remove punishment entry
@@ -630,23 +643,22 @@ export class BushGuildMember extends GuildMember {
guild: this.guild,
extraInfo: channel.id
});
- if (!punishmentEntrySuccess) return 'error removing block entry';
+ if (!punishmentEntrySuccess) return unblockResponse.ACTION_ERROR;
// dm user
const dmSuccess = await this.send({
content: `You have been unblocked from <#${channel.id}> in **${this.guild.name}** for **${
- // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
- options.reason?.trim() || 'No reason provided'
+ options.reason?.trim() ? options.reason?.trim() : 'No reason provided'
}**.`
}).catch(() => false);
dmSuccessEvent = !!dmSuccess;
- if (!dmSuccess) return 'failed to dm';
+ if (!dmSuccess) return unblockResponse.DM_ERROR;
- return 'success';
+ return unblockResponse.SUCCESS;
})();
- if (!(['error creating modlog entry', 'error removing block entry', 'error unblocking'] as const).includes(ret))
+ if (!([unblockResponse.ACTION_ERROR, unblockResponse.MODLOG_ERROR, unblockResponse.ACTION_ERROR] as const).includes(ret))
client.emit(
'bushUnblock',
this,
@@ -667,10 +679,10 @@ export class BushGuildMember extends GuildMember {
*/
public async bushTimeout(options: BushTimeoutOptions): Promise<TimeoutResponse> {
// checks
- if (!this.guild.me!.permissions.has('MODERATE_MEMBERS')) return 'missing permissions';
+ if (!this.guild.me!.permissions.has('MODERATE_MEMBERS')) return timeoutResponse.MISSING_PERMISSIONS;
const twentyEightDays = client.consts.timeUnits.days.value * 28;
- if (options.duration > twentyEightDays) return 'duration too long';
+ if (options.duration > twentyEightDays) return timeoutResponse.INVALID_DURATION;
let caseID: string | undefined = undefined;
let dmSuccessEvent: boolean | undefined = undefined;
@@ -682,7 +694,7 @@ export class BushGuildMember extends GuildMember {
options.duration,
`${moderator.tag} | ${options.reason ?? 'No reason provided.'}`
).catch(() => false);
- if (!timeoutSuccess) return 'error timing out';
+ if (!timeoutSuccess) return timeoutResponse.ACTION_ERROR;
// add modlog entry
const { log: modlog } = await Moderation.createModLogEntry({
@@ -695,19 +707,19 @@ export class BushGuildMember extends GuildMember {
evidence: options.evidence
});
- if (!modlog) return 'error creating modlog entry';
+ if (!modlog) return timeoutResponse.MODLOG_ERROR;
caseID = modlog.id;
// dm user
const dmSuccess = await this.bushPunishDM('timed out', options.reason, options.duration);
dmSuccessEvent = dmSuccess;
- if (!dmSuccess) return 'failed to dm';
+ if (!dmSuccess) return timeoutResponse.DM_ERROR;
- return 'success';
+ return timeoutResponse.SUCCESS;
})();
- if (!(['error timing out', 'error creating modlog entry'] as const).includes(ret))
+ if (!([timeoutResponse.ACTION_ERROR, timeoutResponse.MODLOG_ERROR] as const).includes(ret))
client.emit(
'bushTimeout',
this,
@@ -728,7 +740,7 @@ export class BushGuildMember extends GuildMember {
*/
public async bushRemoveTimeout(options: BushPunishmentOptions): Promise<RemoveTimeoutResponse> {
// checks
- if (!this.guild.me!.permissions.has('MODERATE_MEMBERS')) return 'missing permissions';
+ if (!this.guild.me!.permissions.has('MODERATE_MEMBERS')) return removeTimeoutResponse.MISSING_PERMISSIONS;
let caseID: string | undefined = undefined;
let dmSuccessEvent: boolean | undefined = undefined;
@@ -739,7 +751,7 @@ export class BushGuildMember extends GuildMember {
const timeoutSuccess = await this.timeout(null, `${moderator.tag} | ${options.reason ?? 'No reason provided.'}`).catch(
() => false
);
- if (!timeoutSuccess) return 'error removing timeout';
+ if (!timeoutSuccess) return removeTimeoutResponse.ACTION_ERROR;
// add modlog entry
const { log: modlog } = await Moderation.createModLogEntry({
@@ -751,19 +763,19 @@ export class BushGuildMember extends GuildMember {
evidence: options.evidence
});
- if (!modlog) return 'error creating modlog entry';
+ if (!modlog) return removeTimeoutResponse.MODLOG_ERROR;
caseID = modlog.id;
// dm user
- const dmSuccess = await this.bushPunishDM('un timed out', options.reason);
+ const dmSuccess = await this.bushPunishDM('untimedout', options.reason);
dmSuccessEvent = dmSuccess;
- if (!dmSuccess) return 'failed to dm';
+ if (!dmSuccess) return removeTimeoutResponse.DM_ERROR;
- return 'success';
+ return removeTimeoutResponse.SUCCESS;
})();
- if (!(['error removing timeout', 'error creating modlog entry'] as const).includes(ret))
+ if (!([removeTimeoutResponse.ACTION_ERROR, removeTimeoutResponse.MODLOG_ERROR] as const).includes(ret))
client.emit(
'bushRemoveTimeout',
this,
@@ -892,98 +904,169 @@ export interface BushTimeoutOptions extends BushPunishmentOptions {
duration: number;
}
-export type PunishmentResponse = 'success' | 'error creating modlog entry' | 'failed to dm';
+type ValueOf<T> = T[keyof T];
+
+export const basePunishmentResponse = Object.freeze({
+ SUCCESS: 'success',
+ MODLOG_ERROR: 'error creating modlog entry',
+ ACTION_ERROR: 'error performing action'
+} as const);
+
+export const dmResponse = Object.freeze({
+ ...basePunishmentResponse,
+ DM_ERROR: 'failed to dm'
+} as const);
+
+export const permissionsResponse = Object.freeze({
+ MISSING_PERMISSIONS: 'missing permissions'
+} as const);
+
+export const punishmentEntryAdd = Object.freeze({
+ PUNISHMENT_ENTRY_ADD_ERROR: 'error creating punishment entry'
+} as const);
+
+export const punishmentEntryRemove = Object.freeze({
+ PUNISHMENT_ENTRY_REMOVE_ERROR: 'error removing punishment entry'
+} as const);
+
+export const shouldAddRoleResponse = Object.freeze({
+ USER_HIERARCHY: 'user hierarchy',
+ CLIENT_HIERARCHY: 'client hierarchy',
+ ROLE_MANAGED: 'role managed'
+} as const);
+
+export const baseBlockResponse = Object.freeze({
+ INVALID_CHANNEL: 'invalid channel'
+} as const);
+
+export const baseMuteResponse = Object.freeze({
+ NO_MUTE_ROLE: 'no mute role',
+ MUTE_ROLE_INVALID: 'invalid mute role',
+ MUTE_ROLE_NOT_MANAGEABLE: 'mute role not manageable'
+} as const);
+
+export const warnResponse = Object.freeze({
+ ...dmResponse
+} as const);
+
+export const addRoleResponse = Object.freeze({
+ ...basePunishmentResponse,
+ ...permissionsResponse,
+ ...shouldAddRoleResponse,
+ ...punishmentEntryAdd
+} as const);
+
+export const removeRoleResponse = Object.freeze({
+ ...basePunishmentResponse,
+ ...permissionsResponse,
+ ...shouldAddRoleResponse,
+ ...punishmentEntryRemove
+} as const);
+
+export const muteResponse = Object.freeze({
+ ...dmResponse,
+ ...permissionsResponse,
+ ...baseMuteResponse,
+ ...punishmentEntryAdd
+} as const);
+
+export const unmuteResponse = Object.freeze({
+ ...dmResponse,
+ ...permissionsResponse,
+ ...baseMuteResponse,
+ ...punishmentEntryRemove
+} as const);
+
+export const kickResponse = Object.freeze({
+ ...dmResponse,
+ ...permissionsResponse
+} as const);
+
+export const banResponse = Object.freeze({
+ ...dmResponse,
+ ...permissionsResponse,
+ ...punishmentEntryAdd
+} as const);
+
+export const blockResponse = Object.freeze({
+ ...dmResponse,
+ ...permissionsResponse,
+ ...baseBlockResponse,
+ ...punishmentEntryAdd
+});
+
+export const unblockResponse = Object.freeze({
+ ...dmResponse,
+ ...permissionsResponse,
+ ...baseBlockResponse,
+ ...punishmentEntryRemove
+});
+
+export const timeoutResponse = Object.freeze({
+ ...dmResponse,
+ ...permissionsResponse,
+ INVALID_DURATION: 'duration too long'
+} as const);
+
+export const removeTimeoutResponse = Object.freeze({
+ ...dmResponse,
+ ...permissionsResponse
+} as const);
/**
* Response returned when warning a user.
*/
-export type WarnResponse = PunishmentResponse;
+export type WarnResponse = ValueOf<typeof warnResponse>;
/**
* Response returned when adding a role to a user.
*/
-export type AddRoleResponse =
- | Exclude<PunishmentResponse, 'failed to dm'>
- | 'user hierarchy'
- | 'role managed'
- | 'client hierarchy'
- | 'error creating role entry'
- | 'error adding role';
+export type AddRoleResponse = ValueOf<typeof addRoleResponse>;
/**
* Response returned when removing a role from a user.
*/
-export type RemoveRoleResponse =
- | Exclude<PunishmentResponse, 'failed to dm'>
- | 'user hierarchy'
- | 'role managed'
- | 'client hierarchy'
- | 'error removing role entry'
- | 'error removing role';
+export type RemoveRoleResponse = ValueOf<typeof removeRoleResponse>;
/**
* Response returned when muting a user.
*/
-export type MuteResponse =
- | PunishmentResponse
- | 'missing permissions'
- | 'no mute role'
- | 'invalid mute role'
- | 'mute role not manageable'
- | 'error giving mute role'
- | 'error creating mute entry';
+export type MuteResponse = ValueOf<typeof muteResponse>;
/**
* Response returned when unmuting a user.
*/
-export type UnmuteResponse =
- | PunishmentResponse
- | 'missing permissions'
- | 'no mute role'
- | 'invalid mute role'
- | 'mute role not manageable'
- | 'error removing mute role'
- | 'error removing mute entry';
+export type UnmuteResponse = ValueOf<typeof unmuteResponse>;
/**
* Response returned when kicking a user.
*/
-export type KickResponse = PunishmentResponse | 'missing permissions' | 'error kicking';
+export type KickResponse = ValueOf<typeof kickResponse>;
/**
* Response returned when banning a user.
*/
-export type BanResponse = PunishmentResponse | 'missing permissions' | 'error creating ban entry' | 'error banning';
+export type BanResponse = ValueOf<typeof banResponse>;
/**
* Response returned when blocking a user.
*/
-export type BlockResponse =
- | PunishmentResponse
- | 'invalid channel'
- | 'error creating block entry'
- | 'missing permissions'
- | 'error blocking';
+export type BlockResponse = ValueOf<typeof blockResponse>;
/**
* Response returned when unblocking a user.
*/
-export type UnblockResponse =
- | PunishmentResponse
- | 'invalid channel'
- | 'error removing block entry'
- | 'missing permissions'
- | 'error unblocking';
+export type UnblockResponse = ValueOf<typeof unblockResponse>;
/**
* Response returned when timing out a user.
*/
-export type TimeoutResponse = PunishmentResponse | 'missing permissions' | 'duration too long' | 'error timing out';
+export type TimeoutResponse = ValueOf<typeof timeoutResponse>;
/**
* Response returned when removing a timeout from a user.
*/
-export type RemoveTimeoutResponse = PunishmentResponse | 'missing permissions' | 'duration too long' | 'error removing timeout';
+export type RemoveTimeoutResponse = ValueOf<typeof removeTimeoutResponse>;
export type PartialBushGuildMember = Partialize<BushGuildMember, 'joinedAt' | 'joinedTimestamp'>;
diff --git a/src/lib/extensions/discord.js/BushSelectMenuInteraction.ts b/src/lib/extensions/discord.js/BushSelectMenuInteraction.ts
index 903b43f..23e2453 100644
--- a/src/lib/extensions/discord.js/BushSelectMenuInteraction.ts
+++ b/src/lib/extensions/discord.js/BushSelectMenuInteraction.ts
@@ -1,5 +1,5 @@
import type { BushClient, BushGuild, BushGuildMember, BushGuildTextBasedChannel, BushTextBasedChannel, BushUser } from '#lib';
-import type { APIInteractionGuildMember } from 'discord-api-types/v9';
+import type { APIInteractionGuildMember } from '@discordjs/builders/node_modules/discord-api-types';
import { SelectMenuInteraction, type CacheType, type CacheTypeReducer } from 'discord.js';
import type { RawMessageSelectMenuInteractionData } from 'discord.js/typings/rawDataTypes';
diff --git a/yarn.lock b/yarn.lock
index d0d0d71..2c7cd78 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -6,11 +6,11 @@ __metadata:
cacheKey: 8
"@babel/runtime@npm:^7.16.5":
- version: 7.16.5
- resolution: "@babel/runtime@npm:7.16.5"
+ version: 7.16.7
+ resolution: "@babel/runtime@npm:7.16.7"
dependencies:
regenerator-runtime: ^0.13.4
- checksum: b96e67280efe581c6147b4fe984dfe08a8fbea048934a092f3cbf4dcf61725f6b221cb0c879b6e6e98671f83a104c9e8cfbd24c683e5ebcc886a731aa8984ad0
+ checksum: 47912f0aaacd1cab2e2552aaf3e6eaffbcaf2d5ac9b07a89a12ac0d42029cb92c070b0d16f825e4277c4a34677c54d8ffe85e1f7c6feb57de58f700eec67ce2f
languageName: node
linkType: hard
@@ -461,10 +461,10 @@ __metadata:
languageName: node
linkType: hard
-"@types/node@npm:*, @types/node@npm:^17.0.5":
- version: 17.0.5
- resolution: "@types/node@npm:17.0.5"
- checksum: 105535e78722515c26cfdc1b0cbf1b19f55fe53b814e2e90d8b1e653bc63136d4760c7efc102eca111c6d124a291e37d60d761d569a3f4afb3fba05bad5d9ade
+"@types/node@npm:*, @types/node@npm:^17.0.8":
+ version: 17.0.8
+ resolution: "@types/node@npm:17.0.8"
+ checksum: f4cadeb9e602027520abc88c77142697e33cf6ac98bb02f8b595a398603cbd33df1f94d01c055c9f13cde0c8eaafc5e396ca72645458d42b4318b845bc7f1d0f
languageName: node
linkType: hard
@@ -568,12 +568,13 @@ __metadata:
languageName: node
linkType: hard
-"@typescript-eslint/eslint-plugin@npm:^5.8.1":
- version: 5.8.1
- resolution: "@typescript-eslint/eslint-plugin@npm:5.8.1"
+"@typescript-eslint/eslint-plugin@npm:^5.9.0":
+ version: 5.9.0
+ resolution: "@typescript-eslint/eslint-plugin@npm:5.9.0"
dependencies:
- "@typescript-eslint/experimental-utils": 5.8.1
- "@typescript-eslint/scope-manager": 5.8.1
+ "@typescript-eslint/experimental-utils": 5.9.0
+ "@typescript-eslint/scope-manager": 5.9.0
+ "@typescript-eslint/type-utils": 5.9.0
debug: ^4.3.2
functional-red-black-tree: ^1.0.1
ignore: ^5.1.8
@@ -586,66 +587,82 @@ __metadata:
peerDependenciesMeta:
typescript:
optional: true
- checksum: 9e5b5c1e22563fc0a31f1b916cea8b059b6dd218ccbf809b7453e4563065781e4544a6d5ce4cbf60b40394f2604e925d10cafd468a4dd0f490e75775267839a0
+ checksum: 31443d4331dddf7618d6b3fdbf148ec6d5ce7c64c85ec3973e520e633467d8d5605896f7eab9d7c6f81c050458c84bca10a6b0ed3537d48e6ee728f8b64d46a2
languageName: node
linkType: hard
-"@typescript-eslint/experimental-utils@npm:5.8.1, @typescript-eslint/experimental-utils@npm:^5.0.0":
- version: 5.8.1
- resolution: "@typescript-eslint/experimental-utils@npm:5.8.1"
+"@typescript-eslint/experimental-utils@npm:5.9.0, @typescript-eslint/experimental-utils@npm:^5.0.0":
+ version: 5.9.0
+ resolution: "@typescript-eslint/experimental-utils@npm:5.9.0"
dependencies:
"@types/json-schema": ^7.0.9
- "@typescript-eslint/scope-manager": 5.8.1
- "@typescript-eslint/types": 5.8.1
- "@typescript-eslint/typescript-estree": 5.8.1
+ "@typescript-eslint/scope-manager": 5.9.0
+ "@typescript-eslint/types": 5.9.0
+ "@typescript-eslint/typescript-estree": 5.9.0
eslint-scope: ^5.1.1
eslint-utils: ^3.0.0
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
- checksum: 15c17a7b7a45a9e1ebf537e6d6221e423c8f5114c0a517265698745b9a4ae965487ef7856a0b1ee64cbda8db641a9204270fda88398ab1d7013256e0ccbd3e75
+ checksum: 731b27840642b644e65f4ae321ed47e973ffadacd1aa24a19b02b4b298b5bcfbfa16c2d3d034e87a08c3c45f942c5b974f7619cb143eb23fb950f37418dce791
languageName: node
linkType: hard
-"@typescript-eslint/parser@npm:^5.8.1":
- version: 5.8.1
- resolution: "@typescript-eslint/parser@npm:5.8.1"
+"@typescript-eslint/parser@npm:^5.9.0":
+ version: 5.9.0
+ resolution: "@typescript-eslint/parser@npm:5.9.0"
dependencies:
- "@typescript-eslint/scope-manager": 5.8.1
- "@typescript-eslint/types": 5.8.1
- "@typescript-eslint/typescript-estree": 5.8.1
+ "@typescript-eslint/scope-manager": 5.9.0
+ "@typescript-eslint/types": 5.9.0
+ "@typescript-eslint/typescript-estree": 5.9.0
debug: ^4.3.2
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
peerDependenciesMeta:
typescript:
optional: true
- checksum: bb1702851ff0ade16a50789c517155557ad7e9b8e5e9c4553aad52fedbc8f94acaade1dc5ba12a96b54a13a68dfea13955ab885aad97cf3c526a8b90880bd8a3
+ checksum: ae95a7eb977b7bb4eec98357577b043d8ba48d47ae43ec18eadd350336b485ce91ac969b92e22143cc77797cc96cf37598d2bddcdd974d45fb3ec4f01b53b92a
languageName: node
linkType: hard
-"@typescript-eslint/scope-manager@npm:5.8.1":
- version: 5.8.1
- resolution: "@typescript-eslint/scope-manager@npm:5.8.1"
+"@typescript-eslint/scope-manager@npm:5.9.0":
+ version: 5.9.0
+ resolution: "@typescript-eslint/scope-manager@npm:5.9.0"
dependencies:
- "@typescript-eslint/types": 5.8.1
- "@typescript-eslint/visitor-keys": 5.8.1
- checksum: d9254018d723aff32fc512b7292737b154367198ab58e0faf814b4ce77d4de20552ed1678f2639b35e480eb5594eb9d5f1d34360885f5e4d80ca8e5a9ccf666c
+ "@typescript-eslint/types": 5.9.0
+ "@typescript-eslint/visitor-keys": 5.9.0
+ checksum: 46e7ab0cef558e7faf1aa8d122a265e196566c0073292f5b2f9cede1f63f52860be8e4ef90251c15e0922339c15852584cb5337382035baff87f1203c0c8d1b5
languageName: node
linkType: hard
-"@typescript-eslint/types@npm:5.8.1":
- version: 5.8.1
- resolution: "@typescript-eslint/types@npm:5.8.1"
- checksum: f9809c2c0f523841adeeb66410911f10492d3df7a912bc3d72304f4edbc5b5cb1a3f5f2a6ded20e8b524cc18e92d2a735fb8b96570e75df669061182932200ef
+"@typescript-eslint/type-utils@npm:5.9.0":
+ version: 5.9.0
+ resolution: "@typescript-eslint/type-utils@npm:5.9.0"
+ dependencies:
+ "@typescript-eslint/experimental-utils": 5.9.0
+ debug: ^4.3.2
+ tsutils: ^3.21.0
+ peerDependencies:
+ eslint: "*"
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ checksum: 787c3277e37f6bbd723ff10aec6ddc61a62860bd2b1d354c4a50c1aec9b479ee4f51be9fd1cdeac2e43e22161481e76409c00e6a4d50549ceaee0c59fc5cd73d
languageName: node
linkType: hard
-"@typescript-eslint/typescript-estree@npm:5.8.1":
- version: 5.8.1
- resolution: "@typescript-eslint/typescript-estree@npm:5.8.1"
+"@typescript-eslint/types@npm:5.9.0":
+ version: 5.9.0
+ resolution: "@typescript-eslint/types@npm:5.9.0"
+ checksum: 7c4e142600aec266b41418dab1d0cee8cace980b6990692df6522de6eab6705bf515aef36180e4a38c62acb10c92fb474269ac6856a4266d6b035068cd83fad3
+ languageName: node
+ linkType: hard
+
+"@typescript-eslint/typescript-estree@npm:5.9.0":
+ version: 5.9.0
+ resolution: "@typescript-eslint/typescript-estree@npm:5.9.0"
dependencies:
- "@typescript-eslint/types": 5.8.1
- "@typescript-eslint/visitor-keys": 5.8.1
+ "@typescript-eslint/types": 5.9.0
+ "@typescript-eslint/visitor-keys": 5.9.0
debug: ^4.3.2
globby: ^11.0.4
is-glob: ^4.0.3
@@ -654,17 +671,17 @@ __metadata:
peerDependenciesMeta:
typescript:
optional: true
- checksum: e3cfbd088f1e0104b5b38fcc6e400a0d0e72395694406357e478369c4df532aa2accfe2ee77c71854ca9a04e0e3cddbed86388334805c91ca4241b032cbb6d20
+ checksum: 71e3f720e335fb08e66950d32b723484aa4d1f4a3163e82259f4be2d11091545070c2e71472be470403cb6f82bf1abe84fa89c1d0b1d47adc8550b3f70aabfb5
languageName: node
linkType: hard
-"@typescript-eslint/visitor-keys@npm:5.8.1":
- version: 5.8.1
- resolution: "@typescript-eslint/visitor-keys@npm:5.8.1"
+"@typescript-eslint/visitor-keys@npm:5.9.0":
+ version: 5.9.0
+ resolution: "@typescript-eslint/visitor-keys@npm:5.9.0"
dependencies:
- "@typescript-eslint/types": 5.8.1
+ "@typescript-eslint/types": 5.9.0
eslint-visitor-keys: ^3.0.0
- checksum: 46567678718a227b34a255a3606e1a2c5190a470dc9493d4c175f57566d2c16b88780fb273ca44f22cab06d45d87b25371215e93b88ac10a475877bd64bdfece
+ checksum: 34a595b83b0e7d4f387d6c81b272804b94a1a91478c5f856fdfdd227595bf8562bf3f5d732606d10b4522c3f2617d09d4bacd2193f757a324ea66b3144a68903
languageName: node
linkType: hard
@@ -684,7 +701,7 @@ __metadata:
languageName: node
linkType: hard
-"acorn@npm:^8.6.0":
+"acorn@npm:^8.7.0":
version: 8.7.0
resolution: "acorn@npm:8.7.0"
bin:
@@ -703,13 +720,13 @@ __metadata:
linkType: hard
"agentkeepalive@npm:^4.1.3":
- version: 4.1.4
- resolution: "agentkeepalive@npm:4.1.4"
+ version: 4.2.0
+ resolution: "agentkeepalive@npm:4.2.0"
dependencies:
debug: ^4.1.0
depd: ^1.1.2
humanize-ms: ^1.2.1
- checksum: d49c24d4b333e9507119385895a583872f4f53d62764a89be165926e824056a126955bae4a6d3c6f7cd26f4089621a40f7b27675f7868214d82118f744b9e82d
+ checksum: 89806f83ceebbcaabf6bd581a8dce4870910fd2a11f66df8f505b4cd4ce4ca5ab9e6eec8d11ce8531a6b60f6748b75b0775e0e2fa33871503ef00d535418a19a
languageName: node
linkType: hard
@@ -851,7 +868,7 @@ __metadata:
"@types/eslint": ^8
"@types/express": ^4.17.13
"@types/lodash": ^4.14.178
- "@types/node": ^17.0.5
+ "@types/node": ^17.0.8
"@types/node-os-utils": ^1.2.0
"@types/numeral": ^2.0.2
"@types/pg": ^8
@@ -860,15 +877,15 @@ __metadata:
"@types/source-map-support": ^0
"@types/tinycolor2": ^1.4.3
"@types/validator": ^13.7.1
- "@typescript-eslint/eslint-plugin": ^5.8.1
- "@typescript-eslint/parser": ^5.8.1
+ "@typescript-eslint/eslint-plugin": ^5.9.0
+ "@typescript-eslint/parser": ^5.9.0
canvas: ^2.8.0
chalk: ^5.0.0
deep-lock: ^1.0.0
discord-akairo: "npm:@notenoughupdates/discord-akairo@dev"
discord-api-types: 0.26.0
discord.js: "npm:@notenoughupdates/discord.js@dev"
- eslint: ^8.5.0
+ eslint: ^8.6.0
eslint-config-prettier: ^8.3.0
eslint-plugin-deprecation: ^1.3.2
fuse.js: ^6.5.3
@@ -884,7 +901,7 @@ __metadata:
prettier: ^2.5.1
pretty-bytes: ^5.6.0
rimraf: ^3.0.2
- sequelize: ^6.12.4
+ sequelize: ^6.12.5
source-map-support: ^0.5.21
tinycolor2: ^1.4.2
tslib: ^2.3.1
@@ -1179,16 +1196,23 @@ __metadata:
languageName: node
linkType: hard
-"discord-api-types@npm:0.26.0, discord-api-types@npm:^0.26.0":
+"discord-api-types@npm:0.26.0":
version: 0.26.0
resolution: "discord-api-types@npm:0.26.0"
checksum: 5c2a3f7309fec3830a8da5e98e5260b25304512ae856c770d783492aa4a8c514a64025bb30ceda0c4381bc749db9545c0d7d5573fa0d60bb1718add27c8b4d7d
languageName: node
linkType: hard
+"discord-api-types@npm:^0.26.0":
+ version: 0.26.1
+ resolution: "discord-api-types@npm:0.26.1"
+ checksum: e53bfa7589b24108e6b403dbe213da34c4592f72e2b8fde6800dcb6c703065887ecbd644e1cdf694e4c7796954bc51462ced868f26ec45dc1e0dc4fa8d3c723c
+ languageName: node
+ linkType: hard
+
"discord.js@npm:@notenoughupdates/discord.js@dev":
- version: 14.0.0-dev.1640799852.127ddf6
- resolution: "@notenoughupdates/discord.js@npm:14.0.0-dev.1640799852.127ddf6"
+ version: 14.0.0-dev.1641470979.127ddf6
+ resolution: "@notenoughupdates/discord.js@npm:14.0.0-dev.1641470979.127ddf6"
dependencies:
"@discordjs/builders": ^0.11.0
"@discordjs/collection": ^0.4.0
@@ -1199,7 +1223,7 @@ __metadata:
form-data: ^4.0.0
node-fetch: ^2.6.1
ws: ^8.4.0
- checksum: 2b00905ffcdfabb0158b6be4cfdf00727a9b58c715bd3b627f17cff2a2ed6ce2333ffed64ae0edba45bee7b7e466c0f621792b8be41bceb4d8f709d269f5ab30
+ checksum: 822d334638cb08bbd0dc42b3a40f9468b3983dac214e14f8fb2169e8051a5b9265ffb1226e78a7d0372f6b2bf7461dd18e84c1cb695f6b164d8a9811bdcc4e24
languageName: node
linkType: hard
@@ -1351,9 +1375,9 @@ __metadata:
languageName: node
linkType: hard
-"eslint@npm:^8.5.0":
- version: 8.5.0
- resolution: "eslint@npm:8.5.0"
+"eslint@npm:^8.6.0":
+ version: 8.6.0
+ resolution: "eslint@npm:8.6.0"
dependencies:
"@eslint/eslintrc": ^1.0.5
"@humanwhocodes/config-array": ^0.9.2
@@ -1367,7 +1391,7 @@ __metadata:
eslint-scope: ^7.1.0
eslint-utils: ^3.0.0
eslint-visitor-keys: ^3.1.0
- espree: ^9.2.0
+ espree: ^9.3.0
esquery: ^1.4.0
esutils: ^2.0.2
fast-deep-equal: ^3.1.3
@@ -1395,18 +1419,18 @@ __metadata:
v8-compile-cache: ^2.0.3
bin:
eslint: bin/eslint.js
- checksum: c1a9e26070520a308cc30b62ba0d37d5b115ed23987a93219819537bdea9398e6ebe57c27d97be36ecc83b5162c72e82ecb0a9e5b44b7992980f9be90eb5c4b3
+ checksum: 19ed82fa872ebb45d0f10c2514975b85ab37e78e9b562a5aa3abdbe7802111d65f7d5a8563e394a975337b403163b40624c2cc8bfa585a061e8c7dc55def39b5
languageName: node
linkType: hard
-"espree@npm:^9.2.0":
- version: 9.2.0
- resolution: "espree@npm:9.2.0"
+"espree@npm:^9.2.0, espree@npm:^9.3.0":
+ version: 9.3.0
+ resolution: "espree@npm:9.3.0"
dependencies:
- acorn: ^8.6.0
+ acorn: ^8.7.0
acorn-jsx: ^5.3.1
eslint-visitor-keys: ^3.1.0
- checksum: ae533a058036e3efeeac43a0ee39c74ab347e2a73bbe2946fba33cc0d84aca657e675bc317ed9afd95338f79d5d5a862afec2f717d2539ae13fa9f1638371761
+ checksum: c0f1885c4eab652f9be08eb9228cea0df046b559b29d4aed8d6590ea9bd60177d4cb245d204a6f737a79a096861bb4ab8e480aeb8c1dbafef5beec1157353ce4
languageName: node
linkType: hard
@@ -1720,9 +1744,9 @@ __metadata:
linkType: hard
"graceful-fs@npm:^4.2.6":
- version: 4.2.8
- resolution: "graceful-fs@npm:4.2.8"
- checksum: 5d224c8969ad0581d551dfabdb06882706b31af2561bd5e2034b4097e67cc27d05232849b8643866585fd0a41c7af152950f8776f4dd5579e9853733f31461c6
+ version: 4.2.9
+ resolution: "graceful-fs@npm:4.2.9"
+ checksum: 68ea4e07ff2c041ada184f9278b830375f8e0b75154e3f080af6b70f66172fabb4108d19b3863a96b53fc068a310b9b6493d86d1291acc5f3861eb4b79d26ad6
languageName: node
linkType: hard
@@ -2549,9 +2573,9 @@ __metadata:
linkType: hard
"picomatch@npm:^2.2.3":
- version: 2.3.0
- resolution: "picomatch@npm:2.3.0"
- checksum: 16818720ea7c5872b6af110760dee856c8e4cd79aed1c7a006d076b1cc09eff3ae41ca5019966694c33fbd2e1cc6ea617ab10e4adac6df06556168f13be3fca2
+ version: 2.3.1
+ resolution: "picomatch@npm:2.3.1"
+ checksum: 050c865ce81119c4822c45d3c84f1ced46f93a0126febae20737bd05ca20589c564d6e9226977df859ed5e03dc73f02584a2b0faad36e896936238238b0446cf
languageName: node
linkType: hard
@@ -2800,9 +2824,9 @@ __metadata:
languageName: node
linkType: hard
-"sequelize@npm:^6.12.4":
- version: 6.12.4
- resolution: "sequelize@npm:6.12.4"
+"sequelize@npm:^6.12.5":
+ version: 6.12.5
+ resolution: "sequelize@npm:6.12.5"
dependencies:
"@types/debug": ^4.1.7
debug: ^4.3.3
@@ -2836,7 +2860,7 @@ __metadata:
optional: true
tedious:
optional: true
- checksum: bf781ea640627cb8f32bcc3521ad100c98cca0f77ac1f0bffeaaa1bb5f15dff200c5e225d752f9c7fc8824f3f1885d3d4944f5a31b990008684eedc19e805059
+ checksum: b347e31d18935e58811d276497131cd51e94a392bb7b89577055fd322642c216a653ed348123ab456c839dcb7e188e658140f177ad35cfdb3c985eda209d9ead
languageName: node
linkType: hard