Merge branch 'main' into interaction-struct

This commit is contained in:
Yuzu 2022-06-30 13:26:34 -05:00
commit 228b9dfb3b
12 changed files with 117 additions and 66 deletions

View File

@ -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<T extends unknown[]> = (...args: [Session, number, ...T]) => void;
export type Handler<T extends unknown[]> = (...args: T) => unknown;
export type Ready = [DiscordReady];
export const READY: RawHandler<Ready> = (session, shardId, payload) => {
session.emit("ready", payload, shardId);
};
export type MessageCreate = [DiscordMessage];
export const MESSAGE_CREATE: RawHandler<MessageCreate> = (session, _shardId, message) => {
session.emit("messageCreate", new Message(session, message));
};
export type MessageUpdate = [DiscordMessage];
export const MESSAGE_UPDATE: RawHandler<MessageUpdate> = (session, _shardId, new_message) => {
session.emit("messageUpdate", new Message(session, new_message));
};
export type MessageDelete = [Snowflake];
export const MESSAGE_DELETE: RawHandler<MessageDelete> = (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]>;
}

View File

@ -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<T> = (...args: [Session, number, T]) => void;
// TODO: move this lol
export const READY: Handler<DiscordReady> = (session, shardId, payload) => {
session.emit("ready", shardId, payload);
};
export const MESSAGE_CREATE: Handler<DiscordMessage> = (session, _shardId, message) => {
session.emit("messageCreate", new Message(session, message));
};
export const raw: Handler<unknown> = (session, shardId, data) => {
session.emit("raw", data, shardId);
};

1
mod.ts
View File

@ -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";

View File

@ -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;
}

View File

@ -1,5 +1,6 @@
import type { DiscordGetGatewayBot, GatewayBot, GatewayIntents } from "../vendor/external.ts";
import type { DiscordRawEventHandler, Events } from "./Events.ts";
import type { DiscordGatewayPayload, Shard } 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<K extends keyof Events>(event: K, func: Events[K]): this;
override on<K extends string>(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 {
override off<K extends keyof Events>(event: K, func: Events[K]): this;
override off<K extends string>(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<K extends keyof Events>(event: K, func: Events[K]): this;
override once<K extends string>(event: K, func: (...args: unknown[]) => unknown): this {
return super.once(event, func);
}

View File

@ -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<undefined>(this.session.rest, "DELETE", Routes.GUILD_ROLE(this.id, roleId));
}
// TODO: edit role
async editRole(roleId: Snowflake, options: ModifyGuildRole): Promise<Role> {
const role = await this.session.rest.runMethod<DiscordRole>(
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<void> {
await this.session.rest.runMethod<undefined>(
@ -158,6 +180,16 @@ export class Guild extends BaseGuild implements Model {
return new Invite(this.session, inviteMetadata);
}
async fetchInvites(): Promise<Invite[]> {
const invites = await this.session.rest.runMethod<DiscordInviteMetadata[]>(
this.session.rest,
"GET",
Routes.GUILD_INVITES(this.id),
);
return invites.map((invite) => new Invite(this.session, invite));
}
}
export default Guild;

View File

@ -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<Invite[]> {
const invites = await this.session.rest.runMethod<DiscordInviteMetadata[]>(
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<DiscordChannel>(
this.session.rest,

View File

@ -29,21 +29,9 @@ export interface CreateMessageReference {
* @link https://discord.com/developers/docs/resources/channel#create-message-json-params
*/
export interface CreateMessage {
content: string;
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;
}

View File

@ -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:

View File

@ -7,12 +7,17 @@ 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);
});
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!" });
}
});

View File

@ -135,3 +135,7 @@ export function INVITE(inviteCode: string, options?: GetInvite) {
return url;
}
export function GUILD_INVITES(guildId: Snowflake) {
return `/guilds/${guildId}/invites`;
}

View File

@ -1238,7 +1238,7 @@ export type CamelCase<S extends string> = S extends `${infer P1}_${infer P2}${in
: Lowercase<S>;
export type Camelize<T> = {
[K in keyof T as CamelCase<string & K>]: T[K] extends Array<infer U> ? U extends {} ? Array<Camelize<U>>
: T[K]
: T[K]
: T[K] extends {} ? Camelize<T[K]>
: never;
};
@ -1293,8 +1293,8 @@ export type AnythingBut<T> = Exclude<
* object identity type
*/
export type Id<T> = T extends infer U ? {
[K in keyof U]: U[K];
}
[K in keyof U]: U[K];
}
: never;
export type KeysWithUndefined<T> = {
@ -1319,7 +1319,7 @@ type OptionalizeAux<T extends object> = Id<
export type Optionalize<T> = T extends object
? T extends Array<unknown>
? number extends T["length"] ? T[number] extends object ? Array<OptionalizeAux<T[number]>>
: T
: T
: Partial<T>
: OptionalizeAux<T>
: T;