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

Update djs & knub (#395)

* update pkgs

Signed-off-by: GitHub <noreply@github.com>

* new knub typings

Signed-off-by: GitHub <noreply@github.com>

* more pkg updates

Signed-off-by: GitHub <noreply@github.com>

* more fixes

Signed-off-by: GitHub <noreply@github.com>

* channel typings

Signed-off-by: GitHub <noreply@github.com>

* more message utils typings fixes

Signed-off-by: GitHub <noreply@github.com>

* migrate permissions

Signed-off-by: GitHub <noreply@github.com>

* fix: InternalPoster webhookables

Signed-off-by: GitHub <noreply@github.com>

* djs typings: Attachment & Util

Signed-off-by: GitHub <noreply@github.com>

* more typings

Signed-off-by: GitHub <noreply@github.com>

* fix: rename permissionNames

Signed-off-by: GitHub <noreply@github.com>

* more fixes

Signed-off-by: GitHub <noreply@github.com>

* half the number of errors

* knub commands => messageCommands

Signed-off-by: GitHub <noreply@github.com>

* configPreprocessor => configParser

Signed-off-by: GitHub <noreply@github.com>

* fix channel.messages

Signed-off-by: GitHub <noreply@github.com>

* revert automod any typing

Signed-off-by: GitHub <noreply@github.com>

* more configParser typings

Signed-off-by: GitHub <noreply@github.com>

* revert

Signed-off-by: GitHub <noreply@github.com>

* remove knub type params

Signed-off-by: GitHub <noreply@github.com>

* fix more MessageEmbed / MessageOptions

Signed-off-by: GitHub <noreply@github.com>

* dumb commit for @almeidx to see why this is stupid

Signed-off-by: GitHub <noreply@github.com>

* temp disable custom_events

Signed-off-by: GitHub <noreply@github.com>

* more minor typings fixes - 23 err left

Signed-off-by: GitHub <noreply@github.com>

* update djs dep

* +debug build method (revert this)

Signed-off-by: GitHub <noreply@github.com>

* Revert "+debug build method (revert this)"

This reverts commit a80af1e729.

* Redo +debug build (Revert this)

Signed-off-by: GitHub <noreply@github.com>

* uniform before/after Load shorthands

Signed-off-by: GitHub <noreply@github.com>

* remove unused imports & add prettier plugin

Signed-off-by: GitHub <noreply@github.com>

* env fixes for web platform hosting

Signed-off-by: GitHub <noreply@github.com>

* feat: knub v32-next; related fixes

* fix: allow legacy keys in change_perms action

* fix: request Message Content intent

* fix: use Knub's config validation logic in API

* fix(dashboard): fix error when there are no message and/or slash commands in a plugin

* fix(automod): start_thread action thread options

* fix(CustomEvents): message command types

* chore: remove unneeded type annotation

* feat: add forum channel icon; use thread icon for news threads

* chore: make tslint happy

* chore: fix formatting

---------

Signed-off-by: GitHub <noreply@github.com>
Co-authored-by: almeidx <almeidx@pm.me>
Co-authored-by: Dragory <2606411+Dragory@users.noreply.github.com>
This commit is contained in:
Tiago R 2023-04-01 12:58:17 +01:00 committed by GitHub
parent 293115af22
commit 06877e90cc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
476 changed files with 2965 additions and 3251 deletions

View file

@ -1,6 +1,6 @@
import { EventEmitter } from "events";
import * as t from "io-ts";
import { PluginOptions } from "knub";
import { ConfigPreprocessorFn } from "knub/dist/config/configTypes";
import {
buildCounterConditionString,
CounterTrigger,
@ -10,7 +10,7 @@ import {
import { GuildCounters } from "../../data/GuildCounters";
import { mapToPublicFn } from "../../pluginUtils";
import { convertDelayStringToMS, MINUTES } from "../../utils";
import { StrictValidationError } from "../../validatorUtils";
import { StrictValidationError, validate } from "../../validatorUtils";
import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
import { AddCounterCmd } from "./commands/AddCounterCmd";
import { CountersListCmd } from "./commands/CountersListCmd";
@ -55,46 +55,6 @@ const defaultOptions: PluginOptions<CountersPluginType> = {
],
};
const configPreprocessor: ConfigPreprocessorFn<CountersPluginType> = (options) => {
for (const [counterName, counter] of Object.entries(options.config?.counters || {})) {
counter.name = counterName;
counter.per_user = counter.per_user ?? false;
counter.per_channel = counter.per_channel ?? false;
counter.initial_value = counter.initial_value ?? 0;
counter.triggers = counter.triggers || {};
if (Object.values(counter.triggers).length > MAX_TRIGGERS_PER_COUNTER) {
throw new StrictValidationError([`You can only have at most ${MAX_TRIGGERS_PER_COUNTER} triggers per counter`]);
}
// Normalize triggers
for (const [triggerName, trigger] of Object.entries(counter.triggers)) {
const triggerObj: Partial<TTrigger> = typeof trigger === "string" ? { condition: trigger } : trigger;
triggerObj.name = triggerName;
const parsedCondition = parseCounterConditionString(triggerObj.condition || "");
if (!parsedCondition) {
throw new StrictValidationError([
`Invalid comparison in counter trigger ${counterName}/${triggerName}: "${triggerObj.condition}"`,
]);
}
triggerObj.condition = buildCounterConditionString(parsedCondition[0], parsedCondition[1]);
triggerObj.reverse_condition =
triggerObj.reverse_condition ||
buildCounterConditionString(getReverseCounterComparisonOp(parsedCondition[0]), parsedCondition[1]);
counter.triggers[triggerName] = triggerObj as TTrigger;
}
}
if (Object.values(options.config?.counters || {}).length > MAX_COUNTERS) {
throw new StrictValidationError([`You can only have at most ${MAX_COUNTERS} counters`]);
}
return options;
};
/**
* The Counters plugin keeps track of simple integer values that are tied to a user, channel, both, or neither "counters".
* These values can be changed using the functions in the plugin's public interface.
@ -113,11 +73,55 @@ export const CountersPlugin = zeppelinGuildPlugin<CountersPluginType>()({
description:
"Keep track of per-user, per-channel, or global numbers and trigger specific actions based on this number",
configurationGuide: "See <a href='/docs/setup-guides/counters'>Counters setup guide</a>",
configSchema: ConfigSchema,
},
configSchema: ConfigSchema,
defaultOptions,
configPreprocessor,
// TODO: Separate input and output types
configParser: (input) => {
for (const [counterName, counter] of Object.entries<any>((input as any).counters || {})) {
counter.name = counterName;
counter.per_user = counter.per_user ?? false;
counter.per_channel = counter.per_channel ?? false;
counter.initial_value = counter.initial_value ?? 0;
counter.triggers = counter.triggers || {};
if (Object.values(counter.triggers).length > MAX_TRIGGERS_PER_COUNTER) {
throw new StrictValidationError([`You can only have at most ${MAX_TRIGGERS_PER_COUNTER} triggers per counter`]);
}
// Normalize triggers
for (const [triggerName, trigger] of Object.entries(counter.triggers)) {
const triggerObj = (typeof trigger === "string" ? { condition: trigger } : trigger) as Partial<TTrigger>;
triggerObj.name = triggerName;
const parsedCondition = parseCounterConditionString(triggerObj.condition || "");
if (!parsedCondition) {
throw new StrictValidationError([
`Invalid comparison in counter trigger ${counterName}/${triggerName}: "${triggerObj.condition}"`,
]);
}
triggerObj.condition = buildCounterConditionString(parsedCondition[0], parsedCondition[1]);
triggerObj.reverse_condition =
triggerObj.reverse_condition ||
buildCounterConditionString(getReverseCounterComparisonOp(parsedCondition[0]), parsedCondition[1]);
counter.triggers[triggerName] = triggerObj as TTrigger;
}
}
if (Object.values((input as any).counters || {}).length > MAX_COUNTERS) {
throw new StrictValidationError([`You can only have at most ${MAX_COUNTERS} counters`]);
}
const error = validate(ConfigSchema, input);
if (error) {
throw error;
}
return input as t.TypeOf<typeof ConfigSchema>;
},
public: {
counterExists: mapToPublicFn(counterExists),
@ -136,7 +140,7 @@ export const CountersPlugin = zeppelinGuildPlugin<CountersPluginType>()({
},
// prettier-ignore
commands: [
messageCommands: [
CountersListCmd,
ViewCounterCmd,
AddCounterCmd,
@ -146,32 +150,30 @@ export const CountersPlugin = zeppelinGuildPlugin<CountersPluginType>()({
],
async beforeLoad(pluginData) {
pluginData.state.counters = new GuildCounters(pluginData.guild.id);
pluginData.state.events = new EventEmitter();
pluginData.state.counterTriggersByCounterId = new Map();
const { state, guild } = pluginData;
state.counters = new GuildCounters(guild.id);
state.events = new EventEmitter();
state.counterTriggersByCounterId = new Map();
const activeTriggerIds: number[] = [];
// Initialize and store the IDs of each of the counters internally
pluginData.state.counterIds = {};
state.counterIds = {};
const config = pluginData.config.get();
for (const counter of Object.values(config.counters)) {
const dbCounter = await pluginData.state.counters.findOrCreateCounter(
counter.name,
counter.per_channel,
counter.per_user,
);
pluginData.state.counterIds[counter.name] = dbCounter.id;
const dbCounter = await state.counters.findOrCreateCounter(counter.name, counter.per_channel, counter.per_user);
state.counterIds[counter.name] = dbCounter.id;
const thisCounterTriggers: CounterTrigger[] = [];
pluginData.state.counterTriggersByCounterId.set(dbCounter.id, thisCounterTriggers);
state.counterTriggersByCounterId.set(dbCounter.id, thisCounterTriggers);
// Initialize triggers
for (const trigger of Object.values(counter.triggers)) {
const theTrigger = trigger as TTrigger;
const parsedCondition = parseCounterConditionString(theTrigger.condition)!;
const parsedReverseCondition = parseCounterConditionString(theTrigger.reverse_condition)!;
const counterTrigger = await pluginData.state.counters.initCounterTrigger(
const counterTrigger = await state.counters.initCounterTrigger(
dbCounter.id,
theTrigger.name,
parsedCondition[0],
@ -185,17 +187,19 @@ export const CountersPlugin = zeppelinGuildPlugin<CountersPluginType>()({
}
// Mark old/unused counters to be deleted later
await pluginData.state.counters.markUnusedCountersToBeDeleted([...Object.values(pluginData.state.counterIds)]);
await state.counters.markUnusedCountersToBeDeleted([...Object.values(state.counterIds)]);
// Mark old/unused triggers to be deleted later
await pluginData.state.counters.markUnusedTriggersToBeDeleted(activeTriggerIds);
await state.counters.markUnusedTriggersToBeDeleted(activeTriggerIds);
},
async afterLoad(pluginData) {
const { state } = pluginData;
const config = pluginData.config.get();
// Start decay timers
pluginData.state.decayTimers = [];
state.decayTimers = [];
for (const [counterName, counter] of Object.entries(config.counters)) {
if (!counter.decay) {
continue;
@ -207,7 +211,7 @@ export const CountersPlugin = zeppelinGuildPlugin<CountersPluginType>()({
continue;
}
pluginData.state.decayTimers.push(
state.decayTimers.push(
setInterval(() => {
decayCounter(pluginData, counterName, decayPeriodMs, decay.amount);
}, DECAY_APPLY_INTERVAL),
@ -216,12 +220,14 @@ export const CountersPlugin = zeppelinGuildPlugin<CountersPluginType>()({
},
beforeUnload(pluginData) {
if (pluginData.state.decayTimers) {
for (const interval of pluginData.state.decayTimers) {
const { state } = pluginData;
if (state.decayTimers) {
for (const interval of state.decayTimers) {
clearInterval(interval);
}
}
pluginData.state.events.removeAllListeners();
state.events.removeAllListeners();
},
});

View file

@ -1,13 +1,13 @@
import { Snowflake, TextChannel } from "discord.js";
import { typedGuildCommand } from "knub";
import { waitForReply } from "knub/dist/helpers";
import { guildPluginMessageCommand } from "knub";
import { waitForReply } from "knub/helpers";
import { commandTypeHelpers as ct } from "../../../commandTypes";
import { sendErrorMessage } from "../../../pluginUtils";
import { resolveUser, UnknownUser } from "../../../utils";
import { changeCounterValue } from "../functions/changeCounterValue";
import { CountersPluginType } from "../types";
export const AddCounterCmd = typedGuildCommand<CountersPluginType>()({
export const AddCounterCmd = guildPluginMessageCommand<CountersPluginType>()({
trigger: ["counters add", "counter add", "addcounter"],
permission: "can_edit",

View file

@ -1,10 +1,10 @@
import { typedGuildCommand } from "knub";
import { guildPluginMessageCommand } from "knub";
import { sendErrorMessage } from "../../../pluginUtils";
import { trimMultilineString, ucfirst } from "../../../utils";
import { getGuildPrefix } from "../../../utils/getGuildPrefix";
import { CountersPluginType } from "../types";
export const CountersListCmd = typedGuildCommand<CountersPluginType>()({
export const CountersListCmd = guildPluginMessageCommand<CountersPluginType>()({
trigger: ["counters list", "counter list", "counters"],
permission: "can_view",
@ -44,7 +44,7 @@ export const CountersListCmd = typedGuildCommand<CountersPluginType>()({
message.channel.send(
trimMultilineString(`
${counterLines.join("\n\n")}
${hintLines.join("\n")}
`),
);

View file

@ -1,11 +1,11 @@
import { typedGuildCommand } from "knub";
import { guildPluginMessageCommand } from "knub";
import { commandTypeHelpers as ct } from "../../../commandTypes";
import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
import { confirm, noop, trimMultilineString } from "../../../utils";
import { resetAllCounterValues } from "../functions/resetAllCounterValues";
import { CountersPluginType } from "../types";
export const ResetAllCounterValuesCmd = typedGuildCommand<CountersPluginType>()({
export const ResetAllCounterValuesCmd = guildPluginMessageCommand<CountersPluginType>()({
trigger: ["counters reset_all"],
permission: "can_reset_all",

View file

@ -1,13 +1,13 @@
import { Snowflake, TextChannel } from "discord.js";
import { typedGuildCommand } from "knub";
import { waitForReply } from "knub/dist/helpers";
import { guildPluginMessageCommand } from "knub";
import { waitForReply } from "knub/helpers";
import { commandTypeHelpers as ct } from "../../../commandTypes";
import { sendErrorMessage } from "../../../pluginUtils";
import { resolveUser, UnknownUser } from "../../../utils";
import { setCounterValue } from "../functions/setCounterValue";
import { CountersPluginType } from "../types";
export const ResetCounterCmd = typedGuildCommand<CountersPluginType>()({
export const ResetCounterCmd = guildPluginMessageCommand<CountersPluginType>()({
trigger: ["counters reset", "counter reset", "resetcounter"],
permission: "can_edit",

View file

@ -1,13 +1,13 @@
import { Snowflake, TextChannel } from "discord.js";
import { typedGuildCommand } from "knub";
import { waitForReply } from "knub/dist/helpers";
import { guildPluginMessageCommand } from "knub";
import { waitForReply } from "knub/helpers";
import { commandTypeHelpers as ct } from "../../../commandTypes";
import { sendErrorMessage } from "../../../pluginUtils";
import { resolveUser, UnknownUser } from "../../../utils";
import { setCounterValue } from "../functions/setCounterValue";
import { CountersPluginType } from "../types";
export const SetCounterCmd = typedGuildCommand<CountersPluginType>()({
export const SetCounterCmd = guildPluginMessageCommand<CountersPluginType>()({
trigger: ["counters set", "counter set", "setcounter"],
permission: "can_edit",

View file

@ -1,12 +1,12 @@
import { Snowflake, TextChannel } from "discord.js";
import { typedGuildCommand } from "knub";
import { waitForReply } from "knub/dist/helpers";
import { Snowflake } from "discord.js";
import { guildPluginMessageCommand } from "knub";
import { waitForReply } from "knub/helpers";
import { commandTypeHelpers as ct } from "../../../commandTypes";
import { sendErrorMessage } from "../../../pluginUtils";
import { resolveUser, UnknownUser } from "../../../utils";
import { CountersPluginType } from "../types";
export const ViewCounterCmd = typedGuildCommand<CountersPluginType>()({
export const ViewCounterCmd = guildPluginMessageCommand<CountersPluginType>()({
trigger: ["counters view", "counter view", "viewcounter", "counter"],
permission: "can_view",
@ -68,7 +68,7 @@ export const ViewCounterCmd = typedGuildCommand<CountersPluginType>()({
}
const potentialChannel = pluginData.guild.channels.resolve(reply.content as Snowflake);
if (!potentialChannel?.isText()) {
if (!potentialChannel?.isTextBased()) {
sendErrorMessage(pluginData, message.channel, "Channel is not a text channel, cancelling");
return;
}