fix: TextChannel no longer extends GuildChannel

This commit is contained in:
Yuzu 2022-07-02 10:19:08 -05:00
parent 36acf92ad1
commit a2b53ab51e
8 changed files with 127 additions and 41 deletions

View File

@ -62,7 +62,7 @@ export abstract class BaseChannel implements Model {
return new VoiceChannel(session, channel, channel.guild_id!); return new VoiceChannel(session, channel, channel.guild_id!);
default: default:
if (textBasedChannels.includes(channel.type)) { if (textBasedChannels.includes(channel.type)) {
return new TextChannel(session, channel, channel.guild_id!); return new TextChannel(session, channel);
} }
throw new Error("Channel was not implemented"); throw new Error("Channel was not implemented");
} }

View File

@ -1,24 +1,23 @@
import type { Model } from "./Base.ts"; import type { Model } from "./Base.ts";
import type { Snowflake } from "../util/Snowflake.ts";
import type { Session } from "../session/Session.ts"; import type { Session } from "../session/Session.ts";
import type { DiscordChannel } from "../vendor/external.ts"; import type { ChannelTypes, DiscordChannel } from "../vendor/external.ts";
import BaseChannel from "./BaseChannel.ts"; import TextChannel from "./TextChannel.ts";
import User from "./User.ts"; import User from "./User.ts";
import * as Routes from "../util/Routes.ts"; import * as Routes from "../util/Routes.ts";
export class DMChannel extends BaseChannel implements Model { export class DMChannel extends TextChannel implements Model {
constructor(session: Session, data: DiscordChannel) { constructor(session: Session, data: DiscordChannel) {
super(session, data); super(session, data);
this.user = new User(this.session, data.recipents!.find((r) => r.id !== this.session.botId)!); this.user = new User(this.session, data.recipents!.find((r) => r.id !== this.session.botId)!);
this.type = data.type as ChannelTypes.DM | ChannelTypes.GroupDm;
if (data.last_message_id) { if (data.last_message_id) {
this.lastMessageId = data.last_message_id; this.lastMessageId = data.last_message_id;
} }
} }
override type: ChannelTypes.DM | ChannelTypes.GroupDm;
user: User; user: User;
lastMessageId?: Snowflake;
async close() { async close() {
const channel = await this.session.rest.runMethod<DiscordChannel>( const channel = await this.session.rest.runMethod<DiscordChannel>(

View File

@ -1,20 +1,44 @@
import type { Model } from "./Base.ts"; import type { Model } from "./Base.ts";
import type { Snowflake } from "../util/Snowflake.ts"; import type { Snowflake } from "../util/Snowflake.ts";
import type { Session } from "../session/Session.ts"; import type { Session } from "../session/Session.ts";
import type { DiscordChannel, DiscordInviteMetadata } from "../vendor/external.ts"; import type { ChannelTypes, DiscordChannel, DiscordWebhook, DiscordInviteMetadata } from "../vendor/external.ts";
import { urlToBase64 } from "../util/urlToBase64.ts";
import BaseChannel from "./BaseChannel.ts"; import BaseChannel from "./BaseChannel.ts";
import Invite from "./Invite.ts"; import Invite from "./Invite.ts";
import Webhook from "./Webhook.ts";
import ThreadChannel from "./ThreadChannel.ts";
import * as Routes from "../util/Routes.ts"; import * as Routes from "../util/Routes.ts";
export interface CreateWebhook {
name: string;
avatar?: string;
reason?: string;
}
/**
* Represent the options object to create a Thread Channel
* @link https://discord.com/developers/docs/resources/channel#start-thread-without-message
*/
export interface ThreadCreateOptions {
name: string;
autoArchiveDuration: 60 | 1440 | 4320 | 10080;
type: 10 | 11 | 12;
invitable?: boolean;
reason?: string;
}
export class GuildChannel extends BaseChannel implements Model { export class GuildChannel extends BaseChannel implements Model {
constructor(session: Session, data: DiscordChannel, guildId: Snowflake) { constructor(session: Session, data: DiscordChannel, guildId: Snowflake) {
super(session, data); super(session, data);
this.type = data.type as number
this.guildId = guildId; this.guildId = guildId;
this.position = data.position; this.position = data.position;
data.topic ? this.topic = data.topic : null; data.topic ? this.topic = data.topic : null;
data.parent_id ? this.parentId = data.parent_id : undefined; data.parent_id ? this.parentId = data.parent_id : undefined;
} }
override type: Exclude<ChannelTypes, ChannelTypes.DM | ChannelTypes.GroupDm>;
guildId: Snowflake; guildId: Snowflake;
topic?: string; topic?: string;
position?: number; position?: number;
@ -40,6 +64,31 @@ export class GuildChannel extends BaseChannel implements Model {
}, },
); );
} }
async createThread(options: ThreadCreateOptions): Promise<ThreadChannel> {
const thread = await this.session.rest.runMethod<DiscordChannel>(
this.session.rest,
"POST",
Routes.CHANNEL_CREATE_THREAD(this.id),
options,
);
return new ThreadChannel(this.session, thread, this.guildId);
}
async createWebhook(options: CreateWebhook) {
const webhook = await this.session.rest.runMethod<DiscordWebhook>(
this.session.rest,
"POST",
Routes.CHANNEL_WEBHOOKS(this.id),
{
name: options.name,
avatar: options.avatar ? urlToBase64(options.avatar) : undefined,
reason: options.reason,
}
);
return new Webhook(this.session, webhook);
}
} }
export default GuildChannel; export default GuildChannel;

View File

@ -1,14 +1,17 @@
import type { Snowflake } from "../util/Snowflake.ts"; import type { Snowflake } from "../util/Snowflake.ts";
import type { Session } from "../session/Session.ts"; import type { Session } from "../session/Session.ts";
import type { DiscordChannel } from "../vendor/external.ts"; import type { ChannelTypes, DiscordChannel } from "../vendor/external.ts";
import TextChannel from "./TextChannel.ts"; import GuildChannel from "./GuildChannel.ts";
import Message from "./Message.ts"; import Message from "./Message.ts";
export class NewsChannel extends TextChannel { export class NewsChannel extends GuildChannel {
constructor(session: Session, data: DiscordChannel, guildId: Snowflake) { constructor(session: Session, data: DiscordChannel, guildId: Snowflake) {
super(session, data, guildId); super(session, data, guildId);
this.type = data.type as ChannelTypes.GuildNews;
this.defaultAutoArchiveDuration = data.default_auto_archive_duration; this.defaultAutoArchiveDuration = data.default_auto_archive_duration;
} }
override type: ChannelTypes.GuildNews;
defaultAutoArchiveDuration?: number; defaultAutoArchiveDuration?: number;
crosspostMessage(messageId: Snowflake): Promise<Message> { crosspostMessage(messageId: Snowflake): Promise<Message> {

View File

@ -4,8 +4,7 @@ import type { GetMessagesOptions, GetReactions } from "../util/Routes.ts";
import type { DiscordChannel, DiscordInvite, DiscordMessage, TargetTypes } from "../vendor/external.ts"; import type { DiscordChannel, DiscordInvite, DiscordMessage, TargetTypes } from "../vendor/external.ts";
import type { CreateMessage, EditMessage, ReactionResolvable } from "./Message.ts"; import type { CreateMessage, EditMessage, ReactionResolvable } from "./Message.ts";
import { ChannelTypes } from "../vendor/external.ts"; import { ChannelTypes } from "../vendor/external.ts";
import GuildChannel from "./GuildChannel.ts"; import BaseChannel from "./BaseChannel.ts";
import ThreadChannel from "./ThreadChannel.ts";
import Message from "./Message.ts"; import Message from "./Message.ts";
import Invite from "./Invite.ts"; import Invite from "./Invite.ts";
import * as Routes from "../util/Routes.ts"; import * as Routes from "../util/Routes.ts";
@ -25,18 +24,6 @@ export interface DiscordInviteOptions {
targetApplicationId?: Snowflake; targetApplicationId?: Snowflake;
} }
/**
* Represent the options object to create a Thread Channel
* @link https://discord.com/developers/docs/resources/channel#start-thread-without-message
*/
export interface ThreadCreateOptions {
name: string;
autoArchiveDuration: 60 | 1440 | 4320 | 10080;
type: 10 | 11 | 12;
invitable?: boolean;
reason?: string;
}
export const textBasedChannels = [ export const textBasedChannels = [
ChannelTypes.DM, ChannelTypes.DM,
ChannelTypes.GroupDm, ChannelTypes.GroupDm,
@ -54,14 +41,20 @@ export type TextBasedChannels =
| ChannelTypes.GuildNews | ChannelTypes.GuildNews
| ChannelTypes.GuildText; | ChannelTypes.GuildText;
export class TextChannel extends GuildChannel { export class TextChannel extends BaseChannel {
constructor(session: Session, data: DiscordChannel, guildId: Snowflake) { constructor(session: Session, data: DiscordChannel) {
super(session, data, guildId); super(session, data);
data.last_message_id ? this.lastMessageId = data.last_message_id : undefined; this.type = data.type as number;
data.last_pin_timestamp ? this.lastPinTimestamp = data.last_pin_timestamp : undefined;
this.type = data.type as TextBasedChannels;
this.rateLimitPerUser = data.rate_limit_per_user ?? 0; this.rateLimitPerUser = data.rate_limit_per_user ?? 0;
this.nsfw = !!data.nsfw ?? false; this.nsfw = !!data.nsfw ?? false;
if (data.last_message_id) {
this.lastMessageId = data.last_message_id;
}
if (data.last_pin_timestamp) {
this.lastPinTimestamp = data.last_pin_timestamp;
}
} }
override type: TextBasedChannels; override type: TextBasedChannels;
@ -100,16 +93,6 @@ export class TextChannel extends GuildChannel {
return new Invite(this.session, invite); return new Invite(this.session, invite);
} }
async createThread(options: ThreadCreateOptions): Promise<ThreadChannel> {
const thread = await this.session.rest.runMethod<DiscordChannel>(
this.session.rest,
"POST",
Routes.CHANNEL_CREATE_THREAD(this.id),
options,
);
return new ThreadChannel(this.session, thread, this.guildId);
}
async fetchMessages(options?: GetMessagesOptions): Promise<Message[] | []> { async fetchMessages(options?: GetMessagesOptions): Promise<Message[] | []> {
if (options?.limit! > 100) throw Error("Values must be between 0-100"); if (options?.limit! > 100) throw Error("Values must be between 0-100");
const messages = await this.session.rest.runMethod<DiscordMessage[]>( const messages = await this.session.rest.runMethod<DiscordMessage[]>(

47
structures/Webhook.ts Normal file
View File

@ -0,0 +1,47 @@
import type { Model } from "./Base.ts";
import type { Session } from "../session/Session.ts";
import type { Snowflake } from "../util/Snowflake.ts";
import type { DiscordWebhook, WebhookTypes } from "../vendor/external.ts";
import { iconHashToBigInt } from "../util/hash.ts";
import User from "./User.ts";
export class Webhook implements Model {
constructor(session: Session, data: DiscordWebhook) {
this.session = session;
this.id = data.id;
this.type = data.type;
this.token = data.token;
if (data.avatar) {
this.avatar = iconHashToBigInt(data.avatar);
}
if (data.user) {
this.user = new User(session, data.user);
}
if (data.guild_id) {
this.guildId = data.guild_id;
}
if (data.channel_id) {
this.channelId = data.channel_id;
}
if (data.application_id) {
this.applicationId = data.application_id;
}
}
readonly session: Session;
readonly id: Snowflake;
type: WebhookTypes;
token?: string;
avatar?: bigint;
applicationId?: Snowflake;
channelId?: Snowflake;
guildId?: Snowflake;
user?: User;
}
export default Webhook;

View File

@ -5,6 +5,7 @@ import type { DiscordWelcomeScreenChannel } from "../vendor/external.ts";
import Emoji from "./Emoji.ts"; import Emoji from "./Emoji.ts";
/** /**
* Not a channel
* @link https://discord.com/developers/docs/resources/guild#welcome-screen-object-welcome-screen-channel-structure * @link https://discord.com/developers/docs/resources/guild#welcome-screen-object-welcome-screen-channel-structure
*/ */
export class WelcomeChannel implements Model { export class WelcomeChannel implements Model {

View File

@ -224,3 +224,7 @@ export function CHANNEL_MESSAGE_CROSSPOST(channelId: Snowflake, messageId: Snowf
export function GUILD_MEMBER_ROLE(guildId: Snowflake, memberId: Snowflake, roleId: Snowflake) { export function GUILD_MEMBER_ROLE(guildId: Snowflake, memberId: Snowflake, roleId: Snowflake) {
return `/guilds/${guildId}/members/${memberId}/roles/${roleId}`; return `/guilds/${guildId}/members/${memberId}/roles/${roleId}`;
} }
export function CHANNEL_WEBHOOKS(channelId: Snowflake) {
return `/channels/${channelId}/webhooks`;
}