From c36d47e0b822cb031c248457d3d3692ad4638db9 Mon Sep 17 00:00:00 2001 From: Dragory <2606411+Dragory@users.noreply.github.com> Date: Sat, 1 Apr 2023 02:16:15 +0300 Subject: [PATCH] feat: knub v32-next; related fixes --- backend/package-lock.json | 23 +- backend/package.json | 2 +- backend/src/api/docs.ts | 2 +- backend/src/api/index.ts | 2 +- backend/src/configValidator.ts | 2 +- backend/src/index.ts | 23 +- backend/src/pluginUtils.ts | 119 +---- .../plugins/AutoDelete/AutoDeletePlugin.ts | 7 +- .../AutoReactions/AutoReactionsPlugin.ts | 7 +- backend/src/plugins/Automod/AutomodPlugin.ts | 29 +- .../plugins/Automod/actions/addToCounter.ts | 3 - .../plugins/Automod/actions/changePerms.ts | 3 +- .../src/plugins/Automod/actions/setCounter.ts | 3 - .../events/runAutomodOnCounterTrigger.ts | 3 - backend/src/plugins/Automod/helpers.ts | 2 +- backend/src/plugins/Automod/info.ts | 2 + .../plugins/BotControl/BotControlPlugin.ts | 7 +- backend/src/plugins/Cases/CasesPlugin.ts | 20 +- .../plugins/Cases/functions/getCaseSummary.ts | 2 +- backend/src/plugins/Censor/CensorPlugin.ts | 7 +- .../ChannelArchiver/ChannelArchiverPlugin.ts | 8 +- .../CompanionChannelsPlugin.ts | 7 +- .../plugins/ContextMenus/ContextMenuPlugin.ts | 6 +- .../src/plugins/Counters/CountersPlugin.ts | 22 +- .../Counters/commands/AddCounterCmd.ts | 2 +- .../Counters/commands/ResetCounterCmd.ts | 2 +- .../Counters/commands/SetCounterCmd.ts | 2 +- .../Counters/commands/ViewCounterCmd.ts | 2 +- .../CustomEvents/CustomEventsPlugin.ts | 6 +- .../GuildAccessMonitorPlugin.ts | 6 +- .../GuildConfigReloaderPlugin.ts | 6 +- .../src/plugins/GuildConfigReloader/types.ts | 3 +- .../GuildInfoSaver/GuildInfoSaverPlugin.ts | 6 +- .../InternalPoster/InternalPosterPlugin.ts | 7 +- .../plugins/LocateUser/LocateUserPlugin.ts | 7 +- .../src/plugins/LocateUser/utils/sendWhere.ts | 2 +- backend/src/plugins/Logs/LogsPlugin.ts | 20 +- .../plugins/Logs/logFunctions/logCensor.ts | 2 +- .../MessageSaver/MessageSaverPlugin.ts | 6 +- .../plugins/ModActions/ModActionsPlugin.ts | 8 +- .../src/plugins/ModActions/commands/BanCmd.ts | 2 +- .../plugins/ModActions/commands/MassBanCmd.ts | 2 +- .../ModActions/commands/MassUnbanCmd.ts | 2 +- .../ModActions/commands/MassmuteCmd.ts | 2 +- .../functions/actualKickMemberCmd.ts | 2 +- backend/src/plugins/Mutes/MutesPlugin.ts | 8 +- .../plugins/NameHistory/NameHistoryPlugin.ts | 6 +- .../plugins/NameHistory/commands/NamesCmd.ts | 2 +- backend/src/plugins/Persist/PersistPlugin.ts | 7 +- .../plugins/Phisherman/PhishermanPlugin.ts | 7 +- backend/src/plugins/Phisherman/info.ts | 2 + .../PingableRoles/PingableRolesPlugin.ts | 7 +- backend/src/plugins/Post/PostPlugin.ts | 7 +- .../ReactionRoles/ReactionRolesPlugin.ts | 7 +- .../src/plugins/Reminders/RemindersPlugin.ts | 7 +- .../Reminders/functions/postReminder.ts | 2 +- .../plugins/RoleButtons/RoleButtonsPlugin.ts | 17 +- backend/src/plugins/RoleButtons/info.ts | 2 + .../plugins/RoleManager/RoleManagerPlugin.ts | 7 +- backend/src/plugins/Roles/RolesPlugin.ts | 7 +- .../SelfGrantableRolesPlugin.ts | 24 +- .../src/plugins/Slowmode/SlowmodePlugin.ts | 7 +- .../Slowmode/commands/SlowmodeListCmd.ts | 2 +- backend/src/plugins/Spam/SpamPlugin.ts | 8 +- .../src/plugins/Starboard/StarboardPlugin.ts | 24 +- backend/src/plugins/Tags/TagsPlugin.ts | 25 +- .../src/plugins/Tags/util/findTagByName.ts | 3 +- .../Tags/util/matchAndRenderTagFromString.ts | 3 +- .../src/plugins/Tags/util/renderTagBody.ts | 3 +- .../plugins/TimeAndDate/TimeAndDatePlugin.ts | 8 +- .../UsernameSaver/UsernameSaverPlugin.ts | 6 +- backend/src/plugins/Utility/UtilityPlugin.ts | 8 +- .../src/plugins/Utility/commands/HelpCmd.ts | 4 +- .../src/plugins/Utility/commands/InfoCmd.ts | 2 +- .../Utility/functions/getMessageInfoEmbed.ts | 6 +- backend/src/plugins/Utility/search.ts | 4 +- .../WelcomeMessage/WelcomeMessagePlugin.ts | 7 +- .../src/plugins/ZeppelinPluginBlueprint.ts | 35 +- backend/src/profiler.ts | 3 +- backend/src/utils/async.ts | 2 +- backend/src/utils/createPaginatedMessage.ts | 2 +- backend/src/utils/easyProfiler.ts | 4 +- backend/src/utils/getGuildPrefix.ts | 6 +- backend/src/utils/typeUtils.ts | 2 + backend/src/utils/waitForInteraction.ts | 3 +- backend/tsconfig.json | 8 +- package-lock.json | 495 +----------------- package.json | 3 - shared/tsconfig.json | 8 +- 89 files changed, 287 insertions(+), 931 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index 1bdf9bd9..dae025ac 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -23,7 +23,7 @@ "humanize-duration": "^3.15.0", "io-ts": "^2.0.0", "js-yaml": "^3.13.1", - "knub": "^31.0.0", + "knub": "^32.0.0-next.4", "knub-command-manager": "^9.1.0", "last-commit-log": "^2.1.0", "lodash.chunk": "^4.2.0", @@ -2704,15 +2704,17 @@ } }, "node_modules/knub": { - "version": "31.0.0", - "resolved": "https://registry.npmjs.org/knub/-/knub-31.0.0.tgz", - "integrity": "sha512-mm2PrtQ9G5UoELfJ4kjWaNQZZRMhwJbCf4FgJj92iDy4pg95XPNWAkwTw8avbkslNjb9m5Va1pp3IeJayvz/ag==", + "version": "32.0.0-next.4", + "resolved": "https://registry.npmjs.org/knub/-/knub-32.0.0-next.4.tgz", + "integrity": "sha512-ywZbwcGFSr4Erl/nEUDVmziQHXKVIykWtI2Z05DLt01YmxDS+rTO8l/E6LYx7ZL3m+f2DbtLH0HB8zaZb0pUag==", "dependencies": { - "discord-api-types": "^0.37.10", - "discord.js": "^14", + "discord.js": "^14.8.0", "knub-command-manager": "^9.1.0", "ts-essentials": "^9", "zod": "^3.19.1" + }, + "engines": { + "node": ">=16" } }, "node_modules/knub-command-manager": { @@ -7199,12 +7201,11 @@ } }, "knub": { - "version": "31.0.0", - "resolved": "https://registry.npmjs.org/knub/-/knub-31.0.0.tgz", - "integrity": "sha512-mm2PrtQ9G5UoELfJ4kjWaNQZZRMhwJbCf4FgJj92iDy4pg95XPNWAkwTw8avbkslNjb9m5Va1pp3IeJayvz/ag==", + "version": "32.0.0-next.4", + "resolved": "https://registry.npmjs.org/knub/-/knub-32.0.0-next.4.tgz", + "integrity": "sha512-ywZbwcGFSr4Erl/nEUDVmziQHXKVIykWtI2Z05DLt01YmxDS+rTO8l/E6LYx7ZL3m+f2DbtLH0HB8zaZb0pUag==", "requires": { - "discord-api-types": "^0.37.10", - "discord.js": "^14", + "discord.js": "^14.8.0", "knub-command-manager": "^9.1.0", "ts-essentials": "^9", "zod": "^3.19.1" diff --git a/backend/package.json b/backend/package.json index d14c8da7..b307b431 100644 --- a/backend/package.json +++ b/backend/package.json @@ -38,7 +38,7 @@ "humanize-duration": "^3.15.0", "io-ts": "^2.0.0", "js-yaml": "^3.13.1", - "knub": "^31.0.0", + "knub": "^32.0.0-next.4", "knub-command-manager": "^9.1.0", "last-commit-log": "^2.1.0", "lodash.chunk": "^4.2.0", diff --git a/backend/src/api/docs.ts b/backend/src/api/docs.ts index 1ce9f28d..e2dd63a8 100644 --- a/backend/src/api/docs.ts +++ b/backend/src/api/docs.ts @@ -66,7 +66,7 @@ export function initDocs(app: express.Express) { })); const defaultOptions = plugin.defaultOptions || {}; - const configSchema = plugin.configSchema && formatConfigSchema(plugin.configSchema); + const configSchema = plugin.info?.configSchema && formatConfigSchema(plugin.info.configSchema); res.json({ name, diff --git a/backend/src/api/index.ts b/backend/src/api/index.ts index badc9033..649a3c0b 100644 --- a/backend/src/api/index.ts +++ b/backend/src/api/index.ts @@ -20,5 +20,5 @@ setIsAPI(true); // Connect to the database before loading the rest of the code (that depend on the database connection) console.log("Connecting to database..."); // tslint:disable-line connect().then(() => { - import("./start"); + import("./start.js"); }); diff --git a/backend/src/configValidator.ts b/backend/src/configValidator.ts index 311d18e7..e5b6e5c7 100644 --- a/backend/src/configValidator.ts +++ b/backend/src/configValidator.ts @@ -36,7 +36,7 @@ export async function validateGuildConfig(config: any): Promise { const plugin = pluginNameToPlugin.get(pluginName)!; try { const mergedOptions = configUtils.mergeConfig(plugin.defaultOptions || {}, pluginOptions); - await plugin.configParser?.(mergedOptions as unknown as PluginOptions, true); + await plugin.configParser?.(mergedOptions as unknown as PluginOptions); } catch (err) { if (err instanceof ConfigValidationError || err instanceof StrictValidationError) { return `${pluginName}: ${err.message}`; diff --git a/backend/src/index.ts b/backend/src/index.ts index 7054ebee..19a5eec4 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -2,21 +2,14 @@ import { Client, Events, GatewayIntentBits, - GuildTextBasedChannel, - Message, Options, Partials, RESTEvents, - TextBasedChannel, TextChannel, ThreadChannel, } from "discord.js"; -import { Knub, PluginError } from "knub"; -import { PluginLoadError } from "knub/dist/plugins/PluginLoadError"; -// Always use UTC internally -// This is also enforced for the database in data/db.ts import { EventEmitter } from "events"; -import { PluginNotLoadedError } from "knub/dist/plugins/PluginNotLoadedError"; +import { Knub, PluginError, PluginLoadError, PluginNotLoadedError } from "knub"; import moment from "moment-timezone"; import { performance } from "perf_hooks"; import { AllowedGuilds } from "./data/AllowedGuilds"; @@ -48,18 +41,6 @@ import { DecayingCounter } from "./utils/DecayingCounter"; import { enableProfiling } from "./utils/easyProfiler"; import { loadYamlSafely } from "./utils/loadYamlSafely"; -// TODO: Remove this once fixed on upstream -declare module "knub/dist/helpers" { - export function waitForReply( - client: Client, - channel: GuildTextBasedChannel, - restrictToUserId?: string, - timeout?: number, - ): Promise; - - export function createChunkedMessage(channel: TextBasedChannel, messageText: string): Promise; -} - // Error handling let recentPluginErrors = 0; const RECENT_PLUGIN_ERROR_EXIT_THRESHOLD = 5; @@ -184,6 +165,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 moment.tz.setDefault("UTC"); // Blocking check diff --git a/backend/src/pluginUtils.ts b/backend/src/pluginUtils.ts index be507095..c58b08ba 100644 --- a/backend/src/pluginUtils.ts +++ b/backend/src/pluginUtils.ts @@ -4,17 +4,21 @@ import { GuildMember, Message, MessageCreateOptions, MessageMentionOptions, TextBasedChannel } from "discord.js"; import * as t from "io-ts"; -import { CommandContext, configUtils, ConfigValidationError, GuildPluginData, helpers, PluginOptions } from "knub"; -import { PluginOverrideCriteria } from "knub/dist/config/configTypes"; -import { ExtendedMatchParams } from "knub/dist/config/PluginConfigManager"; // TODO: Export from Knub index -import { AnyPluginData } from "knub/dist/plugins/PluginData"; +import { + AnyPluginData, + CommandContext, + ConfigValidationError, + ExtendedMatchParams, + GuildPluginData, + helpers, + PluginOverrideCriteria, +} from "knub"; import { logger } from "./logger"; -import { ZeppelinPlugin } from "./plugins/ZeppelinPlugin"; import { isStaff } from "./staff"; import { TZeppelinKnub } from "./types"; -import { deepKeyIntersect, errorMessage, successMessage, tDeepPartial, tNullable } from "./utils"; +import { errorMessage, successMessage, tNullable } from "./utils"; import { Tail } from "./utils/typeUtils"; -import { decodeAndValidateStrict, StrictValidationError, validate } from "./validatorUtils"; +import { StrictValidationError, validate } from "./validatorUtils"; const { getMemberLevel } = helpers; @@ -91,102 +95,13 @@ export function strictValidationErrorToConfigValidationError(err: StrictValidati ); } -export function getPluginConfigParser(blueprint: ZeppelinPlugin, customParser?: ZeppelinPlugin["configParser"]) { - return async (options: PluginOptions, strict?: boolean) => { - const ident = `[getPluginConfigParser.${blueprint.name}] | `; - if (blueprint.name === "mutes") { - console.log(ident, "options => ", JSON.stringify(options)); +export function makeIoTsConfigParser>(schema: Schema): (input: unknown) => t.TypeOf { + return (input: unknown) => { + const error = validate(schema, input); + if (error) { + throw error; } - - // 1. Validate the basic structure of plugin config - const basicOptionsValidation = validate(BasicPluginStructureType, options); - if (basicOptionsValidation instanceof StrictValidationError) { - throw strictValidationErrorToConfigValidationError(basicOptionsValidation); - } - - // 2. Validate config/overrides against *partial* config schema. This ensures valid properties have valid types. - const partialConfigSchema = tDeepPartial(blueprint.configSchema); - - if (options.config) { - const partialConfigValidation = validate(partialConfigSchema, options.config); - if (partialConfigValidation instanceof StrictValidationError) { - throw strictValidationErrorToConfigValidationError(partialConfigValidation); - } - } - - if (options.overrides) { - for (const override of options.overrides) { - // Validate criteria and extra criteria - // FIXME: This is ugly - for (const key of Object.keys(override)) { - if (!validTopLevelOverrideKeys.includes(key)) { - if (strict) { - throw new ConfigValidationError(`Unknown override criterion '${key}'`); - } - - delete override[key]; - } - } - if (override.extra != null) { - for (const extraCriterion of Object.keys(override.extra)) { - if (!blueprint.customOverrideCriteriaFunctions?.[extraCriterion]) { - if (strict) { - throw new ConfigValidationError(`Unknown override extra criterion '${extraCriterion}'`); - } - - delete override.extra[extraCriterion]; - } - } - } - - // Validate override config - const partialOverrideConfigValidation = decodeAndValidateStrict(partialConfigSchema, override.config || {}); - if (partialOverrideConfigValidation instanceof StrictValidationError) { - throw strictValidationErrorToConfigValidationError(partialOverrideConfigValidation); - } - } - } - - // 3. Run custom parser, if any - if (customParser) { - options = await customParser(options); - } - - // 4. Merge with default options and validate/decode the entire config - let decodedConfig = {}; - const decodedOverrides: Array & { config: any }> = []; - - if (options.config) { - decodedConfig = blueprint.configSchema - ? decodeAndValidateStrict(blueprint.configSchema, options.config) - : options.config; - if (decodedConfig instanceof StrictValidationError) { - console.error("4.strict:", blueprint.name); - throw strictValidationErrorToConfigValidationError(decodedConfig); - } - } - - if (options.overrides) { - 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) { - console.error("4.overrides.strict:", blueprint.name, options, decodedOverrideConfig); - throw strictValidationErrorToConfigValidationError(decodedOverrideConfig); - } - decodedOverrides.push({ - ...override, - config: deepKeyIntersect(decodedOverrideConfig, override.config || {}), - }); - } - } - - return { - config: decodedConfig, - overrides: decodedOverrides, - }; + return input as t.TypeOf; }; } diff --git a/backend/src/plugins/AutoDelete/AutoDeletePlugin.ts b/backend/src/plugins/AutoDelete/AutoDeletePlugin.ts index f39f3dc8..af3ff607 100644 --- a/backend/src/plugins/AutoDelete/AutoDeletePlugin.ts +++ b/backend/src/plugins/AutoDelete/AutoDeletePlugin.ts @@ -1,6 +1,7 @@ import { PluginOptions } from "knub"; import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { makeIoTsConfigParser } from "../../pluginUtils"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; @@ -23,10 +24,11 @@ export const AutoDeletePlugin = zeppelinGuildPlugin()({ prettyName: "Auto-delete", description: "Allows Zeppelin to auto-delete messages from a channel after a delay", configurationGuide: "Maximum deletion delay is currently 5 minutes", + configSchema: ConfigSchema, }, dependencies: () => [TimeAndDatePlugin, LogsPlugin], - configSchema: ConfigSchema, + configParser: makeIoTsConfigParser(ConfigSchema), defaultOptions, beforeLoad(pluginData) { @@ -62,7 +64,4 @@ export const AutoDeletePlugin = zeppelinGuildPlugin()({ state.guildSavedMessages.events.off("delete", state.onMessageDeleteFn); state.guildSavedMessages.events.off("deleteBulk", state.onMessageDeleteBulkFn); }, - - // FIXME: Proper inherittance from ZeppelinPluginBlueprint - configParser: (o: any) => o, }); diff --git a/backend/src/plugins/AutoReactions/AutoReactionsPlugin.ts b/backend/src/plugins/AutoReactions/AutoReactionsPlugin.ts index c8ccc07c..8ec1ecd7 100644 --- a/backend/src/plugins/AutoReactions/AutoReactionsPlugin.ts +++ b/backend/src/plugins/AutoReactions/AutoReactionsPlugin.ts @@ -1,6 +1,7 @@ import { PluginOptions } from "knub"; import { GuildAutoReactions } from "../../data/GuildAutoReactions"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { makeIoTsConfigParser } from "../../pluginUtils"; import { trimPluginDescription } from "../../utils"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; @@ -31,6 +32,7 @@ export const AutoReactionsPlugin = zeppelinGuildPlugin( description: trimPluginDescription(` Allows setting up automatic reactions to all new messages on a channel `), + configSchema: ConfigSchema, }, // prettier-ignore @@ -38,7 +40,7 @@ export const AutoReactionsPlugin = zeppelinGuildPlugin( LogsPlugin, ], - configSchema: ConfigSchema, + configParser: makeIoTsConfigParser(ConfigSchema), defaultOptions, // prettier-ignore @@ -59,7 +61,4 @@ export const AutoReactionsPlugin = zeppelinGuildPlugin( state.autoReactions = GuildAutoReactions.getGuildInstance(guild.id); state.cache = new Map(); }, - - // FIXME: Proper inherittance from ZeppelinPluginBlueprint - configParser: (o: any) => o, }); diff --git a/backend/src/plugins/Automod/AutomodPlugin.ts b/backend/src/plugins/Automod/AutomodPlugin.ts index 0bc2e648..81a7792c 100644 --- a/backend/src/plugins/Automod/AutomodPlugin.ts +++ b/backend/src/plugins/Automod/AutomodPlugin.ts @@ -1,3 +1,4 @@ +import * as t from "io-ts"; import { configUtils, CooldownManager } from "knub"; import { GuildAntiraidLevels } from "../../data/GuildAntiraidLevels"; import { GuildArchives } from "../../data/GuildArchives"; @@ -8,7 +9,7 @@ import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners"; import { MINUTES, SECONDS } from "../../utils"; import { registerEventListenersFromMap } from "../../utils/registerEventListenersFromMap"; import { unregisterEventListenersFromMap } from "../../utils/unregisterEventListenersFromMap"; -import { StrictValidationError } from "../../validatorUtils"; +import { StrictValidationError, validate } from "../../validatorUtils"; import { CountersPlugin } from "../Counters/CountersPlugin"; import { InternalPosterPlugin } from "../InternalPoster/InternalPosterPlugin"; import { LogsPlugin } from "../Logs/LogsPlugin"; @@ -62,14 +63,15 @@ const defaultOptions = { /** * Config preprocessor to set default values for triggers and perform extra validation + * TODO: Separate input and output types */ - -const configParser = (options) => { - if (options.rules) { +const configParser = (input: unknown) => { + const rules = (input as any).rules; + if (rules) { // Loop through each rule - for (const [name, rule] of Object.entries(options.rules)) { + for (const [name, rule] of Object.entries(rules)) { if (rule == null) { - delete options.rules[name]; + delete rules[name]; continue; } @@ -179,7 +181,12 @@ const configParser = (options) => { } } - return options; + const error = validate(ConfigSchema, input); + if (error) { + throw error; + } + + return input as t.TypeOf; }; export const AutomodPlugin = zeppelinGuildPlugin()({ @@ -188,7 +195,6 @@ export const AutomodPlugin = zeppelinGuildPlugin()({ info: pluginInfo, // prettier-ignore - // @ts-expect-error dependencies: () => [ LogsPlugin, ModActionsPlugin, @@ -198,7 +204,6 @@ export const AutomodPlugin = zeppelinGuildPlugin()({ InternalPosterPlugin, ], - configSchema: ConfigSchema, defaultOptions, configParser, @@ -261,7 +266,6 @@ export const AutomodPlugin = zeppelinGuildPlugin()({ state.onMessageUpdateFn = (message) => runAutomodOnMessage(pluginData, message, true); state.savedMessages.events.on("update", state.onMessageUpdateFn); - // @ts-expect-error const countersPlugin = pluginData.getPlugin(CountersPlugin); state.onCounterTrigger = (name, triggerName, channelId, userId) => { @@ -271,9 +275,7 @@ export const AutomodPlugin = zeppelinGuildPlugin()({ state.onCounterReverseTrigger = (name, triggerName, channelId, userId) => { runAutomodOnCounterTrigger(pluginData, name, triggerName, channelId, userId, true); }; - // @ts-expect-error countersPlugin.onCounterEvent("trigger", state.onCounterTrigger); - // @ts-expect-error countersPlugin.onCounterEvent("reverseTrigger", state.onCounterReverseTrigger); const modActionsEvents = pluginData.getPlugin(ModActionsPlugin).getEventEmitter(); @@ -303,14 +305,11 @@ export const AutomodPlugin = zeppelinGuildPlugin()({ async beforeUnload(pluginData) { const { state, guild } = pluginData; - // @ts-expect-error const countersPlugin = pluginData.getPlugin(CountersPlugin); if (state.onCounterTrigger) { - // @ts-expect-error countersPlugin.offCounterEvent("trigger", state.onCounterTrigger); } if (state.onCounterReverseTrigger) { - // @ts-expect-error countersPlugin.offCounterEvent("reverseTrigger", state.onCounterReverseTrigger); } diff --git a/backend/src/plugins/Automod/actions/addToCounter.ts b/backend/src/plugins/Automod/actions/addToCounter.ts index b8dae6d0..842534ef 100644 --- a/backend/src/plugins/Automod/actions/addToCounter.ts +++ b/backend/src/plugins/Automod/actions/addToCounter.ts @@ -12,9 +12,7 @@ export const AddToCounterAction = automodAction({ defaultConfig: {}, async apply({ pluginData, contexts, actionConfig, matchResult, ruleName }) { - // @ts-expect-error const countersPlugin = pluginData.getPlugin(CountersPlugin); - // @ts-expect-error if (!countersPlugin.counterExists(actionConfig.counter)) { pluginData.getPlugin(LogsPlugin).logBotAlert({ body: `Unknown counter \`${actionConfig.counter}\` in \`add_to_counter\` action of Automod rule \`${ruleName}\``, @@ -22,7 +20,6 @@ export const AddToCounterAction = automodAction({ return; } - // @ts-expect-error countersPlugin.changeCounterValue( actionConfig.counter, contexts[0].message?.channel_id || null, diff --git a/backend/src/plugins/Automod/actions/changePerms.ts b/backend/src/plugins/Automod/actions/changePerms.ts index 4db4ebfd..8e5c1c0e 100644 --- a/backend/src/plugins/Automod/actions/changePerms.ts +++ b/backend/src/plugins/Automod/actions/changePerms.ts @@ -1,8 +1,7 @@ import { PermissionsBitField, PermissionsString } from "discord.js"; import * as t from "io-ts"; -import { noop } from "knub/dist/utils"; import { renderTemplate, TemplateSafeValueContainer } from "../../../templateFormatter"; -import { isValidSnowflake, tNullable, tPartialDictionary } from "../../../utils"; +import { isValidSnowflake, noop, tNullable, tPartialDictionary } from "../../../utils"; import { guildToTemplateSafeGuild, savedMessageToTemplateSafeSavedMessage, diff --git a/backend/src/plugins/Automod/actions/setCounter.ts b/backend/src/plugins/Automod/actions/setCounter.ts index 2369150b..3088f848 100644 --- a/backend/src/plugins/Automod/actions/setCounter.ts +++ b/backend/src/plugins/Automod/actions/setCounter.ts @@ -12,9 +12,7 @@ export const SetCounterAction = automodAction({ defaultConfig: {}, async apply({ pluginData, contexts, actionConfig, matchResult, ruleName }) { - // @ts-expect-error const countersPlugin = pluginData.getPlugin(CountersPlugin); - // @ts-expect-error if (!countersPlugin.counterExists(actionConfig.counter)) { pluginData.getPlugin(LogsPlugin).logBotAlert({ body: `Unknown counter \`${actionConfig.counter}\` in \`add_to_counter\` action of Automod rule \`${ruleName}\``, @@ -22,7 +20,6 @@ export const SetCounterAction = automodAction({ return; } - // @ts-expect-error countersPlugin.setCounterValue( actionConfig.counter, contexts[0].message?.channel_id || null, diff --git a/backend/src/plugins/Automod/events/runAutomodOnCounterTrigger.ts b/backend/src/plugins/Automod/events/runAutomodOnCounterTrigger.ts index 125e3854..9de3dae0 100644 --- a/backend/src/plugins/Automod/events/runAutomodOnCounterTrigger.ts +++ b/backend/src/plugins/Automod/events/runAutomodOnCounterTrigger.ts @@ -14,11 +14,8 @@ export async function runAutomodOnCounterTrigger( ) { const user = userId ? await resolveUser(pluginData.client, userId) : undefined; const member = (userId && (await resolveMember(pluginData.client, pluginData.guild, userId))) || undefined; - // @ts-expect-error const prettyCounterName = pluginData.getPlugin(CountersPlugin).getPrettyNameForCounter(counterName); - // @ts-expect-error const prettyTriggerName = pluginData - // @ts-expect-error .getPlugin(CountersPlugin) .getPrettyNameForCounterTrigger(counterName, triggerName); diff --git a/backend/src/plugins/Automod/helpers.ts b/backend/src/plugins/Automod/helpers.ts index 20bafe7e..15afc545 100644 --- a/backend/src/plugins/Automod/helpers.ts +++ b/backend/src/plugins/Automod/helpers.ts @@ -1,6 +1,6 @@ import * as t from "io-ts"; import { GuildPluginData } from "knub"; -import { Awaitable } from "knub/dist/utils"; +import { Awaitable } from "../../utils/typeUtils"; import { AutomodContext, AutomodPluginType } from "./types"; interface BaseAutomodTriggerMatchResult { diff --git a/backend/src/plugins/Automod/info.ts b/backend/src/plugins/Automod/info.ts index 6a053757..e0102459 100644 --- a/backend/src/plugins/Automod/info.ts +++ b/backend/src/plugins/Automod/info.ts @@ -1,5 +1,6 @@ import { trimPluginDescription } from "../../utils"; import { ZeppelinGuildPluginBlueprint } from "../ZeppelinPluginBlueprint"; +import { ConfigSchema } from "./types"; export const pluginInfo: ZeppelinGuildPluginBlueprint["info"] = { prettyName: "Automod", @@ -99,4 +100,5 @@ export const pluginInfo: ZeppelinGuildPluginBlueprint["info"] = { {matchSummary} ~~~ `), + configSchema: ConfigSchema, }; diff --git a/backend/src/plugins/BotControl/BotControlPlugin.ts b/backend/src/plugins/BotControl/BotControlPlugin.ts index 7e9cf027..76478ca2 100644 --- a/backend/src/plugins/BotControl/BotControlPlugin.ts +++ b/backend/src/plugins/BotControl/BotControlPlugin.ts @@ -3,7 +3,7 @@ import { AllowedGuilds } from "../../data/AllowedGuilds"; import { ApiPermissionAssignments } from "../../data/ApiPermissionAssignments"; import { Configs } from "../../data/Configs"; import { GuildArchives } from "../../data/GuildArchives"; -import { sendSuccessMessage } from "../../pluginUtils"; +import { makeIoTsConfigParser, sendSuccessMessage } from "../../pluginUtils"; import { zeppelinGlobalPlugin } from "../ZeppelinPluginBlueprint"; import { getActiveReload, resetActiveReload } from "./activeReload"; import { AddDashboardUserCmd } from "./commands/AddDashboardUserCmd"; @@ -37,7 +37,7 @@ const defaultOptions = { export const BotControlPlugin = zeppelinGlobalPlugin()({ name: "bot_control", - configSchema: ConfigSchema, + configParser: makeIoTsConfigParser(ConfigSchema), defaultOptions, // prettier-ignore @@ -82,7 +82,4 @@ export const BotControlPlugin = zeppelinGlobalPlugin()({ } } }, - - // FIXME: Proper inherittance from ZeppelinPluginBlueprint - configParser: (o: any) => o, }); diff --git a/backend/src/plugins/Cases/CasesPlugin.ts b/backend/src/plugins/Cases/CasesPlugin.ts index ca946dfc..45f63c79 100644 --- a/backend/src/plugins/Cases/CasesPlugin.ts +++ b/backend/src/plugins/Cases/CasesPlugin.ts @@ -3,7 +3,7 @@ import { Case } from "../../data/entities/Case"; import { GuildArchives } from "../../data/GuildArchives"; import { GuildCases } from "../../data/GuildCases"; import { GuildLogs } from "../../data/GuildLogs"; -import { mapToPublicFn } from "../../pluginUtils"; +import { makeIoTsConfigParser, mapToPublicFn } from "../../pluginUtils"; import { trimPluginDescription } from "../../utils"; import { InternalPosterPlugin } from "../InternalPoster/InternalPosterPlugin"; import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; @@ -18,6 +18,11 @@ import { getTotalCasesByMod } from "./functions/getTotalCasesByMod"; import { postCaseToCaseLogChannel } from "./functions/postToCaseLogChannel"; import { CaseArgs, CaseNoteArgs, CasesPluginType, ConfigSchema } from "./types"; +// The `any` cast here is to prevent TypeScript from locking up from the circular dependency +function getLogsPlugin(): Promise { + return import("../Logs/LogsPlugin.js") as Promise; +} + const defaultOptions = { config: { log_automatic_actions: true, @@ -37,15 +42,11 @@ export const CasesPlugin = zeppelinGuildPlugin()({ description: trimPluginDescription(` This plugin contains basic configuration for cases created by other plugins `), + configSchema: ConfigSchema, }, - dependencies: async () => [ - TimeAndDatePlugin, - InternalPosterPlugin, - // The `as any` cast here is to prevent TypeScript from locking up from the circular dependency - ((await import("../Logs/LogsPlugin")) as any).LogsPlugin, - ], - configSchema: ConfigSchema, + dependencies: async () => [TimeAndDatePlugin, InternalPosterPlugin, (await getLogsPlugin()).LogsPlugin], + configParser: makeIoTsConfigParser(ConfigSchema), defaultOptions, public: { @@ -87,7 +88,4 @@ export const CasesPlugin = zeppelinGuildPlugin()({ state.archives = GuildArchives.getGuildInstance(guild.id); state.cases = GuildCases.getGuildInstance(guild.id); }, - - // FIXME: Proper inherittance from ZeppelinPluginBlueprint - configParser: (o: any) => o, }); diff --git a/backend/src/plugins/Cases/functions/getCaseSummary.ts b/backend/src/plugins/Cases/functions/getCaseSummary.ts index 98841451..c4135e67 100644 --- a/backend/src/plugins/Cases/functions/getCaseSummary.ts +++ b/backend/src/plugins/Cases/functions/getCaseSummary.ts @@ -1,5 +1,5 @@ import { GuildPluginData } from "knub"; -import { splitMessageIntoChunks } from "knub/dist/helpers"; +import { splitMessageIntoChunks } from "knub/helpers"; import moment from "moment-timezone"; import { Case } from "../../../data/entities/Case"; import { convertDelayStringToMS, DAYS, DBDateFormat, disableLinkPreviews, messageLink } from "../../../utils"; diff --git a/backend/src/plugins/Censor/CensorPlugin.ts b/backend/src/plugins/Censor/CensorPlugin.ts index a52fb093..61991e12 100644 --- a/backend/src/plugins/Censor/CensorPlugin.ts +++ b/backend/src/plugins/Censor/CensorPlugin.ts @@ -1,6 +1,7 @@ import { PluginOptions } from "knub"; import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { makeIoTsConfigParser } from "../../pluginUtils"; import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners"; import { trimPluginDescription } from "../../utils"; import { LogsPlugin } from "../Logs/LogsPlugin"; @@ -53,10 +54,11 @@ export const CensorPlugin = zeppelinGuildPlugin()({ For more advanced filtering, check out the Automod plugin! `), legacy: true, + configSchema: ConfigSchema, }, dependencies: () => [LogsPlugin], - configSchema: ConfigSchema, + configParser: makeIoTsConfigParser(ConfigSchema), defaultOptions, beforeLoad(pluginData) { @@ -86,7 +88,4 @@ export const CensorPlugin = zeppelinGuildPlugin()({ state.savedMessages.events.off("create", state.onMessageCreateFn); state.savedMessages.events.off("update", state.onMessageUpdateFn); }, - - // FIXME: Proper inherittance from ZeppelinPluginBlueprint - configParser: (o: any) => o, }); diff --git a/backend/src/plugins/ChannelArchiver/ChannelArchiverPlugin.ts b/backend/src/plugins/ChannelArchiver/ChannelArchiverPlugin.ts index d5dbeedd..b4467819 100644 --- a/backend/src/plugins/ChannelArchiver/ChannelArchiverPlugin.ts +++ b/backend/src/plugins/ChannelArchiver/ChannelArchiverPlugin.ts @@ -1,21 +1,21 @@ import * as t from "io-ts"; +import { makeIoTsConfigParser } from "../../pluginUtils"; import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { ArchiveChannelCmd } from "./commands/ArchiveChannelCmd"; import { ChannelArchiverPluginType } from "./types"; +const ConfigSchema = t.type({}); + export const ChannelArchiverPlugin = zeppelinGuildPlugin()({ name: "channel_archiver", showInDocs: false, dependencies: () => [TimeAndDatePlugin], - configSchema: t.type({}), + configParser: makeIoTsConfigParser(ConfigSchema), // prettier-ignore messageCommands: [ ArchiveChannelCmd, ], - - // FIXME: Proper inherittance from ZeppelinPluginBlueprint - configParser: (o: any) => o, }); diff --git a/backend/src/plugins/CompanionChannels/CompanionChannelsPlugin.ts b/backend/src/plugins/CompanionChannels/CompanionChannelsPlugin.ts index 20a91fc6..bd05d800 100644 --- a/backend/src/plugins/CompanionChannels/CompanionChannelsPlugin.ts +++ b/backend/src/plugins/CompanionChannels/CompanionChannelsPlugin.ts @@ -1,5 +1,6 @@ import { CooldownManager } from "knub"; import { GuildLogs } from "../../data/GuildLogs"; +import { makeIoTsConfigParser } from "../../pluginUtils"; import { trimPluginDescription } from "../../utils"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; @@ -22,10 +23,11 @@ export const CompanionChannelsPlugin = zeppelinGuildPlugin [LogsPlugin], - configSchema: ConfigSchema, + configParser: makeIoTsConfigParser(ConfigSchema), defaultOptions, events: [VoiceStateUpdateEvt], @@ -37,7 +39,4 @@ export const CompanionChannelsPlugin = zeppelinGuildPlugin o, }); diff --git a/backend/src/plugins/ContextMenus/ContextMenuPlugin.ts b/backend/src/plugins/ContextMenus/ContextMenuPlugin.ts index bc6fa5f3..c41e8c09 100644 --- a/backend/src/plugins/ContextMenus/ContextMenuPlugin.ts +++ b/backend/src/plugins/ContextMenus/ContextMenuPlugin.ts @@ -1,5 +1,6 @@ import { PluginOptions } from "knub"; import { GuildContextMenuLinks } from "../../data/GuildContextMenuLinks"; +import { makeIoTsConfigParser } from "../../pluginUtils"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { MutesPlugin } from "../Mutes/MutesPlugin"; import { UtilityPlugin } from "../Utility/UtilityPlugin"; @@ -35,8 +36,8 @@ export const ContextMenuPlugin = zeppelinGuildPlugin()({ name: "context_menu", showInDocs: false, - configSchema: ConfigSchema, dependencies: () => [MutesPlugin, LogsPlugin, UtilityPlugin], + configParser: makeIoTsConfigParser(ConfigSchema), defaultOptions, // prettier-ignore @@ -53,7 +54,4 @@ export const ContextMenuPlugin = zeppelinGuildPlugin()({ afterLoad(pluginData) { loadAllCommands(pluginData); }, - - // FIXME: Proper inherittance from ZeppelinPluginBlueprint - configParser: (o: any) => o, }); diff --git a/backend/src/plugins/Counters/CountersPlugin.ts b/backend/src/plugins/Counters/CountersPlugin.ts index 5dae0e86..b2eb34b1 100644 --- a/backend/src/plugins/Counters/CountersPlugin.ts +++ b/backend/src/plugins/Counters/CountersPlugin.ts @@ -1,4 +1,5 @@ import { EventEmitter } from "events"; +import * as t from "io-ts"; import { PluginOptions } from "knub"; import { buildCounterConditionString, @@ -9,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"; @@ -72,12 +73,13 @@ export const CountersPlugin = zeppelinGuildPlugin()({ description: "Keep track of per-user, per-channel, or global numbers and trigger specific actions based on this number", configurationGuide: "See Counters setup guide", + configSchema: ConfigSchema, }, - configSchema: ConfigSchema, defaultOptions, - configParser: (options) => { - for (const [counterName, counter] of Object.entries(options.counters || {})) { + // TODO: Separate input and output types + configParser: (input) => { + for (const [counterName, counter] of Object.entries((input as any).counters || {})) { counter.name = counterName; counter.per_user = counter.per_user ?? false; counter.per_channel = counter.per_channel ?? false; @@ -90,7 +92,7 @@ export const CountersPlugin = zeppelinGuildPlugin()({ // Normalize triggers for (const [triggerName, trigger] of Object.entries(counter.triggers)) { - const triggerObj: Partial = typeof trigger === "string" ? { condition: trigger } : trigger; + const triggerObj = (typeof trigger === "string" ? { condition: trigger } : trigger) as Partial; triggerObj.name = triggerName; const parsedCondition = parseCounterConditionString(triggerObj.condition || ""); @@ -109,12 +111,16 @@ export const CountersPlugin = zeppelinGuildPlugin()({ } } - if (Object.values(options.counters || {}).length > MAX_COUNTERS) { + if (Object.values((input as any).counters || {}).length > MAX_COUNTERS) { throw new StrictValidationError([`You can only have at most ${MAX_COUNTERS} counters`]); } - // FIXME: Any typing - return options; + const error = validate(ConfigSchema, input); + if (error) { + throw error; + } + + return input as t.TypeOf; }, public: { diff --git a/backend/src/plugins/Counters/commands/AddCounterCmd.ts b/backend/src/plugins/Counters/commands/AddCounterCmd.ts index 486a45d4..ac8c3698 100644 --- a/backend/src/plugins/Counters/commands/AddCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/AddCounterCmd.ts @@ -1,6 +1,6 @@ import { Snowflake, TextChannel } from "discord.js"; import { guildPluginMessageCommand } from "knub"; -import { waitForReply } from "knub/dist/helpers"; +import { waitForReply } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; import { resolveUser, UnknownUser } from "../../../utils"; diff --git a/backend/src/plugins/Counters/commands/ResetCounterCmd.ts b/backend/src/plugins/Counters/commands/ResetCounterCmd.ts index 56e7672e..21191abf 100644 --- a/backend/src/plugins/Counters/commands/ResetCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/ResetCounterCmd.ts @@ -1,6 +1,6 @@ import { Snowflake, TextChannel } from "discord.js"; import { guildPluginMessageCommand } from "knub"; -import { waitForReply } from "knub/dist/helpers"; +import { waitForReply } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; import { resolveUser, UnknownUser } from "../../../utils"; diff --git a/backend/src/plugins/Counters/commands/SetCounterCmd.ts b/backend/src/plugins/Counters/commands/SetCounterCmd.ts index 2b488511..98ffcc9b 100644 --- a/backend/src/plugins/Counters/commands/SetCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/SetCounterCmd.ts @@ -1,6 +1,6 @@ import { Snowflake, TextChannel } from "discord.js"; import { guildPluginMessageCommand } from "knub"; -import { waitForReply } from "knub/dist/helpers"; +import { waitForReply } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; import { resolveUser, UnknownUser } from "../../../utils"; diff --git a/backend/src/plugins/Counters/commands/ViewCounterCmd.ts b/backend/src/plugins/Counters/commands/ViewCounterCmd.ts index f63957fa..d2715c0c 100644 --- a/backend/src/plugins/Counters/commands/ViewCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/ViewCounterCmd.ts @@ -1,6 +1,6 @@ import { Snowflake } from "discord.js"; import { guildPluginMessageCommand } from "knub"; -import { waitForReply } from "knub/dist/helpers"; +import { waitForReply } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; import { resolveUser, UnknownUser } from "../../../utils"; diff --git a/backend/src/plugins/CustomEvents/CustomEventsPlugin.ts b/backend/src/plugins/CustomEvents/CustomEventsPlugin.ts index 7f0b7c97..61683ed2 100644 --- a/backend/src/plugins/CustomEvents/CustomEventsPlugin.ts +++ b/backend/src/plugins/CustomEvents/CustomEventsPlugin.ts @@ -1,6 +1,7 @@ import { GuildChannel, GuildMember, User } from "discord.js"; import { guildPluginMessageCommand, parseSignature } from "knub"; import { commandTypes } from "../../commandTypes"; +import { makeIoTsConfigParser } from "../../pluginUtils"; import { createTypedTemplateSafeValueContainer, TemplateSafeValueContainer } from "../../templateFormatter"; import { UnknownUser } from "../../utils"; import { isScalar } from "../../utils/isScalar"; @@ -24,7 +25,7 @@ export const CustomEventsPlugin = zeppelinGuildPlugin()( name: "custom_events", showInDocs: false, - configSchema: ConfigSchema, + configParser: makeIoTsConfigParser(ConfigSchema), defaultOptions, afterLoad(pluginData) { @@ -67,7 +68,4 @@ export const CustomEventsPlugin = zeppelinGuildPlugin()( beforeUnload() { // TODO: Run clearTriggers() once we actually have something there }, - - // FIXME: Proper inherittance from ZeppelinPluginBlueprint - configParser: (o: any) => o, }); diff --git a/backend/src/plugins/GuildAccessMonitor/GuildAccessMonitorPlugin.ts b/backend/src/plugins/GuildAccessMonitor/GuildAccessMonitorPlugin.ts index 866f4eab..447094c2 100644 --- a/backend/src/plugins/GuildAccessMonitor/GuildAccessMonitorPlugin.ts +++ b/backend/src/plugins/GuildAccessMonitor/GuildAccessMonitorPlugin.ts @@ -4,6 +4,7 @@ import { BasePluginType, GlobalPluginData, globalPluginEventListener } from "knu import { AllowedGuilds } from "../../data/AllowedGuilds"; import { Configs } from "../../data/Configs"; import { env } from "../../env"; +import { makeIoTsConfigParser } from "../../pluginUtils"; import { zeppelinGlobalPlugin } from "../ZeppelinPluginBlueprint"; interface GuildAccessMonitorPluginType extends BasePluginType { @@ -26,7 +27,7 @@ async function checkGuild(pluginData: GlobalPluginData()({ name: "guild_access_monitor", - configSchema: t.type({}), + configParser: makeIoTsConfigParser(t.type({})), events: [ globalPluginEventListener()({ @@ -59,7 +60,4 @@ export const GuildAccessMonitorPlugin = zeppelinGlobalPlugin o, }); diff --git a/backend/src/plugins/GuildConfigReloader/GuildConfigReloaderPlugin.ts b/backend/src/plugins/GuildConfigReloader/GuildConfigReloaderPlugin.ts index a0615958..5ae04fb5 100644 --- a/backend/src/plugins/GuildConfigReloader/GuildConfigReloaderPlugin.ts +++ b/backend/src/plugins/GuildConfigReloader/GuildConfigReloaderPlugin.ts @@ -1,5 +1,6 @@ import * as t from "io-ts"; import { Configs } from "../../data/Configs"; +import { makeIoTsConfigParser } from "../../pluginUtils"; import { zeppelinGlobalPlugin } from "../ZeppelinPluginBlueprint"; import { reloadChangedGuilds } from "./functions/reloadChangedGuilds"; import { GuildConfigReloaderPluginType } from "./types"; @@ -8,7 +9,7 @@ export const GuildConfigReloaderPlugin = zeppelinGlobalPlugin o, }); diff --git a/backend/src/plugins/GuildConfigReloader/types.ts b/backend/src/plugins/GuildConfigReloader/types.ts index 94ada5cf..4ab03116 100644 --- a/backend/src/plugins/GuildConfigReloader/types.ts +++ b/backend/src/plugins/GuildConfigReloader/types.ts @@ -1,10 +1,9 @@ import { BasePluginType } from "knub"; import { Configs } from "../../data/Configs"; -import { TConfigSchema } from "../Mutes/types"; import Timeout = NodeJS.Timeout; export interface GuildConfigReloaderPluginType extends BasePluginType { - config: TConfigSchema; + config: {}; state: { guildConfigs: Configs; unloaded: boolean; diff --git a/backend/src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts b/backend/src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts index cb7464aa..687175f1 100644 --- a/backend/src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts +++ b/backend/src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts @@ -3,6 +3,7 @@ import * as t from "io-ts"; import { guildPluginEventListener } from "knub"; import { AllowedGuilds } from "../../data/AllowedGuilds"; import { ApiPermissionAssignments } from "../../data/ApiPermissionAssignments"; +import { makeIoTsConfigParser } from "../../pluginUtils"; import { MINUTES } from "../../utils"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { GuildInfoSaverPluginType } from "./types"; @@ -11,7 +12,7 @@ export const GuildInfoSaverPlugin = zeppelinGuildPlugin o, }); async function updateGuildInfo(guild: Guild) { diff --git a/backend/src/plugins/InternalPoster/InternalPosterPlugin.ts b/backend/src/plugins/InternalPoster/InternalPosterPlugin.ts index c7b260e8..b0827058 100644 --- a/backend/src/plugins/InternalPoster/InternalPosterPlugin.ts +++ b/backend/src/plugins/InternalPoster/InternalPosterPlugin.ts @@ -1,6 +1,6 @@ import { PluginOptions } from "knub"; import { Webhooks } from "../../data/Webhooks"; -import { mapToPublicFn } from "../../pluginUtils"; +import { makeIoTsConfigParser, mapToPublicFn } from "../../pluginUtils"; import { Queue } from "../../Queue"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { editMessage } from "./functions/editMessage"; @@ -16,7 +16,7 @@ export const InternalPosterPlugin = zeppelinGuildPlugin o, }); diff --git a/backend/src/plugins/LocateUser/LocateUserPlugin.ts b/backend/src/plugins/LocateUser/LocateUserPlugin.ts index 8c3cc5a3..fc3e4303 100644 --- a/backend/src/plugins/LocateUser/LocateUserPlugin.ts +++ b/backend/src/plugins/LocateUser/LocateUserPlugin.ts @@ -1,6 +1,7 @@ import { PluginOptions } from "knub"; import { onGuildEvent } from "../../data/GuildEvents"; import { GuildVCAlerts } from "../../data/GuildVCAlerts"; +import { makeIoTsConfigParser } from "../../pluginUtils"; import { trimPluginDescription } from "../../utils"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { FollowCmd } from "./commands/FollowCmd"; @@ -38,9 +39,10 @@ export const LocateUserPlugin = zeppelinGuildPlugin()({ * Instantly receive an invite to the voice channel of a user * Be notified as soon as a user switches or joins a voice channel `), + configSchema: ConfigSchema, }, - configSchema: ConfigSchema, + configParser: makeIoTsConfigParser(ConfigSchema), defaultOptions, // prettier-ignore @@ -78,7 +80,4 @@ export const LocateUserPlugin = zeppelinGuildPlugin()({ state.unregisterGuildEventListener?.(); }, - - // FIXME: Proper inherittance from ZeppelinPluginBlueprint - configParser: (o: any) => o, }); diff --git a/backend/src/plugins/LocateUser/utils/sendWhere.ts b/backend/src/plugins/LocateUser/utils/sendWhere.ts index b6999a73..7faaad80 100644 --- a/backend/src/plugins/LocateUser/utils/sendWhere.ts +++ b/backend/src/plugins/LocateUser/utils/sendWhere.ts @@ -1,6 +1,6 @@ import { GuildMember, GuildTextBasedChannel, Invite, VoiceChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { getInviteLink } from "knub/dist/helpers"; +import { getInviteLink } from "knub/helpers"; import { sendErrorMessage } from "../../../pluginUtils"; import { LocateUserPluginType } from "../types"; import { createOrReuseInvite } from "./createOrReuseInvite"; diff --git a/backend/src/plugins/Logs/LogsPlugin.ts b/backend/src/plugins/Logs/LogsPlugin.ts index f9ea27e7..4543a33a 100644 --- a/backend/src/plugins/Logs/LogsPlugin.ts +++ b/backend/src/plugins/Logs/LogsPlugin.ts @@ -6,7 +6,7 @@ import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { LogType } from "../../data/LogType"; import { logger } from "../../logger"; -import { mapToPublicFn } from "../../pluginUtils"; +import { makeIoTsConfigParser, mapToPublicFn } from "../../pluginUtils"; import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners"; import { createTypedTemplateSafeValueContainer, TypedTemplateSafeValueContainer } from "../../templateFormatter"; import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; @@ -110,6 +110,11 @@ import { logVoiceChannelJoin } from "./logFunctions/logVoiceChannelJoin"; import { logVoiceChannelLeave } from "./logFunctions/logVoiceChannelLeave"; import { logVoiceChannelMove } from "./logFunctions/logVoiceChannelMove"; +// The `any` cast here is to prevent TypeScript from locking up from the circular dependency +function getCasesPlugin(): Promise { + return import("../Cases/CasesPlugin.js") as Promise; +} + const defaultOptions: PluginOptions = { config: { channels: {}, @@ -138,15 +143,11 @@ export const LogsPlugin = zeppelinGuildPlugin()({ showInDocs: true, info: { prettyName: "Logs", + configSchema: ConfigSchema, }, - dependencies: async () => [ - TimeAndDatePlugin, - InternalPosterPlugin, - // The `as any` cast here is to prevent TypeScript from locking up from the circular dependency - ((await import("../Cases/CasesPlugin")) as any).CasesPlugin, - ], - configSchema: ConfigSchema, + dependencies: async () => [TimeAndDatePlugin, InternalPosterPlugin, (await getCasesPlugin()).CasesPlugin], + configParser: makeIoTsConfigParser(ConfigSchema), defaultOptions, events: [ @@ -326,7 +327,4 @@ export const LogsPlugin = zeppelinGuildPlugin()({ } discardRegExpRunner(`guild-${guild.id}`); }, - - // FIXME: Proper inherittance from ZeppelinPluginBlueprint - configParser: (o: any) => o, }); diff --git a/backend/src/plugins/Logs/logFunctions/logCensor.ts b/backend/src/plugins/Logs/logFunctions/logCensor.ts index e6572a0f..1d9affdd 100644 --- a/backend/src/plugins/Logs/logFunctions/logCensor.ts +++ b/backend/src/plugins/Logs/logFunctions/logCensor.ts @@ -1,6 +1,6 @@ import { GuildTextBasedChannel, User } from "discord.js"; import { GuildPluginData } from "knub"; -import { deactivateMentions, disableCodeBlocks } from "knub/dist/helpers"; +import { deactivateMentions, disableCodeBlocks } from "knub/helpers"; import { resolveChannelIds } from "src/utils/resolveChannelIds"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { LogType } from "../../../data/LogType"; diff --git a/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts b/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts index 3e034cce..9e775251 100644 --- a/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts +++ b/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts @@ -1,5 +1,6 @@ import { PluginOptions } from "knub"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { makeIoTsConfigParser } from "../../pluginUtils"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { SaveMessagesToDBCmd } from "./commands/SaveMessagesToDB"; import { SavePinsToDBCmd } from "./commands/SavePinsToDB"; @@ -24,7 +25,7 @@ export const MessageSaverPlugin = zeppelinGuildPlugin()( name: "message_saver", showInDocs: false, - configSchema: ConfigSchema, + configParser: makeIoTsConfigParser(ConfigSchema), defaultOptions, // prettier-ignore @@ -45,7 +46,4 @@ export const MessageSaverPlugin = zeppelinGuildPlugin()( const { state, guild } = pluginData; state.savedMessages = GuildSavedMessages.getGuildInstance(guild.id); }, - - // FIXME: Proper inherittance from ZeppelinPluginBlueprint - configParser: (o: any) => o, }); diff --git a/backend/src/plugins/ModActions/ModActionsPlugin.ts b/backend/src/plugins/ModActions/ModActionsPlugin.ts index 93acd687..70636c6c 100644 --- a/backend/src/plugins/ModActions/ModActionsPlugin.ts +++ b/backend/src/plugins/ModActions/ModActionsPlugin.ts @@ -5,7 +5,7 @@ import { onGuildEvent } from "../../data/GuildEvents"; import { GuildLogs } from "../../data/GuildLogs"; import { GuildMutes } from "../../data/GuildMutes"; import { GuildTempbans } from "../../data/GuildTempbans"; -import { mapToPublicFn } from "../../pluginUtils"; +import { makeIoTsConfigParser, mapToPublicFn } from "../../pluginUtils"; import { Queue } from "../../Queue"; import { MINUTES, trimPluginDescription } from "../../utils"; import { CasesPlugin } from "../Cases/CasesPlugin"; @@ -120,10 +120,11 @@ export const ModActionsPlugin = zeppelinGuildPlugin()({ description: trimPluginDescription(` This plugin contains the 'typical' mod actions such as warning, muting, kicking, banning, etc. `), + configSchema: ConfigSchema, }, dependencies: () => [TimeAndDatePlugin, CasesPlugin, MutesPlugin, LogsPlugin], - configSchema: ConfigSchema, + configParser: makeIoTsConfigParser(ConfigSchema), defaultOptions, events: [CreateBanCaseOnManualBanEvt, CreateUnbanCaseOnManualUnbanEvt, PostAlertOnMemberJoinEvt], @@ -223,7 +224,4 @@ export const ModActionsPlugin = zeppelinGuildPlugin()({ state.unregisterGuildEventListener?.(); state.events.removeAllListeners(); }, - - // FIXME: Proper inherittance from ZeppelinPluginBlueprint - configParser: (o: any) => o, }); diff --git a/backend/src/plugins/ModActions/commands/BanCmd.ts b/backend/src/plugins/ModActions/commands/BanCmd.ts index d2abfdeb..630ad95d 100644 --- a/backend/src/plugins/ModActions/commands/BanCmd.ts +++ b/backend/src/plugins/ModActions/commands/BanCmd.ts @@ -1,5 +1,5 @@ import humanizeDuration from "humanize-duration"; -import { getMemberLevel } from "knub/dist/helpers"; +import { getMemberLevel } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { clearExpiringTempban, registerExpiringTempban } from "../../../data/loops/expiringTempbansLoop"; diff --git a/backend/src/plugins/ModActions/commands/MassBanCmd.ts b/backend/src/plugins/ModActions/commands/MassBanCmd.ts index e1dd44b2..afef9f1f 100644 --- a/backend/src/plugins/ModActions/commands/MassBanCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassBanCmd.ts @@ -1,5 +1,5 @@ import { Snowflake } from "discord.js"; -import { waitForReply } from "knub/dist/helpers"; +import { waitForReply } from "knub/helpers"; import { performance } from "perf_hooks"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; diff --git a/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts b/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts index d536b760..c5ce37ac 100644 --- a/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts @@ -1,5 +1,5 @@ import { Snowflake } from "discord.js"; -import { waitForReply } from "knub/dist/helpers"; +import { waitForReply } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; diff --git a/backend/src/plugins/ModActions/commands/MassmuteCmd.ts b/backend/src/plugins/ModActions/commands/MassmuteCmd.ts index c7165433..acdd880f 100644 --- a/backend/src/plugins/ModActions/commands/MassmuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassmuteCmd.ts @@ -1,5 +1,5 @@ import { Snowflake } from "discord.js"; -import { waitForReply } from "knub/dist/helpers"; +import { waitForReply } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; diff --git a/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts b/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts index 015dd4c6..bd7c3f3d 100644 --- a/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts @@ -1,6 +1,6 @@ import { GuildMember, GuildTextBasedChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { hasPermission } from "knub/dist/helpers"; +import { hasPermission } from "knub/helpers"; import { LogType } from "../../../data/LogType"; import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { DAYS, errorMessage, resolveMember, resolveUser, SECONDS } from "../../../utils"; diff --git a/backend/src/plugins/Mutes/MutesPlugin.ts b/backend/src/plugins/Mutes/MutesPlugin.ts index 6b3c9aff..5797eed1 100644 --- a/backend/src/plugins/Mutes/MutesPlugin.ts +++ b/backend/src/plugins/Mutes/MutesPlugin.ts @@ -5,7 +5,7 @@ import { GuildCases } from "../../data/GuildCases"; import { onGuildEvent } from "../../data/GuildEvents"; import { GuildLogs } from "../../data/GuildLogs"; import { GuildMutes } from "../../data/GuildMutes"; -import { mapToPublicFn } from "../../pluginUtils"; +import { makeIoTsConfigParser, mapToPublicFn } from "../../pluginUtils"; import { CasesPlugin } from "../Cases/CasesPlugin"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; @@ -65,10 +65,11 @@ export const MutesPlugin = zeppelinGuildPlugin()({ showInDocs: true, info: { prettyName: "Mutes", + configSchema: ConfigSchema, }, - configSchema: ConfigSchema, dependencies: () => [CasesPlugin, LogsPlugin], + configParser: makeIoTsConfigParser(ConfigSchema), defaultOptions, // prettier-ignore @@ -126,7 +127,4 @@ export const MutesPlugin = zeppelinGuildPlugin()({ state.unregisterGuildEventListener?.(); state.events.removeAllListeners(); }, - - // FIXME: Proper inherittance from ZeppelinPluginBlueprint - configParser: (o: any) => o, }); diff --git a/backend/src/plugins/NameHistory/NameHistoryPlugin.ts b/backend/src/plugins/NameHistory/NameHistoryPlugin.ts index 5bdcaf9c..9a9948c8 100644 --- a/backend/src/plugins/NameHistory/NameHistoryPlugin.ts +++ b/backend/src/plugins/NameHistory/NameHistoryPlugin.ts @@ -1,6 +1,7 @@ import { PluginOptions } from "knub"; import { GuildNicknameHistory } from "../../data/GuildNicknameHistory"; import { UsernameHistory } from "../../data/UsernameHistory"; +import { makeIoTsConfigParser } from "../../pluginUtils"; import { Queue } from "../../Queue"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { NamesCmd } from "./commands/NamesCmd"; @@ -24,7 +25,7 @@ export const NameHistoryPlugin = zeppelinGuildPlugin()({ name: "name_history", showInDocs: false, - configSchema: ConfigSchema, + configParser: makeIoTsConfigParser(ConfigSchema), defaultOptions, // prettier-ignore @@ -46,7 +47,4 @@ export const NameHistoryPlugin = zeppelinGuildPlugin()({ state.usernameHistory = new UsernameHistory(); state.updateQueue = new Queue(); }, - - // FIXME: Proper inherittance from ZeppelinPluginBlueprint - configParser: (o: any) => o, }); diff --git a/backend/src/plugins/NameHistory/commands/NamesCmd.ts b/backend/src/plugins/NameHistory/commands/NamesCmd.ts index fcb8c242..81e896f5 100644 --- a/backend/src/plugins/NameHistory/commands/NamesCmd.ts +++ b/backend/src/plugins/NameHistory/commands/NamesCmd.ts @@ -1,5 +1,5 @@ import { Snowflake } from "discord.js"; -import { createChunkedMessage, disableCodeBlocks } from "knub/dist/helpers"; +import { createChunkedMessage, disableCodeBlocks } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { NICKNAME_RETENTION_PERIOD } from "../../../data/cleanup/nicknames"; import { MAX_NICKNAME_ENTRIES_PER_USER } from "../../../data/GuildNicknameHistory"; diff --git a/backend/src/plugins/Persist/PersistPlugin.ts b/backend/src/plugins/Persist/PersistPlugin.ts index 6a3e607c..8b53d9f2 100644 --- a/backend/src/plugins/Persist/PersistPlugin.ts +++ b/backend/src/plugins/Persist/PersistPlugin.ts @@ -1,6 +1,7 @@ import { PluginOptions } from "knub"; import { GuildLogs } from "../../data/GuildLogs"; import { GuildPersistedData } from "../../data/GuildPersistedData"; +import { makeIoTsConfigParser } from "../../pluginUtils"; import { trimPluginDescription } from "../../utils"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; @@ -25,10 +26,11 @@ export const PersistPlugin = zeppelinGuildPlugin()({ Re-apply roles or nicknames for users when they rejoin the server. Mute roles are re-applied automatically, this plugin is not required for that. `), + configSchema: ConfigSchema, }, dependencies: () => [LogsPlugin], - configSchema: ConfigSchema, + configParser: makeIoTsConfigParser(ConfigSchema), defaultOptions, // prettier-ignore @@ -43,7 +45,4 @@ export const PersistPlugin = zeppelinGuildPlugin()({ state.persistedData = GuildPersistedData.getGuildInstance(guild.id); state.logs = new GuildLogs(guild.id); }, - - // FIXME: Proper inherittance from ZeppelinPluginBlueprint - configParser: (o: any) => o, }); diff --git a/backend/src/plugins/Phisherman/PhishermanPlugin.ts b/backend/src/plugins/Phisherman/PhishermanPlugin.ts index 1e5d2aa5..e8f74ce3 100644 --- a/backend/src/plugins/Phisherman/PhishermanPlugin.ts +++ b/backend/src/plugins/Phisherman/PhishermanPlugin.ts @@ -1,6 +1,6 @@ import { PluginOptions } from "knub"; import { hasPhishermanMasterAPIKey, phishermanApiKeyIsValid } from "../../data/Phisherman"; -import { mapToPublicFn } from "../../pluginUtils"; +import { makeIoTsConfigParser, mapToPublicFn } from "../../pluginUtils"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { getDomainInfo } from "./functions/getDomainInfo"; import { pluginInfo } from "./info"; @@ -18,7 +18,7 @@ export const PhishermanPlugin = zeppelinGuildPlugin()({ showInDocs: true, info: pluginInfo, - configSchema: ConfigSchema, + configParser: makeIoTsConfigParser(ConfigSchema), defaultOptions, // prettier-ignore @@ -49,7 +49,4 @@ export const PhishermanPlugin = zeppelinGuildPlugin()({ } } }, - - // FIXME: Proper inherittance from ZeppelinPluginBlueprint - configParser: (o: any) => o, }); diff --git a/backend/src/plugins/Phisherman/info.ts b/backend/src/plugins/Phisherman/info.ts index 5c1ea94f..826da43d 100644 --- a/backend/src/plugins/Phisherman/info.ts +++ b/backend/src/plugins/Phisherman/info.ts @@ -1,5 +1,6 @@ import { trimPluginDescription } from "../../utils"; import { ZeppelinGuildPluginBlueprint } from "../ZeppelinPluginBlueprint"; +import { ConfigSchema } from "./types"; export const pluginInfo: ZeppelinGuildPluginBlueprint["info"] = { prettyName: "Phisherman", @@ -38,4 +39,5 @@ export const pluginInfo: ZeppelinGuildPluginBlueprint["info"] = { clean: true ~~~ `), + configSchema: ConfigSchema, }; diff --git a/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts b/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts index 4cab6026..331410f9 100644 --- a/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts +++ b/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts @@ -1,5 +1,6 @@ import { PluginOptions } from "knub"; import { GuildPingableRoles } from "../../data/GuildPingableRoles"; +import { makeIoTsConfigParser } from "../../pluginUtils"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { PingableRoleDisableCmd } from "./commands/PingableRoleDisableCmd"; import { PingableRoleEnableCmd } from "./commands/PingableRoleEnableCmd"; @@ -24,9 +25,10 @@ export const PingableRolesPlugin = zeppelinGuildPlugin( showInDocs: true, info: { prettyName: "Pingable roles", + configSchema: ConfigSchema, }, - configSchema: ConfigSchema, + configParser: makeIoTsConfigParser(ConfigSchema), defaultOptions, // prettier-ignore @@ -49,7 +51,4 @@ export const PingableRolesPlugin = zeppelinGuildPlugin( state.cache = new Map(); state.timeouts = new Map(); }, - - // FIXME: Proper inherittance from ZeppelinPluginBlueprint - configParser: (o: any) => o, }); diff --git a/backend/src/plugins/Post/PostPlugin.ts b/backend/src/plugins/Post/PostPlugin.ts index 8fbbf704..09d069a2 100644 --- a/backend/src/plugins/Post/PostPlugin.ts +++ b/backend/src/plugins/Post/PostPlugin.ts @@ -3,6 +3,7 @@ import { onGuildEvent } from "../../data/GuildEvents"; import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildScheduledPosts } from "../../data/GuildScheduledPosts"; +import { makeIoTsConfigParser } from "../../pluginUtils"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; @@ -35,10 +36,11 @@ export const PostPlugin = zeppelinGuildPlugin()({ showInDocs: true, info: { prettyName: "Post", + configSchema: ConfigSchema, }, dependencies: () => [TimeAndDatePlugin, LogsPlugin], - configSchema: ConfigSchema, + configParser: makeIoTsConfigParser(ConfigSchema), defaultOptions, // prettier-ignore @@ -73,7 +75,4 @@ export const PostPlugin = zeppelinGuildPlugin()({ state.unregisterGuildEventListener?.(); }, - - // FIXME: Proper inherittance from ZeppelinPluginBlueprint - configParser: (o: any) => o, }); diff --git a/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts b/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts index de710a94..bb7c29dc 100644 --- a/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts +++ b/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts @@ -1,6 +1,7 @@ import { PluginOptions } from "knub"; import { GuildReactionRoles } from "../../data/GuildReactionRoles"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { makeIoTsConfigParser } from "../../pluginUtils"; import { Queue } from "../../Queue"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; @@ -39,10 +40,11 @@ export const ReactionRolesPlugin = zeppelinGuildPlugin( info: { prettyName: "Reaction roles", legacy: "Consider using the [Role buttons](/docs/plugins/role_buttons) plugin instead.", + configSchema: ConfigSchema, }, dependencies: () => [LogsPlugin], - configSchema: ConfigSchema, + configParser: makeIoTsConfigParser(ConfigSchema), defaultOptions, // prettier-ignore @@ -85,7 +87,4 @@ export const ReactionRolesPlugin = zeppelinGuildPlugin( clearTimeout(state.autoRefreshTimeout); } }, - - // FIXME: Proper inherittance from ZeppelinPluginBlueprint - configParser: (o: any) => o, }); diff --git a/backend/src/plugins/Reminders/RemindersPlugin.ts b/backend/src/plugins/Reminders/RemindersPlugin.ts index 43ed2b1f..128e945c 100644 --- a/backend/src/plugins/Reminders/RemindersPlugin.ts +++ b/backend/src/plugins/Reminders/RemindersPlugin.ts @@ -1,6 +1,7 @@ import { PluginOptions } from "knub"; import { onGuildEvent } from "../../data/GuildEvents"; import { GuildReminders } from "../../data/GuildReminders"; +import { makeIoTsConfigParser } from "../../pluginUtils"; import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { RemindCmd } from "./commands/RemindCmd"; @@ -28,10 +29,11 @@ export const RemindersPlugin = zeppelinGuildPlugin()({ showInDocs: true, info: { prettyName: "Reminders", + configSchema: ConfigSchema, }, dependencies: () => [TimeAndDatePlugin], - configSchema: ConfigSchema, + configParser: makeIoTsConfigParser(ConfigSchema), defaultOptions, // prettier-ignore @@ -63,7 +65,4 @@ export const RemindersPlugin = zeppelinGuildPlugin()({ state.unregisterGuildEventListener?.(); state.unloaded = true; }, - - // FIXME: Proper inherittance from ZeppelinPluginBlueprint - configParser: (o: any) => o, }); diff --git a/backend/src/plugins/Reminders/functions/postReminder.ts b/backend/src/plugins/Reminders/functions/postReminder.ts index 91d9d96f..86afbf08 100644 --- a/backend/src/plugins/Reminders/functions/postReminder.ts +++ b/backend/src/plugins/Reminders/functions/postReminder.ts @@ -1,6 +1,6 @@ import { HTTPError, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { disableLinkPreviews } from "knub/dist/helpers"; +import { disableLinkPreviews } from "knub/helpers"; import moment from "moment-timezone"; import { Reminder } from "../../../data/entities/Reminder"; import { DBDateFormat } from "../../../utils"; diff --git a/backend/src/plugins/RoleButtons/RoleButtonsPlugin.ts b/backend/src/plugins/RoleButtons/RoleButtonsPlugin.ts index 04f60d4c..4dc3d345 100644 --- a/backend/src/plugins/RoleButtons/RoleButtonsPlugin.ts +++ b/backend/src/plugins/RoleButtons/RoleButtonsPlugin.ts @@ -1,5 +1,6 @@ +import * as t from "io-ts"; import { GuildRoleButtons } from "../../data/GuildRoleButtons"; -import { StrictValidationError } from "../../validatorUtils"; +import { StrictValidationError, validate } from "../../validatorUtils"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { RoleManagerPlugin } from "../RoleManager/RoleManagerPlugin"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; @@ -13,7 +14,6 @@ import { ConfigSchema, RoleButtonsPluginType } from "./types"; export const RoleButtonsPlugin = zeppelinGuildPlugin()({ name: "role_buttons", - configSchema: ConfigSchema, info: pluginInfo, showInDocs: true, @@ -32,11 +32,10 @@ export const RoleButtonsPlugin = zeppelinGuildPlugin()({ ], }, - configParser(options) { + configParser(input) { // Auto-fill "name" property for buttons based on the object key - const buttonsArray = Array.isArray(options.buttons) ? options.buttons : []; const seenMessages = new Set(); - for (const [name, buttonsConfig] of Object.entries(options.buttons ?? {})) { + for (const [name, buttonsConfig] of Object.entries((input as any).buttons ?? {})) { if (name.length > 16) { throw new StrictValidationError(["Name for role buttons can be at most 16 characters long"]); } @@ -66,8 +65,12 @@ export const RoleButtonsPlugin = zeppelinGuildPlugin()({ } } - // FIXME: any typing lol - return options; + const error = validate(ConfigSchema, input); + if (error) { + throw error; + } + + return input as t.TypeOf; }, dependencies: () => [LogsPlugin, RoleManagerPlugin], diff --git a/backend/src/plugins/RoleButtons/info.ts b/backend/src/plugins/RoleButtons/info.ts index 6f64806e..d63fb17c 100644 --- a/backend/src/plugins/RoleButtons/info.ts +++ b/backend/src/plugins/RoleButtons/info.ts @@ -1,5 +1,6 @@ import { trimPluginDescription } from "../../utils"; import { ZeppelinGuildPluginBlueprint } from "../ZeppelinPluginBlueprint"; +import { ConfigSchema } from "./types"; export const pluginInfo: ZeppelinGuildPluginBlueprint["info"] = { prettyName: "Role buttons", @@ -77,4 +78,5 @@ export const pluginInfo: ZeppelinGuildPluginBlueprint["info"] = { ... # See above for examples for options ~~~ `), + configSchema: ConfigSchema, }; diff --git a/backend/src/plugins/RoleManager/RoleManagerPlugin.ts b/backend/src/plugins/RoleManager/RoleManagerPlugin.ts index 0acddac2..878b2cd4 100644 --- a/backend/src/plugins/RoleManager/RoleManagerPlugin.ts +++ b/backend/src/plugins/RoleManager/RoleManagerPlugin.ts @@ -1,5 +1,5 @@ import { GuildRoleQueue } from "../../data/GuildRoleQueue"; -import { mapToPublicFn } from "../../pluginUtils"; +import { makeIoTsConfigParser, mapToPublicFn } from "../../pluginUtils"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { addPriorityRole } from "./functions/addPriorityRole"; @@ -11,10 +11,10 @@ import { ConfigSchema, RoleManagerPluginType } from "./types"; export const RoleManagerPlugin = zeppelinGuildPlugin()({ name: "role_manager", - configSchema: ConfigSchema, showInDocs: false, dependencies: () => [LogsPlugin], + configParser: makeIoTsConfigParser(ConfigSchema), public: { addRole: mapToPublicFn(addRole), @@ -40,7 +40,4 @@ export const RoleManagerPlugin = zeppelinGuildPlugin()({ state.abortRoleAssignmentLoop = true; await state.pendingRoleAssignmentPromise; }, - - // FIXME: Proper inherittance from ZeppelinPluginBlueprint - configParser: (o: any) => o, }); diff --git a/backend/src/plugins/Roles/RolesPlugin.ts b/backend/src/plugins/Roles/RolesPlugin.ts index a6c3c949..c173ddd1 100644 --- a/backend/src/plugins/Roles/RolesPlugin.ts +++ b/backend/src/plugins/Roles/RolesPlugin.ts @@ -1,5 +1,6 @@ import { PluginOptions } from "knub"; import { GuildLogs } from "../../data/GuildLogs"; +import { makeIoTsConfigParser } from "../../pluginUtils"; import { trimPluginDescription } from "../../utils"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; @@ -39,10 +40,11 @@ export const RolesPlugin = zeppelinGuildPlugin()({ description: trimPluginDescription(` Enables authorised users to add and remove whitelisted roles with a command. `), + configSchema: ConfigSchema, }, - configSchema: ConfigSchema, dependencies: () => [LogsPlugin], + configParser: makeIoTsConfigParser(ConfigSchema), defaultOptions, // prettier-ignore @@ -58,7 +60,4 @@ export const RolesPlugin = zeppelinGuildPlugin()({ state.logs = new GuildLogs(guild.id); }, - - // FIXME: Proper inherittance from ZeppelinPluginBlueprint - configParser: (o: any) => o, }); diff --git a/backend/src/plugins/SelfGrantableRoles/SelfGrantableRolesPlugin.ts b/backend/src/plugins/SelfGrantableRoles/SelfGrantableRolesPlugin.ts index 67c8a435..9a2c7dd1 100644 --- a/backend/src/plugins/SelfGrantableRoles/SelfGrantableRolesPlugin.ts +++ b/backend/src/plugins/SelfGrantableRoles/SelfGrantableRolesPlugin.ts @@ -1,5 +1,7 @@ +import * as t from "io-ts"; import { CooldownManager, PluginOptions } from "knub"; import { trimPluginDescription } from "../../utils"; +import { validate } from "../../validatorUtils"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { RoleAddCmd } from "./commands/RoleAddCmd"; import { RoleHelpCmd } from "./commands/RoleHelpCmd"; @@ -17,9 +19,6 @@ export const SelfGrantableRolesPlugin = zeppelinGuildPlugin { - const config = options; - for (const [key, entry] of Object.entries(config.entries)) { + configParser: (input) => { + const entries = (input as any).entries; + for (const [key, entry] of Object.entries(entries)) { // Apply default entry config - config.entries[key] = { ...defaultSelfGrantableRoleEntry, ...entry }; + entries[key] = { ...defaultSelfGrantableRoleEntry, ...entry }; // Normalize alias names if (entry.roles) { - for (const [roleId, aliases] of Object.entries(entry.roles)) { + for (const [roleId, aliases] of Object.entries(entry.roles)) { entry.roles[roleId] = aliases.map((a) => a.toLowerCase()); } } } - return { ...options, config }; + const error = validate(ConfigSchema, input); + if (error) { + throw error; + } + + return input as t.TypeOf; }, + defaultOptions, // prettier-ignore messageCommands: [ diff --git a/backend/src/plugins/Slowmode/SlowmodePlugin.ts b/backend/src/plugins/Slowmode/SlowmodePlugin.ts index d103c4a4..a79ca25a 100644 --- a/backend/src/plugins/Slowmode/SlowmodePlugin.ts +++ b/backend/src/plugins/Slowmode/SlowmodePlugin.ts @@ -2,6 +2,7 @@ import { PluginOptions } from "knub"; import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildSlowmodes } from "../../data/GuildSlowmodes"; +import { makeIoTsConfigParser } from "../../pluginUtils"; import { SECONDS } from "../../utils"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; @@ -40,6 +41,7 @@ export const SlowmodePlugin = zeppelinGuildPlugin()({ showInDocs: true, info: { prettyName: "Slowmode", + configSchema: ConfigSchema, }, // prettier-ignore @@ -47,7 +49,7 @@ export const SlowmodePlugin = zeppelinGuildPlugin()({ LogsPlugin, ], - configSchema: ConfigSchema, + configParser: makeIoTsConfigParser(ConfigSchema), defaultOptions, // prettier-ignore @@ -84,7 +86,4 @@ export const SlowmodePlugin = zeppelinGuildPlugin()({ state.savedMessages.events.off("create", state.onMessageCreateFn); clearInterval(state.clearInterval); }, - - // FIXME: Proper inherittance from ZeppelinPluginBlueprint - configParser: (o: any) => o, }); diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeListCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeListCmd.ts index 58e2bffd..0fe32f84 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeListCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeListCmd.ts @@ -1,6 +1,6 @@ import { GuildChannel, TextChannel } from "discord.js"; import humanizeDuration from "humanize-duration"; -import { createChunkedMessage } from "knub/dist/helpers"; +import { createChunkedMessage } from "knub/helpers"; import { errorMessage } from "../../../utils"; import { slowmodeCmd } from "../types"; diff --git a/backend/src/plugins/Spam/SpamPlugin.ts b/backend/src/plugins/Spam/SpamPlugin.ts index 1715611e..e4935ca3 100644 --- a/backend/src/plugins/Spam/SpamPlugin.ts +++ b/backend/src/plugins/Spam/SpamPlugin.ts @@ -3,6 +3,7 @@ import { GuildArchives } from "../../data/GuildArchives"; import { GuildLogs } from "../../data/GuildLogs"; import { GuildMutes } from "../../data/GuildMutes"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { makeIoTsConfigParser } from "../../pluginUtils"; import { trimPluginDescription } from "../../utils"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; @@ -52,11 +53,11 @@ export const SpamPlugin = zeppelinGuildPlugin()({ For more advanced spam filtering, check out the Automod plugin! `), legacy: true, + configSchema: ConfigSchema, }, dependencies: () => [LogsPlugin], - - configSchema: ConfigSchema, + configParser: makeIoTsConfigParser(ConfigSchema), defaultOptions, // prettier-ignore @@ -92,7 +93,4 @@ export const SpamPlugin = zeppelinGuildPlugin()({ state.savedMessages.events.off("create", state.onMessageCreateFn); clearInterval(state.expiryInterval); }, - - // FIXME: Proper inherittance from ZeppelinPluginBlueprint - configParser: (o: any) => o, }); diff --git a/backend/src/plugins/Starboard/StarboardPlugin.ts b/backend/src/plugins/Starboard/StarboardPlugin.ts index c67aed35..c4bb4ead 100644 --- a/backend/src/plugins/Starboard/StarboardPlugin.ts +++ b/backend/src/plugins/Starboard/StarboardPlugin.ts @@ -1,8 +1,10 @@ +import * as t from "io-ts"; import { PluginOptions } from "knub"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildStarboardMessages } from "../../data/GuildStarboardMessages"; import { GuildStarboardReactions } from "../../data/GuildStarboardReactions"; import { trimPluginDescription } from "../../utils"; +import { validate } from "../../validatorUtils"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { MigratePinsCmd } from "./commands/MigratePinsCmd"; import { StarboardReactionAddEvt } from "./events/StarboardReactionAddEvt"; @@ -30,9 +32,6 @@ export const StarboardPlugin = zeppelinGuildPlugin()({ name: "starboard", showInDocs: true, - configSchema: ConfigSchema, - defaultOptions, - info: { prettyName: "Starboard", description: trimPluginDescription(` @@ -122,18 +121,25 @@ export const StarboardPlugin = zeppelinGuildPlugin()({ enabled: true ~~~ `), + configSchema: ConfigSchema, }, - configParser(options) { - if (options.boards) { - for (const [name, opts] of Object.entries(options.boards)) { - options.boards[name] = Object.assign({}, defaultStarboardOpts, options.boards[name]); + configParser(input) { + const boards = (input as any).boards; + if (boards) { + for (const [name, opts] of Object.entries(boards)) { + boards[name] = Object.assign({}, defaultStarboardOpts, boards[name]); } } - // FIXME: any typing lol - return options; + const error = validate(ConfigSchema, input); + if (error) { + throw error; + } + + return input as t.TypeOf; }, + defaultOptions, // prettier-ignore messageCommands: [ diff --git a/backend/src/plugins/Tags/TagsPlugin.ts b/backend/src/plugins/Tags/TagsPlugin.ts index 587615b8..2e0a612b 100644 --- a/backend/src/plugins/Tags/TagsPlugin.ts +++ b/backend/src/plugins/Tags/TagsPlugin.ts @@ -1,8 +1,9 @@ import { Snowflake } from "discord.js"; import humanizeDuration from "humanize-duration"; +import * as t from "io-ts"; import { PluginOptions } from "knub"; import moment from "moment-timezone"; -import { StrictValidationError } from "src/validatorUtils"; +import { StrictValidationError, validate } from "src/validatorUtils"; import { GuildArchives } from "../../data/GuildArchives"; import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; @@ -71,9 +72,9 @@ export const TagsPlugin = zeppelinGuildPlugin()({ ${generateTemplateMarkdown(TemplateFunctions)} `), + configSchema: ConfigSchema, }, - configSchema: ConfigSchema, dependencies: () => [LogsPlugin], defaultOptions, @@ -96,17 +97,19 @@ export const TagsPlugin = zeppelinGuildPlugin()({ findTagByName: mapToPublicFn(findTagByName), }, - configParser(options) { - if (options.delete_with_command && options.auto_delete_command) { + configParser(_input) { + const input = _input as any; + + if (input.delete_with_command && input.auto_delete_command) { throw new StrictValidationError([ `Cannot have both (global) delete_with_command and global_delete_invoke enabled`, ]); } // Check each category for conflicting options - if (options.categories) { - for (const [name, opts] of Object.entries(options.categories)) { - const cat = options.categories[name]; + if (input.categories) { + for (const [name, opts] of Object.entries(input.categories)) { + const cat = input.categories[name]; if (cat.delete_with_command && cat.auto_delete_command) { throw new StrictValidationError([ `Cannot have both (category specific) delete_with_command and category_delete_invoke enabled at `, @@ -115,8 +118,12 @@ export const TagsPlugin = zeppelinGuildPlugin()({ } } - // FIXME: any typing lol - return options; + const error = validate(ConfigSchema, input); + if (error) { + throw error; + } + + return input as t.TypeOf; }, beforeLoad(pluginData) { diff --git a/backend/src/plugins/Tags/util/findTagByName.ts b/backend/src/plugins/Tags/util/findTagByName.ts index 4ec61ec5..363006ff 100644 --- a/backend/src/plugins/Tags/util/findTagByName.ts +++ b/backend/src/plugins/Tags/util/findTagByName.ts @@ -1,6 +1,5 @@ import * as t from "io-ts"; -import { GuildPluginData } from "knub"; -import { ExtendedMatchParams } from "knub/dist/config/PluginConfigManager"; +import { ExtendedMatchParams, GuildPluginData } from "knub"; import { Tag, TagsPluginType } from "../types"; export async function findTagByName( diff --git a/backend/src/plugins/Tags/util/matchAndRenderTagFromString.ts b/backend/src/plugins/Tags/util/matchAndRenderTagFromString.ts index db436067..7c781289 100644 --- a/backend/src/plugins/Tags/util/matchAndRenderTagFromString.ts +++ b/backend/src/plugins/Tags/util/matchAndRenderTagFromString.ts @@ -1,7 +1,6 @@ import { GuildMember } from "discord.js"; import escapeStringRegexp from "escape-string-regexp"; -import { GuildPluginData } from "knub"; -import { ExtendedMatchParams } from "knub/dist/config/PluginConfigManager"; +import { ExtendedMatchParams, GuildPluginData } from "knub"; import { StrictMessageContent } from "../../../utils"; import { TagsPluginType, TTagCategory } from "../types"; import { renderTagFromString } from "./renderTagFromString"; diff --git a/backend/src/plugins/Tags/util/renderTagBody.ts b/backend/src/plugins/Tags/util/renderTagBody.ts index 5174e7b1..36103c7e 100644 --- a/backend/src/plugins/Tags/util/renderTagBody.ts +++ b/backend/src/plugins/Tags/util/renderTagBody.ts @@ -1,5 +1,4 @@ -import { GuildPluginData } from "knub"; -import { ExtendedMatchParams } from "knub/dist/config/PluginConfigManager"; +import { ExtendedMatchParams, GuildPluginData } from "knub"; import { renderTemplate, TemplateSafeValue, TemplateSafeValueContainer } from "../../../templateFormatter"; import { renderRecursively, StrictMessageContent } from "../../../utils"; import { TagsPluginType, TTag } from "../types"; diff --git a/backend/src/plugins/TimeAndDate/TimeAndDatePlugin.ts b/backend/src/plugins/TimeAndDate/TimeAndDatePlugin.ts index db425c50..f4d5ded0 100644 --- a/backend/src/plugins/TimeAndDate/TimeAndDatePlugin.ts +++ b/backend/src/plugins/TimeAndDate/TimeAndDatePlugin.ts @@ -1,6 +1,6 @@ import { PluginOptions } from "knub"; import { GuildMemberTimezones } from "../../data/GuildMemberTimezones"; -import { mapToPublicFn } from "../../pluginUtils"; +import { makeIoTsConfigParser, mapToPublicFn } from "../../pluginUtils"; import { trimPluginDescription } from "../../utils"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { ResetTimezoneCmd } from "./commands/ResetTimezoneCmd"; @@ -39,9 +39,10 @@ export const TimeAndDatePlugin = zeppelinGuildPlugin()({ description: trimPluginDescription(` Allows controlling the displayed time/date formats and timezones `), + configSchema: ConfigSchema, }, - configSchema: ConfigSchema, + configParser: makeIoTsConfigParser(ConfigSchema), defaultOptions, // prettier-ignore @@ -64,7 +65,4 @@ export const TimeAndDatePlugin = zeppelinGuildPlugin()({ state.memberTimezones = GuildMemberTimezones.getGuildInstance(guild.id); }, - - // FIXME: Proper inherittance from ZeppelinPluginBlueprint - configParser: (o: any) => o, }); diff --git a/backend/src/plugins/UsernameSaver/UsernameSaverPlugin.ts b/backend/src/plugins/UsernameSaver/UsernameSaverPlugin.ts index 15995214..a14ef791 100644 --- a/backend/src/plugins/UsernameSaver/UsernameSaverPlugin.ts +++ b/backend/src/plugins/UsernameSaver/UsernameSaverPlugin.ts @@ -1,5 +1,6 @@ import * as t from "io-ts"; import { UsernameHistory } from "../../data/UsernameHistory"; +import { makeIoTsConfigParser } from "../../pluginUtils"; import { Queue } from "../../Queue"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { MessageCreateUpdateUsernameEvt, VoiceChannelJoinUpdateUsernameEvt } from "./events/UpdateUsernameEvts"; @@ -9,7 +10,7 @@ export const UsernameSaverPlugin = zeppelinGuildPlugin( name: "username_saver", showInDocs: false, - configSchema: t.type({}), + configParser: makeIoTsConfigParser(t.type({})), // prettier-ignore events: [ @@ -23,7 +24,4 @@ export const UsernameSaverPlugin = zeppelinGuildPlugin( state.usernameHistory = new UsernameHistory(); state.updateQueue = new Queue(); }, - - // FIXME: Proper inherittance from ZeppelinPluginBlueprint - configParser: (o: any) => o, }); diff --git a/backend/src/plugins/Utility/UtilityPlugin.ts b/backend/src/plugins/Utility/UtilityPlugin.ts index 603c4ee6..7f5b2d7e 100644 --- a/backend/src/plugins/Utility/UtilityPlugin.ts +++ b/backend/src/plugins/Utility/UtilityPlugin.ts @@ -5,7 +5,7 @@ import { GuildCases } from "../../data/GuildCases"; import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { Supporters } from "../../data/Supporters"; -import { sendSuccessMessage } from "../../pluginUtils"; +import { makeIoTsConfigParser, sendSuccessMessage } from "../../pluginUtils"; import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { ModActionsPlugin } from "../ModActions/ModActionsPlugin"; @@ -117,10 +117,11 @@ export const UtilityPlugin = zeppelinGuildPlugin()({ showInDocs: true, info: { prettyName: "Utility", + configSchema: ConfigSchema, }, dependencies: () => [TimeAndDatePlugin, ModActionsPlugin, LogsPlugin], - configSchema: ConfigSchema, + configParser: makeIoTsConfigParser(ConfigSchema), defaultOptions, // prettier-ignore @@ -221,7 +222,4 @@ export const UtilityPlugin = zeppelinGuildPlugin()({ beforeUnload(pluginData) { discardRegExpRunner(`guild-${pluginData.guild.id}`); }, - - // FIXME: Proper inherittance from ZeppelinPluginBlueprint - configParser: (o: any) => o, }); diff --git a/backend/src/plugins/Utility/commands/HelpCmd.ts b/backend/src/plugins/Utility/commands/HelpCmd.ts index d4b0e859..7e3391fd 100644 --- a/backend/src/plugins/Utility/commands/HelpCmd.ts +++ b/backend/src/plugins/Utility/commands/HelpCmd.ts @@ -1,5 +1,4 @@ -import { LoadedGuildPlugin } from "knub"; -import { PluginCommandDefinition } from "knub/dist/commands/commandUtils"; +import { LoadedGuildPlugin, PluginCommandDefinition } from "knub"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { createChunkedMessage } from "../../../utils"; import { utilityCmd } from "../types"; @@ -32,7 +31,6 @@ export const HelpCmd = utilityCmd({ if (strTrigger.startsWith(searchStr)) { matchingCommands.push({ plugin, - // @ts-expect-error command: registeredCommand, }); break; diff --git a/backend/src/plugins/Utility/commands/InfoCmd.ts b/backend/src/plugins/Utility/commands/InfoCmd.ts index 567ce1ea..63d0ae81 100644 --- a/backend/src/plugins/Utility/commands/InfoCmd.ts +++ b/backend/src/plugins/Utility/commands/InfoCmd.ts @@ -1,5 +1,5 @@ import { Snowflake } from "discord.js"; -import { getChannelId, getRoleId } from "knub/dist/utils"; +import { getChannelId, getRoleId } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; import { isValidSnowflake, noop, parseInviteCodeInput, resolveInvite, resolveUser } from "../../../utils"; diff --git a/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts b/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts index 3f15e87f..2e97999c 100644 --- a/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts @@ -1,7 +1,6 @@ import { APIEmbed, MessageType, Snowflake, TextChannel } from "discord.js"; import humanizeDuration from "humanize-duration"; -import { GuildPluginData } from "knub"; -import { getDefaultPrefix } from "knub/dist/commands/commandUtils"; +import { getDefaultMessageCommandPrefix, GuildPluginData } from "knub"; import moment from "moment-timezone"; import { chunkMessageLines, EmbedWith, messageLink, preEmbedPadding, trimEmptyLines, trimLines } from "../../../utils"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; @@ -136,8 +135,7 @@ export async function getMessageInfoEmbed( } if (message.embeds.length) { - // @ts-expect-error - const prefix = pluginData.fullConfig.prefix || getDefaultPrefix(pluginData.client); + const prefix = pluginData.fullConfig.prefix || getDefaultMessageCommandPrefix(pluginData.client); embed.fields.push({ name: preEmbedPadding + "Embeds", value: `Message contains an embed, use \`${prefix}source\` to see the embed source`, diff --git a/backend/src/plugins/Utility/search.ts b/backend/src/plugins/Utility/search.ts index cf709706..4340ad23 100644 --- a/backend/src/plugins/Utility/search.ts +++ b/backend/src/plugins/Utility/search.ts @@ -10,8 +10,7 @@ import { User, } from "discord.js"; import escapeStringRegexp from "escape-string-regexp"; -import { GuildPluginData } from "knub"; -import { ArgsFromSignatureOrArray } from "knub/dist/commands/commandUtils"; +import { ArgsFromSignatureOrArray, GuildPluginData } from "knub"; import moment from "moment-timezone"; import { getBaseUrl, sendErrorMessage } from "../../pluginUtils"; import { allowTimeout, RegExpRunner } from "../../RegExpRunner"; @@ -192,6 +191,7 @@ export async function displaySearch( if (msg.author.id !== interaction.user.id) { interaction .reply({ content: `You are not permitted to use these buttons.`, ephemeral: true }) + // tslint:disable-next-line no-console .catch((err) => console.trace(err.message)); } else { if (interaction.customId === `previousButton:${idMod}` && currentPage > 1) { diff --git a/backend/src/plugins/WelcomeMessage/WelcomeMessagePlugin.ts b/backend/src/plugins/WelcomeMessage/WelcomeMessagePlugin.ts index bb319b57..e007b968 100644 --- a/backend/src/plugins/WelcomeMessage/WelcomeMessagePlugin.ts +++ b/backend/src/plugins/WelcomeMessage/WelcomeMessagePlugin.ts @@ -1,5 +1,6 @@ import { PluginOptions } from "knub"; import { GuildLogs } from "../../data/GuildLogs"; +import { makeIoTsConfigParser } from "../../pluginUtils"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { SendWelcomeMessageEvt } from "./events/SendWelcomeMessageEvt"; @@ -18,10 +19,11 @@ export const WelcomeMessagePlugin = zeppelinGuildPlugin [LogsPlugin], + configParser: makeIoTsConfigParser(ConfigSchema), defaultOptions, // prettier-ignore @@ -35,7 +37,4 @@ export const WelcomeMessagePlugin = zeppelinGuildPlugin o, }); diff --git a/backend/src/plugins/ZeppelinPluginBlueprint.ts b/backend/src/plugins/ZeppelinPluginBlueprint.ts index a2ab9869..165c67b5 100644 --- a/backend/src/plugins/ZeppelinPluginBlueprint.ts +++ b/backend/src/plugins/ZeppelinPluginBlueprint.ts @@ -8,9 +8,6 @@ import { GuildPluginBlueprint, GuildPluginData, } from "knub"; -import { PluginOptions } from "knub/dist/config/configTypes"; -import { Awaitable } from "knub/dist/utils"; -import { getPluginConfigParser } from "../pluginUtils"; import { TMarkdown } from "../types"; /** @@ -19,42 +16,30 @@ import { TMarkdown } from "../types"; export interface ZeppelinGuildPluginBlueprint = GuildPluginData> extends GuildPluginBlueprint { - configSchema: t.TypeC; showInDocs?: boolean; - info?: { prettyName: string; description?: TMarkdown; usageGuide?: TMarkdown; configurationGuide?: TMarkdown; legacy?: boolean | string; + configSchema?: t.Type; }; - - // FIXME: need proper typings here - configParser: ( - options: TPluginData["_pluginType"]["config"], - strict?: boolean, - ) => Awaitable>; } -export function zeppelinGuildPlugin( - blueprint: TBlueprint, -): TBlueprint & { configParser: ZeppelinGuildPluginBlueprint["configParser"] }; +export function zeppelinGuildPlugin(blueprint: TBlueprint): TBlueprint; export function zeppelinGuildPlugin(): < TBlueprint extends ZeppelinGuildPluginBlueprint>, >( blueprint: TBlueprint, -) => TBlueprint & { - configParser: ZeppelinGuildPluginBlueprint>["configParser"]; -}; +) => TBlueprint; export function zeppelinGuildPlugin(...args) { if (args.length) { const blueprint = guildPlugin( ...(args as Parameters), ) as unknown as ZeppelinGuildPluginBlueprint; - blueprint.configParser = getPluginConfigParser(blueprint, blueprint.configParser); return blueprint; } else { return zeppelinGuildPlugin as (name, blueprint) => ZeppelinGuildPluginBlueprint; @@ -66,31 +51,23 @@ export function zeppelinGuildPlugin(...args) { */ export interface ZeppelinGlobalPluginBlueprint - extends GlobalPluginBlueprint> { - configSchema: t.TypeC; - // FIXME: need proper typings here - configParser: (options: TPluginType["config"], strict?: boolean) => Awaitable>; -} + extends GlobalPluginBlueprint> {} export function zeppelinGlobalPlugin( blueprint: TBlueprint, -): TBlueprint & { configParser: ZeppelinGlobalPluginBlueprint["configParser"] }; +): TBlueprint; export function zeppelinGlobalPlugin(): < TBlueprint extends ZeppelinGlobalPluginBlueprint, >( blueprint: TBlueprint, -) => TBlueprint & { - configParser: ZeppelinGlobalPluginBlueprint["configParser"]; -}; +) => TBlueprint; export function zeppelinGlobalPlugin(...args) { if (args.length) { const blueprint = globalPlugin( ...(args as Parameters), ) as unknown as ZeppelinGlobalPluginBlueprint; - // @ts-expect-error FIXME: Check the types here - blueprint.configParser = getPluginConfigParser(blueprint, blueprint.configParser); return blueprint; } else { return zeppelinGlobalPlugin as (name, blueprint) => ZeppelinGlobalPluginBlueprint; diff --git a/backend/src/profiler.ts b/backend/src/profiler.ts index b9d0222f..e0b03f20 100644 --- a/backend/src/profiler.ts +++ b/backend/src/profiler.ts @@ -1,5 +1,6 @@ -import { Profiler } from "knub/dist/Profiler"; +import type { Knub } from "knub"; +type Profiler = Knub["profiler"]; let profiler: Profiler | null = null; export function getProfiler() { diff --git a/backend/src/utils/async.ts b/backend/src/utils/async.ts index 5479436a..196067be 100644 --- a/backend/src/utils/async.ts +++ b/backend/src/utils/async.ts @@ -1,4 +1,4 @@ -import { Awaitable } from "knub/dist/utils"; +import { Awaitable } from "./typeUtils"; export async function asyncReduce( arr: T[], diff --git a/backend/src/utils/createPaginatedMessage.ts b/backend/src/utils/createPaginatedMessage.ts index b3c7d7ec..18e8f3d0 100644 --- a/backend/src/utils/createPaginatedMessage.ts +++ b/backend/src/utils/createPaginatedMessage.ts @@ -9,8 +9,8 @@ import { TextBasedChannel, User, } from "discord.js"; -import { Awaitable } from "knub/dist/utils"; import { MINUTES, noop } from "../utils"; +import { Awaitable } from "./typeUtils"; import Timeout = NodeJS.Timeout; export type LoadPageFn = (page: number) => Awaitable; diff --git a/backend/src/utils/easyProfiler.ts b/backend/src/utils/easyProfiler.ts index 5a7ae065..28918526 100644 --- a/backend/src/utils/easyProfiler.ts +++ b/backend/src/utils/easyProfiler.ts @@ -1,7 +1,9 @@ -import { Profiler } from "knub/dist/Profiler"; +import type { Knub } from "knub"; import { performance } from "perf_hooks"; import { noop, SECONDS } from "../utils"; +type Profiler = Knub["profiler"]; + let _profilingEnabled = false; export const profilingEnabled = () => { diff --git a/backend/src/utils/getGuildPrefix.ts b/backend/src/utils/getGuildPrefix.ts index 6eb51494..8623dc09 100644 --- a/backend/src/utils/getGuildPrefix.ts +++ b/backend/src/utils/getGuildPrefix.ts @@ -1,7 +1,5 @@ -import { GuildPluginData } from "knub"; -import { getDefaultPrefix } from "knub/dist/commands/commandUtils"; +import { getDefaultMessageCommandPrefix, GuildPluginData } from "knub"; export function getGuildPrefix(pluginData: GuildPluginData) { - // @ts-expect-error: discord.js version mismatch - return pluginData.fullConfig.prefix || getDefaultPrefix(pluginData.client); + return pluginData.fullConfig.prefix || getDefaultMessageCommandPrefix(pluginData.client); } diff --git a/backend/src/utils/typeUtils.ts b/backend/src/utils/typeUtils.ts index 40c69b1a..7c8b4cbd 100644 --- a/backend/src/utils/typeUtils.ts +++ b/backend/src/utils/typeUtils.ts @@ -9,6 +9,8 @@ export declare type WithRequiredProps = T & { // https://devblogs.microsoft.com/typescript/announcing-typescript-4-1/ export type Awaited = T extends PromiseLike ? Awaited : T; +export type Awaitable = T | Promise; + export type DeepMutable = { -readonly [P in keyof T]: DeepMutable; }; diff --git a/backend/src/utils/waitForInteraction.ts b/backend/src/utils/waitForInteraction.ts index f7917819..70688047 100644 --- a/backend/src/utils/waitForInteraction.ts +++ b/backend/src/utils/waitForInteraction.ts @@ -7,9 +7,9 @@ import { MessageComponentInteraction, MessageCreateOptions, } from "discord.js"; -import { noop } from "knub/dist/utils"; import moment from "moment"; import uuidv4 from "uuid/v4"; +import { noop } from "../utils"; export async function waitForButtonConfirm( channel: GuildTextBasedChannel, @@ -37,6 +37,7 @@ export async function waitForButtonConfirm( if (options?.restrictToId && options.restrictToId !== interaction.user.id) { interaction .reply({ content: `You are not permitted to use these buttons.`, ephemeral: true }) + // tslint:disable-next-line no-console .catch((err) => console.trace(err.message)); } else { if (interaction.customId.startsWith(`confirmButton:${idMod}:`)) { diff --git a/backend/tsconfig.json b/backend/tsconfig.json index cde827e4..04e9bf4d 100644 --- a/backend/tsconfig.json +++ b/backend/tsconfig.json @@ -1,13 +1,13 @@ { "compilerOptions": { - "moduleResolution": "node", - "module": "commonjs", + "moduleResolution": "NodeNext", + "module": "NodeNext", "noImplicitAny": false, "allowSyntheticDefaultImports": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, - "target": "es2020", - "lib": ["esnext"], + "target": "es2022", + "lib": ["es2022"], "baseUrl": ".", "resolveJsonModule": true, "esModuleInterop": true, diff --git a/package-lock.json b/package-lock.json index e0caec99..6a7256a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,9 +7,6 @@ "": { "name": "@zeppelin/zeppelin", "version": "0.0.1", - "dependencies": { - "knub": "^30.0.0-beta.39" - }, "devDependencies": { "husky": "^3.0.9", "lint-staged": "^9.4.2", @@ -40,48 +37,6 @@ "js-tokens": "^4.0.0" } }, - "node_modules/@discordjs/builders": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.5.0.tgz", - "integrity": "sha512-HP5y4Rqw68o61Qv4qM5tVmDbWi4mdTFftqIOGRo33SNPpLJ1Ga3KEIR2ibKofkmsoQhEpLmopD1AZDs3cKpHuw==", - "dependencies": { - "@sindresorhus/is": "^4.0.1", - "discord-api-types": "^0.22.0", - "ow": "^0.27.0", - "ts-mixer": "^6.0.0", - "tslib": "^2.3.0" - }, - "engines": { - "node": ">=14.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/@discordjs/builders/node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" - }, - "node_modules/@discordjs/collection": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.2.1.tgz", - "integrity": "sha512-vhxqzzM8gkomw0TYRF3tgx7SwElzUlXT/Aa41O7mOcyN6wIJfj5JmDWaO5XGKsGSsNx7F3i5oIlrucCCWV1Nog==", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@discordjs/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@discordjs/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-ZfFsbgEXW71Rw/6EtBdrP5VxBJy4dthyC0tpQKGKmYFImlmmrykO14Za+BiIVduwjte0jXEBlhSKf0MWbFp9Eg==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", @@ -129,26 +84,6 @@ "node": ">=6" } }, - "node_modules/@sapphire/async-queue": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.1.4.tgz", - "integrity": "sha512-fFrlF/uWpGOX5djw5Mu2Hnnrunao75WGey0sP0J3jnhmrJ5TAPzHYOmytD5iN/+pMxS+f+u/gezqHa9tPhRHEA==", - "engines": { - "node": ">=14", - "npm": ">=6" - } - }, - "node_modules/@sindresorhus/is": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.1.tgz", - "integrity": "sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, "node_modules/@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", @@ -175,7 +110,8 @@ "node_modules/@types/node": { "version": "12.12.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.5.tgz", - "integrity": "sha512-KEjODidV4XYUlJBF3XdjSH5FWoMCtO0utnhtdLf1AgeuZLOrRbvmU/gaRCVg7ZaQDjVf3l84egiY0mRNe5xE4A==" + "integrity": "sha512-KEjODidV4XYUlJBF3XdjSH5FWoMCtO0utnhtdLf1AgeuZLOrRbvmU/gaRCVg7ZaQDjVf3l84egiY0mRNe5xE4A==", + "dev": true }, "node_modules/@types/normalize-package-data": { "version": "2.4.0", @@ -183,14 +119,6 @@ "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", "dev": true }, - "node_modules/@types/ws": { - "version": "7.4.7", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", - "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/aggregate-error": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", @@ -261,11 +189,6 @@ "node": ">=8" } }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, "node_modules/balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -414,17 +337,6 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -509,14 +421,6 @@ "node": ">=8" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/diff": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", @@ -538,55 +442,6 @@ "node": ">=8" } }, - "node_modules/discord-api-types": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.22.0.tgz", - "integrity": "sha512-l8yD/2zRbZItUQpy7ZxBJwaLX/Bs2TGaCthRppk8Sw24LOIWg12t9JEreezPoYD0SQcC2htNNo27kYEpYW/Srg==", - "engines": { - "node": ">=12" - } - }, - "node_modules/discord.js": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.1.0.tgz", - "integrity": "sha512-gxO4CXKdHpqA+WKG+f5RNnd3srTDj5uFJHgOathksDE90YNq/Qijkd2WlMgTTMS6AJoEnHxI7G9eDQHCuZ+xDA==", - "dependencies": { - "@discordjs/builders": "^0.5.0", - "@discordjs/collection": "^0.2.1", - "@discordjs/form-data": "^3.0.1", - "@sapphire/async-queue": "^1.1.4", - "@types/ws": "^7.4.7", - "discord-api-types": "^0.22.0", - "node-fetch": "^2.6.1", - "ws": "^7.5.1" - }, - "engines": { - "node": ">=16.6.0", - "npm": ">=7.0.0" - } - }, - "node_modules/dot-prop": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", - "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/dot-prop/node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "engines": { - "node": ">=8" - } - }, "node_modules/elegant-spinner": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", @@ -1065,33 +920,6 @@ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, - "node_modules/knub": { - "version": "30.0.0-beta.39", - "resolved": "https://registry.npmjs.org/knub/-/knub-30.0.0-beta.39.tgz", - "integrity": "sha512-L9RYkqh7YcWfw0ZXdGrKEZru/J+mkiyn+8vi1xCvjEdKMPdq4Gov/SG4suajMFhhX3RXdvh8BoE/3gbR2cq4xA==", - "dependencies": { - "discord-api-types": "^0.22.0", - "discord.js": "^13.0.1", - "knub-command-manager": "^9.1.0", - "ts-essentials": "^6.0.7" - } - }, - "node_modules/knub-command-manager": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/knub-command-manager/-/knub-command-manager-9.1.0.tgz", - "integrity": "sha512-pEtpWElbBoTRSL8kWSPRrTIuTIdvYGkP/wzOn77cieumC02adfwEt1Cc09HFvVT4ib35nf1y31oul36csaG7Vg==", - "dependencies": { - "escape-string-regexp": "^2.0.0" - } - }, - "node_modules/knub-command-manager/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "engines": { - "node": ">=8" - } - }, "node_modules/lines-and-columns": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", @@ -1398,11 +1226,6 @@ "node": ">=8" } }, - "node_modules/lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" - }, "node_modules/log-symbols": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", @@ -1457,25 +1280,6 @@ "node": ">=8" } }, - "node_modules/mime-db": { - "version": "1.49.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", - "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.32", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", - "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", - "dependencies": { - "mime-db": "1.49.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", @@ -1528,14 +1332,6 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, - "node_modules/node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", - "engines": { - "node": "4.x || >=6.0.0" - } - }, "node_modules/normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -1617,44 +1413,6 @@ "opencollective-postinstall": "index.js" } }, - "node_modules/ow": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/ow/-/ow-0.27.0.tgz", - "integrity": "sha512-SGnrGUbhn4VaUGdU0EJLMwZWSupPmF46hnTRII7aCLCrqixTAC5eKo8kI4/XXf1eaaI8YEVT+3FeGNJI9himAQ==", - "dependencies": { - "@sindresorhus/is": "^4.0.1", - "callsites": "^3.1.0", - "dot-prop": "^6.0.1", - "lodash.isequal": "^4.5.0", - "type-fest": "^1.2.1", - "vali-date": "^1.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ow/node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/ow/node_modules/type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", @@ -2171,19 +1929,6 @@ "node": ">=8.0" } }, - "node_modules/ts-essentials": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-6.0.7.tgz", - "integrity": "sha512-2E4HIIj4tQJlIHuATRHayv0EfMGK3ris/GRk1E3CFnsZzeNV+hUmelbaTZHLtXaZppM5oLhHRtO04gINC4Jusw==", - "peerDependencies": { - "typescript": ">=3.7.0" - } - }, - "node_modules/ts-mixer": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.0.tgz", - "integrity": "sha512-nXIb1fvdY5CBSrDIblLn73NW0qRDk5yJ0Sk1qPBF560OdJfQp9jhl+0tzcY09OZ9U+6GpeoI9RjwoIKFIoB9MQ==" - }, "node_modules/tslib": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", @@ -2257,6 +2002,7 @@ "version": "4.9.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -2265,14 +2011,6 @@ "node": ">=4.2.0" } }, - "node_modules/vali-date": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/vali-date/-/vali-date-1.0.0.tgz", - "integrity": "sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY=", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -2356,26 +2094,6 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true - }, - "node_modules/ws": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", - "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } } }, "dependencies": { @@ -2399,40 +2117,6 @@ "js-tokens": "^4.0.0" } }, - "@discordjs/builders": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.5.0.tgz", - "integrity": "sha512-HP5y4Rqw68o61Qv4qM5tVmDbWi4mdTFftqIOGRo33SNPpLJ1Ga3KEIR2ibKofkmsoQhEpLmopD1AZDs3cKpHuw==", - "requires": { - "@sindresorhus/is": "^4.0.1", - "discord-api-types": "^0.22.0", - "ow": "^0.27.0", - "ts-mixer": "^6.0.0", - "tslib": "^2.3.0" - }, - "dependencies": { - "tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" - } - } - }, - "@discordjs/collection": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.2.1.tgz", - "integrity": "sha512-vhxqzzM8gkomw0TYRF3tgx7SwElzUlXT/Aa41O7mOcyN6wIJfj5JmDWaO5XGKsGSsNx7F3i5oIlrucCCWV1Nog==" - }, - "@discordjs/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@discordjs/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-ZfFsbgEXW71Rw/6EtBdrP5VxBJy4dthyC0tpQKGKmYFImlmmrykO14Za+BiIVduwjte0jXEBlhSKf0MWbFp9Eg==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, "@nodelib/fs.scandir": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", @@ -2468,16 +2152,6 @@ "any-observable": "^0.3.0" } }, - "@sapphire/async-queue": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.1.4.tgz", - "integrity": "sha512-fFrlF/uWpGOX5djw5Mu2Hnnrunao75WGey0sP0J3jnhmrJ5TAPzHYOmytD5iN/+pMxS+f+u/gezqHa9tPhRHEA==" - }, - "@sindresorhus/is": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.1.tgz", - "integrity": "sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g==" - }, "@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", @@ -2504,7 +2178,8 @@ "@types/node": { "version": "12.12.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.5.tgz", - "integrity": "sha512-KEjODidV4XYUlJBF3XdjSH5FWoMCtO0utnhtdLf1AgeuZLOrRbvmU/gaRCVg7ZaQDjVf3l84egiY0mRNe5xE4A==" + "integrity": "sha512-KEjODidV4XYUlJBF3XdjSH5FWoMCtO0utnhtdLf1AgeuZLOrRbvmU/gaRCVg7ZaQDjVf3l84egiY0mRNe5xE4A==", + "dev": true }, "@types/normalize-package-data": { "version": "2.4.0", @@ -2512,14 +2187,6 @@ "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", "dev": true }, - "@types/ws": { - "version": "7.4.7", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", - "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", - "requires": { - "@types/node": "*" - } - }, "aggregate-error": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", @@ -2572,11 +2239,6 @@ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -2695,14 +2357,6 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, "commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -2777,11 +2431,6 @@ "slash": "^3.0.0" } }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, "diff": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", @@ -2797,41 +2446,6 @@ "path-type": "^4.0.0" } }, - "discord-api-types": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.22.0.tgz", - "integrity": "sha512-l8yD/2zRbZItUQpy7ZxBJwaLX/Bs2TGaCthRppk8Sw24LOIWg12t9JEreezPoYD0SQcC2htNNo27kYEpYW/Srg==" - }, - "discord.js": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.1.0.tgz", - "integrity": "sha512-gxO4CXKdHpqA+WKG+f5RNnd3srTDj5uFJHgOathksDE90YNq/Qijkd2WlMgTTMS6AJoEnHxI7G9eDQHCuZ+xDA==", - "requires": { - "@discordjs/builders": "^0.5.0", - "@discordjs/collection": "^0.2.1", - "@discordjs/form-data": "^3.0.1", - "@sapphire/async-queue": "^1.1.4", - "@types/ws": "^7.4.7", - "discord-api-types": "^0.22.0", - "node-fetch": "^2.6.1", - "ws": "^7.5.1" - } - }, - "dot-prop": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", - "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", - "requires": { - "is-obj": "^2.0.0" - }, - "dependencies": { - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" - } - } - }, "elegant-spinner": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", @@ -3205,32 +2819,6 @@ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, - "knub": { - "version": "30.0.0-beta.39", - "resolved": "https://registry.npmjs.org/knub/-/knub-30.0.0-beta.39.tgz", - "integrity": "sha512-L9RYkqh7YcWfw0ZXdGrKEZru/J+mkiyn+8vi1xCvjEdKMPdq4Gov/SG4suajMFhhX3RXdvh8BoE/3gbR2cq4xA==", - "requires": { - "discord-api-types": "^0.22.0", - "discord.js": "^13.0.1", - "knub-command-manager": "^9.1.0", - "ts-essentials": "^6.0.7" - } - }, - "knub-command-manager": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/knub-command-manager/-/knub-command-manager-9.1.0.tgz", - "integrity": "sha512-pEtpWElbBoTRSL8kWSPRrTIuTIdvYGkP/wzOn77cieumC02adfwEt1Cc09HFvVT4ib35nf1y31oul36csaG7Vg==", - "requires": { - "escape-string-regexp": "^2.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==" - } - } - }, "lines-and-columns": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", @@ -3470,11 +3058,6 @@ "p-locate": "^4.1.0" } }, - "lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" - }, "log-symbols": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", @@ -3517,19 +3100,6 @@ "picomatch": "^2.0.5" } }, - "mime-db": { - "version": "1.49.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", - "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==" - }, - "mime-types": { - "version": "2.1.32", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", - "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", - "requires": { - "mime-db": "1.49.0" - } - }, "mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", @@ -3574,11 +3144,6 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, - "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" - }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -3642,31 +3207,6 @@ "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==", "dev": true }, - "ow": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/ow/-/ow-0.27.0.tgz", - "integrity": "sha512-SGnrGUbhn4VaUGdU0EJLMwZWSupPmF46hnTRII7aCLCrqixTAC5eKo8kI4/XXf1eaaI8YEVT+3FeGNJI9himAQ==", - "requires": { - "@sindresorhus/is": "^4.0.1", - "callsites": "^3.1.0", - "dot-prop": "^6.0.1", - "lodash.isequal": "^4.5.0", - "type-fest": "^1.2.1", - "vali-date": "^1.0.0" - }, - "dependencies": { - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" - }, - "type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==" - } - } - }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", @@ -4053,17 +3593,6 @@ "is-number": "^7.0.0" } }, - "ts-essentials": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-6.0.7.tgz", - "integrity": "sha512-2E4HIIj4tQJlIHuATRHayv0EfMGK3ris/GRk1E3CFnsZzeNV+hUmelbaTZHLtXaZppM5oLhHRtO04gINC4Jusw==", - "requires": {} - }, - "ts-mixer": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.0.tgz", - "integrity": "sha512-nXIb1fvdY5CBSrDIblLn73NW0qRDk5yJ0Sk1qPBF560OdJfQp9jhl+0tzcY09OZ9U+6GpeoI9RjwoIKFIoB9MQ==" - }, "tslib": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", @@ -4115,12 +3644,8 @@ "typescript": { "version": "4.9.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==" - }, - "vali-date": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/vali-date/-/vali-date-1.0.0.tgz", - "integrity": "sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY=" + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true }, "validate-npm-package-license": { "version": "3.0.4", @@ -4189,12 +3714,6 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true - }, - "ws": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", - "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==", - "requires": {} } } } diff --git a/package.json b/package.json index 1ef0c5fe..5091aa24 100644 --- a/package.json +++ b/package.json @@ -28,8 +28,5 @@ "prettier --write", "git add" ] - }, - "dependencies": { - "knub": "^30.0.0-beta.39" } } diff --git a/shared/tsconfig.json b/shared/tsconfig.json index 4b02fab0..c5c16316 100644 --- a/shared/tsconfig.json +++ b/shared/tsconfig.json @@ -1,13 +1,13 @@ { "compilerOptions": { - "moduleResolution": "node", - "module": "commonjs", + "moduleResolution": "NodeNext", + "module": "NodeNext", "noImplicitAny": false, "allowSyntheticDefaultImports": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, - "target": "es2018", - "lib": ["esnext"], + "target": "es2022", + "lib": ["es2022"], "baseUrl": "src", "resolveJsonModule": true, "esModuleInterop": true,