Add custom logger. Fix a bunch of errors. Optimize imports.

This commit is contained in:
Dragory 2020-07-22 22:56:21 +03:00
parent 0dae54745d
commit 1064a1ca46
No known key found for this signature in database
GPG key ID: 5F387BA66DF8AAC1
89 changed files with 198 additions and 229 deletions

View file

@ -1,5 +1,5 @@
import express, { Request, Response } from "express";
import passport, { Strategy } from "passport";
import passport from "passport";
import OAuth2Strategy from "passport-oauth2";
import { Strategy as CustomStrategy } from "passport-custom";
import { ApiLogins } from "../data/ApiLogins";

View file

@ -2,8 +2,6 @@ import express from "express";
import { guildPlugins } from "../plugins/availablePlugins";
import { notFound } from "./responses";
import { indentLines } from "../utils";
import { getPluginName } from "knub/dist/plugins/pluginUtils";
import { ZeppelinPluginBlueprint } from "src/plugins/ZeppelinPluginBlueprint";
function formatConfigSchema(schema) {
if (schema._tag === "InterfaceType" || schema._tag === "PartialType") {
@ -48,12 +46,12 @@ export function initDocs(app: express.Express) {
app.get("/docs/plugins/:pluginName", (req: express.Request, res: express.Response) => {
// prettier-ignore
const plugin = docsPlugins.find(obj => getPluginName(obj) === req.params.pluginName);
const plugin = docsPlugins.find(_plugin => _plugin.name === req.params.pluginName);
if (!plugin) {
return notFound(res);
}
const name = getPluginName(plugin);
const name = plugin.name;
const info = plugin.info || {};
const commands = (plugin.commands || []).map(cmd => ({

View file

@ -5,10 +5,7 @@ import { initAuth } from "./auth";
import { initGuildsAPI } from "./guilds";
import { initArchives } from "./archives";
import { initDocs } from "./docs";
import { connect } from "../data/db";
import path from "path";
import { TokenError } from "passport-oauth2";
import { PluginError } from "knub";
const app = express();

View file

@ -1,12 +1,5 @@
import {
convertDelayStringToMS,
deactivateMentions,
disableCodeBlocks,
resolveMember,
resolveUser,
UnknownUser,
} from "./utils";
import { Client, GuildChannel, Member, Message, User } from "eris";
import { convertDelayStringToMS, disableCodeBlocks, resolveMember, resolveUser, UnknownUser } from "./utils";
import { GuildChannel, Member, User } from "eris";
import { baseTypeConverters, baseTypeHelpers, CommandContext, TypeConversionError } from "knub";
import { createTypeHelper } from "knub-command-manager";

View file

@ -1,19 +1,13 @@
import * as t from "io-ts";
import { pipe } from "fp-ts/lib/pipeable";
import { fold } from "fp-ts/lib/Either";
import { PathReporter } from "io-ts/lib/PathReporter";
import { guildPlugins } from "./plugins/availablePlugins";
import { ZeppelinPluginClass } from "./plugins/ZeppelinPluginClass";
import { decodeAndValidateStrict, StrictValidationError } from "./validatorUtils";
import { ZeppelinPlugin } from "./plugins/ZeppelinPlugin";
import { getPluginName } from "knub/dist/plugins/pluginUtils";
import { IZeppelinGuildConfig } from "./types";
import { PluginOptions } from "knub";
const pluginNameToPlugin = new Map<string, ZeppelinPlugin>();
for (const plugin of guildPlugins) {
const pluginName = getPluginName(plugin);
pluginNameToPlugin.set(pluginName, plugin);
pluginNameToPlugin.set(plugin.name, plugin);
}
const guildConfigRootSchema = t.type({
@ -45,10 +39,16 @@ export function validateGuildConfig(config: any): string[] | null {
}
const plugin = pluginNameToPlugin.get(pluginName);
let pluginErrors = plugin.configPreprocessor(pluginOptions as PluginOptions<any>);
if (pluginErrors) {
pluginErrors = pluginErrors.map(err => `${pluginName}: ${err}`);
return pluginErrors;
try {
plugin.configPreprocessor(pluginOptions as PluginOptions<any>);
} catch (err) {
if (err instanceof StrictValidationError) {
return err.getErrors().map(err => {
return `${pluginName}: ${err.toString()}`;
});
}
throw err;
}
}
}

View file

@ -1,13 +1,5 @@
import { AllowedGuild } from "./entities/AllowedGuild";
import {
getConnection,
getRepository,
Repository,
Transaction,
TransactionManager,
TransactionRepository,
} from "typeorm";
import { BaseGuildRepository } from "./BaseGuildRepository";
import { getRepository, Repository } from "typeorm";
import { BaseRepository } from "./BaseRepository";
import { ApiPermissionTypes } from "./ApiPermissionAssignments";

View file

@ -3,11 +3,9 @@ import { ApiLogin } from "./entities/ApiLogin";
import { BaseRepository } from "./BaseRepository";
import crypto from "crypto";
import moment from "moment-timezone";
// tslint:disable-next-line:no-submodule-imports
import uuidv4 from "uuid/v4";
import { DBDateFormat } from "../utils";
import { log } from "util";
export class ApiLogins extends BaseRepository {
private apiLogins: Repository<ApiLogin>;

View file

@ -1,11 +1,10 @@
import uuid from "uuid/v4"; // tslint:disable-line
import moment from "moment-timezone";
import { ArchiveEntry } from "./entities/ArchiveEntry";
import { getRepository, Repository } from "typeorm";
import { BaseGuildRepository } from "./BaseGuildRepository";
import { trimLines } from "../utils";
import { SavedMessage } from "./entities/SavedMessage";
import { Channel, Guild, User } from "eris";
import { Guild } from "eris";
import { renderTemplate } from "../templateFormatter";
const DEFAULT_EXPIRY_DAYS = 30;

View file

@ -1,7 +1,7 @@
import moment from "moment-timezone";
import { Mute } from "./entities/Mute";
import { BaseGuildRepository } from "./BaseGuildRepository";
import { getRepository, Repository, Brackets } from "typeorm";
import { Brackets, getRepository, Repository } from "typeorm";
export class GuildMutes extends BaseGuildRepository {
private mutes: Repository<Mute>;

View file

@ -1,7 +1,7 @@
import { BaseGuildRepository } from "./BaseGuildRepository";
import { getRepository, In, Repository } from "typeorm";
import { NicknameHistoryEntry } from "./entities/NicknameHistoryEntry";
import { MINUTES, SECONDS, sorter } from "../utils";
import { MINUTES, SECONDS } from "../utils";
import { MAX_USERNAME_ENTRIES_PER_USER } from "./UsernameHistory";
import { isAPI } from "../globals";
import { cleanupNicknames } from "./cleanup/nicknames";

View file

@ -1,12 +1,11 @@
import { getRepository, In, Repository } from "typeorm";
import { getRepository, Repository } from "typeorm";
import { BaseGuildRepository } from "./BaseGuildRepository";
import { ISavedMessageData, SavedMessage } from "./entities/SavedMessage";
import { QueuedEventEmitter } from "../QueuedEventEmitter";
import { GuildChannel, Message } from "eris";
import moment from "moment-timezone";
import { DAYS, DBDateFormat, MINUTES, SECONDS } from "../utils";
import { MINUTES, SECONDS } from "../utils";
import { isAPI } from "../globals";
import { connection } from "./db";
import { cleanupMessages } from "./cleanup/messages";
if (!isAPI()) {

View file

@ -1,5 +1,5 @@
import { BaseGuildRepository } from "./BaseGuildRepository";
import { Repository, getRepository } from "typeorm";
import { getRepository, Repository } from "typeorm";
import { StarboardReaction } from "./entities/StarboardReaction";
export class GuildStarboardReactions extends BaseGuildRepository {

View file

@ -1,5 +1,4 @@
import { BaseGuildRepository } from "./BaseGuildRepository";
import { connection } from "./db";
import { getRepository, Repository } from "typeorm";
import { StatValue } from "./entities/StatValue";

View file

@ -1,8 +1,7 @@
import { getRepository, In, Repository } from "typeorm";
import { UsernameHistoryEntry } from "./entities/UsernameHistoryEntry";
import { MINUTES, SECONDS, sorter } from "../utils";
import { MINUTES, SECONDS } from "../utils";
import { BaseRepository } from "./BaseRepository";
import { connection } from "./db";
import { isAPI } from "../globals";
import { cleanupUsernames } from "./cleanup/usernames";

View file

@ -1,4 +1,4 @@
import { Entity, Column, PrimaryColumn, CreateDateColumn } from "typeorm";
import { Column, Entity, PrimaryColumn } from "typeorm";
@Entity("allowed_guilds")
export class AllowedGuild {

View file

@ -1,4 +1,4 @@
import { Entity, Column, PrimaryColumn } from "typeorm";
import { Column, Entity, PrimaryColumn } from "typeorm";
@Entity("antiraid_levels")
export class AntiraidLevel {

View file

@ -1,4 +1,4 @@
import { Entity, Column, PrimaryColumn, OneToOne, ManyToOne, JoinColumn } from "typeorm";
import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn } from "typeorm";
import { ApiUserInfo } from "./ApiUserInfo";
@Entity("api_logins")

View file

@ -1,4 +1,4 @@
import { Entity, Column, PrimaryColumn, ManyToOne, JoinColumn } from "typeorm";
import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn } from "typeorm";
import { ApiUserInfo } from "./ApiUserInfo";
@Entity("api_permissions")

View file

@ -1,4 +1,4 @@
import { Entity, Column, PrimaryColumn, OneToMany } from "typeorm";
import { Column, Entity, OneToMany, PrimaryColumn } from "typeorm";
import { ApiLogin } from "./ApiLogin";
import { ApiPermissionAssignment } from "./ApiPermissionAssignment";

View file

@ -1,4 +1,4 @@
import { Entity, Column, PrimaryGeneratedColumn } from "typeorm";
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
@Entity("archives")
export class ArchiveEntry {

View file

@ -1,5 +1,4 @@
import { Entity, Column, PrimaryColumn } from "typeorm";
import { ISavedMessageData } from "./SavedMessage";
import { Column, Entity, PrimaryColumn } from "typeorm";
@Entity("auto_reactions")
export class AutoReaction {

View file

@ -1,4 +1,4 @@
import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from "typeorm";
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm";
import { CaseNote } from "./CaseNote";
@Entity("cases")

View file

@ -1,4 +1,4 @@
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from "typeorm";
import { Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from "typeorm";
import { Case } from "./Case";
@Entity("case_notes")

View file

@ -1,4 +1,4 @@
import { Entity, Column, PrimaryColumn, CreateDateColumn, ManyToOne, JoinColumn } from "typeorm";
import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn } from "typeorm";
import { ApiUserInfo } from "./ApiUserInfo";
@Entity("configs")

View file

@ -1,4 +1,4 @@
import { Entity, Column, PrimaryColumn } from "typeorm";
import { Column, Entity, PrimaryColumn } from "typeorm";
@Entity("mutes")
export class Mute {

View file

@ -1,4 +1,4 @@
import { Entity, Column, PrimaryColumn } from "typeorm";
import { Column, Entity, PrimaryColumn } from "typeorm";
@Entity("nickname_history")
export class NicknameHistoryEntry {

View file

@ -1,4 +1,4 @@
import { Entity, Column, PrimaryColumn } from "typeorm";
import { Column, Entity, PrimaryColumn } from "typeorm";
@Entity("persisted_data")
export class PersistedData {

View file

@ -1,5 +1,4 @@
import { Entity, Column, PrimaryColumn } from "typeorm";
import { ISavedMessageData } from "./SavedMessage";
import { Column, Entity, PrimaryColumn } from "typeorm";
@Entity("pingable_roles")
export class PingableRole {

View file

@ -1,4 +1,4 @@
import { Entity, Column, PrimaryColumn } from "typeorm";
import { Column, Entity, PrimaryColumn } from "typeorm";
@Entity("reaction_roles")
export class ReactionRole {

View file

@ -1,4 +1,4 @@
import { Entity, Column, PrimaryColumn } from "typeorm";
import { Column, Entity, PrimaryColumn } from "typeorm";
@Entity("reminders")
export class Reminder {

View file

@ -1,4 +1,4 @@
import { Entity, Column, PrimaryColumn } from "typeorm";
import { Column, Entity, PrimaryColumn } from "typeorm";
export interface ISavedMessageData {
attachments?: object[];

View file

@ -1,4 +1,4 @@
import { Entity, Column, PrimaryColumn } from "typeorm";
import { Column, Entity, PrimaryColumn } from "typeorm";
import { Attachment } from "eris";
import { StrictMessageContent } from "../../utils";

View file

@ -1,4 +1,4 @@
import { Entity, Column, PrimaryColumn } from "typeorm";
import { Column, Entity, PrimaryColumn } from "typeorm";
@Entity("slowmode_channels")
export class SlowmodeChannel {

View file

@ -1,4 +1,4 @@
import { Entity, Column, PrimaryColumn } from "typeorm";
import { Column, Entity, PrimaryColumn } from "typeorm";
@Entity("slowmode_users")
export class SlowmodeUser {

View file

@ -1,4 +1,4 @@
import { Entity, Column, PrimaryColumn, OneToMany, ManyToOne, JoinColumn, OneToOne } from "typeorm";
import { Column, Entity, JoinColumn, OneToOne, PrimaryColumn } from "typeorm";
import { SavedMessage } from "./SavedMessage";
@Entity("starboard_messages")

View file

@ -1,4 +1,4 @@
import { Entity, Column, PrimaryColumn, JoinColumn, OneToOne } from "typeorm";
import { Column, Entity, JoinColumn, OneToOne, PrimaryColumn } from "typeorm";
import { SavedMessage } from "./SavedMessage";
@Entity("starboard_reactions")

View file

@ -1,4 +1,4 @@
import { Entity, Column, PrimaryColumn, CreateDateColumn } from "typeorm";
import { Column, Entity, PrimaryColumn } from "typeorm";
@Entity("stats")
export class StatValue {

View file

@ -1,4 +1,4 @@
import { Entity, Column, PrimaryColumn } from "typeorm";
import { Column, Entity, PrimaryColumn } from "typeorm";
@Entity("supporters")
export class Supporter {

View file

@ -1,4 +1,4 @@
import { Entity, Column, PrimaryColumn, CreateDateColumn } from "typeorm";
import { Column, Entity, PrimaryColumn } from "typeorm";
@Entity("tags")
export class Tag {

View file

@ -1,4 +1,4 @@
import { Entity, Column, PrimaryColumn, CreateDateColumn } from "typeorm";
import { Column, Entity, PrimaryColumn } from "typeorm";
@Entity("tag_responses")
export class TagResponse {

View file

@ -1,4 +1,4 @@
import { Entity, Column, PrimaryColumn } from "typeorm";
import { Column, Entity, PrimaryColumn } from "typeorm";
@Entity("username_history")
export class UsernameHistoryEntry {

View file

@ -1,4 +1,4 @@
import { Entity, Column, PrimaryColumn } from "typeorm";
import { Column, Entity, PrimaryColumn } from "typeorm";
@Entity("vc_alerts")
export class VCAlert {

View file

@ -2,12 +2,27 @@ import path from "path";
import yaml from "js-yaml";
import fs from "fs";
const fsp = fs.promises;
import { Knub, logger, PluginError, pluginUtils } from "knub";
import { Knub, PluginError } from "knub";
import { SimpleError } from "./SimpleError";
import { Configs } from "./data/Configs";
// Always use UTC internally
// This is also enforced for the database in data/db.ts
import moment from "moment-timezone";
import { Client, TextChannel } from "eris";
import { connect } from "./data/db";
import { globalPlugins, guildPlugins } from "./plugins/availablePlugins";
import { errorMessage, isDiscordHTTPError, isDiscordRESTError, successMessage } from "./utils";
import { startUptimeCounter } from "./uptime";
import { AllowedGuilds } from "./data/AllowedGuilds";
import { IZeppelinGlobalConfig, IZeppelinGuildConfig } from "./types";
import { RecoverablePluginError } from "./RecoverablePluginError";
import { GuildLogs } from "./data/GuildLogs";
import { LogType } from "./data/LogType";
import { ZeppelinPlugin } from "./plugins/ZeppelinPlugin";
import { logger } from "./logger";
const fsp = fs.promises;
require("dotenv").config({ path: path.resolve(process.cwd(), "bot.env") });
@ -80,23 +95,8 @@ for (const [i, part] of actualVersionParts.entries()) {
throw new SimpleError(`Unsupported Node.js version! Must be at least ${REQUIRED_NODE_VERSION}`);
}
// Always use UTC internally
// This is also enforced for the database in data/db.ts
import moment from "moment-timezone";
moment.tz.setDefault("UTC");
import { Client, TextChannel } from "eris";
import { connect } from "./data/db";
import { guildPlugins, globalPlugins } from "./plugins/availablePlugins";
import { errorMessage, isDiscordHTTPError, isDiscordRESTError, successMessage } from "./utils";
import { startUptimeCounter } from "./uptime";
import { AllowedGuilds } from "./data/AllowedGuilds";
import { IZeppelinGuildConfig, IZeppelinGlobalConfig } from "./types";
import { RecoverablePluginError } from "./RecoverablePluginError";
import { GuildLogs } from "./data/GuildLogs";
import { LogType } from "./data/LogType";
import { ZeppelinPlugin } from "./plugins/ZeppelinPlugin";
logger.info("Connecting to database");
connect().then(async () => {
const client = new Client(`Bot ${process.env.TOKEN}`, {
@ -152,8 +152,12 @@ connect().then(async () => {
logFn: (level, msg) => {
if (level === "debug") return;
// tslint:disable-next-line
console.log(`[${level.toUpperCase()}] ${msg}`);
if (logger[level]) {
logger[level](msg);
} else {
logger.log(`[${level.toUpperCase()}] ${msg}`);
}
},
performanceDebug: {

23
backend/src/logger.ts Normal file
View file

@ -0,0 +1,23 @@
// tslint-disable:no-console
export const logger = {
info(...args: Parameters<typeof console.log>) {
console.log("[INFO]", ...args);
},
warn(...args: Parameters<typeof console.warn>) {
console.warn("[WARN]", ...args);
},
error(...args: Parameters<typeof console.error>) {
console.error("[ERROR]", ...args);
},
debug(...args: Parameters<typeof console.log>) {
console.log("[DEBUG]", ...args);
},
log(...args: Parameters<typeof console.log>) {
console.log(...args);
},
};

View file

@ -3,6 +3,7 @@ import { connect } from "./data/db";
import { Configs } from "./data/Configs";
import path from "path";
import * as _fs from "fs";
const fs = _fs.promises;
const authorId = process.argv[2];

View file

@ -1,4 +1,4 @@
import { MigrationInterface, QueryRunner, TableColumn, TableIndex } from "typeorm";
import { MigrationInterface, QueryRunner, TableIndex } from "typeorm";
export class AddIndexToArchivesExpiresAt1547392046629 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> {

View file

@ -1,4 +1,4 @@
import { MigrationInterface, QueryRunner, Table, TableIndex } from "typeorm";
import { MigrationInterface, QueryRunner, Table } from "typeorm";
export class CreateConfigsTable1561111990357 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> {

View file

@ -1,4 +1,4 @@
import { MigrationInterface, QueryRunner, Table, TableColumn, createQueryBuilder } from "typeorm";
import { MigrationInterface, QueryRunner, Table, TableColumn } from "typeorm";
export class MoveStarboardsToConfig1573248462469 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> {

View file

@ -2,13 +2,12 @@
* @file Utility functions that are plugin-instance-specific (i.e. use PluginData)
*/
import { Member, TextChannel } from "eris";
import { configUtils, helpers, Knub, PluginData, PluginOptions } from "knub";
import { Member } from "eris";
import { configUtils, helpers, PluginData, PluginOptions } from "knub";
import { decodeAndValidateStrict, StrictValidationError } from "./validatorUtils";
import { deepKeyIntersect, errorMessage, successMessage } from "./utils";
import { ZeppelinPluginClass } from "./plugins/ZeppelinPluginClass";
import { ZeppelinPluginBlueprint } from "./plugins/ZeppelinPluginBlueprint";
import { IZeppelinGlobalConfig, IZeppelinGuildConfig, TZeppelinKnub } from "./types";
import { TZeppelinKnub } from "./types";
const { getMemberLevel } = helpers;
@ -22,33 +21,34 @@ export function canActOn(pluginData: PluginData<any>, member1: Member, member2:
return allowSameLevel ? ourLevel >= memberLevel : ourLevel > memberLevel;
}
export function pluginConfigPreprocessor(
this: typeof ZeppelinPluginClass | ZeppelinPluginBlueprint,
options: PluginOptions<any>,
) {
const decodedConfig = this.configSchema ? decodeAndValidateStrict(this.configSchema, options.config) : options.config;
if (decodedConfig instanceof StrictValidationError) {
throw decodedConfig;
}
const decodedOverrides = [];
for (const override of options.overrides || []) {
const overrideConfigMergedWithBaseConfig = configUtils.mergeConfig(options.config, override.config || {});
const decodedOverrideConfig = this.configSchema
? decodeAndValidateStrict(this.configSchema, overrideConfigMergedWithBaseConfig)
: overrideConfigMergedWithBaseConfig;
if (decodedOverrideConfig instanceof StrictValidationError) {
throw decodedOverrideConfig;
export function getPluginConfigPreprocessor(blueprint: ZeppelinPluginBlueprint) {
return (options: PluginOptions<any>) => {
const decodedConfig = blueprint.configSchema
? decodeAndValidateStrict(blueprint.configSchema, options.config)
: options.config;
if (decodedConfig instanceof StrictValidationError) {
throw decodedConfig;
}
decodedOverrides.push({
...override,
config: deepKeyIntersect(decodedOverrideConfig, override.config || {}),
});
}
return {
config: decodedConfig,
overrides: decodedOverrides,
const decodedOverrides = [];
for (const override of options.overrides || []) {
const overrideConfigMergedWithBaseConfig = configUtils.mergeConfig(options.config, override.config || {});
const decodedOverrideConfig = blueprint.configSchema
? decodeAndValidateStrict(blueprint.configSchema, overrideConfigMergedWithBaseConfig)
: overrideConfigMergedWithBaseConfig;
if (decodedOverrideConfig instanceof StrictValidationError) {
throw decodedOverrideConfig;
}
decodedOverrides.push({
...override,
config: deepKeyIntersect(decodedOverrideConfig, override.config || {}),
});
}
return {
config: decodedConfig,
overrides: decodedOverrides,
};
};
}

View file

@ -1,5 +1,5 @@
import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
import { ConfigSchema, AutoReactionsPluginType } from "./types";
import { AutoReactionsPluginType, ConfigSchema } from "./types";
import { PluginOptions } from "knub";
import { NewAutoReactionsCmd } from "./commands/NewAutoReactionsCmd";
import { DisableAutoReactionsCmd } from "./commands/DisableAutoReactionsCmd";

View file

@ -1,6 +1,6 @@
import { autoReactionsCmd } from "../types";
import { commandTypeHelpers as ct } from "../../../commandTypes";
import { isEmoji, customEmojiRegex, canUseEmoji } from "src/utils";
import { canUseEmoji, customEmojiRegex, isEmoji } from "src/utils";
import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils";
export const NewAutoReactionsCmd = autoReactionsCmd({

View file

@ -1,7 +1,7 @@
import { autoReactionsEvt } from "../types";
import { isDiscordRESTError } from "src/utils";
import { logger } from "knub";
import { LogType } from "src/data/LogType";
import { logger } from "../../../logger";
export const AddReactionsEvt = autoReactionsEvt({
event: "messageCreate",

View file

@ -1,6 +1,5 @@
import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
import { CaseArgs, CaseNoteArgs, CasesPluginType, ConfigSchema } from "./types";
import { resolveUser } from "../../utils";
import { createCase } from "./functions/createCase";
import { GuildLogs } from "../../data/GuildLogs";
import { GuildArchives } from "../../data/GuildArchives";

View file

@ -2,7 +2,8 @@ import { CaseArgs, CasesPluginType } from "../types";
import { resolveUser } from "../../../utils";
import { PluginData } from "knub";
import { createCaseNote } from "./createCaseNote";
import { postToCaseLogChannel } from "./postToCaseLogChannel";
import { postCaseToCaseLogChannel } from "./postToCaseLogChannel";
import { logger } from "../../../logger";
export async function createCase(pluginData: PluginData<CasesPluginType>, args: CaseArgs) {
const user = await resolveUser(pluginData.client, args.userId);
@ -21,7 +22,7 @@ export async function createCase(pluginData: PluginData<CasesPluginType>, args:
const existingAuditLogCase = await pluginData.state.cases.findByAuditLogId(args.auditLogId);
if (existingAuditLogCase) {
delete args.auditLogId;
console.warn(`Duplicate audit log ID for mod case: ${args.auditLogId}`);
logger.warn(`Duplicate audit log ID for mod case: ${args.auditLogId}`);
}
}
@ -66,7 +67,7 @@ export async function createCase(pluginData: PluginData<CasesPluginType>, args:
(!args.automatic || config.log_automatic_actions) &&
args.postInCaseLogOverride !== false
) {
await postToCaseLogChannel(pluginData, createdCase);
await postCaseToCaseLogChannel(pluginData, createdCase);
}
return createdCase;

View file

@ -1,4 +1,4 @@
import { plugin, PluginData } from "knub";
import { PluginData } from "knub";
import { CasesPluginType } from "../types";
import { Message, MessageContent, MessageFile, TextChannel } from "eris";
import { isDiscordRESTError } from "../../../utils";
@ -6,6 +6,7 @@ import { LogType } from "../../../data/LogType";
import { Case } from "../../../data/entities/Case";
import { getCaseEmbed } from "./getCaseEmbed";
import { resolveCaseId } from "./resolveCaseId";
import { logger } from "../../../logger";
export async function postToCaseLogChannel(
pluginData: PluginData<CasesPluginType>,
@ -23,7 +24,7 @@ export async function postToCaseLogChannel(
result = await caseLogChannel.createMessage(content, file);
} catch (e) {
if (isDiscordRESTError(e) && (e.code === 50013 || e.code === 50001)) {
console.warn(
logger.warn(
`Missing permissions to post mod cases in <#${caseLogChannel.id}> in guild ${pluginData.guild.name} (${pluginData.guild.id})`,
);
pluginData.state.logs.log(LogType.BOT_ALERT, {

View file

@ -4,9 +4,7 @@ import { CaseTypes } from "../../data/CaseTypes";
import { BasePluginType } from "knub";
import { GuildLogs } from "../../data/GuildLogs";
import { GuildCases } from "../../data/GuildCases";
import { GuildSavedMessages } from "../../data/GuildSavedMessages";
import { GuildArchives } from "../../data/GuildArchives";
import { Supporters } from "../../data/Supporters";
export const ConfigSchema = t.type({
log_automatic_actions: t.boolean,

View file

@ -1,8 +1,4 @@
import { BasePluginType } from "knub";
import { GuildMutes } from "../../data/GuildMutes";
import { GuildCases } from "../../data/GuildCases";
import { GuildLogs } from "../../data/GuildLogs";
import { GuildArchives } from "../../data/GuildArchives";
import { TConfigSchema } from "../Mutes/types";
import { Configs } from "../../data/Configs";
import Timeout = NodeJS.Timeout;

View file

@ -1,13 +1,13 @@
import { PluginOptions } from "knub";
import { LocateUserPluginType, ConfigSchema } from "./types";
import { ConfigSchema, LocateUserPluginType } from "./types";
import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
import { GuildVCAlerts } from "src/data/GuildVCAlerts";
import { outdatedAlertsLoop } from "./utils/outdatedLoop";
import { fillActiveAlertsList } from "./utils/fillAlertsList";
import { WhereCmd } from "./commands/WhereCmd";
import { FollowCmd } from "./commands/FollowCmd";
import { ListFollowCmd, DeleteFollowCmd } from "./commands/ListFollowCmd";
import { ChannelJoinAlertsEvt, ChannelSwitchAlertsEvt, ChannelLeaveAlertsEvt } from "./events/SendAlertsEvts";
import { DeleteFollowCmd, ListFollowCmd } from "./commands/ListFollowCmd";
import { ChannelJoinAlertsEvt, ChannelLeaveAlertsEvt, ChannelSwitchAlertsEvt } from "./events/SendAlertsEvts";
import { GuildBanRemoveAlertsEvt } from "./events/BanRemoveAlertsEvt";
const defaultOptions: PluginOptions<LocateUserPluginType> = {
@ -40,9 +40,9 @@ export const LocateUserPlugin = zeppelinPlugin<LocateUserPluginType>()("locate_u
// prettier-ignore
events: [
ChannelJoinAlertsEvt,
ChannelSwitchAlertsEvt,
ChannelLeaveAlertsEvt,
ChannelJoinAlertsEvt,
ChannelSwitchAlertsEvt,
ChannelLeaveAlertsEvt,
GuildBanRemoveAlertsEvt
],

View file

@ -1,7 +1,7 @@
import { locateUserCommand } from "../types";
import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils";
import { commandTypeHelpers as ct } from "../../../commandTypes";
import { sorter, createChunkedMessage } from "src/utils";
import { createChunkedMessage, sorter } from "src/utils";
export const ListFollowCmd = locateUserCommand({
trigger: ["follows", "fs"],

View file

@ -1,6 +1,6 @@
import { locateUserEvent } from "../types";
import { sendAlerts } from "../utils/sendAlerts";
import { VoiceChannel, TextableChannel } from "eris";
import { TextableChannel, VoiceChannel } from "eris";
export const ChannelJoinAlertsEvt = locateUserEvent({
event: "voiceChannelJoin",

View file

@ -9,7 +9,7 @@ export async function moveMember(
target: Member,
errorChannel: TextableChannel,
) {
const modMember: Member = await this.bot.getRESTGuildMember(pluginData.guild.id, toMoveID);
const modMember: Member = await pluginData.client.getRESTGuildMember(pluginData.guild.id, toMoveID);
if (modMember.voiceState.channelID != null) {
try {
await modMember.edit({

View file

@ -12,6 +12,6 @@ export async function outdatedAlertsLoop(pluginData) {
}
if (!pluginData.state.unloaded) {
pluginData.state.outdatedAlertsTimeout = setTimeout(() => this.outdatedAlertsLoop(pluginData), ALERT_LOOP_TIME);
pluginData.state.outdatedAlertsTimeout = setTimeout(() => outdatedAlertsLoop(pluginData), ALERT_LOOP_TIME);
}
}

View file

@ -12,7 +12,7 @@ export async function sendAlerts(pluginData: PluginData<LocateUserPluginType>, u
triggeredAlerts.forEach(alert => {
const prepend = `<@!${alert.requestor_id}>, an alert requested by you has triggered!\nReminder: \`${alert.body}\`\n`;
const txtChannel = pluginData.client.getChannel(alert.channel_id) as TextableChannel;
sendWhere.call(this, pluginData.guild, member, txtChannel, prepend);
sendWhere(pluginData, member, txtChannel, prepend);
if (alert.active) {
moveMember(pluginData, alert.requestor_id, member, txtChannel);
}

View file

@ -1,9 +1,17 @@
import { Guild, Member, TextableChannel, VoiceChannel } from "eris";
import { Member, TextableChannel, VoiceChannel } from "eris";
import { getInviteLink } from "knub/dist/helpers";
import { createOrReuseInvite } from "./createOrReuseInvite";
import { PluginData } from "knub";
import { LocateUserPluginType } from "../types";
import { sendErrorMessage } from "../../../pluginUtils";
export async function sendWhere(guild: Guild, member: Member, channel: TextableChannel, prepend: string) {
const voice = guild.channels.get(member.voiceState.channelID) as VoiceChannel;
export async function sendWhere(
pluginData: PluginData<LocateUserPluginType>,
member: Member,
channel: TextableChannel,
prepend: string,
) {
const voice = pluginData.guild.channels.get(member.voiceState.channelID) as VoiceChannel;
if (voice == null) {
channel.createMessage(prepend + "That user is not in a channel");
@ -12,7 +20,7 @@ export async function sendWhere(guild: Guild, member: Member, channel: TextableC
try {
invite = await createOrReuseInvite(voice);
} catch (e) {
this.sendErrorMessage(channel, "Cannot create an invite to that channel!");
sendErrorMessage(pluginData, channel, "Cannot create an invite to that channel!");
return;
}
channel.createMessage(

View file

@ -2,7 +2,7 @@ import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
import { ConfigSchema, MessageSaverPluginType } from "./types";
import { GuildSavedMessages } from "../../data/GuildSavedMessages";
import { PluginOptions } from "knub";
import { MessageCreateEvt, MessageUpdateEvt, MessageDeleteEvt, MessageDeleteBulkEvt } from "./events/SaveMessagesEvts";
import { MessageCreateEvt, MessageDeleteBulkEvt, MessageDeleteEvt, MessageUpdateEvt } from "./events/SaveMessagesEvts";
import { SaveMessagesToDBCmd } from "./commands/SaveMessagesToDB";
import { SavePinsToDBCmd } from "./commands/SavePinsToDB";

View file

@ -1,7 +1,6 @@
import { messageSaverCmd } from "../types";
import { commandTypeHelpers as ct } from "../../../commandTypes";
import { saveMessagesToDB } from "../saveMessagesToDB";
import { TextChannel } from "eris";
import { sendSuccessMessage } from "src/pluginUtils";
export const SaveMessagesToDBCmd = messageSaverCmd({

View file

@ -1,6 +1,6 @@
import { MessageSaverPluginType } from "./types";
import { PluginData } from "knub";
import { TextChannel, Message } from "eris";
import { Message, TextChannel } from "eris";
export async function saveMessagesToDB(
pluginData: PluginData<MessageSaverPluginType>,

View file

@ -1,6 +1,5 @@
import { command } from "knub";
import { MutesPluginType } from "../types";
import { User } from "eris";
import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
import { commandTypeHelpers as ct } from "../../../commandTypes";

View file

@ -1,6 +1,5 @@
import { command } from "knub";
import { MutesPluginType } from "../types";
import { User } from "eris";
import { sendSuccessMessage } from "../../../pluginUtils";
import { resolveMember } from "../../../utils";

View file

@ -2,14 +2,7 @@ import { PluginData } from "knub";
import { MuteOptions, MutesPluginType } from "../types";
import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError";
import humanizeDuration from "humanize-duration";
import {
notifyUser,
resolveMember,
resolveUser,
stripObjectToScalars,
ucfirst,
UserNotificationResult,
} from "../../../utils";
import { notifyUser, resolveUser, stripObjectToScalars, ucfirst, UserNotificationResult } from "../../../utils";
import { renderTemplate } from "../../../templateFormatter";
import { TextChannel, User } from "eris";
import { CasesPlugin } from "../../Cases/CasesPlugin";

View file

@ -8,8 +8,8 @@ import { GuildLogs } from "../../data/GuildLogs";
import { GuildCases } from "../../data/GuildCases";
import { GuildArchives } from "../../data/GuildArchives";
import { GuildMutes } from "../../data/GuildMutes";
import Timeout = NodeJS.Timeout;
import { CaseArgs } from "../Cases/types";
import Timeout = NodeJS.Timeout;
export const ConfigSchema = t.type({
mute_role: tNullable(t.string),

View file

@ -1,5 +1,5 @@
import { PluginOptions } from "knub";
import { NameHistoryPluginType, ConfigSchema } from "./types";
import { ConfigSchema, NameHistoryPluginType } from "./types";
import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
import { GuildNicknameHistory } from "src/data/GuildNicknameHistory";
import { UsernameHistory } from "src/data/UsernameHistory";

View file

@ -1,6 +1,6 @@
import { nameHistoryCmd } from "../types";
import { commandTypeHelpers as ct } from "../../../commandTypes";
import { disableCodeBlocks, createChunkedMessage } from "knub/dist/helpers";
import { createChunkedMessage, disableCodeBlocks } from "knub/dist/helpers";
import { NICKNAME_RETENTION_PERIOD } from "src/data/cleanup/nicknames";
import { DAYS } from "src/utils";
import { MAX_NICKNAME_ENTRIES_PER_USER } from "src/data/GuildNicknameHistory";

View file

@ -1,6 +1,6 @@
import { PluginOptions } from "knub";
import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
import { PersistPluginType, ConfigSchema } from "./types";
import { ConfigSchema, PersistPluginType } from "./types";
import { GuildPersistedData } from "src/data/GuildPersistedData";
import { GuildLogs } from "src/data/GuildLogs";
import { StoreDataEvt } from "./events/StoreDataEvt";

View file

@ -1,10 +1,10 @@
import { PluginOptions } from "knub";
import { PingableRolesPluginType, ConfigSchema } from "./types";
import { ConfigSchema, PingableRolesPluginType } from "./types";
import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
import { GuildPingableRoles } from "src/data/GuildPingableRoles";
import { PingableRoleEnableCmd } from "./commands/PingableRoleEnableCmd";
import { PingableRoleDisableCmd } from "./commands/PingableRoleDisableCmd";
import { TypingEnablePingableEvt, MessageCreateDisablePingableEvt } from "./events/ChangePingableEvts";
import { MessageCreateDisablePingableEvt, TypingEnablePingableEvt } from "./events/ChangePingableEvts";
const defaultOptions: PluginOptions<PingableRolesPluginType> = {
config: {

View file

@ -1,5 +1,5 @@
import * as t from "io-ts";
import { BasePluginType, eventListener, command } from "knub";
import { BasePluginType, command, eventListener } from "knub";
import { GuildPingableRoles } from "src/data/GuildPingableRoles";
import { PingableRole } from "src/data/entities/PingableRole";

View file

@ -45,7 +45,8 @@ export const RemindCmd = remindersCommand({
return;
}
const reminderBody = args.reminder || `https://discord.com/channels/${this.guildId}/${msg.channel.id}/${msg.id}`;
const reminderBody =
args.reminder || `https://discord.com/channels/${pluginData.guild.id}/${msg.channel.id}/${msg.id}`;
await pluginData.state.reminders.add(
msg.author.id,
msg.channel.id,

View file

@ -1,6 +1,6 @@
import { remindersCommand } from "../types";
import { sendErrorMessage } from "src/pluginUtils";
import { sorter, createChunkedMessage } from "src/utils";
import { createChunkedMessage, sorter } from "src/utils";
import moment from "moment-timezone";
import humanizeDuration from "humanize-duration";

View file

@ -21,12 +21,12 @@ export const ContextCmd = utilityCmd({
return;
}
const previousMessage = (await this.bot.getMessages(args.channel.id, 1, args.messageId))[0];
const previousMessage = (await pluginData.client.getMessages(args.channel.id, 1, args.messageId))[0];
if (!previousMessage) {
sendErrorMessage(pluginData, msg.channel, "Message context not found");
return;
}
msg.channel.createMessage(messageLink(this.guildId, previousMessage.channel.id, previousMessage.id));
msg.channel.createMessage(messageLink(pluginData.guild.id, previousMessage.channel.id, previousMessage.id));
},
});

View file

@ -18,7 +18,7 @@ export const HelpCmd = utilityCmd({
const searchStr = args.command.toLowerCase();
const matchingCommands: Array<{
plugin: LoadedPlugin;
plugin: LoadedPlugin<any>;
command: PluginCommandDefinition;
}> = [];
@ -62,12 +62,10 @@ export const HelpCmd = utilityCmd({
.toLowerCase()
.replace(/\s/g, "-");
const pluginName = plugin.blueprint?.name || plugin.class?.pluginName;
let snippet = `**${prefix}${trigger}**`;
if (description) snippet += `\n${description}`;
if (usage) snippet += `\nBasic usage: \`${usage}\``;
snippet += `\n<https://zeppelin.gg/docs/plugins/${pluginName}/usage#command-${commandSlug}>`;
snippet += `\n<https://zeppelin.gg/docs/plugins/${plugin.blueprint.name}/usage#command-${commandSlug}>`;
return snippet;
});

View file

@ -1,6 +1,6 @@
import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
import { PluginOptions } from "knub";
import { WelcomeMessagePluginType, ConfigSchema } from "./types";
import { ConfigSchema, WelcomeMessagePluginType } from "./types";
import { GuildLogs } from "src/data/GuildLogs";
import { SendWelcomeMessageEvt } from "./events/SendWelcomeMessageEvt";

View file

@ -1,6 +1,6 @@
import { welcomeEvent } from "../types";
import { renderTemplate } from "src/templateFormatter";
import { stripObjectToScalars, createChunkedMessage } from "src/utils";
import { createChunkedMessage, stripObjectToScalars } from "src/utils";
import { LogType } from "src/data/LogType";
import { TextChannel } from "eris";

View file

@ -1,7 +1,3 @@
import { ZeppelinPluginClass } from "./ZeppelinPluginClass";
import { ZeppelinPluginBlueprint } from "./ZeppelinPluginBlueprint";
// prettier-ignore
export type ZeppelinPlugin =
| typeof ZeppelinPluginClass
| ZeppelinPluginBlueprint<any>;
export type ZeppelinPlugin = ZeppelinPluginBlueprint<any>;

View file

@ -1,6 +1,6 @@
import { BasePluginType, plugin, PluginBlueprint } from "knub";
import * as t from "io-ts";
import { pluginConfigPreprocessor } from "../pluginUtils";
import { getPluginConfigPreprocessor } from "../pluginUtils";
export interface ZeppelinPluginBlueprint<TPluginType extends BasePluginType = BasePluginType>
extends PluginBlueprint<TPluginType> {
@ -23,7 +23,7 @@ export function zeppelinPlugin<TPluginType extends BasePluginType>(): <
export function zeppelinPlugin(...args) {
if (args.length) {
const blueprint: ZeppelinPluginBlueprint = plugin(...(args as Parameters<typeof plugin>));
blueprint.configPreprocessor = pluginConfigPreprocessor.bind(blueprint);
blueprint.configPreprocessor = getPluginConfigPreprocessor(blueprint);
return blueprint;
} else {
return zeppelinPlugin;

View file

@ -1,16 +0,0 @@
import { BasePluginType, PluginClass, PluginOptions } from "knub";
import * as t from "io-ts";
import { TZeppelinKnub, ZeppelinPluginInfo } from "../types";
import { pluginConfigPreprocessor } from "../pluginUtils";
export class ZeppelinPluginClass<TPluginType extends BasePluginType = BasePluginType> extends PluginClass<TPluginType> {
public static pluginInfo: ZeppelinPluginInfo;
public static showInDocs: boolean = true;
public static configSchema: t.TypeC<any>;
protected readonly knub: TZeppelinKnub;
public static configPreprocessor(options: PluginOptions<any>) {
return pluginConfigPreprocessor.bind(this)(options);
}
}

View file

@ -1,4 +1,4 @@
import { has, get } from "./utils";
import { get, has } from "./utils";
import seedrandom from "seedrandom";
const TEMPLATE_CACHE_SIZE = 200;

View file

@ -23,19 +23,17 @@ import emojiRegex from "emoji-regex";
import * as t from "io-ts";
import fs from "fs";
const fsp = fs.promises;
import https from "https";
import tmp from "tmp";
import { logger, helpers } from "knub";
import { helpers } from "knub";
import { SavedMessage } from "./data/entities/SavedMessage";
import { decodeAndValidateStrict, StrictValidationError } from "./validatorUtils";
import { either } from "fp-ts/lib/Either";
import safeRegex from "safe-regex";
import moment from "moment-timezone";
import { performance } from "perf_hooks";
import { ERRORS } from "./RecoverablePluginError";
import { SimpleCache } from "./SimpleCache";
import { logger } from "./logger";
const fsp = fs.promises;
const delayStringMultipliers = {
w: 1000 * 60 * 60 * 24 * 7,
@ -946,9 +944,9 @@ export function resolveUserId(bot: Client, value: string) {
* Finds a matching User for the passed user id, user mention, or full username (with discriminator).
* If a user is not found, returns an UnknownUser instead.
*/
export function getUser(userResolvable: string): User | UnknownUser {
const id = resolveUserId(this.client, userResolvable);
return id ? this.client.users.get(id) || new UnknownUser({ id }) : new UnknownUser();
export function getUser(client: Client, userResolvable: string): User | UnknownUser {
const id = resolveUserId(client, userResolvable);
return id ? client.users.get(id) || new UnknownUser({ id }) : new UnknownUser();
}
/**
@ -1058,12 +1056,12 @@ export async function resolveRoleId(bot: Client, guildId: string, value: string)
const inviteCache = new SimpleCache<Promise<ChannelInvite>>(10 * MINUTES, 200);
export async function resolveInvite(code: string): Promise<ChannelInvite | null> {
export async function resolveInvite(client: Client, code: string): Promise<ChannelInvite | null> {
if (inviteCache.has(code)) {
return inviteCache.get(code);
}
const promise = this.client.getInvite(code).catch(() => null);
const promise = client.getInvite(code).catch(() => null);
inviteCache.set(code, promise);
return promise;

View file

@ -2,7 +2,6 @@ import { tDeepPartial } from "./utils";
import * as t from "io-ts";
import * as validatorUtils from "./validatorUtils";
import test from "ava";
import util from "util";
test("tDeepPartial works", ava => {
const originalSchema = t.type({

View file

@ -1,6 +1,6 @@
import * as t from "io-ts";
import { pipe } from "fp-ts/lib/pipeable";
import { fold, either } from "fp-ts/lib/Either";
import { either, fold } from "fp-ts/lib/Either";
import { noop } from "./utils";
import deepDiff from "deep-diff";
import safeRegex from "safe-regex";