mirror of
https://github.com/ZeppelinBot/Zeppelin.git
synced 2025-03-15 05:41:51 +00:00
Turn on strict TS compilation. Fix up and tweak types accordingly.
This commit is contained in:
parent
690955a399
commit
629002b8d9
172 changed files with 720 additions and 534 deletions
|
@ -34,7 +34,7 @@ export class Queue {
|
|||
return;
|
||||
}
|
||||
|
||||
const fn = this.queue.shift();
|
||||
const fn = this.queue.shift()!;
|
||||
new Promise(resolve => {
|
||||
// Either fn() completes or the timeout is reached
|
||||
fn().then(resolve);
|
||||
|
|
|
@ -16,7 +16,7 @@ export class QueuedEventEmitter {
|
|||
this.listeners.set(eventName, []);
|
||||
}
|
||||
|
||||
this.listeners.get(eventName).push(listener);
|
||||
this.listeners.get(eventName)!.push(listener);
|
||||
return listener;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ export class QueuedEventEmitter {
|
|||
return;
|
||||
}
|
||||
|
||||
const listeners = this.listeners.get(eventName);
|
||||
const listeners = this.listeners.get(eventName)!;
|
||||
listeners.splice(listeners.indexOf(listener), 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,8 +47,8 @@ export interface RegExpRunner {
|
|||
* Repeatedly failing regexes are put on a cooldown where requests to execute them are ignored.
|
||||
*/
|
||||
export class RegExpRunner extends EventEmitter {
|
||||
private _worker: RegExpWorker;
|
||||
private _failedTimesInterval: Timeout;
|
||||
private _worker: RegExpWorker | null;
|
||||
private readonly _failedTimesInterval: Timeout;
|
||||
|
||||
private cooldown: CooldownManager;
|
||||
private failedTimes: Map<string, number>;
|
||||
|
@ -90,13 +90,13 @@ export class RegExpRunner extends EventEmitter {
|
|||
if (isTimeoutError(e)) {
|
||||
if (this.failedTimes.has(regex.source)) {
|
||||
// Regex has failed before, increment fail counter
|
||||
this.failedTimes.set(regex.source, this.failedTimes.get(regex.source) + 1);
|
||||
this.failedTimes.set(regex.source, this.failedTimes.get(regex.source)! + 1);
|
||||
} else {
|
||||
// This is the first time this regex failed, init fail counter
|
||||
this.failedTimes.set(regex.source, 1);
|
||||
}
|
||||
|
||||
if (this.failedTimes.get(regex.source) >= REGEX_FAIL_TO_COOLDOWN_COUNT) {
|
||||
if (this.failedTimes.has(regex.source) && this.failedTimes.get(regex.source)! >= REGEX_FAIL_TO_COOLDOWN_COUNT) {
|
||||
// Regex has failed too many times, set it on cooldown
|
||||
this.cooldown.setCooldown(regex.source, REGEX_FAIL_COOLDOWN);
|
||||
this.failedTimes.delete(regex.source);
|
||||
|
|
|
@ -13,7 +13,10 @@ export class SimpleCache<T = any> {
|
|||
|
||||
constructor(retentionTime: number, maxItems?: number) {
|
||||
this.retentionTime = retentionTime;
|
||||
this.maxItems = maxItems;
|
||||
|
||||
if (maxItems) {
|
||||
this.maxItems = maxItems;
|
||||
}
|
||||
|
||||
this.store = new Map();
|
||||
}
|
||||
|
@ -48,7 +51,7 @@ export class SimpleCache<T = any> {
|
|||
}
|
||||
}
|
||||
|
||||
get(key: string): T {
|
||||
get(key: string): T | null {
|
||||
const info = this.store.get(key);
|
||||
if (!info) return null;
|
||||
|
||||
|
|
|
@ -147,7 +147,7 @@ export function initAuth(app: express.Express) {
|
|||
res.json({ valid: true });
|
||||
});
|
||||
app.post("/auth/logout", ...apiTokenAuthHandlers(), async (req: Request, res: Response) => {
|
||||
await apiLogins.expireApiKey(req.user.apiKey);
|
||||
await apiLogins.expireApiKey(req.user!.apiKey);
|
||||
return ok(res);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -19,12 +19,12 @@ export function initGuildsAPI(app: express.Express) {
|
|||
guildRouter.use(...apiTokenAuthHandlers());
|
||||
|
||||
guildRouter.get("/available", async (req: Request, res: Response) => {
|
||||
const guilds = await allowedGuilds.getForApiUser(req.user.userId);
|
||||
const guilds = await allowedGuilds.getForApiUser(req.user!.userId);
|
||||
res.json(guilds);
|
||||
});
|
||||
|
||||
guildRouter.get("/:guildId", async (req: Request, res: Response) => {
|
||||
if (!(await hasGuildPermission(req.user.userId, req.params.guildId, ApiPermissions.ViewGuild))) {
|
||||
if (!(await hasGuildPermission(req.user!.userId, req.params.guildId, ApiPermissions.ViewGuild))) {
|
||||
return unauthorized(res);
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ export function initGuildsAPI(app: express.Express) {
|
|||
|
||||
guildRouter.post("/:guildId/check-permission", async (req: Request, res: Response) => {
|
||||
const permission = req.body.permission;
|
||||
const hasPermission = await hasGuildPermission(req.user.userId, req.params.guildId, permission);
|
||||
const hasPermission = await hasGuildPermission(req.user!.userId, req.params.guildId, permission);
|
||||
res.json({ result: hasPermission });
|
||||
});
|
||||
|
||||
|
@ -54,7 +54,7 @@ export function initGuildsAPI(app: express.Express) {
|
|||
config = config.trim() + "\n"; // Normalize start/end whitespace in the config
|
||||
|
||||
const currentConfig = await configs.getActiveByKey(`guild-${req.params.guildId}`);
|
||||
if (config === currentConfig.config) {
|
||||
if (currentConfig && config === currentConfig.config) {
|
||||
return ok(res);
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ export function initGuildsAPI(app: express.Express) {
|
|||
return res.status(422).json({ errors: [error] });
|
||||
}
|
||||
|
||||
await configs.saveNewRevision(`guild-${req.params.guildId}`, config, req.user.userId);
|
||||
await configs.saveNewRevision(`guild-${req.params.guildId}`, config, req.user!.userId);
|
||||
|
||||
ok(res);
|
||||
});
|
||||
|
|
|
@ -24,7 +24,7 @@ export const hasGuildPermission = async (userId: string, guildId: string, permis
|
|||
*/
|
||||
export function requireGuildPermission(permission: ApiPermissions) {
|
||||
return async (req: Request, res: Response, next) => {
|
||||
if (!(await hasGuildPermission(req.user.userId, req.params.guildId, permission))) {
|
||||
if (!(await hasGuildPermission(req.user!.userId, req.params.guildId, permission))) {
|
||||
return unauthorized(res);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ export function initStaff(app: express.Express) {
|
|||
staffRouter.use(...apiTokenAuthHandlers());
|
||||
|
||||
staffRouter.get("/status", (req: Request, res: Response) => {
|
||||
const userIsStaff = isStaff(req.user.userId);
|
||||
const userIsStaff = isStaff(req.user!.userId);
|
||||
res.json({ isStaff: userIsStaff });
|
||||
});
|
||||
|
||||
|
|
|
@ -48,7 +48,9 @@ export const commandTypes = {
|
|||
},
|
||||
|
||||
async resolvedMember(value, context: CommandContext<any>) {
|
||||
if (!(context.message.channel instanceof GuildChannel)) return null;
|
||||
if (!(context.message.channel instanceof GuildChannel)) {
|
||||
throw new TypeConversionError(`Cannot resolve member for non-guild channels`);
|
||||
}
|
||||
|
||||
const result = await resolveMember(context.pluginData.client, context.message.channel.guild, value);
|
||||
if (result == null) {
|
||||
|
@ -110,7 +112,7 @@ export const commandTypeHelpers = {
|
|||
delay: createTypeHelper<number>(commandTypes.delay),
|
||||
resolvedUser: createTypeHelper<Promise<User>>(commandTypes.resolvedUser),
|
||||
resolvedUserLoose: createTypeHelper<Promise<User | UnknownUser>>(commandTypes.resolvedUserLoose),
|
||||
resolvedMember: createTypeHelper<Promise<Member | null>>(commandTypes.resolvedMember),
|
||||
resolvedMember: createTypeHelper<Promise<Member>>(commandTypes.resolvedMember),
|
||||
messageTarget: createTypeHelper<Promise<MessageTarget>>(commandTypes.messageTarget),
|
||||
anyId: createTypeHelper<Promise<string>>(commandTypes.anyId),
|
||||
regex: createTypeHelper<RegExp>(commandTypes.regex),
|
||||
|
|
|
@ -34,10 +34,10 @@ export async function validateGuildConfig(config: any): Promise<string | null> {
|
|||
return `Invalid options specified for plugin ${pluginName}`;
|
||||
}
|
||||
|
||||
const plugin = pluginNameToPlugin.get(pluginName);
|
||||
const plugin = pluginNameToPlugin.get(pluginName)!;
|
||||
try {
|
||||
const mergedOptions = configUtils.mergeConfig(plugin.defaultOptions || {}, pluginOptions);
|
||||
await plugin.configPreprocessor(mergedOptions as PluginOptions<any>);
|
||||
await plugin.configPreprocessor?.(mergedOptions as PluginOptions<any>);
|
||||
} catch (err) {
|
||||
if (err instanceof ConfigValidationError || err instanceof StrictValidationError) {
|
||||
return `${pluginName}: ${err.message}`;
|
||||
|
|
|
@ -37,7 +37,7 @@ export class GuildArchives extends BaseGuildRepository {
|
|||
.execute();
|
||||
}
|
||||
|
||||
async find(id: string): Promise<ArchiveEntry> {
|
||||
async find(id: string): Promise<ArchiveEntry | undefined> {
|
||||
return this.archives.findOne({
|
||||
where: { id },
|
||||
relations: this.getRelations(),
|
||||
|
@ -56,7 +56,7 @@ export class GuildArchives extends BaseGuildRepository {
|
|||
/**
|
||||
* @returns ID of the created entry
|
||||
*/
|
||||
async create(body: string, expiresAt: moment.Moment = null): Promise<string> {
|
||||
async create(body: string, expiresAt?: moment.Moment): Promise<string> {
|
||||
if (!expiresAt) {
|
||||
expiresAt = moment.utc().add(DEFAULT_EXPIRY_DAYS, "days");
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ export class GuildArchives extends BaseGuildRepository {
|
|||
}
|
||||
|
||||
protected async renderLinesFromSavedMessages(savedMessages: SavedMessage[], guild: Guild) {
|
||||
const msgLines = [];
|
||||
const msgLines: string[] = [];
|
||||
for (const msg of savedMessages) {
|
||||
const channel = guild.channels.get(msg.channel_id);
|
||||
const user = { ...msg.data.author, id: msg.user_id };
|
||||
|
@ -88,7 +88,7 @@ export class GuildArchives extends BaseGuildRepository {
|
|||
return msgLines;
|
||||
}
|
||||
|
||||
async createFromSavedMessages(savedMessages: SavedMessage[], guild: Guild, expiresAt = null) {
|
||||
async createFromSavedMessages(savedMessages: SavedMessage[], guild: Guild, expiresAt?: moment.Moment) {
|
||||
if (expiresAt == null) {
|
||||
expiresAt = moment.utc().add(DEFAULT_EXPIRY_DAYS, "days");
|
||||
}
|
||||
|
@ -105,6 +105,10 @@ export class GuildArchives extends BaseGuildRepository {
|
|||
const messagesStr = msgLines.join("\n");
|
||||
|
||||
const archive = await this.find(archiveId);
|
||||
if (archive == null) {
|
||||
throw new Error("Archive not found");
|
||||
}
|
||||
|
||||
archive.body += "\n" + messagesStr;
|
||||
|
||||
await this.archives.update({ id: archiveId }, { body: archive.body });
|
||||
|
|
|
@ -18,7 +18,7 @@ export class GuildAutoReactions extends BaseGuildRepository {
|
|||
});
|
||||
}
|
||||
|
||||
async getForChannel(channelId: string): Promise<AutoReaction> {
|
||||
async getForChannel(channelId: string): Promise<AutoReaction | undefined> {
|
||||
return this.autoReactions.findOne({
|
||||
where: {
|
||||
guild_id: this.guildId,
|
||||
|
|
|
@ -29,7 +29,7 @@ export class GuildCases extends BaseGuildRepository {
|
|||
});
|
||||
}
|
||||
|
||||
async find(id: number): Promise<Case> {
|
||||
async find(id: number): Promise<Case | undefined> {
|
||||
return this.cases.findOne({
|
||||
relations: this.getRelations(),
|
||||
where: {
|
||||
|
@ -39,7 +39,7 @@ export class GuildCases extends BaseGuildRepository {
|
|||
});
|
||||
}
|
||||
|
||||
async findByCaseNumber(caseNumber: number): Promise<Case> {
|
||||
async findByCaseNumber(caseNumber: number): Promise<Case | undefined> {
|
||||
return this.cases.findOne({
|
||||
relations: this.getRelations(),
|
||||
where: {
|
||||
|
@ -49,7 +49,7 @@ export class GuildCases extends BaseGuildRepository {
|
|||
});
|
||||
}
|
||||
|
||||
async findLatestByModId(modId: string): Promise<Case> {
|
||||
async findLatestByModId(modId: string): Promise<Case | undefined> {
|
||||
return this.cases.findOne({
|
||||
relations: this.getRelations(),
|
||||
where: {
|
||||
|
@ -62,7 +62,7 @@ export class GuildCases extends BaseGuildRepository {
|
|||
});
|
||||
}
|
||||
|
||||
async findByAuditLogId(auditLogId: string): Promise<Case> {
|
||||
async findByAuditLogId(auditLogId: string): Promise<Case | undefined> {
|
||||
return this.cases.findOne({
|
||||
relations: this.getRelations(),
|
||||
where: {
|
||||
|
@ -113,7 +113,7 @@ export class GuildCases extends BaseGuildRepository {
|
|||
case_number: () => `(SELECT IFNULL(MAX(case_number)+1, 1) FROM cases AS ma2 WHERE guild_id = ${this.guildId})`,
|
||||
});
|
||||
|
||||
return this.find(result.identifiers[0].id);
|
||||
return (await this.find(result.identifiers[0].id))!;
|
||||
}
|
||||
|
||||
update(id, data) {
|
||||
|
|
|
@ -17,12 +17,12 @@ export class GuildEvents extends BaseGuildRepository {
|
|||
this.pluginListeners.set(pluginName, new Map());
|
||||
}
|
||||
|
||||
const pluginListeners = this.pluginListeners.get(pluginName);
|
||||
const pluginListeners = this.pluginListeners.get(pluginName)!;
|
||||
if (!pluginListeners.has(eventName)) {
|
||||
pluginListeners.set(eventName, []);
|
||||
}
|
||||
|
||||
const pluginEventListeners = pluginListeners.get(eventName);
|
||||
const pluginEventListeners = pluginListeners.get(eventName)!;
|
||||
pluginEventListeners.push(fn);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ export class GuildLogs extends events.EventEmitter {
|
|||
constructor(guildId) {
|
||||
if (guildInstances.has(guildId)) {
|
||||
// Return existing instance for this guild if one exists
|
||||
return guildInstances.get(guildId);
|
||||
return guildInstances.get(guildId)!;
|
||||
}
|
||||
|
||||
super();
|
||||
|
@ -27,7 +27,7 @@ export class GuildLogs extends events.EventEmitter {
|
|||
guildInstances.set(guildId, this);
|
||||
}
|
||||
|
||||
log(type: LogType, data: any, ignoreId = null) {
|
||||
log(type: LogType, data: any, ignoreId?: string) {
|
||||
if (ignoreId && this.isLogIgnored(type, ignoreId)) {
|
||||
this.clearIgnoredLog(type, ignoreId);
|
||||
return;
|
||||
|
@ -36,7 +36,7 @@ export class GuildLogs extends events.EventEmitter {
|
|||
this.emit("log", { type, data });
|
||||
}
|
||||
|
||||
ignoreLog(type: LogType, ignoreId: any, timeout: number = null) {
|
||||
ignoreLog(type: LogType, ignoreId: any, timeout?: number) {
|
||||
this.ignoredLogs.push({ type, ignoreId });
|
||||
|
||||
// Clear after expiry (15sec by default)
|
||||
|
|
|
@ -20,7 +20,7 @@ export class GuildMutes extends BaseGuildRepository {
|
|||
.getMany();
|
||||
}
|
||||
|
||||
async findExistingMuteForUserId(userId: string): Promise<Mute> {
|
||||
async findExistingMuteForUserId(userId: string): Promise<Mute | undefined> {
|
||||
return this.mutes.findOne({
|
||||
where: {
|
||||
guild_id: this.guildId,
|
||||
|
@ -48,7 +48,7 @@ export class GuildMutes extends BaseGuildRepository {
|
|||
expires_at: expiresAt,
|
||||
});
|
||||
|
||||
return this.mutes.findOne({ where: result.identifiers[0] });
|
||||
return (await this.mutes.findOne({ where: result.identifiers[0] }))!;
|
||||
}
|
||||
|
||||
async updateExpiryTime(userId, newExpiryTime) {
|
||||
|
|
|
@ -39,7 +39,7 @@ export class GuildNicknameHistory extends BaseGuildRepository {
|
|||
});
|
||||
}
|
||||
|
||||
getLastEntry(userId): Promise<NicknameHistoryEntry> {
|
||||
getLastEntry(userId): Promise<NicknameHistoryEntry | undefined> {
|
||||
return this.nicknameHistory.findOne({
|
||||
where: {
|
||||
guild_id: this.guildId,
|
||||
|
|
|
@ -27,7 +27,7 @@ export class GuildPingableRoles extends BaseGuildRepository {
|
|||
});
|
||||
}
|
||||
|
||||
async getByChannelAndRoleId(channelId: string, roleId: string): Promise<PingableRole> {
|
||||
async getByChannelAndRoleId(channelId: string, roleId: string): Promise<PingableRole | undefined> {
|
||||
return this.pingableRoles.findOne({
|
||||
where: {
|
||||
guild_id: this.guildId,
|
||||
|
|
|
@ -27,7 +27,7 @@ export class GuildReactionRoles extends BaseGuildRepository {
|
|||
});
|
||||
}
|
||||
|
||||
async getByMessageAndEmoji(messageId: string, emoji: string): Promise<ReactionRole> {
|
||||
async getByMessageAndEmoji(messageId: string, emoji: string): Promise<ReactionRole | undefined> {
|
||||
return this.reactionRoles.findOne({
|
||||
where: {
|
||||
guild_id: this.guildId,
|
||||
|
@ -37,7 +37,7 @@ export class GuildReactionRoles extends BaseGuildRepository {
|
|||
});
|
||||
}
|
||||
|
||||
async removeFromMessage(messageId: string, emoji: string = null) {
|
||||
async removeFromMessage(messageId: string, emoji?: string) {
|
||||
const criteria: any = {
|
||||
guild_id: this.guildId,
|
||||
message_id: messageId,
|
||||
|
|
|
@ -96,7 +96,7 @@ export class GuildSavedMessages extends BaseGuildRepository {
|
|||
.getMany();
|
||||
}
|
||||
|
||||
getUserMessagesByChannelAfterId(userId, channelId, afterId, limit = null) {
|
||||
getUserMessagesByChannelAfterId(userId, channelId, afterId, limit?: number) {
|
||||
let query = this.messages
|
||||
.createQueryBuilder()
|
||||
.where("guild_id = :guild_id", { guild_id: this.guildId })
|
||||
|
@ -241,12 +241,12 @@ export class GuildSavedMessages extends BaseGuildRepository {
|
|||
}
|
||||
}
|
||||
|
||||
async onceMessageAvailable(id: string, handler: (msg: SavedMessage) => any, timeout: number = 60 * 1000) {
|
||||
async onceMessageAvailable(id: string, handler: (msg?: SavedMessage) => any, timeout: number = 60 * 1000) {
|
||||
let called = false;
|
||||
let onceEventListener;
|
||||
let timeoutFn;
|
||||
|
||||
const callHandler = async (msg: SavedMessage) => {
|
||||
const callHandler = async (msg?: SavedMessage) => {
|
||||
this.events.off(`create:${id}`, onceEventListener);
|
||||
clearTimeout(timeoutFn);
|
||||
|
||||
|
@ -259,7 +259,7 @@ export class GuildSavedMessages extends BaseGuildRepository {
|
|||
onceEventListener = this.events.once(`create:${id}`, callHandler);
|
||||
timeoutFn = setTimeout(() => {
|
||||
called = true;
|
||||
callHandler(null);
|
||||
callHandler(undefined);
|
||||
}, timeout);
|
||||
|
||||
const messageInDB = await this.find(id);
|
||||
|
|
|
@ -14,7 +14,7 @@ export class GuildSlowmodes extends BaseGuildRepository {
|
|||
this.slowmodeUsers = getRepository(SlowmodeUser);
|
||||
}
|
||||
|
||||
async getChannelSlowmode(channelId): Promise<SlowmodeChannel> {
|
||||
async getChannelSlowmode(channelId): Promise<SlowmodeChannel | undefined> {
|
||||
return this.slowmodeChannels.findOne({
|
||||
where: {
|
||||
guild_id: this.guildId,
|
||||
|
@ -51,7 +51,7 @@ export class GuildSlowmodes extends BaseGuildRepository {
|
|||
});
|
||||
}
|
||||
|
||||
async getChannelSlowmodeUser(channelId, userId): Promise<SlowmodeUser> {
|
||||
async getChannelSlowmodeUser(channelId, userId): Promise<SlowmodeUser | undefined> {
|
||||
return this.slowmodeUsers.findOne({
|
||||
guild_id: this.guildId,
|
||||
channel_id: channelId,
|
||||
|
|
|
@ -21,7 +21,7 @@ export class GuildTags extends BaseGuildRepository {
|
|||
});
|
||||
}
|
||||
|
||||
async find(tag): Promise<Tag> {
|
||||
async find(tag): Promise<Tag | undefined> {
|
||||
return this.tags.findOne({
|
||||
where: {
|
||||
guild_id: this.guildId,
|
||||
|
@ -61,7 +61,7 @@ export class GuildTags extends BaseGuildRepository {
|
|||
});
|
||||
}
|
||||
|
||||
async findResponseByCommandMessageId(messageId: string): Promise<TagResponse> {
|
||||
async findResponseByCommandMessageId(messageId: string): Promise<TagResponse | undefined> {
|
||||
return this.tagResponses.findOne({
|
||||
where: {
|
||||
guild_id: this.guildId,
|
||||
|
@ -70,7 +70,7 @@ export class GuildTags extends BaseGuildRepository {
|
|||
});
|
||||
}
|
||||
|
||||
async findResponseByResponseMessageId(messageId: string): Promise<TagResponse> {
|
||||
async findResponseByResponseMessageId(messageId: string): Promise<TagResponse | undefined> {
|
||||
return this.tagResponses.findOne({
|
||||
where: {
|
||||
guild_id: this.guildId,
|
||||
|
|
|
@ -39,7 +39,7 @@ export class UsernameHistory extends BaseRepository {
|
|||
});
|
||||
}
|
||||
|
||||
getLastEntry(userId): Promise<UsernameHistoryEntry> {
|
||||
getLastEntry(userId): Promise<UsernameHistoryEntry | undefined> {
|
||||
return this.usernameHistory.findOne({
|
||||
where: {
|
||||
user_id: userId,
|
||||
|
|
|
@ -9,8 +9,8 @@ export class AllowedGuild {
|
|||
@Column()
|
||||
name: string;
|
||||
|
||||
@Column()
|
||||
icon: string;
|
||||
@Column({ nullable: true })
|
||||
icon: string | null;
|
||||
|
||||
@Column()
|
||||
owner_id: string;
|
||||
|
|
|
@ -17,5 +17,5 @@ export class ArchiveEntry {
|
|||
|
||||
@Column() created_at: string;
|
||||
|
||||
@Column() expires_at: string;
|
||||
@Column({ nullable: true }) expires_at: string | null;
|
||||
}
|
||||
|
|
|
@ -13,27 +13,27 @@ export class Case {
|
|||
|
||||
@Column() user_name: string;
|
||||
|
||||
@Column() mod_id: string;
|
||||
@Column({ nullable: true }) mod_id: string | null;
|
||||
|
||||
@Column() mod_name: string;
|
||||
@Column({ nullable: true }) mod_name: string | null;
|
||||
|
||||
@Column() type: number;
|
||||
|
||||
@Column() audit_log_id: string;
|
||||
@Column({ nullable: true }) audit_log_id: string | null;
|
||||
|
||||
@Column() created_at: string;
|
||||
|
||||
@Column() is_hidden: boolean;
|
||||
|
||||
@Column() pp_id: string;
|
||||
@Column({ nullable: true }) pp_id: string | null;
|
||||
|
||||
@Column() pp_name: string;
|
||||
@Column({ nullable: true }) pp_name: string | null;
|
||||
|
||||
/**
|
||||
* ID of the channel and message where this case was logged.
|
||||
* Format: "channelid-messageid"
|
||||
*/
|
||||
@Column() log_message_id: string;
|
||||
@Column({ nullable: true }) log_message_id: string | null;
|
||||
|
||||
@OneToMany(
|
||||
type => CaseNote,
|
||||
|
|
|
@ -12,7 +12,7 @@ export class Mute {
|
|||
|
||||
@Column() created_at: string;
|
||||
|
||||
@Column() expires_at: string;
|
||||
@Column({ nullable: true }) expires_at: string | null;
|
||||
|
||||
@Column() case_id: number;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { Column, Entity, PrimaryColumn } from "typeorm";
|
||||
import { createEncryptedJsonTransformer } from "../encryptedJsonTransformer";
|
||||
import { Sticker } from "eris";
|
||||
import { Attachment, Sticker } from "eris";
|
||||
|
||||
export interface ISavedMessageData {
|
||||
attachments?: object[];
|
||||
attachments?: Attachment[];
|
||||
author: {
|
||||
username: string;
|
||||
discriminator: string;
|
||||
|
|
|
@ -20,16 +20,16 @@ export class ScheduledPost {
|
|||
|
||||
@Column("simple-json") attachments: Attachment[];
|
||||
|
||||
@Column() post_at: string;
|
||||
@Column({ nullable: true }) post_at: string | null;
|
||||
|
||||
/**
|
||||
* How often to post the message, in milliseconds
|
||||
*/
|
||||
@Column() repeat_interval: number;
|
||||
@Column({ nullable: true }) repeat_interval: number | null;
|
||||
|
||||
@Column() repeat_until: string;
|
||||
@Column({ nullable: true }) repeat_until: string | null;
|
||||
|
||||
@Column() repeat_times: number;
|
||||
@Column({ nullable: true }) repeat_times: number | null;
|
||||
|
||||
@Column() enable_mentions: boolean;
|
||||
}
|
||||
|
|
|
@ -212,13 +212,13 @@ connect().then(async () => {
|
|||
|
||||
sendSuccessMessageFn(channel, body) {
|
||||
const guildId = channel instanceof TextChannel ? channel.guild.id : undefined;
|
||||
const emoji = guildId ? bot.getLoadedGuild(guildId).config.success_emoji : undefined;
|
||||
const emoji = guildId ? bot.getLoadedGuild(guildId)!.config.success_emoji : undefined;
|
||||
channel.createMessage(successMessage(body, emoji));
|
||||
},
|
||||
|
||||
sendErrorMessageFn(channel, body) {
|
||||
const guildId = channel instanceof TextChannel ? channel.guild.id : undefined;
|
||||
const emoji = guildId ? bot.getLoadedGuild(guildId).config.error_emoji : undefined;
|
||||
const emoji = guildId ? bot.getLoadedGuild(guildId)!.config.error_emoji : undefined;
|
||||
channel.createMessage(errorMessage(body, emoji));
|
||||
},
|
||||
},
|
||||
|
|
|
@ -19,8 +19,8 @@ export class MigrateUsernamesToNewHistoryTable1556909512501 implements Migration
|
|||
|
||||
const migrateNextBatch = (): Promise<{ finished: boolean; migrated?: number }> => {
|
||||
return new Promise(async resolve => {
|
||||
const toInsert = [];
|
||||
const toDelete = [];
|
||||
const toInsert: any[][] = [];
|
||||
const toDelete: number[] = [];
|
||||
|
||||
const stream = await queryRunner.stream(
|
||||
`SELECT * FROM name_history WHERE type=1 ORDER BY timestamp ASC LIMIT ${BATCH_SIZE}`,
|
||||
|
|
|
@ -2,7 +2,7 @@ import { MigrationInterface, QueryRunner, TableIndex } from "typeorm";
|
|||
|
||||
export class AddMoreIndicesToVCAlerts1562838838927 implements MigrationInterface {
|
||||
public async up(queryRunner: QueryRunner): Promise<any> {
|
||||
const table = await queryRunner.getTable("vc_alerts");
|
||||
const table = (await queryRunner.getTable("vc_alerts"))!;
|
||||
await table.addIndex(
|
||||
new TableIndex({
|
||||
columnNames: ["requestor_id"],
|
||||
|
@ -16,7 +16,7 @@ export class AddMoreIndicesToVCAlerts1562838838927 implements MigrationInterface
|
|||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<any> {
|
||||
const table = await queryRunner.getTable("vc_alerts");
|
||||
const table = (await queryRunner.getTable("vc_alerts"))!;
|
||||
await table.removeIndex(
|
||||
new TableIndex({
|
||||
columnNames: ["requestor_id"],
|
||||
|
|
|
@ -6,7 +6,7 @@ export class AddTypeAndPermissionsToApiPermissions1573158035867 implements Migra
|
|||
await queryRunner.dropPrimaryKey("api_permissions");
|
||||
} catch (e) {} // tslint:disable-line
|
||||
|
||||
const table = await queryRunner.getTable("api_permissions");
|
||||
const table = (await queryRunner.getTable("api_permissions"))!;
|
||||
if (table.indices.length) {
|
||||
await queryRunner.dropIndex("api_permissions", table.indices[0]);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import pkgUp from "pkg-up";
|
|||
|
||||
const backendPackageJson = pkgUp.sync({
|
||||
cwd: __dirname,
|
||||
});
|
||||
}) as string;
|
||||
|
||||
export const backendDir = path.dirname(backendPackageJson);
|
||||
export const rootDir = path.resolve(backendDir, "..");
|
||||
|
|
|
@ -32,26 +32,28 @@ export function hasPermission(pluginData: AnyPluginData<any>, permission: string
|
|||
return helpers.hasPermission(config, permission);
|
||||
}
|
||||
|
||||
const PluginOverrideCriteriaType = t.recursion("PluginOverrideCriteriaType", () =>
|
||||
t.type({
|
||||
channel: tNullable(t.union([t.string, t.array(t.string)])),
|
||||
category: tNullable(t.union([t.string, t.array(t.string)])),
|
||||
level: tNullable(t.union([t.string, t.array(t.string)])),
|
||||
user: tNullable(t.union([t.string, t.array(t.string)])),
|
||||
role: tNullable(t.union([t.string, t.array(t.string)])),
|
||||
const PluginOverrideCriteriaType: t.Type<PluginOverrideCriteria<unknown>> = t.recursion(
|
||||
"PluginOverrideCriteriaType",
|
||||
() =>
|
||||
t.partial({
|
||||
channel: tNullable(t.union([t.string, t.array(t.string)])),
|
||||
category: tNullable(t.union([t.string, t.array(t.string)])),
|
||||
level: tNullable(t.union([t.string, t.array(t.string)])),
|
||||
user: tNullable(t.union([t.string, t.array(t.string)])),
|
||||
role: tNullable(t.union([t.string, t.array(t.string)])),
|
||||
|
||||
all: tNullable(t.array(PluginOverrideCriteriaType)),
|
||||
any: tNullable(t.array(PluginOverrideCriteriaType)),
|
||||
not: tNullable(PluginOverrideCriteriaType),
|
||||
all: tNullable(t.array(PluginOverrideCriteriaType)),
|
||||
any: tNullable(t.array(PluginOverrideCriteriaType)),
|
||||
not: tNullable(PluginOverrideCriteriaType),
|
||||
|
||||
extra: t.unknown,
|
||||
}),
|
||||
extra: t.unknown,
|
||||
}),
|
||||
);
|
||||
|
||||
const BasicPluginStructureType = t.type({
|
||||
enabled: tNullable(t.boolean),
|
||||
config: tNullable(t.unknown),
|
||||
overrides: tNullable(t.array(PluginOverrideCriteriaType)),
|
||||
overrides: tNullable(t.array(t.union([PluginOverrideCriteriaType, t.type({ config: t.unknown })]))),
|
||||
replaceDefaultOverrides: tNullable(t.boolean),
|
||||
});
|
||||
|
||||
|
@ -101,7 +103,7 @@ export function getPluginConfigPreprocessor(
|
|||
|
||||
// 4. Merge with default options and validate/decode the entire config
|
||||
let decodedConfig = {};
|
||||
const decodedOverrides = [];
|
||||
const decodedOverrides: Array<PluginOverrideCriteria<unknown> & { config: any }> = [];
|
||||
|
||||
if (options.config) {
|
||||
decodedConfig = blueprint.configSchema
|
||||
|
|
|
@ -4,6 +4,7 @@ import { tDelayString, MINUTES } from "../../utils";
|
|||
import { GuildLogs } from "../../data/GuildLogs";
|
||||
import { GuildSavedMessages } from "../../data/GuildSavedMessages";
|
||||
import { SavedMessage } from "../../data/entities/SavedMessage";
|
||||
import Timeout = NodeJS.Timeout;
|
||||
|
||||
export const MAX_DELAY = 5 * MINUTES;
|
||||
|
||||
|
@ -25,8 +26,8 @@ export interface AutoDeletePluginType extends BasePluginType {
|
|||
guildLogs: GuildLogs;
|
||||
|
||||
deletionQueue: IDeletionQueueItem[];
|
||||
nextDeletion: number;
|
||||
nextDeletionTimeout;
|
||||
nextDeletion: number | null;
|
||||
nextDeletionTimeout: Timeout | null;
|
||||
|
||||
maxDelayWarningSent: boolean;
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ export async function onMessageCreate(pluginData: GuildPluginData<AutoDeletePlug
|
|||
const member = await resolveMember(pluginData.client, pluginData.guild, msg.user_id);
|
||||
const config = pluginData.config.getMatchingConfig({ member, channelId: msg.channel_id });
|
||||
if (config.enabled) {
|
||||
let delay = convertDelayStringToMS(config.delay);
|
||||
let delay = convertDelayStringToMS(config.delay)!;
|
||||
|
||||
if (delay > MAX_DELAY) {
|
||||
delay = MAX_DELAY;
|
||||
|
|
|
@ -4,11 +4,11 @@ import { deleteNextItem } from "./deleteNextItem";
|
|||
|
||||
export function scheduleNextDeletion(pluginData: GuildPluginData<AutoDeletePluginType>) {
|
||||
if (pluginData.state.deletionQueue.length === 0) {
|
||||
clearTimeout(pluginData.state.nextDeletionTimeout);
|
||||
clearTimeout(pluginData.state.nextDeletionTimeout!);
|
||||
return;
|
||||
}
|
||||
|
||||
const firstDeleteAt = pluginData.state.deletionQueue[0].deleteAt;
|
||||
clearTimeout(pluginData.state.nextDeletionTimeout);
|
||||
clearTimeout(pluginData.state.nextDeletionTimeout!);
|
||||
pluginData.state.nextDeletionTimeout = setTimeout(() => deleteNextItem(pluginData), firstDeleteAt - Date.now());
|
||||
}
|
||||
|
|
|
@ -20,9 +20,9 @@ export const NewAutoReactionsCmd = autoReactionsCmd({
|
|||
},
|
||||
|
||||
async run({ message: msg, args, pluginData }) {
|
||||
const finalReactions = [];
|
||||
const finalReactions: string[] = [];
|
||||
|
||||
const me = pluginData.guild.members.get(pluginData.client.user.id);
|
||||
const me = pluginData.guild.members.get(pluginData.client.user.id)!;
|
||||
const missingPermissions = getMissingChannelPermissions(me, args.channel as GuildChannel, requiredPermissions);
|
||||
if (missingPermissions) {
|
||||
sendErrorMessage(
|
||||
|
|
|
@ -19,7 +19,7 @@ export const AddReactionsEvt = autoReactionsEvt({
|
|||
const autoReaction = await pluginData.state.autoReactions.getForChannel(message.channel.id);
|
||||
if (!autoReaction) return;
|
||||
|
||||
const me = pluginData.guild.members.get(pluginData.client.user.id);
|
||||
const me = pluginData.guild.members.get(pluginData.client.user.id)!;
|
||||
const missingPermissions = getMissingChannelPermissions(
|
||||
me,
|
||||
message.channel as GuildChannel,
|
||||
|
|
|
@ -158,7 +158,7 @@ export const AutomodPlugin = zeppelinGuildPlugin<AutomodPluginType>()("automod",
|
|||
configPreprocessor,
|
||||
|
||||
customOverrideMatcher(pluginData, criteria, matchParams) {
|
||||
return criteria?.antiraid_level && criteria.antiraid_level === pluginData.state.cachedAntiraidLevel;
|
||||
return criteria?.antiraid_level ? criteria.antiraid_level === pluginData.state.cachedAntiraidLevel : false;
|
||||
},
|
||||
|
||||
events: [
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import * as t from "io-ts";
|
||||
import { automodAction } from "../helpers";
|
||||
import { LogType } from "../../../data/LogType";
|
||||
import { unique } from "../../../utils";
|
||||
import { nonNullish, unique } from "../../../utils";
|
||||
import { Constants } from "eris";
|
||||
import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions";
|
||||
import { LogsPlugin } from "../../Logs/LogsPlugin";
|
||||
|
@ -17,8 +17,8 @@ export const AddRolesAction = automodAction({
|
|||
defaultConfig: [],
|
||||
|
||||
async apply({ pluginData, contexts, actionConfig, ruleName }) {
|
||||
const members = unique(contexts.map(c => c.member).filter(Boolean));
|
||||
const me = pluginData.guild.members.get(pluginData.client.user.id);
|
||||
const members = unique(contexts.map(c => c.member).filter(nonNullish));
|
||||
const me = pluginData.guild.members.get(pluginData.client.user.id)!;
|
||||
|
||||
const missingPermissions = getMissingPermissions(me.permission, p.manageRoles);
|
||||
if (missingPermissions) {
|
||||
|
@ -29,8 +29,8 @@ export const AddRolesAction = automodAction({
|
|||
return;
|
||||
}
|
||||
|
||||
const rolesToAssign = [];
|
||||
const rolesWeCannotAssign = [];
|
||||
const rolesToAssign: string[] = [];
|
||||
const rolesWeCannotAssign: string[] = [];
|
||||
for (const roleId of actionConfig) {
|
||||
if (canAssignRole(pluginData.guild, me, roleId)) {
|
||||
rolesToAssign.push(roleId);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import * as t from "io-ts";
|
||||
import { automodAction } from "../helpers";
|
||||
import { LogType } from "../../../data/LogType";
|
||||
import { asyncMap, resolveMember, tNullable, unique } from "../../../utils";
|
||||
import { asyncMap, nonNullish, resolveMember, tNullable, unique } from "../../../utils";
|
||||
import { resolveActionContactMethods } from "../functions/resolveActionContactMethods";
|
||||
import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin";
|
||||
|
||||
|
@ -20,14 +20,14 @@ export const BanAction = automodAction({
|
|||
async apply({ pluginData, contexts, actionConfig, matchResult }) {
|
||||
const reason = actionConfig.reason || "Kicked automatically";
|
||||
const contactMethods = resolveActionContactMethods(pluginData, actionConfig);
|
||||
const deleteMessageDays = actionConfig.deleteMessageDays;
|
||||
const deleteMessageDays = actionConfig.deleteMessageDays || undefined;
|
||||
|
||||
const caseArgs = {
|
||||
modId: pluginData.client.user.id,
|
||||
extraNotes: [matchResult.fullSummary],
|
||||
extraNotes: matchResult.fullSummary ? [matchResult.fullSummary] : [],
|
||||
};
|
||||
|
||||
const userIdsToBan = unique(contexts.map(c => c.user?.id).filter(Boolean));
|
||||
const userIdsToBan = unique(contexts.map(c => c.user?.id).filter(nonNullish));
|
||||
|
||||
const modActions = pluginData.getPlugin(ModActionsPlugin);
|
||||
for (const userId of userIdsToBan) {
|
||||
|
|
|
@ -2,7 +2,7 @@ import * as t from "io-ts";
|
|||
import { automodAction } from "../helpers";
|
||||
import { LogType } from "../../../data/LogType";
|
||||
import { LogsPlugin } from "../../Logs/LogsPlugin";
|
||||
import { unique } from "../../../utils";
|
||||
import { nonNullish, unique } from "../../../utils";
|
||||
|
||||
export const ChangeNicknameAction = automodAction({
|
||||
configType: t.union([
|
||||
|
@ -15,7 +15,7 @@ export const ChangeNicknameAction = automodAction({
|
|||
defaultConfig: {},
|
||||
|
||||
async apply({ pluginData, contexts, actionConfig }) {
|
||||
const members = unique(contexts.map(c => c.member).filter(Boolean));
|
||||
const members = unique(contexts.map(c => c.member).filter(nonNullish));
|
||||
|
||||
for (const member of members) {
|
||||
if (pluginData.state.recentNicknameChanges.has(member.id)) continue;
|
||||
|
|
|
@ -15,12 +15,12 @@ export const CleanAction = automodAction({
|
|||
messageIdsToDeleteByChannelId.set(context.message.channel_id, []);
|
||||
}
|
||||
|
||||
if (messageIdsToDeleteByChannelId.get(context.message.channel_id).includes(context.message.id)) {
|
||||
if (messageIdsToDeleteByChannelId.get(context.message.channel_id)!.includes(context.message.id)) {
|
||||
console.warn(`Message ID to delete was already present: ${pluginData.guild.name}, rule ${ruleName}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
messageIdsToDeleteByChannelId.get(context.message.channel_id).push(context.message.id);
|
||||
messageIdsToDeleteByChannelId.get(context.message.channel_id)!.push(context.message.id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import * as t from "io-ts";
|
||||
import { automodAction } from "../helpers";
|
||||
import { LogType } from "../../../data/LogType";
|
||||
import { asyncMap, resolveMember, tNullable, unique } from "../../../utils";
|
||||
import { asyncMap, nonNullish, resolveMember, tNullable, unique } from "../../../utils";
|
||||
import { resolveActionContactMethods } from "../functions/resolveActionContactMethods";
|
||||
import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin";
|
||||
|
||||
|
@ -22,14 +22,15 @@ export const KickAction = automodAction({
|
|||
|
||||
const caseArgs = {
|
||||
modId: pluginData.client.user.id,
|
||||
extraNotes: [matchResult.fullSummary],
|
||||
extraNotes: matchResult.fullSummary ? [matchResult.fullSummary] : [],
|
||||
};
|
||||
|
||||
const userIdsToKick = unique(contexts.map(c => c.user?.id).filter(Boolean));
|
||||
const userIdsToKick = unique(contexts.map(c => c.user?.id).filter(nonNullish));
|
||||
const membersToKick = await asyncMap(userIdsToKick, id => resolveMember(pluginData.client, pluginData.guild, id));
|
||||
|
||||
const modActions = pluginData.getPlugin(ModActionsPlugin);
|
||||
for (const member of membersToKick) {
|
||||
if (!member) continue;
|
||||
await modActions.kickMember(member, reason, { contactMethods, caseArgs });
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
import * as t from "io-ts";
|
||||
import { automodAction } from "../helpers";
|
||||
import { LogType } from "../../../data/LogType";
|
||||
import { asyncMap, convertDelayStringToMS, resolveMember, tDelayString, tNullable, unique } from "../../../utils";
|
||||
import {
|
||||
asyncMap,
|
||||
convertDelayStringToMS,
|
||||
nonNullish,
|
||||
resolveMember,
|
||||
tDelayString,
|
||||
tNullable,
|
||||
unique,
|
||||
} from "../../../utils";
|
||||
import { resolveActionContactMethods } from "../functions/resolveActionContactMethods";
|
||||
import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin";
|
||||
import { MutesPlugin } from "../../Mutes/MutesPlugin";
|
||||
|
@ -21,16 +29,16 @@ export const MuteAction = automodAction({
|
|||
},
|
||||
|
||||
async apply({ pluginData, contexts, actionConfig, ruleName, matchResult }) {
|
||||
const duration = actionConfig.duration ? convertDelayStringToMS(actionConfig.duration) : null;
|
||||
const duration = actionConfig.duration ? convertDelayStringToMS(actionConfig.duration)! : undefined;
|
||||
const reason = actionConfig.reason || "Muted automatically";
|
||||
const contactMethods = resolveActionContactMethods(pluginData, actionConfig);
|
||||
|
||||
const caseArgs = {
|
||||
modId: pluginData.client.user.id,
|
||||
extraNotes: [matchResult.fullSummary],
|
||||
extraNotes: matchResult.fullSummary ? [matchResult.fullSummary] : [],
|
||||
};
|
||||
|
||||
const userIdsToMute = unique(contexts.map(c => c.user?.id).filter(Boolean));
|
||||
const userIdsToMute = unique(contexts.map(c => c.user?.id).filter(nonNullish));
|
||||
|
||||
const mutes = pluginData.getPlugin(MutesPlugin);
|
||||
for (const userId of userIdsToMute) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import * as t from "io-ts";
|
||||
import { automodAction } from "../helpers";
|
||||
import { LogType } from "../../../data/LogType";
|
||||
import { asyncMap, resolveMember, tNullable, unique } from "../../../utils";
|
||||
import { asyncMap, nonNullish, resolveMember, tNullable, unique } from "../../../utils";
|
||||
import { resolveActionContactMethods } from "../functions/resolveActionContactMethods";
|
||||
import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin";
|
||||
import { getMissingPermissions } from "../../../utils/getMissingPermissions";
|
||||
|
@ -19,8 +19,8 @@ export const RemoveRolesAction = automodAction({
|
|||
defaultConfig: [],
|
||||
|
||||
async apply({ pluginData, contexts, actionConfig, ruleName }) {
|
||||
const members = unique(contexts.map(c => c.member).filter(Boolean));
|
||||
const me = pluginData.guild.members.get(pluginData.client.user.id);
|
||||
const members = unique(contexts.map(c => c.member).filter(nonNullish));
|
||||
const me = pluginData.guild.members.get(pluginData.client.user.id)!;
|
||||
|
||||
const missingPermissions = getMissingPermissions(me.permission, p.manageRoles);
|
||||
if (missingPermissions) {
|
||||
|
@ -31,8 +31,8 @@ export const RemoveRolesAction = automodAction({
|
|||
return;
|
||||
}
|
||||
|
||||
const rolesToRemove = [];
|
||||
const rolesWeCannotRemove = [];
|
||||
const rolesToRemove: string[] = [];
|
||||
const rolesWeCannotRemove: string[] = [];
|
||||
for (const roleId of actionConfig) {
|
||||
if (canAssignRole(pluginData.guild, me, roleId)) {
|
||||
rolesToRemove.push(roleId);
|
||||
|
|
|
@ -28,14 +28,14 @@ export const ReplyAction = automodAction({
|
|||
async apply({ pluginData, contexts, actionConfig }) {
|
||||
const contextsWithTextChannels = contexts
|
||||
.filter(c => c.message?.channel_id)
|
||||
.filter(c => pluginData.guild.channels.get(c.message.channel_id) instanceof TextChannel);
|
||||
.filter(c => pluginData.guild.channels.get(c.message!.channel_id) instanceof TextChannel);
|
||||
|
||||
const contextsByChannelId = contextsWithTextChannels.reduce((map: Map<string, AutomodContext[]>, context) => {
|
||||
if (!map.has(context.message.channel_id)) {
|
||||
map.set(context.message.channel_id, []);
|
||||
if (!map.has(context.message!.channel_id)) {
|
||||
map.set(context.message!.channel_id, []);
|
||||
}
|
||||
|
||||
map.get(context.message.channel_id).push(context);
|
||||
map.get(context.message!.channel_id)!.push(context);
|
||||
return map;
|
||||
}, new Map());
|
||||
|
||||
|
@ -57,7 +57,7 @@ export const ReplyAction = automodAction({
|
|||
const replyMsg = await channel.createMessage(formatted);
|
||||
|
||||
if (typeof actionConfig === "object" && actionConfig.auto_delete) {
|
||||
const delay = convertDelayStringToMS(String(actionConfig.auto_delete));
|
||||
const delay = convertDelayStringToMS(String(actionConfig.auto_delete))!;
|
||||
setTimeout(() => replyMsg.delete().catch(noop), delay);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import { setAntiraidLevel } from "../functions/setAntiraidLevel";
|
|||
|
||||
export const SetAntiraidLevelAction = automodAction({
|
||||
configType: t.string,
|
||||
defaultConfig: null,
|
||||
defaultConfig: "",
|
||||
|
||||
async apply({ pluginData, contexts, actionConfig }) {
|
||||
setAntiraidLevel(pluginData, actionConfig);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import * as t from "io-ts";
|
||||
import { automodAction } from "../helpers";
|
||||
import { LogType } from "../../../data/LogType";
|
||||
import { asyncMap, resolveMember, tNullable, unique } from "../../../utils";
|
||||
import { asyncMap, nonNullish, resolveMember, tNullable, unique } from "../../../utils";
|
||||
import { resolveActionContactMethods } from "../functions/resolveActionContactMethods";
|
||||
import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin";
|
||||
|
||||
|
@ -22,14 +22,15 @@ export const WarnAction = automodAction({
|
|||
|
||||
const caseArgs = {
|
||||
modId: pluginData.client.user.id,
|
||||
extraNotes: [matchResult.fullSummary],
|
||||
extraNotes: matchResult.fullSummary ? [matchResult.fullSummary] : [],
|
||||
};
|
||||
|
||||
const userIdsToWarn = unique(contexts.map(c => c.user?.id).filter(Boolean));
|
||||
const userIdsToWarn = unique(contexts.map(c => c.user?.id).filter(nonNullish));
|
||||
const membersToWarn = await asyncMap(userIdsToWarn, id => resolveMember(pluginData.client, pluginData.guild, id));
|
||||
|
||||
const modActions = pluginData.getPlugin(ModActionsPlugin);
|
||||
for (const member of membersToWarn) {
|
||||
if (!member) continue;
|
||||
await modActions.warnMember(member, reason, { contactMethods, caseArgs });
|
||||
}
|
||||
},
|
||||
|
|
|
@ -4,8 +4,9 @@ import { RECENT_ACTION_EXPIRY_TIME, RecentActionType } from "../constants";
|
|||
import { getEmojiInString, getRoleMentions, getUrlsInString, getUserMentions } from "../../../utils";
|
||||
|
||||
export function addRecentActionsFromMessage(pluginData: GuildPluginData<AutomodPluginType>, context: AutomodContext) {
|
||||
const globalIdentifier = context.message.user_id;
|
||||
const perChannelIdentifier = `${context.message.channel_id}-${context.message.user_id}`;
|
||||
const message = context.message!;
|
||||
const globalIdentifier = message.user_id;
|
||||
const perChannelIdentifier = `${message.channel_id}-${message.user_id}`;
|
||||
const expiresAt = Date.now() + RECENT_ACTION_EXPIRY_TIME;
|
||||
|
||||
pluginData.state.recentActions.push({
|
||||
|
@ -23,8 +24,7 @@ export function addRecentActionsFromMessage(pluginData: GuildPluginData<AutomodP
|
|||
});
|
||||
|
||||
const mentionCount =
|
||||
getUserMentions(context.message.data.content || "").length +
|
||||
getRoleMentions(context.message.data.content || "").length;
|
||||
getUserMentions(message.data.content || "").length + getRoleMentions(message.data.content || "").length;
|
||||
if (mentionCount) {
|
||||
pluginData.state.recentActions.push({
|
||||
context,
|
||||
|
@ -41,7 +41,7 @@ export function addRecentActionsFromMessage(pluginData: GuildPluginData<AutomodP
|
|||
});
|
||||
}
|
||||
|
||||
const linkCount = getUrlsInString(context.message.data.content || "").length;
|
||||
const linkCount = getUrlsInString(message.data.content || "").length;
|
||||
if (linkCount) {
|
||||
pluginData.state.recentActions.push({
|
||||
context,
|
||||
|
@ -58,7 +58,7 @@ export function addRecentActionsFromMessage(pluginData: GuildPluginData<AutomodP
|
|||
});
|
||||
}
|
||||
|
||||
const attachmentCount = context.message.data.attachments && context.message.data.attachments.length;
|
||||
const attachmentCount = message.data.attachments && message.data.attachments.length;
|
||||
if (attachmentCount) {
|
||||
pluginData.state.recentActions.push({
|
||||
context,
|
||||
|
@ -75,7 +75,7 @@ export function addRecentActionsFromMessage(pluginData: GuildPluginData<AutomodP
|
|||
});
|
||||
}
|
||||
|
||||
const emojiCount = getEmojiInString(context.message.data.content || "").length;
|
||||
const emojiCount = getEmojiInString(message.data.content || "").length;
|
||||
if (emojiCount) {
|
||||
pluginData.state.recentActions.push({
|
||||
context,
|
||||
|
@ -93,7 +93,7 @@ export function addRecentActionsFromMessage(pluginData: GuildPluginData<AutomodP
|
|||
}
|
||||
|
||||
// + 1 is for the first line of the message (which doesn't have a line break)
|
||||
const lineCount = context.message.data.content ? (context.message.data.content.match(/\n/g) || []).length + 1 : 0;
|
||||
const lineCount = message.data.content ? (message.data.content.match(/\n/g) || []).length + 1 : 0;
|
||||
if (lineCount) {
|
||||
pluginData.state.recentActions.push({
|
||||
context,
|
||||
|
@ -110,7 +110,7 @@ export function addRecentActionsFromMessage(pluginData: GuildPluginData<AutomodP
|
|||
});
|
||||
}
|
||||
|
||||
const characterCount = [...(context.message.data.content || "")].length;
|
||||
const characterCount = [...(message.data.content || "")].length;
|
||||
if (characterCount) {
|
||||
pluginData.state.recentActions.push({
|
||||
context,
|
||||
|
@ -127,7 +127,7 @@ export function addRecentActionsFromMessage(pluginData: GuildPluginData<AutomodP
|
|||
});
|
||||
}
|
||||
|
||||
const stickerCount = (context.message.data.stickers || []).length;
|
||||
const stickerCount = (message.data.stickers || []).length;
|
||||
if (stickerCount) {
|
||||
pluginData.state.recentActions.push({
|
||||
context,
|
||||
|
|
|
@ -4,8 +4,9 @@ import { RECENT_ACTION_EXPIRY_TIME, RecentActionType } from "../constants";
|
|||
import { getEmojiInString, getRoleMentions, getUrlsInString, getUserMentions } from "../../../utils";
|
||||
|
||||
export function clearRecentActionsForMessage(pluginData: GuildPluginData<AutomodPluginType>, context: AutomodContext) {
|
||||
const globalIdentifier = context.message.user_id;
|
||||
const perChannelIdentifier = `${context.message.channel_id}-${context.message.user_id}`;
|
||||
const message = context.message!;
|
||||
const globalIdentifier = message.user_id;
|
||||
const perChannelIdentifier = `${message.channel_id}-${message.user_id}`;
|
||||
|
||||
pluginData.state.recentActions = pluginData.state.recentActions.filter(act => {
|
||||
return act.identifier !== globalIdentifier && act.identifier !== perChannelIdentifier;
|
||||
|
|
|
@ -7,6 +7,7 @@ import { findRecentSpam } from "./findRecentSpam";
|
|||
import { getMatchingMessageRecentActions } from "./getMatchingMessageRecentActions";
|
||||
import * as t from "io-ts";
|
||||
import { getMessageSpamIdentifier } from "./getSpamIdentifier";
|
||||
import { SavedMessage } from "../../../data/entities/SavedMessage";
|
||||
|
||||
const MessageSpamTriggerConfig = t.type({
|
||||
amount: t.number,
|
||||
|
@ -29,22 +30,25 @@ export function createMessageSpamTrigger(spamType: RecentActionType, prettyName:
|
|||
return;
|
||||
}
|
||||
|
||||
const spamIdentifier = getMessageSpamIdentifier(context.message, triggerConfig.per_channel);
|
||||
const spamIdentifier = getMessageSpamIdentifier(context.message, Boolean(triggerConfig.per_channel));
|
||||
|
||||
const recentSpam = findRecentSpam(pluginData, spamType, spamIdentifier);
|
||||
if (recentSpam) {
|
||||
await pluginData.state.archives.addSavedMessagesToArchive(
|
||||
recentSpam.archiveId,
|
||||
[context.message],
|
||||
pluginData.guild,
|
||||
);
|
||||
if (recentSpam.archiveId) {
|
||||
await pluginData.state.archives.addSavedMessagesToArchive(
|
||||
recentSpam.archiveId,
|
||||
[context.message],
|
||||
pluginData.guild,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
silentClean: true,
|
||||
extra: { archiveId: "" }, // FIXME: Fix up automod trigger match() typings so extra is not required when doing a silentClean
|
||||
};
|
||||
}
|
||||
|
||||
const within = convertDelayStringToMS(triggerConfig.within);
|
||||
const within = convertDelayStringToMS(triggerConfig.within) ?? 0;
|
||||
const matchedSpam = getMatchingMessageRecentActions(
|
||||
pluginData,
|
||||
context.message,
|
||||
|
@ -58,7 +62,7 @@ export function createMessageSpamTrigger(spamType: RecentActionType, prettyName:
|
|||
const messages = matchedSpam.recentActions
|
||||
.map(action => action.context.message)
|
||||
.filter(Boolean)
|
||||
.sort(sorter("posted_at"));
|
||||
.sort(sorter("posted_at")) as SavedMessage[];
|
||||
|
||||
const archiveId = await pluginData.state.archives.createFromSavedMessages(messages, pluginData.guild);
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ export function getMatchingRecentActions(
|
|||
action.type === type &&
|
||||
(!identifier || action.identifier === identifier) &&
|
||||
action.context.timestamp >= since &&
|
||||
action.context.timestamp <= to &&
|
||||
action.context.timestamp <= to! &&
|
||||
!action.context.actioned
|
||||
);
|
||||
});
|
||||
|
|
|
@ -10,23 +10,25 @@ export function getTextMatchPartialSummary(
|
|||
context: AutomodContext,
|
||||
) {
|
||||
if (type === "message") {
|
||||
const channel = pluginData.guild.channels.get(context.message.channel_id);
|
||||
const channelMention = channel ? verboseChannelMention(channel) : `\`#${context.message.channel_id}\``;
|
||||
const message = context.message!;
|
||||
const channel = pluginData.guild.channels.get(message.channel_id);
|
||||
const channelMention = channel ? verboseChannelMention(channel) : `\`#${message.channel_id}\``;
|
||||
|
||||
return `message in ${channelMention}:\n${messageSummary(context.message)}`;
|
||||
return `message in ${channelMention}:\n${messageSummary(message)}`;
|
||||
} else if (type === "embed") {
|
||||
const channel = pluginData.guild.channels.get(context.message.channel_id);
|
||||
const channelMention = channel ? verboseChannelMention(channel) : `\`#${context.message.channel_id}\``;
|
||||
const message = context.message!;
|
||||
const channel = pluginData.guild.channels.get(message.channel_id);
|
||||
const channelMention = channel ? verboseChannelMention(channel) : `\`#${message.channel_id}\``;
|
||||
|
||||
return `message embed in ${channelMention}:\n${messageSummary(context.message)}`;
|
||||
return `message embed in ${channelMention}:\n${messageSummary(message)}`;
|
||||
} else if (type === "username") {
|
||||
return `username: ${context.user.username}`;
|
||||
return `username: ${context.user!.username}`;
|
||||
} else if (type === "nickname") {
|
||||
return `nickname: ${context.member.nick}`;
|
||||
return `nickname: ${context.member!.nick}`;
|
||||
} else if (type === "visiblename") {
|
||||
const visibleName = context.member?.nick || context.user.username;
|
||||
const visibleName = context.member?.nick || context.user!.username;
|
||||
return `visible name: ${visibleName}`;
|
||||
} else if (type === "customstatus") {
|
||||
return `custom status: ${context.member.game.state}`;
|
||||
return `custom status: ${context.member!.game!.state}`;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,10 +7,10 @@ import { AutomodPluginType } from "../types";
|
|||
export function resolveActionContactMethods(
|
||||
pluginData: GuildPluginData<AutomodPluginType>,
|
||||
actionConfig: {
|
||||
notify?: string;
|
||||
notifyChannel?: string;
|
||||
notify?: string | null;
|
||||
notifyChannel?: string | null;
|
||||
},
|
||||
): UserNotificationMethod[] | null {
|
||||
): UserNotificationMethod[] {
|
||||
if (actionConfig.notify === "dm") {
|
||||
return [{ type: "dm" }];
|
||||
} else if (actionConfig.notify === "channel") {
|
||||
|
@ -28,5 +28,5 @@ export function resolveActionContactMethods(
|
|||
return [];
|
||||
}
|
||||
|
||||
return null;
|
||||
return [];
|
||||
}
|
||||
|
|
|
@ -5,13 +5,14 @@ import { availableActions } from "../actions/availableActions";
|
|||
import { AutomodTriggerMatchResult } from "../helpers";
|
||||
import { CleanAction } from "../actions/clean";
|
||||
import { checkAndUpdateCooldown } from "./checkAndUpdateCooldown";
|
||||
import { TextChannel } from "eris";
|
||||
|
||||
export async function runAutomod(pluginData: GuildPluginData<AutomodPluginType>, context: AutomodContext) {
|
||||
const userId = context.user?.id || context.member?.id || context.message?.user_id;
|
||||
const user = context.user || (userId && pluginData.client.users.get(userId));
|
||||
const member = context.member || (userId && pluginData.guild.members.get(userId));
|
||||
const member = context.member || (userId && pluginData.guild.members.get(userId)) || null;
|
||||
const channelId = context.message?.channel_id;
|
||||
const channel = channelId && pluginData.guild.channels.get(channelId);
|
||||
const channel = channelId ? (pluginData.guild.channels.get(channelId) as TextChannel) : null;
|
||||
const categoryId = channel?.parentID;
|
||||
|
||||
const config = pluginData.config.getMatchingConfig({
|
||||
|
@ -29,8 +30,8 @@ export async function runAutomod(pluginData: GuildPluginData<AutomodPluginType>,
|
|||
return;
|
||||
}
|
||||
|
||||
let matchResult: AutomodTriggerMatchResult<any>;
|
||||
let contexts: AutomodContext[];
|
||||
let matchResult: AutomodTriggerMatchResult<any> | null | undefined;
|
||||
let contexts: AutomodContext[] = [];
|
||||
|
||||
triggerLoop: for (const triggerItem of rule.triggers) {
|
||||
for (const [triggerName, triggerConfig] of Object.entries(triggerItem)) {
|
||||
|
|
|
@ -3,9 +3,8 @@ import { Awaitable } from "knub/dist/utils";
|
|||
import * as t from "io-ts";
|
||||
import { AutomodContext, AutomodPluginType } from "./types";
|
||||
|
||||
export interface AutomodTriggerMatchResult<TExtra extends any = unknown> {
|
||||
interface BaseAutomodTriggerMatchResult {
|
||||
extraContexts?: AutomodContext[];
|
||||
extra?: TExtra;
|
||||
|
||||
silentClean?: boolean; // TODO: Maybe generalize to a "silent" value in general, which mutes alert/log
|
||||
|
||||
|
@ -13,12 +12,16 @@ export interface AutomodTriggerMatchResult<TExtra extends any = unknown> {
|
|||
fullSummary?: string;
|
||||
}
|
||||
|
||||
export type AutomodTriggerMatchResult<TExtra extends any = unknown> = unknown extends TExtra
|
||||
? BaseAutomodTriggerMatchResult
|
||||
: BaseAutomodTriggerMatchResult & { extra: TExtra };
|
||||
|
||||
type AutomodTriggerMatchFn<TConfigType, TMatchResultExtra> = (meta: {
|
||||
ruleName: string;
|
||||
pluginData: GuildPluginData<AutomodPluginType>;
|
||||
context: AutomodContext;
|
||||
triggerConfig: TConfigType;
|
||||
}) => Awaitable<null | AutomodTriggerMatchResult<TMatchResultExtra>>;
|
||||
}) => Awaitable<null | undefined | AutomodTriggerMatchResult<TMatchResultExtra>>;
|
||||
|
||||
type AutomodTriggerRenderMatchInformationFn<TConfigType, TMatchResultExtra> = (meta: {
|
||||
ruleName: string;
|
||||
|
|
|
@ -73,15 +73,15 @@ export const MatchAttachmentTypeTrigger = automodTrigger<MatchResultType>()({
|
|||
},
|
||||
|
||||
renderMatchInformation({ pluginData, contexts, matchResult }) {
|
||||
const channel = pluginData.guild.channels.get(contexts[0].message.channel_id);
|
||||
const channel = pluginData.guild.channels.get(contexts[0].message!.channel_id)!;
|
||||
const prettyChannel = verboseChannelMention(channel);
|
||||
|
||||
return (
|
||||
asSingleLine(`
|
||||
Matched attachment type \`${disableInlineCode(matchResult.extra.matchedType)}\`
|
||||
(${matchResult.extra.mode === "blacklist" ? "(blacklisted)" : "(not in whitelist)"})
|
||||
in message (\`${contexts[0].message.id}\`) in ${prettyChannel}:
|
||||
`) + messageSummary(contexts[0].message)
|
||||
in message (\`${contexts[0].message!.id}\`) in ${prettyChannel}:
|
||||
`) + messageSummary(contexts[0].message!)
|
||||
);
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import * as t from "io-ts";
|
||||
import { GuildInvite } from "eris";
|
||||
import { automodTrigger } from "../helpers";
|
||||
import {
|
||||
disableCodeBlocks,
|
||||
disableInlineCode,
|
||||
getInviteCodesInString,
|
||||
GuildInvite,
|
||||
isGuildInvite,
|
||||
resolveInvite,
|
||||
tNullable,
|
||||
|
|
|
@ -19,7 +19,7 @@ export const MemberJoinTrigger = automodTrigger<unknown>()({
|
|||
}
|
||||
|
||||
if (triggerConfig.only_new) {
|
||||
const threshold = Date.now() - convertDelayStringToMS(triggerConfig.new_threshold);
|
||||
const threshold = Date.now() - convertDelayStringToMS(triggerConfig.new_threshold)!;
|
||||
return context.member.createdAt >= threshold ? {} : null;
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,6 @@ export const MemberJoinTrigger = automodTrigger<unknown>()({
|
|||
},
|
||||
|
||||
renderMatchInformation({ pluginData, contexts, triggerConfig }) {
|
||||
return null;
|
||||
return "";
|
||||
},
|
||||
});
|
||||
|
|
|
@ -25,7 +25,7 @@ export const MemberJoinSpamTrigger = automodTrigger<unknown>()({
|
|||
return {};
|
||||
}
|
||||
|
||||
const since = Date.now() - convertDelayStringToMS(triggerConfig.within);
|
||||
const since = Date.now() - convertDelayStringToMS(triggerConfig.within)!;
|
||||
const matchingActions = getMatchingRecentActions(pluginData, RecentActionType.MemberJoin, null, since);
|
||||
const totalCount = sumRecentActionCounts(matchingActions);
|
||||
|
||||
|
@ -46,6 +46,6 @@ export const MemberJoinSpamTrigger = automodTrigger<unknown>()({
|
|||
},
|
||||
|
||||
renderMatchInformation({ pluginData, contexts, triggerConfig }) {
|
||||
return null;
|
||||
return "";
|
||||
},
|
||||
});
|
||||
|
|
|
@ -9,16 +9,16 @@ interface RoleAddedMatchResult {
|
|||
export const RoleAddedTrigger = automodTrigger<RoleAddedMatchResult>()({
|
||||
configType: t.union([t.string, t.array(t.string)]),
|
||||
|
||||
defaultConfig: null,
|
||||
defaultConfig: [],
|
||||
|
||||
async match({ triggerConfig, context, pluginData }) {
|
||||
if (!context.member || !context.rolesChanged || context.rolesChanged.added.length === 0) {
|
||||
if (!context.member || !context.rolesChanged || context.rolesChanged.added!.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const triggerRoles = Array.isArray(triggerConfig) ? triggerConfig : [triggerConfig];
|
||||
for (const roleId of triggerRoles) {
|
||||
if (context.rolesChanged.added.includes(roleId)) {
|
||||
if (context.rolesChanged.added!.includes(roleId)) {
|
||||
if (consumeIgnoredRoleChange(pluginData, context.member.id, roleId)) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -9,10 +9,10 @@ interface RoleAddedMatchResult {
|
|||
export const RoleRemovedTrigger = automodTrigger<RoleAddedMatchResult>()({
|
||||
configType: t.union([t.string, t.array(t.string)]),
|
||||
|
||||
defaultConfig: null,
|
||||
defaultConfig: [],
|
||||
|
||||
async match({ triggerConfig, context, pluginData }) {
|
||||
if (!context.member || !context.rolesChanged || context.rolesChanged.removed.length === 0) {
|
||||
if (!context.member || !context.rolesChanged || context.rolesChanged.removed!.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ export const RoleRemovedTrigger = automodTrigger<RoleAddedMatchResult>()({
|
|||
continue;
|
||||
}
|
||||
|
||||
if (context.rolesChanged.removed.includes(roleId)) {
|
||||
if (context.rolesChanged.removed!.includes(roleId)) {
|
||||
return {
|
||||
extra: {
|
||||
matchedRoleId: roleId,
|
||||
|
|
|
@ -105,13 +105,13 @@ export interface AutomodContext {
|
|||
|
||||
export interface RecentAction {
|
||||
type: RecentActionType;
|
||||
identifier: string;
|
||||
identifier: string | null;
|
||||
count: number;
|
||||
context: AutomodContext;
|
||||
}
|
||||
|
||||
export interface RecentSpam {
|
||||
archiveId: string;
|
||||
archiveId: string | null;
|
||||
type: RecentActionType;
|
||||
identifiers: string[];
|
||||
timestamp: number;
|
||||
|
|
|
@ -45,8 +45,9 @@ export const BotControlPlugin = zeppelinGlobalPlugin<BotControlPluginType>()("bo
|
|||
pluginData.state.configs = new Configs();
|
||||
pluginData.state.apiPermissionAssignments = new ApiPermissionAssignments();
|
||||
|
||||
if (getActiveReload()) {
|
||||
const [guildId, channelId] = getActiveReload();
|
||||
const activeReload = getActiveReload();
|
||||
if (activeReload) {
|
||||
const [guildId, channelId] = activeReload;
|
||||
resetActiveReload();
|
||||
|
||||
const guild = pluginData.client.guilds.get(guildId);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
let activeReload: [string, string] = null;
|
||||
let activeReload: [string, string] | null = null;
|
||||
|
||||
export function getActiveReload() {
|
||||
return activeReload;
|
||||
|
|
|
@ -19,7 +19,7 @@ export const LeaveServerCmd = botControlCmd({
|
|||
return;
|
||||
}
|
||||
|
||||
const guildToLeave = pluginData.client.guilds.get(args.guildId);
|
||||
const guildToLeave = pluginData.client.guilds.get(args.guildId)!;
|
||||
const guildName = guildToLeave.name;
|
||||
|
||||
try {
|
||||
|
|
|
@ -21,7 +21,7 @@ export const ServersCmd = botControlCmd({
|
|||
|
||||
async run({ pluginData, message: msg, args }) {
|
||||
const showList = Boolean(args.all || args.initialized || args.uninitialized || args.search);
|
||||
const search = args.search && new RegExp([...args.search].map(s => escapeStringRegexp(s)).join(".*"), "i");
|
||||
const search = args.search ? new RegExp([...args.search].map(s => escapeStringRegexp(s)).join(".*"), "i") : null;
|
||||
|
||||
const joinedGuilds = Array.from(pluginData.client.guilds.values());
|
||||
const loadedGuilds = pluginData.getKnubInstance().getLoadedGuilds();
|
||||
|
@ -39,7 +39,7 @@ export const ServersCmd = botControlCmd({
|
|||
}
|
||||
|
||||
if (args.search) {
|
||||
filteredGuilds = filteredGuilds.filter(g => search.test(`${g.id} ${g.name}`));
|
||||
filteredGuilds = filteredGuilds.filter(g => search!.test(`${g.id} ${g.name}`));
|
||||
}
|
||||
|
||||
if (filteredGuilds.length) {
|
||||
|
|
|
@ -12,7 +12,7 @@ export async function createCase(pluginData: GuildPluginData<CasesPluginType>, a
|
|||
const mod = await resolveUser(pluginData.client, args.modId);
|
||||
const modName = `${mod.username}#${mod.discriminator}`;
|
||||
|
||||
let ppName = null;
|
||||
let ppName: string | null = null;
|
||||
if (args.ppId) {
|
||||
const pp = await resolveUser(pluginData.client, args.ppId);
|
||||
ppName = `${pp.username}#${pp.discriminator}`;
|
||||
|
|
|
@ -15,7 +15,9 @@ export async function getCaseEmbed(
|
|||
requestMemberId?: string,
|
||||
): Promise<AdvancedMessageContent> {
|
||||
const theCase = await pluginData.state.cases.with("notes").find(resolveCaseId(caseOrCaseId));
|
||||
if (!theCase) return null;
|
||||
if (!theCase) {
|
||||
throw new Error("Unknown case");
|
||||
}
|
||||
|
||||
const timeAndDate = pluginData.getPlugin(TimeAndDatePlugin);
|
||||
|
||||
|
|
|
@ -28,12 +28,13 @@ export async function getCaseSummary(
|
|||
caseOrCaseId: Case | number,
|
||||
withLinks = false,
|
||||
requestMemberId?: string,
|
||||
) {
|
||||
): Promise<string | null> {
|
||||
const config = pluginData.config.get();
|
||||
const timeAndDate = pluginData.getPlugin(TimeAndDatePlugin);
|
||||
|
||||
const caseId = caseOrCaseId instanceof Case ? caseOrCaseId.id : caseOrCaseId;
|
||||
const theCase = await pluginData.state.cases.with("notes").find(caseId);
|
||||
if (!theCase) return null;
|
||||
|
||||
const firstNote = theCase.notes[0];
|
||||
let reason = firstNote ? firstNote.body : "";
|
||||
|
@ -47,7 +48,7 @@ export async function getCaseSummary(
|
|||
|
||||
if (reason.length > CASE_SUMMARY_REASON_MAX_LENGTH) {
|
||||
const match = reason.slice(CASE_SUMMARY_REASON_MAX_LENGTH, 100).match(/(?:[.,!?\s]|$)/);
|
||||
const nextWhitespaceIndex = match ? CASE_SUMMARY_REASON_MAX_LENGTH + match.index : CASE_SUMMARY_REASON_MAX_LENGTH;
|
||||
const nextWhitespaceIndex = match ? CASE_SUMMARY_REASON_MAX_LENGTH + match.index! : CASE_SUMMARY_REASON_MAX_LENGTH;
|
||||
if (nextWhitespaceIndex < reason.length) {
|
||||
reason = reason.slice(0, nextWhitespaceIndex - 1) + "...";
|
||||
}
|
||||
|
@ -56,7 +57,7 @@ export async function getCaseSummary(
|
|||
reason = disableLinkPreviews(reason);
|
||||
|
||||
const timestamp = moment.utc(theCase.created_at, DBDateFormat);
|
||||
const relativeTimeCutoff = convertDelayStringToMS(config.relative_time_cutoff);
|
||||
const relativeTimeCutoff = convertDelayStringToMS(config.relative_time_cutoff)!;
|
||||
const useRelativeTime = config.show_relative_times && Date.now() - timestamp.valueOf() < relativeTimeCutoff;
|
||||
const timestampWithTz = requestMemberId
|
||||
? await timeAndDate.inMemberTz(requestMemberId, timestamp)
|
||||
|
|
|
@ -11,13 +11,13 @@ import { logger } from "../../../logger";
|
|||
export async function postToCaseLogChannel(
|
||||
pluginData: GuildPluginData<CasesPluginType>,
|
||||
content: MessageContent,
|
||||
file: MessageFile = null,
|
||||
file?: MessageFile,
|
||||
): Promise<Message | null> {
|
||||
const caseLogChannelId = pluginData.config.get().case_log_channel;
|
||||
if (!caseLogChannelId) return;
|
||||
if (!caseLogChannelId) return null;
|
||||
|
||||
const caseLogChannel = pluginData.guild.channels.get(caseLogChannelId);
|
||||
if (!caseLogChannel || !(caseLogChannel instanceof TextChannel)) return;
|
||||
if (!caseLogChannel || !(caseLogChannel instanceof TextChannel)) return null;
|
||||
|
||||
let result;
|
||||
try {
|
||||
|
@ -30,7 +30,7 @@ export async function postToCaseLogChannel(
|
|||
pluginData.state.logs.log(LogType.BOT_ALERT, {
|
||||
body: `Missing permissions to post mod cases in <#${caseLogChannel.id}>`,
|
||||
});
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
throw e;
|
||||
|
@ -44,17 +44,17 @@ export async function postCaseToCaseLogChannel(
|
|||
caseOrCaseId: Case | number,
|
||||
): Promise<Message | null> {
|
||||
const theCase = await pluginData.state.cases.find(resolveCaseId(caseOrCaseId));
|
||||
if (!theCase) return;
|
||||
if (!theCase) return null;
|
||||
|
||||
const caseEmbed = await getCaseEmbed(pluginData, caseOrCaseId);
|
||||
if (!caseEmbed) return;
|
||||
if (!caseEmbed) return null;
|
||||
|
||||
if (theCase.log_message_id) {
|
||||
const [channelId, messageId] = theCase.log_message_id.split("-");
|
||||
|
||||
try {
|
||||
await pluginData.client.editMessage(channelId, messageId, caseEmbed);
|
||||
return;
|
||||
return null;
|
||||
} catch (e) {} // tslint:disable-line:no-empty
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +1,9 @@
|
|||
import { GuildPluginData } from "knub";
|
||||
import { CensorPluginType } from "../types";
|
||||
import { SavedMessage } from "../../../data/entities/SavedMessage";
|
||||
import { AnyInvite, Embed, GuildInvite } from "eris";
|
||||
import { Embed, Invite } from "eris";
|
||||
import { ZalgoRegex } from "../../../data/Zalgo";
|
||||
import {
|
||||
getInviteCodesInString,
|
||||
getUrlsInString,
|
||||
resolveMember,
|
||||
resolveInvite,
|
||||
isGuildInvite,
|
||||
isRESTGuildInvite,
|
||||
} from "../../../utils";
|
||||
import { getInviteCodesInString, getUrlsInString, resolveMember, resolveInvite, isGuildInvite } from "../../../utils";
|
||||
import cloneDeep from "lodash.clonedeep";
|
||||
import { censorMessage } from "./censorMessage";
|
||||
import escapeStringRegexp from "escape-string-regexp";
|
||||
|
@ -59,7 +52,7 @@ export async function applyFiltersToMsg(
|
|||
|
||||
const inviteCodes = getInviteCodesInString(messageContent);
|
||||
|
||||
const invites: Array<AnyInvite | null> = await Promise.all(
|
||||
const invites: Array<Invite | null> = await Promise.all(
|
||||
inviteCodes.map(code => resolveInvite(pluginData.client, code)),
|
||||
);
|
||||
|
||||
|
@ -75,7 +68,7 @@ export async function applyFiltersToMsg(
|
|||
return true;
|
||||
}
|
||||
|
||||
if (isRESTGuildInvite(invite)) {
|
||||
if (isGuildInvite(invite)) {
|
||||
if (inviteGuildWhitelist && !inviteGuildWhitelist.includes(invite.guild.id)) {
|
||||
censorMessage(
|
||||
pluginData,
|
||||
|
|
|
@ -46,9 +46,9 @@ export const ArchiveChannelCmd = channelArchiverCmd({
|
|||
const maxMessagesToArchive = args.messages ? Math.min(args.messages, MAX_ARCHIVED_MESSAGES) : MAX_ARCHIVED_MESSAGES;
|
||||
if (maxMessagesToArchive <= 0) return;
|
||||
|
||||
const archiveLines = [];
|
||||
const archiveLines: string[] = [];
|
||||
let archivedMessages = 0;
|
||||
let previousId;
|
||||
let previousId: string | undefined;
|
||||
|
||||
const startTime = Date.now();
|
||||
const progressMsg = await msg.channel.createMessage("Creating archive...");
|
||||
|
@ -80,7 +80,7 @@ export const ArchiveChannelCmd = channelArchiverCmd({
|
|||
}
|
||||
|
||||
if (message.reactions && Object.keys(message.reactions).length > 0) {
|
||||
const reactionCounts = [];
|
||||
const reactionCounts: string[] = [];
|
||||
for (const [emoji, info] of Object.entries(message.reactions)) {
|
||||
reactionCounts.push(`${info.count}x ${emoji}`);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,8 @@ export function getCompanionChannelOptsForVoiceChannelId(
|
|||
return Object.values(config.entries)
|
||||
.filter(
|
||||
opts =>
|
||||
opts.voice_channel_ids.includes(voiceChannel.id) || opts.voice_channel_ids.includes(voiceChannel.parentID),
|
||||
opts.voice_channel_ids.includes(voiceChannel.id) ||
|
||||
(voiceChannel.parentID && opts.voice_channel_ids.includes(voiceChannel.parentID)),
|
||||
)
|
||||
.map(opts => Object.assign({}, defaultCompanionChannelOpts, opts));
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ export async function handleCompanionPermissions(
|
|||
export async function handleCompanionPermissions(
|
||||
pluginData: GuildPluginData<CompanionChannelsPluginType>,
|
||||
userId: string,
|
||||
voiceChannel?: VoiceChannel,
|
||||
voiceChannel: VoiceChannel | null,
|
||||
oldChannel?: VoiceChannel,
|
||||
) {
|
||||
if (pluginData.state.errorCooldownManager.isOnCooldown(ERROR_COOLDOWN_KEY)) {
|
||||
|
@ -65,7 +65,7 @@ export async function handleCompanionPermissions(
|
|||
for (const channelId of permsToDelete) {
|
||||
const channel = pluginData.guild.channels.get(channelId);
|
||||
if (!channel || !(channel instanceof TextChannel)) continue;
|
||||
await channel.deletePermission(userId, `Companion Channel for ${oldChannel.id} | User Left`);
|
||||
await channel.deletePermission(userId, `Companion Channel for ${oldChannel!.id} | User Left`);
|
||||
}
|
||||
|
||||
for (const [channelId, permissions] of permsToSet) {
|
||||
|
@ -76,7 +76,7 @@ export async function handleCompanionPermissions(
|
|||
permissions,
|
||||
0,
|
||||
"member",
|
||||
`Companion Channel for ${voiceChannel.id} | User Joined`,
|
||||
`Companion Channel for ${voiceChannel!.id} | User Joined`,
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
|
|
|
@ -25,7 +25,7 @@ export async function addRoleAction(
|
|||
const target = await resolveMember(pluginData.client, pluginData.guild, targetId);
|
||||
if (!target) throw new ActionError(`Unknown target member: ${targetId}`);
|
||||
|
||||
if (event.trigger.type === "command" && !canActOn(pluginData, (eventData.msg as Message).member, target)) {
|
||||
if (event.trigger.type === "command" && !canActOn(pluginData, eventData.msg.member, target)) {
|
||||
throw new ActionError("Missing permissions");
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ export async function moveToVoiceChannelAction(
|
|||
const target = await resolveMember(pluginData.client, pluginData.guild, targetId);
|
||||
if (!target) throw new ActionError("Unknown target member");
|
||||
|
||||
if (event.trigger.type === "command" && !canActOn(pluginData, (eventData.msg as Message).member, target)) {
|
||||
if (event.trigger.type === "command" && !canActOn(pluginData, eventData.msg.member, target)) {
|
||||
throw new ActionError("Missing permissions");
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import { DeleteFollowCmd, ListFollowCmd } from "./commands/ListFollowCmd";
|
|||
import { ChannelJoinAlertsEvt, ChannelLeaveAlertsEvt, ChannelSwitchAlertsEvt } from "./events/SendAlertsEvts";
|
||||
import { GuildBanRemoveAlertsEvt } from "./events/BanRemoveAlertsEvt";
|
||||
import { trimPluginDescription } from "../../utils";
|
||||
import Timeout = NodeJS.Timeout;
|
||||
|
||||
const defaultOptions: PluginOptions<LocateUserPluginType> = {
|
||||
config: {
|
||||
|
@ -70,7 +71,7 @@ export const LocateUserPlugin = zeppelinGuildPlugin<LocateUserPluginType>()("loc
|
|||
},
|
||||
|
||||
onUnload(pluginData) {
|
||||
clearTimeout(pluginData.state.outdatedAlertsTimeout);
|
||||
clearTimeout(pluginData.state.outdatedAlertsTimeout as Timeout);
|
||||
pluginData.state.unloaded = true;
|
||||
},
|
||||
});
|
||||
|
|
|
@ -14,7 +14,6 @@ export const WhereCmd = locateUserCmd({
|
|||
},
|
||||
|
||||
async run({ message: msg, args, pluginData }) {
|
||||
const member = await resolveMember(pluginData.client, pluginData.guild, args.member.id);
|
||||
sendWhere(pluginData, member, msg.channel, `${msg.member.mention} | `);
|
||||
sendWhere(pluginData, args.member, msg.channel, `${msg.member.mention} | `);
|
||||
},
|
||||
});
|
||||
|
|
|
@ -13,7 +13,7 @@ export interface LocateUserPluginType extends BasePluginType {
|
|||
config: TConfigSchema;
|
||||
state: {
|
||||
alerts: GuildVCAlerts;
|
||||
outdatedAlertsTimeout: Timeout;
|
||||
outdatedAlertsTimeout: Timeout | null;
|
||||
usersWithAlerts: string[];
|
||||
unloaded: boolean;
|
||||
};
|
||||
|
|
|
@ -8,6 +8,7 @@ import { moveMember } from "./moveMember";
|
|||
export async function sendAlerts(pluginData: GuildPluginData<LocateUserPluginType>, userId: string) {
|
||||
const triggeredAlerts = await pluginData.state.alerts.getAlertsByUserId(userId);
|
||||
const member = await resolveMember(pluginData.client, pluginData.guild, userId);
|
||||
if (!member) return;
|
||||
|
||||
triggeredAlerts.forEach(alert => {
|
||||
const prepend = `<@!${alert.requestor_id}>, an alert requested by you has triggered!\nReminder: \`${alert.body}\`\n`;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Member, TextableChannel, VoiceChannel } from "eris";
|
||||
import { Invite, Member, TextableChannel, VoiceChannel } from "eris";
|
||||
import { getInviteLink } from "knub/dist/helpers";
|
||||
import { createOrReuseInvite } from "./createOrReuseInvite";
|
||||
import { GuildPluginData } from "knub";
|
||||
|
@ -11,12 +11,14 @@ export async function sendWhere(
|
|||
channel: TextableChannel,
|
||||
prepend: string,
|
||||
) {
|
||||
const voice = pluginData.guild.channels.get(member.voiceState.channelID) as VoiceChannel;
|
||||
const voice = member.voiceState.channelID
|
||||
? (pluginData.guild.channels.get(member.voiceState.channelID) as VoiceChannel)
|
||||
: null;
|
||||
|
||||
if (voice == null) {
|
||||
channel.createMessage(prepend + "That user is not in a channel");
|
||||
} else {
|
||||
let invite = null;
|
||||
let invite: Invite;
|
||||
try {
|
||||
invite = await createOrReuseInvite(voice);
|
||||
} catch (e) {
|
||||
|
|
|
@ -28,11 +28,11 @@ export const LogsGuildMemberAddEvt = logsEvt({
|
|||
cases.sort((a, b) => (a.created_at > b.created_at ? -1 : 1));
|
||||
|
||||
if (cases.length) {
|
||||
const recentCaseLines = [];
|
||||
const recentCaseLines: string[] = [];
|
||||
const recentCases = cases.slice(0, 2);
|
||||
const casesPlugin = pluginData.getPlugin(CasesPlugin);
|
||||
for (const theCase of recentCases) {
|
||||
recentCaseLines.push(await casesPlugin.getCaseSummary(theCase));
|
||||
recentCaseLines.push((await casesPlugin.getCaseSummary(theCase))!);
|
||||
}
|
||||
|
||||
let recentCaseSummary = recentCaseLines.join("\n");
|
||||
|
|
|
@ -14,16 +14,17 @@ import { renderTemplate, TemplateParseError } from "../../../templateFormatter";
|
|||
import { logger } from "../../../logger";
|
||||
import moment from "moment-timezone";
|
||||
import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
|
||||
import { MessageContent } from "eris";
|
||||
|
||||
export async function getLogMessage(
|
||||
pluginData: GuildPluginData<LogsPluginType>,
|
||||
type: LogType,
|
||||
data: any,
|
||||
opts?: Pick<TLogChannel, "format" | "timestamp_format" | "include_embed_timestamp">,
|
||||
): Promise<string> {
|
||||
): Promise<MessageContent | null> {
|
||||
const config = pluginData.config.get();
|
||||
const format = opts?.format?.[LogType[type]] || config.format[LogType[type]] || "";
|
||||
if (format === "" || format == null) return;
|
||||
if (format === "" || format == null) return null;
|
||||
|
||||
// See comment on FORMAT_NO_TIMESTAMP in types.ts
|
||||
const timestampFormat =
|
||||
|
@ -45,7 +46,7 @@ export async function getLogMessage(
|
|||
|
||||
const usersOrMembers = Array.isArray(inputUserOrMember) ? inputUserOrMember : [inputUserOrMember];
|
||||
|
||||
const mentions = [];
|
||||
const mentions: string[] = [];
|
||||
for (const userOrMember of usersOrMembers) {
|
||||
let user;
|
||||
let member;
|
||||
|
@ -91,7 +92,7 @@ export async function getLogMessage(
|
|||
} catch (e) {
|
||||
if (e instanceof TemplateParseError) {
|
||||
logger.error(`Error when parsing template:\nError: ${e.message}\nTemplate: ${format}`);
|
||||
return;
|
||||
return null;
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
|
|
|
@ -109,13 +109,13 @@ export async function log(pluginData: GuildPluginData<LogsPluginType>, type: Log
|
|||
if (!pluginData.state.batches.has(channel.id)) {
|
||||
pluginData.state.batches.set(channel.id, []);
|
||||
setTimeout(async () => {
|
||||
const batchedMessage = pluginData.state.batches.get(channel.id).join("\n");
|
||||
const batchedMessage = pluginData.state.batches.get(channel.id)!.join("\n");
|
||||
pluginData.state.batches.delete(channel.id);
|
||||
createChunkedMessage(channel, batchedMessage).catch(noop);
|
||||
}, batchTime);
|
||||
}
|
||||
|
||||
pluginData.state.batches.get(channel.id).push(message);
|
||||
pluginData.state.batches.get(channel.id)!.push(message);
|
||||
} else {
|
||||
// If we're not batching log messages, just send them immediately
|
||||
await createChunkedMessage(channel, message).catch(noop);
|
||||
|
|
|
@ -7,7 +7,7 @@ export async function saveMessagesToDB(
|
|||
channel: TextChannel,
|
||||
ids: string[],
|
||||
) {
|
||||
const failed = [];
|
||||
const failed: string[] = [];
|
||||
for (const id of ids) {
|
||||
const savedMessage = await pluginData.state.savedMessages.find(id);
|
||||
if (savedMessage) continue;
|
||||
|
|
|
@ -65,7 +65,7 @@ export const AddCaseCmd = modActionsCmd({
|
|||
modId: mod.id,
|
||||
type: CaseTypes[type],
|
||||
reason,
|
||||
ppId: mod.id !== msg.author.id ? msg.author.id : null,
|
||||
ppId: mod.id !== msg.author.id ? msg.author.id : undefined,
|
||||
});
|
||||
|
||||
if (user) {
|
||||
|
|
|
@ -78,7 +78,7 @@ export const BanCmd = modActionsCmd({
|
|||
contactMethods,
|
||||
caseArgs: {
|
||||
modId: mod.id,
|
||||
ppId: mod.id !== msg.author.id ? msg.author.id : null,
|
||||
ppId: mod.id !== msg.author.id ? msg.author.id : undefined,
|
||||
},
|
||||
deleteMessageDays,
|
||||
});
|
||||
|
|
|
@ -9,6 +9,7 @@ import { LogsPlugin } from "../../Logs/LogsPlugin";
|
|||
import { LogType } from "../../../data/LogType";
|
||||
import moment from "moment-timezone";
|
||||
import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
|
||||
import { Case } from "../../../data/entities/Case";
|
||||
|
||||
export const DeleteCaseCmd = modActionsCmd({
|
||||
trigger: ["delete_case", "deletecase"],
|
||||
|
@ -25,8 +26,8 @@ export const DeleteCaseCmd = modActionsCmd({
|
|||
},
|
||||
|
||||
async run({ pluginData, message, args }) {
|
||||
const failed = [];
|
||||
const validCases = [];
|
||||
const failed: number[] = [];
|
||||
const validCases: Case[] = [];
|
||||
let cancelled = 0;
|
||||
|
||||
for (const num of args.caseNumber) {
|
||||
|
|
|
@ -77,7 +77,7 @@ export const ForcebanCmd = modActionsCmd({
|
|||
modId: mod.id,
|
||||
type: CaseTypes.Ban,
|
||||
reason,
|
||||
ppId: mod.id !== msg.author.id ? msg.author.id : null,
|
||||
ppId: mod.id !== msg.author.id ? msg.author.id : undefined,
|
||||
});
|
||||
|
||||
// Confirm the action
|
||||
|
|
|
@ -14,7 +14,7 @@ export const HideCaseCmd = modActionsCmd({
|
|||
],
|
||||
|
||||
async run({ pluginData, message: msg, args }) {
|
||||
const failed = [];
|
||||
const failed: number[] = [];
|
||||
|
||||
for (const num of args.caseNum) {
|
||||
const theCase = await pluginData.state.cases.findByCaseNumber(num);
|
||||
|
|
|
@ -62,7 +62,7 @@ export const MassbanCmd = modActionsCmd({
|
|||
const loadingMsg = await msg.channel.createMessage("Banning...");
|
||||
|
||||
// Ban each user and count failed bans (if any)
|
||||
const failedBans = [];
|
||||
const failedBans: string[] = [];
|
||||
const casesPlugin = pluginData.getPlugin(CasesPlugin);
|
||||
for (const userId of args.userIds) {
|
||||
try {
|
||||
|
|
|
@ -62,7 +62,7 @@ export const MassmuteCmd = modActionsCmd({
|
|||
|
||||
// Mute everyone and count fails
|
||||
const modId = msg.author.id;
|
||||
const failedMutes = [];
|
||||
const failedMutes: string[] = [];
|
||||
const mutesPlugin = pluginData.getPlugin(MutesPlugin);
|
||||
for (const userId of args.userIds) {
|
||||
try {
|
||||
|
|
|
@ -59,7 +59,7 @@ export const UnbanCmd = modActionsCmd({
|
|||
modId: mod.id,
|
||||
type: CaseTypes.Unban,
|
||||
reason,
|
||||
ppId: mod.id !== msg.author.id ? msg.author.id : null,
|
||||
ppId: mod.id !== msg.author.id ? msg.author.id : undefined,
|
||||
});
|
||||
|
||||
// Confirm the action
|
||||
|
|
|
@ -14,7 +14,7 @@ export const UnhideCaseCmd = modActionsCmd({
|
|||
],
|
||||
|
||||
async run({ pluginData, message: msg, args }) {
|
||||
const failed = [];
|
||||
const failed: number[] = [];
|
||||
|
||||
for (const num of args.caseNum) {
|
||||
const theCase = await pluginData.state.cases.findByCaseNumber(num);
|
||||
|
|
|
@ -24,7 +24,7 @@ export const UpdateCmd = modActionsCmd({
|
|||
],
|
||||
|
||||
async run({ pluginData, message: msg, args }) {
|
||||
let theCase: Case;
|
||||
let theCase: Case | undefined;
|
||||
if (args.caseNumber != null) {
|
||||
theCase = await pluginData.state.cases.findByCaseNumber(args.caseNumber);
|
||||
} else {
|
||||
|
|
|
@ -91,7 +91,7 @@ export const WarnCmd = modActionsCmd({
|
|||
contactMethods,
|
||||
caseArgs: {
|
||||
modId: mod.id,
|
||||
ppId: mod.id !== msg.author.id ? msg.author.id : null,
|
||||
ppId: mod.id !== msg.author.id ? msg.author.id : undefined,
|
||||
reason,
|
||||
},
|
||||
retryPromptChannel: msg.channel as TextChannel,
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue