From e5a8f3b358cb4f35fcdf69d074ec62663bfa333c Mon Sep 17 00:00:00 2001 From: Ayyan Date: Sun, 3 Jan 2021 20:12:42 +0400 Subject: [PATCH] chore: setup "deno lint" (#331) * chore: setup "deno lint" * ci(lint): add --unstable flat to lint script * lint * lint * refactor: destructure assignment for Message#guildID * chore: remove TODO comment * refactor: remove redundant async * chore: switch to Deno stable vscode ext * chore: remove ignore comments * chore: remove ignore comments * chore: remove @ts-ignore comment * fixes * fixes * chore: remove deno-lint-ignore comment * chore: add index signature --- .github/workflows/lint.yml | 4 ++-- .vscode/settings.json | 12 ++++++------ src/api/controllers/cache.ts | 2 ++ src/api/controllers/guilds.ts | 4 +--- src/api/controllers/interactions.ts | 2 +- src/api/controllers/members.ts | 2 ++ src/api/controllers/misc.ts | 7 ++----- src/api/handlers/channel.ts | 4 ++++ src/api/handlers/guild.ts | 4 ++-- src/api/handlers/member.ts | 5 ++++- src/api/structures/channel.ts | 18 +++++++++--------- src/api/structures/guild.ts | 13 ++++++++----- src/api/structures/member.ts | 8 ++++++-- src/api/structures/message.ts | 17 +++++++++-------- src/api/structures/role.ts | 19 +++++++++---------- src/api/structures/structures.ts | 7 ------- src/api/structures/template.ts | 6 ++++-- src/interactions/server.ts | 11 ++++++----- src/interactions/types/interactions.ts | 1 + src/rest/request_manager.ts | 20 ++++++++++++-------- src/types/channel.ts | 2 ++ src/types/guild.ts | 6 ++++++ src/types/member.ts | 2 ++ src/types/message.ts | 3 +++ src/types/options.ts | 2 ++ src/types/role.ts | 3 +++ src/types/webhook.ts | 1 + src/util/cache.ts | 9 +++------ src/util/permissions.ts | 4 ++-- src/util/utils.ts | 1 + src/ws/shard.ts | 4 ++-- src/ws/shard_manager.ts | 10 ++++++++-- tests/mod.test.ts | 4 ++-- 33 files changed, 127 insertions(+), 90 deletions(-) delete mode 100644 src/api/structures/structures.ts diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index f837b23a7..9f0de6ba3 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -16,5 +16,5 @@ jobs: steps: - uses: actions/checkout@v2 - uses: denolib/setup-deno@v2 - - name: Run format script with --check - run: deno fmt --ignore=./docs --check + - name: Run lint script + run: deno lint src/** --unstable diff --git a/.vscode/settings.json b/.vscode/settings.json index ab4781ee3..e15e7fd59 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,11 +1,11 @@ { "deno.enable": true, + "deno.lint": true, + "deno.unstable": true, + "editor.defaultFormatter": "denoland.vscode-deno", "editor.formatOnSave": true, - "deno.import_intellisense_origins": { - "https://deno.land": true - }, "editor.codeActionsOnSave": { - "source.organizeImports": true - }, - "editor.defaultFormatter": "denoland.vscode-deno" + "source.organizeImports": true, + "source.fixAll": true + } } diff --git a/src/api/controllers/cache.ts b/src/api/controllers/cache.ts index f08397188..0077c98e5 100644 --- a/src/api/controllers/cache.ts +++ b/src/api/controllers/cache.ts @@ -1,3 +1,5 @@ +// deno-lint-ignore-file require-await no-explicit-any prefer-const + import { PresenceUpdatePayload } from "../../types/mod.ts"; import { cache } from "../../util/cache.ts"; import { Collection } from "../../util/collection.ts"; diff --git a/src/api/controllers/guilds.ts b/src/api/controllers/guilds.ts index 96c6e1401..bad7fd5d4 100644 --- a/src/api/controllers/guilds.ts +++ b/src/api/controllers/guilds.ts @@ -83,7 +83,6 @@ export async function handleInternalGuildUpdate(data: DiscordPayload) { .map(([key, value]) => { if (keysToSkip.includes(key)) return; - // @ts-ignore const cachedValue = cachedGuild[key]; if (cachedValue !== value) { // Guild create sends undefined and update sends false. @@ -91,13 +90,12 @@ export async function handleInternalGuildUpdate(data: DiscordPayload) { if (Array.isArray(cachedValue) && Array.isArray(value)) { const different = (cachedValue.length !== value.length) || + // @ts-ignore no idea how to fix this cachedValue.find((val) => !value.includes(val)) || value.find((val) => !cachedValue.includes(val)); if (!different) return; } - // This will update the cached guild with the new values - // @ts-ignore cachedGuild[key] = value; return { key, oldValue: cachedValue, value }; } diff --git a/src/api/controllers/interactions.ts b/src/api/controllers/interactions.ts index 34582d2d0..c8def72ba 100644 --- a/src/api/controllers/interactions.ts +++ b/src/api/controllers/interactions.ts @@ -18,7 +18,7 @@ export async function handleInternalInteractionCreate(data: DiscordPayload) { ); } -export async function handleInternalApplicationCommandCreate( +export function handleInternalApplicationCommandCreate( data: DiscordPayload, ) { if (data.t !== "APPLICATION_COMMAND_CREATE") return; diff --git a/src/api/controllers/members.ts b/src/api/controllers/members.ts index 9dede1a50..b3eb33c87 100644 --- a/src/api/controllers/members.ts +++ b/src/api/controllers/members.ts @@ -56,7 +56,9 @@ export async function handleInternalGuildMemberUpdate(data: DiscordPayload) { const newMemberData = { ...payload, + // deno-lint-ignore camelcase premium_since: payload.premium_since || undefined, + // deno-lint-ignore camelcase joined_at: new Date(guildMember?.joinedAt || Date.now()) .toISOString(), deaf: guildMember?.deaf || false, diff --git a/src/api/controllers/misc.ts b/src/api/controllers/misc.ts index 3992c099b..fb455657a 100644 --- a/src/api/controllers/misc.ts +++ b/src/api/controllers/misc.ts @@ -11,10 +11,8 @@ import { import { cache } from "../../util/cache.ts"; import { delay } from "../../util/utils.ts"; import { allowNextShard } from "../../ws/shard_manager.ts"; -import { - initialMemberLoadQueue, - structures, -} from "../structures/structures.ts"; +import { initialMemberLoadQueue } from "../structures/guild.ts"; +import { structures } from "../structures/mod.ts"; import { cacheHandlers } from "./cache.ts"; /** This function is the internal handler for the ready event. Users can override this with controllers if desired. */ @@ -75,7 +73,6 @@ export async function handleInternalUserUpdate(data: DiscordPayload) { if (!member) return; Object.entries(userData).forEach(([key, value]) => { - // @ts-ignore if (member[key] !== value) return member[key] = value; }); return eventHandlers.botUpdate?.(userData); diff --git a/src/api/handlers/channel.ts b/src/api/handlers/channel.ts index 833ccde5c..7f4d81ad5 100644 --- a/src/api/handlers/channel.ts +++ b/src/api/handlers/channel.ts @@ -399,9 +399,13 @@ export async function editChannel( const payload = { ...options, + // deno-lint-ignore camelcase rate_limit_per_user: options.slowmode, + // deno-lint-ignore camelcase parent_id: options.parentID, + // deno-lint-ignore camelcase user_limit: options.userLimit, + // deno-lint-ignore camelcase permission_overwrites: options.overwrites?.map( (overwrite) => { return { diff --git a/src/api/handlers/guild.ts b/src/api/handlers/guild.ts index e77abf550..47449734c 100644 --- a/src/api/handlers/guild.ts +++ b/src/api/handlers/guild.ts @@ -429,8 +429,8 @@ export function fetchMembers(guild: Guild, options?: FetchMembersOptions) { options.limit = options.userIDs.length; } - return new Promise(async (resolve) => { - await requestAllMembers(guild, resolve, options); + return new Promise((resolve) => { + requestAllMembers(guild, resolve, options); }) as Promise>; } diff --git a/src/api/handlers/member.ts b/src/api/handlers/member.ts index b2c4e178c..9acb23954 100644 --- a/src/api/handlers/member.ts +++ b/src/api/handlers/member.ts @@ -1,6 +1,7 @@ import { botID } from "../../bot.ts"; import { RequestManager } from "../../rest/mod.ts"; import { + ChannelCreatePayload, DMChannelCreatePayload, EditMemberOptions, Errors, @@ -128,7 +129,9 @@ export async function sendDirectMessage( ) as DMChannelCreatePayload; // Channel create event will have added this channel to the cache await cacheHandlers.delete("channels", dmChannelData.id); - const channel = await structures.createChannel(dmChannelData); + const channel = await structures.createChannel( + dmChannelData as unknown as ChannelCreatePayload, + ); // Recreate the channel and add it undert he users id await cacheHandlers.set("channels", memberID, channel); dmChannel = channel; diff --git a/src/api/structures/channel.ts b/src/api/structures/channel.ts index af94b6fc0..742d78d72 100644 --- a/src/api/structures/channel.ts +++ b/src/api/structures/channel.ts @@ -32,34 +32,34 @@ export async function createChannel( guildID?: string, ) { const { - guild_id: rawGuildID, + guild_id: rawGuildID = "", last_message_id: lastMessageID, user_limit: userLimit, rate_limit_per_user: rateLimitPerUser, - parent_id: parentID, + parent_id: parentID = undefined, last_pin_timestamp: lastPinTimestamp, - permission_overwrites, - nsfw, + permission_overwrites: permissionOverwrites = [], + nsfw = false, ...rest } = data; const restProps: Record> = {}; for (const key of Object.keys(rest)) { - restProps[key] = createNewProp((rest as any)[key]); + restProps[key] = createNewProp(rest[key]); } const channel = Object.create(baseChannel, { ...restProps, - guildID: createNewProp(guildID || rawGuildID || ""), + guildID: createNewProp(guildID || rawGuildID), lastMessageID: createNewProp(lastMessageID), userLimit: createNewProp(userLimit), rateLimitPerUser: createNewProp(rateLimitPerUser), - parentID: createNewProp(parentID || undefined), + parentID: createNewProp(parentID), lastPinTimestamp: createNewProp( lastPinTimestamp ? Date.parse(lastPinTimestamp) : undefined, ), - permissionOverwrites: createNewProp(permission_overwrites || []), - nsfw: createNewProp(data.nsfw || false), + permissionOverwrites: createNewProp(permissionOverwrites), + nsfw: createNewProp(nsfw), }); await cacheHandlers.set("channels", data.id, channel); diff --git a/src/api/structures/guild.ts b/src/api/structures/guild.ts index 65f5dddca..76d3feaab 100644 --- a/src/api/structures/guild.ts +++ b/src/api/structures/guild.ts @@ -13,6 +13,7 @@ import { MemberCreatePayload, Presence, RoleData, + ValueOf, VoiceState, } from "../../types/mod.ts"; import { cache } from "../../util/cache.ts"; @@ -32,8 +33,7 @@ import { unban, } from "../handlers/guild.ts"; import { Member } from "./member.ts"; -import { Role, structures } from "./mod.ts"; -import { Channel } from "./structures.ts"; +import { Channel, Role, structures } from "./mod.ts"; export const initialMemberLoadQueue = new Map(); @@ -135,7 +135,7 @@ export async function createGuild(data: CreateGuildPayload, shardID: number) { premium_subscription_count: premiumSubscriptionCount, preferred_locale: preferredLocale, joined_at: joinedAt, - member_count: memberCount, + member_count: memberCount = 0, voice_states: voiceStates = [], channels = [], members, @@ -155,7 +155,7 @@ export async function createGuild(data: CreateGuildPayload, shardID: number) { const restProps: Record> = {}; for (const key of Object.keys(rest)) { - restProps[key] = createNewProp((rest as any)[key]); + restProps[key] = createNewProp(rest[key]); } const guild = Object.create(baseGuild, { @@ -188,7 +188,7 @@ export async function createGuild(data: CreateGuildPayload, shardID: number) { presences: createNewProp( new Collection(presences.map((p: Presence) => [p.user.id, p])), ), - memberCount: createNewProp(memberCount || 0), + memberCount: createNewProp(memberCount), voiceStates: createNewProp( new Collection( voiceStates.map((vs: VoiceState) => [ @@ -345,6 +345,9 @@ export interface Guild { unban(memberID: string): ReturnType; /** Get all the invites for this guild. Requires MANAGE_GUILD permission */ invites(): ReturnType; + + // Index signature + [key: string]: ValueOf; } interface CleanVoiceState extends VoiceState { diff --git a/src/api/structures/member.ts b/src/api/structures/member.ts index 14bc5b743..17c0e9b56 100644 --- a/src/api/structures/member.ts +++ b/src/api/structures/member.ts @@ -6,6 +6,7 @@ import { ImageSize, MemberCreatePayload, MessageContent, + ValueOf, } from "../../types/mod.ts"; import { cache } from "../../util/cache.ts"; import { Collection } from "../../util/collection.ts"; @@ -88,12 +89,12 @@ export async function createMember(data: MemberCreatePayload, guildID: string) { data.user || {}; const restProps: Record> = {}; + for (const key of Object.keys(rest)) { - restProps[key] = createNewProp((rest as any)[key]); + restProps[key] = createNewProp(rest[key]); } for (const key of Object.keys(user)) { - // @ts-ignore restProps[key] = createNewProp(user[key]); } @@ -198,4 +199,7 @@ export interface Member { roleID: string, reason?: string, ): ReturnType; + + // Index signature + [key: string]: ValueOf; } diff --git a/src/api/structures/message.ts b/src/api/structures/message.ts index fae678b4b..f622c92f6 100644 --- a/src/api/structures/message.ts +++ b/src/api/structures/message.ts @@ -34,15 +34,15 @@ const baseMessage: Partial = { return cache.channels.get(this.channelID!); }, get guild() { - if (!this.guildID) return; + if (!this.guildID) return undefined; return cache.guilds.get(this.guildID); }, get member() { - if (!this.author?.id) return; + if (!this.author?.id) return undefined; return cache.members.get(this.author?.id); }, get guildMember() { - if (!this.guildID) return; + if (!this.guildID) return undefined; return this.member?.guilds.get(this.guildID); }, get link() { @@ -116,12 +116,13 @@ const baseMessage: Partial = { }, }; +// deno-lint-ignore require-await export async function createMessage(data: MessageCreateOptions) { const { - guild_id: guildID, + guild_id: guildID = "", channel_id: channelID, mentions_everyone: mentionsEveryone, - mention_channels: mentionChannelIDs, + mention_channels: mentionChannelIDs = [], mention_roles: mentionRoleIDs, webhook_id: webhookID, message_reference: messageReference, @@ -133,7 +134,7 @@ export async function createMessage(data: MessageCreateOptions) { const restProps: Record> = {}; for (const key of Object.keys(rest)) { - restProps[key] = createNewProp((rest as any)[key]); + restProps[key] = createNewProp(rest[key]); } const message = Object.create(baseMessage, { @@ -141,11 +142,11 @@ export async function createMessage(data: MessageCreateOptions) { /** The message id of the original message if this message was sent as a reply. If null, the original message was deleted. */ referencedMessageID: createNewProp(referencedMessageID), channelID: createNewProp(channelID), - guildID: createNewProp(guildID || ""), + guildID: createNewProp(guildID), mentions: createNewProp(data.mentions.map((m) => m.id)), mentionsEveryone: createNewProp(mentionsEveryone), mentionRoleIDs: createNewProp(mentionRoleIDs), - mentionChannelIDs: createNewProp(mentionChannelIDs?.map((m) => m.id) || []), + mentionChannelIDs: createNewProp(mentionChannelIDs.map((m) => m.id)), webhookID: createNewProp(webhookID), messageReference: createNewProp(messageReference), timestamp: createNewProp(Date.parse(data.timestamp)), diff --git a/src/api/structures/role.ts b/src/api/structures/role.ts index 0c3611b5a..5c194a31e 100644 --- a/src/api/structures/role.ts +++ b/src/api/structures/role.ts @@ -6,16 +6,16 @@ import { deleteRole, editRole } from "../handlers/guild.ts"; import { Guild } from "./guild.ts"; import { Member } from "./member.ts"; -const baseRole: any = { +const baseRole: Partial = { get guild() { - return cache.guilds.find((g) => g.roles.has(this.id)); + return cache.guilds.find((g) => g.roles.has(this.id!)); }, get hexColor() { return this.color!.toString(16); }, get members() { return cache.members.filter((m) => - m.guilds.some((g) => g.roles.includes(this.id)) + m.guilds.some((g) => g.roles.includes(this.id!)) ); }, get mention() { @@ -66,19 +66,18 @@ const baseRole: any = { }, }; -export async function createRole(data: RoleData) { - const { tags, ...rest } = data; - +// deno-lint-ignore require-await +export async function createRole({ tags = {}, ...rest }: RoleData) { const restProps: Record> = {}; for (const key of Object.keys(rest)) { - restProps[key] = createNewProp((rest as any)[key]); + restProps[key] = createNewProp(rest[key]); } const role = Object.create(baseRole, { ...restProps, - botID: createNewProp(tags?.bot_id), - isNitroBoostRole: createNewProp("premium_subscriber" in (tags ?? {})), - integrationID: createNewProp(tags?.integration_id), + botID: createNewProp(tags.bot_id), + isNitroBoostRole: createNewProp("premium_subscriber" in tags), + integrationID: createNewProp(tags.integration_id), }); return role as Role; diff --git a/src/api/structures/structures.ts b/src/api/structures/structures.ts deleted file mode 100644 index 5c2bdd66c..000000000 --- a/src/api/structures/structures.ts +++ /dev/null @@ -1,7 +0,0 @@ -export * from "./channel.ts"; -export * from "./guild.ts"; -export * from "./member.ts"; -export * from "./message.ts"; -export * from "./mod.ts"; -export * from "./role.ts"; -export * from "./template.ts"; diff --git a/src/api/structures/template.ts b/src/api/structures/template.ts index 1e2b3e40b..b487cbda7 100644 --- a/src/api/structures/template.ts +++ b/src/api/structures/template.ts @@ -3,8 +3,10 @@ import { cache } from "../../util/cache.ts"; import { createNewProp } from "../../util/utils.ts"; import { Guild } from "./guild.ts"; -const baseTemplate: any = { +const baseTemplate: Partial