Reformat all files with Prettier

This commit is contained in:
Dragory 2021-09-11 19:06:51 +03:00
parent 0cde0d46d2
commit ac79eb09f5
No known key found for this signature in database
GPG key ID: 5F387BA66DF8AAC1
206 changed files with 727 additions and 888 deletions

View file

@ -1,24 +1,24 @@
const fs = require('fs'); const fs = require("fs");
const path = require('path'); const path = require("path");
try { try {
fs.accessSync(path.resolve(__dirname, 'bot.env')); fs.accessSync(path.resolve(__dirname, "bot.env"));
require('dotenv').config({ path: path.resolve(__dirname, 'bot.env') }); require("dotenv").config({ path: path.resolve(__dirname, "bot.env") });
} catch { } catch {
try { try {
fs.accessSync(path.resolve(__dirname, 'api.env')); fs.accessSync(path.resolve(__dirname, "api.env"));
require('dotenv').config({ path: path.resolve(__dirname, 'api.env') }); require("dotenv").config({ path: path.resolve(__dirname, "api.env") });
} catch { } catch {
throw new Error("bot.env or api.env required"); throw new Error("bot.env or api.env required");
} }
} }
const moment = require('moment-timezone'); const moment = require("moment-timezone");
moment.tz.setDefault('UTC'); moment.tz.setDefault("UTC");
const entities = path.relative(process.cwd(), path.resolve(__dirname, 'dist/backend/src/data/entities/*.js')); const entities = path.relative(process.cwd(), path.resolve(__dirname, "dist/backend/src/data/entities/*.js"));
const migrations = path.relative(process.cwd(), path.resolve(__dirname, 'dist/backend/src/migrations/*.js')); const migrations = path.relative(process.cwd(), path.resolve(__dirname, "dist/backend/src/migrations/*.js"));
const migrationsDir = path.relative(process.cwd(), path.resolve(__dirname, 'src/migrations')); const migrationsDir = path.relative(process.cwd(), path.resolve(__dirname, "src/migrations"));
module.exports = { module.exports = {
type: "mysql", type: "mysql",
@ -26,7 +26,7 @@ module.exports = {
username: process.env.DB_USER, username: process.env.DB_USER,
password: process.env.DB_PASSWORD, password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE, database: process.env.DB_DATABASE,
charset: 'utf8mb4', charset: "utf8mb4",
supportBigNumbers: true, supportBigNumbers: true,
bigNumberStrings: true, bigNumberStrings: true,
dateStrings: true, dateStrings: true,
@ -39,13 +39,13 @@ module.exports = {
// Pool options // Pool options
extra: { extra: {
typeCast(field, next) { typeCast(field, next) {
if (field.type === 'DATETIME') { if (field.type === "DATETIME") {
const val = field.string(); const val = field.string();
return val != null ? moment.utc(val).format('YYYY-MM-DD HH:mm:ss') : null; return val != null ? moment.utc(val).format("YYYY-MM-DD HH:mm:ss") : null;
} }
return next(); return next();
} },
}, },
// Migrations // Migrations

View file

@ -6,9 +6,9 @@
* https://github.com/TypeStrong/ts-node/pull/254 * https://github.com/TypeStrong/ts-node/pull/254
*/ */
const path = require('path'); const path = require("path");
const tsconfig = require('./tsconfig.json'); const tsconfig = require("./tsconfig.json");
const tsconfigPaths = require('tsconfig-paths'); const tsconfigPaths = require("tsconfig-paths");
// E.g. ./dist/backend // E.g. ./dist/backend
const baseUrl = path.resolve(tsconfig.compilerOptions.outDir, path.basename(__dirname)); const baseUrl = path.resolve(tsconfig.compilerOptions.outDir, path.basename(__dirname));

View file

@ -29,7 +29,7 @@ export class Queue<TQueueFunction extends AnyFn = AnyFn> {
} }
public add(fn: TQueueFunction): Promise<any> { public add(fn: TQueueFunction): Promise<any> {
const promise = new Promise<any>(resolve => { const promise = new Promise<any>((resolve) => {
this.queue.push(async () => { this.queue.push(async () => {
const result = await fn(); const result = await fn();
resolve(result); resolve(result);
@ -50,7 +50,7 @@ export class Queue<TQueueFunction extends AnyFn = AnyFn> {
} }
const fn = this.queue.shift()!; const fn = this.queue.shift()!;
new Promise(resolve => { new Promise((resolve) => {
// Either fn() completes or the timeout is reached // Either fn() completes or the timeout is reached
void fn().then(resolve); void fn().then(resolve);
setTimeout(resolve, this._timeout); setTimeout(resolve, this._timeout);

View file

@ -42,7 +42,7 @@ export class QueuedEventEmitter {
const listeners = [...(this.listeners.get(eventName) || []), ...(this.listeners.get("*") || [])]; const listeners = [...(this.listeners.get(eventName) || []), ...(this.listeners.get("*") || [])];
let promise: Promise<any> = Promise.resolve(); let promise: Promise<any> = Promise.resolve();
listeners.forEach(listener => { listeners.forEach((listener) => {
promise = this.queue.add(listener.bind(null, ...args)); promise = this.queue.add(listener.bind(null, ...args));
}); });

View file

@ -27,7 +27,7 @@ const INITIAL_REGEX_TIMEOUT = 5 * SECONDS;
const INITIAL_REGEX_TIMEOUT_DURATION = 30 * SECONDS; const INITIAL_REGEX_TIMEOUT_DURATION = 30 * SECONDS;
const FINAL_REGEX_TIMEOUT = 5 * SECONDS; const FINAL_REGEX_TIMEOUT = 5 * SECONDS;
const regexTimeoutUpgradePromise = new Promise(resolve => setTimeout(resolve, INITIAL_REGEX_TIMEOUT_DURATION)); const regexTimeoutUpgradePromise = new Promise((resolve) => setTimeout(resolve, INITIAL_REGEX_TIMEOUT_DURATION));
let newWorkerTimeout = INITIAL_REGEX_TIMEOUT; let newWorkerTimeout = INITIAL_REGEX_TIMEOUT;
regexTimeoutUpgradePromise.then(() => (newWorkerTimeout = FINAL_REGEX_TIMEOUT)); regexTimeoutUpgradePromise.then(() => (newWorkerTimeout = FINAL_REGEX_TIMEOUT));

View file

@ -33,21 +33,21 @@ function simpleDiscordAPIRequest(bearerToken, path): Promise<any> {
Authorization: `Bearer ${bearerToken}`, Authorization: `Bearer ${bearerToken}`,
}, },
}, },
res => { (res) => {
if (res.statusCode !== 200) { if (res.statusCode !== 200) {
reject(new Error(`Discord API error ${res.statusCode}`)); reject(new Error(`Discord API error ${res.statusCode}`));
return; return;
} }
let rawData = ""; let rawData = "";
res.on("data", data => (rawData += data)); res.on("data", (data) => (rawData += data));
res.on("end", () => { res.on("end", () => {
resolve(JSON.parse(rawData)); resolve(JSON.parse(rawData));
}); });
}, },
); );
request.on("error", err => reject(err)); request.on("error", (err) => reject(err));
}); });
} }

View file

@ -22,21 +22,21 @@ function formatConfigSchema(schema) {
} else if (schema.name.startsWith("Optional<")) { } else if (schema.name.startsWith("Optional<")) {
return `Optional<${formatConfigSchema(schema.types[0])}>`; return `Optional<${formatConfigSchema(schema.types[0])}>`;
} else { } else {
return schema.types.map(t => formatConfigSchema(t)).join(" | "); return schema.types.map((t) => formatConfigSchema(t)).join(" | ");
} }
} else if (schema._tag === "IntersectionType") { } else if (schema._tag === "IntersectionType") {
return schema.types.map(t => formatConfigSchema(t)).join(" & "); return schema.types.map((t) => formatConfigSchema(t)).join(" & ");
} else { } else {
return schema.name; return schema.name;
} }
} }
export function initDocs(app: express.Express) { export function initDocs(app: express.Express) {
const docsPlugins = guildPlugins.filter(plugin => plugin.showInDocs); const docsPlugins = guildPlugins.filter((plugin) => plugin.showInDocs);
app.get("/docs/plugins", (req: express.Request, res: express.Response) => { app.get("/docs/plugins", (req: express.Request, res: express.Response) => {
res.json( res.json(
docsPlugins.map(plugin => { docsPlugins.map((plugin) => {
const thinInfo = plugin.info ? { prettyName: plugin.info.prettyName, legacy: plugin.info.legacy ?? false } : {}; const thinInfo = plugin.info ? { prettyName: plugin.info.prettyName, legacy: plugin.info.legacy ?? false } : {};
return { return {
name: plugin.name, name: plugin.name,
@ -56,7 +56,7 @@ export function initDocs(app: express.Express) {
const name = plugin.name; const name = plugin.name;
const info = plugin.info || {}; const info = plugin.info || {};
const commands = (plugin.commands || []).map(cmd => ({ const commands = (plugin.commands || []).map((cmd) => ({
trigger: cmd.trigger, trigger: cmd.trigger,
permission: cmd.permission, permission: cmd.permission,
signature: cmd.signature, signature: cmd.signature,

View file

@ -131,7 +131,7 @@ export function initGuildsAPI(app: express.Express) {
} }
const validPermissions = new Set(Object.values(ApiPermissions)); const validPermissions = new Set(Object.values(ApiPermissions));
validPermissions.delete(ApiPermissions.Owner); validPermissions.delete(ApiPermissions.Owner);
if (!Array.isArray(permissions) || permissions.some(p => !validPermissions.has(p))) { if (!Array.isArray(permissions) || permissions.some((p) => !validPermissions.has(p))) {
return clientError(res, "Invalid permissions"); return clientError(res, "Invalid permissions");
} }
if (expiresAt != null && !moment.utc(expiresAt).isValid()) { if (expiresAt != null && !moment.utc(expiresAt).isValid()) {

View file

@ -36,7 +36,7 @@ export async function validateGuildConfig(config: any): Promise<string | null> {
const plugin = pluginNameToPlugin.get(pluginName)!; const plugin = pluginNameToPlugin.get(pluginName)!;
try { try {
const mergedOptions = configUtils.mergeConfig(plugin.defaultOptions || {}, pluginOptions); const mergedOptions = configUtils.mergeConfig(plugin.defaultOptions || {}, pluginOptions);
await plugin.configPreprocessor?.((mergedOptions as unknown) as PluginOptions<any>, true); await plugin.configPreprocessor?.(mergedOptions as unknown as PluginOptions<any>, true);
} catch (err) { } catch (err) {
if (err instanceof ConfigValidationError || err instanceof StrictValidationError) { if (err instanceof ConfigValidationError || err instanceof StrictValidationError) {
return `${pluginName}: ${err.message}`; return `${pluginName}: ${err.message}`;

View file

@ -68,10 +68,7 @@ export class ApiLogins extends BaseRepository {
token: hashedToken, token: hashedToken,
user_id: userId, user_id: userId,
logged_in_at: moment.utc().format(DBDateFormat), logged_in_at: moment.utc().format(DBDateFormat),
expires_at: moment expires_at: moment.utc().add(LOGIN_EXPIRY_TIME, "ms").format(DBDateFormat),
.utc()
.add(LOGIN_EXPIRY_TIME, "ms")
.format(DBDateFormat),
}); });
return `${loginId}.${token}`; return `${loginId}.${token}`;
@ -96,10 +93,7 @@ export class ApiLogins extends BaseRepository {
await this.apiLogins.update( await this.apiLogins.update(
{ id: loginId }, { id: loginId },
{ {
expires_at: moment() expires_at: moment().utc().add(LOGIN_EXPIRY_TIME, "ms").format(DBDateFormat),
.utc()
.add(LOGIN_EXPIRY_TIME, "ms")
.format(DBDateFormat),
}, },
); );
} }

View file

@ -22,7 +22,7 @@ export class ApiUserInfo extends BaseRepository {
} }
update(id, data: ApiUserInfoData) { update(id, data: ApiUserInfoData) {
return connection.transaction(async entityManager => { return connection.transaction(async (entityManager) => {
const repo = entityManager.getRepository(ApiUserInfoEntity); const repo = entityManager.getRepository(ApiUserInfoEntity);
const existingInfo = await repo.findOne({ where: { id } }); const existingInfo = await repo.findOne({ where: { id } });

View file

@ -41,11 +41,7 @@ export class Configs extends BaseRepository {
} }
getActiveLargerThanId(id) { getActiveLargerThanId(id) {
return this.configs return this.configs.createQueryBuilder().where("id > :id", { id }).andWhere("is_active = 1").getMany();
.createQueryBuilder()
.where("id > :id", { id })
.andWhere("is_active = 1")
.getMany();
} }
async hasConfig(key) { async hasConfig(key) {
@ -65,7 +61,7 @@ export class Configs extends BaseRepository {
} }
async saveNewRevision(key, config, editedBy) { async saveNewRevision(key, config, editedBy) {
return connection.transaction(async entityManager => { return connection.transaction(async (entityManager) => {
const repo = entityManager.getRepository(Config); const repo = entityManager.getRepository(Config);
// Mark all old revisions inactive // Mark all old revisions inactive
await repo.update({ key }, { is_active: false }); await repo.update({ key }, { is_active: false });

View file

@ -88,10 +88,10 @@ export class GuildArchives extends BaseGuildRepository {
id: msg.id, id: msg.id,
timestamp: moment.utc(msg.posted_at).format("YYYY-MM-DD HH:mm:ss"), timestamp: moment.utc(msg.posted_at).format("YYYY-MM-DD HH:mm:ss"),
content: msg.data.content, content: msg.data.content,
attachments: msg.data.attachments?.map(att => { attachments: msg.data.attachments?.map((att) => {
return JSON.stringify({ name: att.name, url: att.url, type: att.contentType }); return JSON.stringify({ name: att.name, url: att.url, type: att.contentType });
}), }),
stickers: msg.data.stickers?.map(sti => { stickers: msg.data.stickers?.map((sti) => {
return JSON.stringify({ name: sti.name, id: sti.id, isDefault: isDefaultSticker(sti.id) }); return JSON.stringify({ name: sti.name, id: sti.id, isDefault: isDefaultSticker(sti.id) });
}), }),
user: partialUser, user: partialUser,

View file

@ -123,7 +123,7 @@ export class GuildCases extends BaseGuildRepository {
guild_id: this.guildId, guild_id: this.guildId,
case_number: () => `(SELECT IFNULL(MAX(case_number)+1, 1) FROM cases AS ma2 WHERE guild_id = ${this.guildId})`, case_number: () => `(SELECT IFNULL(MAX(case_number)+1, 1) FROM cases AS ma2 WHERE guild_id = ${this.guildId})`,
}) })
.catch(err => { .catch((err) => {
if (err?.code === "ER_DUP_ENTRY") { if (err?.code === "ER_DUP_ENTRY") {
if (data.audit_log_id) { if (data.audit_log_id) {
console.trace(`Tried to insert case with duplicate audit_log_id`); console.trace(`Tried to insert case with duplicate audit_log_id`);
@ -148,7 +148,7 @@ export class GuildCases extends BaseGuildRepository {
} }
async softDelete(id: number, deletedById: string, deletedByName: string, deletedByText: string) { async softDelete(id: number, deletedById: string, deletedByName: string, deletedByText: string) {
return connection.transaction(async entityManager => { return connection.transaction(async (entityManager) => {
const cases = entityManager.getRepository(Case); const cases = entityManager.getRepository(Case);
const caseNotes = entityManager.getRepository(CaseNote); const caseNotes = entityManager.getRepository(CaseNote);

View file

@ -17,19 +17,11 @@ const MAX_COUNTER_VALUE = 2147483647; // 2^31-1, for MySQL INT
const decayQueue = new Queue(); const decayQueue = new Queue();
async function deleteCountersMarkedToBeDeleted(): Promise<void> { async function deleteCountersMarkedToBeDeleted(): Promise<void> {
await getRepository(Counter) await getRepository(Counter).createQueryBuilder().where("delete_at <= NOW()").delete().execute();
.createQueryBuilder()
.where("delete_at <= NOW()")
.delete()
.execute();
} }
async function deleteTriggersMarkedToBeDeleted(): Promise<void> { async function deleteTriggersMarkedToBeDeleted(): Promise<void> {
await getRepository(CounterTrigger) await getRepository(CounterTrigger).createQueryBuilder().where("delete_at <= NOW()").delete().execute();
.createQueryBuilder()
.where("delete_at <= NOW()")
.delete()
.execute();
} }
setInterval(deleteCountersMarkedToBeDeleted, 1 * HOURS); setInterval(deleteCountersMarkedToBeDeleted, 1 * HOURS);
@ -97,10 +89,7 @@ export class GuildCounters extends BaseGuildRepository {
criteria.id = Not(In(idsToKeep)); criteria.id = Not(In(idsToKeep));
} }
const deleteAt = moment const deleteAt = moment.utc().add(DELETE_UNUSED_COUNTERS_AFTER, "ms").format(DBDateFormat);
.utc()
.add(DELETE_UNUSED_COUNTERS_AFTER, "ms")
.format(DBDateFormat);
await this.counters.update(criteria, { await this.counters.update(criteria, {
delete_at: deleteAt, delete_at: deleteAt,
@ -108,11 +97,7 @@ export class GuildCounters extends BaseGuildRepository {
} }
async deleteCountersMarkedToBeDeleted(): Promise<void> { async deleteCountersMarkedToBeDeleted(): Promise<void> {
await this.counters await this.counters.createQueryBuilder().where("delete_at <= NOW()").delete().execute();
.createQueryBuilder()
.where("delete_at <= NOW()")
.delete()
.execute();
} }
async changeCounterValue( async changeCounterValue(
@ -230,14 +215,11 @@ export class GuildCounters extends BaseGuildRepository {
const triggersToMark = await triggersToMarkQuery.getMany(); const triggersToMark = await triggersToMarkQuery.getMany();
if (triggersToMark.length) { if (triggersToMark.length) {
const deleteAt = moment const deleteAt = moment.utc().add(DELETE_UNUSED_COUNTER_TRIGGERS_AFTER, "ms").format(DBDateFormat);
.utc()
.add(DELETE_UNUSED_COUNTER_TRIGGERS_AFTER, "ms")
.format(DBDateFormat);
await this.counterTriggers.update( await this.counterTriggers.update(
{ {
id: In(triggersToMark.map(t => t.id)), id: In(triggersToMark.map((t) => t.id)),
}, },
{ {
delete_at: deleteAt, delete_at: deleteAt,
@ -247,11 +229,7 @@ export class GuildCounters extends BaseGuildRepository {
} }
async deleteTriggersMarkedToBeDeleted(): Promise<void> { async deleteTriggersMarkedToBeDeleted(): Promise<void> {
await this.counterTriggers await this.counterTriggers.createQueryBuilder().where("delete_at <= NOW()").delete().execute();
.createQueryBuilder()
.where("delete_at <= NOW()")
.delete()
.execute();
} }
async initCounterTrigger( async initCounterTrigger(
@ -278,7 +256,7 @@ export class GuildCounters extends BaseGuildRepository {
throw new Error(`Invalid comparison value: ${reverseComparisonValue}`); throw new Error(`Invalid comparison value: ${reverseComparisonValue}`);
} }
return connection.transaction(async entityManager => { return connection.transaction(async (entityManager) => {
const existing = await entityManager.findOne(CounterTrigger, { const existing = await entityManager.findOne(CounterTrigger, {
counter_id: counterId, counter_id: counterId,
name: triggerName, name: triggerName,
@ -330,7 +308,7 @@ export class GuildCounters extends BaseGuildRepository {
channelId = channelId || "0"; channelId = channelId || "0";
userId = userId || "0"; userId = userId || "0";
return connection.transaction(async entityManager => { return connection.transaction(async (entityManager) => {
const previouslyTriggered = await entityManager.findOne(CounterTriggerState, { const previouslyTriggered = await entityManager.findOne(CounterTriggerState, {
trigger_id: counterTrigger.id, trigger_id: counterTrigger.id,
user_id: userId!, user_id: userId!,
@ -378,7 +356,7 @@ export class GuildCounters extends BaseGuildRepository {
async checkAllValuesForTrigger( async checkAllValuesForTrigger(
counterTrigger: CounterTrigger, counterTrigger: CounterTrigger,
): Promise<Array<{ channelId: string; userId: string }>> { ): Promise<Array<{ channelId: string; userId: string }>> {
return connection.transaction(async entityManager => { return connection.transaction(async (entityManager) => {
const matchingValues = await entityManager const matchingValues = await entityManager
.createQueryBuilder(CounterValue, "cv") .createQueryBuilder(CounterValue, "cv")
.leftJoin( .leftJoin(
@ -395,7 +373,7 @@ export class GuildCounters extends BaseGuildRepository {
if (matchingValues.length) { if (matchingValues.length) {
await entityManager.insert( await entityManager.insert(
CounterTriggerState, CounterTriggerState,
matchingValues.map(row => ({ matchingValues.map((row) => ({
trigger_id: counterTrigger.id, trigger_id: counterTrigger.id,
channel_id: row.channel_id, channel_id: row.channel_id,
user_id: row.user_id, user_id: row.user_id,
@ -403,7 +381,7 @@ export class GuildCounters extends BaseGuildRepository {
); );
} }
return matchingValues.map(row => ({ return matchingValues.map((row) => ({
channelId: row.channel_id, channelId: row.channel_id,
userId: row.user_id, userId: row.user_id,
})); }));
@ -429,7 +407,7 @@ export class GuildCounters extends BaseGuildRepository {
channelId = channelId || "0"; channelId = channelId || "0";
userId = userId || "0"; userId = userId || "0";
return connection.transaction(async entityManager => { return connection.transaction(async (entityManager) => {
const matchingValue = await entityManager const matchingValue = await entityManager
.createQueryBuilder(CounterValue, "cv") .createQueryBuilder(CounterValue, "cv")
.innerJoin( .innerJoin(
@ -468,7 +446,7 @@ export class GuildCounters extends BaseGuildRepository {
async checkAllValuesForReverseTrigger( async checkAllValuesForReverseTrigger(
counterTrigger: CounterTrigger, counterTrigger: CounterTrigger,
): Promise<Array<{ channelId: string; userId: string }>> { ): Promise<Array<{ channelId: string; userId: string }>> {
return connection.transaction(async entityManager => { return connection.transaction(async (entityManager) => {
const matchingValues: Array<{ const matchingValues: Array<{
id: string; id: string;
triggerStateId: string; triggerStateId: string;
@ -496,11 +474,11 @@ export class GuildCounters extends BaseGuildRepository {
if (matchingValues.length) { if (matchingValues.length) {
await entityManager.delete(CounterTriggerState, { await entityManager.delete(CounterTriggerState, {
id: In(matchingValues.map(v => v.triggerStateId)), id: In(matchingValues.map((v) => v.triggerStateId)),
}); });
} }
return matchingValues.map(row => ({ return matchingValues.map((row) => ({
channelId: row.channel_id, channelId: row.channel_id,
userId: row.user_id, userId: row.user_id,
})); }));

View file

@ -46,12 +46,12 @@ export class GuildLogs extends events.EventEmitter {
} }
isLogIgnored(type: LogType, ignoreId: any) { isLogIgnored(type: LogType, ignoreId: any) {
return this.ignoredLogs.some(info => type === info.type && ignoreId === info.ignoreId); return this.ignoredLogs.some((info) => type === info.type && ignoreId === info.ignoreId);
} }
clearIgnoredLog(type: LogType, ignoreId: any) { clearIgnoredLog(type: LogType, ignoreId: any) {
this.ignoredLogs.splice( this.ignoredLogs.splice(
this.ignoredLogs.findIndex(info => type === info.type && ignoreId === info.ignoreId), this.ignoredLogs.findIndex((info) => type === info.type && ignoreId === info.ignoreId),
1, 1,
); );
} }

View file

@ -19,7 +19,7 @@ export class GuildMemberTimezones extends BaseGuildRepository {
} }
async set(memberId, timezone: string) { async set(memberId, timezone: string) {
await connection.transaction(async entityManager => { await connection.transaction(async (entityManager) => {
const repo = entityManager.getRepository(MemberTimezone); const repo = entityManager.getRepository(MemberTimezone);
const existingRow = await repo.findOne({ const existingRow = await repo.findOne({
guild_id: this.guildId, guild_id: this.guildId,

View file

@ -35,12 +35,7 @@ export class GuildMutes extends BaseGuildRepository {
} }
async addMute(userId, expiryTime, rolesToRestore?: string[]): Promise<Mute> { async addMute(userId, expiryTime, rolesToRestore?: string[]): Promise<Mute> {
const expiresAt = expiryTime const expiresAt = expiryTime ? moment.utc().add(expiryTime, "ms").format("YYYY-MM-DD HH:mm:ss") : null;
? moment
.utc()
.add(expiryTime, "ms")
.format("YYYY-MM-DD HH:mm:ss")
: null;
const result = await this.mutes.insert({ const result = await this.mutes.insert({
guild_id: this.guildId, guild_id: this.guildId,
@ -53,12 +48,7 @@ export class GuildMutes extends BaseGuildRepository {
} }
async updateExpiryTime(userId, newExpiryTime, rolesToRestore?: string[]) { async updateExpiryTime(userId, newExpiryTime, rolesToRestore?: string[]) {
const expiresAt = newExpiryTime const expiresAt = newExpiryTime ? moment.utc().add(newExpiryTime, "ms").format("YYYY-MM-DD HH:mm:ss") : null;
? moment
.utc()
.add(newExpiryTime, "ms")
.format("YYYY-MM-DD HH:mm:ss")
: null;
if (rolesToRestore && rolesToRestore.length) { if (rolesToRestore && rolesToRestore.length) {
return this.mutes.update( return this.mutes.update(
@ -89,7 +79,7 @@ export class GuildMutes extends BaseGuildRepository {
.createQueryBuilder("mutes") .createQueryBuilder("mutes")
.where("guild_id = :guild_id", { guild_id: this.guildId }) .where("guild_id = :guild_id", { guild_id: this.guildId })
.andWhere( .andWhere(
new Brackets(qb => { new Brackets((qb) => {
qb.where("expires_at > NOW()").orWhere("expires_at IS NULL"); qb.where("expires_at > NOW()").orWhere("expires_at IS NULL");
}), }),
) )

View file

@ -70,7 +70,7 @@ export class GuildNicknameHistory extends BaseGuildRepository {
if (toDelete.length > 0) { if (toDelete.length > 0) {
await this.nicknameHistory.delete({ await this.nicknameHistory.delete({
id: In(toDelete.map(v => v.id)), id: In(toDelete.map((v) => v.id)),
}); });
} }
} }

View file

@ -46,7 +46,7 @@ export class GuildSavedMessages extends BaseGuildRepository {
}; };
if (msg.attachments.size) { if (msg.attachments.size) {
data.attachments = Array.from(msg.attachments.values()).map(att => ({ data.attachments = Array.from(msg.attachments.values()).map((att) => ({
id: att.id, id: att.id,
contentType: att.contentType, contentType: att.contentType,
name: att.name, name: att.name,
@ -59,14 +59,14 @@ export class GuildSavedMessages extends BaseGuildRepository {
} }
if (msg.embeds.length) { if (msg.embeds.length) {
data.embeds = msg.embeds.map(embed => ({ data.embeds = msg.embeds.map((embed) => ({
title: embed.title, title: embed.title,
description: embed.description, description: embed.description,
url: embed.url, url: embed.url,
timestamp: embed.timestamp, timestamp: embed.timestamp,
color: embed.color, color: embed.color,
fields: embed.fields.map(field => ({ fields: embed.fields.map((field) => ({
name: field.name, name: field.name,
value: field.value, value: field.value,
inline: field.inline, inline: field.inline,
@ -119,7 +119,7 @@ export class GuildSavedMessages extends BaseGuildRepository {
} }
if (msg.stickers?.size) { if (msg.stickers?.size) {
data.stickers = Array.from(msg.stickers.values()).map(sticker => ({ data.stickers = Array.from(msg.stickers.values()).map((sticker) => ({
format: sticker.format, format: sticker.format,
guildId: sticker.guildId, guildId: sticker.guildId,
id: sticker.id, id: sticker.id,

View file

@ -11,10 +11,7 @@ export class GuildScheduledPosts extends BaseGuildRepository {
} }
all(): Promise<ScheduledPost[]> { all(): Promise<ScheduledPost[]> {
return this.scheduledPosts return this.scheduledPosts.createQueryBuilder().where("guild_id = :guildId", { guildId: this.guildId }).getMany();
.createQueryBuilder()
.where("guild_id = :guildId", { guildId: this.guildId })
.getMany();
} }
getDueScheduledPosts(): Promise<ScheduledPost[]> { getDueScheduledPosts(): Promise<ScheduledPost[]> {

View file

@ -67,10 +67,7 @@ export class GuildSlowmodes extends BaseGuildRepository {
const slowmode = await this.getChannelSlowmode(channelId); const slowmode = await this.getChannelSlowmode(channelId);
if (!slowmode) return; if (!slowmode) return;
const expiresAt = moment const expiresAt = moment.utc().add(slowmode.slowmode_seconds, "seconds").format("YYYY-MM-DD HH:mm:ss");
.utc()
.add(slowmode.slowmode_seconds, "seconds")
.format("YYYY-MM-DD HH:mm:ss");
if (await this.userHasSlowmode(channelId, userId)) { if (await this.userHasSlowmode(channelId, userId)) {
// Update existing // Update existing

View file

@ -30,10 +30,7 @@ export class GuildTempbans extends BaseGuildRepository {
} }
async addTempban(userId, expiryTime, modId): Promise<Tempban> { async addTempban(userId, expiryTime, modId): Promise<Tempban> {
const expiresAt = moment const expiresAt = moment.utc().add(expiryTime, "ms").format("YYYY-MM-DD HH:mm:ss");
.utc()
.add(expiryTime, "ms")
.format("YYYY-MM-DD HH:mm:ss");
const result = await this.tempbans.insert({ const result = await this.tempbans.insert({
guild_id: this.guildId, guild_id: this.guildId,
@ -47,10 +44,7 @@ export class GuildTempbans extends BaseGuildRepository {
} }
async updateExpiryTime(userId, newExpiryTime, modId) { async updateExpiryTime(userId, newExpiryTime, modId) {
const expiresAt = moment const expiresAt = moment.utc().add(newExpiryTime, "ms").format("YYYY-MM-DD HH:mm:ss");
.utc()
.add(newExpiryTime, "ms")
.format("YYYY-MM-DD HH:mm:ss");
return this.tempbans.update( return this.tempbans.update(
{ {

View file

@ -19,10 +19,7 @@ export class GuildVCAlerts extends BaseGuildRepository {
} }
async getAllGuildAlerts(): Promise<VCAlert[]> { async getAllGuildAlerts(): Promise<VCAlert[]> {
return this.allAlerts return this.allAlerts.createQueryBuilder().where("guild_id = :guildId", { guildId: this.guildId }).getMany();
.createQueryBuilder()
.where("guild_id = :guildId", { guildId: this.guildId })
.getMany();
} }
async getAlertsByUserId(userId: string): Promise<VCAlert[]> { async getAlertsByUserId(userId: string): Promise<VCAlert[]> {

View file

@ -67,7 +67,7 @@ export class UsernameHistory extends BaseRepository {
if (toDelete.length > 0) { if (toDelete.length > 0) {
await this.usernameHistory.delete({ await this.usernameHistory.delete({
id: In(toDelete.map(v => v.id)), id: In(toDelete.map((v) => v.id)),
}); });
} }
} }

View file

@ -13,10 +13,7 @@ export async function cleanupConfigs() {
let rows; let rows;
// >1 month old: 1 config retained per month // >1 month old: 1 config retained per month
const oneMonthCutoff = moment const oneMonthCutoff = moment.utc().subtract(30, "days").format(DBDateFormat);
.utc()
.subtract(30, "days")
.format(DBDateFormat);
do { do {
rows = await connection.query( rows = await connection.query(
` `
@ -46,7 +43,7 @@ export async function cleanupConfigs() {
if (rows.length > 0) { if (rows.length > 0) {
await configRepository.delete({ await configRepository.delete({
id: In(rows.map(r => r.id)), id: In(rows.map((r) => r.id)),
}); });
} }
@ -54,10 +51,7 @@ export async function cleanupConfigs() {
} while (rows.length === CLEAN_PER_LOOP); } while (rows.length === CLEAN_PER_LOOP);
// >2 weeks old: 1 config retained per day // >2 weeks old: 1 config retained per day
const twoWeekCutoff = moment const twoWeekCutoff = moment.utc().subtract(2, "weeks").format(DBDateFormat);
.utc()
.subtract(2, "weeks")
.format(DBDateFormat);
do { do {
rows = await connection.query( rows = await connection.query(
` `
@ -87,7 +81,7 @@ export async function cleanupConfigs() {
if (rows.length > 0) { if (rows.length > 0) {
await configRepository.delete({ await configRepository.delete({
id: In(rows.map(r => r.id)), id: In(rows.map((r) => r.id)),
}); });
} }

View file

@ -18,18 +18,9 @@ export async function cleanupMessages(): Promise<number> {
const messagesRepository = getRepository(SavedMessage); const messagesRepository = getRepository(SavedMessage);
const deletedAtThreshold = moment const deletedAtThreshold = moment.utc().subtract(DELETED_MESSAGE_RETENTION_PERIOD, "ms").format(DBDateFormat);
.utc() const postedAtThreshold = moment.utc().subtract(RETENTION_PERIOD, "ms").format(DBDateFormat);
.subtract(DELETED_MESSAGE_RETENTION_PERIOD, "ms") const botPostedAtThreshold = moment.utc().subtract(BOT_MESSAGE_RETENTION_PERIOD, "ms").format(DBDateFormat);
.format(DBDateFormat);
const postedAtThreshold = moment
.utc()
.subtract(RETENTION_PERIOD, "ms")
.format(DBDateFormat);
const botPostedAtThreshold = moment
.utc()
.subtract(BOT_MESSAGE_RETENTION_PERIOD, "ms")
.format(DBDateFormat);
// SELECT + DELETE messages in batches // SELECT + DELETE messages in batches
// This is to avoid deadlocks that happened frequently when deleting with the same criteria as the select below // This is to avoid deadlocks that happened frequently when deleting with the same criteria as the select below
@ -60,7 +51,7 @@ export async function cleanupMessages(): Promise<number> {
if (rows.length > 0) { if (rows.length > 0) {
await messagesRepository.delete({ await messagesRepository.delete({
id: In(rows.map(r => r.id)), id: In(rows.map((r) => r.id)),
}); });
} }

View file

@ -11,10 +11,7 @@ export async function cleanupNicknames(): Promise<number> {
let cleaned = 0; let cleaned = 0;
const nicknameHistoryRepository = getRepository(NicknameHistoryEntry); const nicknameHistoryRepository = getRepository(NicknameHistoryEntry);
const dateThreshold = moment const dateThreshold = moment.utc().subtract(NICKNAME_RETENTION_PERIOD, "ms").format(DBDateFormat);
.utc()
.subtract(NICKNAME_RETENTION_PERIOD, "ms")
.format(DBDateFormat);
// Clean old nicknames (NICKNAME_RETENTION_PERIOD) // Clean old nicknames (NICKNAME_RETENTION_PERIOD)
let rows; let rows;
@ -31,7 +28,7 @@ export async function cleanupNicknames(): Promise<number> {
if (rows.length > 0) { if (rows.length > 0) {
await nicknameHistoryRepository.delete({ await nicknameHistoryRepository.delete({
id: In(rows.map(r => r.id)), id: In(rows.map((r) => r.id)),
}); });
} }

View file

@ -11,10 +11,7 @@ export async function cleanupUsernames(): Promise<number> {
let cleaned = 0; let cleaned = 0;
const usernameHistoryRepository = getRepository(UsernameHistoryEntry); const usernameHistoryRepository = getRepository(UsernameHistoryEntry);
const dateThreshold = moment const dateThreshold = moment.utc().subtract(USERNAME_RETENTION_PERIOD, "ms").format(DBDateFormat);
.utc()
.subtract(USERNAME_RETENTION_PERIOD, "ms")
.format(DBDateFormat);
// Clean old usernames (USERNAME_RETENTION_PERIOD) // Clean old usernames (USERNAME_RETENTION_PERIOD)
let rows; let rows;
@ -31,7 +28,7 @@ export async function cleanupUsernames(): Promise<number> {
if (rows.length > 0) { if (rows.length > 0) {
await usernameHistoryRepository.delete({ await usernameHistoryRepository.delete({
id: In(rows.map(r => r.id)), id: In(rows.map((r) => r.id)),
}); });
} }

View file

@ -7,9 +7,9 @@ export let connection: Connection;
export function connect() { export function connect() {
if (!connectionPromise) { if (!connectionPromise) {
connectionPromise = createConnection().then(newConnection => { connectionPromise = createConnection().then((newConnection) => {
// Verify the DB timezone is set to UTC // Verify the DB timezone is set to UTC
return newConnection.query("SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP) AS tz").then(r => { return newConnection.query("SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP) AS tz").then((r) => {
if (r[0].tz !== "00:00:00") { if (r[0].tz !== "00:00:00") {
throw new SimpleError(`Database timezone must be UTC (detected ${r[0].tz})`); throw new SimpleError(`Database timezone must be UTC (detected ${r[0].tz})`);
} }

View file

@ -19,10 +19,7 @@ export class ApiLogin {
@Column() @Column()
expires_at: string; expires_at: string;
@ManyToOne( @ManyToOne((type) => ApiUserInfo, (userInfo) => userInfo.logins)
type => ApiUserInfo,
userInfo => userInfo.logins,
)
@JoinColumn({ name: "user_id" }) @JoinColumn({ name: "user_id" })
userInfo: ApiUserInfo; userInfo: ApiUserInfo;
} }

View file

@ -22,10 +22,7 @@ export class ApiPermissionAssignment {
@Column({ type: String, nullable: true }) @Column({ type: String, nullable: true })
expires_at: string | null; expires_at: string | null;
@ManyToOne( @ManyToOne((type) => ApiUserInfo, (userInfo) => userInfo.permissionAssignments)
type => ApiUserInfo,
userInfo => userInfo.permissionAssignments,
)
@JoinColumn({ name: "target_id" }) @JoinColumn({ name: "target_id" })
userInfo: ApiUserInfo; userInfo: ApiUserInfo;
} }

View file

@ -20,15 +20,9 @@ export class ApiUserInfo {
@Column() @Column()
updated_at: string; updated_at: string;
@OneToMany( @OneToMany((type) => ApiLogin, (login) => login.userInfo)
type => ApiLogin,
login => login.userInfo,
)
logins: ApiLogin[]; logins: ApiLogin[];
@OneToMany( @OneToMany((type) => ApiPermissionAssignment, (p) => p.userInfo)
type => ApiPermissionAssignment,
p => p.userInfo,
)
permissionAssignments: ApiPermissionAssignment[]; permissionAssignments: ApiPermissionAssignment[];
} }

View file

@ -35,9 +35,6 @@ export class Case {
*/ */
@Column({ type: String, nullable: true }) log_message_id: string | null; @Column({ type: String, nullable: true }) log_message_id: string | null;
@OneToMany( @OneToMany((type) => CaseNote, (note) => note.case)
type => CaseNote,
note => note.case,
)
notes: CaseNote[]; notes: CaseNote[];
} }

View file

@ -15,10 +15,7 @@ export class CaseNote {
@Column() created_at: string; @Column() created_at: string;
@ManyToOne( @ManyToOne((type) => Case, (theCase) => theCase.notes)
type => Case,
theCase => theCase.notes,
)
@JoinColumn({ name: "case_id" }) @JoinColumn({ name: "case_id" })
case: Case; case: Case;
} }

View file

@ -22,7 +22,7 @@ export class Config {
@Column() @Column()
edited_at: string; edited_at: string;
@ManyToOne(type => ApiUserInfo) @ManyToOne((type) => ApiUserInfo)
@JoinColumn({ name: "edited_by" }) @JoinColumn({ name: "edited_by" })
userInfo: ApiUserInfo; userInfo: ApiUserInfo;
} }

View file

@ -16,7 +16,7 @@ export class StarboardMessage {
@Column() @Column()
guild_id: string; guild_id: string;
@OneToOne(type => SavedMessage) @OneToOne((type) => SavedMessage)
@JoinColumn({ name: "message_id" }) @JoinColumn({ name: "message_id" })
message: SavedMessage; message: SavedMessage;
} }

View file

@ -16,7 +16,7 @@ export class StarboardReaction {
@Column() @Column()
reactor_id: string; reactor_id: string;
@OneToOne(type => SavedMessage) @OneToOne((type) => SavedMessage)
@JoinColumn({ name: "message_id" }) @JoinColumn({ name: "message_id" })
message: SavedMessage; message: SavedMessage;
} }

View file

@ -144,8 +144,8 @@ if (process.env.NODE_ENV === "production") {
// Verify required Node.js version // Verify required Node.js version
const REQUIRED_NODE_VERSION = "14.0.0"; const REQUIRED_NODE_VERSION = "14.0.0";
const requiredParts = REQUIRED_NODE_VERSION.split(".").map(v => parseInt(v, 10)); const requiredParts = REQUIRED_NODE_VERSION.split(".").map((v) => parseInt(v, 10));
const actualVersionParts = process.versions.node.split(".").map(v => parseInt(v, 10)); const actualVersionParts = process.versions.node.split(".").map((v) => parseInt(v, 10));
for (const [i, part] of actualVersionParts.entries()) { for (const [i, part] of actualVersionParts.entries()) {
if (part > requiredParts[i]) break; if (part > requiredParts[i]) break;
if (part === requiredParts[i]) continue; if (part === requiredParts[i]) continue;
@ -188,7 +188,7 @@ connect().then(async () => {
}); });
client.setMaxListeners(200); client.setMaxListeners(200);
client.on(Constants.Events.RATE_LIMIT, data => { client.on(Constants.Events.RATE_LIMIT, (data) => {
// tslint:disable-next-line:no-console // tslint:disable-next-line:no-console
// console.log(`[DEBUG] [RATE_LIMIT] ${JSON.stringify(data)}`); // console.log(`[DEBUG] [RATE_LIMIT] ${JSON.stringify(data)}`);
}); });
@ -196,7 +196,7 @@ connect().then(async () => {
const safe429DecayInterval = 5 * SECONDS; const safe429DecayInterval = 5 * SECONDS;
const safe429MaxCount = 5; const safe429MaxCount = 5;
const safe429Counter = new DecayingCounter(safe429DecayInterval); const safe429Counter = new DecayingCounter(safe429DecayInterval);
client.on(Constants.Events.DEBUG, errorText => { client.on(Constants.Events.DEBUG, (errorText) => {
if (!errorText.includes("429")) { if (!errorText.includes("429")) {
return; return;
} }
@ -212,7 +212,7 @@ connect().then(async () => {
} }
}); });
client.on("error", err => { client.on("error", (err) => {
errorHandler(new DiscordJSError(err.message, (err as any).code, 0)); errorHandler(new DiscordJSError(err.message, (err as any).code, 0));
}); });
@ -240,9 +240,9 @@ connect().then(async () => {
} }
const configuredPlugins = ctx.config.plugins; const configuredPlugins = ctx.config.plugins;
const basePluginNames = baseGuildPlugins.map(p => p.name); const basePluginNames = baseGuildPlugins.map((p) => p.name);
return Array.from(plugins.keys()).filter(pluginName => { return Array.from(plugins.keys()).filter((pluginName) => {
if (basePluginNames.includes(pluginName)) return true; if (basePluginNames.includes(pluginName)) return true;
return configuredPlugins[pluginName] && configuredPlugins[pluginName].enabled !== false; return configuredPlugins[pluginName] && configuredPlugins[pluginName].enabled !== false;
}); });
@ -308,14 +308,14 @@ connect().then(async () => {
}); });
const debugGuilds = ["877581055920603238", "348468156597010432", "134286179121102848"]; const debugGuilds = ["877581055920603238", "348468156597010432", "134286179121102848"];
bot.on("guildLoaded", guildId => { bot.on("guildLoaded", (guildId) => {
if (!debugGuilds.includes(guildId)) { if (!debugGuilds.includes(guildId)) {
return; return;
} }
console.log(`[!! DEBUG !!] LOADED GUILD ${guildId}`); console.log(`[!! DEBUG !!] LOADED GUILD ${guildId}`);
}); });
bot.on("guildUnloaded", guildId => { bot.on("guildUnloaded", (guildId) => {
if (!debugGuilds.includes(guildId)) { if (!debugGuilds.includes(guildId)) {
return; return;
} }

View file

@ -9,7 +9,7 @@ export class MigrateUsernamesToNewHistoryTable1556909512501 implements Migration
const migratedUsernames = new Set(); const migratedUsernames = new Set();
await new Promise(async resolve => { await new Promise(async (resolve) => {
const stream = await queryRunner.stream("SELECT CONCAT(user_id, '-', username) AS `key` FROM username_history"); const stream = await queryRunner.stream("SELECT CONCAT(user_id, '-', username) AS `key` FROM username_history");
stream.on("data", (row: any) => { stream.on("data", (row: any) => {
migratedUsernames.add(row.key); migratedUsernames.add(row.key);
@ -18,7 +18,7 @@ export class MigrateUsernamesToNewHistoryTable1556909512501 implements Migration
}); });
const migrateNextBatch = (): Promise<{ finished: boolean; migrated?: number }> => { const migrateNextBatch = (): Promise<{ finished: boolean; migrated?: number }> => {
return new Promise(async resolve => { return new Promise(async (resolve) => {
const toInsert: any[][] = []; const toInsert: any[][] = [];
const toDelete: number[] = []; const toDelete: number[] = [];

View file

@ -85,7 +85,7 @@ export function strictValidationErrorToConfigValidationError(err: StrictValidati
return new ConfigValidationError( return new ConfigValidationError(
err err
.getErrors() .getErrors()
.map(e => e.toString()) .map((e) => e.toString())
.join("\n"), .join("\n"),
); );
} }
@ -199,7 +199,7 @@ export async function sendSuccessMessage(
return channel return channel
.send({ ...content }) // Force line break .send({ ...content }) // Force line break
.catch(err => { .catch((err) => {
const channelInfo = channel.guild ? `${channel.id} (${channel.guild.id})` : channel.id; const channelInfo = channel.guild ? `${channel.id} (${channel.guild.id})` : channel.id;
logger.warn(`Failed to send success message to ${channelInfo}): ${err.code} ${err.message}`); logger.warn(`Failed to send success message to ${channelInfo}): ${err.code} ${err.message}`);
return undefined; return undefined;
@ -220,7 +220,7 @@ export async function sendErrorMessage(
return channel return channel
.send({ ...content }) // Force line break .send({ ...content }) // Force line break
.catch(err => { .catch((err) => {
const channelInfo = channel.guild ? `${channel.id} (${channel.guild.id})` : channel.id; const channelInfo = channel.guild ? `${channel.id} (${channel.guild.id})` : channel.id;
logger.warn(`Failed to send error message to ${channelInfo}): ${err.code} ${err.message}`); logger.warn(`Failed to send error message to ${channelInfo}): ${err.code} ${err.message}`);
return undefined; return undefined;
@ -252,7 +252,7 @@ type AnyFn = (...args: any[]) => any;
* Creates a public plugin function out of a function with pluginData as the first parameter * Creates a public plugin function out of a function with pluginData as the first parameter
*/ */
export function mapToPublicFn<T extends AnyFn>(inputFn: T) { export function mapToPublicFn<T extends AnyFn>(inputFn: T) {
return pluginData => { return (pluginData) => {
return (...args: Tail<Parameters<typeof inputFn>>): ReturnType<typeof inputFn> => { return (...args: Tail<Parameters<typeof inputFn>>): ReturnType<typeof inputFn> => {
return inputFn(pluginData, ...args); return inputFn(pluginData, ...args);
}; };

View file

@ -45,13 +45,13 @@ export const AutoDeletePlugin = zeppelinGuildPlugin<AutoDeletePluginType>()({
afterLoad(pluginData) { afterLoad(pluginData) {
const { state, guild } = pluginData; const { state, guild } = pluginData;
state.onMessageCreateFn = msg => onMessageCreate(pluginData, msg); state.onMessageCreateFn = (msg) => onMessageCreate(pluginData, msg);
state.guildSavedMessages.events.on("create", state.onMessageCreateFn); state.guildSavedMessages.events.on("create", state.onMessageCreateFn);
state.onMessageDeleteFn = msg => onMessageDelete(pluginData, msg); state.onMessageDeleteFn = (msg) => onMessageDelete(pluginData, msg);
state.guildSavedMessages.events.on("delete", state.onMessageDeleteFn); state.guildSavedMessages.events.on("delete", state.onMessageDeleteFn);
state.onMessageDeleteBulkFn = msgs => onMessageDeleteBulk(pluginData, msgs); state.onMessageDeleteBulkFn = (msgs) => onMessageDeleteBulk(pluginData, msgs);
state.guildSavedMessages.events.on("deleteBulk", state.onMessageDeleteBulkFn); state.guildSavedMessages.events.on("deleteBulk", state.onMessageDeleteBulkFn);
}, },

View file

@ -45,7 +45,7 @@ export async function deleteNextItem(pluginData: GuildPluginData<AutoDeletePlugi
const timeAndDate = pluginData.getPlugin(TimeAndDatePlugin); const timeAndDate = pluginData.getPlugin(TimeAndDatePlugin);
pluginData.state.guildLogs.ignoreLog(LogType.MESSAGE_DELETE, itemToDelete.message.id); pluginData.state.guildLogs.ignoreLog(LogType.MESSAGE_DELETE, itemToDelete.message.id);
(channel as TextChannel).messages.delete(itemToDelete.message.id as Snowflake).catch(err => { (channel as TextChannel).messages.delete(itemToDelete.message.id as Snowflake).catch((err) => {
if (err.code === 10008) { if (err.code === 10008) {
// "Unknown Message", probably already deleted by automod or another bot, ignore // "Unknown Message", probably already deleted by automod or another bot, ignore
return; return;

View file

@ -4,7 +4,7 @@ import { AutoDeletePluginType } from "../types";
import { scheduleNextDeletion } from "./scheduleNextDeletion"; import { scheduleNextDeletion } from "./scheduleNextDeletion";
export function onMessageDelete(pluginData: GuildPluginData<AutoDeletePluginType>, msg: SavedMessage) { export function onMessageDelete(pluginData: GuildPluginData<AutoDeletePluginType>, msg: SavedMessage) {
const indexToDelete = pluginData.state.deletionQueue.findIndex(item => item.message.id === msg.id); const indexToDelete = pluginData.state.deletionQueue.findIndex((item) => item.message.id === msg.id);
if (indexToDelete > -1) { if (indexToDelete > -1) {
pluginData.state.deletionQueue.splice(indexToDelete, 1); pluginData.state.deletionQueue.splice(indexToDelete, 1);
scheduleNextDeletion(pluginData); scheduleNextDeletion(pluginData);

View file

@ -57,7 +57,7 @@ const defaultOptions = {
/** /**
* Config preprocessor to set default values for triggers and perform extra validation * Config preprocessor to set default values for triggers and perform extra validation
*/ */
const configPreprocessor: ConfigPreprocessorFn<AutomodPluginType> = options => { const configPreprocessor: ConfigPreprocessorFn<AutomodPluginType> = (options) => {
if (options.config?.rules) { if (options.config?.rules) {
// Loop through each rule // Loop through each rule
for (const [name, rule] of Object.entries(options.config.rules)) { for (const [name, rule] of Object.entries(options.config.rules)) {
@ -232,10 +232,10 @@ export const AutomodPlugin = zeppelinGuildPlugin<AutomodPluginType>()({
30 * SECONDS, 30 * SECONDS,
); );
pluginData.state.onMessageCreateFn = message => runAutomodOnMessage(pluginData, message, false); pluginData.state.onMessageCreateFn = (message) => runAutomodOnMessage(pluginData, message, false);
pluginData.state.savedMessages.events.on("create", pluginData.state.onMessageCreateFn); pluginData.state.savedMessages.events.on("create", pluginData.state.onMessageCreateFn);
pluginData.state.onMessageUpdateFn = message => runAutomodOnMessage(pluginData, message, true); pluginData.state.onMessageUpdateFn = (message) => runAutomodOnMessage(pluginData, message, true);
pluginData.state.savedMessages.events.on("update", pluginData.state.onMessageUpdateFn); pluginData.state.savedMessages.events.on("update", pluginData.state.onMessageUpdateFn);
const countersPlugin = pluginData.getPlugin(CountersPlugin); const countersPlugin = pluginData.getPlugin(CountersPlugin);

View file

@ -17,7 +17,7 @@ export const AddRolesAction = automodAction({
defaultConfig: [], defaultConfig: [],
async apply({ pluginData, contexts, actionConfig, ruleName }) { async apply({ pluginData, contexts, actionConfig, ruleName }) {
const members = unique(contexts.map(c => c.member).filter(nonNullish)); const members = unique(contexts.map((c) => c.member).filter(nonNullish));
const me = pluginData.guild.members.cache.get(pluginData.client.user!.id)!; const me = pluginData.guild.members.cache.get(pluginData.client.user!.id)!;
const missingPermissions = getMissingPermissions(me.permissions, p.MANAGE_ROLES); const missingPermissions = getMissingPermissions(me.permissions, p.MANAGE_ROLES);
@ -41,7 +41,7 @@ export const AddRolesAction = automodAction({
if (rolesWeCannotAssign.length) { if (rolesWeCannotAssign.length) {
const roleNamesWeCannotAssign = rolesWeCannotAssign.map( const roleNamesWeCannotAssign = rolesWeCannotAssign.map(
roleId => pluginData.guild.roles.cache.get(roleId as Snowflake)?.name || roleId, (roleId) => pluginData.guild.roles.cache.get(roleId as Snowflake)?.name || roleId,
); );
const logs = pluginData.getPlugin(LogsPlugin); const logs = pluginData.getPlugin(LogsPlugin);
logs.logBotAlert({ logs.logBotAlert({
@ -52,7 +52,7 @@ export const AddRolesAction = automodAction({
} }
await Promise.all( await Promise.all(
members.map(async member => { members.map(async (member) => {
const memberRoles = new Set(member.roles.cache.keys()); const memberRoles = new Set(member.roles.cache.keys());
for (const roleId of rolesToAssign) { for (const roleId of rolesToAssign) {
memberRoles.add(roleId as Snowflake); memberRoles.add(roleId as Snowflake);

View file

@ -41,7 +41,7 @@ export const AlertAction = automodAction({
const theMessageLink = const theMessageLink =
contexts[0].message && messageLink(pluginData.guild.id, contexts[0].message.channel_id, contexts[0].message.id); contexts[0].message && messageLink(pluginData.guild.id, contexts[0].message.channel_id, contexts[0].message.id);
const safeUsers = contexts.map(c => (c.user ? userToTemplateSafeUser(c.user) : null)).filter(isTruthy); const safeUsers = contexts.map((c) => (c.user ? userToTemplateSafeUser(c.user) : null)).filter(isTruthy);
const safeUser = safeUsers[0]; const safeUser = safeUsers[0];
const actionsTaken = Object.keys(pluginData.config.get().rules[ruleName].actions).join(", "); const actionsTaken = Object.keys(pluginData.config.get().rules[ruleName].actions).join(", ");

View file

@ -9,8 +9,8 @@ export const ArchiveThreadAction = automodAction({
async apply({ pluginData, contexts }) { async apply({ pluginData, contexts }) {
const threads = contexts const threads = contexts
.filter(c => c.message?.channel_id) .filter((c) => c.message?.channel_id)
.map(c => pluginData.guild.channels.cache.get(c.message!.channel_id)) .map((c) => pluginData.guild.channels.cache.get(c.message!.channel_id))
.filter((c): c is ThreadChannel => c?.isThread() ?? false); .filter((c): c is ThreadChannel => c?.isThread() ?? false);
for (const thread of threads) { for (const thread of threads) {

View file

@ -35,7 +35,7 @@ export const BanAction = automodAction({
hide: Boolean(actionConfig.hide_case), hide: Boolean(actionConfig.hide_case),
}; };
const userIdsToBan = unique(contexts.map(c => c.user?.id).filter(nonNullish)); const userIdsToBan = unique(contexts.map((c) => c.user?.id).filter(nonNullish));
const modActions = pluginData.getPlugin(ModActionsPlugin); const modActions = pluginData.getPlugin(ModActionsPlugin);
for (const userId of userIdsToBan) { for (const userId of userIdsToBan) {

View file

@ -15,13 +15,13 @@ export const ChangeNicknameAction = automodAction({
defaultConfig: {}, defaultConfig: {},
async apply({ pluginData, contexts, actionConfig }) { async apply({ pluginData, contexts, actionConfig }) {
const members = unique(contexts.map(c => c.member).filter(nonNullish)); const members = unique(contexts.map((c) => c.member).filter(nonNullish));
for (const member of members) { for (const member of members) {
if (pluginData.state.recentNicknameChanges.has(member.id)) continue; if (pluginData.state.recentNicknameChanges.has(member.id)) continue;
const newName = typeof actionConfig === "string" ? actionConfig : actionConfig.name; const newName = typeof actionConfig === "string" ? actionConfig : actionConfig.name;
member.edit({ nick: newName }).catch(err => { member.edit({ nick: newName }).catch((err) => {
pluginData.getPlugin(LogsPlugin).logBotAlert({ pluginData.getPlugin(LogsPlugin).logBotAlert({
body: `Failed to change the nickname of \`${member.id}\``, body: `Failed to change the nickname of \`${member.id}\``,
}); });

View file

@ -31,8 +31,8 @@ export const KickAction = automodAction({
hide: Boolean(actionConfig.hide_case), hide: Boolean(actionConfig.hide_case),
}; };
const userIdsToKick = unique(contexts.map(c => c.user?.id).filter(nonNullish)); const userIdsToKick = unique(contexts.map((c) => c.user?.id).filter(nonNullish));
const membersToKick = await asyncMap(userIdsToKick, id => resolveMember(pluginData.client, pluginData.guild, id)); const membersToKick = await asyncMap(userIdsToKick, (id) => resolveMember(pluginData.client, pluginData.guild, id));
const modActions = pluginData.getPlugin(ModActionsPlugin); const modActions = pluginData.getPlugin(ModActionsPlugin);
for (const member of membersToKick) { for (const member of membersToKick) {

View file

@ -10,7 +10,7 @@ export const LogAction = automodAction({
defaultConfig: true, defaultConfig: true,
async apply({ pluginData, contexts, ruleName, matchResult }) { async apply({ pluginData, contexts, ruleName, matchResult }) {
const users = unique(contexts.map(c => c.user)).filter(isTruthy); const users = unique(contexts.map((c) => c.user)).filter(isTruthy);
const user = users[0]; const user = users[0];
const actionsTaken = Object.keys(pluginData.config.get().rules[ruleName].actions).join(", "); const actionsTaken = Object.keys(pluginData.config.get().rules[ruleName].actions).join(", ");

View file

@ -40,7 +40,7 @@ export const MuteAction = automodAction({
hide: Boolean(actionConfig.hide_case), hide: Boolean(actionConfig.hide_case),
}; };
const userIdsToMute = unique(contexts.map(c => c.user?.id).filter(nonNullish)); const userIdsToMute = unique(contexts.map((c) => c.user?.id).filter(nonNullish));
const mutes = pluginData.getPlugin(MutesPlugin); const mutes = pluginData.getPlugin(MutesPlugin);
for (const userId of userIdsToMute) { for (const userId of userIdsToMute) {

View file

@ -18,7 +18,7 @@ export const RemoveRolesAction = automodAction({
defaultConfig: [], defaultConfig: [],
async apply({ pluginData, contexts, actionConfig, ruleName }) { async apply({ pluginData, contexts, actionConfig, ruleName }) {
const members = unique(contexts.map(c => c.member).filter(nonNullish)); const members = unique(contexts.map((c) => c.member).filter(nonNullish));
const me = pluginData.guild.members.cache.get(pluginData.client.user!.id)!; const me = pluginData.guild.members.cache.get(pluginData.client.user!.id)!;
const missingPermissions = getMissingPermissions(me.permissions, p.MANAGE_ROLES); const missingPermissions = getMissingPermissions(me.permissions, p.MANAGE_ROLES);
@ -42,7 +42,7 @@ export const RemoveRolesAction = automodAction({
if (rolesWeCannotRemove.length) { if (rolesWeCannotRemove.length) {
const roleNamesWeCannotRemove = rolesWeCannotRemove.map( const roleNamesWeCannotRemove = rolesWeCannotRemove.map(
roleId => pluginData.guild.roles.cache.get(roleId as Snowflake)?.name || roleId, (roleId) => pluginData.guild.roles.cache.get(roleId as Snowflake)?.name || roleId,
); );
const logs = pluginData.getPlugin(LogsPlugin); const logs = pluginData.getPlugin(LogsPlugin);
logs.logBotAlert({ logs.logBotAlert({
@ -53,7 +53,7 @@ export const RemoveRolesAction = automodAction({
} }
await Promise.all( await Promise.all(
members.map(async member => { members.map(async (member) => {
const memberRoles = new Set(member.roles.cache.keys()); const memberRoles = new Set(member.roles.cache.keys());
for (const roleId of rolesToRemove) { for (const roleId of rolesToRemove) {
memberRoles.delete(roleId as Snowflake); memberRoles.delete(roleId as Snowflake);

View file

@ -32,8 +32,8 @@ export const ReplyAction = automodAction({
async apply({ pluginData, contexts, actionConfig, ruleName }) { async apply({ pluginData, contexts, actionConfig, ruleName }) {
const contextsWithTextChannels = contexts const contextsWithTextChannels = contexts
.filter(c => c.message?.channel_id) .filter((c) => c.message?.channel_id)
.filter(c => { .filter((c) => {
const channel = pluginData.guild.channels.cache.get(c.message!.channel_id as Snowflake); const channel = pluginData.guild.channels.cache.get(c.message!.channel_id as Snowflake);
return channel instanceof TextChannel || channel instanceof ThreadChannel; return channel instanceof TextChannel || channel instanceof ThreadChannel;
}); });
@ -48,7 +48,7 @@ export const ReplyAction = automodAction({
}, new Map()); }, new Map());
for (const [channelId, _contexts] of contextsByChannelId.entries()) { for (const [channelId, _contexts] of contextsByChannelId.entries()) {
const users = unique(Array.from(new Set(_contexts.map(c => c.user).filter(Boolean)))) as User[]; const users = unique(Array.from(new Set(_contexts.map((c) => c.user).filter(Boolean)))) as User[];
const user = users[0]; const user = users[0];
const renderReplyText = async (str: string) => const renderReplyText = async (str: string) =>

View file

@ -31,8 +31,8 @@ export const WarnAction = automodAction({
hide: Boolean(actionConfig.hide_case), hide: Boolean(actionConfig.hide_case),
}; };
const userIdsToWarn = unique(contexts.map(c => c.user?.id).filter(nonNullish)); const userIdsToWarn = unique(contexts.map((c) => c.user?.id).filter(nonNullish));
const membersToWarn = await asyncMap(userIdsToWarn, id => resolveMember(pluginData.client, pluginData.guild, id)); const membersToWarn = await asyncMap(userIdsToWarn, (id) => resolveMember(pluginData.client, pluginData.guild, id));
const modActions = pluginData.getPlugin(ModActionsPlugin); const modActions = pluginData.getPlugin(ModActionsPlugin);
for (const member of membersToWarn) { for (const member of membersToWarn) {

View file

@ -4,7 +4,7 @@ import { AutomodPluginType } from "../types";
export function clearOldRecentActions(pluginData: GuildPluginData<AutomodPluginType>) { export function clearOldRecentActions(pluginData: GuildPluginData<AutomodPluginType>) {
const now = Date.now(); const now = Date.now();
pluginData.state.recentActions = pluginData.state.recentActions.filter(info => { pluginData.state.recentActions = pluginData.state.recentActions.filter((info) => {
return info.context.timestamp + RECENT_ACTION_EXPIRY_TIME > now; return info.context.timestamp + RECENT_ACTION_EXPIRY_TIME > now;
}); });
} }

View file

@ -4,7 +4,7 @@ import { AutomodPluginType } from "../types";
export function clearOldRecentSpam(pluginData: GuildPluginData<AutomodPluginType>) { export function clearOldRecentSpam(pluginData: GuildPluginData<AutomodPluginType>) {
const now = Date.now(); const now = Date.now();
pluginData.state.recentSpam = pluginData.state.recentSpam.filter(spam => { pluginData.state.recentSpam = pluginData.state.recentSpam.filter((spam) => {
return spam.timestamp + RECENT_SPAM_EXPIRY_TIME > now; return spam.timestamp + RECENT_SPAM_EXPIRY_TIME > now;
}); });
} }

View file

@ -6,7 +6,7 @@ export function clearRecentActionsForMessage(pluginData: GuildPluginData<Automod
const globalIdentifier = message.user_id; const globalIdentifier = message.user_id;
const perChannelIdentifier = `${message.channel_id}-${message.user_id}`; const perChannelIdentifier = `${message.channel_id}-${message.user_id}`;
pluginData.state.recentActions = pluginData.state.recentActions.filter(act => { pluginData.state.recentActions = pluginData.state.recentActions.filter((act) => {
return act.identifier !== globalIdentifier && act.identifier !== perChannelIdentifier; return act.identifier !== globalIdentifier && act.identifier !== perChannelIdentifier;
}); });
} }

View file

@ -60,7 +60,7 @@ export function createMessageSpamTrigger(spamType: RecentActionType, prettyName:
if (matchedSpam) { if (matchedSpam) {
const messages = matchedSpam.recentActions const messages = matchedSpam.recentActions
.map(action => action.context.message) .map((action) => action.context.message)
.filter(Boolean) .filter(Boolean)
.sort(sorter("posted_at")) as SavedMessage[]; .sort(sorter("posted_at")) as SavedMessage[];
@ -75,8 +75,8 @@ export function createMessageSpamTrigger(spamType: RecentActionType, prettyName:
return { return {
extraContexts: matchedSpam.recentActions extraContexts: matchedSpam.recentActions
.map(action => action.context) .map((action) => action.context)
.filter(_context => _context !== context), .filter((_context) => _context !== context),
extra: { extra: {
archiveId, archiveId,

View file

@ -7,7 +7,7 @@ export function findRecentSpam(
type: RecentActionType, type: RecentActionType,
identifier?: string, identifier?: string,
) { ) {
return pluginData.state.recentSpam.find(spam => { return pluginData.state.recentSpam.find((spam) => {
return spam.type === type && (!identifier || spam.identifiers.includes(identifier)); return spam.type === type && (!identifier || spam.identifiers.includes(identifier));
}); });
} }

View file

@ -11,7 +11,7 @@ export function getMatchingRecentActions(
) { ) {
to = to || Date.now(); to = to || Date.now();
return pluginData.state.recentActions.filter(action => { return pluginData.state.recentActions.filter((action) => {
return ( return (
action.type === type && action.type === type &&
(!identifier || action.identifier === identifier) && (!identifier || action.identifier === identifier) &&

View file

@ -29,6 +29,6 @@ export function getTextMatchPartialSummary(
const visibleName = context.member?.nickname || context.user!.username; const visibleName = context.member?.nickname || context.user!.username;
return `visible name: ${visibleName}`; return `visible name: ${visibleName}`;
} else if (type === "customstatus") { } else if (type === "customstatus") {
return `custom status: ${context.member!.presence?.activities.find(a => a.type === "CUSTOM")?.name}`; return `custom status: ${context.member!.presence?.activities.find((a) => a.type === "CUSTOM")?.name}`;
} }
} }

View file

@ -15,7 +15,7 @@ export const ExampleTrigger = automodTrigger<ExampleMatchResultType>()({
}, },
async match({ triggerConfig, context }) { async match({ triggerConfig, context }) {
const foundFruit = triggerConfig.allowedFruits.find(fruit => context.message?.data.content === fruit); const foundFruit = triggerConfig.allowedFruits.find((fruit) => context.message?.data.content === fruit);
if (foundFruit) { if (foundFruit) {
return { return {
extra: { extra: {

View file

@ -33,13 +33,10 @@ export const MatchAttachmentTypeTrigger = automodTrigger<MatchResultType>()({
} }
for (const attachment of context.message.data.attachments) { for (const attachment of context.message.data.attachments) {
const attachmentType = attachment.url const attachmentType = attachment.url.split(".").pop()!.toLowerCase();
.split(".")
.pop()!
.toLowerCase();
const blacklist = trigger.blacklist_enabled const blacklist = trigger.blacklist_enabled
? (trigger.filetype_blacklist || []).map(_t => _t.toLowerCase()) ? (trigger.filetype_blacklist || []).map((_t) => _t.toLowerCase())
: null; : null;
if (blacklist && blacklist.includes(attachmentType)) { if (blacklist && blacklist.includes(attachmentType)) {
@ -52,7 +49,7 @@ export const MatchAttachmentTypeTrigger = automodTrigger<MatchResultType>()({
} }
const whitelist = trigger.whitelist_enabled const whitelist = trigger.whitelist_enabled
? (trigger.filetype_whitelist || []).map(_t => _t.toLowerCase()) ? (trigger.filetype_whitelist || []).map((_t) => _t.toLowerCase())
: null; : null;
if (whitelist && !whitelist.includes(attachmentType)) { if (whitelist && !whitelist.includes(attachmentType)) {

View file

@ -34,7 +34,7 @@ export const MatchMimeTypeTrigger = automodTrigger<MatchResultType>()({
const contentType = (rawContentType || "").split(";")[0]; // Remove "; charset=utf8" and similar from the end const contentType = (rawContentType || "").split(";")[0]; // Remove "; charset=utf8" and similar from the end
const blacklist = trigger.blacklist_enabled const blacklist = trigger.blacklist_enabled
? (trigger.mime_type_blacklist ?? []).map(_t => _t.toLowerCase()) ? (trigger.mime_type_blacklist ?? []).map((_t) => _t.toLowerCase())
: null; : null;
if (contentType && blacklist?.includes(contentType)) { if (contentType && blacklist?.includes(contentType)) {
@ -47,7 +47,7 @@ export const MatchMimeTypeTrigger = automodTrigger<MatchResultType>()({
} }
const whitelist = trigger.whitelist_enabled const whitelist = trigger.whitelist_enabled
? (trigger.mime_type_whitelist ?? []).map(_t => _t.toLowerCase()) ? (trigger.mime_type_whitelist ?? []).map((_t) => _t.toLowerCase())
: null; : null;
if (whitelist && (!contentType || !whitelist.includes(contentType))) { if (whitelist && (!contentType || !whitelist.includes(contentType))) {

View file

@ -64,7 +64,7 @@ export const MatchWordsTrigger = automodTrigger<MatchResultType>()({
// When performing loose matching, allow any amount of whitespace or up to looseMatchingThreshold number of other // When performing loose matching, allow any amount of whitespace or up to looseMatchingThreshold number of other
// characters between the matched characters. E.g. if we're matching banana, a loose match could also match b a n a n a // characters between the matched characters. E.g. if we're matching banana, a loose match could also match b a n a n a
let pattern = trigger.loose_matching let pattern = trigger.loose_matching
? [...word].map(c => escapeStringRegexp(c)).join(`(?:\\s*|.{0,${looseMatchingThreshold})`) ? [...word].map((c) => escapeStringRegexp(c)).join(`(?:\\s*|.{0,${looseMatchingThreshold})`)
: escapeStringRegexp(word); : escapeStringRegexp(word);
if (trigger.only_full_words) { if (trigger.only_full_words) {

View file

@ -30,7 +30,7 @@ export const MemberJoinSpamTrigger = automodTrigger<unknown>()({
const totalCount = sumRecentActionCounts(matchingActions); const totalCount = sumRecentActionCounts(matchingActions);
if (totalCount >= triggerConfig.amount) { if (totalCount >= triggerConfig.amount) {
const extraContexts = matchingActions.map(a => a.context).filter(c => c !== context); const extraContexts = matchingActions.map((a) => a.context).filter((c) => c !== context);
pluginData.state.recentSpam.push({ pluginData.state.recentSpam.push({
type: RecentActionType.MemberJoin, type: RecentActionType.MemberJoin,

View file

@ -35,7 +35,7 @@ export const AddDashboardUserCmd = botControlCmd({
await pluginData.state.apiPermissionAssignments.addUser(args.guildId, user.id, [ApiPermissions.EditConfig]); await pluginData.state.apiPermissionAssignments.addUser(args.guildId, user.id, [ApiPermissions.EditConfig]);
} }
const userNameList = args.users.map(user => `<@!${user.id}> (**${user.tag}**, \`${user.id}\`)`); const userNameList = args.users.map((user) => `<@!${user.id}> (**${user.tag}**, \`${user.id}\`)`);
sendSuccessMessage( sendSuccessMessage(
pluginData, pluginData,
msg.channel as TextChannel, msg.channel as TextChannel,

View file

@ -52,10 +52,7 @@ export const AddServerFromInviteCmd = botControlCmd({
invite.guild.id, invite.guild.id,
msg.author.id, msg.author.id,
[ApiPermissions.ManageAccess], [ApiPermissions.ManageAccess],
moment moment.utc().add(1, "hour").format(DBDateFormat),
.utc()
.add(1, "hour")
.format(DBDateFormat),
); );
} }

View file

@ -48,10 +48,7 @@ export const AllowServerCmd = botControlCmd({
args.guildId, args.guildId,
msg.author.id, msg.author.id,
[ApiPermissions.ManageAccess], [ApiPermissions.ManageAccess],
moment moment.utc().add(1, "hour").format(DBDateFormat),
.utc()
.add(1, "hour")
.format(DBDateFormat),
); );
} }

View file

@ -21,7 +21,7 @@ export const ListDashboardUsersCmd = botControlCmd({
const dashboardUsers = await pluginData.state.apiPermissionAssignments.getByGuildId(guild.id); const dashboardUsers = await pluginData.state.apiPermissionAssignments.getByGuildId(guild.id);
const users = await Promise.all( const users = await Promise.all(
dashboardUsers.map(async perm => ({ dashboardUsers.map(async (perm) => ({
user: await resolveUser(pluginData.client, perm.target_id), user: await resolveUser(pluginData.client, perm.target_id),
permission: perm, permission: perm,
})), })),

View file

@ -13,7 +13,7 @@ export const PerformanceCmd = botControlCmd({
async run({ pluginData, message: msg, args }) { async run({ pluginData, message: msg, args }) {
const stats = pluginData.getKnubInstance().getPluginPerformanceStats(); const stats = pluginData.getKnubInstance().getPluginPerformanceStats();
const averageLoadTimeEntries = Object.entries(stats.averageLoadTimes); const averageLoadTimeEntries = Object.entries(stats.averageLoadTimes);
averageLoadTimeEntries.sort(sorter(v => v[1].time, "DESC")); averageLoadTimeEntries.sort(sorter((v) => v[1].time, "DESC"));
const lines = averageLoadTimeEntries.map( const lines = averageLoadTimeEntries.map(
([pluginName, { time }]) => `${pluginName}: **${formatNumber(Math.round(time))}ms**`, ([pluginName, { time }]) => `${pluginName}: **${formatNumber(Math.round(time))}ms**`,
); );

View file

@ -34,7 +34,7 @@ export const RemoveDashboardUserCmd = botControlCmd({
await pluginData.state.apiPermissionAssignments.removeUser(args.guildId, user.id); await pluginData.state.apiPermissionAssignments.removeUser(args.guildId, user.id);
} }
const userNameList = args.users.map(user => `<@!${user.id}> (**${user.tag}**, \`${user.id}\`)`); const userNameList = args.users.map((user) => `<@!${user.id}> (**${user.tag}**, \`${user.id}\`)`);
sendSuccessMessage( sendSuccessMessage(
pluginData, pluginData,
msg.channel as TextChannel, msg.channel as TextChannel,

View file

@ -22,7 +22,7 @@ export const ServersCmd = botControlCmd({
async run({ pluginData, message: msg, args }) { async run({ pluginData, message: msg, args }) {
const showList = Boolean(args.all || args.initialized || args.uninitialized || args.search); 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") : null; const search = args.search ? new RegExp([...args.search].map((s) => escapeStringRegexp(s)).join(".*"), "i") : null;
const joinedGuilds = Array.from(pluginData.client.guilds.cache.values()); const joinedGuilds = Array.from(pluginData.client.guilds.cache.values());
const loadedGuilds = pluginData.getKnubInstance().getLoadedGuilds(); const loadedGuilds = pluginData.getKnubInstance().getLoadedGuilds();
@ -32,21 +32,21 @@ export const ServersCmd = botControlCmd({
let filteredGuilds = Array.from(joinedGuilds); let filteredGuilds = Array.from(joinedGuilds);
if (args.initialized) { if (args.initialized) {
filteredGuilds = filteredGuilds.filter(g => loadedGuildsMap.has(g.id)); filteredGuilds = filteredGuilds.filter((g) => loadedGuildsMap.has(g.id));
} }
if (args.uninitialized) { if (args.uninitialized) {
filteredGuilds = filteredGuilds.filter(g => !loadedGuildsMap.has(g.id)); filteredGuilds = filteredGuilds.filter((g) => !loadedGuildsMap.has(g.id));
} }
if (args.search) { 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) { if (filteredGuilds.length) {
filteredGuilds.sort(sorter(g => g.name.toLowerCase())); filteredGuilds.sort(sorter((g) => g.name.toLowerCase()));
const longestId = filteredGuilds.reduce((longest, guild) => Math.max(longest, guild.id.length), 0); const longestId = filteredGuilds.reduce((longest, guild) => Math.max(longest, guild.id.length), 0);
const lines = filteredGuilds.map(g => { const lines = filteredGuilds.map((g) => {
const paddedId = g.id.padEnd(longestId, " "); const paddedId = g.id.padEnd(longestId, " ");
const owner = getUser(pluginData.client, g.ownerId); const owner = getUser(pluginData.client, g.ownerId);
return `\`${paddedId}\` **${g.name}** (${g.memberCount} members) (owner **${owner.tag}** \`${owner.id}\`)`; return `\`${paddedId}\` **${g.name}** (${g.memberCount} members) (owner **${owner.tag}** \`${owner.id}\`)`;
@ -57,7 +57,7 @@ export const ServersCmd = botControlCmd({
} }
} else { } else {
const total = joinedGuilds.length; const total = joinedGuilds.length;
const initialized = joinedGuilds.filter(g => loadedGuildsMap.has(g.id)).length; const initialized = joinedGuilds.filter((g) => loadedGuildsMap.has(g.id)).length;
const unInitialized = total - initialized; const unInitialized = total - initialized;
msg.channel.send( msg.channel.send(

View file

@ -22,7 +22,7 @@ export async function createCaseNote(pluginData: GuildPluginData<CasesPluginType
// Add note details to the beginning of the note // Add note details to the beginning of the note
if (args.noteDetails && args.noteDetails.length) { if (args.noteDetails && args.noteDetails.length) {
body = args.noteDetails.map(d => `__[${d}]__`).join(" ") + " " + body; body = args.noteDetails.map((d) => `__[${d}]__`).join(" ") + " " + body;
} }
await pluginData.state.cases.createNote(theCase.id, { await pluginData.state.cases.createNote(theCase.id, {

View file

@ -7,11 +7,11 @@ export async function getCaseTypeAmountForUserId(
userID: string, userID: string,
type: CaseTypes, type: CaseTypes,
): Promise<number> { ): Promise<number> {
const cases = (await pluginData.state.cases.getByUserId(userID)).filter(c => !c.is_hidden); const cases = (await pluginData.state.cases.getByUserId(userID)).filter((c) => !c.is_hidden);
let typeAmount = 0; let typeAmount = 0;
if (cases.length > 0) { if (cases.length > 0) {
cases.forEach(singleCase => { cases.forEach((singleCase) => {
if (singleCase.type === type.valueOf()) { if (singleCase.type === type.valueOf()) {
typeAmount++; typeAmount++;
} }

View file

@ -71,10 +71,10 @@ export const CensorPlugin = zeppelinGuildPlugin<CensorPluginType>()({
afterLoad(pluginData) { afterLoad(pluginData) {
const { state, guild } = pluginData; const { state, guild } = pluginData;
state.onMessageCreateFn = msg => onMessageCreate(pluginData, msg); state.onMessageCreateFn = (msg) => onMessageCreate(pluginData, msg);
state.savedMessages.events.on("create", state.onMessageCreateFn); state.savedMessages.events.on("create", state.onMessageCreateFn);
state.onMessageUpdateFn = msg => onMessageUpdate(pluginData, msg); state.onMessageUpdateFn = (msg) => onMessageUpdate(pluginData, msg);
state.savedMessages.events.on("update", state.onMessageUpdateFn); state.savedMessages.events.on("update", state.onMessageUpdateFn);
}, },

View file

@ -19,7 +19,7 @@ export async function applyFiltersToMsg(
let messageContent = savedMessage.data.content || ""; let messageContent = savedMessage.data.content || "";
if (savedMessage.data.attachments) messageContent += " " + JSON.stringify(savedMessage.data.attachments); if (savedMessage.data.attachments) messageContent += " " + JSON.stringify(savedMessage.data.attachments);
if (savedMessage.data.embeds) { if (savedMessage.data.embeds) {
const embeds = (savedMessage.data.embeds as MessageEmbed[]).map(e => cloneDeep(e)); const embeds = (savedMessage.data.embeds as MessageEmbed[]).map((e) => cloneDeep(e));
for (const embed of embeds) { for (const embed of embeds) {
if (embed.type === "video") { if (embed.type === "video") {
// Ignore video descriptions as they're not actually shown on the embed // Ignore video descriptions as they're not actually shown on the embed
@ -52,7 +52,7 @@ export async function applyFiltersToMsg(
const inviteCodes = getInviteCodesInString(messageContent); const inviteCodes = getInviteCodesInString(messageContent);
const invites: Array<Invite | null> = await Promise.all( const invites: Array<Invite | null> = await Promise.all(
inviteCodes.map(code => resolveInvite(pluginData.client, code)), inviteCodes.map((code) => resolveInvite(pluginData.client, code)),
); );
for (const invite of invites) { for (const invite of invites) {

View file

@ -14,5 +14,5 @@ export const ChannelArchiverPlugin = zeppelinGuildPlugin<ChannelArchiverPluginTy
// prettier-ignore // prettier-ignore
commands: [ commands: [
ArchiveChannelCmd, ArchiveChannelCmd,
] ],
}); });

View file

@ -68,9 +68,9 @@ export const ArchiveChannelCmd = channelArchiverCmd({
for (const message of messages.values()) { for (const message of messages.values()) {
const ts = moment.utc(message.createdTimestamp).format("YYYY-MM-DD HH:mm:ss"); const ts = moment.utc(message.createdTimestamp).format("YYYY-MM-DD HH:mm:ss");
let content = `[${ts}] [${message.author.id}] [${message.author.username}#${ let content = `[${ts}] [${message.author.id}] [${message.author.username}#${message.author.discriminator}]: ${
message.author.discriminator message.content || "<no text content>"
}]: ${message.content || "<no text content>"}`; }`;
if (message.attachments.size) { if (message.attachments.size) {
if (args["attachment-channel"]) { if (args["attachment-channel"]) {

View file

@ -14,9 +14,9 @@ export async function getCompanionChannelOptsForVoiceChannelId(
const config = await pluginData.config.getMatchingConfig({ userId, channelId: voiceChannel.id }); const config = await pluginData.config.getMatchingConfig({ userId, channelId: voiceChannel.id });
return Object.values(config.entries) return Object.values(config.entries)
.filter( .filter(
opts => (opts) =>
opts.voice_channel_ids.includes(voiceChannel.id) || opts.voice_channel_ids.includes(voiceChannel.id) ||
(voiceChannel.parentId && opts.voice_channel_ids.includes(voiceChannel.parentId)), (voiceChannel.parentId && opts.voice_channel_ids.includes(voiceChannel.parentId)),
) )
.map(opts => Object.assign({}, defaultCompanionChannelOpts, opts)); .map((opts) => Object.assign({}, defaultCompanionChannelOpts, opts));
} }

View file

@ -65,7 +65,7 @@ export async function handleCompanionPermissions(
if (!channel || !(channel instanceof TextChannel)) continue; if (!channel || !(channel instanceof TextChannel)) continue;
pluginData.state.serverLogs.ignoreLog(LogType.CHANNEL_UPDATE, channelId, 3 * 1000); pluginData.state.serverLogs.ignoreLog(LogType.CHANNEL_UPDATE, channelId, 3 * 1000);
const fullSerialized = new Permissions(BigInt(permissions)).serialize(); const fullSerialized = new Permissions(BigInt(permissions)).serialize();
const onlyAllowed = filterObject(fullSerialized, v => v === true); const onlyAllowed = filterObject(fullSerialized, (v) => v === true);
await channel.permissionOverwrites.create(userId, onlyAllowed, { await channel.permissionOverwrites.create(userId, onlyAllowed, {
reason: `Companion Channel for ${voiceChannel!.id} | User Joined`, reason: `Companion Channel for ${voiceChannel!.id} | User Joined`,
}); });

View file

@ -48,8 +48,9 @@ export async function muteAction(
const muteMessage = `Muted **${result.case.user_name}** ${ const muteMessage = `Muted **${result.case.user_name}** ${
durationMs ? `for ${humanizeDuration(durationMs)}` : "indefinitely" durationMs ? `for ${humanizeDuration(durationMs)}` : "indefinitely"
} (Case #${result.case.case_number}) (user notified via ${result.notifyResult.method ?? } (Case #${result.case.case_number}) (user notified via ${
"dm"})\nPlease update the new case with the \`update\` command`; result.notifyResult.method ?? "dm"
})\nPlease update the new case with the \`update\` command`;
interaction.followUp({ ephemeral: true, content: muteMessage }); interaction.followUp({ ephemeral: true, content: muteMessage });
} catch (e) { } catch (e) {

View file

@ -26,7 +26,7 @@ export async function loadAllCommands(pluginData: GuildPluginData<ContextMenuPlu
newCommands.push(data); newCommands.push(data);
} }
const setCommands = await comms.set(newCommands, pluginData.guild.id).catch(e => { const setCommands = await comms.set(newCommands, pluginData.guild.id).catch((e) => {
pluginData.getPlugin(LogsPlugin).logBotAlert({ body: `Unable to overwrite context menus: ${e}` }); pluginData.getPlugin(LogsPlugin).logBotAlert({ body: `Unable to overwrite context menus: ${e}` });
return undefined; return undefined;
}); });

View file

@ -55,7 +55,7 @@ const defaultOptions: PluginOptions<CountersPluginType> = {
], ],
}; };
const configPreprocessor: ConfigPreprocessorFn<CountersPluginType> = options => { const configPreprocessor: ConfigPreprocessorFn<CountersPluginType> = (options) => {
for (const [counterName, counter] of Object.entries(options.config?.counters || {})) { for (const [counterName, counter] of Object.entries(options.config?.counters || {})) {
counter.name = counterName; counter.name = counterName;
counter.per_user = counter.per_user ?? false; counter.per_user = counter.per_user ?? false;

View file

@ -13,13 +13,13 @@ export const CountersListCmd = typedGuildCommand<CountersPluginType>()({
async run({ pluginData, message, args }) { async run({ pluginData, message, args }) {
const config = await pluginData.config.getForMessage(message); const config = await pluginData.config.getForMessage(message);
const countersToShow = Array.from(Object.values(config.counters)).filter(c => c.can_view !== false); const countersToShow = Array.from(Object.values(config.counters)).filter((c) => c.can_view !== false);
if (!countersToShow.length) { if (!countersToShow.length) {
sendErrorMessage(pluginData, message.channel, "No counters are configured for this server"); sendErrorMessage(pluginData, message.channel, "No counters are configured for this server");
return; return;
} }
const counterLines = countersToShow.map(counter => { const counterLines = countersToShow.map((counter) => {
const title = counter.pretty_name ? `**${counter.pretty_name}** (\`${counter.name}\`)` : `\`${counter.name}\``; const title = counter.pretty_name ? `**${counter.pretty_name}** (\`${counter.name}\`)` : `\`${counter.name}\``;
const types: string[] = []; const types: string[] = [];

View file

@ -38,10 +38,10 @@ export async function changeCounterValue(
if (triggers) { if (triggers) {
const triggersArr = Array.from(triggers.values()); const triggersArr = Array.from(triggers.values());
await Promise.all( await Promise.all(
triggersArr.map(trigger => checkCounterTrigger(pluginData, counterName, trigger, channelId, userId)), triggersArr.map((trigger) => checkCounterTrigger(pluginData, counterName, trigger, channelId, userId)),
); );
await Promise.all( await Promise.all(
triggersArr.map(trigger => checkReverseCounterTrigger(pluginData, counterName, trigger, channelId, userId)), triggersArr.map((trigger) => checkReverseCounterTrigger(pluginData, counterName, trigger, channelId, userId)),
); );
} }

View file

@ -25,8 +25,8 @@ export async function decayCounter(
const triggers = pluginData.state.counterTriggersByCounterId.get(counterId); const triggers = pluginData.state.counterTriggersByCounterId.get(counterId);
if (triggers) { if (triggers) {
const triggersArr = Array.from(triggers.values()); const triggersArr = Array.from(triggers.values());
await Promise.all(triggersArr.map(trigger => checkAllValuesForTrigger(pluginData, counterName, trigger))); await Promise.all(triggersArr.map((trigger) => checkAllValuesForTrigger(pluginData, counterName, trigger)));
await Promise.all(triggersArr.map(trigger => checkAllValuesForReverseTrigger(pluginData, counterName, trigger))); await Promise.all(triggersArr.map((trigger) => checkAllValuesForReverseTrigger(pluginData, counterName, trigger)));
} }
lock.unlock(); lock.unlock();

View file

@ -35,10 +35,10 @@ export async function setCounterValue(
if (triggers) { if (triggers) {
const triggersArr = Array.from(triggers.values()); const triggersArr = Array.from(triggers.values());
await Promise.all( await Promise.all(
triggersArr.map(trigger => checkCounterTrigger(pluginData, counterName, trigger, channelId, userId)), triggersArr.map((trigger) => checkCounterTrigger(pluginData, counterName, trigger, channelId, userId)),
); );
await Promise.all( await Promise.all(
triggersArr.map(trigger => checkReverseCounterTrigger(pluginData, counterName, trigger, channelId, userId)), triggersArr.map((trigger) => checkReverseCounterTrigger(pluginData, counterName, trigger, channelId, userId)),
); );
} }

View file

@ -29,7 +29,7 @@ export async function addRoleAction(
throw new ActionError("Missing permissions"); throw new ActionError("Missing permissions");
} }
const rolesToAdd = (Array.isArray(action.role) ? action.role : [action.role]).filter( const rolesToAdd = (Array.isArray(action.role) ? action.role : [action.role]).filter(
id => !target.roles.cache.has(id), (id) => !target.roles.cache.has(id),
); );
if (rolesToAdd.length === 0) { if (rolesToAdd.length === 0) {
throw new ActionError("Target already has the role(s) specified"); throw new ActionError("Target already has the role(s) specified");

View file

@ -5,7 +5,7 @@ export const GuildBanRemoveAlertsEvt = locateUserEvt({
async listener(meta) { async listener(meta) {
const alerts = await meta.pluginData.state.alerts.getAlertsByUserId(meta.args.ban.user.id); const alerts = await meta.pluginData.state.alerts.getAlertsByUserId(meta.args.ban.user.id);
alerts.forEach(alert => { alerts.forEach((alert) => {
meta.pluginData.state.alerts.delete(alert.id); meta.pluginData.state.alerts.delete(alert.id);
}); });
}, },

View file

@ -19,7 +19,7 @@ export const VoiceStateUpdateAlertEvt = locateUserEvt({
const triggeredAlerts = await meta.pluginData.state.alerts.getAlertsByUserId(memberId); const triggeredAlerts = await meta.pluginData.state.alerts.getAlertsByUserId(memberId);
const voiceChannel = meta.args.oldState.channel!; const voiceChannel = meta.args.oldState.channel!;
triggeredAlerts.forEach(alert => { triggeredAlerts.forEach((alert) => {
const txtChannel = meta.pluginData.guild.channels.resolve(alert.channel_id as Snowflake) as TextChannel; const txtChannel = meta.pluginData.guild.channels.resolve(alert.channel_id as Snowflake) as TextChannel;
txtChannel.send({ txtChannel.send({
content: `🔴 <@!${alert.requestor_id}> the user <@!${alert.user_id}> disconnected out of \`${voiceChannel.name}\``, content: `🔴 <@!${alert.requestor_id}> the user <@!${alert.user_id}> disconnected out of \`${voiceChannel.name}\``,

View file

@ -4,7 +4,7 @@ import { LocateUserPluginType } from "../types";
export async function fillActiveAlertsList(pluginData: GuildPluginData<LocateUserPluginType>) { export async function fillActiveAlertsList(pluginData: GuildPluginData<LocateUserPluginType>) {
const allAlerts = await pluginData.state.alerts.getAllGuildAlerts(); const allAlerts = await pluginData.state.alerts.getAllGuildAlerts();
allAlerts.forEach(alert => { allAlerts.forEach((alert) => {
if (!pluginData.state.usersWithAlerts.includes(alert.user_id)) { if (!pluginData.state.usersWithAlerts.includes(alert.user_id)) {
pluginData.state.usersWithAlerts.push(alert.user_id); pluginData.state.usersWithAlerts.push(alert.user_id);
} }

View file

@ -10,7 +10,7 @@ export async function sendAlerts(pluginData: GuildPluginData<LocateUserPluginTyp
const member = await resolveMember(pluginData.client, pluginData.guild, userId); const member = await resolveMember(pluginData.client, pluginData.guild, userId);
if (!member) return; if (!member) return;
triggeredAlerts.forEach(alert => { triggeredAlerts.forEach((alert) => {
const prepend = `<@!${alert.requestor_id}>, an alert requested by you has triggered!\nReminder: \`${alert.body}\`\n`; const prepend = `<@!${alert.requestor_id}>, an alert requested by you has triggered!\nReminder: \`${alert.body}\`\n`;
const txtChannel = pluginData.guild.channels.resolve(alert.channel_id as Snowflake) as TextChannel; const txtChannel = pluginData.guild.channels.resolve(alert.channel_id as Snowflake) as TextChannel;
sendWhere(pluginData, member, txtChannel, prepend); sendWhere(pluginData, member, txtChannel, prepend);

View file

@ -177,7 +177,7 @@ export const LogsPlugin = zeppelinGuildPlugin<LogsPluginType>()({
], ],
public: { public: {
getLogMessage: pluginData => { getLogMessage: (pluginData) => {
return <TLogType extends keyof ILogTypeData>( return <TLogType extends keyof ILogTypeData>(
type: TLogType, type: TLogType,
data: TypedTemplateSafeValueContainer<ILogTypeData[TLogType]>, data: TypedTemplateSafeValueContainer<ILogTypeData[TLogType]>,
@ -277,10 +277,10 @@ export const LogsPlugin = zeppelinGuildPlugin<LogsPluginType>()({
state.logListener = ({ type, data }) => log(pluginData, type, data); state.logListener = ({ type, data }) => log(pluginData, type, data);
state.guildLogs.on("log", state.logListener); state.guildLogs.on("log", state.logListener);
state.onMessageDeleteFn = msg => onMessageDelete(pluginData, msg); state.onMessageDeleteFn = (msg) => onMessageDelete(pluginData, msg);
state.savedMessages.events.on("delete", state.onMessageDeleteFn); state.savedMessages.events.on("delete", state.onMessageDeleteFn);
state.onMessageDeleteBulkFn = msg => onMessageDeleteBulk(pluginData, msg); state.onMessageDeleteBulkFn = (msg) => onMessageDeleteBulk(pluginData, msg);
state.savedMessages.events.on("deleteBulk", state.onMessageDeleteBulkFn); state.savedMessages.events.on("deleteBulk", state.onMessageDeleteBulkFn);
state.onMessageUpdateFn = (newMsg, oldMsg) => onMessageUpdate(pluginData, newMsg, oldMsg); state.onMessageUpdateFn = (newMsg, oldMsg) => onMessageUpdate(pluginData, newMsg, oldMsg);

View file

@ -58,10 +58,10 @@ export const LogsGuildMemberUpdateEvt = logsEvt({
logMemberRoleChanges(pluginData, { logMemberRoleChanges(pluginData, {
member, member,
addedRoles: addedRoles.map( addedRoles: addedRoles.map(
roleId => pluginData.guild.roles.cache.get(roleId) ?? { id: roleId, name: `Unknown (${roleId})` }, (roleId) => pluginData.guild.roles.cache.get(roleId) ?? { id: roleId, name: `Unknown (${roleId})` },
), ),
removedRoles: removedRoles.map( removedRoles: removedRoles.map(
roleId => pluginData.guild.roles.cache.get(roleId) ?? { id: roleId, name: `Unknown (${roleId})` }, (roleId) => pluginData.guild.roles.cache.get(roleId) ?? { id: roleId, name: `Unknown (${roleId})` },
), ),
mod: null, mod: null,
}); });
@ -70,7 +70,7 @@ export const LogsGuildMemberUpdateEvt = logsEvt({
logMemberRoleAdd(pluginData, { logMemberRoleAdd(pluginData, {
member, member,
roles: addedRoles.map( roles: addedRoles.map(
roleId => pluginData.guild.roles.cache.get(roleId) ?? { id: roleId, name: `Unknown (${roleId})` }, (roleId) => pluginData.guild.roles.cache.get(roleId) ?? { id: roleId, name: `Unknown (${roleId})` },
), ),
mod: null, mod: null,
}); });
@ -79,7 +79,7 @@ export const LogsGuildMemberUpdateEvt = logsEvt({
logMemberRoleRemove(pluginData, { logMemberRoleRemove(pluginData, {
member, member,
roles: removedRoles.map( roles: removedRoles.map(
roleId => pluginData.guild.roles.cache.get(roleId) ?? { id: roleId, name: `Unknown (${roleId})` }, (roleId) => pluginData.guild.roles.cache.get(roleId) ?? { id: roleId, name: `Unknown (${roleId})` },
), ),
mod: null, mod: null,
}); });

View file

@ -21,7 +21,7 @@ export function logAutomodAction(pluginData: GuildPluginData<LogsPluginType>, da
createTypedTemplateSafeValueContainer({ createTypedTemplateSafeValueContainer({
rule: data.rule, rule: data.rule,
user: data.user ? userToTemplateSafeUser(data.user) : null, user: data.user ? userToTemplateSafeUser(data.user) : null,
users: data.users.map(user => userToTemplateSafeUser(user)), users: data.users.map((user) => userToTemplateSafeUser(user)),
actionsTaken: data.actionsTaken, actionsTaken: data.actionsTaken,
matchSummary: data.matchSummary ?? "", matchSummary: data.matchSummary ?? "",
}), }),

View file

@ -19,7 +19,7 @@ export function logMemberRoleAdd(pluginData: GuildPluginData<LogsPluginType>, da
createTypedTemplateSafeValueContainer({ createTypedTemplateSafeValueContainer({
mod: data.mod ? userToTemplateSafeUser(data.mod) : null, mod: data.mod ? userToTemplateSafeUser(data.mod) : null,
member: memberToTemplateSafeMember(data.member), member: memberToTemplateSafeMember(data.member),
roles: data.roles.map(r => r.name).join(", "), roles: data.roles.map((r) => r.name).join(", "),
}), }),
{ {
userId: data.member.id, userId: data.member.id,

View file

@ -21,8 +21,8 @@ export function logMemberRoleChanges(pluginData: GuildPluginData<LogsPluginType>
createTypedTemplateSafeValueContainer({ createTypedTemplateSafeValueContainer({
mod: data.mod ? userToTemplateSafeUser(data.mod) : null, mod: data.mod ? userToTemplateSafeUser(data.mod) : null,
member: memberToTemplateSafeMember(data.member), member: memberToTemplateSafeMember(data.member),
addedRoles: data.addedRoles.map(r => r.name).join(", "), addedRoles: data.addedRoles.map((r) => r.name).join(", "),
removedRoles: data.removedRoles.map(r => r.name).join(", "), removedRoles: data.removedRoles.map((r) => r.name).join(", "),
}), }),
{ {
userId: data.member.id, userId: data.member.id,

Some files were not shown because too many files have changed in this diff Show more