Turn on strict TS compilation. Fix up and tweak types accordingly.

This commit is contained in:
Dragory 2020-11-09 20:03:57 +02:00
parent 690955a399
commit 629002b8d9
No known key found for this signature in database
GPG key ID: 5F387BA66DF8AAC1
172 changed files with 720 additions and 534 deletions

View file

@ -1,6 +1,6 @@
import { utilityCmd } from "../types";
import { multiSorter, resolveMember, sorter } from "../../../utils";
import { GuildChannel, MessageContent } from "eris";
import { EmbedWith, multiSorter, resolveMember, sorter } from "../../../utils";
import { GuildChannel, MessageContent, Role } from "eris";
import { getCurrentUptime } from "../../../uptime";
import humanizeDuration from "humanize-duration";
import LCL from "last-commit-log";
@ -40,7 +40,7 @@ export const AboutCmd = utilityCmd({
version = "?";
}
const shard = pluginData.client.shards.get(pluginData.client.guildShardMap[pluginData.guild.id]);
const shard = pluginData.client.shards.get(pluginData.client.guildShardMap[pluginData.guild.id])!;
const lastReload = humanizeDuration(Date.now() - pluginData.state.lastReload, {
largest: 2,
@ -59,12 +59,12 @@ export const AboutCmd = utilityCmd({
const loadedPlugins = Array.from(
pluginData
.getKnubInstance()
.getLoadedGuild(pluginData.guild.id)
.getLoadedGuild(pluginData.guild.id)!
.loadedPlugins.keys(),
);
loadedPlugins.sort();
const aboutContent: MessageContent = {
const aboutContent: MessageContent & { embed: EmbedWith<"title" | "fields"> } = {
embed: {
title: `About ${pluginData.client.user.username}`,
fields: [
@ -101,7 +101,7 @@ export const AboutCmd = utilityCmd({
// For the embed color, find the highest colored role the bot has - this is their color on the server as well
const botMember = await resolveMember(pluginData.client, pluginData.guild, pluginData.client.user.id);
let botRoles = botMember.roles.map(r => (msg.channel as GuildChannel).guild.roles.get(r));
let botRoles = botMember?.roles.map(r => (msg.channel as GuildChannel).guild.roles.get(r)!) || [];
botRoles = botRoles.filter(r => !!r); // Drop any unknown roles
botRoles = botRoles.filter(r => r.color); // Filter to those with a color
botRoles.sort(sorter("position", "DESC")); // Sort by position (highest first)

View file

@ -92,7 +92,7 @@ export const CleanCmd = utilityCmd({
const cleaningMessage = msg.channel.createMessage("Cleaning...");
const messagesToClean = [];
const messagesToClean: SavedMessage[] = [];
let beforeId = msg.id;
const timeCutoff = msg.timestamp - MAX_CLEAN_TIME;
@ -104,7 +104,7 @@ export const CleanCmd = utilityCmd({
);
if (potentialMessagesToClean.length === 0) break;
const filtered = [];
const filtered: SavedMessage[] = [];
for (const message of potentialMessagesToClean) {
const contentString = message.data.content || "";
if (args.user && message.user_id !== args.user) continue;

View file

@ -22,7 +22,7 @@ export const HelpCmd = utilityCmd({
command: PluginCommandDefinition;
}> = [];
const guildData = pluginData.getKnubInstance().getLoadedGuild(pluginData.guild.id);
const guildData = pluginData.getKnubInstance().getLoadedGuild(pluginData.guild.id)!;
for (const plugin of guildData.loadedPlugins.values()) {
const registeredCommands = plugin.pluginData.commands.getAll();
for (const registeredCommand of registeredCommands) {
@ -55,8 +55,8 @@ export const HelpCmd = utilityCmd({
: originalTrigger.source
: "";
const description = command.config.extra.blueprint.description;
const usage = command.config.extra.blueprint.usage;
const description = command.config!.extra!.blueprint.description;
const usage = command.config!.extra!.blueprint.usage;
const commandSlug = trigger
.trim()
.toLowerCase()

View file

@ -32,7 +32,7 @@ export const InfoCmd = utilityCmd({
const channelId = getChannelId(value);
const channel = channelId && pluginData.guild.channels.get(channelId);
if (channel) {
const embed = await getChannelInfoEmbed(pluginData, channelId, message.author.id);
const embed = await getChannelInfoEmbed(pluginData, channelId!, message.author.id);
if (embed) {
message.channel.createMessage({ embed });
return;

View file

@ -10,9 +10,9 @@ export const PingCmd = utilityCmd({
permission: "can_ping",
async run({ message: msg, pluginData }) {
const times = [];
const times: number[] = [];
const messages: Message[] = [];
let msgToMsgDelay = null;
let msgToMsgDelay: number | undefined;
for (let i = 0; i < 4; i++) {
const start = performance.now();
@ -20,7 +20,7 @@ export const PingCmd = utilityCmd({
times.push(performance.now() - start);
messages.push(message);
if (msgToMsgDelay === null) {
if (msgToMsgDelay === undefined) {
msgToMsgDelay = message.timestamp - msg.timestamp;
}
}
@ -29,7 +29,7 @@ export const PingCmd = utilityCmd({
const lowest = Math.round(Math.min(...times));
const mean = Math.round(times.reduce((total, ms) => total + ms, 0) / times.length);
const shard = pluginData.client.shards.get(pluginData.client.guildShardMap[pluginData.guild.id]);
const shard = pluginData.client.shards.get(pluginData.client.guildShardMap[pluginData.guild.id])!;
msg.channel.createMessage(
trimLines(`
@ -37,7 +37,7 @@ export const PingCmd = utilityCmd({
Lowest: **${lowest}ms**
Highest: **${highest}ms**
Mean: **${mean}ms**
Time between ping command and first reply: **${msgToMsgDelay}ms**
Time between ping command and first reply: **${msgToMsgDelay!}ms**
Shard latency: **${shard.latency}ms**
`),
);

View file

@ -51,8 +51,8 @@ export const RolesCmd = utilityCmd({
if (!sort) sort = "-memberCount";
roles.sort((a, b) => {
if (a._memberCount > b._memberCount) return -1;
if (a._memberCount < b._memberCount) return 1;
if (a._memberCount! > b._memberCount!) return -1;
if (a._memberCount! < b._memberCount!) return 1;
return 0;
});
} else {

View file

@ -25,6 +25,8 @@ export const VcmoveCmd = utilityCmd({
async run({ message: msg, args, pluginData }) {
let channel: VoiceChannel;
const foo = args.member;
if (isSnowflake(args.channel)) {
// Snowflake -> resolve channel directly
const potentialChannel = pluginData.guild.channels.get(args.channel);
@ -36,7 +38,7 @@ export const VcmoveCmd = utilityCmd({
channel = potentialChannel;
} else if (channelMentionRegex.test(args.channel)) {
// Channel mention -> parse channel id and resolve channel from that
const channelId = args.channel.match(channelMentionRegex)[1];
const channelId = args.channel.match(channelMentionRegex)![1];
const potentialChannel = pluginData.guild.channels.get(channelId);
if (!potentialChannel || !(potentialChannel instanceof VoiceChannel)) {
sendErrorMessage(pluginData, msg.channel, "Unknown or non-voice channel");

View file

@ -3,7 +3,7 @@ import { UtilityPluginType } from "../types";
import { Constants, EmbedOptions } from "eris";
import moment from "moment-timezone";
import humanizeDuration from "humanize-duration";
import { formatNumber, preEmbedPadding, trimLines } from "../../../utils";
import { EmbedWith, formatNumber, preEmbedPadding, trimLines } from "../../../utils";
import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
const TEXT_CHANNEL_ICON =
@ -23,7 +23,7 @@ export async function getChannelInfoEmbed(
return null;
}
const embed: EmbedOptions = {
const embed: EmbedWith<"fields"> = {
fields: [],
};

View file

@ -1,15 +1,16 @@
import { GuildPluginData } from "knub";
import { UtilityPluginType } from "../types";
import { BaseInvite, Constants, EmbedOptions, RESTChannelInvite, RESTPrivateInvite } from "eris";
import { Constants, EmbedOptions } from "eris";
import { snowflakeToTimestamp } from "../../../utils/snowflakeToTimestamp";
import moment from "moment-timezone";
import humanizeDuration from "humanize-duration";
import {
embedPadding,
EmbedWith,
emptyEmbedValue,
formatNumber,
isRESTGroupDMInvite,
isRESTGuildInvite,
isGroupDMInvite,
isGuildInvite,
preEmbedPadding,
resolveInvite,
trimLines,
@ -24,8 +25,8 @@ export async function getInviteInfoEmbed(
return null;
}
if (isRESTGuildInvite(invite)) {
const embed: EmbedOptions = {
if (isGuildInvite(invite)) {
const embed: EmbedWith<"fields"> = {
fields: [],
};
@ -102,8 +103,8 @@ export async function getInviteInfoEmbed(
return embed;
}
if (isRESTGroupDMInvite(invite)) {
const embed: EmbedOptions = {
if (isGroupDMInvite(invite)) {
const embed: EmbedWith<"fields"> = {
fields: [],
};

View file

@ -3,7 +3,7 @@ import { UtilityPluginType } from "../types";
import { Constants, EmbedOptions } from "eris";
import moment from "moment-timezone";
import humanizeDuration from "humanize-duration";
import { chunkMessageLines, messageLink, preEmbedPadding, trimEmptyLines, trimLines } from "../../../utils";
import { chunkMessageLines, EmbedWith, messageLink, preEmbedPadding, trimEmptyLines, trimLines } from "../../../utils";
import { getDefaultPrefix } from "knub/dist/commands/commandUtils";
import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
@ -22,7 +22,7 @@ export async function getMessageInfoEmbed(
const timeAndDate = pluginData.getPlugin(TimeAndDatePlugin);
const embed: EmbedOptions = {
const embed: EmbedWith<"fields"> = {
fields: [],
};
@ -93,10 +93,12 @@ export async function getMessageInfoEmbed(
});
const authorJoinedAt = message.member && moment.utc(message.member.joinedAt, "x");
const tzAuthorJoinedAt = requestMemberId
? await timeAndDate.inMemberTz(requestMemberId, authorJoinedAt)
: timeAndDate.inGuildTz(authorJoinedAt);
const prettyAuthorJoinedAt = tzAuthorJoinedAt.format(timeAndDate.getDateFormat("pretty_datetime"));
const tzAuthorJoinedAt = authorJoinedAt
? requestMemberId
? await timeAndDate.inMemberTz(requestMemberId, authorJoinedAt)
: timeAndDate.inGuildTz(authorJoinedAt)
: null;
const prettyAuthorJoinedAt = tzAuthorJoinedAt?.format(timeAndDate.getDateFormat("pretty_datetime"));
const authorServerAge =
message.member &&
humanizeDuration(Date.now() - message.member.joinedAt, {

View file

@ -1,7 +1,17 @@
import { GuildPluginData } from "knub";
import { UtilityPluginType } from "../types";
import { embedPadding, formatNumber, memoize, MINUTES, preEmbedPadding, resolveUser, trimLines } from "../../../utils";
import { CategoryChannel, EmbedOptions, Guild, RESTChannelInvite, TextChannel, VoiceChannel } from "eris";
import {
embedPadding,
EmbedWith,
formatNumber,
memoize,
MINUTES,
preEmbedPadding,
resolveInvite,
resolveUser,
trimLines,
} from "../../../utils";
import { CategoryChannel, EmbedOptions, Guild, TextChannel, VoiceChannel } from "eris";
import moment from "moment-timezone";
import humanizeDuration from "humanize-duration";
import { getGuildPreview } from "./getGuildPreview";
@ -11,7 +21,7 @@ export async function getServerInfoEmbed(
pluginData: GuildPluginData<UtilityPluginType>,
serverId: string,
requestMemberId?: string,
): Promise<EmbedOptions> {
): Promise<EmbedOptions | null> {
const thisServer = serverId === pluginData.guild.id ? pluginData.guild : null;
const [restGuild, guildPreview] = await Promise.all([
thisServer
@ -24,23 +34,23 @@ export async function getServerInfoEmbed(
return null;
}
const features = (restGuild || guildPreview).features;
const features = (restGuild || guildPreview)!.features;
if (!thisServer && !features.includes("DISCOVERABLE")) {
return null;
}
const embed: EmbedOptions = {
const embed: EmbedWith<"fields"> = {
fields: [],
};
embed.author = {
name: `Server: ${(guildPreview || restGuild).name}`,
icon_url: (guildPreview || restGuild).iconURL,
name: `Server: ${(guildPreview || restGuild)!.name}`,
icon_url: (guildPreview || restGuild)!.iconURL ?? undefined,
};
// BASIC INFORMATION
const timeAndDate = pluginData.getPlugin(TimeAndDatePlugin);
const createdAt = moment.utc((guildPreview || restGuild).createdAt, "x");
const createdAt = moment.utc((guildPreview || restGuild)!.createdAt, "x");
const tzCreatedAt = requestMemberId
? await timeAndDate.inMemberTz(requestMemberId, createdAt)
: timeAndDate.inGuildTz(createdAt);
@ -50,7 +60,7 @@ export async function getServerInfoEmbed(
round: true,
});
const basicInformation = [];
const basicInformation: string[] = [];
basicInformation.push(`Created: **${serverAge} ago** (\`${prettyCreatedAt}\`)`);
if (thisServer) {
@ -79,16 +89,11 @@ export async function getServerInfoEmbed(
thisServer?.members.size ||
0;
let onlineMemberCount = guildPreview?.approximatePresenceCount || restGuild?.approximatePresenceCount;
let onlineMemberCount = (guildPreview?.approximatePresenceCount || restGuild?.approximatePresenceCount)!;
if (onlineMemberCount == null && restGuild?.vanityURL) {
// For servers with a vanity URL, we can also use the numbers from the invite for online count
const invite = (await memoize(
() => pluginData.client.getInvite(restGuild.vanityURL, true),
`getInvite_${restGuild.vanityURL}`,
10 * MINUTES,
)) as RESTChannelInvite;
const invite = await resolveInvite(pluginData.client, restGuild.vanityURL!, true);
if (invite) {
onlineMemberCount = invite.presenceCount;
}
@ -140,7 +145,7 @@ export async function getServerInfoEmbed(
}
// OTHER STATS
const otherStats = [];
const otherStats: string[] = [];
if (thisServer) {
otherStats.push(`Roles: **${thisServer.roles.size}** / 250`);
@ -156,7 +161,7 @@ export async function getServerInfoEmbed(
}[restGuild.premiumTier] || 50;
otherStats.push(`Emojis: **${restGuild.emojis.length}** / ${maxEmojis * 2}`);
} else {
otherStats.push(`Emojis: **${guildPreview.emojis.length}**`);
otherStats.push(`Emojis: **${guildPreview!.emojis.length}**`);
}
if (thisServer) {

View file

@ -1,7 +1,15 @@
import { Message, GuildTextableChannel, EmbedOptions } from "eris";
import { GuildPluginData } from "knub";
import { UtilityPluginType } from "../types";
import { UnknownUser, trimLines, embedPadding, resolveMember, resolveUser, preEmbedPadding } from "../../../utils";
import {
UnknownUser,
trimLines,
embedPadding,
resolveMember,
resolveUser,
preEmbedPadding,
EmbedWith,
} from "../../../utils";
import moment from "moment-timezone";
import { CaseTypes } from "../../../data/CaseTypes";
import humanizeDuration from "humanize-duration";
@ -16,7 +24,7 @@ export async function getSnowflakeInfoEmbed(
showUnknownWarning = false,
requestMemberId?: string,
): Promise<EmbedOptions> {
const embed: EmbedOptions = {
const embed: EmbedWith<"fields"> = {
fields: [],
};

View file

@ -1,4 +1,4 @@
import { Message, GuildTextableChannel, EmbedOptions } from "eris";
import { Message, GuildTextableChannel, EmbedOptions, Role } from "eris";
import { GuildPluginData } from "knub";
import { UtilityPluginType } from "../types";
import {
@ -10,6 +10,7 @@ import {
preEmbedPadding,
sorter,
messageLink,
EmbedWith,
} from "../../../utils";
import moment from "moment-timezone";
import { CaseTypes } from "../../../data/CaseTypes";
@ -29,7 +30,7 @@ export async function getUserInfoEmbed(
const member = await resolveMember(pluginData.client, pluginData.guild, user.id);
const embed: EmbedOptions = {
const embed: EmbedWith<"fields"> = {
fields: [],
};
@ -101,7 +102,7 @@ export async function getUserInfoEmbed(
largest: 2,
round: true,
});
const roles = member.roles.map(id => pluginData.guild.roles.get(id)).filter(r => !!r);
const roles = member.roles.map(id => pluginData.guild.roles.get(id)).filter(r => r != null) as Role[];
roles.sort(sorter("position", "DESC"));
embed.fields.push({

View file

@ -13,6 +13,7 @@ import { getUserInfoEmbed } from "./functions/getUserInfoEmbed";
import { allowTimeout } from "../../RegExpRunner";
import { inputPatternToRegExp, InvalidRegexError } from "../../validatorUtils";
import { asyncFilter } from "../../utils/async";
import Timeout = NodeJS.Timeout;
const SEARCH_RESULTS_PER_PAGE = 15;
const SEARCH_ID_RESULTS_PER_PAGE = 50;
@ -47,12 +48,12 @@ export async function displaySearch(
msg: Message,
) {
// If we're not exporting, load 1 page of search results at a time and allow the user to switch pages with reactions
let originalSearchMsg: Message = null;
let originalSearchMsg: Message;
let searching = false;
let currentPage = args.page || 1;
let hasReactions = false;
let clearReactionsFn = null;
let clearReactionsTimeout = null;
let clearReactionsFn: () => void;
let clearReactionsTimeout: Timeout;
const perPage = args.ids ? SEARCH_ID_RESULTS_PER_PAGE : SEARCH_RESULTS_PER_PAGE;
@ -335,7 +336,7 @@ async function performMemberSearch(
}
}
const [, sortDir, sortBy] = args.sort ? args.sort.match(/^(-?)(.*)$/) : [null, "ASC", "name"];
const [, sortDir, sortBy] = (args.sort && args.sort.match(/^(-?)(.*)$/)) ?? [null, "ASC", "name"];
const realSortDir = sortDir === "-" ? "DESC" : "ASC";
if (sortBy === "id") {
@ -392,7 +393,7 @@ async function performBanSearch(
});
}
const [, sortDir, sortBy] = args.sort ? args.sort.match(/^(-?)(.*)$/) : [null, "ASC", "name"];
const [, sortDir, sortBy] = (args.sort && args.sort.match(/^(-?)(.*)$/)) ?? [null, "ASC", "name"];
const realSortDir = sortDir === "-" ? "DESC" : "ASC";
if (sortBy === "id") {