aboutsummaryrefslogtreecommitdiff
path: root/lib/extensions/discord.js/ExtendedGuildMember.ts
diff options
context:
space:
mode:
Diffstat (limited to 'lib/extensions/discord.js/ExtendedGuildMember.ts')
-rw-r--r--lib/extensions/discord.js/ExtendedGuildMember.ts508
1 files changed, 260 insertions, 248 deletions
diff --git a/lib/extensions/discord.js/ExtendedGuildMember.ts b/lib/extensions/discord.js/ExtendedGuildMember.ts
index b11e9e3..8cfd4f6 100644
--- a/lib/extensions/discord.js/ExtendedGuildMember.ts
+++ b/lib/extensions/discord.js/ExtendedGuildMember.ts
@@ -42,51 +42,51 @@ interface Extension {
* Warn the user, create a modlog entry, and send a dm to the user.
* @param options Options for warning the user.
* @returns An object with the result of the warning, and the case number of the warn.
- * @emits {@link BotClientEvents.warnMember}
+ * @emits {@link TanzaniteEvent.Warn}
*/
customWarn(options: CustomPunishmentOptions): Promise<{ result: WarnResponse; caseNum: number | null }>;
/**
* Add a role to the user, if it is a punishment create a modlog entry, and create a punishment entry if it is temporary or a punishment.
* @param options Options for adding a role to the user.
* @returns A status message for adding the add.
- * @emits {@link BotClientEvents.punishRole}
+ * @emits {@link TanzaniteEvent.PunishRoleAdd}
*/
customAddRole(options: AddRoleOptions): Promise<AddRoleResponse>;
/**
* Remove a role from the user, if it is a punishment create a modlog entry, and destroy a punishment entry if it was temporary or a punishment.
* @param options Options for removing a role from the user.
* @returns A status message for removing the role.
- * @emits {@link BotClientEvents.punishRoleRemove}
+ * @emits {@link TanzaniteEvent.PunishRoleRemove}
*/
customRemoveRole(options: RemoveRoleOptions): Promise<RemoveRoleResponse>;
/**
* Mute the user, create a modlog entry, creates a punishment entry, and dms the user.
* @param options Options for muting the user.
* @returns A status message for muting the user.
- * @emits {@link BotClientEvents.customMute}
+ * @emits {@link TanzaniteEvent.Mute}
*/
customMute(options: CustomTimedPunishmentOptions): Promise<MuteResponse>;
/**
* Unmute the user, create a modlog entry, remove the punishment entry, and dm the user.
* @param options Options for unmuting the user.
* @returns A status message for unmuting the user.
- * @emits {@link BotClientEvents.customUnmute}
+ * @emits {@link TanzaniteEvent.Unmute}
*/
customUnmute(options: CustomPunishmentOptions): Promise<UnmuteResponse>;
/**
* Kick the user, create a modlog entry, and dm the user.
* @param options Options for kicking the user.
* @returns A status message for kicking the user.
- * @emits {@link BotClientEvents.customKick}
+ * @emits {@link TanzaniteEvent.Kick}
*/
customKick(options: CustomPunishmentOptions): Promise<KickResponse>;
/**
* Ban the user, create a modlog entry, create a punishment entry, and dm the user.
* @param options Options for banning the user.
* @returns A status message for banning the user.
- * @emits {@link BotClientEvents.customBan}
+ * @emits {@link TanzaniteEvent.Ban}
*/
- customBan(options: CustomBanOptions): Promise<Exclude<BanResponse, typeof banResponse['ALREADY_BANNED']>>;
+ customBan(options: CustomBanOptions): Promise<Exclude<BanResponse, typeof banResponse['AlreadyBanned']>>;
/**
* Prevents a user from speaking in a channel.
* @param options Options for blocking the user.
@@ -124,6 +124,34 @@ declare module 'discord.js' {
}
export class ExtendedGuildMember extends GuildMember implements Extension {
+ /**
+ * Sets the default values for the options.
+ */
+ #optionDefaults<T extends CustomPunishmentOptions>(options: T): T {
+ options.noDM ??= options.silent ?? false;
+ return options;
+ }
+
+ /**
+ * Check whether or not a role should be added/removed from the user based on hierarchy.
+ * @param role The role to check if can be modified.
+ * @param moderator The moderator that is trying to add/remove the role.
+ * @returns `true` if the role should be added/removed or a string for the reason why it shouldn't.
+ */
+ #checkIfShouldAddRole(
+ role: Role | Role,
+ moderator?: GuildMember
+ ): true | 'user hierarchy' | 'role managed' | 'client hierarchy' {
+ if (moderator && moderator.roles.highest.position <= role.position && this.guild.ownerId !== this.user.id) {
+ return shouldAddRoleResponse.UserHierarchy;
+ } else if (role.managed) {
+ return shouldAddRoleResponse.RoleManaged;
+ } else if (this.guild.members.me!.roles.highest.position <= role.position) {
+ return shouldAddRoleResponse.ClientHierarchy;
+ }
+ return true;
+ }
+
public override async customPunishDM(
punishment: Action,
reason?: string | null,
@@ -144,10 +172,12 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
}
public override async customWarn(options: CustomPunishmentOptions): Promise<{ result: WarnResponse; caseNum: number | null }> {
- let caseID: string | undefined = undefined;
- let dmSuccessEvent: boolean | undefined = undefined;
+ options = this.#optionDefaults(options);
+
+ let caseID: string | null = null;
+ let dmSuccess: boolean | null = null;
const moderator = await this.client.utils.resolveNonCachedUser(options.moderator ?? this.guild.members.me);
- if (!moderator) return { result: warnResponse.CANNOT_RESOLVE_USER, caseNum: null };
+ if (!moderator) return { result: warnResponse.CannotResolveUser, caseNum: null };
const ret = await (async (): Promise<{ result: WarnResponse; caseNum: number | null }> => {
// add modlog entry
@@ -164,32 +194,33 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
},
true
);
- caseID = result.log?.id;
- if (!result || !result.log) return { result: warnResponse.MODLOG_ERROR, caseNum: null };
- if (!options.silent) {
+ caseID = result.log?.id ?? null;
+ if (!result || !result.log) return { result: warnResponse.ModlogError, caseNum: null };
+
+ if (!options.noDM) {
// dm user
- const dmSuccess = await this.customPunishDM(Action.Warn, options.reason);
- dmSuccessEvent = dmSuccess;
- if (!dmSuccess) return { result: warnResponse.DM_ERROR, caseNum: result.caseNum };
+ dmSuccess = await this.customPunishDM(Action.Warn, options.reason);
+
+ if (dmSuccess === false) return { result: warnResponse.DmError, caseNum: result.caseNum };
}
- return { result: warnResponse.SUCCESS, caseNum: result.caseNum };
+ return { result: warnResponse.Success, caseNum: result.caseNum };
})();
- if (!([warnResponse.MODLOG_ERROR] as const).includes(ret.result) && !options.silent)
- this.client.emit(TanzaniteEvent.Warn, this, moderator, this.guild, options.reason ?? undefined, caseID!, dmSuccessEvent!);
+ if (!([warnResponse.ModlogError] as const).includes(ret.result) && !options.silent)
+ this.client.emit(TanzaniteEvent.Warn, this, moderator, this.guild, options.reason ?? undefined, caseID!, dmSuccess);
return ret;
}
public override async customAddRole(options: AddRoleOptions): Promise<AddRoleResponse> {
// checks
- if (!this.guild.members.me!.permissions.has(PermissionFlagsBits.ManageRoles)) return addRoleResponse.MISSING_PERMISSIONS;
+ if (!this.guild.members.me!.permissions.has(PermissionFlagsBits.ManageRoles)) return roleResponse.MissingPermissions;
const ifShouldAddRole = this.#checkIfShouldAddRole(options.role, options.moderator);
if (ifShouldAddRole !== true) return ifShouldAddRole;
- let caseID: string | undefined = undefined;
+ let caseID: string | null = null;
const moderator = await this.client.utils.resolveNonCachedUser(options.moderator ?? this.guild.members.me);
- if (!moderator) return addRoleResponse.CANNOT_RESOLVE_USER;
+ if (!moderator) return roleResponse.CannotResolveUser;
const ret = await (async () => {
if (options.addToModlog || options.duration) {
@@ -205,7 +236,7 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
hidden: options.silent ?? false
});
- if (!modlog) return addRoleResponse.MODLOG_ERROR;
+ if (!modlog) return roleResponse.ModlogError;
caseID = modlog.id;
if (options.addToModlog || options.duration) {
@@ -218,19 +249,17 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
duration: options.duration,
extraInfo: options.role.id
});
- if (!punishmentEntrySuccess) return addRoleResponse.PUNISHMENT_ENTRY_ADD_ERROR;
+ if (!punishmentEntrySuccess) return roleResponse.PunishmentEntryError;
}
}
const removeRoleSuccess = await this.roles.add(options.role, `${moderator.tag}`);
- if (!removeRoleSuccess) return addRoleResponse.ACTION_ERROR;
+ if (!removeRoleSuccess) return roleResponse.ActionError;
- return addRoleResponse.SUCCESS;
+ return roleResponse.Success;
})();
if (
- !(
- [addRoleResponse.ACTION_ERROR, addRoleResponse.MODLOG_ERROR, addRoleResponse.PUNISHMENT_ENTRY_ADD_ERROR] as const
- ).includes(ret) &&
+ !([roleResponse.ActionError, roleResponse.ModlogError, roleResponse.PunishmentEntryError] as const).includes(ret) &&
options.addToModlog &&
!options.silent
)
@@ -250,13 +279,13 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
public override async customRemoveRole(options: RemoveRoleOptions): Promise<RemoveRoleResponse> {
// checks
- if (!this.guild.members.me!.permissions.has(PermissionFlagsBits.ManageRoles)) return removeRoleResponse.MISSING_PERMISSIONS;
+ if (!this.guild.members.me!.permissions.has(PermissionFlagsBits.ManageRoles)) return roleResponse.MissingPermissions;
const ifShouldAddRole = this.#checkIfShouldAddRole(options.role, options.moderator);
if (ifShouldAddRole !== true) return ifShouldAddRole;
let caseID: string | undefined = undefined;
const moderator = await this.client.utils.resolveNonCachedUser(options.moderator ?? this.guild.members.me);
- if (!moderator) return removeRoleResponse.CANNOT_RESOLVE_USER;
+ if (!moderator) return roleResponse.CannotResolveUser;
const ret = await (async () => {
if (options.addToModlog) {
@@ -271,7 +300,7 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
hidden: options.silent ?? false
});
- if (!modlog) return removeRoleResponse.MODLOG_ERROR;
+ if (!modlog) return roleResponse.ModlogError;
caseID = modlog.id;
const punishmentEntrySuccess = await removePunishmentEntry({
@@ -282,26 +311,20 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
extraInfo: options.role.id
});
- if (!punishmentEntrySuccess) return removeRoleResponse.PUNISHMENT_ENTRY_REMOVE_ERROR;
+ if (!punishmentEntrySuccess) return roleResponse.PunishmentEntryError;
}
const removeRoleSuccess = await this.roles.remove(options.role, `${moderator.tag}`);
- if (!removeRoleSuccess) return removeRoleResponse.ACTION_ERROR;
+ if (!removeRoleSuccess) return roleResponse.ActionError;
- return removeRoleResponse.SUCCESS;
+ return roleResponse.Success;
})();
- if (
- !(
- [
- removeRoleResponse.ACTION_ERROR,
- removeRoleResponse.MODLOG_ERROR,
- removeRoleResponse.PUNISHMENT_ENTRY_REMOVE_ERROR
- ] as const
- ).includes(ret) &&
- options.addToModlog &&
- !options.silent
- )
+ const nonSuccess = (
+ [roleResponse.ActionError, roleResponse.ModlogError, roleResponse.PunishmentEntryError] as const
+ ).includes(ret);
+
+ if (!nonSuccess && options.addToModlog && !options.silent) {
this.client.emit(
TanzaniteEvent.PunishRoleRemove,
this,
@@ -312,30 +335,13 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
options.role,
options.evidence
);
- return ret;
- }
-
- /**
- * Check whether or not a role should be added/removed from the user based on hierarchy.
- * @param role The role to check if can be modified.
- * @param moderator The moderator that is trying to add/remove the role.
- * @returns `true` if the role should be added/removed or a string for the reason why it shouldn't.
- */
- #checkIfShouldAddRole(
- role: Role | Role,
- moderator?: GuildMember
- ): true | 'user hierarchy' | 'role managed' | 'client hierarchy' {
- if (moderator && moderator.roles.highest.position <= role.position && this.guild.ownerId !== this.user.id) {
- return shouldAddRoleResponse.USER_HIERARCHY;
- } else if (role.managed) {
- return shouldAddRoleResponse.ROLE_MANAGED;
- } else if (this.guild.members.me!.roles.highest.position <= role.position) {
- return shouldAddRoleResponse.CLIENT_HIERARCHY;
}
- return true;
+ return ret;
}
public override async customMute(options: CustomTimedPunishmentOptions): Promise<MuteResponse> {
+ options = this.#optionDefaults(options);
+
// checks
const checks = await checkMutePermissions(this.guild);
if (checks !== true) return checks;
@@ -343,10 +349,10 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
const muteRoleID = (await this.guild.getSetting('muteRole'))!;
const muteRole = this.guild.roles.cache.get(muteRoleID)!;
- let caseID: string | undefined = undefined;
- let dmSuccessEvent: boolean | undefined = undefined;
+ let caseID: string | null = null;
+ let dmSuccess: boolean | null = null;
const moderator = await this.client.utils.resolveNonCachedUser(options.moderator ?? this.guild.members.me);
- if (!moderator) return muteResponse.CANNOT_RESOLVE_USER;
+ if (!moderator) return muteResponse.CannotResolveUser;
const ret = await (async () => {
// add role
@@ -357,7 +363,7 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
this.client.console.debug(e);
return false;
});
- if (!muteSuccess) return muteResponse.ACTION_ERROR;
+ if (!muteSuccess) return muteResponse.ActionError;
// add modlog entry
const { log: modlog } = await createModLogEntry({
@@ -372,7 +378,7 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
hidden: options.silent ?? false
});
- if (!modlog) return muteResponse.MODLOG_ERROR;
+ if (!modlog) return muteResponse.ModlogError;
caseID = modlog.id;
// add punishment entry so they can be unmuted later
@@ -385,20 +391,20 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
modlog: modlog.id
});
- if (!punishmentEntrySuccess) return muteResponse.PUNISHMENT_ENTRY_ADD_ERROR;
+ if (!punishmentEntrySuccess) return muteResponse.PunishmentEntryError;
- if (!options.silent) {
+ if (!options.noDM) {
// dm user
- const dmSuccess = await this.customPunishDM(Action.Mute, options.reason, options.duration ?? 0, modlog.id);
- dmSuccessEvent = dmSuccess;
- if (!dmSuccess) return muteResponse.DM_ERROR;
+ dmSuccess = await this.customPunishDM(Action.Mute, options.reason, options.duration ?? 0, modlog.id);
+
+ if (dmSuccess === false) return muteResponse.DmError;
}
- return muteResponse.SUCCESS;
+ return muteResponse.Success;
})();
if (
- !([muteResponse.ACTION_ERROR, muteResponse.MODLOG_ERROR, muteResponse.PUNISHMENT_ENTRY_ADD_ERROR] as const).includes(ret) &&
+ !([muteResponse.ActionError, muteResponse.ModlogError, muteResponse.PunishmentEntryError] as const).includes(ret) &&
!options.silent
)
this.client.emit(
@@ -409,13 +415,15 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
options.reason ?? undefined,
caseID!,
options.duration ?? 0,
- dmSuccessEvent!,
+ dmSuccess,
options.evidence
);
return ret;
}
public override async customUnmute(options: CustomPunishmentOptions): Promise<UnmuteResponse> {
+ options = this.#optionDefaults(options);
+
// checks
const checks = await checkMutePermissions(this.guild);
if (checks !== true) return checks;
@@ -423,10 +431,10 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
const muteRoleID = (await this.guild.getSetting('muteRole'))!;
const muteRole = this.guild.roles.cache.get(muteRoleID)!;
- let caseID: string | undefined = undefined;
- let dmSuccessEvent: boolean | undefined = undefined;
+ let caseID: string | null = null;
+ let dmSuccess: boolean | null = null;
const moderator = await this.client.utils.resolveNonCachedUser(options.moderator ?? this.guild.members.me);
- if (!moderator) return unmuteResponse.CANNOT_RESOLVE_USER;
+ if (!moderator) return unmuteResponse.CannotResolveUser;
const ret = await (async () => {
// remove role
@@ -436,7 +444,7 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
await this.client.console.warn('muteRoleAddError', formatError(e, true));
return false;
});
- if (!muteSuccess) return unmuteResponse.ACTION_ERROR;
+ if (!muteSuccess) return unmuteResponse.ActionError;
// add modlog entry
const { log: modlog } = await createModLogEntry({
@@ -450,7 +458,7 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
hidden: options.silent ?? false
});
- if (!modlog) return unmuteResponse.MODLOG_ERROR;
+ if (!modlog) return unmuteResponse.ModlogError;
caseID = modlog.id;
// remove mute entry
@@ -461,22 +469,20 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
guild: this.guild
});
- if (!removePunishmentEntrySuccess) return unmuteResponse.PUNISHMENT_ENTRY_REMOVE_ERROR;
+ if (!removePunishmentEntrySuccess) return unmuteResponse.PunishmentEntryError;
- if (!options.silent) {
+ if (!options.noDM) {
// dm user
- const dmSuccess = await this.customPunishDM(Action.Unmute, options.reason, undefined, '', false);
- dmSuccessEvent = dmSuccess;
- if (!dmSuccess) return unmuteResponse.DM_ERROR;
+ dmSuccess = await this.customPunishDM(Action.Unmute, options.reason, undefined, '', false);
+
+ if (dmSuccess === false) return unmuteResponse.DmError;
}
- return unmuteResponse.SUCCESS;
+ return unmuteResponse.Success;
})();
if (
- !(
- [unmuteResponse.ACTION_ERROR, unmuteResponse.MODLOG_ERROR, unmuteResponse.PUNISHMENT_ENTRY_REMOVE_ERROR] as const
- ).includes(ret) &&
+ !([unmuteResponse.ActionError, unmuteResponse.ModlogError, unmuteResponse.PunishmentEntryError] as const).includes(ret) &&
!options.silent
)
this.client.emit(
@@ -486,21 +492,23 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
this.guild,
options.reason ?? undefined,
caseID!,
- dmSuccessEvent!,
+ dmSuccess,
options.evidence
);
return ret;
}
public override async customKick(options: CustomPunishmentOptions): Promise<KickResponse> {
+ options = this.#optionDefaults(options);
+
// checks
if (!this.guild.members.me?.permissions.has(PermissionFlagsBits.KickMembers) || !this.kickable)
- return kickResponse.MISSING_PERMISSIONS;
+ return kickResponse.MissingPermissions;
- let caseID: string | undefined = undefined;
- let dmSuccessEvent: boolean | undefined = undefined;
+ let caseID: string | null = null;
+ let dmSuccess: boolean | null = null;
const moderator = await this.client.utils.resolveNonCachedUser(options.moderator ?? this.guild.members.me);
- if (!moderator) return kickResponse.CANNOT_RESOLVE_USER;
+ if (!moderator) return kickResponse.CannotResolveUser;
const ret = await (async () => {
// add modlog entry
const { log: modlog } = await createModLogEntry({
@@ -513,21 +521,26 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
evidence: options.evidence,
hidden: options.silent ?? false
});
- if (!modlog) return kickResponse.MODLOG_ERROR;
+ if (!modlog) return kickResponse.ModlogError;
caseID = modlog.id;
// dm user
- const dmSuccess = options.silent ? null : await this.customPunishDM(Action.Kick, options.reason, undefined, modlog.id);
- dmSuccessEvent = dmSuccess ?? undefined;
+ if (!options.noDM) {
+ dmSuccess = await this.customPunishDM(Action.Kick, options.reason, undefined, modlog.id);
+ }
// kick
const kickSuccess = await this.kick(`${moderator?.tag} | ${options.reason ?? 'No reason provided.'}`).catch(() => false);
- if (!kickSuccess) return kickResponse.ACTION_ERROR;
- if (dmSuccess === false) return kickResponse.DM_ERROR;
- return kickResponse.SUCCESS;
+ if (!kickSuccess) return kickResponse.ActionError;
+
+ if (!options.noDM && dmSuccess === false) {
+ return kickResponse.DmError;
+ }
+
+ return kickResponse.Success;
})();
- if (!([kickResponse.ACTION_ERROR, kickResponse.MODLOG_ERROR] as const).includes(ret) && !options.silent)
+ if (!([kickResponse.ActionError, kickResponse.ModlogError] as const).includes(ret) && !options.silent)
this.client.emit(
TanzaniteEvent.Kick,
this,
@@ -535,23 +548,23 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
this.guild,
options.reason ?? undefined,
caseID!,
- dmSuccessEvent!,
+ dmSuccess,
options.evidence
);
return ret;
}
- public override async customBan(
- options: CustomBanOptions
- ): Promise<Exclude<BanResponse, typeof banResponse['ALREADY_BANNED']>> {
+ public override async customBan(options: CustomBanOptions): Promise<Exclude<BanResponse, typeof banResponse['AlreadyBanned']>> {
+ options = this.#optionDefaults(options);
+
// checks
if (!this.guild.members.me!.permissions.has(PermissionFlagsBits.BanMembers) || !this.bannable)
- return banResponse.MISSING_PERMISSIONS;
+ return banResponse.MissingPermissions;
- let caseID: string | undefined = undefined;
- let dmSuccessEvent: boolean | undefined = undefined;
+ let caseID: string | null = null;
+ let dmSuccess: boolean | null = null;
const moderator = await this.client.utils.resolveNonCachedUser(options.moderator ?? this.guild.members.me);
- if (!moderator) return banResponse.CANNOT_RESOLVE_USER;
+ if (!moderator) return banResponse.CannotResolveUser;
// ignore result, they should still be banned even if their mute cannot be removed
await this.customUnmute({
@@ -573,21 +586,20 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
evidence: options.evidence,
hidden: options.silent ?? false
});
- if (!modlog) return banResponse.MODLOG_ERROR;
+ if (!modlog) return banResponse.ModlogError;
caseID = modlog.id;
- // dm user
- const dmSuccess = options.silent
- ? null
- : await this.customPunishDM(Action.Ban, options.reason, options.duration ?? 0, modlog.id);
- dmSuccessEvent = dmSuccess ?? undefined;
+ if (!options.noDM) {
+ // dm user
+ dmSuccess = await this.customPunishDM(Action.Ban, options.reason, options.duration ?? 0, modlog.id);
+ }
// ban
const banSuccess = await this.ban({
reason: `${moderator.tag} | ${options.reason ?? 'No reason provided.'}`,
deleteMessageDays: options.deleteDays
}).catch(() => false);
- if (!banSuccess) return banResponse.ACTION_ERROR;
+ if (!banSuccess) return banResponse.ActionError;
// add punishment entry so they can be unbanned later
const punishmentEntrySuccess = await createPunishmentEntry({
@@ -598,13 +610,16 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
duration: options.duration,
modlog: modlog.id
});
- if (!punishmentEntrySuccess) return banResponse.PUNISHMENT_ENTRY_ADD_ERROR;
+ if (!punishmentEntrySuccess) return banResponse.PunishmentEntryError;
- if (!dmSuccess) return banResponse.DM_ERROR;
- return banResponse.SUCCESS;
+ if (!options.noDM && dmSuccess === false) {
+ return banResponse.DmError;
+ }
+
+ return banResponse.Success;
})();
if (
- !([banResponse.ACTION_ERROR, banResponse.MODLOG_ERROR, banResponse.PUNISHMENT_ENTRY_ADD_ERROR] as const).includes(ret) &&
+ !([banResponse.ActionError, banResponse.ModlogError, banResponse.PunishmentEntryError] as const).includes(ret) &&
!options.silent
)
this.client.emit(
@@ -615,24 +630,26 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
options.reason ?? undefined,
caseID!,
options.duration ?? 0,
- dmSuccessEvent!,
+ dmSuccess,
options.evidence
);
return ret;
}
public override async customBlock(options: BlockOptions): Promise<BlockResponse> {
+ options = this.#optionDefaults(options);
+
const channel = this.guild.channels.resolve(options.channel);
- if (!channel || (!channel.isTextBased() && !channel.isThread())) return blockResponse.INVALID_CHANNEL;
+ if (!channel || (!channel.isTextBased() && !channel.isThread())) return blockResponse.InvalidChannel;
// checks
if (!channel.permissionsFor(this.guild.members.me!)!.has(PermissionFlagsBits.ManageChannels))
- return blockResponse.MISSING_PERMISSIONS;
+ return blockResponse.MissingPermissions;
- let caseID: string | undefined = undefined;
- let dmSuccessEvent: boolean | undefined = undefined;
+ let caseID: string | null = null;
+ let dmSuccess: boolean | null = null;
const moderator = await this.client.utils.resolveNonCachedUser(options.moderator ?? this.guild.members.me);
- if (!moderator) return blockResponse.CANNOT_RESOLVE_USER;
+ if (!moderator) return blockResponse.CannotResolveUser;
const ret = await (async () => {
// change channel permissions
@@ -641,7 +658,7 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
const blockSuccess = await channelToUse.permissionOverwrites
.edit(this, perm, { reason: `[Block] ${moderator.tag} | ${options.reason ?? 'No reason provided.'}` })
.catch(() => false);
- if (!blockSuccess) return blockResponse.ACTION_ERROR;
+ if (!blockSuccess) return blockResponse.ActionError;
// add modlog entry
const { log: modlog } = await createModLogEntry({
@@ -654,7 +671,7 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
evidence: options.evidence,
hidden: options.silent ?? false
});
- if (!modlog) return blockResponse.MODLOG_ERROR;
+ if (!modlog) return blockResponse.ModlogError;
caseID = modlog.id;
// add punishment entry so they can be unblocked later
@@ -667,32 +684,29 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
modlog: modlog.id,
extraInfo: channel.id
});
- if (!punishmentEntrySuccess) return blockResponse.PUNISHMENT_ENTRY_ADD_ERROR;
+ if (!punishmentEntrySuccess) return blockResponse.PunishmentEntryError;
- // dm user
- const dmSuccess = options.silent
- ? null
- : await punishDM({
- client: this.client,
- punishment: Action.Block,
- reason: options.reason ?? undefined,
- duration: options.duration ?? 0,
- modlog: modlog.id,
- guild: this.guild,
- user: this,
- sendFooter: true,
- channel: channel.id
- });
- dmSuccessEvent = !!dmSuccess;
- if (!dmSuccess) return blockResponse.DM_ERROR;
+ if (!options.noDM) {
+ // dm user
+ dmSuccess = await punishDM({
+ client: this.client,
+ punishment: Action.Block,
+ reason: options.reason ?? undefined,
+ duration: options.duration ?? 0,
+ modlog: modlog.id,
+ guild: this.guild,
+ user: this,
+ sendFooter: true,
+ channel: channel.id
+ });
+ if (dmSuccess === false) return blockResponse.DmError;
+ }
- return blockResponse.SUCCESS;
+ return blockResponse.Success;
})();
if (
- !([blockResponse.ACTION_ERROR, blockResponse.MODLOG_ERROR, blockResponse.PUNISHMENT_ENTRY_ADD_ERROR] as const).includes(
- ret
- ) &&
+ !([blockResponse.ActionError, blockResponse.ModlogError, blockResponse.PunishmentEntryError] as const).includes(ret) &&
!options.silent
)
this.client.emit(
@@ -703,7 +717,7 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
options.reason ?? undefined,
caseID!,
options.duration ?? 0,
- dmSuccessEvent!,
+ dmSuccess,
channel,
options.evidence
);
@@ -711,18 +725,20 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
}
public override async customUnblock(options: UnblockOptions): Promise<UnblockResponse> {
+ options = this.#optionDefaults(options);
+
const _channel = this.guild.channels.resolve(options.channel);
- if (!_channel || (_channel.type !== ChannelType.GuildText && !_channel.isThread())) return unblockResponse.INVALID_CHANNEL;
+ if (!_channel || (_channel.type !== ChannelType.GuildText && !_channel.isThread())) return unblockResponse.InvalidChannel;
const channel = _channel as GuildTextBasedChannel;
// checks
if (!channel.permissionsFor(this.guild.members.me!)!.has(PermissionFlagsBits.ManageChannels))
- return unblockResponse.MISSING_PERMISSIONS;
+ return unblockResponse.MissingPermissions;
- let caseID: string | undefined = undefined;
- let dmSuccessEvent: boolean | undefined = undefined;
+ let caseID: string | null = null;
+ let dmSuccess: boolean | null = null;
const moderator = await this.client.utils.resolveNonCachedUser(options.moderator ?? this.guild.members.me);
- if (!moderator) return unblockResponse.CANNOT_RESOLVE_USER;
+ if (!moderator) return unblockResponse.CannotResolveUser;
const ret = await (async () => {
// change channel permissions
@@ -731,7 +747,7 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
const blockSuccess = await channelToUse.permissionOverwrites
.edit(this, perm, { reason: `[Unblock] ${moderator.tag} | ${options.reason ?? 'No reason provided.'}` })
.catch(() => false);
- if (!blockSuccess) return unblockResponse.ACTION_ERROR;
+ if (!blockSuccess) return unblockResponse.ActionError;
// add modlog entry
const { log: modlog } = await createModLogEntry({
@@ -744,7 +760,7 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
evidence: options.evidence,
hidden: options.silent ?? false
});
- if (!modlog) return unblockResponse.MODLOG_ERROR;
+ if (!modlog) return unblockResponse.ModlogError;
caseID = modlog.id;
// remove punishment entry
@@ -755,31 +771,28 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
guild: this.guild,
extraInfo: channel.id
});
- if (!punishmentEntrySuccess) return unblockResponse.ACTION_ERROR;
+ if (!punishmentEntrySuccess) return unblockResponse.ActionError;
- // dm user
- const dmSuccess = options.silent
- ? null
- : await punishDM({
- client: this.client,
- punishment: Action.Unblock,
- reason: options.reason ?? undefined,
- guild: this.guild,
- user: this,
- sendFooter: false,
- channel: channel.id
- });
- dmSuccessEvent = !!dmSuccess;
- if (!dmSuccess) return blockResponse.DM_ERROR;
+ if (!options.noDM) {
+ // dm user
+ dmSuccess = await punishDM({
+ client: this.client,
+ punishment: Action.Unblock,
+ reason: options.reason ?? undefined,
+ guild: this.guild,
+ user: this,
+ sendFooter: false,
+ channel: channel.id
+ });
- dmSuccessEvent = !!dmSuccess;
- if (!dmSuccess) return unblockResponse.DM_ERROR;
+ if (dmSuccess === false) return unblockResponse.DmError;
+ }
- return unblockResponse.SUCCESS;
+ return unblockResponse.Success;
})();
if (
- !([unblockResponse.ACTION_ERROR, unblockResponse.MODLOG_ERROR, unblockResponse.ACTION_ERROR] as const).includes(ret) &&
+ !([unblockResponse.ActionError, unblockResponse.ModlogError, unblockResponse.ActionError] as const).includes(ret) &&
!options.silent
)
this.client.emit(
@@ -789,7 +802,7 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
this.guild,
options.reason ?? undefined,
caseID!,
- dmSuccessEvent!,
+ dmSuccess,
channel,
options.evidence
);
@@ -797,16 +810,18 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
}
public override async customTimeout(options: CustomTimeoutOptions): Promise<TimeoutResponse> {
+ options = this.#optionDefaults(options);
+
// checks
- if (!this.guild.members.me!.permissions.has(PermissionFlagsBits.ModerateMembers)) return timeoutResponse.MISSING_PERMISSIONS;
+ if (!this.guild.members.me!.permissions.has(PermissionFlagsBits.ModerateMembers)) return timeoutResponse.MissingPermissions;
const twentyEightDays = Time.Day * 28;
- if (options.duration > twentyEightDays) return timeoutResponse.INVALID_DURATION;
+ if (options.duration > twentyEightDays) return timeoutResponse.InvalidDuration;
- let caseID: string | undefined = undefined;
- let dmSuccessEvent: boolean | undefined = undefined;
+ let caseID: string | null = null;
+ let dmSuccess: boolean | null = null;
const moderator = await this.client.utils.resolveNonCachedUser(options.moderator ?? this.guild.members.me);
- if (!moderator) return timeoutResponse.CANNOT_RESOLVE_USER;
+ if (!moderator) return timeoutResponse.CannotResolveUser;
const ret = await (async () => {
// timeout
@@ -814,7 +829,7 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
options.duration,
`${moderator.tag} | ${options.reason ?? 'No reason provided.'}`
).catch(() => false);
- if (!timeoutSuccess) return timeoutResponse.ACTION_ERROR;
+ if (!timeoutSuccess) return timeoutResponse.ActionError;
// add modlog entry
const { log: modlog } = await createModLogEntry({
@@ -829,20 +844,20 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
hidden: options.silent ?? false
});
- if (!modlog) return timeoutResponse.MODLOG_ERROR;
+ if (!modlog) return timeoutResponse.ModlogError;
caseID = modlog.id;
- if (!options.silent) {
+ if (!options.noDM) {
// dm user
- const dmSuccess = await this.customPunishDM(Action.Timeout, options.reason, options.duration, modlog.id);
- dmSuccessEvent = dmSuccess;
- if (!dmSuccess) return timeoutResponse.DM_ERROR;
+ dmSuccess = await this.customPunishDM(Action.Timeout, options.reason, options.duration, modlog.id);
+
+ if (dmSuccess === false) return timeoutResponse.DmError;
}
- return timeoutResponse.SUCCESS;
+ return timeoutResponse.Success;
})();
- if (!([timeoutResponse.ACTION_ERROR, timeoutResponse.MODLOG_ERROR] as const).includes(ret) && !options.silent)
+ if (!([timeoutResponse.ActionError, timeoutResponse.ModlogError] as const).includes(ret) && !options.silent)
this.client.emit(
TanzaniteEvent.Timeout,
this,
@@ -851,28 +866,30 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
options.reason ?? undefined,
caseID!,
options.duration ?? 0,
- dmSuccessEvent!,
+ dmSuccess,
options.evidence
);
return ret;
}
public override async customRemoveTimeout(options: CustomPunishmentOptions): Promise<RemoveTimeoutResponse> {
+ options = this.#optionDefaults(options);
+
// checks
if (!this.guild.members.me!.permissions.has(PermissionFlagsBits.ModerateMembers))
- return removeTimeoutResponse.MISSING_PERMISSIONS;
+ return removeTimeoutResponse.MissingPermissions;
- let caseID: string | undefined = undefined;
- let dmSuccessEvent: boolean | undefined = undefined;
+ let caseID: string | null = null;
+ let dmSuccess: boolean | null = null;
const moderator = await this.client.utils.resolveNonCachedUser(options.moderator ?? this.guild.members.me);
- if (!moderator) return removeTimeoutResponse.CANNOT_RESOLVE_USER;
+ if (!moderator) return removeTimeoutResponse.CannotResolveUser;
const ret = await (async () => {
// remove timeout
const timeoutSuccess = await this.timeout(null, `${moderator.tag} | ${options.reason ?? 'No reason provided.'}`).catch(
() => false
);
- if (!timeoutSuccess) return removeTimeoutResponse.ACTION_ERROR;
+ if (!timeoutSuccess) return removeTimeoutResponse.ActionError;
// add modlog entry
const { log: modlog } = await createModLogEntry({
@@ -886,20 +903,20 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
hidden: options.silent ?? false
});
- if (!modlog) return removeTimeoutResponse.MODLOG_ERROR;
+ if (!modlog) return removeTimeoutResponse.ModlogError;
caseID = modlog.id;
- if (!options.silent) {
+ if (!options.noDM) {
// dm user
- const dmSuccess = await this.customPunishDM(Action.Untimeout, options.reason, undefined, '', false);
- dmSuccessEvent = dmSuccess;
- if (!dmSuccess) return removeTimeoutResponse.DM_ERROR;
+ dmSuccess = await this.customPunishDM(Action.Untimeout, options.reason, undefined, '', false);
+
+ if (dmSuccess === false) return removeTimeoutResponse.DmError;
}
- return removeTimeoutResponse.SUCCESS;
+ return removeTimeoutResponse.Success;
})();
- if (!([removeTimeoutResponse.ACTION_ERROR, removeTimeoutResponse.MODLOG_ERROR] as const).includes(ret) && !options.silent)
+ if (!([removeTimeoutResponse.ActionError, removeTimeoutResponse.ModlogError] as const).includes(ret) && !options.silent)
this.client.emit(
TanzaniteEvent.RemoveTimeout,
this,
@@ -907,7 +924,7 @@ export class ExtendedGuildMember extends GuildMember implements Extension {
this.guild,
options.reason ?? undefined,
caseID!,
- dmSuccessEvent!,
+ dmSuccess,
options.evidence
);
return ret;
@@ -945,6 +962,12 @@ export interface CustomPunishmentOptions {
* Makes the punishment silent by not sending the user a punishment dm and not broadcasting the event to be logged.
*/
silent?: boolean;
+
+ /**
+ * Don't send a dm to the user.
+ * @default silent
+ */
+ noDM?: boolean;
}
/**
@@ -960,7 +983,7 @@ export interface CustomTimedPunishmentOptions extends CustomPunishmentOptions {
/**
* Options for a role add punishment.
*/
-export interface AddRoleOptions extends CustomTimedPunishmentOptions {
+export interface AddRoleOptions extends Omit<CustomTimedPunishmentOptions, 'noDM'> {
/**
* The role to add to the user.
*/
@@ -975,7 +998,7 @@ export interface AddRoleOptions extends CustomTimedPunishmentOptions {
/**
* Options for a role remove punishment.
*/
-export interface RemoveRoleOptions extends CustomTimedPunishmentOptions {
+export interface RemoveRoleOptions extends Omit<CustomTimedPunishmentOptions, 'noDM'> {
/**
* The role to remove from the user.
*/
@@ -1028,75 +1051,64 @@ export interface CustomTimeoutOptions extends CustomPunishmentOptions {
}
export const basePunishmentResponse = Object.freeze({
- SUCCESS: 'success',
- MODLOG_ERROR: 'error creating modlog entry',
- ACTION_ERROR: 'error performing action',
- CANNOT_RESOLVE_USER: 'cannot resolve user'
+ Success: 'success',
+ ModlogError: 'error creating modlog entry',
+ ActionError: 'error performing action',
+ CannotResolveUser: 'cannot resolve user'
} as const);
export const dmResponse = Object.freeze({
...basePunishmentResponse,
- DM_ERROR: 'failed to dm'
+ DmError: 'failed to dm'
} as const);
export const permissionsResponse = Object.freeze({
- MISSING_PERMISSIONS: 'missing permissions'
+ MissingPermissions: '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'
+export const punishmentEntryError = Object.freeze({
+ PunishmentEntryError: 'punishment entry error'
} as const);
export const shouldAddRoleResponse = Object.freeze({
- USER_HIERARCHY: 'user hierarchy',
- CLIENT_HIERARCHY: 'client hierarchy',
- ROLE_MANAGED: 'role managed'
+ UserHierarchy: 'user hierarchy',
+ ClientHierarchy: 'client hierarchy',
+ RoleManaged: 'role managed'
} as const);
export const baseBlockResponse = Object.freeze({
- INVALID_CHANNEL: 'invalid channel'
+ InvalidChannel: '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'
+ NoMuteRole: 'no mute role',
+ MuteRoleInvalid: 'invalid mute role',
+ MuteRoleNotManageable: '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({
+export const roleResponse = Object.freeze({
...basePunishmentResponse,
...permissionsResponse,
...shouldAddRoleResponse,
- ...punishmentEntryRemove
+ ...punishmentEntryError
} as const);
export const muteResponse = Object.freeze({
...dmResponse,
...permissionsResponse,
...baseMuteResponse,
- ...punishmentEntryAdd
+ ...punishmentEntryError
} as const);
export const unmuteResponse = Object.freeze({
...dmResponse,
...permissionsResponse,
...baseMuteResponse,
- ...punishmentEntryRemove
+ ...punishmentEntryError
} as const);
export const kickResponse = Object.freeze({
@@ -1107,28 +1119,28 @@ export const kickResponse = Object.freeze({
export const banResponse = Object.freeze({
...dmResponse,
...permissionsResponse,
- ...punishmentEntryAdd,
- ALREADY_BANNED: 'already banned'
+ ...punishmentEntryError,
+ AlreadyBanned: 'already banned'
} as const);
export const blockResponse = Object.freeze({
...dmResponse,
...permissionsResponse,
...baseBlockResponse,
- ...punishmentEntryAdd
+ ...punishmentEntryError
});
export const unblockResponse = Object.freeze({
...dmResponse,
...permissionsResponse,
...baseBlockResponse,
- ...punishmentEntryRemove
+ ...punishmentEntryError
});
export const timeoutResponse = Object.freeze({
...dmResponse,
...permissionsResponse,
- INVALID_DURATION: 'duration too long'
+ InvalidDuration: 'duration too long'
} as const);
export const removeTimeoutResponse = Object.freeze({
@@ -1144,12 +1156,12 @@ export type WarnResponse = ValueOf<typeof warnResponse>;
/**
* Response returned when adding a role to a user.
*/
-export type AddRoleResponse = ValueOf<typeof addRoleResponse>;
+export type AddRoleResponse = ValueOf<typeof roleResponse>;
/**
* Response returned when removing a role from a user.
*/
-export type RemoveRoleResponse = ValueOf<typeof removeRoleResponse>;
+export type RemoveRoleResponse = ValueOf<typeof roleResponse>;
/**
* Response returned when muting a user.