3
0
Fork 0
mirror of https://github.com/ZeppelinBot/Zeppelin.git synced 2025-05-10 12:25:02 +00:00

More documentation work

This commit is contained in:
Dragory 2019-08-22 02:58:32 +03:00
parent 5bbc318c68
commit 1681a45069
33 changed files with 286 additions and 57 deletions

View file

@ -3,9 +3,58 @@ import { availablePlugins } from "../plugins/availablePlugins";
import { ZeppelinPlugin } from "../plugins/ZeppelinPlugin";
import { notFound } from "./responses";
import { CommandManager, ICommandConfig } from "knub/dist/CommandManager";
import { dropPropertiesByName, indentLines } from "../utils";
const commandManager = new CommandManager();
function formatConfigSchema(schema) {
if (schema._tag === "InterfaceType" || schema._tag === "PartialType") {
return (
`{\n` +
Object.entries(schema.props)
.map(([k, value]) => indentLines(`${k}: ${formatConfigSchema(value)}`, 2))
.join("\n") +
"\n}"
);
} else if (schema._tag === "DictionaryType") {
return "{\n" + indentLines(`[string]: ${formatConfigSchema(schema.codomain)}`, 2) + "\n}";
} else {
return schema.name;
}
}
function formatTypeName(typeName) {
let result = "";
let indent = 0;
let skip = false;
for (const char of [...typeName]) {
if (skip) {
skip = false;
continue;
}
if (char === "}") {
result += "\n";
indent--;
skip = true;
}
result += char;
if (char === "{") {
result += "\n";
indent++;
skip = true;
}
if (char === ",") {
result += "\n";
skip = true;
}
}
return result;
}
export function initDocs(app: express.Express) {
const docsPlugins = availablePlugins.filter(pluginClass => pluginClass.showInDocs);
@ -60,9 +109,12 @@ export function initDocs(app: express.Express) {
const options = (pluginClass as typeof ZeppelinPlugin).getStaticDefaultOptions();
const configSchema = pluginClass.configSchema && formatConfigSchema(pluginClass.configSchema);
res.json({
name: pluginClass.pluginName,
info: pluginClass.pluginInfo || {},
configSchema,
options,
commands,
});

View file

@ -4,7 +4,7 @@ import { SavedMessage } from "../data/entities/SavedMessage";
import { GuildAutoReactions } from "../data/GuildAutoReactions";
import { Message } from "eris";
import { customEmojiRegex, errorMessage, isEmoji, successMessage } from "../utils";
import { ZeppelinPlugin } from "./ZeppelinPlugin";
import { trimPluginDescription, ZeppelinPlugin } from "./ZeppelinPlugin";
import * as t from "io-ts";
const ConfigSchema = t.type({
@ -14,7 +14,14 @@ type TConfigSchema = t.TypeOf<typeof ConfigSchema>;
export class AutoReactionsPlugin extends ZeppelinPlugin<TConfigSchema> {
public static pluginName = "auto_reactions";
protected static configSchema = ConfigSchema;
public static configSchema = ConfigSchema;
public static pluginInfo = {
prettyName: "Auto-reactions",
description: trimPluginDescription(`
Allows setting up automatic reactions to all new messages on a channel
`),
};
protected savedMessages: GuildSavedMessages;
protected autoReactions: GuildAutoReactions;

View file

@ -309,7 +309,7 @@ const inviteCache = new SimpleCache(10 * MINUTES);
export class AutomodPlugin extends ZeppelinPlugin<TConfigSchema> {
public static pluginName = "automod";
protected static configSchema = ConfigSchema;
public static configSchema = ConfigSchema;
public static dependencies = ["mod_actions", "mutes"];
protected unloaded = false;

View file

@ -23,7 +23,7 @@ type TConfigSchema = t.TypeOf<typeof ConfigSchema>;
*/
export class BotControlPlugin extends GlobalZeppelinPlugin<TConfigSchema> {
public static pluginName = "bot_control";
protected static configSchema = ConfigSchema;
public static configSchema = ConfigSchema;
protected archives: GuildArchives;

View file

@ -4,7 +4,7 @@ import { CaseTypes } from "../data/CaseTypes";
import { Case } from "../data/entities/Case";
import moment from "moment-timezone";
import { CaseTypeColors } from "../data/CaseTypeColors";
import { ZeppelinPlugin } from "./ZeppelinPlugin";
import { trimPluginDescription, ZeppelinPlugin } from "./ZeppelinPlugin";
import { GuildArchives } from "../data/GuildArchives";
import { IPluginOptions } from "knub";
import { GuildLogs } from "../data/GuildLogs";
@ -45,7 +45,14 @@ export type CaseNoteArgs = {
export class CasesPlugin extends ZeppelinPlugin<TConfigSchema> {
public static pluginName = "cases";
protected static configSchema = ConfigSchema;
public static configSchema = ConfigSchema;
public static pluginInfo = {
prettyName: "Cases",
description: trimPluginDescription(`
This plugin contains basic configuration for cases created by other plugins
`),
};
protected cases: GuildCases;
protected archives: GuildArchives;

View file

@ -14,7 +14,7 @@ import {
import { ZalgoRegex } from "../data/Zalgo";
import { GuildSavedMessages } from "../data/GuildSavedMessages";
import { SavedMessage } from "../data/entities/SavedMessage";
import { ZeppelinPlugin } from "./ZeppelinPlugin";
import { trimPluginDescription, ZeppelinPlugin } from "./ZeppelinPlugin";
import cloneDeep from "lodash.clonedeep";
import * as t from "io-ts";
import { TSafeRegex } from "../validatorUtils";
@ -38,7 +38,14 @@ type TConfigSchema = t.TypeOf<typeof ConfigSchema>;
export class CensorPlugin extends ZeppelinPlugin<TConfigSchema> {
public static pluginName = "censor";
protected static configSchema = ConfigSchema;
public static configSchema = ConfigSchema;
public static pluginInfo = {
prettyName: "Censor",
description: trimPluginDescription(`
Censor words, tokens, links, regex, etc.
`),
};
protected serverLogs: GuildLogs;
protected savedMessages: GuildSavedMessages;

View file

@ -15,6 +15,7 @@ const MAX_ATTACHMENT_REHOST_SIZE = 1024 * 1024 * 8;
export class ChannelArchiverPlugin extends ZeppelinPlugin {
public static pluginName = "channel_archiver";
public static showInDocs = false;
protected isOwner(userId) {
const owners = this.knub.getGlobalConfig().owners || [];

View file

@ -1,5 +1,5 @@
import { decorators as d, IPluginOptions, logger } from "knub";
import { ZeppelinPlugin } from "./ZeppelinPlugin";
import { trimPluginDescription, ZeppelinPlugin } from "./ZeppelinPlugin";
import { Member, Channel, GuildChannel, PermissionOverwrite, Permission, Message, TextChannel } from "eris";
import * as t from "io-ts";
import { tNullable } from "../utils";
@ -28,7 +28,16 @@ const defaultCompanionChannelOpts: Partial<TCompanionChannelOpts> = {
export class CompanionChannelPlugin extends ZeppelinPlugin<TConfigSchema> {
public static pluginName = "companion_channels";
protected static configSchema = ConfigSchema;
public static configSchema = ConfigSchema;
public static pluginInfo = {
prettyName: "Companion channels",
description: trimPluginDescription(`
Set up 'companion channels' between text and voice channels.
Once set up, any time a user joins one of the specified voice channels,
they'll get channel permissions applied to them for the text channels.
`),
};
public static getStaticDefaultOptions(): IPluginOptions<TConfigSchema> {
return {

View file

@ -72,7 +72,7 @@ export class CustomEventsPlugin extends ZeppelinPlugin<TConfigSchema> {
public static pluginName = "custom_events";
public static showInDocs = false;
public static dependencies = ["cases"];
protected static configSchema = ConfigSchema;
public static configSchema = ConfigSchema;
private clearTriggers: () => void;

View file

@ -13,7 +13,7 @@ import { mergeConfig } from "knub/dist/configUtils";
const SLOW_RESOLVE_THRESHOLD = 1500;
export class GlobalZeppelinPlugin<TConfig extends {} = IBasePluginConfig> extends GlobalPlugin<TConfig> {
protected static configSchema: t.TypeC<any>;
public static configSchema: t.TypeC<any>;
public static dependencies = [];
/**

View file

@ -1,5 +1,5 @@
import { decorators as d, IPluginOptions, getInviteLink, logger } from "knub";
import { ZeppelinPlugin } from "./ZeppelinPlugin";
import { trimPluginDescription, ZeppelinPlugin } from "./ZeppelinPlugin";
import humanizeDuration from "humanize-duration";
import { Message, Member, Guild, TextableChannel, VoiceChannel, Channel, User } from "eris";
import { GuildVCAlerts } from "../data/GuildVCAlerts";
@ -17,7 +17,16 @@ const ALERT_LOOP_TIME = 30 * 1000;
export class LocatePlugin extends ZeppelinPlugin<TConfigSchema> {
public static pluginName = "locate_user";
protected static configSchema = ConfigSchema;
public static configSchema = ConfigSchema;
public static pluginInfo = {
prettyName: "Locate user",
description: trimPluginDescription(`
This plugin allows users with access to the commands the following:
* Instantly receive an invite to the voice channel of a user
* Be notified as soon as a user switches or joins a voice channel
`),
};
private alerts: GuildVCAlerts;
private outdatedAlertsTimeout;
@ -68,7 +77,11 @@ export class LocatePlugin extends ZeppelinPlugin<TConfigSchema> {
});
}
@d.command("where", "<member:resolvedMember>", {})
@d.command("where", "<member:resolvedMember>", {
info: {
description: "Posts an instant invite to the voice channel that `<member>` is in",
},
})
@d.permission("can_where")
async whereCmd(msg: Message, args: { member: Member; time?: number; reminder?: string }) {
const member = await resolveMember(this.bot, this.guild, args.member.id);
@ -77,6 +90,9 @@ export class LocatePlugin extends ZeppelinPlugin<TConfigSchema> {
@d.command("vcalert", "<member:resolvedMember> [duration:delay] [reminder:string$]", {
aliases: ["vca"],
info: {
description: "Sets up an alert that notifies you any time `<member>` switches or joins voice channels",
},
})
@d.permission("can_alert")
async vcalertCmd(msg: Message, args: { member: Member; duration?: number; reminder?: string }) {

View file

@ -22,7 +22,7 @@ import { GuildSavedMessages } from "../data/GuildSavedMessages";
import { SavedMessage } from "../data/entities/SavedMessage";
import { GuildArchives } from "../data/GuildArchives";
import { GuildCases } from "../data/GuildCases";
import { ZeppelinPlugin } from "./ZeppelinPlugin";
import { trimPluginDescription, ZeppelinPlugin } from "./ZeppelinPlugin";
import { renderTemplate, TemplateParseError } from "../templateFormatter";
import cloneDeep from "lodash.clonedeep";
import * as t from "io-ts";
@ -53,7 +53,11 @@ type TConfigSchema = t.TypeOf<typeof ConfigSchema>;
export class LogsPlugin extends ZeppelinPlugin<TConfigSchema> {
public static pluginName = "logs";
protected static configSchema = ConfigSchema;
public static configSchema = ConfigSchema;
public static pluginInfo = {
prettyName: "Logs",
};
protected guildLogs: GuildLogs;
protected savedMessages: GuildSavedMessages;

View file

@ -13,7 +13,7 @@ type TConfigSchema = t.TypeOf<typeof ConfigSchema>;
export class MessageSaverPlugin extends ZeppelinPlugin<TConfigSchema> {
public static pluginName = "message_saver";
public static showInDocs = false;
protected static configSchema = ConfigSchema;
public static configSchema = ConfigSchema;
protected savedMessages: GuildSavedMessages;

View file

@ -26,7 +26,7 @@ import { GuildMutes } from "../data/GuildMutes";
import { CaseTypes } from "../data/CaseTypes";
import { GuildLogs } from "../data/GuildLogs";
import { LogType } from "../data/LogType";
import { ZeppelinPlugin } from "./ZeppelinPlugin";
import { trimPluginDescription, ZeppelinPlugin } from "./ZeppelinPlugin";
import { Case } from "../data/entities/Case";
import { renderTemplate } from "../templateFormatter";
import { CaseArgs, CasesPlugin } from "./Cases";
@ -108,18 +108,13 @@ type WarnMemberNotifyRetryCallback = () => boolean | Promise<boolean>;
export class ModActionsPlugin extends ZeppelinPlugin<TConfigSchema> {
public static pluginName = "mod_actions";
public static dependencies = ["cases", "mutes"];
protected static configSchema = ConfigSchema;
public static configSchema = ConfigSchema;
public static pluginInfo = {
prettyName: "Mod actions",
description: trimIndents(
trimEmptyStartEndLines(`
Testing **things**
Multiline haHAA
description: trimPluginDescription(`
This plugin contains the 'typical' mod actions such as warning, muting, kicking, banning, etc.
`),
6,
),
};
protected mutes: GuildMutes;

View file

@ -64,7 +64,11 @@ const FIRST_CHECK_INCREMENT = 5 * 1000;
export class MutesPlugin extends ZeppelinPlugin<TConfigSchema> {
public static pluginName = "mutes";
protected static configSchema = ConfigSchema;
public static configSchema = ConfigSchema;
public static pluginInfo = {
prettyName: "Mutes",
};
protected mutes: GuildMutes;
protected cases: GuildCases;

View file

@ -14,7 +14,7 @@ type TConfigSchema = t.TypeOf<typeof ConfigSchema>;
export class NameHistoryPlugin extends ZeppelinPlugin<TConfigSchema> {
public static pluginName = "name_history";
public static showInDocs = false;
protected static configSchema = ConfigSchema;
public static configSchema = ConfigSchema;
protected nicknameHistory: GuildNicknameHistory;
protected usernameHistory: UsernameHistory;

View file

@ -17,7 +17,11 @@ type TConfigSchema = t.TypeOf<typeof ConfigSchema>;
export class PersistPlugin extends ZeppelinPlugin<TConfigSchema> {
public static pluginName = "persist";
protected static configSchema = ConfigSchema;
public static configSchema = ConfigSchema;
public static pluginInfo = {
prettyName: "Persist",
};
protected persistedData: GuildPersistedData;
protected logs: GuildLogs;

View file

@ -15,7 +15,11 @@ const TIMEOUT = 10 * 1000;
export class PingableRolesPlugin extends ZeppelinPlugin<TConfigSchema> {
public static pluginName = "pingable_roles";
protected static configSchema = ConfigSchema;
public static configSchema = ConfigSchema;
public static pluginInfo = {
prettyName: "Pingable roles",
};
protected pingableRoles: GuildPingableRoles;
protected cache: Map<string, PingableRole[]>;

View file

@ -38,7 +38,11 @@ const SCHEDULED_POST_PREVIEW_TEXT_LENGTH = 50;
export class PostPlugin extends ZeppelinPlugin<TConfigSchema> {
public static pluginName = "post";
protected static configSchema = ConfigSchema;
public static configSchema = ConfigSchema;
public static pluginInfo = {
prettyName: "Post",
};
protected savedMessages: GuildSavedMessages;
protected scheduledPosts: GuildScheduledPosts;

View file

@ -44,7 +44,11 @@ type PendingMemberRoleChanges = {
export class ReactionRolesPlugin extends ZeppelinPlugin<TConfigSchema> {
public static pluginName = "reaction_roles";
protected static configSchema = ConfigSchema;
public static configSchema = ConfigSchema;
public static pluginInfo = {
prettyName: "Reaction roles",
};
protected reactionRoles: GuildReactionRoles;
protected savedMessages: GuildSavedMessages;

View file

@ -24,7 +24,11 @@ const MAX_TRIES = 3;
export class RemindersPlugin extends ZeppelinPlugin<TConfigSchema> {
public static pluginName = "reminders";
protected static configSchema = ConfigSchema;
public static configSchema = ConfigSchema;
public static pluginInfo = {
prettyName: "Reminders",
};
protected reminders: GuildReminders;
protected tries: Map<number, number>;

View file

@ -15,7 +15,7 @@ type TConfigSchema = t.TypeOf<typeof ConfigSchema>;
export class SelfGrantableRolesPlugin extends ZeppelinPlugin<TConfigSchema> {
public static pluginName = "self_grantable_roles";
public static showInDocs = false;
protected static configSchema = ConfigSchema;
public static configSchema = ConfigSchema;
protected selfGrantableRoles: GuildSelfGrantableRoles;

View file

@ -33,7 +33,11 @@ const BOT_SLOWMODE_CLEAR_INTERVAL = 60 * 1000;
export class SlowmodePlugin extends ZeppelinPlugin<TConfigSchema> {
public static pluginName = "slowmode";
protected static configSchema = ConfigSchema;
public static configSchema = ConfigSchema;
public static pluginInfo = {
prettyName: "Slowmode",
};
protected slowmodes: GuildSlowmodes;
protected savedMessages: GuildSavedMessages;

View file

@ -74,7 +74,11 @@ const SPAM_ARCHIVE_EXPIRY_DAYS = 90;
export class SpamPlugin extends ZeppelinPlugin<TConfigSchema> {
public static pluginName = "spam";
protected static configSchema = ConfigSchema;
public static configSchema = ConfigSchema;
public static pluginInfo = {
prettyName: "Spam protection",
};
protected logs: GuildLogs;
protected archives: GuildArchives;

View file

@ -26,7 +26,7 @@ type TConfigSchema = t.TypeOf<typeof ConfigSchema>;
export class StarboardPlugin extends ZeppelinPlugin<TConfigSchema> {
public static pluginName = "starboard";
public static showInDocs = false;
protected static configSchema = ConfigSchema;
public static configSchema = ConfigSchema;
protected starboards: GuildStarboards;
protected savedMessages: GuildSavedMessages;

View file

@ -23,7 +23,11 @@ type TConfigSchema = t.TypeOf<typeof ConfigSchema>;
export class TagsPlugin extends ZeppelinPlugin<TConfigSchema> {
public static pluginName = "tags";
protected static configSchema = ConfigSchema;
public static configSchema = ConfigSchema;
public static pluginInfo = {
prettyName: "Tags",
};
protected archives: GuildArchives;
protected tags: GuildTags;

View file

@ -82,7 +82,11 @@ type MemberSearchParams = {
export class UtilityPlugin extends ZeppelinPlugin<TConfigSchema> {
public static pluginName = "utility";
protected static configSchema = ConfigSchema;
public static configSchema = ConfigSchema;
public static pluginInfo = {
prettyName: "Utility",
};
protected logs: GuildLogs;
protected cases: GuildCases;
@ -698,7 +702,9 @@ export class UtilityPlugin extends ZeppelinPlugin<TConfigSchema> {
msg.channel.createMessage({ embed });
}
@d.command(/(?:nickname|nick) reset/, "<member:resolvedMember>")
@d.command("nickname reset", "<member:resolvedMember>", {
aliases: ["nick reset"],
})
@d.permission("can_nickname")
async nicknameResetCmd(msg: Message, args: { member: Member }) {
if (msg.member.id !== args.member.id && !this.canActOn(msg.member, args.member)) {
@ -718,7 +724,9 @@ export class UtilityPlugin extends ZeppelinPlugin<TConfigSchema> {
msg.channel.createMessage(successMessage(`The nickname of <@!${args.member.id}> has been reset`));
}
@d.command(/nickname|nick/, "<member:resolvedMember> <nickname:string$>")
@d.command("nickname", "<member:resolvedMember> <nickname:string$>", {
aliases: ["nick"],
})
@d.permission("can_nickname")
async nicknameCmd(msg: Message, args: { member: Member; nickname: string }) {
if (msg.member.id !== args.member.id && !this.canActOn(msg.member, args.member)) {

View file

@ -16,11 +16,15 @@ type TConfigSchema = t.TypeOf<typeof ConfigSchema>;
export class WelcomeMessagePlugin extends ZeppelinPlugin<TConfigSchema> {
public static pluginName = "welcome_message";
protected static configSchema = ConfigSchema;
public static configSchema = ConfigSchema;
public static pluginInfo = {
prettyName: "Welcome message",
};
protected logs: GuildLogs;
protected getDefaultOptions(): IPluginOptions<TConfigSchema> {
public static getStaticDefaultOptions(): IPluginOptions<TConfigSchema> {
return {
config: {
send_dm: false,

View file

@ -11,6 +11,8 @@ import {
resolveMember,
resolveUser,
resolveUserId,
trimEmptyStartEndLines,
trimIndents,
UnknownUser,
} from "../utils";
import { Member, User } from "eris";
@ -34,11 +36,15 @@ export interface CommandInfo {
};
}
export function trimPluginDescription(str) {
return trimIndents(trimEmptyStartEndLines(str), 6);
}
export class ZeppelinPlugin<TConfig extends {} = IBasePluginConfig> extends Plugin<TConfig> {
public static pluginInfo: PluginInfo;
public static showInDocs: boolean = true;
protected static configSchema: t.TypeC<any>;
public static configSchema: t.TypeC<any>;
public static dependencies = [];
protected throwPluginRuntimeError(message: string) {

View file

@ -39,7 +39,16 @@ export const HOURS = 60 * MINUTES;
export const DAYS = 24 * HOURS;
export function tNullable<T extends t.Type<any, any, unknown>>(type: T) {
return t.union([type, t.undefined, t.null]);
return t.union([type, t.undefined, t.null], type.name);
}
export function dropPropertiesByName(obj, propName) {
if (obj.hasOwnProperty(propName)) delete obj[propName];
for (const value of Object.values(obj)) {
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
dropPropertiesByName(value, propName);
}
}
}
/**
@ -275,6 +284,17 @@ export function trimIndents(str: string, indentLength: number) {
.join("\n");
}
export function indentLine(str: string, indentLength: number) {
return " ".repeat(indentLength) + str;
}
export function indentLines(str: string, indentLength: number) {
return str
.split("\n")
.map(line => indentLine(line, indentLength))
.join("\n");
}
export const emptyEmbedValue = "\u200b";
export const embedPadding = "\n" + emptyEmbedValue;