From ea18fbc71de73c4ea656dcc60cc0bd0226c01f42 Mon Sep 17 00:00:00 2001 From: Yuzu Date: Thu, 30 Jun 2022 11:30:27 -0500 Subject: [PATCH 1/4] feat: final Guild endpoints --- structures/Guild.ts | 34 +++++++++++++++++++++++++++++++++- structures/Role.ts | 7 ++++++- util/Routes.ts | 4 ++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/structures/Guild.ts b/structures/Guild.ts index b3d387f..9466149 100644 --- a/structures/Guild.ts +++ b/structures/Guild.ts @@ -26,6 +26,14 @@ export interface CreateRole { mentionable?: boolean; } +export interface ModifyGuildRole { + name?: string; + color?: number; + hoist?: boolean; + mentionable?: boolean; + unicodeEmoji?: string; +} + export interface CreateGuildEmoji { name: string; image: string; @@ -138,7 +146,21 @@ export class Guild extends BaseGuild implements Model { await this.session.rest.runMethod(this.session.rest, "DELETE", Routes.GUILD_ROLE(this.id, roleId)); } - // TODO: edit role + async editRole(roleId: Snowflake, options: ModifyGuildRole): Promise { + const role = await this.session.rest.runMethod( + this.session.rest, + "PATCH", + Routes.GUILD_ROLE(this.id, roleId), + { + name: options.name, + color: options.color, + hoist: options.hoist, + mentionable: options.mentionable, + } + ); + + return new Role(this.session, role, this.id); + } async deleteInvite(inviteCode: string): Promise { await this.session.rest.runMethod( @@ -158,6 +180,16 @@ export class Guild extends BaseGuild implements Model { return new Invite(this.session, inviteMetadata); } + + async fetchInvites(): Promise { + const invites = await this.session.rest.runMethod( + this.session.rest, + "GET", + Routes.GUILD_INVITES(this.id), + ); + + return invites.map((invite) => new Invite(this.session, invite)); + } } export default Guild; diff --git a/structures/Role.ts b/structures/Role.ts index 64365e5..b8a53cf 100644 --- a/structures/Role.ts +++ b/structures/Role.ts @@ -4,7 +4,7 @@ import type { Session } from "../session/Session.ts"; import { Snowflake } from "../util/Snowflake.ts"; import { iconHashToBigInt } from "../util/hash.ts"; import Permissions from "./Permissions.ts"; -import Guild from "./Guild.ts"; +import Guild, { ModifyGuildRole } from "./Guild.ts"; export class Role implements Model { constructor(session: Session, data: DiscordRole, guildId: Snowflake) { @@ -52,6 +52,11 @@ export class Role implements Model { await Guild.prototype.deleteRole.call({ id: this.guildId, session: this.session }, this.id); } + async edit(options: ModifyGuildRole) { + const role = await Guild.prototype.editRole.call({ id: this.guildId, session: this.session }, this.id, options); + return role; + } + toString() { switch (this.id) { case this.guildId: diff --git a/util/Routes.ts b/util/Routes.ts index 73166e7..03442a7 100644 --- a/util/Routes.ts +++ b/util/Routes.ts @@ -135,3 +135,7 @@ export function INVITE(inviteCode: string, options?: GetInvite) { return url; } + +export function GUILD_INVITES(guildId: Snowflake) { + return `/guilds/${guildId}/invites`; +} From 9e6a8699ff203efeaa256831e9c4919357239f86 Mon Sep 17 00:00:00 2001 From: Yuzu Date: Thu, 30 Jun 2022 11:41:23 -0500 Subject: [PATCH 2/4] feat: GuildChannel.fetchInvites --- structures/GuildChannel.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/structures/GuildChannel.ts b/structures/GuildChannel.ts index 2d60291..99ea4ff 100644 --- a/structures/GuildChannel.ts +++ b/structures/GuildChannel.ts @@ -1,8 +1,9 @@ import type { Model } from "./Base.ts"; import type { Snowflake } from "../util/Snowflake.ts"; import type { Session } from "../session/Session.ts"; -import type { DiscordChannel } from "../vendor/external.ts"; +import type { DiscordChannel, DiscordInviteMetadata } from "../vendor/external.ts"; import Channel from "./Channel.ts"; +import Invite from "./Invite.ts"; import * as Routes from "../util/Routes.ts"; export abstract class GuildChannel extends Channel implements Model { @@ -19,6 +20,16 @@ export abstract class GuildChannel extends Channel implements Model { position?: number; parentId?: Snowflake; + async fetchInvites(): Promise { + const invites = await this.session.rest.runMethod( + this.session.rest, + "GET", + Routes.CHANNEL_INVITES(this.id), + ); + + return invites.map((invite) => new Invite(this.session, invite)); + } + async delete(reason?: string) { await this.session.rest.runMethod( this.session.rest, From 9b7e1b9b1b28e25b72886e8d193d24b080d105e7 Mon Sep 17 00:00:00 2001 From: Yuzu Date: Thu, 30 Jun 2022 12:33:00 -0500 Subject: [PATCH 3/4] stuff --- handlers/Actions.ts | 40 +++++++++++++++++++++++++++++++++++++- handlers/MessageRelated.ts | 18 ----------------- mod.ts | 1 - session/Events.ts | 10 ---------- session/Session.ts | 27 ++++++++++++------------- structures/Message.ts | 14 +------------ tests/mod.ts | 2 +- 7 files changed, 53 insertions(+), 59 deletions(-) delete mode 100644 handlers/MessageRelated.ts delete mode 100644 session/Events.ts diff --git a/handlers/Actions.ts b/handlers/Actions.ts index 0721737..c8be5f6 100644 --- a/handlers/Actions.ts +++ b/handlers/Actions.ts @@ -1 +1,39 @@ -export * from "./MessageRelated.ts"; +import type { DiscordMessage, DiscordReady } from "../vendor/external.ts"; +import type { Snowflake } from "../util/Snowflake.ts"; +import type { Session } from "../session/Session.ts"; +import Message from "../structures/Message.ts"; + +export type RawHandler = (...args: [Session, number, ...T]) => void; +export type Handler = (...args: T) => unknown; + +export type Ready = [DiscordReady]; +export const READY: RawHandler = (session, shardId, payload) => { + session.emit("ready", payload, shardId); +}; + +export type MessageCreate = [DiscordMessage]; +export const MESSAGE_CREATE: RawHandler = (session, _shardId, message) => { + session.emit("messageCreate", new Message(session, message)); +}; + +export type MessageUpdate = [DiscordMessage]; +export const MESSAGE_UPDATE: RawHandler = (session, _shardId, new_message) => { + session.emit("messageUpdate", new Message(session, new_message)); +}; + +export type MessageDelete = [Snowflake]; +export const MESSAGE_DELETE: RawHandler = (session, _shardId, deleted_message_id) => { + session.emit("messageDelete", deleted_message_id); +} + +export const raw: RawHandler<[unknown]> = (session, shardId, data) => { + session.emit("raw", data, shardId); +}; + +export interface Events { + "ready": Handler<[DiscordReady, number]>; + "messageCreate": Handler<[Message]>; + "messageUpdate": Handler<[Message]>; + "messageDelete": Handler<[Snowflake]>; + "raw": Handler<[unknown]>; +} diff --git a/handlers/MessageRelated.ts b/handlers/MessageRelated.ts deleted file mode 100644 index afd1a3d..0000000 --- a/handlers/MessageRelated.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { DiscordMessage, DiscordReady } from "../vendor/external.ts"; -import type { Session } from "../session/Session.ts"; -import { Message } from "../structures/Message.ts"; - -type Handler = (...args: [Session, number, T]) => void; - -// TODO: move this lol -export const READY: Handler = (session, shardId, payload) => { - session.emit("ready", shardId, payload); -}; - -export const MESSAGE_CREATE: Handler = (session, _shardId, message) => { - session.emit("messageCreate", new Message(session, message)); -}; - -export const raw: Handler = (session, shardId, data) => { - session.emit("raw", data, shardId); -}; diff --git a/mod.ts b/mod.ts index fc4e693..b462a6d 100644 --- a/mod.ts +++ b/mod.ts @@ -23,7 +23,6 @@ export * from "./structures/WelcomeChannel.ts"; export * from "./structures/WelcomeScreen.ts"; export * from "./session/Session.ts"; -export * from "./session/Events.ts"; export * from "./util/shared/flags.ts"; export * from "./util/shared/images.ts"; diff --git a/session/Events.ts b/session/Events.ts deleted file mode 100644 index d024a6c..0000000 --- a/session/Events.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { DiscordGatewayPayload, DiscordReady, Shard } from "../vendor/external.ts"; -import type { Message } from "../structures/Message.ts"; - -export type DiscordRawEventHandler = (shard: Shard, data: DiscordGatewayPayload) => unknown; - -export interface Events { - ready(shardId: number, payload: DiscordReady): unknown; - messageCreate(message: Message): unknown; - raw(data: DiscordGatewayPayload, shardId: number): unknown; -} diff --git a/session/Session.ts b/session/Session.ts index cce960e..f66519b 100644 --- a/session/Session.ts +++ b/session/Session.ts @@ -1,5 +1,6 @@ import type { DiscordGetGatewayBot, GatewayBot, GatewayIntents } from "../vendor/external.ts"; -import type { DiscordRawEventHandler, Events } from "./Events.ts"; +import type { Shard, DiscordGatewayPayload } from "../vendor/external.ts"; +import type { Events } from "../handlers/Actions.ts"; import { Snowflake } from "../util/Snowflake.ts"; import { EventEmitter } from "../util/EventEmmiter.ts"; @@ -8,6 +9,8 @@ import { createGatewayManager, createRestManager } from "../vendor/external.ts"; import * as Routes from "../util/Routes.ts"; import * as Actions from "../handlers/Actions.ts"; +export type DiscordRawEventHandler = (shard: Shard, data: DiscordGatewayPayload) => unknown; + export interface RestOptions { secretKey?: string; applicationId?: Snowflake; @@ -71,24 +74,18 @@ export class Session extends EventEmitter { // TODO: set botId in Session.botId or something } - override on(event: "ready", func: Events["ready"]): this; - override on(event: "messageCreate", func: Events["messageCreate"]): this; - override on(event: "raw", func: Events["raw"]): this; - override on(event: keyof Events, func: Events[keyof Events]): this { + override on(event: K, func: Events[K]): this; + override on(event: K, func: (...args: unknown[]) => unknown): this { return super.on(event, func); } - override off(event: "ready", func: Events["ready"]): this; - override off(event: "messageCreate", func: Events["messageCreate"]): this; - override off(event: "raw", func: Events["raw"]): this; - override off(event: keyof Events, func: Events[keyof Events]): this { - return super.off(event, func); + override off(event: K, func: Events[K]): this; + override off(event: K, func: (...args: unknown[]) => unknown): this { + return super.off(event, func); } - - override once(event: "ready", func: Events["ready"]): this; - override once(event: "messageCreate", func: Events["messageCreate"]): this; - override once(event: "raw", func: Events["raw"]): this; - override once(event: keyof Events, func: Events[keyof Events]): this { + + override once(event: K, func: Events[K]): this; + override once(event: K, func: (...args: unknown[]) => unknown): this { return super.once(event, func); } diff --git a/structures/Message.ts b/structures/Message.ts index bf9b2af..d2a8da6 100644 --- a/structures/Message.ts +++ b/structures/Message.ts @@ -31,19 +31,7 @@ export interface CreateMessageReference { export interface CreateMessage { content: string; allowedMentions?: AllowedMentions; - messageReference?: CreateMessageReference; -} - -export interface CreateMessage { - allowedMentions?: AllowedMentions; - files: FileContent[]; - messageReference?: CreateMessageReference; -} - -export interface CreateMessage { - content: string; - allowedMentions?: AllowedMentions; - files: FileContent[]; + files?: FileContent[]; messageReference?: CreateMessageReference; } diff --git a/tests/mod.ts b/tests/mod.ts index 75ed69d..9b933fd 100644 --- a/tests/mod.ts +++ b/tests/mod.ts @@ -7,7 +7,7 @@ if (!Deno.args[0]) { const intents = GatewayIntents.MessageContent | GatewayIntents.Guilds | GatewayIntents.GuildMessages; const session = new Session({ token: Deno.args[0], intents }); -session.on("ready", (_shardId, payload) => { +session.on("ready", (payload) => { console.log("Logged in as:", payload.user.username); }); From bc3dee754f82c54bef0b4fa594ea4b4da76a129d Mon Sep 17 00:00:00 2001 From: Yuzu Date: Thu, 30 Jun 2022 13:17:35 -0500 Subject: [PATCH 4/4] idk --- handlers/Actions.ts | 2 +- session/Session.ts | 6 +++--- structures/Guild.ts | 12 ++++++------ structures/Message.ts | 2 +- tests/mod.ts | 7 ++++++- vendor/types/shared.ts | 8 ++++---- 6 files changed, 21 insertions(+), 16 deletions(-) diff --git a/handlers/Actions.ts b/handlers/Actions.ts index c8be5f6..e9ec833 100644 --- a/handlers/Actions.ts +++ b/handlers/Actions.ts @@ -24,7 +24,7 @@ export const MESSAGE_UPDATE: RawHandler = (session, _shardId, new export type MessageDelete = [Snowflake]; export const MESSAGE_DELETE: RawHandler = (session, _shardId, deleted_message_id) => { session.emit("messageDelete", deleted_message_id); -} +}; export const raw: RawHandler<[unknown]> = (session, shardId, data) => { session.emit("raw", data, shardId); diff --git a/session/Session.ts b/session/Session.ts index f66519b..31263fb 100644 --- a/session/Session.ts +++ b/session/Session.ts @@ -1,5 +1,5 @@ import type { DiscordGetGatewayBot, GatewayBot, GatewayIntents } from "../vendor/external.ts"; -import type { Shard, DiscordGatewayPayload } from "../vendor/external.ts"; +import type { DiscordGatewayPayload, Shard } from "../vendor/external.ts"; import type { Events } from "../handlers/Actions.ts"; import { Snowflake } from "../util/Snowflake.ts"; @@ -81,9 +81,9 @@ export class Session extends EventEmitter { override off(event: K, func: Events[K]): this; override off(event: K, func: (...args: unknown[]) => unknown): this { - return super.off(event, func); + return super.off(event, func); } - + override once(event: K, func: Events[K]): this; override once(event: K, func: (...args: unknown[]) => unknown): this { return super.once(event, func); diff --git a/structures/Guild.ts b/structures/Guild.ts index 9466149..ef265cb 100644 --- a/structures/Guild.ts +++ b/structures/Guild.ts @@ -27,11 +27,11 @@ export interface CreateRole { } export interface ModifyGuildRole { - name?: string; - color?: number; - hoist?: boolean; - mentionable?: boolean; - unicodeEmoji?: string; + name?: string; + color?: number; + hoist?: boolean; + mentionable?: boolean; + unicodeEmoji?: string; } export interface CreateGuildEmoji { @@ -156,7 +156,7 @@ export class Guild extends BaseGuild implements Model { color: options.color, hoist: options.hoist, mentionable: options.mentionable, - } + }, ); return new Role(this.session, role, this.id); diff --git a/structures/Message.ts b/structures/Message.ts index d2a8da6..2f101b0 100644 --- a/structures/Message.ts +++ b/structures/Message.ts @@ -29,7 +29,7 @@ export interface CreateMessageReference { * @link https://discord.com/developers/docs/resources/channel#create-message-json-params */ export interface CreateMessage { - content: string; + content?: string; allowedMentions?: AllowedMentions; files?: FileContent[]; messageReference?: CreateMessageReference; diff --git a/tests/mod.ts b/tests/mod.ts index 9b933fd..f5e7a96 100644 --- a/tests/mod.ts +++ b/tests/mod.ts @@ -11,8 +11,13 @@ session.on("ready", (payload) => { console.log("Logged in as:", payload.user.username); }); +const PREFIX = "&"; + session.on("messageCreate", (message) => { - if (message.content.startsWith("&ping")) { + const args = message.content.slice(PREFIX.length).trim().split(/\s+/gm); + const name = args.shift()?.toLowerCase(); + + if (name === "ping") { message.reply({ content: "pong!" }); } }); diff --git a/vendor/types/shared.ts b/vendor/types/shared.ts index 6c90cdf..e2b205d 100644 --- a/vendor/types/shared.ts +++ b/vendor/types/shared.ts @@ -1238,7 +1238,7 @@ export type CamelCase = S extends `${infer P1}_${infer P2}${in : Lowercase; export type Camelize = { [K in keyof T as CamelCase]: T[K] extends Array ? U extends {} ? Array> - : T[K] + : T[K] : T[K] extends {} ? Camelize : never; }; @@ -1293,8 +1293,8 @@ export type AnythingBut = Exclude< * object identity type */ export type Id = T extends infer U ? { - [K in keyof U]: U[K]; -} + [K in keyof U]: U[K]; + } : never; export type KeysWithUndefined = { @@ -1319,7 +1319,7 @@ type OptionalizeAux = Id< export type Optionalize = T extends object ? T extends Array ? number extends T["length"] ? T[number] extends object ? Array> - : T + : T : Partial : OptionalizeAux : T;