mirror of
https://github.com/tiramisulabs/seyfert.git
synced 2025-07-03 05:26:07 +00:00
commit
ac77337a81
6
mod.ts
6
mod.ts
@ -10,3 +10,9 @@ export * from "./structures/Message.ts";
|
||||
export * from "./structures/BaseGuild.ts";
|
||||
export * from "./structures/Attachment.ts";
|
||||
export * from "./structures/AnonymousGuild.ts";
|
||||
export * from "./structures/DMChannel.ts";
|
||||
export * from "./structures/TextChannel.ts";
|
||||
export * from "./structures/VoiceChannel.ts";
|
||||
export * from "./structures/ThreadChannel.ts";
|
||||
export * from "./structures/NewsChannel.ts";
|
||||
export * from "./structures/Emoji.ts";
|
||||
|
@ -6,7 +6,7 @@ import type { DiscordAttachment } from "../vendor/external.ts";
|
||||
/**
|
||||
* Represents an attachment
|
||||
* @link https://discord.com/developers/docs/resources/channel#attachment-object
|
||||
* */
|
||||
*/
|
||||
export class Attachment implements Model {
|
||||
constructor(session: Session, data: DiscordAttachment) {
|
||||
this.session = session;
|
||||
@ -19,7 +19,7 @@ export class Attachment implements Model {
|
||||
this.size = data.size;
|
||||
this.height = data.height ? data.height : undefined;
|
||||
this.width = data.width ? data.width : undefined;
|
||||
this.ephemeral = !!data.ephemeral
|
||||
this.ephemeral = !!data.ephemeral;
|
||||
}
|
||||
|
||||
readonly session: Session;
|
||||
|
@ -6,7 +6,7 @@ import { iconHashToBigInt } from "../util/hash.ts";
|
||||
|
||||
/**
|
||||
* Class for {@link Guild} and {@link AnonymousGuild}
|
||||
* */
|
||||
*/
|
||||
export abstract class BaseGuild implements Model {
|
||||
constructor(session: Session, data: DiscordGuild) {
|
||||
this.session = session;
|
||||
@ -37,4 +37,3 @@ export abstract class BaseGuild implements Model {
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
|
||||
|
19
structures/Channel.ts
Normal file
19
structures/Channel.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import type { Model } from "./Base.ts";
|
||||
import { ChannelTypes, DiscordChannel, Session, Snowflake } from "../mod.ts";
|
||||
|
||||
export abstract class Channel implements Model {
|
||||
constructor(session: Session, data: DiscordChannel) {
|
||||
this.id = data.id;
|
||||
this.session = session;
|
||||
this.name = data.name;
|
||||
this.type = data.type;
|
||||
}
|
||||
readonly id: Snowflake;
|
||||
readonly session: Session;
|
||||
name?: string;
|
||||
type: ChannelTypes;
|
||||
|
||||
toString(): string {
|
||||
return `<#${this.id}>`;
|
||||
}
|
||||
}
|
22
structures/DMChannel.ts
Normal file
22
structures/DMChannel.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { Channel } from "./Channel.ts";
|
||||
//import { User } from "./User.ts";
|
||||
import { DiscordChannel, Routes, Session, Snowflake } from "../mod.ts";
|
||||
|
||||
export class DMChannel extends Channel {
|
||||
constructor(session: Session, data: DiscordChannel) {
|
||||
super(session, data);
|
||||
data.last_message_id ? this.lastMessageId = data.last_message_id : undefined;
|
||||
// Waiting for implementation of botId in session
|
||||
//this.user = new User(this.session, data.recipents!.find((r) => r.id !== this.session.botId));
|
||||
}
|
||||
lastMessageId?: Snowflake;
|
||||
|
||||
async close() {
|
||||
const channel = await this.session.rest.runMethod<DiscordChannel>(
|
||||
this.session.rest,
|
||||
"DELETE",
|
||||
Routes.CHANNEL(this.id),
|
||||
);
|
||||
return new DMChannel(this.session, channel);
|
||||
}
|
||||
}
|
18
structures/Emoji.ts
Normal file
18
structures/Emoji.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { DiscordEmoji, Session, Snowflake } from "../mod.ts";
|
||||
|
||||
export class Emoji {
|
||||
constructor(session: Session, data: DiscordEmoji) {
|
||||
this.id = data.id;
|
||||
this.name = data.name;
|
||||
this.animated = !!data.animated;
|
||||
this.available = !!data.available;
|
||||
this.requireColons = !!data.require_colons;
|
||||
this.session = session;
|
||||
}
|
||||
readonly id?: Snowflake;
|
||||
readonly session: Session;
|
||||
name?: string;
|
||||
animated: boolean;
|
||||
available: boolean;
|
||||
requireColons: boolean;
|
||||
}
|
@ -2,8 +2,12 @@ import type { Model } from "./Base.ts";
|
||||
import type { Snowflake } from "../util/Snowflake.ts";
|
||||
import type { Session } from "../session/Session.ts";
|
||||
import type { DiscordGuild, DiscordRole } from "../vendor/external.ts";
|
||||
import { DefaultMessageNotificationLevels, ExplicitContentFilterLevels, VerificationLevels } from "../vendor/external.ts";
|
||||
import { iconHashToBigInt, iconBigintToHash } from "../util/hash.ts";
|
||||
import {
|
||||
DefaultMessageNotificationLevels,
|
||||
ExplicitContentFilterLevels,
|
||||
VerificationLevels,
|
||||
} from "../vendor/external.ts";
|
||||
import { iconBigintToHash, iconHashToBigInt } from "../util/hash.ts";
|
||||
import { Member } from "./Member.ts";
|
||||
import { BaseGuild } from "./BaseGuild.ts";
|
||||
import { Role } from "./Role.ts";
|
||||
@ -21,7 +25,7 @@ export interface CreateRole {
|
||||
/**
|
||||
* Represents a guild
|
||||
* @link https://discord.com/developers/docs/resources/guild#guild-object
|
||||
* */
|
||||
*/
|
||||
export class Guild extends BaseGuild implements Model {
|
||||
constructor(session: Session, data: DiscordGuild) {
|
||||
super(session, data);
|
||||
@ -55,8 +59,7 @@ export class Guild extends BaseGuild implements Model {
|
||||
if (options.iconHash) {
|
||||
if (typeof options.iconHash === "string") {
|
||||
icon = options.iconHash;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
icon = iconBigintToHash(options.iconHash);
|
||||
}
|
||||
}
|
||||
@ -72,10 +75,10 @@ export class Guild extends BaseGuild implements Model {
|
||||
unicode_emoji: options.unicodeEmoji,
|
||||
hoist: options.hoist,
|
||||
mentionable: options.mentionable,
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return new Role(this.session, this, role);
|
||||
return new Role(this.session, this.id, role);
|
||||
}
|
||||
|
||||
async deleteRole(roleId: Snowflake): Promise<void> {
|
||||
|
29
structures/GuildChannel.ts
Normal file
29
structures/GuildChannel.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import { Channel } from "./Channel.ts";
|
||||
import { Guild } from "./Guild.ts";
|
||||
import { DiscordChannel, Routes, Session, Snowflake } from "../mod.ts";
|
||||
|
||||
export abstract class GuildChannel extends Channel {
|
||||
constructor(session: Session, data: DiscordChannel, guildId: Guild["id"]) {
|
||||
super(session, data);
|
||||
this.guildId = guildId;
|
||||
this.position = data.position;
|
||||
data.topic ? this.topic = data.topic : null;
|
||||
data.parent_id ? this.parentId = data.parent_id : undefined;
|
||||
}
|
||||
|
||||
guildId: Snowflake;
|
||||
topic?: string;
|
||||
position?: number;
|
||||
parentId?: Snowflake;
|
||||
|
||||
delete(reason?: string) {
|
||||
return this.session.rest.runMethod<DiscordChannel>(
|
||||
this.session.rest,
|
||||
"DELETE",
|
||||
Routes.CHANNEL(this.id),
|
||||
{
|
||||
reason,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
15
structures/GuildEmoji.ts
Normal file
15
structures/GuildEmoji.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { DiscordEmoji, Emoji, Session, Snowflake, User } from "../mod.ts";
|
||||
|
||||
export class GuildEmoji extends Emoji {
|
||||
constructor(session: Session, data: DiscordEmoji, guildId: Snowflake) {
|
||||
super(session, data);
|
||||
this.guildId = guildId;
|
||||
this.roles = data.roles;
|
||||
this.user = data.user ? new User(this.session, data.user) : undefined;
|
||||
this.managed = !!data.managed;
|
||||
}
|
||||
guildId: Snowflake;
|
||||
roles?: Snowflake[];
|
||||
user?: User;
|
||||
managed?: boolean;
|
||||
}
|
@ -9,19 +9,19 @@ import { User } from "./User.ts";
|
||||
|
||||
/**
|
||||
* @link https://discord.com/developers/docs/resources/guild#create-guild-ban
|
||||
* */
|
||||
*/
|
||||
export interface CreateGuildBan {
|
||||
/** Number of days to delete messages for (0-7) */
|
||||
deleteMessageDays?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;
|
||||
/** Reason for the ban */
|
||||
reason?: string;
|
||||
/** Number of days to delete messages for (0-7) */
|
||||
deleteMessageDays?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;
|
||||
/** Reason for the ban */
|
||||
reason?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a guild member
|
||||
* TODO: add a `guild` property somehow
|
||||
* @link https://discord.com/developers/docs/resources/guild#guild-member-object
|
||||
* */
|
||||
*/
|
||||
export class Member implements Model {
|
||||
constructor(session: Session, data: MakeRequired<DiscordMember, "user">) {
|
||||
this.session = session;
|
||||
@ -33,7 +33,9 @@ export class Member implements Model {
|
||||
this.deaf = !!data.deaf;
|
||||
this.mute = !!data.mute;
|
||||
this.pending = !!data.pending;
|
||||
this.communicationDisabledUntilTimestamp = data.communication_disabled_until ? Number.parseInt(data.communication_disabled_until) : undefined;
|
||||
this.communicationDisabledUntilTimestamp = data.communication_disabled_until
|
||||
? Number.parseInt(data.communication_disabled_until)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
readonly session: Session;
|
||||
@ -63,16 +65,18 @@ export class Member implements Model {
|
||||
|
||||
/**
|
||||
* Bans the member
|
||||
* */
|
||||
*/
|
||||
async ban(guildId: Snowflake, options: CreateGuildBan): Promise<Member> {
|
||||
await this.session.rest.runMethod<undefined>(
|
||||
this.session.rest,
|
||||
"PUT",
|
||||
Routes.GUILD_BAN(guildId, this.id),
|
||||
options ? {
|
||||
delete_message_days: options.deleteMessageDays,
|
||||
reason: options.reason
|
||||
} : {}
|
||||
options
|
||||
? {
|
||||
delete_message_days: options.deleteMessageDays,
|
||||
reason: options.reason,
|
||||
}
|
||||
: {},
|
||||
);
|
||||
|
||||
return this;
|
||||
@ -80,13 +84,13 @@ export class Member implements Model {
|
||||
|
||||
/**
|
||||
* Kicks the member
|
||||
* */
|
||||
*/
|
||||
async kick(guildId: Snowflake, { reason }: { reason?: string }): Promise<Member> {
|
||||
await this.session.rest.runMethod<undefined>(
|
||||
this.session.rest,
|
||||
"DELETE",
|
||||
Routes.GUILD_MEMBER(guildId, this.id),
|
||||
{ reason }
|
||||
{ reason },
|
||||
);
|
||||
|
||||
return this;
|
||||
|
@ -55,10 +55,12 @@ export class Message implements Model {
|
||||
this.attachments = data.attachments.map((attachment) => new Attachment(session, attachment));
|
||||
|
||||
// user is always null on MessageCreate and its replaced with author
|
||||
this.member = data.member ? new Member(session, {
|
||||
...data.member,
|
||||
user: data.author,
|
||||
}) : undefined;
|
||||
this.member = data.member
|
||||
? new Member(session, {
|
||||
...data.member,
|
||||
user: data.author,
|
||||
})
|
||||
: undefined;
|
||||
}
|
||||
|
||||
readonly session: Session;
|
||||
|
9
structures/NewsChannel.ts
Normal file
9
structures/NewsChannel.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { DiscordChannel, Guild, Session, TextChannel } from "../mod.ts";
|
||||
|
||||
export class NewsChannel extends TextChannel {
|
||||
constructor(session: Session, data: DiscordChannel, guildId: Guild["id"]) {
|
||||
super(session, data, guildId);
|
||||
this.defaultAutoArchiveDuration = data.default_auto_archive_duration;
|
||||
}
|
||||
defaultAutoArchiveDuration?: number;
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
import { BitwisePermissionFlags } from "../vendor/external.ts";
|
||||
|
||||
export type PermissionString = keyof typeof BitwisePermissionFlags;
|
||||
export type PermissionResolvable=
|
||||
export type PermissionResolvable =
|
||||
| bigint
|
||||
| PermissionString
|
||||
| PermissionString[]
|
||||
@ -32,7 +32,9 @@ export class Permissions {
|
||||
case "string":
|
||||
return BigInt(Permissions.Flags[bit]);
|
||||
case "object":
|
||||
return Permissions.resolve(bit.map((p) => BigInt(Permissions.Flags[p])).reduce((acc, cur) => acc | cur, 0n));
|
||||
return Permissions.resolve(
|
||||
bit.map((p) => BigInt(Permissions.Flags[p])).reduce((acc, cur) => acc | cur, 0n),
|
||||
);
|
||||
default:
|
||||
throw new TypeError(`Cannot resolve permission: ${bit}`);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import type { Model } from "./Base.ts";
|
||||
import type { Session } from "../session/Session.ts";
|
||||
import type { DiscordRole } from "../vendor/external.ts";
|
||||
import { Snowflake } from "../util/Snowflake.ts";
|
||||
import { Snowflake } from "../mod.ts";
|
||||
import { iconHashToBigInt } from "../util/hash.ts";
|
||||
import { Permissions } from "./Permissions.ts";
|
||||
import { Guild } from "./Guild.ts";
|
||||
@ -42,7 +42,7 @@ export class Role implements Model {
|
||||
}
|
||||
|
||||
get hexColor() {
|
||||
return `#${this.color.toString(16).padStart(6, '0')}`;
|
||||
return `#${this.color.toString(16).padStart(6, "0")}`;
|
||||
}
|
||||
|
||||
async delete(): Promise<void> {
|
||||
|
93
structures/TextChannel.ts
Normal file
93
structures/TextChannel.ts
Normal file
@ -0,0 +1,93 @@
|
||||
import { GuildChannel } from "./GuildChannel.ts";
|
||||
import { Guild } from "./Guild.ts";
|
||||
import { ThreadChannel } from "./ThreadChannel.ts";
|
||||
import { Message } from "./Message.ts";
|
||||
import { DiscordChannel, DiscordInviteCreate, DiscordMessage, Routes, Session, Snowflake } from "../mod.ts";
|
||||
import { GetMessagesOptions } from "../util/Routes.ts";
|
||||
|
||||
/**
|
||||
* Represents the options object to create an invitation
|
||||
* @link https://discord.com/developers/docs/resources/channel#create-channel-invite-json-params
|
||||
*/
|
||||
|
||||
export interface DiscordInviteOptions {
|
||||
max_age?: number;
|
||||
max_uses?: number;
|
||||
unique?: boolean;
|
||||
temporary: boolean;
|
||||
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 TextChannel extends GuildChannel {
|
||||
constructor(session: Session, data: DiscordChannel, guildId: Guild["id"]) {
|
||||
super(session, data, guildId);
|
||||
data.last_message_id ? this.lastMessageId = data.last_message_id : undefined;
|
||||
data.last_pin_timestamp ? this.lastPinTimestamp = data.last_pin_timestamp : undefined;
|
||||
this.rateLimitPerUser = data.rate_limit_per_user ?? 0;
|
||||
this.nsfw = !!data.nsfw ?? false;
|
||||
}
|
||||
|
||||
lastMessageId?: Snowflake;
|
||||
lastPinTimestamp?: string;
|
||||
rateLimitPerUser: number;
|
||||
nsfw: boolean;
|
||||
|
||||
async fetchPins(): Promise<Message[] | []> {
|
||||
const messages = await this.session.rest.runMethod<DiscordMessage[]>(
|
||||
this.session.rest,
|
||||
"GET",
|
||||
Routes.CHANNEL_PINS(this.id),
|
||||
);
|
||||
return messages[0] ? messages.map((x: DiscordMessage) => new Message(this.session, x)) : [];
|
||||
}
|
||||
// TODO return Invite Class
|
||||
createInvite(options?: DiscordInviteOptions) {
|
||||
return this.session.rest.runMethod<DiscordInviteCreate>(
|
||||
this.session.rest,
|
||||
"POST",
|
||||
Routes.CHANNEL_INVITES(this.id),
|
||||
options,
|
||||
);
|
||||
}
|
||||
|
||||
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[] | []> {
|
||||
if (options?.limit! > 100) throw Error("Values must be between 0-100");
|
||||
const messages = await this.session.rest.runMethod<DiscordMessage[]>(
|
||||
this.session.rest,
|
||||
"GET",
|
||||
Routes.CHANNEL_MESSAGES(this.id, options),
|
||||
);
|
||||
return messages[0] ? messages.map((x) => new Message(this.session, x)) : [];
|
||||
}
|
||||
|
||||
sendTyping() {
|
||||
this.session.rest.runMethod<undefined>(
|
||||
this.session.rest,
|
||||
"POST",
|
||||
Routes.CHANNEL_TYPING(this.id),
|
||||
);
|
||||
}
|
||||
}
|
23
structures/ThreadChannel.ts
Normal file
23
structures/ThreadChannel.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { GuildChannel } from "./GuildChannel.ts";
|
||||
import { Guild } from "./Guild.ts";
|
||||
import { DiscordChannel, Session, Snowflake } from "../mod.ts";
|
||||
|
||||
export class ThreadChannel extends GuildChannel {
|
||||
constructor(session: Session, data: DiscordChannel, guildId: Guild["id"]) {
|
||||
super(session, data, guildId);
|
||||
this.archived = !!data.thread_metadata?.archived;
|
||||
this.archiveTimestamp = data.thread_metadata?.archive_timestamp;
|
||||
this.autoArchiveDuration = data.thread_metadata?.auto_archive_duration;
|
||||
this.locked = !!data.thread_metadata?.locked;
|
||||
this.messageCount = data.message_count;
|
||||
this.memberCount = data.member_count;
|
||||
this.ownerId = data.owner_id;
|
||||
}
|
||||
archived?: boolean;
|
||||
archiveTimestamp?: string;
|
||||
autoArchiveDuration?: number;
|
||||
locked?: boolean;
|
||||
messageCount?: number;
|
||||
memberCount?: number;
|
||||
ownerId?: Snowflake;
|
||||
}
|
20
structures/VoiceChannel.ts
Normal file
20
structures/VoiceChannel.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { GuildChannel } from "./GuildChannel.ts";
|
||||
import { Guild } from "./Guild.ts";
|
||||
import { DiscordChannel, Session, Snowflake, VideoQualityModes } from "../mod.ts";
|
||||
|
||||
export class VoiceChannel extends GuildChannel {
|
||||
constructor(session: Session, data: DiscordChannel, guildId: Guild["id"]) {
|
||||
super(session, data, guildId);
|
||||
this.bitRate = data.bitrate;
|
||||
this.userLimit = data.user_limit ?? 0;
|
||||
data.rtc_region ? this.rtcRegion = data.rtc_region : undefined;
|
||||
this.videoQuality = data.video_quality_mode;
|
||||
this.nsfw = !!data.nsfw;
|
||||
}
|
||||
bitRate?: number;
|
||||
userLimit: number;
|
||||
rtcRegion?: Snowflake;
|
||||
|
||||
videoQuality?: VideoQualityModes;
|
||||
nsfw?: boolean;
|
||||
}
|
@ -26,6 +26,30 @@ export interface GetMessagesOptions {
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
export function CHANNEL(channelId: Snowflake) {
|
||||
return `/channels/${channelId}`;
|
||||
}
|
||||
|
||||
export function CHANNEL_INVITES(channelId: Snowflake) {
|
||||
return `/channels/${channelId}/invites`;
|
||||
}
|
||||
|
||||
export function CHANNEL_TYPING(channelId: Snowflake) {
|
||||
return `/channels/${channelId}/typing`;
|
||||
}
|
||||
|
||||
export function CHANNEL_CREATE_THREAD(channelId: Snowflake) {
|
||||
return `/channels/${channelId}/threads`;
|
||||
}
|
||||
|
||||
export function MESSAGE_CREATE_THREAD(channelId: Snowflake, messageId: Snowflake) {
|
||||
return `/channels/${channelId}/messages/${messageId}/threads`;
|
||||
}
|
||||
|
||||
export function CHANNEL_PINS(channelId: Snowflake) {
|
||||
return `/channels/${channelId}/pins`;
|
||||
}
|
||||
|
||||
/** used to send messages */
|
||||
export function CHANNEL_MESSAGES(channelId: Snowflake, options?: GetMessagesOptions) {
|
||||
let url = `/channels/${channelId}/messages?`;
|
||||
@ -56,9 +80,9 @@ export function GUILD_BAN(guildId: Snowflake, userId: Snowflake) {
|
||||
}
|
||||
|
||||
export interface GetBans {
|
||||
limit?: number;
|
||||
before?: Snowflake;
|
||||
after?: Snowflake;
|
||||
limit?: number;
|
||||
before?: Snowflake;
|
||||
after?: Snowflake;
|
||||
}
|
||||
|
||||
/** used to unban members */
|
||||
|
2
vendor/types/discord.ts
vendored
2
vendor/types/discord.ts
vendored
@ -752,6 +752,8 @@ export interface DiscordChannel {
|
||||
permissions?: string;
|
||||
/** When a thread is created this will be true on that channel payload for the thread. */
|
||||
newly_created?: boolean;
|
||||
/** The recipients of the DM*/
|
||||
recipents?: DiscordUser[];
|
||||
}
|
||||
|
||||
/** https://discord.com/developers/docs/topics/gateway#presence-update */
|
||||
|
Loading…
x
Reference in New Issue
Block a user